鉤子(hooks)是一些在"$GIT-DIR/hooks"目錄的腳本, 在被特定的事件(certain points)觸發后被調用。當"git init"命令被調用后, 一些非常有用的示例鉤子文件(hooks)被拷到新倉庫的hooks目錄中; 但是在默認情況下這些鉤子(hooks)是不生效的。 把這些鉤子文件(hooks)的".sample"文件名后綴去掉就可以使它們生效了。
## applypatch-msg
~~~
GIT_DIR/hooks/applypatch-msg
~~~
當'git-am'命令執行時,這個鉤子就被調用。它只有一個參數:就是存有提交消息(commit log message)的文件的名字。如果鉤子的執行結果是非零,那么補丁(patch)就不會被應用(apply)。
The hook is allowed to edit the message file in place, and can be used to normalize the message into some project standard format (if the project has one). It can also be used to refuse the commit after inspecting the message file. The default applypatch-msg hook, when enabled, runs the commit-msg hook, if the latter is enabled.
這個鉤子用于在其它地方編輯提交消息,并且可以把這些消息規范成項目的標準格式(如果項目些類的標準的話)。它也可以在分析(inspect)完消息文件后拒絕此次提交(commit)。在默認情況下,當 applypatch-msg 鉤子被啟用時。。。。
()
## pre-applypatch
~~~
GIT_DIR/hooks/pre-applypatch
~~~
當'git-am'命令執行時,這個鉤子就被調用。它沒有參數,并且是在一個補丁(patch)被應用后還未提交(commit)前被調用。如果鉤子的執行結果是非零,那么剛才應用的補丁(patch)就不會被提交。
It can be used to inspect the current working tree and refuse to make a commit if it does not pass certain test. The default pre-applypatch hook, when enabled, runs the pre-commit hook, if the latter is enabled.
它用于檢查當前的工作樹,當提交的補丁不能通過特定的測試就拒絕將它提交(commit)進倉庫。 ()
## post-applypatch
~~~
GIT_DIR/hooks/post-applypatch
~~~
This hook is invoked by 'git-am'. It takes no parameter, and is invoked after the patch is applied and a commit is made.
當'git-am'命令執行時,這個鉤子就被調用。它沒有參數,并且是在一個補丁(patch)被應用且在完成提交(commit)情況下被調用。
This hook is meant primarily for notification, and cannot affect the outcome of 'git-am'.
這個鉤子的主要用途是通知提示(notification),它并不會影響'git-am'的執行和輸出。
## pre-commit
~~~
GIT_DIR/hooks/pre-commit
~~~
這個鉤子被 'git-commit' 命令調用, 而且可以通過在命令中添加`\--no-verify`?參數來跳過。這個鉤子沒有參數,在得到提交消息和開始提交(commit)前被調用。如果鉤子執行結果是非零,那么 'git-commit' 命令就會中止執行。
譯注:此鉤子可以用來在提交前檢查代碼錯誤(運行類似lint的程序)。
當默認的'pre-commit'鉤子開啟時,如果它發現文件尾部有空白行,那么就會中止此次提交。
譯注:新版的默認鉤子和這里所說有所有不同。
All the 'git-commit' hooks are invoked with the environment variable?`GIT_EDITOR=:`?if the command will not bring up an editor to modify the commit message.
下面是一個運行 Rspec 測試的 Ruby 腳本,如果沒有通過這個測試,那么不允許提交(commit)。
html_path = "spec_results.html"
`spec -f h:#{html_path} -f p spec` # run the spec. send progress to screen. save html results to html_path
# find out how many errors were found
html = open(html_path).read
examples = html.match(/(\d+) examples/)[0].to_i rescue 0
failures = html.match(/(\d+) failures/)[0].to_i rescue 0
pending = html.match(/(\d+) pending/)[0].to_i rescue 0
if failures.zero?
puts "0 failures! #{examples} run, #{pending} pending"
else
puts "\aDID NOT COMMIT YOUR FILES!"
puts "View spec results at #{File.expand_path(html_path)}"
puts
puts "#{failures} failures! #{examples} run, #{pending} pending"
exit 1
end
## prepare-commit-msg
~~~
GIT_DIR/hooks/prepare-commit-msg
~~~
當'git-commit'命令執行時:在編輯器(editor)啟動前,默認提交消息準備好后,這個鉤子就被調用。
It takes one to three parameters. The first is the name of the file that the commit log message. The second is the source of the commit message, and can be:?`message`?(if a?`-m`?or?`-F`?option was given);?`template`?(if a?`-t`?option was given or the configuration option?`commit.template`?is set);?`merge`?(if the commit is a merge or a?`.git/MERGE_MSG`?file exists);?`squash`?(if a?`.git/SQUASH_MSG`?file exists); or?`commit`, followed by a commit SHA1 (if a?`-c`,?`-C`?or?`\--amend`?option was given).
它有三個參數。第一個是提交消息文件的名字。第二個是提交消息的來源,它可以是:().
如果鉤子的執行結果是非零的話,那么'git-commit'命令就會被中止執行。
The purpose of the hook is to edit the message file in place, and it is not suppressed by the?`\--no-verify`?option. A non-zero exit means a failure of the hook and aborts the commit. It should not be used as replacement for pre-commit hook.
The sample?`prepare-commit-msg`?hook that comes with git comments out the?`Conflicts:`?part of a merge's commit message.
## commit-msg
~~~
GIT_DIR/hooks/commit-msg
~~~
當'git-commit'命令執行時,這個鉤子被調用;也可以在命令中添加`\--no-verify`參數來跳過。這個鉤子有一個參數:就是被選定的提交消息文件的名字。如這個鉤子的執行結果是非零,那么'git-commit'命令就會中止執行。
The hook is allowed to edit the message file in place, and can be used to normalize the message into some project standard format (if the project has one). It can also be used to refuse the commit after inspecting the message file.
這個鉤子的是為提交消息更適當,可以用于規范提交消息使之符合項目的標準(如果有的話);如果它檢查完提交消息后,發現內容不符合某些標準,它也可以拒絕此次提交(commit)。
The default 'commit-msg' hook, when enabled, detects duplicate "Signed-off-by" lines, and aborts the commit if one is found.
默認的'commit-msg'鉤子啟用后,它后檢查里面是否有重復的簽名結束線(Signed-off-by lines),如果找到它就是中止此次提交(commit)操作。
## post-commit
~~~
GIT_DIR/hooks/post-commit
~~~
當'git-commit'命令執行時,這個鉤子就被調用。它沒有參數,并且是在一個提交(commit)完成時被調用。
這個鉤子的主要用途是通知提示(notification),它并不會影響'git-commit'的執行和輸出。
## pre-rebase
~~~
GIT_DIR/hooks/pre-rebase
~~~
當'git-base'命令執行時,這個鉤子就被調用;主要目的是阻止那不應被rebase的分支被rebase(例如,一個已經發布的分支提交就不應被rebase)。
## post-checkout
~~~
GIT_DIR/hooks/post-checkout
~~~
當'git-checkout'命令更新完整個工作樹(worktree)后,這個鉤子就會被調用。這個鉤子有三個參數:前一個HEAD的 ref,新HEAD的 ref,判斷一個簽出是分支簽出還是文件簽出的標識符(分支簽出=1,文件簽出=0)。這個鉤子不會影響'git-checkout'命令的輸出。
這個鉤子可以用于檢查倉庫的一致性,自動顯示簽出前后的代碼的區別,也可以用于設置目錄的元數據屬性。
## post-merge
~~~
GIT_DIR/hooks/post-merge
~~~
This hook is invoked by 'git-merge', which happens when a 'git-pull' is done on a local repository. The hook takes a single parameter, a status flag specifying whether or not the merge being done was a squash merge. This hook cannot affect the outcome of 'git-merge' and is not executed, if the merge failed due to conflicts.
它有一個參數:
This hook can be used in conjunction with a corresponding pre-commit hook to save and restore any form of metadata associated with the working tree (eg: permissions/ownership, ACLS, etc). See contrib/hooks/setgitperms.perl for an example of how to do this.
## pre-receive
~~~
GIT_DIR/hooks/pre-receive
~~~
This hook is invoked by 'git-receive-pack' on the remote repository, which happens when a 'git-push' is done on a local repository. Just before starting to update refs on the remote repository, the pre-receive hook is invoked. Its exit status determines the success or failure of the update.
當用戶在本地倉庫執行'git-push'命令時,服務器上運端倉庫就會對應執行'git-receive-pack'命令,而'git-receive-pack'命令會調用 pre-receive 鉤子。在開始更新遠程倉庫上的ref之前,這個鉤子被調用。鉤子的執行結果(exit status)決定此次更新能否成功。
This hook executes once for the receive operation. It takes no arguments, but for each ref to be updated it receives on standard input a line of the format:
每執行一個接收(receive)操作都會調用一次這個鉤子。它沒有命令行參數,但是它會從標準輸入(standard input)讀取需要更新的ref,格式如下:
~~~
SP?SP?LF
~~~
譯者注:SP是空格,LF是回車。
where?``?is the old object name stored in the ref,?``?is the new object name to be stored in the ref and``?is the full name of the ref. When creating a new ref,?``?is 40?`0`.
``是保存在ref里的老對象的名字,``是保存在ref里的新對象的名字,``就是此次要更新的ref的全名。如果是創建一個新的ref,那么``就是由40個`0`組成的字符串表示。
If the hook exits with non-zero status, none of the refs will be updated. If the hook exits with zero, updating of individual refs can still be prevented by the > hook.
如果鉤子的執行結果是非零,那么沒有引用(ref)會被更新。如果執行結果為零,更新操作還可以被后面的 > 鉤子所阻止。
Both standard output and standard error output are forwarded to 'git-send-pack' on the other end, so you can simply?`echo`messages for the user.
鉤子(hook)的標準輸出和標準錯誤輸出(stdout & stderr)都會通'git-send-pack'轉發給客戶端(other end),你可以把這個信息回顯(echo)給用戶。
If you wrote it in Ruby, you might get the args this way:
如果你用ruby,那么可以像下面的代碼一樣得到它們的參數。
rev_old, rev_new, ref = STDIN.read.split(" ")
Or in a bash script, something like this would work:
在bash腳本中,下面代碼也可能得到參數。
~~~
#!/bin/sh
# <oldrev> <newrev> <refname>
# update a blame tree
while read oldrev newrev ref
do
echo "STARTING [$oldrev $newrev $ref]"
for path in `git diff-tree -r $oldrev..$newrev | awk '{print $6}'`
do
echo "git update-ref refs/blametree/$ref/$path $newrev"
`git update-ref refs/blametree/$ref/$path $newrev`
done
done
~~~
## update
~~~
GIT_DIR/hooks/update
~~~
當用戶在本地倉庫執行'git-push'命令時,服務器上運端倉庫就會對應執行'git-receive-pack',而'git-receive-pack'會調用 update 鉤子。在更新遠程倉庫上的ref之前,這個鉤子被調用。鉤子的執行結果(exit status)決定此次update能否成功。
每更新一個引用(ref),鉤子就會被調用一次,并且使用三個參數:
* the name of the ref being updated, # 要被更的ref的名字
* the old object name stored in the ref, # ref 中更新前的對象名
* and the new objectname to be stored in the ref. # ref 中更新后的對象名
如果 update hook 的執行結果是零,那么引用(ref)就會被更新。如果執行結果是非零,那么’git-receive-pack'就不會更新這個引用(ref)。
This hook can be used to prevent 'forced' update on certain refs by making sure that the object name is a commit object that is a descendant of the commit object named by the old object name. That is, to enforce a "fast forward only" policy.
這個鉤子也可以用于防止強制更新某些 refs,確保old object是new object的父對象。這樣也就是強制執行"fast forward only"策略。
It could also be used to log the old..new status. However, it does not know the entire set of branches, so it would end up firing one e-mail per ref when used naively, though. The > hook is more suited to that.
它也可以用于跟蹤(log)更新詳情。但是由于它不知道每次更新的ref全體集合,盡管可以傻傻的每個ref更新就發送email;但是>鉤子更適合這種情況。
在郵件列表(mailing list)上講了另外一種用法:用這個 update hook 實現細粒度(finer grained)權限控制。
鉤子(hook)的標準輸出和標準錯誤輸出(stdout & stderr)都會通'git-send-pack'轉發給客戶端(other end),你可以把這個信息回顯(echo)給用戶。
當默認的 update hook 被啟用,且`hooks.allowunannotated`選項被打開時,那么沒有注釋(unannotated)的標簽就不能被推送到服務器上。
## post-receive
~~~
GIT_DIR/hooks/post-receive
~~~
This hook is invoked by 'git-receive-pack' on the remote repository, which happens when a 'git-push' is done on a local repository. It executes on the remote repository once after all the refs have been updated.
當用戶在本地倉庫執行'git-push'命令時,服務器上運端倉庫就會對應執行'git-receive-pack'命令;在所有遠程倉庫的引用(ref)都更新后,這個鉤子就會被'git-receive-pack'調用。
This hook executes once for the receive operation. It takes no arguments, but gets the same information as the > hook does on its standard input.
服務器端倉庫每次執行接收(receive)操作時,這個鉤子就會被調用。此鉤子執行不帶任何命令行參數,但是和>鉤子一樣從標準輸入(standard input)讀取信息,并且讀取的信息內容也是一樣的。
This hook does not affect the outcome of 'git-receive-pack', as it is called after the real work is done.
這個鉤子不會影響'git-receive-pack'命令的輸出,因為它是在命令執行完后被調用的。
This supersedes the > hook in that it gets both old and new values of all the refs in addition to their names.
這個鉤子可以取代 >鉤子;因為后者只能得到需要更新的ref的名字,而沒有更新前后的對象的名字。
Both standard output and standard error output are forwarded to 'git-send-pack' on the other end, so you can simply?`echo`messages for the user.
鉤子(hook)的標準輸出和標準錯誤輸出(stdout & stderr)都會通'git-send-pack'轉發給客戶端(other end),你可以把這個信息回顯(echo)給用戶。
The default 'post-receive' hook is empty, but there is a sample script?`post-receive-email`?provided in the?`contrib/hooks`directory in git distribution, which implements sending commit emails.
默認的'post-receive'的鉤子是空的,但是在git distribution?`contrib/hooks`?目錄里有一個名為?`post-receive-email`?的示例腳本,實實了發送commit emails的功能。
## post-update
~~~
GIT_DIR/hooks/post-update
~~~
This hook is invoked by 'git-receive-pack' on the remote repository, which happens when a 'git-push' is done on a local repository. It executes on the remote repository once after all the refs have been updated.
當用戶在本地倉庫執行'git-push'命令時,服務器上運端倉庫就會對應執行'git-receive-pack'。在所有遠程倉庫的引用(ref)都更新后,post-update 就會被調用。
It takes a variable number of parameters, each of which is the name of ref that was actually updated.
它的參數數目是可變的,每個參數代表實際被更新的 ref。
This hook is meant primarily for notification, and cannot affect the outcome of 'git-receive-pack'.
這個鉤子的主要用途是通知提示(notification),它并不會影響'git-receive-pack'的輸出。
The 'post-update' hook can tell what are the heads that were pushed, but it does not know what their original and updated values are, so it is a poor place to do log old..new. The > hook does get both original and updated values of the refs. You might consider it instead if you need them.
'post-update'可以行訴我們哪些 heads 被更新了,但是它不知道head更新前后的值,所以這里不大適合記錄更新詳情。而>鉤子可以得到ref(也可說是head)更新前后的值,如果你要記錄更詳情的話,可以考慮使用這個鉤子。
When enabled, the default 'post-update' hook runs 'git-update-server-info' to keep the information used by dumb transports (e.g., HTTP) up-to-date. If you are publishing a git repository that is accessible via HTTP, you should probably enable this hook.
如果默認的'post-update'鉤子啟用的話,它們執行‘git-update-server-info'命令去更新一些dumb協議(如http)所需要的信息。如果你的git倉庫是通http協議來訪問,那么你就應該開啟它。
Both standard output and standard error output are forwarded to 'git-send-pack' on the other end, so you can simply?`echo`messages for the user.
鉤子(hook)的標準輸出和標準錯誤輸出(stdout & stderr)都會通'git-send-pack'轉發給客戶端(other end),你可以把這個信息回顯(echo)給用戶。
## pre-auto-gc
~~~
GIT_DIR/hooks/pre-auto-gc
~~~
當調用'git-gc --auto'命令時,這個鉤子(hook)就會被調用。它沒有調用參數,如果鉤子的執行結果是非零的話,那么'git-gc --auto'命令就會中止執行。
## 參考
[Git Hooks](http://www.kernel.org/pub/software/scm/git/docs/githooks.html)?* http://probablycorey.wordpress.com/2008/03/07/git-hooks-make-me-giddy/
- 1. 介紹
- 歡迎使用Git
- GIT對象模型
- Git目錄 與 工作目錄
- Git索引
- 2. 第一步
- 安裝Git
- 安裝與初始化
- 3. 基本用法
- 獲得一個Git倉庫
- 正常的工作流程
- 分支與合并@基礎
- 查看歷史 -Git日志
- 比較提交 - Git Diff
- 分布式的工作流程
- Git標簽
- 4. 中級技能
- 忽略某些文件
- rebase
- 交互式rebase
- 交互式添加
- 儲藏
- Git樹名
- 追蹤分支
- 使用Git Grep進行搜索
- Git的撤消操作 - 重置, 簽出 和 撤消
- 維護Git
- 建立一個公共倉庫
- 建立一個私有倉庫
- 5. 高級技能
- 創建新的空分支
- 修改你的歷史
- 高級分支與合并
- 查找問題的利器 - Git Bisect
- 查找問題的利器 - Git Blame
- Git和Email
- 定制Git
- Git Hooks
- 找回丟失的對象
- 子模塊
- 6. Git生態體系
- Git 與之 Windows
- 使用Git進行系統部署
- 與 Subversion 集成
- 從其他代碼管理工具遷移到Git
- 圖形化的Git
- Git倉庫托管
- Git的其它用法
- Git的腳本支持
- Git 與編輯器
- 7. 原理解析
- Git是如何存儲對象的
- 查看Git對象
- Git引用
- Git索引
- 打包文件
- 更底層的Git
- 傳輸協議
- 術語表