Jak cofnąć zatwierdzenie ostatniego nieprzesuniętego zatwierdzenia git bez utraty zmian

539

Czy istnieje sposób, aby przywrócić popełnić tak, że moja kopia lokalna utrzymuje zmiany dokonane w które popełniają, ale stają się one Niezaangażowane zmiany w mojej kopii roboczej? Wycofanie zatwierdzenia przenosi cię do poprzedniego zatwierdzenia - chcę zachować wprowadzone zmiany, ale zatwierdziłem je w niewłaściwej gałęzi.

Nie zostało to popchnięte, tylko popełnione.

Mr. Boy
źródło
6
git reset --softi git reset --mixedoba robią to (nieco inaczej), patrz git-reset
torek

Odpowiedzi:

930

Można to zrobić na wiele sposobów, na przykład:

w przypadku, gdy jeszcze nie opublikowałeś zatwierdzenia publicznie:

git reset HEAD~1 --soft   

To wszystko, zmiany zatwierdzenia będą w twoim katalogu roboczym, a LAST zatwierdzenia zostaną usunięte z twojego aktualnego oddziału. Zobacz git reset man


W przypadku, gdy nie pchnięcie publicznie (na oddział o nazwie „Master”):

git checkout -b MyCommit //save your commit in a separate branch just in case (so you don't have to dig it from reflog in case you screw up :) )

cofnij zatwierdzenie normalnie i wciśnij

git checkout master
git revert a8172f36 #hash of the commit you want to destroy
# this introduces a new commit (say, it's hash is 86b48ba) which removes changes, introduced in the commit in question (but those changes are still visible in the history)
git push origin master

teraz, jeśli chcesz mieć te zmiany podczas lokalnych zmian w kopii roboczej („aby lokalna kopia zachowała zmiany dokonane w tym zatwierdzeniu”) - po prostu przywróć cofnij zatwierdzenie z --no-commitopcją:

git revert --no-commit 86b48ba (hash of the revert commit).

Stworzyłem mały przykład: https://github.com/Isantipov/git-revert/commits/master

Isantipov
źródło
5
dziękuję bardzo, w moim przypadku miałem dwa zatwierdzenia, które chciałem anulować, a uruchomienie „git reset HEAD ~ 1 - soft” dwa razy z rzędu doprowadziło mnie do tego, gdzie powinienem być.
Geoff Gunter
2
aby dodać trochę jasności, jeśli nie używasz CLI, pierwsze resetwspomniane polecenie mówi „miękko” zresetować do 1 obrotu przed głową, co zachowuje wszystkie lokalne zmiany. nie było to od razu widoczne dla mnie w SourceTree. po prostu upewnij się, że miękko resetujesz się do poprzedniej wersji, a nie do wersji, którą próbujesz zresetować
Jon B
1
Wypróbowałem podejście „już wypchnięte” i nie działa ono dla mnie z git 2.14.1: mówi "Already up to date"podczas scalania.
Fabio A.
1
@FabioA. , Zaktualizowałem odpowiedź działającą wersją. Dzięki za zauważenie tego!
Isantipov
1
To nie działa Pominąłem resetowanie i zatwierdzanie, a git cofnął się i wypchnął ... teraz może zmiany nie są jeszcze pewne ... na szczęście utworzyłem kopię zapasową w prosty sposób, mam nadzieję, że nadal będzie działać;) w przeciwnym razie można skopiować zmiany z tego .
Skybuck Flying
13

Jeśli wprowadziłeś zmiany, możesz to undozrobić i przenieść pliki z powrotem na scenę bez korzystania z innej gałęzi.

git show HEAD > patch
git revert HEAD
git apply patch

Stworzy plik łatki, który zawiera ostatnie zmiany w gałęzi. Następnie przywraca zmiany. Na koniec zastosuj pliki łatek do działającego drzewa.

Aminadav Glickshtein
źródło
możesz rm patchteż chcieć
Max Coplan
6

W przypadku: „Nie zostało to popchnięte, tylko popełnione ”. - jeśli używasz IntelliJ (lub innego JetBrains IDE) i nie wprowadziłeś jeszcze zmian, możesz to zrobić dalej.

  1. Przejdź do okna Kontrola wersji ( Alt + 9 / Command + 9 ) - zakładka „Log”.
  2. Kliknij zatwierdzenie prawym przyciskiem myszy przed ostatnim.
  3. Zresetuj bieżącą gałąź tutaj
  4. wybierz Soft (!!!)
  5. naciśnij przycisk Resetuj w dolnej części okna dialogowego.

Gotowy.

Spowoduje to „anulowanie” zmian i przywrócenie statusu git do punktu przed ostatnim zatwierdzeniem lokalnym. Nie stracisz żadnych dokonanych zmian.

Eduard Streltsov
źródło
2
Uwielbiam uczyć się JetBrains, dzięki! Jest to równoważne z git reset --soft "HEAD^"Windows, btw. :)
payne
3

U mnie dzieje się to głównie wtedy, gdy pcham zmiany do niewłaściwej gałęzi i uzmysławiam sobie później. I śledzenie działa przez większość czasu.

git revert commit-hash
git push

git checkout my-other-branch
git revert revert-commit-hash
git push
  1. cofnij zatwierdzenie
  2. (utwórz i) kasy inne oddziały
  3. cofnij cofnij
Mubashar
źródło
1
Przetestowałem to. Twoje podejście działa również, jeśli nie naciskałeś na pilota. $ git revert <komenda- skrót> ... następnie sprawdź inną gałąź, a następnie wpisz $ git revert <komenda- skrót> (bez wypychania). Dziękujemy za podzielenie się tym prostym podejściem !!
Natalie Cottrill,
1

Pamiętaj, aby wykonać kopię zapasową zmian przed uruchomieniem tych poleceń w osobnym folderze

git kasa nazwa_gałęzi

Kasa w oddziale

git merge --abort

Przerwij scalanie

status git

Sprawdź status kodu po przerwaniu scalania

git reset --hard origin / nazwa_gałęzi

polecenie to zresetuje zmiany i wyrówna kod z kodem nazwa_gałęzi (gałąź).

Mohit Singh
źródło
1

2020 prosty sposób:

git reset <commit_hash>

Zatwierdź skrót ostatniego zatwierdzenia, które chcesz zachować.

Xys
źródło