Я просто хотел бы отметить другой возможный подход - это использование git
git-notes (1) , существующего с версии 1.6.6 ( Примечание для Self -Git ) (я использую git
версия 1.7.9.5).
По сути, я использовал git svn
для клонирования SVN-репозитория с линейной историей (без стандартной компоновки, без ветвей, без тегов), и я хотел сравнить номера ревизий в клонированном репозитории git
.Этот git-клон не имеет тегов по умолчанию, поэтому я не могу использовать git describe
.Стратегия здесь, вероятно, будет работать только для линейной истории - не знаю, как это получится с объединениями и т. Д .;но вот основная стратегия:
- Запросить
git rev-list
список всей истории изменений - Поскольку
rev-list
по умолчанию в «обратном хронологическом порядке», мы будем использоватьего переключатель --reverse
для получения списка коммитов, отсортированных по старым первым
- Использование оболочки
bash
для - увеличения переменной счетчика для каждого коммита в качестве счетчика ревизий,
- сгенерируйте и добавьте «временную» заметку git для каждого коммита
- Затем просмотрите журнал, используя
git log
с --notes
, который также выведет дамппримечание коммита, которое в данном случае будет «номером ревизии» - Когда закончите, удалите временные заметки ( Примечание: я не уверен, зафиксированы ли эти заметки или нет;действительно показывать в
git status
)
Во-первых, давайте заметим, что git
имеет расположение заметок по умолчанию - но вы также можете указать ref
(erence) для заметок - чтобудет хранить их в другом каталоге под .git
;например, находясь в папке репо git
, вы можете позвонить по номеру git notes get-ref
и узнать, какой это будет каталог:
$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever
Следует отметить, что если вы notes add
с --ref
, вы также должны впоследствии использовать эту ссылку снова - в противном случае вы можете получить ошибки типа " Примечание не найдено для объекта XXX ... ".
Для этого примера я выбралНазовите ref
примечаний "linrev" (для линейного пересмотра) - это также означает, что маловероятно, что процедура будет мешать уже существующим примечаниям.Я также использую переключатель --git-dir
, так как я был новичком git
, у меня были некоторые проблемы с его пониманием - поэтому я хотел бы "запомнить на потом" :)
;и я также использую --no-pager
для подавления нереста less
при использовании git log
.
Итак, если вы находитесь в каталоге, с подпапкой myrepo_git
, которая является репозиторием git
;можно сделать:
### 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.
Так что, по крайней мере, в моем конкретном случае полностью линейной истории без ветвей номера ревизий, кажется, соответствуют этому подходу - и, кроме того, кажется, что этот подход позволит использоватьgit log
с диапазонами ревизий, при этом получая правильные номера ревизий - YMMV с другим контекстом, хотя ...
Надеюсь, это кому-нибудь поможет,
Приветствия!
РЕДАКТИРОВАТЬ: Хорошо, здесь это немного проще, с псевдонимами git
для вышеуказанных циклов, называемых setlinrev
и unsetlinrev
;в папке git-репозитория выполните ( Обратите внимание на неприятные bash
экранирования, см. также # 16136745 - Добавьте псевдоним Git, содержащий точку с запятой ):
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
... так что вы можете просто вызвать git setlinrev
, прежде чем пытаться вести журнал, включающий линейные заметки о ревизиях;и git unsetlinrev
чтобы удалить эти заметки, когда вы закончите;пример из каталога 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 <<
Время, которое потребуется оболочке для завершения этих псевдонимов, будет зависеть от размера истории хранилища.