Как показать git commit с использованием количества коммитов с тега
С git describe
вы можете получить количество коммитов со времени последнего тега. Если у вас был только тег и количество коммитов, что лучше всего показать описанную коммит?
Я знаю, что вы могли бы использовать git log tag..
и передать его в script, который делает подсчет, но я надеялся на более элегантное решение, подобное git show tag~n
.
Чтобы добавить больше контекста, мы планируем использовать git describe
для создания номеров релизов, например, с помощью
$ git describe
v1.5-39-g5ede964
мы будем использовать foo_1.5.39. То, что мы хотели бы сделать, это знать, что 1.5.39 означает 39-ю фиксацию после тега v1.5, найдите это commit, т.е. Найдите g5ede964. Как отмечено в комментарии, 39-я фиксация после версии 1.5 может быть не уникальной. Поэтому, возможно, лучший способ спросить об этом - это лучший способ найти все коммиты X, которые, если бы HEAD указывал на X git describe
, вернулись бы
v1.5-39-*****
.
Ответы
Ответ 1
То, о чем вы просите, невозможно в общем случае. Количество коммитов не может ничего вам сказать, если в вашей истории есть какие-либо слияния.
Например, учитывая следующую структуру репо:
a - b - c - d - h
\ /
e - f - g
С тегом, помещенным в a
, выходы git describe d
и git describe g
идентичны, кроме SHA1:
> git describe d
tag-3-ge8dca33
> git describe g
tag-3-g4fecc2e
Тем не менее, если у вас нет параллельных ветвей, идущих сразу, то вы можете разрешить данный номер фиксации обратно на один фиксатор, но если у вас есть хотя бы одна активная боковая ветвь на время вашего тега, тогда это может не сработать.
Если вам нужны надежные номера релизов, вы должны придерживаться явных тегов.
Ответ 2
Try
git rev-list tag..HEAD --count
ИЛИ
git rev-list tag.. --count
Они означают одно и то же.
Ответ 3
Если вы ищете количество коммитов со времени последнего тега, для меня работало следующее
git rev-list `git rev-list --tags --no-walk --max-count=1`..HEAD --count
Ответ 4
Вы можете:
git log --oneline tag.. | wc -l
это даст вам количество коммитов
Ответ 5
Как ответ Кевина объяснил, это вообще невозможно. Для решения проблемы в особых случаях он упомянул:
Тем не менее, если у вас нет параллельных ветвей, идущих сразу, то вы можете разрешить данный номер фиксации обратно на один фиксатор, но если у вас есть хотя бы одна активная боковая ветвь на время вашего тега, тогда это может не сработать.
вы можете использовать следующую команду (с n
- количество коммитов со времени тега)
git rev-list tag..HEAD --reverse | awk NR==n
Ответ 6
что лучший способ найти все коммиты X такие, что если HEAD
указывал на X git describe
, он возвращал бы v1.5-39-*****
все еще не тот вопрос. Правильный вопрос:
как найти все коммиты X такие, что если HEAD указывал на X, обычный git describe
мог когда-либо возвращаться v1.5-39-*****
и не все так легко ответить на это. Тем не менее, при отсутствии действия врага эта процедура будет перечислять правильную фиксацию, возможно, среди некоторых других возможностей:
ancestor=v1.5 n=39
git rev-list --all --reverse --topo-order --parents --ancestry-path ^$ancestor \
| awk ' function minmore( i) {
for ( i=2; i <= NF; ++i )
if ( gen[$i] > gen[$1] )
gen[$1]=gen[$i]
return ++gen[$1]
}
minmore()<=n {
print "[[ $(git rev-list --count "ancestor".."$1") == "n" ]] &&"
print " git describe --match="ancestor" "$1 }
' ancestor=$ancestor n=$n \
# | sh # lose the first `#` here to actually run the generated checks
Причина неопределенности и сложности заключается в том, что git describe
просто пытается получить разумную базу, поэтому (см. ее документы) он выберет самые последние из ближайших текущих тегов, которые он может увидеть, и посчитайте, сколько дополнительных коммитов есть в описанной истории, и создайте прозвище таким образом. Например, новые теги могут изменить свою предпочтительную базу так, что голый git describe
больше не будет генерировать этот прозвище; и хотя SHA неизменяемы, ссылки могут быть переписаны.