16 Şubat 2013 Cumartesi

Git'i proje içinde kullanmak

Daha önce "git notlarım" isimli bir blog yazmıştım. Ancak burda sadece komutlar bulunuyor. Detaylı kullanım yer almıyor. Her nekadar bu kullanım İbrahim Gündür kardeşimiz tarafından ele alındıysada ( ibrahimgunduz.net/yar-yaban-ellere-git-mis/ ) talep üzerine (Hakan Bey'e beni teşvik ettiği için teşekkür ediyorum) bende birşeyler yazmaya çalışacağım.

Öncelikle "git" hızlı, kolay ve mantıklı bir kullanım sunuyor. Ayrıca piyasada ücretli ücretsiz servis alacağınız çok sağlam firtmalar bulunuyor ve Enterprise desteğide mevcut. (http://github.com , https://bitbucket.org/)

Yeni bir projeye başladığımızda proje klasöründeyken aşağıdaki komutu yazıp git'i aktif ediyoruz.
$git init

İlk olarak projede birşey eklemeden çıkarmadan önce kendimizi git'e tanıtmalıyız.

$git config --local user.name "isim.soyisim"
$git config --local user.email "volkan.altan@gmail.com"

Böylece yapacağım işlemler artık github veya x hesabımla değil. Bu bilgiler ile olacak.
Aslında bu bilgiler "jira" veya proje takibi için kullandığımız hesap bilgilerimiz olursa iyi olur.

Sonrasında projede hiçbir zaman gitmesini istemediğimiz dosyaları tanımlıyoruz. Bunu global veya her proje için ayrı tanımlayabiliriz, proje içerisinde ".gitignore" isimli bir dosya oluşturursak içine yazacağımız klasör isimleri veya dosyalar hiçbir zaman gitmeyecektir. Daha fazla bilgi için bu link faydalı olacaktır https://help.github.com/articles/ignoring-files .

Yukarda oluşturduğumuz projeyi şimdi github'a gönderelim.
github.com dan proje oluşturalım. Adı "deneme" olsun.

$git add .
$git commit -m 'ilk göndermeler'
$git remote add origin git@github.com:volkan/deneme.git
$git push -u origin master

Proje ile github arasındaki bağ kuruldu. Artık istediğimiz gibi çalışabiliriz.

Ben size linux kullanıyorsanız "oh my zsh" kurup kullanmanızı tavsiye ediyorum. Bunun en çok işimize yaracak yönlerinden biri bulunduğumuz "dalı" o an görebilecek olmamız.

Projede açılan her işe yeni bir "dal" açmak veya ihtiyaca göre sadece developer'a özel "dal" açabilirsiniz. Biz işleri jira'da açıp işin adına göre yeni bir "dal" açmayı tercih ediyoruz.

$git checkout -b PRJ-10
$git status
(-b hem "dal" oluşturur hem checkout işlemini yapar)
Bu şekilde her geliştirici sisteme kendini tanıtıp çalıştığı iş için "dal" açabilir.

Projede çalışırken, yaptığımız işi kaybetmemek için ara ara "commit" edip github'a göndermeliyiz.

$git push origin PRJ-10
(origin bulunduğunuz nokta yani bulunduğunuz "dal" demektir)
Gün içinde bunu birkaç defa yapabiliriz. Bu çalışma temponuzla alakalı.

Bu arada siz geliştirme yaparken projede boş durmuyor. Sizden önce işini yapıp bitiren arkadaşların işleri çeşitli statuslerden geçtikten sonra "master"'a alınıyor.  Ve sizin ilk başladığınız "dal", "ana daldan" geri kalmış oluyor. Bu yüzden çalıştığınız "dal" çeşitli statüslerden geçip "master"'a alınacağı zaman bu işleri yapan kişi sizden master'ını güncelleyip dalını "rebase" eder misin? der.

Siz yaptığınız bütün işleri add, commit ve push ettikten sonra master'a geçip.

$git fetch 

Yazarsanız hangi dalda olursanız olun bütün değişiklikleri alırsınız. Ancak bu değişiklikler herhangi bir yere yazılmaz.

$git pull

Derseniz hem fetch, hem "merge" yapmış olursunuz. Yani bulunduğunuz "dal" sunucuda bir yere bağlı ve mevcutsa ordan aldığı güncellemeleri sizin dalınıza birleştirir. Bu nedenle "git pull" yerine

$git pull --rebase

Daha uygun bir çözüm gibi geliyor.

merge ile rebase arasındaki fark, "merge" de üstünde yazılırken "rebase" aralara yazıyor.

Bu nedenle değişiklikler her commit'e uygulanıyor.

Velhasıl sizden rebase al dediklerinde sırasıyla aşağıdaki komutları çalıştırmanız gerekiyor.

$git status (gözümüzden kaçan birşey var mı diye bakıyoruz.)
$git checkout master
$git pull
$git checkout PRJ-10
$git rebase master

Burda çakışmalar çıkarsa onları düzeltmek için "ara yüzü" olan bir araç iyi olacaktır.
http://michaelgalloy.com/2008/01/29/opendiff.html

$git mergetool 

İle çakışmaları düzeltmeye başlayabiliriz.

Bununla birlikte commit sayımız çok olduğu zaman çakışmalarda o kadar çok düzeltme isteyecektik.
Ara ara commit, push ettikten sonra son commitimizde, bütün commitleri birleştirip tek commit yapabiliriz.

$git rebase -i HEAD~3

Burda 3, son 3 commit demek. Yukardaki komutu yazdığımız da tanımlı editör açılacaktır.
Bu bende "vim" açılan ekrandan;

pick 73a45d3 mesaj1 pick b5f70f9 mesaj2 pick a2c63a4 mesaj3 sondan iki "pick" i "f" yapıyoruz, böylece diğer commit mesajları "mesaj1" olarak güncellenecek. pick 73a45d3 mesaj1 f b5f70f9 mesaj2 f a2c63a4 mesaj3 :wq! (kaydet ve çık)

İşlemler başarılı olursa geriye kodu psuh etmek kalıyor.

$git push origin PRJ-10 -f

Burda "-f" parametresi kullandık, çünkü github'da bulunan kodlar ile bizdeki kodlar arasında fark oluştu. Bu fark kod farkı değil "başlık" farkıdır.

Yazdıklarım %100 doğru veya en uygun çalışma şekli değildir. Bu sadece naçizane bir tavsiyedir. Daha iyi yöntemleri olan yorum olarak yazarsa memnun oluruz.

2 yorum:

Gökhan Aygün dedi ki...

Makale için teşekkürler volkan, Jira da açılan her iş için yeni bir dal açalım demişsin, ancak yeni bir dal oluşturmanın amacı, yeni bir iş midir acaba ?

Mesela sisteme yeni bir feature(özellik) eklediğimizde mi yeni bir dal(branch) oluşturmak doğru olur.

Çünkü, örneğin githubtaki repoda çok ciddi branch oluşuyor, çok sayıda iş var çünkü, ben o branch listesini gördüğümde çekiniyorum biraz.

Bu konuda düşüncelerini alabilirmiyiz.

Volkan dedi ki...

Merhaba Gökhan, ilgin için teşekkür ederim.

Bu sorunun cevabı aslında projede kaç kişi çalıştığınız / o an yapılan işin büyüklüğü ile ilgili.

1. Çünkü tek bir kişi çalışıyorsa ve kısa bir iş ise oturup branch açmasına gerek yok! Direk "development" (sizde adı neyse) branch'inde ilgili değişiklikleri yapıp

git commit -m 'PRJ-233 hata düzeltildi'

Şeklinde işi gönderebilir. Nihayetinde ayrı branch açsaydı sonunda olacak olan buydu. İlgili branch gidip "development" branchine merge olacaktı.

2. Ama uzun bir işe bu kez araya girecek küçük işlerde sorun yaşanabilir. Veya "development" branchinde başkası değişiklik yaptığında sen bu değişikliği aldığın zaman kodları çakışabilir vs...

3. Ek olarak işler ayrı branch'de olduğu zaman github üzerinden code review yapmak ve onaylanan kodu merge etmek bir butona basmak kadar kolay. Veya değişikliğin farklarını bir ekran da görmek çok kolay...

Sonuç:
Bu sorunlarıda aşmanın elbet yolları var ancak amacımız geliştiricinin rahatını bozmadan işlerini yürümesini sağlamak olmalı.

Bu nedenlerle biz projelerde bu şekilde kullanıyoruz sen farklı yol ve yöntemler deneyebilirsin.

Hâtta biz oluşan bu branchleri şu an silmiyoruz bile çünkü github bunları silmemiz istemiyor, sakladığı için ekstra parada istemiyor. Ancak piyasada jiradaki statusu resolved olan issueların github branch'ini silecek scriptler bulunuyor veya jira API'sini kullanarak sende yazabilirsin. O nedenle bu kısım bizim için bir sorun teşkil etmiyor.

Şunu incelemeni tavsiye ederim:
git-flow