我有一个 git 存储库,它包含在另一个 git 存储库中;如何在保留其提交历史的同时将内部永久合并到外部?为了更说明性的解释,这是我的目录结构:
[dev]
> [ext]
...
> [libs]
...
> [tools]
...
dev
是我的 git 存储库 A 的根目录,它通过 .gitignore规则排除了
ext
目录中的所有内容。 ext
又是我的 git 存储库 B 的根目录。我只想继续存储库 A,并让它包含 dev
下的所有内容,包括 ext
的内容,而将 B 的提交历史合并到 A 中——这样我就只有一个存储库,其中包含所有内容以及 A 和 B 的所有历史。
不涉及子模块;存储库的分离仅通过外部存储库的排除规则完成。
最好的方法是什么?
首先,备份。其次,将所有内容从
ext
推到B
:
cd ext
git push --all origin
cd ..
删除子目录
ext
并从.gitignore
中删除它:
rm -rf ext
`git var GIT_EDITOR` .gitignore
现在使用
B
将A
导入
git subtree
:
git subtree add --prefix=ext URL-for-B master # or whatever branch you want to import
首先移动存储库B的内容(在
ext
中)到存储库中的新ext
目录(即<project>/ext/ext
)。
$ cd ./ext
$ mkdir ext
$ for f in *; do git mv "$f" "./ext/$f"; done
这样,存储库 B 的历史将在下一步“记住”它的源代码树属于
ext
目录。
不要忘记提交此更改。
之后,您可以进入存储库 A(根项目),将存储库 B 添加为远程,获取其不相关的历史记录,然后创建一个继承两个修订历史记录的合并提交。请注意,您需要将
--allow-unrelated-histories
传递给 git-merge
以允许合并不相关的历史记录。这面旗帜的描述是:
默认情况下,
命令拒绝合并不具有共同祖先的历史记录。在合并两个独立开始的项目的历史时,此选项可用于覆盖此安全性。git merge
总而言之,这些是要运行的命令:
# Add "repo B" as a remote of "repo A"
$ git remote add ext_repo ./ext
# Fetch the unrelated history of "repo B"
$ git fetch ext_repo
# Create a commit with parents from both repos histories.
$ git merge --allow-unrelated-histories ext_repo/main