Git直接修改索引的内容,用于预提交格式化挂钩

tel*_*ium 3 git code-formatting githooks

我想在将文件添加到Git索引之前自动格式化我的文件.现在,我有一个预提交钩子,看起来像这样:

#!/bin/bash

set -e
exec 1>&2

workingext="working.$$"
ext="bak.$$"
git diff -z --cached --name-only | egrep -z '\.(pl|pm|t)$' | \
        while read -d'' -r f; do
    # First modify the file in the index
    mv "$f" "$f.$workingext"
    git show :"$f" > "$f"
    perl -c "$f"
    perltidy -pbp -nst -b -bext="$ext" "$f";
    rm -f "$f.$ext"
    git add "$f"
    mv "$f.$workingext" "$f"
    # Then the working copy
    perl -c "$f"
    perltidy -pbp -nst -b -bext="$ext" "$f";
    rm -f "$f.$ext"
done
Run Code Online (Sandbox Code Playgroud)

基本上,我备份工作副本,检查索引副本,格式化它们,将它们添加到索引,然后还原工作副本并格式化它们,以便工作副本和索引副本之间的差异也不会增长大.我首先检查文件的语法,perl -c以便格式化perltidy程序不会被语法无效的文件弄得太混乱.

到目前为止,这似乎工作得很好.但是,我想知道是否有办法将一个文件的内容添加到另一个文件名下的索引中.也就是说,一个命令git update-index-from-file --from-file foo.pl.tmp foo.pl会更新文件foo.pl,使其索引中的内容完全来自foo.pl.tmp,但其工作目录中的版本仍未修改.这可能会避免我现在正在做的重命名之舞(虽然这可能有助于确保我不会无可挽回地丢失索引的内容).

Chr*_*ial 9

是的,这是可能的.首先,您需要通过运行以下命令从文件中创建blob:

git hash-object -w foo.pl.tmp
Run Code Online (Sandbox Code Playgroud)

请参见:http://www.kernel.org/pub/software/scm/git/docs/git-hash-object.html

使用指定文件的内容(可以在工作树之外)计算具有指定类型的对象的对象ID值,并可选择将结果对象写入对象数据库.将其对象ID报告给其标准输出.

使用git hash-object发送到STDOUT 的blob sha ,您现在可以通过运行将此blob作为"foo.pl"添加到索引中

git update-index --add --cacheinfo 100644 *YOURSHA* foo.pl
Run Code Online (Sandbox Code Playgroud)

update-index联机帮助页:

--cacheinfo用于注册不在当前工作目录中的文件.这对于最小结账合并非常有用.

假装你有一个模式和路径sha1的文件,说:

$ git update-index --cacheinfo mode sha1 path
Run Code Online (Sandbox Code Playgroud)

但是我想要指出,你的情况看起来很像你应该使用涂抹过滤器来做那些事情.请参阅此处了解它们:https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Keyword-Expansion