Git branch: Sezgi ve Gerçeklik
(jvns.ca)- Birçok kişi Git branch’in nasıl çalıştığını sezgisel bulmuyor.
- Git branch’lere dair yaygın sezgisel model ile branch’lerin Git’in içinde gerçekte nasıl temsil edildiği arasındaki fark açıklanıyor.
- Sezgisel model ile Git’in gerçek çalışma biçiminin aslında birbirine çok yakından bağlı olduğu gösteriliyor.
- Sezgisel modelin sınırları ve neden sorun çıkarabileceği tartışılıyor.
Sezgisel branch modeli
- Birçok kişi branch’i “elma ağacının dalı” benzetmesiyle düşünüyor.
- Git’te branch’in “ebeveyn” kavramı yok; bu yüzden bir branch’i
main’den dallanmış gibi düşünmekten farklı.
Git’te branch, tüm geçmişi kapsar
- Git’te branch, yalnızca ayrılmış commit’lerden ibaret değil; önceki tüm commit geçmişini içerir.
- Örnek bir depo üzerinden hem
mainhem demybranchiçin 4 commit bulunduğu gösteriliyor.
Branch’ler commit ID ile saklanır
- Git içinde branch’ler, commit ID içeren küçük metin dosyaları olarak saklanır.
- Her branch’in en son commit’i ilgili dosyada kayıtlıdır.
- Commit’ler arasında ebeveyn-çocuk ilişkisi olmadığı için Git, branch’ler arasındaki ilişkiyi bilemez.
İnsanların sezgisi genelde o kadar da yanlış değil
- İnsanların Git’e dair sezgisinin “yanlış” olduğunu söylemek biraz anlamsız.
- “Yanlış” bir model bile pratikte faydalı olabilir.
Rebase, “sezgisel” branch kavramını kullanır
- Rebase, yalnızca “sezgisel” branch’e ait commit’leri
mainüzerine yeniden uygular. - Rebase sonucu, sezgisel modelle uyumludur.
Merge de “sezgisel” branch kavramını kullanır
- Merge commit’leri kopyalamaz, ancak ortak bir temel commit gerektirir.
- Merge base, sezgisel modele göre branch’in ayrıldığı commit’i bulur.
GitHub pull request’leri de sezgisel fikri kullanır
- GitHub’da
mybranch’imainile birleştirmek için pull request oluşturduğunuzda, yalnızca sezgisel branch’e ait commit’ler gösterilir.
Sezgi iyidir ama sınırları vardır
- Sezgisel branch tanımı gerçek Git çalışmasıyla oldukça iyi örtüşür, ancak Git
mainile ondan ayrılmış bir branch’i farklı şekilde algılayamaz.
Trunk ve ondan ayrılan branch’ler
- İnsanlar
mainilemybranch’i farklı algılar ve bu, Git’i kullanma biçimlerini etkiler. - Git, bir branch’in başka bir branch’in “dalı” olup olmadığını ayırt etmez.
Git, rebase’i “ters yönde” de yapabilir
- Git, bir branch’in başka bir branch’in “dalı” olup olmadığını bilmediği için hangi branch’in ne zaman rebase edilmesi gerektiğini kullanıcı belirlemelidir.
- Hem
git rebase mainhem de ters yöndekigit rebase mybranchmümkündür. Merge için de aynısı geçerlidir.
Git branch’leri arasında hiyerarşi olmaması biraz tuhaf
mainbranch’inin özel olmadığı sözü, Git’in branch’ler arasındaki ilişkiyi tanımamasından kaynaklanır.- Branch’ler arasında ilişkiler vardır, ama Git bundan habersizdir.
Git branch arayüzü de tuhaf
- Yalnızca “ayrılmış” commit’leri görmek istediğinizde
git logilegit diffkullanma biçimi farklıdır.
GitHub’da varsayılan branch özeldir
- GitHub’ın “varsayılan branch”i vardır ve bu branch özel bir rol oynar.
GN⁺ görüşü
Bu yazıdaki en önemli nokta, insanların Git branch’lerine dair sezgisel anlayışı ile Git’in gerçekte nasıl çalıştığı arasındaki farkı kavramak. Yazı, özellikle başlangıç seviyesindeki yazılım mühendislerinin Git branch kavramını daha iyi anlamasına ve daha etkili kullanmasına yardımcı olacaktır. Git branch’lerine dair sezgisel modelin gerçek iş akışıyla nasıl örtüştüğünü ve Git’in branch’ler arasındaki ilişkileri neden takip etmediğini görmek ilgi çekici ve öğretici.
1 yorum
Hacker News görüşü
git reset --hardvegit stashile değişiklikleri ve branch pointer'larını manipüle ettiğimi gören arkadaşlarım bazen sinirleniyor. Hatalı bir merge'ü geri almak içingit reset --hard <merge öncesi son commit>kullanıyorum; yerel branch'teki küçük düzeltmeleri main branch'e uygulamak içinsegit stashkullandıktan sonra main branch'e checkout edipgit stash applyçalıştırıyorum.git addvegit commitkullanımını bilenlere yönelik dinamik bir eğitim var. Bu eğitim, branch'leri görselleştirerek okumanıza ve anlamanıza yardımcı oluyor.git merge my-branch, my-branch'i mevcut branch'e merge eder;git rebase my-branchise mevcut branch'i my-branch'in üzerine rebase eder.maine ait olduğunu söylese daha kullanışlı olurdu.git range-diffkullanırken de tabanı akılda tutmak gerekir. Bu araç,main..previousvemain..currentgibi iki aralığı karşılaştırır.