Git SCM Nedir? Nasıl Kurulur?

Versiyon kontrol sistemi (Version Control System / VCS) yazısının devamı olarak git versiyon kontrol sistemi (ya da diğer ifadelerle; revizyon kontrolü veya kaynak kontrolü) ile devam edelim.

AA

Bu yazı içerisinde git’e dair detaylar, tarihçe, git üzerine inşa edilmiş platformlar ve temel bazı komutlara değinmeye çalışacağım. Daha ileri komutlar ve conflict çözümleri için ileri okumalar başlığı altındaki yazılara göz atabilirsiniz.

Git (Git SCM)

Git’in ortaya çıkış sürecinde Linux önemli bir yer tutmakta. Oldukça büyük ölçekli bir açık kaynak projesi olan Linux çekirdeği (kernel) 1991-2002 yılları arasındaki dönemde yamalar ve arşiv dosyaları üzerinden düzenlenmekteydi. Bu kadar kapsamlı bir projenin bu şekilde yürütülüyor olması elbette geliştirme sürecinin ağır işlemesine ve karmaşık bir hal almasına neden olmaktaydı.

Çözüm arayışı içerisinde olan Linux geliştiricileri, 2002 yılında, açık kaynak projeler için ücretsiz lisanslama modeli sunan BitKeeper1 adında tescilli bir Dağıtık Versiyon Kontrol Sistemi uygun bir çözüm olduğunu düşünerek projeyi bu sisteme taşımaya karar verdiler. Ancak, projenin büyümesi, geliştirici sayısının hızlı bir şekilde artması başta olmak üzere bazı nedenlerden dolayı 2005 yılında BitKeeper’ı geliştiren şirket ücretsiz sağladığı lisansı geri çekmeye karar verdi. BitKeeper’ın ücretsiz sağladığı lisansı geri çekmesi üzerine Linus Torvalds2 ve Linux ekibi kendi dağıtık versiyon kontrol sistemini geliştirmeye karar verdiler. Bu olumsuz durum beraberinde yeni bir sürecin de başlamasına neden oldu.

Özellikle Linux’un yaratıcısı olan Linus Torvalds başta olmak üzere diğer geliştiriciler BitKeeper’ı kullanırken edindikleri tecrübe ve ihtiyaçları temel alarak kendi araçlarını geliştirmeye karar verdiler. Hedeflenen özelliklerden bazıları şunlardı:

  • Basit tasarım,
  • Hız ve pratiklik,
  • Çizgisel (lineer) olmayan geliştirme iş akışı desteği (büyük projeler için binlerce sayıya ulaşabilecek dallar (branch)),
  • Tamamen dağıtık olma.

Git için atılan ilk adımlardan bu yana pek çok özellik sisteme dahil edilmiş olsa da Git’in kullanım kolaylığı ve hız özellikleri ödün verilmeksizin sürdürülmekte.

Git’in Sunduğu Farklılıklar

Git’i Apache Subversion3 gibi sistemlerle kıyasladığımızda, esas farklılık sistemlerin bilgiyi yorumlayış biçimleri olacaktır. Çünkü CVS4, Subversion3, Perforce5, Bazaar6 gibi Git harici sistemlerin çoğu bilgiyi dosya-tabanlı bir dizi değişiklik ve bir dosya kümesi olarak depolar. Ayrıca, bilgi her bir dosya üzerinde yapılan değişikliklerin listesi olarak yorumlanır. Aşağıda yer alan grafik ile bu süreç örneklendirilebilir.

Versiyon Kontrol Sistemleri
Pro Git – What is Git?

Referans görselden de anlaşıldığı üzere, Git haricindeki sistemlerde veri her bir dosyanın ilk sürümu üzerinde yapılan değişiklikler olarak (patch) depolanmaktadır. Git ise bu yapının aksine, veriyi bir mini dosya sisteminin bellek kopyaları olarak yorumlar. Her commit (kayıt) işleminde ya da proje konumunun kayıt edilmesi durumunda Git o dosyaların nasıl göründüğünün bir fotoğrafını çekip o bellek kopyasına bir referansı depolar. Verimlilik amacıyla değişmeyen dosyalar yeniden depolanmaz ancak halihazırda depolanmış bir önceki özdeş kopyaya bir bağlantı sağlanır. Bu özellik Git’i diğer versiyon kontrol sistemlerinden ciddi bir biçimde ayırır. Aşağıdaki görselde Git’in değişiklikleri ele alış biçimi gösterilmektedir.

Git’in sunduğu diğer özellikleri şu başlıklar altında özetleyebiliriz:

Hız

Git işlemlerin çoğunu yerel dosyalar ve kaynaklar üzerinden yürütür, bu nedenle çoğu durumda bilgisayar ağındaki başka bir bilgisayara bağlanması gerekmez. Çünkü projenin tam tarihçesinin bir kez yerel diskte kayıt edilmiş olması yeterlidir. Artık Git’in tekrar bir bağlantı kurmasına gerek kalmaz, bu da işlemlerin anlık gerçekleşiyorcasına hızlı olmasını sağlar.

Sürüm Karşılaştırma

Git ya bir sunucudan fark hesaplaması yapmasını talep eder ya da karşılaştırmayı (diff) yerelde ilgili dosyaları bulup kıyaslar. Bu sayede internet bağlantınız kesilse dahi dosyalar üzerinde istediğiniz gibi çalışmaya devam edebilirsiniz.

SHA-1 Özeti

Git’e fark ettirmeden bir dosya ya da klasörde işlem yapmak pek mümkün değildir. Git tüm dosya işlemlerini izler ve depolama işleminden önce dosyaları sınama toplamından geçirilir (checksum). Git’in sınama toplamı için kullandığı mekanizmaya SHA-1 özeti denir. Bu işlem Git’in merkezi işlevlerinden biridir. Bu özellik sayesinde, transfer aşamasında bir veri kaybı olmuşsa ya da doysa arızası mevcutsa sistem tarafından fark edilir.

Git’te bir işlem gerçekleştirildiğinde Git işlemi veritabanına veri ekler. Bu kayıt dosya adıyla değil, içeriğinin özet değeriyle ifade edilir. Git’e kayıt edilen bir bellek kopyasının veri kaybına uğraması oldukça zordur. Özellikle veritabanı düzenli olarak başka bir yazılım havuzuna (repository) push ediliyorsa veri kaybı gibi bir aksilik yaşanması pek muhtemel değildir.

Git ve Dosya / Proje Aşamaları

Git’te, dosyalar şu üç aşamadan (state) birinde yer alır; modified, staged ve committed.

  1. Modified (değiştirilmiş), dosyayı değiştirmiş ancak henüz veritabanına kaydetmediğimiz aşamadır.
  2. Staged (hazırlanmış), ara aşamadır. Bir dosyaki değişikliğin bir sonraki kayıt işleminde bellek kopyasına alınmak üzere işaretlendiği aşamayı ifade eder.
  3. Committed (kaydedilmiş), verinin güvenli biçimde veritabanında depolanmış olduğu anlamına gelir.

Dosyaları çözümlediğimize göre, şimdi de projelerin bölümlerine bakalım. Bir Git projesin de üç ana bölüme sahiptir; working directory (çalışma klasörü), .git directory (Git klasörü) veya repository ve staging area (hazırlık alanı).

Versiyon Kontrol Sistemleri
Pro Git – What is Git?
  1. Working directory (çalışma klasörü), projenin bir sürümünden yapılan tek bir seçmedir. Bu dosyalar Git klasöründeki sıkıştırılmış veritabanından çıkartılıp kullanım için uygun hale getirilir.
  2. Staging area (hazırlık alanı), indeks olarak da ifade edilir. Genellikle Git klasöründe bulunan ve işlemlerin kayıt düşüldüğü dosyadır.
  3. .git directory (Git klasörü) veya repository, Git’in projeye ait üstverileri (metadata) ve nesne veritabanını depoladığı yerdir. Bir projeyi bir bilgisayardan bir diğerine klonladığımızda aktardığımız şeydir.

Bu süreç şu şekilde işler:

  1. Çalışma klasöründeki dosyalar üzerinde değişiklik yaparız,
  2. Değişikliklerin tamamlanmasının ardından, dosyaların bellek kopyalarını alır ve dosyaları .git klasörüne gönderilmek üzere hazırlarız (stage area).
  3. Dosyaların hazırlık alanındaki hallerini alıp oradaki bellek kopyasını kalıcı olarak .git klasörüne depolayan commit işlemini yaparız.

Git Kurulumu

Git’in ortaya çıkışı ve sunduğu özelliklere değindik. Peki, bu özelliklerden nasıl faydalanabiliriz?

Git kurulumunu kaynak kodundan ya da platform için sunulan paket ile gerçekleştirebiliriz. Önerilen yöntem, güncelliği sebebiyle kaynak kodun kullanılmasıdır. git-scm.com/download7 adresinde üzerinden macOS, Unix-like ve Windows için sunulan güncel dağıtıma ulaşabilirsiniz.

Ubuntu gibi Debian-tabanlı bir sistem için:

apt-get install git
# ya da
add-apt-repository ppa:git-core/ppa
apt update
apt install git

macOS için:

brew install git

Artık Git sisteminizde kurulu olduğuna göre, onu ihtiyacınıza göre uyarlamak için bazı düzenlemeler yapabilirsiniz.

Git Konfigürasyonu

Konfigürasyon işlemlerini yalnızca bir kere yapmamız yeterli. İlerleyen zaman içerisinde yapılacak bir güncelleme konfigürasyon işlemlerini etkilemez ve istediğimiz zaman bu ayarları değiştirebiliriz.

Konfigürasyon değişkenlerini git config aracıyla düzenleriz. Bu araçla yapılan değişiklikler üç farklı yerde depolanabilirler:

  • /etc/gitconfig, sistemdeki bütün kullanıcılar ve onlara ait yazılım havuzları için geçerlidir. git config komutunu --system ile kullandığımızda işlemler bu dosyadan okunur ve bu dosyaya işlenir.
  • ~/.gitconfig, aktif kullanıcıya özeldir. --global ile işlemlerin bu dosyadan okunup yine bu dosyaya işlenmesini sağlayabiliriz.
  • .git/config, projeye özeldir ve diğer konfigürasyon dosyalarından daha öncelikli olarak değerlendirilir (override).

Git Konfigürasyon İşlemleri

Kurulumun ardından yapılması gereken ilk işlem ad ve e-posta ile sistem ile ilişkilendirilmektir. Bu bilgiler dolaşımdaki her bir Git kaydına değişmez bir biçimde işlenir.

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

Komutlardan da görüldüğü üzere bu tanımlama ~/.gitconfig dosyasına kayıt edilir ve bir kez yapılması yeterlidir. Artık, ilişkili sistemdeki her işlem için bu bilgiler kullanılacaktır. Kimlik bilgilerimizin projelere göre değişiklik göstermesi gerekiyor ise komutu değişiklik yapmak istediğimiz projede --global olmadan çalıştırmamız yeterli olacaktır.

cd proje-adi
git config user.name "John Doe"
git config user.email johndoe@example.com

Bu durumda bilgiler .git/config dosyasına işlenir ve oradan okunur. Yapılan işlemler sonrasında, ayarları gözden geçirmek istersek git config --list komutunu kullanabiliriz.

git config --list
user.name=John Doe
user.email=johndoe@example.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...

Unutmadan ekleyeyim. Az önce --global yerine projeye özel konfigürasyon tanımları yapabileceğimizi belirtmiştim. Bu gibi durumlarda bir ayarı birden çok kez görebiliriz. İşte bu gibi durumlarda, olası karışıklıkları önlemek adına, Git tarafından kullanılacak son değerleri git config {degisken} komutu ile edinebiliriz.

git config user.name
John Doe

Ayrıca, aksi belirtilmedikçe Git sistemde öntanımlı olan editörü kullanır. Farklı bir metin editörü tanımını şu şekilde yapabiliriz.

git config --global core.editor [editor-adi]

Bir diğer düzenleme de birleştirme (merge) uyuşmazlıklarında (conflict) kullanacağımız karşılaştırma (diff) aracıyla ilgilidir.

git config --global merge.tool [diff-araci]

Son olarak, yukarıdaki konuların dışında aklımıza takılan her türlü işlem için Git yardım kılavuzundan (manpage) faydalanabiliriz. Bu dosyaya şu 3 şekilde erişmek mümkün:

git help
git --help
man git-

Daha önce yayınladığım yazılar ve örneklerin yanı sıra, ilerleyen zaman içerisindeki paylaşımlarda da yukarıdaki pek çok konuya değinmeye devam edeceğim. Bir sonraki yazıda ise Git sürüm yönetiminde kullanacağımız çeşitli platformlara ve ilgili komutlara değinmeye çalışacağım.