Git 预接收钩子

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2569960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 04:13:07  来源:igfitidea点击:

Git pre-receive hook

git

提问by rzajac

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:

< old-value > SP < new-value > SP < ref-name > 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. When creating a new ref, < old-value > is 40 0.

它不接受任何参数,但是对于每个要更新的 ref,它会在标准输入上接收一行格式如下:

<旧值> SP <新值> SP <引用名称> LF

其中 <old-value> 是存储在 ref 中的旧对象名称,< new-value> 是要存储在 ref 中的新对象名称,是 ref 的全名。创建新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.

谢谢。

回答by brool

Oddly, I had some code laying around from a git -> Wordpress utility that might help. 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 maniuplation.

奇怪的是,我有一些来自 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)

回答by drizzo4shizzo

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:

    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 commit:filepath
    

    do whatever checking of file contents here. If you want to notify the user of an issue, write to stderr

  4. after iterating all the refs, commits and files exit nonzero to reject the push, or zero to allow it

  1. 对于每个 (oldref, newref) 对,您需要列出所有提交:

    git show --format=format:%H --quiet oldref..newref
    
  2. 对于每次提交,您需要列出所有文件:

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

    git show commit:filepath
    

    在这里检查文件内容。如果您想将问题通知用户,请写入 stderr

  4. 在迭代所有引用后,提交和文件退出非零以拒绝推送,或零以允许它

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.

请注意,此方法按顺序遍历所有提交,因此如果在多次提交中修改了文件,则每个版本都会被检查。如果您只想查看一次推送中的每个文件,请以相反的顺序遍历提交,并且不要检查给定文件两次。但是,我推荐第一种方法,以便检查所有版本的推送文件。

回答by Vinay

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.

该命令给出了一个文件及其权限的列表,可以在推送之前对其进行解析以检查文件的权限是否更改。