从git历史记录中删除已删除的文件

54
我想将一个子项目从我的git仓库中分离出来。 然而,与将子目录移动到单独的Git仓库中不同的是,我没有将其放在自己的子目录中(并且将其移动并执行上述操作后只生成移动后的历史记录)。
我已经克隆了我想要从中分离出子项目的分支,并删除了所有没有被子项目使用的东西,所以基本上我可以将其用作子项目的库。
现在,我想摆脱所有不再在此仓库中的文件的历史记录,以便仅保留进入新仓库的文件的文件历史记录。
我认为这可以通过git-filter-branch实现,但我无法弄清楚如何操作。
非常感谢您提前的帮助。

你找到解决办法了吗?我现在正好遇到同样的问题。 - Felix Cen
3个回答

14

33
我想让Git只保留工作目录中的文件和它们的历史记录,而忘记其他所有文件。使用上述命令删除所有已删除的文件可能很麻烦,这就是为什么尽管我找到了这个命令,但并没有太大用处的原因。 - Niklas Schnelle
请注意,您可以使用 git rm -r 删除整个目录,进行递归删除。 - Oyvind
@Oyvind 使用 git rm -r 只会从工作目录中删除文件/目录,不会删除任何文件/目录的历史记录。它只会将删除添加到历史记录的顶部。 - David Maness

9

现在我正在尝试以下技术,如果成功的话会回报,因为这似乎需要很长时间才能完成: 在克隆的存储库上使用zsh或bash。

git log --diff-filter=D --summary <start_commit>..HEAD | egrep -o '*[[:alnum:]]*(/[[:alnum:].]*)+$' > deleted.txt

获取所有已删除的文件

for del in `cat deleted.txt`
do
    git filter-branch --index-filter "git rm --cached --ignore-unmatch $del" --prune-empty -- --all
    # The following seems to be necessary every time
    # because otherwise git won't overwrite refs/original
    git reset --hard
    git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
    git reflog expire --expire=now --all
    git gc --aggressive --prune=now
done;

这可能极其危险,会影响您的数据,因此只在克隆环境中尝试。


1
你最终找到了什么? - Thorbjørn Ravn Andersen
4
你感觉git filter-branch命令运行缓慢的原因是你在每个文件上都执行了一次此命令,加上其他一些命令(运行git gc命令不仅成本高昂而且速度很慢),而不是对所有文件只执行一次。因此,这可能极其低效。请参阅 New repo with copied history of only currently tracked files 上的评论。 - user456814
推送到 Github 或 GitLab 会清理远程仓库吗? - oxygen

1

你的朋友是 git filter-repo。例如,最新的LTS Ubuntu存储库中可以使用它。

sudo apt install git-filter-repo

试试这个

ls > /tmp/files.list
git filter-repo --paths-from-file /tmp/files.list

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接