Usuń stare zatwierdzenia git

88

Jestem bardzo nowy w git i zastanawiałem się, czy coś takiego jest możliwe?

>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.

czy to możliwe?

Josh
źródło

Odpowiedzi:

63

Jest to możliwe dzięki git rebase. Spróbuj wykonać następujące czynności

git rebase -i HEAD~4

a następnie postępuj zgodnie z interaktywnymi instrukcjami w swoim edytorze. W pierwszym kroku „zgniatasz” commity. Powinien wyglądać mniej więcej tak:

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

W drugim kroku możesz edytować komunikaty dotyczące zmian.

Deve
źródło
25
Czy nie chodzi raczej o usuwanie zatwierdzeń niż ich zgniatanie?
Richard,
3
@Stony: Cóż, prawdopodobnie mógłbyś je również usunąć. Ale z komentarzy do zatwierdzenia w OP („Spieprzyć” i „Naprawiono schrzanić”) założyłem, że jeden cofa drugi i że równie dobrze możesz po prostu zgnieść te dwa.
Deve
85

Jeśli naprawdę chcesz je usunąć (wymazując je z historii, nigdy więcej ich nie widać), możesz

uruchom rebase:

git rebase -i HEAD~4

a następnie po prostu usuń (lub zakomentuj) wiersze odpowiadające zatwierdzeniom, które chcesz usunąć, na przykład:

pick 2f05aba ... #will be preserved
#pick 3371cec ... #will be deleted
#pick daed25c ... #will be deleted
pick e2b2a84 ... #will be preserved
Shathur
źródło
2
Jestem nowy na githubie, jak wypychasz zmiany po tym (kiedy klikam Synchronizuj, po prostu przywraca to, co zrobiłem). Myślę, że udało mi się to: git push origin HEAD --force
Nicolas Thery
@NicolasThery you don't. Dlatego git push odmawia pracy bez --force, ponieważ piszesz historię od nowa i zepsujesz repozytoria innych ludzi. Jeśli już pchnąłeś, jedyną opcją jest wykonanie git revert. Co, kiedy o tym myślisz, jest rozsądne, ponieważ gdybyś wyciągnął kod kogoś innego, nie chciałbyś, aby mógł on usunąć twoje stare zmiany bez jakiejś historii, prawda?
Angry Dan
Zakładam, że to po prostu działa w bieżącym repozytorium Git i nie zmienia niczego nadrzędnego / żadnego innego węzła Git?
Alexander Mills,
2
@AlexanderMills To nie zmienia niczego w górę strumienia, o ile go nie naciskasz (a jeśli to zrobisz, musisz dodać flagę --force, jak powiedział Angry Dan).
Shathur
dlub dropjest poleceniem usunięcia zatwierdzeń z historii.
Opuszczony
5

Aby całkowicie usunąć zmiany, jest teraz nowa opcja dropdla rebase interaktywnych git. Pierwszy bieg:

git rebase -i HEAD~4

Następnie zastępuje picksię dropdla zatwierdzenia (y), które spadły:

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

To działało w Fedorze z następującą wersją:

$ git version
git version 2.21.0
russoue
źródło
2

Squash jest przydatny, gdy chcesz wygenerować listę połączonych zatwierdzeń pod jednym hashem, ale jeśli chcesz wziąć trzy oddzielne zatwierdzenia i uzyskać ostateczne wyjście, które wygląda tak, jakby było to pojedyncze zatwierdzenie, polecam 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

Więcej informacji można znaleźć na liście poleceń w interaktywnym interfejsie użytkownika rebase.

Opuszczony wózek
źródło