Skip to content

Promote develop to main: Qualify local_review's Remote-Tracking Target So a Local Branch Cannot Shadow It - #2110

Merged
ptr727 merged 1 commit into
mainfrom
develop
Sep 29, 2026
Merged

ptr727 merged 1 commit into
mainfrom
develop

Conversation

@ptr727

@ptr727 ptr727 commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Promotes develop to main, carrying #2108.

That PR stops a local branch from shadowing the remote-tracking target scripts/local_review.py measures a review against. target_ref now looks each remote-tracking candidate up by its exact name with git show-ref --verify and returns it fully qualified as refs/remotes/..., so git merge-base can no longer resolve a same-named local branch such as upstream/main or origin/develop in its place. A remote-tracking ref that does not resolve to a commit refuses instead of falling through, and a target already written as refs/remotes/... is not also tried under origin/. Receipts keep the target as typed, so no existing receipt changes key.

Follow-ups filed from the reviews: #2106, #2107, #2109.

CodeRabbit reviewed #2108 through its final head b0e5a0ab. This promotion carries byte-identical content, checkable with two commands:

  • git rev-parse b0e5a0ab^{tree} 4c9087df^{tree} prints f7e6c9a2... for both.
  • git diff origin/main origin/develop | git hash-object --stdin and git diff 6c56130f b0e5a0ab | git hash-object --stdin both print 479a53e4....

Closes #1235

🤖 Generated with Claude Code

…t Shadow It (#2108)

`local_review.py`'s `target_ref` returned a remote-tracking target as
its short name, such as `upstream/main` or `origin/develop`, and
`merge_base` handed that name to `git merge-base`. Git resolves a short
name through `refs/heads/` before `refs/remotes/`, so a local branch
literally named like the remote-tracking ref silently defined the review
scope.

- `target_ref` now looks each remote-tracking candidate up by its exact
name with `git show-ref --verify` (a new `remote_tracking_ref` helper)
and returns it fully qualified as `refs/remotes/...`. A full-name lookup
through `rev-parse` was not enough, since `rev-parse` also resolves
`refs/remotes/<x>` through a local branch of that full name.
- An exact remote-tracking ref that does not resolve to a commit refuses
rather than falling through to the as-written step, where a same-named
local branch would win.
- The final refusal names the three refs actually tried, and the
`--target` help names the remote-tracking check that runs before
`origin/<value>`.
- Tests pin a local branch shadowing the `upstream/main` form, the
`origin/<target>` form, and the full `refs/remotes/...` form, plus the
non-commit refusal. Each new test was run against the unfixed
`local_review.py` and fails there.

The value only reaches `git merge-base`. Receipts store the target as
the caller typed it, so no existing receipt changes key.

Follow-ups filed from the local review passes rather than widening this
change:
- #2106: a dangling remote-tracking symref, or one naming a missing
object, is rejected by `show-ref` and still falls through. This predates
the change.
- #2107: the `local-strict-review` Skill's `git merge-base
origin/<target> HEAD` command still resolves the short name, so in the
shadowed case it now disagrees with the engine.

Closes on promotion: #1235

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Target selection now checks matching remote-tracking branches before
`origin` or the target as written. Targets already qualified as
remote-tracking refs are checked only as written, preventing local
branches from shadowing remote branches or qualified targets from being
reinterpreted under `origin`.
* A remote-tracking ref that does not resolve to a commit now produces
an error.

* **Documentation**
  * Updated `--target` help text to explain the target resolution order.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 29, 2026 23:51
@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository: ptr727/ProjectTemplate/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: f0dcb43e-d7fc-4572-ac11-4d767c0cfa88


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.47%. Comparing base (6c56130) to head (4c9087d).
⚠️ Report is 295 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2110      +/-   ##
==========================================
+ Coverage   56.39%   56.47%   +0.07%     
==========================================
  Files          16       16              
  Lines        7442     7455      +13     
==========================================
+ Hits         4197     4210      +13     
  Misses       3245     3245              
Flag Coverage Δ
python-3.13 56.47% <100.00%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

It promotes a change to the core local-review verification engine's git ref-resolution into main, an area with subtle edge cases and explicitly deferred follow-ups, so final promotion sign-off warrants human review.

Review effort: Balanced
Findings: None

What changed in this PR

This is a develop → main promotion PR that carries a single behavioral fix to the fleet's local-review verification engine (scripts/local_review.py). Previously, target_ref() returned a remote-tracking target as its short name (e.g. upstream/main, origin/develop), which merge_base() passed to git merge-base. Because git resolves a short name through refs/heads/ before refs/remotes/, a local branch of the identical name silently defined the review scope. The fix resolves each remote-tracking candidate by its exact name via a new remote_tracking_ref() helper (git show-ref --verify) and returns it fully qualified as refs/remotes/..., so a same-named local branch can no longer shadow it. A remote-tracking ref that resolves to a non-commit now refuses instead of falling through, and a target already written as refs/remotes/... is not re-tried under origin/. Receipts still key on the target as typed, so no existing receipt changes.

Changes:

  • Add remote_tracking_ref() helper that matches refs/remotes/<name> exactly (avoiding rev-parse's local-branch fallback) and refuses when the ref names a non-commit.
  • Rewrite target_ref() to return fully qualified refs/remotes/... refs, skip the origin/ candidate for already-qualified targets, and give a clearer refusal message; update --target help text.
  • Add tests pinning the shadowing, qualified-target, non-commit-refusal, and full-name-not-remote-tracking cases.
File Description
scripts/​local_review.py Adds remote_tracking_ref(), rewrites target_ref() to return qualified refs and skip redundant origin/ lookups, refines the refusal message and --target help.
tests/​test_local_review.py Updates expectations to the qualified refs/remotes/... return values and adds tests for local-branch shadowing (both upstream/ and origin/ forms), qualified-target handling, non-commit refusal, and exact-name matching.

I reviewed both changed files end to end. The new resolution logic is correct across all branches, the error messages accurately name the refs tried, the docstrings and help text match the implemented behavior and are ASCII-clean with no mid-sentence semicolons, and the tests comprehensively cover the new paths. The linked issues #2106, #2107, and #2109 are correctly scoped as follow-ups rather than claimed as fixed here. I found no objective defects.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@ptr727
ptr727 merged commit d224918 into main Sep 29, 2026
11 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.

local_review.py: target_ref returns a bare name a same-named local branch can shadow

2 participants