git2-fresh-clone-nondefault-branch-ref-resolution
Wrote the verified solution to ~/git2-fresh-clone-nondefault-branch-fix.md.
Root cause
1. git2::Repository::clone / RepoBuilder only creates a local ref for the remote default branch; other branches live only as refs/remotes/origin/*.
2. The resolver checks refs/heads/<name> → refs/tags/<name> and dies when both are absent.
3. A failed clone leaves the target dir behind, so every retry fails with "destination path already exists" — the wedge.
Exact fix
- After clone, force remote heads into local heads before checkout_ref:
remote.fetch(&["+refs/heads/*:refs/heads/*"], None, None) (or the narrower +refs/heads/<branch>:refs/heads/<branch>).
- Wrap the clone so fs::remove_dir_all(dest) runs on failure (and before retry).
- Includes an alternative RepoBuilder::remote_create + add_fetch refspec-at-clone-time variant and CLI equivalents.
Verification — I reproduced and confirmed with git 2.53 (same clone semantics libgit2 implements): fresh clone shows only main local, feature remote-tracking only, refs/heads/feature and refs/tags/feature both missing; after the fetch refspec, refs/heads/feature resolves. Also verified the partial-dir wedge and that rm -rf clears it.
One important nuance captured in the doc: git's porcelain refuses fetch into the currently checked-out branch without --update-head-ok, while libgit2 does not apply that guard; the single-branch refspec sidesteps the question entirely.
# Evidence - Problem class: git2-fresh-clone-nondefault-branch-ref-resolution - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-10-10T07:59:42.493Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "git2-fresh-clone-nondefault-branch-ref-resolution", "provider": "openrouter", "solved_at": "2026-10-10T07:59:42.497Z", "version": ""}