Re: [PATCH v2 0/4] worktree: add lifecycle hooks

Junio C Hamano <[email protected]> Tue, 04 Aug 2026 13:28:23 -0700
Newsgroups org.kernel.vger.git
Message-ID <[email protected]>
Caleb White <[email protected]> writes:

> On Tue Aug 4, 2026 at 1:14 PM CDT, Domen Kožar wrote:
>> Hi everyone,
>>
>> First, apologies that my earlier reply reached the list as a separate
>> message rather than as part of this thread. This is my first patch series
>> submitted by email, and I am still getting the threading details right. I
>> have made sure this reroll is plain text and correctly threaded.
>>
>> Thanks,
>> Domen
>
> Hi Domen,
>
> I love the idea of having hooks for worktrees, especially now that
> they are becoming more popular for having agents work on tasks in
> parallel.

Before going there, we need to consider if these hooks are necessary
in the first place.  If you _always_ want to perform something
before or after running "git worktree add" or "git worktree remove",
you can instruct your agents to use "git wt" script when they want
to run "git worktree", and install a "git-wt" script on their $PATH,
which essentially would be something like

	#!/bin/sh
	# git worktree [add/remove] ...
	case "$1" in
	add)
		... do whatever you want to do before add ...
		;;
	remove)
		... do whatever you want to do before remove ...
		;;
	esac

	git worktree "$@"

	case "$1" in
	add)
		... do whatever you want to do after add ...
		;;
	remove)
		... do whatever you want to do after remove ...
		;;
	esac

The users would need to write the "... do whatever you want to do"
part as the hook script _anyway_, and unless there are compelling
reason why these _must_ be implemented as hooks, you should resist
the temptation to pile more hooks on the system.

Having said all that.

There are five valid reasons you might still want to have a hook in
a Git command or operation:

 (1) A hook that countermands the normal decision made by the
     underlying command.  Examples of this class are the 'update'
     hook and the 'pre-commit' hook.

 (2) A hook that operates on data generated after the command starts
     to run.  The ability to munge the commit log message via the
     'commit-msg' hook is an example.  You cannot easily prepare
     what the 'commit-msg' hook may produce before you run
     'git commit'.

 (3) A hook that operates on the remote end of the connection that
     you may not otherwise have access to, other than over the Git
     protocol.  An example is the 'post-update' hook that runs
     update-server-info().

 (4) A hook that runs under a lock acquired by the command for
     mutual exclusion.  Currently there is no example, but if we
     allowed the 'update' hook to modify the commit that was pushed
     through a send-pack and receive-pack pair (which was discussed on
     the list a while ago), it would be a good example of this.

 (5) A hook that is run differently depending on the outcome of the
     command.  The 'post-merge' hook conditionally run by 'git pull' is
     an example of this (it is not run if no merge takes place).
     Another example is the 'post-checkout' hook that gets
     information that is otherwise harder to get (namely, whether it
     was a branch checkout or a file checkout -- you can figure it
     out by examining the command line, but that is already part of the
     processing 'git checkout' does anyway, so there is no need to
     force duplication of that code in userland).

If you cannot do an equivalent operation from outside the Git command
for the above classes of operations, you need hooks for them.

On the other hand, if you want to always trigger an action before or
after running a Git operation locally, you do not need a hook.  This
is true even if the action you perform after running a Git operation
depends on what happened (class (5) above), provided the result is
easily observable after the fact.

Of course, one very valid exception to the above policy is when an
action is common enough that the policy effectively forces everyone
to reinvent the same wrapper.  We may be better off adding it as an
officially supported hook in such a case.

But for the hooks proposed in this topic, I do not think such an
exception applies.

Thanks.