在远程 squash 后提取旧的提交 ID

Posted

技术标签:

【中文标题】在远程 squash 后提取旧的提交 ID【英文标题】:Extract old commit IDs after squash in remote 【发布时间】:2022-01-22 05:20:07 【问题描述】:

在我们的本地 Bitbucket 实例上,我可以通过压缩功能分支的所有更改(通过 Git rebase)将功能分支“合并”到我们的主分支中。这样做时,提交消息包含所有压缩提交的 Git 提交 ID/哈希。此提交附加到主分支,功能分支将被删除。

我曾怀疑在删除功能分支时旧的提交也会被删除,但似乎并非如此。由于主分支上的提交消息包含所有压缩提交的提交 ID,因此我可以通过 URL 访问 Bitbucket 中的每一个旧提交。但是,由于提交不再属于分支,我无法从 UI 中找到提交 - 无论是在 Bitbucket 中还是从任何其他 Git 客户端 UI。

因此,现在来自功能分支的压缩提交只是“隐藏”的,但它们仍然存在于 Git 存储库中。

现在我的(相当学术的)问题:

    总是这样吗?即使之前关联的分支已被删除,Git 是否始终保留压缩的提交? 是否有任何方法可以提取以前压缩提交的提交 ID,即使“旧”提交 ID 不会成为压缩提交消息的一部分? 是否可以“硬删除”旧的提交?

提前致谢!

【问题讨论】:

【参考方案1】:
    总是这样吗?即使之前关联的分支已被删除,Git 是否始终保留压缩的提交?

没有。 Git 可能会或可能不会在一段时间内或什至永远保留原始提交,但对此没有硬性规定,除了通常情况:如果提交是可访问(通过一些名称(例如分支或标签名称),它必须保留。

(GitHub 有一个自己的简单规则:永远不会删除任何提交。这可以解决他们使用的 fork 模型可能遇到的一些问题。Bitbucket 可能自己添加了相同的规则,也可能没有。这个规则有一些缺点,这可能会导致这些托管网站实施更高级的规则,最终允许删除未引用的提交。)

    是否有任何方法可以提取以前压缩提交的提交 ID,即使“旧”提交 ID 不会成为压缩提交消息的一部分?

没有。

    是否可以“硬删除”旧的提交?

仅当您可以直接控制存储库时。在这种情况下,您可以使用某些维护命令(git gcgit prune 等)。

您也可以克隆一个存储库,然后删除原始存储库(如果您有正确的访问/权限,请安装新的克隆代替原始存储库,使整个操作对“外人不可见” “除了停机时间有多长来做这一切)。克隆通常不会复制任何未引用的(“除哈希 ID 外不可见”,名义上已删除)提交,因此这为您提供了一种在错误后进行清理的简单方法。但这通常意味着使用镜像克隆并可以直接登录访问托管存储库的任何站点。

【讨论】:

以上是关于在远程 squash 后提取旧的提交 ID的主要内容,如果未能解决你的问题,请参考以下文章

如何在GIT Rebase Interactive Squash之后删除远程存储库上的历史记录提交消息

Git squash 重命名文件的提交(保留历史记录)

如何从 Xcode 中的本地分支中提取

推送后更改 git commit 消息(假设没有人从远程拉出)

Linux使用NFS服务实现远程共享

如何在 Git 中标记较旧的提交?