通过将dirs转换为新分支来展平git子目录

时间:2017-06-05 15:40:18

标签: git

我有一个git分支,其中包含许多我希望在所有新分支中展平的目录。它看起来像这样:

git / dev / us - >我们 - 一个,我们两个,我们三个

我希望它最终会像这样:

GIT中的/ dev / US-一个 混帐的/ dev /我们两 等

看起来这可能是使用git-filter-branch,但我不确定如何在所有目录中使用它。我可以这样做:

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

1 个答案:

答案 0 :(得分:2)

嗯,我想有办法做到这一点。首先为后人指出一些事情......

<强>注意事项

由于您正在谈论使用filter-branch,我想您已经考虑过为每个分支创建单独的历史记录的含义。为了以防万一,我要指出,使用您的旧仓库的人可能很难在新仓库中找到相应的代码版本。此外,如果跨目录的更改得到协调,那么这些协调将会丢失(除非您执行某些操作以重新创建它们)。

可能与最后一点有关,如果每个目录中的结构足够相似以使其有意义,那么如果他们有时不需要分享&#34;那将会令人惊讶。变化。当前的状态都不是&#34;你描述的结构,以及&#34;目标状态&#34;如果这确实是一个问题,那么你已经要求了,真的会非常支持。

但是你会怎么做?

在最简单的情况下,您只想拥有一个分支机构,并且需要突破#34;对于每个目录。您的问题暗示了这一点,但万一我会提供一个稍微更通用的程序,应该适用于多个分支。

首先,你需要实际创建你最终想要的所有分支。如果你有标签,你可能也希望复制它们,但我会回过头来看。

对于您拥有的每个分支:

git checkout `branchA`
git branch `branchA-one`
git branch `branchA-two`
...
git checkout `branchB`
git branch `branchB-one`
git branch `branchB-two`
...
...

然后你可以在每组ref上运行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的每次运行都会创建一些&#34;备份参考&#34;你想要清理(refs/original/...

请注意,此无法提供的内容很可能是一个常见的root提交。你将在回购中获得字面上独立的历史。通常这并不重要。如果您稍后决定将它们拆分为不同的回购,这很方便。如果你能预见到这些历史的融合,那就不那么方便了。

在最后一种情况下,您可以在大多数时间处理独立历史记录(例如合并中的--allow-unrelated-histories),但如果您不想这样做,那么您就可以了修改上述程序。在执行filter-branches之前,您将创建一个空的&#34;共享根&#34;

git branch --orphan newRoot
git rm -r *
git commit --allow-empty

然后你会包含一个parent-filter来将每次重写的根移植到newRoot上。