如何从驻留在 GIT superrepo 中的 GIT subrepos 中提取

How to pull from GIT subrepos residing inside GIT superrepo

我有一个包含大量数据的项目。 由于它的大小,我无法通过 Internet 使用远程 GIT 存储库和 push/pull。相反,我随身携带一个便携式硬盘,其中包含项目的当前状态(即工作目录)。 此 workdir 的 GIT 存储库位于我台式计算机中的另一个 HDD 上(我使用 --separate-git-dir 来实现)。 有时,我硬着头皮,将我的外部硬盘连接到我的桌面,并进行另一个庞大的 GIT 提交,以跟踪项目数据的历史。

问题是在这个项目中,有几个小的子项目由它们自己的 GIT 回购跟踪。它们(相对)轻量级,并定期接收提交。

portable HDD                             desktop HDD
|                                        |
|-.git <- text file (gitlink) to here -> |-ProjectGit
|                                        | |-objects
|-project1                               | |-refs
| |-.git <- actual git dir               | |-HEAD
| |-some files                           . . ...
|
|-project2
| |-.git <- actual git dir
| |-some files
|
|-loads
|-and
|-loads
|-of
|-files

当我尝试在主 superrepo 中执行 git add --all . 时,GIT 可以理解地对嵌套的 .git 文件夹感到生气,并对我大喊我应该使用子模块。 我很乐意这样做,除了子模块位于 (a) superrepo 的 .git/modules 文件夹中,或者 (b) 可以强制使用遗留(过时)模式并将子模块存储在工作目录。在情况 (a) 中,我的外部硬盘上没有 .git 文件夹,并且无法在工作期间提交子存储库中的更改;在情况 (b) 中,superrepo 的 .git 文件夹将没有 subrepo 提交的副本,因此如果便携式 HDD 搞砸了,数据就会丢失。

每次提交 superrepo 时,我都想通过某种方式将嵌套子存储库中的所有提交拉入桌面 HDD。到目前为止我能想到的唯一方法是以某种方式使用 git 挂钩,并向它们附加一个脚本,它将自动将所有更改拉入驻留在桌面硬盘上的几个小回购以及 superrepo 的 git目录

我最后只使用了 "old submodules" 选项:

  1. 将 subrepo 文件夹移动到桌面 HDD,靠近 superrepo 的 git 目录;写下他们原来的路径
  2. 确保 superrepo workdir 是干净的
  3. 使用 git submodule add --name NAME RESERVE_HDD_PATH PORTABLE_HDD_PATH 将子仓库添加回超级仓库,其中 NAME 是一些有效的目录名称,RESERVE_HDD_PATH 是桌面硬盘上子仓库的路径,PORTABLE_HDD_PATH是您在步骤 1 中记下的原始子仓库路径,相对于超级仓库的根
  4. 删除在 workdir 中创建的 .git 文件,并从桌面硬盘复制原始子库而不是那些文件
  5. 从 superrepo 的 git 目录中删除 modules 文件夹(这是多余的)
  6. 将现在在便携式硬盘上的子库作为遥控器添加到桌面硬盘上的相应子库中。

就是这样。现在您可以使用便携式硬盘在子库中工作,每次将其连接到桌面并提交超级库时,它都会记住所有子库的当前提交。您只需要制作这些子仓库的保留副本,例如使用这样的脚本(驻留在 subrepo 文件夹附近的桌面硬盘上):

#!/bin/bash

while read filename
do
  echo "Pulling into $filename..."
  cd "$filename"
  git pull hdd master
  cd ..
done < submodules-list

其中 submodules-list 是一个包含您的子仓库列表的文本文件。 我想我可以使用 git 钩子进一步自动化它,但我对现在的情况很满意。