git tag nedir, tag nasıl oluşturulur & git remote tag(ler)i nasıl checkout edilir
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.
467
3
Git'te bir etiketin ne olduğunu açıklayarak başlayalım
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
Sonra koşarak etiketi kontrol edin
origin
yerine
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:
Etiket yalnızca belirli bir commit'e işaretçi olduğu için yukarıdakilerin tümü aynı şeyi yapacaktır.
Tüm etiketlerin listesini nasıl görebilirim?
Etiketler nasıl oluşturulur?
Etiket oluşturmanın 2 yolu vardır:
İ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
Etiketler nasıl silinir?
Belirli bir etiket nasıl klonlanır?
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 kullanabilirizSeçenek 1:
Seçenek 2:
Clone komutunu kullanma
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 bilirEtiketler nasıl itilir?
git push --tags
Tüm etiketleri itmek için:
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
(Bu cevabı yazmak biraz zaman aldı ve codeWizard'ın cevabı amaç ve öz olarak doğru, ancak tamamen eksiksiz değil, bu yüzden bunu yine de yayınlayacağım).
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.Refspecs
Git,
fetch
vepush
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 buradafetch
ü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:Bu refspec Git'inize
refs/heads/*
ile eşleşen her ismi (yani uzaktaki her dalı) almasını ve isminirefs/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/
, özelliklerefs/remotes/origin/
) değiştirir. Bu refspec* aracılığıylaorigin
'in dalları, uzakorigin
için uzaktan izleme dallarınız haline gelir. Dal adı, uzak dalın (bu durumdaorigin
) 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).Etiketler
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 (ancak bu isimde bir etiketiniz zaten varsa *sizin* etiketinizi güncellemez, *uzaktaki etiketin ne dediğine bakılmaksızın* 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.Getirme sırasında otomatik etiketler
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 sizingit 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.Alt satır
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çingit 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 birgit 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.Nitelikli isimlere ihtiyaç duyduğunuzda
Yukarıda
refs/
ifadesini neredeyse her zaman,refs/heads/
verefs/tags/
ifadelerini ise çoğu zaman atlayabileceğinizi belirtmiştim. Ama ne zaman yapamazsınız? Tam (ya da neredeyse tam) cevap thegitrevisions
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 birxyzzy
etiketi ve birxyzzy
dalı varsa ve bunlar farklı commitlere işaret ediyorsa, o zaman:size etiketin işaret ettiği kimliği verecektir. Ancak -ve bu
gitrevisions
da eksik olan şeydir-git checkout
dal isimlerini tercih eder, bu nedenlegit 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
veyarefs/tags/xyzzy
. (Bunungit 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 sadecetags/xyzzy
yazabilirsiniz. (Ancak birisi$GIT_DIR
içinexyzzy
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.Belirli etiket kodunu almak için yeni bir dal oluşturmayı deneyin ve etiket kodunu bu dala ekleyin. Bunu şu komutla yaptım:
$git checkout -b newBranchName tagName