fix(uncheck): prevent an empty commit when the fixes undo every staged change - #10
Conversation
# Conflicts: # packages/uncheck/README.md # packages/uncheck/src/commands/staged.ts
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Important
Completing a merge whose resolved tree the fixes normalize back to HEAD's tree is blocked as an "empty commit", even though git would create that merge commit. lint-staged shares the limitation, but the PR body documents --amend and not merges — the inline note has a cheap guard.
Reviewed changes
staged.ts— after staging the fixes, compares the index tree (write-tree) againstHEAD^{tree}and fails when they match, adding aheadTreehelper that treats an unbornHEADas no tree.command.test.ts— adds a test for the empty case (with an unstaged hunk) and for a commit on an unborn branch; changes one prior test's base commit so its fix no longer produces an empty tree.README.md— documents the new failure.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏
There was a problem hiding this comment.
ℹ️ No new issues in the incremental changes —
--allow-emptyis implemented cleanly and covered by tests. The merge-commit concern from the prior review is unaffected by this commit and still stands.
Reviewed changes since the prior review
staged.ts— adds an--allow-emptyflag; the guard becomesempty && !allowEmpty, and the message now points at the flag instead ofgit commit --no-verify.prepare.ts— adds--allow-emptyand writes it into the hook command after--fix.command.test.ts— extends the empty-case test with a passing--allow-emptyrun and asserts the hook line in thepreparetest.README.md— notes--allow-emptyin both thestagedandprepareparagraphs.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏
There was a problem hiding this comment.
✅ No new issues found — the merge-commit concern from the prior review is now addressed with a working regression test.
Reviewed changes — reviewed the delta since the prior pullfrog review (b318240 → 0a8abea).
staged.ts— added amerginghelper (git rev-parse -q --verify MERGE_HEAD, mapped tofalseonGitFailed) and gated the empty check on!(yield* merging(cwd)), so a merge whose resolved tree the fixes normalize back toHEAD^{tree}is no longer blocked. Verified--verify MERGE_HEADexits non-zero outside a merge and prints its SHA during one.command.test.ts— added a regression test that concludes a--no-commit --no-ffmerge after re-staging content the formatter turns back intoHEAD's; its resolved tree matchesHEAD^{tree}, so it fails without the new guard.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏

uncheck staged --fixno longer lets git record an empty commit. git decides there is something to commit before it runs the pre-commit hook, so when the fixes turned the staged content back into what HEAD has, the commit went through with the same tree as its parent. The hook now fails instead, and--allow-emptylets such a commit through. Both follow lint-staged 17.Fixes
export const a=1over a committedexport const a = 1;, now fails with a message instead of recording an empty commit. This covers bothgit commitandgit commit <paths>.Behavior, as in lint-staged
uncheck staged --allow-emptylets the empty commit through, like lint-staged's flag of the same name.uncheck prepare --pre-commit --allow-emptywrites it into the hook line.--allow-empty, as lint-staged's "prevented an empty git commit" message does.git commit --amendwhose staged changes the fixes undo is refused too, as it is with lint-staged.git diff --staged --diff-filter=ACMR, so a commit that only has staged deletions left counts as empty there. uncheck compares the index tree withHEAD^{tree}, so that commit goes through.MERGE_HEADexists.Testing
--allow-empty, and a commit on an unborn branch. It fails without this change.MERGE_HEADcheck.preparetest checks that--allow-emptyis written into the hook line.uncheck staged#8 staged a change the formatter turns back into HEAD's content. It now commits a different base and still covers what it was written for.git commitorgit commit <path>, with--allow-emptygit records the empty commit, and that merge is recorded as a merge commit.