uzak git etiketini kontrol ettiğimde aşağıdaki gibi bir komut kullanıyorum:
git checkout -b local_branch_name origin/remote_tag_name
Böyle bir hata aldım:
error: pathspec `origin/remote_tag_name` did not match any file(s) known to git.
git tag komutunu kullandığımda remote_tag_name'i bulabiliyorum.
Bir etiket, geçmişteki belirli bir commit'i etiketlemek ve işaretlemek için kullanılır.
Genellikle sürüm noktalarını işaretlemek için kullanılır (örn. v1.0, vb.).
Bir etiket bir dala benzer görünse de, bir etiket değişmez.
Geçmişteki belirli bir işleme doğrudan işaret eder.
Deponuzda yerel olarak bulunmuyorsa etiketleri kontrol edemezsiniz, bu nedenle önce etiketleri yerel deponuza `getirmeniz' gerekir.
İlk olarak, etiketin yerel olarak var olduğundan emin olun
# --all will fetch all the remotes.
# --tags will fetch all tags as well
git fetch --all --tags --prune
Sonra koşarak etiketi kontrol edin
git checkout tags/<tag_name> -b <branch_name>
originyerine
tags/` önekini kullanın.
Bu örnekte, sürüm 1.0 ve sürüm 1.1 olmak üzere 2 etiketiniz var, bunları aşağıdakilerden herhangi biriyle kontrol edebilirsiniz:
git checkout A ...
git checkout version 1.0 ...
git checkout tags/version 1.0 ...
Etiket yalnızca belirli bir commit'e işaretçi olduğu için yukarıdakilerin tümü aynı şeyi yapacaktır.
kaynak: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png
# list all tags
git tag
# list all tags with given pattern ex: v-
git tag --list 'v-*'
Etiket oluşturmanın 2 yolu vardır:
# lightweight tag
git tag
# annotated tag
git tag -a
İkisi arasındaki fark, açıklamalı bir etiket oluştururken git commit'inde olduğu gibi meta veri ekleyebilmenizdir:
isim, e-posta, tarih, yorum & imza
# delete any given tag
git tag -d <tag name>
# Don't forget to remove the deleted tag form the server with push tags
Belirli bir etiketin içeriğini almak için checkout
komutunu kullanabilirsiniz.
Yukarıda açıklandığı gibi etiketler diğer komutlar gibidir, bu nedenle checkout
kullanabiliriz ve SHA-1 yerine tag_name kullanabiliriz
Seçenek 1:
# Update the local git repo with the latest tags from all remotes
git fetch --all
# checkout the specific tag
git checkout tags/<tag> -b <branch>
Seçenek 2:
git, clone komutuna --branch
ekleyerek shallow clone desteği sağladığından, şube adı yerine etiket adını kullanabiliriz. Git, verilen SHA-1'i ilgili commit'e nasıl "translate" edeceğini bilir
# Clone a specific tag name using git clone
git clone <url> --branch=<tag_name>
git clone --branch=
--branch
ayrıca etiketleri alabilir ve sonuçta ortaya çıkan depodaki o commit'teki HEAD'i ayırır.
git push --tags
Tüm etiketleri itmek için:
git push --tags
Açıklamalı etiketleri ve mevcut geçmiş zincir etiketlerini göndermek için: öğesini kullanın:
git push --follow-tags
Bu `--follow-tags' bayrağı hem commits hem de only tags etiketlerini iter:
Git 2.4'ten itibaren yapılandırmayı kullanarak ayarlayabilirsiniz
git config --global push.followTags true
Uzak Git etiketi" diye bir şey yoktur. Sadece "etiketler" vardır. Tüm bunları bilgiçlik taslamak için değil,1 ama sıradan Git kullanıcıları arasında bu konuda büyük bir kafa karışıklığı olduğu ve Git dokümantasyonunun yeni başlayanlara pek yardımcı olmadığı için2 belirtiyorum. (Kafa karışıklığının yetersiz dokümantasyondan mı kaynaklandığı, yoksa yetersiz dokümantasyonun bunun doğası gereği biraz kafa karıştırıcı olmasından mı kaynaklandığı net değil).
"uzak dallar" vardır, daha doğrusu "uzak takip dalları" olarak adlandırılır, ancak bunların aslında yerel varlıklar olduğunu belirtmek gerekir. Yine de uzak etiketler yoktur (siz onları (yeniden) icat etmedikçe). Sadece yerel etiketler vardır, bu nedenle etiketi kullanmak için yerel olarak almanız gerekir.
Git'in referanslar olarak adlandırdığı belirli taahhütlerin adları için genel biçim refs/
ile başlayan herhangi bir dizedir. refs/heads/ile başlayan bir dizge bir dalı adlandırır;
refs/remotes/ile başlayan bir dizge bir uzaktan izleme dalını adlandırır; ve
refs/tags/ile başlayan bir dizge bir etiketi adlandırır. refs/stash
adı stash referansıdır (git stash
tarafından kullanıldığı gibi; sondaki eğik çizginin eksikliğine dikkat edin).
refs/ile başlamayan bazı alışılmadık özel durum adları vardır:
HEAD,
ORIG_HEAD,
MERGE_HEADve
CHERRY_PICK_HEADgibi adların hepsi de belirli komutlara gönderme yapabilen adlardır (ancak
HEADnormalde bir dalın adını içerir, yani <code>ref: refs/heads/*branch*</code> içerir). Ancak genel olarak referanslar
refs/ile başlar. Git'in bunu kafa karıştırıcı hale getirmek için yaptığı bir şey,
refs/ve genellikle
refs/den sonraki kelimeyi atlamanıza izin vermesidir. Örneğin, yerel bir dala veya etikete atıfta bulunurken
refs/heads/veya
refs/tags/kelimelerini atlayabilirsiniz ve aslında yerel bir dalı kontrol ederken
refs/heads/kelimesini atlamanız *zorunludur! Bunu sonuç net olduğunda ya da -az önce belirttiğimiz gibi- yapmanız gerektiğinde yapabilirsiniz (<code>git checkout *branch*</code> için). Referansların yalnızca kendi deponuzda değil, aynı zamanda uzak depolarda da bulunduğu doğrudur. Ancak, Git size uzak bir deponun referanslarına yalnızca çok özel zamanlarda erişim sağlar: yani,
fetchve
pushişlemleri sırasında. Bunları görmek için
git ls-remoteveya
git remote showda kullanabilirsiniz, ancak
fetchve
push` daha ilginç temas noktalarıdır.
Git, fetch
ve push
sırasında referansları yerel ve uzak depolar arasında aktarmak için refspecs adını verdiği dizeleri kullanır. Böylece, bu zamanlarda ve refspecs aracılığıyla iki Git deposu birbiriyle senkronize olabilir. İsimleriniz senkronize olduktan sonra, uzaktaki birinin kullandığı ismi kullanabilirsiniz. Ancak burada fetch
üzerinde bazı özel sihirler vardır ve hem dal adlarını hem de etiket adlarını etkiler.
Git fetchi Git
inizi başka bir Giti - "remote"- çağırmaya (ya da belki metin mesajı göndermeye) ve onunla konuşmaya yönlendirmek olarak düşünmelisiniz. Bu konuşmanın başlarında, remote tüm referanslarını listeler:
refs/heads/içindeki her şey ve
refs/tags/içindeki her şey, sahip olduğu diğer referanslarla birlikte. Git'iniz bunları tarar ve (normal fetch refspec'e dayanarak) dallarını *yeniden adlandırır*. Şimdi
origin` isimli uzak için normal refspec'e bir göz atalım:
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$
Bu refspec Git'inize refs/heads/*
ile eşleşen her ismi (yani uzaktaki her dalı) almasını ve ismini refs/remotes/origin/*
olarak değiştirmesini söyler, yani eşleşen kısmı aynı tutarak dal ismini (refs/heads/
) uzaktan takip eden bir dal ismiyle (refs/remotes/
, özellikle refs/remotes/origin/
) değiştirir.
Bu refspec* aracılığıyla origin
'in dalları, uzak origin
için uzaktan izleme dallarınız haline gelir. Dal adı, uzak dalın (bu durumda origin
) adı da dahil olmak üzere, uzak izleme dalı adı haline gelir. Refspecin önündeki artı işareti
+"force" bayrağını ayarlar, yani remote-tracking branch
ınız remoteın branch ismiyle eşleşecek şekilde güncellenecektir, eşleşmesi için ne gerekiyorsa yapılacaktır. (
+' olmadan, dal güncellemeleri "fast forward" değişiklikleriyle sınırlıdır ve etiket güncellemeleri Git sürüm 1.8.2'den bu yana basitçe göz ardı edilir - o zamandan önce aynı hızlı ileri alma kuralları uygulanır).
Peki ya etiketler? Onlar için bir refspec yok - en azından varsayılan olarak yok. Bir tane ayarlayabilirsiniz, bu durumda refspec'in şekli size bağlıdır; veya git fetch --tags
komutunu çalıştırabilirsiniz. --tagskullanımı refspec'e
refs/tags/:refs/tags/ekleme etkisine sahiptir, yani, tüm etiketleri getirir (<s>ancak bu isimde bir etiketiniz zaten varsa *sizin* etiketinizi güncellemez, *uzaktaki etiketin ne dediğine bakılmaksızın*</s> Düzenleme, Ocak 2017: Git 2'den itibaren.10'dan itibaren yapılan testler,
--tags' ifadesinin sanki refspec'te +refs/tags/*:refs/tags/*' yazıyormuş gibi etiketlerinizi uzaktaki etiketlerden zorla güncellediğini gösteriyor; bu, Git'in önceki bir sürümünden kaynaklanan bir davranış farkı olabilir). Burada yeniden adlandırma olmadığına dikkat edin: eğer uzak
originde
xyzzyetiketi varsa ve sizde yoksa ve
git fetch origin "refs/tags/:refs/tags/"yaparsanız, deponuza
refs/tags/xyzzyeklenir (uzaktaki ile aynı commit'e işaret eder). Eğer
+refs/tags/:refs/tags/kullanırsanız, o zaman
xyzzyetiketiniz, eğer varsa,
originetiketi ile *değiştirilir*. Yani, bir refspec üzerindeki
+` force bayrağı "referansımın değerini Git'imin Git'lerinden aldığı değerle değiştir" anlamına gelir.
Tarihsel nedenlerden dolayı,3 ne --tags
seçeneğini ne de --no-tags
seçeneğini kullanırsanız, git fetch
özel bir işlem yapar. Yukarıda, yerel Git'iniz onları görmek istesin ya da istemesin, uzaktan kumandanın yerel Git'inize tüm referanslarını göstererek başladığını söylediğimizi hatırlayın.4 Git'iniz bu noktada gördüğü tüm etiketleri not alır. Daha sonra, getirdiği her şeyi işlemek için ihtiyaç duyduğu commit nesnelerini indirmeye başladığında, bu commit'lerden biri bu etiketlerden herhangi biriyle aynı kimliğe sahipse, git bu etiketi - veya birden fazla etiket bu kimliğe sahipse bu etiketleri - deponuza ekleyecektir.
Düzenleme, Ocak 2017: testler Git 2.10'daki davranışın şimdi olduğunu gösteriyor: Eğer onların Git'i T adında bir etiket sağlıyorsa, ve sizin T adında bir etiketiniz yoksa, ve T ile ilişkili commit ID'si sizin git fetch'inizin incelediği dallardan birinin atasıysa, Git'iniz
--tags' olsun ya da olmasın etiketlerinize T ekler. Etiketlerin eklenmesi Git'inizin tüm etiketleri almasına ve ayrıca güncellemeye zorlamasına neden olur.
Etiketlerini almak için git fetch --tags
kullanmanız gerekebilir. Etiket adları mevcut etiket adlarınızla çakışıyorsa, (Git sürümüne bağlı olarak) bazı etiketlerinizi silmeniz (veya yeniden adlandırmanız) ve ardından etiketlerini almak için git fetch --tags
komutunu çalıştırmanız bile gerekebilir. Etiketler -uzak dalların aksine- otomatik yeniden adlandırmaya sahip olmadığından, etiket adlarınız onların etiket adlarıyla eşleşmelidir, bu nedenle çakışmalarla ilgili sorunlar yaşayabilirsiniz.
Yine de çoğu normal durumda, basit bir git fetch
işi yapacak, onların taahhütlerini ve eşleşen etiketlerini getirecektir ve onlar -her kim olurlarsa olsunlar- taahhütleri yayınladıkları anda etiketleyeceklerinden, onların etiketlerini takip edeceksiniz. Eğer kendi etiketlerinizi oluşturmazsanız ya da onların depoları ile diğer depoları karıştırmazsanız (birden fazla uzaktan kumanda ile), herhangi bir etiket adı çakışması da olmaz, böylece onların etiketlerini elde etmek için etiketleri silmek ya da yeniden adlandırmakla uğraşmak zorunda kalmazsınız.
Yukarıda refs/
ifadesini neredeyse her zaman, refs/heads/
ve refs/tags/
ifadelerini ise çoğu zaman atlayabileceğinizi belirtmiştim. Ama ne zaman yapamazsınız?
Tam (ya da neredeyse tam) cevap the gitrevisions
documentation adresinde bulunmaktadır. Git, bağlantıda verilen altı adımlı diziyi kullanarak bir ismi bir commit ID'sine çözümleyecektir. İlginç bir şekilde, etiketler dalları geçersiz kılar: eğer bir xyzzy
etiketi ve bir xyzzy
dalı varsa ve bunlar farklı commitlere işaret ediyorsa, o zaman:
git rev-parse xyzzy
gitrevisions
da eksik olan şeydir- git checkout
dal isimlerini tercih eder, bu nedenle git checkout xyzzy
etiketi göz ardı ederek sizi dala yerleştirecektir.
Belirsizlik durumunda, neredeyse her zaman ref adını tam adını kullanarak heceleyebilirsiniz, refs/heads/xyzzy
veya refs/tags/xyzzy
. (Bunun git checkout
ile çalıştığını unutmayın, ancak belki de beklenmedik bir şekilde: git checkout refs/heads/xyzzybir dal kontrolünden ziyade ayrılmış bir HEAD kontrolüne neden olur. Bu nedenle
git checkoutun önce kısa adı dal adı olarak kullanacağına dikkat etmeniz gerekir:
xyzzyetiketi mevcut olsa bile
xyzzydalını bu şekilde kontrol edersiniz. Eğer etiketi kontrol etmek istiyorsanız,
refs/tags/xyzzykullanabilirsiniz). Çünkü (
gitrevisionsın belirttiği gibi) Git <code>refs/*name*</code> deneyecektir, ayrıca
xyzzyetiketli commit
i tanımlamak için sadece tags/xyzzy
yazabilirsiniz. (Ancak birisi $GIT_DIR
içine xyzzy
adında geçerli bir referans yazmayı başarmışsa, bu $GIT_DIR/xyzzy
olarak çözümlenecektir. Ancak normalde sadece çeşitli *HEAD
isimleri $GIT_DIR
içinde olmalıdır).1Tamam, tamam, "sadece* bilgiçlik taslamak için değil". :-)
2Bazıları "çok yardımcı değil" diyebilir ve ben de aynı fikirdeyim aslında.
3Temel olarak, git fetch
ve tüm uzaktan kumanda ve refspecs kavramı, Git 1.5 zamanında Git'e biraz geç eklenmiştir. O zamandan önce sadece bazı geçici özel durumlar vardı ve etiket-getirme bunlardan biriydi, bu yüzden özel kod yoluyla büyükbabası oldu.
4Eğer yardımcı olacaksa, uzak Git'i argo anlamıyla bir flasher olarak düşünün.