如何使用git subtree将本地存储库添加到项目中?

6

假设我有一个已经是git仓库的目录"sub",现在我想将其作为子树添加到我的新创建的超级目录"sup"中。

我已经搜索了文档,但所有的教程都是关于添加远程仓库或从现有提交中分离。我该如何将现有的git仓库添加到主git仓库中?

使用git subtree add --prefix=sub sub会提示sub已经存在。

1个回答

5

根据您的期望,有两种方法可以实现。

  1. 将子仓库添加为子模块。这些仓库保持独立。
  2. 将子仓库添加为此子仓库的子树。它们的历史记录会合并。

对于第一点,您需要使用git子模块。具体来说,在已经初始化了git init的sup目录中,您需要运行:

git submodule add location-of-sub

它将会把子仓库克隆到父仓库中。如果子仓库已经存在于其他位置,你可以将其删除。
请注意,子模块仍然是不同于顶级仓库的仓库。
请参阅子模块的文档:

https://git-scm.com/book/en/v2/Git-Tools-Submodules


对于第二个问题,它有点复杂。
首先,您需要获取另一个存储库的提交记录:
# add remote
git remote add sub <locationofsubrepo>
# fetch commits
git fetch
# create local branch with sub
git checkout -b sub_branch sub/master
# switch to master
git checkout master
# now, merge commit as a subdirectory
git read-tree --prefix=sub/ -u sub_branch

在未来,您可以继续从子文件中提取,并将其合并到父文件中。

1
'git remote add sub sub'; 'git fetch sub'. 然后必须删除本地目录sub。如果要保留git日志,我想我应该使用'git merge -s ours --no-commit'。 - Thomas Wang
阅读了许多赞扬子树优于子模块的文章,但最终我浪费了很多时间试图采用v1书中描述的复杂范例。v2书籍对复杂性进行了模糊的引用,但没有描述问题--将从主子树合并的更改推送到分支将导致分支的上游存储库拥有本地存储库中的所有对象,包括_master_所引用的对象。 - bvj
这个答案非常有帮助。但是需要注意的是,对于较新版本的git(例如我的v2.38.1),"file"协议默认被阻止,使用上述子模块命令会导致错误,类似于Cloning into '/tmp/repo1/sub'... fatal: transport 'file' not allowed fatal: clone of '/tmp/repo2' into submodule path '/tmp/repo1/sub' failed。为了避免这种情况,需要使用-c选项来覆盖protocol.file.allow配置属性,例如:git -c protocol.file.allow=always submodule add --name subrepo /tmp/repo2 path-under-parent-repo - zpangwin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接