2009-12-10 17 views
32

Ho letto moltissimi articoli "vai da svn a git" e altri articoli "git-svn workflow" sul web, eppure penso che spesso si occupino di situazioni troppo semplici. Sono spesso rivolti a ragazzi che vogliono solo usare git e hacker localmente, senza usare tutta la potenza di git, come pull, fetch, merge e simili tra più sviluppatori che avrebbero tutti clonato il repository svn con git-svn, quindi aspettiamo ancora di essere in grado di spingere le loro modifiche in qualsiasi momento al repository svn (ufficiale), e tornare a lavorare in git e condividere le loro cose ecc.È possibile che diversi cloni git-svn dello stesso repository svn siano in grado di condividere le modifiche, quindi git svn dcommit?

Ogni volta che questi articoli ammettono che non puoi fare tutto ciò che vorresti fare nel puro idiota, le conseguenze e gli eventuali fallimenti non sono mai spiegati chiaramente (o forse sono solo io?). Persino la pagina man di git-svn menziona i caveat, ma in realtà non in maniera estesa.

Sulla base di ciò che ho letto, ritengo che potrebbero esserci problemi quando git-svn viene usato in quel modo specifico, che descriverò qui sotto. Qualcuno può dirmi se ho ragione su questo?

Ecco la "voluto" modo di fare le cose:

  1. Abbiamo un progetto in un repository svn
  2. Developer Uno di git-svn-clone il repo svn. Inizia a hackerare le cose localmente
  3. Sviluppatore B git-svn-clone è lo stesso svn repo. Comincia a hackerare le cose da solo.
  4. Dopo averlo fatto per un po 'di tempo, magari aggiungendo gli sviluppatori C/D/... e avendo altri sviluppatori che eseguono commit "standard" sul repository originale, gli utenti git vorranno condividere il loro codice e fare tutti i tipi di magia git.
  5. Ogni uno di quegli utenti git vorrebbe essere in grado di spingere l'ora fusa modifiche svn

La mia domanda è (dcommit?): Sto sognando? Ho letto qualche tempo fa, in un libro di git credo, che git-svn-clone potrebbe creare repository git che sono ovviamente un "mirror" del repository svn, ma che i repository git creati in questo modo da diversi sviluppatori avrebbero diversi " id "e commits avrebbero hash diversi. Quindi la mia comprensione era che quei repository git non avrebbero condiviso alcun antenato git comune, e quindi non sarebbero stati in grado di usare tutti i comandi git necessari per condividere, unire e così via. È vero, stiamo andando ad affrontare problemi con questo flusso di lavoro?

A volte ho letto che questo potrebbe essere fatto, usando almeno un repository git "ufficiale" nudo, che sarebbe l'unico a essere git-svn-cloned, e tutti gli utenti git dovrebbero iniziare a formarlo. Allora hai bisogno di qualcuno che si occupi di questo repository git centrale, e raccolga le modifiche tra gli sviluppatori git, prima di mandare tutto al repository svn. Questo sarebbe l'unico modo per gli utenti git di essere "inconsapevoli" che il repository git originale provenga da svn, e permetterebbe loro di usare tutti i comandi git a loro piacimento. L'unica persona che avrebbe bisogno di essere fluente sia in git che in svn (e conoscere i caveat di git-svn) sarebbe il "gestore di fusione" (o qualsiasi altra cosa venga chiamata).

Sto fraintendendo completamente i caveat di git-svn? C'è un modo più semplice per farlo?

risposta

18

Il problema è passo 4 naturalmente. Un dcommit tenta di riprodurre la cronologia locale sul server. Dcommit finge di essere un cliente SVN. Ora, se il codice che stai inviando non è solo tuo, è qualcosa che è difficile da convincere a SVN.

Ecco ciò che il guru scrive sulla questione:

  • Per ragioni di semplicità e interoperabilità con SVN, è raccomanda che tutti gli utenti git-svn clone, recuperano e dcommit direttamente da il server SVN (il repository SVN remoto) ed evitare tutte le operazioni git-clone/pull/merge/push tra repository e branch git che vengono recuperati tramite git svn clone e che sono anche utilizzati per spingere i changeset indietro nel repository SVN remoto.
  • Il metodo consigliato per lo scambio di codice tra i rami git e gli utenti è git format-patch e git am, o semplicemente git svn dcommit nel repository SVN .
  • Da git svn dcommit utilizza git svn rebase internamente, i rami Git abbiamo git push per prima git svn dcommit su essi richiedono forzando una sovrascrittura della ref esistente sul repository remoto . Questo è generalmente considerato una cattiva pratica, vedere la documentazione di git-push per i dettagli.
  • L'esecuzione di git merge o git pull non è raccomandata su un ramo che abbiamo in programma di git svn dcommit da. SVN non rappresenta fusioni in qualsiasi modo ragionevole o utile in modo che gli utenti che utilizzano SVN non possano vedere alcuna fusione che abbiamo fatto. Inoltre, se uniamo git o git da un ramo git che è un mirror di un ramo SVN, git svn dcommit potrebbe commettere nel ramo errato.
  • git clone non clonera rami sotto i riferimenti/remoti/gerarchia o qualsiasi metadata git-svn o config. Quindi i repository creati e gestiti con utilizzando git-svn devono utilizzare rsync per la clonazione, se la clonazione deve essere eseguita affatto.
  • Non dovremmo usare l'opzione --amend di git commit su una modifica che abbiamo già emesso . È considerato una cattiva pratica per --amend commit che abbiamo già inviato a un repository remoto per altri utenti, e dcommit con SVN è analogo a quello. Ulteriori informazioni al riguardo sono disponibili in Modifica di un singolo commit e Problems with rewriting history.
+0

Grazie. Non sapevo del "guru". Beh, sembra che siamo bloccati. Non sono consigliate merge/pull, diffs e patch, questo non suona come la potenza di Git (tranne che per piccole cose fatte localmente e individualmente) –

+1

Il guru dice che le patch distribuite per posta sono ok. – nes1983

+2

"No merge/pull, diffs e patches" ..-- ma solo: "su un ramo abbiamo intenzione di git svn dcommit from". Ciò significa che sì * puoi * andare a unirsi a gergo/tirare/cherrypick e ottenere potere/magia; devi solo appianare le tue modifiche su un altro ramo; prima di spingerlo in svn. Non è troppo difficile, rebase o si fondono - dovresti farlo qui. – inger

3

Quello che ho usato per fare, è creare un git svn clone iniziale, quindi ho condiviso il file .git tra gli sviluppatori utilizzando git, quindi avevamo esattamente gli stessi riferimenti.

Sembra funzionare correttamente poiché siamo stati in grado di utilizzare "specifiche funzionalità git" tra gli utenti git, purché fossimo rimasti in un albero lineare (ad esempio, la ridefinizione anziché l'unione).

2

ho trovato this blog post che suggerisce tenere un ramo separato per la sincronizzazione con il repository, in modo tale che sarà ancora possibile fare push/pull nel ramo master.

+0

Il collegamento è interrotto e la risposta fornisce ben pochi indizi su ciò che il blog copre. Questo è il problema con il semplice collegamento a un blog, ma senza fornire ulteriori dettagli ... – mutex

23

Ultimamente sto sperimentando molto con questo, e penso di essere riuscito a creare un setup che funziona in qualche modo. Sì, è un regime basato esclusivamente su rebase, sì è complicato, ma puoi usare Git per lavorare localmente (velocità, cronologia, scorta, indice, ecc.).

Puoi usare i rami dietro le quinte quando collabori con altri utenti Git nella tua squadra, penso, ma non ho sperimentato personalmente troppo con questo. Finché si linearizza il log prima di dcommitting dovrebbe funzionare.

Ecco la versione corta (ripete molto ciò che è stato già detto):

  1. Clone repo Subversion in un "recupero" pronti contro termine su un server centrale
  2. Init un pronti contro termine "nuda" sulla stessa Server
  3. spinta dal repo fecthing al repo nuda
  4. Avere sviluppatori clonare il repo nuda e poi
    1. git svn init svnurl di config ure telecomando git-svn e
    2. git update-ref refs/remotes/git-svn refs/remotes/origin/master così git-svn ha un puntatore a una revisione
  5. automaticamente (commit hook) hanno il "recupero" svn rebase repo, e spingere verso il repository nudo
  6. Gli sviluppatori ritirano dal repository nudo con git pull --rebase
  7. Gli sviluppatori che eseguono git svn dcommit devono prima ripetere lo update-ref in caso di nuove versioni provenienti da SVN.

C'è uno illustration of the workflow on this page (ho bisogno di più punti reputazione prima di poter allineare l'immagine). Aggiornamento: Qui andiamo:

+1

Interessante. +1 – VonC

+0

Il ** punto chiave ** in questa risposta è il passo '6': ' git update-ref ref/remotes/git-svn refs/remotes/origin/master'. Questo è ciò che consente agli sviluppatori di collegare i loro cloni a svn. Questo è ciò che consente di condividere 'origine/master' e, * allo stesso tempo *, utilizzarlo per premendo su svn. Senza il passo '6', gli sviluppatori dovrebbero saltare tra i rami ' origine/master' e 'git-svn'. Il recupero dei repository e il commit degli hook non sono assolutamente necessari: gli sviluppatori possono semplicemente mettere a nudo il 'master' di repo subito dopo' dcommit'ting to svn. – Oleg

1

Uno dei problemi che ho percepire con git-svn è che memorizza il git-svn-id nel messaggio di commit; poiché riscrive questo commit, cambia SHA1, quindi non puoi spingerlo ovunque la gente lo condividerà.

In realtà preferisco bzr-svn perché invece memorizza bzr revid nella revisione SVN remota utilizzando la funzione di proprietà di revisione SVN che invece non significa riscrittura di revisione locale. Ha anche la proprietà desiderata, che due pull indipendenti dello stesso ramo SVN si tradurranno in rami bzr identici e interoperabili.

+0

100% d'accordo. Non essere in grado di condividere i rami git che ereditano dallo stesso albero svn usando git-svn è super-doloroso –

2

C'è uno strumento che risolve il problema della condivisione del repository Git sincronizzato con il repository Subversion.

SubGit è uno specchio bidirezionale lato server Git-SVN.

Si può installare SubGit in repository Subversion e ricevere repository Git sincronizzati automaticamente con SVN:

$ subgit configure $SVN_REPOS 
# Adjust $SVN_REPOS/conf/subgit.conf to specify branches, tags and other options; 
# Adjust $SVN_REPOS/conf/authors.txt to specify git & svn authors mapping 
$ subgit install $SVN_REPOS 
... 
$ INSTALLATION SUCCESSFUL 

SubGit installa pre-commit e post-commit ganci nelle repository Subversion, pre-ricezione e post-ricezione ganci in Repository Git. Come risultato, traduce immediatamente le modifiche in arrivo dai lati SVN e Git. Dopo l'installazione di SubGit, gli sviluppatori possono utilizzare qualsiasi client Git per clonare e lavorare con il repository Git.

SubGit non si basa su git-svn, utilizza il proprio motore di traduzione sviluppato dal nostro team. Maggiori dettagli su questo si può trovare al confronto SubGit vs. git-svn. La documentazione generale su SubGit è disponibile here.

La versione 1.0 di SubGit richiede l'accesso locale al repository Subversion, vale a dire che i repository SVN e Git devono risiedere sullo stesso host. Ma con la versione 2.0 introdurremo la modalità proxy Git, quando i repository Subversion e Git possono essere posizionati ovunque e solo i repository Git hanno installato SubGit, ad esempio i repository Subversion rimangono intatti.

SubGit è un prodotto commerciale. È gratuito per progetti accademici open-source e anche per progetti con un massimo di 10 utenti.

Disclaimer: Sono uno degli sviluppatori di SubGit.

Problemi correlati