将 git 子模块转换为常规目录并保留主树中的历史记录?

Dou*_*son 10 git git-submodules

我有一个由许多子模块组成的项目。然而,事后看来,其中一些子模块不应该是子模块,因为它们并不意味着或永远不会在另一个项目中使用,而且我偶尔会在它们之间传输代码。这个项目同时也是子模块中的实验,所以我对它有点疯狂。

我想知道是否有一种方法可以将子模块转换为常规目录,维护更改历史记录,但重写主项目的历史记录,以便将它们视为常规目录。

我看过有关子树合并的内容,但我希望有一种方法来重写提交,以便文件路径以子模块的路径为前缀。

doa*_*oak 9

git subtree如果您只想保留每个子模块的单个分支的历史记录,那么使用起来非常容易:

git fetch <path/to/submodule> HEAD
git rm <path/to/submodule>
git commit -m "Prepare to integrate Git submodules' history into repository"
git subtree add --prefix=<path/to/submodule> FETCH_HEAD 
Run Code Online (Sandbox Code Playgroud)

这将集成子模块当前签出版本的历史记录。确保之前处于干净状态,因此运行 例如git submodule update并用 仔细检查git status

您将获得两次提交:第一个删除子模块,第二个将先前的历史记录(现在存储在FETCH_HEAD)集成到存储库中。没有简单的方法(至少我不知道)可以通过“原子”提交来做到这一点。为此,您需要摆弄 Git 的管道命令集。

如果您需要集成多个子模块的历史记录,我建议将所有删除操作放入第一个提交中,并将所有集成操作放入第二个提交中。在这种情况下,您需要通过其他方式记住获取的 HEADS。


注意:虽然git subtree存在于./contrib上游 Git 中,但自 v1.9.1(2014 年 3 月)以来,它似乎(至少)在 Debian 上可用。


eft*_*ft0 1

我没有太多使用子模块的经验,但这就是我要做的:

  • 从项目中删除子模块**。添加“原始子模块”存储库作为项目的远程并获取。
  • 将您想要引入的任何分支合并到您的项目中。如果我想将其他项目中的文件放入主项目的单独目录中,我要做的可能是签出子模块分支(不再是子模块,它现在是一个真正的远程分支),将其中的文件重命名为我的意思是它的目录(这样它就不会与主项目中的任何内容发生冲突),然后我会将这个新修订版合并到我的主项目中。

也许不是最好的方法,但如果我想将不同的项目引入我的项目,同时保持事物独立,我就会这样做。

** 这可能吗?我确实需要获得更多有关子模块等的实践经验。