Usuń ostatnie zatwierdzenie w programie Bitbucket

105

Popełniłem błąd i nie wiem, jak usunąć mój ostatni push w repozytorium. Pobieram najnowsze aktualizacje aplikacji, ale występują konflikty i wysyłam ją do repozytorium.

Jak usunąć moje ostatnie zatwierdzenie? Albo jak to naprawić?

Katarzyna
źródło

Odpowiedzi:

104

Po pierwsze, jeśli pracujesz z innymi osobami na tym samym repozytorium kodu, nie powinieneś usuwać zatwierdzenia, ponieważ wymuszenie aktualizacji repozytorium pozostawi lokalne repozytoria Twoich współpracowników w nielegalnym stanie (np. dokonane zatwierdzenia po usuniętym, te zatwierdzenia będą nieprawidłowe, ponieważ były oparte na nieistniejącym zatwierdzeniu).

Powiedział, że możesz cofnąć zatwierdzenie. Ta procedura jest wykonywana inaczej (różne polecenia) w zależności od używanego CVS:

Na git :

git revert <commit>

Na mercurial :

hg backout <REV>

EDYCJA: Operacja przywracania tworzy nowe zatwierdzenie, które robi odwrotnie niż przywrócone zatwierdzenie (np. Jeśli oryginalne zatwierdzenie dodało linię, zatwierdzenie cofnięcia usuwa tę linię), skutecznie usuwając zmiany w niepożądanym zatwierdzeniu bez przepisywania historii repozytorium.

asermax
źródło
Dzięki za informację. I znam konsekwencje, jeśli usunę zatwierdzenie, po prostu nie wiem, jak cofnąć swoje działanie, ponieważ po raz pierwszy popełniłem błąd. Muszę cofnąć zatwierdzenie, ponieważ system już działa. Tylko nas dwoje pracuje z tym repozytorium.
catherine
git backout <REV>? Albo hg backout <REV>:?
Armando Pérez Marqués
Ale co, jeśli zatwierdzenia dodane po tym, który ma zostać przywrócony, spowodowały zmiany w usuwanej linii?
rahs
@RahulSaha, ponieważ to, co robisz, to po prostu próba scalenia commit w gałęzi, jestem prawie pewien, że da ci to konflikt scalania, który będziesz musiał rozwiązać.
asermax
99

Jeśli nie pracujesz z innymi (lub z przyjemnością sprawiasz im znaczną irytację) , możesz usunąć commity z gałęzi bitbucket.

Jeśli próbujesz zmienić gałąź inną niż główna:

git reset HEAD^               # remove the last commit from the branch history
git push origin :branch_name  # delete the branch from bitbucket
git push origin branch_name   # push the branch back up again, without the last commit

jeśli próbujesz zmienić gałąź główną

Generalnie w gicie gałąź główna nie jest wyjątkowa - to tylko konwencja. Jednak bitbucket, github i podobne strony zwykle wymagają, aby istniała główna gałąź (prawdopodobnie dlatego, że jest to łatwiejsze niż pisanie większej ilości kodu do obsługi zdarzenia, w którym repozytorium nie ma gałęzi - nie jestem pewien). Musisz więc utworzyć nową gałąź i ustawić ją jako główną:

# on master:
git checkout -b master_temp  
git reset HEAD^              # undo the bad commit on master_temp
git push origin master_temp  # push the new master to Bitbucket

W Bitbucket przejdź do ustawień repozytorium i zmień „gałąź główną” na master_temp(na Github zmień „gałąź domyślną”).

git push origin :master     # delete the original master branch from Bitbucket
git checkout master
git reset master_temp       # reset master to master_temp (removing the bad commit)
git push origin master      # re-upload master to bitbucket

Teraz przejdź do Bitbucket i powinieneś zobaczyć żądaną historię. Możesz teraz przejść do strony ustawień i zmienić gałąź główną z powrotem na master.

Ten proces będzie również działał z innymi zmianami historii (np git filter-branch.). Musisz tylko upewnić się, że zresetowałeś do odpowiednich zatwierdzeń, zanim nowa historia oddzieli się od starej.

edycja : najwyraźniej nie musisz przechodzić do tych wszystkich kłopotów na githubie, ponieważ możesz wymusić reset gałęzi .

Radzenie sobie z zirytowanymi współpracownikami

Następnym razem, gdy ktoś spróbuje pobrać z twojego repozytorium (jeśli już ściągnął złe zatwierdzenie), ściąganie zakończy się niepowodzeniem. Będą musieli ręcznie zresetować do zatwierdzenia przed zmianą historii, a następnie ponownie pociągnąć.

git reset HEAD^
git pull

Jeśli wyciągnęli złe zatwierdzenie i popełnili po nim , to będą musieli zresetować, a następnie git cherry-pickdobre zatwierdzenia, które chcą utworzyć, skutecznie odtwarzając całą gałąź bez złego zatwierdzenia.

Jeśli nigdy nie popełnili złego zobowiązania, cały ten proces nie wpłynie na nich i będą mogli zrobić to normalnie.

naught101
źródło
1
Dla bardziej komfortowych w korzystaniu z SourceTree: 1) Aby zmienić główną gałąź w interfejsie WWW dla BitBucket, spójrz na Ustawienia repozytorium. 2) Aby usunąć oddział w interfejsie internetowym, spójrz na stronę Oddziały. 3) Zresetuj lokalne repozytorium zgodnie z powyższym. 4) Wprowadź zmiany lokalne, aby odtworzyć te gałęzie.
Richard Le Mesurier
2
Jako ktoś, kto przypadkowo zepchnął tajemnicę, bardzo doceniam dokładność tej odpowiedzi. Dzięki!
Torque
48

możesz zresetować, HEAD^a następnie wymusić wciśnięcie.

git reset HEAD^
git push -u origin master --force

Spowoduje to usunięcie ostatniego zatwierdzenia i zostanie odzwierciedlone w bitbuckecie jako usunięte zatwierdzenie, ale nadal pozostanie na ich serwerze.

Shubanker
źródło
Github pozwoli na to, ale w chwili pisania tego tekstu Bitbucket nie zezwala na użycie siły.
JamesQMurphy
4
w rzeczywistości bitbucket obsługuje wypychanie siłowe, tylko różnica zamiast całkowicie usuwać nieprzesłuchane zatwierdzenia oznacza je jako usunięte.
Shubanker
Zalecanym sposobem z bitbucket jest użycie przywracania. Ale myślę, że w moim przypadku jest to bardziej odpowiednie. Ponieważ tylko ja go używam i wydaje się bardziej czysty niż używanie przywracania. Dzięki.
nafsaka
1
Tak, to nadal działa na Bitbucket. Właśnie zaoszczędziłeś mi dużo czasu! Zrobiłem commit / push z mojego Eclipse i wmieszałem się w inny projekt, który miałem. Częściowo z powodu złej praktyki z mojej strony, używając zarówno wiersza poleceń, jak i wbudowanego zaćmienia do pracy z git.
DarkCygnus
genialne lub łatwiejsze: zresetuj bieżącą gałąź do tego zatwierdzenia, a następnie użyj tego wymuszenia na serwerze, aby naprawić mój problem
Anthony Kal
5

Oto proste podejście w maksymalnie 4 krokach:

0 - Poinformuj zespół, że zamierzasz naprawić repozytorium

Połącz się z zespołem i poinformuj ich o nadchodzących zmianach.

1 - Usuń ostatnie zatwierdzenie

Zakładając, że Twoja gałąź docelowa to master:

$ git checkout master              # move to the target branch
$ git reset --hard HEAD^           # remove the last commit
$ git push -f                      # push to fix the remote

W tym momencie jesteś skończony, jeśli pracujesz sam.

2 - Napraw lokalne repozytoria swojego kolegi z drużyny

Na kolegach z drużyny:

$ git checkout master              # move to the target branch
$ git fetch                        # update the local references but do not merge  
$ git reset --hard origin/master   # match the newly fetched remote state

Jeśli twój kolega z drużyny nie miał nowych zatwierdzeń, w tym momencie jesteś skończony i powinieneś być zsynchronizowany.

3 - Przywracanie utraconych zatwierdzeń

Powiedzmy, że kolega z zespołu ma nowe i nieopublikowane zatwierdzenie, które zostało utracone w tym procesie.

$ git reflog                       # find the new commit hash
$ git cherry-pick <commit_hash>

Zrób to dla tylu zatwierdzeń, ile potrzeba.

Wielokrotnie z powodzeniem stosowałem to podejście. Zapewnienie synchronizacji wszystkiego wymaga pracy zespołowej.

rbento
źródło
3

W przeszłości miałem problemy z przywracaniem git (głównie dlatego, że nie jestem do końca pewien, jak to działa). Miałem problemy z przywróceniem z powodu problemów ze scalaniem.

Moje proste rozwiązanie jest takie.

Krok 1.

 git clone <your repos URL> .

Twój projekt w innym folderze, a następnie:

Krok 2.

git reset --hard <the commit you wanna go to>

następnie Krok 3.

w swoim najnowszym (i głównym) katalogu projektu (tym, który ma problematyczne ostatnie zatwierdzenie) wklej pliki z kroku 2

Krok 4.

git commit -m "Fixing the previous messy commit" 

Krok 5.

Cieszyć się

SudoPlz
źródło
1
Cięcie i wklejanie jest naprawdę nieuporządkowane. Poza tym nie rozwiązałoby to problemu z pytania.
Daniel Lee
1
git revertjest proste: tworzy nowe zatwierdzenie, które odwraca zmiany w poprzednim zatwierdzeniu (lub wielu zatwierdzeniach). Nie usuwa zatwierdzeń, więc nie ma znaczenia dla tego pytania. Ponadto krok klonowania tutaj nie jest naprawdę konieczny.
naught101
1
Przywrócenie Git jest takim samym mechanizmem jak powyżej.
nafsaka
2

Jak powiedzieli inni, zwykle chcesz użyć hg backoutlub git revert. Jednak czasami naprawdę chcesz pozbyć się zatwierdzenia.

Najpierw będziesz chciał przejść do ustawień repozytorium. Kliknij Strip commitsłącze.

Usuń link zatwierdzeń w ustawieniach Bitbucket

Wprowadź identyfikator zestawu zmian, który chcesz zniszczyć, i kliknij Preview strip. Dzięki temu zobaczysz, jakie szkody zamierzasz wyrządzić, zanim to zrobisz. Następnie kliknij, Confirma Twoje zatwierdzenie nie jest już historią. Upewnij się, że powiedziałeś wszystkim swoim współpracownikom, co zrobiłeś, aby przypadkowo nie odepchnęli naruszającego commita z powrotem.

nmichaels
źródło
Która to wersja i jakie uprawnienia są wymagane? Wygląda inaczej w wersji 6.4.3, na którą patrzę, a tego elementu nie ma. Ja jestem repozytorium administratora.
Raphael
1

Po zatwierdzeniu zmian nie będzie można ich usunąć. ponieważ podstawową naturą commita nie jest usuwanie.

Co możesz zrobić (łatwa i bezpieczna metoda),

Interaktywny Rebase:

1) git rebase -i HEAD~2 # pokaże ostatnie 2 zatwierdzenia

2) Twoje zatwierdzenie wyświetli się w następujący sposób, Ostatnie pojawi się na dole strony LILO (ostatnie w Last Out)

wprowadź opis obrazu tutaj

Całkowicie usuń ostatni wiersz zatwierdzenia

3) zapisz go przez ctrl+XlubESC:wq

teraz twoja gałąź zostanie zaktualizowana bez twojego ostatniego zatwierdzenia.

Mohideen bin Mohammed
źródło
1

Możesz napisać polecenie również dla Bitbucket, jak wspomniał Dustin :

git push -f origin HEAD^:master

Uwaga: zamiast mastera możesz użyć dowolnej gałęzi. I usuwa po prostu wciśnij Bitbucket.

Aby usunąć ostatnie zatwierdzenie lokalnie w git, użyj:

git reset --hard HEAD~1
invzbl3
źródło
0

W tej chwili bitbucket w chmurze (nie jestem pewien, która wersja) pozwala na przywrócenie zatwierdzenia z systemu plików w następujący sposób (nie widzę, jak cofnąć się z interfejsu Bitbucket w przeglądarce Chrome).

- wykonaj kopię zapasową całego katalogu, aby zabezpieczyć zmiany, które zostały nieumyślnie wprowadzone

-wybierz wyewidencjonowany katalog

- prawy przycisk myszy: menu git żółwia

-repo-browser (opcja menu „revert” cofa tylko niezatwierdzone zmiany)

-naciśnij przycisk HEAD

-wybierz najwyższą linię (ostatnie zatwierdzenie)

- prawy przycisk myszy: cofnij zmianę przez to zatwierdzenie

- po cofnięciu zmian w systemie plików naciśnij commit

-To aktualizuje GIT z komunikatem „Przywróć (poprzednia wiadomość). To przywraca popełnienie takiego a takiego ''

-wybierz „Zatwierdź i wypchnij”.

smriti
źródło