2016-12-28 42 views
0

我有一个git pre-commit hook,它可以确定linting。当它被调用时,它循环遍历文件并在它们上运行一个linter。这很好。如何判断git是否在预提交钩子中使用“-a”标志执行?

但是,当您运行git commit -am 'Foo'它运行时没有任何分阶段文件。我如何判断它是否被-a--all标志调用?有没有更容易的方法来获取将存储在git中的文件?

+0

你所描述的不是这种情况。但是,如果你调用'commit',那么预先提交就会被设置为将被提交的内容,并且适当地设置'HEAD',这样你就可以'git diff --cached --name-only'或者其他任何你需要的东西做。 –

+0

我正在使用'pygit2'。当我使用unstaged文件调用'repo.status()。items()'时,我得到如下所示的结果:'[('config/git_hooks/pre-commit',256),('bin/run_flake8',256)] '。 '256'是GIT_STATUS_WT_MODIFIED的标志。 –

+0

我还没有看过pygit2(我写了自己的Python Git回到了git 1. [567],python 2. [345]时代,但那是几个职位以前,可能长期被丢弃),但它值得注意'git status'不会*两个*差异,一个用于索引-vs-HEAD,另一个用于worktree-vs-index。 Pygit2可能会尝试做同样的事情,但是如果是这样的话,它会出错,如果你是在你的预提交钩子内执行并运行'git commit -a'。 – torek

回答

0

全部索引中的文件将被存储。您正在查找“索引中与HEAD中的文件不同的文件”,您可以通过git diff找到这些文件,或者查找脚本git diff-index

请注意,分阶段版本可能会不同于工作树版本,使检查一切特别恼人和棘手。 (举一个例子,在某些复杂的变化运行git add -p,并选择它部分。)

这里的一个虚设pre-commit钩子的一个例子,显示名称和每个文件的状态相对于HEAD,即,该指数与现有的HEAD承诺有什么不同。

#! /bin/sh 

git diff-index --cached -r --name-status HEAD 

echo pre-commit fail 
exit 1 

你的任务是采取从git diff-index --cached -r --name-status HEAD输出(也许-z补充说,也许不是),并找出如何测试在索引中的版本,而不是在工作树的版本。

请注意,您可以使用git checkout-index将索引提取到工作树。当然,你要避免覆盖真正工作树,即在其他地方建立一个临时的工作树:

TMPTREE=$(mktemp -d) 
... 
git --work-tree=$TMPTREE checkout-index -- . 

例如。您可能需要建立一个临时的指数,比一般的指数,这个其他为好,因为这可能会干扰常规的索引缓存方面:

TMPINDEX=$(mktemp) 
NORMINDEX=${GIT_INDEX_FILE:-$(git rev-parse --git-dir)/.index} 
cp $NORMINDEX $TMPINDEX 
GIT_INDEX_FILE=$TMPINDEX GIT_WORK_TREE=$TMPTREE checkout-index -- . 

一定要清理临时文件和/或目录完成后。

(这些代码片段都没有经过测试。)