How to get a list of incoming commits on git push for a new branch in a hook

后端 未结 3 1475
北恋
北恋 2021-02-03 13:12

I\'m writing a pre-receive hook to do some validation before accepting commits on the push. It works fine with existing branches since I use following git command to get a list

相关标签:
3条回答
  • 2021-02-03 13:41

    The following helped in my case. I personally think it's very simple.

    OLD_REV=$2
    NEW_REV=$3
    
    if [ $OLD_REV == "0000000000000000000000000000000000000000" ]; then
        OLD_REV=$(git merge-base master $NEW_REV)
    fi;
    
    git diff --name-only $OLD_REV $NEW_REV
    
    0 讨论(0)
  • 2021-02-03 13:53

    More simply, you can use this:

    git rev-list $new_sha1 --not --all
    

    It's quite the same principle as in Aristotle Pagaltzis' answer, but it just uses rev-list's built-in options (which I guess were added after this question was answered...).
    The --all parameter is equivalent to the for-each-ref part: it adds all known refs to the command args. The --not parameter, in this particular case, is like adding the ^ prefix to all refs added by --all.
    Thus this command will print commits reachable from the new SHA1 except all those reachable from the known (i.e. already pushed) refs.

    0 讨论(0)
  • 2021-02-03 13:57

    Try this:

    git rev-list $new_sha1 $(git for-each-ref --format '^%(refname:short)' refs/heads/)
    

    This uses git for-each-ref to print known refs; specifies in --format that the short name be output along with a preceding caret; and says with refs/heads/ to selecting just local heads. You end up running something like this:

    git rev-list $new_sha1 ^master ^foo ^bar ^baz
    

    The caret means “exclude commits reachable from here”. So this will give you all commits that are reachable from $new_sha1, but aren’t from any of the existing refs.

    To handle the new-ref and existing-ref cases at once, you can use bash’s array support:

    if ! [ $old_sha1 = 0000000000000000000000000000000000000000 ] ; then
        excludes=( ^$old_sha1 )
    else
        excludes=( $(git for-each-ref --format '^%(refname:short)' refs/heads/) )
    fi
    
    git rev-list $new_sha1 "${excludes[@]}"
    
    0 讨论(0)
提交回复
热议问题