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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3511057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 04:30:08  来源:igfitidea点击:

Git receive/update hooks and new branches

gitgit-pushgithooks

提问by marc.guenther

I have a problem with the 'update' hook. In the case of a new branch, it gets a 0000000000000000000000000000000000000000 as the 'oldrev'. And I don't know how to handle that case.

我的“更新”挂钩有问题。在新分支的情况下,它获得 000000000000000000000000000000000000000 作为“oldrev”。我不知道如何处理这种情况。

We have the requirement, that every commit message references a valid Jira issue. So I have installed an "update" hook on our central repository. That hook gets an "oldrev" and a "newrev". I then pass those to "git rev-list" like this:

我们要求每条提交消息都引用一个有效的 Jira 问题。所以我在我们的中央存储库上安装了一个“更新”钩子。这个钩子得到一个“oldrev”和一个“newrev”。然后我将它们传递给“git rev-list”,如下所示:

git rev-list $oldrev..$newrev

git rev-list $oldrev..$newrev

This gives me the list of all revs, which I can then iterate through, and do whatever I need to do.

这给了我所有转速的列表,然后我可以遍历它,并做我需要做的任何事情。

The problem is, when the user pushes a new branch, the hook gets 0000000000000000000000000000000000000000 as the oldrev. And "git rev-list" simply complains with:

问题是,当用户推送一个新分支时,钩子得到 0000000000000000000000000000000000000000 作为旧版本。而“git rev-list”只是抱怨:

fatal: Invalid revision range 0000000000000000000000000000000000000000..21bac83b2

fatal: Invalid revision range 0000000000000000000000000000000000000000..21bac83b2

So how do I get the list of all the revs that are on that new branch? I have searched the net for quite some time now, and found nothing. The example hooks I found either

那么我如何获得该新分支上所有转速的列表?我已经在网上搜索了一段时间,但一无所获。我找到的示例钩子

  • don't handle the problem, and fail with the above error message
  • incorrectly try to fix the problem by setting the oldrev to "", which returns the wrong results from rev-list
  • simply give up when they encounter that oldrev
  • 不处理问题,失败并出现上述错误信息
  • 错误地尝试通过将 oldrev 设置为 "" 来解决问题,这会从 rev-list 返回错误的结果
  • 当他们遇到那个oldrev时干脆放弃

None of these sound particularly exciting.

这些听起来都不是特别令人兴奋。

So does someone have any idea how to get the right answer in that case? I was thinking about querying git for "give me all revs that are reachable from newrev, but not from any of the other branches (=all branches except the new one)". But even that would give the wrong answer if there had been a merge from the new branch to any of the old ones.

那么有人知道如何在这种情况下获得正确答案吗?我正在考虑向 git 查询“给我所有可从 newrev 访问的转速,但不能从任何其他分支(=除新分支以外的所有分支)”。但是,如果从新分支合并到任何旧分支,即使这样也会给出错误的答案。

采纳答案by Cascabel

The term "right answer" is a bit ambiguous in this case. I actually think that "all revs reachable from newrev but nowhere else" is completely correct. This is true even if there was a merge - in that case, you should see the commits unique to the new ref, and the merge commit, but not the commits that were merged.

在这种情况下,“正确答案”一词有点含糊不清。我实际上认为“所有 revs 都可以从 newrev 到达,但在其他任何地方都没有”是完全正确的。即使有合并也是如此 - 在这种情况下,您应该看到新引用独有的提交和合并提交,但不是合并的提交。

So, I would say, check if the "oldrev" is all zeroes, and if it is, act accordingly:

所以,我会说,检查“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

回答by Joseph

When $oldrevis all zeros, a different git rev-listcommand does all you need:

$oldrev全为零时,一个不同的git rev-list命令可以满足您的所有需求:

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

will give you a list of revisions reachable from $newrevbut not from any branches.

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

Note that this definitely does notdo the same thing as git rev-list $oldrev..$newrevwhen oldrev is notall zeros, so you'll want to check which case you're in and pick the appropriate command to run.

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

回答by mattmilten

I just figured it out myself.

我只是自己想出来的。

git log newref --not otherheads

git log newref --not otherheads

is the key to get all logs of a branch that are not on any other branch. Below is my python script to check for the correct maximum line length of the commit messages.

是获取不在任何其他分支上的分支的所有日志的关键。下面是我的 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)

回答by bender bending rodriguez

I solved this for my update hook using the following:

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

if [ "$oldrev" -eq 0 ]; then
git log "$(git show-branch --merge-base)".."$newrev"; else
foo;
fi