2012-05-25 8 views
17

Ich habe versucht, meinen Kopf um Git verzweigende Modelle zu wickeln. Ich habe mir http://nvie.com/posts/a-successful-git-branching-model/ für einige Ideen angeschaut und von Subversion eine Sache, auf die ich mich wirklich gefreut habe, war, an einem einzigen Ort eine Veränderung vorzunehmen und sie mit all den Zweigen zu verschmelzen, die sie brauchten. In Subversion haben wir uns zu viel Code herumgesprochen.Git merkt Hotfix zu mehreren Zweigen

Allerdings bekomme ich das immer noch nicht komplett. Hier ist eine Standard-Art von Workflow, die ich habe und es wird immer zu Konflikten kommen.

# create new version branch 
git checkout master 
git checkout -b v3 
vim pom.xml # change branch version to "3.1-SNAPSHOT" 
git commit -a 
git checkout master 
vim pom.xml # change master version to "4.0-SNAPSHOT" 
git commit -a 

So ist der Meister bei 4,0-snapshot und die Verzweigung mit 3,1-SNAPSHOT.

Nicht ich möchte einen Hotfix auf dem Zweig erstellen und es in den Stamm verschieben.

git checkout v3 
git checkout -b hotfix 
vim file.txt # make a bugfix change 
git commit -a 
git checkout v3 
git merge hotfix # this works fine 
git checkout master 
git merge hotfix # this has a conflict since both branches have changed the version 

Ich verstehe, warum es passiert und es Sinn macht. Gibt es einen besseren Weg, dies zu tun?

ich über cherry-pick lesen, die ich getestet und funktioniert:

git checkout v3 
git cherry-pick a518b0b75eaf28868 
git checkout master 
git cherry-pick a518b0b75eaf28868 

jedoch, die wie die „richtige“ Art und Weise scheint nicht zu handhaben. Irgendwelche Vorschläge?

Antwort

11

Wirklich, Ihre Die Antwort hängt davon ab, ob Sie möchten, dass Ihre Bäume auf dem gleichen Verlauf basieren ... Zum Beispiel basiert 4.0 auf dem letzten 3.X + alle Änderungen in 4.0 ...

Persönlich, ich don ' t empfehlen es, wenn Sie sich entscheiden, eine oder mehrere neue Zweige für eine neue Version zu starten. Zu gegebener Zeit geht die Software in eine andere Richtung, also sollten auch Ihre Filialen.

Dies lässt git cherry-pick als Ihre ideale Lösung. Machen Sie die Änderung in jedem Zweig, der am sinnvollsten ist, und dann wählen Sie es zu den älteren Versionen aus. Dies ist das gleiche, als ob Sie den alten Zweig ausgecheckt hätten und manuell die gleiche Änderung angewendet und ein neues Commit gemacht hätten. Es hält es sauber und auf den Punkt.

Git fusionieren oder rebase werden versuchen, die Zweige der Geschichte zusammen, die jeweils auf ihre eigene Weise zu integrieren, was ich Sie vermuten, dass nicht wollen, wenn Fehlerbehebungen Zurückportieren, etc ...

+0

Ich stimme zu (obwohl ich denke, dass @ ellotheths Antwort je nach den Umständen eleganter sein kann). Laut Git's [Branching-Philosophie] (http://gitester.livejournal.com/42247.html) sind Sie wirklich sind sagen, dass _this Commit_ ist das einzige, was zu allen Filialen gehört. So sagt "Rosinenpicken" das. –

+0

Danke, ich denke das macht Sinn. Von Subversion kommend, und wie schmerzhaft es manchmal für uns war, Fixes an den Stamm und an Zweige zu schicken (im Grunde genommen zweimal), hatte ich mir gedacht, dass ich Feature-Zweige einfach irgendwo zusammenführen könnte, wo ich will. Als das nicht wie erwartet funktionierte, war ich irgendwie enttäuscht. "cherry-pick" macht aber sehr viel Sinn. Ich muss nur einen Prozess entwickeln, der für alle Entwickler einfach zu verstehen ist, und ich denke, dass dies deutlich gemacht werden kann. –

1

Im Fall arbeiten Sie auf einem Ast „4,0“ und ein Update vornehmen müssen auf „3.1“, können Sie „4.0“ rebase, nachdem Sie „3.1“ begehen:

git checkout 4.0 # you are on the feature brnach 4.0 
git stash # save current work so you can check out other branch 
git checkout 3.1  
git commit -a -m "bug fix" # do editing and commit 
git checkout "4.0" 
git stash apply # get back your changes 
git rebase "3.1" # change 4.1 so it branches of the current head of "3.1" 
+3

Ich möchte kommentieren, dass, während dies möglich ist, es die Fähigkeit entfernt, sich auf Tags zu verlassen, Pushing oder 4.0 Code effizient zu teilen. Rebase ist großartig, persönlich, aber nicht so toll, wenn Sie schon gedrängt haben. – gahooa

18

Wenn Sie wollte super-technische bekommt darüber, könnten Sie das Hotfix von einem gemeinsamen Vorfahren erstellen:

git merge-base v3 master 
git checkout -b hotfix <whatever you got from merge-base> 
# make your fix 
git checkout v3 && git merge --no-ff hotfix 
git checkout master && git merge --no-ff hotfix 

     v3--------v3 (hotfixed) 
    /  /
ancestor----hotfix 
     \   \ 
     master----master (hotfixed) 

die --no-ff Flagge halten die hotfix Sprungmarke an der Hotfix-Spitze, statt das Etikett zu v3 oder master ziehen.

Persönlich denke ich, das ist Overkill. Ich würde mit gahooa gehen: Machen Sie den Hotfix auf den Zweig, der Sinn macht, dann fusionieren oder Kirsche-pick abhängig davon, wie Sie wollen, dass die Zweige miteinander in Beziehung stehen.

+3

+1 für 'merge-base',' -no-ff' und all die guten Tipps. 'cherry-pick' erzeugt neues Commit: dasselbe Diff, Log-Nachricht, Timestamp, aber anderes Hash. Wenn eine klare Historie wichtig ist, glaube ich nicht, dass Merge-Base überhaupt ein Overkill ist. Cherry Picking funktioniert in einfachen Fällen, aber hüte dich vor solchen Dingen: http://news.ycombinator.com/item?id=3947950 –

+0

hast du viel von deiner Antwort gelernt, danke! –

0

Ich habe auch mit dieser Frage zu kämpfen, und ich denke, wenn Sie bereit sind, Ihre Versionierungsstrategie ein wenig zu ändern, weichen von den -SNAPSHOT-Versionen ab, die Maven ermutigt), dies könnte gelöst werden, indem eine feste Version (wie SNAPSHOT oder 0.0.0-SNAPSHOT) auf dem Master (oder was auch immer Ihr Entwicklungszweig ist) verwendet wird. (Das SNAPSHOT-Suffix ist wichtig, wenn Sie Maven verwenden, da Maven SNAPSHOT-versionierte Artefakte anders behandelt als andere.)

In der Tat, ich denke, Sie möchten eine Richtlinie einführen, die nur die Versionsnummer ändert auf Ihrem Produktionszweig (demjenigen, von dem Sie Releases erstellen) oder auf Zweigen, die nur für Release-Zwecke vorgesehen sind (z. B. Versionsnummern ändern) und die Sie nie wieder in den Entwicklungszweig einfügen möchten.

Ich habe diese Strategie noch nicht benutzt, aber ich habe gerade darüber nachgedacht, und ich denke, ich werde es versuchen.