Ich habe ursprünglich im „newfeature“-Zweig gearbeitet und wurde gerufen, um dringend einen Fehler im Live-Zweig zu beheben. Ich habe dafür einen Branch mit dem Namen „generalmaintenance“ erstellt, die Arbeit erledigt und bin dann auf „development“ umgestiegen und habe ihn eingebunden. Ich möchte jetzt zum „newfeature“-Branch zurückkehren und die Änderungen zusammenführen, die ich zuvor darin gemergt habe.
Als ich zu ‘newfeature’ wechselte und in ‘develop’ zusammenführte, gab es Konflikte in 3 Dateien.
Ich geriet in Schwierigkeiten, die Konflikte zu lösen, und entschied mich schließlich, den Befehl “Zurücksetzen” im Menü “Team” von Aptana Studio 3 (das ist meine IDE) zu verwenden. Ich hatte erwartet, dass dies mich vor der Zusammenführung zurückrollen würde, was anscheinend der Fall war.
Wie auch immer, wenn ich wieder in ‘develop’ einfüge, heißt es: Already-up-to-date
, aber beim Vergleichen von Dateien zwischen den beiden Zweigen sind sie sehr unterschiedlich und die Änderungen, die ich im anderen Zweig hinzugefügt habe, werden nicht zusammengeführt.
Wie kann ich die beiden Zweige jetzt bitte zusammenführen?
Zusammenführungen rückgängig machen vs. Zusammenführungen zurücksetzen
Meine Vermutung ist, dass Sie tatsächlich sind Already-up-to-date
.
Das Problem ist, dass git zurücksetzen macht die Zusammenführung nicht rückgängig, es macht nur die Änderungen rückgängig, die die Zusammenführung mit sich gebracht hat. Wenn Sie einen Merge-Commit erstellen, kombinieren Sie die Commit-Verläufe dieser beiden Branches.
Zusammenführen
develop
|
A---B---C
E---F---M
|
newfeature
Im obigen Fall develop
wird zusammengeführt newfeature
, Erstellung der M
verpflichten. Wenn du laufen würdest git log newfeature
Sie würden alle Commits aus beiden Zweigen sehen, jedoch aus der Perspektive des newfeature
Branch wurden all diese Änderungen von der durchgeführt M
verpflichten.
Zurücksetzen
Der git revert
Der Befehl entfernt keine Commits, sondern erstellt stattdessen einen neuen Commit, der die im Commit enthaltenen Änderungen rückgängig macht. Wenn Sie zum Beispiel einen Commit hatten, der diesen Unterschied enthält …
-This is the old sentence.
+This is the new sentence.
Wenn Sie dies dann rückgängig machen, würde der Revert-Befehl einen neuen Commit erstellen, der nur den gegenteiligen Diff durchführt, er dreht einfach die Zeichen um.
-This is the new sentence.
+This is the old sentence.
Dies ist wirklich nützlich, um Schäden rückgängig zu machen, die durch Commits verursacht wurden, die andere Entwickler bereits haben. Es bringt die Geschichte voran, anstatt die Geschichte zu verändern.
Zusammenführungen rückgängig machen
Im Zusammenhang mit einer Nicht-Fastforward-Zusammenführung kann dies jedoch einen unerwünschten Effekt haben.
develop
|
A---B---C
E---F---M---W
|
newfeature
Angenommen, W ist ein Reversion-Commit, können Sie sehen, wie ausgeführt wird git log newfeature
enthält weiterhin alle Commits aus dem Entwicklungszweig. Dadurch fallen zusätzliche Zusammenführungen aus develop
wird nicht funktionieren, weil es nichts in Ihrem Zweig vermisst sieht.
Verwenden git zurücksetzen statt zurück.
In Zukunft möchten Sie vielleicht die Verwendung von in Betracht ziehen git reset --hard <ref>
(wo <ref>
ist der Commit-Hash der Zusammenführung), um eine Zusammenführung rückgängig zu machen, wenn diese Zusammenführung nicht mit anderen Entwicklern geteilt wurde. Im obigen Beispiel, nachdem Merge-Commit erstellt wurde M
, Ausführen des Befehls git reset --hard F
würde folgendes ergeben.
develop
|
A---B---C
E---F---M
|
newfeature
Wie Sie sehen können, löscht diese Technik das Commit nicht aus, wie manche Leute denken, es verschiebt einfach Ihren Zweig zurück zu dem Commit, das Sie ausgewählt haben. Wenn Sie jetzt gerannt sind git log newfeature
Sie würden nur verpflichtet werden F
, E
, und A
. Jetzt ist die Zusammenführung tatsächlich aus Ihrem Branches-Verlauf verschwunden, sodass später versucht wird, sie erneut zusammenzuführen develop
wird keine Probleme machen.
Diese Methode ist nicht ohne Komplikationen. Stellen Sie fest, dass Sie jetzt den Verlauf ändern, also wenn die newfeature
Zweig wurde nach dem in einen Remote-Zweig verschoben M
merge gemacht wurde, dann wird git denken, dass du einfach veraltet bist und dir sagen, dass du laufen musst git pull
. Wenn nur Sie an diesem Remote-Zweig arbeiten, können Sie das gerne tun force-push
– git push -f <remote> <branch>
. Dies hat die gleiche Auswirkung wie das Zurücksetzen, jedoch auf den Remote-Zweig.
Wenn dieser Zweig von mehreren Entwicklern verwendet wird, die inzwischen schon davon abgezogen hätten – dann ist dies eine schlechte Idee. Das ist der eigentliche Grund git revert
ist nützlich, da es Änderungen rückgängig macht, ohne die tatsächliche Historie zu ändern.
Das Zurücksetzen des Verlaufs ist wirklich nur eine Option für Commits, die nicht geteilt wurden.
Die Lösung – die Umkehrung rückgängig machen.
Wenn der Merge-Commit bereits geteilt wurde, ist es wahrscheinlich der beste Ansatz, ihn zu verwenden git revert
auf dieser Fusion. Wie wir jedoch bereits gesagt haben, können Sie den Zweig dann nicht einfach wieder zusammenführen und erwarten, dass alle Änderungen dieses Zweigs erneut angezeigt werden. Die Antwort ist, den Revert-Commit rückgängig zu machen.
Nehmen wir an, Sie haben etwas daran gearbeitet develop
verzweigen, nachdem die Zusammenführung rückgängig gemacht wurde newfeature
. Ihr Verlauf würde in etwa so aussehen.
develop
|
A---B---C---D
E---F---M---W
|
newfeature
Wenn Sie fusionieren develop
hinein newfeature
jetzt würden Sie nur bekommen D
weil es das einzige Commit ist, das nicht bereits Teil der Geschichte von ist newfeature
Ast. Was Sie auch tun müssen, ist das rückgängig zu machen W
verpflichten – git revert W
sollte den Trick tun, gefolgt von git merge develop
.
develop
|
A---B---C-----------D
E---F---M---W---M---G
|
newfeature
Dadurch werden alle Änderungen wiederhergestellt, die vom ursprünglichen Merge-Commit vorgenommen wurden – die tatsächlich von vorgenommen wurden C
und B
wurden aber zurückgebucht W
, bringt es dann ein D
über einen neuen Merge-Commit G
Ich würde empfehlen, das Zurücksetzen rückgängig zu machen Vor Zusammenführen in den jüngsten Änderungen an develop
, vermute ich, dass es in dieser Reihenfolge weniger wahrscheinlich ist, Konflikte auszulösen.
TL;DR
Beim Zurücksetzen wird ein „Revert-Commit“ erstellt. Wenn Sie eine Wiederherstellung rückgängig machen, müssen Sie den Befehl „revert“ für das Wiederherstellungs-Commit ausführen, das bei der ersten Wiederherstellung erstellt wurde. Es sollte leicht zu finden sein, git neigt dazu, Reverts automatisch zu kommentieren, sodass sie mit dem Wort „Reverted“ beginnen.
git revert <commit>
Habe eine hackige Lösung gefunden. Aber es funktioniert.
Was auch immer eddiemoya geantwortet hat, ist total hilfreich. Vielen Dank für die Erklärung. Ich bin auf eine ähnliche Situation gestoßen. Wo ich viele Inhalte sehen konnte git diff <branch>
aber git merge meinte schon aktuell.
Und ich konnte den genauen Revert-Commit aufgrund vieler Reverts im Protokoll nicht finden. (Ja, schlimme Sache. Hätte gar nicht erst passieren sollen)
Lösung
git checkout branchX -- .
Dadurch werden alle Änderungen von branchX zu meinem aktuellen Branch inszeniert. Verwenden Sie einen Ihrer bevorzugten Git-Clients, entfernen Sie die Bereitstellung und setzen Sie alles zurück, was nicht beabsichtigt ist.
Machen Sie ein neues Commit und seien Sie glücklich 🙂
.