为什么`git -C`在Python的post接收钩子中不起作用?

时间:2019-02-06 19:35:26

标签: git githooks git-post-receive

尝试一下:

mkdir /tmp/one
cd /tmp/one
git init
echo -e "#!/usr/bin/env python3\nimport os\nos.system('git -C /tmp/one show')" > /tmp/one/.git/hooks/post-receive
chmod +x /tmp/one/.git/hooks/post-receive
touch test.txt
git add test.txt
git commit -m 'Initial commit'
cd /tmp/
git clone one two
cd two
git checkout -b test
echo "Why doesn't this work?" >> test.txt
git add test.txt
git commit -m "testing"
git push -u origin test

并观察非常令人困惑的消息:

remote: fatal: Not a git repository: '.'

什么?

严重的是,实际情况是什么?为什么这完全坏了?我可以转到不是git存储库(cd / && git -C /tmp/one/show)的文字文件夹,它可以正常工作。为什么此命令不起作用?

如果我执行os.chdir('/tmp/one'),它也不起作用。我无法使接收后挂钩真正弄清楚到底发生了什么。运行其他命令(例如git merge)非常高兴,但它不了解git show,git status或更重要的是git -C /tmp/one checkout master。我也尝试过光秃秃的

#!/bin/sh
git -C /tmp/one status

它给了我同样的错误信息-not a git repostiory: '.'

任何线索,这是怎么回事?

1 个答案:

答案 0 :(得分:2)

这里的问题是,从Git挂钩运行的命令是在设置了各种环境变量的情况下运行的。打击您的人是$GIT_DIR,但可能还有其他人(例如$GIT_WORK_TREE$GIT_INDEX_FILE,依此类推)。

已正确设置 ,以处理在钩子运行时位于的存储库。但是您不希望该挂钩处理该存储库。您希望此钩子chdir到其他地方并处理某些 other 存储库。此时,您应该清除不需要的环境变量,或使用那个存储库的正确设置覆盖它们。

简而言之,添加:

unset GIT_DIR

(用于sh / bash / etc),或在Python中:

del os.environ['GIT_DIR']

(请注意,Python版本仅在实际设置时有效),或者在使用env等时使用subprocess参数。