Geschichte umschreiben¶
Es gibt in Git mehrere Befehle zum Umschreiben der Geschcihte. git rebase -i
ist das bekannteste und flexibelste: ihr könnt Commits neu anordnen,
zusammenfassen, bearbeiten und entfernen. diese Flexibilität geht jedoch mit
einiger Komplexität einher: euer Working Tree
und euer Index werden
aktualisiert und Konflikte können entstehen, die gelöst werden müssen, bevor ihr
mit der Arbeit fortfahren könnt.
Mit git commit --fixup und git rebase --autosquash könnt ihr hingegen
relativ einfach eine Reihe von Commits korrigieren. Im Folgenden wollen wir dies
an einem Beispiel demonstrieren:
Wir haben in unserem
my-feature-Branch zwei Commits: den einen für die eigentliche Funktion, den anderen für die zugehörigen Tests:$ git log --oneline my-feature ^origin/main a4587fa (my-feature) Add test for my new feature 56e34e9 Add new feature
Beim Merge- oder Pull-Request erhalten wir sowohl zu unserer Funktion wie auch zu unseren Tests Feedback, das wir gerne in unsere bestehenden Commits integrieren würden. Hierfür erstellen wir nun zunächst temporäre Commits:
$ git commit -m "Feedback on the tests from my function" $ git commit -m "Feedback on my function" $ git log --oneline my-feature ^origin/main 556c1e8 (my-feature) Feedback on my function 8780db6 Feedback on the tests from my function a4587fa Add test for my new feature 56e34e9 Add new feature
… mit git rebase¶
Mit
git rebase -ikönnen wir interaktiv diepick-Zeilen neu anordnen:$ git rebase -i origin/main
Dies öffnet unseren Editor:
pick 56e34e9 Add new feature pick a4587fa Add test for my new feature pick 8780db6 Feedback on the tests from my function pick 556c1e8 Feedback on my function
Anschließend können wir die Zeilen umändern, z.B. in:
pick 56e34e9 Add new feature squash 556c1e8 Feedback on my function pick a4587fa Add test for my new feature squash 8780db6 Feedback on the tests from my function
Nun haben wir erneut zwei Commits:
$ git log --oneline my-feature ^origin/main 31a140a (my-feature) Add test for my new feature 132ae9b Add new feature
Die Änderungen können nun mit
git push --force-with-leasean unseren entfernten Zweig gesendet werden.--force-with-leasegewährleistet, dass Änderungen im entfernten Zweig ggf. nicht überschrieben werden.
…mit git commit --fixup und git rebase --autosquash¶
In Git gibt es jedoch noch einen einfacheren Weg, einen vorherigen Commit zu
korrigieren: mit git commit--fixup und git rebase --autosquash.
Wir erstellen erneut zwei temporäre Commits, diesmal jedoch mit
git commit--fixup:# Further changes to the tests $ git commit --fixup=31a140a [my-feature dd0c0d1] fixup! Add test for my new feature 1 file changed, 1 insertion(+) # Further changes to my function $ git commit --fixup=132ae9b [my-function bc2298a] fixup! Add new feature 1 file changed, 1 insertion(+) $ git log --oneline my-feature ^origin/main bc2298a (my-feature) fixup! Add new feature dd0c0d1 fixup! Add test for my new feature 31a140a Add test for my new feature 132ae9b Add new feature
Bei Commits mit der Option
--fixup=SHAschreibt Git eine speziell formatierte Commit-Nachricht, die als dieser Commit korrigiert jenen gelesen werden kann.Anstatt nun mit
git rebase -idiePick/Squash-Zeilen manuell festzulegen, können wir nun einfachgit rebase --autosquashausführen:$ git rebase --autosquash origin/main Successfully rebased and updated refs/heads/my-feature. $ git log --oneline my-feature ^origin/main 694cb48 (my-feature) Add test for my new feature 55cbe9b Add new feature
git rebase --autosquashautomatisiert das, was wir gerade manuell mitgit rebase -igetan haben – es öffnete sich jedoch kein Editor, in dem wir die Commits manuell verschieben mussten.Tipp
Die Option
--fixupenthält auch die Optionenamendundreword, um die Commit-Nachricht umzuformulieren, z.B.git commit --fixup:amend=SHA.Weitere Optionen findet ihr in der Git Commit-Dokumentation.
git history¶
Added in version 2.54: Git 2.54 führt experimentell git history ein, d. h.,
dass sich die Schnittstelle noch weiterentwickeln kann. Mit git history
wird die Korrektur von Tippfehlern früherer Commit-Meldungen und das
Aufteilen von Commits in zwei Teile erleichtert:
git history reword SHAöffnet deinen Editor mit der Nachricht des angegebenen Commits und schreibt diese direkt um, wobei alle Zweige aktualisiert werden, die von diesem Commit abstammen. Im Gegensatz zu Git rebase greift es weder auf deinen Working Tree noch auf deinen Index zu.
git history split SHAteilt einen Commit interaktiv in zwei Teile, wobei ihr auswählt, welche Teile in einen neuen übergeordneten Commit ausgelagert werden sollen. Das Interface entspricht dem von
git add –p. Nach der Auswahl der Blöcke erstellt Git einen neuen Commit mit diesen Änderungen als Vorgänger des ursprünglichen Commits, der alle nicht ausgewählten Blöcke beibehält, und schreibt alle nachgelagerten Zweige um, sodass sie auf den aktualisierten Verlauf verweisen.
Warnung
history unterstützt keine Historien, die Merge-Commits enthalten, und
es können auch keine Operationen ausgeführt werden, die zu einem
Merge-Konflikt führen würden.