recommit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Recommit

Recommit

Rewrite the commits after a branch's merge base into a sequence where each commit tells one story and stands on its own. Preserve the final committed tree and leave the updated branch local. This skill reshapes history; it does not edit code.
Do not use this skill to change behavior, to rewrite commits that the target branch already contains, or on a branch that other people build on without coordination.
将分支合并基准之后的提交重写为每个提交都能独立完整地呈现一个变更故事的序列。保留最终提交树,并将更新后的分支保留在本地。本技能仅重构提交历史,不修改代码。
请勿使用本技能来变更代码行为、重写目标分支已包含的提交,或在未经协调的情况下对其他人基于其开发的分支进行操作。

Contract

约定

  • Start and end with a clean Git-visible working tree.
  • Rewrite only commits after the confirmed merge base.
  • Preserve the exact committed tree from the original branch tip.
  • Show the proposed sequence and the recovery point before the rewrite.
  • Stop before every push.
  • 操作前后保持Git可见的工作树处于干净状态。
  • 仅重写已确认的合并基准之后的提交。
  • 完全保留原始分支尖端的提交树。
  • 在重写前展示拟议的提交序列和恢复点。
  • 在每次推送前停止操作。

Workflow

工作流程

0. Pin the safe range

0. 确定安全范围

Require a named branch and a clean Git-visible working tree:
bash
git branch --show-current
git status --porcelain=v1 --untracked-files=all
Stop when the branch name is empty or the status output is not empty. A clean start makes the recorded branch tip a complete recovery point. When the tree is dirty because review fixes are still uncommitted, tell the user that
git commit --fixup=<sha>
, or
git absorb
when it is installed, turns them into
fixup!
commits that this skill folds.
Determine the target from PR or MR tracker metadata when it is available, and refresh its remote-tracking ref when a remote exists. Without tracker metadata, use
origin/HEAD
. Ask the user only when these sources are absent or disagree.
Validate the target and record these values:
bash
git rev-parse --verify <TARGET_REF>^{commit}
git rev-parse HEAD
git rev-parse HEAD^{tree}
git merge-base <TARGET_REF> HEAD
Call the target ref
TARGET_REF
and the outputs
ORIG
,
ORIG_TREE
, and
MERGE_BASE
; use the recorded literal values in later commands so they survive separate tool calls. Inspect the range shape (step 1 reads the full diff):
bash
git log <MERGE_BASE>..<ORIG> --oneline
git diff <MERGE_BASE>..<ORIG> --stat
The step is complete when the target is known, the range is non-empty, the starting state is clean, and all four recorded values are available.
需要指定命名分支且Git可见的工作树处于干净状态:
bash
git branch --show-current
git status --porcelain=v1 --untracked-files=all
若分支名称为空或状态输出非空,则停止操作。干净的初始状态会将记录的分支尖端作为完整的恢复点。若工作树因评审修复内容尚未提交而处于脏状态,请告知用户可使用
git commit --fixup=<sha>
,或在安装了
git absorb
时使用该工具,将这些内容转换为
fixup!
提交,以便本技能将其合并。
若PR或MR跟踪器元数据可用,则从中确定目标分支,若存在远程分支则刷新其远程跟踪引用。若无跟踪器元数据,则使用
origin/HEAD
。仅当这些来源缺失或不一致时,才询问用户。
验证目标分支并记录以下值:
bash
git rev-parse --verify <TARGET_REF>^{commit}
git rev-parse HEAD
git rev-parse HEAD^{tree}
git merge-base <TARGET_REF> HEAD
将目标引用称为
TARGET_REF
,输出结果分别称为
ORIG
ORIG_TREE
MERGE_BASE
;在后续命令中使用记录的字面量值,以便在不同工具调用中保持有效。检查范围形态(步骤1会读取完整差异):
bash
git log <MERGE_BASE>..<ORIG> --oneline
git diff <MERGE_BASE>..<ORIG> --stat
当目标分支明确、范围非空、初始状态干净且四个记录值均已获取时,本步骤完成。

1. Design the commit sequence

1. 设计提交序列

Read the complete diff of
MERGE_BASE..<ORIG>
and the existing commits. Then write the proposed commits in order. For each commit, state its title, its owned files or hunks, and the checks that validate it.
  • Give each commit one coherent purpose, independently buildable and testable.
  • Put behavior-preserving preparation before the behavior that uses it. A refactor that makes the change easy lands first.
  • Give a standalone improvement its own commit. A bug fix or UX fix that justifies itself without the feature is easier to review and revert alone.
  • Keep infrastructure with its first user. A commit that adds a mechanism nothing calls yet is dead code on arrival.
  • Put a dependency before the commit that uses it.
  • Keep generated files (lockfiles, translations, snapshots) with the change that requires them.
  • Combine changes when a split would make either commit invalid. Artificial atomization is as bad as a grab bag.
The step is complete when every changed path and hunk belongs to exactly one proposed commit and every proposed commit has a validation command or an explicit reason that none exists.
读取
MERGE_BASE..<ORIG>
的完整差异及现有提交记录,然后按顺序编写拟议的提交。对于每个提交,说明其标题、涉及的文件或代码块,以及验证该提交的检查项。
  • 每个提交应有一个连贯的目标,可独立构建和测试。
  • 将不改变行为的准备工作放在使用该准备工作的变更之前。例如,先提交使后续变更更易实现的重构代码。
  • 独立的改进应单独作为一个提交。无需依赖其他功能即可成立的bug修复或UX修复更易于评审和单独回退。
  • 基础设施变更应与首次使用它的提交放在一起。提交一个尚未被任何代码调用的机制会导致死代码。
  • 将依赖项放在使用该依赖项的提交之前。
  • 将生成文件(锁文件、翻译文件、快照)与需要它们的变更放在一起。
  • 若拆分提交会导致其中任何一个提交无效,则合并这些变更。人为的过度拆分与杂乱无章的提交同样糟糕。
当每个变更路径和代码块都恰好属于一个拟议提交,且每个拟议提交都有验证命令或明确说明无需验证的原因时,本步骤完成。

2. Show the plan

2. 展示计划

Show the confirmed target,
MERGE_BASE..<ORIG>
, the complete proposed sequence, and the recovery command
git reset --hard <ORIG>
. The rewrite changes only local history and that one command reverts it, so continue without waiting; the push in step 5 is the action that needs permission.
展示已确认的目标分支、
MERGE_BASE..<ORIG>
范围、完整的拟议提交序列,以及恢复命令
git reset --hard <ORIG>
。重写仅会改变本地历史,且该命令可恢复到初始状态,因此无需等待即可继续;步骤5中的推送操作需要获得许可。

3. Rebuild the history

3. 重构历史

Read REBUILD.md and use the method that matches the planned sequence. The step is complete when the local history matches the planned sequence and all final changes are committed.
阅读REBUILD.md并使用与计划序列匹配的方法。当本地历史与计划序列匹配且所有最终变更均已提交时,本步骤完成。

4. Verify the result

4. 验证结果

Check the state invariants from the Contract:
bash
test "<ORIG_TREE>" = "$(git rev-parse HEAD^{tree})"
test -z "$(git status --porcelain=v1 --untracked-files=all)"
Then use the temporary-worktree procedure in REBUILD.md to run the planned checks on every commit in
MERGE_BASE..HEAD
. Remaining changes from later commits must not be visible during an earlier commit's checks.
If an invariant or check fails, restore the clean starting point with
git reset --hard <ORIG>
, confirm that status is clean, and report the failed check. Recovery restores the recorded starting point, so it needs no separate permission.
The step is complete only when both invariants and every planned per-commit check pass.
检查约定中的状态不变量:
bash
test "<ORIG_TREE>" = "$(git rev-parse HEAD^{tree})"
test -z "$(git status --porcelain=v1 --untracked-files=all)"
然后使用REBUILD.md中的临时工作树流程,对
MERGE_BASE..HEAD
中的每个提交运行计划的检查项。在检查较早的提交时,后续提交的变更必须不可见。
若不变量或检查项失败,使用
git reset --hard <ORIG>
恢复到干净的初始状态,确认状态干净后报告失败的检查项。恢复操作会还原到记录的初始状态,因此无需单独获得许可。
仅当两个不变量和所有计划的每提交检查项均通过时,本步骤完成。

5. Stop

5. 停止操作

Show
git log <MERGE_BASE>..HEAD --reverse --oneline
, the saved
ORIG
, and the checks that passed. State that the branch is local and that updating its PR or MR requires
git push --force-with-lease
. Ask for explicit final permission immediately before that push. Do not push as part of this skill.
展示
git log <MERGE_BASE>..HEAD --reverse --oneline
的输出、保存的
ORIG
值,以及通过的检查项。说明分支当前仅存在于本地,更新其PR或MR需要使用
git push --force-with-lease
。在执行该推送操作前,立即请求用户明确的最终许可。本技能不包含推送操作。

Worked example

示例

A "Language setting" PR had two commits: a
_create_combo
refactor, then one grab-bag
feat
commit that bundled a generic dialog auto-sizing improvement, a
note
caption mechanism, and the language feature with 20 generated translation files. The planned sequence:
  1. refactor(settings): extract _create_combo
    holds the behavior-preserving preparation.
  2. feat(settings): fit the dialog height to the active tab
    holds the standalone UX fix, split out with cumulative hunk staging.
  3. feat: add a Language setting
    holds the feature, the
    note
    mechanism (nothing used it until here), and the generated translations.
The final tree matched
ORIG_TREE
, every commit passed lint and type checks in the temporary worktree, and the branch stayed local with the force-push left to the user.
一个"语言设置"PR包含两个提交:一个
_create_combo
重构提交,然后是一个包含通用对话框自动调整大小改进、
note
标题机制、语言功能及20个生成的翻译文件的杂乱
feat
提交。拟议的提交序列如下:
  1. refactor(settings): extract _create_combo
    包含不改变行为的准备工作。
  2. feat(settings): fit the dialog height to the active tab
    包含独立的UX修复,通过累积代码块暂存拆分出来。
  3. feat: add a Language setting
    包含语言功能、
    note
    机制(此前未被使用)及生成的翻译文件。
最终提交树与
ORIG_TREE
匹配,每个提交在临时工作树中均通过了lint和类型检查,分支保留在本地,强制推送操作由用户自行完成。