Git Cherry-pick vs Merge Workflow

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

  1. I cherry-pick każdy commit z pilota (w kolejności). W tym przypadku Git zapisuje commit jako niezwiązany ze zdalną gałęzią.
  2. i merge gałąź, pobierając wszystkie zmiany i dodając nowy commit "conflict" (w razie potrzeby).
  3. I merge każdy commit ze zdalnej gałęzi osobno (ponownie w kolejności), pozwalając na rejestrowanie konfliktów dla każdego commita, zamiast grupować wszystkie razem jako jeden.
  4. dla kompletności, można zrobić rebase (tak samo jak cherry-pick opcja?), jednak rozumiem, że może to powodować zamieszanie dla wnoszącego. Może to eliminuje opcję 1.

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

Jakie są pro i con pomiędzy użyciem cherry-pick LUB merge metody opisane? rozumiem, że metoda 2 jest normą, ale uważam, że rozwiązanie dużego commita za pomocą pojedynczego" konfliktu " nie jest najczystszym rozwiązaniem.

Author: cmcginty, 2009-08-07

3 answers

Zarówno rebase (i cherry-pick) jak i merge mają swoje wady i zalety. Argumentuję za merge tutaj, ale warto zrozumieć oba. (Poszukaj alternatywnej, dobrze argumentowanej odpowiedzi wyliczającej przypadki, w których preferowane jest rebase.)

merge jest preferowana przez cherry-pick i rebase z kilku powodów.

  1. solidność . Identyfikator SHA1 commita identyfikuje go nie tylko sam w sobie, ale także w odniesieniu do wszystkich innych commitów to poprzedza to. Daje to gwarancję, że stan repozytorium w danym SHA1 jest identyczny we wszystkich klonach. Nie ma (w teorii) szans, że ktoś zrobił coś, co wygląda jak ta sama zmiana, ale faktycznie psuje lub przejmuje Twoje repozytorium. Możesz wybrać poszczególne zmiany i są one prawdopodobnie takie same, ale nie masz gwarancji. (Jako drugorzędny problem nowy commit cherry-picked zajmie dodatkowe miejsce, jeśli ktoś inny cherry-picked w tym samym Zatwierdź ponownie, ponieważ oba będą obecne w historii, nawet jeśli Twoje kopie robocze będą identyczne.)
  2. łatwość użycia. Ludzie dość łatwo rozumieją obieg pracy merge. rebase Najlepiej zrozumieć oba, ale ludzie, którzy nie chcą być ekspertami w kontroli wersji (co z mojego doświadczenia wynika z wielu kolegów, którzy są cholernie dobrzy w tym, co robią, ale nie chcą spędzać dodatkowego czasu) mają łatwiejszy czas po prostu / align = "left" /

Nawet z Merge-heavy workflow rebase i cherry-pick są nadal przydatne w szczególnych przypadkach:

  1. jednym minusem merge jest zaśmiecona historia. rebase zapobiega rozrzucaniu długich serii commitów w twojej historii, tak jak byłoby, gdybyś okresowo łączył zmiany innych. To jest w rzeczywistości jego główny cel, ponieważ go używam. To, na co chcesz być Bardzo ostrożnym, to nigdy nie rebase kod, który udostępniasz innym repozytoriom. Gdy commit zostanie pushed, ktoś inny może się na nim zaangażować, a rebasing w najlepszym wypadku spowoduje powielenie omawianego powyżej. W najgorszym przypadku 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 małego podzbioru zmian z gałęzi tematycznej, którą zasadniczo zdecydowałeś się odrzucić, ale zdałeś sobie sprawę, że jest kilka przydatnych elementów.

Co do preferowania łączenia wielu zmiany w jednym: jest po prostu o wiele prostsze. To może się bardzo żmudne do łączenia poszczególnych zestawów zmian, gdy zaczniesz mieć wiele z nich. Rozdzielczość merge w git (i w Mercurial, i w Bazaar) jest bardzo bardzo dobra. Nie napotkasz większych problemów łącząc nawet długie gałęzie przez większość czasu. Ogólnie scalam wszystko na raz i tylko jeśli pojawi się duża liczba konfliktów, wykonuję kopię zapasową i ponownie uruchamiam fragment scalania. Nawet wtedy robię to w dużych kawałkach. Jako bardzo prawdziwy przykład miałem kolegę, który miał 3 miesiące warte zmian do scalenia, i dostał jakieś konflikty 9000 w 250000 linii kodu bazy. To, co zrobiliśmy, aby naprawić, to scalanie o wartości jednego miesiąca na raz: konflikty nie narastają liniowo, a robienie tego w kawałkach skutkuje mniej niż 9000 konfliktów. To nadal było dużo pracy, ale nie tak dużo, jak próba zrobienia tego jeden commit na raz.

 266
Author: quark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:16

Moim zdaniem cherry-picking powinien być zarezerwowany dla rzadkich sytuacji, w których jest to wymagane, na przykład, jeśli zrobiłeś jakąś poprawkę bezpośrednio na gałęzi ' master '(trunk, main development branch), a następnie zdałeś sobie sprawę, że powinno być stosowane również do 'maint'. Powinieneś bazować na merge lub rebase (lub "git pull --rebase").

Proszę pamiętać, że commit cherry-picked lub rebased jest Inny z punktu widzenia Git (ma inny identyfikator SHA-1) niż oryginalny, więc jest inny niż commit w zdalnym repozytorium. (Rebase zazwyczaj radzi sobie z tym, ponieważ sprawdza patch id tzn. zmiany, a nie commit id).

Również w git możesz łączyć wiele gałęzi na raz: tzw. Octopus merge . Zauważ, że połączenie ośmiornicy musi się udać bez konfliktów. Niemniej jednak może się przydać.

HTH.

 89
Author: Jakub Narębski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 12:22:19

Rebase i Cherry-pick to jedyny sposób na zachowanie czystej historii zmian. Unikaj używania merge i unikaj tworzenia konfliktu merge. Jeśli używasz gerrit ustaw jeden projekt do scalenia w razie potrzeby i jeden projekt do trybu cherry-pick i spróbuj sam.

 -4
Author: Nagaraj Magadum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-13 06:10:38