Git接收/更新挂钩和新分支

mar*_*her 31 git git-push githooks

我有'更新'钩子的问题.在新分支的情况下,它获得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到达的转,但不能从任何其他分支(=除了新分支之外的所有分支)".但是,如果从新分支到任何旧分支的合并,即使这样也会给出错误的答案.

Cas*_*bel 16

在这种情况下,术语"正确答案"有点模棱两可.我实际上认为"所有转速都可以从newrev到达而不是其他地方"是完全正确的.即使存在合并也是如此 - 在这种情况下,您应该看到新引用的唯一提交和合并提交,而不是合并的提交.

所以,我想说,检查"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
Run Code Online (Sandbox Code Playgroud)

  • 我不确定我的环境或git的更新是否有些奇怪,但是否定就是删除当前分支上的refs.我必须做这样的事情:`git rev-list $(git for-each-ref --format ='%(refname)'"refs/heads/*"| grep -v'$ ref'| sed 's/^ /\^ /')"$ newrev"` (2认同)

小智 12

什么时候$oldrev全零,git rev-list你需要一个不同的命令:

git rev-list $newrev --not --branches=*
Run Code Online (Sandbox Code Playgroud)

将为您提供可$newrev从任何分支机构到达但不可从任何分支机构获得的修订列表.

请注意,这绝对不会这样做同样的事情,git rev-list $oldrev..$newrev当OLDREV是不是全部为零,所以你要检查你是这种情况,并选择适当的命令来运行.

  • 虽然实际上这确实有用_in预接收和更新hooks_因为当这些钩子运行时,新的分支还没有!太好了! (2认同)

mat*_*ten 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)
Run Code Online (Sandbox Code Playgroud)