Home > Back-end >  githooks(5): what is the Git "null-ref"
githooks(5): what is the Git "null-ref"

Time:07-17

On the documentation for the post-checkout hook, it says

It is also run after git-clone[1], unless the --no-checkout (-n) option is used. The first parameter given to the hook is the null-ref, the second the ref of the new HEAD and the flag is always 1. Likewise for git worktree add unless --no-checkout is used.

What does the "null-ref" refer to here?

CodePudding user response:

I added the following line to ~/.config/git/template/hooks/post-checkout:

echo "post-checkout" "$@" 1>&2

and then cloned a new repository, getting the following output:

post-checkout 0000000000000000000000000000000000000000 4abcac4ddfb69f6dfde1af0164f2f0ee0e230336 1

So it looks like the "null-ref" in the post-checkout script is 0000000000000000000000000000000000000000.

The context behind this question is that I want to set a special per-repo Git config user.email value only when I clone repositories from my work's Gitlab server. Now I can put the following in the post-checkout script to change it:

# This value of `$1` is the null-ref from githooks(5) - see
# https://stackoverflow.com/a/73000183/207384.
if [[ "$1" = "0000000000000000000000000000000000000000" ]]; then
    # Set user.email specially for work repositories.
    if [[ "$(git config remote."$(git config branch."$(git branch --show-current)".remote)".url)" =~ "gitlab.example.com" ]]; then
        git config user.name "John Doe"
        git config user.email "John [email protected]"
    fi
fi

CodePudding user response:

This documentation probably ought to be updated a bit as the word null-ref is misleading, but you're correct that it is an all-zeros hash ID. Git uses the phrase "null oid" elsewhere, especially internally with a function is_null_oid. Since "OID" is an acronym it's usually upper-cased in English text, and "null" sometimes comes along for the ride: see, e.g., the 2.18 Release Notes, vs the git cat-file documentation where it's spelled "null OID".

I personally think git rev-parse should have an option for spitting this out (along with the hash ID of the empty tree), since SHA-256 OIDs are 64 bytes long instead of 40 bytes long. However, as a stopgap measure, one can use:

null_oid=$(git rev-parse HEAD | sed s/./0/g)

or, taking the hash-object trick a bit further:

empty_tree=$(git hash-object -t tree --stdin </dev/null)
null_oid=$(echo $empty_tree | sed s/./0/g)

which gets you both and will continue to work in some future Git that has longer OIDs.

  • Related