v5: git: submodule, canonical remote for relative URLs#2074
Merged
pjbgf merged 3 commits intoMay 7, 2026
Conversation
A relative submodule URL like `../sibling` has to be joined onto a base URL — the superproject's remote — to produce the actual URL to clone. Submodule.Repository() picked `Repository.Remotes()[0]` as the base. That slice is built by iterating a Go map, so its order is randomized: in any superproject with more than one remote (the common `origin` + `upstream` fork setup), the chosen base flipped between runs and the same `git submodule update` could clone the sibling from either namespace. Canonical Git is deterministic[1][2]: it uses `branch.<HEAD>.remote` if configured, the sole remote when there is exactly one, otherwise the literal `"origin"`. The submodule helper[3] then joins the relative URL onto that remote's URL. Mirror that rule in an unexported `defaultRemote` and call it from the relative-URL branch. Tests cover the rule directly and the end-to-end submodule flow; the integration test loops to catch any future regression that re-introduces map-order dependence. Backport of go-git#2071 from main; the prerequisite relative-URL detection landed separately in go-git#2070. [1]: https://github.com/git/git/blob/v2.54.0/remote.c#L1801-L1809 [2]: https://github.com/git/git/blob/v2.54.0/remote.c#L655-L669 [3]: https://github.com/git/git/blob/v2.54.0/builtin/submodule--helper.c#L53-L75 Assisted-by: Claude Opus 4.7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Submodule.Repository() must skip its relative-URL branch when the configured URL is a native Windows absolute path (`C:\…` or `\\server\share\…`); otherwise these get wrongly joined onto the superproject's remote, producing nonsense like `file:///parent/origin/C:\path\to\repo`. The v5 source already pairs `path.IsAbs` with `filepath.IsAbs` on the raw `s.c.URL` since go-git#2070, so the production behaviour is correct on this branch. Add the Windows-only regression test from 01c23780 (a follow-up commit on go-git#2071) as a guard, ported to gocheck to match the existing `*_windows_test.go` convention (see `repository_windows_test.go`). Backport (test-only) of 01c23780 from go-git#2071. Assisted-by: Claude Opus 4.7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
`MatchesScpLike` accepted any string that fit the regex
`^[user@]host:[port:]path`, but the regex's host class permits
`/` and single ASCII letters, so it matched strings that are
actually local filesystem paths:
- `./relative:path` and `/abs/with:colon/file` matched with host
`./relative` or `/abs/with`.
- On Windows, `C:/path/to/repo` matched with host `C` — a
Windows drive-letter path treated as SSH to a single-character
hostname.
`transport.NewEndpoint` then returned an `ssh://` endpoint where
canonical Git would return a local path. The Windows drive-prefix
case is the practical impact: a submodule URL of `C:/path/to/repo`
in .gitmodules is a valid Windows-absolute path, and go-git was
attempting an SSH connection to a host named `C` instead of
opening the local repository.
Mirror canonical Git's `url_is_local_not_ssh`[1]: after the regex
matches, reject the SCP classification when (a) the URL has a `/`
before the first `:`, or (b) on Windows, the URL begins with a
DOS drive prefix. The drive-prefix check is a small byte-wise
helper rather than a regex, mirroring Git's
`win32_has_dos_drive_prefix`[2] and matching the canonical
implementation more closely.
Add positive tests for the rejected forms (portable for (a),
gated by `runtime.GOOS == "windows"` for (b)) and a regression
test verifying that real SCP forms still match.
Backport of 96eb1ba from go-git#2071.
[1]: https://github.com/git/git/blob/v2.54.0/connect.c#L710-L716
[2]: https://github.com/git/git/blob/v2.54.0/compat/win32/path-utils.c#L20-L29
Assisted-by: Claude Opus 4.7
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
chhe
pushed a commit
to chhe/act_runner
that referenced
this pull request
May 19, 2026
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) | `v5.19.0` → `v5.19.1` |  |  | --- ### Release Notes <details> <summary>go-git/go-git (github.com/go-git/go-git/v5)</summary> ### [`v5.19.1`](https://github.com/go-git/go-git/releases/tag/v5.19.1) [Compare Source](go-git/go-git@v5.19.0...v5.19.1) #### What's Changed - v5: plumbing: transport/ssh, Shell-quote path by [@​hiddeco](https://github.com/hiddeco) in [#​2068](go-git/go-git#2068) - v5: git: submodule, Fix relative URL resolution by [@​hiddeco](https://github.com/hiddeco) in [#​2070](go-git/go-git#2070) - v5: git: submodule, canonical remote for relative URLs by [@​hiddeco](https://github.com/hiddeco) in [#​2074](go-git/go-git#2074) - v5: git: submodule, error on remote without URLs by [@​hiddeco](https://github.com/hiddeco) in [#​2078](go-git/go-git#2078) - v5: plumbing: format/idxfile, Validate offset64 indices by [@​hiddeco](https://github.com/hiddeco) in [#​2084](go-git/go-git#2084) - v5: \*: Reject malformed variable-length integers by [@​hiddeco](https://github.com/hiddeco) in [#​2092](go-git/go-git#2092) - v5: plumbing: format/packfile, Tighten delta validation by [@​hiddeco](https://github.com/hiddeco) in [#​2091](go-git/go-git#2091) - v5: Add `worktreeFilesystem` wrapper for worktree and hardening by [@​hiddeco](https://github.com/hiddeco) in [#​2100](go-git/go-git#2100) - v5: config: validate submodule names by [@​hiddeco](https://github.com/hiddeco) in [#​2082](go-git/go-git#2082) - build: Update module github.com/go-git/go-git/v5 to v5.19.0 \[SECURITY] (releases/v5.x) by [@​go-git-renovate](https://github.com/go-git-renovate)\[bot] in [#​2111](go-git/go-git#2111) - v5: git: Allow MkdirAll on worktree-root paths by [@​hiddeco](https://github.com/hiddeco) in [#​2117](go-git/go-git#2117) - v5: git: Stop validating symlink target paths by [@​pjbgf](https://github.com/pjbgf) in [#​2116](go-git/go-git#2116) - v5: plumbing: format decoder input bounds and contracts by [@​hiddeco](https://github.com/hiddeco) in [#​2125](go-git/go-git#2125) - plumbing: format/packfile, cap delta chain depth in parser by [@​pjbgf](https://github.com/pjbgf) in [#​2137](go-git/go-git#2137) **Full Changelog**: <go-git/go-git@v5.19.0...v5.19.1> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xODIuMSIsInVwZGF0ZWRJblZlciI6IjQzLjE4Mi4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://gitea.com/gitea/runner/pulls/980 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Renovate Bot <renovate-bot@gitea.com> Co-committed-by: Renovate Bot <renovate-bot@gitea.com>
Maks1mS
pushed a commit
to stplr-dev/stplr
that referenced
this pull request
May 20, 2026
This PR contains the following updates: | Package | Type | Update | Change | OpenSSF | |---|---|---|---|---| | [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) | require | patch | `v5.19.0` → `v5.19.1` | [](https://securityscorecards.dev/viewer/?uri=github.com/go-git/go-git) | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/23) for more information. --- ### Release Notes <details> <summary>go-git/go-git (github.com/go-git/go-git/v5)</summary> ### [`v5.19.1`](https://github.com/go-git/go-git/releases/tag/v5.19.1) [Compare Source](go-git/go-git@v5.19.0...v5.19.1) #### What's Changed - v5: plumbing: transport/ssh, Shell-quote path by [@​hiddeco](https://github.com/hiddeco) in [#​2068](go-git/go-git#2068) - v5: git: submodule, Fix relative URL resolution by [@​hiddeco](https://github.com/hiddeco) in [#​2070](go-git/go-git#2070) - v5: git: submodule, canonical remote for relative URLs by [@​hiddeco](https://github.com/hiddeco) in [#​2074](go-git/go-git#2074) - v5: git: submodule, error on remote without URLs by [@​hiddeco](https://github.com/hiddeco) in [#​2078](go-git/go-git#2078) - v5: plumbing: format/idxfile, Validate offset64 indices by [@​hiddeco](https://github.com/hiddeco) in [#​2084](go-git/go-git#2084) - v5: \*: Reject malformed variable-length integers by [@​hiddeco](https://github.com/hiddeco) in [#​2092](go-git/go-git#2092) - v5: plumbing: format/packfile, Tighten delta validation by [@​hiddeco](https://github.com/hiddeco) in [#​2091](go-git/go-git#2091) - v5: Add `worktreeFilesystem` wrapper for worktree and hardening by [@​hiddeco](https://github.com/hiddeco) in [#​2100](go-git/go-git#2100) - v5: config: validate submodule names by [@​hiddeco](https://github.com/hiddeco) in [#​2082](go-git/go-git#2082) - build: Update module github.com/go-git/go-git/v5 to v5.19.0 \[SECURITY] (releases/v5.x) by [@​go-git-renovate](https://github.com/go-git-renovate)\[bot] in [#​2111](go-git/go-git#2111) - v5: git: Allow MkdirAll on worktree-root paths by [@​hiddeco](https://github.com/hiddeco) in [#​2117](go-git/go-git#2117) - v5: git: Stop validating symlink target paths by [@​pjbgf](https://github.com/pjbgf) in [#​2116](go-git/go-git#2116) - v5: plumbing: format decoder input bounds and contracts by [@​hiddeco](https://github.com/hiddeco) in [#​2125](go-git/go-git#2125) - plumbing: format/packfile, cap delta chain depth in parser by [@​pjbgf](https://github.com/pjbgf) in [#​2137](go-git/go-git#2137) **Full Changelog**: <go-git/go-git@v5.19.0...v5.19.1> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At 12:00 AM through 04:59 AM and 10:00 PM through 11:59 PM, Monday through Friday (`* 0-4,22-23 * * 1-5`) - Only on Sunday and Saturday (`* * * * 0,6`) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzAuMjIiLCJ1cGRhdGVkSW5WZXIiOiI0My4xNzAuMjIiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbIktpbmQvRGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://altlinux.space/stapler/stplr/pulls/435
12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A relative submodule URL like
../siblinghas to be joined onto a base URL — the superproject's remote — to produce the actual URL to clone. Submodule.Repository() pickedRepository.Remotes()[0]as the base. That slice is built by iterating a Go map, so its order is randomized: in any superproject with more than one remote (the commonorigin+upstreamfork setup), the chosen base flipped between runs and the samegit submodule updatecould clone the sibling from either namespace.Canonical Git is deterministic1 2: it uses
branch.<HEAD>.remoteif configured, the sole remote when there is exactly one, otherwise the literal"origin". The submodule helper3 then joins the relative URL onto that remote's URL.Mirror that rule in an unexported
defaultRemoteand call it from the relative-URL branch. Tests cover the rule directly and the end-to-end submodule flow; the integration test loops to catch any future regression that re-introduces map-order dependence.Backport of #2071; the prerequisite relative-URL detection landed separately in #2070.