为git存储库启用预接收挂钩时:
它不需要参数,但是对于每个ref都要更新它在标准输入上接收格式的一行:
<旧值> SP<新值> SP< ref-name> LF
其中<旧值>是存储在ref中的旧对象名称,<新值>是要存储在ref中的新对象名称,是ref的全名。在创建新的ref时,<旧值>是40 0。
如果我允许此提交,是否有人可以解释我如何检查将在存储库中更改的所有文件?
我想通过一些脚本来运行这些文件来检查语法等等。
感谢。
答案 0 :(得分:19)
奇怪的是,我有一些代码来自git - > Wordpress实用程序可能有所帮助。以下内容将为您提供接收中更改的所有文件的列表及其内容。没有保证,可能有错误,可能不是最有效的方法,等等等等等等。这些代码中的一些基于gitshelve中的内容,这对于通用git maniuplation来说是一件非常棒的事情。
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)
答案 1 :(得分:10)
我刚刚这样做了。这是我使用的基本流程。
在你的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
在迭代所有引用后,提交和文件退出非零以拒绝推送,或者零返回以允许它
请注意,此方法按顺序遍历所有提交,因此如果在多个提交中修改了文件,则会检查每个版本。如果您只想在推送中查看每个文件,请改为以相反的顺序遍历提交,而不是两次检查给定的文件。我推荐第一种方法,以便检查推送文件的所有版本。
答案 2 :(得分:1)
如果要在推送到远程存储库之前知道文件的权限是否在本地存储库中更改,请运行git ls-tree -r commit
,其中commit是本地存储库的SHA提交值。
此命令提供具有其权限的文件列表,可以对其进行解析以检查在推送之前是否更改了文件的权限。