将 Git 子模块推送到单独的工作树中

发布于 2024-12-14 07:14:54 字数 2218 浏览 1 评论 0原文

在我们的临时服务器上,我们有一个被推送到的裸仓库。它有一个 post-receive 钩子,然后执行我们所有的部署工作,所有这些工作都被检出到一个单独的工作树(没有 git 文件夹)中。

所以设置是这样的:

裸仓库位于

/var/www/apps/e_learning_staging/elearning_resource.git

工作树位于

/var/www/apps/e_learning_staging/www

此设置当前工作正常。但是,我已向项目添加了四个子模块(实际上仅使用两个单独的存储库 - 每个子模块在项目中的两个位置重复)。子模块存储库都位于不同的服务器上。

这些都列在裸存储库的配置文件中,如下所示:

[core]
  repositoryformatversion = 0 
  filemode = true
  bare = true
  logallrefupdates=true
  worktree = /var/www/apps/e_learning_staging/www
  gitdir = /var/www/apps/e_learning_staging/elearning_resource.git
  [submodule "public/assets/players/virgin_lesson_viewer"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer.git
  [submodule "public/assets/players/virgin_lesson_viewer_staging"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer_staging.git
  [submodule "public/assets/dvd_files/Virgin_lesson_viewer"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer.git
  [submodule "public/assets/dvd_files/Virgin_lesson_viewer_staging"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer_staging.git

如果 git 文件夹位于工作树内,那就很容易了 - 我只需

git submodule add [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer.git public/assets/dvd_files/Virgin_lesson_viewer

对每个子模块执行操作,然后执行“git submodule update”即可更新他们。但是,我无法弄清楚如何从单独的 git 文件夹中执行此操作。谁能帮我纠正一下吗?

On our staging server we have a bare repo that gets pushed to. This has a post-receive hook that then does all of our deploy stuff, which all gets checked out into a separate working tree (which doesn't have a git folder).

So the setup is this:

bare repo is at

/var/www/apps/e_learning_staging/elearning_resource.git

working tree is at

/var/www/apps/e_learning_staging/www

This setup currently works fine. However, I've added four submodules to the project (which actually only use two separate repos - each is duplicated in two places in the project). The submodule repos are all on a different server.

These are all listed in the bare repo's config file, which looks like this:

[core]
  repositoryformatversion = 0 
  filemode = true
  bare = true
  logallrefupdates=true
  worktree = /var/www/apps/e_learning_staging/www
  gitdir = /var/www/apps/e_learning_staging/elearning_resource.git
  [submodule "public/assets/players/virgin_lesson_viewer"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer.git
  [submodule "public/assets/players/virgin_lesson_viewer_staging"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer_staging.git
  [submodule "public/assets/dvd_files/Virgin_lesson_viewer"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer.git
  [submodule "public/assets/dvd_files/Virgin_lesson_viewer_staging"]
    url = [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer_staging.git

If the git folder was inside the working tree it would be easy enough - i would just do

git submodule add [email protected]:/home/charangadh/source_code/git/virgin_lesson_viewer.git public/assets/dvd_files/Virgin_lesson_viewer

for each of the submodules, then do "git submodule update" to update them. But, I can't work out how to do it from the separate git folder. Can anyone set me straight?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尸血腥色 2024-12-21 07:14:54

如果我很好地理解你的问题,你基本上想在部署目录中执行 git submodule update ,但你不能,因为它不是真正的工作目录。

我的解决方案是实现一个类似于 git submodule update 的自定义命令:

  1. 确定超级模块引用了哪个子模块版本,
  2. 将此版本签入目标目录。您可以使用与签出超级模块相同的方式来执行此操作。

假设您的服务器上有以下设置:

  • 裸存储库存储在 /opt/repos/supermodule.git/opt/repos/submodule.git
  • 当您推送时超级模块,您想要将超级模块检出到 /var/www/supermodule 中,并将子模块检出到 /var/www/supermodule/assets/submodule

您必须执行以下操作以下在/opt/repos/supermodule.git 的 post-receive 钩子:

# Checkout supermodule
export GIT_WORK_TREE=/var/www/supermodule git checkout -f

# Determine submodule version
submodule_version=$(git ls-tree HEAD assets/submodule | awk '{print $3}')

# Checkout submodule
export GIT_DIR=/opt/repos/submodule.git
export GIT_WORK_TREE=/var/www/supermodule/assets/submodule
git checkout -f $submodule_version

可能有一个更简单的解决方案(例如使用一些环境变量破解 git submodule update 命令),但是无论如何,我经常使用 git ls-tree 来确定引用的子模块版本。

如果将子模块推送到不同的服务器,您仍然可以使用此解决方案,只需稍作修改:

  • 将子模块克隆到目标服务器上的 /opt/repos/submodule.git
  • 添加一个 在 git checkout 之前执行 git fetch 命令

,结果如下:

# Checkout submodule
export GIT_DIR=/opt/repos/submodule.git
export GIT_WORK_TREE=/var/www/supermodule/assets/submodule
git fetch
git checkout -f $submodule_version

If I understand your problem well, you basically want to do a git submodule update in the deploy directory, but you can't, because it is not a real working directory.

My solution would be to implement a custom git submodule update-like command:

  1. Determine which submodule version is referenced by the supermodule
  2. Checkout this version into the target directory. You can do this the same way as you checkout the supermodule.

Let's say you have the following setup on your server:

  • Bare repositories are stored in /opt/repos/supermodule.git and /opt/repos/submodule.git
  • When you push the supermodule, you want to checkout the supermodule into /var/www/supermodule, and the submodule to /var/www/supermodule/assets/submodule

You have to do the following in the post-receive hook of /opt/repos/supermodule.git:

# Checkout supermodule
export GIT_WORK_TREE=/var/www/supermodule git checkout -f

# Determine submodule version
submodule_version=$(git ls-tree HEAD assets/submodule | awk '{print $3}')

# Checkout submodule
export GIT_DIR=/opt/repos/submodule.git
export GIT_WORK_TREE=/var/www/supermodule/assets/submodule
git checkout -f $submodule_version

There may be an easier solution (e.g. hack the git submodule update command around with some environment variables), but I often use git ls-tree to determine the referenced submodule version anyway.

If you push the submodules to a different server, you can still use this solution, with a little modification:

  • Clone the submodule to /opt/repos/submodule.git on the target server
  • Add a git fetch command before the git checkout

So the result is the following:

# Checkout submodule
export GIT_DIR=/opt/repos/submodule.git
export GIT_WORK_TREE=/var/www/supermodule/assets/submodule
git fetch
git checkout -f $submodule_version
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文