Entfernen Sie alte Git-Commits

88

Ich bin sehr neu in Git und habe mich gefragt, ob so etwas möglich ist?

>git log --pretty=oneline --abbrev-commit
2f05aba Added new feature
3371cec Fixed screw up    <-- I want to remove this
daed25c Screw up          <-- and remove this.
e2b2a84 First.                So it's like they never happend.

Ist das möglich?

Josh
quelle

Antworten:

63

Dies ist möglich mit git rebase. Versuche Folgendes

git rebase -i HEAD~4

Befolgen Sie anschließend die interaktiven Anweisungen in Ihrem Editor. Im ersten Schritt "quetschen" Sie die Commits. Es sollte ungefähr so ​​aussehen:

pick 2f05aba ... will be preserved
squash 3371cec ... will be squashed with daed25c
squash daed25c ... will be squashed with e2b2a84
pick e2b2a84 .. will contain this and 3371cec and daed25c

Im zweiten Schritt können Sie die Commit-Nachrichten bearbeiten.

Deve
quelle
25
Geht es nicht darum, die Commits zu löschen, anstatt sie zu quetschen?
Richard
3
@Stony: Nun, du könntest sie wahrscheinlich auch löschen. Aber aus den Commit-Kommentaren im OP ("Screw up" und "Fixed Screw up") ging ich davon aus, dass der eine den anderen rückgängig macht und dass Sie die beiden auch einfach zerquetschen könnten.
Deve
85

Wenn Sie sie wirklich löschen möchten (sie aus dem Verlauf löschen, nie mehr gesehen werden), können Sie dies tun

Rebase ausführen:

git rebase -i HEAD~4

und dann löschen (oder kommentieren) Sie einfach die Zeilen, die den Commits entsprechen, die Sie löschen möchten, wie folgt:

pick 2f05aba ... #will be preserved
#pick 3371cec ... #will be deleted
#pick daed25c ... #will be deleted
pick e2b2a84 ... #will be preserved
Shathur
quelle
2
Ich bin neu in Github. Wie können Sie die Änderungen danach verschieben (wenn ich auf "Synchronisieren" klicke, wird nur das zurückgesetzt, was ich getan habe). Ich glaube, ich habe es verstanden: git push origin HEAD --force
Nicolas Thery
@NicolasThery du nicht. Aus diesem Grund weigert sich git push, ohne --force zu arbeiten, weil Sie die Geschichte neu schreiben und die Repositories anderer Leute beschädigen. Wenn Sie bereits gepusht haben, besteht Ihre einzige Option darin, a git revert. Was, wenn Sie darüber nachdenken, sinnvoll ist, denn wenn Sie den Code eines anderen ziehen, möchten Sie nicht, dass dieser Ihre alten Commits ohne irgendeine Art von Geschichte löschen kann, oder?
Angry Dan
Ich gehe davon aus, dass dies im aktuellen Git-Repo einfach funktioniert und nichts Upstream / irgendeinen anderen Git-Knoten ändert.
Alexander Mills
2
@AlexanderMills Es ändert nichts stromaufwärts, solange Sie es nicht drücken (und wenn Sie dies tun, müssen Sie das Flag --force hinzufügen, wie Angry Dan sagte).
Shathur
doder dropist der Befehl zum Entfernen von Commits aus dem Verlauf.
Verlassener Wagen
5

Um Commits vollständig zu löschen, gibt es dropjetzt eine neue Option für interaktive Git-Rebases. Erster Lauf:

git rebase -i HEAD~4

Dann ersetzen Sie pickmit dropfür den Commit (s) fallen gelassen werden:

pick 2f05aba ... #will be preserved
drop 3371cec ... #will be dropped
drop daed25c ... #will be dropped
pick e2b2a84 ... #will be preserved

Dies funktionierte bei Fedora für mich mit der folgenden Version:

$ git version
git version 2.21.0
russoue
quelle
2

Squash ist nützlich, wenn Sie eine Liste zusammengeführter Commits unter einem einzelnen Hash erstellen möchten. Wenn Sie jedoch drei separate Commits ausführen und eine endgültige Ausgabe erhalten möchten, die aussieht, als wäre es ein einzelnes Commit, empfehle ich fixup

git rebase -i HEAD~4

pick 2f05aba ... will be preserved
fixup 3371cec ... will be merged with daed25c
fixup daed25c ... will be merged with e2b2a84
pick e2b2a84 .. will include 3371cec and daed25c, but only the commit message of e2b2a84

Weitere Informationen finden Sie in der Befehlsliste der interaktiven Rebase-Benutzeroberfläche.

Verlassener Wagen
quelle