代码之家  ›  专栏  ›  技术社区  ›  mipadi

如何在Git repo中为所有提交移动目录?

  •  65
  • mipadi  · 技术社区  · 14 年前

    repo/
      blog/
        _posts/
          some-post.html
      another-file.txt
    

    我想搬家 _posts 在回购的顶层,结构如下:

    repo/
      _posts/
        some-post.html
      another-file.txt
    

    git mv ,但我想让历史看起来 总是 存在于回购的根源,我希望能够得到整个回购的历史 some-post.html git log -- _posts/some-post.html . 我想我可以用魔法 git filter-branch 但我还没弄清楚怎么做。有什么想法吗?

    2 回复  |  直到 14 年前
        1
  •  101
  •   slm yuvaeasy    9 年前

    您可以使用子目录过滤器来实现这一点

     $ git filter-branch --subdirectory-filter blog/ -- --all
    

    编辑1: 如果你不想 _posts 对于根,请改用树筛选器:

     $ git filter-branch --tree-filter 'mv blog/_posts .' HEAD
    

    编辑2: blog/_posts 在某些提交中不存在,上述操作将失败。改用这个:

     $ git filter-branch --tree-filter 'test -d blog/_posts && mv blog/_posts . || echo "Nothing to do"' HEAD
    
        2
  •  37
  •   theduke    11 年前

    虽然拉姆库马尔的回答很有帮助,也很有价值,但在很多情况下都行不通。 例如,当您要将一个目录和其他子目录移动到一个新位置时。

    为此,手册页包含完美的命令:

    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
    

    只需将NEWSUBDIR替换为所需的新目录。 也可以使用嵌套的dir,如dir1/dir2/dir3/-“

        3
  •  2
  •   Jonas Berlin    3 年前

    为任意移动/重命名创建了通用脚本: https://gist.github.com/xkr47/f766f4082112c086af63ef8d378c4304

    示例:

    git filter-mv 's!^!subdir/!'
    

    git filter-mv 's!^foo/bar.txt$!foo/barbar.txt!'
    

    在当前分支的所有提交中将foo/bar.txt重命名为foo/barbar.txt