git 如何重写历史记录,以便除我已经移动的文件之外的所有文件都在子目录中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4042816/
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-19 04:40:59  来源:igfitidea点击:

How can I rewrite history so that all files, except the ones I already moved, are in a subdirectory?

githistorymvgit-filter-branch

提问by Alexander Sandler

I have a project under git. One day I moved all project files from current directory to foo/bar/under the project. I did it using git mv. Then I added some more files and did some changes to already existing files.

我在git. 有一天,我将所有项目文件从当前目录移动到foo/bar/项目下。我是用git mv. 然后我添加了更多文件并对现有文件进行了一些更改。

As a result, now when I look at the history of foo/bar/file.c, I can only see changes that I did after I moved the file.

结果,现在当我查看 的历史记录时foo/bar/file.c,我只能看到我移动文件后所做的更改。

I tried to fix this in various ways (filter-branchwith subdirectory filter, etc), but nothing helped, so I am pretty stacked here. I'll appreciate any help that you can give me. Thanks!

我试图以各种方式解决这个问题(filter-branch使用子目录过滤器等),但没有任何帮助,所以我在这里堆积如山。我会很感激你能给我的任何帮助。谢谢!

回答by Dan Moulding

To rewrite the history with the files moved:

要使用移动的文件重写历史记录:

If you want the project's history to look as though all files have always been in the directory foo/bar, then you need to do a little surgery. Use git filter-branchwith the "tree filter" to rewrite the commits so that anywhere foo/bardoesn't exist, it is created and all files are moved to it:

如果您希望项目的历史记录看起来好像所有文件都一直在目录中foo/bar,那么您需要做一些小手术。git filter-branch与“树过滤器”一起使用来重写提交,以便任何地方foo/bar都不存在,它被创建并将所有文件移动到它:

git filter-branch --prune-empty --tree-filter '
if [ ! -e foo/bar ]; then
    mkdir -p foo/bar
    git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files foo/bar
fi'

Now the history will be recorded as if all files were alwayslocated in foo/bar.

现在历史记录将被记录,就好像所有文件总是位于foo/bar.

To see the history of a moved file:

要查看移动文件的历史记录:

If you just want to see the history of a file that has been moved or renamed at some point in the past, then simply use the --followoption to git log:

如果您只想查看过去某个时间点已移动或重命名的文件的历史记录,则只需使用以下--follow选项即可git log

git log --follow foo/bar/file.c

回答by Alexander Sandler

To wrap things up here's a short summary of what I did. The command that worked for me was:

最后总结一下我所做的事情。对我有用的命令是:

if [ ! -e foo/bar ]; then mkdir -p foo/bar; git ls-tree --name-only $GIT_COMMIT | grep -v ^foo$ | xargs -I files mv files foo/bar || echo ""; fi

The echo command that I added at the end ensured that even when mv fails entire command will continue running. It didn't move contents of foo/bar/foo, but I can live with that.

我在最后添加的 echo 命令确保即使 mv 失败,整个命令也会继续运行。它没有移动 foo/bar/foo 的内容,但我可以忍受。

Thanks a lot to Dan Moulding(!!!) and Jefromi for the help.

非常感谢Dan Molding(!!!) 和 Jefromi 的帮助。