如何从驻留在 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" 选项:
- 将 subrepo 文件夹移动到桌面 HDD,靠近 superrepo 的 git 目录;写下他们原来的路径
- 确保 superrepo workdir 是干净的
- 使用
git submodule add --name NAME RESERVE_HDD_PATH PORTABLE_HDD_PATH
将子仓库添加回超级仓库,其中 NAME
是一些有效的目录名称,RESERVE_HDD_PATH
是桌面硬盘上子仓库的路径,PORTABLE_HDD_PATH
是您在步骤 1 中记下的原始子仓库路径,相对于超级仓库的根
- 删除在 workdir 中创建的
.git
文件,并从桌面硬盘复制原始子库而不是那些文件
- 从 superrepo 的 git 目录中删除
modules
文件夹(这是多余的)
- 将现在在便携式硬盘上的子库作为遥控器添加到桌面硬盘上的相应子库中。
就是这样。现在您可以使用便携式硬盘在子库中工作,每次将其连接到桌面并提交超级库时,它都会记住所有子库的当前提交。您只需要制作这些子仓库的保留副本,例如使用这样的脚本(驻留在 subrepo 文件夹附近的桌面硬盘上):
#!/bin/bash
while read filename
do
echo "Pulling into $filename..."
cd "$filename"
git pull hdd master
cd ..
done < submodules-list
其中 submodules-list
是一个包含您的子仓库列表的文本文件。
我想我可以使用 git 钩子进一步自动化它,但我对现在的情况很满意。
我有一个包含大量数据的项目。
由于它的大小,我无法通过 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" 选项:
- 将 subrepo 文件夹移动到桌面 HDD,靠近 superrepo 的 git 目录;写下他们原来的路径
- 确保 superrepo workdir 是干净的
- 使用
git submodule add --name NAME RESERVE_HDD_PATH PORTABLE_HDD_PATH
将子仓库添加回超级仓库,其中NAME
是一些有效的目录名称,RESERVE_HDD_PATH
是桌面硬盘上子仓库的路径,PORTABLE_HDD_PATH
是您在步骤 1 中记下的原始子仓库路径,相对于超级仓库的根 - 删除在 workdir 中创建的
.git
文件,并从桌面硬盘复制原始子库而不是那些文件 - 从 superrepo 的 git 目录中删除
modules
文件夹(这是多余的) - 将现在在便携式硬盘上的子库作为遥控器添加到桌面硬盘上的相应子库中。
就是这样。现在您可以使用便携式硬盘在子库中工作,每次将其连接到桌面并提交超级库时,它都会记住所有子库的当前提交。您只需要制作这些子仓库的保留副本,例如使用这样的脚本(驻留在 subrepo 文件夹附近的桌面硬盘上):
#!/bin/bash
while read filename
do
echo "Pulling into $filename..."
cd "$filename"
git pull hdd master
cd ..
done < submodules-list
其中 submodules-list
是一个包含您的子仓库列表的文本文件。
我想我可以使用 git 钩子进一步自动化它,但我对现在的情况很满意。