无效 BFG 使用后 Git 合并重复

Posted

技术标签:

【中文标题】无效 BFG 使用后 Git 合并重复【英文标题】:Git Merge Duplication after Ineffective BFG Use 【发布时间】:2014-08-23 22:02:16 【问题描述】:

我对整个存储库(仅供我使用)感到非常厌烦,并且可以使用一些帮助来整理它。

这就是我所做的。我意识到在我的提交历史中,有一些文件包含我不想随便放置的凭据。因此,我决定合法并尝试使用 BFG Repo-Cleaner 来解决这些问题。我将所有凭据都放入 .gitignores 中,然后继续尝试将它们从历史记录中删除。根据文档说明,我执行了以下命令:

git clone --mirror myrepo.git
java -jar bfg.jar --delete-files stuffthatshouldbedeleted.txt  myrepo.git

此时,BFG 告诉我已经找到并删除了 x 个文件。甜蜜。

cd myrepo.git
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push

根据终端日志,它更新了 repo。到目前为止一切顺利,对吧?我进入我的 github 帐户,单击几下后,在我的历史记录中找到仍然存在的凭据、文件和所有内容。我回去尝试相同的命令集,但使用这一行而不是文件删除器:

java -jar bfg.jar --replace-text passwords.txt  myrepo.git

其中 passwords.txt 是一个文件,其中包含我想要删除的所有凭据的字符串实例。同样,BFG 日志表明它已经修复了几个实例。我向上推,检查,证书还在,坐在 Github 上。我注意到我所有提交的 SHA-1 密钥都已更改,所以大概 BFG 做了一些事情,而不是我想要它做的事情。

在这一点上,我放弃并尝试重新开始工作,我想我稍后会解决它。我做了一些工作,尝试向上推,得到一个奇怪的合并冲突(你在提交时领先 50 和落后 50)。什么?我尝试拉取和合并,突然间,我的 git 历史记录中的每一个提交都在名称上重复,其中一些只是空白。我检查了我的 Github 网络图,看起来从我的初始提交开始有第二个分支,它完全反映了我上次提交时压缩的所有提交(我从未分支过,只是一直在线性增长)。

我无法恢复到之前的提交,因为它们都是按时间顺序重复的。我的凭证仍然在那里,现在有两倍多的实例,我的历史翻了一番,而且很难理解。当我现在尝试从头开始运行 BFG,重新克隆和镜像 repo 时,它告诉我其中没有凭据,尽管我可以在 Github 中看到它们。我真的可以借助一些帮助来了解发生了什么,以及如何(如果有的话)重新回到原来的状态。

我正在考虑删除整个回购并重新开始。我真的不想那样做。

tldr;尝试使用 BFG,以某种方式复制了我的 repo 中所有提交的半生不熟的版本,无法解开,并且雪上加霜,BFG 什么也没做,并声称它已经完成了它的工作。

【问题讨论】:

【参考方案1】:

我是 BFG 的作者,我将尝试根据您的帐户逐步描述我认为发生的事情:

预 BFG 手动清洁...

首先是你:

在 .gitignores 中抛出所有凭据,然后继续尝试将它们从历史记录中删除。

对您的操作的描述省略了两个基本步骤:

    从当前文件树中手动删除凭据,并将更改提交到您的存储库。如果您不这样做,BFG 会从您的旧提交中删除内容,但保护当前提交中的污垢。此行为在 BFG 文档中标题为“Your current files are sacred...”的部分下进行了介绍,如果您忘记这样做,BFG 会在您运行它时打印一条警告消息(“WARNING: The dirty content above may be removed from other commits, but as the protected commits still use it, it will STILL exist in your repository...”等, 等等)。您在运行 BFG 时是否看到该消息?

    在克隆存储库的完整镜像之前,需要将该提交推送到您的 GitHub 存储库。你忘了那一步吗?

如果您没有做这些事情,那将说明您的凭据没有从您的存储库中完全清除。

第一次运行 BFG...

继续前进,那么你:

从 GitHub 对您的存储库进行了全新的镜像克隆 运行 BFG,使用 --delete-files 选项进行过滤(您是否看到受保护的内容警告?) 已将更新的存储库推送到 GitHub

...此时:

根据终端日志,它更新了 repo。到目前为止一切顺利,对吧?我进入我的 github 帐户,点击几下后,在我的历史记录中找到仍然存在的凭据、文件和所有内容

所以,假设您在运行 BFG 之前 确实 正确地手动从最新提交中删除了不良内容,那么您看到的情况就相当奇怪了。一些可能的原因:

a) 没有使用--mirror 标志克隆存储库,因此并非 GitHub 上的所有分支都被覆盖,在非主分支中留下脏历史。但是,您已明确声明您使用了 --mirror 标志。

b) 即使将镜像推送到 GitHub,当显式 commit-id(即其中包含 commit-id 的 GitHub url)引用时,旧提交仍然可用,直到您的 GitHub runs it's automatic garbage-collection存储库。拉取请求和分叉还可以保留来自旧历史的提交。这将是您看到的脏提交的另一种可能解释。

第二次运行 BFG...

无论如何,那时你很担心,并且:

再次运行 BFG,这次使用 --replace-text passwords.txt,它会更新文件内容而不是删除整个文件。

同样,BFG 日志表明它已修复多个实例。我向上推,检查,凭证还在,在 Github 上。

BFG 说有更多内容需要清理,这有点奇怪 - 可能你的凭据在你认为的更多地方 - 但无论如何,不​​管是什么原因让你在第一次运行后看到它们仍然存在,与您在第二次运行后看到它们的原因相同。

回去工作

此时,我放弃并尝试重新开始工作,我想我会解决的。

因此,此时您已经重写了 Git 存储库历史记录(两次!)并将其推送到 GitHub。但您的帐户并未提及您删除所有本地 回购副本,如 BFG 说明中所述:

“此时,您已经准备好让每个人都放弃旧的 repo 副本,对漂亮的新原始数据进行新的克隆。”

那么,您是否删除了工作机器上的旧 Git 存储库工作副本,并使用新的 Git 存储库历史记录重新克隆?您的旧仓库中的历史记录将与当时存在于 GitHub 中的“已清理”历史记录不同(即使“已清理”历史记录不像您那样“已清理”喜欢它!)。

我做了一些工作,尝试向上推,得到一个奇怪的合并冲突(你在提交时领先 50 和落后 50)。

如果您在 Git 存储库的旧本地副本中进行工作(而不是从 GitHub 重新克隆),那么这就是您所看到的。您实际上是在向 GitHub 推送 50 个旧的、肮脏的历史提交,而对于 Git,您似乎很高兴地没有意识到该分支上已经有 50 个完全不同的提交(对于 Git,它只关心这里的提交 ID)。 Git 认为你正在做的事情有点奇怪(“领先 50 和落后 50”)并试图告诉你。

让事情变得更糟......

什么?我尝试拉取和合并,突然间,我的 git 历史记录中的每一个提交都在名称上重复,其中一些只是空白。我检查了我的 Github 网络图,看起来从我的初始提交开始有第二个分支,它完全反映了我上次提交时压缩的所有提交

因此,通过拉取和合并,您已经将清理过的历史记录和肮脏的历史记录连接在一起,并通过合并提交将它们统一起来。在整理你的历史方面,这是一个坏主意。一个更好的主意是在清理过的历史记录的基础上重新构建你的新工作,推送它,删除你的旧工作存储库,然后进行新的克隆。

后果

当我现在尝试从头开始运行 BFG,重新克隆和镜像 repo 时,它告诉我其中没有凭据,尽管我可以在 Github 中看到它们。

这很奇怪,但是除了上面已经给出的“GitHub gc”解释之外,除了操作员错误之外,我真的没有任何解释。您可以与我共享存储库(如果您愿意),以便我可以执行更详细的检查,或者只是向我发送“.bfg-report”目录的压缩副本,以便我可以查看 BFG 在执行时捕获的诊断信息。

恢复

我真的需要一些帮助来了解发生了什么,以及如何(如果有的话)再次回到原来的状态。

我希望我已经设法解释了发生的一些事情。

在整理您的历史记录(即摆脱这两个重复的链)方面,您需要在添加该合并提交之前将您的 Git 历史记录重置回(清理)点。查看合并提交,并确定您喜欢哪个父历史记录。在您进行合并之前,该历史记录中的最后一次提交 (xxxx) 是什么?

git reset --hard master xxxx

这很可能会丢失您对旧的、肮脏的历史所做的最后一点工作。确定该提交 (yyyy),然后根据您的历史记录重新设置它,或者只是挑选它:

git cherry-pick yyyy

最后,使用“force”标志将恢复的历史记录推送到 GitHub:

git push origin master -f

...压缩您的旧仓库的存档,然后删除您的仓库的所有旧本地副本,以防止您进一步混淆。做一个新的克隆。

【讨论】:

非常感谢您的详细解释。我犯的错误是忘记删除我的本地副本,然后在我尝试继续工作和更新我的存储库时不小心错误警告。我最终只是把旧的扔掉了,然后把所有东西都放到了一个新的仓库中。因为我是这个项目的唯一贡献者,所以失去 Github 核仁巧克力饼积分比任何真正重要的东西都多。再次感谢您的时间和详细的解释,我期待在未来更仔细地使用 BFG(好名字!)! 另外,Github 上的垃圾收集可能是我仍然有凭据浮动的原因。我以前不知道它是如何完全工作的。谢谢! 不管怎样,恢复步骤对我有用。我有同样的问题。这将教会我阅读所有说明。 我有类似的情况,我用不同的字符串多次运行 replace-text。在这里张贴***.com/questions/35214238/… 然后我发现了这个。我正在考虑 git reset --hard master 到我的 fork 之前的最后一次提交,然后挑选我所有后来的提交。我收到消息“致命:无法使用路径进行硬重置。”

以上是关于无效 BFG 使用后 Git 合并重复的主要内容,如果未能解决你的问题,请参考以下文章

了解与 Git 合并的 Meld 3 方式 [重复]

Git合并提交[重复]

Git:将完整回购与另一个合并[重复]

在推入 Git 之前合并多个提交 [重复]

如何在 Git 中合并两个分支(主分支和演示分支)代码 [重复]

Git将多个分支合并到一个新分支中[重复]