git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Relative submodule URLs

From
RDRobert Dailey <rcdailey.lists@gmail.com>
Date
Aug 19, 2014, 16:07 UTC
Message-ID
<CAHd499DVf4N3Y6m5qoiy-WQGX4K54umefRzehZMsrxiWbaiZ=g@mail.gmail.com>
In-Reply-To
<20140818205505.GA20185@google.com>
On Mon, Aug 18, 2014 at 3:55 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 12 quoted lines
> Thanks for reporting.  The remote used is the default remote that "git
> fetch" without further arguments would use:
>
>         get_default_remote () {
>                 curr_branch=$(git symbolic-ref -q HEAD)
>                 curr_branch="${curr_branch#refs/heads/}"
>                 origin=$(git config --get "branch.$curr_branch.remote")
>                 echo ${origin:-origin}
>         }
>
> The documentation is wrong.  git-fetch(1) doesn't provide a name for
> this thing.  Any ideas for wording?

I guess a good start would be to call it the "tracked remote" instead of "remote origin". The word "tracked" here makes it very obvious that if I have a remote tracking branch setup, it will use the remote portion of that configuration.

The real question is, how will `git submodule update` function if a tracking remote is not configured? Will it fail with some useful error message? I don't like the idea of it defaulting to "self remote" mode, where it will be relative to my repo directory. That seems like it would fail is subtle ways in a worst-case scenario (if I did by happenstance have a bare repository cloned up one directory level for other reasons).

> Currently there isn't, short of reconfiguring the remote used by
> default by "git fetch".

I wish there was a way to specify the remote on a per-branch basis separately from the tracking branch. I read a while back that someone proposed some changes to git to support decentralized tracking (concept of an upstream tracking branch and a separate one for origin, i think). If that were implemented, then relative submodules could utilize the 'upstream' remote by default for each branch, which would provide more predictable default behavior. Right now most people on my team would not be aware that if they tracked a branch on their fork, they would subsequently need to fork the submodules to that same remote.

Show 18 quoted lines
>> Various co-workers use the remote named "central" instead of
>> "upstream" and "fork" instead of "origin" (because that just makes
>> more sense to them and it's perfectly valid).
>>
>> However if relative submodules require 'origin' to exist AND also
>> represent the upstream repository (in triangle workflow), then this
>> breaks on several levels.
>
> Can you explain further?  In a triangle workflow, "git fetch" will
> pull from the 'origin' remote by default and will push to the remote
> named in the '[remote] pushdefault' setting (see "remote.pushdefault"
> in git-config(1)).  So you can do
>
>         [remote]
>                 pushDefault = whereishouldpush
>
> and then 'git fetch' and 'git fetch --recurse-submodules' will fetch
> from "origin" and 'git push' will push to the whereishouldpush remote.
I didn't know about this option, seems useful.

A common workflow that we use on my team is to set the tracking branch to 'upstream' for convenient pulls with rebase. This means a feature branch of mine can track its parent branch on 'upstream', so that when other pull requests get merged in on the remote repo branch, I can just do `git pull` and my feature branch rebases onto the latest of that parent branch.

Cases like these would work with relative submodules because 'upstream' is the tracked remote (and most of the time we don't want to fork submodules). However sometimes I like to track the same pushed branch on origin (my fork), especially when it is up for pull request. In these cases, my submodule update will fail because I didn't fork my submodules when I changed my tracking branch. Is this correct?

"breaks on several levels" was basically my way of saying that various workflow choices will break when you introduce submodules. One of the beautiful things about Git is that it allows everyone to choose their own workflow. But submodules seem to prevent that to some degree. I think addressing relative submodule usability issues is the best approach for the long term as they feel more sustainable and scalable. It's an absolute pain to move a submodule URL, I think we've all experienced it. It's even harder for me because I'm the go-to at work for help with Git. Most people that aren't advanced with Git will not know what to do without a ton of reading & such.

Show 7 quoted lines
> It might make sense to introduce a new
>
>         [remote]
>                 default = whereishouldfetch
>
> setting to allow the name "origin" above to be replaced, too.  Is that
> what you mean?

I think you're on the right path. However I'd suggest something like the following:

[submodule]
    remote = <remote_for_relative_submodules> (e.g. `upstream`)
[branch.<name>]
    submoduleRemote = <remote_for_relative_submodule>

Above, `submodule.remote` is the 'default' remote used by all relative submodules on all branches. If unspecified, it defaults to `branch.<name>.remote` as it currently behaves.

`branch.<name>.submoduleRemote` is an override for `submodule.remote`.
Basically if you consider this scenario:
[branch.myfoo]
   remote = origin
   submoduleRemote = upstream
I can track an origin branch, but the submodule will refer to 'upstream'.

I can optionally set `submodule.remote` in my global config so I don't need to set the submodule remote on each branch. This is useful if most branches I track are on origin instead of upstream.

I'm sure I'm missing other important aspects of Git that these options conflict with, and perhaps 2 additional options may be too redundant. It's just some food for thought.

Show 8 quoted lines
> Meanwhile it is hard to fork a project that uses relative submodule
> URLs without also forking the submodules (or, conversely, to fork some
> of the submodules of a project that uses absolute submodule URLs).
> That's a real and serious problem but I'm not sure how it relates to
> the names of remotes.  My preferred fix involves teaching git to read
> a refs/meta/git (or similarly named) ref when cloning a project with
> submodules and let settings from .gitmodules in that ref override
> .gitmodules in other branches.  Is that what you were referring to?

Could you explain this a bit more? What is refs/meta/git? Never heard of that one. Does that have to be done while cloning or can an existing repository be configured? I'm interested in your idea but it sounds confusing to me.

Thanks for taking the time to brainstorm with me.
Previous: Heiko VoigtNext: Marc Branchaud
Message 14 of 25 in “Relative submodule URLs”
  1. Robert DaileyAug 18, 2014
  2. Jonathan NiederAug 18, 2014
  3. Heiko VoigtAug 19, 2014
  4. Robert DaileyAug 19, 2014
  5. Junio C HamanoAug 19, 2014
  6. Robert DaileyAug 19, 2014
  7. Junio C HamanoAug 19, 2014
  8. Robert DaileyAug 19, 2014
  9. Heiko VoigtAug 19, 2014
  10. Robert DaileyAug 19, 2014
  11. Heiko VoigtAug 19, 2014
  12. Robert DaileyAug 20, 2014
  13. Heiko VoigtAug 21, 2014
  14. Robert DaileyAug 19, 2014
  15. Marc BranchaudAug 22, 2014
  16. Heiko VoigtAug 24, 2014
  17. Robert DaileyAug 25, 2014
  18. Robert DaileyAug 25, 2014
  19. Heiko VoigtAug 26, 2014
  20. Robert DaileyAug 26, 2014
  21. Heiko VoigtAug 26, 2014
  22. Robert DaileyAug 25, 2014
  23. Marc BranchaudAug 28, 2014
  24. Heiko VoigtAug 28, 2014
  25. Marc BranchaudAug 29, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.