如何仅对分阶段内容运行git预提交检查?

15 git pre-commit pre-commit-hook

假设git status给出了这个:

# On branch X
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   file1.cc
#   modified:   file1.h
#   modified:   file1_test.cc
#   modified:   SConscript
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#   (commit or discard the untracked or modified content in submodules)
#
#   modified:   file1.cc
#   modified:   tinyxml2 (untracked content)
#
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只有一些对file1.cc所做的更改已经为下一次提交暂存 /索引.

我运行一个预提交脚本来运行样式检查器:

#!/bin/bash                                                                                                                                                                     

git stash -q --keep-index

# Do the checks                                                                                                                                                                 
RESULT=0
while read status file
do
    if python ~/python/cpplint.py "$file"; then
        let RESULT=1
    fi
done < <(git diff --cached --name-status --diff-filter=ACM | grep -P  '\.((cc)|(h)|(cpp)|(c))$' )

git stash pop -q

[ $RESULT -ne 0 ] && exit 1
exit 0
Run Code Online (Sandbox Code Playgroud)

正如这里所建议的那样,我在运行样式检查之前存储未分段的文件,然后将它们弹出.但是,在仅暂存文件中的某些更改的情况下,当我在预提交挂钩结束时弹出存储时,这会导致合并冲突.

有什么更好的方法呢?我想针对即将提交的文件的分阶段版本运行样式检查.

ony*_*ony 10

我会避免git stash在钩子中自动使用.我发现可以git show ':filename'用来获取存储文件的内容.
相反,我使用下一个方法:

git diff --cached --name-only --diff-filter=ACMR | while read filename; do
    git show ":$filename" | GIT_VERIFY_FILENAME="$filename" verify_copyright \
        || exit $?
done \
    || exit $?
Run Code Online (Sandbox Code Playgroud)


use*_*342 5

替换git stash -q --keep-index为:

git diff --full-index --binary > /tmp/stash.$$
git stash -q --keep-index
Run Code Online (Sandbox Code Playgroud)

......并且git stash pop -q:

git apply --whitespace=nowarn < /tmp/stash.$$` && git stash drop -q
rm /tmp/stash.$$
Run Code Online (Sandbox Code Playgroud)

这会将diff保存到临时文件中,并git apply在最后使用它重新应用它.这些更改仍然被冗余地保存到存储(稍后被删除),因此如果重新应用出现问题,您可以使用git stash show -p它来检查它们而无需查找临时文件.