Skip to content

Finish the conversion of git submodule to a built-in #541

Open
@dscho

Description

@dscho

The git-submodule.sh script weighs in with just over 1,000 lines. That is a rather tall order, so most likely it will take the equivalent of multiple Google Summer of Code projects to finish.

Taking a bit of a deeper look into the git-submodule.sh script, we see a peculiar pattern in some of the subcommands, e.g. in cmd_foreach: https://github.com/git/git/blob/v2.21.0/git-submodule.sh#L320-L349

Essentially, it spends two handfuls of lines on option parsing, and then the real business logic is performed by the submodule--helper, which is already a built-in.

Most of that business logic is implemented in submodule.c.

The important part is to identify those commands in git-submodule.sh that do not yet follow this
pattern "parse options then hand off to submodule--helper". See more on that below.

The commit history of the commands that do use the submodule--helper will help see how they were converted, what conventions were used, whether there were recurring patterns, etc. This style should be imitated for the rest of the conversion.

An important thing to realize is that it is not so much a conversion as a re-implementation, and the best way to go about it is incremental.

Take for example the git submodule init subcommand. It has been re-implemented in C a long time ago, and the shell script version merely parses the command-line arguments and then passes them on to the built-in git submodule--helper command:

https://github.com/git/git/blob/v2.24.1/git-submodule.sh#L361-L390

It probably would make sense to study the initial re-implementation (or "port"): 3604242

It appears that cmd_add, cmd_init, cmd_deinit, (partially) cmd_update, (partially) cmd_set_branch and cmd_summary still need to be ported while cmd_foreach, cmd_status, cmd_sync and cmd_absorbgitdirs already use the submodule--helper-provided built-in code.

The easiest of the sub-commands that still need to be ported might be cmd_set_branch. In the git.git fork of the contributor who started the porting effort, there are some branches that might or might not have useful commits in them, but given that set_branch already calls the submodule--helper a couple of times and does little on its own, it might make sense to just do that port "from scratch".

The idea here will be to pass the options using the construct ${GIT_QUIET:+--quiet} (which expands to --quiet if $GIT_QUIET would expand to a non-empty string) to the submodule--helper, and to add a new sub-command to said helper, by implementing static int set_branch(int argc, const char **argv, const char *prefix) in builtin/submodule--helper.c and appending the corresponding entry to the commands array.

Likewise, it should be easy to figure out which functions are used by the submodule--helper to perform the actions asked for by the current shell script function cmd_set_branch, and call them directly from the newly-implemented set_branch() function in builtin/submodule--helper.c.

It is highly recommended to contribute this work in small chunks, e.g. as soon as cmd_set_branch is done, even if it is not working yet (in which case it should be marked as request for help). The hardest part, as with every project, is to get started, from there on it will be easier.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions