如何在git中执行一个命令来跟随fetch或pull命令?

40
我克隆了 GHC(Glasgow Haskell Compiler)存储库。为了构建编译器,您需要几个库,所有这些库都可以作为git存储库获得。为了简化操作,GHC黑客包含了一个名为 sync-all 的脚本,执行该脚本会更新所有相关的存储库。
现在我的问题是:我如何让git在执行git pull后自动执行./sync-all pull?我听说过使用钩子(hooks),但我不知道该怎么做。

3
请查看 Git 钩子文档:http://www.kernel.org/pub/software/scm/git/docs/githooks.html - Laurent Pireyn
https://dev59.com/u2855IYBdhLWcg3wuGwM - Ohad Schneider
2个回答

31
如果您需要在客户端(即您的计算机)上执行git pull命令后运行脚本,则没有可靠的解决方案。 post-merge客户端钩子此处提到)不会被每个拉取操作触发(例如,在拉出rebase时不会触发,在快进合并的情况下不会触发)。因此,一个包装这两个命令的别名仍然是一个可能的解决方法。
如果您需要在服务器端进行操作,即您要检出裸库并从工作树(在服务器上)中拉出每次推送到裸库(在服务器上)之后:post-receivepost-update 钩子通常用于此类任务,在每次推送后执行。 post-receivepost-update钩子之间的差异在于参数:除了名称外,post-receive将获得所有引用的旧值和新值。缺少的一部分是: 该钩子在哪里执行?来自(伟大的)SO贡献者Mark Longair的博客文章“Missing git hooks documentation”揭示了这一点:

当前工作目录将是git目录。

  • 因此,如果这是称为“/ src / git / test.git /”的裸库,则它将是当前工作目录 - 如果这是非裸库并且工作树的顶层为“/ home / mark / test /”,则当前工作目录将为“/ home / mark / test / .git /

Chris Johnsen在他的SO答案中详细说明:“如果指定了--git-dir或GIT_DIR,但没有指定-–work-tree、GIT_WORK_TREE和core.worktree,则当前工作目录被视为您的工作树的顶级目录。”

换句话说,您的工作树也将是当前目录(即.git目录),这几乎肯定不是您想要的。

确保你创建并设置了可执行的hook/post-receive脚本,将GIT_WORK_TREE设置为正确的路径,以便在正确的目录中执行./sync-all pull(即不在“xxx.git”目录中执行)。


9
post-receive和post-update钩子在Git push之后在远程库上运行。这对于在Git pull之后在本地库上运行它没有帮助。 - decocijo
1
@decocijo 是的,想法是推送到一个裸仓库,这将触发一个 post-receive 钩子并进入非裸仓库,进行 git pull - VonC
这不是在拉取之后运行命令的答案。post-receive 或 post-update 在向该代码库推送之后运行。 - Onur Demir

16
当你运行 git pull 命令时,实际上 Git 会先执行一次抓取操作,然后再合并代码。这意味着你可以使用 post-merge 钩子来在拉取代码完成后执行脚本。
要设置这个钩子,你只需要在你的代码仓库的 .git/hooks/ 目录下创建一个名为 post-merge 的可执行脚本即可。
请注意,如果由于冲突导致合并失败,则不会运行此脚本。

4
然而,这对于 git fetch 是行不通的。另外,你可以使用 git pull --rebase,所以你需要为 post-rewrite 添加一个钩子。但即使如此,你也无法区分独立的合并/变基与紧随其后的拉取之间的区别... - Ohad Schneider
根据分支配置,即如果配置为变基或合并,则可以分别具有预变基或后合并。 - solstice333

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接