Jak (i dlaczego!) Zachować czystą historię zatwierdzeń Git

Zatwierdzenia są jedną z kluczowych części repozytorium Git, a co więcej, komunikat zatwierdzenia jest dziennikiem życia repozytorium. W miarę jak projekt / repozytorium ewoluuje w czasie (dodawane są nowe funkcje, naprawiane błędy, refaktoryzacja architektury), komunikaty zmian są miejscem, w którym można zobaczyć, co zostało zmienione i jak. Dlatego ważne jest, aby te komunikaty odzwierciedlały podstawową zmianę w krótki, precyzyjny sposób.

Dlaczego znacząca historia zmian w Git jest ważna

Co robi commit w Git? to odciski palców, które zostawiasz na kodzie, którego dotykasz. Każdy kod, który popełnisz dzisiaj, za rok od teraz, gdy spojrzysz na tę samą zmianę; byłbyś wdzięczny za jasną, znaczącą wiadomość o zatwierdzeniu, którą napisałeś, a także ułatw życie innym programistom. Kiedy zatwierdzenia są izolowane na podstawie kontekstu, szybciej można znaleźć błąd, który został wprowadzony przez określone zatwierdzenie, i tym łatwiej jest przywrócić zatwierdzenie, które spowodowało błąd.

Podczas pracy nad dużym projektem często mamy do czynienia z wieloma ruchomymi częściami, które są aktualizowane, dodawane lub usuwane. Zapewnienie, że komunikaty dotyczące zmian są utrzymywane w takich przypadkach, może być trudne, zwłaszcza gdy programowanie zajmuje kilka dni, tygodni, a nawet miesięcy, aby uprościć wysiłek związany z utrzymaniem zwięzłości Historia zmian, w tym artykule zostaną wykorzystane niektóre typowe sytuacje, z którymi programiści mogą się spotkać podczas pracy nad repozytorium Git.

  • Sytuacja 1: Muszę zmienić najnowsze zatwierdzenie
  • Sytuacja 2: Muszę zmienić konkretne zatwierdzenie
  • Sytuacja 3: Muszę dodać, usunąć lub połączyć zatwierdzenia
  • Sytuacja 4: Moja historia zmian nie robi sens, potrzebuję nowego startu!

Ale zanim zagłębimy się w temat, przyjrzyjmy się szybko, jak wygląda typowy przepływ pracy programistycznej w naszej hipotetycznej aplikacji Ruby.

Uwaga: w tym artykule założono, że znasz podstawy Gita, jak działają gałęzie, jak dodawać niezatwierdzone zmiany gałęzi do etapu i jak zatwierdzać zmiany. Jeśli nie jesteś pewien tych przepływów, nasza dokumentacja jest świetnym punktem wyjścia.

Dzień z życia

Tutaj pracujemy nad małym projektem Ruby on Rails, w którym trzeba dodać widok nawigacji na stronie głównej, co wiąże się z aktualizacją i dodaniem kilku plików. Poniżej przedstawiono szczegółowy podział całego przepływu:

  • Rozpoczynasz pracę nad funkcją od aktualizacji pliku ; nazwijmy to application_controller.rb
  • Ta funkcja wymaga również zaktualizowania widoku: index.html.haml
  • Dodałeś część, która jest używana na stronie indeksu: _navigation.html.haml
  • Style strony również muszą zostać zaktualizowane, aby odzwierciedlały dodaną przez nas część: styles.css.scss
  • Funkcja jest teraz gotowa z żądanymi zmianami, czas również zaktualizować testy; pliki do zaktualizowania to:
    • application_controller_spec.rb
    • navigation_spec.rb
  • Testy są aktualizowane i przebiegają zgodnie z oczekiwaniami, teraz czas na zatwierdzenie zmian!

Ponieważ wszystkie pliki należą do różnych obszarów architektury, zatwierdzamy zmiany odizolowane od siebie, aby zapewnić, że każde zatwierdzenie reprezentuje określony kontekst i jest wykonane w określonej kolejności. Zwykle wolę backend – > kolejność frontendową, w której większość zmian zorientowanych na backend jest zatwierdzana jako pierwsza, następnie następuje środkowa warstwa, a następnie zatwierdzane są zmiany zorientowane na frontend na liście Git.

Teraz, gdy mamy zatwierdzone zmiany, tworzymy żądanie scalenia z gałęzią. Gdy otworzysz prośbę o scalenie, zwykle jest ona sprawdzana przez partnera, zanim zmiany zostaną scalone w gałąź repozytorium master. Teraz dowiedzmy się, z jakimi różnymi sytuacjami możemy się spotkać podczas przeglądu kodu.

Sytuacja 1: muszę zmienić ostatnie zatwierdzenie

Wyobraź sobie przypadek, w którym recenzent spojrzał na styles.css.scss i zasugerował zmianę. W takim przypadku zmiana jest bardzo prosta, ponieważ zmiany w arkuszu stylów są częścią ostatniego zatwierdzenia w twojej gałęzi. Oto jak możemy sobie z tym poradzić;

  • Dokonujesz bezpośrednio niezbędnych zmian w styles.css.scss w swoim oddziale.
  • Raz skończyłeś ze zmianami, dodaj je do etapu; uruchom git add styles.css.scss.
  • Po wprowadzeniu zmian musimy dodać je do naszego ostatniego zatwierdzenia; uruchom git commit --amend.
    • Zestawienie poleceń: w tym przypadku „prosimy polecenie git commit o poprawienie wszelkich zmian obecnych w etap do ostatniego zatwierdzenia.
  • To otworzy twoje ostatnie zatwierdzenie w edytorze tekstu zdefiniowanym przez Git, który zawiera komunikat o zatwierdzeniu Dodaj style do nawigacji.
  • Ponieważ zaktualizowaliśmy tylko deklarację CSS, nie musimy zmieniać informacji o zatwierdzeniu.W tym momencie możesz po prostu zapisać i wyjść z edytora tekstu, który otworzył dla ciebie Git, a twoje zmiany zostaną odzwierciedlone w zatwierdzeniu.

Ponieważ zmodyfikowałeś istniejące zatwierdzenie, te zmiany są wymagane do wymuszenia wypchnięcia do zdalnego repozytorium za pomocą git push --force-with-lease <remote_name> <branch_name>. To polecenie nadpisuje zatwierdzenie Add styles for navigation w zdalnym repozytorium zaktualizowanym zatwierdzeniem, które właśnie wprowadziliśmy w naszym lokalnym repozytorium.

Jedna rzecz, o której należy pamiętać podczas wymuszania wypychania gałęzi polega na tym, że jeśli pracujesz na tej samej gałęzi z wieloma osobami, wymuszone wypychanie może powodować problemy dla innych użytkowników, gdy próbują normalnie wypchnąć swoje zmiany w zdalnej gałęzi, która ma nowe zatwierdzenia wymuszone. Dlatego mądrze korzystaj z tej funkcji. Możesz dowiedzieć się więcej o opcjach wymuszonych wypychania Git tutaj.

Sytuacja 2: Muszę zmienić konkretną zmianę

W poprzedniej sytuacji poprawka była dość prosta, ponieważ musieliśmy zmodyfikować tylko nasze ostatnie zatwierdzenie Git, ale wyobraź sobie, że recenzent zasugerował zmianę czegoś w _navigation.html.haml. W tym przypadku jest to drugie zatwierdzenie od góry, więc jego zmiana nie będzie tak bezpośrednia, jak w pierwszej sytuacji. Zobaczmy, jak sobie z tym poradzimy:

Kiedykolwiek zatwierdzenie jest wykonany w gałęzi, jest identyfikowany przez unikalny ciąg skrótu SHA1. Pomyśl o tym jak o unikalnym identyfikatorze, który oddziela jedno zatwierdzenie od drugiego. Możesz wyświetlić wszystkie zatwierdzenia wraz z ich skrótami SHA1 w gałęzi, uruchamiając git log. Dzięki temu zobaczysz wynik wyglądający mniej więcej tak, jak poniżej, gdzie najnowsze zatwierdzenia znajdują się na górze;

Tutaj pojawia się polecenie git rebase. Ilekroć chcemy edytować konkretne zatwierdzenie za pomocą git rebase, musimy najpierw zmienić bazę naszej gałęzi, cofając się HEAD do punktu tuż przed zmianą, którą chcemy edytować. W naszym przypadku musimy zmienić zatwierdzenie, które brzmi Page Navigation View.

Tutaj zwróć uwagę na skrót zatwierdzenia, który znajduje się tuż przed zatwierdzeniem, które chcemy zmodyfikować; skopiuj hash i wykonaj następujące kroki:

  • Przeładuj gałąź, aby przejść do zatwierdzenia przed zatwierdzeniem docelowym; uruchom git rebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20
    • Zestawienie poleceń: Tutaj „uruchamiamy Git” s rebase polecenie z trybem interaktywnym z podanym hashem SHA1 jako commit do rebase to.
  • Spowoduje to uruchomienie komendy rebase dla Gita w trybie interaktywnym i otworzy twój edytor tekstu pokazujący wszystkie twoje zatwierdzenia, które pojawiły się po zatwierdzeniu, do którego zmieniono bazę . Będzie wyglądać mniej więcej tak:

Zwróć uwagę, że każde zatwierdzenie ma słowo pick przed nim, aw treści poniżej znajdują się wszystkie możliwe słowa kluczowe, których możemy użyć. Ponieważ chcemy edytować zatwierdzenie, musimy zmienić pick 4155df1cdc7 Page Navigation View na edit 4155df1cdc7 Page Navigation View. Zapisz zmiany i wyjdź z edytora.

Teraz twoja gałąź jest przebudowana do punktu w czasie tuż przed dokonanym zatwierdzeniem, które obejmowało _navigation.html.haml. Otwórz plik i wprowadź żądane zmiany zgodnie z opinią o recenzji. Gdy skończysz ze zmianami, przeprowadź je, uruchamiając git add _navigation.html.haml.

Ponieważ dokonaliśmy zmian, nadszedł czas, aby przenieść gałąź HEAD z powrotem do zatwierdzenie, które pierwotnie mieliśmy (włączając w to również nowe zmiany, które dodaliśmy), uruchom git rebase --continue, to otworzy twój domyślny edytor w terminalu i pokaże ci komunikat o zatwierdzeniu, który edytowaliśmy podczas rebase; Page Navigation View. Jeśli chcesz, możesz zmienić tę wiadomość, ale na razie zostawimy ją tak, jak jest, więc zapisz i zamknij edytor. W tym momencie Git odtworzy ponownie wszystkie zatwierdzenia następujący po zatwierdzeniu, które właśnie edytowałeś, a teraz gałąź HEAD powraca do pierwszego zatwierdzenia, które mieliśmy pierwotnie, i obejmuje również nowe zmiany wprowadzone w jednym z zatwierdzeń.

Ponieważ ponownie zmodyfikowaliśmy zatwierdzenie, które jest już obecne w zdalnym repozytorium, musimy ponownie wymusić wypchnięcie tej gałęzi za pomocą git push --force-with-lease <remote_name> <branch_name>.

Sytuacja 3 : Muszę dodawać, usuwać lub łączyć zatwierdzenia

Często zdarza się, że wykonałeś kilka zatwierdzeń, aby naprawić coś, co zostało wcześniej popełnione. Teraz zredukujmy je tak bardzo, jak to tylko możliwe, łącząc je z oryginalnymi zatwierdzeniami.

Wszystko, co musisz zrobić, to rozpocząć interaktywne ponowne bazowanie, tak jak w innych scenariuszach.

Teraz wyobraź sobie, że chcesz połączyć wszystkie te poprawki w c22a3fa0c5c Render navigation partial. Wystarczy:

  1. Przenieś poprawki w górę, tak aby znajdowały się tuż pod zatwierdzeniem, które chcesz zachować na końcu.
  2. Zmień pick na squash lub fixup dla każdej z poprawek.

Uwaga: squash zachowuje komunikaty o zatwierdzeniach w opisie. fixup zapomni komunikatów o zatwierdzeniach poprawek i zachowa oryginał.

Otrzymasz coś takiego:

Zapisz zmiany, wyjdź z edytora , i jesteś skończony! Oto wynikowa historia:

Tak jak poprzednio, wszystko, co musisz teraz zrobić, to git push --force-with-lease <remote_name> <branch_name> i zmiany są gotowe.

Jeśli chcesz całkowicie usunąć zatwierdzenie z gałęzi, zamiast squash lub fixup, po prostu napisz drop lub po prostu usuń tę linię.

Unikaj konfliktów

Aby uniknąć konfliktów, upewnij się, że zatwierdzasz „przesuwanie w górę osi czasu” nie dotyka tych samych plików, które zostały dotknięte przez zatwierdzenia pozostawione po nich.

Wskazówka : Szybkie poprawki

Jeśli dokładnie wiesz, które zatwierdzenie chcesz naprawić, wykonując zatwierdzenie nie musisz tracić cykli mózgowych na myślenie o dobrych tymczasowych nazwach dla „Poprawka 1”, „Poprawka 2”,…, „Poprawka 42”.

Krok 1: Poznaj --fixup

Po przygotowaniu zmian naprawiających wszystko, co wymaga naprawy, po prostu Git zatwierdź wszystkie zmiany w ten sposób:

(Zauważ, że jest to skrót dla zatwierdzenia c22a3fa0c5c Render navigation partial)

Spowoduje to wygenerowanie komunikatu o zatwierdzeniu: fixup! Render navigation partial.

Krok 2: I pomocnik --autosquash

Łatwa interaktywna rebase. Możesz mieć git umieszczać fixup automatycznie we właściwych miejscach.

git rebase -i 4155df1cdc7 --autosquash

Historia będzie wyświetlana w następujący sposób:

Wszystko gotowe przejrzyj i kontynuuj.

Jeśli czujesz się na siłach, możesz przeprowadzić nieinteraktywną rebase git rebase --autosquash, ale tylko wtedy, gdy lubisz żyć w niebezpieczeństwie. nie mam możliwości przejrzenia tworzonych squashów przed ich ponownym zastosowaniem.

Sytuacja 4: Moja historia zatwierdzeń Git nie ma sensu, potrzebuję nowego startu!

Jeśli „Pracując nad dużą funkcjonalnością, często zdarza się, że wprowadzanych jest kilka poprawek i zmian opinii zwrotnych, które są często zatwierdzane. Zamiast stale zmieniać bazę gałęzi, możemy pozostawić czyszczenie zatwierdzeń do końca rozwoju.

Tutaj tworzenie plików poprawek jest niezwykle przydatne. W rzeczywistości pliki poprawek były głównym sposobem udostępniania kodu pocztą e-mail podczas współpracy w dużych projektach open source, zanim usługi oparte na Git, takie jak GitLab, były dostępne dla programistów. Wyobraź sobie, że masz taką gałąź (np. add-page-navigation), w której jest mnóstwo zatwierdzeń, które nie przekazują jasno podstawowych zmian. Oto jak możesz stworzyć plik łatki dla wszystkich zmiany, które wprowadziłeś w tej gałęzi:

  • Pierwszym krokiem tworzenia pliku poprawki jest upewnienie się, że Twoja gałąź zawiera wszystkie zmiany obecne w master gałąź i nie ma z nią konfliktów.
  • Możesz uruchomić git rebase master lub git merge master podczas ponownego sprawdzania w gałęzi add-page-navigation, aby pobrać wszystkie zmiany z master do swojej gałęzi.
  • Teraz utwórz plik poprawki ; uruchom git diff master add-page-navigation > ~/add_page_navigation.patch.
    • Zestawienie poleceń: tutaj „używamy funkcji porównywania Gita” i pytamy o różnicę między master branch i add-page-navigation branch i przekierowanie danych wyjściowych (przez symbol >) do pliku o nazwie add_page_navigation.patch w naszych nas er katalog domowy (zwykle ~/ w systemach operacyjnych * nix).
  • Możesz określić dowolną ścieżkę, którą chcesz zachować ten plik in, a nazwa i rozszerzenie pliku mogą być dowolne.
  • Po uruchomieniu polecenia i nie widać żadnych błędów, generowany jest plik poprawki.
  • Teraz do kasy master oddział; uruchom git checkout master.
  • Usuń gałąź add-page-navigation z lokalnego repozytorium; uruchom git branch -D add-page-navigation. Pamiętaj, że mamy już zmiany tej gałęzi w utworzonym pliku łatki.
  • Teraz utwórz nową gałąź o tej samej nazwie (podczas gdy master jest wyrejestrowany); uruchom git checkout -b add-page-navigation.
  • W tym momencie jest to nowa gałąź i nie zawiera żadnych zmian.
  • Na koniec zastosuj Twoje zmiany z pliku poprawki; git apply ~/add_page_navigation.patch.
  • Tutaj wszystkie zmiany są zastosowane w gałęzi i będą wyglądać jako niezatwierdzone, tak jakby wszystkie modyfikacje gdzie to zrobiono, ale żadna z modyfikacji nie została faktycznie zatwierdzona w gałęzi.
  • Teraz możesz zatwierdzić pojedyncze pliki lub pliki pogrupowane według obszaru wpływu w żądanej kolejności ze zwięzłymi komunikatami o zatwierdzeniach.

Podobnie jak w poprzednich sytuacjach, w zasadzie zmodyfikowaliśmy całą gałąź, więc nadszedł czas, aby wymusić push!

Podsumowanie

Chociaż omówiliśmy większość typowych i podstawowych sytuacji, które pojawiają się w codziennym przepływie pracy z Gitem, przepisywanie historii Git to rozległy temat, a gdy się z nim zapoznasz powyższe wskazówki, możesz nauczyć się bardziej zaawansowanych koncepcji na ten temat w oficjalnej dokumentacji Git. Happy git „ing!

Zdjęcie pan xiaozhen na Unsplash

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *