Ich verwende 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 eine Menge Gepäck mit in die Beziehung.
Ich habe gehört, dass Git hervorragend zum Verzweigen und Zusammenführen geeignet ist, aber bisher sehe ich das nicht. Sicher, das Verzweigen ist ganz einfach, aber wenn ich versuche, zusammenzuführen, geht alles zum Teufel. Das bin ich von SVN gewohnt, aber mir scheint, dass ich gerade ein minderwertiges Versionierungssystem gegen ein anderes eingetauscht habe.
Mein Partner sagt mir, dass meine Probleme daher rühren, dass ich willkürlich zusammenführen will, und dass ich in vielen Situationen rebase statt merge verwenden sollte. Hier ist zum Beispiel der Arbeitsablauf, 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
Im Wesentlichen erstellen Sie einen Feature-Zweig, führen IMMER einen Re-Base von Master auf den Zweig durch und führen den Zweig wieder auf Master zusammen. Wichtig dabei ist, dass der Zweig immer lokal bleibt.
Hier ist der Arbeitsablauf, 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 (denke ich): Ich verwende "merge always" anstelle von "rebasing", und ich schiebe meinen Feature-Branch (und meine Feature-Branch-Commits) in das entfernte Repository.
Der Grund für die Remote-Zweigstelle ist, dass ich meine Arbeit während der Arbeit sichern möchte. Unser Repository wird automatisch gesichert und kann wiederhergestellt werden, wenn etwas schief geht. Bei meinem Laptop ist das nicht der Fall, oder nicht so gründlich. Deshalb hasse ich es, Code auf meinem Laptop zu haben, der nicht irgendwo anders gespiegelt ist.
Meine Begründung für die Zusammenführung anstelle von rebase ist, dass merge eine Standardfunktion und rebase eine erweiterte Funktion zu sein scheint. Mein Gefühl sagt mir, dass es sich bei dem, was ich vorhabe, nicht um ein fortgeschrittenes Setup handelt, so dass Rebase unnötig sein sollte. Ich habe sogar das neue Buch Pragmatic Programming über Git durchgelesen, und dort wird merge ausführlich behandelt und rebase kaum erwähnt.
Wie auch immer, ich folgte meinem Arbeitsablauf auf einem aktuellen Zweig, und als ich versuchte, es zurück zu Master zusammenzuführen, ging alles zum Teufel. Es gab Unmengen von Konflikten mit Dingen, die nicht von Bedeutung sein sollten. Die Konflikte ergaben für mich einfach keinen Sinn. Ich brauchte einen Tag, um alles zu sortieren, und gipfelte schließlich in einem erzwungenen Push auf den entfernten Master, da mein lokaler Master alle Konflikte gelöst hat, aber der entfernte Master immer noch nicht zufrieden war.
Was ist der "richtige" Arbeitsablauf für so etwas? Git soll das Verzweigen und Zusammenführen super-einfach machen, und ich sehe es einfach nicht.
Aktualisierung 2011-04-15
Dies scheint eine sehr beliebte Frage zu sein, also dachte ich, ich bringe meine zweijährige Erfahrung seit meiner ersten Frage auf den neuesten Stand.
Es stellt sich heraus, dass der ursprüngliche Arbeitsablauf richtig ist, zumindest in unserem Fall. Mit anderen Worten: Das ist es, 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
Unser Arbeitsablauf ist ein wenig anders, denn wir neigen dazu, Folgendes zu tun Kürbisfusionen anstelle von rohen Zusammenführungen. ( Anmerkung: T ) Dies ermöglicht es uns, unseren gesamten Feature-Zweig in einen einzigen Commit auf Master zu verwandeln. Dann löschen wir unseren Feature-Zweig. Auf diese Weise können wir unsere Commits auf Master logisch strukturieren, auch wenn sie auf unseren Zweigen ein wenig unordentlich sind. Wir gehen also folgendermaßen vor:
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
Squash Merge Kontroverse - Wie mehrere Kommentatoren bemerkt haben, wird beim Squash Merge die gesamte Historie des Funktionszweigs gelöscht. Wie der Name schon sagt, werden alle Commits zu einem einzigen zusammengeführt. Für kleine Features ist das sinnvoll, da es sie in einem einzigen Paket zusammenfasst. Für größere Features ist es wahrscheinlich keine gute Idee, vor allem wenn die einzelnen Commits bereits atomar sind. Es kommt wirklich auf die persönlichen Vorlieben an.
Github und Bitbucket (andere?) Pull Requests - Falls du dich fragst, wie merge/rebase mit Pull Requests zusammenhängt, empfehle ich, alle oben genannten Schritte zu befolgen, bis du bereit bist, zurück zu Master zu mergen. Anstatt manuell mit Git zusammenzuführen, akzeptieren Sie einfach den PR. Beachten Sie, dass dies kein Squash Merge ist (zumindest nicht standardmäßig), aber Non-Squash, Non-Fast-Forward ist die akzeptierte Merge-Konvention in der Pull Request Community (soweit ich weiß). Genauer gesagt, 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 lieben gelernt und möchte nie wieder zu SVN zurückkehren. Wenn Sie Probleme haben, bleiben Sie einfach dabei und irgendwann werden Sie das Licht am Ende des Tunnels sehen.