Subject: Re: [PATCH v2] checkout & worktree: introduce checkout.implicitRemote

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Fri, 04 May 2018 20:02:33 +0200

On Fri, May 04 2018, Duy Nguyen wrote:

> On Fri, May 4, 2018 at 9:54 AM, Ævar Arnfjörð Bjarmason
> <[email-masked]> wrote:
>> Realistically the way we do hooks now would make the UI of this suck,
>> i.e. you couldn't configure it globally or system-wide easily. Something
>> like what I noted in
>> https://public-inbox.org/git/[email-masked]/ would
>> make it suck less, but that's a much bigger task.
>
> I thought you would bring this up :) I've given some more thoughts on
> this topic and am willing to implement something like below, in a week
> or two. Would that help change your mind?
>
> I proposed hooks.* config space in that same thread. Here is the
> extension to make it cover both of your points.
>
> hooks.* can have multiple values. So you can specify
> hooks.post-checkout multiple times and all those scripts will run (in
> the same order you specified). Since we already have a search path for
> config (/etc/gitconfig -> $HOME/.gitconfig -> $REPO/config) this helps
> hooks management as well. Execution order is still the same: if you
> specify hooks.post-checkout in both /etc/gitconfig and .git/config,
> then the one in /etc/gitconfig is executed first, the one in .git
> second.
>
> And here's something extra to make it possible to override the search
> order: if you specify hooks.post-checkout = reset (reset is a random
> keyword) then _all_ post-checkout hooks before this point are ignored.
> So you can put this in .git/config
>
> [hooks]
>     post-checkout = reset
>     post-checkout = ~/some-hook
>
> and can be sure that post-checkout specified in $HOME and /etc will
> not affect you, only ~/some-hook will run. If you drop the second line
> then you have no post-checkout hooks. This is a workaround for a
> bigger problem (not being able to unset a config entry) but I think
> it's sufficient for this use case.

A few things:

 1) I don't see a reason to hold back this feature in particular waiting
    for some way to do it via config / hooks. If we grow some compatible
    way to do it via hooks in the future, great, then we can just make
    this (and numerous other config values) historical aliases for that
    facility.

 2) Let's not have some per-config type way to reset earlier config. I
    suggested a way to do it generally in
    https://public-inbox.org/git/[email-masked]/ I'm
    not saying we should go for that suggestion in particular, but that
    we should have something general.

 3) Doing #2 will take a lot longer to implement than what you're
    suggesting.

 4) I think such a facility should also be able to replace something
    like https://docs.gitlab.com/ee/administration/custom_hooks.html
    which requires not just supporting hooks from the config, but
    executing some hooks on the FS in glob() order.

 5) What you're describing above is just 1/2 of what we need to have a
    viable way to replace something like this checkout.implicitRemote
    with a hook while providing the same functionality to the end
    user.

    If something ships as a config value like checkout.implicitRemote
    users can just turn it on in their ~/.gitconfig without any further
    config, or you can tell users in docs via one-liner to enable it.

    We also need the other half which some method of shipping "standard"
    hooks with git, i.e. with your proposal something like (along with
    the general config reset):

        [config]
            reject = hooks.post-checkout
        [hooks]
            # Reads config from hooks.post-checkout-implicit-remote.*
            # (e.g. hooks.post-checkout-implicit-remote.remote = origin)
            post-checkout = git-hooks://post-checkout-implicit-remote-config

   Only then will this be as easy to enable as `git config --global..`
   (although you'll need two invocations of that, which is fine...)

 6) The feature being discussed here would not be a post-checkout hook,
    but would need to be fairly integrated with the internals of
    checkout, see `dwim_ok` and the big comment in
    parse_branchname_arg().

    I.e. the thing that makes this work is the Nth step in some fairly
    intricate fallback logic. It's not clear to me in the general case
    how we'd turn this into a hook without having N number of
    checkout-what-step-N-hooks, or requiring every checkout-what hook to
    implement a huge part of what checkout.c is doing now just to tweak
    some tiny aspect of it, such as this tweak of
    unique_tracking_name().