强制git运行post-receive hook,即使所有内容都是“最新的”

即使我没有新的提交推送,我如何强制git在服务器上运行post-receive挂钩?

背景

我使用git自动部署网站到服务器。 我有一个在服务器的保护区域和一个post-receive钩子的裸回购,检查出内容并系统地将某些文件复制到一个public_html文件夹中。 (受本教程的启发)

我厌倦了在服务器上手动修改post-receive钩子,所以我的post-receive钩子现在实际上是从repo拷贝了一个新的版本:

 #!/bin/sh rm -rf ~/../protected/* GIT_WORK_TREE=~/../protected git checkout -f # Rewrite over this file with any updates from the post-receive file cp ~/../protected/post-receive hooks/post-receive # Delete public_html # Copy stuff public_html 

这个问题当然是,新的post-receive hook永远不会运行。 一个看似简单的解决scheme只是再次推动,但现在一切已经是最新的了。 这很烦人,因为每次我更新post-receive钩子时都需要我伪造一个新的提交。 有没有办法来调用post-receive钩子而不伪造提交或ssh ing?

我试过了

 git push git push -f 

使用'–allow-empty'

在最初的replace脚本之后,你可以这样做:

 git commit --allow-empty -m 'push to execute post-receive' 

--allow-empty标志覆盖了git默认的行为,当你没有改变的时候,它会阻止你进行提交。

使用别名,让你的生活更轻松

将以下内容添加到~/.gitconfig

 [alias] pushpr = "!f() { git push origin master;git commit --allow-empty -m 'push to execute post-receive';git push origin master; }; f" 

现在只要做git pushpr

 git pushpr 

这将推动任何变化的主人,在你的情况下,将触发您的后接收replace脚本,然后将再次推(使用--allow-empty标志),然后将执行您更新post-receive脚本。

我知道这可能会被认为是“危险的”,但我喜欢住在边缘。

我只是删除远程分支,然后再次推。 确保您的本地分支是最新的,以限制丢失东西的机会。

所以如果我想要触发post-receive,在我的情况下,让testing分支提供,我所做的只是:

 $ git push origin :testing $ git push origin testing 

不要接受这个答案。 这仅仅是一个简单的事情。

恐怕你必须ssh到服务器并手动运行钩子脚本。 如果没有添加任何东西(即,当git打印所有内容为最新的 ), git push不会使服务器运行预先推送预接收后接收钩子。

其余的答案是关于版本跟踪后接收挂钩,所以你可以修改它,而不需要sshing到服务器。

将名为do-post-receive的shell脚本添加到本地存储库中:

 $ ls -ld .git $ echo 'echo "Hello, World!"' >do-post-receive $ git add do-post-receive $ git commit do-post-receive -m 'added do-post-receive' 

将服务器上的hooks/post-receive挂钩replace为:

 #! /bin/sh while read OLDID NEWID BRANCH; do test "$BRANCH" = refs/heads/master && eval "$(git show master:do-post-receive)" done 

(确保在服务器上chmod 755 hooks/post-receive 。)

将您的更改从本地存储库推送到服务器,并观察您的do-post-receive代码运行:

 $ git push origin master ... remote: Hello, World! ... 

我试过空提交并删除上传分支 。

但是直接的ssh命令呢?

 ssh your_host /path/to/your_repo/hooks/post-receive 

我喜欢杰米卡尔的build议,但它不起作用,我得到了错误:

remote:error:默认情况下,删除当前分支被拒绝,因为下一个错误:'git clone'不会导致任何文件检出,造成混乱。

在我的情况下,我正在testing我的本地主机上的接收挂钩对裸仓库。 警告/超级重要, 只能remote服务器位置运行此命令!

 git update-ref -d refs/heads/develop 

它会删除开发分支的引用(你可能还需要删除你为这个分支部署的任何文件),那么你可以继续做git push deploy_localtest develop或者任何你想要的push命令。