[英]Git pre-receive hook
当您为 git 存储库启用预接收挂钩时:
它不接受任何参数,但是对于每个要更新的 ref,它在标准输入上接收一行格式如下:
<旧值> SP <新值> SP <引用名称> LF
其中 <old-value> 是存储在 ref 中的旧对象名称,< new-value> 是要存储在 ref 中的新对象名称,是 ref 的全名。 创建新ref时,<old-value>为40 0。
有谁可以解释一下,如果我允许此提交,我将如何检查存储库中将更改的所有文件?
我想通过一些脚本运行这些文件来检查语法等等。
谢谢。
奇怪的是,我有一些来自 git -> Wordpress 实用程序的代码可能会有所帮助。 以下将为您提供接收中更改的所有文件及其内容的列表。 没有保证,可能有错误,可能不是最有效的方法,等等。 其中一些代码基于gitshelve 中的内容,这对于通用 git 操作来说非常棒。
import sys
import os
import subprocess
def git(args, **kwargs):
environ = os.environ.copy()
if 'repo' in kwargs:
environ['GIT_DIR'] = kwargs['repo']
if 'work' in kwargs:
environ['GIT_WORK_TREE'] = kwargs['work']
proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=environ)
return proc.communicate()
def get_changed_files(base, commit, **kw):
(results, code) = git(('git', 'diff', '--numstat', "%s..%s" % (base, commit)), **kw)
lines = results.split('\n')[:-1]
return map(lambda x: x.split('\t')[2], lines)
def get_new_file(filename, commit):
(results, code) = git(('git', 'show', '%s:%s' % (commit, filename)))
return results
repo = os.getcwd()
basedir = os.path.join(repo, "..")
line = sys.stdin.read()
(base, commit, ref) = line.strip().split()
modified = get_changed_files(base, commit)
for fname in modified:
print "=====", fname
print get_new_file(fname, commit)
我就是这样做的。 这是我使用的基本流程。
在您的 pre-receive 钩子中,从 stdin 读取每一行,(如您所述)如下所示:
oldref newref refname
对于每个 (oldref, newref) 对,您需要列出所有提交:
git show --format=format:%H --quiet oldref..newref
对于每次提交,您需要列出所有文件:
git diff --name-only commit^..commit
要检查文件,请使用 git show:
git show commit:filepath
在这里检查文件内容。 如果您想将问题通知用户,请写入 stderr
在迭代所有引用后,提交和文件退出非零以拒绝推送,或零以允许它
请注意,此方法按顺序遍历所有提交,因此如果在多次提交中修改了一个文件,每个版本都将被检查。 如果您只想查看一次推送中的每个文件,请以相反的顺序遍历提交,并且不要检查给定文件两次。 但是,我推荐第一种方法,以便检查所有版本的推送文件。
如果你想在推送到远程仓库之前知道本地仓库中文件的权限是否发生了变化,运行git ls-tree -r commit
,其中 commit 是本地仓库的 SHA 提交值。
该命令给出了一个文件及其权限的列表,可以在推送之前对其进行解析以检查文件的权限是否已更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.