Yürü “Git”! :) – Bölüm 1: “Git” Nedir?

Kedi görünümli sevimli ahtopot 'Git'
“Git” Nedir?

Git(Türkçe: cit), bir versiyon kontrol sistemidir. Versiyon kontrolü(değişiklik kontrolü),  dosyalardaki değişiklikleri kayıt altında tutarak değişiklik tarihçesi oluşturmaktır. Bu şekilde kullanıcılar, tarihçe boyunca ilerleyip istedikleri duruma(state) geri dönebilirler. Bu amaca, değişikliğe başlamadan önce “Save as” diyerek değişiklik yaptığımız dosyaların kopyasını oluşturarak da ulaşabilirdik ama, değişiklik yaptığımız dosya sayısı arttıkça bunları aklımızda takip etmek yerine versiyon kontrol sisteminin takip etmesini sağlamak uygundur. Ayrıca, “Git”, sadece değişikliklerin yedeğini tutar dosyaların değil.  [Bunun nasıl yapıldığını ilerleyen bölümlerde “Git’in İç Yapısı, Çalışma Mekanizması” başlığı altında anlatacağım.]

Eş anlamlı kavramlar

Tarihçe = Tüm Versiyonlar

Versiyon = Commit = Değişiklik Kaydı = Değişiklik (Ekleme, Silme yapmak anlamındaki değil; belirli ekleme silmeleri niteleyen bir nokta) = Durum = State = Checkpoint = Geri Dönüş Noktası

Git’i diğer versiyon sistemlerinden ayıran özellikler nelerdir?
  1. Git dağıtık bir versiyon kontrol sistemidir: Bir yazılımın kullandığı dosyalardaki değişikliklerin tüm tarihçesi(tüm versiyonları) dosyalar(son versiyon) ile birlikte bir sunucu üzerinde bulunur. Yazılım üzerinde geliştirme yapmak isteyen biri, yazılımı oluşturan dosyaları, tüm versiyonları ile birlikte yerel bilgisayarına alır(pull) ve Git  ile bu dosyalarda yapacağı değişiklikleri kayıt altında tutmaya başlar. Geliştirme işlemi bittikten sonra değiştirdiği dosyalardan istediklerini, değişiklik kaydıyla birlikte istediği bir versiyonu sunucuya bırakır(push). Subversion(SVN) gibi klasik versiyon kontrol sistemleri, merkezi( centralized) dir. Yani, dosyalar ve bu dosyaların tek bir tane olan değişiklik tarihçesi vardır. Bu tarz sistemlerde kullanıcılar değişiklik tarihçesinin yerel bir kopyasına sahip değillerdir, sahip oldukları şey sadece üzerinde değişiklik yaptıkları dosyalardır,  değişiklik tarihçesine yani eski versiyonlara sahip değillerdir.  Neden dağıtık bir versiyon kontrol sistemine ihtiyaç duyulsun ki? Projede birlikte çalışan kişi sayısının (Collaboration) çok fazla olduğunu düşünelim. Bu kişiler merkezi bir versiyon kontrol sistemini kullanıyor olsun. Herkes, üzerinde değişiklik yapmak istediği dosyaları merkezi sunucudan alsın. Değişikliklerini yaparken, önceki versiyondan dosyalar almaya ihtiyaç duyduklarında sunucuyla tekrar iletişime geçmek zorunda kalacaklardır. Önceki versiyonun alınmak istenmesenin çeşitli sebepleri olabilir; eski bir özelliği geliştirmek, yeni özelliği eski özellikle karşılaştırmak, eski versiyondaki bir tasarım kalıbını yenisiyle karşılaştırmak gibi. Sunucuyla sürekli iletişime geçmek yerine bütün versiyonları bir anda yerel bilgisayarına alabilseydi, zaman kayıpları yaşanmayacaktı. Bu cevabı açıklarken Git Magic – Introduction#Distributed Control daki yazıda verilen bilgisayar oyunu kayıtları benzetmesinden yararlandım. Her ne kadar bu sebep bana yeterince somut görünmese de bu özelliğin birçok kişinin aynı anda üzerinde çalıştığı açık kaynak projelerde ortaya çıkan ihtiyaçtardan dolayı olduğu aklımda. Bu yazı serisinin ilerleyen bölümlerinde bu özelliğin kullanıldığı bir iş akışını(workflow) göstereceğim.
  2. “Index a.k.a. Staging Area”, Incremental Committing:  Diğer versiyon kontrol sistemlerinde, bir Commit birden fazla küçük Commit lerden oluşabilir. Oysa bir Commit in belirttiği değişiklikler, atomik olmalıdır. Burada atomik derken kastettiğim şey, sadece tek bir amacı olan değişiklikler kayıtlarıdır. Bunun amacı, daha net geri dönüş noktaları oluşturabilmektir. Bu sayede; tarihçeye bakarak bir versiyona geri döndüğümüzde karşılaşacağımız durum(state), tam istediğimiz durum olacaktır. Genelde dosyalar üzerinde yapılan değişikliklerinin ne kadarının bir Commit için yeterli olacağı düşünülmez, daha doğrusu versiyon kontrol sistemlerinin buna elverişli bir aracı yoktur. İşte Git, Staging Area ile incremental olarak atomik Commit’ler yapabilmeye elverişli bir ortam sağlar. Diğer versiyon kontrol sistemlerinde bu ara yapı yoktur. Git’ te ise üzerinde değişiklik yapılan dosyalar ile bu dosyaların değişiklik kaydının tutulduğu veritabanı arasında bir ara yapı, sahne(Staging Area) vardır. [Bu yazı serisinin ilerleyen bölümlerinde
    git  status, git add, git mv, git rm, git diff

    gibi Git komutları ile sahne üzerine işlemler yapan iş akışları göstereceğim.][Bu veritabanının yapısı ilerleyen bölümlerde “Git’in İç Yapısı, Çalışma Mekanizması” başlığı altında anlatılacak].

  3. “Remote Repo” ve “Code Hosting”: GitHub ve Gitorious gibi web uygulamaları hem yerelde geliştirilen projelerin konulabileceği bir ortam sağlar, hem de başka geliştiricilerin üzerinde çalıştığı çeşitli projelere ulaşıp o projelere katılabilmeyi sağlar. [Collaboration and Open Source]
  4. Unix üzerinde Vi(m) ile birlikte kullanımı: Vi(m)(Vee-eye-improved) ile birlikte tam olarak profesyonel bir şekilde yazılım geliştirme imkanı sağlar. [Kişisel Görüşüm 🙂 ]
Git Terminolojisi (Remote -> Local -> Remote işlem sırasına göre)

Repository(Repo)    :  Değişiklik tarihçesi(Versiyon, Checkpoint, Durum)nin tutulduğu veritabanıdır.

Remote Repository :  GitHub gibi sitelerde, versiyonları(tüm değişiklik tarihçesini) ve Dosyaları(Son Versiyonu) tutan veritabanlarıdır. Buradan birisinin ya da kendimizin bir repo sunu yerel bilgisayarımıza almak istediğimizde aşağıdaki gibi

git clone

komutunu kullanarak tüm değişiklik tarihçesini ve son versiyon anlamına gelen asıl dosyaları alırız:

$ git clone git://github.com/schacon/simplegit.git
Initialized empty Git repository in /private/tmp/simplegit/.git/
remote: Counting objects: 100, done.
remote: Compressing objects: 100% (86/86), done.
remote: Total 100 (delta 35), reused 0 (delta 0)
Receiving objects: 100% (100/100), 9.51 KiB, done.
Resolving deltas: 100% (35/35), done.
$ cd simplegit/
$ ls
README   Rakefile lib
Local Repository : Yukarıdaki işlemden sonra simplegit klasörü içinde bu projedeki değişikliklerin kaydının tutulacağı bir Git veritabanı oluşturulmuş olur.(initialize). Bu veritabanına Local Repo denir.
Working Copy : Uzaktaki(remote git hosting place) bir repodan alınan versiyonun belittiği dosyalar, ya da bir proje klasörünün altında yerelde oluşturulan dosyalar üzerinde ekleme silme değişikliklerinin yapılacağı kaynaklardır. Bunlara Working Copy denir. Git init edildiği andan itibaren tüm versiyon kontrol sistemi süreci working copy deki değişikleri local repo ya kontrollü bir şekilde commit ekmekten ibarettir.
You stage the files, adding snapshots of them to your staging area.
Stage, Snapshot, Staging Area: Yukarıdaki alıntıdan gidecek olursam, working copy de olan, üzerinde değişiklik yapılan dosyalar sahne(stage)lenir. Git terminolojisinde bu teknikten ziyade mantıksal bir kavramdır. Burada yapılan şey, mantıksal anlamda, bir değişikliği sahneleyerek değişikliğin hatıra fotoğrafı(snapshot)nı almaktır.  Bu fotoğraf hala çıkmamıştır, sahne alanı(staging area) dadır karanlık odada bekletilecek diye düşünebiliriz. Daha sonra karanlık odadan çıkıp fotoğrafın basılması demek; değişikliği Local repo ya commit etmektir. Bu durum, Git’in diğer versiyon kontrol sistemlerinden farklarını anlatırken bahsettiğim incremental committing özelliğinden dolayıdır.
Index: Yukarıdaki staging area nın teknik karşılığıdır. Yani, teknik anlamda, Working Copy deki örnek bir dosyadaki değişiklikler yapıldı diyelim, bu dosya  git add ile index e eklenir. Dosyanın o andaki hali yani yapılan değişiklik geçici, ara, bir yerde saklanmış olur. Bundan sonra working copy de aynı dosyada değişiklik yapılmaya devam edilebilir. Diyelim ki, dosyanın sonuna üç satır daha eklendi; bu durumda commit yapılırsa bu eklenen üç satır o commit e dahil edilmez. Bu durum ilk bakışta  karışıklara yol açabilecek gibi görünse de Index yapısının incremental commit amacından kaynaklanır. index e eklenen herhangi bir değişiklikten yani snapshot tan sonra, yine tek bir dosya için konuşursak eğer, working copy deki o dosya ile stage teki snapshot u arasındaki fark
git diff

ile görülebilir. Her zaman tek dosya ile uğraşmayız. Birden fazla dosyadaki değişikler sahnede durduğunda, çeşitli Git komutları ile, bir sonraki Commit e hangi değişiklerin dahil olacağı seçilebilir.

Push: Yereldeki geliştirmede commitler ile Local Repoya değişiklik kayıtları işlenip geliştirmenin o aşaması tamamlandığında oluşan versiyon, belirtilen remote repoya push edilir. Local Repodaki versiyon ile Remote Repodaki versiyon arasında çakışmalar Merge işleminden sonra Git in gösterdiği conflict mesajlarından tespit edilir.

Pull: Remote Repodaki bir versiyonu Local Repo‘ya alıp o versiyonu oluşturan dosyalar working copy olarak kabul edilir ve versiyon kontrolü altında geliştirmeye devam edilir. Bu işleme Pull işlemi denir.

[Push, Pull, Branching, Merging gibi Remote Repo ile işlem içeren konular; üzerinde birden fazla kişinin üzerinde yapılan projelerde Giti etkin kullanırken gereklidir. Bireysel geliştirmeden ortak geliştirmeye doğru ilerlendikçe senaryolar karmaşıklaşır. Bu yüzden bu konularda, bu yazı serisi içerisinde, çeşitli yazılar yazmayı düşünüyorum]

Bu yazı serisinde sonraki yazıları bu konularda yazmayı düşünüyorum:

[GitHub‘da hesap oluşturmak ve açılan hesap altında yerelde geliştirilen uygulamanın aktarılacağı Remote Repo açmak ve buraya ilk Push‘u yapmak.]

[Git Global Config dosyasını ayarlamak]

[Git’in değişiklik kontrolü altında geliştirilen örnek bir uygulamanın yerelde başlayıp yerelde biten geliştirme adımları]

[Yerel geliştirmede sık kullanılan Git komutlarının referansı]

[Git’in İç Yapısı, Çalışma Mekanizması]

[Remote Repo İşlemleri: push ve pull, clone]

[Branch işlemleri]

[Release, Tag işlemleri]

Git konusunda okumakta olduğum çeşitli makaleler: http://tyb.tumblr.com/tagged/git

NOT: My Git Workflow da yukarıda anlattığım kavramların, git’i kullanırken oluşan, birbirleri arasındaki ilişkiler resimli olarak gösterilmiştir.

Bu yazı serisinin motivasyonu:

Eğer bir konuyu altı yaşındaki bir çocuğa açıklayamıyorsan, o konuyu kendin de anlamıyorsun demektir.

Einstein

Einstein’ın sözlerinden örnek vermeyi severim, çünkü kimse ona karşı çıkmaz istemez.

Söyleyen kişiyi unuttum 🙂

Advertisements

1 Comment

Filed under git

One response to “Yürü “Git”! :) – Bölüm 1: “Git” Nedir?

  1. sleepforlife

    repodan kopyasını aldımız bir dizini nasıl kurbiliriz?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s