Monthly Archives: Eylül 2015

Genel

Neşet Ertaş’ı Özlemle Anıyoruz

Yıllar, yıllar önce büyük hayranlıkla dinlediğim Selda Bağcan, Barış Manço ve daha nice yorumcuların seslendirdiği eserlerin altında gördüğüm imzası ve yaptığı bunca güzel işe rağmen eksilmeyen alçak gönüllülüğüyle kendisine olan hayranlığım katlanarak büyüdü. Mekanın cennet olsun.


Büyük ustayı saygıyla anıyoruz

Genel

Doğru GIT Kullanımı ve Birlikte Çalışma Kültürü

Uzun bir aradan sonra tekrar merhaba.

Dağıtık yapısı ve zengin komut setiyle GIT hakikaten geliştiricinin hayatını kolaylaştıran mükemmel bir versiyon kontrol aracı. Ancak temel komut setinin yeteri kadar anlaşılamaması ve birlikte çalışma kültürünün tam anlamıyla yerleşememesi projede zaman zaman kod kayıplarına varan sonuçlara neden olabilmektedir.

GIT kullanımı ile ilgili problemleri genel olarak aşağıdaki gibi gruplayabiliriz:

* Komut setinin yeterince anlaşılamaması.
* Hatalı sürüm hazırlama stratejisi.
* Birlikte çalışma kültüründen kaynaklanan problemler

Komut Setinin Yeterince Anlaşılamaması:

Günlük hayatta kullandığımız temel git komutları olan, fetch, merge, rebase ve pull komutlarının tam olarak ne yaptığının anlaşılamamasıyla başlayan bu problem, geliştirme yapılan dallarda hatalı kullanım nedeniyle meydana gelen sapmalar ve hatta zaman zaman ciddi çakışmalar sonrasında oluşabilecek kod kayıplarıyla sonuçlanabilmektedir.

Dilerseniz öncelikle bu dört komutun tam olarak ne yaptığını özetleyelim.

git fetch:

Uzak depoda oluşturulan nesneleri (commit, tag vs.) yerel geliştirme ortamına transfer eder. Ancak yapılan değişiklikleri projeye yansıtmaz. Aslında kabaca sadece referans bilgilerini aktarır şeklinde düşünebiliriz. Bu işlem sonrasında merge veya rebase komutlarını çalıştıranadek git log branchA veya git diff origin/branchA branchA çalıştırarak uzak ve yerel depolar arasındaki farklılıkları görebilirsiniz.

git merge:

fetch komutu ile uzak depodan aktarılan değişiklikleri, kronolojik sıraya göre (zamana sırasına göre) projeyle birleştirir.

merge komutu çalıştırılmadan önceki durum:

	 branchA

      F    G     H
      o----o-----o
     /
o---o---o----o-----o---
A   B   C    D     E

master

merge komutu çalıştırılmadan sonraki durum:

o---o-o--o--o--o--o--o---
A   B F  C  G  D  H  E
merge edilen dal (master veya branchA)

git rebase:

fetch komutu ile uzak depodan aktarılan değişiklikler, yerel depodaki projeyle birleştirmeden önce ilgili dalın, ana daldan ayrıldığı noktadan itibaren yapılan değişiklikler bir kenarda tutularak dal, rebase edilen dal ile aynı seviyeye getirildikten sonra kenara alınan değişiklikler uygulanır. Böylece ana dalın taban daldan ayrıldığı noktadan itibaren gerçekleştirilen değişiklikler dalın en tepesine taşınır.

rebase komutu çalıştırılmadan önceki durum:

	 branchA

      F    G     H
      o----o-----o
     /
o---o---o----o-----o---
A   B   C    D     E

master

rebase komutu çalıştırılmadan sonraki durum:

	 branchA

                     F    G     H
                     o----o-----o
                    /
o---o---o----o-----o---
A   B   C    D     E

master

git pull:

Bu komut aslında GIT in geliştiricilere sağladığı bir kısayoldur. SVN kullanıcıları hatırlayacaktır. svn update çalıştırıldığında uzak repodaki değişiklikler olduğu gibi alınıp projeye aktarılırdı. pull komutu ise, fetch ve merge veya rebase komutlarını birlikte kullanabilmek için geliştirilmiş bir kısayoldur.

git pull = git fetch + git merge

git pull –rebase = git fetch + git rebase

Görüldüğü üzere pull komutu sonrasında kullanılan –rebase parametresi, komutun uzakta yapılan değişiklikleri dalla birleştirilmesi ile ilgili stratejiyi değiştirir. pull komutu ile birlikte herhangibir parametre kullanmazsanız uzakta yapılan değişiklikler repodan yerel geliştirme ortamına aktarıldıktan sonra doğrudan kronolojik sıraya göre projeyle birleştirilir. Böylece fetch ve merge komutları bir kerede uygulanmış olur. Ancak –rebase parametresinin eklenmesi durumunda GIT birleştirme stratejisi için rebase komutunu uygular.

Hatalı Sürüm Hazırlama Stratejisi

GIT ile ilgili değişik dallandırma ve sürümleme stratejileri mevcut. Aşağıdaki dökümanları inceleyerek sizin için en uygun olan bir model üzerinden devam edebilirsiniz.

A successful Git branching model
GIT: Comparing Workflows

Çok kabaca, projeyi dağıttığınız alfa, beta, pre-prod, … prod gibi birden çok ortam varsa hazırladığınız her sürüm yayına girmeyebilir. Değişen öncelikler, oluşan hatalar veya hataların giderilmesi için harcanan süre nedeniyle sürüme dahil olan paketler sıklıklıkla eklenebilir veya çıkartılabilir. Bu noktada numaralandırılmış release branchleri kullanmak, master dalı temiz tutmak için efektif bir çözüm olabilir. Etiketleme gibi çözümleri de değerlendirebilirsiniz.

Ancak hangi metodolojiyi kullanırsanız kullanın planlanan sürümün oluşturulmasına geçmeden önce mutlaka sürümün oluşturulduğu ortamdaki git repolarını güncelleyin. Aksi durumlarda geliştiricilerden gelen değişikliklerin sürüme yansımaması, oluşan çakışmalar nedeniyle meydana gelebilecek kod kayıpları ve master dalda meydana gelebilecek bozulmalar gibi bir dizi istenmeyen sonuçlarla karşılaşmanız olasıdır.

Aşağıda örnek bir sürüm paketinin hazırlanması ile ilgili akış görülüyor.

* master dalı güncelleyin.

	$ git checkout master 
	$ git pull origin master

* Sürüme girecek dalları rebase ederek master seviyesine getirin.

	$ git checkout ab-001
	...
	$ git rebase origin/master	

	$ git checkout ab-002
	...
	$ git rebase origin/master	

	$ git checkout ab-003
	...
	$ git rebase origin/master	

* Yeni bir sürüm dalı oluşturun.

	$ git checkout -b v1.0.15091301 -t origin/master

* Geliştirmelerin yeraldığı dalları sürüm dalıyla birleştirin.

	$ git merge ab-001 ab-002 ab-003

* Sürümün stabil olduğundan emin olduktan sonra oluşturduğunuz sürüm dalını master dal ile birleştirin.

	$ git checokut master
	$ git merge v1.0.15091301
	$ git push origin master

Eğer sürüm herhangibir problem ihtiva ediyorsa ilgili geliştirme mutlaka hatanın meydana geldiği dalda gerçekleştirilmelidir. Geri dönülebilirliği imkansız hale gelmesi ve yaşanabilecek kayıplar nedeniyle sürüm dalında asla geliştirme gerçekleştirilmemelidir.

Birlikte Çalışma Kültüründen Kaynaklanan Problemler

Geliştirme dalları genellikle master ve release dallarına göre daha sık değişikliğe maruz kalırlar. Özellikle birden fazla kişinin birlike çalıştığı geliştirme dallarında geliştirme ortamının güncel tutulması ve bunun diğer geliştiricileri de düşünerek doğru şekilde yapılması yüksek önem arz eder.

Projeye eklenecek yeni özelliklerle ilgili geliştiricilerin birlikte çalıştığı dallarda, dal hem yerel ortamda hem de uzak depoda sık değişikliklere maruz kaldığından güncellemeler mutlaka geliştirme ortamındaki değişikliklerin sona taşınması suretiyle gerçekleştirilmelidir. Böylece dalda oluşabilecek sapmaların önüne geçilmiş olunur.

Geliştirme ortamınızdaki değişiklikleri tepeye taşımak için git fetch ve git rebase veya git pull –rebase komutlarını kullanabilirsiniz.

Düzgün versiyonlanan bir projede geliştirme yapılan daldaki commit dizilimi, dalın master daldan ayrıldığı noktadan itibaren ip gibi olmalı ve herhangibir sapma meydana gelmemelidir.

Aşağıdaki resimde pull kullanılarak sapma meydana gelmiş bir dalın commit ağacı görülüyor.

Bir sonraki resimde ise pull –rebase kullanılarak güncellenmiş dalın commit ağacı görülüyor.

Sizlerde aşağıdaki komutu kullanarak çalıştığınız daldaki commit dizilimini görüntüleyebilirsiniz. Böylece herhangibir sapma meydana geldiğinde hızlıca müdahale ederek oluşabilecek hasarı ve zaman kaybını minimuma çekmiş olursunuz.

	$ git log --graph --decorate --pretty=oneline --abbrev-commit

Eğer bu ağacı oluşturmak için yukarıdaki uzun komut/parametre dizisini ezberlemek istemiyorsanız aşağıdaki komutu kullanarak lol isimli yeni bir takma ad oluşturabilirsiniz.

	$ git config --global alias.lol "log --graph --decorate --pretty=oneline --abbrev-commit"