【问题标题】:How do I hook a git pull on the remote?如何在遥控器上挂一个 git pull?
【发布时间】:2011-02-17 04:35:47
【问题描述】:

有没有办法在远程发生 git pull 时进行挂钩(类似于 pre-receive 或 post-receive)。基本上我希望能够让遥控器在拉动时提交它所拥有的任何东西。

在我的情况下,远程上的任何内容都是权威来源,可以在没有 git 提交的情况下进行修改。我想确保当我拉动时,我总是能够获得最新的直播内容。

【问题讨论】:

  • 那么,您正在向远程仓库发送提交,并希望远程仓库在您的更改合并到其中之前提交?
  • 不完全。更像这样: 1:在远程 fileA.txt 上被编辑 2:在本地我运行 'git pull remote' 我想要的是对 fileA.txt 的编辑得到提交,以便我的 pull 降低更改制作完成。
  • 为什么不在本地编辑 fileA.txt,提交它,然后在远程服务器上执行拉取操作?更改应该从开发人员的本地设置开始,并逐渐渗透到生产环境,而不是相反。
  • 遥控器不是生产环境,只是不同的环境。这是我的 repo 的“实时”副本,它以有限的编辑能力在网络上公开。基于实时网络的编辑适用于当我需要访问或偶尔修改文件并且我无法关闭完整存储库(例如使用朋友的计算机)时。

标签: git pull githooks


【解决方案1】:

首先,回答您的实际问题:当有人提取时,远程端没有调用任何钩子。 (当有人拉动时,遥控器只知道他们从中获取了 - 它不知道他们是否运行git pullgit fetchgit remote update...)

至于您的实际情况:我同意 Magnus 的观点,即最好在编辑后简单地进行提交,否则,有某种定期任务(cronjob?)检查修改并提交,如果它找到任何。如果您不喜欢其中任何一个选项,则可以简化操作,以便在拉取之前快速轻松地触发远程存储库中的提交。

另外,我建议不要将具有工作树的存储库作为您的规范存储库。如果您需要推动它,那就是自找麻烦。相反,您可以拥有一个裸规范存储库,您的实时存储库在提交后推送到该存储库,并在该裸存储库中安装一个 post-receive 挂钩,以便在必要时更新实时存储库。

【讨论】:

  • 至于你的最后一段,这根本不能解决问题。这可以用 gitolite 来完成,但是当有人从裸仓库中提取时,你如何让它告诉非裸仓库的人提交所有内容,除非 gitolite 用户具有调用“git commit”的直接权限,这可能并不总是一个好主意.基本上,许多人需要的是能够通过 noop 触发远程存储库上的钩子。这就是为什么人们认为 fetch 可能很好,结果发现没有 pre-fetch 钩子。我认为可以通过推送到不存在的分支来解决...
  • ...对于像 gitolite 这样自动化的东西来说没问题,但是如果人类在拉动之前必须记住这一点,那就很烦人了...
【解决方案2】:

不幸的是,git 本身并没有为此提供钩子,因为它是一个完美的用例,希望在允许拉取/获取之前检查某些内容。

我不知道您的“远程”是否在本地机器上,但如果不是,请查看 gitolite,它有专门用于此目的的钩子:

来自v2 gitolite docs

“gl-pre-git”钩子

虽然 git 有很多不错的钩子可供你使用,但它们都可以运行 只有在推动。没有任何东西可以在 fetch 或 clone 上运行,并且 在 git-receive-pack 或之前无法运行某些东西 git-upload-pack,(视情况而定)被调用。

这就是 gl-pre-git 钩子的用途。如果一个可执行的钩子调用 gl-pre-git 存在,它将使用当前目录调用 设置为 repo.git,并带有一个参数,该参数将是 R 或 W 取决于客户想要做什么。

对于 v3 gitolite,这里是the docs about triggers。文档有点神秘,但它是这样工作的:

  1. 在 ~/.gitolite.rc 添加(在全局范围内):

    PRE_GIT => [ '<pre_git_trigger_script_name>' ]

  2. 在同一个文件中查看允许设置 LOCAL_CODE 的行并将其设置为您喜欢的任何位置

  3. 在您为 LOCAL_CODE 设置的目录中,创建一个名为 'triggers' 的子目录并创建一个名为 &lt;pre_git_trigger_script_name&gt; 的脚本,其中包含您当时想要执行的任何操作...(确保执行到:@987654325 @

  4. 运行gitolite setup

  5. 测试 && 祝你有美好的一天

更新:实际上使用 gitolite,我认为你可以让 pre-git 触发器做一些事情,比如推送到一个不存在的分支,然后挂钩在你的非裸存储库中预接收以拒绝推,但在这个过程中做git add --all . &amp;&amp; git commit -m"autocommit" &amp;&amp; push gitolite。当您不想让 gitolite 托管用户权限直接在您的非裸存储库中运行命令时,这很方便。

【讨论】:

  • “在 git-receive-pack 或 git-upload-pack 之前没有办法运行某些东西” ...当然,除了前端...这只是代码。
【解决方案3】:

我没有 git hooks 的直接经验,this page 可能会有所帮助,但看起来你无法做到。

更简单(更好的 IMO)解决方案是使用生产环境以外的存储库作为权威来源。你能做这个吗?生产环境很少用作权威来源,因为最新和最稳定是两个截然不同的东西......

仅供参考,我只曾经在生产环境中执行 git pull 或 git status。任何更改都在我的本地 repo 上进行、测试、提交、推送到 github,然后下拉到生产环境。

更新
我应该指出,git 的一大优势和特点是它是一个分布式 源代码控制系统。因此,实际上没有任何权威来源。

【讨论】:

  • 也许权威不是恰当的术语,更像是一个“对等”来源,这正是 git 所提倡的。唯一的问题是 peer 不能自己提交,所以我试图弄清楚 git hooks 是否可以帮助它。
【解决方案4】:

我认为你不能用钩子来做到这一点,据我了解阅读钩子的文档没有符合你要求的钩子。

如果我需要你想要的东西,我会在“远程”上创建一个每小时运行一次的脚本,并检查是否有任何文件被更改(git status)并提交所有文件( git commit -a -m "自动提交").

【讨论】:

  • 不可能,因为远程只是存储在云存储上的文件共享。不过谢谢,我意识到这似乎不存在。当我推而不拉时,我有钩子。我想我必须做一些空提交+推送。
  • 尝试找到一种方法在本地挂载此文件存储,以便您可以使用本地计算机的 git 命令。我猜是否可以将云存储作为本地存储访问,您可以直接从计算机上完成所有操作。如果云存储只是一个包含您的文件的简单存储,并且恰好在里面有 .git 目录但没有运行 Git,那么就不可能在其中挂钩。
【解决方案5】:

这不是我以前做过的事情,但你可以在 php 中运行 bash 脚本:

http://www.devx.com/opensource/Article/40785
http://us2.php.net/function.exec

这应该允许您通过 PHP 脚本提交和推送一组更改。在它上面设置一个界面或将其集成到您当前的编辑过程中,您应该很高兴。

【讨论】:

    【解决方案6】:

    谁/什么在编辑这个文件?如果当某人更改站点上的某些内容时发生了某些更改,则必须由某些内容触发,这意味着您可以自动执行此操作。当发生这种情况并保存文件时,您应该在那里触发提交。提交必须在某个时间完成,也可能在那个时候完成。

    【讨论】:

    • 假设远程实际上能够执行 git 命令。但就我而言,它是 skydrive 上的文件服务器/卷影副本,我希望偶尔能够从网络上进行编辑。
    猜你喜欢
    • 2012-08-01
    • 1970-01-01
    • 2014-08-11
    • 2014-10-28
    • 2011-09-07
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多