git cherry-pick: tek bir commit'i başka branch'e nasıl taşırsınız
git cherry-pick, belirttiğiniz commit'in değişikliklerini mevcut branch'e alır ve aynı farkı ve mesajı taşıyan yeni bir commit oluşturur; hash'i ise farklıdır. Hedef branch'e geçip git cherry-pick <hash> çalıştırın; çakışma olursa dosyaları düzeltip git add ve git cherry-pick --continue komutlarını kullanın.
git cherry-pick, belirli bir commit'in değişikliklerini mevcut branch'e taşır ve tüm branch'i birleştirmez. Git, seçilen commit'in farkını ebeveynine göre hesaplar, bunu HEAD'inize uygular ve yeni bir commit oluşturur. Bu commit aynı mesajı ve yazarı taşır, ama ebeveyni farklı olduğu için hash'i farklıdır.
Tipik bir senaryo: bir özellik (feature) branch'inde hata düzelttiniz ve bu düzeltmeyi, özelliğin henüz hazır olmadığı bir sürüm branch'ine acilen almanız gerekiyor. Tüm branch'i birleştirmek mümkün değil, ama tek bir commit'i taşımak yeterli.
Tek bir commit'i başka branch'e taşıma
Önce istediğiniz commit'in hash'ini bulun, sonra commit'i taşıyacağınız branch'e geçip cherry-pick çalıştırın.
# 1. feature branch'indeki commit'i bulun
git log --oneline feature
a1b2c3d İndirim hesabında sıfıra bölme hatasını düzelt
9f8e7d6 Yeni ödeme ekranını ekle
# 2. Hedef branch'e geçin
git switch release-1.4
# 3. Commit'i taşıyın
git cherry-pick a1b2c3d
[release-1.4 4e5f6a7] İndirim hesabında sıfıra bölme hatasını düzelt
Date: Mon Oct 5 14:12:03 2026 +0300
1 file changed, 3 insertions(+), 1 deletion(-)
Dikkat: yeni commit a1b2c3d yerine 4e5f6a7 hash'ini aldı. Bunlar aynı değişiklikleri içeren iki farklı nesnedir. Kaynak branch feature değişmez.
Hash yerine herhangi bir commit referansı da verebilirsiniz: git cherry-pick feature branch'in son commit'ini, git cherry-pick feature~2 ise sondan üçüncüsünü alır.
Birden fazla commit'i taşıma
Tek tek listeleyerek
Hash'leri liste halinde verebilirsiniz; Git bunları verilen sırayla uygular ve o kadar yeni commit oluşturur.
git cherry-pick a1b2c3d 7c8d9e0 3f4a5b6
Sıra önemlidir: ikinci commit birinciye bağlıysa ve sıralamayı ters yazarsanız çakışma alır ya da bozuk kod elde edersiniz. Güvenli olan, eskiden yeniye doğru yazmaktır.
Aralık ile
Arka arkaya gelen commit'ler için aralık sözdizimini kullanabilirsiniz. Burada neredeyse herkesin takıldığı bir tuzak var: A..B, «B'den erişilebilen ama A'dan erişilemeyen commit'ler» anlamına gelir; yani A'nın kendisi aralığa dahil değildir.
# A'dan SONRAKİ commit'leri, B dahil, taşır
git cherry-pick A..B
# A'yı ve B'ye kadar olan her şeyi taşır
git cherry-pick A^..B
feature branch'inde olup main'de olmayan her şeyi taşımak istiyorsanız git cherry-pick main..feature kullanışlıdır. Ama commit sayısı fazlaysa bir kez düşünün: belki cherry-pick değil rebase ya da merge gerekir.
Kullanışlı git cherry-pick bayrakları
| Bayrak | Ne yapar | Ne zaman gerekir |
|---|---|---|
-x | Mesajın sonuna «(cherry picked from commit …)» satırı ekler | Herkese açık branch'ler arasında düzeltme taşırken kökenin görünmesi için |
-n, --no-commit | Değişiklikleri commit yapmadan index'e ve çalışma dizinine uygular | Birkaç commit'i tek commit'te birleştirmek ya da commit öncesi düzeltmek istediğinizde |
-e, --edit | Mesajı düzenlemek için editörü açar | Mesajı hedef branch'e göre netleştirmek gerektiğinde |
-s, --signoff | Signed-off-by satırı ekler | DCO gerektiren projelerde |
-m 1 | Birleştirme (merge) commit'i için «ana» ebeveyni belirtir | Bir merge commit'ini taşırken |
--ff | Seçilen commit'in ebeveyni HEAD ise branch'i yalnızca ileri sarar | Nadiren; gereksiz kopya oluşmasını önler |
--allow-empty | Baştan boş olan commit'lerin taşınmasına izin verir | Servis amaçlı boş commit'lerde |
-x neden gerekli
Altı ay sonra biri sürüm branch'inde bu düzeltmeyi görür ve nereden geldiğini merak eder. -x ile eklenen satır doğrudan cevap verir:
git cherry-pick -x a1b2c3d
git log -1
İndirim hesabında sıfıra bölme hatasını düzelt
(cherry picked from commit a1b2c3d4e5f60718293a4b5c6d7e8f9012345678)
Kaynak commit zaten yayımlandıysa -x kullanın. Sonradan sileceğiniz kendi yerel branch'inizden taşıyorsanız bağlantı boşa gider; orada bayrağa gerek yoktur.
Birden fazla commit'i tek commit'te toplamak: -n
git cherry-pick -n a1b2c3d 7c8d9e0
git status # iki commit'in değişiklikleri index'te
git commit -m "İndirim hesabı düzeltmeleri"
cherry-pick sırasında çakışmalar ve çözümü
Çakışma, commit'in değişiklikleri mevcut koda oturmadığında çıkar: hedef branch'te aynı satırlar farklı görünüyordur. Git durur ve bunu bildirir.
git cherry-pick a1b2c3d
Auto-merging src/discount.js
CONFLICT (content): Merge conflict in src/discount.js
error: could not apply a1b2c3d... İndirim hesabında sıfıra bölme hatasını düzelt
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
Bundan sonra üç yolunuz var:
- Çözüp devam etmek. Dosyayı açın,
<<<<<<<,=======,>>>>>>>işaretlerini kaldırıp doğru sürümü bırakın, ardındangit add src/discount.jsvegit cherry-pick --continueçalıştırın. - Commit'i atlamak. Bir liste taşıyorsanız
git cherry-pick --skipsorunlu commit'i atlar ve sıradakine geçer. - Her şeyi geri almak.
git cherry-pick --abortbranch'i işlem başlamadan önceki duruma döndürür.
Bir de git cherry-pick --quit vardır: işlemi durdurur ama o ana kadar uygulanmış commit'leri ve dosyaların mevcut durumunu olduğu gibi bırakır. Listenin yarısını başarıyla taşıdıysanız ve kalanını elle yapmak istiyorsanız işinize yarar.
Aynı çakışmalar tekrar tekrar çıkıyorsa (örneğin düzeltmeleri birkaç sürüm branch'ine düzenli olarak taşıyorsanız), git config rerere.enabled true ayarını açın. Git çakışmayı nasıl çözdüğünüzü hatırlar ve bir dahaki sefere çözümü kendisi uygular.
Birleştirme (merge) commit'i nasıl taşınır
Merge commit'inin iki ebeveyni vardır ve Git farkı hangisine göre hesaplayacağını bilemez. Bir ipucu vermezseniz hata alırsınız:
git cherry-pick 5d6e7f8
error: commit 5d6e7f8 is a merge but no -m option was given.
-m 1 bayrağı şunu söyler: değişiklikleri birinci ebeveyne göre hesapla. Bu genellikle birleştirmenin yapıldığı branch'tir. Böylece birleştirilen branch'in getirdiği her şey tek bir commit'te taşınır.
git cherry-pick -m 1 5d6e7f8
Bunun bir sonucu var: Git bu branch'i birleştirilmiş saymaz. Sonraki bir merge'de aynı değişiklikleri yeniden uygulamaya çalışabilir.
git cherry-pick mi, git apply mi
git apply ile cherry-pick çoğu zaman yan yana anılır, çünkü ikisi de değişiklikleri «uygular». Ama farklı girdilerle çalışırlar.
| git cherry-pick | git apply | |
|---|---|---|
| Girdi | Depoda bulunan bir commit | Bir yama dosyası (diff) |
| Commit oluşturur mu | Evet (-n yoksa) | Hayır, yalnızca dosyaları değiştirir (--index ile index'i de) |
| Yazarı ve mesajı korur mu | Evet | Hayır, yamada bunlar yoktur |
| Çakışmalar | İşaretli üçlü birleştirme | Varsayılan olarak reddeder; --3way ile işaretler |
| Ortak bir depo gerekli mi | Evet, commit yerelde olmalı | Hayır, yama istediğiniz yolla iletilebilir |
Commit'in depoda olmadığı durumda git apply örneği: bir meslektaşınız farkı dosya olarak gönderdi.
# Meslektaşınız yapar
git diff main..fix-discount > fix.patch
# Siz kontrol edip uygularsınız
git apply --check fix.patch # yamanın oturup oturmayacağını kontrol et
git apply fix.patch # çalışma dizinine uygula
git apply --3way fix.patch # farklılık varsa çakışma işaretleriyle
Commit'i yazarı ve mesajıyla birlikte göndermek istiyorsanız git format-patch ve git am ikilisini kullanın: ilki commit'leri dosyalara kaydeder, ikincisi bu dosyalardan commit'ler oluşturur. Bu, «e-posta ile cherry-pick» gibidir.
Bu arada, cherry-pick'i başka bir depodan da yapabilirsiniz: o depoyu remote olarak ekleyin, git fetch çalıştırın, commit'ler hash ile erişilebilir olur.
Ne zaman cherry-pick kötü bir fikirdir
Cherry-pick kopyalar üretir: aynı değişiklik geçmişte iki farklı hash ile yaşar. Az sayıda kullanımda bu normaldir, ama bazı senaryolarda zarar verir.
- Onlarca commit taşımak. Neredeyse tüm branch'i taşıyorsanız bu rebase ya da merge işidir. Cherry-pick burada uzun bir kopya geçmişi ve daha çok çakışma üretir.
- İki yönlü taşımalar. Bir commit feature'dan main'e taşındı, sonra feature main'e birleştirildi. Git genellikle başa çıkar (değişiklikler aynıdır), ama taşıma sonrası satırlar yeniden düzenlendiyse sebepsiz yere çakışma çıkar.
- Bağımlı commit'ler. Bir commit, iki commit önce eklenmiş bir fonksiyonu kullanıyor. Cherry-pick yalnızca o commit'i taşır ve hedef branch'teki kod derlenmez. Taşıma sonrası mutlaka derlemeyi ve testleri çalıştırın.
Hotfix'ler için iyi bir uygulama, düzeltmeyi hâlâ desteklenen en eski branch'te yapıp yeni branch'lere «yukarı» birleştirmektir. Bu durumda cherry-pick yalnızca istisna olarak kalır.
cherry-pick nasıl geri alınır
İşlem hâlâ sürüyorsa (çakışma varsa) git cherry-pick --abort. Commit oluşturulmuş ama sunucuya gönderilmemişse kaldırın:
git reset --hard HEAD~1
Commit zaten ortak branch'e gönderildiyse geçmişi yeniden yazmak olmaz; tersini içeren yeni bir commit oluşturun:
git revert 4e5f6a7
Bir reset yaptıktan sonra vazgeçtiyseniz kaybolan commit'i git reflog ile bulabilirsiniz.
Bir commit'in zaten taşınıp taşınmadığını kontrol etme
Hash'ler farklı olduğu için sıradan git branch --contains işe yaramaz. Git, commit'leri değişikliklerinin içeriğine göre (patch-id) karşılaştırabilir:
git cherry -v release-1.4 feature
- a1b2c3d İndirim hesabında sıfıra bölme hatasını düzelt
+ 9f8e7d6 Yeni ödeme ekranını ekle
Eksi işareti, release-1.4 içinde eşdeğer değişikliğin zaten bulunduğunu, artı işareti ise henüz bulunmadığını gösterir. Alternatif olarak git log --cherry-pick --oneline release-1.4...feature ikiz commit'leri gizler. -x kullandıysanız mesaja göre de arayabilirsiniz: git log --grep="cherry picked from commit a1b2c3d".
Kısaca
git cherry-pick hassas bir araçtır: bir hotfix'i sürüme taşımak, terk edilmiş bir branch'ten faydalı bir commit almak ya da yanlış yere yapılmış bir commit'i düzeltmek için idealdir. Üç noktayı akılda tutun: yeni commit yeni bir hash alır, A..B aralığı A'yı dahil etmez ve herkese açık branch'lerde -x eklemek gerekir. Commit değil de dosya farkı taşımak istiyorsanız git apply kullanın. Rebase, stash, cherry-pick ve etiketler Git kursunda uygulamalı olarak ele alınmaktadır.
Sık sorulan sorular
cherry-pick kaynak branch'i değiştirir mi?
Hayır. Kaynak commit yerinde kalır, mevcut branch'e yeni hash ile bir kopyası eklenir.
Uzak bir branch'teki commit'i cherry-pick yapabilir miyim?
Evet. Önce git fetch çalıştırın; commit artık hash ile ya da origin/branch-adi üzerinden erişilebilir olur ve git cherry-pick'e verilebilir.
cherry-pick sonrası commit neden farklı hash aldı?
Hash; ebeveyne, commit zamanına ve ağaç içeriğine bağlıdır. Kopyanın ebeveyni ve committer zamanı farklı olduğu için hash de farklıdır.
cherry-pick yapınca commit'in yazarı korunur mu?
Evet, yazar ve yazar tarihi kaynak commit'ten alınır. Committer ise siz olursunuz ve tarih o anki tarihtir.
cherry-pick «commit boş» diyorsa ne yapmalıyım?
Bu değişikliklerin branch'te zaten olduğu anlamına gelir. git cherry-pick --skip ile atlayabilir ya da git commit --allow-empty ile boş olarak kaydedebilirsiniz.
Bu konu “Sıfırdan Güvenilir Geliştiriciye Git” kursunda uygulamalı olarak ayrıntılı işleniyor.
Kursa git