Po prostu wykonałem w lokalnym repozytorium git cherry-pick SHA
bez żadnych konfliktów i problemów. Wtedy zdałem sobie sprawę, że nie chcę robić tego, co właśnie zrobiłem. Nigdzie tego nie pchałem.
Jak mogę usunąć tylko ten kilof?
Chciałbym wiedzieć, czy jest na to sposób:
- kiedy mam inne lokalne zmiany
- kiedy nie mam innych lokalnych zmian
Najlepiej z jednym poleceniem dla obu przypadków, jeśli to możliwe.
Aby cofnąć ostatnie zatwierdzenie, po prostu zrób
git reset --hard HEAD~
.Edycja : ta odpowiedź dotyczy wcześniejszej wersji pytania, w której nie wspomniano o zachowaniu lokalnych zmian; przyjęta odpowiedź Tima jest rzeczywiście poprawna. Dzięki qwertzguy za heads up.
źródło
HEAD
) są bardziej niezawodne: rozważ niefortunny przypadek, w którymhead
jest nazwa istniejącego odniesienia.Jeśli to możliwe, unikaj twardego resetu. Twardy reset to jedna z niewielu destrukcyjnych operacji w git. Na szczęście możesz cofnąć wybór bez resetowania i uniknąć niczego destrukcyjnego.
Zanotuj skrót wiśniowego wyboru, który chcesz cofnąć, powiedz, że tak
${bad_cherrypick}
. Zróbgit revert ${bad_cherrypick}
. Teraz zawartość twojego drzewa roboczego jest taka, jaka była przed twoim złym wyborem wiśni.Powtórz
git cherry-pick ${wanted_commit}
, a kiedy będziesz zadowolony z nowego wyboru, zróbgit rebase -i ${bad_cherrypick}~1
. Podczas rebase usuń oba${bad_cherrypick}
i odpowiadające im przywrócenia.Gałąź, nad którą pracujesz, będzie miała tylko dobry wybór. Brak konieczności resetowania!
źródło
git reflog
może przyjść ci na ratunek.Wpisz go w konsoli, a otrzymasz listę swojej historii git wraz z reprezentującym ją SHA-1.
Po prostu sprawdź dowolny SHA-1, do którego chcesz powrócić
Zanim odpowiemy, dodajmy trochę tła, wyjaśniając, co to jest
HEAD
.First of all what is HEAD?
HEAD
jest po prostu odniesieniem do aktualnego zatwierdzenia (ostatniego) w bieżącej gałęzi.W
HEAD
danym momencie może istnieć tylko jeden . (wyłączającgit worktree
)Zawartość
HEAD
jest przechowywana wewnątrz.git/HEAD
i zawiera 40 bajtów SHA-1 aktualnego zatwierdzenia.detached HEAD
Jeśli nie jesteś na najnowszym zatwierdzeniu - co oznacza, że
HEAD
wskazuje na wcześniejsze zatwierdzenie w historii, jego wywołaniedetached HEAD
.W linii poleceń będzie wyglądać następująco - SHA-1 zamiast nazwy gałęzi, ponieważ
HEAD
nie wskazuje końca bieżącej gałęziKilka opcji odzyskiwania po odłączonej GŁOWIE:
git checkout
Spowoduje to pobranie nowej gałęzi wskazującej na żądane zatwierdzenie.
To polecenie spowoduje pobranie do podanego zatwierdzenia.
W tym momencie możesz utworzyć gałąź i zacząć od tego momentu.
git reflog
Zawsze możesz też użyć
reflog
.git reflog
wyświetli każdą zmianę, która zaktualizowała,HEAD
a sprawdzenie żądanego wpisu reflog spowodujeHEAD
powrót do tego zatwierdzenia.Za każdym razem, gdy HEAD zostanie zmodyfikowany, pojawi się nowy wpis w
reflog
Spowoduje to powrót do pożądanego zobowiązania
git reset --hard <commit_id>
„Przenieś” swoją HEAD z powrotem do pożądanego zatwierdzenia.
# This will destroy any local modifications. # Don't do it if you have uncommitted work you want to keep. git reset --hard 0d1d7fc32 # Alternatively, if there's work to keep: git stash git reset --hard 0d1d7fc32 git stash pop # This saves the modifications, then reapplies that patch after resetting. # You could get merge conflicts if you've modified things which were # changed since the commit you reset to.
możesz również użyć
git rebase --no-autostash
.git revert <sha-1>
„Cofnij” podany zatwierdzenie lub zakres zatwierdzenia.
Polecenie reset "cofnie" wszelkie zmiany wprowadzone w danym zatwierdzeniu.
Nowe zatwierdzenie z cofniętą łatką zostanie zatwierdzone, podczas gdy oryginalne zatwierdzenie pozostanie również w historii.
# add new commit with the undo of the original one. # the <sha-1> can be any commit(s) or commit range git revert <sha-1>
Ten schemat ilustruje, które polecenie robi co.
Jak widać,
reset && checkout
zmodyfikuj plikHEAD
.źródło
git reset --hard
W obliczu tego samego problemu odkryłem, że jeśli popełniłeś i / lub odepchnąłeś się na odległość od swojego udanego wyboru i chcesz go usunąć, możesz znaleźć SHA wiśniowego wyboru, uruchamiając:
git log --graph --decorate --oneline
Następnie (po użyciu,
:wq
aby wyjść z dziennika) możesz usunąć kilof za pomocągit rebase -p --onto YOUR_SHA_HERE^ YOUR_SHA_HERE
gdzie
YOUR_SHA_HERE
równa się 40- lub skróconemu 7-znakowemu SHA zatwierdzonego wyboru.Na początku nie będziesz w stanie przesłać zmian, ponieważ zdalne repozytorium i lokalne repozytorium będą miały różne historie zatwierdzania. Możesz zmusić lokalne zatwierdzenia do zastąpienia tego, co jest na twoim pilocie, używając
git push --force origin YOUR_REPO_NAME
(Zaadaptowałem to rozwiązanie od Setha Robertsona : zobacz „Usuwanie całego zatwierdzenia”).
źródło
Jedno polecenie i nie używa
git reset
polecenia niszczącego :GIT_SEQUENCE_EDITOR="sed -i 's/pick/d/'" git rebase -i HEAD~ --autostash
Po prostu odrzuca zatwierdzenie, przywracając dokładnie stan sprzed wyboru, nawet jeśli nastąpiły lokalne zmiany.
źródło
git reset HEAD^
robi?git reset
cofa zatwierdzenie bez porzucania jakichkolwiek zmian. Polecam przeczytanie git-scm.com/docs/git-reset . Pytanie od OP to cofnięcie najlepszego wyboru. Wypróbuj oba polecenia, moje przywrócą ci dokładnie taki stan, w jakim byłeś przed wybiciem.git reset
zepsuje twoje drzewo robocze, ponieważ pozostawi wybrane zmiany i staną się one nie do odróżnienia od wcześniej istniejących lokalnych zmian.reset --hard
. Nie pozostawia żadnych zmiangit reset --hard
to destrukcyjne polecenie, które usunie również niepowiązane zmiany lokalne i zrobi to w nieodwracalny sposób! Więc nie o to prosił PO.sed
robi to polecenie, czym różni się od wykonywania go ręcznie i co--autostash
robi.