Splitting a commit into reviewable pieces

SkillDev tools

Stack Claude Skill lets your agent split one large commit into small standalone commits in git or Jujutsu.

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the Splitting a commit into reviewable pieces skill

About this skill

Split one large or hard-to-review commit into several commits that each stand on their own for review, in a git or a Jujutsu (jj) checkout. Use when asked to split a commit or patch, break up a big diff for review, or make a lumped commit more reviewable. One commit at a time - `stack-reorganize` re

What this skill tells your AI

The instructions your AI receives, as published by mozilla-firefox/firefox in .agents/skills/stack-split-commit/SKILL.md and read by ahel’s review.

Split without changing the final tree. Every prefix of the result has to leave the tree building, linting and passing tests, and no commit's code or comments may mention a concept that only a later commit introduces; its message may say what it prepares for.

Pick the cuts by the rules below. Before the first commit or rebase, read the mechanics reference for this checkout's version control system in full: it holds the procedure, the whole-tree restore that makes the last piece free and the rules for editing at a rebase stop, none of which this file repeats. Use jj where the checkout has a .jj directory at its root: it rebases descendants for you and records conflicts instead of halting. Do not fall back to git commands there even if available.

  • Jujutsu (jj): references/jj.md
  • git: references/git.md

Split by concern, not by "new vs. deleted"

A reviewer checks a move or a replacement by diffing the new code against the code it replaces, so both go in the same commit.

  • A behavior-neutral move, such as inlining logic into a shared helper, is one commit, old-out and new-in side by side.
  • A genuine shape change, such as an IPDL message or a data-format swap, is a separate commit, again with old and new together.
  • A renamed file whose content also changes is two commits, even when the rename exists only to serve the change: the rename, with only the edits that update what names the old file (inside the file as well as outside it), then the change. Git stores no renames; its diff pairs a deleted path with an added one only when their contents are at least half the same, so a rename folded into a rewrite shows as a whole-file deletion beside a whole-file addition, with no diff between them, and blame and git log --follow stop at the new name. The target's diff hides such a pair the same way; the mechanics reference says how to find one.
  • A piece that both moves and changes behavior is split into the neutral move and the behavior change.
  • A piece that changes what existing code observes goes in one commit with that code's adaptation, even where no build or test would fail without it. Check each piece in both directions: what its new code needs from the pieces below it, and what existing code sees change once it lands.

A cut may need code that neither end state contains

The intermediate state often needs code written for it alone: a compatibility stub so the earlier commit still builds, or an interim form of a function that neither the parent nor the target has. Write it; a later commit removes it. Don't assume every piece falls out of the original diff.

Revisit each piece's message

The original's message now over-scopes, since it still describes what moved out: narrow it to its own piece, and write the new piece's message from scratch. The firefox-commits skill says what a message contains; what the split adds is a body line for what only the split made true, such as a claim of behavior-neutrality for a moved piece or an ordering that looks incidental but isn't. When a subagent builds the pieces, specify each subject and only the bodies that are warranted.

Review-tool side

Submitting the split creates the new revisions but leaves the stack's parent/child edges where they were. moz-phab reorg [start_rev] [end_rev] recomputes them from the local order and previews the changes before acting (docs/contributing/stack_quickref.md).

Stop if the preview proposes abandoning a revision. reorg abandons every revision that is in the remote stack but not in the local range (those already abandoned excepted), and narrowing the range grows that set: a WIP tip above the range and the landed floor of a partially-landed stack are remote-only under any range. --no-abandon re-wires the edges without the abandon transactions. Never re-push without explicit approval.

Splitting a revision that is already in review

Keep the original revision on the piece that retains the subject, usually the higher-level concept: it keeps the Differential Revision trailer, so its revision updates in place with a smaller diff, and the extracted piece lands as (New) below it. The submit does not make the retained revision depend on the new one; moz-phab reorg does, per above. Revisit both messages as above.

Signals

GitHub stars
13k
Forks
2k
Last commit
Sep 2026

ahel review

  • K4blow
    destructive-scoped (in references/git.md)

Automated review, not a security audit. Ruleset v1+k2.

Others that do the same job

Advanced
Item type
skill
Key
stack-split-commit
Source
github.com/mozilla-firefox/firefox