Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.
/ cmt Public archive

Write consistent git commit messages based on a custom template

License

Notifications You must be signed in to change notification settings

smallhadroncollider/cmt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

12a69d3 · Jan 26, 2020
Jan 24, 2020
Nov 1, 2019
Feb 22, 2019
Jan 26, 2020
Jan 26, 2020
Jan 26, 2020
Mar 9, 2019
Feb 22, 2019
Jan 25, 2020
Feb 22, 2019
Feb 22, 2019
Mar 26, 2019
Feb 22, 2019
Feb 22, 2019
Jan 26, 2020
Feb 22, 2019
Jan 26, 2020
Jan 26, 2020
Jan 24, 2020
Jan 24, 2020

Repository files navigation

cmt

Write consistent git commit messages based on a custom template.

Similar idea to commitizen, but with an emphasis on making it easy to define a custom commit style.

Demo

Concept

It's important to write consistent commit messages, but depending on the project you may well want to use different commit styles.

With cmt you create a .cmt file in your project directory. The .cmt file enforces a particular style of commit message for that project. You can also add predefined commit messages for things like version bumps and updating the readme.

For example, for my programming projects I try to use a commit style similar to the AngularJS Commit Message Guidelines. However, this isn't appropriate for my teaching notes repos or for my capistrano build repos.

Format

A .cmt file consist of two parts: the input parts and the output format.

A basic .cmt file to include a subject and body would look like:

# The input parts
{
    "Subject" = @ # Single line input
    "Body" = !@ # Multi-line input
}

# predefined commit messages
# this section is optional
{
    vb = "version bump"
}

# The output format
${Subject}

${Body}

A more complex example, the AngularJS Commit Message Guidelines:

# The input parts
{
    # Shows a list of options
    "Type" = [
        "feat",
        "fix",
        "docs",
        "style",
        "refactor",
        "test",
        "chore"
    ]
    "Scope" = @ # Single line input
    "Subject" = @
    "Body" = !@ # Multi-line input
    "Footer" = !@
}

# predefined messages
# this section is optional
{
    vb = "chore: version bump"
    readme = "docs: updated readme"
}

# The output format
# Takes the values provided from the input stage
# and interpolates them in
${Type} (${Scope}): ${Subject}

${Body}

${Footer}

For my capistrano build repos the .cmt file is simply:

{}

"latest build"

Input Parts

These are at the top of the .cmt file and surrounded by opening and closing curly braces. A consist of a name and a type:

  • @: single line input
  • !@: multi line input
  • %: select from a list of staged files
  • ["option 1", "option 2"]: list of options

Predefined Messages

The predefined messages section is optional. You can provide a list of names and messages and then use the -p <name> command-line argument to use one of them.

For example, with the following config, cmt -p vb would use the message "version bump".

vb = "version bump"

Predefined messages can also use any input parts defined in the prior section. An example of this would be:

{
    "Project" = [
        "ghc",
        "cabal"
    ]
}
{
    vb = "${Project}: version bump"
}

Running cmt -p vb will now prompt you to select which project is getting version bumped.

Output Format

The output format consists of named input parts (${<name>}) plus anything else you want.

Wildcard Output

You can accept an output called ${*}, which will add in whatever is passed to cmt as command-line arguments.

For example:

# Input parts
# * input not needed, as comes from command-line
{
    "Scope" = %
}

# Scope from input and * from command-line
(${Scope}): ${*}

Then use with:

cmt "Blah blah blah"

Usage

Add a .cmt file to your project directory.

cmt # will show the options and then commit

cmt will also look in your home directory if a .cmt file isn't found in the project directory hierarchy. This can be used to define a global commit style, which you can then override on a per-project basis.

Predefined Messages

If there are commit message you use frequently (such as "version bump"), you can setup predefined messages with aliases:

cmt -p vb # use the version bump message

Wildcard Output

If you're using the ${*} format option then:

cmt "blah blah blah" # this will go in ${*} place

Dry Runs

If you add --dry-run as the first argument, cmt will show you the output, but not try and make a commit. It will store the output so you can easily run it without having to re-enter everything.

cmt --dry-run "Blah blah blah"
cmt --dry-run -p vb

Re-run Failed/Dry Run Commits

If the commit returns with a non-zero status code or you run with --dry-run, your previous commit message is stored in a .cmt.bkp file. You can re-run the commit when you're ready with:

cmt --prev

Colour Output

By default the output uses bash colour codes. You can turn this off using the --no-color setting.

Other Options

cmt -h # displays usage information
cmt -v # displays version number
cmt -c # displays location of .cmt file

Install

Binaries for Mac and Linux are available. Add the binary to a directory in your path (such as /usr/local/bin).

Cabal

Requirements: Cabal

cabal install cmt

Make sure you run cabal update if you haven't run it recently.

Building

Requirements: Stack

The following command will build cmt and then install it in ~/.local/bin:

stack build && stack install