git-filter-branch:保持目录结构不变

时间:2012-03-01 16:18:56

标签: git

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

|-repository/
|  |  |-repository/fileOne
|  |
|  |-subOne/
|  |  |-subOne/fileTwo
|  |
|  |-subTwo/
|     |-subTwo/fileThree

我想将目录subOne移动到另一个存储库中。为此,我正在使用subOne分隔git-filter-branch,如下所示:

$ git filter-branch --subdirectory-filter subOne --prune-empty

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

$ git log --oneline
0c0ea11 subOne history
6318bba subOne history
c96fddb Initial commit

这正是我想要的;从另一个存储库我可以执行git fetchgit merge,将subOne和历史记录添加到另一个存储库中。那很好。

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

$ ls
fileOne
$ pwd
/this/is/a/path/repository

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

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

1 个答案:

答案 0 :(得分:5)

  

pwd应该是:/ this /是/ 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

编辑:这不适用于MAC OS X 。有关详细信息,请参阅我的问题hereBSD sedGNU sed不同,这很烦人。要在OS X上运行该示例,请将sed更改为gsed;过滤器然后工作得很好。