git push –force i jak sobie z nim radzić

Czy kiedykolwiek znalazłeś się w sytuacji, w której błędna komenda git spowodowała spustoszenie w repo twojego projektu? Ludzie popełniają błędy, a czasami te błędy mogą kosztować godziny czasu twojego zespołu. W tym poradniku pokażemy ci, jak szybko odzyskać równowagę po niefortunnym git push --force.

Nie bądźmy zbyt pewni siebie. Prędzej czy później, to się zdarzy. Podczas pracy z kilkoma pilotami w tym samym repozytorium git, w końcu git push --force do master (lub innej ważnej gałęzi, z którą nigdy nie należy zadzierać).

To może się zdarzyć, na przykład podczas wdrażania z Deis lub Heroku, które używają oddzielnych pilotów git do budowania i wdrażania aplikacji. Po długim dniu pracy, niewiarygodnie łatwo jest wykonać git push --force zamiast zwykłego git push --force deis master.

Oops! W mgnieniu oka twoi koledzy z zespołu stracili całą swoją ostatnią pracę. Czas stawić czoła ich wściekłości.

Jednakże, jak mówi nam jeden z doskonałych przewodników, NIE PANIKUJ! Dobrą rzeczą jest to, że używasz git, a to oznacza, że wszystko można naprawić.

Najlepszy scenariusz: ktoś inny, kto pracuje nad tym samym kodem, wyciągnął najnowszą wersję master tuż przed tym, jak ją zepsułeś. Wtedy wszystko, co musisz zrobić, to wejść na czat swojego zespołu i poprosić tę osobę, aby wymusiła push swoich ostatnich zmian.

Jeśli masz szczęście, ich lokalne repozytorium będzie miało pełną historię commitów, twój błąd zostanie nadpisany świeżym kodem i nic nie zostanie utracone. Ale co jeśli nie masz tyle szczęścia? Wtedy czytaj dalej!

Przypadek 1: Byłeś ostatnią osobą, która pchała do Mastera przed popełnieniem błędu

Dobra wiadomość! Masz wszystko, czego potrzebujesz, aby cofnąć swój błąd na swoich oczach. Tylko nie zamykaj ani nie czyść swojego terminala. Po pierwsze, wejdź na czat swojego zespołu i wyznaj swoje grzechy. Poproś ludzi, aby nie robili bałaganu w repo przez następną minutę lub tak, podczas gdy ty będziesz naprawiał rzeczy.

W wyjściu polecenia git push --force w twojej powłoce szukaj linii, która przypomina tę:

 + deadbeef...f00f00ba master -> master (forced update)

Pierwsza grupa symboli (która wygląda jak prefiks SHA commit’a) jest kluczem do ratunku. deadbeef jest twoim ostatnim dobrym commitem do master tuż przed tym, jak wyrządziłeś szkody.

Więc wszystko, czego potrzebujesz, to… wymusić przepchnięcie (zwalczając ogień ogniem!) tego commitu z powrotem do gałęzi master, na wierzchu złego.

$ git push --force origin deadbeef:master

Gratulacje! Uratowałeś dzień. Teraz czas uczyć się na błędach.

Przypadek 2: master został zmieniony przez kogoś innego, zanim Ty narozrabiałeś

Więc, tuż przed tym jak zrobiłeś git push --force ktoś zamknął kilka pull requestów, a master teraz nie wygląda jak Twoja lokalna kopia. Nie możesz już zrobić git push --force sha1:master, ponieważ nie masz lokalnie ostatnich commitów (i nie możesz ich zdobyć za pomocą git fetch, ponieważ nie należą już do żadnej gałęzi). Mimo to zachowaj spokój i poproś kolegów z zespołu, aby przez jakiś czas nie korzystali ze zdalnego dostępu.

Skorzystamy na tym, że GitHub nie usuwa od razu nieosiągalnych commitów. Oczywiście, nie można ich również pobrać, ale jest na to sposób.

Zauważ, że będzie to działać tylko wtedy, gdy „obserwujesz” repozytorium, więc wszystko, co się w nim dzieje, pojawia się w kanale wyświetlanym na stronie głównej GitHuba. Otwórz ten kanał i poszukaj czegoś takiego:

an hour agoUsername pushed to master at org/repo - deadbeef Implement foo - deadf00d Fix bar

Teraz możesz:

  • Skomponować adres URL https://github.com/org/repo/tree/deadbeef, gdzie deadbeef jest hashem ostatniego dobrego commitu do uszkodzonej gałęzi;
  • Otworzyć przełącznik gałęzi/tagów w interfejsie internetowym GitHuba;

GitHub branch/tag switcher

GitHub branch/tag switcher

  • Utwórz nazwę dla nowego tymczasowego oddziału (np.g., master-before-force-push);
  • Kliknij „Utwórz gałąź”.

Teraz możesz pobrać wszystkie brakujące commity:

$ git fetchFrom github.com:org/repo * master-before-force-push -> origin/master-before-force-push

Twój problem jest teraz zredukowany do tego opisanego w poprzednim przykładzie:

$ git push --force origin origin/master-before-force-push:master

Jeśli nadal potrzebujesz, aby twoja praca znajdowała się w master, po prostu rebase na wierzchu:

$ git rebase origin/master

Jak uniknąć takiej katastrofy w przyszłości

  1. GitHub i GitLab mają funkcję zwaną „chronionymi gałęziami.” Oznacz master, develop, stable, lub jakiekolwiek inne kluczowe gałęzie jako chronione i nikt nie będzie mógł wymusić push do nich. Zawsze można tymczasowo „odbezpieczyć” gałąź, jeśli naprawdę trzeba nadpisać historię.

    Zapoznaj się z dokumentami GitHuba, aby uzyskać szczegółowe informacje.

  2. Zamiast opcji --force użyj --force-with-lease. To zatrzyma operację push, jeśli ktoś pchnął do tej samej gałęzi, gdy pracowałeś nad nią (i nie wyciągnął żadnych zmian).

    Zobacz ten artykuł z Atlassian.

  3. Utwórz aliasy dla poleceń, które używają git push --force, aby zapobiec przypadkowym destrukcyjnym działaniom:

    # ~/.gitconfig deploy = "!git push --force deis \"$(git rev-parse --abbrev-ref HEAD):master\""

    Przeczytaj rozdział ProGit o aliasach.

  4. Nigdy nie rób swoich eksperymentów w głównej gałęzi repozytorium! git checkout -b experiments jest twoim najlepszym przyjacielem.

Pro Tip: git push ma wiele opcji. --force i --all działają razem szczególnie dobrze. Możesz użyć tego combo, gdy wracasz do projektu po kilku miesiącach nieaktywności. Spróbuj, jeśli czujesz się wyjątkowo odważny!

.

Leave a Reply