Przewodnik po usuwaniu błędów za pomocą Gita (część 2)

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ Błędy. Ci okrutni złoczyńcy nie zatrzymują się nawet w pięknym świecie tworzenia oprogramowania. Ale chociaż nie możemy uniknąć popełniania błędów, możemy nauczyć się je cofać! W tym artykule przedstawimy odpowiednie narzędzia do codziennej pracy z Git. Możesz również zapoznać się z pierwszym artykułem z serii.

W tej drugiej części naszej serii „Undoing Mistakes with Git” ponownie odważnie spojrzymy niebezpieczeństwu w oczy: przygotowałem cztery nowe scenariusze końca świata — w tym oczywiście kilka sprytnych sposobów na uratowanie naszych karków! Ale zanim zagłębimy się w to: spójrz na poprzednie artykuły na Git, aby uzyskać jeszcze więcej metod samoratowania, które pomogą Ci naprawić błędy z Git!

Chodźmy!

Odzyskiwanie usuniętej gałęzi za pomocą Reflog

Czy kiedykolwiek usunąłeś gałąź i wkrótce potem zdałeś sobie sprawę, że nie powinieneś? W mało prawdopodobnym przypadku, gdy nie znasz tego uczucia, mogę ci powiedzieć, że nie jest ono dobre. Mieszanina smutku i złości wkrada się do ciebie, gdy myślisz o całej ciężkiej pracy włożonej w zmiany tej gałęzi, o całym cennym kodzie, który teraz zgubiłeś.

Na szczęście istnieje sposób na przywrócenie tej gałęzi do życia — za pomocą narzędzia Git o nazwie „Reflog”. Używaliśmy tego narzędzia w pierwszej części naszej serii, ale oto małe odświeżenie: Reflog jest jak dziennik, w którym Git odnotowuje każdy ruch wskaźnika HEAD w lokalnym repozytorium. Innymi słowy, mniej nerdowe: za każdym razem, gdy kasujesz, zatwierdzasz, scalasz, zmieniasz bazę, wybierasz wiśnie i tak dalej, tworzony jest wpis do dziennika. To sprawia, że ​​Reflog jest idealną siatką bezpieczeństwa, gdy coś pójdzie nie tak!

Rzućmy okiem na konkretny przykład:

 $ git branch * feature/login master

Widzimy, że obecnie mamy sprawdzony nasz oddział feature/login . Powiedzmy, że to jest gałąź, którą zamierzamy usunąć (nieumyślnie). Jednak zanim to zrobimy, musimy przejść do innej gałęzi, ponieważ nie możemy usunąć naszej obecnej gałęzi HEAD!

 $ git checkout master $ git branch -d feature/login

Nasza cenna gałąź funkcji już zniknęła — dam ci chwilę, aby (a) zrozumieć powagę naszego błędu i (b) trochę opłakiwać. Po otarciu łez musimy znaleźć sposób na przywrócenie tej gałęzi! Otwórzmy Reflog (po prostu wpisując git reflog ) i zobaczmy, co dla nas kryje:

Git's Reflog protokołuje wszystkie główne działania w naszym lokalnym repozytorium
Git's Reflog protokołuje wszystkie główne działania w naszym lokalnym repozytorium. (duży podgląd)

Oto kilka komentarzy, które pomogą Ci zrozumieć wyniki:

  • Przede wszystkim musisz wiedzieć, że Reflog sortuje swoje wpisy chronologicznie: najnowsze pozycje znajdują się na górze listy.
  • Najwyższym (a zatem najnowszym) elementem jest polecenie git checkout , które wykonaliśmy przed usunięciem gałęzi. Jest on tutaj zarejestrowany w Reflog, ponieważ jest to jeden z tych „ruchów wskaźnika HEAD”, które Reflog tak sumiennie rejestruje.
  • Aby cofnąć nasz poważny błąd, możemy po prostu wrócić do stanu sprzed tego — który jest również czysto i wyraźnie odnotowany w Reflog!

Spróbujmy więc tego, tworząc nową gałąź (o nazwie naszej „zagubionej” gałęzi), która zaczyna się od tego hasha SHA-1 stanu „przed”:

 $ git branch feature/login 776f8ca

I voila! Będziesz zachwycony, widząc, że teraz przywróciliśmy naszą pozornie utraconą gałąź!

Jeśli używasz graficznego interfejsu użytkownika Git, takiego jak „Tower”, możesz skorzystać ze skrótu: po prostu naciśnij CMD + Z na klawiaturze, aby cofnąć ostatnie polecenie — nawet jeśli właśnie brutalnie usunąłeś gałąź!

Graficzny interfejs użytkownika, taki jak Tower, może ułatwić proces usuwania błędów.
Więcej po skoku! Kontynuuj czytanie poniżej ↓

Przenoszenie zobowiązania do innego oddziału

W wielu zespołach istnieje zgoda, aby nie zatwierdzać długotrwałych gałęzi, takich jak main lub develop : gałęzie takie jak te powinny otrzymywać nowe zatwierdzenia tylko poprzez integracje (np. scalenia lub zmiany bazy). A jednak oczywiście błędy są nieuniknione: czasami zapominamy i popełniamy na tych gałęziach! Jak więc możemy posprzątać bałagan, który zrobiliśmy?

Przenoszenie zatwierdzenia do właściwej gałęzi docelowej
Nasze zobowiązanie wylądowało na niewłaściwej gałęzi. Jak możemy przenieść go do właściwej gałęzi docelowej? (duży podgląd)

Na szczęście tego typu problemy można łatwo naprawić. Zakasajmy rękawy i zabierzmy się do pracy.

Pierwszym krokiem jest przełączenie się na właściwą gałąź docelową, a następnie przeniesienie zatwierdzenia nadmiernie za pomocą polecenia cherry-pick :

 $ git checkout feature/login $ git cherry-pick 776f8caf

Będziesz teraz mieć zatwierdzenie w żądanej gałęzi, gdzie powinno być na pierwszym miejscu. Świetny!

Pozostaje jednak jeszcze jedna rzecz do zrobienia: musimy najpierw wyczyścić gałąź, na której przypadkowo wylądowała! Polecenie cherry-pick , że tak powiem, utworzyło kopię zatwierdzenia — ale oryginał jest nadal obecny w naszej długo działającej gałęzi:

Kopia zatwierdzenia we właściwej gałęzi, ale oryginał nadal znajduje się w złej gałęzi
Pomyślnie utworzyliśmy kopię zatwierdzenia we właściwej gałęzi, ale oryginał wciąż tu jest — w złej gałęzi. (duży podgląd)

Oznacza to, że musimy wrócić do naszej długo działającej gałęzi i użyć git reset , aby ją usunąć:

 $ git checkout main $ git reset --hard HEAD~1

Jak widać, używamy tutaj polecenia git reset , aby usunąć wadliwe zatwierdzenie. Parametr HEAD~1 mówi Gitowi, aby „cofnął się o 1 wersję za HEAD”, skutecznie usuwając najwyższy (w naszym przypadku: niechciany) commit z historii tej gałęzi.

I voila: zatwierdzenie jest teraz tam, gdzie powinno być na pierwszym miejscu , a nasza długo działająca gałąź jest czysta — tak jakby nasz błąd nigdy się nie wydarzył!

Edycja przesłania starego zobowiązania

Zbyt łatwo jest przemycić literówkę do wiadomości o zatwierdzeniu — i odkryć ją dopiero znacznie później. W takim przypadku stara dobra opcja --amend git commit nie może zostać użyta do rozwiązania tego problemu, ponieważ działa tylko dla ostatniego zatwierdzenia. Aby poprawić każdy zatwierdzenie, które jest starsze, musimy skorzystać z narzędzia Git o nazwie „Interaktywna zmiana bazy”.

Wiadomość o zatwierdzeniu, którą warto zmienić
Oto komunikat, który warto zmienić. (duży podgląd)

Najpierw musimy powiedzieć Interactive Rebase, którą część historii zatwierdzenia chcemy edytować. Odbywa się to poprzez podanie mu hasha zatwierdzenia: nadrzędnego zatwierdzenia tego, którym chcemy manipulować.

 $ git rebase -i 6bcf266b

Otworzy się okno edytora. Zawiera listę wszystkich zatwierdzeń po tym, który podaliśmy jako podstawę dla interaktywnej zmiany bazy w poleceniu:

Pokazuje zakres zatwierdzeń, które wybraliśmy do edycji w naszej interaktywnej sesji zmiany bazy
Zakres zatwierdzeń, które wybraliśmy do edycji w naszej sesji Interaktywnej zmiany bazy. (duży podgląd)

Tutaj ważne jest, abyś nie podążał za pierwszym impulsem: w tym kroku nie edytujemy jeszcze komunikatu o zatwierdzeniu. Zamiast tego mówimy Gitowi, jakiego rodzaju manipulację chcemy wykonać, z jakim(i) zatwierdzeniem(ami). Całkiem wygodnie, na dole tego okna w komentarzach znajduje się lista słów kluczowych działań. W naszym przypadku oznaczamy wiersz #1 za pomocą reword (zastępując w ten sposób standardowy pick ).

Wszystko, co pozostało do zrobienia w tym kroku, to zapisanie i zamknięcie okna edytora. W zamian otworzy się nowe okno edytora, które zawiera aktualną wiadomość o zatwierdzeniu, które oznaczyliśmy. A teraz wreszcie nadszedł czas na wprowadzenie zmian!

Oto cały proces w skrócie:

Używanie interaktywnej zmiany bazy do edycji wiadomości starego zatwierdzenia, od początku do końca.

Korygowanie złamanego zobowiązania (w bardzo elegancki sposób)

Na koniec przyjrzymy się fixup , szwajcarskiemu scyzorykowi narzędzi do cofania. Mówiąc prościej, pozwala to naprawić zepsute/niekompletne/niepoprawne zatwierdzenie po fakcie. To naprawdę wspaniałe narzędzie z dwóch powodów:

  1. Nie ma znaczenia, jaki jest problem.
    Być może zapomniałeś dodać plik, powinieneś coś usunąć, wprowadzić nieprawidłową zmianę lub po prostu popełnić literówkę. fixup działa we wszystkich tych sytuacjach!
  2. Jest niezwykle elegancki.
    Naszą normalną, instynktowną reakcją na błąd w zatwierdzeniu jest utworzenie nowego zatwierdzenia, które rozwiąże problem. Ten sposób pracy, jakkolwiek intuicyjny może się wydawać, sprawi, że Twoja historia zatwierdzeń będzie wyglądała bardzo szybko, bardzo chaotycznie. Masz „oryginalne” zatwierdzenia, a następnie te małe „zapasowe” zatwierdzenia, które naprawiają rzeczy, które poszły nie tak w oryginalnych zatwierdzeniach. Twoja historia jest zaśmiecona małymi, bezsensownymi zatwierdzeniami bandy, co sprawia, że ​​trudno jest zrozumieć, co wydarzyło się w Twojej bazie kodu.
Twoja historia zatwierdzeń może być bardzo trudna do odczytania, jeśli stale naprawiasz małe błędy za pomocą tak zwanych zatwierdzeń pomocy zespołu
Ciągłe naprawianie małych błędów za pomocą „zatwierdzeń z pomocą bandy” sprawia, że ​​twoja historia zatwierdzeń jest bardzo trudna do odczytania. (duży podgląd)

W tym miejscu pojawia się fixup . Pozwala to na wykonanie tego poprawiającego zatwierdzenia bandaży. Ale tu pojawia się magia: następnie stosuje go do oryginalnego, zepsutego zatwierdzenia (naprawiając go w ten sposób), a następnie całkowicie odrzuca brzydki zatwierdzenie opatrunku!

Fixup stosuje twoje poprawki do oryginalnego zatwierdzenia, a następnie usuwa niepotrzebne zatwierdzenie bandaży
Fixup stosuje twoje poprawki do oryginalnego zatwierdzenia, a następnie usuwa zbędne zatwierdzenie pomocy opaski. (duży podgląd)

Możemy razem przejść przez praktyczny przykład! Załóżmy, że wybrany tutaj zatwierdzenie jest zepsuty.

Naprawienie wybranego nieprawidłowego zatwierdzenia w elegancki sposób
Wybrane zatwierdzenie jest nieprawidłowe — i zamierzamy to w elegancki sposób naprawić. (duży podgląd)

Powiedzmy też , że przygotowałem zmiany w pliku o nazwie error.html , które rozwiążą problem. Oto pierwszy krok, który musimy zrobić:

 $ git add error.html $ git commit --fixup 2b504bee

Tworzymy nowe zatwierdzenie, ale mówimy Gitowi, że jest to specjalne zatwierdzenie: jest to poprawka dla starego zatwierdzenia z określonym hashem SHA-1 (w tym przypadku 2b504bee ).

Drugim krokiem jest teraz rozpoczęcie sesji Interactive fixup — ponieważ naprawa należy do dużego zestawu narzędzi Interactive Rebase.

 $ git rebase -i --autosquash 0023cddd

Na temat tego polecenia warto wyjaśnić dwie rzeczy. Po pierwsze, dlaczego podałem tutaj 0023cddd jako skrót wersji? Ponieważ musimy rozpocząć naszą sesję Interactive Rebase od zatwierdzenia rodzicielskiego naszego zepsutego kolegi.

Po drugie, do czego służy opcja --autosquash ? To zabiera nam dużo pracy! W oknie edytora, które się teraz otwiera, wszystko jest już dla nas przygotowane:

Okno sesji interaktywnej zmiany bazy
Okno sesji Interaktywnej zmiany bazy (duży podgląd)

Dzięki opcji --autosquash , Git wykonał już dla nas ciężkie podnoszenie:

  1. Oznaczyło to nasze małe zatwierdzenie opatrunku za pomocą słowa kluczowego fixup action. W ten sposób Git połączy go z zatwierdzeniem bezpośrednio powyżej , a następnie odrzuci go.
  2. Zmienił również odpowiednio kolejność wierszy, przesuwając nasze zatwierdzenie opatrunkowe bezpośrednio pod zatwierdzenie, które chcemy naprawić (ponownie: fixup działa poprzez połączenie zatwierdzenia oznaczonego z tym powyżej !).

W skrócie: nie pozostaje nam nic innego jak zamknąć okno!

Przyjrzyjmy się końcowemu efektowi.

  • Poprzednio zepsuty zatwierdzenie jest naprawione: teraz zawiera zmiany, które przygotowaliśmy w naszym zatwierdzeniu opatrunku.
  • Samo brzydkie zatwierdzenie opatrunku zostało odrzucone: historia zatwierdzeń jest czysta i łatwa do odczytania — tak jakby w ogóle nie wystąpił żaden błąd.
Przykład, jak wygląda czysta historia zmian
Wynik końcowy po użyciu narzędzia do naprawy: czysta historia zmian! (duży podgląd)

Umiejętność cofania błędów to supermoc

Gratulacje! Teraz jesteś w stanie uratować szyję w wielu trudnych sytuacjach! Nie możemy tak naprawdę uniknąć takich sytuacji: bez względu na to, jak bardzo jesteśmy doświadczeni jako programiści, błędy są po prostu częścią pracy. Ale teraz, kiedy już wiesz, jak sobie z nimi radzić, możesz stawić im czoła z wyluzowanym tętnem.

Jeśli chcesz dowiedzieć się więcej o usuwaniu błędów z Git, mogę polecić darmowy „Apteczka pierwszej pomocy dla Git”, serię krótkich filmów o dokładnie tym temacie.

Baw się, popełniając błędy — i oczywiście z łatwością je usuwając!