Come ottenere l'ultimo nome tag nell'attuale ramo in Git?


463

Qual è il modo più semplice per ottenere il tag più recente in Git?

git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag

produzione:

a
b
c

Devo scrivere uno script per ottenere il datetime di ogni tag e confrontarli?


1
ultimo tag creato o ultimo tag ordinato per data di commit? La tua risposta accettata mostra l'ultimo tag creato. Questo potrebbe essere un problema se si decide di modificare i tag esistenti ...
Paebbels

Risposte:


412

Potresti dare un'occhiata git describe, che fa qualcosa di simile a quello che stai chiedendo.


194
Con --abbrev=0esso dovrebbe restituire il tag annotato più vicino
Jakub Narębski,

13
Restituisce l'ultimo tag nel ramo corrente.
Brittohalloran,

42
Per ottenere l' ultimo tag annotato che ha come target solo il commit corrente nel ramo corrente , utilizzare git describe --exact-match --abbrev=0.
Naftuli Kay,

5
Questa risposta, con commenti, non mi ha fornito il tag corretto. @kilianic ha fornito una soluzione corretta.
Herman J. Radtke III,

21
git describe --tagse confronta l'ultimo tag nella pagina di rilascio di github
Adriano Resende l'

628

Per ottenere il tag più recente:

git describe --tags

Per ottenere il tag annotato più recente :

git describe --abbrev=0

2
Sì, come git describedice la pagina man per : --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
Giorgos Kylafas,

22
O semplicementegit describe --tags
james_womack

5
Questa risposta (e probabilmente le altre) si guasta se hai due tag che puntano allo stesso commit. A meno che i tag non siano tag con annotazioni, penso che non ci sia modo per git di distinguere quale dei due è stato creato in precedenza.
Paul Lynch,

10
Questa dovrebbe essere la risposta accettata. Grazie per aver inviato.
crmpicco,

6
se vuoi controllare direttamente il tag più recente:git checkout $(git describe --abbrev=0 --tags)
JohnRDOrazio,

321

Produrrà il tag dell'ultimo commit con tag su tutti i rami

git describe --tags $(git rev-list --tags --max-count=1)

8
oppure TAG=$(git describe --tags $(git rev-list --tags --max-count=1))@ william-pursell
kilianc,

20
Questa è la risposta migliore In realtà ottiene tag in tutti i rami, non solo nel ramo corrente, come fa l'attuale risposta "corretta".
Brittohalloran,

61
Tranne la domanda che chiede specificamente il ramo corrente.
michaeltwofish,

3
@michaeltwofish, all'epoca non lo sapevo, l'ho capito in seguito e ho corretto di conseguenza la mia risposta. Mi dispiace per quello.
Kilianc,

3
Note: questo comando restituisce il tag "più recente" anche se questo tag si trova su un altro ramo.
Alan Zhiliang Feng,

47

Per ottenere il tag più recente, puoi fare:

$ git for-each-ref refs / tags --sort = -taggerdate --format = '% (refname)' --count = 1

Ovviamente, puoi modificare l'argomento count o il campo di ordinamento come desiderato. Sembra che tu abbia potuto voler porre una domanda leggermente diversa, ma questo risponde alla domanda mentre la interpreto.


2
Questo è quasi esattamente quello che stavo cercando (il tag più recente in tutti i rami), ma almeno con la mia versione di git (1.7.7.6) i tag sono prodotti nello stesso ordine per entrambi --sort=-authordatee --sort=authordate.
Larks

3
Ah, perché quello che veramente vuoi è --sort=-taggerdate. Per i tag authordatee committerdatesono vuoti (così inutili come chiavi di ordinamento).
Larks

8
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1è ancora meglio :)
Christophe Eblé,

5
Davvero, il downgrade di una risposta perfettamente corretta che ha quasi 5 anni senza un commento? È maleducato.
William Pursell,

1
E --points-at=$SHAti darà il tag per un hash di commit.
Ryan

35

Cosa ne pensi di questo?

TAG=$(git describe $(git rev-list --tags --max-count=1))

Tecnicamente, non otterrai necessariamente il tag più recente, ma l'ultimo commit che è taggato, che potrebbe essere o meno la cosa che stai cercando.


Questo non ottiene l'ultimo tag nel ramo corrente ma per tutti i rami. Il che è fantastico, perché è esattamente quello di cui avevo bisogno. Grazie Wincent.
jasongregori,

2
Se avete bisogno di ottenere modello tag corrispondente è possibile utilizzare --tags=<pattern>in rev-list. Ad esempio, ottieni il tag dell'ultima versionegit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
Wirone,

1
$ (git descrivi - contiene $ (git rev-parse HEAD))
Vaidas Zilionis

Grazie, ha funzionato, ma ho dovuto aggiungere --tags git describe --tags $(git rev-list --tags --max-count=1)
Gianluca Casati il

25

Puoi eseguire: git describe --tags $(git rev-list --tags --max-count=1)parlato qui: come ottenere il nome tag più recente?


Ho iniziato con la risposta migliore / accettata e sono sceso giù. Questa è la prima risposta che in realtà mi dà il tag più recente (non sai perché ma il semplice vecchio git describe ...restituisce un tag precedente ?!)
Jeremy Davis,

Questo è l'unico che funziona per me. --abbrev=0Ho provato alcune delle risposte e hanno tagliato parte del tag che voglio.
Luke Davis,

22

"Più recenti" potrebbe avere due significati in termini di git.

Potresti voler dire "quale tag ha la data di creazione più recente nel tempo" e la maggior parte delle risposte qui sono per quella domanda. In termini di domanda, vorrai restituire il tag c.

Oppure si potrebbe dire "che tag è il più vicino nella storia dello sviluppo di qualche ramo chiamato", di solito il ramo si è in, HEAD. Nella tua domanda, questo restituirebbe il tag a.

Questi potrebbero essere diversi ovviamente:

A->B->C->D->E->F (HEAD)
       \     \
        \     X->Y->Z (v0.2)
         P->Q (v0.1)

Immagina che lo sviluppatore sia stato etichettato Zcome v0.2lunedì, quindi etichettato Qcome v0.1martedì. v0.1è il più recente, ma v0.2è più vicino nella storia dello sviluppo a HEAD, nel senso che il percorso su cui inizia inizia in un punto più vicino a HEAD.

Penso che di solito desideri questa seconda risposta, più vicina alla storia dello sviluppo. Puoi scoprirlo usando git log v0.2..HEADetc per ogni tag. Questo ti dà il numero di commit su HEAD poiché il percorso che termina in v0.2divergente dal percorso seguito da HEAD.

Ecco uno script Python che lo fa ripetendo tutti i tag che eseguono questo controllo e quindi stampando il tag con il minor numero di commit su HEAD poiché il percorso del tag è divergente:

https://github.com/MacPython/terryfy/blob/master/git-closest-tag

git describefa qualcosa di leggermente diverso, in quanto segue da (ad esempio) HEAD per trovare il primo tag che si trova su un percorso nella storia da HEAD. In termini git, git describecerca i tag "raggiungibili" da HEAD. Pertanto non troverà tag del genere v0.2che non si trovano sul percorso di ritorno da HEAD, ma un percorso divergente da lì.


21

git describe --tags

restituisce l'ultimo tag che può essere visto dal ramo corrente


15
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed  's ......  '

SE AVETE BISOGNO DI PIÙ DI UN ULTIMO TAG

(git descrive - le etichette a volte danno hash sbagliati, non so perché, ma per me - max-count 2 non funziona)

questo è il modo in cui puoi ottenere l'elenco con gli ultimi 2 nomi di tag in ordine cronologico inverso, funziona perfettamente su git 1.8.4. Per le versioni precedenti di git (come 1.7. *), Non esiste una stringa "tag:" nell'output - basta eliminare l'ultima chiamata sed

Se desideri più di 2 tag recenti, modifica questo "sed 2q" in "sed 5q" o qualsiasi altra cosa ti serva

Quindi puoi facilmente analizzare ogni nome di tag in una variabile o giù di lì.


questo è davvero utile, molti sviluppatori cercheranno di automatizzare il processo di rilascio ripristinando il tag precedente in caso di interruzione della distribuzione. Roba impressionante!!!
AkD

1
Per fare ciò: git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p' dove in %Desclude i ()caratteri circostanti e la seds iniziale 5q lascia 4 righe prima di 5, quindi stampa tutti i caratteri tra 'tag: `e il primo', '. Quindi ... supponendo che non vengano utilizzate virgole all'interno del tag, questo funziona perfettamente.
Cometsong,

14

Cosa c'è di sbagliato in tutti i suggerimenti (tranne la spiegazione di Matthew Brett , aggiornato su questo post di risposta)?

Basta eseguire qualsiasi comando fornito da altri sulla cronologia di jQuery Git quando ci si trova in diversi punti della cronologia e controllare il risultato con la rappresentazione della cronologia dei tag visivi (l'ho fatto è per questo che vedi questo post):

$ git log --graph --all --decorate --oneline --simplify-by-decoration

Oggi molti progetti eseguono rilasci (e così tag) in un ramo separato dalla linea principale .

Ci sono forti ragioni per questo. Guarda tutti i progetti JS / CSS ben consolidati. Per le convenzioni degli utenti portano file di rilascio binari / minimizzati in DVCS. Naturalmente, in qualità di manutentore del progetto, non si desidera eliminare la cronologia delle differenze della mainline con BLOB binari inutili ed eseguire il commit di manufatti di build dalla mainline .

Perché Git usa DAG e non una storia lineare - è difficile definire la metrica della distanza, quindi possiamo dire - oh, che il giro è il più vicino al mio HEAD!

Comincio il mio viaggio (guarda dentro, non ho copiato immagini a prova di fantasia in questo lungo post):

Qual è il tag più vicino in passato rispetto alla ramificazione in Git?

Attualmente ho 4 definizioni ragionevoli di distanza tra tag e revisione con riduzione dell'utilità:

  • lunghezza del percorso più breve da HEADa base di fusione con la modifica
  • data di unione base tra HEADe tag
  • numero di giri raggiungibile da HEAD ma non raggiungibile dal tag
  • data del tag indipendentemente dalla base di unione

Non so come calcolare la lunghezza del percorso più breve .

Script che ordina i tag in base alla data di unione base tra HEADe tag:

$ git tag \
     | while read t; do \
         b=`git merge-base HEAD $t`; \
         echo `git log -n 1 $b --format=%ai` $t; \
       done | sort

Utilizzabile sulla maggior parte dei progetti.

Script che ordina i tag in base al numero di giri raggiungibile da HEAD ma non raggiungibile dal tag:

$ git tag \
    | while read t; do echo `git rev-list --count $t..HEAD` $t; done \
    | sort -n

Se la cronologia del tuo progetto ha date strane su commit (a causa di ribassi o un'altra riscrittura della cronologia o qualche idiota dimentica di sostituire la batteria del BIOS o altre magie che fai sulla storia) usa lo script sopra.

Per l'ultima opzione ( data del tag indipendentemente dalla base di unione ) per ottenere un elenco di tag ordinati per data utilizzare:

$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r

Per conoscere la data di revisione corrente utilizzare:

$ git log --max-count=1

Nota che git describe --tags hanno un utilizzo sui propri casi, ma non per trovare il tag più vicino previsto nella storia del progetto .

NOTA È possibile utilizzare le ricette sopra riportate su qualsiasi revisione, basta sostituire HEADcon ciò che si desidera!


12

git describe --abbrev=0 --tags

Se non vedi il tag più recente, assicurati di recuperare l'origine prima di eseguirlo:

git remote update


12
git tag -l ac* | tail -n1

Ottieni l'ultimo tag con il prefisso "ac" . Ad esempio, tag denominato con ac1.0.0o ac1.0.5. Altre categorie denominate 1.0.0, 1.1.0saranno ignorati.

git tag -l [0-9].* | tail -n1

Ottieni l'ultimo tag, il cui primo carattere è 0-9. Quindi, quei tag con il primo carattere a-zverranno ignorati.

Ulteriori informazioni

git tag --help # Help for `git tag`

git tag -l <pattern>

Elenca i tag con nomi che corrispondono al modello dato (o tutti se non viene fornito alcun modello). L'esecuzione di "tag git" senza argomenti elenca anche tutti i tag. Il modello è un jolly di shell (cioè, abbinato usando fnmatch (3)). Si possono dare più schemi; se uno di questi corrisponde, viene mostrato il tag.


tail -n <number> # display the last part of a file
tail -n1 # Display the last item 

Aggiornare

Con git tag --help, circa l' sortargomento. Utilizzerà lexicorgraphic orderper impostazione predefinita, se la tag.sortproprietà non esiste.

L'ordinamento predefinito è il valore configurato per la variabile tag.sort, se esiste, o l'ordine lessicografico in caso contrario. Vedi git-config (1).

Dopo google, qualcuno ha detto che git 2.8.0 supporta la sintassi seguente.

git tag --sort=committerdate

non è wok per me, l'ultimo tag è 2.11.174 ma questa stampa 2.11.99 perché ordina non come versioning
Ali.MD

8
git tag --sort=committerdate | tail -1

Spiega in che modo questo frammento di codice risolverà il problema, anziché pubblicare una risposta di solo codice.
Arun Vinoth,

5

Quanto segue funziona per me nel caso in cui siano necessari gli ultimi due tag (ad esempio, al fine di generare il registro delle modifiche tra il tag corrente e il tag precedente). L'ho provato solo in situazioni in cui l'ultimo tag era il 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_"`

Si adatta alle mie esigenze, ma poiché non sono un mago git, sono sicuro che potrebbe essere ulteriormente migliorato. Ho anche il sospetto che si spezzerà nel caso in cui la cronologia del commit passi avanti. Sto solo condividendo nel caso in cui aiuti qualcuno.


4

Il mio primo pensiero è che potresti usare git rev-list HEAD, che elenca tutti i giri in ordine cronologico inverso, in combinazione con git tag --contains. Quando trovi un riferimento in cui viene git tag --containsprodotto un elenco non vuoto, hai trovato i tag più recenti.


4

Se vuoi trovare l'ultimo tag che è stato applicato su un ramo specifico, puoi provare quanto segue:

git describe --tag $(git rev-parse --verify refs/remotes/origin/"branch_name")

3

Se hai bisogno di un solo liner che ottiene l' ultimo nome del tag (per data del tag) sul ramo corrente :

git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD

Usiamo questo per impostare il numero di versione nell'impostazione.

Esempio di output:

v1.0.0

Funziona anche su Windows.


1
Su Linux (Debian Stretch) ottengo-bash: syntax error near unexpected token '('
Jeremy Davis il

1
Se avvolgo quella parte tra virgolette (es. --format="%(refname:short)") E la salto --points-at=HEADfunziona. Con quell'ultimo interruttore non restituisce nulla, immagino perché il mio HEADnon è taggato?
Jeremy Davis,

@JeremyDavis, sì, penso che sia perché il tuo HEADnon è taggato.
Markus,

2

Questo è un vecchio thread, ma sembra che a molte persone manchi la risposta più semplice, più facile e più corretta alla domanda di OP: per ottenere l'ultimo tag per il ramo corrente , si usagit describe HEAD . Fatto.

Modifica: puoi anche fornire qualsiasi nome di riferimento valido, anche telecomandi; cioè, git describe origin/masterti dirà l'ultimo tag che può essere raggiunto da origin / master.


Nulla garantisce che "il tag più recente" sia gestito da qualsiasi filiale. Le due soluzioni di lavoro sono il for-each-refcomando ( stackoverflow.com/a/5261470/515973 ) e la combinazione di rev-liste describe( stackoverflow.com/a/7979255/515973 )
Julien Carsique

1
Questo non ottiene il tag più recente per me.
K - La tossicità in SO sta crescendo.

git describe branchname --tagsfunziona per me ottenere l'ultimo tag sul ramo (versione git 2.12.2)
Rob_M

0

Per ottenere l'ultimo tag solo sul nome del ramo / tag corrente che ha il prefisso con il ramo corrente, ho dovuto eseguire quanto segue

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH

Direttore di filiale:

git checkout master

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

master-1448

Filiale personalizzata:

git checkout 9.4

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

9.4-6

E il mio ultimo bisogno di aumentare e ottenere il tag +1 per il prossimo tagging.

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags  --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'

0

Per la domanda posta,

Come ottenere il nome tag più recente nel ramo corrente

tu vuoi

git log --first-parent --pretty=%d | grep -m1 tag:

--first-parentdice di git lognon dettagliare le storie unite, --pretty=%ddice di mostrare solo le decorazioni, cioè i nomi locali per ogni commit. grep -m1dice "match one one", in modo da ottenere solo il tag più recente.


0

se i tag sono ordinabili:

git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1

0

Qui non c'è molta menzione di tag non annotati rispetto a quelli annotati. 'descrivi' funziona con tag annotati e ignora quelli non annotati.

Questo è brutto ma fa il lavoro richiesto e non troverà alcun tag su altri rami (e non su quello specificato nel comando: master nell'esempio seguente)

Il filtro dovrebbe probabilmente essere ottimizzato (consolidato), ma, di nuovo, questo sembra funzionare.

git log  --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1

Le critiche sono benvenute mentre vado ora a metterle in pratica :)


-2

Un altro modo semplice per ottenere l' ultimo nome tag è con

git tag | tail -1

o

TAG=$(git tag | tail -1)

per memorizzarlo in una variabile.

git tagelenca tutti i tag disponibili e restituirà l'ultima riga se il risultato.tail-1


4
Senza smistamento, questa è una mossa sbagliata.
mjd2,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.