Git Rebase nach vorheriger Git Merge


79

Ich habe folgende Situation:

  • Ich habe ein clone(Y) aus einem Haupt-Repository (X) erstellt, weil viele Leute an Y gearbeitet haben. Wir haben rebasenur merges gemacht. Wenn wir ( push) Y an X liefern wollen, möchten wir a machen rebase, um die Dinge schön und sauber zu haben

Das Problem ist, dass rebasewir dabei aufgefordert werden, alle Zusammenführungen durchzuführen, die wir bereits in den vorherigen mergeSchritten durchgeführt haben. Gibt es eine Lösung dafür neben der, die bedeutet, dass die Zusammenführungen tatsächlich wiederholt werden?

Ich habe erwartet, dass es ziemlich einfach sein wird, da wir die widersprüchlichen Zusammenschlüsse bereits gelöst haben.


Bei: "Da viele Leute an Y gearbeitet haben, haben wir keine Rebase durchgeführt, sondern nur Zusammenführungen", meinst du Zusammenführung mit dem Upstream, oder?
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

Antworten:


82

Das Wiederherstellen, um einen "sauberen" Verlauf zu erhalten, wird überbewertet. Der beste Weg, wenn Sie den Verlauf beibehalten möchten, besteht darin, die Zusammenführung anstelle einer erneuten Basis durchzuführen. Auf diese Weise ist es genau das gleiche, das Sie während der Entwicklung getestet haben , wenn Sie jemals zu einer Revision zurückkehren müssen . Dies löst auch Ihr Problem mit den zuvor gelösten Zusammenführungskonflikten.

Wenn Sie den Verlauf nicht beibehalten möchten, können Sie einen neuen Zweig außerhalb des Masters erstellen, ihn auschecken und dann git read-tree -u -m devIhren Arbeitsbaum so aktualisieren, dass er mit dem devZweig übereinstimmt . Dann können Sie alles zu einem großen Commit festschreiben und es wie gewohnt zum Master zusammenführen.


1
Was Sie hier effektiv getan haben, ist eine Zusammenführung. Der neue Zweig ist nicht erforderlich.
Isak Gilbert

1
@isakgilbert Es ist nur das gleiche, wenn Sie mit verschmelzen --squash. Bei einer regelmäßigen Zusammenführung werden N oder N + 1 Commits zum Master hinzugefügt , wenn N Commits in der Verzweigung vorhanden waren. Der obige Vorschlag oder merge --squashfügt immer nur ein einziges Commit zum Master hinzu.
Peterflynn

3
@ytpete, ja genau. Ich bin der Meinung, dass das oben Genannte nur ein Umweg ist, um einen Merge-Quash vom Entwickler zum Master durchzuführen. "Erstellen eines neuen Zweigs" zeigt nur auf die Stelle, an der sich der Master befindet. "Alles in einem großen Commit festschreiben" macht nur den Squash.
Isak Gilbert

2
Merge-Commits sind verrauscht, wenn versucht wird, alle Änderungen in einem einzelnen Zweig anzuzeigen. Es ist ein Schmerz, das Diff zu extrahieren und es zu betrachten, wenn eine saubere Geschichte es einfach macht.
Ajax

2
Ich könnte nicht mehr damit einverstanden sein, dass eine "saubere" Geschichte überbewertet ist. Es ist nicht überbewertet, es spart Zeit und macht die Dinge weniger verwirrend.
Basickarl

122

git merge --squashist jetzt meine bevorzugte Methode zur Neugründung nach viel Arbeit und vielen Zusammenführungen ( siehe diese Antwort ). Wenn der Zweig, an dem Sie arbeiten, aufgerufen wird my-branchund Sie eine Basis erstellen möchten, gehen Sie wie folgt vor master:

git checkout my-branch
git branch -m my-branch-old
git checkout master
git checkout -b my-branch
git merge --squash my-branch-old
git commit

12

Zwei Bemerkungen:

  • Sie können Ihre eigene (noch nicht gepusste) Arbeit so oft neu erstellen, wie Sie möchten, zusätzlich zu neu abgerufenen Commits.
  • Sie könnten die Zusammenführungskonflikte (während der Rebase) vermeiden, wenn Sie sie aktiviert hättengit rerere , was für diese Art von Situation der Fall ist.
    http://git-scm.com/images/rerere2.png Weitere Informationen finden Sie unter git rerere.

@lulian: In diesem Fall müssen Sie diese Zusammenführungskonfliktlösungen erneut durchführen, wenn Sie Ihre Arbeit neu aufbauen müssen.
VonC

@krlmlr Danke. Ich habe den Link wiederhergestellt, eine Illustration und einen Verweis auf die Manpage dieses Befehls hinzugefügt.
VonC

7

Sie können alle Änderungen in Ihrer Branche übernehmen und sie wie masterfolgt in ein neues Commit einfügen:

git diff master > my_branch.patch
git checkout master
patch -p1 < my_branch.patch

Stellen Sie dann Ihre Dateien bereit und legen Sie fest.


1

In Bezug auf die Wiedergabe von Zusammenführungskonflikten können Sie mit git rerere eine Datenbank darüber verwalten, wie Zusammenführungskonflikte bereits gelöst wurden, sodass bei der Durchführung einer Neuausrichtung, die zu denselben Konflikten führt, die mühsamen Teile automatisch für Sie erledigt werden.

https://hackernoon.com/fix-conflicts-only-once-with-git-rerere-7d116b2cec67

git config --global rerere.enabled true

Das Einzige, worauf Sie achten müssen, ist, dass Sie etwas falsch gelöst haben es auch beim nächsten Mal automatisch für Sie borked wird und Sie es möglicherweise nicht wirklich bemerken.

Eine formellere Dokumentation finden Sie hier: https://git-scm.com/docs/git-rerere

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.