Solo me gustaría señalar otro enfoque posible, y eso es mediante el uso de git
git-notes (1) , existente desde v 1.6.6 ( Note to Self - Git ) (estoy usando la git
versión 1.7.9.5).
Básicamente, solía git svn
clonar un repositorio SVN con historial lineal (sin diseño estándar, sin ramas, sin etiquetas), y quería comparar los números de revisión en el git
repositorio clonado . Este clon de git no tiene etiquetas por defecto, por lo que no puedo usarlo git describe
. La estrategia aquí probablemente funcionaría solo para la historia lineal, no estoy seguro de cómo resultaría con fusiones, etc .; Pero aquí está la estrategia básica:
- Solicite
git rev-list
una lista de todos los historiales de confirmación
- Como
rev-list
está por defecto en "orden cronológico inverso", usaríamos su --reverse
interruptor para obtener la lista de confirmaciones ordenadas por las más antiguas primero
- Use
bash
shell para
- aumentar una variable de contador en cada confirmación como un contador de revisión,
- generar y agregar una nota git "temporal" para cada confirmación
- Luego, explore el registro usando
git log
with --notes
, que también volcará una nota de confirmación, que en este caso sería el "número de revisión"
- Cuando termine, borre las notas temporales ( Nota: no estoy seguro de si estas notas están confirmadas o no; en realidad no se muestran
git status
)
Primero, observemos que git
tiene una ubicación predeterminada de notas, pero también puede especificar una ref
(diferencia) para las notas, que las almacenaría en un directorio diferente en .git
; por ejemplo, mientras está en una git
carpeta de repositorio, puede llamar git notes get-ref
para ver qué directorio será:
$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever
Lo que debe tenerse en cuenta es que si notes add
tiene un --ref
, también debe usar esa referencia nuevamente; de lo contrario, puede obtener errores como " No se encontró nota para el objeto XXX ... ".
Para este ejemplo, he elegido llamar a las ref
notas "linrev" (para revisión lineal); esto también significa que no es probable que el procedimiento interfiera con las notas ya existentes. También estoy usando el --git-dir
interruptor, ya que siendo un git
novato, tuve algunos problemas para entenderlo, así que me gustaría "recordar para más adelante" :)
; y también uso --no-pager
para suprimir el desove less
cuando lo uso git log
.
Entonces, suponiendo que esté en un directorio, con una subcarpeta myrepo_git
que es un git
repositorio; uno podría hacer:
### 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.
Entonces, al menos en mi caso específico de historia completamente lineal sin ramificaciones, los números de revisión parecen coincidir con este enfoque, y además, parece que este enfoque permitirá usar git log
con rangos de revisión, mientras sigue obteniendo los números de revisión correctos: YMMV con un contexto diferente, aunque ...
Espero que esto ayude a alguien,
¡salud!
EDITAR: Ok, aquí es un poco más fácil, con git
alias para los bucles anteriores, llamado setlinrev
y unsetlinrev
; cuando esté en su carpeta de repositorio de git, haga ( Note el desagradable bash
escape, vea también # 16136745 - Agregue un alias de Git que contenga un punto y coma ):
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 pueda simplemente invocar git setlinrev
antes de intentar hacer un registro con notas de revisión lineal; y git unsetlinrev
para eliminar esas notas cuando haya terminado; un ejemplo desde dentro del directorio 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 <<
El tiempo que le llevaría al shell completar estos alias dependería del tamaño del historial del repositorio.