2017-06-05 71 views
0

我有一个Git分支,它包含了许多,我想拉平到所有新枝目录的拼合git的子目录。它看起来有点像这样:由迪尔斯转换为新的分支机构

混帐的/ dev /我们 - >我们一,美国二,美国三

我想它最终会是这样的:

混帐的/ dev/us-one git/dev/us-two etc

它看起来像这是可能的使用git-filter-branch,但我不知道如何使用它与所有的目录。我可以做类似:

for branch in `find . -type d -d 1`; do 
    git filter-branch --subdirectory-filter $branch --prune-empty -- --all 
done 
+0

'git filter-branch'用于*复制现有的提交*,同时对每个进行一些转换(在创建新副本之前)。 filter-branch的参数提供了转换并告诉它要更新哪些分支*名称,以将它们指向新复制的提交,而不是它们原始的(现在被复制的)提交。它不会创建任何新的分支名称。 – torek

+0

所以这听起来像'git-filter-branch'可以用于几乎樱桃挑选从一个地方到另一个地方?这是否意味着如果我将SVN中的repo转换为git,并且在git更改完成之前svn repo中有更改,那么可以使用'git-filter-branch'来仅移动这些特定的提交? – user3270760

+0

你当然可以滥用'git filter-branch'来做这样的事情(樱桃采摘),但这不是它的设计目的。 (当然也可以参考马克阿德尔斯伯格的答案。) – torek

回答

2

嗯,我想有一种方法可以做到这一点。他指出了一些东西给后人第一...

注意事项

既然你在谈论使用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