Cercando di rispondere alla mia domanda: l'uso di git per svn merges sembra promettente.
Aggiornamento: non è solo promettente, è un grande successo. In breve, Linus was right.
Ha appena completato un'enorme fusione di 2 rami svn separati da 1,5 anni; File 3k sono stati cambiati, ha ottenuto tonnellate di conflitti in svn (~ 800 penso).
ho trovato git & git-svn un risparmiatore di vita:
- risoluzione automatica dei conflitti: per cominciare, ha dato un sacco di file di meno in conflitto (~ metà credo)
- prestazioni incredibili
- eccellente repo/branching model, flussi di lavoro flessibili: facile sperimentazione con vari approcci, come il chunk-by-chunk (in tempo) si fondono, eseguendo sempre controlli di integrità (compilazione, ecc.); ogni volta che si verificano problemi: basta tornare indietro. Puoi sempre fare un passo indietro quando necessario.
- usabilità, grandi attrezzature:
git-log
(e le sottostanti git-rev-parse
opzioni), nulla può essere più potente di questo. È anche utile: -p
ti dà le differenze in un colpo solo; in svn si ottiene un registro, quindi si trova il diff per quel "revision-1: revision", o si usano le UI goffe. Trova quando una stringa è stata aggiunta/rimossa nel repository, ricerca simultaneamente su più diramazioni
gitk
: estremamente utile per la visualizzazione di storie di filiali, combinate con ottime capacità di ricerca. Non ho visto nulla di simile in altri strumenti, specialmente non così veloce come questo.Nevermind è in Tk, è semplicemente eccezionale
git gui
: funziona bene, anche se non il più sexy - grande aiuto per i principianti di scoprire cose
blame
: un miracolo. Sì, rileva dove il segmento originale viene da (copia & incolla ecc)
mergetool
: molta esperienza più piacevole che dando il via alla grande svn merge
che poi si ferma ogni volta (. Cioè ogni 5 minuti) si corre in un conflitto, premere ' (p) ostpone ', che cercare manualmente i file in conflitto successivamente. Preferito un sapore di questo integrato in git gui
(necessario uno tiny patch per quello). Trovato integrazione di strumenti di diffusione esterni meglio configurabili rispetto a svn
.
- pluggable fondono driver e controllo a grana fine di loro
rebase
consentito di filtrare le parti Messier della storia svn
- distribuzione: non c'è bisogno di venire in ufficio quando si lavora su questo, potrebbe mettere in pausa & progresso step-by-step su treno/aereo, ecc ..
- un drive USB con Unison fatta la sincronizzazione di lavoro < -> a casa un pezzo di torta
- questo non sarebbe h ave stato possibile senza la compressione folle di git (5 anni di progetto con 26k impegna, tonnellate di rami e file binari, tronco svn checkout: 1.9GB => tutti questi in repo piena git:! 1.4GB)
Quindi, questo può davvero fare la differenza da un incubo alla gioia - specialmente se ti piace imparare (cosa che richiede un certo sforzo in questo caso - immagino come imparare una moto dopo una bicicletta).
Anche se non posso costringere tutti in azienda a passare immediatamente - non intendevo davvero farlo. Anche in questo caso, git-svn
ci salva da 'immergendo la punta prima' approccio .. Ma vedendo le reazioni dei colleghi l'interruttore potrebbe accadere molto prima che qualcuno aspettava :)
avrei dire- anche se ci dimentichiamo fonde & commit, questa roba è già grande come un frontend di sola lettura per le query, la visualizzazione, backup, ecc ..
Caveat:
"non dcommit Git merge impegna a repository Subversion Subversion non gestisce. si fonde allo stesso modo come Git, e questo causerà problemi. Questo significa che si dovrebbe tenere il Git sviluppo storia lineare (cioè non la fusione da altri rami, proprio rebasing)." (ultimo comma http://learn.github.com/p/git-svn.html)
Un'altra fonte eccellente è la sezione Pro Git book ' Il cambio di rami attivi dice sostanzialmente che l'unione funziona, ma dcommit
memorizzerà solo il contenuto dell'unione, ma la cronologia verrà compromessa (che interrompe le successive fusioni), quindi è necessario rilasciare il ramo di lavoro dopo l'unione. senso dopo tutto, e in pratica è facile evitare trappole qui ..in Svn, ho trovato che le persone di solito non si riuniscono di nuovo, quindi questo potrebbe essere visto come un passo indietro se vieni da Git World in primo luogo.
In ogni caso, il dcommit ha funzionato per me. L'ho fatto sul mio svn workbranch che ho tenuto solo per questo, quindi ho evitato qualsiasi conflitto extra in quel momento. Tuttavia, ho deciso di eseguire l'unione finale da questo workbranch al tronco svn in svn (dopo aver sincronizzato tutto in git); --ignore-ancestry
ha dato i migliori risultati lì.
Aggiornamento: come ho scoperto in seguito, gli ultimi passaggi sopra (ramo svn extra e unione - ignora-ascendenza) sono facilmente evitati semplicemente mantenendo lineare il ramo da cui si sta inviando. Come dice Gabe in basso, merge --squash
crea semplicemente un semplice commit stupido svn-friendly. Proprio quando pronto con enorme merge (s) sul mio ramo locale (che potrebbe richiedere giorni/settimane), vorrei ora solo:
git checkout -b dcommit_helper_for_svnbranch svnbranch
git merge --squash huge_merge_work_with_messy_nonlinear_history
git commit 'nice merge summary' # single parent, straight from the fresh svnbranch
git dcommit
so che il monitoraggio fusione non sarà grande lavoro dal svn-side , finché non passiamo completamente. Non posso aspettare per quello.
UPDATE: @ Kevin ha chiesto qualche dettaglio in più su tutto il processo di fusione rami SVN .. Ci sono tantissime articoli, messaggi là fuori, ma come un principiante ho trovato alcuni dei confusione/fuorvianti/out di data .. in ogni caso, il modo in cui lo faccio in questi giorni (ovviamente, bloccati con git-svn dopo quella storia si fondono, così come alcuni colleghi infettati) ..
git svn clone -s http://svn/path/to/just-above-trunk # the slowest part, but needed only once ever..you can every single branch from the svn repo since revision #1. 2)
git svn fetch # later, anytime: keep it up to date, talking to svn server to grab new revisions. Again: all branches - and yet it's usually a faster for me than a simple 'svn up' on the trunk:)
# Take a look, sniff around - some optional but handy commands:
git gui & # I usually keep this running, press F5 to refresh
gitk --all # graph showing all branches
gitk my-svn-target-branch svn-branch-to-merge # look at only the branches in question
git checkout -b my-merge-fun my-svn-target-branch # this creates a local branch based on the svn one and switches to it..before you notice :)
# Some handy config, giving more context for conflicts
git config merge.conflictstyle diff3
# The actual merge..
git merge svn-branch-to-merge # the normal case, with managable amount of conflicts
# For the monster merge, this was actually a loop for me: due to the sheer size, I split up the 2 year period into reasonable chunks, eg. ~1 months, tagged those versions ma1..ma25 and mb1..mb25 on each branch using gitk, and then repeated these for all of them
git merge ma1 # through ma25
git merge mb1 # through mb25
# When running into conflicts, just resolve them.. low tech way: keep the wanted parts, then "git add file" but you can
git mergetool # loops through each conflicted file, open your GUI mergetool of choice..when successful, add the file automatically.
git mergetool my-interesting-path # limit scope to that path
in realtà ho preferito usare 'git integrazione incorporata di mergetool di gui (clic destro su file in conflitto). Comunque è un po 'limitato, quindi vedi la mia piccola patch qui sopra, che ti permette di collegare uno script di shell in cui puoi invocare qualsiasi mergetools che preferisci (ne ho provati a volte in parallelo perché causavano una quantità sorprendente di dolore .. ma normalmente mi sono bloccato con kdiff3 ..
Quando un passo di fusione va bene (nessun conflitto), una fusione commit avviene automaticamente, in caso contrario, di risolvere i conflitti allora
git commit # am usually doing this in the git gui as well.. again, lightning fast.
l'ultima fase .. si noti che finora avevamo solo commit locali, non parlando ancora con il server svn. A meno che tu non abbia usato --squash o altri trucchi, ora finisci con un grafico in cui il tuo commit di unione ha 2 genitori: i suggerimenti del tuo sv rami n-mirror. Ora questo è il solito trucco: svn può solo prendere la cronologia lineare ... quindi 'git-svn' lo semplifica semplicemente lasciando cadere il secondo genitore (svn-branch-to-merge nel caso precedente) .. quindi il vero tracciamento di unione è andato sul lato svn..ma altrimenti in questo caso va bene.
Se si desidera un modo più sicuro/pulito, è qui che entra in gioco il frammento precedente: esegui l'unione finale con --squash. Adattato il precedente a questo flusso:
git checkout -b dcommit_helper_for_svnbranch my-svn-target-branch # another local workbranch.. basically needed as svn branches (as any other remote branch) are read-only
git merge --squash my-merge-fun
git commit 'nice merge summary' # single parent, straight from the fresh svn branch
git dcommit # this will result in a 'svn commit' on the my-svn-target-branch
oops, questo sta diventando troppo lungo, fermandosi prima troppo tardi .. Buona fortuna.
Perché non * solo * utilizzando git-svn per tutto? –
@ Vi.questa è una domanda separata di primo livello - potresti aggiungerla come segue: -/Il mio era approssimativamente: "introduresti git-svn in un team basato su SVN, solo per dare una mano con un grande fusione? " – inger
Dopo aver unito * solo * potrebbero pensare di iniziare * solo * utilizzandolo ... –