尝试一下:
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: '.'
任何线索,这是怎么回事?
答案 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
参数。