嗯,我想有一种方法可以做到这一点。他指出了一些东西给后人第一...
注意事项
既然你在谈论使用filter-branch
,我想你已经通过了这些分支的创建单独的历史的影响想。为了以防万一,我会指出,使用旧回购的人可能很难在新回购中找到相应的代码版本。另外,如果跨目录进行的更改得到协调,那么这些协调将会丢失(除非您执行某些操作来重新创建它们)。
可能与最后一点,如果在这些目录的结构都非常相似,这是有道理的,那么如果没有他们有时会让人感到意外需要“分享”的变化。如果这确实是一个问题,那么你描述的“现状”结构以及你所要求的“目标状态”都不会真正支持这一结构。
但是,你会怎么做呢?
在你刚刚得到了简单的情况下一个分支你想“突围”为每个目录。这意味着你的问题,但以防万一我会提供一个更适用于多个分支的一般程序。
所以首先,你需要真正创建所有你到底想要的分支。如果你有标签,你可能也想复制它们,但我会回到那个。
对于您的每个分支:
git checkout `branchA`
git branch `branchA-one`
git branch `branchA-two`
...
git checkout `branchB`
git branch `branchB-one`
git branch `branchB-two`
...
...
然后你就可以在每一组裁判的运行filter-branch
。你一定会使用一个subdirectory-filter
,如果你有标签来保存你要一个tag-name-filter
为好。如果典型的变化会影响一些(但不是全部)子目录,那么您需要决定是否希望(a)保留并行历史,或(b)使filter-branch
消除空提交
因此,在最简单的情况下
git filter-branch --subdirectory-filter dir-one -- branchA-one branchB-one ...
如果你想保留的标签,最简单的办法就是将它们复制到每一个新的历史(使用相同后缀的分支机构),所以
git filter-branch --subdirectory dir-one --tag-name-filter 'sed s/$/-one' -- branchA-one branchB-one
而且你可以在--prune-empty
如果扔你想删除提交不影响分支的子树。
的filte-branch
每次运行都会产生一些“备用裁判”,你会想清理(refs/original/...
)
请注意,这是什么不提供,最有可能的,是一个共同的根源提交。您将以回购的字面独立历史结尾。通常这并不重要。如果您稍后决定将其拆分成不同的回购方式,则很方便。如果您曾预见过这些历史的合并,那么这样做不太方便。
在最后一种情况下,大多数情况下可以解决独立历史记录(例如合并中的--allow-unrelated-histories
),但如果您不想要,那么您将修改上述过程。在做之前,filter-branches
您将创建一个空的“共享根”
git branch --orphan newRoot
git rm -r *
git commit --allow-empty
然后你将包括一个parent-filter
嫁接每一根改写到newRoot
。
'git filter-branch'用于*复制现有的提交*,同时对每个进行一些转换(在创建新副本之前)。 filter-branch的参数提供了转换并告诉它要更新哪些分支*名称,以将它们指向新复制的提交,而不是它们原始的(现在被复制的)提交。它不会创建任何新的分支名称。 – torek
所以这听起来像'git-filter-branch'可以用于几乎樱桃挑选从一个地方到另一个地方?这是否意味着如果我将SVN中的repo转换为git,并且在git更改完成之前svn repo中有更改,那么可以使用'git-filter-branch'来仅移动这些特定的提交? – user3270760
你当然可以滥用'git filter-branch'来做这样的事情(樱桃采摘),但这不是它的设计目的。 (当然也可以参考马克阿德尔斯伯格的答案。) – torek