Co oznacza wybranie zatwierdzenia w Git?

2336

Ostatnio zostałem poproszony cherry-picko zatwierdzenie.

Więc co oznacza wybranie cherry git? Jak ty to robisz?

Rahul
źródło
13
Zamiast scalania, łatwiejsze jest ponowne wybieranie z gałęzi do gałęzi docelowej (np. Master).
Levent Divilioglu,

Odpowiedzi:

2855

Zbieranie wiśni w Git oznacza wybranie zatwierdzenia z jednej gałęzi i zastosowanie go do innej.

Jest to sprzeczne z innymi sposobami, takimi jak mergei rebasektóre zwykle stosują wiele zatwierdzeń do innej gałęzi.

  1. Upewnij się, że jesteś w gałęzi, do której chcesz zastosować zatwierdzenie.

    git checkout master
    
  2. Wykonaj następujące czynności:

    git cherry-pick <commit-hash>
    

NB:

  1. Jeśli wybierzesz z publicznego oddziału, powinieneś rozważyć użycie

    git cherry-pick -x <commit-hash>
    

    Spowoduje to wygenerowanie standardowego komunikatu zatwierdzenia. W ten sposób Ty (i Twoi współpracownicy) nadal możecie śledzić pochodzenie zatwierdzenia i uniknąć konfliktów scalania w przyszłości.

  2. Jeśli masz dołączone notatki do zatwierdzenia, nie są one zgodne z wyborem. Aby je również przynieść, musisz użyć:

    git notes copy <from> <to>
    

Dodatkowe linki:

Philip Fourie
źródło
246
Jeśli wybierzesz z publicznego oddziału, powinieneś rozważyć użycie git cherry-pick -x <commit-hash>. Spowoduje to wygenerowanie standardowego komunikatu zatwierdzenia. W ten sposób Ty (i Twoi współpracownicy) nadal możecie śledzić pochodzenie zatwierdzenia i uniknąć konfliktów scalania w przyszłości.
MBober
2
Czy zbieranie wiśni jest naprawdę konieczne? Czy mieszany reset lub miękki reset nie wykonają podobnej pracy?
Nav
10
Zauważ, że jeśli masz dołączone notatki do zatwierdzenia, nie są one zgodne z wyborem. Musisz git notes copy <from> <to>ich również przynieść.
Zitrax
5
git push jest ostatnim krokiem do wprowadzenia zmian w master
czuj się dobrze i programuj
58
FYI: Zatwierdzenie semantycznie zawiera wszystkie pliki drzewa roboczego z tego momentu (i skrót mieszania poprzedniego zatwierdzenia), więc nie stosuje się całego zatwierdzenia do innego zatwierdzenia, ale zmiany, które dokonał w poprzednim zatwierdzeniu "cherry-pick commit applies the changes introduced by the named commit on the current branch"Większość ppl mają tendencję do myślenia o zatwierdzeniu jako o zmianach (jak svn was iirc), ale nie jest tak, każde zatwierdzenie odnosi się do pełnego działającego drzewa. Chociaż w tym przypadku nie robi to różnicy, może pomóc zrozumieć, dlaczego git działa tak, jak działa.
Emile Vrijdags
314

Ten cytat pochodzi z; Kontrola wersji za pomocą Git (Naprawdę świetna książka, zachęcam do jej zakupu, jeśli jesteś zainteresowany Gitem )

Edycja: Ponieważ ta odpowiedź wciąż robi wrażenie, chciałbym dodać bardzo fajny film instruktażowy na ten temat:

Youtube: Wprowadzenie do Git cherry-pick

Korzystanie z git cherry-pick Polecenie git cherry-pick commit stosuje zmiany wprowadzone przez nazwany commit w bieżącej gałęzi. Wprowadzi nowe, wyraźne zatwierdzenie. Ściśle mówiąc, użycie git cherry-pick nie zmienia istniejącej historii w repozytorium; zamiast tego dodaje się do historii. Podobnie jak w przypadku innych operacji Git, które wprowadzają zmiany w procesie stosowania mechanizmu różnicowego, konieczne może być rozwiązanie konfliktu, aby w pełni zastosować zmiany z podanego zatwierdzenia . Polecenie git cherry-pick jest zwykle używane do wprowadzania określonych zatwierdzeń z jednej gałęzi w repozytorium do innej gałęzi. Powszechnym zastosowaniem jest przekazywanie lub cofanie zmian z gałęzi serwisowej do gałęzi programistycznej.

$ git checkout rel_2.3
$ git cherry-pick dev~2 # commit F, above

przed: przed

po: po

Teoman Shipahi
źródło
12
kiedy wybrane wybory są podejmowane w jakiejś gałęzi (b1), a następnie dostarczane do mistrza. A jeśli gałąź b1 (z której pierwotnie pobrano zatwierdzenia) również jest próbowana dostarczyć do master. A co z konfliktami? Czy to jest załatwione lub jak to działa?
parasrish
3
@parasrish Tak, są już zajęci twoimi poprzednimi połączeniami. Więc zrobiłeś zmiany a, b, c, d z gałęzi (b1). Wybrałeś tylko „c”. Następnie w przyszłości, kiedy scalisz z (b1) do master, ponieważ zmiany „c” są takie same, scali tylko zmiany a, b, d i pozostaną zmiany „c”. Ale jeśli cofniesz scalanie, to cofniesz zmiany z „c”. Musisz je osobno wycofać.
Teoman shipahi
12
Należy podkreślić: w podanym przykładzie tylko różnica (F - E) dotyczy Z. To wąski przypadek. Cherry-pick może być zastosowany do zastosowania różnic między wieloma zatwierdzeniami, powiedzmy, wszystkimi różnicami między dwoma nieprzylegającymi do siebie zobowiązaniami. Na przykład po powyższym, (F - E), (E - D), (D - C) i (C - B). Jest to równoważne z zastosowaniem różnicy (F - B).
Thomas Bitonti,
2
Co się też stanie, jeśli wybrane zatwierdzenie (F w przykładzie) ma więcej niż jednego bezpośredniego poprzednika?
Thomas Bitonti,
2
@ j2emanue, innymi słowy, cherry-pick przyjmuje tylko zmiany ostatniego zatwierdzenia. Jeśli zatwierdzisz 3 razy i jeśli wybierzesz ostatni raz, nie będzie on wprowadzać zmian przy pierwszym i drugim zatwierdzeniu. Polecenie Scal weźmie wszystkie zmiany i zastosuje się do gałęzi docelowej (głównej).
Teoman shipahi
157

Zbieranie wiśni w Git ma na celu zastosowanie zatwierdzenia z jednej gałęzi do innej gałęzi. Można to zrobić, jeśli np. popełnił błąd i popełnił zmianę w niewłaściwej gałęzi, ale nie chce scalać całej gałęzi. Możesz po prostu np. cofnij zatwierdzenie i wybierz go w innej gałęzi.

Aby go użyć, wystarczy git cherry-pick hash, gdzie hashjest hash zatwierdzenia z innej gałęzi.

Pełna procedura znajduje się na stronie: http://technosophos.com/2009/12/04/git-cherry-picking-move-small-code-patches-across-branches.html

Tadeck
źródło
96

Krótki przykład sytuacji, w której potrzebujesz cherry pick

Rozważ następujący scenariusz. Masz dwie gałęzie.

a) release1 - Ta gałąź trafia do twojego klienta, ale wciąż jest kilka błędów do naprawienia .

b) master - Klasyczna gałąź master, w której możesz na przykład dodać funkcjonalność dla release2.

TERAZ : Naprawiasz coś w wersji 1 . Oczywiście potrzebujesz tej poprawki również w trybie głównym . I to jest typowy przypadek użycia do zbierania wiśni. Zatem wybór wiśni w tym scenariuszu oznacza, że pobierasz zatwierdzenie z gałęzi release1 i dołączasz ją do gałęzi master .

Daniel Perník
źródło
3
Możesz po prostu potrzebować innego sposobu. Naprawiono błąd w master i powinieneś wybrać go do wydania1. Mogą też być repozytoriami, a nie oddziałami
canbax
1
Dlaczego nie używać do tego scalania?
FreeLightman
Chciałbym: utworzyć gałąź poza wydaniem, naprawić ją w gałęzi, scalić gałąź w wersji, scalić wydanie w trybie głównym.
Jasper-M
57

cherry-pick to funkcja Git. Jeśli ktoś chce zatwierdzić określone zatwierdzenia w jednej gałęzi do gałęzi docelowej, wówczas używana jest funkcja cherry-pick.
kroki git-pick-cherry są jak poniżej.

  1. kasa (zmiana na) gałąź docelowa.
  2. git cherry-pick <commit id>
    

    Tutaj ID zatwierdzenia jest identyfikatorem aktywności innej gałęzi.

    git cherry-pick 9772dd546a3609b06f84b680340fb84c5463264f
    
  3. push do gałęzi docelowej

Odwiedź https://git-scm.com/docs/git-cherry-pick

Vijay SB
źródło
43

Przygotowałem ilustracje krok po kroku, co robi cherry-pick - oraz animację tych ilustracji (pod koniec).

  1. Przed wybraniem czereśni
    (zrobimy wybranie zatwierdzenia Lz oddziału feature): wprowadź opis zdjęcia tutaj

  1. Uruchomienie polecenia git cherry-pick feature~2
    ( feature~2jest 2 nd popełnić przed
    feature, czyli popełnić L): wprowadź opis zdjęcia tutaj

  1. Po wykonaniu polecenia ( git cherry-pick feature~2): wprowadź opis zdjęcia tutaj

To samo animowane: wprowadź opis zdjęcia tutaj


Uwaga:

Zatwierdzenie L'jest z punktu widzenia użytkownika (zatwierdzenie = migawka) dokładną kopią zatwierdzenia L.

Technicznie (wewnętrznie) jest to nowe, inne zatwierdzenie (ponieważ np. LZawiera wskaźnik do K(jako jego rodzic), podczas gdy L'zawiera wskaźnik do E).

MarianD
źródło
Czy to znaczy, że L 'będzie N -> M -> L na głównym oddziale? lub spowoduje to wyłącznie zatwierdzenie L w gałęzi master
Priyank Thakkar
1
@PriyankThakkar, tak, wyłącznie L , nic więcej (jak widać na zdjęciach / animacjach).
MarianD
22

Możesz pomyśleć, czy wybór wiśni jest podobny do rebase, czy raczej jest zarządzany jak rebase. Rozumiem przez to, że pobiera istniejące zatwierdzenie i regeneruje je, przyjmując jako punkt wyjścia szef gałęzi, w której aktualnie się znajdujesz.

rebaseTrwa popełnić że miał dominującą X i regeneruje popełnić tak jakby rzeczywiście miała rodzica Y, i to jest dokładnie to, co cherry-pickrobi.

Cherry pick to więcej o tym, jak wybierasz zatwierdzenia. Z pull(rebase), git niejawnie regeneruje lokalne zatwierdzenia na podstawie tego, co zostało ściągnięte do twojej gałęzi, ale wraz z cherry-picktobą wyraźnie wybierasz niektóre zatwierdzenia i domyślnie regenerujesz je (ich) na bieżącym oddziale.

Więc sposób, w jaki to robisz, różni się, ale pod maską są to bardzo podobne operacje - regeneracja zatwierdzeń.

Hugh
źródło
1
Uważam, że jest to dość pomocny obraz rzeczy. To implikuje, dlaczego cherry-pickzachowuje się tak, jak później, gdy gałąź docelowa jest później scalana z powrotem w gałąź źródłową. Dziękuję Panu.
Aluan Haddad,
3
Chciałbym użyć cherry pick zamiast git merge po zakończeniu funkcji. wszyscy zawsze łączą git feature_branch, kiedy ukończą funkcję. dlaczego nie użyć polecenia cherry-pick? masz jakieś przemyślenia? po co zawracać sobie głowę zgniataniem, jeśli potrafię wybrać wiśni
j2emanue
11

To trochę jak Kopiuj (skądś) i Wklej (gdzieś), ale dla określonych zatwierdzeń.

Jeśli chcesz na przykład wykonać poprawkę, możesz skorzystać z tej cherry-pickfunkcji.

Wykonaj swoją pracę cherry-pickw gałęzi deweloperskiej, a następnie mergew gałęzi wydania. Podobnie, wykonaj cherry-pickod gałęzi wydania do opanowania. Voila

Ajeet Sharma
źródło
11

Podczas pracy z zespołem programistów nad projektem zarządzanie zmianami między wieloma gałęziami git może stać się złożonym zadaniem. Czasami nie chcesz scalać całej gałęzi w inną i wystarczy wybrać jeden lub dwa konkretne zatwierdzenia. Ten proces nazywa się „zbieraniem wiśni”.

Znalazłem świetny artykuł na temat zbierania wiśni, sprawdź szczegółowe informacje: https://www.previousnext.com.au/blog/intro-cherry-picking-git

Wolfack
źródło
7

Jeśli chcesz połączyć bez identyfikatorów zatwierdzenia, możesz użyć tego polecenia

git cherry-pick master~2 master~0

Powyższe polecenie połączy trzy ostatnie zatwierdzenia master od 1 do 3

Jeśli chcesz to zrobić dla pojedynczego zatwierdzenia, po prostu usuń ostatnią opcję

git cherry-pick master~2

W ten sposób scalisz 3. zatwierdzenie od końca master.

Rachunki
źródło
To jest mylące. Myślę, że tutaj jesteś na gałęzi innej niż master, prawda? A kiedy wspomniałeś o dwóch zatwierdzeniach, odwołujesz się do zatwierdzeń <from> i <to> w celu zdefiniowania zakresu, który chcesz wybrać. Poprawny? Byłoby to bardzo pomocne, gdyby opisany został scenariusz. Dobry dodatek. Dzięki.
Saurabh Patil
6

Zastosuje określone zatwierdzenie do twojego obecnego oddziału.

To znaczy :

  • wszystkie pliki dodane przez ten zatwierdzenie zostaną dodane
  • wszystkie pliki usunięte tym zatwierdzeniem zostaną usunięte
  • wszystkie pliki zmodyfikowane przez to zatwierdzenie zostaną scalone. Oznacza to cały plik z zatwierdzenia, a nie tylko zmiany z tego zatwierdzenia!

Np .: Rozważ zatwierdzenie A.

added newFileA
modified main:
+ import './newFileA'

popełnić B

added newFileB
modified main:
+ import './newFileB'

Jeśli wybierzesz zatwierdzenie B w innym oddziale, skończysz z:

/newFileB
/main :
   import './newFileA'
   import './newFileB'

ponieważ zatwierdzenie B zawiera newFileB i main , ale nie ma newFileA , co powoduje błąd, więc używaj go ostrożnie.

mandelf
źródło
0

Fragment oficjalnych dokumentów:

Biorąc pod uwagę jeden lub więcej istniejących zatwierdzeń, zastosuj zmianę, którą każdy wprowadza, rejestrując nowe zatwierdzenie dla każdego. To wymaga, aby twoje drzewo robocze było czyste (bez modyfikacji z zatwierdzenia HEAD).

Gdy nie jest oczywiste, jak zastosować zmianę, dzieje się tak:

  1. Bieżąca gałąź i wskaźnik HEAD pozostają na ostatnim zatwierdzeniu, które zostało pomyślnie wykonane.

  2. Referencja CHERRY_PICK_HEAD jest ustawiona tak, aby wskazywała na zatwierdzenie, które wprowadziło trudną do zastosowania zmianę.

  3. Ścieżki, w których zastosowana zmiana została zaktualizowana, zarówno w pliku indeksu, jak iw drzewie roboczym.

  4. W przypadku sprzecznych ścieżek plik indeksu rejestruje maksymalnie trzy wersje, jak opisano w sekcji „PRAWDA MERGE” git-merge. Pliki drzewa roboczego będą zawierać opis konfliktu w nawiasach zwykłych znaczników konfliktu <<<<<<< i >>>>>>>.

Nie wprowadza się żadnych innych modyfikacji.

Czytaj więcej...

Saikat
źródło