npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

git-commit-diy-hook

v1.1.0

Published

Add a fixed timestamp suffix to git commit titles via commit-msg hooks.

Readme

git-commit-diy-hook

Add a fixed timestamp suffix to the Git commit title.

为 Git commit 标题追加一个固定格式的时间后缀。

feat: demo <🐥 2026-05-07 10:11:14>

Configuration / 配置

Configure the consuming repository in package.json:

在使用方仓库的 package.json 中配置:

{
  "gitCommitDiyHook": {
    "allowedEmails": [
      "[email protected]",
      "[email protected]",
      "[email protected]",
      "[email protected]"
    ],
    "defaultTemplate": " <🐥 ${time}>",
    "formatByEmail": {
      "[email protected]": " <🚀 ${time}>",
      "[email protected]": " <🚀 ${time}>",
      "[email protected]": " 【🚀 ${time}】"
    }
  }
}

Config fields / 配置字段

| Field | Type | Default | Description | | --- | --- | --- | --- | | allowedEmails | string[] | undefined | If omitted, all users are enabled. If provided, only matching git config user.email values will trigger the hook. / 不配置时表示所有用户都启用;配置后只有匹配 git config user.email 的用户才会生效。 | | defaultTemplate | string | <🐥 ${time}> | Default suffix template. / 默认后缀模板。 | | formatByEmail | Record<string, string> | {} | Per-email template override. / 按邮箱覆盖模板。 |

Template rules / 模板规则

  1. ${time} is the built-in variable.

  2. ${time} resolves to YYYY-MM-DD HH:MM:SS.

  3. Email matching is case-insensitive and trims surrounding spaces.

  4. Users without a personal template in formatByEmail fall back to defaultTemplate.

  5. ${time} 是内置变量。

  6. ${time} 会被替换成 YYYY-MM-DD HH:MM:SS

  7. 邮箱匹配时会忽略大小写并自动去掉首尾空格。

  8. formatByEmail 中没有单独模板的用户会回退到 defaultTemplate

Configuration examples / 配置示例

Enable everyone with the default template / 全员启用默认模板

{
  "gitCommitDiyHook": {
    "defaultTemplate": " <🐥 ${time}>"
  }
}

Only enable a whitelist / 只对白名单用户启用

{
  "gitCommitDiyHook": {
    "allowedEmails": ["[email protected]", "[email protected]"]
  }
}

Different template by email / 不同邮箱使用不同模板

{
  "gitCommitDiyHook": {
    "allowedEmails": ["[email protected]", "[email protected]"],
    "defaultTemplate": " <🐥 ${time}>",
    "formatByEmail": {
      "[email protected]": " <🚀 ${time}>"
    }
  }
}

This package provides:

  1. a small CLI for commit-msg hooks
  2. a reusable core API for custom integrations

这个包同时提供:

  1. 可直接接入 commit-msg hook 的 CLI
  2. 可复用的核心 API,方便自定义集成

Table of contents / 目录

  1. Install / 安装
  2. Quick start / 快速开始
  3. Hook integration methods / 各种 Hook 接入方式
  4. Configuration / 配置
  5. CLI / 命令行
  6. API / 编程接口
  7. Behavior details / 行为说明
  8. Troubleshooting / 常见问题

Install / 安装

npm install -D git-commit-diy-hook

This package is usually installed as a development dependency in the consuming repository.

通常把它安装为业务仓库里的开发依赖。

Quick start / 快速开始

English

  1. Install the package in the target repository.
  2. Add gitCommitDiyHook configuration to that repository's package.json.
  3. Wire git-commit-diy-hook run "$1" into the repository's commit-msg hook.
  4. Commit as usual.

中文

  1. 在目标仓库中安装本包。
  2. 在目标仓库的 package.json 里添加 gitCommitDiyHook 配置。
  3. git-commit-diy-hook run "$1" 接到仓库的 commit-msg hook。
  4. 正常执行 git commit 即可。

Hook integration methods / 各种 Hook 接入方式

The core integration command is always:

核心接入命令始终是:

git-commit-diy-hook run "$1"

$1 is the commit message file path passed by Git, usually .git/COMMIT_EDITMSG.

$1 是 Git 传入的提交信息文件路径,通常是 .git/COMMIT_EDITMSG

1. Plain Git hook managed by this package / 使用本包直接管理原生 Git Hook

Use this when the repository does not already use a hook manager such as Husky or simple-git-hooks.

适用于仓库本身没有使用 Husky、simple-git-hooks 等 hook 管理器的情况。

npx git-commit-diy-hook install

What this command does:

这个命令会做以下事情:

  1. write a managed .git/hooks/commit-msg

  2. update that hook in place if it was previously generated by this package

  3. refuse to overwrite an unmanaged existing commit-msg hook

  4. 写入一个受管的 .git/hooks/commit-msg

  5. 如果该 hook 本来就是本包生成的,则原地更新

  6. 如果发现已有非本包生成的 commit-msg hook,则拒绝覆盖

The generated hook looks like this:

生成出来的 hook 大致如下:

#!/bin/sh
# git-commit-diy-hook managed hook
set -eu

ROOT="$(git rev-parse --show-toplevel)"
LOCAL_BIN="$ROOT/node_modules/.bin/git-commit-diy-hook"

if [ -x "$LOCAL_BIN" ]; then
  "$LOCAL_BIN" run "$1"
  exit 0
fi

if command -v git-commit-diy-hook >/dev/null 2>&1; then
  git-commit-diy-hook run "$1"
  exit 0
fi

echo "[git-commit-diy-hook] executable not found. Install dependencies or add the package to PATH." >&2
exit 1

.git/hooks/* files are local Git metadata and are not committed into the repository.

.git/hooks/* 属于本地 Git 元数据,不会进入仓库版本管理。

2. simple-git-hooks

If the repository already uses simple-git-hooks, add a commit-msg entry in package.json:

如果仓库已经使用 simple-git-hooks,在 package.json 中添加 commit-msg 配置:

{
  "scripts": {
    "prepare": "simple-git-hooks"
  },
  "simple-git-hooks": {
    "commit-msg": "git-commit-diy-hook run \"$1\""
  }
}

Then run dependency installation or the prepare script so the hook is installed:

然后执行依赖安装或手动执行 prepare,让 hook 真正落地:

npm install
# or
npm run prepare

3. Husky

If the repository already uses Husky, add a commit-msg hook that delegates to this package.

如果仓库已经使用 Husky,就在 Husky 的 commit-msg 里调用本包。

npx husky add .husky/commit-msg 'git-commit-diy-hook run "$1"'

An example .husky/commit-msg file:

示例 .husky/commit-msg 内容:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

git-commit-diy-hook run "$1"

4. Merge into an existing custom commit-msg hook / 合并到已有自定义 commit-msg Hook

If your repository already has a custom commit-msg script, do not overwrite it blindly. Add this command into your existing flow:

如果仓库已经有自己的 commit-msg 脚本,不要直接覆盖;把下面这行合并进现有流程即可:

git-commit-diy-hook run "$1"

Example:

示例:

#!/bin/sh
set -eu

# your own checks
./scripts/check-commit-message.sh "$1"

# append or replace the timestamp suffix
git-commit-diy-hook run "$1"

5. Any other hook manager / 其他 Hook 管理器

Any hook manager can integrate this package as long as it supports the commit-msg lifecycle and can pass the commit message file path.

只要某个 hook 管理器支持 commit-msg 生命周期,并且能把提交信息文件路径传进来,就可以接入本包。

Use the same command:

统一使用同一个命令:

git-commit-diy-hook run "$1"

CLI / 命令行

git-commit-diy-hook install

Install a managed native Git commit-msg hook into the current repository.

给当前仓库安装一个受管的原生 Git commit-msg hook。

git-commit-diy-hook install

git-commit-diy-hook run <message-file>

Transform the commit message file in place.

直接修改指定的提交信息文件。

git-commit-diy-hook run .git/COMMIT_EDITMSG

This is the command that hook scripts should call.

这就是各种 hook 脚本最终应该调用的命令。

API / 编程接口

import {
  DEFAULT_TIME_TEMPLATE,
  formatTimestamp,
  resolveGitCommitDiyHookRuntime,
  shouldRunForCurrentUser,
  transformCommitMessage,
} from 'git-commit-diy-hook';

const timestamp = formatTimestamp(new Date());

if (shouldRunForCurrentUser()) {
  const runtime = resolveGitCommitDiyHookRuntime();
  const nextMessage = transformCommitMessage(
    'feat: demo\n',
    timestamp,
    runtime.template ?? DEFAULT_TIME_TEMPLATE,
    runtime.knownTemplates,
  );
}

Useful exported functions:

常用导出方法:

  1. formatTimestamp(date?): format a date as YYYY-MM-DD HH:MM:SS

  2. transformCommitMessage(message, timestamp, template?, removableTemplates?): add or replace the suffix on the first commit title line

  3. resolveGitCommitDiyHookRuntime(cwd?): read config, current email, active template, and known templates

  4. shouldRunForCurrentUser(cwd?): check whether the current Git user should trigger the hook

  5. formatTimestamp(date?):把日期格式化为 YYYY-MM-DD HH:MM:SS

  6. transformCommitMessage(message, timestamp, template?, removableTemplates?):在标题首行追加或替换后缀

  7. resolveGitCommitDiyHookRuntime(cwd?):读取配置、当前邮箱、当前模板和所有已知模板

  8. shouldRunForCurrentUser(cwd?):判断当前 Git 用户是否应该触发 hook

Behavior details / 行为说明

  1. Only the first non-empty, non-comment line is modified.

  2. The rest of the commit body is preserved.

  3. Lines starting with # are preserved.

  4. If a known template already exists at the end of the title, it is replaced instead of duplicated.

  5. CRLF line endings are preserved.

  6. 只会修改第一行非空、且不是注释的内容。

  7. commit body 其他正文会保留。

  8. # 开头的注释行会保留。

  9. 如果标题末尾已经有已知模板生成的时间后缀,会替换而不是重复追加。

  10. 会保留 CRLF 换行格式。

Troubleshooting / 常见问题

The commit title is not changing / 提交时没有生效

Check the following:

检查以下几点:

  1. Is the repository actually running a commit-msg hook?

  2. If allowedEmails is configured, does it match git config user.email exactly?

  3. Is the package installed in the repository where you are committing?

  4. Are you using a hook manager such as Husky or simple-git-hooks but forgot to wire git-commit-diy-hook run "$1"?

  5. 当前仓库是否真的执行了 commit-msg hook?

  6. 如果配置了 allowedEmails,它是否和 git config user.email 完全匹配?

  7. 你提交的那个仓库里是否已经安装了本包?

  8. 是否使用了 Husky 或 simple-git-hooks,但没有把 git-commit-diy-hook run "$1" 接进去?

install refuses to overwrite commit-msg / install 拒绝覆盖已有 commit-msg

This means the repository already has an unmanaged commit-msg hook.

这说明仓库里已经有一个不是本包生成的 commit-msg hook。

Recommended handling:

推荐处理方式:

  1. keep the existing hook

  2. manually add git-commit-diy-hook run "$1" into that script

  3. 保留原来的 hook

  4. 手动把 git-commit-diy-hook run "$1" 合并进去

executable not found / 提示找不到可执行文件

The generated native hook first looks for:

原生受管 hook 会按这个顺序查找可执行文件:

  1. node_modules/.bin/git-commit-diy-hook
  2. global git-commit-diy-hook in PATH

If neither exists, install dependencies in the target repository first.

如果两者都不存在,请先在目标仓库中安装依赖。

Does .git/hooks/commit-msg get committed? / .git/hooks/commit-msg 会提交到仓库吗?

No. .git/hooks/* is local-only.

不会。.git/hooks/* 只存在于本地。

If you want a team-wide setup, prefer Husky or simple-git-hooks, because their configuration is stored in the repository.

如果你想让团队统一接入,优先使用 Husky 或 simple-git-hooks,因为它们的配置是放在仓库里的。