Git hooks

 

当某些重要事件发生时,Git 以调用自定义脚本。有两组挂钩:客户端和服务器端。客户端挂钩用于客户端的操作,如提交和合并。服务器端挂钩用于 Git 服务器端的操作,如接收被推送的提交。

 

激活挂钩

挂钩都被存储在 Git 目录下的hooks子目录中,即大部分项目中的.git/hooks。把一个正确命名且可执行的文件放入 Git 目录下的hooks子目录中,可以激活该挂钩脚本,因此,之后他一直会被Git 调用

 

客户端挂钩

有 4个挂钩被用来处理提交的过程。

pre-commit挂钩在键入提交信息前运行,被用来检查即将提交的快照,例如,检查是否有东西被遗漏,确认测试是否运行,以及检查代码。当从该挂钩返回非零值时,Git 放弃此次提交。

$ catpre-commit.sample

#!/bin/sh

#

# An example hookscript to verify what is about to be committed.

# Called by"git commit" with no arguments. The hook should

# exit with non-zerostatus after issuing an appropriate message if

# it wants to stopthe commit.

#

# To enable this hook, rename this file to"pre-commit".

 

if git rev-parse--verify HEAD >/dev/null 2>&1

then

        against=HEAD

else

        # Initial commit: diff against an emptytree object

       against=4b825dc642cb6eb9a060e54bf8d69288fbee4904

fi

 

# If you want toallow non-ascii filenames set this variable to true.

allownonascii=$(gitconfig hooks.allownonascii)

 

# Redirect output tostderr.

exec 1>&2

 

# Cross platformprojects tend to avoid non-ascii filenames; prevent

# them from beingadded to the repository. We exploit the fact that the

# printable rangestarts at the space character and ends with tilde.

if ["$allownonascii" != "true" ] &&

        # Note that the use of brackets arounda tr range is ok here, (it's

        # even required, for portability toSolaris 10's /usr/bin/tr), since

        # the square bracket bytes happen tofall in the designated range.

        test $(git diff --cached --name-only--diff-filter=A -z $against |

          LC_ALL=C tr -d '[ -~]\0' | wc -c) !=0

then

        echo "Error: Attempt to add anon-ascii file name."

        echo

        echo "This can cause problems ifyou want to work"

        echo "with people on otherplatforms."

        echo

        echo "To be portable it isadvisable to rename the file ..."

        echo

        echo "If you know what you aredoing you can disable this"

        echo "check using:"

        echo

        echo "  git config hooks.allownonascii true"

        echo

        exit 1

fi

 

# If there arewhitespace errors, print the offending file names and fail.

exec git diff-index--check --cached $against --

 

prepare-commit-msg挂钩在提交信息编辑器显示之前,默认信息被创建之后运行。因此,可以有机会在提交作者看到默认信息前进行编辑。该挂钩接收一些选项:拥有提交信息的文件路径,提交类型,如果是一次修订的话,提交的SHA-1校验和。在自动产生的默认提交信息的情况下有作用,如提交信息模板、合并、压缩和修订提交等。

$ catprepare-commit-msg.sample

#!/bin/sh

#

# An example hookscript to prepare the commit log message.

# Called by"git commit" with the name of the file that has the

# commit message,followed by the description of the commit

# message'ssource.  The hook's purpose is to editthe commit

# message file.  If the hook fails with a non-zero status,

# the commit isaborted.

#

# To enable thishook, rename this file to "prepare-commit-msg".

 

# This hook includesthree examples.  The first comments outthe

#"Conflicts:" part of a merge commit.

#

# The secondincludes the output of "git diff --name-status -r"

# into the message,just before the "git status" output. It is

# commented becauseit doesn't cope with --amend or with squashed

# commits.

#

# The third exampleadds a Signed-off-by line to the message, that can

# still beedited.  This is rarely a good idea.

 

case"$2,$3" in

  merge,)

    /usr/bin/perl -i.bak -ne 's/^/# /, s/^##/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

 

# ,|template,)

#   /usr/bin/perl -i.bak -pe '

#      print "\n" . `git diff --cached--name-status -r`

#        if /^#/ && $first++ == 0'"$1" ;;

 

  *) ;;

esac

 

# SOB=$(git varGIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')

# grep -qs"^$SOB" "$1" || echo "$SOB" >>"$1"

 

commit-msg挂钩接收一个参数,此参数是包含最近提交信息的临时文件的路径。如果该挂钩脚本以非零退出,Git 放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。

$ catcommit-msg.sample

#!/bin/sh

#

# An example hookscript to check the commit log message.

# Called by"git commit" with one argument, the name of the file

# that has thecommit message.  The hook should exitwith non-zero

# status afterissuing an appropriate message if it wants to stop the

# commit.  The hook is allowed to edit the commitmessage file.

#

# To enable thishook, rename this file to "commit-msg".

 

# Uncomment thebelow to add a Signed-off-by line to the message.

# Doing this in ahook is a bad idea in general, but the prepare-commit-msg

# hook is moresuited to it.

#

# SOB=$(git varGIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')

# grep -qs"^$SOB" "$1" || echo "$SOB" >>"$1"

 

# This examplecatches duplicate Signed-off-by lines.

 

test "" ="$(grep '^Signed-off-by: ' "$1" |

         sort | uniq -c | sed -e '/^[   ]*1[   ]/d')" || {

        echo >&2 Duplicate Signed-off-bylines.

        exit 1

}

 

post-commit挂钩在整个提交过程完成后运行,他不会接收任何参数,但可以运行git log -1 HEAD来获得最后的提交信息。总之,该挂钩是作为通知之类使用的。

 

提交工作流的客户端挂钩脚本可以在任何工作流中使用,他们经常被用来实施某些策略,但值得注意的是,这些脚本在clone期间不会被传送。可以在服务器端实施策略来拒绝不符合某些策略的推送,但这完全取决于开发者在客户端使用这些脚本的情况。所以,这些脚本对开发者是有用的,由他们自己设置和维护,而且在任何时候都可以覆盖或修改这些脚本。

 

pre-rebase挂钩在衍合前运行,脚本以非零退出可以中止衍合的过程。你可以使用这个挂钩来禁止衍合已经推送的提交对象,Gitpre-rebase挂钩样本就是这么做的。该样本假定next是你定义的分支名,因此,你可能要修改样本,把next改成你定义过且稳定的分支名。

 

在gitcheckout成功运行后,post-checkout挂钩会被调用。他可以用来为你的项目环境设置合适的工作目录。例如:放入大的二进制文件、自动产生的文档或其他一切你不想纳入版本控制的文件。

 

最后,在merge命令成功执行后,post-merge挂钩会被调用。他可以用来在 Git无法跟踪的工作树中恢复数据,诸如权限数据。该挂钩同样能够验证在 Git 控制之外的文件是否存在,因此,当工作树改变时,你想这些文件可以被复制。

 

服务器端挂钩

这些挂钩脚本可以在提交对象推送到服务器前被调用,也可以在推送到服务器后被调用。推送到服务器前调用的挂钩可以在任何时候以非零退出,拒绝推送,返回错误消息给客户端,还可以如你所愿设置足够复杂的推送策略。

 

pre-receive 和 post-receive

处理来自客户端的推送(push)操作时最先执行的脚本就是 pre-receive。它从标准输入(stdin)获取被推送引用的列表;如果它退出时的返回值不是0,所有推送内容都不会被接受。利用此挂钩脚本可以实现类似保证最新的索引中不包含非fast-forward类型的这类效果;抑或检查执行推送操作的用户拥有创建,删除或者推送的权限或者他是否对将要修改的每一个文件都有访问权限。

 

post-receive挂钩在整个过程完结以后运行,可以用来更新其他系统服务或者通知用户。它接受与 pre-receive相同的标准输入数据。应用实例包括给某邮件列表发信,通知实时整合数据的服务器,或者更新软件项目的问题追踪系统 ——甚至可以通过分析提交信息来决定某个问题是否应该被开启,修改或者关闭。该脚本无法组织推送进程,不过客户端在它完成运行之前将保持连接状态;所以在用它作一些消耗时间的操作之前请三思。

 

update

update脚本和 pre-receive脚本十分类似。不同之处在于它会为推送者更新的每一个分支运行一次。假如推送者同时向多个分支推送内容,pre-receive 只运行一次,相比之下 update则会为每一个更新的分支运行一次。它不会从标准输入读取内容,而是接受三个参数:索引的名字(分支),推送前索引指向的内容的 SHA-1 值,以及用户试图推送内容的SHA-1 值。如果 update 脚本以退出时返回非零值,只有相应的那一个索引会被拒绝;其余的依然会得到更新。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值