Repository navigation
fix(core): fetch every branch when reusing a git clone - #3702
Conversation
Updating an existing clone (`CopyAndFetch` / `RenameAndFetch`) fetched only the remote's default branch, while a fresh clone fetches all of them. For a node pinned with `branch: dev` (or a `rev:` that is only reachable from a non-default branch), the commit to check out was never downloaded, so the rebuild after a new push to that branch failed with "failed to parse ref" -- and `RenameAndFetch` had already moved the previous clone into a temp dir that the failure cleanup then deleted. Fetch with the remote's configured refspecs instead, so the reuse path sees the same commits as a new clone. Since that fetches more than before, skip the fetch entirely when the wanted commit is already in the clone (commit hashes are immutable). The `refname` parameter was always `None` and is dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D6z9PTSqfQtU5GZJVR2oYV
|
😎 Merged successfully - details. |
|
🤖 Automated codebase review run: summary (machine-generated by Claude Code; no human has reviewed these findings) I scanned
I verified every finding against PRs opened (5)Correctness
Correctness / security hygiene (template)
Optimization / Documentation / Simplification: no standalone PR met the bar. Simplifications found while doing the above went into those PRs: the unused Validation on the combined diff:
Rejected or deferred findings
Generated by Claude Code |
|
🤖 Automated review (fully automated Claude Code review; no human checked it) I found no issues.
Generated by Claude Code |
Problem
When
dora buildreuses an existing git clone (ReuseOptions::CopyAndFetch/RenameAndFetchinlibraries/core/src/build/git.rs),fetch_changesfetched only the remote's default branch. A fresh clone (NewClone) fetches every branch, so the two paths saw different commits.For a node pinned to a non-default branch, the build fails:
dev, and you rebuild. The CLI resolvesdevto the new hash.choose_clone_dirfinds the previous clone of the same repo and picksRenameAndFetch(orCopyAndFetch).mainis fetched, so the newdevcommit is never downloaded, andcheckout_treefails withfailed to parse ref.RenameAndFetch, the previous clone has already been moved into the temp dir, and the failure cleanup deletes it.rev:pins on commits that are only reachable from a non-default branch hit the same failure.Fix
fetch_changesnow callsremote.fetch(&[], ...). An empty refspec list makes libgit2 use the remote's configured refspecs (+refs/heads/*:refs/remotes/origin/*), so the reuse path sees the same commits as a fresh clone.refnameparameter was alwaysNone, so it is removed.Known edge case, not new to this PR: plain
git fetchwithout--prunehas the same limitation. If upstream deletes branchfeatureand createsfeature/x, the stalerefs/remotes/origin/featurein an old clone blocks the update ("cannot lock ref"). This only happens when the commit is missing locally, and it is much rarer than the failure fixed here.Validation
Class: B (git build path in
dora-core, not the descriptor)build::git::tests::fetch_reuse_reaches_commits_on_non_default_branches. It covers both the Copy and Rename arms: a local file:// origin with adevbranch, a clone of it, then a new commit ondev.called Result::unwrap() on an Err value: failed to parse ref.cargo test -p dora-core --features build --lib build::git: 24 passed.cargo test -p dora-core --all-features: all pass excepttopics::tests::unreachable_peer_teardown_bounded. That test also fails on unmodifiedmainin this sandbox, which has no IPv6 (tcp/[::]:0: address family not supported).cargo clippy -p dora-core --all-targets --all-features -- -D warnings: clean.cargo fmt --check: clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01D6z9PTSqfQtU5GZJVR2oYV
Generated by Claude Code