cmt: Write consistent git commit messages

[ bsd3, command-line-tools, library, program ] [ Propose Tags ]

Please see the README on GitHub at

[Skip to Readme]
Versions [faq],,,
Dependencies attoparsec (>= && <0.14), base (>=4.7 && <5), classy-prelude (>=1.5.0 && <1.6), cmt, containers (>= && <0.7), directory (>= && <1.4), filepath (>= && <1.5), process (>= && <1.7), terminal-size (>= && <0.4), text (>= && <1.3) [details]
License BSD-3-Clause
Copyright Small Hadron Collider / Mark Wales
Author Small Hadron Collider / Mark Wales
Category Command Line Tools
Home page
Bug tracker
Source repo head: git clone
Uploaded by smallhadroncollider at Tue Mar 26 20:39:45 UTC 2019
Distributions NixOS:
Executables cmt
Downloads 191 total (55 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2019-03-26 [all 1 reports]


[Index] [Quick Jump]


Maintainer's Corner

For package maintainers and hackage trustees

Readme for cmt-

[back to package description]


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.



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.


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


A more complex example, the AngularJS Commit Message Guidelines:

# The input parts
    # Shows a list of options
    "Type" = [
    "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}



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" = [
    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"


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

Re-run Failed Commits

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

cmt --prev


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


Requirements: Cabal

cabal install cmt

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


Requirements: Stack

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

stack build && stack install