Skip to content

feat(rust): port stack edit + add rebase-todo machinery#1516

Open
jd wants to merge 1 commit into
devs/jd/feat/rust-stack-new/port-stack-note-native-rust--aff21093from
devs/jd/feat/rust-stack-new/port-stack-edit-add-rebase-todo-machinery--d6b5db4e
Open

feat(rust): port stack edit + add rebase-todo machinery#1516
jd wants to merge 1 commit into
devs/jd/feat/rust-stack-new/port-stack-note-native-rust--aff21093from
devs/jd/feat/rust-stack-new/port-stack-edit-add-rebase-todo-machinery--d6b5db4e

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented Jun 3, 2026

The Rust binary now serves mergify stack edit [<commit>]
natively. The Python implementation (mergify_cli/stack/edit.py,
its click registration, and mergify_cli/tests/stack/test_edit.py)
is removed in the same PR.

Third stack subcommand to land natively. More importantly,
this slice introduces the reusable rebase-todo machinery that
will unlock the rest of the rebase family in subsequent slices:

  • mergify_stack::rebase_todo::rewrite — pure transformer over
    the rebase-todo file git rebase -i would otherwise open in
    $GIT_EDITOR. Today it speaks one action (edit);
    drop/reword/fixup/reorder/move/squash
    land as additional Action variants when those ports
    follow. The pure split keeps the parser exhaustively unit-
    testable without spawning git.

  • mergify _internal rebase-todo-rewrite --action edit --sha <SHA> <TODO_PATH> — self-invocation target the
    orchestrating subcommand sets as GIT_SEQUENCE_EDITOR
    before git rebase -i. Hidden, unstable wire format,
    listed in NATIVE_COMMANDS so looks_native recognises
    it even when called from outside the stack subcommand path.

mergify stack edit <COMMIT>:

  1. Resolves the trunk (reusing the helper added with
    stack new) and computes git merge-base trunk HEAD.
  2. Walks the stack via local_commits::read and matches the
    <COMMIT> argument against either the SHA prefix or the
    Change-Id prefix (consistent with stack note).
  3. Spawns git rebase -i <base> with GIT_SEQUENCE_EDITOR
    pointing at this binary's
    _internal rebase-todo-rewrite subcommand, which marks
    the target commit's pick line as edit and writes the
    todo back. Git proceeds, pauses on that commit, and exits 0
    so the user can git commit --amend + git rebase --continue.

mergify stack edit (no argument) spawns the rebase
interactively — git opens $GIT_EDITOR on the full todo for
free-form editing. Same flow as Python's os.execvp fallback.

Exit-code mapping: StackNotFound for unresolved trunk or
unknown commit prefix, InvalidState for ambiguous Change-Id
prefix matches, GenericError for git invocation failures.
Empty stack prints No commits in the stack and exits 0,
matching Python.

End-to-end coverage lives in crates/mergify-cli/tests/stack_edit.rs
where CARGO_BIN_EXE_mergify resolves to the freshly-built
binary — spawning git rebase -i against a real repo
verifies the editor wiring end to end. The pure pieces (commit
prefix matching, todo rewriting) are unit-tested in
crates/mergify-stack.

Also ships mergify_stack::test_env::isolated_git — a test-
only helper that returns a Command with
GIT_CONFIG_GLOBAL=/dev/null and GIT_CONFIG_NOSYSTEM=1
pre-applied. Without it, the new git-spawning tests were
flaking under workspace cargo test because of contention
with the developer's global git config. Existing test helpers
in trunk.rs, local_commits.rs,
commands/{new,note,edit}.rs are routed through it.

Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com

Depends-On: #1515

@jd
Copy link
Copy Markdown
Member Author

jd commented Jun 3, 2026

This pull request is part of a Mergify stack:

# Pull Request Link
1 feat(rust): port stack note to native Rust #1515
2 feat(rust): port stack edit + add rebase-todo machinery #1516 👈
3 feat(rust): port stack drop to native Rust #1517
4 feat(rust): port stack fixup to native Rust #1518
5 feat(rust): port stack reword to native Rust #1519
6 feat(rust): port stack reorder + stack move to native Rust #1520
7 feat(rust): port stack squash to native Rust #1521
8 feat(rust): port stack checkout to native Rust #1522
9 feat(rust): port stack sync to native Rust #1523
10 feat(rust): port stack list + stack open to native Rust #1524

@mergify mergify Bot had a problem deploying to Mergify Merge Protections June 3, 2026 15:35 Failure
@jd jd temporarily deployed to func-tests-live June 3, 2026 15:35 — with GitHub Actions Inactive
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Jun 3, 2026

Merge Protections

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

🔴 ⛓️ Depends-On Requirements

Waiting for

This rule is failing.

Requirement based on the presence of Depends-On in the body of the pull request

🔴 👀 Review Requirements

Waiting for

  • #approved-reviews-by>=2
This rule is failing.
  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🔴 🔎 Reviews

Waiting for

  • #review-requested = 0
This rule is failing.
  • #review-requested = 0
  • #changes-requested-reviews-by = 0
  • #review-threads-unresolved = 0

🟢 🤖 Continuous Integration

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

🟢 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)(?:\(.+\))?:

🟢 📕 PR description

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

The Rust binary now serves ``mergify stack edit [<commit>]``
natively. The Python implementation (``mergify_cli/stack/edit.py``,
its click registration, and ``mergify_cli/tests/stack/test_edit.py``)
is removed in the same PR.

Third ``stack`` subcommand to land natively. More importantly,
this slice introduces the reusable rebase-todo machinery that
will unlock the rest of the rebase family in subsequent slices:

- ``mergify_stack::rebase_todo::rewrite`` — pure transformer over
  the rebase-todo file ``git rebase -i`` would otherwise open in
  ``$GIT_EDITOR``. Today it speaks one action (``edit``);
  ``drop``/``reword``/``fixup``/``reorder``/``move``/``squash``
  land as additional ``Action`` variants when those ports
  follow. The pure split keeps the parser exhaustively unit-
  testable without spawning git.

- ``mergify _internal rebase-todo-rewrite --action edit
  --sha <SHA> <TODO_PATH>`` — self-invocation target the
  orchestrating subcommand sets as ``GIT_SEQUENCE_EDITOR``
  before ``git rebase -i``. Hidden, unstable wire format,
  listed in ``NATIVE_COMMANDS`` so ``looks_native`` recognises
  it even when called from outside the stack subcommand path.

``mergify stack edit <COMMIT>``:

1. Resolves the trunk (reusing the helper added with
   ``stack new``) and computes ``git merge-base trunk HEAD``.
2. Walks the stack via ``local_commits::read`` and matches the
   ``<COMMIT>`` argument against either the SHA prefix or the
   ``Change-Id`` prefix (consistent with ``stack note``).
3. Spawns ``git rebase -i <base>`` with ``GIT_SEQUENCE_EDITOR``
   pointing at this binary's
   ``_internal rebase-todo-rewrite`` subcommand, which marks
   the target commit's ``pick`` line as ``edit`` and writes the
   todo back. Git proceeds, pauses on that commit, and exits 0
   so the user can ``git commit --amend`` + ``git rebase --continue``.

``mergify stack edit`` (no argument) spawns the rebase
interactively — git opens ``$GIT_EDITOR`` on the full todo for
free-form editing. Same flow as Python's ``os.execvp`` fallback.

Exit-code mapping: ``StackNotFound`` for unresolved trunk or
unknown commit prefix, ``InvalidState`` for ambiguous Change-Id
prefix matches, ``GenericError`` for git invocation failures.
Empty stack prints ``No commits in the stack`` and exits 0,
matching Python.

End-to-end coverage lives in ``crates/mergify-cli/tests/stack_edit.rs``
where ``CARGO_BIN_EXE_mergify`` resolves to the freshly-built
binary — spawning ``git rebase -i`` against a real repo
verifies the editor wiring end to end. The pure pieces (commit
prefix matching, todo rewriting) are unit-tested in
``crates/mergify-stack``.

Also ships ``mergify_stack::test_env::isolated_git`` — a test-
only helper that returns a ``Command`` with
``GIT_CONFIG_GLOBAL=/dev/null`` and ``GIT_CONFIG_NOSYSTEM=1``
pre-applied. Without it, the new git-spawning tests were
flaking under workspace ``cargo test`` because of contention
with the developer's global git config. Existing test helpers
in ``trunk.rs``, ``local_commits.rs``,
``commands/{new,note,edit}.rs`` are routed through it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Change-Id: Id6b5db4e7c418cb338b99c2b51f752b82d144260
@jd jd force-pushed the devs/jd/feat/rust-stack-new/port-stack-edit-add-rebase-todo-machinery--d6b5db4e branch from 2bed535 to 023c02f Compare June 3, 2026 21:01
@jd
Copy link
Copy Markdown
Member Author

jd commented Jun 3, 2026

Revision history

# Type Changes Reason Date
1 initial 2bed535 2026-06-03 21:01 UTC
2 content 2bed535 → 023c02f 2026-06-03 21:01 UTC

@jd jd temporarily deployed to func-tests-live June 3, 2026 21:01 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections June 3, 2026 21:01 Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant