繁体   English   中英

如何在git pre-commit钩子中将文件添加到索引中

[英]How to add a file to the index in a git pre-commit hook

我一直在寻找复制品,虽然其中一些有类似的标题,但我没有发现任何人和我有同样的问题,所以这里有。

我编写了一个在pre-commit运行的脚本,并使用git status --porcelain的输出来编译已更改的项目中的任何LESS文件。 这部分工作正常。 但我希望.css文件包含在当前提交中。 所以除了运行编译器之外,我的脚本还运行git add <filename> 而这里的事情变得棘手。

该文件添加到索引中,但它不是当前提交的索引。 因此,如果我修改style.less ,并运行git commit -a (或手动git add style.less ),编译器应生成style.cssstyle.min.css并将它们添加到当前提交。 但我注意到的行为只是style.less被提交,尽管两个.css文件被添加到下一次提交的索引中。

所以我的问题是:有没有办法在预提交钩子中向提交添加文件,以便它们对该提交生效? 请注意,在运行预提交挂钩之前,不会修改这两个.css文件,因此我不能在此之前添加它们。 我也知道我可以以非零状态退出钩子,因此提交被取消但文件被添加,但我希望避免这种情况。 有更好的想法吗?

我无法重现您的问题。 我最初的猜测是你的pre-commit钩子没有设置GIT_INDEX_FILE环境变量。 但是,当我尝试从pre-commit GIT_INDEX_FILE时,我遇到了另一个问题(Git抱怨说.git/index被锁定)。

这是一个示例脚本,显示Git的功能与您期望的一样,其他一些必须是错误的。 此脚本初始化一个新的测试存储库,创建一个pre-commit钩子,模拟钩子的作用,并进行一些测试提交:

#!/bin/sh

# initialize the test repository
rm -rf testrepo
git init testrepo
cd testrepo

# create the pre-commit hook
cat <<\EOF >.git/hooks/pre-commit
#!/bin/sh
git status --porcelain | while IFS= read -r line; do
    # todo: handle renames and deletions of a *.less file
    f=${line#???}
    case ${f} in
        *.less)
            fb=${f%.less}
            echo bar >>"${fb}".css
            echo baz >>"${fb}".min.css
            git add "${fb}".css "${fb}".min.css
            ;;
    esac
done
EOF
chmod +x .git/hooks/pre-commit

# create foo.less, commit it
echo foo >foo.less
git add foo.less
git commit -m "add foo.less"

# modify foo.less, commit it
echo foo2 >>foo.less
git commit -a -m "modify foo.less"

如果你运行git log -p测试库,并查看最终的承诺,你会看到foo.cssfoo.min.css每当进行了修改foo.less进行了修改。

这就是为什么我认为您的问题是由更改/ GIT_INDEX_FILE环境变量引起的:

运行git commit -a ,Git会生成一个临时索引文件,并使用该文件而不是默认的.git/index来创建提交。 为了让像git add这样的操作在pre-commit钩子中工作,Git将GIT_INDEX_FILE环境变量设置为它在运行pre-commit之前创建的临时索引的名称。 如果您的钩子GIT_INDEX_FILE设置GIT_INDEX_FILE ,或将其设置为.git/index ,那么钩子内的所有Git操作都将尝试修改原始索引,而不是用于生成提交的临时索引。

但是,临时索引文件还充当原始索引文件的锁。 如果一个钩子试图修改原始索引,并且临时索引存在,那么Git将中止并出现错误。

我发现你可以将git属性“clean”作为更新生成文件的脚本。 通常,钩子可以运行脚本来整理你的源代码,但我认为它可以用来“清理”你生成的输出。 执行'git add'时会触发此属性,您可以让脚本在生成的文件上执行另一个'git add'。

您可以利用修改最后一次提交。 只是一个想法。

你为什么要首先这样做? 您正试图将生成的文件包含到版本控制中,这通常是一个不太好的想法。 如果你需要在结账时使用style.min.css,为什么你不能在结账步骤结账后生成它?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM