强制git运行post-receive hook,即使一切都是"最新的"

And*_*dyL 67 git

即使我没有新的提交推送,如何强制在服务器上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
Run Code Online (Sandbox Code Playgroud)

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

我尝试了什么

git push
git push -f
Run Code Online (Sandbox Code Playgroud)

And*_*ewD 53

使用'--allow-empty'

初始推送替换脚本后,您可以这样做:

git commit --allow-empty -m 'push to execute post-receive'
Run Code Online (Sandbox Code Playgroud)

--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"
Run Code Online (Sandbox Code Playgroud)

现在就做 git pushpr

git pushpr
Run Code Online (Sandbox Code Playgroud)

这会将任何更改推送到master,在您的情况下将触发您的post post replacement脚本,然后它将再次推送(使用--allow-empty标志),然后执行更新的post-receive脚本.

  • @Andrew您可以运行`git commit --allow-empty --amend --no-edit`来重用提交消息,而无需重新输入或打开编辑器. (12认同)
  • @thomasd好的建议。使用`--amend --no-edit`,您不再需要`--allow-empty`。 (2认同)

Jam*_*arl 23

我知道这可能会被认为是"危险的",但我喜欢生活在边缘.

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

因此,如果我想触发post-receive,在我的情况下要让测试分支进行配置,我所做的就是:

$ git push origin :testing
$ git push origin testing
Run Code Online (Sandbox Code Playgroud)

不要接受这个作为答案.这更像是一个FYI的事情.

  • 如果它只是一个只读的遥控器,这实际上很方便. (4认同)
  • 非常适合_bare_ git repos,heroku风格 (2认同)
  • 您需要运行“git config receive.denyDeleteCurrent false”才能删除远程分支 (2认同)

pts*_*pts 13

我担心你必须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'
Run Code Online (Sandbox Code Playgroud)

用以下内容替换hooks/post-receive服务器上的挂钩:

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

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

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

$ git push origin master
...
remote: Hello, World!
...
Run Code Online (Sandbox Code Playgroud)


lau*_*lic 11

如果你想避免伪造新的提交,你可以简单地使用

git commit --amend --no-edit
Run Code Online (Sandbox Code Playgroud)

这将修改最后一个提交记录,您将能够使用git push -f(假设从您的回答中您可以使用覆盖).

  • 方便:它不会创建额外的提交
  • 好的:它不使用远程仓库中的钩子的显式路径
  • bad:覆盖历史记录,这在您的用例中很好,但不应在共享存储库中使用

我在推送之前相对经常使用此命令修复上次提交中的内容,因此我为它创建了一个别名:

git config --global alias.amend 'commit --amend --no-edit'
Run Code Online (Sandbox Code Playgroud)

现在我可以直接将它用作你的用例(git amend),或者

  • 将(所有)修改过的文件添加到上次提交中: git amend -a
  • 修改消息: git amend -m 'better message'


小智 5

就我而言,我登录远程并运行:

$ sh project.git/hooks/post-receive

工作正常!