Strategia przeglądu kodu przed scaleniem w celu opanowania z gałęzi funkcji

22

Ja i mój zespół używamy gałęzi funkcji (z git). Zastanawiam się, która strategia jest najlepsza do przeglądu kodu przed scaleniem z master.

  1. Sprawdzam nowy oddział w master, nazwijmy go fb_ # 1
  2. Popełniam kilka razy, a potem chcę scalić go z powrotem z mistrzem
  3. Zanim scalę, ktoś powinien dokonać przeglądu kodu

Teraz są 2 możliwości:

1. miejsce

  1. Scalić kapitanowi fb_ nr 1 ( nie fb_ nr 1 do opanowania), aby uczynić go jako up-to-date, jak to możliwe
  2. Kolega z drużyny sprawdza zmiany między głową główną a głową fb_ # 1
  3. Jeśli fb_ # 1 jest w porządku, łączymy fb_ # 1 z masterem
  4. Plusy: brak recenzji przestarzałego kodu
  5. Minusy: jeśli ktoś inny scali coś między „1” i „2.” jego zmiany pojawiają się w recenzji, choć należą do innej recenzji.

2. miejsce

  1. Kolega z drużyny sprawdza zmiany między punktem kasy (git merge-base master fb_ # 1) a głową fb_ # 1
  2. Plusy: widzimy dokładnie, co zostało zmienione podczas pracy nad gałęzią funkcji
  3. Minusy: w recenzji może pojawić się przestarzały kod.

Jak myślisz, który sposób jest lepszy i dlaczego ? Może istnieje inne bardziej odpowiednie podejście?

Andrzej Gis
źródło

Odpowiedzi:

9

Istnieje wariant Twojej 1. opcji:

  1. połącz master z fb_ # 1 (nie fb_ 1 z master), aby był jak najbardziej aktualny
  2. Kolega z drużyny sprawdza zmiany między mistrzem w punkcie, w którym się scaliłeś, a głową fb_ # 1
  3. Jeśli fb_ # 1 jest w porządku, łączymy fb_ # 1 z masterem
  4. szybkie sprawdzenie, czy scalenie jest prawidłowe

na przykład.

... ma -- ... -- mm -- ... -- mf  <- master
      \            \         /
       f1 ... fn -- fm -----      <-- fb_#1

gdzie:

  • ma jest przodkiem mistrza, a fb_ # 1.
  • fn jest ostatnią zmianą w twoim oddziale
  • mm jest zatwierdzeniem, które było master / HEAD w momencie, gdy połączyłeś się z oddziałem (dając fm ).

Tak więc porównujesz mm i fm w swojej początkowej recenzji, a następnie szybko sprawdzasz po scaleniu mf, aby upewnić się, że nic znaczącego nie zmieniło się na wzorcu podczas kroków 1-3. Wydaje się, że ma to wszystkie zalety i wady pierwszego przeglądu.

Zakłada się, że przegląd jest szybki w porównaniu z normalną częstotliwością zmian wprowadzanych do master, więc fm -> mf często byłby szybkim przewijaniem do przodu.

Jeśli tak nie jest , z jakiegokolwiek powodu minusy po prostu przejdą od przeglądu początkowego do przeglądu po scaleniu, a prostsze może być po prostu scalenie bezpośrednio w wzorcu i wykonanie tam pojedynczej recenzji.

Bezużyteczny
źródło
Jak uzyskać „punkt, który scaliłeś”? Czy „Git Merge-Base Master Head” będzie w porządku, czy pokaże początkowy punkt rozgałęzienia?
Andrzej Gis,
O ile celowo nie zaktualizujesz wzorca po scaleniu, będzie on tylko wzorcem.
Bezużyteczne
Tak, ale jak zdobyć ten punkt, jeśli ktoś inny go zaktualizuje?
Andrzej Gis
Gdy jesteś w gałęzi fb, użyj git show HEAD. Ponieważ będzie to fm commit commit , wyświetli listę obojga rodziców. Tak, masz hash mm . Alternatywnie, możesz w trywialny sposób zobaczyć rodzica w gitkdowolnej przeglądarce git
Bezużyteczne
13

3. miejsce

  • Państwo zmieniają bazę oddział na mistrza zarówno Make it up-to-date i zachować zmiany rozdzielić.

    To tworzy nową historię oddziału. Będą to nowe wersje z nowymi identyfikatorami, które będą miały tę samą treść, ale będą pochodzić z najnowszego wzorca i nie będą łączyły się ze starymi wersjami. Stare wersje są nadal dostępne w „reflog”, jeśli musisz się do nich odwoływać, np. Ponieważ okazało się, że popełniłeś błąd przy rozwiązywaniu konfliktu. Poza tym są bezwartościowe. Domyślnie Git przycina dziennik po 3 miesiącach i odrzuca stare wersje.

  • Korzystasz z interaktywnego rebase ( git rebase -ii git commit --amend) do zmiany kolejności, edycji i czyszczenia zmian, aby każda z nich dokonała zmiany logicznie zamkniętej.

    To ponownie tworzy nową historię, tym razem z dodatkową korzyścią, że możesz zrestrukturyzować zmiany, aby były jak najbardziej sensowne podczas przeglądu.

  • Plusy:

    • brak przestarzałego kodu w recenzji
    • widzimy dokładnie, co zostało zmienione podczas pracy nad gałęzią funkcji
  • Cons:
    • trochę więcej pracy
    • musisz uważać, aby nie wyodrębnić niczego, co jest już scalone lub udostępnione, a odbiorca nie oczekuje, że zostanie ono przewinięte.

Zwykle dodatkowa praca oznacza, że ​​najpierw dokładnie zapoznasz się z kodem, co również spowoduje wiele problemów.

To właśnie robią Linux i Git. I nie jest niczym niezwykłym, że seria 20 do 25 łatek jest poddawana przeglądowi i wielokrotnie przepisywana w tych projektach.

W rzeczywistości Linux robił to od samego początku projektu, kiedy ich kontrola wersji z wyboru była tarballami i łatkami. Kiedy wiele lat później Linus postanowił stworzyć git, był to główny powód wdrożenia rebasepolecenia i jego interaktywnego wariantu. Również ze względu na to git ma oddzielne pojęcie autora i committer . Autor jest pierwszym, który stworzył wersję, a osoba, która ją dotknęła, jako ostatnia. Ponieważ zarówno w systemie Linux, jak i Git łatki są nadal przesyłane pocztą elektroniczną, prawie nigdy nie są to ta sama osoba.

Jan Hudec
źródło
1
+1 również OP nie pytał o kolejne kroki, ale aby wprowadzić twoją funkcję w master, możesz użyć takiego, merge --no-ffktóry wyraźnie pokaże gałąź na master zamiast funkcji po prostu znikającej w pozostałych
commits
@stijn: --no-ffma swoje zalety i wady. Osobiście uważam, że to więcej hałasu niż cokolwiek innego. YMMV.
Jan Hudec
tak, to kwestia preferencji. Jeśli mistrz jest normalnie czysty i prosty, nie mam nic przeciwko dużym funkcjom posiadającym osobną „bańkę”. Jeśli mistrz jest już bałaganem, no-ff tylko pogorszy sytuację
stijn
Chciałbym zaakceptować tryb niż jedną odpowiedź. Idealne byłoby rozwiązanie hybrydowe. Wydaje się, że najlepszym rozwiązaniem jest użycie bazy i porównanie z punktem rozgałęzienia.
Andrzej Gis,
Second Con - Nie sądzę, że możesz to zrobić, jeśli już udostępniasz swój oddział komukolwiek. Kiedy przepisujesz historię, pojawią się niespójności.
sixtyfootersdude
4

Istnieje faktycznie trzecia możliwość - i najprawdopodobniej mnóstwo innych, ponieważ GIT jest raczej implementacją środowiska SCM niż implementacją metodologii SCM. Ta trzecia możliwość oparta jest na rebase.

rebaseGIT Komenda wykonuje serię commit (zazwyczaj z punktu rozgałęzienia do czubka swojego tematu gałęzi topic) i odtworzyć je gdzieś indziej (zazwyczaj na końcu swojego oddziału integracyjnego, na przykład master). rebaseKomenda wytwarza nowe rewizje, które daje możliwość rozmieszczanie zobowiązuje się w formie, która jest łatwiejsza do przeglądu. Daje to nową serię zatwierdzeń, podobną do topicpoprzedniej, ale wyglądającą na zakorzenioną w górnej części gałęzi integracji. Ta nowa gałąź jest nadal wywoływana topicprzez GIT, więc stare odwołanie jest odrzucane. Nieformalnie nazywam topic-0pierwotny stan twojego oddziału topic-1i tak dalej na temat różnych refaktoryzacji.

Oto moja propozycja dla twojego topicoddziału:

  1. (Opcjonalny etap) można interaktywnie rebase tematu oddział topicna jego punkcie rozgałęzienia (zobacz --fixupopcję commiti -ioraz --autosquashopcje rebase), co daje możliwość przepisać zobowiązuje w sposób, który jest łatwiejszy do przeglądu ci. To powoduje powstanie oddziału topic-1.

  2. Bazujesz na gałęzi tematu u góry gałęzi integracji, przypomina to scalanie, ale „nie zanieczyszcza” historii łączeniem, które jest jedynie artefaktem inżynierii oprogramowania. To powoduje powstanie oddziału topic-2.

  3. Wyślij topic-2do członka drużyny, który dokona przeglądu na końcu master.

  4. Jeśli topic-2wszystko jest w porządku, połącz je w master.

UWAGA Gałęzie - gdzie gałąź odnosi się do drzewa zatwierdzeń - wszystkie będą nazywane przez GIT tak samo, więc pod koniec procesu tylko gałąź topic-2ma nazwę w GIT.

Plusy:

  • Brak sprawdzonego kodu.
  • Brak fałszywych recenzji „połączeń zagranicznych” (zjawisko opisane w 1).
  • Możliwość przepisania zmian w czysty sposób.

Cons:

  • Zamiast jednego oddziału topic-0, nie ma trzy gałęzie artefakty topic-0, topic-1a topic-2które są tworzone w commit drzewo. (Chociaż w dowolnym momencie tylko jeden z nich ma nazwę w GIT.)

W twoim pierwszym scenariuszu «jeśli ktoś połączy coś między" 1 " a „2.” »oznacza czas między utworzeniem punktu rozgałęzienia a czasem, w którym zdecydujesz się połączyć. W tym scenariuszu «jeśli ktoś scalił coś między„ 1 ” a „2.” »oznacza czas między rebase a scaleniem, który zwykle jest bardzo krótki. Dlatego w przedstawionym przeze mnie scenariuszu można „zablokować” mastergałąź na czas scalania, nie zakłócając w sposób znaczący przepływu pracy, podczas gdy w pierwszym scenariuszu jest to niepraktyczne.

Jeśli przeprowadzasz systematyczne przeglądy kodu, prawdopodobnie dobrym pomysłem jest zmiana kolejności zatwierdzeń w odpowiedni sposób (krok opcjonalny).

Zarządzanie artefaktami gałęzi pośredniej stanowi trudność tylko wtedy, gdy dzielisz je między repozytoriami.

Michael Le Barbier Grünewald
źródło
Nie powinno być topic-0, topic-1i topic-2gałęzie. W momencie zakończenia rebase poprzednia wersja nie ma znaczenia. Więc nie będzie to topic@{1}, topic@{2}, topic@{yesterday}, topic@{3.days.ago}itd., Aby zapisać swój tyłek w przypadku uznasz wkręca rozwiązywanie konfliktów w rebase.
Jan Hudec
Trzy gałęzie istnieją, ale nie mają nazwy (bez referencji). Może powinienem to podkreślić.
Michael Le Barbier Grünewald
Zmiany istnieją i są wskazywane przez wpisy ponownego logowania. Ale jak oddziałów jest tylko jedna, topic. Ponieważ gałąź w git to tylko nazwa.
Jan Hudec
W jaki sposób chroni mnie przed „zagranicznymi połączeniami”? Co się stanie, jeśli ktoś połączy się z mistrzem po tym, jak wyślę temat-2 do kolegi z drużyny i że kolega z drużyny oceni go na podstawie wskazówki mistrza?
Andrzej Gis,
@JanHudec W każdej chwili istnieje tylko jeden oddział zwany topicw GIT, jest zawsze jednym z oddziałów (oddział w popełnić jak drzewo, a nie w odniesieniu GIT) I oznakowane topic-0, topic-1, topic-2.
Michael Le Barbier Grünewald