Relative submodule URLs vs. clone URL DWIMming
- From
Johan Herland <johan@herland.net>
- Date
- Aug 27, 2008, 12:00 UTC
- Message-ID
- <200808271400.54302.johan@herland.net>
Hi,
I'm observing a couple of bugs/issues when using relative submodule URLs:
Say, I have a repo "foo" with a couple of submodules "bar", "baz", and the following .gitmodules:
[submodule "bar"] path = bar url = ./bar [submodule "baz"] path = baz url = ./baz
Now, what I want to do is to clone this repo and initialize the submodules using the following commands:
git clone <URL> <DIR> cd <DIR> git submodule update --init
I will demonstrate that whether or not the "git submodule update --init" succeeds depends on the value of <URL>:
Scenarios:
#1: <URL> is a non-bare local repo: "/home/user/foo"
builtin-clone.c:get_repo_path() will DWIM this to "/home/user/foo/.git", and store this as the origin URL. Relative submodule URLs will be resolved against this, and end up looking like "/home/user/foo/.git/bar".
Result: FAIL
#2: <URL> is a non-bare remote repo: "file:///home/user/foo"
(For the purposes of this discussion, a file:// URL is equivalent to a real remote URL) builtin-clone.c:get_repo_path() fails to DWIM it, and we fall back to using it verbatim as the origin URL. Relative submodule URLs will be resolved against this, and end up like "file:///home/user/foo/bar".
Result: Success
Note: When using bare repos below, I assume that the repos are laid out in the following manner:
/home/user/foo.git /home/user/foo.git/bar.git /home/user/foo.git/baz.git
#3: <URL> is a bare local repo (indirectly): "/home/user/foo"
builtin-clone.c:get_repo_path() will DWIM it to "/home/user/foo.git", and store this as the origin URL. Relative submodule URLs will be resolved against this, and end up looking like "/home/user/foo.git/bar", which will work (because the same DWIMming is applied when cloning submodules).
Result: Success
#4: <URL> is a bare local repo (directly): "/home/user/foo.git"
This ends up looking exactly like scenario #3.
Result: Success
#5: <URL> is a bare remote repo (indirectly): "file:///home/user/foo"
As in scenario #2, builtin-clone.c:get_repo_path() fails to DWIM it, and the origin URL ends up as a verbatim copy, but the initial clone still works because of similar DWIMing at the remote/transport level. Relative submodule URLs will be resolved against the origin URL, however, and end up looking like "file:///home/user/foo/bar", which will not work, since - on the submodule clone - remote/transport level will only try to DWIM the last path component (i.e. "file:///home/user/foo/bar.git", and not "file:///home/user/foo.git/bar.git").
Result: FAIL
#6: <URL> is a bare remote repo (directly): "file:///home/user/foo.git"
The initial clone goes off without a hitch, and the submodule URLs end up looking like "file:///home/user/foo.git/bar", which is subsequently DWIMmed "correctly" to "file:///home/user/foo.git/bar".
Result: Success
I'd like to fix this, but I'm not sure whether the fix belongs in builtin-clone.c (i.e. making sure the origin URL is always "correct" wrt. resolving relative submodule URLs), or in git-submodule.sh (i.e. adding smarts when resolving relative submodule URLs against the super-repo's origin URL).
...Johan