Je voudrais juste noter une autre approche possible - et c'est en utilisant git
git-notes (1) , existant depuis la v 1.6.6 ( Note to Self - Git ) (j'utilise la git
version 1.7.9.5).
Fondamentalement, j'avais l'habitude git svn
de cloner un référentiel SVN avec un historique linéaire (pas de disposition standard, pas de branches, pas de balises), et je voulais comparer les numéros de révision dans le git
référentiel cloné . Ce clone git n'a pas de balises par défaut, donc je ne peux pas l'utiliser git describe
. La stratégie ici ne fonctionnerait probablement que pour l'histoire linéaire - je ne sais pas comment cela se passerait avec les fusions, etc .; mais voici la stratégie de base:
- Demander la
git rev-list
liste de tous les historiques de commit
- Puisqu'il
rev-list
est par défaut dans "l'ordre chronologique inverse", nous utiliserions son --reverse
commutateur pour obtenir la liste des validations triées par les plus anciennes en premier
- Utilisez
bash
shell pour
- augmenter une variable de compteur à chaque validation comme compteur de révision,
- générer et ajouter une note git "temporaire" pour chaque commit
- Ensuite, parcourez le journal en utilisant
git log
avec --notes
, qui videra également une note de commit, qui dans ce cas serait le "numéro de révision"
- Une fois terminé, effacez les notes temporaires ( NB: je ne sais pas si ces notes sont validées ou non; elles n'apparaissent pas vraiment
git status
)
Tout d'abord, notons qu'il git
a un emplacement par défaut des notes - mais vous pouvez également spécifier une ref
(érence) pour les notes - qui les stockerait dans un répertoire différent sous .git
; par exemple, dans un git
dossier repo, vous pouvez appeler git notes get-ref
pour voir de quel répertoire il s'agit:
$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever
La chose à noter est que si vous avez notes add
un --ref
, vous devez également utiliser à nouveau cette référence - sinon vous pouvez obtenir des erreurs comme " Aucune note trouvée pour l'objet XXX ... ".
Pour cet exemple, j'ai choisi d'appeler la ref
note "linrev" (pour la révision linéaire) - cela signifie également qu'il est peu probable que la procédure interfère avec les notes déjà existantes. J'utilise également le --git-dir
commutateur, car étant un git
débutant, j'ai eu quelques problèmes à le comprendre - je voudrais donc "me souvenir de plus tard" :)
; et j'utilise également --no-pager
pour supprimer le frai less
lors de l'utilisation git log
.
Donc, en supposant que vous êtes dans un répertoire, avec un sous-dossier myrepo_git
qui est un git
référentiel; on pourrait faire:
### 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.
Donc, au moins dans mon cas spécifique d'historique entièrement linéaire sans branches, les numéros de révision semblent correspondre à cette approche - et en outre, il semble que cette approche permettra d'utiliser git log
avec des plages de révision, tout en obtenant les bons numéros de révision - YMMV avec un contexte différent, cependant ...
J'espère que cela aide quelqu'un,
Cheers!
EDIT: Ok, ici c'est un peu plus facile, avec des git
alias pour les boucles ci-dessus, appelées setlinrev
et unsetlinrev
; lorsque dans votre dossier de dépôt git, faites ( Notez l' bash
échappement méchant , voir aussi # 16136745 - Ajoutez un alias Git contenant un point-virgule ):
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
... afin que vous puissiez simplement l'invoquer git setlinrev
avant d'essayer de créer un journal impliquant des notes de révision linéaires; et git unsetlinrev
pour supprimer ces notes lorsque vous avez terminé; un exemple à l'intérieur du répertoire 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 <<
Le temps qu'il faudrait au shell pour terminer ces alias dépendrait de la taille de l'historique du référentiel.