git通过子文件夹拆分存储库并保留所有旧分支 [英] git splitting repository by subfolder and retain all old branches

查看:77
本文介绍了git通过子文件夹拆分存储库并保留所有旧分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有2个目录和多个分支的git repo,我想将它们拆分并创建所有分支

I have a git repo with 2 directories and multiple branches, I want to split them and create all branches

`-- Big-repo
    |-- dir1
    `-- dir2

Branches : branch1, branch2, branch3 ...

我想要的

我想将dir1和dir2拆分为两个单独的存储库,并在两个存储库中保留分支branch1,branch2....

I want to split dir1 and dir2 as two separate repos and retain branches branch1, branch2 ... in both repositories.

dir1
Branches : branch1, branch2, branch3 ...

dir2
Branches : branch1, branch2, branch3 ...

我尝试过的事情:

我可以使用

git subtree split -P dir1 -b dir1-only 
git subtree split -P dir2 -b dir2-only 

但是,分离后它不会创建任何分支.

But, it is not creating any branches after separation.

获取所有分支:

git checkout branch1 (in Big-repo)
git subtree split -p dir1 -b dir1-branch1

git checkout branch2 (in Big-repo)
git subtree split -p dir1 -b dir1-branch2

And push these branches to newly created repo.

这涉及更多的人工工作,我确定可能有一种快速的方法来实现这一目标?

This involves more manual effort and I am sure there might be a quick way to achieve this?

任何想法?

推荐答案

简短答案

git filter-branch 完全提供了您想要的功能.使用--subdirectory-filter选项,您可以创建一组新的提交,其中subDirectory的内容位于目录的根目录.

Short answer

git filter-branch offers exactly the functionality you want. With the --subdirectory-filter option you can create a new set of commits where the contents of subDirectory are at the root of the directory.

git filter-branch --prune-empty --subdirectory-filter subDirectory -- --branches

演练

下面是一个以安全方式执行此操作的示例.您需要对将被隔离到其自己的存储库中的每个子目录执行此操作,在本例中为dir1.

首先克隆您的存储库以使更改保持隔离:

First clone your repository to keep the changes isolated:

git clone yourRemote dir1Clone
cd dir1Clone

要准备克隆的存储库,我们将所有远程分支重新创建为本地分支.我们跳过以*开头的那个,因为那是当前分支,在这种情况下,由于我们处于无头状态,因此它将读为(no branch):

To prepare the cloned repository we will recreate all remote branches as local ones. We skip the one starting with * since that is the current branch, which in this case would read (no branch) since we are in a headless state:

# move to a headless state
# in order to delete all branches without issues
git checkout --detach

# delete all branches
git branch | grep --invert-match "*" | xargs git branch -D

要在本地重新创建所有远程分支,请检查git branch --remotes的结果.我们跳过包含->的那些,因为它们不是分支:

To recreate all remote branches locally we go through the results of git branch --remotes. We skip the ones containing -> since those are not branches:

# get all local branches for remote
git branch --remotes --no-color | grep --invert-match "\->" | while read remote; do
    git checkout --track "$remote"
done

# remove remote and remote branches
git remote remove origin

最后运行filter-branch命令.这将使用所有触摸dir1子目录的提交来创建新的提交.所有也触摸此子目录的分支都将得到更新.输出将列出所有未更新的引用,对于完全不触摸dir1的分支就是这种情况.

Finally run the filter-branch command. This will create new commits with all the commits that touch the dir1 subdirectory. All branches that also touch this subdirectory will get updated. The output will list all the references that where not updated, which is the case for branches that do not touch dir1 at all.

# Isolate dir1 and recreate branches
# --prune-empty removes all commits that do not modify dir1
# -- --all updates all existing references, which is all existing branches
git filter-branch --prune-empty --subdirectory-filter dir1 -- --all

此后,您将拥有一组新的提交,这些提交在存储库的根目录中具有dir1.只需添加您的遥控器即可推送新的提交,或将它们完全用作新的存储库.

After this you will have a new set of commits that have dir1 at the root of the repository. Just add your remote to push the new commits, or use these as a new repository altogether.

如果您在乎存储库的大小,这是最后一个附加步骤:

As an additional last step if you care about the repository size:

即使更新存储库的所有分支仍将具有原始存储库的所有对象,也只能通过引用日志访问.如果您想删除这些内容,请阅读如何垃圾收集提交

Even if all branches where updated your repository will still have all the objects of the original repository, tho only reachable through the ref-logs. If you want to drop these read how to garbage collect commits

一些其他资源:

  • Github Teaching for filter branch
  • Git Book for rewriting history

这篇关于git通过子文件夹拆分存储库并保留所有旧分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆