Einführung
Git führt mehrere spezielle "Hilfs"-Refs in .git/, um den Zustand mehrstufiger Operationen aufzuzeichnen. Sie zu kennen verwandelt beängstigende Wiederherstellungen in Einzeiler.
ORIG_HEAD
ORIG_HEAD wird gesetzt, wenn eine "gefährliche" Operation HEAD stark bewegt: merge, rebase, reset, am. Es erfasst die vorherige Spitze, sodass Sie zurücksetzen können:
git merge feature
# entscheiden, dass es ein Fehler war
git reset --hard ORIG_HEAD
Derselbe Trick nach einem schlechten Rebase oder Reset:
git rebase main
git reset --hard ORIG_HEAD # zurück zum Pre-Rebase-Zustand
MERGE_HEAD
Während eines Merges zeichnet MERGE_HEAD die Spitze des hinein-gemergten Branches auf. Es existiert vom Beginn von git merge, bis der Merge-Commit erstellt oder der Merge abgebrochen wird:
git merge feature
cat .git/MERGE_HEAD
git merge --abort # entfernt MERGE_HEAD
Wenn Sie das Lösen von Konflikten beendet haben und den Merge-Commit schreiben wollen:
git commit # nutzt MERGE_HEAD, um den zweiten Elternteil aufzuzeichnen
MERGE_MSG und AUTO_MERGE
Begleitdateien sind .git/MERGE_MSG (die vorbereitete Commit-Nachricht) und seit Git 2.40 AUTO_MERGE (ein Tree mit Gits Best-Effort-Auto-Auflösung). Letzteres ist nützlich zum Diffen gegen Ihre manuelle Auflösung.
CHERRY_PICK_HEAD und REVERT_HEAD
Während eines Cherry-Picks oder Reverts zeichnet Git den Quell-Commit auf:
git cherry-pick a1b2c3d
cat .git/CHERRY_PICK_HEAD
git cherry-pick --abort
git cherry-pick --continue # nach dem Lösen von Konflikten
Dasselbe Muster gilt für git revert mit REVERT_HEAD.
BISECT_HEAD und REBASE_HEAD
Beim Bisecten oder Rebasen schreibt Git auch BISECT_HEAD oder REBASE_HEAD, um den laufenden Zustand zu verfolgen. Werkzeuge wie git status verwenden diese, um genaue "Sie sind mitten in X"-Nachrichten auszugeben.
FETCH_HEAD
Nach einem Fetch listet FETCH_HEAD auf, was gefetcht wurde, eine Ref pro Zeile. git pull liest sie, um zu wissen, was zu mergen ist:
git fetch origin main
cat .git/FETCH_HEAD
git merge FETCH_HEAD
Zusammensetzen
git status # referenziert all diese nach Bedarf
ls .git/*HEAD # aktuelle Hilfs-Refs auflisten
Laufende Operationen erkennen
git status liest diese Hilfs-Refs, um Ihnen zu sagen, was läuft. Skripte können dasselbe tun, indem sie auf die Existenz der Dateien testen:
if test -f "$(git rev-parse --git-dir)/MERGE_HEAD"; then
echo "merge in progress"
fi
if test -f "$(git rev-parse --git-dir)/CHERRY_PICK_HEAD"; then
echo "cherry-pick in progress"
fi
if test -d "$(git rev-parse --git-dir)/rebase-merge"; then
echo "interactive rebase in progress"
fi
Genau das tun Shell-Prompt-Integrationen wie __git_ps1, um (main|MERGING) darzustellen.
Häufige Fehler
Versuchen, MERGE_HEAD manuell zu löschen, um aus einem Merge zu entkommen; verwenden Sie git merge --abort. Vergessen, dass ORIG_HEAD existiert, und Commits nach einem schlechten Reset von Hand neu erstellen. FETCH_HEAD (letzter Fetch, transient) mit Remote-Tracking-Refs wie origin/main (persistent) verwechseln. Und schließlich: Skripten um diese Refs herum mit der Annahme, sie existierten; MERGE_HEAD existiert nur während eines Merges, also testen Sie immer auf die Datei, bevor Sie lesen.