Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/bahmutov/pre-git

Automatically install pre-commit / pre-push hooks in your git repo
https://github.com/bahmutov/pre-git

git git-hook hooks

Last synced: about 1 month ago
JSON representation

Automatically install pre-commit / pre-push hooks in your git repo

Awesome Lists containing this project

README

        

# pre-git

> Important git hooks implemented using Nodejs for your project.

[![NPM][pre-git-icon]][pre-git-url]

[![Build status][pre-git-ci-image]][pre-git-ci-url]
[![Build Status][snapci-image]][snapci-url]
[![dependencies][pre-git-dependencies-image]][pre-git-dependencies-url]
[![devdependencies][pre-git-devdependencies-image]][pre-git-devdependencies-url]
[![semantic-release][semantic-image] ][semantic-url]
[![manpm](https://img.shields.io/badge/manpm-%E2%9C%93-3399ff.svg)](https://github.com/bahmutov/manpm)
[![renovate-app badge][renovate-badge]][renovate-app]

## Why?

You can easily run the `pre-commit` and `pre-push` Git hooks to
[avoid breaking the local master branch](http://glebbahmutov.com/blog/never-break-master-by-accident/)
or the [remote master](http://glebbahmutov.com/blog/never-break-remote-master-again/).

### Installation

It's advised to install this module as `devDependency` in your `package.json`
file so it doesn't get installed on production servers. Run:

```
npm install pre-git --save-dev
```

### Configuration

Specify commands to run on *commit* and on *push* in your package.json under `config > pre-git`
object.

```json
"scripts": {
"test": "node-qunit *.js"
},
"config": {
"pre-git": {
"enabled": true,
"msg-pattern": "^(US|DE)\\d+ - .+",
"commit-msg": "simple",
"pre-commit": [
"grunt jshint"
],
"post-commit": "git status",
"pre-push": [
"rm -rf node_modules",
"npm install",
"grunt build",
"grunt test"
],
"post-checkout": "npm install",
"post-merge": "npm install"
}
}
```

If there are older settings like `pre-commit`, etc, you will have to move
them to the `config > pre-git` object manually.

Related project: [post-merge-make](https://github.com/bahmutov/post-merge-make)
runs `make post-merge` after pull or merge.

### Subprojects

If you have large repo, it is possible that there might be nested files with
different `package.json` files. In this case, the search will proceed up
from the current working directory until it finds `package.json` with valis
`config.pre-git` object inside.

## Windows

Thanks to [ybiquitous](https://github.com/ybiquitous) for
[adding support](https://github.com/bahmutov/pre-git/pull/72) for Windows.

* Git Bash (Git for Windows): work fine!
* Command prompt: work if sh.exe in PATH (e.g. `set PATH=C:\Program Files\Git\bin;%PATH%`)

## Untracked files

Before the commit, we check if there are any untracked files. A commit does
not continue if there are any. Please `git ignore` or delete unnecessary
files before running the `git commit` command to ensure clean tests.
In every case where I forgot to add files to the repo, this was by accident
and caused breaking tests.

This can be disabled by setting the `allow-untracked-files` option to true

```json
{
"config": {
"pre-git": {
"allow-untracked-files": true
}
}
```

## Details

You can disable all `pre-git` hooks by setting the configuration option to
false

```json
{
"config": {
"pre-git": {
"enabled": false
}
}
```

If the 'config.pre-git' object has the option 'enabled' missing, it is
assumed to be "true" and the hooks are executed.

You can always skip pre-commit hook (but not pre-push hook!) by using `-n` option

git commit -m "done, don't check me" -n

You can skip the pre-push hook using `--no-verify` option

To run just the hook (for example to test what it does), execute

```bash
.git/hooks/pre-commit
.git/hooks/pre-push
```

Since there might be no changes to push, you can force the `pre-commit` hook to execute
using `-f` or `--force` argument

```bash
.git/hooks/pre-commit -f
```

## Validating commit message

By default, this package will install both the message validator
and the message format helper. You can disable the validation
by removing the below command.

```json
"config": {
"pre-git": {
"commit-msg": "conventional"
}
}
```

When you run `git commit -m "message ..."` the hook will enforce the default style
`type(scope): message ...`. To better form the message, there is a CLI wizard
installed based on [commitizen](https://www.npmjs.com/package/commitizen) project,
very well shown in the tutorial
[video](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-writing-conventional-commits-with-commitizen). The commit wizard is available under "node_modules/.bin/commit-wizard" link
and can be started from command line

node --harmony node_modules/.bin/commit-wizard

or via a script

```json
"scripts": {
"commit": "commit-wizard"
}
```

Then run

npm run commit

The wizard will look something like this

```
? Select the type of change that you're committing:
feat: A new feature
❯ fix: A bug fix
chore: Changes to the build process or auxiliary tools
and libraries such as documentation generation
```

There are 2 plugins included with `pre-git`:

* "conventional" follows AngularJS log convention,
see [conventional-commit-message](https://github.com/bahmutov/conventional-commit-message)
* "simple" only allows "feat", "fix" and "chore" commit types,
see [simple-commit-message](https://github.com/bahmutov/simple-commit-message)

I recommend sticking with "simple" unless you need more release types.

## Development

In order to locally test this package, from another git repo execute the install script
using `-f` or `--force` argument. For example

```
$ node ../pre-git/src/install.js -f
pre-git 0.7.2 in /Users/kensho/git/test-git-hooks
/Users/kensho/git/test-git-hooks
read target package from /Users/kensho/git/test-git-hooks/package.json
added empty command list for hook commit-msg
added empty command list for hook pre-commit
added empty command list for hook pre-push
added empty command list for hook post-commit
added empty command list for hook post-merge
saving updated files /Users/kensho/git/test-git-hooks/package.json
```

```json
"config": {
"pre-git": {
"msg-pattern": "whatever-regex-without-delimiters"
}
}
```

When using msg-pattern, the pre-git will match the commit message against the given pattern,
if the test fails, then it will stop the execution and will exit the commit,
this feature is optional and can be used along with any of the commit wizards, however
those can be omitted using only the pattern, this is a useful manner of checking
a custom message, as some commit may require custom codes as user story prefixes and so on.

It is also possible to customize your own msg-pattern-error along with msg-pattern to be more descriptive
as to why the pattern fails.

```json
"config": {
"pre-git": {
"msg-pattern": "whatever-regex-without-delimiters",
"msg-pattern-error": "whatever error message that will be thrown when the pattern fails"
}
}
```

I am using a small project [test-pre-git](https://github.com/bahmutov/test-pre-git)
as a test playground for these hooks.

### End to end testing

To create a sample project and test the hooks, just run the included script
`npm run e2e` which should finish with status zero.

To see how `pre-git` stops a commit when a hook fails, run
`npm run test-no-commit-on-test-fail` command, which should exit with status 1.

You can verify the git hooks are not running when the `pre-git` is disabled
via a config option by running `npm run e2e-pre-git-disabled` which allows
the commit to go through.

To see how `allow-untracked-files` option lets the commit go through,
run `npm run test-allow-untracked-files`

## Debugging

If a hook does not behave as expected, you can see verbose log messages by setting
the environment variable `DEBUG=pre-git` when running a git command. For example, to
see the messages when committing

DEBUG=pre-git git commit -m "a message"
running pre-commit script
pre-git pre-commit +0ms arguments [ 'node',
'/instant-vdom-todo/node_modules/.bin/pre-commit' ]
pre-commit No changes detected, bailing out.
pre-git found package in folder +0ms /instant-vdom-todo
pre-git commit message wizard name from +5ms
...

This should provide plenty of information to debug the hooks

## Desktop Git clients

The Git hooks should work in desktop clients, like [GitHub Desktop app](https://desktop.github.com/).
If something does not work, it is usually because the desktop App cannot find `node`.
See what [Git Tower application suggests](https://www.git-tower.com/help/mac/faq-and-tips/faq/hook-scripts)
you do in that case.

## Local development

To execute commit message validation, run `npm run demo-commit-message` and vary the
test message to see how the hook validates it.

## Recent contributors

* [ybiquitous](https://github.com/ybiquitous)
* [Marko Schulz](https://github.com/datenreisender)

### Small print

Author: Gleb Bahmutov © 2014

* [@bahmutov](https://twitter.com/bahmutov)
* [glebbahmutov.com](https://glebbahmutov.com)
* [blog](https://glebbahmutov.com/blog)

License: MIT - do anything with the code, but don't blame me if it does not work.

Spread the word: tweet, star on github, etc.

Support: if you find any problems with this module, email / tweet /
[open issue](https://github.com/bahmutov/pre-git/issues?state=open) on Github

[snapci-image]: https://snap-ci.com/bahmutov/pre-git/branch/master/build_image
[snapci-url]: https://snap-ci.com/bahmutov/pre-git/branch/master
[pre-git-icon]: https://nodei.co/npm/pre-git.svg?downloads=true
[pre-git-url]: https://npmjs.org/package/pre-git
[pre-git-ci-image]: https://travis-ci.org/bahmutov/pre-git.svg?branch=master
[pre-git-ci-url]: https://travis-ci.org/bahmutov/pre-git
[pre-git-dependencies-image]: https://david-dm.org/bahmutov/pre-git.svg
[pre-git-dependencies-url]: https://david-dm.org/bahmutov/pre-git
[pre-git-devdependencies-image]: https://david-dm.org/bahmutov/pre-git/dev-status.svg
[pre-git-devdependencies-url]: https://david-dm.org/bahmutov/pre-git#info=devDependencies
[semantic-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
[semantic-url]: https://github.com/semantic-release/semantic-release
[renovate-badge]: https://img.shields.io/badge/renovate-app-blue.svg
[renovate-app]: https://renovateapp.com/