34

我的“更新”挂钩有问题。在新分支的情况下,它会获得 00000000000000000000000000000000000000000 作为“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

4 回答 4

17

在这种情况下,“正确答案”一词有点含糊。实际上,我认为“从 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
于 2010-08-18T12:55:42.560 回答
13

$oldrev全为零时,git rev-list您需要一个不同的命令:

git rev-list $newrev --not --branches=*

将为您提供可从$newrev但不能从任何分支访问的修订列表。

请注意,这绝对不会git rev-list $oldrev..$newrevoldrev 不全为零时同样的事情,因此您需要检查您所处的情况并选择适当的命令来运行。

于 2013-11-02T01:54:05.820 回答
7

我只是自己想通了。

git log newref --not otherheads

是获取不在任何其他分支上的分支的所有日志的关键。下面是我的 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)
于 2011-03-23T16:22:52.103 回答
2

我使用以下方法为我的更新挂钩解决了这个问题:

if [ "$oldrev" -eq 0 ]; then
git log "$(git show-branch --merge-base)".."$newrev"; else
foo;
fi
于 2012-06-01T12:41:02.440 回答