1647 Stimmen

Wie kann man mehrere Git-Commits rückgängig machen?

Ich habe ein Git-Repository, das wie folgt aussieht:

A <- B <- C <- D <- HEAD

Ich möchte, dass der Kopf der Verzweigung auf A zeigt, d.h. ich möchte, dass B, C, D und HEAD verschwinden, und ich möchte, dass head ein Synonym für A ist.

Es klingt so, als ob ich entweder versuchen könnte, neu zu basen (trifft nicht zu, da ich zwischendurch Änderungen vorgenommen habe) oder zu revertieren. Aber wie kann ich mehrere Übertragungen rückgängig machen? Mache ich einen nach dem anderen rückgängig? Ist die Reihenfolge wichtig?

7voto

Dorian Punkte 20663

Keine davon funktionierte bei mir, also hatte ich drei Commits zum Zurücknehmen (die letzten drei Commits), was ich auch tat:

git revert HEAD
git revert HEAD~2
git revert HEAD~4
git rebase -i HEAD~3 # pick, squash, squash

Hat wunderbar funktioniert :)

7voto

nulll Punkte 1308

Meiner Meinung nach könnte das ein sehr einfacher und sauberer Weg sein:

zurück zu A

git checkout -f A

den Kopf des Meisters auf den aktuellen Stand bringen

git symbolic-ref HEAD refs/heads/master

speichern

git commit

5voto

Ian Punkte 246

Wahrscheinlich weniger elegant als andere Ansätze hier, aber ich habe immer get reset --hard HEAD~N um mehrere Übertragungen rückgängig zu machen, wobei N ist die Anzahl der Commits, die Sie zurückgehen wollen.

Wenn Sie die genaue Anzahl der Übertragungen nicht kennen, können Sie auch einfach Folgendes ausführen git reset --hard HEAD^ (die eine Übertragung zurückgeht) mehrmals, bis Sie den gewünschten Zustand erreicht haben.

3voto

ti7 Punkte 12361

Ich musste eine ganze Reihe von Commits rückgängig machen und dann erneut rückgängig machen, um einem Team dabei zu helfen, eine klare Pull-Anfrage zu stellen, ohne ihren Zielzweig (in den direkt committed wurde) mit Gewalt zu verschieben

# checkout the branch that should be targeted
git checkout $branch_target

# revert the commits in $branch_target to some $count where
#   $count is the number of commits to revert
#   cut is used to slice just the commit hash field from each line of output
#   xargs runs the command once for each line of input, reversing the commits!
git log --oneline -n $count | cut -d' ' -f1 | xargs git revert

# check out the branch which should be the source of the pull request
git checkout -b $branch_for_pull

# revert the revert commits
# $count is that same number of commits being reverted (again)
git log --oneline -n $count | cut -d' ' -f1 | xargs git revert

# push branches up and go off to create PR in whatever web UI
git push --set-upstream origin $branch_for_pull  # it's new!
git checkout $branch_target
git push  # if this branch wasn't pushed, just fix the issue locally instead..

Da dies alle Übertragungen von HEAD a git log -n $count in umgekehrter Reihenfolge, funktioniert es gut und sauber mit einer beliebigen Anzahl von Übertragungen

Ansicht von $branch_target in diesem Zustand

% git log --oneline origin/$branch_target
ffff006 (origin/$branch_target, $branch_target) Revert "first commit"
ffff005 Revert "second commit"
ffff004 Revert "third commit"
ffff003 third commit
ffff002 second commit
ffff001 first commit

Ansicht von $branch_for_pull in diesem Zustand

% git log --oneline origin/$branch_for_pull
ffff009 (origin/$branch_for_pull, $branch_for_pull) Revert "Revert "third commit""
ffff008 Revert "Revert "second commit""
ffff007 Revert "Revert "first commit""
ffff006 (origin/$branch_target, $branch_target) Revert "first commit"
ffff005 Revert "second commit"
ffff004 Revert "third commit"
ffff003 third commit
ffff002 second commit
ffff001 first commit

Wenn die Absicht war, N Zweige mit Changesets zu erstellen, diese aber alle in denselben Zweig übertragen wurden, können Sie immer noch alle zum Basis-Commit zurückkehren und dann nur die benötigten Reverts zurücknehmen, da die Changesets logisch geordnet sein sollten (versuchen Sie das 5x schnell zu sagen)

Mit einer Syntax wie HEAD~7..HEAD~5 kann bei der Beschreibung der Bereiche helfen, um die Umkehrzweige genau aufzuteilen

Hier würde es Sinn machen, wenn die letzten 7 Commits rückgängig gemacht werden ( git log -n 7 ), aber die Wiederherstellung von 5 mit in einem Zweig ( git log -n 5 ) und 2 dann die oberste 2 in einer anderen git log HEAD~12..HEAD~10 (12 ist 7 Übertragungen + 5 Übertragungen, wenn man davon ausgeht, dass der neue PR-Zweig entweder auf dem Zweig "davor" basiert oder das Ergebnis einer FF (nicht gequetschten) Zusammenführung des Zweigs "davor" mit dem ursprünglichen Zielzweig ist)

1voto

Nebulastic Punkte 7640

Ich wollte wirklich vermeiden, dass die Daten hart zurückgesetzt werden, und so kam ich auf diese Idee.

A -> B -> C -> D -> HEAD

Um zu A zurückzukehren (das sind 4 Schritte zurück):

git pull                  # Get latest changes
git reset --soft HEAD~4   # Set back 4 steps
git stash                 # Stash the reset
git pull                  # Go back to head
git stash pop             # Pop the reset 
git commit -m "Revert"    # Commit the changes

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X