Skip to content

fix(git): fix submodule init on workspace restart#518

Merged
mafredri merged 2 commits into
mainfrom
485-r2-followup
May 22, 2026
Merged

fix(git): fix submodule init on workspace restart#518
mafredri merged 2 commits into
mainfrom
485-r2-followup

Conversation

@mafredri
Copy link
Copy Markdown
Member

Patch PR for #485 (round 2) that addresses the second review pass. Targets the PR's branch.

Changes

P1: git.Open arguments swapped (AMREM-14)

Both calls at lines 112 and 136 passed (fsStorage, gitDir) when the correct order is (storer-backed-by-.git, worktree-fs). This made every workspace restart fail to detect the existing repo, enter the clone path, and hit ErrRepositoryAlreadyExists. The AlreadyCloned test is updated to actually clone first (producing the right on-disk layout) instead of using gittest.NewRepo which writes objects at the root.

P2: Orphaned .git blocks retries (AMREM-16)

If CloneContext fails (network timeout, auth error), the .git directory created by MkdirAll persisted. On the next start, Stat(".git") took the already-cloned fast path and tried to Open a corrupt repo. Now the .git directory is removed on clone failure.

P3 fixes

  • extractHost rewritten to use transport.NewEndpoint, removing the duplicate SCP regex parser (AMREM-24).
  • Already-cloned branch in cloneSubmodule now calls openSubmoduleRepo instead of duplicating the Chroot/NewStorage/Open sequence (AMREM-25).
  • fetchErr included in the "Direct fetch failed" log message (AMREM-22).
  • initSubmodules tracks warnings and adjusts the final log line accordingly (AMREM-23).
  • SameHost doc corrected: port is ignored as a simplification, not to match git credential helpers (AMREM-27).
  • "positive integer" changed to "non-negative integer (0 disables)" everywhere (AMREM-28).
  • SubmoduleDepth capped at 100 (AMREM-31).
  • Cross-protocol auth forwarding documented as intentional in submoduleAuthFor (AMREM-15).
  • Test logf fixed to use fmt.Fprintf so format args are expanded (AMREM-20).

Docs: PR description updated (AMREM-18)

The behavior section now accurately describes the retry-on-every-start semantics.

Contested

AMREM-17 and AMREM-21 re-raise the ./-relative URL resolution claim from DEREM-2 (R1), which was already contested with a native git reproduction showing the current behavior is correct. No change.

🤖 This PR was created with the help of Coder Agents, and will be reviewed by a human. 🏂🏻

- Fix swapped git.Open arguments at lines 112 and 136. The storer was
  backed by the worktree root and the worktree arg was the .git/
  filesystem. This made every workspace restart fail to detect the
  existing repo, fall through to CloneContext, and hit
  ErrRepositoryAlreadyExists. (AMREM-14)

- Clean up orphaned .git directory when CloneContext fails in
  cloneSubmodule. Without this, one failed clone permanently poisons
  the submodule directory: the next Stat(".git") takes the
  already-cloned fast path and tries to Open a broken repo. (AMREM-16)

- Use openSubmoduleRepo in the already-cloned branch of
  cloneSubmodule, removing the duplicate Chroot/NewStorage/Open
  sequence. (AMREM-25)

- Rewrite extractHost to delegate to transport.NewEndpoint instead of
  reimplementing SCP URL parsing with a separate regex. (AMREM-24)

- Include fetchErr in the "Direct fetch failed" log message so
  operators see why the targeted fetch was rejected. (AMREM-22)

- Track warnings in initSubmodules and adjust the final log line so
  it does not claim all submodules initialized successfully when
  warnings were emitted. (AMREM-23)

- Correct the SameHost doc comment: port is ignored as a
  simplification, not to match git credential helpers (which do
  include port). (AMREM-27)

- Change "positive integer" to "non-negative integer (0 disables)"
  in SubmoduleDepth docs and error messages, matching the actual
  guard (n < 0). (AMREM-28)

- Cap SubmoduleDepth at 100 to bound runaway recursion. (AMREM-31)

- Document cross-protocol auth forwarding in submoduleAuthFor as
  intentional. go-git rejects incompatible auth at the transport
  layer. (AMREM-15)

- Fix test logf to use fmt.Fprintf so format args are expanded and
  the warning check is not vacuously true. (AMREM-20)

- Fix TestCloneRepo/AlreadyCloned to produce a repo in the layout
  CloneRepo expects (.git/ subdirectory) by cloning first, rather
  than using gittest.NewRepo which writes objects at the root.
  Skip the subtest when the test case expects the initial clone to
  fail. (AMREM-14 test fix)
@mafredri mafredri requested review from bjornrobertsson and johnstcn and removed request for bjornrobertsson May 22, 2026 09:11
Comment thread docs/env-variables.md
Comment thread git/git.go Outdated
@mafredri mafredri marked this pull request as ready for review May 22, 2026 09:18
If billyutil.RemoveAll fails to remove the orphaned .git directory,
log a warning so the operator knows the submodule directory may be in
a broken state.
@mafredri mafredri enabled auto-merge (squash) May 22, 2026 09:28
@mafredri mafredri changed the title fix(git): address R2 review feedback on submodule support fix(git): fix submodule init on workspace restart May 22, 2026
@mafredri mafredri merged commit afe8c56 into main May 22, 2026
4 checks passed
@mafredri mafredri deleted the 485-r2-followup branch May 22, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants