Skip to content

cli: error when git clone destination equals the source#9714

Open
petejm wants to merge 1 commit into
jj-vcs:mainfrom
petejm:fix-6918-clone-colocate-self
Open

cli: error when git clone destination equals the source#9714
petejm wants to merge 1 commit into
jj-vcs:mainfrom
petejm:fix-6918-clone-colocate-self

Conversation

@petejm

@petejm petejm commented Jun 27, 2026

Copy link
Copy Markdown

Fixes #6918.

jj git clone <source> without an explicit destination infers it from the source; for a local source that can resolve to the source's own path. With --colocate, an empty .git is initialized at the destination before the fetch, so jj fetches from the repo it just created and silently produces an empty clone. An explicit destination resolving to the source (including through a symlink) hit the same trap.

The fix canonicalizes both source and destination through absolute_git_url and errors when they resolve to the same local (file:) path. Per @martinvonz's note on the issue, only the local-path case is handled; ssh://localhost-style self-clones remain out of scope.

Checklist

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added/updated tests to cover my changes
  • I fully understand the code that I am submitting (what it does, how it works, how it's organized), including any code drafted by an LLM.
  • For any prose generated by an LLM, I have proof-read and copy-edited with an eye towards deleting anything that is irrelevant, clarifying anything that is confusing, and adding details that are relevant.

When `jj git clone <source>` is run without an explicit destination, the
destination is inferred from the source. For a local source this can
resolve to the same path as the source itself. With `--colocate` a valid
empty `.git` is initialized at the destination before the fetch runs, so
the fetch then reads from the empty repo jj just created and silently
produces an empty clone instead of erroring. An explicit destination that
resolves to the source (including through a symlink) hit the same trap.

`absolute_git_url` now also returns the parsed `gix::Url`. The clone
command normalizes both the source and the destination through it, so both
sides are canonicalized identically (gix resolves symlinks and applies unix
separators on Windows), then gates on a `file:` scheme and compares the
parsed paths. This fixes an earlier asymmetry where the source was
symlink-resolved but the destination was only logically normalized, letting
a symlinked explicit destination defeat the guard. The error message now
distinguishes the inferred-destination case from an explicit one.

Fixes jj-vcs#6918

Assisted-by: Claude Code (Opus 4.8)
@petejm petejm requested a review from a team as a code owner June 27, 2026 21:36
@petejm

petejm commented Jun 27, 2026

Copy link
Copy Markdown
Author

CI is green except for one check: test_concurrent_operations::test_git_head_race_condition on test (windows-x86_64). It passed on macOS, Linux, and windows-aarch64, and this change only touches the git clone / absolute_git_url path and its tests — nothing in the concurrent-operations code — so this looks like a pre-existing flake on the Windows x86_64 runner rather than something introduced here.

I don't have permission to re-run CI on this repo. Could a maintainer re-trigger that job when convenient? Happy to rebase/force-push instead if that's preferred.

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.

jj git clone --colocate nonexistent_dir_name creates an empty repo

1 participant