Zacznijmy od wyjaśnienia, czym jest tag w git
Tag służy do oznaczania i oznaczania konkretnego zatwierdzenia w historii.
Zwykle służy do oznaczania punktów uwalniania (np. V1.0 itp.).
Chociaż tag może wyglądać podobnie do gałęzi, nie zmienia się . Wskazuje bezpośrednio na konkretne zatwierdzenie w historii.
Nie będzie można wyewidencjonować tagów, jeśli nie są one lokalnie w twoim repozytorium, więc najpierw musisz przejść do fetch
tagów do lokalnego repozytorium.
Po pierwsze, upewnij się, że tag istnieje lokalnie, wykonując
# --all will fetch all the remotes.
# --tags will fetch all tags as well
$ git fetch --all --tags --prune
Następnie sprawdź tag, uruchamiając
$ git checkout tags/<tag_name> -b <branch_name>
Zamiast origin
używać tags/
przedrostka.
W tym przykładzie masz 2 tagi w wersji 1.0 i wersji 1.1, możesz je sprawdzić za pomocą jednego z poniższych:
$ git checkout A ...
$ git checkout version 1.0 ...
$ git checkout tags/version 1.0 ...
Wszystkie powyższe zrobią to samo, ponieważ znacznik jest tylko wskaźnikiem do danego zatwierdzenia.
pochodzenie: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png
Jak wyświetlić listę wszystkich tagów?
# list all tags
$ git tag
# list all tags with given pattern ex: v-
$ git tag --list 'v-*'
Jak tworzyć tagi?
Istnieją 2 sposoby utworzenia tagu:
# lightweight tag
$ git tag
# annotated tag
$ git tag -a
Różnica między nimi polega na tym, że podczas tworzenia znacznika z adnotacjami można dodawać metadane w git commit:
imię, adres e-mail, datę, komentarz i podpis
Jak usunąć tagi?
# delete any (local) given tag
$ git tag -d <tag name>
# Delete a tag from the server with push tags
$ git push --delete origin <tag name>
Jak sklonować określony tag?
Aby pobrać zawartość danego znacznika, możesz użyć checkout
polecenia. Jak wyjaśniono powyżej, tagi są jak wszelkie inne zatwierdzenia, więc możemy używać checkout
i zamiast używać SHA-1, po prostu zastępując go tag_name
Opcja 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>
Opcja 2:
Za pomocą polecenia klonowania
Ponieważ git obsługuje płytkie klonowanie poprzez dodanie polecenia --branch
do klonowania, możemy użyć nazwy znacznika zamiast nazwy gałęzi. Git wie, jak „przetłumaczyć” dany SHA-1 na odpowiedni zatwierdzenie
# Clone a specific tag name using git clone
$ git clone <url> --branch=<tag_name>
git clone --branch =
--branch
może również pobierać tagi i odłącza HEAD przy tym zatwierdzeniu w wynikowym repozytorium.
Jak przesuwać tagi?
git push --tags
Aby wypchnąć wszystkie tagi:
# Push all tags
$ git push --tags
Używanie refs/tags
zamiast tylko określenia <tagname>
.
Dlaczego? - Zaleca się używać, refs/tags
ponieważ czasami tagi mogą mieć taką samą nazwę jak twoje gałęzie, a zwykłe git push popchnie gałąź zamiast tag
Aby przesłać tagi z adnotacjami i bieżące tagi łańcucha historii, użyj:
git push --follow-tags
Ta flaga --follow-tags
wypycha zarówno zatwierdzenia, jak i tylko tagi, które są jednocześnie:
- Tagi z adnotacjami (dzięki czemu można pominąć tagi budowania lokalnego / tymczasowego)
- Osiągalne znaczniki (przodek) z bieżącej gałęzi (znajdujące się w historii)
W Git 2.4 możesz to ustawić za pomocą konfiguracji
$ git config --global push.followTags true
Ściągawka:
git checkout A
. co jestA
? Jak stworzyłeśA
?A
jest hashem zatwierdzającymgit checkout tags/<tag_name> -b <branch_name>
wymaga-b <branch_name>
.git checkout tags/<tag_name>
obdarzył mnie oderwaną głową. Zgodnie z tym artykułem na temat odłączonej głowy , unikniesz odłączonej głowy, tymczasowo tworząc i usuwając gałąź. To dość obcy proces pracy. Oczywiście jako użytkownik git muszę przyzwyczaić się do tworzenia i usuwania oddziałów dla zabawy i zysków.( Napisanie tej odpowiedzi zajęło trochę czasu, a odpowiedź CodeWizard jest poprawna pod względem celu i istoty, ale nie do końca pełna, więc i tak to opublikuję.)
Nie ma czegoś takiego jak „zdalny tag Git”. Są tylko „tagi”. Zwracam uwagę na to, aby nie być pedantycznym 1, ale ponieważ istnieje wiele zamieszania na ten temat z przypadkowymi użytkownikami Git, a dokumentacja Git nie jest zbyt pomocna 2 dla początkujących. (Nie jest jasne, czy zamieszanie nastąpiło z powodu złej dokumentacji, czy też złej dokumentacji, ponieważ z natury jest to nieco mylące, czy co.)
Nie są „zdalne oddziały”, bardziej poprawnie nazywane „zdalne śledzenie oddziałów”, ale warto zauważyć, że są to w rzeczywistości podmioty lokalne. Nie ma jednak zdalnych tagów (chyba że je wymyślisz). Są tylko tagi lokalne, więc musisz go pobrać lokalnie, aby go użyć.
Ogólna forma nazw dla konkretnych zatwierdzeń - do których odwołuje się Git - to dowolny ciąg zaczynający się od
refs/
. Ciąg rozpoczynający się odrefs/heads/
nazwy gałęzi; ciąg rozpoczynający się odrefs/remotes/
nazwy gałęzi zdalnego śledzenia; oraz ciąg rozpoczynający się odrefs/tags/
nazwy znacznika. Nazwarefs/stash
jest odniesieniem do skrytki (w znaczeniu używanym przezgit stash
; zwróć uwagę na brak ukośnika końcowego).Istnieją pewne nietypowe imiona specjalnym etui, które nie zaczynają się
refs/
:HEAD
,ORIG_HEAD
,MERGE_HEAD
, aCHERRY_PICK_HEAD
w szczególności są również nazwy, które mogą odnosić się do konkretnych zatwierdzeń (choćHEAD
zazwyczaj zawiera nazwę oddziału, czyli zawiera ). Ale ogólnie odniesienia zaczynają się od .ref: refs/heads/branch
refs/
Jedną z rzeczy, które Git robi, aby wprowadzić to w błąd, jest to, że pozwala ci to pominąć
refs/
i często słowo porefs/
. Na przykład możesz pominąćrefs/heads/
lubrefs/tags/
odnosząc się do lokalnego oddziału lub tagu - i faktycznie musisz go pominąćrefs/heads/
podczas sprawdzania lokalnego oddziału! Możesz to zrobić, gdy wynik jest jednoznaczny, lub - jak właśnie zauważyliśmy - kiedy musisz to zrobić (dla ).git checkout branch
To prawda, że referencje istnieją nie tylko w twoim własnym repozytorium, ale także w zdalnych repozytoriach. Jednak Git daje dostęp do referencji zdalnego repozytorium tylko w bardzo określonych momentach: mianowicie podczas
fetch
ipush
operacji. Można również użyćgit ls-remote
lubgit remote show
je zobaczyć, alefetch
ipush
są bardziej interesujące punkty styku.Refspecs
Podczas
fetch
ipush
Git używa ciągów, które wywołuje refspecs do przesyłania referencji między lokalnym a zdalnym repozytorium. Tak więc w tych czasach i poprzez refspecs dwa repozytoria Git mogą się zsynchronizować. Gdy twoje imiona zostaną zsynchronizowane, możesz użyć tego samego imienia, którego używa osoba z pilotem. Jest tu jednak trochę magiifetch
, która wpływa zarówno na nazwy oddziałów, jak i nazwy znaczników.Powinieneś pomyśleć o poleceniu
git fetch
Gitowi wywołania (lub wiadomości tekstowej) innego Gita - „zdalnego” - i przeprowadzenia z nim rozmowy. Na początku tej rozmowy pilot wyświetla wszystkie swoje odniesienia: wszystko wewnątrzrefs/heads/
i wszystko w środkurefs/tags/
, wraz z wszelkimi innymi odniesieniami, które posiada. Twój Git skanuje je i (na podstawie zwykłego refspecu pobierania) zmienia nazwy swoich gałęzi.Rzućmy okiem na normalny refspec dla pilota o nazwie
origin
:Ten refspec instruuje Gita, aby pobierał każdą pasującą nazwę -
refs/heads/*
tj. Każdą gałąź na pilocie - i zmieniał jej nazwę narefs/remotes/origin/*
, tj. Utrzymywał tę samą dopasowaną część, zmieniając nazwę gałęzi (refs/heads/
) na nazwę gałęzi zdalnego śledzenia (refs/remotes/
w szczególności ,refs/remotes/origin/
).To dzięki tej refspec że
origin
„s oddziały stają się twoje gałęzie zdalnego śledzenia do zdalnegoorigin
. Nazwa oddziału staje się nazwą oddziału śledzącego zdalnie, wraz z nazwą pilota, w tym przypadkuorigin
zawartą. Znak plus+
z przodu refspec ustawia flagę „force”, tzn. Gałąź zdalnego śledzenia zostanie zaktualizowana, aby pasowała do nazwy gałęzi pilota, niezależnie od tego, co trzeba zrobić, aby dopasować. (Bez tego+
aktualizacje oddziałów są ograniczone do zmian „szybkiego przewijania do przodu”, a aktualizacje znaczników są po prostu ignorowane od wersji Git 1.8.2 lub wcześniej - wcześniej stosowane były te same reguły szybkiego przewijania).Tagi
Ale co z tagami? Nie ma dla nich żadnego odniesienia - przynajmniej domyślnie. Możesz ustawić jeden, w którym to przypadku forma refspec zależy od Ciebie; lub możesz biegać
git fetch --tags
. Korzystanie--tags
skutkuje dodaniemrefs/tags/*:refs/tags/*
do refspec, czyli przynosi nad wszystkimi znacznikami (ale nie aktualizuje swój znacznik jeśli masz już tag z tą nazwą, niezależnie od tego, co tag zdalnego mówiEdit sty 2017: jak Git 2.10 , testy pokazują, że--tags
siłą aktualizuje tagi z tagów pilota, tak jakby czytał refspec+refs/tags/*:refs/tags/*
; może to różnić się w zachowaniu od wcześniejszej wersji Git).Zauważ, że nie ma tutaj zmiany nazwy: jeśli pilot
origin
ma tagxyzzy
, a ty nie, a tygit fetch origin "refs/tags/*:refs/tags/*"
zostanieszrefs/tags/xyzzy
dodany do repozytorium (wskazując na to samo zatwierdzenie, co na pilocie). Jeśli go użyjesz,+refs/tags/*:refs/tags/*
Twój tagxyzzy
, jeśli go masz, zostanie zastąpiony tym zorigin
. Oznacza to, że+
flaga siły na refspec oznacza „zastąp wartość mojej referencji tą, którą mój Git otrzymuje z Git”.Automagiczne tagi podczas pobierania
Ze względów historycznych 3, jeśli nie użyjesz ani
--tags
opcji, ani--no-tags
opcji,git fetch
podejmuje specjalne działania. Pamiętaj, że powiedzieliśmy powyżej, że pilot zaczyna się od wyświetlania w lokalnym Git wszystkich swoich referencji, niezależnie od tego, czy lokalny Git chce je zobaczyć, czy nie. 4 Twój Git bierze pod uwagę wszystkie tagi, które widzi w tym momencie.Następnie, gdy zacznie pobierać dowolne obiekty zatwierdzania, których potrzebuje, aby obsłużyć wszystko, co jest pobierane, jeśli jeden z tych zatwierdzeń ma taki sam identyfikator, jak dowolny z tych znaczników, git doda ten znacznik - lub te znaczniki, jeśli wiele znaczników ma ten identyfikator - do twoje repozytorium.Edytuj, styczeń 2017 r .: testowanie pokazuje, że zachowanie w Git 2.10 jest teraz: Jeśli ich Git zapewnia znacznik o nazwie T , a ty nie masz znacznika o nazwie T , a identyfikator zatwierdzenia powiązany z T jest przodkiem jednej z jego gałęzi że Twój
git fetch
bada, Twój Git dodaje T do tagów z lub bez--tags
. Dodanie--tags
powoduje, że Twój Git otrzymuje wszystkie swoje tagi, a także wymusza aktualizację.Dolna linia
Być może będziesz musiał użyć
git fetch --tags
ich, aby uzyskać ich tagi. Jeśli ich nazwy znaczników konflikt z istniejącymi nazwami znaczników, to może (w zależności od wersji Git) nawet usunąć (lub zmienić nazwę) niektóre z tagów, a następnie uruchomićgit fetch --tags
, aby uzyskać ich tagi. Ponieważ znaczniki - w przeciwieństwie do zdalnych gałęzi - nie mają automatycznej zmiany nazwy, nazwy znaczników muszą odpowiadać ich nazwom, dlatego możesz mieć problemy z konfliktami.Jednak w większości normalnych przypadków prosty
git fetch
wykona zadanie, przynosząc swoje zatwierdzenia i odpowiadające im znaczniki, a ponieważ oni - kimkolwiek są - będą oznaczać zatwierdzenia w momencie ich publikowania, będziesz nadążał za ich znacznikami. Jeśli nie utworzysz własnych tagów ani nie wymieszasz ich repozytorium z innymi repozytoriami (za pomocą wielu pilotów), nie będziesz mieć żadnych kolizji nazw tagów, więc nie będziesz musiał się martwić usuwaniem lub zmianą nazw tagów uzyskać ich tagi.Kiedy potrzebujesz kwalifikowanych nazwisk
Wspomniałem wyżej, że można pominąć
refs/
prawie zawsze, irefs/heads/
arefs/tags/
i tak na większość czasu. Ale kiedy nie możesz?Kompletny (lub prawie pełna tak) Odpowiedź jest w tej
gitrevisions
dokumentacji . Git rozpozna nazwę do identyfikatora zatwierdzenia, korzystając z sześcioetapowej sekwencji podanej w łączu. Co ciekawe, znaczniki zastępują gałęzie: jeśli istnieje znacznikxyzzy
i gałąźxyzzy
i wskazują one różne zatwierdzenia, to:poda ci identyfikator, na który wskazuje tag. Jednak - i tego właśnie brakuje
gitrevisions
-git checkout
preferuje nazwy gałęzi, więcgit checkout xyzzy
umieści cię w gałęzi, ignorując tag.W przypadku niejasności prawie zawsze możesz przeliterować nazwę ref, używając jej pełnej nazwy
refs/heads/xyzzy
lubrefs/tags/xyzzy
. (Należy pamiętać, że to czyni pracę zgit checkout
, ale w może nieoczekiwany sposób:git checkout refs/heads/xyzzy
powoduje kasę wolnostojący-Head zamiast kasie oddziału To dlatego po prostu trzeba pamiętać, że.git checkout
Będzie używać nazwy skróconej jako nazwa oddziału pierwsze: to, w jaki sposób sprawdź gałąź,xyzzy
nawet jeśli tagxyzzy
istnieje. Jeśli chcesz sprawdzić tag, możesz użyćrefs/tags/xyzzy
).Ponieważ (jak
gitrevisions
zauważa) Git spróbuje , możesz po prostu napisać, aby zidentyfikować zatwierdzony tag . (Jeśli ktoś udało się napisać poprawny nazwie odniesienie do , jednakże będzie to rozwiązać jak . Ale zazwyczaj tylko różne nazwy powinny być ).refs/name
tags/xyzzy
xyzzy
xyzzy
$GIT_DIR
$GIT_DIR/xyzzy
*HEAD
$GIT_DIR
1 Dobra, dobra, „nie tylko być pedantycznym”. :-)
2 Niektórzy powiedzieliby „bardzo nieużyteczni”, a ja raczej raczej się zgadzam.
3 Zasadniczo
git fetch
i cała koncepcja pilotów i referencji była nieco późnym dodatkiem do Git, działającym w czasach Gita 1.5. Wcześniej istniały tylko specjalne przypadki ad-hoc, a pobieranie tagów było jednym z nich, więc zostało wprowadzone w życie za pomocą specjalnego kodu.4 Jeśli to pomoże, pomyśl o zdalnym Gicie jako flasherze w znaczeniu slangu.
źródło
git fetch
pobierze tylko tagi pilota, biorąc pod uwagę--tags
arg.--tags
,--no-tags
i domyślnie jest całkiem trudne. Domyślnie wprowadzane są tagi, których nie masz, a które są w zatwierdzonych przez Ciebie zmianach (zobacz edycję z stycznia 2017 r.) Ale są tu również usterki, a współczesny Git ma swoje --tagi / --no-tag obsługuje kod jeszcze raz poprawiony, co prawdopodobnie doprowadzi do jeszcze bardziej specjalnych przypadków narożnych.Aby pobrać tag git, należy wykonać następujące polecenie
np. jak wspomniano poniżej.
Aby pobrać wszystkie tagi, użyj polecenia
źródło
Aby uzyskać konkretny kod tagu, spróbuj utworzyć nowy oddział i dodaj kod tagu. Zrobiłem to z polecenia:
$git checkout -b newBranchName tagName
źródło