Cosa fare della grande storia svn quando si passa a git?


23

Modifica: a differenza di alcune domande simili come Spostare un repository SVN multi-GB su Git o /programming/540535/managing-large-binary-files-with-git Il mio scenario non prevede diversi sottoprogetti che può essere facilmente convertito in sottomodelli git, né pochi file binari molto grandi che sono adatti per git-annex. È un singolo repository in cui i binari sono la suite di test che è strettamente accoppiata al codice sorgente principale della stessa revisione, proprio come se fossero risorse di compilazione come la grafica.

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

Il problema con il repository corrente per quanto riguarda git è la dimensione. C'è molto vecchio innesto lì dentro e pulirlo con --filter-branch quando si converte in git può ridurlo di dimensioni di un ordine di grandezza, a circa 5-10 GB. Questo è ancora troppo grande. Il motivo principale della grande dimensione del repository è che ci sono molti documenti binari che vengono immessi nei 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 sembra sbagliato, così come avere l'allegato per molti file per i quali si desidera la cronologia completa.

Quindi la natura distribuita di git è davvero ciò che mi impedisce di adottarlo. Non mi interessa molto la distribuzione, voglio solo la ramificazione economica e le potenti funzionalità di fusione. Come suppongo facciano 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 usa git? Se il flusso di lavoro non è decentralizzato, cosa stanno facendo i dati sui dischi degli utenti? So che nelle ultime versioni di git è possibile utilizzare un clone superficiale con solo cronologia recente. La mia domanda è: è fattibile farlo come modalità operativa standard per un'intera squadra? Git può essere configurato per essere sempre superficiale in modo da poter avere una cronologia completa solo centralmente, ma gli utenti di default hanno solo 1000 giri di cronologia? L'opzione ovviamente sarebbe quella di convertire solo 1000 giri in git e mantenere il repository svn per l'archeologia. In quello scenario, tuttavia, incontreremmo di nuovo lo stesso problema dopo le successive migliaia di revisioni ai documenti di prova.

  • Che cosa è un buon best practice per l'utilizzo di git con grandi repos contenenti molti file binari che non vuole la storia per? La maggior parte delle migliori pratiche e tutorial sembra evitare questo caso. Risolvono il problema di pochi enormi binari o propongono di abbandonare completamente i binari.
  • È poco profondo clonazione utilizzabile come una modalità normale di funzionamento o è un "hack"?
  • I sottomoduli potrebbero 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 in fase di compilazione o in una suite di test unitari)?
  • Quanto è grande "troppo grande" per un repository git (locale)? Dovremmo evitare di passare se possiamo arrivare a 4 GB? 2GB?


Ho cercato molte informazioni su questo, e non ho trovato nulla che risponda alla mia domanda. Nella domanda collegata i workaounrds (sottomoduli, allegato ecc.) Funzionerebbero molto meglio rispetto al mio scenario.
Anders Forsgren l'


Perforce potrebbe essere un'opzione migliore di git, poiché è progettato per far fronte a molti file binari di grandi dimensioni, quindi utilizzato da molti sviluppatori di giochi. Anche Plasticscm merita una visita.
Ian,

Solo un lato: evita i sottomoduli git se puoi, poiché complicano eccessivamente il sistema di compilazione (che è già complicato nel tuo caso).
IgorGanapolsky,

Risposte:


10

Wow, questa è una lunga domanda (e un problema complesso). Proverò a provarci.

Non sono sicuro di capire perché ogni utente deve avere una cronologia locale completa quando usa git?

Questa è una decisione di progettazione centrale con git. Per le ragioni esatte che dovresti chiedere all'autore (Linus Torvalds), ma per quanto ne so, il motivo principale è la velocità: avere tutto locale (su un disco veloce o anche memorizzato nella RAM) rende le operazioni sulla cronologia molto più veloci evitando l'accesso alla rete.

Il motivo principale della grande dimensione del repository è che ci sono molti documenti binari che vengono immessi nei test. Questi file variano tra .5mb e 30mb e ce ne sono centinaia. Hanno anche molti cambiamenti.

Questo è il punto a cui penserei per primo. Avere così tanti file binari in costante cambiamento nel controllo del codice sorgente mi sembra problematico (anche con SVN). Non puoi usare un approccio diverso? idee:

  • A differenza del codice sorgente, un file binario da 3 MB probabilmente non è scritto a mano. Se qualche strumento / processo lo genera, considera di integrarlo nella tua build, invece di archiviare i dati.

  • Se ciò non è pratico, i file binari sono in genere migliori in un repository di artefatti (come Artifactory for Maven & co.). Forse questa è un'opzione per te.

Ho esaminato i sottomoduli, git-annex ecc., Ma avere i test in un sottomodulo sembra sbagliato, così come avere l'allegato per molti file per i quali si desidera la cronologia completa.

In realtà, sembra che git-annex si adatterebbe perfettamente. git-annex in pratica consente di archiviare il contenuto dei file all'esterno di un repository git (invece il repository contiene un segnaposto). Puoi archiviare il contenuto del file in vari modi (repository git centrale, unità condivisa, archiviazione cloud ...) e puoi controllare quali contenuti desideri avere localmente.

Hai forse frainteso come funziona git-annex? git-annex memorizza la cronologia completa per tutti i file che gestisce - ti permette solo di scegliere quale contenuto di file vuoi avere localmente.

Infine, sulle tue domande:

Qual è una buona pratica per usare git con repository di grandi dimensioni contenenti molti file binari per cui vuoi la cronologia?

Nella mia esperienza, le opzioni di solito sono:

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

È poco profondo clonazione utilizzabile come una modalità normale di funzionamento o è un "hack"?

Questo potrebbe essere fattibile; tuttavia, non penso che questo risolverà il tuo problema:

  • perderai i benefici di Git che derivano dall'avere una cronologia completa, come una rapida ricerca della cronologia
  • le fusioni possono diventare complicate, perché AKAIK per fondere devi avere almeno la cronologia al punto di diramazione
  • gli utenti dovrebbero ripetere la clonazione periodicamente per mantenere ridotte le dimensioni del clone
  • è solo un modo insolito di usare git, quindi probabilmente incontreresti problemi con molti strumenti

Quanto è grande "troppo grande" per un repository git (locale)? Dovremmo evitare di passare se possiamo arrivare a 4 GB? 2GB?

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

Per darti un'idea veloce: sul mio laptop (nuovo, ma con poche specifiche), il commit di un file da 500 MB richiede 30-60 secondi. Il solo fatto di elencare la cronologia (git log ecc.) Non è influenzato dai file di grandi dimensioni; cose come "git log -S" che devono scansionare il contenuto del file sono molto lente - tuttavia, la velocità è principalmente dominata dall'I / O, quindi non è davvero colpa di git.

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

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


Grazie per la tua risposta dettagliata. Cercherò sicuramente di utilizzare l'allegato per i documenti di prova. La barra per "prestazioni ragionevoli" è probabilmente "vicino a svn", cioè se è significativamente più lenta per qualsiasi operazione, allora ci sarebbe troppa frizione per passare.
Anders Forsgren,

Penso che Git LFS possa essere utilizzato anche per l'archiviazione di file binari di grandi dimensioni.
IgorGanapolsky,

@IgorG .: Sì, Git LFS è un'alternativa, ce ne sono altri. Grazie per averlo sottolineato, ho modificato il mio post.
sleske,

4

Man mano che il numero di utenti è cresciuto, c'è molto churn nel trunk e le funzionalità sono spesso distribuite su più commit rendendo difficile la revisione del codice. Inoltre, senza la diramazione non c'è modo di "eliminare" il codice errato, le recensioni possono essere fatte solo dopo che sono state impegnate nel trunk

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

Puoi diramare in svn altrettanto facilmente in git, e la fusione è generalmente altrettanto semplice e ha le stesse insidie. Git è stato progettato per funzionare con il codice sorgente del kernel, quindi ha formulato alcune ipotesi che potrebbero non essere applicabili in tutti i casi, come il tuo con grandi binari e storie enormi. L'intenzione alla base di un DVCS è che ogni utente lavora efficacemente da solo e collabora solo dopo, ovvero ha il proprio repository (una copia), funziona come preferisce e quindi invia le modifiche a chiunque lo desideri. Un sistema federato utilizzato nello sviluppo del kernel di Linux è perfetto per questo: spingi le tue modifiche al ragazzo successivo nella catena che lo unisce alla sua base di codice e poi lo spinge al ragazzo successivo fino a quando non arriva a Linus che lo mette nella versione. La maggior parte dei team usa git in modo simile, ma con un solo ragazzo a monte che è spesso un repository "gold" sul lato server,

Quindi vorrei prima cambiare il tuo flusso di lavoro, migrando a git solo quando hai un modo migliore di lavorare. Implementa la diramazione e l'unione in SVN, se non rinomini file o directory l'unione va abbastanza bene.


4
"Puoi diramare in svn altrettanto facilmente in git, e fondersi è generalmente altrettanto facile e ha le stesse insidie", wow è un'affermazione davvero controversa. La fusione in git secondo me di solito è un gioco da ragazzi e in svn di solito un incubo, anche nelle versioni dopo che è stato introdotto un tentativo semi-cotto di unire-tracking (sì, lavoro con git, non solo su questo repository). Il flusso di lavoro che vogliamo avere è quello in cui si crea un ramo di funzionalità, revisione del codice / build CI su quel ramo. Non c'è modo di farlo in SVN senza una grande frustrazione.
Anders Forsgren,

2
no, lo facciamo sempre qui. Sto solo esaminando i 157 rami nel mio repository SVN per vedere quali possono essere eliminati. Ci ramifichiamo, sviluppiamo, rivediamo e quindi ci uniamo quasi quotidianamente qui, a volte ci troviamo nei guai, ma ciò viene sempre risolto togliendo un nuovo ramo dal trunk e unendo le modifiche a quello (in modo che possa essere facilmente ricondotto al trunk in un secondo momento) . Questo vale solo per i rami antichi però. Se hai una grande frustrazione, non la capisci abbastanza bene. Git ti darà anche enormi frustrazioni.
gbjbaanb,

2
Semplicemente non lo provo. Quando lavoro con git (come ho detto che faccio, ma in piccoli repository) trovo abbastanza facile e naturale fare ramificazione, rebasing, schiacciamento e fusione. "Conflitti tra alberi dopo la ridenominazione" ecc. Sembrano molto più rari e il fatto che sia possibile emulare una storia lineare e semplice (tramite rebase + squash ecc.) È molto importante. Quindi: per mantenere la domanda sull'argomento (git con repository di grandi dimensioni): supponiamo che svn non supporti il ​​flusso di lavoro di cui ho bisogno, e git lo fa.
Anders Forsgren,

1
In una società precedente avevamo usato git e conosco qualcuno che ha perso regolarmente il suo lavoro usandolo, quindi non è affatto un sistema perfetto! Né è SVN, ma SVN è molto più adatto alle tue circostanze rispetto a git IMHO, e funziona. A proposito, come far funzionare git come vuoi tu ... Non sono sicuro che lo farà, scusa.
gbjbaanb,

7
@gbjbaanb se qualcuno sta perdendo il lavoro con Git, sta facendo qualcosa di terribilmente sbagliato.
RubberDuck,

2

Cerca nella mailing list di GCC. La migrazione dell'albero dei sorgenti del compilatore GCC da SVN a GIT è discussa in questo momento (agosto e settembre 2015), mantenendo la storia di GCC. Vedi ad esempio repository per i macchinari di conversione e criteri di accettazione per i thread di posta di conversione git ; troverai riferimenti a strumenti e procedure relativi alla conversione (che non è così semplice come sembra; la conversione di una cronologia di codice così ampia richiede 36 ore e circa 64 Gbyte di RAM, IIRC)


Intendevi migrare da SVN a Git? La migrazione da un sistema di controllo della versione a una suite di compilatori sembra un po '... strana. Inoltre, questo sembra un po 'più simile a un commento che a una risposta.
8

Sì. Ci scusiamo per l'errore di battitura.
Basile Starynkevitch,

Grazie. 36 ore suona come una brezza, la nostra può convertirsi in un paio di settimane ...
Anders Forsgren

2

Se la conversione dell'intero repository SVN in Git si traduce in un enorme repository che non è possibile clonare, è possibile provare a utilizzare SubGit per creare mirror Git più piccoli per alcune parti del 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'uso di SubGit, consultare la relativa documentazione .

Non appena si dispone del mirror Git di quella directory, è possibile utilizzare il repository Git per inviare nuove modifiche che si riflettono immediatamente nel repository SVN. Dal momento che sincronizzi solo una parte del repository SVN che riduce significativamente le dimensioni del repository Git convertito e puoi ancora creare rami, 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 comunque utilizzare Git per inviare le loro modifiche al repository Subversion.

Nota che questa soluzione dovrebbe funzionare bene per te se sei pronto a mantenere in esecuzione il server Subversion e utilizzare Git insieme al tuo repository SVN.

Disclaimer: sono uno degli sviluppatori di SubGit; SubGit è un software commerciale con una serie di opzioni gratuite disponibili.


1

Mi avvicinerò alla tua situazione nel modo seguente:

1) Inizializza un repository git nella stessa directory del tuo repository SVN. Fare git inite git remote add originavviare quel repository git. In questo modo puoi continuare a impegnarti su SVN e git separatamente senza occuparti di una conversione completa dall'uno all'altro fino a quando non sei pronto.

2) Utilizzare attivamente gli strumenti bfg e filter-branch per provare a ridurre il repository git, come discusso qui: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3) Usa git-annex, o Git LFS, o solo un server di archiviazione esterno per i tuoi file binari di grandi dimensioni (trasporto dei file usando script di shell al momento della compilazione).

4) Una volta che ti senti a tuo agio con la strategia di fusione / ramificazione nel tuo repository git e ti senti a tuo agio con le dimensioni del tuo repository git, puoi quindi eseguire una migrazione completa dal tuo svn a git.

Spero che sia di aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.