【问题标题】:How to remove user sensitive data from Github如何从 Github 中删除用户敏感数据
【发布时间】:2020-01-24 12:39:09
【问题描述】:

我正在发送 Github 文章 "Removing sensitive data from a repository" 以便从 Github 存储库中删除一些敏感数据,但我不知道如何将我在本地所做的所有更改“强制推送”到 Github,让我更好地解释一下:

  1. 我创建了一个测试存储库并提交了一些 fake sensitive data,这是一个名为 fake_sensitive_data.txt 的文件,位于项目的根目录中。
  2. 我开始 committing more files 到 repo
  3. 我创建了一个 commit to remove 来自 repo 的敏感数据
  4. 我将项目克隆到不同的文件夹中
  5. 在新克隆的文件夹中,我使用命令 bfg --delete-files fake_sensitive_data.txt 从 git 历史记录中删除了 fake_sensitive_data.txt

Using repo : git-test-removing-sensitive-data-clean/.git

Found 7 objects to protect
Found 3 tag-pointing refs : refs/tags/v1, refs/tags/v2, refs/tags/v3
Found 5 commit-pointing refs : HEAD, refs/heads/master, refs/remotes/origin/HEAD, ...

Protected commits
-----------------

These are your protected commits, and so their contents will NOT be altered:

* commit b8c88b09 (protected by 'HEAD')

Cleaning
--------

Found 11 commits
Cleaning commits:       100% (11/11)
Cleaning commits completed in 73 ms.

Updating 6 Refs
---------------

       Ref                                       Before     After   
       -------------------------------------------------------------
       refs/heads/master                       | b8c88b09 | 82104232
       refs/remotes/origin/lev/pr-to-stay-open | 2b131b17 | 0bcfb420
       refs/remotes/origin/master              | b8c88b09 | 82104232
       refs/tags/v1                            | c740754e | b8a33de1
       refs/tags/v2                            | 4abc08c8 | a0fdb11d
       refs/tags/v3                            | a448a05e | 4c4176a7

Updating references:    100% (6/6)
...Ref update completed in 18 ms.

Commit Tree-Dirt History
------------------------

       Earliest      Latest
       |                  |
       . D D D DD D D D m m

       D = dirty commits (file tree fixed)
       m = modified commits (commit message or parents changed)
       . = clean commits (no changes to file tree)

                               Before     After   
       -------------------------------------------
       First modified commit | 0cd750f6 | dedd68e8
       Last dirty commit     | 2b131b17 | 0bcfb420

Deleted files
-------------

       Filename                  Git id          
       ------------------------------------------
       fake_sensitive_data.txt | cc86c97f (199 B)


In total, 18 object ids were changed. Full details are logged here:

       git-test-removing-sensitive-data-clean.bfg-report/2020-01-24/09-22-19

BFG run is complete! When ready, run: git reflog expire --expire=now --all && git gc --prune=now --aggressive
  1. 清理完成后,我使用以下命令将内容强制推送到 Github:git push origin --force --all && git push origin --force --tags

所以这些是我为了从我的仓库中清除文件 fake_sensitive_data.txt 所遵循的步骤,现在是我面临的问题:

  1. 文件仍保留在ACTIVE 分支中。
  2. 文件仍保留在来自已删除分支的COMMITSnever merged
  3. 该文件仍保留在已合并到 master 的 PRs 中。

所以我的问题是,如何从所有分支、提交、PR、标签(任何东西)中删除文件和历史并将其推送到 Github?

【问题讨论】:

    标签: git github version-control


    【解决方案1】:

    TL;DR

    你必须让 GitHub 来做你需要的事情。即使这样,如果提交已被复制到其他地方的其他存储库,那么您必须让所有这些 other 副本(以及拥有它们的人)也更新 他们的 副本.

    实际上没有任何东西可以从包含该文件的提交中删除该文件。没有什么可以改变任何现有的提交,永远。一旦提交,它实际上是一成不变的,或者永远冻结。

    BFG 和 git filter-branch 所做的是通过 复制 具有文件的提交到没有文件的新提交来制作 新的和改进的 提交。吨。 (在这种情况下,新提交没有文件 的事实是改进。)

    到目前为止,这很简单。旧的提交仍然存在,现在新的提交也在那里。但是您希望旧的消失。这就是一切出错的地方。这也是事情变得有点复杂的地方。

    此时你应该问的问题是:

    • Git 首先如何找到提交?
    • 就此而言,任何人如何找到提交?提交的真实名称是什么?

    上面有四个链接,其中一个是https://github.com/luivilella/git-test-removing-sensitive-data/tree/124e5707bf29a24cfb4167c869250fd919c42446。我将在此处显示完整的 URL。注意末尾很长的随机十六进制数字字符串124e5707bf29a24cfb4167c869250fd919c42446。这是提交的哈希 ID。它

    这是提交的真实名称。 是拥有提交的人每次都能可靠地找到它的方式。你只需要记住124eblahblah(硬)或者写在某个地方然后剪切粘贴(简单)然后运行git checkout <em>hash-id</em>,你就可以把它拿出来并准备好使用了。

    现在,每个存储库(包括某个原始存储库的每个克隆)都在其中每个提交了它曾经拾取的,减去任何它被丢弃的提交。请注意,BFG 以运行建议结束其会话:

    git reflog expire --expire=now --all && git gc --prune=now --aggressive
    

    git gc 命令是 Git 的 Grim Reaper 垃圾收集器。它是管家程序,或者更准确地说,是各个管家程序的主管,他们四处寻找提交和其他没人能找到的 Git 对象。如果您无法找到该对象——如果它的哈希 ID 没有写在 Git 可以看到的任何地方——那么,你显然不在乎 Grim Collector 是否将其完全擦除。

    所以现在我们要问:

    • 可以在哪里写下这些哈希 ID,以便 Git 可以看到它们?

    对于 Git 本身,答案主要是:在其他提交中。每个提交都可以列出一些其他提交的哈希 ID。如果带有哈希 H 的提交列出了提交哈希 ID G,那么任何可以找到 H 的人都可以使用它来找到 G。如果哈希 ID 为 G 的提交列出了提交 F 的哈希 ID,那么任何具有 HG 的人> 可以找到F

    如果要绘制它,请绘制一个带有一些箭头的提交。这些是提交中的父提交哈希 ID。大多数提交都只有一个。合并提交有两个,它们的两个父级。1这些箭头总是指向向后,指向某个先前的提交。因此,如果您只能找到 last 次提交,则可以找到 每个 次提交。

    这就是分支名称 (master)、标签名称 (v1.2) 和远程跟踪名称 (origin/master) 之类的地方。Git 为您提供了这些命名设备来查找一个特定的commit.2 有了分支名称,这就是我们应该说是分支的一部分的 last 提交。对于任何其他名称,这只是一些哈希 ID,例如,标签可以将特定提交标记为“使用此提交访问版本 1.2”。

    这些名称统称为 refsreferences。当 BFG 说:

    更新 6 条参考文献

    这就是它所说的。 BFG 复制一些特定的原始提交到新的和改进的提交。然后,在复制了这些之后,它还必须复制所有 subsequent 提交,要么也改进它们(因为它们有你想要的文件),要么只是因为旧的拥有一些 的哈希 ID em>other 现在已经改进的旧的和坏的提交。

    一旦 BFG 复制并改进了所有需要改进的内容,并复制了由于复制和改进而必须复制的所有其他内容,BFG 就会进入并更改每个 ref em> 适当。

    但是 BFG 只能更改 your 存储库中的 refs。 存在的每个 Git 存储库都有自己的 refs。 所有 Gits share 提交(通过复制),但它们不一定共享所有 refs。

    在更新了您自己的存储库的 refs 之后,BFG 现在建议您清除 Git 的 reflogs,其中保存了 ref 哈希 ID 的日志(当然还有 Git可以看到所有这些,所以那些保留旧的提交)。这就是git reflog expire 命令。 --expire=now 部分说不要将条目保留 30 或 90 天:现在全部删除。 然后,BFG 建议您运行内务管理 git gc 程序。 --prune=now 删除了 Git 使用的标准 14 天宽限期,以便后台 git gc 操作不会删除其他 Git 命令正在制作的对象/em>.3

    因此,在此步骤之后,您的 存储库不再有“错误”提交。如果你尝试git checkout <em>hash</em>,你的 Git 会说:我的对象数据库中似乎没有那个哈希 ID。 它不见了!一切都很好。

    但那是 你的 Git 存储库。所以现在你使用git push origin --force:这会让你的 Git 调用另一个 Git——GitHub 上的那个——并为他们提供他们需要的任何新对象(提交和内部对象),例如 BFG 的新的和改进的对象制作。然后你的 Git 发送强制命令:对于分支名称master,设置该分支名称以记住提交 X!对于标签名称v1.2,将该标签名称设置为记住提交Q等等。

    如果他们服从(如果你有正确的权限他们会服从),现在 GitHub 的 Git 只能通过这些名称找到这些提交。这些提交可以找到更早的提交,依此类推。 但是 GitHub 的Git 没有 删除 其他提交。当他们的 Git 开始运行git gc 时,他们会这样做,无论何时。此外,他们可能拥有从未告诉过您的参考名称。

    您在这里提到的是拉取请求。 GitHub 通过设置特殊的 GitHub 专用名称 refs/pull/* 来实现拉取请求。他们根据使 GitHub 工作的所有规则,在适当的时候将这些名称复制到其他 GitHub 端存储库中。但他们不允许设置或删除它们。另见Delete a closed pull request from GitHub

    所以:您必须联系 GitHub 支持并让 他们 删除任何使“坏”提交保持活动状态的 PR。您必须让他们强制他们的 Git 运行适当的 git gc 以在默认维护窗口过去之前放弃提交。只有这样,引用这些 PR 或通过哈希 ID 提交的 URL 才会停止工作。当然,您必须记住,任何可以克隆或访问您的 GitHub 存储库的人现在可能已经将这些提交复制到他们自己的 存储库,并且可能拥有您的数据:这是获取 他们放弃就是去找他们,不管他们是谁。


    1某些合并提交(Git 称为 octopus 合并)可以有两个以上的父级。箭头仍然必须指向后方。

    2标签名称可以直接指向其他 Git 内部对象,例如 treesblob。树是 Git 如何存储与提交相关的文件的名称,而 blob 是 Git 如何存储文件的内容——每个文件的数据。标记名称也可以指向 Git 的最后一个内部对象类型,即 带注释的标记 对象。带注释的标记对象包含一些先前存在的对象的哈希 ID,当然还有注释。

    3当 Git 构建 new 提交或其他数据时,此宽限期大大简化了它的构建方式。 Git 可以左右创建对象,获得目前只有一个程序拥有的新哈希 ID:没有一个被保存在任何地方,也找不到这些对象。然后,最后,当一切准备就绪时,对象创建者将最重要的哈希 ID(例如,分支中的 last 提交的那个 ID)写入某个 ref。现在对象都可以找到了,整个过程就完成了。

    如果出现问题——Git 发现由于某种原因无法进行某些提交,例如——对象——创建程序可以简单地立即退出。它创建的任何未使用的对象都将在宽限期内闲置,然后下一次运行 git gc,无论何时——Git 会自动为你运行它,这样你就不需要考虑它——会找到并删除剩余的垃圾。

    【讨论】:

      猜你喜欢
      • 2019-01-12
      • 1970-01-01
      • 2020-05-08
      • 2013-12-24
      • 1970-01-01
      • 2015-09-11
      • 1970-01-01
      • 2011-08-22
      相关资源
      最近更新 更多