Odpowiedzi:
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
# list all tags
$ git tag
# list all tags with given pattern ex: v-
$ git tag --list 'v-*'
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
# 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>
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:
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.
git push --tags
Aby wypchnąć wszystkie tagi:
# Push all tags
$ git push --tags
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:
W Git 2.4 możesz to ustawić za pomocą konfiguracji
$ git config --global push.followTags true
A
jest hashem zatwierdzającym
git 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ę od refs/heads/
nazwy gałęzi; ciąg rozpoczynający się od refs/remotes/
nazwy gałęzi zdalnego śledzenia; oraz ciąg rozpoczynający się od refs/tags/
nazwy znacznika. Nazwa refs/stash
jest odniesieniem do skrytki (w znaczeniu używanym przez git 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
, a CHERRY_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 po refs/
. Na przykład możesz pominąć refs/heads/
lub refs/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
i push
operacji. Można również użyć git ls-remote
lub git remote show
je zobaczyć, ale fetch
i push
są bardziej interesujące punkty styku.
Podczas fetch
i push
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ę magii fetch
, 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ątrz refs/heads/
i wszystko w środku refs/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
:
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$
Ten refspec instruuje Gita, aby pobierał każdą pasującą nazwę - refs/heads/*
tj. Każdą gałąź na pilocie - i zmieniał jej nazwę na refs/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 zdalnego origin
. Nazwa oddziału staje się nazwą oddziału śledzącego zdalnie, wraz z nazwą pilota, w tym przypadku origin
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).
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 dodaniem refs/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ówi Edit 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 tag xyzzy
, a ty nie, a ty git fetch origin "refs/tags/*:refs/tags/*"
zostaniesz refs/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 tag xyzzy
, jeśli go masz, zostanie zastąpiony tym z origin
. Oznacza to, że +
flaga siły na refspec oznacza „zastąp wartość mojej referencji tą, którą mój Git otrzymuje z Git”.
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ę.
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.
Wspomniałem wyżej, że można pominąć refs/
prawie zawsze, i refs/heads/
a refs/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 znacznik xyzzy
i gałąź xyzzy
i wskazują one różne zatwierdzenia, to:
git rev-parse xyzzy
poda ci identyfikator, na który wskazuje tag. Jednak - i tego właśnie brakuje gitrevisions
- git checkout
preferuje nazwy gałęzi, więc git 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
lub refs/tags/xyzzy
. (Należy pamiętać, że to czyni pracę z git 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 tag xyzzy
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.
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 uzyskać konkretny kod tagu, spróbuj utworzyć nowy oddział i dodaj kod tagu. Zrobiłem to z polecenia:$git checkout -b newBranchName tagName
git checkout A
. co jestA
? Jak stworzyłeśA
?