在git push上重置

Dav*_*vid 15 git hook reset git-post-receive

我有一个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
Run Code Online (Sandbox Code Playgroud)

我在这里不明白的是 - 遥控器说头部现在在XXX但是当我登录服务器时 - 远程工作副本根本没有更新!

任何的想法?

Chr*_*sen 25

问题是Git命令在为钩子脚本创建的环境中的行为与正常环境的区别.

首先,钩子脚本运行时将其当前工作目录设置为Git目录本身(即.git/非裸存储库的目录).其次,钩子脚本使用GIT_DIR环境变量集运行并指向Git存储库(同样,.git/非裸存储库的目录).

通常,如果您尝试git reset --hard.git/目录运行,它将死于以下消息:

fatal: This operation must be run in a work tree
Run Code Online (Sandbox Code Playgroud)

但是当设置GIT_DIR时,Git命令假定当前目录是工作树.由于钩子运行时的当前目录是.git/目录,因此您git reset --hard实际上是"检出"您的工作树文件.git/而不是其父目录(即您现在在您的.git/目录中有您的版本化内容的副本).

希望您的存储库中的任何版本化内容都没有与Git在Git存储库中使用的路径名一致的路径名.如果它们确实重合,那么您的git reset --hard意志将覆盖存储库的某些内部结构,您可能希望从其他存储库重新克隆它.如果您确信没有任何版本化内容与Git的内部路径名冲突,那么您可以使用以下方法清除它:

# make a backup of your repository first!
(cd .git && GIT_DIR=$PWD git ls-files -cz | xargs -0 rm)
Run Code Online (Sandbox Code Playgroud)

这将只删除当前跟踪的文件(它将留下已被删除的文件,但是在已断开的挂钩处于活动状态时被推送的提示中一次跟踪).


一种解决方案是将当前工作目录更改为正常工作树,并在调用Git命令之前取消设置GIT_DIR和GIT_WORK_TREE.

?
test "${PWD%/.git}" != "$PWD" && cd .. 
unset GIT_DIR GIT_WORK_TREE
# you can now safely use Git commands
?
Run Code Online (Sandbox Code Playgroud)

另一个解决方案是显式重置GIT_DIR,在那里设置GIT_WORK_TREE和chdir.Git常见问题解答"为什么我不会在"git push"之后看到远程仓库中的变化?"推荐一个更新后的脚本.链接脚本也更安全,因为如果索引或工作树在执行硬重置之前是脏的,它会成为存储.


leo*_*leo 16

简而言之,使用钩子单线:

git --git-dir=. --work-tree=$PWD/.. reset --hard
Run Code Online (Sandbox Code Playgroud)

更准确地说,编辑.git/hooks/post-receive服务器上的文件:

#!/bin/sh
git --git-dir=. --work-tree=$PWD/.. reset --hard
Run Code Online (Sandbox Code Playgroud)

设置它可执行:

chmod +x .git/hooks/post-receive
Run Code Online (Sandbox Code Playgroud)

当从客户端推送到这个回购时,应该说:

HEAD is now at abcd123 comment
Run Code Online (Sandbox Code Playgroud)


seh*_*ehe 0

那么脚本可能没有运行。它不会在哑 http 服务器上运行。它将通过 ssh 运行。我不确定智能 http 服务器。

如果不是这样,您应该检查钩子上的“执行”权限(chmod +x .git/hooks/post-receive)。当您这样做时,通常要检查所有权和权限。

如果这看起来没问题,只需在脚本中包含一个日志语句作为第一行(例如date "%T $0 executed" >> /tmp/debug_hook.log)并检查日志文件以查看是否有任何更新。

此外,推送也可能实际上执行任何操作(一切都是最新的)。在这种情况下,不调用钩子是有道理的

如果所有这些都没有给出提示,请发布 .git/config,因为它驻留在服务器(或至少部分)上。是否git log -1 HEAD在服务器上给出了预期结果?您的钩子脚本是否包含任何可能覆盖 GIT_DIR、GIT_WORK_TREE 或 GIT_INDEX_FILE 的内容?