Problem
When a downstream carry commit is tagged UPSTREAM: 123:, rebasebot checks if PR 123 is merged and its merge commit is reachable from the source branch. If the PR targets a different branch than the one being synced, _is_pr_merged silently returns False and the commit is carried — even if the fix is already present in the source branch via a different PR.
Example: A downstream repo has been syncing against upstream release-4.18. Carry commits reference PRs targeting release-4.18. When the downstream switches to syncing release-4.19, those PRs are merged but their merge commits are not reachable from release-4.19 — they targeted a different branch. Rebasebot silently carries these commits even though the equivalent fixes landed in release-4.19 (via main and then backport). This leads to redundant or conflicting carry commits that are hard to diagnose.
Proposed Solution
After _is_pr_merged returns False, look up the PR's target branch via the GitHub API (pr.base.ref). If the target branch doesn't match the source ref, emit a warning or fail depending on a configurable policy.
When source ref is a branch:
- Compare
pr.base.ref directly against the source branch name.
When source ref is a tag:
- Check if the tag commit is an ancestor of
source/<pr_target_branch> using gitwd.is_ancestor(). If not, the tag is not on the PR's target branch — mismatch detected.
Configuration:
- Add
--tag-mismatch-policy flag with values none (default, current behavior), warn (log warning, continue carrying), strict (abort the rebase).
Resolution for detected mismatches
When a mismatch is detected, a human should review the commit and determine the correct action:
- Update the tag to
UPSTREAM: <carry>: if the fix should be kept regardless
- Update the tag to
UPSTREAM: <drop>: if the fix is confirmed present in the source branch
- Update the PR number to reference the correct backport PR targeting the source branch
Additional cost
- One GitHub API call per PR-tagged commit (to fetch
pr.base.ref)
- One
is_ancestor call per PR-tagged commit when syncing a tag (already a pattern used in _is_pr_merged)
Problem
When a downstream carry commit is tagged
UPSTREAM: 123:, rebasebot checks if PR 123 is merged and its merge commit is reachable from the source branch. If the PR targets a different branch than the one being synced,_is_pr_mergedsilently returns False and the commit is carried — even if the fix is already present in the source branch via a different PR.Example: A downstream repo has been syncing against upstream
release-4.18. Carry commits reference PRs targetingrelease-4.18. When the downstream switches to syncingrelease-4.19, those PRs are merged but their merge commits are not reachable fromrelease-4.19— they targeted a different branch. Rebasebot silently carries these commits even though the equivalent fixes landed inrelease-4.19(viamainand then backport). This leads to redundant or conflicting carry commits that are hard to diagnose.Proposed Solution
After
_is_pr_mergedreturns False, look up the PR's target branch via the GitHub API (pr.base.ref). If the target branch doesn't match the source ref, emit a warning or fail depending on a configurable policy.When source ref is a branch:
pr.base.refdirectly against the source branch name.When source ref is a tag:
source/<pr_target_branch>usinggitwd.is_ancestor(). If not, the tag is not on the PR's target branch — mismatch detected.Configuration:
--tag-mismatch-policyflag with valuesnone(default, current behavior),warn(log warning, continue carrying),strict(abort the rebase).Resolution for detected mismatches
When a mismatch is detected, a human should review the commit and determine the correct action:
UPSTREAM: <carry>:if the fix should be kept regardlessUPSTREAM: <drop>:if the fix is confirmed present in the source branchAdditional cost
pr.base.ref)is_ancestorcall per PR-tagged commit when syncing a tag (already a pattern used in_is_pr_merged)