如何自动拉取 Git 子模块?

5
我被分配了一个项目,我将负责后端开发,另一个人将处理前端开发。有一个要求是前端开发人员无权访问开发服务器或项目代码。因此,我们决定为前端创建另一个存储库。
问题在于,我不知道如何使子模块在远程库提交内容时立即从远程服务器上拉取。我需要开发人员提交并立即看到前端的变化。
我一直在阅读关于Git钩子的文档,并且发现我可以使用“post-receive”钩子来完成这个任务。然而,它似乎没有起作用。这是我所做的:
  1. From the main project's root directory, I found the following directory /.git/modules/submodule-directory/hooks
  2. I created post-receive file with executable permission allowed.
  3. Contents of post-receive file:

    #!/bin/sh
    git pull
    
  4. Pushed a change from my local machine to the submodule repo but nothing happened.

我做错了什么?

编辑:我想澄清一些关于我的问题的点。

我有两个存储库:一个是“main”存储库,它是整个项目;另一个是前端存储库(视图、资源等)。让我们称其为“frontend”存储库。

对于我的主存储库,我将前端存储库作为子模块添加到了/submodules/frontend文件夹中。这样,外部承包商就无法看到实际项目的任何内容。他们只能看到自己正在开发的东西。

从访问控制方面来说,这实际上很完美,并且我可以轻松地监控前端开发的进度,与项目分开。但是还有一个问题我不知道该怎么解决。

我们的项目有两台独立的服务器——开发服务器和生产服务器。开发服务器需要始终处于主repo和前端repo的master分支。这样,前后端团队都能看到他们的更新。尽管前端团队主要使用模板,但这些模板可以访问存储在数据库中的数据,并且使用了许多已经集成到后端的内容(例如模型)。

为了使这个“系统”工作,我需要前端存储库在“frontend”远程存储库有新的提交时始终fetch和merge。换句话说,如果前端团队执行git commitgit push,开发服务器中的“frontend”子模块需要立即执行git pull。因此,当前端团队测试他们的东西时,他们将立即看到最新的更改。

我了解到可以使用post-receive hook来实现这一点,但我需要这个hook仅用于子模块。因此,在查找后,我发现所有子模块钩子都存在于/.git/modules/submodules/frontend/hooks中。因此,我在该目录下创建了一个post-receive hook,并编写了以下代码:

#!/bin/sh
git pull

但这并没有起作用。我的问题是如何使钩子在子模块内部的post-receive下正常工作?
我知道我所采取的方法远非完美,但这是唯一让我感到有意义的方式,因为它可以让开发人员只访问一个目录,而无需访问开发服务器。
我希望这有意义。

手动执行 git pull 可能会给你一些提示。 - renefritze
另一个需要注意的精度问题是:例如在开发服务器方面,您将代码从本地推送到哪个存储库?是推送到一个“--bare”存储库?还是直接推送到用于开发的目录中? - Asenar
我正在推送到位于Gitlab.com的“--bare”存储库。 - Gasim
好的,所以你有两个本地仓库(在你的本地机器上),2个远程仓库用于推送(GitLab),另外还有2个在开发服务器上的仓库(暂且不谈生产环境)。 - Asenar
是的,我想要每个开发服务器上的存储库在本地存储库推送到它们的远程存储库时从其相应的远程存储库拉取。 - Gasim
1个回答

3
当你执行git pull命令时,基本上相当于执行git fetch && git merge命令。但这不会更新子模块。
如果我理解你的需求正确的话,你可以在主目录下的.git/hooks文件夹中使用git submodule update命令(或者git submodule foreach 'git pull'命令)来完成你想要的操作。
根据你的编辑,你需要在gitlab前端库中添加post-receive钩子,并且你的钩子必须执行git submodule update命令(或者在开发服务器中使用ssh命令执行git submodule foreach 'git fetch && git merge'命令)。
但是,重新思考一下你的开发服务器安装方式可能更容易,你可以将两个仓库完全分开安装(而不是将前端作为子模块),并将子模块/前端添加到你的.gitignore目录中。这并不一定意味着你必须从子模块中移除frontend,只是在开发服务器中不使用它即可。

我的问题表述不够清晰。我想给子模块添加一个钩子,使其能够独立工作。因此,如果我向主仓库提交内容,它不会更新子模块。只有当子模块的远程仓库发生更改时,才会更新子模块。 - Gasim
我还不太清楚你所说的“commit to main repository”是什么意思。 该commit是否等同于push?是指本地子模块存储库,还是远程子模块存储库? 还是指本地“主项目存储库”等等。 - Asenar
我总是commit并push,所以我只说commit。请查看我的编辑。我已经澄清了我使用的所有术语以及我希望它工作的方式。对于造成的困扰,我很抱歉。 - Gasim
1
在编程中使用相同的名称表示两个完全不同的事物是一个不好的习惯;)我对我的答案进行了一些澄清。 - Asenar

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