Git Cherry-pick vs Merge Workflow

302

Zakładając, że jestem opiekunem repozytorium i chcę pobierać zmiany od współautora, istnieje kilka możliwych przepływów pracy:

  1. I cherry-pickkażda popełnienia z pilota (w tej kolejności). W takim przypadku git zapisuje zatwierdzenie jako niezwiązane ze zdalną gałęzią.
  2. I mergegałąź, wprowadzając wszystkie zmiany i dodając nowe zatwierdzenie „konfliktowe” (w razie potrzeby).
  3. I mergekażdy popełnić ze zdalnego oddział indywidualnie (ponownie w kolejności), pozwalając konflikty powinny być rejestrowane za każdym popełnienia, zamiast zgrupowane razem jako jeden.
  4. Dla kompletności, możesz zrobić rebase(tak samo jak cherry-pickopcję?), Jednak rozumiem, że może to powodować zamieszanie dla autora. Może to eliminuje opcję 1.

W obu przypadkach 2 i 3 git zapisuje historię gałęzi zatwierdzeń, w przeciwieństwie do 1.

Jakie są zalety i wady pomiędzy użyciem jednej cherry-picklub mergeopisanych metod? Rozumiem, że metoda 2 jest normą, ale uważam, że rozwiązanie dużego zatwierdzenia za pomocą pojedynczego scalenia „konfliktu” nie jest najczystszym rozwiązaniem.

cmcginty
źródło

Odpowiedzi:

296

Zarówno rebase(i cherry-pick) i mergemają swoje zalety i wady. Popieram mergetutaj, ale warto zrozumieć oba. (Zajrzyj tutaj, aby znaleźć alternatywną, dobrze uzasadnioną odpowiedź z wyszczególnieniem przypadków, w których rebasejest preferowany).

mergejest korzystniejszy cherry-picki rebasena kilka powodów.

  1. Solidność . Identyfikator SHA1 zatwierdzenia identyfikuje go nie tylko sam w sobie, ale także w odniesieniu do wszystkich innych zatwierdzeń, które go poprzedzają. Daje to gwarancję, że stan repozytorium na danym SHA1 jest identyczny we wszystkich klonach. Teoretycznie nie ma szans, że ktoś zrobił coś, co wygląda jak ta sama zmiana, ale w rzeczywistości psuje lub porywa twoje repozytorium. Możesz wybierać poszczególne zmiany i są one prawdopodobnie takie same, ale nie masz gwarancji. (Jako drugorzędny drugorzędny problem nowe zatwierdzone wybory zajmą dodatkowe miejsce, jeśli ktoś inny wybierze ponownie w tym samym zatwierdzeniu, ponieważ oba będą obecne w historii, nawet jeśli kopie robocze będą identyczne.)
  2. Łatwość użycia . Ludzie zazwyczaj mergedość łatwo rozumieją przebieg pracy. rebasejest zwykle uważany za bardziej zaawansowany. Najlepiej zrozumieć oba, ale ludzie, którzy nie chcą być ekspertami w zakresie kontroli wersji (co z mojego doświadczenia obejmowało wielu kolegów, którzy są cholernie dobrzy w tym, co robią, ale nie chcą spędzać dodatkowego czasu), mają łatwiej czas po prostu się łączy.

Nawet przy dużym obciążeniu roboczym rebasei cherry-picknadal są przydatne w określonych przypadkach:

  1. Jednym minusem mergejest zagracona historia. rebaseZapobiega rozproszeniu długiej serii zatwierdzeń w twojej historii, tak jak w przypadku okresowego łączenia zmian innych. To w rzeczywistości jego główny cel, gdy go używam. To, na co chcesz bardzo uważać, to nigdy nie rebasekodować kodu udostępnionego innym repozytoriom. Kiedy pushedycja jest zatwierdzona, ktoś inny mógł ją zatwierdzić, a ponowne bazowanie w najlepszym wypadku spowoduje rodzaj duplikacji omówiony powyżej. W najgorszym wypadku możesz skończyć z bardzo zdezorientowanym repozytorium i subtelnymi błędami, które zajmie ci dużo czasu.
  2. cherry-pick jest przydatny do próbkowania niewielkiego zestawu zmian z gałęzi tematycznej, którą w zasadzie postanowiłeś odrzucić, ale zdałeś sobie sprawę, że jest kilka przydatnych elementów.

Jeśli chodzi o łączenie wielu zmian w jedną: jest to o wiele prostsze. Połączenie wielu zestawów zmian może być bardzo uciążliwe, gdy zaczniesz mieć ich wiele. Rozdzielczość scalania w git (oraz w Mercurial i na Bazaar) jest bardzo dobra. Przez większość czasu nie będziesz mieć problemów z łączeniem nawet długich oddziałów. Generalnie łączę wszystko naraz i tylko w przypadku dużej liczby konfliktów wykonuję kopię zapasową i ponownie uruchamiam fragmentarycznie scalanie. Nawet wtedy robię to w dużych kawałkach. Jako bardzo realny przykład miałem kolegę, który miał 3 miesiące zmian do scalenia i dostałem około 9000 konfliktów w 250000 bazach kodu linii. Naprawiliśmy scalanie wartości jednego miesiąca: konflikty nie narastają liniowo, a robienie tego w kawałkach skutkuje dalekomniej niż 9000 konfliktów. Wciąż było dużo pracy, ale nie tyle, ile próba zrobienia tego pojedynczo.

twaróg
źródło
1
W rzeczywistości teoretycznie istnieje szansa, że ​​Mallory może uszkodzić twoje repozytorium, tworząc zatwierdzenia z tym samym SHA1, ale inną zawartością, prawdopodobnie nie zdarzy się to nigdy w praktyce. :)
Bombe,
1
Ha :) Miałem na myśli „teoretycznie szanse są tak niskie, że możesz polegać na tym, że się nie dzieje”, ale masz rację, że brzmi to zawadiacko.
kwark
Co sądzisz o „merge - quiz”?
cmcginty,
@Bombe Jeśli Mallory chce odnieść sukces, będzie musiała zbudować oryginalne zatwierdzenie i drugie zatwierdzenie z tym samym SHA1. Kolejne pytanie może brzmieć: jakie są szanse, że pojawią się dwa (nieco) fałszywe zobowiązania, a ty ich nie zauważysz? ;)
João Portela
64
9000 konfliktów? Rzuciłem pracę i zostałem pszczelarzem.
Sebastian Patten
95

Moim zdaniem wybieranie wiśni powinno być zarezerwowane na rzadkie sytuacje, w których jest to wymagane, na przykład, jeśli dokonałeś poprawki bezpośrednio w gałęzi „master” (trunk, main gałąź programistyczna), a następnie zdałeś sobie sprawę, że należy ją również zastosować do „. Powinieneś oprzeć przepływ pracy albo na scalaniu, albo na rebase (lub „git pull --rebase”).

Proszę pamiętać, że wybranie Cherry lub rebased jest inne z punktu widzenia Git (ma inny identyfikator SHA-1) niż oryginał, więc różni się od zatwierdzenia w zdalnym repozytorium. (Rebase zwykle sobie z tym radzi, ponieważ sprawdza identyfikator łatki, tj. Zmiany, a nie identyfikator zatwierdzenia).

Również w git możesz łączyć wiele gałęzi jednocześnie: tak zwane scalanie ośmiornic . Zauważ, że scalenie ośmiornicy musi się udać bez konfliktów. Niemniej jednak może być przydatne.

HTH.

Jakub Narębski
źródło
19
+1 za punkt, w którym rebase / pick-picking faktycznie „kopiują” zatwierdzenia i dlatego tracą powiązanie z pierwotnym zatwierdzeniem.
studgeek
1
Używamy cherry-pick w ten sposób, wyłącznie do przenoszenia commits dla poprawek błędów (być może BARDZO MAŁYCH funkcji) do istniejącej gałęzi wydania w celu przygotowania łatki. Funkcje obejmujące wiele zatwierdzeń zazwyczaj wymagają przejścia do gałęzi wydania opartej na masterie.
foxxtrot
3
@foxxtrot: Innym rozwiązaniem jest utworzenie oddzielnej gałęzi dla poprawki błędu, na podstawie najstarszego zatwierdzenia, która wykazuje ten błąd, i scalenie go w „keep” i w „master” ... chociaż w tym przypadku musisz wiedzieć, że wspomniana poprawka dotyczy obu gałęzi.
Jakub Narębski
4
@Jakub Dwa polecenia, które są niezbędne do utworzenia i scalenia gałęzi git blamepoprawki błędów : aby znaleźć zatwierdzenie, które wprowadziło błąd, i git branch --containsustalić, gdzie połączyć gałąź. Bardziej szczegółowo opisane w tym poście
gcbenison
-10

Rebase i Cherry-pick to jedyny sposób na zachowanie czystej historii zatwierdzeń. Unikaj używania scalania i unikaj tworzenia konfliktów scalania. Jeśli używasz gerrit, ustaw jeden projekt, aby Scalić, jeśli to konieczne, a jeden projekt w tryb wyboru i spróbuj sam.

Nagaraj Magadum
źródło
wcale nie jest jasne, jak to odpowiada na pytanie, może niektóre przykłady przyniosą trochę światła.
Adrian Nasui,
1
Fakt, że twoja historia wyglądałaby prosto, nie oznacza, że ​​łatwiej byłoby ją zrozumieć.
nicolimo86,
Scalanie to zwykły sposób na uzyskanie czystej historii. Cherry-pick i rebase są używane głównie w sytuacjach, w których musisz zmodyfikować historię. Co oznacza, że ​​łączenie powinno zawsze być pierwszym wyborem. Bo zmiana bazy zmieniła to, co jest bardzo niebezpieczne, gdy pracujesz z pilotami i wieloma osobami.
Radon8472,
Ten facet tutaj zasługuje na medal. Wie, że nadal będzie głosowany, ale to dobra odpowiedź. Sława.
PW Kad
Niestety, do tej pory nie widziałem tych komentarzy. Proszę wypróbować je w środowisku testowym przed zakończeniem i zrób to, co działa dla Ciebie! Mam około 600 programistów uczestniczących w wielu gałęziach produktów, nie dbam o to, co robią programiści w lokalnym obszarze roboczym, gdy zmiana zostanie zgłoszona do integracji, powinna być w stanie wybrać gałąź rozwoju, a czasem gałąź wydania lub naprawy błędów. FYI ... Używam Gerrit.
Nagaraj Magadum