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

时间:2010-10-28 12:18:06

标签: git history mv git-filter-branch

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

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

我尝试以各种方式修复此问题(filter-branch使用子目录过滤器等),但没有任何帮助,所以我很好地堆叠在这里。我很感激你能给我的任何帮助。 谢谢!

3 个答案:

答案 0 :(得分:92)

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

如果您希望项目的历史记录看起来好像所有文件一直位于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'

现在,我们会记录历史记录,好像所有文件始终位于foo/bar

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

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

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

答案 1 :(得分:7)

总结一下这里的内容是我所做的简短总结。对我有用的命令是:

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

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

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

答案 2 :(得分:0)

安装 git-filter-repo:

git clone https://github.com/newren/git-filter-repo/

将 git-filter-repo 可执行文件添加到您的 $PATH(有关其他选项,请参阅 INSTALL.MD):

# this is just an example, you probably want to edit bashrc,
# or add a symlink to ~/bin or /usr/local/bin
PATH=$PATH:${PWD}/git-filter-repo

现在 cd 到您要修改的 git 存储库,然后运行:

git filter-repo --to-subdirectory-filter foo/bar