Restructure Local Commit History
Reconstruct a continuous segment of unintegrated local development commits into a small number of understandable commits while keeping the final tree unchanged. A typical scenario is when AI generates a large number of interleaved fixes, patches, and mechanical commits, which need to be regrouped based on the final file content instead of mechanically squashing old commits.
Authorization and Boundaries
- When the user explicitly calls this skill or requests to recommit / rewrite history, it authorizes rewriting the local history within the confirmed scope; maintain read-only mode when only analysis or suggestions are requested.
- The default target branch is the current branch, the target endpoint is before the operation, and the baseline is local . If does not exist, use the baseline explicitly provided by the user; if neither exists, you must ask and must not arbitrarily switch to , common ancestor or guessed hash.
- Only rewrite unintegrated local commits. If the target commits have been merged into the baseline, other shared branches or published history, first explain the impact and obtain explicit confirmation.
- Do not fetch, pull, push, create PR or update remote endpoints. Publishing the rewritten branch is a separate operation, which usually requires the user to authorize separately.
- Do not modify the internal history or workspace of submodules. The parent repository gitlink can only be included if the target final tree originally contains its changes.
Pre-Operation Confirmation
Collect and judge at one time:
- Repository root, current branch, , baseline parsing result,
git status --short --branch
.
- Number of commits, topology, commit messages, author/committer dates and timezones of each commit, file changes and final diff in the range .
- Whether the baseline is an ancestor of , whether the range includes merge, signed commits, multi-author history, and whether the target commits are included in other local or remote tracking branches.
- Submodule/gitlink status, and checks required by repository instructions.
Stop if there are existing changes in the root working tree or index, to avoid mixing the user's current state with the content to be reconstructed via reset. Also ask first in the following situations:
- The baseline is not an ancestor of the old ; this has changed from organizing continuous history to transplanting the final tree to another baseline.
- The user only generically refers to "organizing history" but the range includes merges, and needs to decide whether to allow flattening the topology; if the user has explicitly requested to reset and recommit by file, flattening within this scope is authorized, but the lost merge topology must still be reported.
- Published, signed or multi-author history will lose signatures, topology or accurate attribution.
- It is impossible to approach the target number of commits without significantly breaking content boundaries.
After clarifying the conditions, save first:
- The hash and tree hash of the old .
- A unique, easily identifiable local recovery branch or tag, such as
backup/<branch>-before-recommit-<timestamp>
; the current time here is only used for naming the recovery reference, and must not be used for commit dates.
- Pre-operation status, branch inclusion relationship and submodule status, for verification at the end.
Do not reset until the recovery reference is successfully created.
Design New Commits
Complete grouping before rewriting history. The basis is the final file content, historical diff and dependency relationship of
; old commit messages can only be used as clues.
- If the user does not specify the number, first use
max(1, round(original number of commits × 20%))
as the planning target. It is not a rigid quota to force the count: if complete files and clear responsibilities naturally form fewer batches, you can continue to compress; if reasonable boundaries are obviously more, explain the deviation and ask if necessary.
- Prioritize grouping by independently understandable functions, fixes or closed-loop configurations; implementation, direct testing, necessary spec/docs and supporting lockfiles can be placed in the same commit.
- By default, a file is only assigned to one new commit, staged by full path, and patch staging is not used. When a file spans multiple old commits, assign its final version to the batch that best explains its complete responsibility.
- Renaming, deletion, generated files, manifest/lockfiles, migrations and gitlinks should be grouped in pairs or with their actual dependencies, not mechanically classified by file extension.
- Only when grouping complete files will cause obvious wrong boundaries and cannot be solved by adjusting batches, consider splitting the same file; first explain the reason and the minimal splitting scheme to the user.
- Arrange commits in the order of dependencies and reader understanding. Do not break content boundaries to replicate the old time order, nor claim that unverified intermediate commits can be built or run independently.
Before starting reset, you should be able to list the purpose of each batch, complete path set, intended commit message and selected old time source. Continue directly when the scope is clear and the user has explicitly requested rewriting; only request confirmation when there is substantial ambiguity in boundaries or quantity.
Reconstruct Commits
Use a reset method that retains the final content of the working tree to return to the confirmed baseline; prohibit
,
,
or deleting user files.
Execute batch by batch:
- Only stage the full paths explicitly listed in this batch; deletions and renames must also be correctly added to the index.
- Check
git diff --cached --name-status
and the actual staged diff, and run git diff --cached --check
to confirm no omissions, cross-batch files or additional changes generated by hooks.
- Generate a concise commit message from the real staged content, following the existing conventions of the repository; do not copy old messages that do not match the current batch, nor claim content that is not included or verified.
- Select a real old commit from the original scope as the time source, and reuse its complete author date and committer date verbatim, including seconds and timezone offset. Prioritize records related to the main files or milestones of this batch; if no content correspondence can be found, still only select from the original records, and ensure that the selected time increases reasonably in the order of new commits.
- Set with the original record's , set with its , then commit. Do not use current time, whole hours, rounded values, averages, manual adjustment of seconds or other fabricated times; do not copy the author date as the originally different committer date.
Empty commits are discarded by default. If a commit hook rewrites or generates files, stop immediately and recheck, do not automatically mix the new content into the next batch.
Verification and Delivery
After completion, verify at least the following:
- The tree hash of the new is exactly the same as the tree hash of the old saved in the recovery reference; tree equality is the hard threshold for ensuring unchanged final content.
- The working tree and index are clean; the submodule workspace status existing before the operation has not changed, and the final gitlink is consistent with the old tree.
- The number of new commits and its proportion to the original number of commits meet the user's requirements or the explained reasonable deviation.
- Check the , stat, message, author/committer time of each new commit, and confirm that the time values do exist in the original scope.
- Audit the occurrence times of each path in the new scope; except for explicitly approved exceptions, a file should not span multiple new commits.
- Run the mandatory repository checks and low-cost verification directly related to the final content. Only after actual execution can you claim to have passed.
Stop if any new commit fails or the final tree is inconsistent, do not push, do not delete the recovery reference. Prioritize returning to the recovery reference to redesign grouping, do not cover up errors with patch commits.
Finally report the baseline, number of old/new commits, compression ratio, new commit hash and subject, time source, tree equality, actual verification, recovery reference and remaining workspace status. Clearly state that it has not been pushed; do not actively delete the recovery reference.