Cosa fare riguardo la grande cronologia di svn quando si passa a git?

22

Modifica: a differenza di alcune domande simili come Spostamento di un repository SVN multi-GB su Git o link Il mio scenario non coinvolge diversi sottoprogetti che possono essere facilmente convertiti in submoduit git, né alcuni file binari molto grandi che sono adatti per git-annex. È un singolo repository in cui i binari sono la suite di test strettamente accoppiata al codice sorgente principale della stessa revisione, proprio come se fossero risorse di tempo compilabili come la grafica.

Sto studiando il passaggio da un vecchio repository di codice di dimensioni medio / grandi (50 utenti, revisioni 60k, cronologia 80Gb, copia di lavoro 2Gb) da svn. Man mano che il numero di utenti è cresciuto, c'è molto churn in trunk e le funzionalità sono spesso distribuite su più commit rendendo difficile la revisione del codice. Inoltre, senza diramazione non c'è modo di "uscire" dal codice errato, le recensioni possono essere fatte solo dopo che è stato impegnato nel trunk. Sto studiando alternative. Speravo che potessimo passare al git, ma ho qualche problema.

Il problema con il repository corrente per quanto riguarda git è la dimensione. C'è un sacco di vecchi cruft, e pulirlo con --filter-branch quando si converte in git può ridurlo in dimensioni di un ordine di grandezza, a circa 5-10 GB. Questo è ancora troppo grande. La più grande ragione per la dimensione del repository di grandi dimensioni è che ci sono molti documenti binari che sono input per i test. Questi file variano tra .5mb e 30mb e ce ne sono centinaia. Hanno anche molti cambiamenti. Ho esaminato i sottomoduli, git-annex, ecc, ma avere i test in un sottomodulo è sbagliato, così come avere un allegato per molti file per i quali si desidera avere una cronologia completa.

Quindi la natura distribuita di git è davvero ciò che mi impedisce di adottarlo. Non mi interessa davvero distribuito, voglio solo la ramificazione economica e potenti funzionalità di fusione. Come suppongo che faccia il 99,9% degli utenti git, useremo un repository centrale benedetto e nudo.

Non sono sicuro di capire perché ogni utente deve avere una cronologia locale completa quando si utilizza git? Se il flusso di lavoro non è decentralizzato, che cosa stanno facendo quei dati sui dischi degli utenti? So che nelle versioni recenti di git puoi usare un clone poco profondo con solo una storia recente. La mia domanda è: è praticabile farlo come modalità operativa standard per un intero team? Può essere configurato per essere sempre superficiale in modo da avere una cronologia completa solo centralmente, ma gli utenti di default hanno solo 1000 giri di storia? L'opzione ovviamente sarebbe quella di convertire solo 1000 giri in git e mantenere il repository svn per l'archeologia. In tale scenario, tuttavia, riscontreremmo di nuovo lo stesso problema dopo le prossime migliaia di revisioni dei documenti di test.

  • Quale è una buona pratica migliore per l'utilizzo di git con repository di grandi dimensioni contenenti molti file binari per i quali fai vuoi la cronologia? La maggior parte delle best practice e dei tutorial sembrano evitare questo caso. Risolvono il problema di alcuni binari enormi o propongono di eliminare completamente i binari.
  • La clonazione superficiale è utilizzabile come una normale modalità operativa o è un "trucco"?
  • I sottomoduli possono essere utilizzati per il codice in cui si ha una stretta dipendenza tra la revisione del sorgente principale e la revisione del sottomodulo (come nelle dipendenze binarie del tempo di compilazione o in una suite di test unitario)?
  • Quanto è grande "troppo grande" per un repository git (in locale)? Dovremmo evitare di cambiare se riusciamo a portarlo a 4 GB? 2GB?
posta Anders Forsgren 08.06.2015 - 08:58
fonte

5 risposte

10

Wow, questa è una lunga domanda (e un problema complesso). Proverò ad avere un vai a questo.

I'm not sure I understand why each user has to have a full local history when using git?

Questa è una decisione centrale sul design con git. Per i motivi esatti che avresti ho bisogno di chiedere all'autore (Linus Torvalds), ma per quanto ne so, il principale la ragione è la velocità: avere tutto locale (su un disco veloce o addirittura in cache nella RAM) rende le operazioni sulla storia molto più veloci evitando la rete l'accesso.

The biggest reason for the large repository size is that there are a lot of binary documents being inputs to tests. These files vary between .5mb and 30mb, and there are hundreds. They also have quite a lot of changes.

Questo è il punto su cui penserei prima. Avere così tanti costantemente cambiare i file binari nel controllo del codice sorgente mi sembra problematico (anche con SVN). Non puoi usare un approccio diverso? Idee:

  • Diversamente dal codice sorgente, probabilmente non viene scritto un file binario da 3 MB mano. Se qualche strumento / processo lo genera, considera di integrarlo nella tua build, invece di memorizzare i dati.

  • Se ciò non è pratico, i file binari di solito sono meglio in un repository di risorse (come Artifactory for Maven & co.). Forse quello è un'opzione per te.

I have looked at submodules, git-annex etc, but having the tests in a submodule feels wrong, as does having annex for many files for which you want full history.

In realtà, sembra che git-annex si adatterebbe perfettamente. git-allegato fondamentalmente consente di memorizzare il contenuto del file al di fuori di un repository git (il repository contiene invece un segnaposto). È possibile memorizzare il file i contenuti in vari modi (repo git centrale, unità condivisa, cloud storage ...) e puoi controllare quali contenuti vuoi avere localmente.

Hai forse frainteso il funzionamento di git-annex? git-annex non memorizza cronologia completa per tutti i file che gestisce: ti lascia solo scegliere quale contenuto di file vuoi avere localmente.

Infine, riguardo alle tue domande:

What is a good best practice for using git with large repos containing many binary files that you do want history for?

Nella mia esperienza, le opzioni di solito sono:

  • evitare la necessità di binari nel repository (generarli su richiesta, memorizzali altrove)
  • usa git-annex (o una soluzione simile, come Git LFS)
  • vivi con un grande repo (non tutte le operazioni git sono influenzate da grandi) file, e se si dispone di un computer veloce e unità, può essere abbastanza praticabile)

Is shallow cloning usable as a normal mode of operation or is it a "hack"?

Potrebbe essere fattibile; tuttavia, non penso che questo risolva il tuo problema:

  • perdi i benefici di git che provengono dall'avere una cronologia completa, ad esempio come ricerca rapida della cronologia
  • le fusioni possono diventare complicate, perché AKAIK devi avere almeno il la cronologia torna al punto di diramazione per unire
  • gli utenti dovrebbero ri-clonare periodicamente per mantenere la dimensione del loro clone piccolo
  • è solo un modo insolito di usare git, quindi probabilmente ti verrebbero a capo problemi con molti strumenti

How big is "too big" for a git repository (on premises)? Should we avoid switching if we can get it down to 4GB? 2GB?

Dipende dalla struttura del repository (pochi / molti file ecc.), su cosa vuoi fare, su quanto siano robusti i tuoi computer e sulla tua pazienza : -).

Per darti una rapida idea: sul mio computer portatile (nuovo, ma con poche specifiche), l'invio di un file da 500 MB richiede 30-60 secondi. Basta elencare la cronologia (git log ecc.) non è influenzato da file di grandi dimensioni; cose come "git log -S" che devono la scansione del contenuto del file è molto lenta, tuttavia la velocità è principalmente dominata per I / O, quindi non è proprio colpa di Git.

Su un repository di 3 GB con una manciata di revisioni, "git log -S" richiede circa a minuto.

Quindi direi che un paio di GB sono ok, anche se non ideali. Più di 10-20 GB è probabilmente spingendolo, ma potrebbe essere fattibile - dovresti provarlo.

    
risposta data 03.09.2015 - 15:42
fonte
4

As the number of users have grown, there is a lot of churn in trunk, and features are often spread out on multiple commits making code review hard to do. Also without branching there is no way to "gate" bad code out, reviews can only be done after it is committed to trunk

Il passaggio a git non risolverà questi problemi, sono problemi nel modo in cui utilizzi lo strumento e se utilizzi git nello stesso modo, i problemi rimarranno.

È possibile diramare in svn altrettanto facilmente in git, e la fusione è generalmente altrettanto semplice e ha le stesse insidie. Git è stato progettato per lavorare con il codice sorgente del kernel, quindi ha fatto alcune ipotesi che potrebbero non essere applicabili in tutti i casi, come il vostro con grossi binari e storie enormi. L'intenzione dietro a un DVCS è che ogni utente lavora in modo efficace da solo e collabora solo dopo - cioè ha un proprio repository (una copia), lavora come preferisce e quindi spinge le modifiche a chiunque lo desideri. Un sistema federato utilizzato nello sviluppo del kernel linux è perfetto per questo - si spinge le modifiche al prossimo ragazzo della catena che lo fonde con il suo codebase e poi lo spinge al ragazzo successivo fino a che non arriva a Linus che lo inserisce nel rilascio. La maggior parte delle squadre usa git in modo simile, ma con solo 1 ragazzo upstream che è spesso un repository "gold" sul lato server, rendendo piuttosto git simile a un CVCS disconnesso.

Quindi guarderei prima di cambiare il tuo flusso di lavoro, solo migrando verso git una volta che hai un modo migliore di lavorare. Implementare la ramificazione e l'unione in SVN, se non si rinomina il file o la fusione delle directory va piuttosto bene.

    
risposta data 08.06.2015 - 10:17
fonte
2

Guarda nella mailing list di GCC. La migrazione dell'albero dei sorgenti del compilatore GCC da SVN a GIT viene discussa in questo momento (agosto e settembre 2015), pur mantenendo la cronologia di GCC. Vedi per es. repository per il macchinario di conversione & Criteri di accettazione per la conversione di git thread di posta; troverai riferimenti a strumenti e procedure relativi alla conversione (che non è così semplice come sembra, la conversione di una cronologia di un codice così grande richiede 36 ore e circa 64 GB di RAM, IIRC)

    
risposta data 03.09.2015 - 16:18
fonte
2

Se la conversione dell'intero repository SVN in Git risulta in un enorme repository che non è possibile clonare, puoi provare a utilizzare SubGit per creare piccoli mirror Git per alcune parti del tuo repository Subversion.

Ad esempio, puoi importare e sincronizzare alcune sottodirectory del tuo repository SVN http://domain/repos/trunk/project/src :

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

Per maggiori dettagli sull'utilizzo di SubGit, fare riferimento alla sua documentazione .

Non appena hai Git mirror di quella directory, puoi utilizzare il repository Git per inviare nuove modifiche che si riflettono immediatamente nel repository SVN. Poiché sincronizzi solo una determinata parte del repository SVN che riduce in modo significativo la dimensione del repository Git convertito e puoi ancora creare branch, unirli, impiegare qualsiasi flusso di lavoro dal lato Git.

In alternativa, puoi importare l'intero repository SVN ma escludere file di grandi dimensioni dalla sincronizzazione:

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

Il repository Git risultante dovrebbe avere dimensioni ragionevoli e gli sviluppatori possono ancora utilizzare Git per inviare le loro modifiche al repository Subversion.

Si noti che questa soluzione dovrebbe funzionare bene se si è pronti a mantenere in esecuzione il server Subversion e a utilizzare Git accanto al repository SVN.

Dichiarazione di non responsabilità: sono uno degli sviluppatori di SubGit; SubGit è un software commerciale con una serie di opzioni gratuite disponibili.

    
risposta data 20.09.2016 - 17:14
fonte
1

Mi avvicino alla tua situazione nel modo seguente:

1) Inizializza un repository git nella stessa directory del repository SVN. Fai git init e git remote add origin per avviare quel repository git. In questo modo puoi continuare a eseguire il commit su SVN e git separatamente senza occuparti di una conversione completa da uno all'altro fino a quando non sei pronto.

2) Utilizza attivamente gli strumenti bfg e filter-branch per provare e ridurre il tuo repository git, come discusso qui: link

3) Usa git-annex, o Git LFS, o semplicemente un server di archiviazione esterno per i tuoi binari di grandi dimensioni (trasporto dei file usando gli script di shell in fase di compilazione).

4) Una volta che hai dimestichezza con la strategia fusione / ramificazione nel tuo repository git, e sei a tuo agio con le dimensioni del tuo repository git, puoi eseguire una migrazione completa da svn a git.

Spero che questo aiuti.

    
risposta data 21.10.2016 - 19:55
fonte

Leggi altre domande sui tag