Git

Ubuntu Türkiye Wiki sitesinden
Gezinti kısmına atla Arama kısmına atla

Git, hıza vurgu yapılarak dağıtılmış gözden geçirme kontrolüdür. Git ilk önce Linus Torvalds tarafından Linux çekirdeği için tasarlanıp geliştirilmiştir.

Her Git'in çalışan dizini, tüm geçmişini ve gözden geçirmeleri içinde saklayabilecek yeteneğe sahip, tam donanımlı bir depodur. Ağ erişimine veya merkezi sunucuya ihtiyaç duymaz.

Git'in mevcut yazılım devamı Junio Hamano tarafından yapılır. Git, özgür yazılımdır ve GNU Genel Kamu Lisansı sürüm 2 altında dağıtılır.

Linus Torvalds, Britanya İngilizce'sinde kabaca aptal veya nezaketsiz kişi için kullanılan "git" adını nükte olsun diye şöyle bir cümlede kullandı: "Ben bencil, aşağılık herifin biriyim ve tüm projelerimi kendimden sonra adlandırdım. İlk Linux, şimdi git". (Bu bir kinayedir. Çünkü Linus, kendi işletim sistemi çekirdeği için Linux adını kullanmamayı yeğledi.)

Kullanım

Burada, yeni bir projenin bir git deposuna nasıl aktarılacağını, değişikliklerin nasıl yapılacağını ve değişikliklerin diğer geliştiricilerle nasıl paylaştırılacağı açıklanıyor.

Öncelikle, bir komut için yazılmış belgeyi her zaman aşağıdaki komut ile görüntüleyebilirsiniz. Örneğin, git log --graph belgesini görüntülemek için:

Görevi: belge görüntüler
man git-log

Başlamadan önce git'e adınız ve e-posta adresinizi vermeniz önerilir. Bunu yapmanın en kolay yolu şu komutları çalıştırmaktır:


git config --global user.name "Adınız Soyadınız"<br>
git config --global user.email mail@adresiniz.com

Yeni bir projeyi aktarmak

Proje klasöründe başladığınız bir iş olduğunu varsayalım. Projenizi git sürüm kontrolüne vermek için:


cd proje<br>
git init

Git'in cevabı aşağıdaki gibi olacaktır:

Initialized empty Git repository in .git/

Yani .git/ adında yeni bir çalışma dizini başlattığınızı söyler.

Şimdi, git'ten geçerli dizindeki bütün dosyaların bir görüntüsünü almasını isteyelim:


 git add .

Buradaki . işaretine dikkat edin

Bu görüntü, git'in "index" adını verdiği geçici bir alanda saklanır. Index'in içeriğini kalıcı olarak saklamak için şu komutu kullanın:


git commit

Bu komut sizden bir teslim iletisi isteyecektir. Şimdi, projenizin ilk sürümünü git içinde sakladınız.

Değişiklik yapma

Birkaç dosyayı değiştirin ve sonra güncellenmiş içeriği index'e ekleyin:


git add dosya1 dosya2 dosya3

Teslim için hazırsınız, Nelerin teslim edilmek üzere olduğunu şu söz dizimini kullanarak görebilirsiniz:


git diff --cached

(Burada eğer --cached seçeneğini kullanmasaydık, git-diff bize, index'e eklenmemiş değişikliklerinizi gösterirdi.) Ayrıca, durumunuzun kısa bir özeti için şu komutu kullanabilirsiniz:


git status

Bunun çıktısı şuna benzer olacaktır:

# master dalında<br>
# Yapılan değişiklikler:<br>
# (kararsız yapmak için "git reset HEAD ..." kullanın)<br>
#<br>
# düzenlenen: dosya1<br>
# düzenlenen: dosya2<br>
# düzenlenen: dosya3<br>
#

Yapacağınız başka değişiklikler varsa, bu aşamada yapın ve değişen dosyaları index'e ekleyin. Sonunda, yaptığınız değişiklikleri teslim etmek için şunu kullanın:


git commit

Sizden tekrar yaptığınız değişiklikleri açıklayan bir ileti isteyecek ve ardından projenizin yeni bir sürümünü kaydedecektir.

Her dosya için, git-add kullanmak yerine, şunu kullanabilirsiniz:


git commit -a

Bu komut otomatik olarak içeriği değişen dosyaları fark edecek, (yeni dosyaları değil ) onları index'e ekleyecek ve teslim edecektir. Bu kadarcık bir işlem ile tüm bu işlemleri gerçekleştirebilirsizin.

Teslim iletileri hakkında: Zorunlu olmasa da, teslim iletilerinin değişikliğini özetleyen kısa bir cümle ile (50 karakterden az) başlamanız önerilir. İlk satırın ardından bir satır boşluk daha ekleyin ve sonra daha fazla açıklama girin. Teslimleri e-posta olarak gönderen araçlar, ilk satırı konu başlığı, kalan kısmı ise ileti metni olarak kullanırlar. Git, içerikleri takip eder, dosyaları değil.

Birçok sürüm kontrol sistemi, bir add komutu sunar. Bu komut sisteme yeni bir dosya için değişiklikleri izlemesini bildirir. Git ile gelen add komutu daha basit ve güçlü bir iş yapar: git-add komutu, hem yeni hem de değişen dosyalar için kullanılır ve iki durum için de dosyaların ve ortamın görüntüsünü, bir sonraki teslim için kaydeder.

Proje geçmişini görüntüleme

Herhangi bir noktada, yaptığınız değişikliklerin geçmişini aşağıdaki komut ile görebilirsiniz:


git log

Ayrıca, her adımda yaptığınız değişikliklerin tamamını görmek için şunu kullanın:


git log -p

Genellikle, değişikliklerin özetini görmek her adımı hatırlamakta faydalıdır. Bunun için de:


git log --stat --summary

Dalları yönetme

Bir git deposu, geliştirmenin birçok dalını idare edebilir. "Deneysel" adında yeni bir dal oluşturmak için şunu kullanın:


git branch deneysel

Şu komutu verdiğinizde:


git branch

var olan bütün dalların bir listesini görürsünüz:

deneysel<br>
* master

Deneysel dalı sizin şimdi oluşturduğunuz daldır ve "master" ise varsayılan dala verilen isimdir. Yıldız işareti (*), hangi dal üzerinde çalıştığınızı gösterir, dal değiştirmek için şunu yazın:


git checkout deneysel

ve deneysel dala geçin. Şimdi bir dosyayı değiştirin, değişikliği teslim edin ve tekrar master dala geçiş yapın:


git commit -a<br>
git checkout master

Şimdi yaptığınız değişikliklerin yerinde olmadığını bir kontrol edin. Yaptığınız değişiklikler deneysel dalda kaldı ve siz master dala geçtiniz.

Ana dalda başka bir değişiklik daha yapın:


git commit -a

Bu noktada, iki dal birbirinden ayrıldı, ikisinde de farklı değişiklikler var. Deneysel dalda yapılan değişiklikleri master'da birleştirmek için, şunu çalıştırın:


git merge deneysel

Eğer değişiklikler çakışmazsa, tamamdır. Çakışmalar varsa, şüpheli dosyaların solunda bir işaret görülür;


git diff

komutu bunu yapacaktır. Dosyaları düzenleyerek çakışmaları çözdükten sonra,


git commit -a

komutu birleştirmenin sonucunu teslim edecektir. Son olarak,


gitk

size geçmişteki değişikliklerin, görsel bir temsilini sunacaktır.

Bu noktada, deneysel dalı silebilirsiniz.


git branch -d deneysel

Bu komut deneysel dalda yapılan değişikliklerin, geçerli dalda da bulunduğunu kontrol eder.

Eğer cilgin-fikir dalında yaptığınız bir geliştirmeden pişman olduysanız o dalı şöyle silebilirsiniz:


git branch -D cilgin-fikir

Dallar basit ve kolaydır, bir şeyleri denemenin iyi bir yoludur.

Birlikte çalışma için git kullanma

Diyelim ki, Esat yeni bir proje başlattı ve git deposu da /home/esat/proje klasöründe, ve aynı bilgisayar üzerinde bir kullanıcı olan Yusuf katkıda bulunmak istiyor.

Yusuf şu komutla başlıyor:


yusuf$ git clone /home/esat/proje depom

Bu komut depom adında yeni bir dizin oluşturur, bu dizin Esat'ın deposunun tamamen bir kopyasıdır, özgün projenin tüm geçmişi ile birlikte.

Yusuf bazı değişiklikler yapar ve teslim eder:


yusuf$ git commit -a

(gerektikçe tekrar edin)

Hazır olduğunda, Esat'ın değişiklikleri /home/yusuf/depom adresinden çekmesini söyler. Esat bunu yapmak için şu komutu uygular:


esat$ cd /home/esat/proje<br>
esat$ git pull /home/yusuf/depom master

Bu komut Yusuf'un "master" dalındaki değişiklikleri, Esat'ın geçerli dalıyla birleştirir. Eğer o sırada Esat'ın de yaptığı değişiklikler varsa, çakışmaları elle düzeltmesi gerekebilir.

"pull" komutu şu iki işlemi gerçekleştirir: değişiklikleri uzak bir daldan alır ve geçerli dalda birleştirir.

Genellikle, Esat yaptığı değişiklikleri, "pull" işleminde önce teslim etmek isteyecektir. Eğer Yusuf'un işi, geçmişleri çatallandığından beri Esat'ın yaptıklarıyla çakışıyorsa, Esat kendi çalışma dizininde çakışmaları giderecek ve kendi değişiklikleri bu çakışmaların çözüm sürecinde ona engel olacaktır. (git, değişiklikleri çekecektir ancak birleştirme yapmayı reddedecektir --- Esat bir şekilde kendi değişikliklerinden kurtulacak ve tekrar uzaktaki değişiklikleri çekmeyi deneyecektir.)

Esat, birleştirmeyi yapmadan önce, Yusuf'un ne yaptığına bakabilir ve değişikliklerin çekmeye değer olup olmadığına karar verebilir, bunun için "fetch" komutu kullanılabilir;


esat$ git fetch /home/yusuf/depom master<br>
esat$ git log -p HEAD..FETCH_HEAD

Esat, geçmişleri çatallandığından bu yana Yusuf'un yaptığı değişiklikleri görselleştirmek isterse, şu komutu kullanabilir:


gitk HEAD..FETCH_HEAD

Bu komut git log ile gördüğümüz iki-noktalı aralık gösterimini kullanıyor.

Esat, çatallanmadan sonra ikisinin de yaptıkları değişiklikleri görmek isterse üç-noktalı biçimi şöyle kullanmalı:


gitk HEAD...FETCH_HEAD

Bu komutun anlamı, "her iki tarafta da olan değişiklikleri gösterme, taraflardan herhangi birinde olmayan değişiklikleri göster" demektir.

Bu aralık gösteriminin, hem gitk hem de "git log" ile kullanılabileceğini hatırlayın.

Yusuf'un ne yaptığını incelikten sonra, eğer önemli bir durum söz konusu değilse, Esat değişiklikleri Yusuf'dan çekmeden çalışmaya devam edebilir. Yusuf'un geçmişi önemli bir değişiklik içeriyorsa, Esat geliştirmekte olduğu işi saklayabilir, bir "pull" komutu ile Yusuf'dan değişiklikleri çekebilir, sonra ortaya çıkan geçmiş üzerinde sakladığı dosyalarla çalışmaya devam edebilir.

Bir topluluk içinde çalışırken, genellikle bir depo ile tekrar tekrar çalışırsınız. Uzak (remote) bir depo tanımı yaparak işinizi kolaylaştırabilirsiniz:


esat$ git remote add yusuf /home/yusuf/depom

Aşağıdaki komutla, Esat çekme işleminin ilk kısmını şu komut ile, dalları birleştirmeden yapabilir:


esat$ git fetch yusuf

Uzun haline göre, Esat Yusuf'dan değişiklikleri, git-remote ile kurulan uzak depo kısayolu ile çekmektedir. Çekilen ne varsa, bir uzak takip dalında tutulur. Bu durumda, dalın adı yusuf/master'dır.


esat$ git log -p master..yusuf/master

bu komut, Esat'in master dalından ayrıldığı andan itibaren Yusuf'un yaptığı değişiklikleri listeler.

Esat, bu değişiklikleri inceledikten sonra, değişiklikieri kendi master dalında birleştirmek isteyebilir. Bunun için:


esat$ git merge yusuf/master

Bu merge (birleştirme) ayrıca, uzak takip dalından çekilerek de yapılabilir:


esat$ git pull . remotes/yusuf/master

Komut satırında ne verilirse verilsin, pull her zaman geçerli dal ile birleştirir.

Daha sonra Yusuf, deposunu Esat'ın yaptığı değişikliklerle güncelleyebilir:


yusuf$ git pull

Esat'ın yaptığı değişiklikleri almak için Yusuf'un depo adresini vermediğine dikkat edin. Yusuf, Esat'ın deposunu kopyaladığı zaman, git deponun adresini kaydetti ve bu adresi çekme işlemi için kullandı:


yusuf$ git config --get remote.origin.url<br>
/home/esat/proje

(git-clone tarafından ayarlanan tüm yapılandırma git config -l ile öğrenilebilir ve git-config(1) kılavuz sayfası her seçeneğin ne anlama geldiğini açıklamaktadır.)

Git ayrıca, Esat'ın bozulmamış master dalını da "origin/master" adı altında saklar:


yusuf$ git branch -r origin/master

Yusuf eğer başka bir makineden çalışmak isterse, SSH protokolü ile kopyalama ve çekme yapabilir:


yusuf$ git clone esat.org:/home/esat/proje depom

Ayrıca, git kendi yerel protokolüne sahiptir, rsync ya da http kullanabilir.

Git ayrıca, CVS-benzeri bir şekilde merkezi bir depo ile kullanılabilir.

Geçmişe yolculuk

Git geçmişi birbiriyle ilişkili teslimler halinde gösterir. git-log komutunun bu teslimleri listelediğini gördük. Her bir kayıt girdisindeki ilk satırın, teslime verilen ad olduğunu unutmayın:


$ git log<br>
commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7<br>
Author: Junio C Hamano<br>
Date: Tue May 16 17:18:22 2006 -0700

merge-base: Clarify the comments on post processing.

Biz bu adı, git-show komutuna vererek, teslim hakkındaki detaylara ulaşabiliriz:


git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7

Teslimleri belirtmenin başka yolları da var. Teslim adının eşsiz kalacak kadar kısmını kullanabilirsiniz:


git show c82a22c39c # ilk birkaç karakter genellikle yeterlidir<br>
git show HEAD # geçerli daldaki değişiklikler<br>
git show experimental # deneysel daldaki değişiklikler

Hemen hemen her teslim, bir önceki durumu işaret eden bir ana-baba teslime sahiptir.


git show HEAD^<br>
git show HEAD^^<br>
git show HEAD~4<br>

git show HEAD^1<br>
git show HEAD^2

Ayrıca, teslimlere kendi istediğiniz bir adı verebilirsiniz.


git tag v2.5 1b2e1d63ff

1b2e1d63ff yerine "v2.5" kullanabilirsiniz. Eğer, bu adı başkalarıyla paylaşmak istiyorsanız (örneğin, bir sürüm belirlemek için), bir "tag" nesnesi yaratmalı ve imzalamalısınız.

Bir teslimin adına ihtiyaç duyan her git komutu için, bunlardan herhangi birini kullanabilirsiniz, örneğin:


git diff v2.5 HEAD # HEAD ile v2.5 karşılaştırılır<br>
git branch kararli v2.5 # v2.5 temel alınarak "kararli" adinda bir dal yaratır<br>
git reset --hard HEAD^ # Mevcut dalınızı iptal eder ve durumunuzu HEAD^ öncesine çevirir.

Son komutu kullanırken dikkatli olun, son teslimden bu yana yaptığınız tüm değişiklikleri siler ve teslim edilecek bir değişiklik bırakmaz. git-reset komutunu ortak çalışılan bir depoda kullanmayın, bu diğer geliştiricilerin de gereksiz birleştirmeler yapmasına sebep verir. Ortak depoya gönderdiğiniz değişiklikleri geri almak için git-revert komutunu kullanın.

Herhangi bir metni, herhangi bir sürüm içinde aramak için şunu kullanabilirsiniz:


git grep "merhaba" v2.5

Bu komut v2.5 içinde "merhaba" geçen tüm dosyaları arayacaktır.

Teslim adını vermezseniz, git-grep dizindeki bütün dosyalarda arama yapacaktır.


git grep "merhaba"

git ile takip edilen dosyalarda arama yapmanın kısa bir yoludur.

Birçok git komutu teslimlere göre çalışabilir. git-log ile bir örnek:


git log v2.5..v2.6 # v2.5 ile v2.6 arasında yapılan teslimler.<br>
git log v2.5.. # v2.5'ten bu yana teslimler<br>
git log --since="2 hafta önce" # 2 haftadan bu yana teslimler<br>
git log v2.5.. Dosya # 2.5'ten itibaren dosyayı değiştiren teslimler

Deneysel dalda yapılan ancak kararli dalda bulunmayan teslimleri listelemek için:


git log kararli..deneysel

Kararli dalda yapılan ancak, deneysel dalda bulunmayan teslimleri listelemek için:


git log deneysel..kararli

gitk --since="2 hafta önce" drivers/<br>
git diff v2.5:Makefile HEAD:Makefile.in

Dosyaları görüntülemek için de şu komutu kullanabilirsiniz:


git show v2.5:Makefile

Kaynaklar