Skip to content

fix: peel revspecs to a commit in gix merge-base - #2896

Merged
Sebastian Thiel (Byron) merged 2 commits into
GitoxideLabs:mainfrom
shuvamk:fix/merge-base-peel-tag
Aug 8, 2026
Merged

fix: peel revspecs to a commit in gix merge-base#2896
Sebastian Thiel (Byron) merged 2 commits into
GitoxideLabs:mainfrom
shuvamk:fix/merge-base-peel-tag

Conversation

@shuvamk

Copy link
Copy Markdown
Contributor

This PR was written by an AI agent (Claude) speaking through my GitHub account.

What's wrong (AI)

A revspec that resolves to an annotated tag is not dereferenced in gix merge-base: the id of the tag object is what reaches the commit-only traversal. In a clone of this repository, where cargo-smart-release-v0.10.0 is an annotated tag on an ancestor of main:

revspecs git merge-base gix merge-base
cargo-smart-release-v0.10.0 HEAD rc=0, ceb6dff13362a2b4318a551893217c1d11643b9f rc=1, Error: No base found for cargo-smart-release-v0.10.0 and HEAD
HEAD cargo-smart-release-v0.10.0 cargo-smart-release-v0.1.0 rc=0, ceb6dff13362a2b4318a551893217c1d11643b9f rc=0, 0fa37f5d8c96aee551bb6442756059dc203a6cbc

The second row is a wrong answer with no error: 0fa37f5d8 is cargo-smart-release-v0.1.0, the base of the two revspecs left once the tag is dropped, while ceb6dff13 is the commit the annotated tag points at.

gitoxide-core/src/repository/merge_base.rs:16,19 resolves each revspec with rev_parse_single() and passes the result to merge_bases_many_with_graph() unchanged. gix-revwalk's get_or_insert_full_commit finds no commit for a tag-object id and returns without queueing it and without reporting an error. git merge-base dereferences tags before computing anything.

What this does

Each revspec is peeled to a commit before the traversal. Lightweight tags, branches and raw commit ids resolve exactly as before.

One deliberate side effect: a revspec that cannot be peeled to a commit is now rejected with the peel error. gix merge-base 'HEAD^{tree}' HEAD reports Error: Last encountered object … was tree while trying to peel to commit, closer to git's fatal: Not a valid commit name HEAD^{tree}.

Tests

Two journey tests under gix merge-base, both in the existing small-repo-in-sandbox fixture, which already creates an annotated tag on the second of its three commits: gix merge-base annotated HEAD covers the error, and gix merge-base HEAD annotated unannotated covers the wrong answer. With the change to merge_base.rs reverted the first fails on its exit status and the second on a snapshot mismatch — it prints the first commit where the second is correct; restored, both pass. Checked for the max, small and async binaries, since the sub-command is built into all of them.

cargo test --workspace passes, and cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- -D warnings -A unknown-lints -A unfulfilled_lint_expectations, cargo doc --workspace --no-deps and cargo run -p internal-tools -- check-mode are clean. (An earlier full-suite run here failed one gix-prompt pty test under parallel load; cargo test -p gix-prompt is green in isolation on main as well as on this branch. just isn't installed on this machine, so those are the raw cargo lines, and the clippy allow is because clean main already trips three of those expectations in gix-ref on rustc 1.95.0. The journey run skips journey/ein.sh — its TUI panic snapshot needs a real terminal.)

Shuvam Kumar (shuvamk) and others added 2 commits August 8, 2026 16:43
The revspecs were resolved with `rev_parse_single()` and handed to the
commit-only merge-base traversal unchanged, so a revspec naming an annotated
tag arrived as the id of the tag object. No commit is found for such an id and
no error is raised. In a clone of this repository,
`gix merge-base HEAD cargo-smart-release-v0.10.0 cargo-smart-release-v0.1.0`
printed 0fa37f5, dropping the tag and
computing the base of the two revspecs that were left, while `git merge-base`
with the same arguments prints ceb6dff - the
commit the annotated tag points at. Git dereferences tags before computing
anything.

Each revspec is now peeled to a commit before the traversal. Lightweight tags,
branches and raw commit ids resolve as before, and a revspec that cannot be
peeled to a commit is rejected with the peel error.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- remove integration tests which won't be needed for development tools
  which can change at will.
@Byron

Copy link
Copy Markdown
Member

Thanks, but: please do not focus on gix (CLI) or gitoxide-core for that matter. The aim for these is to help running gix in the real world, not to be a git replacement.

Future PRs will be closed if they appear to compare gix (CLI) to Git, which misses the point.
Thanks for your understanding.

@Byron
Sebastian Thiel (Byron) merged commit e1af444 into GitoxideLabs:main Aug 8, 2026
31 checks passed
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.

2 participants