Skip to content

fix(git): preserve submodule root pathname identity - #35119

Closed
OrcaWin wants to merge 1 commit into
mainfrom
OrcaWin/git-submodule-path-routing
Closed

OrcaWin wants to merge 1 commit into
mainfrom
OrcaWin/git-submodule-path-routing

Conversation

@OrcaWin

@OrcaWin OrcaWin commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator
Files Added Deleted Net
Test 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​136 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​136
Prod 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​2 $\color{#cf222e}{\Huge{\mathbf{−}}}$​2 0

A literal backslash is part of a filename on POSIX hosts. The submodule diff router changed it to / before matching .gitmodules, then repeated that conversion while extracting the inner path. An expanded vendor\module/file.txt row could therefore show vendor/module/file.txt from the parent repository as its original content, and the root pointer diff could show tree metadata instead of subproject commits.

Convert only the owning process's filesystem separator at both existing routing steps. POSIX submodule names remain exact, and native Windows/Windows-host WSL retain backslash separator compatibility. No new resolver, wire field, cache, Git command, filesystem I/O or UI change is added.

Evidence and validation

  • Actual production status/submodule expansion/path validator/diff/runner proof on Git 2.25.5 and 2.55.0. Each fixture contains a real embedded submodule plus a different committed parent neighbor at vendor/module/file.txt. Baseline inner diff returns the neighbor's original bytes; fixed returns the child's original and working bytes. Root pointer diffs return exact subproject commits after the fix. The version executed through the production runner is asserted. Parent/child indexes and neighbor bytes remain unchanged; fixtures are removed.
  • Checked-in regressions fail on baseline (2 failures, 4 controls pass) and final focused coverage passes 29 tests across four suites on both current and Git 2.25.5. Final real-Git tests verify setup/production executed-version equality, inner status, clean root pointer, staged moved gitlink, committed inner range, both indexes and neighbor preservation. Host-separator controls distinguish both POSIX spellings and retain Windows slash/backslash input behavior.
  • All nine changed-code quality scans pass before the final version-assertion-only test addition; the required gate checks the frozen final source. Independent source/evidence review found no blocker. Required ORCA_BACKGROUND_LAUNCH=1 pnpm check:changed --base=2d3e7e452000c26433650d75422e79a06be80684 --maxWorkers=2 completed 19 of 20 checks successfully in 604.6 seconds under Node 24. The broad affected-test selection was stopped at 600.5 seconds without an aggregate result; only its four verified owned descendants were terminated and all exited. The gate therefore exits nonzero and is not a full test pass. Its type, format, lint and quality checks passed.

Reachability and integration

Source Control receives the exact submodule name from status. Its expansion combines that name with the inner status path in buildSubmoduleChildEntry; registered local diff validation preserves the POSIX path before these two faulty conversions. The owning server executes remote paths on its own OS. Folder repositories keep their existing Git provider/root-validation path.

#35012 separately fixes .gitmodules config parsing; this patch uses ordinary subsection syntax and preserves its parser changes. #27757 fixes early runtime path normalization and committed blob-reader filenames, while #35092 fixes index blob filenames. Those are still needed for literal backslashes inside an inner filename and for runtime requests normalized before this reader; this patch covers submodule-root identity only. Integrate both replacements with the adjacent #34779/#34967/#35048/#35084 diff-reader work without losing metadata, error, cancellation or symlink semantics. Actual #15994 patch changes host test fixtures, not these production conversions. Targeted open submodule/path/backslash searches and the relevant actual patches found no duplicate fix.

Validation is Linux execution of both Git versions plus simulated separator tests. Native Windows/WSL/macOS, live SSH, Electron, physical mobile and packaged app build were not run. The runtime route's earlier normalization remains separately scoped above. Screenshots are not applicable to these two path-routing expressions; exact before/after content is asserted through real production readers.

@OrcaWin

OrcaWin commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Closing: this only triggers for a submodule whose directory name contains a literal backslash on a POSIX host, which nobody plausibly creates and which cannot be checked out on Windows. The fix is also partial: the same normalization remains in runtime-relative-paths and the blob readers, and WSL-from-Windows is unchanged. It would add 136 lines of mock and real-git tests.

@OrcaWin OrcaWin closed this Oct 30, 2026
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.

1 participant