fix(aios-commit): --vault commits a staged rename as a rename - #188
Merged
chuycepeda merged 2 commits intoSep 29, 2026
Merged
Conversation
With rename detection on (git diff's default), a rename already staged in the real index (`git mv`, an editor that stages its moves) listed only its new name in the --vault sweep. The commit, built from HEAD, added the new path and never removed the old one: both names landed in HEAD. The sweep's diff calls now pass --no-renames, so both sides are listed. A duplicate left by the old sweep is removed by the next --vault commit, since the old file is no longer on disk. tests/aios-commit.test.sh covers git mv, plain mv, the old hook pinned by sha, and the healing run. The commit-scan test's git shim now also matches the new argv. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
|
Thank you, Matías. This shipped in v0.8.6 (merged via #195). One follow-up on top: after a staged rename, the post-commit index sync tried to add the old path, which no longer exists, and printed a false warning. It now skips paths that are gone from both the disk and the index, and the test checks that no warning appears and the status is clean. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
aios-commit --vaultcould commit a rename as a copy. When the rename was already staged in the real index, both names ended up in HEAD. That happens withgit mv, or with an editor that stages its own moves.The cause is that the sweep lists paths with
git diff --name-only HEAD, and rename detection is on by default forgit diff. A staged rename is therefore reported only under its new name. The commit is built in a throwaway index seeded from HEAD, so it added the new path and kept the old one. A plainmvwith nothing staged was unaffected, because it shows as a deletion plus an untracked file, and that is why this hid.Fix
--no-renameson both of the sweep's diff calls: the one against HEAD, and the--cachedone for a repo with no commits yet. Both sides of a rename are then listed. The pathspec is unchanged, so a move into or out ofvault/contributes only the side inside it.A vault that already holds a duplicate heals itself. The old file is no longer on disk, so the next
--vaultrun reports it as a deletion.Proof
tests/aios-commit.test.sh, which already runs in both CI lanes, gains four cases:git mvthen--vault: HEAD holds only the new name.mvthen--vault: HEAD holds only the new name, the control.git mvagainst the hook pinned at the pre-change commit: both names land in HEAD. This case is skipped with a message when that commit is absent.Removing
--no-renamesfails the first case.tests/commit-scan-fail-closed.test.shfails one sweep call through a git shim matched on the exact argv, so the shim now matches the new argv too. 34 pass under bash 5 and bash 3.2, and the fulltests/run passes.Scope
hooks/aios-commit(two flags and a comment), the two tests, and the CHANGELOG entry. It closes the lastaios-commititem from the hooks audit in the series announced in #158.🤖 Generated with Claude Code