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.

NoteIt’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去掉,它就会生效了。

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

具体使用

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

# 新建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进行实现。

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值