Git receive/update hooks and new branches

前端 未结 4 830
一生所求
一生所求 2020-12-05 17:28

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

相关标签:
4条回答
  • 2020-12-05 17:54

    When $oldrev is all zeros, a different git rev-list command does all you need:

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

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

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

    0 讨论(0)
  • 2020-12-05 17:56

    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
    
    0 讨论(0)
  • 2020-12-05 18:04

    I just figured it out myself.

    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.

    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)
    
    0 讨论(0)
  • 2020-12-05 18:17

    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.

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

    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
    
    0 讨论(0)
提交回复
热议问题