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

时间:2011-11-07 20:21:56

标签: git git-submodules

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

所以设置如下:

裸仓库在

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

工作树位于

/var/www/apps/e_learning_staging/www

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

这些都列在bare repo的配置文件中,如下所示:

[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 = user@another.server.com:/home/charangadh/source_code/git/virgin_lesson_viewer.git
  [submodule "public/assets/players/virgin_lesson_viewer_staging"]
    url = user@another.server.com:/home/charangadh/source_code/git/virgin_lesson_viewer_staging.git
  [submodule "public/assets/dvd_files/Virgin_lesson_viewer"]
    url = user@another.server.com:/home/charangadh/source_code/git/virgin_lesson_viewer.git
  [submodule "public/assets/dvd_files/Virgin_lesson_viewer_staging"]
    url = user@another.server.com:/home/charangadh/source_code/git/virgin_lesson_viewer_staging.git

如果git文件夹在工作树中,那就很容易 - 我会做

git submodule add user@another.server.com:/home/charangadh/source_code/git/virgin_lesson_viewer.git public/assets/dvd_files/Virgin_lesson_viewer

对于每个子模块,然后执行“git submodule update”更新它们。但是,我无法弄清楚如何从单独的git文件夹中执行此操作。谁能让我直截了当?

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,你基本上想在deploy目录中做git submodule update,但你不能,因为它不是真正的工作目录。

我的解决方案是实现自定义git submodule update - 类命令:

  1. 确定超级模块引用的子模块版本
  2. 将此版本签出到目标目录中。您可以像检查超级模块一样执行此操作。
  3. 假设您在服务器上进行了以下设置:

    • 裸存储库存储在/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 fetch
    • 之前添加git checkout命令

    结果如下:

    # 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