Skip to content

Suggest reftable migration when HEAD can't be read - #1853

Open
Jorge-Polanco-Roque wants to merge 2 commits into
o2sh:mainfrom
Jorge-Polanco-Roque:fix/head-ref-instantiation
Open

Suggest reftable migration when HEAD can't be read#1853
Jorge-Polanco-Roque wants to merge 2 commits into
o2sh:mainfrom
Jorge-Polanco-Roque:fix/head-ref-instantiation

Conversation

@Jorge-Polanco-Roque

Copy link
Copy Markdown

Fixes #1743.

Problem

On a repository that uses git's reftable backend, onefetch crashes with an opaque error:

The reference at "HEAD" could not be instantiated
  → The path "refs/heads/.invalid" ... is invalid
  → Reference name cannot start with a dot

Root cause

Git's reftable backend intentionally points HEAD at the sentinel refs/heads/.invalid so older clients fail early. gitoxide cannot read the reftable format yet, so every HEAD resolution fails.

Approach

Detect that specific case and turn the crash into an actionable message suggesting git refs migrate --ref-format=files. Detection matches the git-hardcoded sentinel refs/heads/.invalid (not a gix message), so it stays stable across gitoxide versions. Applied via .map_err(...) at the traversal call — the earliest, user-facing HEAD failure.

Testing

  • reftable_sentinel_error_gets_migration_hint and unrelated_error_is_left_untouched (the latter guards against over-matching). Verified the hint test fails without the fix.
  • cargo fmt --check clean · cargo clippy --all-targets zero warnings · cargo test --lib 102 passed.

Note: this is the graceful-error fix (as suggested in the thread); reading reftable itself belongs upstream in gitoxide.

Repositories created with git's reftable backend point HEAD at the
sentinel refs/heads/.invalid so older clients fail early. gitoxide
cannot read the reftable format yet, so HEAD resolution fails with an
opaque error and onefetch aborts commit traversal.

Detect that specific error and surface an actionable suggestion to
convert the repo with `git refs migrate --ref-format=files`, as
discussed with the maintainers on the issue. The sentinel path is
hard-coded by git itself, so the match is stable across gitoxide
versions.

@spenserblack spenserblack left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Duplicate of #1755, but the solution here looks a bit cleaner, so I'll leave this open.

Is there any chance that, rather than pattern matching on a string generated by to_string(), you could check the actual error type that the gix utilities return in traverse_commit_graph? Let me know if you feel that this would be overly complex, and I'll approve.

Per review: detect the reftable case by downcasting to
gix::refs::...::decode::Error::RefnameValidation (an invalid symbolic-ref
target) rather than string-matching `refs/heads/.invalid`, so it stays
correct regardless of message wording. Test builds the real typed error.
@Jorge-Polanco-Roque

Copy link
Copy Markdown
Author

Good call — switched to checking the typed error instead of the message string. reftable_head_hint now downcasts the error chain to gix::refs::file::loose::reference::decode::Error and matches the RefnameValidation variant (an invalid symbolic-ref target), which is exactly what gitoxide raises when it resolves HEADrefs/heads/.invalid on a reftable repo — independent of the message wording.

The unit test builds the real typed error via gix::validate::reference::name(...), and I re-verified end-to-end on a git init --ref-format=reftable repo. Thanks for keeping this open!

spenserblack

This comment was marked as resolved.

@spenserblack spenserblack left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I suspect that this PR violates the AI policy since the replies have been very LLM-like, but overall the code is still decent I suppose.

I'm curious if the user is copying and pasting comments and LLM responses, or if the account is a fully autonomous AI agent. If you are a fully autonomous AI agent, you must disclose.

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.

The reference at "HEAD" could not be instantiated: Reference name cannot start with a dot

2 participants