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?
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?
Risposte:
Potresti dare un'occhiata git describe
, che fa qualcosa di simile a quello che stai chiedendo.
--abbrev=0
esso dovrebbe restituire il tag annotato più vicino
git describe --exact-match --abbrev=0
.
git describe --tags
e confronta l'ultimo tag nella pagina di rilascio di github
Per ottenere il tag più recente:
git describe --tags
Per ottenere il tag annotato più recente :
git describe --abbrev=0
git describe
dice la pagina man per : --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)
Produrrà il tag dell'ultimo commit con tag su tutti i rami
git describe --tags $(git rev-list --tags --max-count=1)
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
@ william-pursell
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.
--sort=-authordate
e --sort=authordate
.
--sort=-taggerdate
. Per i tag authordate
e committerdate
sono vuoti (così inutili come chiavi di ordinamento).
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1
è ancora meglio :)
--points-at=$SHA
ti darà il tag per un hash di commit.
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.
--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)
git describe --tags $(git rev-list --tags --max-count=1)
Puoi eseguire: git describe --tags $(git rev-list --tags --max-count=1)
parlato qui: come ottenere il nome tag più recente?
git describe ...
restituisce un tag precedente ?!)
--abbrev=0
Ho provato alcune delle risposte e hanno tagliato parte del tag che voglio.
"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 Z
come v0.2
lunedì, quindi etichettato Q
come v0.1
martedì. 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..HEAD
etc per ogni tag. Questo ti dà il numero di commit su HEAD poiché il percorso che termina in v0.2
divergente 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 describe
fa 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 describe
cerca i tag "raggiungibili" da HEAD. Pertanto non troverà tag del genere v0.2
che non si trovano sul percorso di ritorno da HEAD, ma un percorso divergente da lì.
git describe --tags
restituisce l'ultimo tag che può essere visto dal ramo corrente
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ì.
git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p'
dove in %D
esclude i ()
caratteri circostanti e la sed
s 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.
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à:
HEAD
a base di fusione con la modificaHEAD
e tagNon so come calcolare la lunghezza del percorso più breve .
Script che ordina i tag in base alla data di unione base tra HEAD
e 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 HEAD
con ciò che si desidera!
git tag -l ac* | tail -n1
Ottieni l'ultimo tag con il prefisso "ac" . Ad esempio, tag denominato con ac1.0.0
o ac1.0.5
. Altre categorie denominate 1.0.0
, 1.1.0
saranno 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-z
verranno ignorati.
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
Con git tag --help
, circa l' sort
argomento. Utilizzerà lexicorgraphic order
per impostazione predefinita, se la tag.sort
proprietà 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
git tag --sort=committerdate | tail -1
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.
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 --contains
prodotto un elenco non vuoto, hai trovato i tag più recenti.
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.
-bash: syntax error near unexpected token '('
--format="%(refname:short)"
) E la salto --points-at=HEAD
funziona. Con quell'ultimo interruttore non restituisce nulla, immagino perché il mio HEAD
non è taggato?
HEAD
non è taggato.
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/master
ti dirà l'ultimo tag che può essere raggiunto da origin / master.
for-each-ref
comando ( stackoverflow.com/a/5261470/515973 ) e la combinazione di rev-list
e describe
( stackoverflow.com/a/7979255/515973 )
git describe branchname --tags
funziona per me ottenere l'ultimo tag sul ramo (versione git 2.12.2)
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}'
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-parent
dice di git log
non dettagliare le storie unite, --pretty=%d
dice di mostrare solo le decorazioni, cioè i nomi locali per ogni commit. grep -m1
dice "match one one", in modo da ottenere solo il tag più recente.
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 :)