Qual é a maneira mais simples de obter a tag mais recente no Git?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
resultado:
a
b
c
Devo escrever um script para obter o datetime de cada tag e compará-los?
Qual é a maneira mais simples de obter a tag mais recente no Git?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
resultado:
a
b
c
Devo escrever um script para obter o datetime de cada tag e compará-los?
Respostas:
Você pode dar uma olhada git describe
, o que faz algo parecido com o que você está perguntando.
--abbrev=0
ele deve retornar mais próximo anotada tag
git describe --exact-match --abbrev=0
.
git describe --tags
e compare a última tag com na página de lançamento do github
Para obter a tag mais recente:
git describe --tags
Para obter a tag anotada mais recente :
git describe --abbrev=0
git describe
diz: --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)
Produzirá a tag do último commit marcado em todas as ramificações
git describe --tags $(git rev-list --tags --max-count=1)
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
@ william-pursell
Para obter a tag mais recente, você pode:
$ git for-each-ref refs / tags --sort = -taggerdate --format = '% (refname)' --count = 1
Obviamente, você pode alterar o argumento de contagem ou o campo de classificação, conforme desejado. Parece que você pretende fazer uma pergunta um pouco diferente, mas isso responde à pergunta como eu a interpreto.
--sort=-authordate
e --sort=authordate
.
--sort=-taggerdate
. Para tags authordate
e committerdate
está vazio (tão inútil quanto as chaves de classificação).
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1
é ainda melhor :)
--points-at=$SHA
fornecerá a tag para um hash de confirmação.
Que tal agora?
TAG=$(git describe $(git rev-list --tags --max-count=1))
Tecnicamente, você não necessariamente obterá a tag mais recente, mas o commit mais recente que está marcado, que pode ou não ser o que você está procurando.
--tags=<pattern>
-lo rev-list
. Por exemplo, obtenha a tag da última versãogit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
git describe --tags $(git rev-list --tags --max-count=1)
Você pode executar: git describe --tags $(git rev-list --tags --max-count=1)
falou aqui: Como obter o nome da tag mais recente?
git describe ...
retorna uma tag antes ?!)
--abbrev=0
respostas e eles cortaram parte da tag que eu quero.
"Mais recente" pode ter dois significados em termos de git.
Você pode dizer "qual tag tem a data de criação mais recente" e a maioria das respostas aqui são para essa pergunta. Em termos de sua pergunta, você deseja retornar a tagc
.
Ou você pode significar "qual tag é a mais próxima do histórico de desenvolvimento de algum ramo nomeado", geralmente o ramo em que você está HEAD
,. Na sua pergunta, isso retornaria a taga
.
Estes podem ser diferentes, é claro:
A->B->C->D->E->F (HEAD)
\ \
\ X->Y->Z (v0.2)
P->Q (v0.1)
Imagine que o desenvolvedor marcou Z
como v0.2
segunda-feira e depois Q
como v0.1
terça-feira. v0.1
é o mais recente, masv0.2
está mais próximo na história do desenvolvimento do HEAD, no sentido de que o caminho em que ele começa começa em um ponto mais próximo do HEAD.
Eu acho que você geralmente quer essa segunda resposta, mais próxima da história do desenvolvimento. Você pode descobrir isso usando git log v0.2..HEAD
etc para cada tag. Isso fornece o número de confirmações no HEAD desde o caminho que termina emv0.2
divergiu do caminho seguido por HEAD.
Aqui está um script Python que faz isso iterando todas as tags que executam essa verificação e, em seguida, imprimindo a tag com menos confirmações no HEAD, pois o caminho da tag divergiu:
https://github.com/MacPython/terryfy/blob/master/git-closest-tag
git describe
faz algo um pouco diferente, na medida em que rastreia de (por exemplo) HEAD para encontrar a primeira tag que está no caminho de volta da história a partir de HEAD. Em termos de git, git describe
procura por tags "acessíveis" a partir do HEAD. Portanto, ele não encontrará tags como v0.2
essas que não estão no caminho de volta do HEAD, mas em um caminho que divergiu a partir daí.
git describe --tags
retorna a última tag capaz de ser vista pelo ramo atual
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed 's ...... '
SE VOCÊ PRECISA DE MAIS DE UM ÚLTIMO TAG
(git descrevem - tags às vezes dão hashes errados, eu não sei por que, mas para mim --max-count 2 não funciona)
é assim que você pode obter a lista com os 2 últimos nomes de tags em ordem cronológica reversa, funciona perfeitamente no git 1.8.4. Para versões anteriores do git (como 1.7. *), Não há "tag:" string na saída - apenas exclua a última chamada sed
Se você quiser mais de duas tags mais recentes - altere "sed 2q" para "sed 5q" ou o que você precisar
Em seguida, você pode analisar facilmente cada nome de tag como variável.
git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p'
where in %D
exclui os ()
caracteres circundantes , e o sed
s inicial 5q deixa 4 linhas antes de 5, depois imprime todos os caracteres entre 'tag: `e o primeiro', '. Então ... supondo que nenhuma vírgula seja usada dentro da tag, isso funciona perfeitamente.
O que há de errado com todas as sugestões (exceto a explicação de Matthew Brett , atualizada nesta resposta)?
Basta executar qualquer comando fornecido por outro no histórico do jQuery Git quando você estiver em um ponto diferente do histórico e verificar o resultado com a representação visual do histórico de marcação (eu fiz por isso que você vê este post):
$ git log --graph --all --decorate --oneline --simplify-by-decoration
Atualmente, muitos projetos realizam lançamentos (e, portanto, marcam) em ramificações separadas da linha principal .
Há fortes razões para isso. Basta olhar para qualquer projeto JS / CSS bem estabelecido. Para convenções de usuários, eles carregam arquivos de liberação binária / minificada no DVCS. Naturalmente, como mantenedor do projeto, você não deseja descartar o histórico de diferenças da linha principal com blobs binários inúteis e executar o commit de artefatos de construção fora da linha principal .
Como o Git usa o DAG e não o histórico linear - é difícil definir a métrica da distância para que possamos dizer - oh, essa rev é a mais próxima da minha HEAD
!
Começo minha própria jornada (olhe para dentro, não copiei imagens de prova sofisticadas para este longo post):
Qual é a tag mais próxima no passado em relação à ramificação no Git?
Atualmente, tenho 4 definições razoáveis de distância entre tag e revisão com diminuição da utilidade:
HEAD
de base de intercalação com tagHEAD
e tagNão sei como calcular o comprimento do caminho mais curto .
Script que classifica as tags de acordo com a data da base de mesclagem entre 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
É utilizável na maioria dos projetos.
Script que classifica as tags de acordo com o número de rotações alcançáveis a partir de HEAD, mas não alcançáveis a partir da tag:
$ git tag \
| while read t; do echo `git rev-list --count $t..HEAD` $t; done \
| sort -n
Se o histórico do seu projeto tiver datas estranhas nas confirmações (devido a rebase ou outra reescrita do histórico ou algum idiota, esqueça de substituir a bateria do BIOS ou outras mágicas que você faz no histórico) use o script acima.
Para a última opção ( data da tag, independentemente da base de mesclagem ), para obter a lista de tags classificadas por data, use:
$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r
Para conhecer a data atual da revisão, use:
$ git log --max-count=1
Observe que eles git describe --tags
têm uso em seus próprios casos, mas não para encontrar a marca mais próxima esperada humana no histórico do projeto .
NOTA Você pode usar as receitas acima em qualquer revisão, basta substituir HEAD
pelo que deseja!
git tag -l ac* | tail -n1
Obtenha a última tag com o prefixo "ac" . Por exemplo, tag nomeada com ac1.0.0
, ou ac1.0.5
. Outras marcas nomeados 1.0.0
, 1.1.0
serão ignorados.
git tag -l [0-9].* | tail -n1
Obtenha a última tag, cujo primeiro caractere é 0-9
. Portanto, essas tags com o primeiro caractere a-z
serão ignoradas.
git tag --help # Help for `git tag`
git tag -l <pattern>
Listar tags com nomes que correspondam ao padrão fornecido (ou todos, se nenhum padrão for fornecido). Executar "tag git" sem argumentos também lista todas as tags. O padrão é um curinga do shell (ou seja, corresponde ao uso de fnmatch (3)). Padrões múltiplos podem ser dados; se algum deles corresponder, a tag será mostrada.
tail -n <number> # display the last part of a file
tail -n1 # Display the last item
Com git tag --help
, sobre o sort
argumento. Ele será usado lexicorgraphic order
por padrão, se a tag.sort
propriedade não existir.
O padrão da ordem de classificação é o valor configurado para a variável tag.sort, se existir, ou a ordem lexicográfica, caso contrário. Veja git-config (1).
Depois do google, alguém disse que o suporte ao git 2.8.0 segue a sintaxe.
git tag --sort=committerdate
git tag --sort=committerdate | tail -1
O seguinte funciona para mim, caso você precise das duas últimas tags (por exemplo, para gerar um log de alterações entre a tag atual e a tag anterior). Eu testei apenas na situação em que a última tag foi 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_"`
Atende às minhas necessidades, mas como não sou um git wizard, tenho certeza de que poderia ser melhorado ainda mais. Eu também suspeito que isso será interrompido caso o histórico de consolidação avance. Estou apenas compartilhando, caso isso ajude alguém.
Meu primeiro pensamento é que você poderia usar git rev-list HEAD
, que lista todas as rotações em ordem cronológica reversa, em combinação com git tag --contains
. Quando você encontra uma referência onde git tag --contains
produz uma lista não vazia, você encontra as tags mais recentes.
Se você precisar de um liner que obtenha o nome mais recente da tag (por data da tag) na ramificação atual :
git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD
Usamos isso para definir o número da versão na configuração.
Exemplo de saída:
v1.0.0
Também funciona no Windows.
-bash: syntax error near unexpected token '('
--format="%(refname:short)"
) e pular o texto, --points-at=HEAD
ele funcionará. Com essa última opção, ele não retorna nada, acho que porque o meu HEAD
não está marcado?
HEAD
não está marcado.
Este é um tópico antigo, mas parece que muitas pessoas estão perdendo a resposta mais simples, fácil e correta à pergunta do OP: para obter a última tag do ramo atual , usegit describe HEAD
. Feito.
Editar: você também pode fornecer qualquer nome de referência válido, mesmo controles remotos; ou seja, git describe origin/master
informará a tag mais recente que pode ser acessada a partir da origem / mestre.
for-each-ref
comando ( stackoverflow.com/a/5261470/515973 ) e a combinação de rev-list
e describe
( stackoverflow.com/a/7979255/515973 )
git describe branchname --tags
não trabalho para mim para receber as últimas tag no ramo (git versão 2.12.2)
Para obter a tag mais recente apenas no nome da filial / marca atual que prefixa a filial atual, tive que executar o seguinte
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH
Mestre da filial:
git checkout master
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH
master-1448
Filial personalizada:
git checkout 9.4
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH
9.4-6
E minha necessidade final de incrementar e obter a tag +1 para a próxima tag.
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'
Para a pergunta feita,
Como obter o nome da tag mais recente na ramificação atual
você quer
git log --first-parent --pretty=%d | grep -m1 tag:
--first-parent
diz git log
para não detalhar nenhuma história mesclada, --pretty=%d
diz para mostrar apenas as decorações, ou seja, nomes locais para quaisquer confirmações. grep -m1
diz "corresponder a apenas um", para que você obtenha apenas a tag mais recente.
Não há muita menção de tags não anotadas versus tags anotadas aqui. 'description' funciona em tags anotadas e ignora as não anotadas.
Isso é feio, mas faz o trabalho solicitado e não encontrará nenhuma tag em outras ramificações (e não na especificada no comando: master no exemplo abaixo)
A filtragem provavelmente deve ser otimizada (consolidada), mas, novamente, isso parece funcionar.
git log --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1
As críticas são bem-vindas, pois agora vou colocar isso em uso :)