如何为所有提交移动 Git 存储库中的目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3142419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:38:21  来源:igfitidea点击:

How can I move a directory in a Git repo for all commits?

gitgit-filter-branch

提问by mipadi

Let's say I have a repo that includes this directory structure:

假设我有一个包含此目录结构的存储库:

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

I want to move _poststo the top level of the repo, so the structure will look like this:

我想移动_posts到 repo 的顶层,所以结构看起来像这样:

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

This is simple enough with git mv, but I want to make the history look as though _postsalwaysexisted at the root of the repo, and I want to be able to get the entire history of some-post.htmlvia git log -- _posts/some-post.html. I imagine I can use some magic with git filter-branchto accomplish this, but I haven't figured out exactly how to do that. Any ideas?

这很简单git mv,但是我想让历史看起来好像_posts总是存在于 repo 的根目录,我希望能够获得some-post.htmlvia的整个历史git log -- _posts/some-post.html。我想我可以使用一些魔法git filter-branch来实现这一点,但我还没有弄清楚如何做到这一点。有任何想法吗?

回答by artagnon

You can use the subdirectory filter to achieve this

您可以使用子目录过滤器来实现此目的

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

EDIT 1:If you don't want to effectively make _poststhe root, use a tree-filter instead:

编辑 1:如果您不想有效地创建_posts根,请改用树过滤器:

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

EDIT 2:If blog/_postsdid not exist in some of the commits, the above will fail. Use this instead:

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

 $ git filter-branch --tree-filter 'test -d blog/_posts && mv blog/_posts . || echo "Nothing to do"' HEAD

回答by theduke

While Ramkumar's answer is very helpful and worthwile, it will not work in many situations. For example, when you want to move a directory with other subdirectories to a new location.

虽然 Ramkumar 的回答非常有用且值得,但它在很多情况下都行不通。例如,当您想要将包含其他子目录的目录移动到新位置时。

For this, the man page contains the perfect command:

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

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

Just replace NEWSUBDIR with your desired new directory. You can also use nested dirs like dir1/dir2/dir3/-"

只需将 NEWSUBDIR 替换为您想要的新目录。您还可以使用嵌套目录,如 dir1/dir2/dir3/-"