我有以下文件夹结构:
foo/
foo/bar
foo/baz
foo/bee
我在foo / bar / .git上创建了一个git存储库。
我后来意识到我需要在foo存储库中包含foo中的所有其他目录,所以我在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。
答案 0 :(得分:8)
为什么不在bar
中创建foo/bar
目录,git mv
将所有内容创建到foo/bar/bar
,然后将foo/bar/.git
移动到.git
到foo/bar/bar
foo/bar
最多foo/bar/bar
的内容最终删除了现在为空的foo
子文件夹。
然后,您可以将其余的子目录添加到现在位于{{1}}的git存储库中。
答案 1 :(得分:5)
您正在寻找子树合并
Github的帮助有a good guide on this,其中a chapter in Pro Git与此the Git Community book相同
答案 2 :(得分: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
当然你也可以克隆回购来摆脱备份/垃圾。