Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

githooks(5): what is the Git "null-ref"

Tags:

git

githooks

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?

like image 562
telotortium Avatar asked Nov 29 '25 01:11

telotortium


2 Answers

It is the commit ID consisting of all zeros.

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.
# for sed trick see torek's answer
if [[ "$1" = "$(git rev-parse HEAD | sed s/./0/g)" ]]; 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
like image 97
telotortium Avatar answered Dec 01 '25 16:12

telotortium


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.

like image 31
torek Avatar answered Dec 01 '25 15:12

torek