简体   繁体   English

Git 预接收钩子

[英]Git pre-receive hook

When you enable pre-receive hook for git repository:当您为 git 存储库启用预接收挂钩时:

It takes no arguments, but for each ref to be updated it receives on standard input a line of the format:它不接受任何参数,但是对于每个要更新的 ref,它在标准输入上接收一行格式如下:

< old-value > SP < new-value > SP < ref-name > LF <旧值> SP <新值> SP <引用名称> LF

where < old-value > is the old object name stored in the ref, < new-value > is the new object name to be stored in the ref and is the full name of the ref.其中 <old-value> 是存储在 ref 中的旧对象名称,< new-value> 是要存储在 ref 中的新对象名称,是 ref 的全名。 When creating a new ref, < old-value > is 40 0.创建新ref时,<old-value>为40 0。

Does anyone can explain me how do I examine all the files that will be changed in the repository if i allow this commit?有谁可以解释一下,如果我允许此提交,我将如何检查存储库中将更改的所有文件?

I'd like to run that files through some scripts to check syntax and so on.我想通过一些脚本运行这些文件来检查语法等等。

Thanks.谢谢。

Oddly, I had some code laying around from a git -> Wordpress utility that might help.奇怪的是,我有一些来自 git -> Wordpress 实用程序的代码可能会有所帮助。 The following will give you a list of all files changed in the receive, as well as their contents.以下将为您提供接收中更改的所有文件及其内容的列表。 No guarantees, may have bugs, may not be the most efficient way to do it, blah blah blah.没有保证,可能有错误,可能不是最有效的方法,等等。 Some of this code is based off stuff in gitshelve , which is a really great thing to look at for generic git manipulation.其中一些代码基于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)

I just did this.我就是这样做的。 Here's the basic flow I used.这是我使用的基本流程。

In your pre-receive hook, read each line from stdin, which (as you mentioned) look like this:在您的 pre-receive 钩子中,从 stdin 读取每一行,(如您所述)如下所示:

oldref newref refname
  1. For each (oldref, newref) pair you need to list all the commits:对于每个 (oldref, newref) 对,您需要列出所有提交:

     git show --format=format:%H --quiet oldref..newref
  2. for each commit you need to list all the files:对于每次提交,您需要列出所有文件:

     git diff --name-only commit^..commit
  3. to examine a file, use git show:要检查文件,请使用 git show:

     git show commit:filepath

    do whatever checking of file contents here.在这里检查文件内容。 If you want to notify the user of an issue, write to stderr如果您想将问题通知用户,请写入 stderr

  4. after iterating all the refs, commits and files exit nonzero to reject the push, or zero to allow it在迭代所有引用后,提交和文件退出非零以拒绝推送,或零以允许它

Note that this approach walks all the commits in order, so if a file is modified in several commits each version will get examined.请注意,此方法按顺序遍历所有提交,因此如果在多次提交中修改了一个文件,每个版本都将被检查。 If you wanted to only view each file in a push once, traverse the commits in reverse order instead, and just don't examine a given file twice.如果您只想查看一次推送中的每个文件,请以相反的顺序遍历提交,并且不要检查给定文件两次。 I recommend the first approach however so that all versions of pushed files are examined.但是,我推荐第一种方法,以便检查所有版本的推送文件。

If you want to know the whether permissions of the files are changed in the local repository before pushing to remote repository, run git ls-tree -r commit , where commit is the SHA commit value of the local repository.如果你想在推送到远程仓库之前知道本地仓库中文件的权限是否发生了变化,运行git ls-tree -r commit ,其中 commit 是本地仓库的 SHA 提交值。

This command gives a list of files with their permissions, which can be parsed to check if the permission of a file is changed before pushing.该命令给出了一个文件及其权限的列表,可以在推送之前对其进行解析以检查文件的权限是否已更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM