我想要要求SVG与其他所有内容分开提交,以保持其他所有内容的diff输出更清晰。例如,我想禁止像这样的提交:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: src/css/main.css
modified: src/images/example.svg
modified: src/index.html
这可以通过预提交挂钩完成吗?怎么会写?
编辑:我认为git ls-files -dmo
在这里很有用,但我不知道如何编写脚本来解析其输出。
答案 0 :(得分:2)
这可以通过预提交钩子完成吗?
是。 (但请注意,可以绕过这种钩子。)
怎么写?
取决于您要用什么语言来编写它。
Shell脚本往往是最简单的,因为您可以直接运行Git工具。在这里,您可以运行git diff-index --name-status
来比较索引(建议的提交)与当前的ie HEAD
提交,然后读取正在添加,修改或删除的文件以查看是否有任何名称以.svg
,如果有任何名称以其他任何结尾。这使您可以调整规则以允许删除 .svg文件,同时进行其他更改。或者,如果文件状态(添加/删除/修改)不相关,则更简单一点:
# straight from the sample pre-commit hook
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# create a temp file to hold diff output
tmpfile=$(mktemp)
trap "rm -f $tmpfile; exit" 0 1 2 3 15
git diff-index --cached --name-only --diff-filter=ADM $against > $tmpfile
# read the status and names from the temp file.
# we use a temp file simply because "| while read ..." runs
# a sub-shell which means that variable changes don't make
# it back to the parent shell. there are other workarounds
# but this one is simple.
num_svg=0
num_nonsvg=0
while read name; do
case "$name" in
*.svg) num_svg=$((num_svg + 1));;
*) num_nonsvg=$((num_nonsvg + 1));;
esac
done < $tmpfile
# now disallow commit if there are mixed svg and non-svg files
if [ $num_svg -gt 0 -a $num_nonsvg -gt 0 ]; then
echo "this commit affects both .svg files and non-svg files" 1>&2
exit 1
fi
# run any other checks here too
exit 0
(注意:这是完全未经测试的)