Improve Git hooks documentation
This commit is contained in:
Родитель
5ebbc58d6b
Коммит
e0dc9c0c6e
|
@ -4,89 +4,66 @@ title: Installing Git hooks
|
|||
navigation_source: docs_nav
|
||||
---
|
||||
|
||||
The Git version control system allows you to configure hook scripts that will be invoked when certain actions are
|
||||
performed. (See Git's [Customizing Git](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) chapter
|
||||
for complete documentation.) The basic idea is that you create shell scripts under your `.git/hooks` folder with
|
||||
well-known names such as **pre-commit**, **post-update**, **prepare-commit-msg**, and so forth.
|
||||
If the Git client sees these scripts, it will invoke them whenever the corresponding operations are performed.
|
||||
The Git version control system allows you to configure hook scripts that will be invoked whenever certain actions
|
||||
are performed. (See Git's [Customizing Git](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) chapter
|
||||
for complete documentation.) The basic idea is that you create shell scripts with well-known names such as
|
||||
**pre-commit**, **post-update**, **prepare-commit-msg**, and so forth. If the Git client finds these scripts
|
||||
in the local **.git/hooks** folder, it will run the scripts whenever the corresponding operations are performed.
|
||||
|
||||
For security reasons, Git does not automatically install these scripts when you clone a repo. Instead, you must
|
||||
invoke a command that creates them and chmods them to be executable. Rush can automate this for you!
|
||||
For security reasons, Git will not automatically install these scripts when you clone a repo. Instead, each
|
||||
developer must invoke a command that creates the files and chmods them to be executable. Rush can automate
|
||||
this for you!
|
||||
|
||||
## Configuring Rush to install a Git hook script
|
||||
|
||||
As an example, suppose that we want to keep our source code tidy by automatically invoking the
|
||||
[Prettier](https://prettier.io/) code formatter whenever someone commits a change to Git.
|
||||
As an example, suppose we find that developers are making commits without a meaningful description of their work.
|
||||
As a result, the Git history is difficult to understand. To solve this problem, might want to add a `commit-msg`
|
||||
hook that requires the commit message to meet certain requirements. For example, here's a simple Bash script that
|
||||
requires at least 3 words of text:
|
||||
|
||||
Here's how to set that up:
|
||||
|
||||
**1<!---->. Check your Rush version.** Make sure your **rush.json** file installs Rush 5.5.1 or newer, which
|
||||
introduced support for Git hooks.
|
||||
|
||||
**2<!---->. Write the hook script.** In your repo folder, create a **pre-commit** shell script under the
|
||||
"common" folder where Rush stores its configuration files. For this example, we'll use the popular
|
||||
[pretty-quick](https://github.com/azz/pretty-quick) helper that invokes Prettier on a Git change set.
|
||||
(This avoids reformatting the entire code base every time someone makes a change.)
|
||||
|
||||
**common/git-hooks/pre-commit**
|
||||
```sh
|
||||
**common/git-hooks/commit-msg**
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# This is an example Git hook for use with Rush. To enable this hook, rename this file
|
||||
# to "commit-msg" and then run "rush install", which will copy it from common/git-hooks
|
||||
# to the .git/hooks folder.
|
||||
#
|
||||
# TO LEARN MORE ABOUT GIT HOOKS
|
||||
#
|
||||
# The Git documentation is here: https://git-scm.com/docs/githooks
|
||||
# Some helpful resources: https://githooks.com
|
||||
#
|
||||
# ABOUT THIS EXAMPLE
|
||||
#
|
||||
# The commit-msg hook is called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero status after issuing
|
||||
# an appropriate message if it wants to stop the commit. The hook is allowed to edit
|
||||
# the commit message file.
|
||||
|
||||
COMMAND=common/temp/node_modules/.bin/pretty-quick
|
||||
|
||||
echo --------------------------------------------
|
||||
echo Starting Git hook: pre-commit
|
||||
|
||||
if [ -f $COMMAND ]; then
|
||||
echo Invoking $COMMAND
|
||||
$COMMAND
|
||||
else
|
||||
echo Command not installed: $COMMAND
|
||||
# This example enforces that commit message should contain a minimum amount of
|
||||
# description text.
|
||||
if [ `cat $1 | wc -w` -lt 3 ]; then
|
||||
echo ""
|
||||
echo "Invalid commit message: The message must contain at least 3 words."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Finished Git hook: pre-commit
|
||||
echo --------------------------------------------
|
||||
|
||||
```
|
||||
|
||||
**3<!---->. Configure any required dependencies.** The script above requires the **pretty-quick** NPM package,
|
||||
which in turn has a peer dependency on **prettier**. Since we're not setting up a full tooling project with its own
|
||||
**package.json** file, we can simply add **prettier** and **pretty-quick** as Rush "preferred versions". This will
|
||||
ensure that they get installed in the **common/temp/node_modules** folder root whenever `rush install` runs.
|
||||
You would use it as follows:
|
||||
|
||||
**common/config/rush/common-versions.json**
|
||||
```json
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/common-versions.schema.json",
|
||||
1. Add this file in your **common/git-hooks** folder, and commit to Git.
|
||||
2. When a developer runs `rush install`, Rush will copy this file to be **.git/hooks/commit-msg**
|
||||
3. When you run `git commit`, Git will find the script and invoke it
|
||||
4. If the commit message is too short, the script returns a nonzero exit code; Git shows the
|
||||
`Invalid commit message` notice and rejects the operation.
|
||||
|
||||
"preferredVersions": {
|
||||
"prettier": "~1.15.1",
|
||||
"pretty-quick": "~1.8.0"
|
||||
}
|
||||
}
|
||||
Using Rush to install the hook script avoids the need for a separate solution such as the popular
|
||||
[Husky](https://www.npmjs.com/package/husky) package. Note that Husky expects your repo to have a
|
||||
root-level **package.json** and **node_modules** folder, and Husky runs shell commands for every Git operation
|
||||
(even unused hooks); using Rush to install hooks avoids those limitations.
|
||||
|
||||
```
|
||||
|
||||
**4<!---->. Confirm that the hooks were installed.** Run `rush update`, and verify that Rush copied your
|
||||
**pre-commit** script into into the **.git/hooks** folder of your local working folder.
|
||||
|
||||
Now we can try committing a change to Git. You should see our `Starting Git hook: pre-commit` message included
|
||||
in Git's log output:
|
||||
|
||||
```sh
|
||||
$ git commit -m "This is a test"
|
||||
--------------------------------------------
|
||||
Starting Git hook: pre-commit
|
||||
Invoking common/temp/node_modules/.bin/pretty-quick
|
||||
🔍 Finding changed files since git revision ac03c77b6.
|
||||
🎯 Found 1 changed files.
|
||||
✍️ Fixing up projects/test/src/TestClass.ts.
|
||||
✅ Everything is awesome!
|
||||
Finished Git hook: pre-commit
|
||||
--------------------------------------------
|
||||
[my-branch 0d4550305] test
|
||||
1 file changed, 3 insertions(+), 1 deletions(-)
|
||||
```
|
||||
> The sample file shown above is a template that `rush init` generates when setting up a new repo.
|
||||
> You can probably find a copy as
|
||||
> [common/git-hooks/commit-msg.sample](https://github.com/microsoft/rush-example/blob/master/common/git-hooks/commit-msg.sample)
|
||||
> in your own repo.
|
||||
|
|
Загрузка…
Ссылка в новой задаче