Search code examples
gitgit-submodules

custom command in git submodule.<name>.update


I am trying to add a custom command to the .gitmodule file. According to documentation:

arbitrary shell command that takes a single argument (the sha1 of the commit recorded in the superproject) is executed. When submodule.<name>.update is set to !command, the remainder after the exclamation mark is the custom command.

I tried something like the following:

[submodule "mysub"]
    path = mysub
    url = mysub-url
    branch = a-branch
    update = !ls   <<  a custom command is here

Moreover, the code in submodule-config.c contains this:

    } else if (!strcmp(item.buf, "update")) {
        if (!value)
            ret = config_error_nonbool(var);
        else if (!me->overwrite &&
             submodule->update_strategy.type != SM_UPDATE_UNSPECIFIED)
            warn_multiple_config(me->treeish_name, submodule->name,
                         "update");
        else if (parse_submodule_update_strategy(value,
             &submodule->update_strategy) < 0 ||
             submodule->update_strategy.type == SM_UPDATE_COMMAND)  //<<< bummer! is it supposed to be
            die(_("invalid value for %s"), var);
    }

However, all attempts to do so end up in: fatal: invalid value for submodule...

So, any idea what is going on with custom commands in submodule updates? Is it just an oversight which had never been tested? Am I missing something?

I use git 2.26.0


Solution

  • after some digging I now think that this behavior was intentional, but it had not been reflected in documentation nor in the error message.

    As a matter of fact, it works if configured in .git/config.

    The reasoning could be: "passing around pointers to a custom command via clone can end up with inaccessible path to the custom command. So, .gitmodules could only contain predefined keywords. Otherwise, .git/config could be used to have it configured in a local config.". I do not necessarily agree with this. It all depends on the intention of the project.

    Anyway, git blame shows this line:

    e904deb89d9 (Jonathan Nieder      2019-12-05 01:28:28 -0800 498)                         submodule->update_strategy.type == SM_UPDATE_COMMAND)
    

    and the log log for the commit:

     e904deb89d - submodule: reject submodule.update = !command in .gitmodules (1 year, 1 month ago) <Jonathan Nieder>
    *   d3ac8c3f27 - Sync with 2.14.6 (1 year, 1 month ago) <Johannes Schindelin>
    |\  
    | * 66d2a6159f - (tag: v2.14.6) Git 2.14.6 (1 year, 1 month ago) <Johannes Schindelin>
    

    So, this is intentional and looks like it was added after 2.14.6. @torek suggested that this is due to security considerations. I agree that it makes sense.

    However, it would be nice if this was spelled out in the error message and/or in documentation.