From: Jacob Keller Date: Sun, 25 Oct 2026 23:11:28 GMT Subject: Re: [RFC PATCH] submodule: make '^/' work like '../' but with an absolute path Message-ID: In-Reply-To: <20261025212517.479922-1-lightofmysoul@gmail.com> On Sun, Oct 25, 2026 at 2:25 PM Stanislav Aleksandrov wrote: > > On Sun, Oct 25, 2026 at 12:42 PM Jacob Keller > wrote: > > On Tue, Sep 29, 2026 at 11:51 AM Stanislav Aleksandrov > > wrote: > >> - Why not url..insteadOf? It has to be set up on every clone; > >> .gitmodules cannot carry it. > > > > Could .gitmodules be extended to carry this information? > > Not as a rewrite rule. A rule maps one fixed prefix to another, and > .gitmodules is the same for everyone, so it can't send one person over > https and another over ssh with their own host alias. What differs per > clone is the superproject's remote URL, and that's what "../" and "^/" > resolve against. > > We could add a separate "same server as the superproject" key next to > an absolute URL and then Git would ignore the host written in that > URL, but that would be really confusing. > > >> - Compatibility: a local "^/..." path needs a "^" directory in the > >> superproject and protocol.file.allow=always, and "git submodule > >> add" refuses it. > > > > What do you mean here by "refuses it" Is this character already > > refused? I.e. "^" isn't considered a valid directory, which is why its > > suitable for converting to a special meaning? > > No, "^" is a valid directory name, and today "^/org/lib.git" means a > repository in a "^" directory of the superproject. By "refuses" I > meant that "git submodule add" rejects it, as it does "foo/lib.git": > > fatal: repo URL: '^/org/lib.git' must be absolute or begin with ./|../ > > So such a URL has to be written into .gitmodules by hand or with "git > submodule set-url", and since 2.38.1 it can't be cloned without > protocol.file.allow=always. It is possible, just very unlikely. > I see. Because protocol.file.allow is set to "user" by default, submodules can't use file-based URLs that get interpreted as local paths so only very weird setups could be using "^" in their current configuration. Makes sense. The likelihood of breaking someone would be very low then. > > The ultimate goal would be to allow users to specify what protocol > > they want to operate on. > > Relative URLs already do that: a superproject cloned over ssh gets its > "../" submodules over ssh too. The problem is that they also follow > where the superproject lives. > Right. I guess it is more that using relative URLs breaks forks but using absolute paths forces protocol on everyone so it is not a great fallback. > > I guess "insteadOf" even in the .gitmodules wouldn't work because you > > wouldn't want to apply that to everyone. The issue seems to be caused > > because of the URLs on Gitlab changing such that relative paths don't > > work anymore? > > The URLs don't change. Forks are the problem. A fork lives in another > namespace, and on GitLab often at a different depth, because groups > can be nested. > Right. The "relative" URL of the fork just doesn't work unless the subproject itself is forked. > > Does doing something like "../../" work to allow the subproject to > > find the root from a relative path? Or does the current logic not > > support multiple ".."? > > Multiple ".." work, but the count has to match how deep the > superproject is. Let's say the upstream is https://gitlab.com/org/super.git > and lib is https://gitlab.com/org/lib.git: > > - "../lib.git" gives me/lib.git for a fork at me/super.git, which > only exists if lib was forked too. > - "../../org/lib.git" works for me/super.git, but gives > group/org/lib.git for a fork at group/team/super.git. > - "../../../org/lib.git" works for group/team/super.git, but for > me/super.git it climbs past the root and eats the host: > https://org/lib.git. > > "^/org/lib.git" gives https://gitlab.com/org/lib.git for all of them, > or git@gitlab.com:org/lib.git if the superproject was cloned over ssh. > > On GitHub every repository is two levels deep, so "../../org/lib.git" > works for everyone. GitLab and plain SSH servers have no fixed > depth. Yep, that lays out the full reasoning for why you'd want this. Forking the main repository could end up with broken submodule URLs unless you *also* fork the submodules. Depending on your project you may (or may not) want to do that, so having the option to use ^/ is good. Of course using "^/" would mean that forking both super and subproject would potentially break, until/unless you update your fork to point to the new fork URL. I guess that is more semantically correct, your fork of a super project woudl only change once you officially tell it to move to the appropriate fork. I think the concept does make sense, if being driven somewhat by a specific forge decision. Of course this could be useful on other forges in the future.