将“子”git repo 合并/移动到“父”git repo

Posted

技术标签:

【中文标题】将“子”git repo 合并/移动到“父”git repo【英文标题】:Merging/moving "child" git repo into "parent" git repo 【发布时间】:2021-09-19 02:32:15 【问题描述】:

我对 git 很陌生,只将它用于简单的项目提交等,所以我可能会犯错误!

我最近开始在最初未版本化的代码上使用 git。我在 Visual Studio 2017 中使用 git。如果我没记错的话,Visual Studio 创建了存储库,我没有手动创建它们。

我在 Visual Studio 的同一解决方案中有 4 个项目。我最近注意到 1 个特定项目没有通知我未提交的更改(Visual Studio 将图标放在文件旁边),它不会让我提交更改,但我能够看到提交历史记录。使用 Git GUI 或 Bash,我可以看到未暂存的更改等并提交它们。

查看文件资源管理器,我可以看到解决方案根目录中有一个 git repo,而 3 个正在工作的项目目录中没有 git repo。但是在无法正常工作的项目中,它有自己的 git repo。我不确定这是怎么发生的。

我认为这导致了冲突,导致 Visual Studio 无法识别我的更改。我想基本上删除项目目录中的“子”git repo,并让“父”repo 管理整个解决方案。

我尝试按照这种方法合并两个 repos(来自Git GUI on Windows: merging conflicts):

cd path/to/project-b
git remote add project-a /path/to/project-a
git fetch project-a --tags
git merge --allow-unrelated-histories project-a/master # or whichever branch you want to merge
git remote remove project-a

我可以在我的提交历史记录中看到“子”存储库的历史记录似乎已被合并,但在有问题的项目中仍未检测到更改。

我重命名了子 git repo 看看是否有帮助,但没有改变。

我需要遵循一个流程来合并两个 repo,并让解决方案级别的 git repo 管理所有项目吗?

如果可能,最好保留子项目的提交历史。

【问题讨论】:

存储库由提交(不是文件)组成。一个存储库不能包含另一个存储库:相反,它将具有对另一个存储库的引用。 Git 将此称为 子模块。如果您已经有一个子模块,并且想要“去子模块化”它,这往往很困难:据我所知,没有工具可以做到这一点。 感谢您的帮助。我发现我可以使用以下命令取消初始化子模块:git submodule deinit。这个程序可能对我的情况有所帮助吗? 如果你取消初始化子模块,然后完全删除内部.git,你可以将子模块中的文件添加到超级项目中。这不会将子模块中的 commits 添加到超级项目中,因此您实际上已经丢弃了子模块中的所有历史记录。如果没问题,那就是摆脱这种困境的简单方法。如果没有,就没有简单的出路。 感谢您的帮助,我按照本文的建议尝试从子模块中获取一些历史记录。 【参考方案1】:

我在这里找到了一个合理的解决方案:How To: Merge a Git submodule into its main repository

我会在这里放一些摘录,以防将来删除该文章。本文将引导您将 src/models 中脚本的子模块合并到主存储库中。

主要思路是在子模块目录的根目录下新建一个目录结构,就好像它是父目录一样,将所有被跟踪的文件移动到那个目录,然后推送到远程。

在模型目录中:

mkdir -p src/models
git ls-tree master --name-only | xargs -I git mv  src/models
git commit -m 'Move all files into src/models directory'
git push

然后删除所有对子模块的引用,并删除目录:

Git 子模块元数据存储在 .gitmodules 文件中:

从该文件中删除子模块。

git add .gitmodules

.git/config 有一个类似的条目,请编辑该文件。

git rm --cached models

rm -rf .git/modules/models

git commit -m 'Remove models submodule'

rm -rf models

然后你从远程合并子模块文件:

在主存储库中运行命令:

git remote add models-origin git@github.com/exampleUser/models
git fetch models-origin
git merge --allow-unrelated-histories models-origin/master
git remote remove models-origin

对于我自己来说,我遇到了一个奇怪的情况,大多数子模块引用都不存在,我得到了错误:

No submodule mapping found in .gitmodules for path 'submodule/path'

这个答案帮助了我:https://***.com/a/13394710/1324919 删除缓存的子模块后,我必须运行子模块更新:

git rm --cached submodule-name
git submodule update --init

现在我有来自子模块的历史记录,主仓库正在跟踪文件。看起来它并不容易/不可能恢复。至少我有那里的历史,我可以阅读并在必要时复制/粘贴。

【讨论】:

以上是关于将“子”git repo 合并/移动到“父”git repo的主要内容,如果未能解决你的问题,请参考以下文章

Xcode Bots 不会将 git 子模块更新为指定的提交

根据扩展名将git repo文件移动到子文件夹

从 Azure DevOps 中的子模块触发父存储库中的构建

将 git repo 合并到另一个 repo 的分支中

将 git repo 分支(具有不同的历史记录)合并到主分支 [重复]

使用 git 子模块恢复 Nuget 包