Git получает / обновляет хуки и новые ветки
У меня проблема с крючком "update". В случае новой ветки он получает 0000000000000000000000000000000000000000 как "oldrev". И я не знаю, как справиться с этим делом.
У нас есть требование, чтобы каждое сообщение о фиксации ссылалось на действительную проблему Jira. Поэтому я установил хук обновления в нашем центральном хранилище. Этот хук получает "oldrev" и "newrev". Затем я передаю их в "git rev-list" следующим образом:
git rev-list $oldrev..$newrev
Это дает мне список всех оборотов, которые я затем могу перебрать и сделать все, что мне нужно.
Проблема в том, что когда пользователь выдвигает новую ветвь, ловушка получает 0000000000000000000000000000000000000000 как oldrev. А "git rev-list" просто жалуется на:
fatal: Invalid revision range 0000000000000000000000000000000000000000..21bac83b2
Итак, как мне получить список всех оборотов, которые находятся в этой новой ветви? Я довольно долго искал в сети и ничего не нашел. Примеры хуков я нашел либо
- не справиться с проблемой и потерпеть неудачу с приведенным выше сообщением об ошибке
- неправильно попытаться решить проблему, установив oldrev на "", который возвращает неверные результаты из rev-list
- просто сдаваться, когда они сталкиваются с этим oldrev
Ничто из этого не звучит особенно захватывающе.
Так есть ли у кого-нибудь идеи, как получить правильный ответ в этом случае? Я думал о том, чтобы запросить git для "дайте мне все обороты, которые доступны из newrev, но не из любой другой ветви (= все ветви, кроме новой)". Но даже это дало бы неправильный ответ, если бы произошло слияние новой ветви с какой-либо из старых.
4 ответа
Термин "правильный ответ" в этом случае немного неоднозначен. Я на самом деле считаю, что "все обороты достижимы от newrev, но нигде больше" совершенно правильно. Это верно, даже если произошло слияние - в этом случае вы должны увидеть коммиты, уникальные для нового ref, и коммит слияния, но не коммиты, которые были объединены.
Итак, я бы сказал, проверьте, является ли "oldrev" все нули, и если это так, действуйте соответственно:
if [ "$oldrev" -eq 0 ]; then
# list everything reachable from newrev but not any heads
git rev-list $(git for-each-ref --format='%(refname)' refs/heads/* | sed 's/^/\^/') "$newrev"
else
git rev-list "$oldrev..$newrev"
fi
Когда $oldrev
это все нули, разные git rev-list
Команда делает все, что вам нужно:
git rev-list $newrev --not --branches=*
даст вам список ревизий, доступных с $newrev
но не из каких-либо веток.
Обратите внимание, что это определенно не делает то же самое, что git rev-list $oldrev..$newrev
когда oldrev не все нули, вам нужно проверить, в каком случае вы находитесь, и выбрать подходящую команду для запуска.
Я просто понял это сам.
git log newref - не другие
является ключом для получения всех журналов ветви, которые не находятся ни в одной другой ветви. Ниже приведен мой скрипт на python для проверки правильности максимальной длины строки сообщений коммита.
import sys
import commands
ref = sys.argv[1]
old = sys.argv[2]
new = sys.argv[3]
x = 0
# only a tag is pushed to server, nothing to check
if ref.find('refs/tags/') >= 0:
if len(ref.strip('refs/tags/')) > 25:
print 'tag name is longer than 25 characters'
exit(1)
else:
exit(0)
# either a new branch is pushed or an empty repo is being pushed
if old == '0000000000000000000000000000000000000000':
heads = commands.getoutput("git for-each-ref --format='%(refname)' 'refs/heads/*'")
heads = heads.replace(ref+'\n','').replace('\n',' ')
hashes = commands.getoutput('git log '+new+' --pretty=%H --not '+heads).split('\n')
else:
hashes = commands.getoutput('git log '+old+'..'+new+' --pretty=%H').split('\n')
for hash in hashes:
subject = commands.getoutput('git show '+hash+' --format=%s --summary').split('\n')
body = commands.getoutput('git show '+hash+' --format=%b --summary').split('\n')
if len(subject[0]) > 75:
print
print 'commit: '+hash
print 'bad commit message(s): header line is too long or second line is not blank (max 75 chars)'
print 'bad line: "%s"' % subject[0]
print 'length of header line: %d' % len(subject[0])
print 'try again with correct message format'
print
x = 1
for line in body:
if len(line) > 75:
print
print 'commit: '+hash
print 'bad commit message(s): description lines are too long (max 75 chars)'
print 'bad line: "%s"' % line
print 'length of line: %d' % len(line)
print 'try again with correct message format'
print
x = 1
if x == 0:
exit(0)
else:
exit(1)
Я решил это для моего крюка обновления, используя следующее:
if [ "$oldrev" -eq 0 ]; then
git log "$(git show-branch --merge-base)".."$newrev"; else
foo;
fi