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=0nią powinien zwrócić najbliższy tag z komentarzem
git describe --exact-match --abbrev=0.
git describe --tagsi 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 describemó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=-authordatei --sort=authordate.
--sort=-taggerdate. Dla tagów authordatei committerdatesą puste (tak bezużyteczne jak klucze sortowania).
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1jest jeszcze lepszy :)
--points-at=$SHAda 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=0odpowiedzi 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 Zjak v0.2w poniedziałek, a następnie tag'ed Qjak v0.1we wtorek. v0.1jest nowszy, ale v0.2bliż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..HEADetc dla każdego tagu. Daje to liczbę zatwierdzeń w HEAD, ponieważ ścieżka kończąca się na v0.2odbiegał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 describerobi 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 describeszuka 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 %Dwyklucza otaczające ()znaki, a seds 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:
HEADdo połączenia bazy ze znacznikiemHEADi znacznikaNie wiem, jak obliczyć długość najkrótszej ścieżki .
Skrypt tagi sortowania według daty z bazy seryjnej pomiędzy HEADi 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 --tagsmają 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ć HEADto, co chcesz!
git tag -l ac* | tail -n1
Pobierz ostatni tag z prefiksem „ac” . Na przykład znacznik o nazwie z ac1.0.0lub ac1.0.5. Inne znaczniki nazwane 1.0.0, 1.1.0bę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 sortkłótni. Będzie używać lexicorgraphic orderdomyślnie, jeśli tag.sortwł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 --containspowstaje 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=HEADto działa. Z tym ostatnim przełącznikiem nic nie zwraca, bo chyba mój HEADtag nie jest oznaczony?
HEADnie 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/masterpowie Ci najnowszy tag, który można uzyskać z origin / master.
for-each-refpolecenie ( stackoverflow.com/a/5261470/515973 ) oraz połączenie rev-listi describe( stackoverflow.com/a/7979255/515973 )
git describe branchname --tagsdział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-parentmówi, git logaby nie wyszczególniać żadnych połączonych historii, --pretty=%dmówi, aby pokazywać tylko dekoracje, tj. lokalne nazwy dla jakichkolwiek zatwierdzeń. grep -m1mó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 :)