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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions