2

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?

telotortium
  • 3,383
  • 2
  • 23
  • 25

3 Answers3

3

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 Doe@example.com"
    fi
fi
telotortium
  • 3,383
  • 2
  • 23
  • 25
1

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.

torek
  • 448,244
  • 59
  • 642
  • 775
0

The documentation says, for the normal git checkout case that the first two parameters are

The hook is given three parameters: the ref of the previous HEAD, the ref of the new HEAD (which may or may not have changed), ..."

But in a git clone case, obviously, there is no previous ref. So some sort of a "null" parameter must be given. In git, the "null ref" of all zeros is provided.

Mort
  • 3,379
  • 1
  • 25
  • 40