Resetowanie pilota do określonego zatwierdzenia

709

Chcę odrzucić wszystkie zmiany wprowadzone po zatwierdzeniu <commit-hash>. Więc zrobiłem:

git reset --hard <commit-hash>

Teraz chcę zrobić to samo z moim pilotem. W jaki sposób mogę to zrobić? Później wykonałem kilka zatwierdzeń (i wypycham) <commit-hash>i chcę je wszystkie odrzucić. Jest po prostu coś poszło strasznie źle w drodze i nie chcę, aby to gorzej niż już jest. ; (

Zasadniczo chcę, aby przewinąć mój origin/masterTO<commit-hash>

nacho4d
źródło
3
Czy na pewno origin/masternie zostałeś pociągnięty i zepchnięty przez innych użytkowników? Zawsze należy unikać zmiany historii publicznego (tj. Nielokalnego) repozytorium.
vindia
Możliwy duplikat Jak cofnąć wiele zatwierdzeń git?
Michael Freidgeim,

Odpowiedzi:

1251

Zakładając, że twoja gałąź jest wywoływana masterzarówno tutaj, jak i zdalnie, a twój pilot jest nazywany, originmożesz:

 git reset --hard <commit-hash>
 git push -f origin master

Należy jednak tego unikać, jeśli ktoś inny pracuje ze zdalnym repozytorium i wyciągnął zmiany. W takim przypadku lepiej cofnąć niepotrzebne zatwierdzenia, a następnie wcisnąć jak zwykle.

Aktualizacja: wyjaśniłeś poniżej, że inne osoby wyciągnęły zmiany, które wprowadziłeś, więc lepiej utworzyć nowe zatwierdzenie, które cofnie wszystkie te zmiany . W tej odpowiedzi Jakuba Narębskiego jest dobre wyjaśnienie twoich możliwości zrobienia tego . To, który z nich jest najwygodniejszy, zależy od liczby zmian, które chcesz przywrócić, i która metoda jest dla Ciebie najbardziej sensowna.

Ponieważ z twojego pytania jasno wynika, że git reset --hardzresetowałeś już swój masteroddział, być może będziesz musiał zacząć od git reset --hard ORIG_HEADprzeniesienia swojego oddziału z powrotem do poprzedniego miejsca. (Jak zawsze git reset --hard, upewnij się, że git statusjest czysty, że jesteś na właściwej gałęzi i że znasz się git reflogjako narzędzie do odzyskiwania pozornie utraconych zatwierdzeń.) Powinieneś również sprawdzić, czy ORIG_HEADwskazuje to na prawidłowe zatwierdzenie, za pomocą git show ORIG_HEAD.

Rozwiązywanie problemów:

Jeśli pojawi się komunikat „ ! [Zdalne odrzucenie] a60f7d85 -> master (odrzucony hak wstępny)

musisz zezwolić na przepisywanie historii gałęzi dla określonej gałęzi. Na przykład w BitBucket napisano: „Ponowne zapisywanie historii oddziału jest niedozwolone”. Jest pole wyboru o nazwie, Allow rewriting branch historyktóre musisz zaznaczyć.

Mark Longair
źródło
21
Niebezpieczeństwo: ten reset zakłada, że ​​odpowiednia gałąź ( śledząca ) jest obecnie sprawdzona i nie ma żadnych niezatwierdzonych zmian, które chciałbyś zachować. Użyj git update-refzamiastreset --hard ; pozwoli ci to zrobić bez posiadania działającego drzewa / sprawdzonej gałęzi
patrz
3
Widzę. Zostało popchnięte i zmienione przez innych. Więc powinienem użyć, revert ale powiedzmy, że chcę cofnąć poprzednie 4 zatwierdzenia, więc powinienem to zrobić, git revert comit1; git push; git revert comit2; git push; ...czy po prostu git revert commit4; git push?
nacho4d
1
@ nacho4d: nie musisz naciskać po każdym przywróceniu - w tej odpowiedzi Jakub Narębski podaje ładny opis tego, co robić . Musisz cofnąć każde zatwierdzenie cofając się - po prostu git revert commit4tworzy nowe zatwierdzenie, które tylko cofa wprowadzone zmiany commit4. Jednak w odpowiedzi, na którą wskazałem, można połączyć je w jeden zatwierdzenie.
Mark Longair
1
@ Mark Już uruchomiłem, git reset --hardale usunąłem plik lokalny i ponownie wyciągnąłem z pochodzenia, więc mogę git revert ...teraz zrobić. Mam teraz wątpliwości: czy muszę cofać każdy zatwierdzenie i wypychać (jeden po drugim), czy po prostu wycofać pierwszy zatwierdzenie po prawda tylko zatwierdzić?
nacho4d
1
@sehe: jest trudny w użyciu, ponieważ musisz użyć pełnej nazwy ref, więc ludzie mogą łatwo zaśmiecać swój .gitkatalog refami, których nie chcieli stworzyć. Myliłem się twierdząc, że nie ma kontroli bezpieczeństwa. Możesz znaleźć klasyfikację do poleceń „hydraulika” i „porcelana” na stronie git man .
Mark Longair
123

Użyj innych odpowiedzi, jeśli nie masz nic przeciwko utracie lokalnych zmian. Ta metoda nadal może zniszczyć pilota, jeśli wybierzesz niewłaściwy skrót zatwierdzenia, do którego chcesz wrócić.

Jeśli chcesz, aby zdalne dopasowanie było zatwierdzeniem, które jest w dowolnym miejscu w lokalnym repozytorium:

  1. Czy nie robić żadnych kasowanie.
  2. Użyj, git logaby znaleźć zatwierdzenie, do którego chcesz mieć pilota. git log -paby zobaczyć zmiany lub git log --graph --all --oneline --decoratezobaczyć zwarte drzewo.
  3. Skopiuj skrót zatwierdzenia lub jego znacznik lub nazwę jego gałęzi, jeśli jest to wskazówka.
  4. Uruchom polecenie takie jak:

    git push --force <remote> <commit-ish>:<the remote branch>
    

    na przykład

    git push --force origin 606fdfaa33af1844c86f4267a136d4666e576cdc:master
    

    lub

    git push --force staging v2.4.0b2:releases
    

Korzystam z wygodnego aliasu ( git go) do przeglądania historii, jak w kroku 2, który można dodać w następujący sposób:

    git config --global alias.go 'log --graph --all --decorate --oneline'`
Walf
źródło
3
Wykres był bardzo fajną wskazówką, właśnie dodałem -5, aby uzyskać tylko ostatnie n zatwierdzeń, było to ogromne drzewo. Również unikanie resetowania było tym, czego szukałem. Świetnie
AlexanderD
@AlexanderD Możesz także dodać alias do Gita zamiast do swojej powłoki, więc działa wszędzie. Git rozumie te aliasy i tabulatory z pełnego polecenia, więc możesz dodawać argumenty. git config --global alias.graph 'log --graph --all --decorate --oneline'jest mniej niechlujny i nadal można go ograniczyć, np .:git graph -5
Walf
To jest doskonałe. Zawsze bałaganiłem lokalnych. Właśnie tego potrzebowałem po przypadkowym popchnięciu mojej inscenizacji do życia :( Dzięki!
Jake
1
W systemie Windows wprowadź, qaby zamknąć dziennik git. 2 minuty, nigdy nie wrócę.
dst3p
1
@ dst3p To na każdej platformie, kolego. Program pagera jest zwykle lessi qjest normalnym sposobem na jego wyjście. Git Bash jest jak terminal * nix.
Walf 18.01.19
63

Rozwiązałem problem podobny do twojego za pomocą następujących poleceń:

git reset --hard <commit-hash> 
git push -f <remote> <local branch>:<remote branch> 
Ibrohim Ermatov
źródło
13

Na GitLab może być konieczne ustawienie oddziału jako niezabezpieczonego przed wykonaniem tego. Możesz to zrobić w [repo]> Ustawienia> Repozytorium> Chronione gałęzie. Następnie działa metoda z odpowiedzi Marka.

git reset --hard <commit-hash>
git push -f origin master
dudasaus
źródło
10

Jeśli chcesz poprzednią wersję pliku, polecam korzystanie z usługi git checkout.

git checkout <commit-hash>

W ten sposób cofniesz się w czasie, nie wpłynie to na bieżący stan twojego projektu, możesz przejść do głównej linii głównej git Checkout głównej

ale kiedy dodajesz plik w argumencie, plik ten jest przywracany z poprzedniego czasu do bieżącego czasu projektu, tzn. twój bieżący projekt jest zmieniany i musi zostać zatwierdzony.

git checkout <commit-hash> -- file_name
git add .
git commit -m 'file brought from previous time'
git push

Zaletą tego jest to, że nie usuwa historii ani nie przywraca określonych zmian kodu (git revert)

Sprawdź więcej tutaj https://www.atlassian.com/git/tutorials/undoing-changes#git-checkout

priya khokher
źródło
To doskonała odpowiedź: działa, kropka i jest bardzo bezpieczna; jeśli się zepsujesz, łatwo będzie wrócić.
Bob
8

Moje dwa centy do poprzednich odpowiedzi: jeśli

git push --force <remote> <the-hash>:<the remote branch>

nadal nie działa, możesz edytować <your-remote-repo>.git/configsekcję odbioru pliku:

[receive]
  #denyNonFastforwards = true
  denyNonFastforwards = false
badbishop
źródło
Warto wiedzieć, jak skonfigurować pilota, aby zezwalał na wypychanie bez przewijania do przodu, ponieważ większość odpowiedzi wydaje się zakładać zdalną usługę, taką jak github lub bitbucket.
strongbutgood
2

Jeśli twoja gałąź nie jest programistyczna ani produkcyjna, najprostszym sposobem na osiągnięcie tego jest zresetowanie do określonego zatwierdzenia lokalnie i utworzenie z niego nowej gałęzi. Możesz użyć:

Git Checkout 000000

(gdzie 000000 to identyfikator zatwierdzenia, do którego chcesz przejść) w problematycznej gałęzi, a następnie po prostu utwórz nową gałąź:

git remote add [nazwa_zdjecia]

Następnie możesz utworzyć nowy PR i wszystko będzie działać dobrze!

Gerardo Suarez
źródło
1

Zrób jedną rzecz, uzyskaj numer SHA zatwierdzenia. takich jak 87c9808, a następnie

  1. przenieś się, to jest twoja głowa do określonego zatwierdzenia (wykonując git reset - hard 89cef43 // podaj tutaj swój numer)
  2. Następnie dokonaj pewnych zmian w losowym pliku, aby git poprosił cię o zatwierdzenie tego lokalnie, a następnie zdalnie. Zatem teraz musisz zrobić. po zastosowaniu zmiany git commit -a -m „wersja próbna”
  3. Teraz wypchnij następujące zatwierdzenie (jeśli zostało to zatwierdzone lokalnie) przez git push master master
  4. Teraz to, o co prosi cię git, to to

błąd: nie udało się przesłać niektórych odnośników do „ https://github.com/YOURREPOSITORY/AndroidExperiments.git ” wskazówka: Aktualizacje zostały odrzucone, ponieważ wskazówka twojego obecnego oddziału znajduje się za wskazówką: jego zdalny odpowiednik. Zintegruj zmiany zdalne (np. Podpowiedź: „git pull ...”) przed ponownym naciśnięciem. **

  1. Zatem teraz możesz to zrobić

git push --force origin master

  1. Mam nadzieję, że to zadziała :)
Siddharth Choudhary
źródło
1

Sourcetree: resetowanie pilota do określonego zatwierdzenia

  1. Jeśli wypchnąłeś złe zatwierdzenie do twojego pilota (origin / feature / 1337_MyAwesomeFeature) jak na poniższym obrazku

Idź do Piloty

  1. Idź do Piloty> pochodzenie> funkcja> 1337_MójAwesomeFeature
  2. Kliknij prawym przyciskiem myszy i wybierz „Usuń początek / funkcję / 1337_MyAwesomeFeature” (lub zmień jego nazwę, jeśli chcesz wykonać kopię zapasową i pomiń krok 4.)
  3. Kliknij „Wymuś usunięcie” i „OK”.

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

  1. Wybierz starsze zatwierdzenie i wybierz „Zresetuj bieżącą gałąź do tego zatwierdzenia”
  2. Wybierz tryb, który chcesz mieć (trudny, jeśli nie chcesz ostatnich zmian) i „OK”.

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

  1. Wciśnij to zatwierdzenie do nowego początku / funkcji / 1337_MyAwesomeFeature wprowadź opis zdjęcia tutaj

  2. Twój lokalny oddział funkcji i twój zdalny oddział funkcji są teraz na poprzednim (wybranym przez Ciebie) zatwierdzeniu wprowadź opis zdjęcia tutaj

Joel Wiklund
źródło