Git钩子(Hooks)之commit之前自动执行脚本

介绍

官方文档:

下面只复制了pre-commit部分文档,其他详见官方文档。

Git Hooks

Like many other Version Control Systems, Git has a way to fire off custom scripts when certain important actions occur. There are two groups of these hooks: client-side and server-side. Client-side hooks are triggered by operations such as committing and merging, while server-side hooks run on network operations such as receiving pushed commits. You can use these hooks for all sorts of reasons.

Installing a Hook

The hooks are all stored in the hooks subdirectory of the Git directory. In most projects, that's .git/hooks. When you initialize a new repository with git init, Git populates the hooks directory with a bunch of example scripts, many of which are useful by themselves; but they also document the input values of each script. All the examples are written as shell scripts, with some Perl thrown in, but any properly named executable scripts will work fine -- you can write them in Ruby or Python or whatever language you are familiar with. If you want to use the bundled hook scripts, you'll have to rename them; their file names all end with .sample.

To enable a hook script, put a file in the hooks subdirectory of your .git directory that is named appropriately (without any extension) and is executable. From that point forward, it should be called. We'll cover most of the major hook filenames here.

Client-Side Hooks

There are a lot of client-side hooks. This section splits them into committing-workflow hooks, email-workflow scripts, and everything else.

Note It's important to note that client-side hooks are not copied when you clone a repository. If your intent with these scripts is to enforce a policy, you'll probably want to do that on the server side; see the example in An Example Git-Enforced Policy.
Committing-Workflow Hooks

The first four hooks have to do with the committing process.

The pre-commit hook is run first, before you even type in a commit message. It's used to inspect the snapshot that's about to be committed, to see if you've forgotten something, to make sure tests run, or to examine whatever you need to inspect in the code. Exiting non-zero from this hook aborts the commit, although you can bypass it with git commit --no-verify. You can do things like check for code style (run lint or something equivalent), check for trailing whitespace (the default hook does exactly this), or check for appropriate documentation on new methods.

翻译:

Git 钩子

和其它版本控制系统一样,Git 能在特定的重要动作发生时触发自定义脚本。 有两组这样的钩子:客户端的和服务器端的。 客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 你可以随心所欲地运用这些钩子。

安装一个钩子

钩子都被存储在 Git 目录下的 hooks 子目录中。 也即绝大部分项目中的 .git/hooks 。 当你用 git init 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。 这些脚本除了本身可以被调用外,它们还透露了被触发时所传入的参数。 所有的示例都是 shell 脚本,其中一些还混杂了 Perl 代码,不过,任何正确命名的可执行脚本都可以正常使用 ------ 你可以用 Ruby 或 Python,或任何你熟悉的语言编写它们。 这些示例的名字都是以 .sample 结尾,如果你想启用它们,得先移除这个后缀。

把一个正确命名(不带扩展名)且可执行的文件放入 .git 目录下的 hooks 子目录中,即可激活该钩子脚本。 这样一来,它就能被 Git 调用。接下来,我们会讲解常用的钩子脚本类型。

客户端钩子

客户端钩子分为很多种。 下面把它们分为:提交工作流钩子、电子邮件工作流钩子和其它钩子。

Note 需要注意的是,克隆某个版本库时,它的客户端钩子 并不 随同复制。 如果需要靠这些脚本来强制维持某种策略,建议你在服务器端实现这一功能。 (请参照 使用强制策略的一个例子 中的例子。)
提交工作流钩子

前四个钩子涉及提交的过程。

pre-commit 钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 git commit --no-verify 来绕过这个环节。 你可以利用该钩子,来检查代码风格是否一致(运行类似 lint 的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。

分析

结合文档说明,git init之后其实就会生成hooks示例文件,在./.git/hooks/目录下,*.sample就是,使用的时候我们需要把后缀.sample去掉,它就会生效了。

shell 复制代码
$ ls -alh ./.git/hooks/
total 53K
drwxr-xr-x 1 Administrator 197121    0  5月 26 23:59 ./
drwxr-xr-x 1 Administrator 197121    0  5月 27 18:52 ../
-rwxr-xr-x 1 Administrator 197121  478  5月 26 23:59 applypatch-msg.sample*
-rwxr-xr-x 1 Administrator 197121  896  5月 26 23:59 commit-msg.sample*
-rwxr-xr-x 1 Administrator 197121 4.6K  5月 26 23:59 fsmonitor-watchman.sample*
-rwxr-xr-x 1 Administrator 197121  189  5月 26 23:59 post-update.sample*
-rwxr-xr-x 1 Administrator 197121  424  5月 26 23:59 pre-applypatch.sample*
-rwxr-xr-x 1 Administrator 197121 1.7K  5月 26 23:59 pre-commit.sample*
-rwxr-xr-x 1 Administrator 197121  416  5月 26 23:59 pre-merge-commit.sample*
-rwxr-xr-x 1 Administrator 197121 1.5K  5月 26 23:59 prepare-commit-msg.sample*
-rwxr-xr-x 1 Administrator 197121 1.4K  5月 26 23:59 pre-push.sample*
-rwxr-xr-x 1 Administrator 197121 4.8K  5月 26 23:59 pre-rebase.sample*
-rwxr-xr-x 1 Administrator 197121  544  5月 26 23:59 pre-receive.sample*
-rwxr-xr-x 1 Administrator 197121 2.8K  5月 26 23:59 push-to-checkout.sample*
-rwxr-xr-x 1 Administrator 197121 3.6K  5月 26 23:59 update.sample*

具体使用

以pre-commit为例,进行测试,文档介绍了例子是在提交之前进行代码的操作,这里就简单点:将当前时间打印到某个文件。

shell 复制代码
# 新建shell
echo 'date >> now_time.txt' > print_time.sh
chmod +x print_time.sh

# 去掉后缀
mv ./.git/hooks/pre-commit.sample ./.git/hooks/pre-commit
vim ./.git/hooks/pre-commit

# <<<内容
#!/bin/sh
echo "Running pre-commit hook"
sh ./print_time.sh
git add now_time.txt
# 内容>>>

git add print_time.sh
git commit -m "feat: add print_time.sh"

# 提交打印的日志
$ git commit -m "feat: update print_time.sh"
Running pre-commit hook
[main c9bf1ef] feat: update test.sh
 2 files changed, 2 insertions(+)
 create mode 100644 print_time.sh
 create mode 100644 now_time.txt

至此,成功实现在提交之前自动执行脚本的效果。

其他类型的hooks其实就是嵌入的时机不同,当然也有一些各自的属性,可参照这个pre-commit进行实现。

相关推荐
苏三有春22 分钟前
五分钟学会如何在GitHub上自动化部署个人博客(hugo框架 + stack主题)
git·go·github
high201111 小时前
【Git】-- 版本说明
git
kaixin_learn_qt_ing12 小时前
git clone
git
sin220112 小时前
git stash
git
喝鸡汤12 小时前
一起学Git【第二节:创建版本库】
git
慢慢成长的码农12 小时前
git 同步分支操作
git
sin220112 小时前
git推送本地仓库到远程(Gitee)
git·gitee
丁总学Java14 小时前
git branch -r(--remotes )显示你本地仓库知道的所有 远程分支 的列表
git
yylの博客17 小时前
Windows通过git-bash安装zsh
windows·git·bash·zsh
丁总学Java17 小时前
(Z Shell)zsh: no matches found: ? 使用单引号包裹
git·zsh