Ich benutze Git jetzt seit ein paar Monaten für ein Projekt mit einem anderen Entwickler. Ich habe mehrere Jahre Erfahrung mit SVN , also bringe ich wohl viel Gepäck in die Beziehung.
Ich habe gehört, dass Git hervorragend zum Verzweigen und Zusammenführen geeignet ist, und bis jetzt sehe ich es einfach nicht. Sicher, das Verzweigen ist denkbar einfach, aber wenn ich versuche, es zusammenzuführen, geht alles zur Hölle. Nun, ich bin das von SVN gewohnt, aber es scheint mir, dass ich gerade ein unterdurchschnittliches Versionsverwaltungssystem gegen ein anderes getauscht habe.
Mein Partner sagt mir, dass meine Probleme auf meinem Wunsch beruhen, wohl oder übel zusammenzuführen, und dass ich in vielen Situationen Rebase anstelle von Zusammenführung verwenden sollte. Hier ist zum Beispiel der Workflow, den er festgelegt hat:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge my_new_feature
Erstellen Sie im Wesentlichen einen Feature-Zweig, der IMMER von Master zu Zweig zurückgesetzt und von Zweig zurück zu Master zusammengeführt wird. Es ist wichtig zu beachten, dass die Niederlassung immer lokal bleibt.
Hier ist der Workflow, mit dem ich begonnen habe
clone remote repository
create my_new_feature branch on remote repository
git checkout -b --track my_new_feature origin/my_new_feature
..work, commit, push to origin/my_new_feature
git merge master (to get some changes that my partner added)
..work, commit, push to origin/my_new_feature
git merge master
..finish my_new_feature, push to origin/my_new_feature
git checkout master
git merge my_new_feature
delete remote branch
delete local branch
Es gibt zwei wesentliche Unterschiede (glaube ich): Ich verwende Merge immer anstelle von Rebasing und schiebe meinen Feature-Zweig (und meine Feature-Branch-Commits) in das Remote-Repository.
Meine Argumentation für den Remote-Zweig ist, dass ich möchte, dass meine Arbeit während der Arbeit gesichert wird. Unser Repository wird automatisch gesichert und kann wiederhergestellt werden, wenn etwas schief geht. Mein Laptop ist nicht oder nicht so gründlich. Daher hasse ich es, Code auf meinem Laptop zu haben, der nicht woanders gespiegelt wird.
Meine Argumentation für das Zusammenführen anstelle des erneuten Basierens ist, dass das Zusammenführen Standard zu sein scheint und das erneute Basieren eine erweiterte Funktion zu sein scheint. Mein Bauchgefühl ist, dass das, was ich versuche, kein fortgeschrittenes Setup ist, daher sollte eine Neustart unnötig sein. Ich habe sogar das neue Pragmatic Programming-Buch auf Git gelesen, und sie behandeln das Zusammenführen ausführlich und erwähnen kaum die Basis.
Wie auch immer, ich habe meinen Workflow in einem kürzlich durchgeführten Zweig verfolgt, und als ich versuchte, ihn wieder zum Master zusammenzuführen, ging alles zur Hölle. Es gab Unmengen von Konflikten mit Dingen, die keine Rolle hätten spielen sollen. Die Konflikte machten für mich einfach keinen Sinn. Ich brauchte einen Tag, um alles zu klären, und gipfelte schließlich in einem erzwungenen Druck auf den Remote-Master, da mein lokaler Master alle Konflikte gelöst hat, aber der Remote-Master immer noch nicht glücklich war.
Was ist der "richtige" Workflow für so etwas? Git soll das Verzweigen und Zusammenführen sehr einfach machen, und ich sehe es einfach nicht.
Update 15.04.2011
Dies scheint eine sehr beliebte Frage zu sein, daher dachte ich, ich würde meine zweijährige Erfahrung seit meiner ersten Frage aktualisieren.
Es stellt sich heraus, dass der ursprüngliche Workflow zumindest in unserem Fall korrekt ist. Mit anderen Worten, das ist was wir tun und es funktioniert:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge my_new_feature
Tatsächlich ist unser Workflow etwas anders, da wir eher Squash-Merges als Raw-Merges durchführen. ( Hinweis: Dies ist umstritten, siehe unten. ) Auf diese Weise können wir unseren gesamten Feature-Zweig in ein einziges Commit für den Master verwandeln. Dann löschen wir unseren Feature-Zweig. Dies ermöglicht es uns, unsere Commits auf Master logisch zu strukturieren, auch wenn sie in unseren Filialen etwas chaotisch sind. Das machen wir also:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge --squash my_new_feature
git commit -m "added my_new_feature"
git branch -D my_new_feature
Kontroverse um Squash-Zusammenführung - Wie mehrere Kommentatoren hervorgehoben haben, wirft die Squash-Zusammenführung den gesamten Verlauf Ihres Feature-Zweigs weg. Wie der Name schon sagt, werden alle Commits zu einem einzigen zusammengefasst. Für kleine Funktionen ist dies sinnvoll, da es zu einem einzigen Paket zusammengefasst wird. Für größere Funktionen ist dies wahrscheinlich keine gute Idee, insbesondere wenn Ihre individuellen Commits bereits atomar sind. Es kommt wirklich auf die persönlichen Vorlieben an.
Pull-Anforderungen von Github und Bitbucket (andere?) - Falls Sie sich fragen, wie sich das Zusammenführen / Wiederherstellen auf Pull-Anforderungen bezieht, empfehle ich, alle oben genannten Schritte auszuführen, bis Sie bereit sind, wieder zum Master zusammenzuführen. Anstatt manuell mit git zu verschmelzen, akzeptieren Sie einfach die PR. Beachten Sie, dass dies keine Squash-Zusammenführung durchführt (zumindest nicht standardmäßig), aber Nicht-Squash, Nicht-Schnellvorlauf ist die akzeptierte Zusammenführungskonvention in der Pull-Request-Community (soweit ich weiß). Im Einzelnen funktioniert es so:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git push # May need to force push
...submit PR, wait for a review, make any changes requested for the PR
git rebase master
git push # Will probably need to force push (-f), due to previous rebases from master
...accept the PR, most likely also deleting the feature branch in the process
git checkout master
git branch -d my_new_feature
git remote prune origin
Ich habe Git geliebt und möchte nie wieder zu SVN zurückkehren. Wenn Sie Probleme haben, bleiben Sie einfach dabei und irgendwann sehen Sie das Licht am Ende des Tunnels.
rebase
Verständnis beigetragen hat