Git
Chapters ▾ 2nd Edition

3.2 Git Branching - Kısaca Dallandırma ve Birleştirme Temelleri

Kısaca Dallandırma ve Birleştirme Temelleri

Şimdi gerçek dünyada kullanabileceğiniz bir iş akışıyla basit bir dallandırma ve birleştirme örneğini inceleyelim. Bu adımları takip edeceksiniz:

  1. Bir web projesi üzerinde birşeyleri değiştirin.

  2. Üzerinde çalıştığınız iş paketi (user story) için yeni bir dal oluşturun.

  3. Bu dal üzerinde çalışın.

Diyelim ki bu aşamada, başka bir sorunun daha kritik olduğuna ve acilen düzeltmeniz (hotfix) gerektiğine dair bir çağrı aldınız. Şunları yapmanız gerekiyor:

  1. Üretim (production) dalına geçin (Bu sizin canlı yayındaki dalınızdır, genellikle master veya main olarak adlandırılır).

  2. Onarım amaçlı yeni bir dal oluşturun.

  3. Düzgün çalıştığını test ettikten sonra onarım dalını üretim dalıyla birleştirin ve üretime itin.

  4. Asıl iş paketinize geri dönün ve çalışmaya devam edin.

Dallandırma

İlk olarak, projeniz üzerinde çalışıyorsunuz ve master dalında halihazırda birkaç katkınız var diyelim.

Basit bir katkı geçmişi.
Görsel 18. Basit bir katkı geçmişi

#53 numaralı sorun (Ya da şirketinizin kullandığı iş takip sisteminde nasıl gösteriliyorsa) üzerinde çalışmaya karar verdiniz. Yeni bir dal oluşturup aynı zamanda bu dala geçmek için git checkout komutunu -b (branch) bayrağı ile çalıştırabilirsiniz:

$ git checkout -b iss53
Switched to a new branch "iss53"

Bu komut şunun kısa yoludur:

$ git branch iss53
$ git checkout iss53
Yeni bir dal işaretçisi oluşturmak.
Görsel 19. Yeni bir dal işaretçisi oluşturmak

Web siteniz üzerinde çalışıyor ve bazı bazı katkılar işliyorsunuz. Bu dala geçiş yapmış olduğunuz için (yani, HEAD artık onu işaret ediyor) katkı işlemek iss53 dalını ileri taşır:

$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
`iss53` dalı siz çalıştıkça ilerler.
Görsel 20. iss53 dalı siz çalıştıkça ilerler

Şimdi, web sitesinde bir sorun olduğu ve bunu derhal düzeltmeniz gerektiğine dair bir çağrı alıyorsunuz. Git’te, ne yapmış olduğunuz iss53 değişiklikleri ve onarımınızı birlikte yükleme zorunluluğunuz var, ne de bu değişiklikleri üretime uygulamadan önce geri almak için büyük çaba sarf etmenize. Yapmanız gereken tek şey, master dalınıza geri dönmektir.

Ancak bunu yapmadan önce, çalışma dizininiz veya izlemde (stage) henüz katkılanmamış değişiklikler varsa ve bu değişiklikler, geçiş yapmak istediğiniz dal ile çakışıyorsa, Git’in sizin dal değiştirmenize izin vermeyeceğini bilmeniz lazım. Dallar arasında geçiş yaparken temiz bir çalışma durumuna sahip olmak en iyisidir. Bu sorunun etrafından dolaşmanın tabi ki belli (stashing ve commit amending gibi) yolları var ama bunları Saklama ve Silme bölümünde ele alacağız. Şu anda, tüm değişikliklerinizi katkıladığınızı varsayalım, böylece master dalına geri dönebilirsiniz:

$ git checkout master
Switched to branch 'master'

Bu aşamada, projenizin çalışma dizini, #53 sorunu üzerinde çalışmaya başlamadan önceki haline tam olarak geri dönmüş durumda ve şimdi onarımınıza odaklanabilirsiniz. Çok önemli bir hatırlatma!: Dallar arasında geçiş yaptığınızda, Git çalışma dizininizi o dala en son katkı işlediğiniz anda olduğu gibi ayarlar. Çalışma kopyanızı, dal üzerindeki son katkıladığınız gibi görünmesi için otomatik olarak dosya ekler, kaldırır ve değiştirir.

Şimdi, bir onarım yapmanız gerekiyor. Sorunu düzeltene kadar üzerinde değişiklikler yapabileceğimiz hotfix adında bir dal oluşturalım:

$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
 1 file changed, 2 insertions(+)
`master` üzerinden oluşturulmuş `hotfix` dalı.
Görsel 21. master üzerinden oluşturulmuş hotfix dalı

Testlerinizi çalıştırabilir, düzeltmenin istediğiniz gibi çalıştığından emin olabilir ve son olarak hotfix dalınızı master dalınıza birleştirerek üretime alabilirsiniz. Bunu git merge komutuyla yaparsınız:

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

Bu birleştirmede ``fast-forward`` ifadesini fark edeceksiniz. Çünkü birleştirdiğiniz hotfix dalını işaret eden C4 katkısı, üzerinde bulunduğunuz C2 katkısından doğrudan ilerideydi, Git sadece işaretçiyi ileri taşıdı. Başka bir deyişle, bir katkıyı, katkı geçmişini takip ederek ulaşılabilen bir katkıyla birleştirmeye çalıştığınızda, birleştirilecek ayrı çalışma olmadığından, Git işaretçiyi doğrudan ileri taşıyarak işleri basitleştirir. Buna ``fast-forward`` (ileri sarma) denir.

Artık değişikliğiniz, master dalının işaret ettiği katkı anlık görüntüsünde bulunuyor ve düzeltmeyi artık yükleyebilirsiniz.

`master`
Görsel 22. master, `hotfix`e doğru ileri sarıldı

Bu süper önemli düzeltmeniz yüklendikten sonra, kesintiye uğradığınız çalışmaya geri dönmeye hazırsınız. Neticede master dalı da aynı yere işaret ettiği için, artık ihtiyacınız olmayan, hotfix dalını sileceksiniz. Bu dalı git branch komutunun -d (delete) seçeneği ile silebilirsiniz:

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).

Şimdi #53 sorunu üzerindeki bekleyen işinize geri dönebilir ve çalışmaya devam edebilirsiniz.

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
`iss53` üzerinde devam eden iş.
Görsel 23. iss53 üzerinde devam eden iş

Burada hotfix dalında yaptığınız çalışmanın iss53 dalındaki dosyalarda bulunmadığını unutmayın. Eğer onu çekmeniz gerekiyorsa, git merge master komutunu çalıştırarak master dalını iss53 dalına kaynaştırabilirsiniz, veya bu değişiklikleri birleştirmek için iss53 dalını daha sonra master dalına çekmeye karar verene kadar bekleyebilirsiniz.

Birleştirme

Diyelimk ki #53 sorunu üzerindeki çalışmanızın tamamlandığına ve master dalına birleştirilmeye hazır olduğuna karar verdiniz. Bunu yapmak için, aynı hotfix dalınızı daha önce birleştirdiğiniz gibi, iss53 dalınızı da master dalına birleştireceksiniz. Yapmanız gereken tek şey, birleştirmek istediğiniz dala geçmek ve ardından git merge komutunu çalıştırmaktır:

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

Bu, önceki yaptığınız "hotfix" birleştirmesinden biraz farklı görünüyor. Mevcut durumda, geliştirme geçmişiniz eski bir katkıdan itibaren ayrılmış durumda. Çünkü üzerinde bulunduğunuz dalın son katkısı, birleştirmeye çalıştığınız dalın doğrudan önceli değilse, Git bazı işlemleri gerçekleştirmek zorundadır. Yukarıdaki senaryoda, Git bu iki dalın ortak öncelini ve her iki dal ucu tarafından işaret edilen iki farklı anlık görüntüyü kullanarak, üç yollu bir birleştirme yapar.

Tipik bir birleştirmede kullanılan üç poz.
Görsel 24. Tipik bir birleştirmede kullanılan üç poz

Sadece dal işaretçisini ileri taşımak yerine, Git, bu üç yollu birleştirmenin sonucu olan yeni bir poz oluşturur ve otomatik olarak ona işaret eden yeni bir katkı oluşturur. Buna birleştirme katkısı denir ve birden fazla üst dala sahip olması bakımından özeldir.

Bir birleştirme katkısı.
Görsel 25. Bir birleştirme katkısı

Şimdi çalışmanız birleştirildiğine göre iss53 dalına artık ihtiyacınız yok. İş takip sisteminizdeki biletinizi (ticket) kapatabilir ve dalı silebilirsiniz:

$ git branch -d iss53

Birleştirme Çakışması (merge conflict)

Bazen birleştirme süreci sorunsuz tamamlanamayabilir. Eğer bir dosyanın aynı kısmını, iki farklı dalda iki farklı şekilde değiştirdiyseniz, Git bu değişimlerden hangisini birleştirmeye katacağını bilemeyeceği için, temiz bir birleştirme işlemi yapamaz. Eğer #53 sorunu için yaptığınız düzeltme, hotfix dalının aynı dosyasının aynı bölümünü değiştirmişse, aşağıdakine benzer bir çakışma uyarısı (merge conflict) alacaksınız:

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Git otomatik olarak yeni bir birleştirme katkısı oluşturmadı. Siz çakışmayı çözene kadar süreci duraklattı. Eğer çakışma uyarısı aldıktan sonra hangi dosyaların birleştirilmediğini görmek istiyorsanız, git status komutunu çalıştırabilirsiniz:

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

Çakışmaları çözülmemiş olan her şey "unmerged" (birleştirilmemiş) olarak listelenir. Git, çakışmaları olan dosyalara "standart çakışma çözüm işaretçilerini" ekler, böylece bunları manuel olarak açabilir ve çakışmaları çözebilirsiniz. Dosyanız, aşağıdakine benzer bir bölüm içerir:

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

Bunun anlamı: ======= işaretinin üstündeki her şey HEAD (merge komutunu çalıştırdığınızda üzerinde bulunduğunuz dal yani bu senaryoda master dalı) içindeki sürümü gösterirken, işaretin altındaki kısımların ise iss53 dalı içindeki sürümü gösterdiğidir. Çakışmayı çözmek için ya bir tarafı ya da diğerini seçmek yahut da içeriği kendiniz birleştirmek zorundasınız. Örneğin, bu çakışmayı aşağıdaki gibi tüm bloğu değiştirerek çözebilirsiniz:

<div id="footer">
please contact us at email.support@github.com
</div>

Bu çözüm, her iki bölümün birazını içerir ve <<<<<<<, ======= ve >>>>>>> satırları tamamen kaldırılmıştır. Her bir çakışmış dosyanın her bir çakışmasını çözdükten sonra, her bir dosya üzerinde git add komutunu çalıştırarak onu çözülmüş olarak işaretleyin. Dosyayı izleme almak, Git’te çözülmüş olarak işaretler.

Bu sorunları çözmek için görsel bir araç kullanmak istiyorsanız, git mergetool komutunu çalıştırabilirsiniz. Bu, uygun bir görsel birleştirme aracını başlatır ve çakışmaları çözme sürecinde sizi yönlendirir:

$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html

Normal merge conflict for 'index.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (opendiff):

Eğer varsayılan birleştirme aracı dışında bir birleştirme aracı kullanmak istiyorsanız (Eğer komutu Mac işletim sisteminde çalıştırıyorsanaz Git kendisi opendiff aracını seçecektir), "one of the following tools" ifadesinin hemen altında desteklenen tüm araçların listesini görebilirsiniz. Kullanmayı tercih ettiğiniz aracın adını yazmanız yeterlidir.

Karmaşık birleştirme çatışmalarını çözmek için daha gelişmiş araçlara ihtiyacınız varsa, daha fazlasını <<_advanced_merging>> bölümünde ele alacağız.

Birleştirme aracından çıktıktan sonra, Git size birleştirmenin başarılı olup olmadığını sorar. Eğer başarılı olduysa, dosyayı çatışması çözüldü olarak işaretlemek üzere izleme gönderir. Tüm çakışmaların çözüldüğünü doğrulamak için tekrar git status komutunu çalıştırabilirsiniz:

$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   index.html

Eğer bu durumdan memnunsanız ve çakışmaları olan her şeyin aşamalandırıldığını doğruladıysanız, birleştirme işlemini sonuca ulaştırmak için git commit komutunu yazabilirsiniz. Varsayılan olarak, katkı mesajı şu şekilde görünür:

Merge branch 'iss53'

Conflicts:
    index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#	.git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#	modified:   index.html
#

Eğer bu açıklamalar yeterli değilse ve gelecekte bu birleşmeyi inceleyecek diğer kullanıcılara yardımcı olabileceğini düşünüyorsanız; bu katkı mesajını çakışmayı nasıl çözdüğünüz ve yaptığınız değişiklikleri neden yaptığınızı açıklayacak şekilde değiştirebilirsiniz.

scroll-to-top