
Security News
Feross on the 10 Minutes or Less Podcast: Nobody Reads the Code
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.
better-commits
Advanced tools
A CLI for creating better commits following the conventional commits specification
A CLI for writing better commits, following the conventional commits specification.
https://github.com/Everduin94/better-commits/assets/14320878/8fb15d46-17c4-4e5d-80d9-79abe0a2a00a
better-branchAs a side-effect of formatting messages
npm install -g better-commits
To run the CLI in your terminal:
better-commits # Create a new commit
better-branch # Create a new branch
better-commits will prompt a series of questions. These prompts will build a commit message, which you can preview, before confirming the commit.
Some of the values in these prompts will be inferred by your branch name and auto populated. You can adjust this in your .better-commits.json configuration file.
To better understand these prompts and their intention, read Conventional Commits Summary
Your first time running better-commits, a default config will be generated in your $HOME directory, named .better-commits.json
To create a repository-specific config, navigate to the root of your project.
better-commits-init.better-commits.jsonconfirm_with_editor and overrides will prefer the global config[!NOTE]
All properties are optional and can be removed from the config. It will be replaced by the default at run-time.
- See
.better-commits.jsonin this repository as an example
{
"check_status": true,
"commit_type": {
"enable": true,
"initial_value": "feat",
"max_items": 20,
"infer_type_from_branch": true,
"append_emoji_to_label": false,
"append_emoji_to_commit": false,
"emoji_commit_position": "Start",
"options": [
{
"value": "feat",
"label": "feat",
"hint": "A new feature",
"emoji": "๐",
"trailer": "Changelog: feature"
},
{
"value": "fix",
"label": "fix",
"hint": "A bug fix",
"emoji": "๐",
"trailer": "Changelog: fix"
},
{
"value": "docs",
"label": "docs",
"hint": "Documentation only changes",
"emoji": "๐",
"trailer": "Changelog: documentation"
},
{
"value": "refactor",
"label": "refactor",
"hint": "A code change that neither fixes a bug nor adds a feature",
"emoji": "๐จ",
"trailer": "Changelog: refactor"
},
{
"value": "perf",
"label": "perf",
"hint": "A code change that improves performance",
"emoji": "๐",
"trailer": "Changelog: performance"
},
{
"value": "test",
"label": "test",
"hint": "Adding missing tests or correcting existing tests",
"emoji": "๐จ",
"trailer": "Changelog: test"
},
{
"value": "build",
"label": "build",
"hint": "Changes that affect the build system or external dependencies",
"emoji": "๐ง",
"trailer": "Changelog: build"
},
{
"value": "ci",
"label": "ci",
"hint": "Changes to our CI configuration files and scripts",
"emoji": "๐ค",
"trailer": "Changelog: ci"
},
{
"value": "chore",
"label": "chore",
"hint": "Other changes that do not modify src or test files",
"emoji": "๐งน",
"trailer": "Changelog: chore"
},
{
"value": "",
"label": "none"
}
]
},
"commit_scope": {
"enable": true,
"custom_scope": false,
"initial_value": "app",
"max_items": 20,
"options": [
{
"value": "app",
"label": "app"
},
{
"value": "shared",
"label": "shared"
},
{
"value": "server",
"label": "server"
},
{
"value": "tools",
"label": "tools"
},
{
"value": "",
"label": "none"
}
]
},
"check_ticket": {
"infer_ticket": true,
"confirm_ticket": true,
"add_to_title": true,
"append_hashtag": false,
"prepend_hashtag": "Never",
"surround": "",
"title_position": "start"
},
"commit_title": {
"max_size": 70
},
"commit_body": {
"enable": true,
"required": false,
"split_by_period": false
},
"commit_footer": {
"enable": true,
"initial_value": [],
"options": ["closes", "trailer", "breaking-change", "deprecated", "custom"]
},
"breaking_change": {
"add_exclamation_to_title": true
},
"confirm_commit": true,
"cache_last_value": true,
"confirm_with_editor": false,
"print_commit_output": true,
"branch_pre_commands": [],
"branch_post_commands": [],
"worktree_pre_commands": [],
"worktree_post_commands": [],
"branch_user": {
"enable": true,
"required": false,
"separator": "/"
},
"branch_type": {
"enable": true,
"separator": "/"
},
"branch_version": {
"enable": false,
"required": false,
"separator": "/"
},
"branch_ticket": {
"enable": true,
"required": false,
"separator": "-"
},
"branch_description": {
"max_length": 70,
"separator": ""
},
"branch_action_default": "branch",
"branch_order": ["user", "version", "type", "ticket", "description"],
"worktrees": {
"enable": true,
"base_path": "..",
"folder_template": "{{repo_name}}-{{ticket}}-{{branch_description}}"
},
"overrides": {
"shell": "/bin/sh"
}
}
[!NOTE]
Some properties allow a set of specific string values
- See config file explanations for possible values
Expand to see explanations and possible values
. refers to nesting. i.e. if a property is commit_type.enable then expect in the config for it to be:
"commit_type": {
"enable": true
}
| Property | Description |
|---|---|
check_status | If true run interactive git status |
commit_type.enable | If true include commit type |
commit_type.initial_value | Initial selection of commit type |
commit_type.max_items | Maximum number of type displayed on the screen |
commit_type.infer_type_from_branch | If true infer type from branch name |
commit_type.append_emoji_to_label | If true append emoji to prompt |
commit_type.append_emoji_to_commit | If true append emoji to commit |
commit_type.emoji_commit_position | Emoji position, "Start" (default) or "After-Colon" |
commit_type.options.value | Commit type prompt value |
commit_type.options.label | Commit type prompt label |
commit_type.options.hint | Commit type inline hint (like this) |
commit_type.options.emoji | Commit type emoji |
commit_type.options.trailer | Commit type trailer |
commit_scope.enable | If true include commit scope |
commit_scope.custom_scope | If true allow custom scope at run-time |
commit_scope.initial_value | Default commit scope selected |
commit_scope.max_items | Maximum number of scope displayed on the screen |
commit_scope.options.value | Commit scope value |
commit_scope.options.label | Commit scope label |
check_ticket.infer_ticket | If true infer ticket from branch name |
check_ticket.confirm_ticket | If true manually confirm inference |
check_ticket.add_to_title | If true add ticket to title |
check_ticket.append_hashtag | Deprecated: see prepend_hashtag |
check_ticket.prepend_hashtag | "Never" (default), "Prompt", or "Always" |
check_ticket.title_position | "start" (of description) (default), "end", "before-colon", "beginning" (of the entire commit title) |
check_ticket.surround | "" (default), "[]", "()", "{}" - Wraps ticket in title |
commit_title.max_size | Max size of title including scope, type, etc... |
commit_body.enable | If true include body |
commit_body.required | If true body is required |
commit_body.split_by_period | Automatically split sentences into new lines |
commit_footer.enable | If true include footer |
commit_footer.initial_value | Initial values selected in footer |
commit_footer.options | Footer options |
breaking_change.add_exclamation_to_title | If true adds exclamation mark to title for breaking changes |
confirm_commit | If true manually confirm commit at end |
confirm_with_editor | Confirm / Edit commit with $GIT_EDITOR / $EDITOR |
cache_last_value | Reuse last prompt value after cancel |
print_commit_output | If true pretty print commit preview |
overrides.shell | Override default shell, useful for windows users |
Branch configuration (same config file, split for readability)
| Property | Description |
|---|---|
branch_pre_commands | Array of shell commands to run before branching |
branch_post_commands | Array of shell commands to run after branching |
worktree_pre_commands | Array of shell commands to run before creating worktree |
worktree_post_commands | Array of shell commands to run after creating worktree |
branch_user.enable | If enabled include user name |
branch_user.required | If enabled require user name |
branch_user.separator | Branch delimeter - "/" (default), "-", "_" |
branch_type.enable | If enabled include type |
branch_type.separator | Branch delimeter - "/" (default), "-", "_" |
branch_ticket.enable | If enabled include ticket |
branch_ticket.required | If enabled require ticket |
branch_ticket.separator | Branch delimeter - "/", "-" (default), "_" |
branch_description.max_length | Max length branch name |
branch_description.separator | Branch delimeter - "" (default), "/", "-", "_" |
branch_version.enable | If enabled include version |
branch_version.required | If enabled require version |
branch_version.separator | Branch delimeter - "", "/" (default), "-", "_" |
branch_order | Order of branch name values (doesn't affect prompt order) |
branch_action_default | "branch" or "worktree" |
enable_worktrees | Deprecated see worktrees.enable |
worktrees.enable | If false, always default to branch action |
worktrees.base_path | Directory where worktrees are created (default: "..") |
worktrees.folder_template | Template for worktree folder names with variables like {{repo_name}}, {{branch_description}}, {{user}}, {{type}}, {{ticket}}, {{version}} |
better-commits will attempt to infer the ticket/issue and the commit-type from your branch name. It will auto populate the corresponding field if found.
Ticket / Issue-Number
STRING-NUMBER or NUMBER are at the start of the branch name or after a /Commit Type
/Better branch is a secondary feature that works with better commits
To run the CLI in your terminal:
better-branch
better-branch will prompt for Branch or Worktree. The Worktree flow creates a folder/worktree from your branch description and a git branch inside with your full branch name.
[!NOTE]
Creating a worktree namedeverduin94/feat/TAC-123-add-worktreeswith the native git command would create a nested folder for each/.better-branchremoves the hassle by creating 1 folder while still using the full name for the branch.
[!TIP] By default,
better-branchwill create worktrees as a sibling folder. To change this, seeworktrees.base_path.
Optionally configure pre and post checkout commands, for example:
npm install before branchingnpm run dev after branchingSee branch_pre_commands and branch_post_commands in default config. (or worktree_pre_commands and worktree_post_commands for creating worktrees)
better-commits works with Semantic Release
If you use better-commits to create your first commit on a new branch
If you're using Github issues to track your work, and select the closes footer option when writing your commit. Github will automatically link and close that issue when your pr is merged
better-commits can append a commit trailer per commit type. This allows you to automate change logs with tools like Gitlab.
better-commits uses native git commands under the hood. So any hooks, tools, or staging should work as if it was a normal commit.
Setting confirm_with_editor=true will allow you to edit/confirm a commit with your editor.
git config --global core.editor "nvim"git config --global core.editor "code -n --wait"You can add this badge to your repository to display that you're using a better-commits repository config
You can pass arguments to git through better-commits like so:
better-commits --git-dir="$HOME/.config" --work-tree="$HOME"
A practical example of this would be managing dotfiles, as described in this Atlassian Article
TTY initialization failed: uv_tty_init returned EBADF (bad file descriptor). This may happen because you're running something like git-bash on Windows. Try another terminal/command-prompt or winpty to see if its still an issue.
If your are having issues with multilines for commits on windows, you can override the shell via your .better-commits.json config.
Example
"overrides": {
"shell": "c:\\Program Files\\Git\\bin\\bash.exe"
}
FAQs
A CLI for creating better commits following the conventional commits specification
The npm package better-commits receives a total of 1,876 weekly downloads. As such, better-commits popularity was classified as popular.
We found that better-commits demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.

Research
/Security News
Campaign of 108 extensions harvests identities, steals sessions, and adds backdoors to browsers, all tied to the same C2 infrastructure.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.