如何强制开发者使用指定提交信息模板?寻求跨Windows与Unix系统的兼容实现方案
The issue here is that your existing pre-commit hook relies on Bash-specific syntax (backticks for command substitution, grep -q, pipe operators) which won't work on Windows—Git hooks there run via Command Prompt (cmd.exe) by default, which doesn’t support those Bash features.
Here are two reliable cross-platform solutions that work seamlessly on both Windows and Unix-like systems:
Solution 1: Use a Node.js Script (Recommended)
Node.js is inherently cross-platform, so writing a small script avoids shell syntax inconsistencies entirely. Here's how to set it up:
Create a new file at your project root named
check-commit-template.js:const { execSync } = require('child_process'); try { // Fetch the current commit.template configuration const configuredTemplate = execSync('git config commit.template', { encoding: 'utf8' }).trim(); // Verify it matches our required .gitmessage file if (configuredTemplate !== '.gitmessage') { console.error('\x1b[31m%s\x1b[0m', 'Commit template not configured correctly!'); console.error('Please run: git config commit.template .gitmessage'); process.exit(1); } // If valid, run lint-staged as usual execSync('npx lint-staged', { stdio: 'inherit' }); } catch (error) { // Handle case where commit.template isn't set at all (git config exits with code 1) if (error.status === 1) { console.error('\x1b[31m%s\x1b[0m', 'Commit template not configured!'); console.error('Please run: git config commit.template .gitmessage'); process.exit(1); } // Propagate any other unexpected errors throw error; }Update your
package.jsonhusky configuration to use this script:"husky": { "hooks": { "pre-commit": "node check-commit-template.js" } }
This approach is clean, maintainable, and eliminates all OS-specific shell issues.
Solution 2: Inline Node.js One-Liner (For Quick Setup)
If you prefer not to add a separate file, you can embed the logic directly in your package.json with a Node.js one-liner:
"husky": { "hooks": { "pre-commit": "node -e \"const {execSync} = require('child_process'); try { const t = execSync('git config commit.template', {encoding:'utf8'}).trim(); if (t !== '.gitmessage') { console.error('Commit template not set correctly. Run: git config commit.template .gitmessage'); process.exit(1); } execSync('npx lint-staged', {stdio:'inherit'}); } catch(e) { if (e.status ===1) { console.error('Commit template not set. Run: git config commit.template .gitmessage'); process.exit(1); } throw e; }\"" } }
While this works, it’s less readable than the separate script approach, so the first solution is better for long-term maintenance.
Why Your Original Hook Failed
Windows' cmd.exe doesn’t understand Bash-specific features like:
- Backtick command substitution (
`git config ...`) - The
grep -qsilent matching flag - Pipe chaining directly in the
ifcondition
By switching to Node.js, you bypass all these shell-specific syntax limitations.
内容的提问来源于stack exchange,提问作者Ruan Mendes

