git - 修剪旧的 Git 提交而不用 rebase

标签 git garbage-collection git-rewrite-history

假设我有一个 Git 存储库,其中包含巨大的树 (~60 GiB) 和一些历史记录,其中旧版本包含许多已删除的文件。

我现在想修剪旧历史,但是没有 rebase修剪点之后的所有提交,因为那会花费几个小时对于每次提交。

  • 我可以只删除要删除的第一个提交对象,并希望 git gc 删除所有(现在未引用的)旧提交对象吗?或者这会因为丢失对象而导致 panic 吗?

  • 我可以使用 git replace 将我要删除的第一个提交替换为虚拟提交,然后然后调用 git gc ?

  • 是否有其他方法可以就地删除我的旧提交?

最佳答案

without rebasing all the commits after the prune point, because that would take several hours for each commit.

Git 2.18(2018 年第 2 季度)之后

从 Git 2.18 开始,graft has been superseded by git ref/replace/ ):参见“What are .git/info/grafts for?”。

如评论中所述,您可以改用
git replace --convert-graft-file :

Creates graft commits for all entries in $GIT_DIR/info/grafts and deletes that file upon success.
The purpose is to help users with transitioning off of the now-deprecated graft file.

所以在 git rev-parse HEAD~100 > .git/info/grafts 之后。

git filter-branch or BFG are obsolete after Git 2.22

安装 git filter-repouse git filter-repo --force


Git 2.18(2018 年第 2 季度)之前:

这就是graft point是为了(在那种特殊情况下比 git replace 更好,因为我 detail here )

文件 .git/info/grafts 只有一行带有提交 ID,表示该提交没有父项。
要保留最后 100 次提交,请使用 git rev-parse :

 git rev-parse HEAD~100 > .git/info/grafts

然后:

 git filter-branch -- --all

最后:

rm -Rf .git/refs/original

然后你可以修剪剩下的部分:

git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
git repack -Ad      # kills in-pack garbage
git prune           # kills loose garbage

关于git - 修剪旧的 Git 提交而不用 rebase,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24740744/

相关文章:

exception - 我可以选择哪些选项来寻找 Monotouch 异常(例如 "System.Exception: Selector invoked from objective-c on a managed object that has been GC' ed”)?

git: 找不到 blob - 想从包中删除它

Git - 将 .git 目录移动到另一个驱动器,将源代码保留在原处

git - ansible git clone 权限被拒绝问题

java - 过于激进的垃圾收集支配着 CPU

java - 如何从命令行检查正在运行的 JVM 的堆使用情况?

git - rebase 未按预期运行

git - 在 'git merge' 之后保留提交历史

带有索引过滤器的 Git 过滤器分支不起作用并按预期删除目录

git - 将2个分支 merge 为一个分支