从git消息中完全删除敏感信息

时间:2017-12-06 03:44:55

标签: git

我不小心在git commit消息中包含了一些敏感信息。实际的文件都很好 - 它只是消息本身的内容需要回滚。

如何清除邮件,使其无法 ,包括git reflog历史记录?

1 个答案:

答案 0 :(得分:3)

TL; DR

进行替换提交,然后手动删除或清除不需要的reflog条目(其中有两个)。然后,您可以根据需要运行git gc,并使用git show hash-id查看是否将其丢弃。它可能不会 - 它仍然可以通过哈希ID访问长达14天。有关详细信息和其他选项,请参阅下文。

描述

您无法更改现有提交。

可以进行新的提交,就像现有提交一样,除了_____(填空)。

git commit有一个方便的Git内置选项,用于完成最近的提交:

git commit --amend

默认情况下,这会占用索引中的任何内容 - 如果您刚刚进行了一个您后悔的提交,可能仍然匹配您刚刚提交的提交 - 并从中进行新的提交。但是,它不使用当前提交作为新提交的父级,而是使用当前提交的父级作为新提交的父级。它还会在编辑器上显示当前提交的消息,让您重写消息。

结果是新提交。与往常一样,git commit命令使当前分支名称​​指向刚刚进行的新提交。但是新提交的要点不是回到上一个提示,而是回到那个小费的父母那里。实际上,您之前提交的提交是"推到一边":

...--o--o--X   <-- branch    # where X is the bad commit

变为:

          X   [abandoned]
         /
...--o--o--N   <-- branch

现在,问题在于,尽管被放弃了,旧提交仍然存在于您的存储库中一段时间​​。 可以找到它的任何名称,足以找到它。这包括reflog条目可以到达提交的任何其他分支和标记名称。

由于您刚刚提交了提交,因此可能没有其他名称。这意味着只有reflog条目:一个用于HEAD,一个用于名为branch的分支。

清除reflog条目的最简单方式也是最危险的(或者,第二大):您可以运行git reflog expire --expire-unreachable=now --all。这会丢弃从相关引用的提示无法访问的所有reflog条目,而不会查看它们的年龄。

最佳方式可能是删除这两个特定的reflog条目,即HEAD@{1}branch@{1},其中 branch 是当前的分支。您可以运行git reflog delete HEAD@{1}来删除插槽1中的HEAD条目,对于当前分支的插槽1条目也是如此。 (您可能需要{1}左右的引号或类似内容来保护它免受shell攻击,具体取决于你的shell。)

此时应该提交 no 名称。它不会显示在git log中,甚至不会显示在git reflog中。但是,可以运行git fsck --unreachablegit fsck --lost-found来查找无法访问的对象,或者如果您知道其原始哈希ID,则git show hash-id可以查看它。

Git通常会将无法访问的对象放置至少14天,以防他们在施工期间仅暂时无法访问。经过14天后,他们可能仍然不需要尚未完成运行的Git命令,因此它们会被git gc删除。如果您确定仍然没有正在运行的Git命令,这些命令正在构建尚未完成但尚未显示的内容,您可以通过运行{{{{{{ 1}}。

如果对象已经打包到受保护的(git gc --prune=all)包中,有些情况甚至不够,但这不适用于您的情况。在任何情况下,首先要付出这么大的努力通常是没有意义的 - 如果它没有出现在.keep中,大多数人再也看不到了。