Visitar URL original
Read the Husky Hook's Path List Once, Diff a Merge Against MERGE_HEAD, and Drop the LF Pin by ptr727 · Pull Request #4132 · ptr727/ProjectTemplate · GitHub
Skip to content

Read the Husky Hook's Path List Once, Diff a Merge Against MERGE_HEAD, and Drop the LF Pin - #4132

Merged
ptr727 merged 1 commit into
developfrom
burndown/husky-snippet-gate
Nov 13, 2026
Merged

ptr727 merged 1 commit into
developfrom
burndown/husky-snippet-gate

Conversation

@ptr727

@ptr727 ptr727 commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • The path list is read once and its read is checked (The Husky Snippet's Prose Gate Skips Silently When Its Second git diff Fails #4122). Both the hub's own .husky/pre-commit and catalog/snippets/husky/pre-commit ran git diff --cached --name-only twice: a checked preflight, then an unchecked second run piped into xargs. Under POSIX sh a failure of the second run reached the gate as an empty list, which skips it. The list now goes to a mktemp file whose write is checked, and xargs reads that file. An EXIT trap removes it, and INT/TERM traps print one line and exit 130/143 so the EXIT trap runs under dash too.
  • The snippet diffs a merge commit against MERGE_HEAD (Judge a Merge Commit's Resolution, Not Its Merged-In Lines, in the Pre-Commit Prose Gate #4104). It now picks its base the way the hub's own hook already does, so the lines a merged-in parent brought are not read as added. After merging the target branch in, MERGE_HEAD is the merge base the pull request gate reads, so the hook and CI read the same lines. The issue floated the merge base of HEAD and MERGE_HEAD. That base would read the merged-in parent's own lines as added, which is the defect itself.
  • The snippet README drops the per-file LF pin (The Husky Snippet README Asks for a Per-File LF Pin That recurring.eol Forbids #4121). The paired LF defaults recurring.eol requires already give the hook LF. Only a repository whose two defaults are CRLF pins it. The hub hook's header line naming "the line-ending pins" is removed with it.
  • Tests. tests/test_pre_commit_hook.py now runs every case against both hooks. New cases fail the first or the second list read through a git stub and assert the commit is refused, and signal the hook mid-gate and assert the 130/143 status with the list file gone. Against the develop hooks, eight of the new or re-run cases fail. Against this branch, all 24 pass.

Pre-existing findings, filed

Local review findings declined

  • .husky/pre-commit:52-65 and catalog/snippets/husky/pre-commit:52-65, design (one primitive per defect class): the local pass suggested moving the base choice and the staged-list read into a prose_lint.py option. That file is a carried gate outside this change's scope, and the new option would change its interface. The two hooks already carried the same list read and xargs filter side by side before this change. Diff a Merge Commit Against MERGE_HEAD in the pre-commit Framework Snippet's Prose Gate #4131 records the prose_lint.py shape as the fix that would also reach the framework config.

Closes on promotion: #4122, #4104, #4121

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Commit checks now focus on staged, working-tree files and account for merge resolutions, reducing unrelated or generated content from being flagged.
    • Temporary check files are cleaned up when checks finish or are interrupted, and failures are reported with appropriate exit statuses.
  • Documentation

    • Clarified when copied commit hooks need explicit line-ending settings, including for repositories that use CRLF defaults.

…, and Drop the LF Pin

The prose gate's path list now goes to a temporary file whose write is checked, so a failed
list refuses the commit rather than reaching the gate as an empty list and skipping it. Both
the hub's own hook and the catalog snippet read the list twice before, checking only the read
that did not feed the gate. The file is removed on exit and on SIGINT or SIGTERM.

The snippet now diffs a merge commit against MERGE_HEAD, as the hub's own hook already does,
so the lines a merged-in parent brought are not read as added.

The snippet README no longer asks for a per-file LF pin the paired LF defaults already cover.

The hook tests now run against both hooks, and cover a failed list read and an interrupt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings November 13, 2026 05:36
@ptr727 ptr727 added the comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses label Nov 13, 2026
@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Both pre-commit hooks now use temporary files for staged-path lists and clean them up on exit. The Husky snippet selects MERGE_HEAD for merge commits and runs the prose gate on remaining working-tree files. Tests cover both hooks, including failures and signals.

Changes: Pre-commit prose gates

Layer / File(s) Summary
Hook path handling and line-ending guidance
.husky/pre-commit, catalog/snippets/husky/pre-commit, catalog/snippets/husky/README.md
The hooks store staged paths in temporary files, clean them up, and report SIGINT or SIGTERM with the corresponding exit status. The snippet selects MERGE_HEAD for merge commits, filters paths to working-tree files, and passes the selected base to the prose gate. The README documents when LF pins are needed.
Hook fixtures and behavior tests
tests/test_pre_commit_hook.py
The tests run both hooks in temporary repositories. They check merge behavior, staged-path filtering, failed path-list reads, temporary-file cleanup, and SIGINT and SIGTERM handling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

  • Issue 4122: The snippet now reads the staged path list into a temporary file and fails if that read fails.
  • Issue 4123: The hooks now handle SIGINT and SIGTERM with exit statuses 130 and 143.
  • Issue 4121: The README removes the instruction to always add a per-file LF pin.
  • Issue 4104: The snippet now uses MERGE_HEAD as the diff base for merge commits.
Merge Risk: Minimal · up to e2837

This change makes the pre-commit prose gate more robust: a failed staged-path read now refuses the commit instead of passing an empty list, merge commits are diffed against MERGE_HEAD, and temporary files are cleaned up on exit or interrupt. No merge-blocking risk was found. The author-reported pre-existing issue in the framework config is tracked separately as #4131.

Pre-merge checks: Passed 4

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the main changes in the PR: the hook reads the staged path list once, the snippet diffs merges against MERGE_HEAD, and the LF pin is removed. The raw summary and objectives confirm eac…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the main changes in the PR: the hook reads the staged path list once, the snippet diffs merges against MERGE_HEAD, and the LF pin is removed. The raw summary and objectives confirm each of these changes, so the title matches the changeset. It is long (17 words) but specific and not vague.

Finishing Touches

Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between fa06887 and e2837ea.

Files selected for processing: 4

  • .husky/pre-commit
  • catalog/snippets/husky/README.md
  • catalog/snippets/husky/pre-commit
  • tests/test_pre_commit_hook.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

@ptr727

ptr727 commented Nov 13, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head e2837ea124bf5bd8b45e1af2e94b40f32c762431, the content this pull request carries at that commit against develop, and it recorded 2 findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The change still has active moderate issues because the SIGINT/SIGTERM traps can exit the hook without terminating and waiting for the foreground prose-gate child, allowing it to outlive the commit.

2 open issues
What changed in this PR

This PR hardens both Husky pre-commit hooks by making staged-path handling reliable, aligning merge-commit diffing, and updating the snippet's line-ending guidance.

Changes:

  • Capture the staged path list once and clean it up on exit.
  • Diff merge commits against MERGE_HEAD.
  • Remove the unnecessary per-file LF pin guidance.
  • Expand tests across both hook implementations and interruption scenarios.
File Description
tests/​test_pre_commit_hook.py Extends coverage to both hooks, including merge behavior, failed path-list reads, cleanup, and signal handling.
catalog/​snippets/​husky/​README.md Removes the unnecessary per-file LF pin guidance in favor of the repository-wide defaults.
catalog/​snippets/​husky/​pre-commit Updates staged-path capture, merge-aware diffing, cleanup, and signal handling for the Husky snippet.
.husky/​pre-commit Updates the repository hook's staged-path capture, merge-aware diffing, cleanup, and signal handling.

Review effort: Lite

Comment thread .husky/pre-commit Resolved
Comment thread catalog/snippets/husky/pre-commit Resolved
@codecov

codecov Bot commented Nov 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.69%. Comparing base (fa06887) to head (e2837ea).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #4132   +/-   ##
========================================
  Coverage    76.69%   76.69%           
========================================
  Files           40       40           
  Lines        14146    14146           
========================================
  Hits         10849    10849           
  Misses        3297     3297           
Flag Coverage Δ
python-3.13 76.69% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ptr727

ptr727 commented Nov 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@ptr727

ptr727 commented Nov 13, 2026

Copy link
Copy Markdown
Owner Author

/review

@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ptr727
ptr727 merged commit 025da5c into develop Nov 13, 2026
14 checks passed
@ptr727
ptr727 deleted the burndown/husky-snippet-gate branch November 13, 2026 06:37
ptr727 added a commit that referenced this pull request Nov 13, 2026
… Rules (#4189)

## Summary

Promotes the backlog-burndown rounds and changes from other hub sessions
from `develop` to `main`.

- Hooks and the prose gate: #4132, #4134, #4136, #4145, #4152, #4184.
The Husky hook reads its path list once and diffs a merge against
`MERGE_HEAD`. Interrupts re-raise their signal, a Markdown code span
reads as quoted data, and the gate picks a commit's diff base and
recognizes a conflicted promotion's branch cut from `main`.
- Procedures and carried rules: #4133, #4139, #4141, #4149, #4166,
#4177, #4179, #4183, #4185. Resync, audit and check-this-repo procedure
gaps, code style and shell interrupt rules, review-loop gaps across four
skills, the context and delegation section of `AGENTS.md`, question
rules in governance, the promotion line in pull request bodies,
closing-keyword behavior on promotion, and the history-rewrite premise.
- Review and cleanup tooling: #4138, #4148, #4154, #4156, #4157, #4163,
#4164, #4168, #4174, #4180. Cleanliness reads, parked handoffs, the
backlog report's JSON output, exact inline script pins, trusted inputs,
env-file includes, the bounded review wait, side-reviewer matching, and
a Copilot billing-failure notice read as a refusal.
- Workflow and runbook contract: #4153, #4155, #4169, #4171, #4178,
#4182. The runtime-secrets check, a registry entry and spec references,
the Copilot runbook pointers, credential-free checkout steps, and the
deploy-key and runner wording.
- From other hub sessions: #4159 (a repository's own .NET line under a
fleet default), #4161 (the 1Password CLI as an optional host tool),
#4162 (Codex's Windows installer and one managed opencode copy). These
carry no promotion line.

#4182 carries no promotion line by design, and #4175 holds the split-out
part of #4057's scope. Both #1448 and #4175 stay open.

Fixes #1071
Fixes #1154
Fixes #1391
Fixes #1471
Fixes #1594
Fixes #1620
Fixes #1627
Fixes #1650
Fixes #1801
Fixes #2853
Fixes #3620
Fixes #3668
Fixes #3697
Fixes #3766
Fixes #3787
Fixes #3837
Fixes #3840
Fixes #3842
Fixes #3844
Fixes #3865
Fixes #3882
Fixes #3890
Fixes #3894
Fixes #3912
Fixes #3916
Fixes #3954
Fixes #4014
Fixes #4015
Fixes #4016
Fixes #4043
Fixes #4050
Fixes #4057
Fixes #4058
Fixes #4062
Fixes #4084
Fixes #4097
Fixes #4098
Fixes #4099
Fixes #4104
Fixes #4108
Fixes #4114
Fixes #4115
Fixes #4117
Fixes #4118
Fixes #4119
Fixes #4121
Fixes #4122
Fixes #4123
Fixes #4131
Fixes #4135
Fixes #4140
Fixes #4142
Fixes #4143
Fixes #4144
Fixes #4151

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants