1

我试图从我的历史记录中删除包含秘密 API 令牌和一些端点的文件中的几行,这些端点作为环境变量传递比在那里硬编码要好得多,所以如果我有一天将回购公开,他们将不会在那里轻率的眼睛。

为此,我使用了 BFG 存储库清理器这个很棒的工具,我过去也使用它从我的 git 历史记录中删除整个残留和敏感文件。这次按照说明替换文本:

$ java -jar ~/bfg.jar --replace-text tokens.txt myRepo.git

但在输出中,出现了:

...
* commit 10134503 (protected by 'HEAD') - contains 1 dirty file :
- app.py (640 B)
...
If you *really* want this content gone, make a manual commit that removes it,
and then run the BFG on a fresh copy of your repo.

所以我就这么做了,克隆了整个东西,提交了替换我想要os.environ[]在 python 上调用 2 次的两行并推送它。然后我再次运行 BFG,git reflog一切似乎都像一个魅力。

我检查了 gitlab 的提交浏览器,文本***REMOVED***到处都是,但在倒数第二个提交中,发生了这种情况:

图像

我猜它的发生是因为文件在下一次提交中被编辑(现在是受“HEAD”保护的那个),GIT 需要这些令牌来重新创建我所做的更改以摆脱这 2 行。但是,我该如何实现呢?

4

1 回答 1

2

重写 Git 历史是一项棘手的工作,用户很容易犯一些模糊不清的错误,从而否定他们正在尝试做的事情。作为 BFG 的作者,我花了很多时间评估 用户 报告,试图弄清楚为什么会发生奇怪的事情。BFG 只是清理 repo 过程中的中间步骤,在之前和之后的步骤中有足够的用户错误空间 - BFG 本身实际上存在错误是相当罕见的*

因此,如果我正确理解了您的描述,您的提交历史现在看起来像这样(最旧的在前,最新的在后):

  • ...cleaned commits containing ***REMOVED*** where the credentials used to be
  • a penultimate commit where the unwanted credentials *are* present
  • the 'manual' cleaning commit where you instead read credentials from os.environ[]

让我们看看你的动作:

所以我就这么做了,克隆了整个东西,提交了替换我想要的两行代码,以便在 python 上对 os.environ[] 进行 2 次调用并推送它。[X]然后我再次运行 BFG,git reflog,一切似乎都像一个魅力。[是]

问题是,您在X的 GitLab 中的提交历史将正是您在 GitLab 中报告的最终提交历史。所以在XY之间,GitLab 没有任何变化。

所以,两种可能的解释:

  • BFG 中有一个错误(正如@torek 建议的那样) - 我很想看到一个简单的测试用例来证明这一点
  • Y的决赛没有发生或失败,例如因为git push没有使用。--force

如果您可以尝试在您的 repo 的新镜像克隆上再次运行 BFG,我们可能会消除其中一个选项。

最后:

我猜它的发生是因为该文件在下一次提交中被编辑(现在受“HEAD”保护的那个)并且 GIT 需要这些令牌来重新创建我所做的更改以摆脱这 2 行。

Git 将提交存储为每次提交时文件树的完整快照,它不会将它们存储为您可能认为它会使用的差异。所以不用担心,Git不需要那些旧凭据来创建最终的手工提交(凭据是从os.environ[]).

顺便说一句,BFG 是根据用户行为的“改革后酗酒”模型设计的——只有在你意识到自己有问题并清理自己之后,你才应该运行 BFG——所以确保你的存储库中的最新提交在运行 BFG 之前是干净的。

* 肯定有条件使 BFG 因致命异常而死亡,但我不知道 BFG 实际完成运行并表现超出规格的地方的错误。

于 2016-11-07T22:05:27.930 回答