{"id":15552202,"url":"https://github.com/bahmutov/pre-git","last_synced_at":"2025-09-28T23:31:08.382Z","repository":{"id":10942128,"uuid":"13249722","full_name":"bahmutov/pre-git","owner":"bahmutov","description":"Automatically install pre-commit / pre-push hooks in your git repo","archived":false,"fork":false,"pushed_at":"2024-09-27T19:13:36.000Z","size":226,"stargazers_count":168,"open_issues_count":38,"forks_count":23,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-03T14:12:05.950Z","etag":null,"topics":["git","git-hook","hooks"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bahmutov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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":"2013-10-01T16:51:53.000Z","updated_at":"2024-08-08T15:18:22.000Z","dependencies_parsed_at":"2023-12-06T08:28:10.781Z","dependency_job_id":"0abba851-23d1-4624-8dc0-34264b7805b5","html_url":"https://github.com/bahmutov/pre-git","commit_stats":{"total_commits":356,"total_committers":19,"mean_commits":"18.736842105263158","dds":0.4185393258426966,"last_synced_commit":"b9960644402103ee02a8f52de619ff47eb200bbf"},"previous_names":[],"tags_count":127,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fpre-git","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fpre-git/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fpre-git/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Fpre-git/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bahmutov","download_url":"https://codeload.github.com/bahmutov/pre-git/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234570296,"owners_count":18854152,"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":["git","git-hook","hooks"],"created_at":"2024-10-02T14:12:07.797Z","updated_at":"2025-09-28T23:31:03.041Z","avatar_url":"https://github.com/bahmutov.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pre-git\n\n\u003e Important git hooks implemented using Nodejs for your project.\n\n[![NPM][pre-git-icon]][pre-git-url]\n\n[![Build status][pre-git-ci-image]][pre-git-ci-url]\n[![Build Status][snapci-image]][snapci-url]\n[![dependencies][pre-git-dependencies-image]][pre-git-dependencies-url]\n[![devdependencies][pre-git-devdependencies-image]][pre-git-devdependencies-url]\n[![semantic-release][semantic-image] ][semantic-url]\n[![manpm](https://img.shields.io/badge/manpm-%E2%9C%93-3399ff.svg)](https://github.com/bahmutov/manpm)\n[![renovate-app badge][renovate-badge]][renovate-app]\n\n## Why?\n\nYou can easily run the `pre-commit` and `pre-push` Git hooks to\n[avoid breaking the local master branch](http://glebbahmutov.com/blog/never-break-master-by-accident/)\nor the [remote master](http://glebbahmutov.com/blog/never-break-remote-master-again/).\n\n### Installation\n\nIt's advised to install this module as `devDependency` in your `package.json`\nfile so it doesn't get installed on production servers. Run:\n\n```\nnpm install pre-git --save-dev\n```\n\n### Configuration\n\nSpecify commands to run on *commit* and on *push* in your package.json under `config \u003e pre-git`\nobject.\n\n```json\n\"scripts\": {\n  \"test\": \"node-qunit *.js\"\n},\n\"config\": {\n  \"pre-git\": {\n    \"enabled\": true,\n    \"msg-pattern\": \"^(US|DE)\\\\d+ - .+\",\n    \"commit-msg\": \"simple\",\n    \"pre-commit\": [\n      \"grunt jshint\"\n    ],\n    \"post-commit\": \"git status\",\n    \"pre-push\": [\n      \"rm -rf node_modules\",\n      \"npm install\",\n      \"grunt build\",\n      \"grunt test\"\n    ],\n    \"post-checkout\": \"npm install\",\n    \"post-merge\": \"npm install\"\n  }\n}\n```\n\nIf there are older settings like `pre-commit`, etc, you will have to move\nthem to the `config \u003e pre-git` object manually.\n\nRelated project: [post-merge-make](https://github.com/bahmutov/post-merge-make)\nruns `make post-merge` after pull or merge.\n\n### Subprojects\n\nIf you have large repo, it is possible that there might be nested files with\ndifferent `package.json` files. In this case, the search will proceed up\nfrom the current working directory until it finds `package.json` with valis\n`config.pre-git` object inside.\n\n## Windows\n\nThanks to [ybiquitous](https://github.com/ybiquitous) for\n[adding support](https://github.com/bahmutov/pre-git/pull/72) for Windows.\n\n* Git Bash (Git for Windows): work fine!\n* Command prompt: work if sh.exe in PATH (e.g. `set PATH=C:\\Program Files\\Git\\bin;%PATH%`)\n\n## Untracked files\n\nBefore the commit, we check if there are any untracked files. A commit does\nnot continue if there are any. Please `git ignore` or delete unnecessary\nfiles before running the `git commit` command to ensure clean tests.\nIn every case where I forgot to add files to the repo, this was by accident\nand caused breaking tests.\n\nThis can be disabled by setting the `allow-untracked-files` option to true\n\n```json\n{\n\"config\": {\n  \"pre-git\": {\n     \"allow-untracked-files\": true\n  }\n}\n```\n\n## Details\n\nYou can disable all `pre-git` hooks by setting the configuration option to\nfalse\n\n```json\n{\n\"config\": {\n  \"pre-git\": {\n     \"enabled\": false\n  }\n}\n```\n\nIf the 'config.pre-git' object has the option 'enabled' missing, it is\nassumed to be \"true\" and the hooks are executed.\n\nYou can always skip pre-commit hook (but not pre-push hook!) by using `-n` option\n\n    git commit -m \"done, don't check me\" -n\n\nYou can skip the pre-push hook using `--no-verify` option\n\nTo run just the hook (for example to test what it does), execute\n\n```bash\n.git/hooks/pre-commit\n.git/hooks/pre-push\n```\n\nSince there might be no changes to push, you can force the `pre-commit` hook to execute\nusing `-f` or `--force` argument\n\n```bash\n.git/hooks/pre-commit -f\n```\n\n## Validating commit message\n\nBy default, this package will install both the message validator\nand the message format helper. You can disable the validation\nby removing the below command.\n\n```json\n\"config\": {\n  \"pre-git\": {\n    \"commit-msg\": \"conventional\"\n  }\n}\n```\n\nWhen you run `git commit -m \"message ...\"` the hook will enforce the default style\n`type(scope): message ...`. To better form the message, there is a CLI wizard\ninstalled based on [commitizen](https://www.npmjs.com/package/commitizen) project,\nvery well shown in the tutorial\n[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\nand can be started from command line\n\n    node --harmony node_modules/.bin/commit-wizard\n\nor via a script\n\n```json\n\"scripts\": {\n  \"commit\": \"commit-wizard\"\n}\n```\n\nThen run\n\n    npm run commit\n\nThe wizard will look something like this\n\n```\n? Select the type of change that you're committing:\n  feat:     A new feature\n❯ fix:      A bug fix\n  chore:    Changes to the build process or auxiliary tools\n            and libraries such as documentation generation\n```\n\nThere are 2 plugins included with `pre-git`:\n\n* \"conventional\" follows AngularJS log convention,\n  see [conventional-commit-message](https://github.com/bahmutov/conventional-commit-message)\n* \"simple\" only allows \"feat\", \"fix\" and \"chore\" commit types,\n  see [simple-commit-message](https://github.com/bahmutov/simple-commit-message)\n\n\nI recommend sticking with \"simple\" unless you need more release types.\n\n## Development\n\nIn order to locally test this package, from another git repo execute the install script\nusing `-f` or `--force` argument. For example\n\n```\n$ node ../pre-git/src/install.js -f\npre-git 0.7.2 in /Users/kensho/git/test-git-hooks\n/Users/kensho/git/test-git-hooks\nread target package from /Users/kensho/git/test-git-hooks/package.json\nadded empty command list for hook commit-msg\nadded empty command list for hook pre-commit\nadded empty command list for hook pre-push\nadded empty command list for hook post-commit\nadded empty command list for hook post-merge\nsaving updated files /Users/kensho/git/test-git-hooks/package.json\n```\n\n```json\n\"config\": {\n  \"pre-git\": {\n    \"msg-pattern\": \"whatever-regex-without-delimiters\"\n  }\n}\n```\n\nWhen using msg-pattern, the pre-git will match the commit message against the given pattern,\nif the test fails, then it will stop the execution and will exit the commit,\nthis feature is optional and can be used along with any of the commit wizards, however\nthose can be omitted using only the pattern, this is a useful manner of checking\na custom message, as some commit may require custom codes as user story prefixes and so on.\n\nIt is also possible to customize your own msg-pattern-error along with msg-pattern to be more descriptive\nas to why the pattern fails.\n\n```json\n\"config\": {\n  \"pre-git\": {\n    \"msg-pattern\": \"whatever-regex-without-delimiters\",\n    \"msg-pattern-error\": \"whatever error message that will be thrown when the pattern fails\"\n  }\n}\n```\n\nI am using a small project [test-pre-git](https://github.com/bahmutov/test-pre-git)\nas a test playground for these hooks.\n\n### End to end testing\n\nTo create a sample project and test the hooks, just run the included script\n`npm run e2e` which should finish with status zero.\n\nTo see how `pre-git` stops a commit when a hook fails, run\n`npm run test-no-commit-on-test-fail` command, which should exit with status 1.\n\nYou can verify the git hooks are not running when the `pre-git` is disabled\nvia a config option by running `npm run e2e-pre-git-disabled` which allows\nthe commit to go through.\n\nTo see how `allow-untracked-files` option lets the commit go through,\nrun `npm run test-allow-untracked-files`\n\n## Debugging\n\nIf a hook does not behave as expected, you can see verbose log messages by setting\nthe environment variable `DEBUG=pre-git` when running a git command. For example, to\nsee the messages when committing\n\n    DEBUG=pre-git git commit -m \"a message\"\n    running pre-commit script\n    pre-git pre-commit +0ms arguments [ 'node',\n      '/instant-vdom-todo/node_modules/.bin/pre-commit' ]\n    pre-commit No changes detected, bailing out.\n    pre-git found package in folder +0ms /instant-vdom-todo\n    pre-git commit message wizard name from +5ms\n    ...\n\nThis should provide plenty of information to debug the hooks\n\n## Desktop Git clients\n\nThe Git hooks should work in desktop clients, like [GitHub Desktop app](https://desktop.github.com/).\nIf something does not work, it is usually because the desktop App cannot find `node`.\nSee what [Git Tower application suggests](https://www.git-tower.com/help/mac/faq-and-tips/faq/hook-scripts)\nyou do in that case.\n\n## Local development\n\nTo execute commit message validation, run `npm run demo-commit-message` and vary the\ntest message to see how the hook validates it.\n\n## Recent contributors\n\n* [ybiquitous](https://github.com/ybiquitous)\n* [Marko Schulz](https://github.com/datenreisender)\n\n### Small print\n\nAuthor: Gleb Bahmutov \u0026copy; 2014\n\n* [@bahmutov](https://twitter.com/bahmutov)\n* [glebbahmutov.com](https://glebbahmutov.com)\n* [blog](https://glebbahmutov.com/blog)\n\nLicense: MIT - do anything with the code, but don't blame me if it does not work.\n\nSpread the word: tweet, star on github, etc.\n\nSupport: if you find any problems with this module, email / tweet /\n[open issue](https://github.com/bahmutov/pre-git/issues?state=open) on Github\n\n[snapci-image]: https://snap-ci.com/bahmutov/pre-git/branch/master/build_image\n[snapci-url]: https://snap-ci.com/bahmutov/pre-git/branch/master\n[pre-git-icon]: https://nodei.co/npm/pre-git.svg?downloads=true\n[pre-git-url]: https://npmjs.org/package/pre-git\n[pre-git-ci-image]: https://travis-ci.org/bahmutov/pre-git.svg?branch=master\n[pre-git-ci-url]: https://travis-ci.org/bahmutov/pre-git\n[pre-git-dependencies-image]: https://david-dm.org/bahmutov/pre-git.svg\n[pre-git-dependencies-url]: https://david-dm.org/bahmutov/pre-git\n[pre-git-devdependencies-image]: https://david-dm.org/bahmutov/pre-git/dev-status.svg\n[pre-git-devdependencies-url]: https://david-dm.org/bahmutov/pre-git#info=devDependencies\n[semantic-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg\n[semantic-url]: https://github.com/semantic-release/semantic-release\n[renovate-badge]: https://img.shields.io/badge/renovate-app-blue.svg\n[renovate-app]: https://renovateapp.com/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahmutov%2Fpre-git","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbahmutov%2Fpre-git","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahmutov%2Fpre-git/lists"}