Qual é o equivalente do Git para o número de revisão?


244

Usamos o SVN no trabalho, mas para meus projetos pessoais, decidi usar o Git. Então eu instalei o Git ontem e me pergunto qual é o número de revisão equivalente no Git .

Digamos que trabalhemos na versão 3.0.8 e cada correção de bug possui seu próprio número de revisão que podemos usar quando falamos sobre essa correção. Então, se eu codifico o código no Git para 3.0.8, o que posso usar como número de revisão ou algum outro tipo de identificação mais detalhado? Acho que o hash não é tão amigável para os seres humanos.



Há um artigo para uma das possíveis soluções. Pode parecer um pouco pesado, mas integrado na saída "git log" e não requer comandos adicionais além de "git push / pull / fetch".
Dmitry Pavlenko

Infelizmente, o artigo vinculado de @DmitryPavlenko está em um domínio morto: gitsvn.x10.mx. Sem indicação do assunto, será difícil para alguém encontrá-lo em outro lugar.
Michael Donohue 02/02

Nota: não é mais necessária a abreviação com o git description: consulte stackoverflow.com/a/41308073/6309
VonC

1
Não, Laurence Gonsalves, isso não é uma duplicata de "como obter a contagem de confirmação do git?" - esta é sobre o número da versão, e mesmo que a contagem de consolidações podem ser manipuladas a olhar um pouco parecidos - a versão de hash é muito diferente do que a contagem de consolidação :-)
David Svarrer

Respostas:


149

Boas ou más notícias para você, esse hash é o número da revisão. Eu também tive problemas com isso quando mudei de SVN para git.

Você pode usar "marcação" no git para marcar uma determinada revisão como "liberação" para uma versão específica, facilitando a consulta a essa revisão. Confira esta postagem no blog .

A principal coisa a entender é que o git não pode ter números de revisão - pense na natureza descentralizada. Se os usuários A e B estão se comprometendo com seus repositórios locais, como o git pode atribuir razoavelmente um número de revisão seqüencial? A não tem conhecimento de B antes de empurrar / puxar as mudanças um do outro.

Outra coisa a considerar é a ramificação simplificada para ramos de correção de bugs:

Comece com um release: 3.0.8. Depois desse lançamento, faça o seguinte:

git branch bugfixes308

Isso criará um ramo para correções de bugs. Faça o checkout da filial:

git checkout bugfixes308

Agora faça as alterações desejadas.

git commit -a

Confirme-os e volte para a ramificação principal:

git checkout master

Em seguida, puxe essas alterações do outro ramo:

git merge bugfixes308

Dessa forma, você tem um ramo de correção de bug específico para a versão em separado, mas ainda está inserindo as alterações da correção de bug no seu principal tronco de desenvolvimento.


11
Eu entendi que hash é o número da revisão, mas eu esperava que não fosse :-))) obrigado por uma explicação muito boa e por sugestões agora para lidar com isso.
Radek

3
De nada. Eu estava muito frustrado com git quando eu peguei ele pela primeira vez a partir do SVN, mas agora eu balançar a outra maneira ...
makdad

4
Além disso, já faz um tempo desde que eu publiquei isso, mas lembre-se de que você também pode fazer "git checkout -b new_branch_name" para fazer "git branch foo" e "git checkout foo" como uma linha.
217126

1
Estou correto que os hashes são hashes "verdadeiros" e nem mesmo remotamente sequenciais? Portanto, o mais importante é que, se o banco de dados de erros indicar fixed in 547cc3e..c4b2eba, e você tiver alguma outra revisão, você não tem idéia se o seu código deve ou não conter a correção ?! Certamente os gits do git-central têm uma solução para isso?!?!
Olie 23/05

3
No SVN, o fato de um bug ser corrigido no r42 não informa se ele também foi corrigido no r43 assim que você usa as ramificações.
Matthieu Moy

186

Com o Git moderno (1.8.3.4 no meu caso) e não usando branches, você pode:

$ git rev-list --count HEAD
68

22
Considere usargit rev-list --count --first-parent HEAD
Flimm

8
Dadas essas informações (o número 68), existe uma maneira de determinar a revisão para readquirir o código? Suponha que a "revisão 68" seja lançada em um ambiente de teste, o desenvolvimento continue e, mais tarde, um desenvolvedor precisará readquirir a "revisão 68" do controle de origem. Como ele segmentaria a versão específica para clonar? Ou estou sentindo falta de algo no Git que torna isso desnecessário?
David

9
Lembre-se de que esta solução produziria resultados diferentes para diferentes desenvolvedores. Além disso, o cálculo inverso da "contagem" para o commit produziria commits diferentes para diferentes desenvolvedores !! Isso ocorre devido à natureza distribuída do Git e que os commit acontecem em repositórios diferentes durante o mesmo período, mas podem não ser contabilizados git rev-list --count HEADdependendo de quando os últimos push e pull foram feitos.
Jason

2
@ Jason, o comentário de David sobre a adição de um --first-parentendereço para sua preocupação? Eu odiaria evitar uma solução aparentemente mais simples por causa de um caso raro, se houver uma solução igualmente simples ou uma maneira de torná-la mais robusta.
MarkHu

4
@MarkHu, --first-parentajuda. Contanto que não seja feito o rebaseamento e o mesmo ramo seja sempre usado para fazer lançamentos (e para calcular esse número, é claro), acho que isso poderia ser usado. No entanto, ainda estou incerto de que sempre identificaria exclusivamente o commit de onde o lançamento veio. Há tantas coisas que podem dar errado aqui ... mas, no momento, não consigo pensar em algo que definitivamente iria quebrar isso (considerando minhas declarações "contanto que" acima). O git describemétodo mencionado em outra resposta é o caminho a percorrer. Crie uma tag se quiser algo legível por humanos.
Jason

104

O git describecomando cria um nome legível um pouco mais humano que se refere a um commit específico. Por exemplo, da documentação:

Com algo como a árvore atual do git.git, recebo:

[torvalds@g5 git]$ git describe parent
v1.0.4-14-g2414721

ou seja, o cabeçalho atual do meu ramo "pai" é baseado na v1.0.4, mas como ele tem alguns commits além disso, o description adicionou o número de commits adicionais ("14") e um nome de objeto abreviado para o commit próprio ("2414721") no final.

Desde que você use tags com nome sensato para marcar versões específicas, isso pode ser considerado aproximadamente equivalente a um "número de revisão" do SVN.


7
Gostaria apenas de observar que isso funciona apenas se o seu gitrepositório já tiver tags; caso contrário, você poderá obter uma falha no git description com "fatal: nenhum nome encontrado, não pode descrever nada". - Estouro de pilha ; o que significa que você teria que configurar as tags por conta própria.
Sdaau

14
@sdaau: Se você estiver usando isso em um script ou algo assim e quiser git describenunca falhar, use a git describe --alwaysopção
precisa saber é o seguinte

A saída de pode git describeser usada para encontrar a fonte confirmada, de alguma forma? Falta menos de contagem manual de confirmações no log, quero dizer.
Lii

@Lii: O que você quer dizer com "commit de origem"? Tanto o tag mais próximo ( v1.0.4) quanto o id de confirmação mais recente ( 2414721) já fazem parte da saída de descrição do git.
Greg Hewgill 15/10/1918

@GregHewgill: Sim, obrigado, quando fiz a pergunta, não percebi que o "nome abreviado do objeto" é um valor que pode ser usado para identificar a confirmação. Isso é brilhante!
Lii 16/10

67

Os outros pôsteres estão certos, não há "número de revisão".

Eu acho que a melhor maneira é usar tags para "lançamentos"!

Mas usei o seguinte para falsificar os números de revisão (apenas para os clientes verem as revisões e o progresso, pois eles queriam ter as mesmas revisões crescentes do git do que costumavam usar por subversão).

Mostre que a "revisão atual" de "HEAD" é simulada usando o seguinte:

git rev-list HEAD | wc -l

Mas e se o cliente me disser que há um erro na "revisão" 1302?

Para isso, adicionei o seguinte à seção [alias] do meu ~ / .gitconfig:

show-rev-number = !sh -c 'git rev-list --reverse HEAD | nl | awk \"{ if(\\$1 == "$0") { print \\$2 }}\"'

usando git show-rev-number 1302imprimirá o hash para a "revisão" :)

Fiz uma postagem no blog (em alemão) sobre essa "técnica" há algum tempo.


@Radek - "às vezes precisa saber o que 'code change = commit' corrigiu algo" - então git bisect(link) é a ferramenta apropriada para identificar o que mudou quando e por quem.
5136 Michael

@Radek Sim, é um número cada vez maior. Apenas conta as revisões que você fez check-in no HEAD. Portanto, todo commit é uma nova revisão. Isso não funcionará para ramificações diferentes.
OderWat

1
Eu gosto da sua solução. Observe que você pode simplificá-lo: show-rev-number =! Sh -c 'git rev-list --reverse HEAD | awk NR == $ 0 '
avner

@avner Obrigado! Eu não uso um monte de awk na minha vida, obviamente :)
OderWat

3
Eu tive que usargit rev-list --reverse HEAD | awk "{ print NR }" | tail -n 1
Gerry

27

Git não tem o mesmo conceito de números de revisão que subversão. Em vez disso, cada instantâneo fornecido com uma confirmação é marcado por uma soma de verificação SHA1. Por quê? Existem vários problemas com um revno em execução em um sistema de controle de versão distribuído:

Primeiro, como o desenvolvimento não é linear, o anexo de um número é bastante difícil como um problema para resolver de uma maneira que satisfaça sua necessidade como programador. Tentar corrigir isso adicionando um número pode rapidamente se tornar problemático quando o número não se comporta conforme o esperado.

Segundo, os números de revisão podem ser gerados em máquinas diferentes. Isso torna a sincronização de números muito mais difícil - especialmente porque a conectividade é unidirecional; você pode nem ter acesso a todas as máquinas que possuem o repositório.

Terceiro, no git, pioneiro no sistema OpenCM, agora extinto, a identidade de uma confirmação (o que é a confirmação) é equivalente ao seu nome (o ID SHA). Esse conceito de nomeação = identidade é muito forte. Quando você se senta com um nome de confirmação na mão, ele também identifica o commit de uma maneira imperdoável. Isso, por sua vez, permite que você verifique todas as suas confirmações de volta à primeira inicial quanto à corrupção com o git fsckcomando

Agora, como temos um DAG (gráfico acíclico direcionado) e essas constituem a árvore atual, precisamos de algumas ferramentas para resolver seu problema: Como discriminamos versões diferentes. Primeiro, você pode omitir parte do hash se um determinado prefixo, 1516bd , identifica exclusivamente seu commit. Mas isso também é bastante artificial. Em vez disso, o truque é usar tags e ou branches. Uma tag ou ramificação é semelhante a uma "nota amarela" anexada a um determinado ID SHA1 de confirmação. Tags são, em essência, destinadas a não serem movidas, enquanto um ramo se moverá quando novas confirmações forem feitas em seu HEAD. Existem maneiras de se referir a um commit em torno de uma tag ou ramificação, consulte a página de manual do git-rev-parse.

Geralmente, se você precisar trabalhar em um trecho de código específico, esse trecho está passando por alterações e, como tal, deve ser um ramo com um nome de tópico dizendo. Criar muitas ramificações (20 a 30 por programador não é algo inédito, com algumas 4-5 publicadas para que outras pessoas possam trabalhar) é o truque para um git eficaz. Todo trabalho deve começar como seu próprio ramo e depois ser mesclado quando for testado. Ramos não publicados podem ser reescritos inteiramente e essa parte da destruição da história é uma força do git.

Quando a mudança é aceita no mestre, ela congela um pouco e se torna arqueologia. Nesse ponto, você pode marcá-lo, mas com mais freqüência é feita uma referência ao commit específico em um rastreador de erros ou rastreador de problemas por meio da soma sha1. As tags tendem a ser reservadas para bumps de versão e pontos de ramificação para ramificações de manutenção (para versões antigas).


18

Se você estiver interessado, gerenciei números de versão automaticamente a partir de informações do git aqui, no formato

<major>.<minor>.<patch>-b<build>

onde build é o número total de confirmações. Você verá o código interessante no Makefile. Aqui está a parte relevante para acessar a parte diferente do número da versão:

LAST_TAG_COMMIT = $(shell git rev-list --tags --max-count=1)
LAST_TAG = $(shell git describe --tags $(LAST_TAG_COMMIT) )
TAG_PREFIX = "latex-tutorial-v"

VERSION  = $(shell head VERSION)
# OR try to guess directly from the last git tag
#VERSION    = $(shell  git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//")
MAJOR      = $(shell echo $(VERSION) | sed "s/^\([0-9]*\).*/\1/")
MINOR      = $(shell echo $(VERSION) | sed "s/[0-9]*\.\([0-9]*\).*/\1/")
PATCH      = $(shell echo $(VERSION) | sed "s/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/")
# total number of commits       
BUILD      = $(shell git log --oneline | wc -l | sed -e "s/[ \t]*//g")

#REVISION   = $(shell git rev-list $(LAST_TAG).. --count)
#ROOTDIR    = $(shell git rev-parse --show-toplevel)
NEXT_MAJOR_VERSION = $(shell expr $(MAJOR) + 1).0.0-b$(BUILD)
NEXT_MINOR_VERSION = $(MAJOR).$(shell expr $(MINOR) + 1).0-b$(BUILD)
NEXT_PATCH_VERSION = $(MAJOR).$(MINOR).$(shell expr $(PATCH) + 1)-b$(BUILD)

9

Uma função Bash:

git_rev ()
{
    d=`date +%Y%m%d`
    c=`git rev-list --full-history --all --abbrev-commit | wc -l | sed -e 's/^ *//'`
    h=`git rev-list --full-history --all --abbrev-commit | head -1`
    echo ${c}:${h}:${d}
}

produz algo como

$ git_rev
2:0f8e14e:20130220

Isso é

commit_count:last_abbrev_commit:date_YYmmdd

Esse tipo de coisa pode ser útil, mas se alguém estiver interessado em números de versão incrementais, eles trocariam as posições do campo para que o hash (não incremental) seja o último.
MarkHu

8

O hash SHA1 do commit é equivalente a um número de revisão do Subversion.


7
Infelizmente, possui propriedades bastante diferentes de um número de revisão. É bastante longo e não aumenta monotonamente. Acho que é o preço a pagar para distribuição ...
CodesInChaos

1
@CodeInChaos: Eu sei do que você está falando, mas geralmente é possível se referir ao commit de git com apenas os primeiros 6 ou 8 caracteres do código hash.
22420 Chris Pitman

5
@Radek: Eles não têm garantia única (embora, se você encontrar uma colisão, possa ganhar uma pequena quantidade de celebridade).
precisa

8
@Radek De acordo com o en.wikipedia.org/wiki/Collision_attack , com 4 caracteres do hash, você tem um ID de 16 bits, o que significa que em um repo com 256 (= 2 ^ (16/2)) confirma há 50 % de chance de que duas confirmações tenham o mesmo prefixo de quatro caracteres (e com 65536 confirmações, isso é certo, pois o intervalo de IDs de 4 caracteres acaba). Quando você adiciona um caractere, você tem um ID de 20 bits, o que significa que o limite de 50% está em 1024 confirmações. Mas, como esse é um parâmetro estatístico, nada garante que essas colisões não ocorram antes.
Rudi

2
Como o hash é baseado no conteúdo, ainda é provável que dois commits tenham o mesmo prefixo de hash, não uma certeza. No commit de 65536, é muito provável que dois tenham o mesmo prefixo de quatro caracteres, mas ainda não é certo. Como um aparte, o hash completo não tem uma colisão ainda, mas git está trabalhando nisso :) stackoverflow.com/questions/3475648/...
goodeye

6

Foi o que fiz no meu makefile com base em outras soluções. Observe que isso não apenas fornece ao seu código um número de revisão, mas também anexa o hash, que permite recriar a versão.

# Set the source control revision similar to subversion to use in 'c'
# files as a define.
# You must build in the master branch otherwise the build branch will
# be prepended to the revision and/or "dirty" appended. This is to
# clearly ID developer builds.
REPO_REVISION_:=$(shell git rev-list HEAD --count)
BUILD_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
BUILD_REV_ID:=$(shell git rev-parse HEAD)
BUILD_REV_ID_SHORT:=$(shell git describe --long --tags --dirty --always)
ifeq ($(BUILD_BRANCH), master)
REPO_REVISION:=$(REPO_REVISION_)_g$(BUILD_REV_ID_SHORT)
else
REPO_REVISION:=$(BUILD_BRANCH)_$(REPO_REVISION_)_r$(BUILD_REV_ID_SHORT)
endif
export REPO_REVISION
export BUILD_BRANCH
export BUILD_REV_ID

3
Parece que a maneira mais segura de usar git-describepara evitar erros, é com a git describe --always --dirty --long --tagsqual funciona em todos os casos em que consigo pensar.
MarkHu

5

O problema com o uso do hash git como número de compilação é que ele não está aumentando monotonicamente. OSGi sugere usar um carimbo de data / hora para o número da compilação. Parece que o número de confirmações no ramo poderia ser usado no lugar do número de alteração subversion ou forforce.


5

Escrevi alguns utilitários do PowerShell para recuperar informações de versão do Git e simplificar a marcação

funções: Get-LastVersion, Get-Revisão, Get-NextMajorVersion, Get-NextMinorVersion, TagNextMajorVersion, TagNextMinorVersion:

# Returns the last version by analysing existing tags,
# assumes an initial tag is present, and
# assumes tags are named v{major}.{minor}.[{revision}]
#
function Get-LastVersion(){
  $lastTagCommit = git rev-list --tags --max-count=1
  $lastTag = git describe --tags $lastTagCommit
  $tagPrefix = "v"
  $versionString = $lastTag -replace "$tagPrefix", ""
  Write-Host -NoNewline "last tagged commit "
  Write-Host -NoNewline -ForegroundColor "yellow" $lastTag
  Write-Host -NoNewline " revision "
  Write-Host -ForegroundColor "yellow" "$lastTagCommit"
  [reflection.assembly]::LoadWithPartialName("System.Version")

  $version = New-Object System.Version($versionString)
  return $version;
}

# Returns current revision by counting the number of commits to HEAD
function Get-Revision(){
   $lastTagCommit = git rev-list HEAD
   $revs  = git rev-list $lastTagCommit |  Measure-Object -Line
   return $revs.Lines
}

# Returns the next major version {major}.{minor}.{revision}
function Get-NextMajorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $major = $version.Major+1;
    $rev = Get-Revision
    $nextMajor = New-Object System.Version($major, 0, $rev);
    return $nextMajor;
}

# Returns the next minor version {major}.{minor}.{revision}
function Get-NextMinorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $minor = $version.Minor+1;
    $rev = Get-Revision
    $next = New-Object System.Version($version.Major, $minor, $rev);
    return $next;
}

# Creates a tag with the next minor version
function TagNextMinorVersion($tagMessage){
    $version = Get-NextMinorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next minor version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

# Creates a tag with the next major version (minor version starts again at 0)
function TagNextMajorVersion($tagMessage){
    $version = Get-NextMajorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next majo version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

4

Cada confirmação possui um hash exclusivo. Fora isso, não há números de revisão no git. Você terá que marcar confirmações se quiser mais facilidade de uso.


3

Gostaria apenas de observar outra abordagem possível - e isso é usando o git git-notes (1) , existente desde a v 1.6.6 ( Note to Self - Git ) (estou usando a gitversão 1.7.9.5).

Basicamente, eu costumava git svnclonar um repositório SVN com histórico linear (sem layout padrão, sem ramificações, sem tags) e queria comparar os números de revisão no gitrepositório clonado . Esse clone do git não tem tags por padrão, então não posso usá-lo git describe. A estratégia aqui provavelmente funcionaria apenas para o histórico linear - não tenho certeza de como seria o resultado das fusões, etc .; mas aqui está a estratégia básica:

  • Peça git rev-listuma lista de todo o histórico de consolidação
    • Como, rev-listpor padrão, está em "ordem cronológica reversa", usaríamos sua --reverseopção para obter a lista de confirmações ordenadas pela mais antiga primeiro
  • Use bashshell para
    • aumentar uma variável de contador em cada confirmação como um contador de revisão,
    • gerar e adicionar uma nota git "temporária" para cada confirmação
  • Em seguida, navegue no log usando git logwith --notes, que também irá despejar a nota de uma confirmação, que nesse caso seria o "número da revisão"
  • Quando terminar, apague as notas temporárias ( NB: não tenho certeza se essas notas foram confirmadas ou não; elas realmente não aparecemgit status )

Primeiro, vamos observar que gitpossui um local padrão de anotações - mas você também pode especificar uma ref(referência) para anotações - que as armazenaria em um diretório diferente em .git; por exemplo, enquanto estiver em uma gitpasta de repo, você pode ligar git notes get-refpara ver qual diretório será:

$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever

A única coisa a se notar é que se você notes addcom um --ref, você também deve usar depois que a referência novamente - caso contrário você pode obter erros como " Sem nota encontrada para o objeto XXX ... ".

Neste exemplo, eu escolhi chamar as refnotas de "linrev" (para revisão linear) - isso também significa que não é provável que o procedimento interfira nas notas já existentes. Também estou usando o --git-dirswitch, desde que giteu era novato, tive alguns problemas para entendê-lo - então eu gostaria de "lembrar para mais tarde" :); e eu também uso --no-pagerpara suprimir a desova lessao usar git log.

Então, supondo que você esteja em um diretório, com uma subpasta myrepo_gitque seja um gitrepositório; alguém poderia fazer:

### check for already existing notes:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

### iterate through rev-list three, oldest first,
### create a cmdline adding a revision count as note to each revision

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD add $ih -m \"(r$((++ix)))\""; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done

# git --git-dir=./myrepo_git/.git notes --ref linrev add 6886bbb7be18e63fc4be68ba41917b48f02e09d7 -m "(r1)"
# git --git-dir=./myrepo_git/.git notes --ref linrev add f34910dbeeee33a40806d29dd956062d6ab3ad97 -m "(r2)"
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev add 04051f98ece25cff67e62d13c548dacbee6c1e33 -m "(r15)"

### check status - adding notes seem to not affect it:

$ cd myrepo_git/
$ git status
# # On branch master
# nothing to commit (working directory clean)
$ cd ../

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# (r15)

### note is saved - now let's issue a `git log` command, using a format string and notes:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
# 77f3902: _user_: Sun Apr 21 18:29:00 2013 +0000:  >>test message 14<< (r14)
# ...
# 6886bbb: _user_: Sun Apr 21 17:11:52 2013 +0000:  >>initial test message 1<< (r1)

### test git log with range:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)

### erase notes - again must iterate through rev-list

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD remove $ih"; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# Removing note for object 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# git --git-dir=./myrepo_git/.git notes --ref linrev remove f34910dbeeee33a40806d29dd956062d6ab3ad97
# Removing note for object f34910dbeeee33a40806d29dd956062d6ab3ad97
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 04051f98ece25cff67e62d13c548dacbee6c1e33
# Removing note for object 04051f98ece25cff67e62d13c548dacbee6c1e33

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

Portanto, pelo menos no meu caso específico de histórico totalmente linear sem ramificações, os números de revisão parecem coincidir com essa abordagem - e, além disso, parece que essa abordagem permitirá o uso git logcom intervalos de revisão e, ao mesmo tempo, os números de revisão corretos - YMMV com um contexto diferente, embora ...

Espero que isso ajude alguém,
Saúde!


EDIT: Ok, aqui é um pouco mais fácil, com gitaliases para os loops acima, chamados setlinreve unsetlinrev; quando estiver na sua pasta de repositório git, faça ( observe o bashescape desagradável , consulte também # 16136745 - Adicione um alias do Git contendo um ponto-e-vírgula ):

cat >> .git/config <<"EOF"
[alias]
  setlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD add $ih -m \\\"(r\\$((++ix)))\\\"\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD\"; \n\
    done; \n\
    echo \"Linear revision notes are set.\" '"

  unsetlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD remove $ih\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD 2>/dev/null\"; \n\
    done; \n\
    echo \"Linear revision notes are unset.\" '"
EOF

... para que você possa simplesmente chamar git setlinrevantes de tentar fazer log envolvendo notas de revisão lineares; e git unsetlinrevexcluir essas anotações quando terminar; um exemplo de dentro do diretório git repo:

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

$ git setlinrev
Linear revision notes are set.
$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
$ git unsetlinrev
Linear revision notes are unset.

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

O tempo que o shell levaria para concluir esses aliases dependeria do tamanho do histórico do repositório.


2

Para pessoas que têm um processo de construção do Ant , você pode gerar um número de versão para um projeto no git com este destino:

<target name="generate-version">

    <exec executable="git" outputproperty="version.revisions">
        <arg value="log"/>
        <arg value="--oneline"/>
    </exec>

    <resourcecount property="version.revision" count="0" when="eq">
        <tokens>
            <concat>
                <filterchain>
                    <tokenfilter>
                        <stringtokenizer delims="\r" />
                    </tokenfilter>
                </filterchain>
            <propertyresource name="version.revisions" />
            </concat>
        </tokens>
    </resourcecount>
    <echo>Revision : ${version.revision}</echo>

    <exec executable="git" outputproperty="version.hash">
        <arg value="rev-parse"/>
        <arg value="--short"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Hash : ${version.hash}</echo>


    <exec executable="git" outputproperty="version.branch">
        <arg value="rev-parse"/>
        <arg value="--abbrev-ref"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Branch : ${version.branch}</echo>

    <exec executable="git" outputproperty="version.diff">
        <arg value="diff"/>
    </exec>

    <condition property="version.dirty" value="" else="-dirty">
        <equals arg1="${version.diff}" arg2=""/>
    </condition>

    <tstamp>
        <format property="version.date" pattern="yyyy-mm-dd.HH:mm:ss" locale="en,US"/>
    </tstamp>
    <echo>Date : ${version.date}</echo>

    <property name="version" value="${version.revision}.${version.hash}.${version.branch}${version.dirty}.${version.date}" />

    <echo>Version : ${version}</echo>

    <echo file="version.properties" append="false">version = ${version}</echo>

</target>

O resultado fica assim:

generate-version:
    [echo] Generate version
    [echo] Revision : 47
    [echo] Hash : 2af0b99
    [echo] Branch : master
    [echo] Date : 2015-04-20.15:04:03
    [echo] Version : 47.2af0b99.master-dirty.2015-04-20.15:04:03

O sinalizador sujo está aqui quando você possui arquivos não confirmados ao gerar o número da versão. Como geralmente, quando você constrói / empacota seu aplicativo, todas as modificações de código precisam estar no repositório.


1

Juntamente com o ID SHA-1 da confirmação, a data e a hora da hora do servidor teriam ajudado?

Algo assim:

a confirmação ocorreu às 11:30:25 em 19 de agosto de 2013 seria exibida como 6886bbb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025


1

No manual do Git, as tags são uma resposta brilhante para esse problema:

Criar uma tag anotada no Git é simples. A maneira mais fácil é especificar -a quando você executar o comando tag:

$ git tag -a v1.4 -m 'my version 1.4'

$ git tag
v0.1
v1.3
v1.4

Confira 2.6 Noções básicas do Git - Etiquetagem


Pena que você tem que pular os bastidores para alterar os padrões:By default, the git push command doesn’t transfer tags to remote servers.
MarkHu 8/16

1

Estamos usando este comando para obter versão e revisão do git:

git describe --always --tags --dirty

Retorna

  • confirmar hash como revisão quando nenhuma tag é usada (por exemplo gcc7b71f)
  • nome da tag como versão quando em uma tag (por exemplo v2.1.0, usada para liberações)
  • nome da tag, número da revisão desde a última tag e confirmar o hash depois de uma tag (por exemplo v5.3.0-88-gcc7b71f)
  • igual ao acima, além de uma tag "suja" se a árvore de trabalho tiver modificações locais (por exemplo v5.3.0-88-gcc7b71f-dirty)

Consulte também: https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt


0

Evento pós-compilação para o Visual Studio

echo  >RevisionNumber.cs static class Git { public static int RevisionNumber =
git  >>RevisionNumber.cs rev-list --count HEAD
echo >>RevisionNumber.cs ; }

-1

Considere usar

git-rev-label

Dá informações sobre a revisão do repositório Git em formato como master-c73-gabc6bec. Pode preencher uma string ou arquivo de modelo com variáveis ​​de ambiente e informações do Git. Útil para fornecer informações sobre a versão do programa: ramificação, etiqueta, hash de confirmação, contagem de confirmações, status sujo, data e hora. Uma das coisas mais úteis é a contagem de confirmações, sem levar em consideração as ramificações mescladas - apenas o primeiro pai.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.