-
1. Başlangıç
- 1.1 Sürüm Denetimi
- 1.2 Git’in Kısa Tarihçesi
- 1.3 Git Nedir?
- 1.4 Komut Satırı
- 1.5 Git’i Yüklemek
- 1.6 Git’i İlk Defa Kurmak
- 1.7 Yardım Almak
- 1.8 Özet
-
2. Git Temelleri
-
3. Git Dalları
- 3.1 Dallar
- 3.2 Kısaca Dallandırma ve Birleştirme Temelleri
- 3.3 Dal Yönetimi
- 3.4 İş Akışı Dallandırması
- 3.5 Uzak Dallar
- 3.6 Yeniden Temelleme (rebase)
- 3.7 Özet
-
4. Bir Sunucuda Git Kurma
- 4.1 İletişim Kuralları (Protocols)
- 4.2 Bir Sunucuda Git Kurma
- 4.3 SSH Ortak Anahtarınızı Oluşturma
- 4.4 Sunucu Kurma
- 4.5 Git Cini (Daemon)
- 4.6 Akıllı HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Üçüncü Taraf Barındırma (Hosting) Seçenekleri
- 4.10 Özet
-
5. Dağıtık Git
- 5.1 Dağıtık İş Akışları
- 5.2 Projenin Gelişiminde Rol Almak
- 5.3 Bir Projeyi Yürütme
- 5.4 Özet
-
6. GitHub
- 6.1 Bir Projeye Katkıda Bulunmak
- 6.2 Proje Bakımı
- 6.3 Kurumsal Yönetim
- 6.4 GitHub’ı otomatikleştirme
- 6.5 Özet
-
7. Git Araçları
- 7.1 Düzeltme Seçimi
- 7.2 Etkileşimli İzlemleme (Staging)
- 7.3 Saklama ve Silme
- 7.4 Çalışmanızı İmzalama
- 7.5 Arama
- 7.6 Geçmişi Yeniden Yazma
- 7.7 Reset Komutunun Gizemleri
- 7.8 İleri Seviye Birleştirme
- 7.9 Rerere
- 7.10 Git’le Hata Ayıklama
- 7.11 Alt Modüller
- 7.12 Demetleme (Bundling)
- 7.13 Git Nesnesini Değiştirme
- 7.14 Kimlik Bilgisi Depolama
- 7.15 Özet
-
8. Git’i Özelleştirmek
- 8.1 Git Yapılandırması
- 8.2 Git Nitelikleri
- 8.3 Git Kancaları (Hooks)
- 8.4 Bir Örnek: Mecburi Git Politikası
- 8.5 Özet
-
9. Git ve Diğer Sistemler
- 9.1 İstemci Olarak Git
- 9.2 Git’e Geçiş
- 9.3 Özet
-
10. Dahili Git Ögeleri
- 10.1 Tesisat ve Döşeme (Plumbing ve Porcelain)
- 10.2 Git Nesneleri
- 10.3 Git Referansları
- 10.4 Packfiles
- 10.5 Refspec
- 10.6 Transfer Protokolleri
- 10.7 Bakım ve Veri Kurtarma
- 10.8 Ortam Değişkenleri
- 10.9 Özet
-
A1. Ek bölüm A: Diğer Ortamlarda Git
- A1.1 Görsel Arayüzler
- A1.2 Visual Studio ile Git
- A1.3 Visual Studio Code ile Git
- A1.4 Eclipse ile Git
- A1.5 Sublime Text ile Git
- A1.6 Bash ile Git
- A1.7 Zsh ile Git
- A1.8 PowerShell ile Git
- A1.9 Özet
-
A2. Ek bölüm B: Git’i Uygulamalarınıza Gömmek
- A2.1 Git Komut Satırı
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Ek bölüm C: Git Komutları
- A3.1 Kurulum ve Yapılandırma Komutları
- A3.2 Proje Oluşturma Komutları
- A3.3 Kısaca Poz (Snapshot) Alma
- A3.4 Dallandırma ve Birleştirme Komutları
- A3.5 Projeleri Paylaşma ve Güncelleme Komutları
- A3.6 İnceleme ve Karşılaştırma Komutları
- A3.7 Hata Ayıklama (Debugging) Komutları
- A3.8 Yamalama (Patching)
- A3.9 E-Posta Komutları
- A3.10 Harici Sistemler
- A3.11 Yönetim
- A3.12 Tesisat (Plumbing) Komutları
9.2 Git ve Diğer Sistemler - Git’e Geçiş
Git’e Geçiş
Başka bir VCS’te mevcut bir kod tabanınız varsa ancak Git’i kullanmaya başlamaya karar verdiyseniz, projenizi bir şekilde taşımanız gerekir. Bu bölüm, yaygın sistemler için bazı içe aktarıcıları ele alır ve ardından kendi özel içe aktarıcınızı nasıl geliştireceğinizi gösterir. Profesyonel olarak kullanılan SCM sistemlerinin çoğunluğunu oluşturdukları ve yüksek kaliteli araçların bulunması kolay olduğu için, bu sistemlerden veri içe aktarma işlemini öğreneceksiniz.
Subversion
git svn
kullanımıyla ilgili önceki bölümü okuduysanız, bir repoyu svn ile kopyalamak (git svn clone
) için bu talimatları kolayca kullanabilirsiniz: Sonra Subversion sunucusunu durdurup, yeni bir Git sunucusuna itin ve onu kullanmaya başlayın.
Geçmişi istiyorsanız, bunu Subversion sunucusundan verileri çektiğiniz kadar hızlı bir şekilde gerçekleştirebilirsiniz (bu biraz zaman alabilir).
Ancak içe aktarma tamamen mükemmel değildir; çok uzun süreceği için bunu doğru yapsanız iyi olur.
İlk sorun yazar bilgisidir.
Subversion’da katkıda bulunan her kişinin sistemde katkı bilgilerinde kayıtlı bir kullanıcısı vardır.
Önceki bölümdeki örneklerde, blame
çıktısı ve git svn log
gibi bazı yerlerde schacon
gösterilmektedir.
Bunu daha iyi Git yazar verileriyle eşleştirmek istiyorsanız, Subversion kullanıcılarından Git yazarlarına bir eşleştirmeye ihtiyacınız vardır.
Bu eşlemeyi şu şekilde içeren users.txt
adlı bir dosya oluşturun:
schacon = Scott Chacon <schacon@geemail.com>
selse = Someo Nelse <selse@geemail.com>
SVN’nin kullandığı yazar adlarının bir listesini almak için şunu çalıştırabilirsiniz:
$ svn log --xml --quiet | grep author | sort -u | \
perl -pe 's/.*>(.*?)<.*/$1 = /'
Bu komut dizini günlük (log) çıktısını XML biçiminde oluşturur, ardından yalnızca yazar bilgilerinin bulunduğu satırları tutar, yinelenenleri atar ve XML etiketlerini çıkarır (Bariz şekilde, bu yalnızca grep, sort ve Perl yüklü bir makinede çalışır.)
Ardından, her girişin yanına eşdeğer Git kullanıcı verilerini ekleyebilmeniz için bu çıktıyı users.txt
dosyanıza yönlendirin.
Yazar verilerini daha doğru bir şekilde eşleştirmesine yardımcı olmak için bu dosyayı git svn
'ye sağlayabilirsiniz.
Ayrıca, clone
veya init
komutuna --no-metadata
seçeneğini ileterek, git svn
'ye Subversion’ın normalde içe aktardığı meta verileri eklememesini de söyleyebilirsiniz (ancak senkronizasyon meta verilerini korumak istiyorsanız, bu parametreyi atlamakta özgürsünüz).
Bu, import
komutunuzun şu şekilde görünmesini sağlar:
$ git svn clone http://my-project.googlecode.com/svn/ \
--authors-file=users.txt --no-metadata --prefix "" -s my_project
$ cd my_project
Artık my_project
dizininizde daha güzel bir Subversion içe aktarımına sahip olmalısınız.
Buna benzeyen katkılar yerine
commit 37efa680e8473b615de980fa935944215428a35a
Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunk
git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
be05-5f7a86268029
şunun gibi:
commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
Author: Scott Chacon <schacon@geemail.com>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunk
Yazar alanı çok daha iyi görünmekle kalmıyor, aynı zamanda git-svn-id
de artık orada değil.
Ayrıca biraz içe aktarma sonrası temizlik de yapmalısınız.
Bunlardan biri git svn
'nin oluşturduğu tuhaf referansları temizlemektir.
Öncelikle etiketleri, tuhaf uzak dallar yerine gerçek etiketler olacak şekilde, ve ardından geri kalan dalları da yerel olacak şekilde taşıyacaksınız.
Etiketleri uygun Git etiketleri olacak şekilde taşımak için şunu çalıştırın:
$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done
Bu, refs/remotes/tags/
ile başlayan uzak dal referanslarını alır ve onları gerçek (hafif) etiketler haline getirir.
Ardından, referansların geri kalanını refs/remotes
altında yerel şubelere taşıyın:
$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done
Subversion’da yalnızca bir dal görürken, sonuna @xxx
(burada xxx bir sayıdır) eklenmiş bazı ekstra dallar görebilirsiniz.
Bu aslında ``peg-revizyonlar`` adı verilen bir Subversion özelliğidir ve Git’te sözdizimsel karşılığı olmayan bir şeydir.
Bu nedenle git svn
, svn sürüm numarasını dal adına ekler (tıpkı o dalın sabit revizyonunu ele almak için svn’de yazdığınız gibi) .
Artık sabit düzeltmeleri umursamıyorsanız, bunları kaldırmanız yeterlidir:
$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done
Artık tüm eski dallar gerçek Git dalları ve tüm eski etiketler gerçek Git etiketleridir.
Temizlenecek son bir şey daha var.
Ne yazık ki, git svn
Subversion’un varsayılan dalına eşlenen trunk
adında fazladan bir dal oluşturur, ancak trunk
ref’i, master
ile aynı yeri işaret eder.
master
kelimesi Git’e daha uyggun bir ifade biçimi olduğundan, fazladan dalın nasıl kaldırılacağı aşağıda açıklanmıştır:
$ git branch -d trunk
Yapılacak son şey, yeni Git sunucunuzu uzak olarak eklemek ve ona itmektir. Sunucunuzu uzak olarak eklemenin bir örneği:
$ git remote add origin git@my-git-server:myrepository.git
Tüm dallarınızın ve etiketlerinizin üste çıkmasını istediğiniz için artık şunu çalıştırabilirsiniz:
$ git push origin --all
$ git push origin --tags
Artık tüm dal ve etiketleriniz güzel ve temiz bir içe aktarma işlemiyle yeni Git sunucunuzda olmalıdır.
Mercurial
Mercurial ve Git’in sürümleri temsil etme modelleri çok benzer olduğundan ve Git biraz daha esnek olduğundan; bir repoyu Mercurial’den Git’e dönüştürmek oldukça basittir.
Bu dönüşüm için hg-fast-export
adlı bir araca ihtiyacınız olacak.
$ git clone https://github.com/frej/fast-export.git
Dönüşümün ilk adımı, dönüştürmek istediğiniz Mercurial reposunun tam kopyasını almaktır:
$ hg clone <remote repo URL> /tmp/hg-repo
Bir sonraki adım, bir yazar eşleştirme dosyası oluşturmaktır.
Değişiklik setlerindeki yazar alanına koyabileceği şeyler konusunda Mercurial, Git’ten biraz daha esnek olduğu için; temizlemek için bu iyi bir zamandır.
Bunu yapmak için bir bash
shell’inde tek satırlık bir komut kullanabilirsiniz:
$ cd /tmp/hg-repo
$ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors
Bu projenizin geçmişinin ne kadar uzun olduğuna bağlı olarak birkaç saniye sürecektir ve sonrasında /tmp/authors
dosyası şöyle görünecektir:
bob
bob@localhost
bob <bob@company.com>
bob jones <bob <AT> company <DOT> com>
Bob Jones <bob@company.com>
Joe Smith <joe@company.com>
Bu örnekte, aynı kişi (Bob), dört farklı ad altında değişiklik setleri oluşturmuştur; bunlardan biri Git katkısı için doğru görünürken, biri tamamen geçersiz olacaktır.
Hg-fast-export her bir satırı bir kurala dönüştürerek bunu düzeltmemize izin verir: "<input>"="<output>"
, bir <giriş>
'i bir <çıkış>
'a eşleyen bir kural.
<giriş>
ve <çıkış>
dizelerinin içinde, python string_escape
kodlaması tarafından anlaşılan tüm kaçış dizileri desteklenir.
Eğer yazar eşleştirme dosyası eşleşen bir <input>
içermiyorsa, bu yazar Git’e değiştirilmeden gönderilecektir.
Eğer tüm kullanıcı adları uygun görünüyorsa, bu dosyaya hiç ihtiyacımız olmayacaktır.
Bu örnekte, dosyamızın şu şekilde görünmesini istiyoruz:
"bob"="Bob Jones <bob@company.com>"
"bob@localhost"="Bob Jones <bob@company.com>"
"bob <bob@company.com>"="Bob Jones <bob@company.com>"
"bob jones <bob <AT> company <DOT> com>"="Bob Jones <bob@company.com>"
Aynı türdeki eşleştirme dosyası, Mercurial adı Git tarafından izin verilmediğinde dalları ve etiketleri yeniden adlandırmak için de kullanılabilir.
Bir sonraki adım, yeni Git reposunu oluşturmak ve dışa aktarma komut dosyasını çalıştırmaktır:
$ git init /tmp/converted
$ cd /tmp/converted
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
-r
bayrağı, dönüştürmek istediğimiz Mercurial reposunu bulması için hg-fast-export’a nerede bakacağını ve -A
bayrağı da yazar eşleştirme dosyasını nerede bulacağını söyler (dallar ve etiket eşleştirme dosyaları sırasıyla -B
ve -T
bayrakları ile belirtilir).
Betik Mercurial değişiklik setlerini ayrıştırır ve bunları Git’in "fast-import" özelliği için bir betiğe dönüştürür (bu özelliği biraz sonra detaylı bir şekilde inceleyeceğiz).
Bu biraz zaman alır (ancak ağ üzerinden yapılmasından çok daha hızlıdır) ancak çıktı oldukça ayrıntılıdır:
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Loaded 4 authors
master: Exporting full revision 1/22208 with 13/0/0 added/changed/removed files
master: Exporting simple delta revision 2/22208 with 1/1/0 added/changed/removed files
master: Exporting simple delta revision 3/22208 with 0/1/0 added/changed/removed files
[…]
master: Exporting simple delta revision 22206/22208 with 0/4/0 added/changed/removed files
master: Exporting simple delta revision 22207/22208 with 0/2/0 added/changed/removed files
master: Exporting thorough delta revision 22208/22208 with 3/213/0 added/changed/removed files
Exporting tag [0.4c] at [hg r9] [git :10]
Exporting tag [0.4d] at [hg r16] [git :17]
[…]
Exporting tag [3.1-rc] at [hg r21926] [git :21927]
Exporting tag [3.1] at [hg r21973] [git :21974]
Issued 22315 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects: 120000
Total objects: 115032 ( 208171 duplicates )
blobs : 40504 ( 205320 duplicates 26117 deltas of 39602 attempts)
trees : 52320 ( 2851 duplicates 47467 deltas of 47599 attempts)
commits: 22208 ( 0 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 109 ( 2 loads )
marks: 1048576 ( 22208 unique )
atoms: 1952
Memory total: 7860 KiB
pools: 2235 KiB
objects: 5625 KiB
---------------------------------------------------------------------
pack_report: getpagesize() = 4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 90430
pack_report: pack_mmap_calls = 46771
pack_report: pack_open_windows = 1 / 1
pack_report: pack_mapped = 340852700 / 340852700
---------------------------------------------------------------------
$ git shortlog -sn
369 Bob Jones
365 Joe Smith
İşte hepsi bu kadar. Tüm Mercurial etiketleri Git etiketlerine, Mercurial dalları ve yer imleri de Git dallarına dönüştürülmüştür. Şimdi, reponuzu yeni sunucu ana dizinine gönderecek durumdasınız:
$ git remote add origin git@my-git-server:myrepository.git
$ git push origin --all
Bazaar
Bazaar, Git gibi bir Dağıtık Sürüm Kontrol Sistemi (DVCS) aracıdır ve sonuç olarak bir Bazaar reposunu bir Git reposuna dönüştürmek oldukça basittir.
Bunun için bzr-fastimport
eklentisini içe aktarmanız gerekecek.
bzr-fastimport Eklentisini Edinme
UNIX benzeri işletim sistemlerinde hızlı içe aktarma eklentisini kurmanın yolu ve Windows’tan farklıdır.
UNIX’te en kolayı gerekli tüm bağımlılıkları kuracak olan bzr-fastimport
paketini kurmaktır.
Örneğin, Debian ve türevlerinde şunları yapabilirsiniz:
$ sudo apt-get install bzr-fastimport
RHEL ile şunları yapabilirsiniz:
$ sudo yum install bzr-fastimport
Fedora ile sürüm 22’den beri paket yöneticisi dnf’tir:
$ sudo dnf install bzr-fastimport
Paket mevcut değilse, onu eklenti olarak yükleyebilirsiniz:
$ mkdir --parents ~/.bazaar/plugins # creates the necessary folders for the plugins
$ cd ~/.bazaar/plugins
$ bzr branch lp:bzr-fastimport fastimport # imports the fastimport plugin
$ cd fastimport
$ sudo python setup.py install --record=files.txt # installs the plugin
Bu eklentinin çalışması için ayrıca fastimport
Python modülüne de ihtiyacınız olacaktır.
Onun mevcut olup olmadığını kontrol edebilir ve aşağıdaki komutlarla yükleyebilirsiniz:
$ python -c "import fastimport"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named fastimport
$ pip install fastimport
Eğer mevcut değilse, onu https://pypi.python.org/pypi/fastimport/ adresinden indirebilirsiniz.
Windows’ta bzr-fastimport
standalone (bağımsız) sürümüyle ve varsayılan kurulumla (tüm onay kutularını işaretleyerek) otomatik olarak kuruludır.
Bu durumda yapmanız gereken bir şey yoktur.
Bu noktada, bir Bazaar reposunu içe aktarma yöntemi, tek bir dalınızın olup olmadığına veya birçok dala sahip bir repoyla çalışıp çalışmadığınıza göre farklılık gösterir.
Tek Dallı Proje
Şimdi, Bazaar reposunu içeren dizine gidin ve Git reposunu başlatın:
$ cd /path/to/the/bzr/repository
$ git init
Şimdi, Bazaar reposunu dışa aktarabilir ve aşağıdaki komutu kullanarak bir Git reposuna dönüştürebilirsiniz:
$ bzr fast-export --plain . | git fast-import
Proje boyutuna bağlı olarak, Git reposunun oluşturulması birkaç saniye ile birkaç dakika arasında sürebilir.
Bir Anadal ve Bir Çalışma Dalı Olan Proje Durumu
Dallara sahip bir Bazaar reposunu da içe aktarabilirsiniz. Diyelim ki iki dalınız var: biri ana dalı temsil eder (myProject.trunk), diğeri ise çalışma dalıdır (myProject.work).
$ ls
myProject.trunk myProject.work
Git reposunu oluşturun ve dizinine gidin:
$ git init git-repo
$ cd git-repo
Master dalını Git’e çekin:
$ bzr fast-export --export-marks=../marks.bzr ../myProject.trunk | \
git fast-import --export-marks=../marks.git
Çalışma dalını Git’e çekin:
$ bzr fast-export --marks=../marks.bzr --git-branch=work ../myProject.work | \
git fast-import --import-marks=../marks.git --export-marks=../marks.git
Şimdi git branch
komutu hem master
dalını, hem de work
dalını gösterir.
Tamam olduğundan emin olmak için; log kayıtlarını kontrol edip, marks.bzr
ve marks.git
dosyalarını temizleyin.
İzleme Alanını (Stage) Senkronize Etme
Ne kadar çok dalınız olursa olsun ve hangi içe aktarma yöntemini kullanırsanız kullanın, izleme alanınız HEAD
ile senkronize değildir; ve birden fazla dalın içe aktarılmasıyla, çalışma diziniz de senkronize değildir.
Bu durumu aşağıdaki komutla kolayca çözebilirsiniz:
$ git reset --hard HEAD
.bzrignore ile Yoksayılmış Dosyaları Yoksaymak
Şimdi yoksayılacak dosyalara bir göz atalım.
İlk yapmanız gereken .bzrignore
dosyasını .gitignore
olarak yeniden adlandırmaktır.
.bzrignore
dosyası "!!" veya "RE:" ile başlayan bir veya birkaç satır içeriyorsa, bunu değiştirmeniz ve belki de Bazaar’ın yoksaydığı tam olarak aynı dosyaları yoksaymak için birkaç .gitignore
dosyası oluşturmanız gerekebilir.
Son olarak, bu değişikliği içeren taşınma (migration) için bir katkı oluşturmanız gerekecektir:
$ git mv .bzrignore .gitignore
$ # modify .gitignore if needed
$ git commit -am 'Migration from Bazaar to Git'
Reponuzu Sunucuya Göndermek
İşte oldu! Artık reponuzu yeni ana sunucusuna aktarabilirsiniz:
$ git remote add origin git@my-git-server:mygitrepository.git
$ git push origin --all
$ git push origin --tags
Git reponuz kullanıma hazırdır.
Perforce
İçe aktarmayı inceleyeceğimiz bir sonraki sistem Perforce’tur. Yukarıda belirttiğimiz gibi Git ve Perforce’un birbirleriyle konuşmasına izin vermenin iki yolu vardır: git-p4 ve Perforce Git Fusion.
Perforce Git Fusion
Git Fusion bu süreci oldukça ağrısız hale getirir. Proje ayarlarınızı, kullanıcı eşlemelerinizi ve dallarınızı bir yapılandırma dosyası kullanarak (Git Fusion bölümünde anlatıldığı gibi) yapılandırın ve repoyu kopyalayın. Git Fusion size yerel bir Git reposuna benzer bir şey bırakır. Bunu daha sonra isterseniz yerel bir Git ana bilgisayarına gönderebilirsiniz. İsterseniz Perforce’u Git sunucunuz olarak bile kullanabilirsiniz.
Git-p4
Git-p4 aynı zamanda bir içe aktarma aracı görevi de görebilir. Örnek olarak Jam projesini "Perforce Public Depot" 'dan içe aktaracağız. İstemcinizi kurmak için P4PORT ortam değişkenini Perforce deposunu işaret edecek şekilde dışa aktarmanız gerekir:
$ export P4PORT=public.perforce.com:1666
Not
|
Takip etmek için bağlantı kurabileceğiniz bir Perforce deposuna ihtiyacınız olacak. Örneklerimiz için public.perforce.com adresindeki genel depoyu kullanacağız, ancak erişiminiz olan herhangi bir depoyu da kullanabilirsiniz. |
Jam projesini Perforce sunucusundan içe aktarmak için depo ve proje yolunu ve projeyi içe aktarmak istediğiniz yolu sağlayarak git p4 clone
komutunu çalıştırın:
$ git-p4 clone //guest/perforce_software/jam@all p4import
Importing from //guest/perforce_software/jam@all into p4import
Initialized empty Git repository in /private/tmp/p4import/.git/
Import destination: refs/remotes/p4/master
Importing revision 9957 (100%)
Bu özel projenin yalnızca bir dalı vardır, ancak dal görünümleriyle (veya yalnızca bir dizin kümesi) yapılandırılmış dallarınız varsa; tüm dosyaları ve projenin alt dallarını içe aktarmak için --detect-branches
işaretini git p4 clone
komutuna ekleyerek kullanabilirsiniz.
Bu konuda biraz daha ayrıntılı bilgi için Dallandırma konusuna bakın.
Bu noktada işiniz neredeyse bitti.
p4import
dizinine gidip git log
çalıştırırsanız, içe aktarılan çalışmanızı görebilirsiniz:
$ git log -2
commit e5da1c909e5db3036475419f6379f2c73710c4e6
Author: giles <giles@giles@perforce.com>
Date: Wed Feb 8 03:13:27 2012 -0800
Correction to line 355; change </UL> to </OL>.
[git-p4: depot-paths = "//public/jam/src/": change = 8068]
commit aa21359a0a135dda85c50a7f7cf249e4f7b8fd98
Author: kwirth <kwirth@perforce.com>
Date: Tue Jul 7 01:35:51 2009 -0800
Fix spelling error on Jam doc page (cummulative -> cumulative).
[git-p4: depot-paths = "//public/jam/src/": change = 7304]
git-p4
'ün her katkı mesajında bir tanımlayıcı bıraktığını görebilirsiniz.
Daha sonra Perforce değişiklik numarasına başvurmanız gerekebileceği ihtimaline karşı, bu tanımlayıcıyı orada tutmanızda bir sakınca yoktur.
Ancak tanımlayıcıyı kaldırmak isterseniz (ki yeni repo üzerinde çalışmaya başlamadan önce bunu yapmanın tam zamanıdır),
tanımlayıcı dizeleri topluca kaldırmak için git filter-branch
'ı kullanabilirsiniz:
$ git filter-branch --msg-filter 'sed -e "/^\[git-p4:/d"'
Rewrite e5da1c909e5db3036475419f6379f2c73710c4e6 (125/125)
Ref 'refs/heads/master' was rewritten
git log
'u çalıştırırsanız, katkılara ilişkin tüm SHA-1 sağlama toplamlarının değiştiğini, ancak git-p4
dizelerinin artık katkı mesajlarında olmadığını görebilirsiniz:
$ git log -2
commit b17341801ed838d97f7800a54a6f9b95750839b7
Author: giles <giles@giles@perforce.com>
Date: Wed Feb 8 03:13:27 2012 -0800
Correction to line 355; change </UL> to </OL>.
commit 3e68c2e26cd89cb983eb52c024ecdfba1d6b3fff
Author: kwirth <kwirth@perforce.com>
Date: Tue Jul 7 01:35:51 2009 -0800
Fix spelling error on Jam doc page (cummulative -> cumulative).
İçe aktarma işleminiz yeni Git sunucunuza gönderilmeye hazırdır.
TFS
Takımınız kaynak kontrolünü TFVC’den Git’e dönüştürüyorsa, bunu en yüksek doğrulukta gerçekleştirmek isteyeceksiniz. Ara işlev bölümünde hem git-tfs’i hem de git-tf’yi ele aldığımızı göz önünde bulundurursak, bu bölümde yalnızca git-tfs’i ele alacağımız anlamına gelir. Çünkü git-tfs dallarını destekler ve bunu git-tf ile yapmak oldukça zordur.
Not
|
Bu tek yönlü bir dönüşümdür. Oluşan Git reposu, orijinal TFVC projesi ile bağlantı kuramaz. |
İlk yapmanız gereken şey, kullanıcı adlarını eşlemektir.
TFVC değişiklik setleri için yazar alanına neyin gireceği konusunda oldukça serbesttir, ancak Git okunabilir bir ad ve e-posta adresi ister.
Bu bilgiyi tf
komut satırı istemcisinden şöyle alabilirsiniz:
PS> tf history $/myproject -recursive > AUTHORS_TMP
Bu projenin tarihindeki tüm değişiklik setlerini alır ve bunları işleyeceğimiz AUTHORS_TMP dosyasına koyar.
User sütununun (ikinci sütun) verilerini çıkarmak için dosyayı açın ve sütunun hangi karakterlerde başladığını ve bittiğini bulun, ardından aşağıdaki komut satırındaki cut
komutunun 11-20
parametrelerini bulunanlarla değiştirin:
PS> cat AUTHORS_TMP | cut -b 11-20 | tail -n+3 | sort | uniq > AUTHORS
cut
komutu her satırdan 11 ile 20 arasındaki karakterleri korur.
tail
komutu başlık alanları ve ASCII alt çizgileri olan ilk iki satırı atlar.
Elde edilen sonuç, yinelenenleri ortadan kaldırmak için sort
ve uniq
e yönlendirilir ve AUTHORS
adında bir dosyaya kaydedilir.
Sonraki adım el ile yapılmalıdır, git-tfs’nin bu dosyayı etkin bir şekilde kullanabilmesi için her satır bu formatta olmalıdır:
DOMAIN\username = User Name <email@address.com>
Sol taraftaki bölüm TFVC’den gelen "Kullanıcı" (user) alanıdır, eşittir işaretinin sağ tarafındaki bölüm ise Git işlemleri için kullanılacak olan kullanıcı adıdır.
Bu dosyayı aldıktan sonra, yapmanız gereken sıradaki şey ilgilendiğiniz TFVC projesinin bir kopyasını yapmaktır:
PS> git tfs clone --with-branches --authors=AUTHORS https://username.visualstudio.com/DefaultCollection $/project/Trunk project_git
Aşağıdaki komut, katkı mesajlarının altındaki git-tfs-id
bölümlerini temizleyecektir:
PS> git filter-branch -f --msg-filter 'sed "s/^git-tfs-id:.*$//g"' '--' --all
Bu komut Git-bash ortamındaki sed
komutunu kullanarak git-tfs-id:
ile başlayan her satırı boş bir metinle değiştirir ve Git’in bu satırları görmezden gelmesini sağlar.
Hepsi tamamlandıktan sonra yeni bir uzak repo ekleyebilir, tüm dalları üstakıma itebilir ve ekibinizin Git üzerinden çalışmaya başlamasını sağlayabilirsiniz.
Farklı Bir İçe-Aktarıcı
Eğer sisteminiz yukarıdakilerden biri değilse, çevrimiçi bir içe aktarıcı aramalısınız.
Bir çok farklı sistem için CVS, Clear Case, Visual Source Safe ve hatta dizinler için bir arşiv de içeren kaliteli aktarıcılar mevcuttur.
Eğer bu araçlardan hiçbiri sizin için uygun değilse, daha az bilinen bir araç kullanıyorsanız veya bir şekilde daha özel bir içe aktarma işlemine ihtiyacınız varsa, git fast-import
'u kullanmalısınız.
Bu komut belirli Git verilerini yazmak için stdin’den basit talimatlar okur.
Bu şekilde Git nesneleri oluşturmak, ham Git komutlarını çalıştırmaktan veya ham nesneleri yazmaya çalışmaktan çok daha kolaydır (daha fazla bilgi için Dahili Git Ögeleri bölümüne bakın).
Bu şekilde, içe aktardığınız sistemden gerekli bilgileri okuyup, stdout’a basit talimatlar yazdıracak bir içe aktarma betiği oluşturabilirsiniz.
Ardından, bu programı çalıştırabilir ve çıktısını git fast-import
üzerinden akıtarak içe aktarabilirsiniz.
Size hızlı bir şekilde öğretmek için, basit bir içe aktarıcı yazdıracağız.
Şimdi, mevcut bir dizinde çalıştığınızı varsayalım. Projenizi zaman zaman dizini zaman damgasıyla işaretlenmiş bir back_YYYY_MM_DD
yedek dizinine kopyalayarak yedekliyorsunuz ve bunu Git’e içe aktarmak istiyorsunuz.
Dizin yapınız şöyle görünüyor:
$ ls /opt/import_from
back_2014_01_02
back_2014_01_04
back_2014_01_14
back_2014_02_03
current
Git dizinini içe aktarmak için, Git’in verilerini nasıl depoladığını gözden geçirmeniz gerekir.
Hatırlayacağınız üzere, Git temel olarak, içeriğin pozlarına işaret eden katkı nesnelerinin bir listesinden oluşur.
Yapmanız gereken tek şey, fast-import
ile içerik pozlarının ne olduğunu, onlara işaret eden katkı verilerini ve bunların sıralanma düzenini söylemektir.
Stratejiniz pozları tek tek geçerken, her dizinin içeriğini bir önceki katkıyla ilişkilendirekek yeni bir katkı oluşturmaktır.
Bir Örnek: Mecburi Git Politikası bölümünde yaptığımız gibi, genellikle bununla çalıştığımız ve okuması kolay alduğu için kodumuzu Ruby’de yazacağız.
Siz aşina olduğunuz herhangi bir dilde de bunu yazabilirsiniz (yalnızca uygun bilgilerin stdout
a yazdırılması gerekmektedir).
Ve eğer Windows’ta çalışıyorsanız, sadece satır sonuna taşıma dönüşlerini (CRLF) koymamaya, özel bir dikkat göstermeniz gerekecektir.
'git fast-import Windows’un kullandığı satır başı satır beslemelerini (CRLF) değil, yalnızca satır beslemelerini (LF) isteme konusunda çok hassasdır.
Başlamak için, hedef dizine gidip, her birinin bir katkı olarak içe aktarılmasını istediğiniz her alt dizini tanımlayacaksınız. Her alt dizine geçip, onu dışa aktarmak için gerekli komutları yazdırırsınız. Temel ana döngünüz şöyle görünecektir:
last_mark = nil
# loop through the directories
Dir.chdir(ARGV[0]) do
Dir.glob("*").each do |dir|
next if File.file?(dir)
# move into the target directory
Dir.chdir(dir) do
last_mark = print_export(dir, last_mark)
end
end
end
Her dizin içinde print_export
'u çalıştırırsınız: bu önceki anlık görüntünün bildirimini ve işaretini alırarak sıradakinin bildirim ve işaretini döndürür.
Bu şekilde, onları uygun şekilde bağlayabilirsiniz.
Mark
katkıya verdiğiniz bir "hızlı-içe-aktarma" tanımıdır: katkı oluşturduğunuzda, her birine başka katkılardan bağlantı kurmak için kullanabileceğiniz bir işaret verirsiniz.
Dolayısıyla, print_export
yönteminizde yapmanız gereken ilk şey, dizin adından bir işaret oluşturmaktır:
mark = convert_dir_to_mark(dir)
İşaretin bir tamsayı olması gerektiği için, bunu bir dizin serisi oluşturarak ve işaret olarak indeks değerini kullanarak yapacaksınız. Yönteminiz şuna benzer:
$marks = []
def convert_dir_to_mark(dir)
if !$marks.include?(dir)
$marks << dir
end
($marks.index(dir) + 1).to_s
end
Şimdi katkınız bir tam sayı temsilini aldığına göre, katkı meta verileri için bir tarih gerekmektedir.
Tarih dizinin adında ifade edildiğinden, bunu dışarı çıkarmanız gerekecektir.
print_export
dosyanızdaki bir sonraki satır şu şekildedir:
date = convert_dir_to_date(dir)
burada convert_dir_to_date
şu şekilde tanımlanır:
def convert_dir_to_date(dir)
if dir == 'current'
return Time.now().to_i
else
dir = dir.gsub('back_', '')
(year, month, day) = dir.split('_')
return Time.local(year, month, day).to_i
end
end
Bu her dizinin tarihi için bir tamsayı değeri döndürür. Her katkı için ihtiyacınız olan son meta bilgi parçası, global bir değişkene kodladığınız katkı verileridir:
$author = 'John Doe <john@example.com>'
Artık aktarıcınız için katkı verilerini yazdırmaya başlamaya hazırsınız. İlk bilgiler, bir katkı nesnesini tanımladığınızı ve bunun hangi dalda olduğunu; ardından, oluşturduğunuz işareti, katkılayanın bilgilerini ve katkı mesajını; ve onun ardından da -varsa- önceki katkıyı belirtir. Kodunuz şuna benzer:
# print the import information
puts 'commit refs/heads/master'
puts 'mark :' + mark
puts "committer #{$author} #{date} -0700"
export_data('imported from ' + dir)
puts 'from :' + last_mark if last_mark
Yapması kolay olduğu için saat dilimini (-0700) kodlayın. Başka bir sistemden içe aktarıyorsanız saat dilimini fark olarak belirtmeniz gerekir. Katkı mesajı özel bir formatta ifade edilmelidir:
data (size)\n(contents)
Format: kelime verileri, okunacak verinin boyutu, yeni satır ve son olarak verilerden oluşur.
Daha sonra dosya içeriğini belirtmek için aynı biçimi kullanmanız gerektiğinden, export_data
adında bir yardımcı yöntem oluşturursunuz:
def export_data(string)
print "data #{string.size}\n#{string}"
end
Geriye kalan tek şey, her poz için dosya içeriğini belirtmektir.
Bunların hepsi tek bir dizinde bulunduğu için bu da kolaydır; deleteall
komutunu ve ardından dizindeki her dosyanın içeriğini yazdırabilirsiniz.
Git daha sonra her pozu uygun şekilde kaydedecektir:
puts 'deleteall'
Dir.glob("**/*").each do |file|
next if !File.file?(file)
inline_data(file)
end
Not: Birçok sistem, revizyonlarını bir katkıdan diğerine yapılan değişiklikler olarak düşündüğünden, hızlı içe aktarma, her bir katkıda hangi dosyaların eklendiğini, kaldırıldığını veya değiştirildiğini; ve yeni içeriklerin neler olduğunu belirtmek için komutlar alabilir. Pozlar arasındaki farkları hesaplayabilir ve yalnızca bu verileri sağlayabilirsiniz, ancak bunu yapmak daha karmaşıktır: Git’e tüm verileri verip, onun çözmesine izin verebilirsiniz. Eğer bu verileriniz için daha uygunsa, verilerinizi bu şekilde nasıl sağlayacağınıza ilişkin ayrıntılar için hızlı içe aktarma kılavuz sayfasına bakın.
Yeni dosya içeriklerini listeleme veya yeni içeriklerle değiştirilmiş bir dosyayı belirtme formatı aşağıdaki gibidir:
M 644 inline path/to/file
data (size)
(file contents)
Burada mod 644’tür (yürütülebilir dosyalarınız varsa, bunun yerine 755’i tespit edip belirtmeniz gerekir) ve satır içinde bu satırın hemen ardından içerikleri listeleyeceğiniz yazmaktadır. inline_data yönteminiz şuna benzer:
def inline_data(file, code = 'M', mode = '644')
content = File.read(file)
puts "#{code} #{mode} inline #{file}"
export_data(content)
end
Katkı mesajı verilerinizi belirttiğiniz yöntemle aynı olduğu için daha önce tanımladığınız export_data
yöntemini yeniden kullanırsınız.
Yapmanız gereken son şey, bir sonraki yinelemeye aktarılabilmesi için mevcut işareti döndürmektir:
return mark
Not
|
Windows üzerinde çalışıyorsanız fazladan bir adım eklediğinizden emin olmanız gerekir.
Daha önce de belirtildiği gibi, Windows yeni satır karakterleri için CRLF’yi kullanırken
|
Bu kadar. İşte senaryonun tamamı:
#!/usr/bin/env ruby
$stdout.binmode
$author = "John Doe <john@example.com>"
$marks = []
def convert_dir_to_mark(dir)
if !$marks.include?(dir)
$marks << dir
end
($marks.index(dir)+1).to_s
end
def convert_dir_to_date(dir)
if dir == 'current'
return Time.now().to_i
else
dir = dir.gsub('back_', '')
(year, month, day) = dir.split('_')
return Time.local(year, month, day).to_i
end
end
def export_data(string)
print "data #{string.size}\n#{string}"
end
def inline_data(file, code='M', mode='644')
content = File.read(file)
puts "#{code} #{mode} inline #{file}"
export_data(content)
end
def print_export(dir, last_mark)
date = convert_dir_to_date(dir)
mark = convert_dir_to_mark(dir)
puts 'commit refs/heads/master'
puts "mark :#{mark}"
puts "committer #{$author} #{date} -0700"
export_data("imported from #{dir}")
puts "from :#{last_mark}" if last_mark
puts 'deleteall'
Dir.glob("**/*").each do |file|
next if !File.file?(file)
inline_data(file)
end
mark
end
# Loop through the directories
last_mark = nil
Dir.chdir(ARGV[0]) do
Dir.glob("*").each do |dir|
next if File.file?(dir)
# move into the target directory
Dir.chdir(dir) do
last_mark = print_export(dir, last_mark)
end
end
end
Bu betiği çalıştırırsanız şuna benzer bir içerik elde edersiniz:
$ ruby import.rb /opt/import_from
commit refs/heads/master
mark :1
committer John Doe <john@example.com> 1388649600 -0700
data 29
imported from back_2014_01_02deleteall
M 644 inline README.md
data 28
# Hello
This is my readme.
commit refs/heads/master
mark :2
committer John Doe <john@example.com> 1388822400 -0700
data 29
imported from back_2014_01_04from :1
deleteall
M 644 inline main.rb
data 34
#!/bin/env ruby
puts "Hey there"
M 644 inline README.md
(...)
Aktarıcıyı çalıştırmak için, içe aktarmak istediğiniz Git dizinindeyken bu çıktıyı git fast-import
aracılığıyla aktarın.
Yeni bir dizin oluşturabilir ve ardından başlangıç noktası olarak bu dizin içinde git init
'i çalıştırabilir ve ardından betiğinizi çalıştırabilirsiniz:
$ git init
Initialized empty Git repository in /opt/import_to/.git/
$ ruby import.rb /opt/import_from | git fast-import
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects: 5000
Total objects: 13 ( 6 duplicates )
blobs : 5 ( 4 duplicates 3 deltas of 5 attempts)
trees : 4 ( 1 duplicates 0 deltas of 4 attempts)
commits: 4 ( 1 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 1 ( 1 loads )
marks: 1024 ( 5 unique )
atoms: 2
Memory total: 2344 KiB
pools: 2110 KiB
objects: 234 KiB
---------------------------------------------------------------------
pack_report: getpagesize() = 4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 10
pack_report: pack_mmap_calls = 5
pack_report: pack_open_windows = 2 / 2
pack_report: pack_mapped = 1457 / 1457
---------------------------------------------------------------------
Gördüğünüz gibi, başarıyla tamamlandığında, size neleri başardığına dair bir sürü istatistik veriyor.
Burada, 1 dalda 4 katkı için toplam 13 nesneyi içe aktardınız.
Artık yeni geçmişinizi görmek için git log
'u çalıştırabilirsiniz:
$ git log -2
commit 3caa046d4aac682a55867132ccdfbe0d3fdee498
Author: John Doe <john@example.com>
Date: Tue Jul 29 19:39:04 2014 -0700
imported from current
commit 4afc2b945d0d3c8cd00556fbe2e8224569dc9def
Author: John Doe <john@example.com>
Date: Mon Feb 3 01:00:00 2014 -0700
imported from back_2014_02_03
İşte güzel ve temiz bir Git reposu.
Hiçbir şeyin henüz alınmadığını farketmeniz önemlidir (başlangıçta çalışma dizininizde herhangi bir dosya yoktur).
Bunları almak için dalınızı, şu anda master
'ın olduğu yere sıfırlamanız gerekmektedir:
$ ls
$ git reset --hard master
HEAD is now at 3caa046 imported from current
$ ls
README.md main.rb
fast-import
aracıyla çok daha fazlasını yapabilirsiniz; farklı modları, ikili verileri, birden fazla dallanmayı ve birleştirmeyi, etiketleri, ilerleme göstergelerini ve daha fazlasını yönetebilirsiniz.
Git kaynak kodunun contrib/fast-import
dizininde daha karmaşık senaryoların bir dizi örneği mevcuttur.