"W. Trevor King" <wk...@tremily.us> writes:

> From: "W. Trevor King" <wk...@tremily.us>
> The current `update` command incorporates the superproject's gitlinked
> SHA-1 ($sha1) into the submodule HEAD ($subsha1).  Depending on the
> options you use, it may checkout $sha1, rebase the $subsha1 onto
> $sha1, or merge $sha1 into $subsha1.  This helps you keep up with
> changes in the upstream superproject.
> However, it's also useful to stay up to date with changes in the
> upstream subproject.  Previous workflows for incorporating such
> changes include the ungainly:
>   $ git submodule foreach 'git checkout $(git config --file 
> $toplevel/.gitmodules submodule.$name.branch) && git pull'
> With this patch, all of the useful functionality for incorporating
> superproject changes can be reused to incorporate upstream subproject
> updates.  When you specify --remote, the target $sha1 is replaced with
> a $sha1 of the submodule's origin/master tracking branch.  If you want
> to merge a different tracking branch, you can configure the
> `submodule.<name>.branch` option in `.gitmodules`.  You can override
> the `.gitmodules` configuration setting for a particular superproject
> by configuring the option in that superproject's default configuration
> (using the usual configuration hierarchy, e.g. `.git/config`,
> `~/.gitconfig`, etc.).
> Previous use of submodule.<name>.branch
> =======================================
> Because we're adding a new configuration option, it's a good idea to
> check if anyone else is already using the option.  The foreach-pull
> example above was described by Ævar in
>   commit f030c96d8643fa0a1a9b2bd9c2f36a77721fb61f
>   Author: Ævar Arnfjörð Bjarmason <ava...@gmail.com>
>   Date:   Fri May 21 16:10:10 2010 +0000
>     git-submodule foreach: Add $toplevel variable
> Gerrit uses the same interpretation for the setting, but because
> Gerrit has direct access to the subproject repositories, it updates
> the superproject repositories automatically when a subproject changes.
> Gerrit also accepts the special value '.', which it expands into the
> superproject's branch name.
> Although the --remote functionality is using `submodule.<name>.branch`
> slightly differently, the effect is the same.  The foreach-pull
> example uses the option to record the name of the local branch to
> checkout before pulls.  The tracking branch to be pulled is recorded
> in `.git/modules/<name>/config`, which was initialized by the module
> clone during `submodule add` or `submodule init`.  Because the branch
> name stored in `submodule.<name>.branch` was likely the same as the
> branch name used during the initial `submodule add`, the same branch
> will be pulled in each workflow.
> Implementation details
> ======================
> In order to ensure a current tracking branch state, `update --remote`
> fetches the submodule's remote repository before calculating the
> SHA-1.  However, I didn't change the logic guarding the existing fetch:
>   if test -z "$nofetch"
>   then
>     # Run fetch only if $sha1 isn't present or it
>     # is not reachable from a ref.
>     (clear_local_git_env; cd "$path" &&
>       ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
>        test -z "$rev") || git-fetch)) ||
>     die "$(eval_gettext "Unable to fetch in submodule path '\$path'")"
>   fi
> There will not be a double-fetch, because the new $sha1 determined
> after the `--remote` triggered fetch should always exist in the
> repository.  If it doesn't, it's because some racy process removed it
> from the submodule's repository and we *should* be re-fetching.

As you hinted in the first paragraph, you could flip between merge,
rebase, and detach with a command line option when running the
"update" subcommand, but I would imagine that the expected use
pattern is that for a particular project, you would choose one mode
and consistently stick to that mode.  To make it easier, the user
can set submodule.$name.update once and run "update" without having
to give any flags.

And this is about adding another mode to the "update" subcommand
where the HEAD is not detached, nor merged, nor rebased, but is set
to follow whatever commit a remote branch points at.

Shouldn't the patch add a way for the user to set a configuration
variable to signal that this new mode is always used when "update"
is run without a command line flag?

As the user has to configure submodule.$name.branch in order to use
this mode anyway, I have a feeling that taking that as a signal, and
ignoring submodule.$name.update altogether, might be a simpler
interface from the end user's point of view.  That is,

 (1) if you are not interested in the submodule $name, you do not
     "init" it; you "init" it for all of the following.

 (2) if you want to have the tree state as recorded in the
     superproject, you do "update" without any option to make the
     HEAD of the submodule detached at the commit the superproject's
     tree records;

 (3) if you want to follow the upstream project of the submodule,
     you set submodule.$name.branch to the branch you want to
     follow, and you do "update"---submodule.$name.update is ignored
     and you will make the HEAD of the submodule detached at the tip
     of the branch at the remote (using remote-tracking branch);

 (4) if you want to --merge or --rebase, you give them from the
     command line, or use submodule.$name.update.

I may be oversimplifying a bit, but a separate
submodule.$name.remote feels very wrong; if it were a new token
"remote" that can be set as the value of submodule.$name.update (in
addition to existing "none", "rebase" and "merge"), it might be a
bit more understandable, though.

How does this compare with the floating submodules Heiko has been
working on?
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to