Skip to content

feat(stack): rebase-aware compare URLs in revision history comments#1325

Merged
mergify[bot] merged 1 commit intomainfrom
devs/jd/worktree-rebase-detect/rebase-aware-compare-urls-revision-history--4b161304
May 4, 2026
Merged

feat(stack): rebase-aware compare URLs in revision history comments#1325
mergify[bot] merged 1 commit intomainfrom
devs/jd/worktree-rebase-detect/rebase-aware-compare-urls-revision-history--4b161304

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented Apr 30, 2026

After a stack push that includes both a rebase onto a moved trunk and
content edits, the standard compare/old_sha...new_sha URL anchored at
merge-base(old, new) shows the user's actual changes mixed with every
upstream commit pulled in by the rebase. Reviewers see noise instead of
intent.

This change synthesises a "replay" commit per content-change push:
cherry-pick the previous PR head onto the new PR head's parent (via
git merge-tree --write-tree — no working-tree side effects), upload
it as an unreferenced commit through the GitHub Git Data API, and use
its SHA as the URL anchor for a clean rebase-aware diff. The visible
SHA-shorthand label still shows the actual old/new SHAs so users see
what they expect, and a small (raw) fallback link points at the
original three-dot URL — useful when GitHub eventually GCs the
unreferenced replay commit. Pure-rebase pushes (patch-IDs match) skip
the synthesis entirely and render a _(rebase only)_ badge with no
link, since the meaningful diff is empty.

Failure modes (cherry-pick conflict, missing parents, GitHub API
errors, git < 2.38) all return None silently and the renderer falls
back to the existing three-dot URL — no behaviour regression.

New module mergify_cli/stack/replay.py:

  • compute_merged_tree → runs git merge-tree --write-tree with
    parallel parent rev-parses, returns merged tree SHA + parent_new SHA
  • compute_tree_delta → parses git diff-tree -r --raw --no-renames
    into Git Data API tree entries, with mode/type preservation for
    executables, symlinks, and submodules
  • upload_replay_commit → POSTs the tree delta with base_tree then a
    parentless-of-new commit; returns the new commit SHA or None on
    any HTTP error
  • replay_for_revision → top-level orchestration with all-failure-mode
    fallback to None

Wired into stack_push: replay_for_revision runs concurrently per
"content"-classified PR (bounded by the existing
MAX_CONCURRENT_API_CALLS semaphore) before the force-push to GitHub.
The resulting replay SHA flows through the revision-history comment
data path as a new _RevisionEntry.replay_sha field, persisted in the
JSON marker for round-trip and re-render across subsequent pushes.

Tests: 12 new in test_replay.py (covering merge-tree clean/conflict,
tree-delta parsing for M/A/D/T statuses including submodule mode
preservation, two-stage API upload happy and partial-failure paths,
end-to-end orchestration including conflict / no-diff / rev-parse-tree
short-circuits) plus 5 new in test_push.py covering the data-model
round-trip, the rebase-only badge, the dual-link rendering with and
without replay_sha, and end-to-end propagation through stack_push.

Copilot AI review requested due to automatic review settings April 30, 2026 13:23
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 30, 2026 13:23 Failure
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 30, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 🤖 Continuous Integration

Wonderful, this rule succeeded.
  • all of:
    • check-success=ci-gate

🟢 👀 Review Requirements

Wonderful, this rule succeeded.
  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?:

🟢 🔎 Reviews

Wonderful, this rule succeeded.
  • #changes-requested-reviews-by = 0
  • #review-requested = 0
  • #review-threads-unresolved = 0

🟢 📕 PR description

Wonderful, this rule succeeded.
  • body ~= (?ms:.{48,})

@jd jd marked this pull request as ready for review April 30, 2026 13:24
@mergify mergify Bot requested a review from a team April 30, 2026 13:29
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a rebase-aware diff anchor for revision-history compare links by synthesizing and uploading a “replay” commit (so content-change pushes show only the user’s changes, not upstream rebase noise), and updates revision-history rendering/data to carry this anchor across pushes.

Changes:

  • Introduce mergify_cli/stack/replay.py to compute a merged tree via git merge-tree, derive a Git Data API tree delta, and upload an unreferenced replay commit.
  • Wire replay generation into stack_push and propagate a new replay_sha field through revision-history comment JSON markers and rendering (including a “rebase only” badge and optional raw fallback link).
  • Add/extend tests covering replay orchestration and revision-history round-trip/rendering behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
mergify_cli/stack/replay.py New module that computes and uploads a synthetic “replay” commit for clean compare URLs.
mergify_cli/stack/push.py Integrates replay computation into stack_push; extends revision-history entry model + rendering/marker persistence.
mergify_cli/tests/stack/test_replay.py New unit tests for merge-tree, diff-tree parsing, API upload, and orchestration fallbacks.
mergify_cli/tests/stack/test_push.py Updates existing tests and adds coverage for replay_sha propagation and rebase-only rendering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mergify_cli/stack/push.py Outdated
@jd jd force-pushed the devs/jd/worktree-rebase-detect/rebase-aware-compare-urls-revision-history--4b161304 branch from dfca0a7 to 55e9b3a Compare April 30, 2026 14:04
@jd
Copy link
Copy Markdown
Member Author

jd commented Apr 30, 2026

Revision history

# Type Changes Reason Date
1 initial dfca0a7 2026-04-30 14:04 UTC
2 content dfca0a7 → 55e9b3a (raw) 2026-04-30 14:04 UTC
3 content 55e9b3a → 3ce743d (raw) 2026-04-30 14:38 UTC

@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 30, 2026 14:04 Failure
After a stack push that includes both a rebase onto a moved trunk and
content edits, the standard `compare/old_sha...new_sha` URL anchored at
`merge-base(old, new)` shows the user's actual changes mixed with every
upstream commit pulled in by the rebase. Reviewers see noise instead of
intent.

This change synthesises a "replay" commit per content-change push:
cherry-pick the previous PR head onto the new PR head's parent (via
`git merge-tree --write-tree` — no working-tree side effects), upload
it as an unreferenced commit through the GitHub Git Data API, and use
its SHA as the URL anchor for a clean rebase-aware diff. The visible
SHA-shorthand label still shows the actual old/new SHAs so users see
what they expect, and a small `(raw)` fallback link points at the
original three-dot URL — useful when GitHub eventually GCs the
unreferenced replay commit. Pure-rebase pushes (patch-IDs match) skip
the synthesis entirely and render a `_(rebase only)_` badge with no
link, since the meaningful diff is empty.

Failure modes (cherry-pick conflict, missing parents, GitHub API
errors, git < 2.38) all return None silently and the renderer falls
back to the existing three-dot URL — no behaviour regression.

New module `mergify_cli/stack/replay.py`:
- compute_merged_tree → runs `git merge-tree --write-tree` with
  parallel parent rev-parses, returns merged tree SHA + parent_new SHA
- compute_tree_delta → parses `git diff-tree -r --raw --no-renames`
  into Git Data API tree entries, with mode/type preservation for
  executables, symlinks, and submodules
- upload_replay_commit → POSTs the tree delta with `base_tree` then a
  parentless-of-new commit; returns the new commit SHA or None on
  any HTTP error
- replay_for_revision → top-level orchestration with all-failure-mode
  fallback to None

Wired into `stack_push`: `replay_for_revision` runs concurrently per
"content"-classified PR (bounded by the existing
MAX_CONCURRENT_API_CALLS semaphore) before the force-push to GitHub.
The resulting replay SHA flows through the revision-history comment
data path as a new `_RevisionEntry.replay_sha` field, persisted in the
JSON marker for round-trip and re-render across subsequent pushes.

Tests: 12 new in `test_replay.py` (covering merge-tree clean/conflict,
tree-delta parsing for M/A/D/T statuses including submodule mode
preservation, two-stage API upload happy and partial-failure paths,
end-to-end orchestration including conflict / no-diff / rev-parse-tree
short-circuits) plus 5 new in `test_push.py` covering the data-model
round-trip, the rebase-only badge, the dual-link rendering with and
without replay_sha, and end-to-end propagation through `stack_push`.

Change-Id: I4b16130414084031dc79dc3de22fc1ae32334409
@jd jd force-pushed the devs/jd/worktree-rebase-detect/rebase-aware-compare-urls-revision-history--4b161304 branch from 55e9b3a to 3ce743d Compare April 30, 2026 14:38
@mergify mergify Bot deployed to Mergify Merge Protections April 30, 2026 14:38 Active
@mergify mergify Bot requested a review from a team May 4, 2026 07:20
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 4, 2026

Merge Queue Status

This pull request spent 12 minutes 19 seconds in the queue, including 11 minutes 46 seconds running CI.

Required conditions to merge

mergify Bot added a commit that referenced this pull request May 4, 2026
@mergify mergify Bot added the queued label May 4, 2026
@mergify mergify Bot merged commit 1b711ca into main May 4, 2026
22 checks passed
@mergify mergify Bot deleted the devs/jd/worktree-rebase-detect/rebase-aware-compare-urls-revision-history--4b161304 branch May 4, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

4 participants