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?


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:


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


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


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 .


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


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).


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ń.


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


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


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.


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.


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...

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.