DVCS evreni yalnızca Git’ten ibaret değildir. Aslında bu alanda, dağıtılmış sürüm kontrolünün doğru şekilde nasıl yapılacağı konusunda her birinin kendi bakış açısı olan birçok sistem daha vardır. Git’ten sonra en popüler olanı Mercurial’dır ve bu ikisi birçok yönden çok benzer.
Git’in istemci tarafı davranışını tercih ediyorsanız ancak kaynak kodu Mercurial tarafından kontrol edilen bir projeyle çalışıyorsanız; iyi haber, Git’i Mercurial tarafından barındırılan bir reponun istemcisi olarak kullanmanın bir yolu vardır. Git’in sunucu repolarıyla iletişim kurma şekli uzak repolar aracılığıyla olduğu için, bu köprünün bir uzak yardımcı olarak uygulandığı şaşırtıcı olmamalıdır. Projenin adı git-remote-hg’dir ve https://github.com/felipec/git-remote-hg adresinde bulunabilir.
Öncelikle git-remote-hg’yi kurmanız gerekiyor. Bu, temel olarak dosyasını yolunuzun üzerinde bir yere bırakmayı gerektirir:
$ curl -o ~/bin/git-remote-hg \
https://raw.githubusercontent.com/felipec/git-remote-hg/master/git-remote-hg
$ chmod +x ~/bin/git-remote-hg…'~/bin' öğesinin '$PATH' dizininizde olduğunu varsayıyoruz. Git-remote-hg’nin başka bir bağımlılığı daha var: Python için "Mercurial" kütüphanesi. Python’u yüklediyseniz, bu şu kadar basittir:
$ pip install mercurial(Python yüklü değilse https://www.python.org/ adresini ziyaret edin ve önce onu kurun.)
İhtiyacınız olan son şey Mercurial istemcisidir. https://www.mercurial-scm.org/ adresine gidin ve henüz yapmadıysanız yükleyin.
Artık dansa hazırsınız. İhtiyacınız olan tek şey, itebileceğiniz bir Mercurial reposudur. Neyse ki, her Mercurial reposu bu şekilde davranır, bu nedenle herkesin Mercurial’ı öğrenmek için kullandığı "merhaba dünya" reposunu kullanacağız:
$ hg clone http://selenic.com/repo/hello /tmp/helloArtık uygun bir “sunucu tarafı” repomuz olduğuna göre, tipik bir iş akışını gerçekleştirebiliriz. Göreceğiniz üzere, bu iki sistem fazla sürtünme olmayacak kadar benzerdir.
Git’te her zaman olduğu gibi önce repoyu kopyalarız:
$ git clone hg::/tmp/hello /tmp/hello-git
$ cd /tmp/hello-git
$ git log --oneline --graph --decorate
* ac7955c (HEAD, origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master, master) Create a makefile
* 65bb417 Create a standard "hello, world" programMercurial reposuyla çalışmanın standart "git clone" komutunu kullandığını fark edeceksiniz. Bunun nedeni, git-remote-hg’nin Git’in HTTP/S protokolünün uygulanmasına (uzaktan yardımcılar) benzer bir mekanizma kullanarak oldukça düşük bir düzeyde çalışmasıdır. Git ve Mercurial’ın her ikisi de her kullanıcının repo geçmişinin tam bir kopyasına sahip olması için tasarlandığından, bu komut tüm projenin geçmişini içeren tam bir kopya oluşturur ve bunu çok hızlı bir şekilde yapar.
Log komutu, en sonuncusu bir dizi referans tarafından işaret edilen iki işlemi gösterir.
Bunlardan bazılarının aslında orada olmadığı ortaya çıktı.
.git dizininde gerçekte ne olduğuna bir bakalım:
$ tree .git/refs
.git/refs
├── heads
│ └── master
├── hg
│ └── origin
│ ├── bookmarks
│ │ └── master
│ └── branches
│ └── default
├── notes
│ └── hg
├── remotes
│ └── origin
│ └── HEAD
└── tags
9 directories, 5 filesGit-remote-hg işleri daha deyimsel olarak Git benzeri hale getirmeye çalışır, ancak aslında birbirinden biraz farklı iki sistem arasındaki kavramsal eşlemeyi yönetir. 'refs/hg' dizini gerçek uzak referansların saklandığı yerdir. Örneğin, "refs/hg/origin/branches/default", "master"ın işaret ettiği katkı olan "ac7955c" ile başlayan SHA-1’i içeren bir Git ref dosyasıdır. Yani 'refs/hg' dizini bir nevi sahte 'refs/remotes/Origin' gibidir, ancak yer imleri ve dallar arasında ek bir ayrım vardır.
'notes/hg' dosyası, git-remote-hg’nin Git katkı karmalarını Mercurial değişiklik kümesi kimlikleriyle nasıl eşlediğinin başlangıç noktasıdır. Hadi biraz araştıralım:
$ cat notes/hg
d4c10386...
$ git cat-file -p d4c10386...
tree 1781c96...
author remote-hg <> 1408066400 -0800
committer remote-hg <> 1408066400 -0800
Notes for master
$ git ls-tree 1781c96...
100644 blob ac9117f... 65bb417...
100644 blob 485e178... ac7955c...
$ git cat-file -p ac9117f
0a04b987be5ae354b710cefeba0e2d9de7ad41a9Yani 'refs/notes/hg', Git nesne veritabanında adları olan diğer nesnelerin listesi olan bir ağaca işaret eder.
'git ls-tree' bir ağacın içinde yer alan öğeler için: mod, tür, nesne karması ve dosya adını verir.
Ağaç öğelerinden birini incelediğimizde, içinde ac9117f'' ("master" ile gösterilen katkının SHA-1 karması) adında ve 0a04b98'' içeriğine sahip bir blob olduğunu görürüz (bu, 'varsayılan' dalın ucundaki Mercurial değişiklik kümesinin kimliğidir).
Güzel olan şu ki, çoğunlukla tüm bunlar için endişelenmemize gerek yoktur. Tipik iş akışı Git uzaktan reposuyla çalışmaktan çok farklı olmayacaktır.
Devam etmeden önce ilgilenmemiz gereken bir şey daha var: yoksayılanlar.
Mercurial ve Git bunun için çok benzer bir mekanizma kullanır, ancak muhtemelen bir .gitignore dosyasını Mercurial reposuna işlemek istemezsiniz.
Neyse ki Git’in diskteki bir repoda yerel olan dosyaları yok saymanın bir yolu var ve bu Mercurial formatı Git ile uyumludur; dolayısıyla onu kopyalamanız yeterli:
$ cp .hgignore .git/info/exclude.git/info/exclude dosyası tıpkı .gitignore gibi davranır ancak katkılara dahil edilmez.
Diyelim ki 'master' dalında bazı değişiklikler yaptık ve bazı katkılar işledik ve siz de bunu uzak repoya göndermeye hazırsınız. Repomuz şu anda şöyle görünüyor:
$ git log --oneline --graph --decorate
* ba04a2a (HEAD, master) Update makefile
* d25d16f Goodbye
* ac7955c (origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master) Create a makefile
* 65bb417 Create a standard "hello, world" programBizim 'master' dalımız, Origin/master 'dan iki katkı ileridedir, ancak bu iki katkı yalnızca yerel makinemizde mevcuttur.
Bakalım aynı anda, başka biri de önemli işler yapıyor mu:
$ git fetch
From hg::/tmp/hello
ac7955c..df85e87 master -> origin/master
ac7955c..df85e87 branches/default -> origin/branches/default
$ git log --oneline --graph --decorate --all
* 7b07969 (refs/notes/hg) Notes for default
* d4c1038 Notes for master
* df85e87 (origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master) Add some documentation
| * ba04a2a (HEAD, master) Update makefile
| * d25d16f Goodbye
|/
* ac7955c Create a makefile
* 65bb417 Create a standard "hello, world" program--all bayrağını kullandığımız için, git-remote-hg tarafından dahili olarak kullanılan notes referanslarını görüyoruz, ancak onları görmezden gelebiliriz.
Gerisi beklediğimiz gibidir; 'Origin/master' tek bir katkı ilerledi ve artık geçmişimiz ayrıştı.
Bu bölümde üzerinde çalıştığımız diğer sistemlerden farklı olarak; Mercurial, birleştirme işlemlerini gerçekleştirebilir, dolayısıyla havalı bir şey yapmayacağız.
$ git merge origin/master
Auto-merging hello.c
Merge made by the 'recursive' strategy.
hello.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline --graph --decorate
* 0c64627 (HEAD, master) Merge remote-tracking branch 'origin/master'
|\
| * df85e87 (origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master) Add some documentation
* | ba04a2a Update makefile
* | d25d16f Goodbye
|/
* ac7955c Create a makefile
* 65bb417 Create a standard "hello, world" programMükemmel. Testleri yapıyoruz ve her şey başarılı oluyor, böylece çalışmalarımızı ekibin geri kalanıyla paylaşmaya hazırız:
$ git push
To hg::/tmp/hello
df85e87..0c64627 master -> masterBu kadar! Mercurial reposuna bakarsanız, bunun beklediğimiz şeyi yaptığını göreceksiniz:
$ hg log -G --style compact
o 5[tip]:4,2 dc8fa4f932b8 2014-08-14 19:33 -0700 ben
|\ Merge remote-tracking branch 'origin/master'
| |
| o 4 64f27bcefc35 2014-08-14 19:27 -0700 ben
| | Update makefile
| |
| o 3:1 4256fc29598f 2014-08-14 19:27 -0700 ben
| | Goodbye
| |
@ | 2 7db0b4848b3c 2014-08-14 19:30 -0700 ben
|/ Add some documentation
|
o 1 82e55d328c8c 2005-08-26 01:21 -0700 mpm
| Create a makefile
|
o 0 0a04b987be5a 2005-08-26 01:20 -0700 mpm
Create a standard "hello, world" program2 numaralı değişiklik seti Mercurial tarafından, 3 ve 4 numaralı değişiklik seti ise Git-remote-hg tarafından Git ile yapılan katkıların itilmesiyle yapıldı.
Git’in yalnızca tek bir tür dalı vardır: katkılar işlendiğinde hareket eden bir referans.
Mercurial’da bu tür bir referansa yer imi (bookmark) adı verilir ve Git dalıyla hemen hemen aynı şekilde davranır.
Mercurial’ın dal kavramı daha ağırdır.
Değişiklik kümesinin yapıldığı dal, değişiklik kümesiyle birlikte kaydedilir. Bu da her zaman repo geçmişinde yeralacağı anlamına gelir.
develop dalında yapılan bir katkı örneği:
$ hg log -l 1
changeset: 6:8f65e5e02793
branch: develop
tag: tip
user: Ben Straub <ben@straub.cc>
date: Thu Aug 14 20:06:38 2014 -0700
summary: More documentationbranch ile başlayan satıra dikkat edin.
Git bunu gerçekten kopyalayamaz (her iki dal türü de Git referansı olarak temsil edilebildiği için gerek de yoktur zaten), ancak Mercurial bunu önemsediği için git-remote-hg’nin farkı anlaması gereklidir.
Mercurial yer imleri oluşturmak Git dalları oluşturmak kadar kolaydır. Git tarafında:
$ git checkout -b featureA
Switched to a new branch 'featureA'
$ git push origin featureA
To hg::/tmp/hello
* [new branch] featureA -> featureAHepsi bu kadardır. Mercurial tarafında ise şöyle görünür:
$ hg bookmarks
featureA 5:bd5ac26f11f9
$ hg log --style compact -G
@ 6[tip] 8f65e5e02793 2014-08-14 20:06 -0700 ben
| More documentation
|
o 5[featureA]:4,2 bd5ac26f11f9 2014-08-14 20:02 -0700 ben
|\ Merge remote-tracking branch 'origin/master'
| |
| o 4 0434aaa6b91f 2014-08-14 20:01 -0700 ben
| | update makefile
| |
| o 3:1 318914536c86 2014-08-14 20:00 -0700 ben
| | goodbye
| |
o | 2 f098c7f45c4f 2014-08-14 20:01 -0700 ben
|/ Add some documentation
|
o 1 82e55d328c8c 2005-08-26 01:21 -0700 mpm
| Create a makefile
|
o 0 0a04b987be5a 2005-08-26 01:20 -0700 mpm
Create a standard "hello, world" programRevizyon 5’teki yeni [featureA] etiketine dikkat edin.
Bunlar, bir istisna dışında Git tarafındaki Git dalları gibi davranır (Git tarafından bir yer işaretini silemezsiniz: bu, uzak yardımcılara yönelik bir sınırlamadır).
Ayrıca ağır'' bir Mercurial dalı üzerinde de çalışabilirsiniz: branches`` ad alanına (namespace) bir dal koymanız yeterlidir:
$ git checkout -b branches/permanent
Switched to a new branch 'branches/permanent'
$ vi Makefile
$ git commit -am 'A permanent change'
$ git push origin branches/permanent
To hg::/tmp/hello
* [new branch] branches/permanent -> branches/permanentMercurial tarafın şöyle görünür:
$ hg branches
permanent 7:a4529d07aad4
develop 6:8f65e5e02793
default 5:bd5ac26f11f9 (inactive)
$ hg log -G
o changeset: 7:a4529d07aad4
| branch: permanent
| tag: tip
| parent: 5:bd5ac26f11f9
| user: Ben Straub <ben@straub.cc>
| date: Thu Aug 14 20:21:09 2014 -0700
| summary: A permanent change
|
| @ changeset: 6:8f65e5e02793
|/ branch: develop
| user: Ben Straub <ben@straub.cc>
| date: Thu Aug 14 20:06:38 2014 -0700
| summary: More documentation
|
o changeset: 5:bd5ac26f11f9
|\ bookmark: featureA
| | parent: 4:0434aaa6b91f
| | parent: 2:f098c7f45c4f
| | user: Ben Straub <ben@straub.cc>
| | date: Thu Aug 14 20:02:21 2014 -0700
| | summary: Merge remote-tracking branch 'origin/master'
[...]permanent (kalıcı) dal adı, 7 işaretli değişiklik kümesiyle kaydedildi.
Git açısından bakıldığında, bu dal stillerinden herhangi biriyle çalışmak aynıdır: normalde yaptığınız gibi yalnızca geçiş yapın, kaydedin, getirin, birleştirin, çekin ve itin. Bilmeniz gereken bir şey de Mercurial’ın tarihin yeniden yazılmasını desteklememesidir. Ona yalnızca ekleme yapabilirsiniz. Etkileşimli bir yeniden temelleme (rebase) ve zorla itme (forced push) sonrasında Mercurial repomuz şu şekilde görünür:
$ hg log --style compact -G
o 10[tip] 99611176cbc9 2014-08-14 20:21 -0700 ben
| A permanent change
|
o 9 f23e12f939c3 2014-08-14 20:01 -0700 ben
| Add some documentation
|
o 8:1 c16971d33922 2014-08-14 20:00 -0700 ben
| goodbye
|
| o 7:5 a4529d07aad4 2014-08-14 20:21 -0700 ben
| | A permanent change
| |
| | @ 6 8f65e5e02793 2014-08-14 20:06 -0700 ben
| |/ More documentation
| |
| o 5[featureA]:4,2 bd5ac26f11f9 2014-08-14 20:02 -0700 ben
| |\ Merge remote-tracking branch 'origin/master'
| | |
| | o 4 0434aaa6b91f 2014-08-14 20:01 -0700 ben
| | | update makefile
| | |
+---o 3:1 318914536c86 2014-08-14 20:00 -0700 ben
| | goodbye
| |
| o 2 f098c7f45c4f 2014-08-14 20:01 -0700 ben
|/ Add some documentation
|
o 1 82e55d328c8c 2005-08-26 01:21 -0700 mpm
| Create a makefile
|
o 0 0a04b987be5a 2005-08-26 01:20 -0700 mpm
Create a standard "hello, world" program8, 9 ve 10 değişiklik kümeleri oluşturuldu ve permanent dalına aitler, ancak eski değişiklik kümeleri hâlâ duruyor.
Bu, Mercurial kullanan takım arkadaşlarınız için çok kafa karıştırıcı olabilir, bu yüzden bundan kaçınmaya çalışın.