在另一个git存储库的父文件夹中创建git存储库并删除子存储库,但将其历史记录集成到父存储库中

Creating a git repository in a parent folder of another git repository and removing the child repository but integrating its history into the parent

我有以下文件夹结构:

1
2
3
4
foo/
foo/bar
foo/baz
foo/bee

我在foo/bar/.git上创建了一个git存储库。

后来我意识到我需要将foo中的所有其他目录包含在git存储库中,所以我在foo/.git上创建了一个git存储库。

1
2
3
4
foo/.git
foo/bar/.git
foo/baz
foo/bee

我可以只删除foo/bar/.git,但我希望能够保留该git存储库的历史记录,但要保留在foo/.git中,而不是foo/bar/.git中。

我试图阅读子模块,但如果我理解正确,这是一种将现有存储库版本集成为您自己存储库子树的方法。

我不完全确定这就是我需要的。我不需要保留foo/bar/.git。我希望foo/.git是我的主要存储库。我只是想知道是否有一种方法可以将foo/bar/.git的历史记录保存或集成到foo/.git中,以便删除foo/bar/.git。


为什么不在foo/bargit mv中创建一个bar目录,把所有内容都放到foo/bar/bar中,然后(不涉及git)把foo/bar/.git移到.git中,把foo/bar/bar的内容移到foo/bar中,最后删除了现在空的foo/bar/bar子文件夹。

然后,您可以将其余的子目录添加到Git存储库中,该存储库现在位于foo中。


您正在查找子树合并

Github的帮助对此有一个很好的指导,在pro-git中有一章是关于这个的,和Git社区手册一样。


我建议在存储库的克隆上使用一次对filter-branch的调用:

1
2
3
git filter-branch --index-filter 'git ls-files -s | sed"s-\t"*-&bar/-" |
           GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info &&
         mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE'  --tag-name-filter cat -- --all

这将把所有文件移动到一个子目录"bar"中,重写所有修订历史记录(所有分支和标记)。

现在,您可以将重写的历史记录视为新的存储库。

(command adapted from a sample in man git-filter-branch):

可选背景信息

要删除旧的cruft/reflogs/filter分支备份,请执行以下操作:

1
2
3
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --prune=now

当然,您也可以克隆repo来除去备份/垃圾。