git-filter-branch:离开目录结构

sim*_*ont 5 git

我的存储库中有一个目录结构:

|-repository/
|  |  |-repository/fileOne
|  |
|  |-subOne/
|  |  |-subOne/fileTwo
|  |
|  |-subTwo/
|     |-subTwo/fileThree
Run Code Online (Sandbox Code Playgroud)

我想将目录移动subOne到不同的存储库中.要做到这一点,我是这样分开subOne使用git-filter-branch:

$ git filter-branch --subdirectory-filter subOne --prune-empty
Run Code Online (Sandbox Code Playgroud)

这给我留下了一个如下所示的分支历史记录:

$ git log --oneline
0c0ea11 subOne history
6318bba subOne history
c96fddb Initial commit
Run Code Online (Sandbox Code Playgroud)

这正是我想要的; 从另一个仓库,我可以做一个git fetchgit merge,增加了subOne历史到其他仓库.那很棒.

但是,git-filter-branch已删除subOne.检查我的分支上的目录结构:

$ ls
fileOne
$ pwd
/this/is/a/path/repository
Run Code Online (Sandbox Code Playgroud)

pwd 阅读:/this/is/a/path/repository,但ls应显示subOne在存储库中.我得到的是subOne向上移动的文件,并删除了目录.

如何在subOne不丢失目录的情况下提取?

sim*_*ont 6

pwd应该显示为:/ this / is / a / path / repository,但是ls应该在存储库中显示subOne。相反,我得到的是subOne中的文件向上移动,并删除了目录。

原来,这是默认操作git-filter-branch --subdirectory-filter。引用自man git-filter-branch

结果将包含该目录(并且仅包含该目录)作为其项目根目录。

要解决此问题,我想将所有内容/移至/subdirectory。幸运的是,有一块巫毒看代码man git-filter-branch,下EXAMPLES

To move the whole tree into a subdirectory, or remove it from there:
       git filter-branch --index-filter \
               'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
                       GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                               git update-index --index-info &&
                mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
Run Code Online (Sandbox Code Playgroud)

编辑:这在MAC OS X上将不起作用。有关更多信息,请参见此处BSD sed与并不相同GNU sed,这很烦人。要在OS X上运行该示例,请更改sedgsed;过滤器就可以很好地工作了。