无效BFG使用后Git合并重复

时间:2014-07-02 23:13:10

标签: git github merge git-rewrite-history bfg-repo-cleaner

我已经被整个存储库深深地淹没了(仅由我使用)并且可以使用一些帮助来整理它。

这就是我所做的。我意识到在我的提交历史中,有一些文件包含我不想放置的凭据。因此,我决定合法并尝试使用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

根据终端日志,它更新了回购。到目前为止一切都那么好吧?我弹出我的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,以某种方式复制了我的回购中所有提交的半成品版本,无法解开,并且为了加重侮辱伤害,BFG什么也没做,并声称它已经完成了它的工作。

1 个答案:

答案 0 :(得分:18)

我是BFG的作者,我会尝试根据您的帐户逐步描述我的想法:

BFG前手动清洁......

首先你:

  

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

您对此行为的描述省略了两个基本步骤:

  1. 手动删除当前文件树中的凭据,并将更改提交到您的仓库。如果您没有这样做,那么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时看到了那条消息吗?

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

  3. 如果您没有执行这些操作,则会导致您的凭据无法从存储库中完全清除。

    第一次运行BFG ......

    继续,然后你:

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

    ......此时:

      

    根据终端日志,它更新了回购。到目前为止一切都那么好吧?我弹出我的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说明中的说明,您的帐户没有提及您删除回购的所有本地副本:

    "此时,您已准备好让所有人放弃他们旧的回购副本,并为新的原始数据做新的克隆。"

    那么,您是否在工作机器上删除了旧的Git仓库工作副本,并使用新的Git存储库历史记录重新克隆?旧回购中的历史记录与“已清理”的历史记录不同。 GitHub当时会出现的历史(即使清理过的历史记录并没有像您希望的那样清理过#!)。

      

    我做了一些工作,试图推高,得到一个奇怪的合并冲突(你提前50个,提交50个)。

    如果您在Git仓库的旧本地副本中进行工作(而不是从GitHub重新克隆),那么您就会看到这一点。你本质上是向GitHub推送50个旧的,脏的历史提交,而对于Git,你似乎幸福地没有意识到已经有50个完全不同的(对于Git,这里只关心commit-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
    

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