我有一个post-receive钩子脚本坐在我要推送的远程仓库上git reset --hard
这样的事情:
$ git push opal
Counting objects: 74, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (45/45), done.
Writing objects: 100% (53/53), 16.68 KiB, done.
Total 53 (delta 20), reused 0 (delta 0)
remote: warning: updating the current branch
remote: HEAD is now at 88f1e35 tweak lavalamp styles
我在这里不明白的是 - 遥控器说头部现在在XXX但是当我登录服务器时 - 远程工作副本根本没有更新!
任何想法?
答案 0 :(得分:24)
问题是Git命令在为钩子脚本创建的环境中的行为与普通环境的区别。
首先,钩子脚本运行时将其当前工作目录设置为Git目录本身(即非裸存储库的.git/
目录)。其次,钩子脚本使用GIT_DIR环境变量集运行并指向Git存储库(同样,非裸存储库的.git/
目录)。
通常情况下,如果您尝试从git reset --hard
目录运行.git/
,它将会消失并显示以下消息:
fatal: This operation must be run in a work tree
但是当设置GIT_DIR时,Git命令假定当前目录是工作树。由于钩子运行时的当前目录是.git/
目录,因此git reset --hard
实际上将您的工作树文件“检出”到.git/
而不是其父目录(即您现在有您.git/
目录中的版本化内容的副本。
希望您的存储库中的任何版本化内容都没有与pathnames that Git uses in Git repositories themselves重合的路径名。如果它们一致,那么您的git reset --hard
将覆盖存储库的某些内部结构,您可能希望从其他存储库重新克隆它。如果您确信没有任何版本化内容与Git的内部路径名冲突,那么您可以使用它来清理它:
# make a backup of your repository first!
(cd .git && GIT_DIR=$PWD git ls-files -cz | xargs -0 rm)
这只会删除当前跟踪的文件(它会留下已经被删除的文件,但是在破解的钩子处于活动状态时被推送的提示一次被跟踪)。
一种解决方案是将当前工作目录更改为正常工作树,并在调用Git命令之前取消设置GIT_DIR和GIT_WORK_TREE。
⋮
test "${PWD%/.git}" != "$PWD" && cd ..
unset GIT_DIR GIT_WORK_TREE
# you can now safely use Git commands
⋮
另一个解决方案是显式重置GIT_DIR,在那里设置GIT_WORK_TREE和chdir。 Git常见问题“Why won't I see changes in the remote repo after "git push"?”建议post-update script执行此操作。链接脚本也更安全,因为如果在执行硬重置之前索引或工作树是脏的,它会产生存储。
答案 1 :(得分:15)
简而言之,使用钩子单线:
git --git-dir=. --work-tree=$PWD/.. reset --hard
更准确地说,编辑服务器上的文件.git/hooks/post-receive
:
#!/bin/sh
git --git-dir=. --work-tree=$PWD/.. reset --hard
设置可执行文件:
chmod +x .git/hooks/post-receive
当从客户端推送这个回购时,应该说:
HEAD is now at abcd123 comment
答案 2 :(得分:0)
脚本可能没有运行。它不会在愚蠢的http服务器上运行。 它会在ssh上运行。我不确定智能http服务器。
如果不是这样,你应该检查钩子上的'执行'permisssion(chmod + x .git / hooks / post-receive)。当你在这里时,通常会检查所有权和权限。
如果这似乎没问题,只需在脚本中添加一个logstatement作为第一行(例如date "%T $0 executed" >> /tmp/debug_hook.log
)并检查日志文件以查看是否有任何更新。
此外,推送到而不是实际上可以做任何事情(一切都是最新的)。在这种情况下,钩子不被称为
是有意义的如果所有这些都没有提示,请发布.git / config,因为它驻留在服务器上(或至少部分)。 git log -1 HEAD
是否在服务器上给出了预期的结果?您的钩子脚本是否包含可能覆盖GIT_DIR,GIT_WORK_TREE或GIT_INDEX_FILE的任何内容?