preface

Git hooks presumably many siege is not all strange lions, official for hooks have detailed documents, also have online articles within the station git hooks (1) : introduction, git hooks (2) : script classification, said very detailed, there is not much to do, here mainly introduce how to write a hook.

What does a basic Git hook look like?

In the git/hooks directory, which contains a number of hooks that are automatically generated when the git repository is created. When the suffix is removed, it becomes a usable hook.

Take a chestnut

This hook is triggered at git commit time. I will not paste the code, it is not interesting, the main points are:

  1. This is a shell script

  2. The script runs something and exits

  3. The exit error code is not fixed when exiting

This is the basic structure of a hook: When a git operation is executed on the command line, the corresponding executable script in the hooks directory is automatically executed, and the exit status of the script determines whether the operation is successful. If the error code is not 0, the operation fails and terminates. Otherwise, the operation continues.

Simulation scenario

If you have a git repository that doesn’t allow you to commit to the dist directory, and you pass mocha’s test, you won’t allow it to commit.

First of all, this is a limitation at commit time, so consider using a pre-commit hook to stop writing code. Orz), the whole process is as follows:

  1. Check if there is dist directory, if not next, otherwise exit, error code set to 1.

  2. Run the mocha command to test. If all the tests pass, exit with error code 0; otherwise, exit with error code 1.

If any of the above steps fail, the hook is aborted and the Git-commit cannot pass, thus limiting the commit.

Limitations of shell scripts — can’t be written

As an ordinary front-end engineer, I am not very familiar with shell scripts. I can’t even handle Linux commands, let alone write 666 shell scripts, so I have to find another way to do this.

Front-end players should be very familiar with JS, so wouldn’t it be cool if you could use JS to write hooks? And Node.js just gives us hope, grateful words will not say more, absolutely moved to cry!

Node.js scripts are also very simple to write, such as a simple script

#! /usr/bin/env node console.log('Hello World! ');Copy the code

Once the script is given executable permission, it can be run as a shell script, so Mommy doesn’t have to worry about me not being able to shell. Similarly, we can use this in hooks. Here’s another chestnut

Do not allow dist directory, pass all the Mocha tests, and use Node to write this (this time I can show code)

#! /usr/bin/env node var fs = require('fs'), spawnSync = require('child_process').spawnSync; if(fs.existsSync('./dist')){ console.log('Commit Abort! Please remove dist directory.'); process.exit(1); } // Run the mocha command using the synchronization method spawnSync. The test result is 0 in result.status. Var result = spawnSync('./node_modules/.bin/mocha',['test']); if(result.status){ console.log('Commit Abort! Test failure.'); } process.exit(result.status);Copy the code

This is a basic Git-hook implemented in Node.js.

Limitations of Node.js — you can’t move

One problem with client-side hooks is that they cannot change with the repository. If there are many project members, everyone needs to add them locally.

The solution

I have a simple solution to this problem, which is to create a git-hooks node. After every hooks are written, build a file that looks like an installer, and commit it to a remote repository. For example, pre-commit. Pre-commit. Installer. js is a generated installation file, which is also a script. Each file on Github has its raw address. Curl = curl = curl = curl = curl = curl = curl = curl

curl https://raw.githubusercontent.com/y8n/git-hooks-node/master/xgfe-ma/pre-commit.installer.js | nodeCopy the code

The installation effect is as follows

So once you write a hook and publish it, project members can click on it as long as they know the address (which is a little exciting to think about). This does not solve the problem that the hooks will not move with the warehouse, but it also provides a solution for a common set of hooks in the project team.

Other solutions

Husky is an open source project on GitHub that automatically creates hooks in the.git/hooks directory when NPM installs this module, and then specifies the execution script for each hook in package.json, as shown below

"scripts": { "precommit": "npm test", "prepush": "npm test", "commit-msg": "./validate-commit-msg.js", "..." : "..." }Copy the code

It is possible to use the hooks on your project to achieve the same git hook as the hooks on your project. The problem is that you must rely on husky on your project.