Git: 是否有安全的方法删除一个分支,包括其中的所有 commits/history 以恢复原始回购大小

Git: Is there a safe way to delete a branch, including all commits/history from it to restore original repo size

有人要求我使用 Git 传输大型二进制文件作为一次性解决方法(在 2 人之间传输文件)。他遇到一些网络问题,无法使用标准工具(如 Dropbox、GDrive、Ftp 等),但可以完全连接到我的 Git 存储库。

我最担心的是允许他这样做会增加我的存储库的大小。即使他创建一个新的分支,用二进制文件提交,并在对方成功拉取后删除该分支,repo 不会保留与该提交相关的历史记录吗?

如果文件相当大 (100M),即使分支被删除,我的 repo 是否也不会增长那么多?我需要做什么才能将回购重新缩小到提交前的大小?

Once all 引用了一些提交及其关联的文件——实际上,底层 Git 对象(与那些相关的树和 blob commits)——消失了,对象变得符合的垃圾回收条件。然而,它们实际上不会 收集,直到某些东西运行 git gc (或 git prune 它们至少是和 "prune time".

一样老

默认的修剪时间是两周,但您可以使用 git gc --prune=yesterday--prune=10.minutes.ago 或类似的方式降低它。如果您将这段时间设置得非常短,请确保没有人在存储库中创建新对象。

摆脱对各种 Git 对象的 所有 引用可能比看起来更难。明显的是分支名称和标签名称。这些引用名称通常也有reflogs,并且HEAD本身还有一个额外的reflog;所有这些 reflogs 都包含引用,然后使对象保持活动状态。删除分支名称(当前)会删除分支的引用日志,但 HEAD 的引用日志中的那些仍然存在。

reflog 条目本身过期,默认情况下,reachable 对象在 90 天后过期,unreachable 对象在 30 天后过期,具有此可达性由相应参考的当前值确定。如果对提交的唯一引用在 HEAD reflog 中并且 HEAD 本身没有分离,则该 reflog 引用指向无法访问的提交(根据定义:如果 HEAD 附加到分支,那么 HEAD 只包含一个分支名称,我们已经说过没有分支名称指向提交本身,也没有指向提交的后代),所以只适用较短的到期时间。您可以使用 git reflog expire --expire-unreachable=... 进一步缩短它,使用与 git gc --prune=... 相同的语法,当然您将过期 all 此类无法访问的 reflog 条目,除非您限制它至 HEAD(然后您将仅剔除 HEAD 的无法访问的条目)。

除此之外,还可以引用其中一个特殊的 *_HEAD 名称(ORIG_HEADMERGE_HEADCHERRY_PICK_HEAD 等)。不过,对于这种特殊情况,这不太可能。