将许多子目录拆分为一个新的独立Git存储库

时间:2015-08-05 17:35:06

标签: git git-subtree git-filter-branch

这个问题与:

有关

我想分离一对子,而不是分离一个子目录。例如,这是我的文件夹结构:

/app1
  /file1
  /file2
  /folder1
  /folder2
/app2
  /file3
  /file4
  /folder3
  /folder4
/test
  /file5
  /file6
  /folder5
  /folder6
/README.md
/new_file

而我想这样做:

/app1
  /file1
  /file2
  /folder1
  /folder2
/app2
  /file3
  /file4
  /folder3
  /folder4

我已经尝试了以下替代方案,到目前为止还没有工作:

git filter-branch --index-filter 'git rm --cached -qr -- . && git reset -q $GIT_COMMIT -- /app1/* app2/*' --prune-empty -- --all

Error: 
    pathspec '.' did not match any files

第二次尝试:

git filter-branch --tree-filter "mkdir samples; mv app1 app2 samples/" HEAD

Error:
   rename app1 to samples/app1: No such file or directory
   Same error for the second sub-directory

有什么想法吗?

2 个答案:

答案 0 :(得分:6)

在树形过滤器的情况下,您将评估每个提交的脚本,甚至可能不存在app1和app2的提交,这可以通过一个保护和一个不会失败的替代命令来解决。

 git filter-branch --tree-filter "mkdir samples && test -d app1 && mv app1 samples/|| test -d app2 && mv app2 samples/ || echo 'nothing to do'" HEAD

然后将示例设为根目录,这会将app1和app2移动到项目的根目录。

git filter-branch -f --subdirectory-filter samples -- --all

我建议您先进行备份!

答案 1 :(得分:0)

# safety play: do this in a scratch clone
git clone --mirror . ../redo
cd !$

# build the exact index you want:
git filter-branch --index-filter '
        git read-tree --empty
        git read-tree --prefix=app1/ $GIT_COMMIT:app1
        git read-tree --prefix=app2/ $GIT_COMMIT:app2
' -- --all

...可能会--tag-name-filter cat将旧标签指向新的(已重写)提交,而无需更改名称。