Gibt es eine Art 'git rebase --dry-run', die mich im Voraus über Konflikte informieren würde?

73

Ich versuche, das Skript neu zu basieren, und mein Skript nimmt unterschiedliche Pfade, je nachdem, ob das erneute Basieren zu Konflikten führt.

Gibt es eine Möglichkeit zu bestimmen, ob eine Rebase zu Konflikten führen würde, bevor die Rebase ausgeführt wird?

Jonathan.Brink
quelle
Was ist die genaue Form des git rebaseBefehls, den Sie verwenden? Verwenden Sie optionale Flags? Und welche Skriptsprache verwenden Sie? Schale?
Jub0bs
3
Wenn Sie git rebaseeinen Zusammenführungskonflikt ausführen und ausführen , wird der Prozess gestoppt und mit einem Status ungleich Null beendet. Sie können den Exit-Status des Rebase-Vorgangs überprüfen und, wenn er nicht Null ist, ausführen git rebase --abort, um den Vorgang abzubrechen.
jub0bs
1
Haben Sie einen Weg gefunden, dies zu tun?
Crmpicco
1
@crmpicco Ich habe im Grunde genommen das getan, was Jubobs vorgeschlagen hat, indem ich die Rebase durchgeführt, nach Konflikten gesucht und bei Bedarf abgebrochen habe. Ich wünschte, es gäbe einen eleganteren Weg ...
Jonathan.Brink
2
Bei unordentlichen Rebases erstelle ich häufig einen neuen Zweig und führe dort zuerst einen Probelauf durch. Wenn alles reibungslos verläuft, wird der Testlauf zur Rebase, andernfalls wechseln Sie einfach zurück zum ursprünglichen Zweig.
Jordanpg

Antworten:

48

Zum Zeitpunkt des Schreibens (Git v2.6.1v2.10.0) bietet der git rebaseBefehl keine --dry-runOption. Es gibt keine Möglichkeit zu wissen, ob Sie in Konflikte geraten, bevor Sie tatsächlich versuchen, eine Rebase durchzuführen.

Wenn Sie jedoch git rebaseeinen Konflikt ausführen und darauf stoßen, wird der Prozess mit einem Status ungleich Null gestoppt und beendet. Sie können den Exit-Status der Rebase-Operation überprüfen und, falls er nicht Null ist, ausführen git rebase --abort, um die Rebase abzubrechen:

git rebase ... || git rebase --abort
jub0bs
quelle
9
Und was ist, wenn die Rebase erfolgreich ist, ich aber merke, dass ich zurück will? Zum Beispiel, weil ich keinen Push erzwingen möchte.
bluenote10
2
@ bluenote10 Sie können das Reflog des Zweigs verwenden , um es auf das Commit zurückzusetzen, auf das vor dem Rebase verwiesen wird.
Jub0bs
2
@ bluenote10 Oder wenn Sie wissen, dass Sie das Rebase-Ergebnis auf jeden Fall verwerfen möchten, können Sie einfach mit einem abgenommenen Kopf beginnen : git checkout --detach foo.
Infiltrator
1
Sie können git reset --hard ORIG_HEADden Zweig auch verwenden , um ihn wieder an den Ort vor der Neubasis zu verschieben.
Jacob Errington
37

Wenn Sie nur sehen wollen , wenn das Fütterungsmaterial sei erfolgreich , aber dann wollen Sie auf „roll back“ können Sie alle Tage die Zweigspitze neu positionieren zurück verpflichten zum Original. Markieren Sie einfach die ursprüngliche SHA oder notieren Sie sie.

Oder erstellen Sie einfach einen neuen temporären Zweig, in dem Sie die Rebase "inszenieren" können:

git checkout your-branch
git checkout -b tmp
git rebase other-branch

Wenn es erfolgreich war, Sie aber "zurückrollen" möchten, your-branchbleibt es unberührt. Nur git branch -D tmpund du bist wieder da, wo du angefangen hast.

Wenn es Konflikte gab und Sie einige Arbeit geleistet haben, um sie zu lösen, und Sie jetzt die Basis behalten möchten, positionieren Sie einfach Ihren Zweig-Tipp auf tmp(und dann git branch -D tmp).

Joneit
quelle
11
Ein einziger Befehl anstelle der ersten beiden:git checkout -b tmp your-branch
Ruvim
7

Ich vermute, dass git rebase ... --dry-rundies aus folgendem Grund nicht möglich ist.

Wenn Sie a git rebaseausführen, wird git zum Startpunkt zurückgesetzt und dann schrittweise Patches für jedes Commit angewendet, um den Zweig auf den neuesten Stand zu bringen. Wenn ein Konflikt auftritt, wird er angehalten und darauf gewartet, dass Sie den Konflikt lösen, bevor Sie fortfahren. Der Weg, den die Rebase nach diesem Konflikt einschlägt, hängt davon ab, wie Sie den Konflikt lösen. Wenn Sie ihn auf eine bestimmte Weise lösen, kann dies zu späteren Konflikten führen (oder diese beseitigen).

Sie können also git rebase ... --dry-runnur den ersten Konflikt angeben - Berichte über spätere Konflikte hängen davon ab, wie dieser erste Konflikt gelöst wird.

Ich kann mir nur git diffvorstellen, dies zwischen der aktuellen Position und dem letzten Commit in dem Zweig zu tun, auf den Sie zurückgreifen. Aber das gibt Ihnen nicht wirklich das, wonach Sie suchen - Sie brauchen wirklich nur eine Liste widersprüchlicher Änderungen zwischen den beiden Punkten. Es gibt vielleicht eine Möglichkeit, dies zu tun git diff, aber es ist kein normaler Patch.

Kryten
quelle
5

Sie können immer noch Git-Rebase durchführen, damit spielen, wie Sie möchten, und dann alle Änderungen von zuvor wiederherstellen. Angenommen, Sie haben einen Zweig in den Zweig zurückgesetzt masterund es gefällt Ihnen nicht:

  1. git reflog -20 - gibt Ihnen die letzten 20 Positionen Ihres KOPFES mit einer kleinen Beschreibung
  2. git checkout <the_branch_name> - Platziert Ihren KOPF auf dem Ast
  3. git reset --hard <old_sha1_found_in_reflog> - Platziert Ihren KOPF und Zweig auf dem alten Ref. Auf diese Weise können Sie den alten Zweig wiederherstellen.

Hier sind einige Mechaniken zu verstehen:

  1. Sie löschen NIEMALS etwas in Git, jedenfalls nicht mit Befehlen. Es ist der Garbage Collector, der nicht referenzierte Zweige durchläuft und löscht (Standard 3 Monate). Ihr Zweig existiert also noch vor dem Rebase.
  2. Gleiches gilt für die Rebase auf demselben Zweig, es ist nur ein neuer Baum, der neben dem alten neu geschrieben wurde.
  3. Die gesamte Geschichte rebaseund Ihre anderen Informationen zu HEAD-Manipulationen sind in derreflog
  4. Sie können @{N}Anmerkungen von verwendenreflog

Nach dem rebasegeht also nichts verloren , Sie müssen nur wissen, wie Sie es finden und wiederherstellen können.

Zum Beispiel können Sie sich ein Tag setzen, bevor Sie darauf rebasezurückgreifen oder es löschen. Es entzieht Ihnen den gesamten SHA1-Forschungsschritt.

Lukasz Kruszyna
quelle
2

Aufbauend auf der Lösung von @joneit :

Erstellen Sie einen neuen tempZweig aus your-branchund versuchen Sie, diesen temporären Zweig auf Folgendes umzustellen new-base:

git checkout -b temp <your-branch> && git rebase <new-base>

zB um zu testen, ob der Zweig feature1auf Folgendes zurückgesetzt werden kann master:

git checkout -b temp feature1 && git rebase master
Isapir
quelle