Wie kann ich meine letzten X Commits mit Git zu einem Commit zusammenfassen?
Wie kann ich meine letzten x Commits zusammenquetschen?
markdorison
Anomie
Verwenden git rebase -i <after-this-commit>
und ersetzen Sie „pick“ beim zweiten und nachfolgenden Commits durch „squash“ oder „fixup“, wie in beschrieben das Handbuch.
In diesem Beispiel <after-this-commit>
ist entweder der SHA1-Hash oder die relative Position vom HEAD des aktuellen Zweigs, von dem Commits für den Rebase-Befehl analysiert werden. Wenn der Benutzer beispielsweise 5 Commits aus dem aktuellen HEAD in der Vergangenheit anzeigen möchte, lautet der Befehl git rebase -i HEAD~5
.
-
Was ist damit gemeint
<after-this-commit>
?– 2540625
4. November 2014 um 5:49 Uhr
-
<after-this-commit>
ist Commit X+1, dh Elternteil des ältesten Commits, den Sie quetschen möchten.– joozek
4. November 2014 um 12:04 Uhr
-
Wenn Sie die Commits bereits gepusht haben, müssen Sie -f drücken, um den Remote-Zweig zwangsweise zu Ihrem neuen Commit zu verschieben. Dies wird jedoch jeden verärgern, der an den alten Commits gearbeitet hat.
– überschneiden
8. Dezember 2014 um 18:31 Uhr
-
Der Unterschied zwischen diesem
rebase -i
Ansatz undreset --soft
ist,rebase -i
ermöglicht es mir, den Commit-Autor zu behalten, währendreset --soft
erlaubt mir, mich neu zu verpflichten. Manchmal muss ich Commits von Pull-Requests quetschen und dabei die Autoreninformationen beibehalten. Manchmal muss ich meine eigenen Commits weich zurücksetzen. Upvotes für beide großartigen Antworten.– Zionix
15. September 2015 um 9:31 Uhr
-
Use git rebase -i <after-this-commit> and replace "pick" on the second and subsequent commits with "squash" or "fixup", as described in the manual.
ähhhh… was?– Käse
27. Juli 2016 um 3:18 Uhr
-
@Mark Amery: Es gibt verschiedene Gründe, warum ich gesagt habe, dass dies eleganter ist. Beispielsweise muss nicht unnötigerweise ein Editor erstellt und dann eine Zeichenfolge in der „to-do“-Datei gesucht und ersetzt werden. Verwenden
git merge --squash
ist auch einfacher in einem Skript zu verwenden. Im Wesentlichen war die Begründung, dass Sie die “Interaktivität” von nicht benötigengit rebase -i
überhaupt dafür.– Mark Longair
8. Juli 2013 um 15:59 Uhr
-
Obwohl ich den Vorteil schätze, eine ausführliche Commit-Nachricht für große Änderungen wie diese zu haben, gibt es auch eine echte Nachteil dieser Methode über die von Chris: Doing a schwer zurücksetzen (
git reset --hard
) berührt viel mehr Dateien. Wenn Sie beispielsweise Unity3D verwenden, werden Sie es zu schätzen wissen, dass weniger Dateien berührt werden.– Cregox
26. November 2013 um 12:35 Uhr
-
Ein weiterer Vorteil ist das
git merge --squash
führt angesichts von Verschiebungen/Löschvorgängen/Umbenennungen weniger wahrscheinlich zu Merge-Konflikten als Rebasing, insbesondere wenn Sie von einem lokalen Zweig mergen. (Haftungsausschluss: basiert auf nur einer Erfahrung, korrigiert mich, wenn dies im Allgemeinen nicht zutrifft!)– Cheezmeister
27. Februar 2014 um 22:21 Uhr
-
Ich bin immer sehr zurückhaltend, wenn es um Hard-Resets geht – ich würde stattdessen ein temporales Tag verwenden
HEAD@{1}
Nur um auf der sicheren Seite zu sein, zB wenn Ihr Arbeitsablauf für eine Stunde durch einen Stromausfall usw. unterbrochen wird.– Tobias Kienzler
11. August 2014 um 12:18 Uhr
-
@BT: Dein Commit zerstört? 🙁 Ich bin mir nicht sicher, was du damit meinst. Alles, was du festgeschrieben hast, kannst du leicht aus dem Reflog von git wiederherstellen. Wenn du nicht festgeschriebene Arbeit hattest, aber die Dateien bereitgestellt wurden, solltest du immer noch in der Lage sein, sie zu bekommen ihren Inhalt zurück, obwohl das mehr Arbeit sein wird. Wenn Ihre Arbeit nicht einmal inszeniert war, befürchte ich, dass da wenig getan werden kann; deshalb lautet die Antwort gleich vorweg: “Überprüfen Sie zuerst, ob der Git-Status sauber ist (da git reset –hard inszenierte und nicht inszenierte Änderungen wegwirft)”.
– Mark Longair
22. Mai 2016 um 9:55 Uhr
Ich empfehle zu vermeiden git reset
wenn möglich – besonders für Git-Neulinge. Es sei denn, Sie müssen wirklich einen Prozess basierend auf a automatisieren Nummer von Commits gibt es einen weniger exotischen Weg…
- Legen Sie die zu quetschenden Commits in einen funktionierenden Zweig (falls dies noch nicht geschehen ist) – verwenden Sie dafür gitk
- Überprüfen Sie den Ziel-Zweig (z. B. ‘master’)
git merge --squash (working branch name)
git commit
Die Commit-Nachricht wird basierend auf dem Squash vorab ausgefüllt.
-
Dies ist die sicherste Methode: kein Reset soft/hard (!!), oder Reflog verwendet!
– TeChn4K
30. November 2016 um 14:08 Uhr
-
Es wäre großartig, wenn Sie (1) erweitern würden.
– Adam
11. April 2017 um 14:16 Uhr
-
@Adam: Grundsätzlich bedeutet dies, die GUI-Oberfläche von zu verwenden
gitk
um die Codezeile zu beschriften, die Sie quetschen, und auch die Basis, auf die gequetscht werden soll. Im Normalfall sind diese beiden Labels bereits vorhanden, so dass Schritt (1) übersprungen werden kann.– Brent Bradburn
11. April 2017 um 21:48 Uhr
-
Beachten Sie, dass diese Methode den funktionierenden Zweig nicht als vollständig zusammengeführt markiert, sodass das Löschen erzwungen werden muss, um ihn zu entfernen. 🙁
– Kyrstellaine
13. April 2017 um 20:17 Uhr
-
Für (1) habe ich gefunden
git branch your-feature && git reset --hard HEAD~N
der bequemste Weg. Es ist jedoch erneut ein Git-Reset erforderlich, was diese Antwort zu vermeiden versuchte.– eis
30. Mai 2017 um 17:01 Uhr
Muya_
Dank an diesen praktischen Blogbeitrag Ich habe festgestellt, dass Sie diesen Befehl verwenden können, um die letzten 3 Commits zu quetschen:
git rebase -i HEAD~3
Dies ist praktisch, da es auch dann funktioniert, wenn Sie sich in einer lokalen Filiale ohne Tracking-Informationen/Remote-Repo befinden.
Der Befehl öffnet den interaktiven Rebase-Editor, mit dem Sie dann ganz normal neu ordnen, squashen, neu formulieren usw. können.
Verwenden des interaktiven Rebase-Editors:
Der interaktive Rebase-Editor zeigt die letzten drei Commits an. Diese Einschränkung wurde bestimmt durch HEAD~3
beim Ausführen des Befehls git rebase -i HEAD~3
.
Das letzte Commit, HEAD
wird zuerst in Zeile 1 angezeigt. Die Zeilen beginnend mit a #
sind Kommentare/Dokumentation.
Die angezeigte Dokumentation ist ziemlich klar. In jeder Zeile können Sie den Befehl ändern pick
zu einem Befehl Ihrer Wahl.
Ich bevorzuge den Befehl fixup
da dies die Änderungen des Commits in den Commit in der obigen Zeile “quetscht” und die Nachricht des Commits verwirft.
Wie der Commit auf Zeile 1 steht HEAD
in den meisten Fällen würden Sie dies so belassen pick
. Sie können nicht verwenden squash
oder fixup
da es keinen anderen Commit gibt, in den der Commit gequetscht werden könnte.
Sie können auch die Reihenfolge der Commits ändern. Auf diese Weise können Sie Commits, die nicht chronologisch benachbart sind, squashen oder korrigieren.
Ein praktisches Alltagsbeispiel
Ich habe kürzlich ein neues Feature festgeschrieben. Seitdem habe ich zwei Fehlerbehebungen vorgenommen. Aber jetzt habe ich einen Fehler (oder vielleicht auch nur einen Rechtschreibfehler) in dem neuen Feature entdeckt, das ich übernommen habe. Wie nervig! Ich möchte nicht, dass ein neues Commit meinen Commit-Verlauf verschmutzt!
Das erste, was ich tue, ist, den Fehler zu beheben und einen neuen Commit mit dem Kommentar zu machen squash this into my new feature!
.
Ich laufe dann git log
oder gitk
und erhalten Sie den Commit-SHA der neuen Funktion (in diesem Fall 1ff9460
).
Als nächstes rufe ich den interaktiven Rebase-Editor mit auf git rebase -i 1ff9460~
. Das ~
nach dem Commit weist SHA den Editor an, diesen Commit in den Editor aufzunehmen.
Als nächstes verschiebe ich den Commit, der den Fix enthält (fe7f1e0
) unter dem Feature-Commit und ändern pick
zu fixup
.
Beim Schließen des Editors wird der Fix in den Feature-Commit gequetscht und mein Commit-Verlauf sieht schön und sauber aus!
Dies funktioniert gut, wenn alle Commits lokal sind, aber wenn Sie versuchen, Commits zu ändern, die bereits auf die Remote übertragen wurden, können Sie wirklich Probleme für andere Entwickler verursachen, die denselben Zweig ausgecheckt haben!
-
Dies ist die sicherste Methode: kein Reset soft/hard (!!), oder Reflog verwendet!
– TeChn4K
30. November 2016 um 14:08 Uhr
-
Es wäre großartig, wenn Sie (1) erweitern würden.
– Adam
11. April 2017 um 14:16 Uhr
-
@Adam: Grundsätzlich bedeutet dies, die GUI-Oberfläche von zu verwenden
gitk
um die Codezeile zu beschriften, die Sie quetschen, und auch die Basis, auf die gequetscht werden soll. Im Normalfall sind diese beiden Labels bereits vorhanden, so dass Schritt (1) übersprungen werden kann.– Brent Bradburn
11. April 2017 um 21:48 Uhr
-
Beachten Sie, dass diese Methode den funktionierenden Zweig nicht als vollständig zusammengeführt markiert, sodass das Löschen erzwungen werden muss, um ihn zu entfernen. 🙁
– Kyrstellaine
13. April 2017 um 20:17 Uhr
-
Für (1) habe ich gefunden
git branch your-feature && git reset --hard HEAD~N
der bequemste Weg. Es ist jedoch erneut ein Git-Reset erforderlich, was diese Antwort zu vermeiden versuchte.– eis
30. Mai 2017 um 17:01 Uhr
2020 einfach Lösung ohne Rebase:
git reset --soft HEAD~2
git commit -m "new commit message"
git push -f
2 bedeutet, dass die letzten beiden Commits gequetscht werden. Sie können es durch eine beliebige Zahl ersetzen
-
Diese Lösung sollte nicht gefördert werden. Verwendung der
-f (force)
Möglichkeit einpush
ist eine gefährliche Praxis, besonders wenn Sie auf ein gemeinsam genutztes Repo (dh öffentliche Geschichte) pushen, das den Mitwirkenden das Leben schwer macht– FXQuantTrader
17. November 2020 um 5:09 Uhr
-
Wenn das Ziel darin besteht, dieses neue Commit als Teil einer laufenden PR zum Master hinzuzufügen, könnten Sie verwenden
git reset --soft $(git merge-base feature master)
und danngit commit
.– Karl Pokus
15. Februar 2021 um 8:42 Uhr
-
@FXQuantTrader: Wenn alle forcieren, ist das Gegenteil der Fall. Fast immer muss mitgedrückt werden
--force
. Auf diese Weise können Sie sich gut mit dem Rest des Teams und verschiedenen entfernten Standorten abstimmen, da Sie wissen, was vor sich geht. Außerdem wissen Sie, welcher Teil der Geschichte sich bereits stabilisiert hat. Das muss man nicht verbergen.– hakre
30. März 2021 um 23:05 Uhr
-
Ich würde argumentieren, dass mit schieben
force
sollte eigentlich sein ermutigte mit sehr gut kommunizierten Auswirkungen dieses Ansatzes –– Force-Pushing geht Hand in Hand mit Rebase und Synchronisierung der Arbeit, daher ist es meiner bescheidenen Meinung nach besser, dass mehr Menschen über die Auswirkungen dieser Aktion Bescheid wissen, als dass es sich um einen exoterischen Befehl handelt dass die Leute Angst haben, es zu benutzen.– Matheus Felipe
13. April 2021 um 23:16 Uhr
-
Stimmen Sie Matheus zu, das Erzwingen von Pushing zum Feature-Zweige ist in Ordnung und sollte durch Rebasing gefördert werden. Das direkte Pushen auf die Hauptleitung sollte sowieso immer eingeschränkt werden.
– Sich beeilen
18. Dezember 2021 um 21:26 Uhr
Siehe auch: Git – Kombinieren mehrerer Commits vor dem Pushen.
– Benutzer456814
6. Juni 2014 um 8:07 Uhr
Informationen zum Squashing bis zum ersten Commit finden Sie unter http://stackoverflow.com/questions/1657017/…
– Gulasch
6. März 2016 um 13:26 Uhr
Nach dem Squash muss man Push erzwingen. stackoverflow.com/questions/10298291/…
– vikramvi
14. Juli 2016 um 13:04 Uhr
Zusätzlich zu den geposteten Antworten können GUI-Clients dies problemlos tun. Ich kann Dutzende von Commits in GitKraken mit nur vier Klicks quetschen.
– Aaron Franke
14. Januar 2019 um 12:56 Uhr