|
1 | 1 | [[_git_hooks]]
|
2 |
| -=== Git Hooks |
| 2 | +=== Git 钩子 |
3 | 3 |
|
4 | 4 | (((hooks)))
|
5 |
| -Like many other Version Control Systems, Git has a way to fire off custom scripts when certain important actions occur. |
6 |
| -There are two groups of these hooks: client-side and server-side. |
7 |
| -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. |
8 |
| -You can use these hooks for all sorts of reasons |
| 5 | +和其它版本控制系统一样,Git 能在特定的重要动作发生时触发自定义脚本。 |
| 6 | +有两组这样的钩子:客户端的和服务器端的。 |
| 7 | +客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 |
| 8 | +你可以随心所欲地运用这些钩子。 |
9 | 9 |
|
10 |
| -==== Installing a Hook |
| 10 | +==== 安装一个钩子 |
11 | 11 |
|
12 |
| -The hooks are all stored in the `hooks` subdirectory of the Git directory. |
13 |
| -In most projects, that's `.git/hooks`. |
14 |
| -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. |
15 |
| -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 what have you. |
16 |
| -If you want to use the bundled hook scripts, you'll have to rename them; their file names all end with `.sample`. |
| 12 | +钩子都被存储在 Git 目录下的 `hooks` 子目录中。 |
| 13 | +也即绝大部分项目中的 `.git/hooks` 。 |
| 14 | +当你用 `git init` 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。这些脚本除了本身可以被调用外,它们还透露了被触发时所传入的参数。 |
| 15 | +所有的示例都是 shell 脚本,其中一些还混杂了 Perl 代码,不过,任何正确命名的可执行脚本都可以正常使用 —— 你可以用 Ruby 或 Python,或其它语言编写它们。 |
| 16 | +这些示例的名字都是以 `.sample` 结尾,如果你想启用它们,得先移除这个后缀。 |
17 | 17 |
|
18 |
| -To enable a hook script, put a file in the `hooks` subdirectory of your Git directory that is named appropriately and is executable. |
19 |
| -From that point forward, it should be called. |
20 |
| -I'll cover most of the major hook filenames here. |
| 18 | +把一个正确命名且可执行的文件放入 Git 目录下的 `hooks` 子目录中,即可激活该钩子脚本。 |
| 19 | +这样一来,它就能被 Git 调用。 |
| 20 | +接下来,我会讲解常用的钩子脚本类型。 |
21 | 21 |
|
22 |
| -==== Client-Side Hooks |
| 22 | +==== 客户端钩子 |
23 | 23 |
|
24 |
| -There are a lot of client-side hooks. |
25 |
| -This section splits them into committing-workflow hooks, e-mail-workflow scripts, and everything else. |
| 24 | +客户端钩子分为很多种。 |
| 25 | +下面把它们分为:提交工作流钩子、电子邮件工作流钩子和其它钩子。 |
26 | 26 |
|
27 | 27 | [NOTE]
|
28 | 28 | ====
|
29 |
| -It's important to note that client-side hooks are *not* copied when you clone a repository. |
30 |
| -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>>. |
| 29 | +需要注意的是,克隆某个版本库时,它的客户端钩子 *并不* 随同复制。 |
| 30 | +如果需要靠这些脚本来强制维持某种策略,建议你在服务器端实现这一功能。(请参照 <<_an_example_git_enforced_policy>> 中的例子。) |
31 | 31 | ====
|
32 | 32 |
|
33 |
| -===== Committing-Workflow Hooks |
| 33 | +===== 提交工作流钩子 |
34 | 34 |
|
35 |
| -The first four hooks have to do with the committing process. |
| 35 | +前四个钩子涉及提交的过程。 |
36 | 36 |
|
37 |
| -The `pre-commit` hook is run first, before you even type in a commit message. |
38 |
| -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. |
39 |
| -Exiting non-zero from this hook aborts the commit, although you can bypass it with `git commit --no-verify`. |
40 |
| -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. |
| 37 | +`pre-commit` 钩子在键入提交信息前运行。 |
| 38 | +它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 |
| 39 | +如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 `git commit --no-verify` 来绕过这个环节。 |
| 40 | +你可以利用该钩子,来检查代码风格是否一致(运行类似 `lint` 的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。 |
41 | 41 |
|
42 |
| -The `prepare-commit-msg` hook is run before the commit message editor is fired up but after the default message is created. |
43 |
| -It lets you edit the default message before the commit author sees it. |
44 |
| -This hook takes a few parameters: the path to the file that holds the commit message so far, the type of commit, and the commit SHA-1 if this is an amended commit. |
45 |
| -This hook generally isn't useful for normal commits; rather, it's good for commits where the default message is auto-generated, such as templated commit messages, merge commits, squashed commits, and amended commits. |
46 |
| -You may use it in conjunction with a commit template to programmatically insert information. |
| 42 | +`prepare-commit-msg` 钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 |
| 43 | +它允许你编辑提交者所看到的默认信息。 |
| 44 | +该钩子接收一些选项:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验。 |
| 45 | +它对一般的提交来说并没有什么用;然而对那些会自动产生默认信息的提交,如提交信息模板、合并提交、压缩提交和修订提交等非常实用。 |
| 46 | +你可以结合提交模板来使用它,动态地插入信息。 |
47 | 47 |
|
48 |
| -The `commit-msg` hook takes one parameter, which again is the path to a temporary file that contains the commit message written by the developer. |
49 |
| -If this script exits non-zero, Git aborts the commit process, so you can use it to validate your project state or commit message before allowing a commit to go through. |
50 |
| -In the last section of this chapter, I'll demonstrate using this hook to check that your commit message is conformant to a required pattern. |
| 48 | +`commit-msg` 钩子接收一个参数,此参数即上文提到的,存有当前提交信息的临时文件的路径。 |
| 49 | +如果该钩子脚本以非零值退出,Git 将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。 |
| 50 | +在本章的最后一节,我将展示如何使用该钩子来核对提交信息是否遵循指定的模板。 |
51 | 51 |
|
52 |
| -After the entire commit process is completed, the `post-commit` hook runs. |
53 |
| -It doesn't take any parameters, but you can easily get the last commit by running `git log -1 HEAD`. |
54 |
| -Generally, this script is used for notification or something similar. |
| 52 | +`post-commit` 钩子在整个提交过程完成后运行。 |
| 53 | +它不接收任何参数,但你可以很容易地通过运行 `git log -1 HEAD` 来获得最后一次的提交信息。 |
| 54 | +该钩子一般用于通知之类的事情。 |
55 | 55 |
|
56 | 56 | [[_email_hooks]]
|
57 |
| -===== E-mail Workflow Hooks |
| 57 | +===== 电子邮件工作流钩子 |
58 | 58 |
|
59 |
| -You can set up three client-side hooks for an e-mail-based workflow. |
60 |
| -They're all invoked by the `git am` command, so if you aren't using that command in your workflow, you can safely skip to the next section. |
61 |
| -If you're taking patches over e-mail prepared by `git format-patch`, then some of these may be helpful to you. |
| 59 | +你可以给电子邮件工作流设置三个客户端钩子。 |
| 60 | +它们都是由 `git am` 命令调用的,因此如果你没有在你的工作流中用到这个命令,可以跳到下一节。 |
| 61 | +如果你需要通过电子邮件接收由 `git format-patch` 产生的补丁,这些钩子也许用得上。 |
62 | 62 |
|
63 |
| -The first hook that is run is `applypatch-msg`. |
64 |
| -It takes a single argument: the name of the temporary file that contains the proposed commit message. |
65 |
| -Git aborts the patch if this script exits non-zero. |
66 |
| -You can use this to make sure a commit message is properly formatted, or to normalize the message by having the script edit it in place. |
| 63 | +第一个运行的钩子是 `applypatch-msg` 。 |
| 64 | +它接收单个参数:包含请求合并信息的临时文件的名字。 |
| 65 | +如果脚本返回非零值,Git 将放弃该补丁。 |
| 66 | +你可以用该脚本来确保提交信息符合格式,或直接用脚本修正格式错误。 |
67 | 67 |
|
68 |
| -The next hook to run when applying patches via `git am` is `pre-applypatch`. |
69 |
| -Somewhat confusingly, it is run _after_ the patch is applied but before a commit is made, so you can use it to inspect the snapshot before making the commit. |
70 |
| -You can run tests or otherwise inspect the working tree with this script. |
71 |
| -If something is missing or the tests don't pass, exiting non-zero aborts the `git am` script without committing the patch. |
| 68 | +下一个在 `git am` 运行期间被调用的是 `pre-applypatch` 。 |
| 69 | +有些难以理解的是,它正好运行于应用补丁 _之后_,产生提交之前,所以你可以用它在提交前检查快照。 |
| 70 | +你可以用这个脚本运行测试或检查工作区。 |
| 71 | +如果有什么遗漏,或测试未能通过,脚本会以非零值退出,中断 `git am` 的运行,这样补丁就不会被提交。 |
72 | 72 |
|
73 |
| -The last hook to run during a `git am` operation is `post-applypatch`, which runs after the commit is made. |
74 |
| -You can use it to notify a group or the author of the patch you pulled in that you've done so. |
75 |
| -You can't stop the patching process with this script. |
| 73 | +`post-applypatch` 运行于提交产生之后,是在 `git am` 运行期间最后被调用的钩子。 |
| 74 | +你可以用它把结果通知给一个小组或所拉取的补丁的作者。 |
| 75 | +但你没办法用它停止打补丁的过程。 |
76 | 76 |
|
77 | 77 | [[_other_client_hooks]]
|
78 |
| -===== Other Client Hooks |
| 78 | +===== 其它客户端钩子 |
79 | 79 |
|
80 |
| -The `pre-rebase` hook runs before you rebase anything and can halt the process by exiting non-zero. |
81 |
| -You can use this hook to disallow rebasing any commits that have already been pushed. |
82 |
| -The example `pre-rebase` hook that Git installs does this, although it makes some assumptions that may not match with your workflow. |
| 80 | +`pre-rebase` 钩子运行于变基之前,以非零值退出可以中止变基的过程。 |
| 81 | +你可以使用这个钩子来禁止对已经推送的提交变基。 |
| 82 | +Git 自带的 `pre-rebase` 钩子示例就是这么做的,不过它所做的一些假设可能与你的工作流程不匹配。 |
83 | 83 |
|
84 |
| -The `post-rewrite` hook is run by commands that replace commits, such as `git commit --amend` and `git rebase` (though not by `git filter-branch`). |
85 |
| -Its single argument is which command triggered the rewrite, and it receives a list of rewrites on `stdin`. |
86 |
| -This hook has many of the same uses as the `post-checkout` and `post-merge` hooks. |
| 84 | +`post-rewrite` 钩子被那些会替换提交记录的命令调用,比如 `git commit --amend` 和 `git rebase`(不过不包括 `git filter-branch`)。 |
| 85 | +它唯一的参数是触发重写的命令名,同时从标准输入中接受一系列重写的提交记录。 |
| 86 | +这个钩子的用途很大程度上跟 `post-checkout` 和 `post-merge` 差不多。 |
87 | 87 |
|
88 |
| -After you run a successful `git checkout`, the `post-checkout` hook runs; you can use it to set up your working directory properly for your project environment. |
89 |
| -This may mean moving in large binary files that you don't want source controlled, auto-generating documentation, or something along those lines. |
| 88 | +在 `git checkout` 成功运行后,`post-checkout` 钩子会被调用。你可以根据你的项目环境用它调整你的工作目录。 |
| 89 | +其中包括放入大的二进制文件、自动生成文档或进行其他类似这样的操作。 |
90 | 90 |
|
91 |
| -The `post-merge` hook runs after a successful `merge` command. |
92 |
| -You can use it to restore data in the working tree that Git can't track, such as permissions data. |
93 |
| -This hook can likewise validate the presence of files external to Git control that you may want copied in when the working tree changes. |
| 91 | +在 `git merge` 成功运行后,`post-merge` 钩子会被调用。 |
| 92 | +你可以用它恢复 Git 无法跟踪的工作区数据,比如权限数据。 |
| 93 | +这个钩子也可以用来验证某些在 Git 控制之外的文件是否存在,这样你就能在工作区改变时,把这些文件复制进来。 |
94 | 94 |
|
95 |
| -The `pre-push` hook runs during `git push`, after the remote refs have been updated but before any objects have been transferred. |
96 |
| -It receives the name and location of the remote as parameters, and a list of to-be-updated refs through `stdin`. |
97 |
| -You can use it to validate a set of ref updates before a push occurs (a non-zero exit code will abort the push). |
| 95 | +`pre-push` 钩子会在 `git push` 运行期间, 更新了远程引用但尚未传送对象时被调用。 |
| 96 | +它接受远程分支的名字和位置作为参数,同时从标准输入中读取一系列待更新的引用。 |
| 97 | +你可以在推送开始之前,用它验证对引用的更新操作(一个非零的退出码将终止推送过程)。 |
98 | 98 |
|
99 |
| -Git occasionally does garbage collection as part of its normal operation, by invoking `git gc --auto`. |
100 |
| -The `pre-auto-gc` hook is invoked just before the garbage collection takes place, and can be used to notify you that this is happening, or to abort the collection if now isn't a good time. |
| 99 | +Git 的一些日常操作在运行时,偶尔会调用 `git gc --auto` 进行垃圾回收。 |
| 100 | +`pre-auto-gc` 钩子会在垃圾回收开始之前被调用,可以用它来提醒你现在要回收垃圾了,或者依情形判断是否要中断回收。 |
101 | 101 |
|
102 |
| -==== Server-Side Hooks |
| 102 | +==== 服务器端钩子 |
103 | 103 |
|
104 |
| -In addition to the client-side hooks, you can use a couple of important server-side hooks as a system administrator to enforce nearly any kind of policy for your project. |
105 |
| -These scripts run before and after pushes to the server. |
106 |
| -The pre hooks can exit non-zero at any time to reject the push as well as print an error message back to the client; you can set up a push policy that's as complex as you wish. |
| 104 | +除了客户端钩子,作为系统管理员,你还可以使用若干服务器端的钩子对项目强制执行各种类型的策略。 |
| 105 | +这些钩子脚本在推送到服务器之前和之后运行。 |
| 106 | +推送到服务器前运行的钩子可以在任何时候以非零值退出,拒绝推送并给客户端返回错误消息,还可以依你所想设置足够复杂的推送策略。 |
107 | 107 |
|
108 | 108 | ===== `pre-receive`
|
109 | 109 |
|
110 |
| -The first script to run when handling a push from a client is `pre-receive`. |
111 |
| -It takes a list of references that are being pushed from stdin; if it exits non-zero, none of them are accepted. |
112 |
| -You can use this hook to do things like make sure none of the updated references are non-fast-forwards, or to do access control for all the refs and files they're modifying with the push. |
| 110 | +处理来自客户端的推送操作时,最先被调用的脚本是 `pre-receive`。 |
| 111 | +它从标准输入获取一系列被推送的引用。如果它以非零值退出,所有的推送内容都不会被接受。 |
| 112 | +你可以用这个钩子阻止对引用进行非快进(non-fast-forward)的更新,或者对该推送所修改的所有引用和文件进行访问控制。 |
113 | 113 |
|
114 | 114 | ===== `update`
|
115 | 115 |
|
116 |
| -The `update` script is very similar to the `pre-receive` script, except that it's run once for each branch the pusher is trying to update. |
117 |
| -If the pusher is trying to push to multiple branches, `pre-receive` runs only once, whereas update runs once per branch they're pushing to. |
118 |
| -Instead of reading from stdin, this script takes three arguments: the name of the reference (branch), the SHA-1 that reference pointed to before the push, and the SHA-1 the user is trying to push. |
119 |
| -If the update script exits non-zero, only that reference is rejected; other references can still be updated. |
| 116 | +`update` 脚本和 `pre-receive` 脚本十分类似,不同之处在于它会为每一个准备更新的分支各运行一次。 |
| 117 | +假如推送者同时向多个分支推送内容,`pre-receive` 只运行一次,相比之下 `update` 则会为每一个被推送的分支各运行一次。 |
| 118 | +它不会从标准输入读取内容,而是接受三个参数:引用的名字(分支),推送前的引用指向的内容的 SHA-1 值,以及用户准备推送的内容的 SHA-1 值。 |
| 119 | +如果 update 脚本以非零值退出,只有相应的那一个引用会被拒绝;其余的依然会被更新。 |
120 | 120 |
|
121 | 121 | ===== `post-receive`
|
122 | 122 |
|
123 |
| -The `post-receive` hook runs after the entire process is completed and can be used to update other services or notify users. |
124 |
| -It takes the same stdin data as the `pre-receive` hook. |
125 |
| -Examples include e-mailing a list, notifying a continuous integration server, or updating a ticket-tracking system – you can even parse the commit messages to see if any tickets need to be opened, modified, or closed. |
126 |
| -This script can't stop the push process, but the client doesn't disconnect until it has completed, so be careful if you try to do anything that may take a long time. |
| 123 | +`post-receive` 挂钩在整个过程完结以后运行,可以用来更新其他系统服务或者通知用户。 |
| 124 | +它接受与 `pre-receive` 相同的标准输入数据。 |
| 125 | +它的用途包括给某个邮件列表发信,通知持续集成(continous integration)的服务器,或者更新问题追踪系统(ticket-tracking system) —— 甚至可以通过分析提交信息来决定某个问题(ticket)是否应该被开启,修改或者关闭。 |
| 126 | +该脚本无法终止推送进程,不过客户端在它结束运行之前将保持连接状态,所以如果你想做其他操作需谨慎使用它,因为它将耗费你很长的一段时间。 |
0 commit comments