{"id":37160948,"url":"https://github.com/stefan-niemeyer/githooks","last_synced_at":"2026-04-05T13:01:12.179Z","repository":{"id":39880731,"uuid":"457316745","full_name":"stefan-niemeyer/githooks","owner":"stefan-niemeyer","description":"Repository with Git hooks","archived":false,"fork":false,"pushed_at":"2026-03-31T19:48:40.000Z","size":12962,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-31T21:34:51.012Z","etag":null,"topics":["git","githooks"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stefan-niemeyer.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-02-09T10:45:59.000Z","updated_at":"2022-05-26T09:04:12.000Z","dependencies_parsed_at":"2022-09-01T06:31:36.652Z","dependency_job_id":null,"html_url":"https://github.com/stefan-niemeyer/githooks","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/stefan-niemeyer/githooks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-niemeyer%2Fgithooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-niemeyer%2Fgithooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-niemeyer%2Fgithooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-niemeyer%2Fgithooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stefan-niemeyer","download_url":"https://codeload.github.com/stefan-niemeyer/githooks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-niemeyer%2Fgithooks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31436301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T08:13:15.228Z","status":"ssl_error","status_checked_at":"2026-04-05T08:13:11.839Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","githooks"],"created_at":"2026-01-14T19:09:23.277Z","updated_at":"2026-04-05T13:01:12.162Z","avatar_url":"https://github.com/stefan-niemeyer.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Content of githooks\n\nThis repository includes a Git hook to prevent commits without a Jira issue key in the commit message.  \nCompliance with Conventional Commits can also be ensured.\n\nGit-generated merge and revert commit messages that start with **Merge** or **revert** are always accepted.\n\nIf you are working on a branch that contains an issue key in its name, for example `feature/DS-17`, the commit message will be enhanced with that issue key. There are several format styles available to choose how the issue key will be inserted.\n\nThe insertion will only happen if the commit message does not already contain that key.\n\n\u003ca name=\"global-installation\"\u003e\u003c/a\u003e\n# 1. Global Installation with githooks\n\nSometimes you have multiple repositories in a folder, and they all should use the same hooks.  \nThis can be done via the Git configuration variable `core.hooksPath`.\n\nLet us assume you work on two projects. Project **Alpha** uses a Jira project with the key `ALPHA`.  \nThe second project is **Beta** and uses a Jira project with the key `BETA`.\n\nTo simplify the installation and creation of the folders and files needed, you can use the `githooks`\nCLI tool. It is a command line application that is developed with Go.  \nOnce it is built, you can run it directly.\n\n## Linux / macOS Installation\n```shell\n$ curl -sfL https://raw.githubusercontent.com/stefan-niemeyer/githooks/main/install.sh | sh\n$ chmod +x githooks\n$ mv githooks \u003cfolder-in-your-PATH\u003e\n```\n\n## Windows Installation\n```\nirm https://raw.githubusercontent.com/stefan-niemeyer/githooks/main/install.ps1 | iex\n```\n\n## 1.1 Initialization\n\nWhen you use `githooks` for the first time, you need to set up the usage by calling:\n\n```shell\n$ githooks init\n```\n\nThe `init` command will create the Git hook command `commit-msg` under `$HOME/.githooks`.  \n`commit-msg` is just a symbolic link to the `githooks` file. If you install a newer version of `githooks`, the actual Git hook command `commit-msg` will be updated as well, because it is just a link.\n\nThe behavior under Windows is different. `githooks init` will copy the file `githooks.exe` to `$HOME/.githooks/commit-msg.exe`.  \nIt is the same program with different names. The name defines the behavior when it is called.\n\nFurther configuration files will be created under `$HOME/.githooks/config`. This folder is called the **githooks config folder** in this documentation.  \nHere you will find files such as `githooks.json`.  \nIf you are not familiar with `githooks`, please do not touch these files.\n\nYou can modify the content of this file via the `githooks` commands `add`, `edit`, and `delete`.\n\n## 1.2 Updating the Git Hooks\n\nBy calling `githooks update` the Git hooks file `commit-msg` will be reinstalled.\n\nIf you move `githooks` to another folder under Linux, `githooks update` will recreate the symbolic link.\n\nOn a Windows machine, where `commit-msg.exe` is just a copy of `githooks.exe` and not a symbolic link, calling `githooks update` is necessary after installing a newer version of `githooks`.\n\n## 1.3 Workspaces\n\nA workspace for this application consists of the following elements:\n\n- Name  \n- ProjectKeyRE  \n- CommitMessageStyle  \n- AllowedTypes  \n- Folder  \n\n### Workspace Name\n\nThe `Name` is used to distinguish the workspace definitions.\n\n### Project Key Regular Expression\n\n`ProjectKeyRE` is a regular expression to determine if a commit message contains an issue key of the right project(s).  \nIf only one project is allowed, just type the project key, e.g. `ALPHA`.  \nIf you work with several Jira projects, you can use a regular expression like `(ALPHA|BETA|GAMMA)`.\n\nGo supports the RE2 format. The syntax is explained in the official [Go documentation](https://pkg.go.dev/regexp/syntax).  \nHowever, the example above should fit for most use cases.\n\nIf you do not specify a particular project key, `githooks` just checks for the existence of a Jira issue key, regardless of the project key.\n\n### Commit Message Style\n\nYou can place a Jira issue key in a commit message wherever you want. If the project key matches `ProjectKeyRE`, the commit message will not be changed by `githooks`.\n\nThe strength of `githooks` is extracting the Jira issue key from a Git branch and inserting that issue key into the commit message.  \nThis is convenient and prevents typos.\n\nThe insertion of the issue key can be influenced. `githooks` supports several format styles.  \nThe table below shows how a commit message will be modified.\n\n| Format Style   | Original                  | Result                                          |\n|----------------|---------------------------|-------------------------------------------------|\n| Plain Space    | add feature               | JIRA-123 add feature                            |\n| Plain Colon    | add feature               | JIRA-123: add feature                           |\n| Plain Brackets | add feature               | [JIRA-123] add feature                          |\n| Conventional   | fix(parser)!: changes API | fix(parser)!: changes API\u003cbr\u003e\u003cbr\u003eRefs: JIRA-123 |\n\n#### Issue Key Positioning for Conventional Commits\n\nThe position where `githooks` inserts an issue key from a branch is special for the format style `Conventional`.  \nThe application uses [`git interpret-trailers`](https://git-scm.com/docs/git-interpret-trailers) to add the issue key in the footer of a commit message.\n\nBy default, `githooks` uses the trailer key `Refs`. This will produce an output like the example above.  \nYou can go to a Git repository and call:\n\n```shell\ngit config set trailer.refs.key \"Reference\"\n```\n\nThen Git will change the key `Refs` passed by `githooks` to `Reference` as the key in the footer of the commit message.\n\n### Allowed Types\n\nThe format style `Conventional` ensures compliance of a commit message with the Conventional Commits requirements.\n\nThere is a specification of Conventional Commits: https://www.conventionalcommits.org\n\nThe Angular project demands this style, see [Commit Message Format](https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md).\n\nAnother project is [Karma](https://karma-runner.github.io/1.0/dev/git-commit-msg.html).\n\nAs you can see, the projects differ in the allowed types in the commit message.  \nFor that purpose, `githooks` accepts a list of types that the commit message can or must contain.\n\nThis is defined per workspace, so you can adapt it to your needs.\n\n### Folder\n\nThe configuration of a workspace is valid for all Git repositories in this folder and its subfolders.\n\nHowever, the definition of a workspace with the folder `~/projects/alpha` takes precedence over the configuration of a workspace for the folder `~/projects`.\n\n## 1.4 Adding a Workspace\n\n```shell\n$ githooks add\n```\n\nThe **add** command will add a new workspace to the `githooks` workspace list.\n\nOnce it is done, it will generate a config file under the githooks config folder with the following pattern: `gitconfig-\u003cPROJECT_NAME\u003e`.  \nBecause `githooks` is essentially a Git extension, it will append extra configuration at the bottom of `$HOME/.gitconfig`.\n\n## 1.5 Listing the Workspaces\n\nBy using the command **list**, `githooks` prints all workspaces it manages.\n\n## 1.6 Editing a Workspace\n\nThe configuration elements of a workspace can be changed by using the command **edit**.\n\n## 1.7 Deleting a Workspace\n\nThe **delete** command will list all `githooks` workspaces. You can select one of the workspaces to delete by moving the cursor.  \nIf a workspace was removed successfully, its config files will also be removed or updated by `githooks`.  \nAgain, if you are not familiar with `githooks`, just do not touch these config files; otherwise `githooks` will lose control of them.\n\n# 2. Under the Hood\n\nLet us assume you have called `githooks init` and added the workspaces **Alpha** and **Beta** with `githooks add`.  \nThen `githooks` will have created the following file and folder structure:\n\n```\n~\n├── .gitconfig\n└── .githooks\n    ├── commit-msg\n    └── config\n        ├── gitconfig-alpha\n        ├── gitconfig-beta\n        └── githooks.json\n\n```\n\nThe file `.gitconfig` will contain the configuration settings depending on the location of the repositories.  \nIn the example below, the configuration file `gitconfig-alpha` is read for all Git repositories that have `~/work/ws-alpha` as a parent folder.  \nThe settings for the project **Beta** are analogous.\n\n```\n# settings in .gitconfig\n\n[includeIf \"gitdir:~/work/ws-alpha/\"]\n    path = .githooks/config/gitconfig-alpha\n[includeIf \"gitdir:~/work/ws-beta/\"]\n    path = .githooks/config/gitconfig-beta\n```\n\nThe files `gitconfig-alpha` and `gitconfig-beta` set the Git hooks folder and the allowed Jira project keys.  \nThey might look like this:\n\n```\n# settings in gitconfig-alpha\n\n[core]\n    hooksPath=~/.githooks\n[user]\n    jiraProjects=ALPHA\n    commitMessageStyle=conventional\n    allowedTypes=build,chore,ci,docs,feat,fix,ops,perf,refactor,style,test\n```\n\nThe variable `core.hooksPath` is set to the folder with the shared hooks `~/.githooks`.\n\nThe Git variable `user.jiraProjects` is used to set different Jira project keys for the workspaces.  \nThis is a custom-defined variable and not part of the Git core. The same applies to the entries `commitMessageStyle`\nand `allowedTypes`.\n\n\n# 3. Related Projects\n\nIf you are only interested in the conventional commits format and do not need the Jira issue key existence, have\na look at [Bengt Brodersen's](https://github.com/qoomon) project [Git Conventional Commits](https://github.com/qoomon/git-conventional-commits)\nHis code allows the creation of change logs as well.\n\nAnd check out [Bai Xia's](https://github.com/xiabai84) project [githooks](https://github.com/xiabai84/githooks).\n\nMost of the workspace configuration was contributed by him. Thank's again Bai.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefan-niemeyer%2Fgithooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstefan-niemeyer%2Fgithooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefan-niemeyer%2Fgithooks/lists"}