Skip to content

Detect UPSTREAM tag branch mismatch when PR targets a different branch than source #90

Description

@RadekManak

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions