Jaki jest najprostszy sposób na uzyskanie najnowszego tagu w Git?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
wynik:
a
b
c
Czy powinienem napisać skrypt, aby uzyskać datę i godzinę każdego tagu i porównać je?
Jaki jest najprostszy sposób na uzyskanie najnowszego tagu w Git?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
wynik:
a
b
c
Czy powinienem napisać skrypt, aby uzyskać datę i godzinę każdego tagu i porównać je?
Odpowiedzi:
Możesz rzucić okiem git describe
, co robi coś bliskiego temu, o co pytasz.
--abbrev=0
nią powinien zwrócić najbliższy tag z komentarzem
git describe --exact-match --abbrev=0
.
git describe --tags
i porównaj com ostatni tag na stronie wydania github
Aby uzyskać najnowszy tag:
git describe --tags
Aby uzyskać najnowszy tag z adnotacjami :
git describe --abbrev=0
git describe
mówi strona --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
git describe --tags
git checkout $(git describe --abbrev=0 --tags)
Wysyła tag najnowszego zatwierdzonego zatwierdzenia we wszystkich gałęziach
git describe --tags $(git rev-list --tags --max-count=1)
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
@ william-pursell
Aby uzyskać najnowszy tag, możesz:
$ git for-each-ref refs / tags --sort = -taggerdate --format = '% (refname)' --count = 1
Oczywiście możesz zmienić argument licznika lub pole sortowania według potrzeb. Wygląda na to, że mogłeś zadać nieco inne pytanie, ale to odpowiada na pytanie, gdy je interpretuję.
--sort=-authordate
i --sort=authordate
.
--sort=-taggerdate
. Dla tagów authordate
i committerdate
są puste (tak bezużyteczne jak klucze sortowania).
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1
jest jeszcze lepszy :)
--points-at=$SHA
da ci tag skrótu zatwierdzenia.
Co powiesz na to?
TAG=$(git describe $(git rev-list --tags --max-count=1))
Technicznie niekoniecznie dostaniesz najnowszy tag, ale ostatni zatwierdzony tag, który może, ale nie musi być tym, czego szukasz.
--tags=<pattern>
w rev-list
. Na przykład pobierz tag ostatniej wersjigit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
git describe --tags $(git rev-list --tags --max-count=1)
Możesz wykonać: git describe --tags $(git rev-list --tags --max-count=1)
rozmawiałem tutaj: Jak uzyskać najnowszą nazwę tagu?
git describe ...
zwraca wcześniejszy tag ?!)
--abbrev=0
odpowiedzi i odciąłem część tagu, który chcę.
„Najnowsze” może mieć dwa znaczenia pod względem git.
Możesz powiedzieć „który tag ma datę utworzenia najpóźniej w czasie”, a większość odpowiedzi tutaj dotyczy tego pytania. Jeśli chodzi o twoje pytanie, chciałbyś zwrócić tag c
.
Lub może masz na myśli „która znajduje się najbliżej tag w historii rozwoju do pewnego nazwie oddziału”, zwykle gałęzi na której się znajdujesz, HEAD
. W twoim pytaniu zwróci to tag a
.
Mogą być oczywiście inne:
A->B->C->D->E->F (HEAD)
\ \
\ X->Y->Z (v0.2)
P->Q (v0.1)
Wyobraźmy sobie, deweloper tag'ed Z
jak v0.2
w poniedziałek, a następnie tag'ed Q
jak v0.1
we wtorek. v0.1
jest nowszy, ale v0.2
bliżej historii rozwoju do HEAD, w tym sensie, że ścieżka, którą podąża zaczyna się w punkcie bliższym HEAD.
Myślę, że zwykle potrzebujesz drugiej odpowiedzi, bliżej historii rozwoju. Możesz się tego dowiedzieć, używając git log v0.2..HEAD
etc dla każdego tagu. Daje to liczbę zatwierdzeń w HEAD, ponieważ ścieżka kończąca się na v0.2
odbiegała od ścieżki, po której następuje HEAD.
Oto skrypt w języku Python, który robi to poprzez iterację wszystkich tagów wykonujących tę kontrolę, a następnie wydrukowanie tagu z najmniejszą liczbą zatwierdzeń w HEAD od czasu rozejścia się ścieżki tagu:
https://github.com/MacPython/terryfy/blob/master/git-closest-tag
git describe
robi coś nieco innego, ponieważ śledzi wstecz (np.) HEAD, aby znaleźć pierwszy znacznik, który znajduje się na ścieżce wstecz w historii od HEAD. Mówiąc git, git describe
szuka tagów „osiągalnych” z HEAD. Dlatego nie znajdzie takich tagów v0.2
, które nie znajdują się na ścieżce powrotnej od HEAD, ale na ścieżce, która się od niej różni.
git describe --tags
zwraca ostatni znacznik widoczny dla bieżącej gałęzi
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed 's ...... '
JEŚLI POTRZEBUJESZ WIĘCEJ NIŻ JEDNA OSTATNIA TAGA
(git opisz - tagi czasami dają nieprawidłowe hasze, nie wiem dlaczego, ale dla mnie - max-count 2 nie działa)
w ten sposób możesz uzyskać listę z 2 najnowszymi nazwami znaczników w odwrotnej kolejności chronologicznej, działa idealnie na git 1.8.4. We wcześniejszych wersjach git (jak 1.7. *) W danych wyjściowych nie ma łańcucha „tag:” - wystarczy usunąć ostatnie wywołanie sed
Jeśli chcesz więcej niż 2 najnowsze tagi - zmień to „sed 2q” na „sed 5q” lub cokolwiek potrzebujesz
Następnie możesz łatwo parsować każdą nazwę znacznika na zmienną lub inną.
git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p'
gdzie in %D
wyklucza otaczające ()
znaki, a sed
s zaczynające się od 5q pozostawia 4 wiersze przed 5, a następnie wypisuje wszystkie znaki między „tag:” a pierwszym „,”. Więc ... zakładając, że w tagu nie ma przecinków, działa to idealnie.
Co jest złego we wszystkich sugestiach (oprócz wyjaśnień Matthew Bretta , aktualnych odpowiedzi na ten post)?
Po prostu uruchom dowolne polecenie dostarczone przez innych w historii jQuery Git, gdy jesteś w innym punkcie historii i sprawdź wynik za pomocą wizualnej reprezentacji historii tagowania ( zrobiłem właśnie dlatego widzisz ten post):
$ git log --graph --all --decorate --oneline --simplify-by-decoration
Obecnie wiele projektów wykonuje wydania (a więc oznaczanie) w oddzielnej gałęzi od głównej linii .
Jest ku temu silny powód . Wystarczy spojrzeć na wszelkie dobrze znane projekty JS / CSS. Zgodnie z konwencjami użytkowników przenoszą one binarne / zminimalizowane pliki wydań w DVCS. Naturalnie, jako opiekun projektu, nie chcesz usuwać swojej historii różnic głównych z bezużytecznymi binarnymi obiektami blob i wykonywać zatwierdzanie kompilacji kompilacji poza linią główną .
Ponieważ Git używa DAG, a nie historii liniowej - trudno jest zdefiniować metrykę odległości, więc możemy powiedzieć - och, ta prędkość jest najbliższa mojej HEAD
!
Zaczynam własną podróż (zajrzyj do środka, nie skopiowałem fantazyjnych zdjęć próbnych do tego długiego postu):
Jaki jest najbliższy tag w przeszłości w odniesieniu do rozgałęziania w Git?
Obecnie mam 4 rozsądne definicje odległości między tagiem a wersją ze zmniejszeniem użyteczności:
HEAD
do połączenia bazy ze znacznikiemHEAD
i znacznikaNie wiem, jak obliczyć długość najkrótszej ścieżki .
Skrypt tagi sortowania według daty z bazy seryjnej pomiędzy HEAD
i TAG:
$ git tag \
| while read t; do \
b=`git merge-base HEAD $t`; \
echo `git log -n 1 $b --format=%ai` $t; \
done | sort
Nadaje się do większości projektów.
Skrypt sortujący tagi według liczby obrotów osiągalnych z HEAD, ale niedostępnych z tagu:
$ git tag \
| while read t; do echo `git rev-list --count $t..HEAD` $t; done \
| sort -n
Jeśli historia twojego projektu ma dziwne daty na zatwierdzeniach (z powodu rebaseów lub innego przepisywania historii lub jakiegoś kretyna, zapomnij wymienić baterię BIOS lub inną magię, którą robisz w historii), użyj powyższego skryptu.
Aby uzyskać ostatnią opcję ( datę znacznika niezależnie od podstawy scalania ), aby uzyskać listę znaczników posortowaną według daty, użyj:
$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r
Aby poznać aktualną datę zmiany, użyj:
$ git log --max-count=1
Zauważ, że git describe --tags
mają zastosowanie we własnych przypadkach, ale nie do znajdowania oczekiwanego przez człowieka najbliższego znacznika w historii projektu .
UWAGA Możesz stosować powyższe przepisy w każdej wersji, wystarczy zastąpić HEAD
to, co chcesz!
git tag -l ac* | tail -n1
Pobierz ostatni tag z prefiksem „ac” . Na przykład znacznik o nazwie z ac1.0.0
lub ac1.0.5
. Inne znaczniki nazwane 1.0.0
, 1.1.0
będą ignorowane.
git tag -l [0-9].* | tail -n1
Zdobądź ostatni tag, którego pierwszym znakiem jest 0-9
. Te tagi z pierwszym chara-z
zostaną zignorowane.
git tag --help # Help for `git tag`
git tag -l <pattern>
Wyświetl tagi z nazwami pasującymi do podanego wzorca (lub wszystkich, jeśli nie podano wzorca). Uruchomienie „git tag” bez argumentów wyświetla również wszystkie tagi. Wzorzec jest znakiem wieloznacznym powłoki (tzn. Dopasowanym za pomocą fnmatch (3)). Można podać wiele wzorów; jeśli którykolwiek z nich pasuje, znacznik jest wyświetlany.
tail -n <number> # display the last part of a file
tail -n1 # Display the last item
Z git tag --help
, o sort
kłótni. Będzie używać lexicorgraphic order
domyślnie, jeśli tag.sort
właściwość nie istnieje.
Domyślna kolejność sortowania to wartość skonfigurowana dla zmiennej tag.sort, jeśli istnieje, lub w przeciwnym razie kolejność leksykograficzna. Zobacz git-config (1).
Po google ktoś powiedział , że obsługuje git 2.8.0 zgodnie ze składnią.
git tag --sort=committerdate
git tag --sort=committerdate | tail -1
Poniższe działa dla mnie, jeśli potrzebujesz dwóch ostatnich znaczników (na przykład, aby wygenerować dziennik zmian między bieżącym i poprzednim znacznikiem). Testowałem to tylko w sytuacji, gdy najnowszy tag był HEAD
.
PreviousAndCurrentGitTag=`git describe --tags \`git rev-list --tags --abbrev=0 --max-count=2\` --abbrev=0`
PreviousGitTag=`echo $PreviousAndCurrentGitTag | cut -f 2 -d ' '`
CurrentGitTag=`echo $PreviousAndCurrentGitTag | cut -f 1 -d ' '`
GitLog=`git log ${PreviousGitTag}..${CurrentGitTag} --pretty=oneline | sed "s_.\{41\}\(.*\)_; \1_"`
Odpowiada moim potrzebom, ale ponieważ nie jestem git-magiem, jestem pewien, że można go jeszcze ulepszyć. Podejrzewam też, że się zepsuje, jeśli historia zatwierdzeń pójdzie do przodu. Po prostu dzielę się na wypadek, gdyby komuś to pomogło.
Moja pierwsza myśl jest taka, że możesz użyć git rev-list HEAD
, który wymienia wszystkie obroty w odwrotnej kolejności chronologicznej, w połączeniu z git tag --contains
. Gdy znajdziesz referencję, w której git tag --contains
powstaje niepusta lista, znalazłeś najnowsze tagi.
Jeśli potrzebujesz jednego linera, który pobiera najnowszą nazwę tagu (według daty tagu) w bieżącym oddziale :
git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD
Używamy tego do ustawienia numeru wersji w konfiguracji.
Przykład wyjściowy:
v1.0.0
Działa również w systemie Windows.
-bash: syntax error near unexpected token '('
--format="%(refname:short)"
) I pomijam, --points-at=HEAD
to działa. Z tym ostatnim przełącznikiem nic nie zwraca, bo chyba mój HEAD
tag nie jest oznaczony?
HEAD
nie jest oznaczony.
To jest stary wątek, ale wydaje się, że wielu ludziom brakuje najprostszej, najłatwiejszej i najbardziej poprawnej odpowiedzi na pytanie OP: aby uzyskać najnowszy tag dla bieżącego oddziału , używaszgit describe HEAD
. Gotowy.
Edycja: możesz także podać dowolną prawidłową nazwę, nawet piloty; tzn. git describe origin/master
powie Ci najnowszy tag, który można uzyskać z origin / master.
for-each-ref
polecenie ( stackoverflow.com/a/5261470/515973 ) oraz połączenie rev-list
i describe
( stackoverflow.com/a/7979255/515973 )
git describe branchname --tags
działa dla mnie, aby uzyskać najnowszy tag na gałęzi (git wersja 2.12.2)
Aby uzyskać najnowszy tag tylko dla bieżącej nazwy gałęzi / tagu, która poprzedza bieżącą gałąź, musiałem wykonać następujące czynności
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH
Mistrz oddziału:
git checkout master
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH
master-1448
Niestandardowy oddział:
git checkout 9.4
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH
9.4-6
I moja ostatnia potrzeba zwiększenia i uzyskania tagu +1 do następnego tagowania.
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'
W przypadku zadanego pytania
Jak uzyskać najnowszą nazwę znacznika w bieżącym oddziale
chcesz
git log --first-parent --pretty=%d | grep -m1 tag:
--first-parent
mówi, git log
aby nie wyszczególniać żadnych połączonych historii, --pretty=%d
mówi, aby pokazywać tylko dekoracje, tj. lokalne nazwy dla jakichkolwiek zatwierdzeń. grep -m1
mówi „dopasuj tylko jeden”, więc otrzymujesz tylko najnowszy tag.
Nie ma tu wiele wzmianek o tagach bez adnotacji w porównaniu z tagami z adnotacjami. „opisz” działa na tagach z adnotacjami i ignoruje te bez adnotacji.
Jest to brzydkie, ale wykonuje zlecenie i nie znajdzie żadnych znaczników w innych gałęziach (a nie w tym określonym w poleceniu: master w poniższym przykładzie)
Filtrowanie powinno być zoptymalizowane (skonsolidowane), ale znowu wydaje się, że to zadanie.
git log --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1
Krytyki są mile widziane, ponieważ zamierzam teraz użyć tego :)