commit-msg 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. #!/bin/sh
  2. commit_msg_file="$1"
  3. if [ ! -f "$commit_msg_file" ]; then
  4. echo "commit-msg hook error: commit message file not found"
  5. exit 1
  6. fi
  7. header="$(sed -n '/^[[:space:]]*#/!{/^[[:space:]]*$/!{p;q;}}' "$commit_msg_file")"
  8. if [ -z "$header" ]; then
  9. echo "Invalid commit message: empty message"
  10. exit 1
  11. fi
  12. case "$header" in
  13. Merge\ *|Revert\ *|fixup!\ *|squash!\ *)
  14. exit 0
  15. ;;
  16. esac
  17. type_pattern="feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|wip|workflow|types|release"
  18. commit_pattern="^($type_pattern)(\([a-z0-9][a-z0-9._/-]*\))?!?: .{1,}$"
  19. if ! printf '%s\n' "$header" | grep -Eq "$commit_pattern"; then
  20. echo "Invalid commit message format."
  21. echo ""
  22. echo "Expected Conventional Commits format:"
  23. echo " <type>[optional scope][optional !]: <description>"
  24. echo ""
  25. echo "Allowed types:"
  26. echo " feat, fix, docs, style, refactor, perf, test, build, ci, chore,"
  27. echo " revert, wip, workflow, types, release"
  28. echo ""
  29. echo "Examples:"
  30. echo " feat: add user search"
  31. echo " fix(backend): handle token expiry"
  32. echo " docs(readme): update setup guide"
  33. echo " refactor(web)!: remove legacy auth flow"
  34. exit 1
  35. fi
  36. exit 0