如何将Git仓库中的一部分提取成自己的仓库,并保留历史记录和文件结构?

4

我有一个大型的git代码库,其文件夹结构如下:

/A
/B
/C
/D
...

我希望能够将/A和/B文件夹从原有仓库中提取出来,并且保留它们的历史记录(我只关心主分支)。因此,新的仓库应该是这样的:

/A
/B

我该怎么做?我发现git filter-branch可以帮助重写历史记录,但我不确定如何在保留多个子目录的同时使用它。

2个回答

5
git clone initial final
cd final
git filter-branch --tree-filter 'rm -rf <list of folders separated by space>' HEAD

以上命令将删除列表中提到的任何文件夹,但您的原始提交历史记录将被保留。
git filter-branch -f --prune-empty 

可以用来删除在已删除文件夹列表中出现的任何空提交。

或者,如果您有一个具有相当长历史记录的大型存储库,则可能需要一段时间。在这种情况下,您可以采取稍微不同的方法 -

首先为要迁移的每个文件夹创建单独的存储库。可以使用以下filter-branch命令完成此操作。

 git filter-branch –prune-empty –subdirectory-filter A/ master
 git filter-branch –prune-empty –subdirectory-filter B/ master

每个人都将拥有各自文件夹的内容和所有历史记录。然后,您可以将这些内容作为临时存储库推送到远程服务器上。(如果需要重新执行此过程,这些内容也可以作为检查点)。
接下来,创建您的新存储库。
git clone <remote path> NewRepo
cd NewRepo

# add a readme file
touch Readme.md
git add .
git commit -am "Adding ReadMe file"

您可以将您的个人文件夹(A和B仓库)合并到NewRepo中。
# Merge Repo A
git remote add -f A <remote path for A>
git merge -s ours --no-commit A/master
git read-tree --prefix=A/ -u A/master
git commit -m "Merge A into NewRepo"
git remote remove A

# Merge Repo B
git remote add -f B <remote path for B>
git merge -s ours --no-commit B/master
git read-tree --prefix=B/ -u B/master
git commit -m "Merge B into NewRepo"
git remote remove B

接下来您可以确认您的源已经设置为指向NewRepo并推送代码。
git remote add origin <remote path for NewRepo>
git push origin master

NewRepo现在应该包含这些文件夹以及它们的所有历史记录。


旧的帖子,所以可能事情已经改变了:在https://git-scm.com/docs/git-filter-branch网站上有一个警告,并建议使用https://github.com/newren/git-filter-repo/代替。我用过它一次,效果很好。 - David

0

filter-branch 可能需要一些时间来运行,但我建议尝试在本地复制存储库并将其用于测试。

git clone repoA repoB
cd repoB
git filter-branch --tree-filter 'rm -rf C D <other files you DON'T want>' HEAD

可能需要很长时间才能运行,但我认为它会做你要找的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接