12

我有以下文件夹结构:

foo/
foo/bar
foo/baz
foo/bee

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

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

foo/.git
foo/bar/.git
foo/baz
foo/bee

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

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

我不完全确定这是我需要的。我不需要保留 foo/bar/.git。我希望 foo/.git 成为我的主要存储库。我只是想知道是否有办法在 foo/.git 中保留或整合 foo/bar/.git 的历史记录,以便我可以删除 foo/bar/.git。

4

3 回答 3

9

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

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

于 2012-05-03T10:31:23.507 回答
6

您正在寻找子树合并

Github 的帮助对此有很好的指导,Pro Git 中有一个章节对此进行了介绍,与Git 社区书相同

于 2012-05-03T10:38:48.183 回答
3

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

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”中,重写所有修订历史记录(所有分支和标签)。

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

(命令改编自 中的示例man git-filter-branch):


可选背景信息

要删除旧的 cruft/reflogs/filter 分支备份,请执行

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 以摆脱备份/垃圾。

于 2012-05-03T10:39:21.353 回答