Skip to content

fix: resolve remote HEAD fetches against remote refs#2660

Merged
Sebastian Thiel (Byron) merged 3 commits into
mainfrom
resolve-fetch-head-againnst-remote-refs
Jun 21, 2026
Merged

fix: resolve remote HEAD fetches against remote refs#2660
Sebastian Thiel (Byron) merged 3 commits into
mainfrom
resolve-fetch-head-againnst-remote-refs

Conversation

@Byron

@Byron Sebastian Thiel (Byron) commented Jun 21, 2026

Copy link
Copy Markdown
Member

Tasks

This section is for Byron only. Models continuing this PR must not add, remove, check, uncheck, rename, or reorder checkboxes here.

  • refackiew
  • remove special (made-up) handling of symrefs on the remote to avoid unintended behaviour. Stick to plain Git.

Everything below this line was generated by Codex GPT-5.

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Fixes #2613

Summary

  • Resolve unmapped born remote symbolic refs, including HEAD, to the object advertised by the remote instead of consulting same-named local refs.
  • Preserve existing mapped symbolic-ref behavior and unborn symbolic-ref handling.
  • Add a local transport regression where remote and local HEAD targets share a refname but point at different commits.

Git Baseline

git fetch <remote> +HEAD:refs/test/repo writes the object advertised by the remote HEAD, not a symbolic ref through the local repository.

Validation

  • cargo test -p gix --features blocking-network-client remote::connection::fetch::refs::tests::update -- --nocapture
  • cargo test -p gix --features blocking-network-client --test gix remote::fetch::blocking_and_async_io -- --nocapture
  • cargo test -p gix --features async-network-client-async-std --test gix remote::fetch::blocking_and_async_io::local_transport_fetches_head_against_remote_refs -- --nocapture
  • git diff --check

Review

codex review --commit 688619a513eed9e54a5285605e04b7b407ba78b7 reported no discrete introduced bug in the modified code paths.

Fetching a local transport remote with a refspec like +HEAD:refs/test/repo could
write a symbolic local ref to the client repository's refs/heads/main when the
remote HEAD was symbolic and the client happened to have a same-named branch.
That made the fetched destination resolve to the local branch instead of the
remote HEAD object.

Add a fetch regression that creates distinct local and remote
repositories with matching HEAD target names but different commits, then fetches
+HEAD:refs/test/repo and asserts the destination is the remote object as a
direct ref.

Match Git behavior observed with the local Git checkout: git fetch <remote>
+HEAD:refs/test/repo creates refs/test/repo as the remote HEAD object, and Git's
remote.c resolves symrefs against the advertised remote ref list.

Fix the unmapped remote-symbolic-ref fallback to peel born remote symrefs to
their advertised object id instead of consulting local refs. Mapped symrefs
still rewrite to their corresponding local tracking ref, and unborn remote refs
remain symbolic.

Co-authored-by: Sebastian Thiel <[email protected]>
@Byron
Sebastian Thiel (Byron) force-pushed the resolve-fetch-head-againnst-remote-refs branch from 688619a to 6730316 Compare June 21, 2026 08:08
Previously `gix` had made-up behaviour to 'improve' on standard Git,
but it's clear this isn't backed up or tested well enough to be worth
the risk of introducing subtle or not so subtle bugs.

Co-authored-by: Sebastian Thiel <[email protected]>
@Byron
Sebastian Thiel (Byron) force-pushed the resolve-fetch-head-againnst-remote-refs branch from 4af2994 to fa42565 Compare June 21, 2026 08:27
@Byron
Sebastian Thiel (Byron) marked this pull request as ready for review June 21, 2026 08:28
Copilot AI review requested due to automatic review settings June 21, 2026 08:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes fetch ref-updates so remote symbolic refs (notably HEAD) are resolved against the remote-advertised target object, rather than being (incorrectly) resolved via same-named local refs when using local/file transports. This aligns behavior with git fetch <remote> +HEAD:....

Changes:

  • Change ref-update logic to peel born remote symbolic refs to their advertised object id when writing locally (unborn refs remain symbolic).
  • Adjust/update existing ref-update tests to reflect the new “remote symrefs are written as direct refs” behavior.
  • Add a regression test ensuring +HEAD:refs/test/repo fetches the remote HEAD target even when local HEAD points elsewhere.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
gix/tests/gix/remote/fetch.rs Adds a regression test for local transport fetching HEAD against remote refs.
gix/src/remote/connection/fetch/update_refs/tests.rs Updates expectations/documentation in unit tests for peeled (direct) handling of remote symrefs.
gix/src/remote/connection/fetch/update_refs/mod.rs Simplifies new_value_by_remote() to always store born remote symrefs as direct object targets.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread gix/src/remote/connection/fetch/update_refs/mod.rs
The CI test-fast jobs failed in clone::blocking_io::fetch_only_with_configuration after the PR changed born remote symbolic refs to be written as direct object refs.

The failing assertion still expected two loose symbolic refs, including refs/remotes/<remote>/HEAD, and expected 14 packed non-symbolic refs. With born remote symrefs peeled, only the clone HEAD remains loose and the remote HEAD contributes one more packed direct ref.

Update the clone test to assert the peeled remote HEAD object id while keeping the existing check that the local clone HEAD adopts the remote branch name.
@Byron
Sebastian Thiel (Byron) merged commit a8c5257 into main Jun 21, 2026
32 checks passed
@Byron
Sebastian Thiel (Byron) deleted the resolve-fetch-head-againnst-remote-refs branch June 21, 2026 09:05
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.

Local Transport Silently Fails on Symbolic Refs

3 participants