Search code examples
bashgitshellgit-worktree

How to run a git hook only when running git worktree add command


I am wanting to run a shell script when I invoke the command git worktree add. Reading the docs for post-checkout seems like it would run for git worktree add but it would also run for other commands which I don't want to use it for, such as git checkout.

Is there any other hook I could use? Or perhaps I could use post checkout but have the script setup so it exits if it isn't the git worktree add command?

The reason I want to do this is to run a set of commands to set up my directory that is required when I run git worktree add, but I wouldn't need to do this setup for a normal git repository that is just using git checkout commands.


Solution

  • I have come up with a solution, though I am not sure how rebust it is. I use the post-checkout hook as a bash script, and I have the following lines at the top.

    if ! [[ "$0" =~ ".bare/hooks/post-checkout" ]] \
        || ! [[ "$1" == "0000000000000000000000000000000000000000" ]]; then
        echo "WARNING: post-checkout hook running for reason otherwise than git worktree add, bailing";
        exit 0;
    fi
    
    # Do something down here every time we run `git worktree add`
    

    How this works: $0 is the path of the script and $1 is the reference of the previous head.

    By convention I have been cloning my bare repository into a directory called .bare which is what the first statement is checking. The second statement is checking that the previous ref of HEAD is that string of 0s. This catches and exits if you are just using other checkout commands such as git checkout because in that case the previous HEAD is not the string of 0s because it was pointing to a commit. However, it seems that because I create a new HEAD every time we run git worktree add it sets the previous HEAD ref to that string of 0s, which allows me to assert on that condition.

    This does work for my use case so I am not sure if there is a better way or not. If anyone has a better suggestion then let me know.

    P.S. I can get the directory of the new branch simply using pwd in my post-checkout script, which is useful for the commands that I want to run in the hook.