{"id":15403665,"url":"https://github.com/ana06/git-cop","last_synced_at":"2025-06-25T08:05:09.739Z","repository":{"id":98170369,"uuid":"95652554","full_name":"Ana06/git-cop","owner":"Ana06","description":"Enforces consistent Git commits.","archived":false,"fork":false,"pushed_at":"2017-09-26T06:59:09.000Z","size":313,"stargazers_count":0,"open_issues_count":0,"forks_count":12,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-24T12:18:54.073Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.alchemists.io","language":"Ruby","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ana06.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-28T09:29:44.000Z","updated_at":"2025-01-30T00:27:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"97872f5d-b059-419d-afbe-3ec894e116ae","html_url":"https://github.com/Ana06/git-cop","commit_stats":{"total_commits":165,"total_committers":2,"mean_commits":82.5,"dds":"0.024242424242424288","last_synced_commit":"c43d645543f0a6be286f8dcb5c52cbf60adc0bcf"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Ana06/git-cop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ana06%2Fgit-cop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ana06%2Fgit-cop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ana06%2Fgit-cop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ana06%2Fgit-cop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ana06","download_url":"https://codeload.github.com/Ana06/git-cop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ana06%2Fgit-cop/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261832634,"owners_count":23216495,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T16:09:35.120Z","updated_at":"2025-06-25T08:05:09.684Z","avatar_url":"https://github.com/Ana06.png","language":"Ruby","funding_links":["https://www.patreon.com/bkuhlmann"],"categories":[],"sub_categories":[],"readme":"# Git Cop\n\n[![Gem Version](https://badge.fury.io/rb/git-cop.svg)](http://badge.fury.io/rb/git-cop)\n[![Code Climate GPA](https://codeclimate.com/github/bkuhlmann/git-cop.svg)](https://codeclimate.com/github/bkuhlmann/git-cop)\n[![Code Climate Coverage](https://codeclimate.com/github/bkuhlmann/git-cop/coverage.svg)](https://codeclimate.com/github/bkuhlmann/git-cop)\n[![Gemnasium Status](https://gemnasium.com/bkuhlmann/git-cop.svg)](https://gemnasium.com/bkuhlmann/git-cop)\n[![Circle CI Status](https://circleci.com/gh/bkuhlmann/git-cop.svg?style=svg)](https://circleci.com/gh/bkuhlmann/git-cop)\n[![Patreon](https://img.shields.io/badge/patreon-donate-brightgreen.svg)](https://www.patreon.com/bkuhlmann)\n\nEnforces Git rebase workflow with consistent Git commits for a clean and easy to read/debug project\nhistory.\n\n\u003c!-- Tocer[start]: Auto-generated, don't remove. --\u003e\n\n## Table of Contents\n\n  - [Features](#features)\n  - [Screencasts](#screencasts)\n  - [Requirements](#requirements)\n  - [Setup](#setup)\n    - [Install](#install)\n    - [Configuration](#configuration)\n      - [Enablement](#enablement)\n      - [Severity Levels](#severity-levels)\n      - [Regular Expressions](#regular-expressions)\n    - [Rake](#rake)\n  - [Usage](#usage)\n    - [Command Line Interface (CLI)](#command-line-interface-cli)\n    - [Git Hooks](#git-hooks)\n      - [Commit Message](#commit-message)\n      - [Post Commit](#post-commit)\n    - [Continuous Integration (CI)](#continuous-integration-ci)\n      - [Circle CI](#circle-ci)\n      - [Travis CI](#travis-ci)\n  - [Cops](#cops)\n    - [Commit Author Email](#commit-author-email)\n    - [Commit Author Name Capitalization](#commit-author-name-capitalization)\n    - [Commit Author Name Parts](#commit-author-name-parts)\n    - [Commit Body Bullet](#commit-body-bullet)\n    - [Commit Body Bullet Capitalization](#commit-body-bullet-capitalization)\n    - [Commit Body Issue Tracker Link](#commit-body-issue-tracker-link)\n    - [Commit Body Leading Line](#commit-body-leading-line)\n    - [Commit Body Leading Space](#commit-body-leading-space)\n    - [Commit Body Line Length](#commit-body-line-length)\n    - [Commit Body Paragraph Capitalization](#commit-body-paragraph-capitalization)\n    - [Commit Body Phrase](#commit-body-phrase)\n    - [Commit Body Presence](#commit-body-presence)\n    - [Commit Body Single Bullet](#commit-body-single-bullet)\n    - [Commit Subject Length](#commit-subject-length)\n    - [Commit Subject Prefix](#commit-subject-prefix)\n    - [Commit Subject Suffix](#commit-subject-suffix)\n  - [Style Guide](#style-guide)\n    - [General](#general)\n    - [Commits](#commits)\n    - [Branches](#branches)\n    - [Tags](#tags)\n    - [Rebases](#rebases)\n    - [Pull Requests](#pull-requests)\n    - [GitHub](#github)\n  - [Tests](#tests)\n  - [Versioning](#versioning)\n  - [Code of Conduct](#code-of-conduct)\n  - [Contributions](#contributions)\n  - [License](#license)\n  - [History](#history)\n  - [Credits](#credits)\n\n\u003c!-- Tocer[finish]: Auto-generated, don't remove. --\u003e\n\n## Features\n\n- Enforces a [Git Rebase Workflow](http://www.bitsnbites.eu/a-tidy-linear-git-history).\n- Enforces a clean and consistent Git commit history.\n- Provides Continuous Integration (CI) build server support.\n- Provides Git Hook support for local use.\n- Provides a customizable suite of style cops.\n\n## Screencasts\n\n[![asciicast](https://asciinema.org/a/131420.png)](https://asciinema.org/a/131420)\n\n## Requirements\n\n0. [Ruby 2.4.1](https://www.ruby-lang.org)\n\n## Setup\n\n### Install\n\nFor a secure install, type the following (recommended):\n\n    gem cert --add \u003c(curl --location --silent https://www.alchemists.io/gem-public.pem)\n    gem install git-cop --trust-policy MediumSecurity\n\nNOTE: A HighSecurity trust policy would be best but MediumSecurity enables signed gem verification\nwhile allowing the installation of unsigned dependencies since they are beyond the scope of this\ngem.\n\nFor an insecure install, type the following (not recommended):\n\n    gem install git-cop\n\n### Configuration\n\nThis gem can be configured via a global configuration:\n\n    ~/.config/git-cop/configuration.yml\n\nIt can also be configured via [XDG environment variables](https://github.com/bkuhlmann/runcom#xdg)\nas provided by the [Runcom](https://github.com/bkuhlmann/runcom) gem.\n\nThe default configuration is:\n\n    :commit_author_email:\n      :enabled: true\n      :severity: :error\n    :commit_author_name_capitalization:\n      :enabled: true\n      :severity: :error\n    :commit_author_name_parts:\n      :enabled: true\n      :severity: :error\n      :minimum: 2\n    :commit_body_bullet:\n      :enabled: true\n      :severity: :error\n      :blacklist:\n        - \"\\\\*\"\n        - \"•\"\n    :commit_body_bullet_capitalization:\n      :enabled: true\n      :severity: :error\n      :whitelist: \"\\\\-\"\n    :commit_body_issue_tracker_link:\n      :enabled: true,\n      :severity: :error\n      :blacklist:\n        - \"(f|F)ix(es|ed)?\\\\s\\\\#\\\\d+\"\n        - \"(c|C)lose(s|d)?\\\\s\\\\#\\\\d+\"\n        - \"(r|R)esolve(s|d)?\\\\s\\\\#\\\\d+\"\n        - \"github\\\\.com\\\\/.+\\\\/issues\\\\/\\\\d+\"\n    :commit_body_leading_line:\n      :enabled: false\n      :severity: :warn\n    :commit_body_leading_space:\n      :enabled: true\n      :severity: :error\n    :commit_body_line_length:\n      :enabled: true\n      :severity: :error\n      :length: 72\n    :commit_body_paragraph_capitalization:\n      :enabled: true\n      :severity: :error\n    :commit_body_phrase:\n      :enabled: true\n      :severity: :error\n      :blacklist:\n        - obviously\n        - basically\n        - simply\n        - of course\n        - just\n        - everyone knows\n        - however\n        - easy\n    :commit_body_presence:\n      :enabled: false\n      :severity: :warn\n      :minimum: 1\n    :commit_body_single_bullet:\n      :enabled: true\n      :severity: :error\n      :whitelist: \"\\\\-\"\n    :commit_subject_length:\n      :enabled: true\n      :severity: :error\n      :length: 72\n    :commit_subject_prefix:\n      :enabled: true\n      :severity: :error\n      :whitelist:\n        - Fixed\n        - Added\n        - Updated\n        - Removed\n        - Refactored\n    :commit_subject_suffix:\n      :enabled: true\n      :severity: :error\n      :whitelist:\n        - \"\\\\.\"\n\nFeel free to take this default configuration, modify, and save as your own custom\n`configuration.yml`.\n\n#### Enablement\n\nBy default, most cops are enabled. Accepted values are `true` or `false`. If you wish to disable a\ncop, set it to `false`.\n\n#### Severity Levels\n\nBy default, most cops are set to `error` severity. If you wish to reduce the severity level of a\ncop, you can set it to `warn` instead. Here are the accepted values and what each means:\n\n- `warn`: Will count as an issue and display a warning but will not cause the program/build to\n  fail. Use this if you want to display issues as reminders or cautionary warnings.\n- `error`: Will count as an issue, display error output, and cause the program/build to fail. Use\n  this setting if you want to ensure bad commits are prevented.\n\n#### Regular Expressions\n\nSome cops support *whitelist* or *blacklist* options. These lists can consist of strings, regular\nexpressions, or a combination thereof. Regardless of your choice, all lists are automatically\nconverted to regular expression for use by the cops. This means a string like `\"example\"` becomes\n`/example/` and a regular expression of `\"\\\\AExample.+\"` becomes `/\\AExample.+/`.\n\nIf you need help constructing complex regular expressions for these lists, try launching an IRB\nsession and using `Regexp.new` or `Regexp.escape` to experiment with the types of words/phrases you\nwant to turn into regular expressions. *For purposes of the YAML configuration, these need to be\nexpressed as strings with special characters escaped properly for internal conversion to a regular\nexpression.*\n\n### Rake\n\nThis gem provides optional Rake tasks. They can be added to your project by adding the following\nrequirement to the top of your `Rakefile`:\n\n    require \"git/cop/rake/setup\"\n\nNow, when running `bundle exec rake -T`, you'll see `git_cop` included in the list.\n\nIf you need a concrete example, check out the [Rakefile](Rakefile) of this project for details.\n\n## Usage\n\n### Command Line Interface (CLI)\n\nFrom the command line, type: `git-cop --help`\n\n    git-cop --hook                # Add Git Hook support.\n    git-cop -c, [--config]        # Manage gem configuration.\n    git-cop -h, [--help=COMMAND]  # Show this message or get help for a command.\n    git-cop -p, [--police]        # Check feature branch for issues.\n    git-cop -v, [--version]       # Show gem version.\n\nTo check if your Git commit history is clean, run: `git-cop --police`. It will exit with a failure\nif at least one issue, with error severity, is detected.\n\nThis gem does not check commits on `master`. This is intentional as you would, generally, not want\nto rewrite or fix commits on `master`. This gem is best used on feature branches as it automatically\ndetects all commits made since `master` on the feature branch.\n\nHere is an example workflow, using gem defaults with issues detected:\n\n    cd example\n    git checkout -b test\n    touch text.txt\n    git add --all .\n    git commit --message \"This is a bogus commit message that is also terribly long and will word wrap\"\n    git-cop --police\n\n    # Output:\n    Running Git Cop...\n\n    83dbad531d84a184e55cbb38c5b2a4e5fa5bcaee (Brooke Kuhlmann, 0 seconds ago): This is a bogus commit message that is also terribly long and will word wrap\n      Commit Body Presence Warning. Use minimum of 1 line (non-empty).\n      Commit Subject Length Error. Use 72 characters or less.\n      Commit Subject Prefix Error. Use: /Fixed/, /Added/, /Updated/, /Removed/, /Refactored/.\n      Commit Subject Suffix Error. Use: /\\./.\n\n    1 commit inspected. 4 issues detected (1 warning, 3 errors).\n\n### Git Hooks\n\nThis gem supports\n[Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks).\n\nIt is *highly recommended* you manage Git Hooks as global scripts as it'll reduce project\nmaintenance costs for you. To configure global Git Hooks, add the following to your `~/.gitconfig`:\n\n    [core]\n      hooksPath = ~/.git_template/hooks\n\nThen you can customize Git Hooks for all of your projects.\n[Check out these examples](https://github.com/bkuhlmann/dotfiles/tree/master/home_files/.git_template/hooks).\n\nIf using a global configuration is not desired, you can add Git Hooks at a per project level by\nediting any of the scripts within the `.git/hooks` directory of the repository.\n\n#### Commit Message\n\nThe *commit-msg* hook, which is the best way to use this gem as a Git Hook, is provided as a\n`--hook` option. Run `git-cop --help --hook` for usage:\n\n    Usage:\n      git-cop --hook\n\n    Options:\n      [--commit-message=PATH]  # Check commit message.\n\n    Add Git Hook support.\n\nAs shown above, the `--commit-message` option accepts a file path (i.e. `.git/COMMIT_EDITMSG`) which\nis provided to you by Git within the `.git/hooks/commit-msg` script. Here is a working example of\nwhat that script might look like:\n\n    #! /usr/bin/env bash\n\n    set -o nounset\n    set -o errexit\n    set -o pipefail\n    IFS=$'\\n\\t'\n\n    if ! command -v git-cop \u003e /dev/null; then\n       printf \"%s\\n\" \"[git]: Git Cop not found. To install, run: gem install git-cop --trust-policy MediumSecurity.\"\n       exit 1\n    fi\n\n    git-cop --hook --commit-message \"${BASH_ARGV[0]}\"\n\nWhenever you attempt to add a commit, Git Cop will check your commit for issues prior to saving it.\n\n#### Post Commit\n\nThe *post-commit* hook is possible via the `--police --commits` option. Usage:\n\n    Usage:\n      git-cop -p, [--police]\n\n    Options:\n      -c, [--commits=one two three]  # Check specific commit SHA(s).\n\n    Check feature branch for issues.\n\nThe *post-commit* hook can be used multiple ways but, if you want it to check each commit after it\nhas been made, here is a working example which can be used as a `.git/hooks/post-commit` script:\n\n    #! /usr/bin/env bash\n\n    set -o nounset\n    set -o errexit\n    set -o pipefail\n    IFS=$'\\n\\t'\n\n    if ! command -v git-cop \u003e /dev/null; then\n       printf \"%s\\n\" \"[git]: Git Cop not found. To install, run: gem install git-cop --trust-policy MediumSecurity.\"\n       exit 1\n    fi\n\n    git-cop --police --commits $(git log --pretty=format:%H -1)\n\nWhenever a commit has been saved, this script will run Git Cop to check for issues.\n\n### Continuous Integration (CI)\n\nThis gem automatically configures itself for known CI build servers.\n\nCalculation of commits is done by reviewing all commits made on the feature branch since branching\nfrom `master`. Below are the build servers which are supported and *tested*. If you have a build\nserver that is not listed, please open a pull request with support.\n\n#### Circle CI\n\nThis gem automatically detects and configures itself for [Circle CI](https://circleci.com) builds by\nchecking the `CIRCLECI` environment variable. No additional setup required!\n\n#### Travis CI\n\nThis gem automatically detects and configures itself for [Travis CI](https://travis-ci.org) builds\nby checking the `TRAVIS` environment variable. No additional setup required!\n\n## Cops\n\nThe following details the various cops provided by this gem to ensure a high standard of commits for\nyour project.\n\n### Commit Author Email\n\n| Enabled | Severity | Defaults |\n|---------|----------|----------|\n| true    | error    | none     |\n\nEnsures author email address exists. Git requires an author email when you use it for the first time\ntoo. This takes it a step further to ensure the email address loosely resembles an email address.\n\n    # Disallowed\n    mudder_man\n\n    # Allowed\n    jayne@serenity.com\n\n### Commit Author Name Capitalization\n\n| Enabled | Severity | Defaults |\n|---------|----------|----------|\n| true    | error    | none     |\n\nEnsures auther name is properly capitalized. Example:\n\n    # Disallowed\n    jayne cobb\n    dr. simon tam\n\n    # Allowed\n    Jayne Cobb\n    Dr. Simon Tam\n\n### Commit Author Name Parts\n\n| Enabled | Severity |  Defaults  |\n|---------|----------|------------|\n| true    | error    | minimum: 2 |\n\nEnsures author name consists of, at least, a first and last name. Example:\n\n    # Disallowed\n    Kaylee\n\n    # Allowed\n    Kaywinnet Lee Frye\n\n### Commit Body Bullet\n\n| Enabled | Severity |          Defaults         |\n|---------|----------|---------------------------|\n| true    | error    | blacklist: `[\"\\\\*\", \"•\"]` |\n\nEnsures commit message bodies use a standard Markdown syntax for bullet points. Markdown supports\nthe following syntax for bullets:\n\n    *\n    -\n\nIt's best to use `-` for bullet point syntax as `*` are easier to read when used for *emphasis*.\nThis makes parsing the Markdown syntax easier when reviewing a Git commit as the syntax used for\nbullet points and *emphasis* are now, distinctly, unique.\n\n### Commit Body Bullet Capitalization\n\n| Enabled | Severity |       Defaults       |\n|---------|----------|----------------------|\n| true    | error    | whitelist: `[\"\\\\-\"]` |\n\nEnsures commit body bullet lines are capitalized. Example:\n\n    # Disallowed\n\n    - an example bullet.\n\n    # Allowed\n\n    - An example bullet.\n\n### Commit Body Issue Tracker Link\n\n| Enabled | Severity |                       Defaults                       |\n|---------|----------|------------------------------------------------------|\n| true    | error    | blacklist: (see configuration list, mentioned above) |\n\nEnsures commit body doesn't contain a link to an issue tracker. The blacklist defaults to GitHub\nIssue links but can be customized for any issue tracker.\n\nThere are several reasons for exluding issue tracker links from commit bodies:\n\n0. Not all issue trackers preserve issues (meaning they can be deleted). This makes make reading\n   historic commits much harder to understand why the change was made when the link no longer works.\n0. When not connected to the internet or working on a laggy connection, it's hard to understand why\n   a commit was made when all you have is a link to an issue with no other supporting context.\n0. During the course of a repository's life, issue trackers can be replaced (rare but it does\n   happen). If the old issue tracker service is no longer paid for, none of the links within the\n   commit will be of any relevance.\n0. An issue might span several commits in order to resolve it. Including a link in each commit is\n   tedious and can create noise within the issue's history which is distracting.\n\nInstead of linking to issues, take the time to write a short summary as to *why* the commit was\nmade. Doing this will make it easier to understand *why* the commit was made, keeps the commit self-\ncontained, and makes learning about/debugging the commit faster.\n\nIssue tracker links are best used at the pull request level due to an issue usually spanning\nmultiple commits in order to complete the work. When reading a pull request, this is a great\nopportunity to link to an issue in order to provide a high level overview and reason why the pull\nrequest exists.\n\n### Commit Body Leading Line\n\n| Enabled | Severity | Defaults |\n|---------|----------|----------|\n| true    | error    | none     |\n\nEnsures there is a leading, empty line, between the commit subject and body. Generally, this isn't\nan issue but sometimes the Git CLI can be misued or a misconfigured Git editor will smash the\nsubject line and start of the body as one run-on paragraph. Example:\n\n    # Disallowed\n\n    Curabitur eleifend wisi iaculis ipsum.\n    Pellentque morbi-trist sentus et netus et malesuada fames ac turpis egestas. Vestibulum tortor\n    quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu_libero sit amet quam\n    egestas semper. Aenean ultricies mi vitae est. Mauris placerat's eleifend leo. Quisque et sapien\n    ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, orn si amt wit.\n\n    # Allowed\n\n    Curabitur eleifend wisi iaculis ipsum.\n\n    Pellentque morbi-trist sentus et netus et malesuada fames ac turpis egestas. Vestibulum tortor\n    quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu_libero sit amet quam\n    egestas semper. Aenean ultricies mi vitae est. Mauris placerat's eleifend leo. Quisque et sapien\n    ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, orn si amt wit.\n\n### Commit Body Leading Space\n\n| Enabled | Severity | Defaults |\n|---------|----------|----------|\n| false   | warn     | none     |\n\nThis cop has been deprecated and is a duplicate of the *Commit Body Leading Line* cop mentioned\nabove. If enabled, this cop will print deprecation warnings and recommend using the *Commit Body\nLeading Line* cop instead.\n\nThis cop will be permantently removed in the 2.0.0 version release.\n\n### Commit Body Line Length\n\n| Enabled | Severity |  Defaults  |\n|---------|----------|------------|\n| true    | error    | length: 72 |\n\nEnsures each line of the commit body is no longer than 72 characters in length for consistent\nreadabilty and word-wrap prevention on smaller screen sizes. For further details, read Tim Pope's\noriginal [article](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) on the\nsubject.\n\n### Commit Body Paragraph Capitalization\n\n| Enabled | Severity | Defaults |\n|---------|----------|----------|\n| true    | error    | none     |\n\nEnsures each paragraph of the commit body is capitalized. Example:\n\n    # Disallowed\n\n    curabitur eleifend wisi iaculis ipsum.\n\n    # Allowed\n\n    Curabitur eleifend wisi iaculis ipsum.\n\n### Commit Body Phrase\n\n| Enabled | Severity |                       Defaults                       |\n|---------|----------|------------------------------------------------------|\n| true    | error    | blacklist: (see configuration list, mentioned above) |\n\nEnsures non-descriptive words/phrases are avoided in order to keep commit message bodies informative\nand specific. The blacklist is case insensitive. Detection of blacklisted words/phrases is case\ninsensitve as well. Example:\n\n    # Disallowed\n\n    Obviously, the existing implementation was too simple for my tastes. Of course, this couldn't be\n    allowed. Everyone knows the correct way to implement this code is to do just what I've added in\n    this commit. Easy!\n\n    # Allowed\n\n    Necessary to fix due to a bug detected in production. The included implentation fixes the bug\n    and provides the missing spec to ensure this doesn't happen again.\n\n### Commit Body Presence\n\n| Enabled | Severity |  Defaults  |\n|---------|----------|------------|\n| false   | warn     | minimum: 1 |\n\nEnsures a minimum number of lines are present within the commit body. Lines with empty characters\n(i.e. whitespace, carriage returns, etc.) are considered to be empty.\n\nAutomatically ignores *fixup!* commits as they are not meant to have bodies.\n\n### Commit Body Single Bullet\n\n| Enabled | Severity |      Defaults      |\n|---------|----------|--------------------|\n| true    | error    | whitelist: `\"\\\\-\"` |\n\nEnsures a single bullet is never used when a paragraph could be used instead. Example:\n\n    # Disallowed\n\n    - Pellentque morbi-trist sentus et netus et malesuada fames ac turpis egestas. Vestibulum tortor\n      quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu_libero sit amet quam.\n\n    # Allowed\n\n    Pellentque morbi-trist sentus et netus et malesuada fames ac turpis egestas. Vestibulum tortor\n    quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu_libero sit amet quam.\n\n### Commit Subject Length\n\n| Enabled | Severity |  Defaults  |\n|---------|----------|------------|\n| true    | error    | length: 72 |\n\nEnsures the commit subject length is no more than 72 characters in length. This default is more\nlenient than the [50/72 rule](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)\nas it gives one the ability to formulate a more descriptive subject line without being too wordy or\nsuffer being word wrapped.\n\nAutomatically ignores *fixup!* or *squash!* commit prefixes when calculating subject length.\n\n### Commit Subject Prefix\n\n| Enabled | Severity |        Defaults        |\n|---------|----------|------------------------|\n| true    | error    | whitelist: (see below) |\n\nEnsures the commit subject uses consistent prefixes that help explain *what* is being commited. The\nwhitelist *is* case sensitive. The default whitelist consists of the following prefixes:\n\n- *Fixed* - Existing code that has been fixed.\n- *Removed* - Code that was once added and is now removed.\n- *Added* - New code that is an enhancement, feature, etc.\n- *Updated* - Existing code that has been modified.\n- *Refactored* - Existing code that has been cleaned up and does not change functionality.\n\nIn practice, using a prefix other than what has been detailed above to explain *what* is being\ncommitted is never needed. This whitelist is not only short and easy to remember but also has the\nadded benefit of categorizing the commits for building release notes, change logs, etc. This becomes\nhandy when coupled with another tool, [Milestoner](https://github.com/bkuhlmann/milestoner), for\nproducing consistent project milestones and Git tag histories.\n\nAutomatically ignores *fixup!* or *squash!* commit prefixes when used as a Git Hook in order to not\ndisturb interactive rebase workflows.\n\n### Commit Subject Suffix\n\n| Enabled | Severity |       Defaults       |\n|---------|----------|----------------------|\n| true    | error    | whitelist: `[\"\\\\.\"]` |\n\nEnsures commit subjects are suffixed consistently. The whitelist *is* case sensitive and only allows\nfor periods (`.`) to ensure each commit is sentance-like when generating release notes, Git tags,\nchange logs, etc. This is handy when coupled with a tool, like\n[Milestoner](https://github.com/bkuhlmann/milestoner), which automate project milestone releases.\n\n## Style Guide\n\nIn addition to what is described above and automated for you, the following style guide is also\nworth considering:\n\n### General\n\n- Use a [Git rebase workflow](http://www.bitsnbites.eu/a-tidy-linear-git-history) instead of a Git\n  merge workflow.\n- Use `git commit --fixup` when fixing a previous commit, addressing pull request feedback, etc.,\n  and don't need to modifiy the original commit message.\n- Use `git commit --squash` when fixing a previous commit, addressing pull request feedback, etc.,\n  and want to combine the original commit message with the squash commit message into a single\n  message.\n- Use `git rebase --interactive` when cleaning up commit history, order, messages, etc. Should be\n  done prior to submitting a pull request or when pull request feedback has been addressed and you\n  are ready to merge to `master`.\n- Use `git push --force-with-lease` instead of `git push --force` when pushing changes after an\n  interactive rebasing session.\n- Avoid checking in development-specific configuration files (add to `.gitignore` instead).\n- Avoid checking in sensitive information (i.e. security keys, passphrases, etc).\n- Avoid \"WIP\" (a.k.a. \"Work in Progress\") commits and/or pull requests. Be confident with your code\n  and collegues' time. Use branches, stashes, etc. instead -- share a link to a diff if you have\n  questions/concerns during development.\n\n### Commits\n\n- Use small, atomic commits:\n  - Easier to review and provide feedback.\n  - Easier to review implementation and corresponding tests.\n  - Easier to document with detailed subject messages (especially when grouped together in a pull\n    request).\n  - Easier to reword, edit, squash, fix, or drop when interactively rebasing.\n  - Easier to merge together versus tearing apart a larger commit into smaller commits.\n- Use commits in a logical order:\n  - Each commit should tell a story and be a logical building block to the next commit.\n  - Each commit, when reviewed in order, should be able to explain *how* the feature or bug fix was\n    completed and implemented properly.\n- Use a commit subject that explains *what* is being commited.\n- Use a commit message body that explains *why* the commit is necessary. Additional considerations:\n  - If the commit has a dependency to the previous commit or is a precursor to the commit that will\n    follow, make sure to explain that.\n  - Include links to dependent projects, stories, etc. if available.\n\n### Branches\n\n- Use feature branches for new work.\n- Maintain branches by rebasing upon `master` on a regular basis.\n\n### Tags\n\n- Use tags to denote milestones/releases:\n  - Makes it easier to record milestones and capture associated release notes.\n  - Makes it easier to compare differences between versions.\n  - Provides a starting point for debugging production issues (if any).\n\n### Rebases\n\n- Avoid rebasing a shared branch. If you must do this, clear communcation should be used to warn\n  those ahead of time, ensure that all of their work is checked in, and that their local branch is\n  deleted first.\n\n### Pull Requests\n\n- Avoid authoring and reviewing your own pull request.\n- Keep pull requests short and easy to review:\n  - Provide a high level overview that answers *why* the pull request is necessary.\n  - Provide a link to the story/task that prompted the pull request.\n  - Provide screenshots/screencasts if possible.\n  - Ensure all commits within the pull request are related to the purpose of the pull request.\n- Review and merge pull requests quickly:\n  - Maintain a consistent pace -- Review morning, noon, and night.\n  - Try not to let them linger more than a day.\n- Use emojis to help identify the types of comments added during the review process:\n  - Generally, an emoji should prefix all feedback. Format: `\u003cemoji\u003e \u003cfeedback\u003e`.\n  - :tea: - Signifies you are reviewing the pull request. This is *non-blocking* and is meant to be\n    informational. Useful when reading over a pull request with a large number of commits, reviewing\n    complex code, requires additional testing by the reviewer, etc.\n  - :information_source: - Signifies informational feedback that is *non-blocking*. Can also be used\n    to let one know you are done reviewing but haven't approved yet (due to feedback that needs\n    addressing), rebasing a pull request and then merging, waiting for a blocking pull request to be\n    resolved, status updates to the pull request, etc.\n  - :art: - Signifies an issue with code style and/or code quality. This can be *blocking* or *non-\n    blocking* feedback but is feedback generally related to the style/quality of the code,\n    implementation details, and/or alternate solutions worth considering.\n  - :bulb: - Indicates a helpful tip or trick for improving the code. This can be *blocking* or\n    *non-blocking* feedback and is left up to the author to decide (generally, it is a good idea to\n    address and resolve the feedback).\n  - :star: - Signifies code that is liked, favorited, remarkable, etc. This feedback is *non-\n    blocking* and is always meant as positive/uplifting.\n  - :white_check_mark: - Signifies approval of a pull request. The author can merge to `master` and\n    delete the feature branch at this point.\n- If the pull request discussion gets noisy, stop typing and switch to face-to-face chat.\n- If during a code review, additional features are discovered, create stories for them and then\n  return to reviewing the pull request.\n- The author, not the reviewer, should merge the feature branch upon approval.\n- Ensure the following criteria is met before merging your feature branch to master:\n  - Ensure all `fixup!` and `squash!` commits are interactively rebased and merged.\n  - Ensure your feature branch is rebased upon `master`.\n  - Ensure all tests and code quality checks are passing.\n  - Ensure the feature branch is deleted after being successfully merged.\n\n### GitHub\n\nWhen using GitHub, make sure to enforce a rebase workflow for all of your GitHub projects (*highly\nrecommended*). You can do this via your project options (i.e.\n`https://github.com/\u003cusername/organization\u003e/\u003cproject\u003e/settings`) and editing your merge options for\npull requests as follows:\n\n![GitHub Merge Options](doc/github-settings-options.png)\n\nDoing this will help maintain a clean Git history.\n\n## Tests\n\nTo test, run:\n\n    bundle exec rake\n\n## Versioning\n\nRead [Semantic Versioning](http://semver.org) for details. Briefly, it means:\n\n- Major (X.y.z) - Incremented for any backwards incompatible public API changes.\n- Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.\n- Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.\n\n## Code of Conduct\n\nPlease note that this project is released with a [CODE OF CONDUCT](CODE_OF_CONDUCT.md). By\nparticipating in this project you agree to abide by its terms.\n\n## Contributions\n\nRead [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## License\n\nCopyright (c) 2017 [Alchemists](https://www.alchemists.io).\nRead [LICENSE](LICENSE.md) for details.\n\n## History\n\nRead [CHANGES](CHANGES.md) for details.\nBuilt with [Gemsmith](https://github.com/bkuhlmann/gemsmith).\n\n## Credits\n\nDeveloped by [Brooke Kuhlmann](https://www.alchemists.io) at\n[Alchemists](https://www.alchemists.io).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fana06%2Fgit-cop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fana06%2Fgit-cop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fana06%2Fgit-cop/lists"}