Cherry-pick — to polecenie Git, które stosuje zmiany z określonego commita w bieżącej gałęzi, nie przenosząc całej historii źródłowej gałęzi. W przeciwieństwie do merge lub rebase, cherry-pick działa z każdym commitem indywidualnie: programista wybiera konkretny commit po skrócie i przenosi tylko jego zmiany. Według dokumentacji Git (2026), cherry-pick jest szczególnie przydatny do punktowego przenoszenia poprawek między gałęziami wydaniowymi, gdy całe merge jest zbędne lub ryzykowne. Polecenie tworzy nowego commita z nowym skrótem, ale zachowuje oryginalną wiadomość i autora.
Najważniejsze
Cherry-pick — to polecenie git cherry-pick, które pobiera zmiany z istniejącego commita i stosuje je jako nowy commit w bieżącej gałęzi. Oryginalny commit pozostaje na swoim miejscu w swojej gałęzi, a w docelowej gałęzi tworzona jest kopia zmian. Polecenie jest przydatne, gdy trzeba przenieść konkretną poprawkę, nie przenosząc całej gałęzi.
Składnia: git cherry-pick <commit-hash>. Git analizuje różnicę (diff) określonego commita z jego rodzicem i stosuje tę różnicę do bieżącej gałęzi. Jeśli zmian jest kilka plików — wszystkie są przenoszone razem. Polecenie przyjmuje również zakresy: git cherry-pick A..B — wszystkie commity od A do B, nie włączając A.
Flagi rozszerzają możliwości: -n (--no-commit) stosuje zmiany do katalogu roboczego i indeksu bez tworzenia commita — przydatne, gdy trzeba połączyć zmiany z kilku commitów w jeden. Flaga -x dodaje do wiadomości commita linię (cherry picked from commit ...), co ułatwia śledzenie pochodzenia zmian w historii.
# Cherry-pick pojedynczego commita po skrócie
git cherry-pick a1b2c3d
# Cherry-pick wielu commitów (sekwencyjnie)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# Cherry-pick bez automatycznego zatwierdzania
git cherry-pick -n a1b2c3d
# Flaga -x dodaje odniesienie do oryginalnego commita
git cherry-pick -x a1b2c3d
Główny scenariusz — przenoszenie poprawek między gałęziami wydaniowymi. Wyobraź sobie: w develop znaleziono i naprawiono krytyczny błąd. Gałąź wydaniowa release/v2.1 jest już oddzielona i ten błąd również w niej występuje. Merge całego develop do release przeniesie dużo niegotowego kodu, a cherry-pick jednego commita z poprawką to bezpieczne i precyzyjne rozwiązanie.
Drugi scenariusz — anulowanie zmian (revert) z następnym przywróceniem. Jeśli commit został anulowany przez git revert, a potem okazało się, że anulowanie było błędne — cherry-pick anulowanego commita przywraca zmiany. Jest to bardziej poprawne niż anulowanie revert, ponieważ nie tworzy powtórnych konfliktów.
Trzeci scenariusz — łączenie commitów z różnych gałęzi feature do jednej testowej gałęzi do testów integracyjnych. Zamiast scalać kilka nieukończonych gałęzi (z niedokończonym kodem), można wybrać tylko gotowe commity z każdej i przetestować ich współdziałanie.
Cherry-pick różni się od rebase i merge tym, że działa na poziomie pojedynczych commitów, a nie całych gałęzi. Podczas gdy rebase przenosi wszystkie commity gałęzi, a merge łączy dwie gałęzie, cherry-pick wybiera tylko potrzebne. To czyni go bardziej precyzyjnym narzędziem, ale również bardziej ręcznym.
Kolejna różnica — autorstwo. Przy cherry-pick Git domyślnie zachowuje autora oryginalnego commita (Author), ale committerem (Committer) staje się bieżący użytkownik. W wiadomości commita można śledzić pochodzenie poprzez flagę -x. Przy rebase autor i committer — obaj bieżący użytkownik z nowym skrótem.
Wydajność: cherry-pick jednego commita wykonuje się szybciej niż merge dwóch gałęzi z dużą liczbą commitów. Ale jeśli trzeba przenieść dziesiątki commitów, lepiej utworzyć tymczasową gałąź i wykonać rebase — będzie to bardziej wydajne i nie będzie wymagać podawania dziesiątków skrótów.
| Operacja | Zakres zastosowania | Efekty uboczne |
|---|---|---|
| Cherry-pick | Pojedyncze commity | Nowy skrót, duplikacja kodu |
| Rebase | Wszystkie commity gałęzi | Przepisanie historii, nowe skróty |
| Merge | Pełne scalanie gałęzi | Merge-commit, zachowanie historii |
Wiele commitów można przenieść jednym poleceniem, wymieniając ich skróty oddzielone spacją: git cherry-pick A B C. Git zastosuje commity sekwencyjnie w podanej kolejności. Jeśli któryś z commitów powoduje konflikt, cherry-pick zostaje wstrzymany, a programista musi rozwiązać konflikt, po czym kontynuować poleceniem git cherry-pick --continue.
Zakres commitów: git cherry-pick A..B (wszystkie commity po A do B, nie włączając A) oraz git cherry-pick A^..B (wszystkie commity od A włącznie do B). Zakresy są wygodne, gdy trzeba przenieść wszystkie commity z jednej gałęzi, ale bez więzi rodzicielskiej — na przykład przy przenoszeniu gotowej funkcji ze starej gałęzi do nowej.
Flaga --strategy określa, jak Git będzie stosować zmiany. Domyślnie używana jest strategia recursive, ale można wskazać ours lub theirs do automatycznego wyboru strony konfliktu. Flaga --mainline jest używana przy cherry-pick merge-commita — wskazuje numer rodzica (1 lub 2), względem którego obliczany jest diff.
# Zakres commitów cherry-pick
git cherry-pick develop~5..develop~2
# Cherry-pick merge-commita (określ rodzica)
git cherry-pick -m 1 m9n0o1p
# Użyj strategii theirs
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# Kontynuuj po rozwiązaniu konfliktu
git cherry-pick --continue
Konflikty przy cherry-pick powstają, gdy zmiany przenoszonego commita dotykają tych samych linii, które zostały zmienione w gałęzi docelowej. Git wstrzymuje wykonanie, oznacza pliki powodujące konflikt i oczekuje na rozwiązanie. W statusie takie pliki wyświetlane są jako both modified.
Kolejność działań przy konflikcie: otworzyć plik z konfliktem, znaleźć znaczniki konfliktu (<<<<<<<, =======, >>>>>>>), edytować treść, usunąć znaczniki, wykonać git add dla rozwiązanych plików i uruchomić git cherry-pick --continue. Jeśli konflikt jest nierozwiązywalny — git cherry-pick --abort anuluje cały cherry-pick, przywracając gałąź do stanu wyjściowego.
Częsty problem: commit już zawiera zmiany równoważne istniejącym. W takim przypadku Git zgłasza «nothing to commit» lub «empty commit» przy próbie cherry-pick. Flagii --keep-redundant-commits i --empty=keep zmuszają Git do tworzenia pustego commita w celu zachowania sekwencji, a --skip pozwala pominąć taki commit.
# Konflikt podczas cherry-pick — zatrzymaj
git cherry-pick a1b2c3d
# błąd: nie można zastosować a1b2c3d... treść commita
# Rozwiąż konflikt → dodaj do indeksu
git add src/conflicted_file.swift
git cherry-pick --continue
# Pomiń pustego commita (już zastosowany)
git cherry-pick --skip
# Pełne przerwanie
git cherry-pick --abort
Pierwsza zasada: zawsze sprawdzaj, czy przenoszony commit jest samowystarczalny. Jeśli commit A zależy od zmian w commicie B, który nie jest przenoszony, cherry-pick A może zepsuć kompilację. Przed cherry-pick warto sprawdzić, jakie pliki zmienił commit, przez git show --stat <hash>.
Druga zasada: dokumentuj cherry-pick. Używaj flagi -x, aby w wiadomości commita zachować odniesienie do źródłowego commita. Pomoże to w późniejszej analizie historii ustalić, skąd pochodzi zmiana. Bez -x cherry-pick wygląda jak zwykły commit, a jego pochodzenie można ustalić tylko przez git log --graph.
Trzecia zasada: unikaj cherry-pick między gałęziami, które różnią się zbyt mocno. Jeśli od momentu utworzenia commita minęło dużo czasu i baza kodu znacznie się zmieniła, konflikty będą liczne i złożone. W takich przypadkach lepiej zrobić poprawkę od nowa w gałęzi docelowej — zajmie to mniej czasu niż rozwiązywanie dziesiątków konfliktów.
Często zadawane pytania
Zrobić cherry-pick — zastosować zmiany określonego commita w bieżącej gałęzi przez git cherry-pick. Polecenie tworzy nowego commita z tymi samymi zmianami, ale nowym skrótem. Oryginalny commit pozostaje bez zmian w swojej gałęzi. To alternatywa dla scalania całej gałęzi, gdy potrzebny jest tylko jeden konkretny commit.
Cherry-pick jest wybierany, gdy trzeba przenieść jeden lub kilka konkretnych commitów bez przenoszenia całej gałęzi. Merge jest stosowany do pełnego łączenia gałęzi. Typowy scenariusz cherry-pick — przeniesienie hotfixa z gałęzi rozwojowej do wydaniowej, w której nie są jeszcze gotowe pozostałe zmiany.
Przed zakończeniem — git cherry-pick --abort anuluje operację całkowicie. Po pomyślnym zakończeniu — git revert <hash> tworzy commit anulujący zmiany cherry-pick. Różnica od --abort: revert nie usuwa commita z historii, ale tworzy nowy anulujący commit.
Pusty commit powstaje, gdy zmiany już istnieją w gałęzi docelowej. Użyj git cherry-pick --skip aby pominąć taki commit, lub git cherry-pick --keep-redundant-commits aby utworzyć pusty commit dla zachowania sekwencji skrótów.
Cherry-pick przenosi wybrane commity (pojedynczo lub listą) do bieżącej gałęzi. Rebase przenosi wszystkie commity gałęzi na nową bazę. Cherry-pick nie zmienia źródłowej gałęzi, rebase przepisuje historię. Cherry-pick jest precyzyjny, ale ręczny; rebase jest automatyczny, ale niebezpieczny dla publicznych gałęzi.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również