Hier ist ein Workflow, mit dem ich mich normalerweise bei der Arbeit beschäftige.
git checkout -b feature_branch
# Do some development
git add .
git commit
git push origin feature_branch
Zu diesem Zeitpunkt steht der Feature-Zweig zur Überprüfung durch meine Kollegen zur Verfügung, aber ich möchte mich weiter auf andere Features konzentrieren, die davon abhängig sind feature_branch
. Also, während feature_branch
im Rückblick ...
git checkout feature_branch
git checkout -b dependent_branch
# Do some more development
git add .
git commit
Jetzt nehme ich einige Änderungen als Antwort auf die Codeüberprüfung auf feature_branch vor
git checkout feature_branch
# Do review fixes
git add .
git commit
git checkout dependent_branch
git merge feature_branch
Hier bekommen wir Probleme. Wir haben eine Squash-Richtlinie für Master, was bedeutet, dass Feature-Zweige, die zu Master zusammengeführt werden, zu einem einzigen Commit gequetscht werden müssen.
git checkout feature_branch
git log # Look for hash at beginning of branch
git rebase -i first_hash_of_branch # Squash feature_branch into a single commit
git merge master
Alles ist cool, außer mit dependent_branch
. Wenn ich versuche, abhängige Zweige auf Master umzustellen oder Master darin zusammenzuführen, wird Git durch die neu geschriebene / gequetschte Historie verwirrt und markiert im Grunde jede einzelne Änderung depedendent_branch
als Konflikt. Es ist eine PITA, alle Änderungen in zu durchlaufen und im Grunde genommen zu wiederholen oder zu konfliktisieren dependent_branch
. Gibt es eine Lösung dafür? Manchmal erstelle ich manuell einen Patch und wende ihn von einem neuen Master-Zweig aus an. Wenn es jedoch echte Konflikte gibt, ist es noch schlimmer, ihn zu beheben.
git checkout dependent_branch
git diff > ~/Desktop/dependent_branch.diff
git checkout master
git checkout -b new_dependent_branch
patch -p1 < ~/Desktop/dependent_branch.diff
# Pray for a clean apply.
Irgendwelche Ideen? Ich weiß, dass dies aufgrund der neu geschriebenen Geschichte während des Squashs passiert, aber das ist eine Voraussetzung, die ich nicht ändern kann. Was ist die beste Lösung / Problemumgehung? Kann ich etwas zaubern? Oder gibt es eine schnellere Möglichkeit, alle Schritte zum manuellen Erstellen des Diff auszuführen?
git add .
ist es völlig böse und wird dich irgendwann beißen, wenn du Dinge begehst, die du nicht vorhast. Sie sollten verwendengit add -p
oder zumindestgit add -u .
Antworten:
Ein bisschen darüber, warum das passiert:
Ich werde
O
"ursprünglicher Master" undFB
"neuer Master" sein, nachdem ein Feature-Zweig zusammengeführt wurde in:Say
feature_branch
sieht aus wie:dependent_feature
hat noch ein paar zusätzliche Commits:Sie führen Ihren ursprünglichen Feature-Zweig zu Master zusammen und drücken ihn zusammen, um Folgendes zu erhalten:
Wenn Sie nun versuchen, den abhängigen Zweig neu zu gründen, wird git versuchen, den gemeinsamen Vorfahren zwischen diesen Zweigen herauszufinden. Während es ursprünglich gewesen wäre
C
, wenn Sie die Commits nicht niedergeschlagen hätten, findet git stattdessenO
als gemeinsamen Vorfahren. Als Ergebnis git versucht zu wiederholenA
,B
undC
die sind bereits enthalten ist inFB
, und Sie werden eine Reihe von Konflikten zu bekommen.Aus diesem Grund können Sie sich nicht wirklich auf einen typischen Rebase-Befehl verlassen, und Sie müssen dies genauer angeben, indem Sie den folgenden
--onto
Parameter angeben :Ändern Sie den
HEAD~3
Parameter nach Bedarf für Ihre Zweige, und Sie sollten sich nicht mit redundanter Konfliktlösung befassen müssen.Eine alternative Syntax, wenn Sie keine Bereiche angeben möchten und Ihren ursprünglichen Feature-Zweig noch nicht gelöscht haben:
quelle
In diesem speziellen Fall scheinen Sie "zu wissen", dass nur die gequetschte Arbeit des Zweigs, an dem Sie ursprünglich gearbeitet haben, in den Master übernommen wurde.
Sie können also problemlos zusammenführen, indem Sie Ihre Änderungen jedes Mal beibehalten, wenn ein Konflikt vorliegt. Dafür gibt es eine Option:
git merge -Xours master
Weitere Informationen finden Sie unter https://git-scm.com/docs/git-rebase .
quelle
Ich bin von Herzen anderer Meinung als die Richtlinie "Jede Feature-Entwicklung in einem einzigen Commit zusammenfassen", aber es ist ihr Aufruf ...
Ich würde die Zweige unverändert lassen und ein zusammengesetztes Commit nur zur Veröffentlichung in einem speziellen Zweig erstellen. Es ist wertvoll, die Entwicklung Schritt für Schritt verfolgen zu können, auch wenn das Management nicht daran glaubt. Markieren Sie die Stellen von Squashes durch Tags in den "echten" Zweigen. Sie können auch Tags zwischen Squashs mit Nachrichten hinzufügen, die auf die realen Commits verweisen.
quelle