@naverpay/commithelper-go
v1.5.0
Published
A CLI tool to assist with commit messages based on branch names and configuration.
Downloads
1,403
Maintainers
Keywords
Readme
@naverpay/commithelper-go
A Go-based CLI tool to assist your commit messages based on husky commit-msg hook.
Performance Comparison with @naverpay/commit-helper
@naverpay/commithelper-go is a Go-based rewrite of @naverpay/commit-helper with significant performance improvements:
- ⚡ Speed: 5-6x faster execution compared to Node.js version
- 📦 Memory: Lower memory footprint due to compiled binary
- 🚀 Startup: Instant startup time vs Node.js runtime initialization
- 🔧 Dependencies: Zero runtime dependencies after installation
Installation
npm install @naverpay/commithelper-goOr install globally:
npm install -g @naverpay/commithelper-goHow to use
.husky/commit-msg
node node_modules/@naverpay/commithelper-go/bin/cli.js "$1"
@latestis not necessary but this option always provides latest version of commithelper-go.
.lefthook.yml
commit-msg:
commands:
commithelper:
run: node node_modules/@naverpay/commithelper-go/bin/cli.js {1}[!TIP]
npxadds ~460ms of overhead even when the package is installed locally. Callingnode cli.jsdirectly takes ~76ms — about 6x faster thannpx. For hooks that run on every commit, directnodeinvocation is recommended.
What it does
Tag related issue
Automatically Add your related github issue number at your commit message through your branch name
➜ your-repo git:(feature/1) git add . && git commit -m ":memo: test"
ℹ No staged files match any configured task.
$ git branch --show-current
feature/1
[feature/1 1e70c244f] [#1] :memo: test
1 file changed, 1 insertion(+)Your issue number is automatically tagged based on your setting (.commithelperrc.json)
Tracker keys that already carry the project (Jira/Linear-style PROJ-1871) are supported too — see passthrough.
Blocking commit
- Blocks direct commit toward
main,developmasterbranch by throwing error on commit attempt. - To block specific branches, add at
protectfield oncommithelperrc.
Re-tagging (idempotency)
commithelper adds your current branch's reference unless that exact reference is already in the message, so re-running the hook or git commit --amend never duplicates the tag.
| Message already contains… | Result |
| --------------------------------------------------------- | ----------------------------------------------------- |
| the branch's reference (e.g. [#123], or #123 in body) | left unchanged |
| only a different issue's tag (e.g. [#999]) | branch's reference is still added → [#123] [#999] … |
| no reference | branch's reference is added |
Two consequences follow:
- commithelper only recognizes its own resolved reference, not other issue tags — a hand-written tag for a different issue does not stop it from adding the branch's reference.
- If the message body already mentions the branch's reference (e.g.
fixes #123onfeature/123), it is treated as already tagged and left as-is.
Configuration
commithelperrc
This is Basic rule of .commithelperrc.json.
{
"protect": ["main", "master", "develop"],
"rules": {
"feature": null,
"qa": "your-org/your-repo"
}
}extends
Inherit a shared base config. Accepts an HTTP/HTTPS URL or a local file path — useful for teams managing many repositories with a common set of rules.
Local file path (recommended for private registries):
{
"extends": "./node_modules/@my-org/commithelperrc/.commithelperrc.json",
"rules": {
"my-feature": "my-org/my-repo"
}
}Install the shared config as a dev dependency and reference it via a relative path. Works offline, versioned through package.json, no auth required.
Remote URL:
{
"extends": "https://raw.githubusercontent.com/my-org/.github/main/.commithelperrc.json",
"rules": {
"my-feature": "my-org/my-repo"
}
}Merge strategy (local always wins on conflict):
| Field | How merged |
| ------------- | ---------- |
| rules | base is the default; local key overrides on conflict |
| protect | union of base + local (deduped) |
| passthrough | union of base + local (deduped) |
| template | local wins; falls back to base if local is unset |
Constraints:
- Local path: relative paths are resolved from the current working directory (repo root).
- Remote URL: only
http://andhttps://are accepted. 10-second timeout. - The base config's own
extendsfield is ignored — no recursive loading. - Load failure is a fatal error (exits with code 1).
$schema (optional — editor autocompletion)
Add a $schema reference so your editor offers autocompletion, inline docs, and validation while editing .commithelperrc.json. The schema ships inside the installed package, so a relative path works offline (no CDN, Nexus-friendly):
{
"$schema": "./node_modules/@naverpay/commithelper-go/schema.json",
"rules": { "feature": null }
}Prefer the relative path above (resolved from the installed package) over a public CDN URL — consistent with this package shipping everything locally.
rules
- Key of rules field means branch prefix. By
featurekey, this rule is applied to branches named using thefeature/***pattern. - Value represents the repository to be tagged. For example, rule with value 'your-org/your-repo' tags 'your-org/your-repo#1'.
- A rule with a
nullvalue tags repository itself.
passthrough
For trackers whose issue key already contains the project (e.g. Jira/Linear PROJ-1871), the branch carries the full key — there is nothing to look up. passthrough lists the project keys to copy verbatim into the commit message, as opposed to rules, which translate a prefix into a repo reference.
{ "passthrough": ["PROJ", "OPS"] }A branch like feature/PROJ-1871 is tagged [PROJ-1871]. Only listed projects are recognized (OPS-9 is tagged only if OPS is listed), so unrelated UPPERCASE-NUMBER tokens such as UTF-8 are never mistaken for issues. Omit the field to disable verbatim tagging (rules still apply).
How a key is recognized. Recognition matches Jigit (the Jira↔Git integration), so a listed project links the same way in commithelper and Jigit. A key is <PROJECT>-<NUMBER> found anywhere in the branch:
PROJECT— an uppercase letter followed by uppercase letters/digits (≥2 chars:PROJ,OPS,AB,ABC2).NUMBER— 1–7 digits (an 8+ digit run is not a key).
| Branch (with ["PROJ"]) | Result | Why |
| ----------------------------- | ------------- | ------------------------------------------ |
| feature/PROJ-1871 | [PROJ-1871] | standard key |
| feature/PROJ-1871-add-login | [PROJ-1871] | trailing text after the number is ignored |
| feature/PROJ-1871-20260101 | [PROJ-1871] | a -<number> (date) suffix is ignored too |
| feature_PROJ-1871 | [PROJ-1871] | the key may appear anywhere in the branch |
| feature/OPS-42 | not tagged | OPS is not listed |
| feature/PROJ-12345678 | not tagged | the number has more than 7 digits |
| PROJECT/123 | not tagged | keys use -, not / (that's a rules prefix) |
rules (GitHub prefixes) take precedence over passthrough when a branch matches both.
protect
- Defines branches that are blocked from committing. Supports glob-style wildcard patterns.
*matches any sequence of characters except/?matches any single character except/[...]matches any character in the set- Note:
*does not match across/, sorelease/*matchesrelease/1.0but notrelease/1.0/hotfix. Userelease/*/*for nested branches.
{
"protect": ["main", "master", "develop", "release/*", "epic/*"]
}template
- Defines a custom format for commit messages using Go template syntax.
- If not specified, uses the default format:
[{{.Prefix}}] {{.Message}} - Available template variables:
{{.Message}}: Original commit message{{.Number}}: Issue number extracted from branch name{{.Repo}}: Repository name (empty string if not specified in rules){{.Prefix}}: Full reference (#123,org/repo#123, or a verbatim key likePROJ-1871)
- For
passthrough(verbatim) branches,{{.Prefix}}is the full key (e.g.PROJ-123) and{{.Number}}its number (123), while{{.Repo}}is empty — prefer{{.Prefix}}for templates that must work with both styles. - Put the reference in your template as
{{.Prefix}}for safe re-tagging: commithelper skips an already-tagged message by looking for that exact reference, so rendering it another way (e.g.#{{.Number}}for a repo-scoped or verbatim rule) can add it twice ongit commit --amend.
Template Examples
Example 1: Add issue reference at the end
{
"rules": {
"feature": null
},
"template": "{{.Message}}\n\nRef. [{{.Prefix}}]"
}Result:
:memo: Update documentation
Ref. [#123]Example 2: Custom format with repository
{
"rules": {
"qa": "your-org/your-repo"
},
"template": "{{.Message}}\n\nSee: {{.Prefix}}"
}Result:
:bug: Fix login bug
See: your-org/your-repo#456Example 3: Conditional formatting
{
"rules": {
"feature": null
},
"template": "[{{.Prefix}}] {{.Message}}"
}Result:
[#123] :sparkles: Add new featureExample
// .commithelperrc.json
{
"protect": ["epic"],
"rules": {
"feature": null,
"qa": "your-org/your-repo"
}
}For example as above,
- commit on
feature/1branch will be tagged as[#1].- commit on
qa/1branch will be tagged as[your-org/your-repo#1].- direct commit attempt toward
main,master,develop,epic/*branch will be blocked
Platform Support
The appropriate platform-specific binary package is automatically installed via optionalDependencies.
- macOS: Intel (x64) and Apple Silicon (arm64)
- Linux: x64
- Windows: x64
Q&A
- What happens if the commit is already tagged?
- If it already contains the reference for your current branch, it is left unchanged (safe on re-run /
git commit --amend). A tag for a different issue does not prevent your branch's reference from being added — see Re-tagging.
- If it already contains the reference for your current branch, it is left unchanged (safe on re-run /
- How does commithelper-go behaves on
feature/1_xxxfeature/1-xxxpatterned branch name?- It works same as
feature/1branch.
- It works same as
- What's the difference between
@naverpay/commit-helperand@naverpay/commithelper-go?commithelper-gois a Go-based rewrite with significantly better performance and lower resource usage.
License
MIT
