如何将嵌套的git repo合并到父repo中,保留历史记录?

时间:2013-02-12 16:20:44

标签: git

现在我知道大多数git专家会立即想到git rebase,但我在更广泛的意义上使用“rebase”这个词:我的项目结构如下:

.
..
.git
tools
lib
src
    .git
build

../src目录都显然是git个存储库,并且具有很长的历史记录和大量的提交。 .中的存储库忽略src目录(这是它自己的仓库)。

我刚刚意识到我想要在.中只有一个单独的回购来跟踪包括源文件在内的所有内容,因为坦率地说,构建系统随着源代码一起发展,并且变得相当广泛

我的问题是我不知道如何让此存储库保留历史记录,该历史记录现在是src中存储库的一部分。它甚至可能吗?这就是'rebasing'所指的意思 - 如果./src/main.c中的./src/.git中的更改在某些N次提交中被./.git跟踪,那么我想保留这些更改并让它们成为新存储库的一部分{{1 }}。相同的历史,重新定位的文件路径。

更新

从我收集到的SO上,子树合并不是我想要的东西。简而言之,它比我需要的更多。我只需要旧回购的内容,一起所有分支的开发和所有提交,标签等看起来好像它们总是父回购的一部分。在本质上,唯一的变化是文件本身的路径 - 在子回购跟踪./main.c之前,新的回购现在将跟踪./src/main.c,并且正如我所听到的,git跟踪内容,而不是文件,然后改变文件路径,如上所述和对这些路径的引用,应该是相当简单的,对吗?

4 个答案:

答案 0 :(得分:1)

快捷方式:

重命名src中的所有文件,因此它们将以src/开头。将src repo添加为remote,fetch&合并。删除旧的src repo,现在所有内容都在./

这将使您在历史记录中记录此操作。

历史记录重写:

要使此合并不可见,您需要使用git filter-branch --tree-filter在src存储库中添加src/前缀。然后将其作为远程添加到./存储库并获取它(尚未合并)。要很好地混合历史记录,您需要重新排序提交。使用git log --date-order master src/master以正确的顺序检索这些提交并挑选它们:

git checkout -b new-master your-first-commit
git log --format='%H' --date-order --reverse master src/master | xargs git cherry-pick

这基本上会对您的提交进行合并排序,并将它们排列为线性历史记录。

这不会保留您的合并,所以除非您有平坦的历史记录,否则不要这样做。在这种情况下,只使用filter-branch,然后进行正常合并。

答案 1 :(得分:0)

没有真正使用,如果这可行,但值得一试。假设src位于远程服务器上,而父服务器位于远程服务器上。您可以尝试以下方法。

  • git clone url to remote server to clone the repo with tools,lib和build
  • git将远程src url添加到src remote repo
  • 创建src远程仓库的跟踪分支,然后在父仓库
  • 上查看它
  • 将远程跟踪分支合并到您的主分支中。
  • 删除第二个遥控器。

答案 2 :(得分:0)

使用子树合并。

我会列出步骤,但它们就是这个问题的答案:How do you merge two git repositories?

答案 3 :(得分:0)

我需要做同样的事情,这对我有用:

来自父回购,

git remote add -f subrepo git@github.com:sub/repo.git
git merge -s ours --no-commit subrepo/master
git read-tree --prefix=subrepo/ -u subrepo/master
git commit -m "Subtree merged"

这是来自GitHub帖子,其中还有更多细节: https://help.github.com/articles/about-git-subtree-merges/