origin - git rebase problems




Wie identifiziere ich widersprüchliche Commits per Hash während git rebase? (4)

Kurze Antwort

Wenn es heißt

Patch failed at 0001 commit message for F

Dann renne

$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001

Um die SHA ad1c77 des fehlgeschlagenen Commits git show ad1c77 , verwenden Sie git show ad1c77 , um einen Blick darauf zu werfen.

Lange Antwort

Beginnen wir mit diesem Baum:

A---B---C---D
     \
      E---F---G

$ git checkout G
$ git rebase D

Wenn ein Rebase-Konflikt auftritt, liegt ein Konflikt zwischen

  • Die Upstream-Änderungen ( C--D ) vom gemeinsamen Vorfahren ( B ) plus die bereits basierten Änderungen und der bereits gelöste Konflikt ( E' ) gegenüber
  • der Patch des nächsten Commits ( F )

Mal sehen was passiert:

1) A---B---C---D---E'          <- E patched and committed successfully as E'
2) A---B---C---D---E'---       <- failed to patch F onto E'

Hier ist die Fehlermeldung:

First, rewinding head to replay your work on top of it...
Applying: commit message for F
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Failed to merge in the changes.
Patch failed at 0001 commit message for F

Zunächst können Sie feststellen, dass es sich um F , da die Commit-Meldung angezeigt wird. Wenn Ihre Commit-Nachrichten jedoch alle wie "foo", "Dokumentation" oder "einige Korrekturen" aussehen, ist dies nicht hilfreich, und Sie möchten wirklich die SHA-ID ad1c77 oder den Inhalt des Patches.

So erfahren Sie die wahre Identität von F :

Wenn es den Rebase-Konflikt auflistet, wird es ungefähr so ​​lauten:

Patch failed at 0001 commit message for F

Nun schauen Sie in .git/rebase-apply/ , wo Sie die Patch-Datei 0001 :

$ ls .git/rebase-apply
0001          head-name     msg           orig-head     sign
0002          info          msg-clean     patch         threeway
apply-opt     keep          next          quiet         utf8
final-commit  last          onto          rebasing

Die Patch-Datei enthält die ursprüngliche Festschreibungs-ID

$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001

Sie können sich das dann anschauen.

Es muss einen einfacheren Weg geben, aber das funktioniert.

Beachten Sie, dass die Tatsache, dass der Patch fehlgeschlagen ist, möglicherweise auf ein anderes Commit zurückzuführen ist (wenn Sie auf einen gemeinsamen Vorfahren von HEAD und das Rebase-Ziel umbasieren). Das Feststellen dieses Commits ist etwas komplizierter, obwohl Sie versuchen könnten, die Rebase in umgekehrter Reihenfolge auszuführen, um es zu finden:

$ git checkout D
$ git rebase G

Wie kann ich, wenn ich mit git rebase auf einen Zusammenführungskonflikt git rebase , die git rebase des Konflikts anhand von Commits identifizieren und nicht nur git rebase ?

Ich weiß bereits, wie man (grundlegende) Verwendung von git mergetool oder git add vor git rebase --continue , aber manchmal git rebase --continue die Unterschiede zwischen den Dateien nicht aus: Ich möchte das Commit-Protokoll und den diff des Commits sehen, die gerade fehlgeschlagen sind auf den Arbeitsbaum angewendet werden.

Ich habe in anderen Fragen gelesen, dass git log --merge die übergebenen Commits git log --merge würde, wenn ich git merge . Ich habe es trotzdem versucht, als ich auf einen Konflikt stieß und mir wurde fatal: --merge without MERGE_HEAD? gesagt fatal: --merge without MERGE_HEAD? .

Wie kann ich das problematische Commit identifizieren?


Zeigt das aktuelle / fehlgeschlagene Commit an

Dies kann eine neue Funktion sein, aber REBASE_HEAD gibt Ihnen das Commit an, an dem Sie gerade angehalten wurden (z. B. wenn das Commit nicht REBASE_HEAD ). Wenn Sie das Commit vollständig anzeigen möchten, können Sie es verwenden

git show REBASE_HEAD

Als ausführlichere Alternative können Sie git rebase --show-commit-patch . Die Dokumente sagen, dass sie gleichwertig sind.

Zeigen Sie, was sich seit Beginn Ihrer Arbeit geändert hat

Wenn Sie sehen möchten, was sich zwischen dem Umbasierungspunkt und dem Umbasierungspunkt geändert hat, können Sie einen Unterschied zwischen den beiden Zweigen feststellen. Wenn Sie beispielsweise von master auf origin/master umbasieren, können Sie Folgendes verwenden:

git diff master..origin/master

Oder wenn Sie die Änderungen als einzelne Commits sehen möchten:

git log -p master..origin/master

Wenn Sie es vorziehen, den Hash zu verwenden oder nach einer Weile zu einer Rebase zurückzukehren und sich nicht daran erinnern können, welche Äste Sie neu basieren, können Sie git status , um die beiden Äste zu sehen. Zum Beispiel:

Sie ändern derzeit die Filiale 'master' in 'b5284275'.

Dann können Sie sehen, was sich geändert hat:

git diff master..b5284275

Oft befinden Sie sich mitten in einer Rebase und möchten die nicht benötigten Commits überspringen.

Während git status Ihnen sagt, dass Sie sich gerade in einem Commit befinden, empfiehlt es sich, git rebase --continue git rebase --skip oder git rebase --abort , aber es sagt Ihnen nicht, zu welchem ​​Commit Sie gerade gehen.

Daher ist es oft schwer zu wissen, ob Sie git rebase --skip oder nicht.

Es gibt jedoch immer noch einen Weg, um herauszufinden, welches Commit Sie ausführen, indem Sie Folgendes ausführen:

git log -1 $(< .git/rebase-apply/original-commit)

Während einer git rebase die git rebase Konflikte git rebase , zeigt der folgende Befehl das widersprüchliche Commit (alles, nicht nur die in Konflikt stehenden Dateien), d. H. Ihr Commit wird gerade auf der neuen Basis abgespielt / neu basiert, unabhängig von Ihrem Standort bis zu:

git show $(< .git/rebase-apply/original-commit)

Wenn Sie nur die Konflikte für eine bestimmte Konfliktdatei anzeigen möchten (die Sie lösen), dann isoliert:

git show $(< .git/rebase-apply/original-commit) -- /path/to/conflicting/file

Beim Aufbau dieser Antwort wurden keine Katzen missbraucht :).





git-rebase