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 git
versão 1.7.9.5).
Basicamente, eu costumava git svn
clonar 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 git
repositó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-list
uma lista de todo o histórico de consolidação
- Como,
rev-list
por padrão, está em "ordem cronológica reversa", usaríamos sua --reverse
opção para obter a lista de confirmações ordenadas pela mais antiga primeiro
- Use
bash
shell 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 log
with --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 aparecem
git status
)
Primeiro, vamos observar que git
possui 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 git
pasta de repo, você pode ligar git notes get-ref
para 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 add
com 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 ref
notas 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-dir
switch, desde que git
eu era novato, tive alguns problemas para entendê-lo - então eu gostaria de "lembrar para mais tarde" :)
; e eu também uso --no-pager
para suprimir a desova less
ao usar git log
.
Então, supondo que você esteja em um diretório, com uma subpasta myrepo_git
que seja um git
repositó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 log
com 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 git
aliases para os loops acima, chamados setlinrev
e unsetlinrev
; quando estiver na sua pasta de repositório git, faça ( observe o bash
escape 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 setlinrev
antes de tentar fazer log envolvendo notas de revisão lineares; e git unsetlinrev
excluir 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.