NotlarKararlı
Git cherry-pick: Tek Bir Commit'i Doğru Dala Taşımak
git cherry-pick neden kullanılır, hangi problemi çözer ve çatışma yönetimi dâhil pratik örneklerle nasıl kullanılır?
- Yayın
Git cherry-pick
git cherry-pick, başka bir branch’teki belirli bir commit’in değişikliğini bulunduğun branch’e uygular. Commit geçmişini veya branch’in tamamını birleştirmez; yalnızca seçtiğin değişikliği yeni bir commit olarak taşır.
Kısaca: “feature/payment dalındaki şu hata düzeltmesi release dalına da hemen gelsin” dediğin anda doğru araç çoğu zaman cherry-picktir.
Neyi çözer?
merge bir branch’in bütün geçmişini, rebase ise commit’lerin tabanını taşır. Bazen bunların ikisi de gereğinden büyüktür: ihtiyacın yalnızca tek bir düzeltme, güvenlik yaması veya bağımsız iyileştirmedir.
Örnek durum:
main: A --- B --- C
\
feature/search: D --- E --- F
^
kritik hata düzeltmesi
feature/search dalını main ile birleştirmek, E ve F ile birlikte henüz hazır olmayan işleri de taşır. Bunun yerine D commit’ini seçebilirsin:
main: A --- B --- C --- D'
feature/search: D --- E --- F
D', D ile aynı değişikliği içerir; fakat main üzerinde oluşturulduğu için farklı bir commit kimliği vardır.
Ne zaman kullanılmalı?
- Release veya hotfix dalına, geliştirme dalındaki tek bir hata düzeltmesini almak gerektiğinde.
- Birden çok dalda gereken bağımsız bir iyileştirme olduğunda.
- Yanlış branch’e atılmış bir commit’i hedef branch’e güvenli şekilde taşırken.
- Bir PR’ın tamamını değil, içindeki belirli ve incelenmiş bir commit’i almak istediğinde.
Özellikle production hotfix akışlarında değerlidir: büyük ve riskli bir merge yerine, kapsamı net tek değişikliği alırsın.
Ne zaman kullanılmamalı?
Bir feature dalındaki commitlerin çoğunu veya tamamını istiyorsan merge ya da ekip akışına uygunsa rebase daha anlaşılırdır. Aynı commitleri sürekli farklı dallara cherry-pick etmek de branch’lerin birbirinden koptuğunun işareti olabilir.
Başka bir risk: taşınan commit zaten hedef branch’te dolaylı olarak bulunuyorsa, aynı değişikliğin tekrar uygulanması çatışma veya yinelenen kod üretebilir. Önce değişikliğin mevcut olup olmadığını incele.
Temel kullanım
Önce commit kimliğini bul:
git log --oneline feature/search
# a1b2c3d Fix: boş arama sonucunda oluşan çökme
Değişikliğin gideceği branch’e geç ve commit’i uygula:
git switch main
git pull --ff-only origin main
git cherry-pick a1b2c3d
Başarılı olursa Git, aktif branch üzerinde yeni bir commit oluşturur. Kontrol için:
git log --oneline -3
git show --stat HEAD
git pull --ff-onlyzorunlu değildir; ancak ortak bir branch’te güncel tabandan çalışmayı ve beklenmeyen merge commit’lerini önlemeyi sağlar.
Örnek: Release dalına hotfix taşımak
develop dalında ödeme ekranındaki kritik hata için şu commit atılmış olsun:
7f3e91a fix(payment): timeout durumunda kullanıcıya tekrar deneme seçeneği göster
Sadece bu düzeltmeyi yayın dalına al:
git switch release/2.4
git cherry-pick -x 7f3e91a
git push origin release/2.4
Buradaki -x, yeni commit mesajına kaynak commit bilgisini ekler:
(cherry picked from commit 7f3e91a...)
Paylaşılan release ve bakım branch’lerinde -x kullanmak iyi bir izlenebilirlik alışkanlığıdır. Daha sonra bir değişikliğin nereden geldiği kolayca anlaşılır.
Birden fazla commit taşımak
Commitleri bağımlılık sırasıyla tek tek seçebilirsin:
git cherry-pick 12ab34c 56de78f 90ab12c
Ardışık bir commit aralığı için:
git cherry-pick 12ab34c^..90ab12c
Bu ifade ilk commit’i de içerir. ^ işareti olmazsa başlangıç commit’i aralığa dahil edilmez; bu, sık yapılan küçük bir hatadır.
Çatışma çıkarsa
Hedef branch’te aynı satırlar farklı şekilde değişmişse Git otomatik karar veremez ve cherry-pick durur.
git cherry-pick a1b2c3d
# CONFLICT (content): Merge conflict in src/services/search.ts
İzlenecek akış:
git status
# Çatışan dosyaları düzenle; <<<<<<<, ======= ve >>>>>>> işaretlerini kaldır.
git add src/services/search.ts
git cherry-pick --continue
Değişikliği almaktan vazgeçmek istersen çalışma ağacını cherry-pick öncesi hâline döndür:
git cherry-pick --abort
Git, çözüm sonrası değişikliğin gereksiz veya zaten uygulanmış olduğunu söylerse o commit’i atlayabilirsin:
git cherry-pick --skip
--skip yalnızca değişikliğin gerçekten hedef branch’te bulunduğundan veya uygulanmasına artık ihtiyaç olmadığından eminken kullanılmalı.
Commit etmeden önce incelemek
Değişikliği çalışma alanına uygula, test et ve commit mesajını kendin oluştur:
git cherry-pick --no-commit a1b2c3d
npm test
git commit -m "fix(search): boş sonuç durumunu işle"
Kısa biçimi -ndir. Bu yöntem, birkaç küçük commit’i tek bir release fix commit’inde birleştirmek veya hedef branch’e özgü küçük uyarlamalar yapmak gerektiğinde kullanışlıdır.
Güvenli çalışma kontrol listesi
- Hedef branch’te olduğunu
git branch --show-currentile doğrula. - Önce kaynak commit’i
git show <hash>ile oku; taşımadığın yan etkiler olmadığından emin ol. - Commit başka commitlere bağımlıysa, bağımlılıklarını da doğru sırayla al.
- Uygulama sonrası testleri ve
git diff HEAD^ HEADçıktısını kontrol et. - Ortak branch’e taşıyorsan
-xkullan ve sonucu push etmeden önce gözden geçir.
Kısa komut özeti
| Amaç | Komut |
|---|---|
| Tek commit uygula | git cherry-pick <commit> |
| Kaynağı commit mesajına ekle | git cherry-pick -x <commit> |
| Commit oluşturmadan uygula | git cherry-pick -n <commit> |
| Çatışmayı çözdükten sonra devam et | git cherry-pick --continue |
| İşlemi geri al | git cherry-pick --abort |
| Geçerli commit’i atla | git cherry-pick --skip |
Cherry-pick bir kopyalama sihri değil, kontrollü bir değişiklik taşıma aracıdır. Kapsamı küçük, gerekçesi açık ve test edilmiş commit’lerde kullanıldığında; hotfix ve release akışlarını hızlandırırken ana branch’in gereksiz değişikliklerle kirlenmesini önler.