gpt4 book ai didi

git - 如何追溯并完全删除添加到 .gitignore 的文件和文件夹的痕迹

转载 作者:行者123 更新时间:2023-12-01 15:07:39 25 4
gpt4 key购买 nike

请注意:我已阅读 this , this , this , 还有很多。
他们要么没有完全回答我的问题,要么我没有足够的经验从他们那里提取我的解决方案。

我错误地将敏感信息提交给了我的本地 git 存储库。现在,我已将相关文件和文件夹添加到 .gitignore。如何从 repo 中删除这些文件的所有痕迹?

我有一个庞大的项目,其中一些敏感信息保存在整个项目的不同文件夹中。出于无知,我没有将这些文件夹添加到 .gitignore。既然我已经这样做了,我如何确保所有这些文件都从 git 历史记录中完全删除?

如果有帮助的话,相关文件和文件夹遵循类似的模式。

自从我开始这个项目以来,我也做了很多提交。

我的 .gitignore 中的相关文件夹如下所示:

js/*/sensitiveData
python/*/sensitiveData

有没有办法在保留其余 git 历史记录的同时删除它们?

理想情况下,我会从 git 历史记录中删除我添加到 .gitignore 的所有这些文件夹/文件,同时将它们保留在我的本地磁盘上并保留我的 git 提交。

如果有任何帮助,我还没有任何 Remote 。一切都保存在我的本地磁盘上。

最佳答案

Remove sensitive files and their commits from Git history ,但是——这很重要——你的问题更简单 , 因为:

If it's of any help, I don't have any remotes, yet. Everything is kept on my local disk.



这确实非常有帮助。你要做的——你必须做的,无论你选择哪种方式——是“改写历史”。在 Git 中,历史只不过是 Git 存储库中的一组提交。每次提交都会保存每个文件的完整快照,1 加上一些元数据,如提交者(姓名和电子邮件)、时间(日期和时间戳)以及原因(日志消息)。元数据的一部分指定哪个提交是前一个提交:这次提交的直接历史记录。

历史只是意味着:从(所有)最后一次提交开始,并从每个点向后工作到其前一个(父)提交。就是这样 - 这就是它的全部,真的。但是,每个提交都被永远卡住:您不能更改它拥有的文件,也不能更改它标识的父提交。因此,要“更改历史记录”,您必须构建一个全新的历史记录,从具有您不希望它们拥有的文件的提交开始。从那时起,每个后代也必须更改:没有文件,和/或将没有文件的提交列为他们的直接历史记录。

在具有大量提交的大型存储库中,这往往等于:将每个提交复制到新的和改进的提交。然后你只需从使用旧提交切换到使用新提交。旧的无法找到,最终会被清理2并且确实消失了。同时,您只需携带所有内容的双份副本——由于 Git 存储文件的方式,这并不会真正占用太多额外空间。

接下来,虽然我从未真正使用过 The BFG,但我建议考虑 this answer到链接的问题。

最后,无论您使用来自 Remove sensitive files and their commits from Git history 的各种方法中的哪一种,我建议你这样做:
  • 复制您的存储库(有关复制方法,请参见下文)。
  • 将您选择的“重写历史”方法应用于副本。
  • 检查结果。好吗?如果是这样,请切换到使用副本。如果没有,请删除副本并从步骤 1 重新开始。

  • 如果您选择的方法是 git filter-branch ,实际上不需要步骤 1 中的副本。它只是让那些不熟悉 Git 的人更容易,因为如果您没有修改原始文件,只需删除尝试就可以感到非常安全。原件还在,完好无损。

    1显然,每次提交实际上只保存您与该提交一起保存的每个文件的完整副本。但这是您上次提交的所有文件,加上您添加的所有文件,减去您明确删除的所有文件。

    这不会使您的存储库几乎立即变得非常胖的原因是,某个先前提交中文件的卡住、压缩副本可以——并且正在——在使用相同数据的任何后续提交中重用。这是完全安全的,因为所有提交都一直被卡住。最多,提交本身可以被遗忘,然后最终被删除:如果它的某些文件仍在被其他提交使用,则文件数据仍然存在。文件数据只有在没有提交使用时才会消失。

    2“最终”基于对提交的 stash 引用(保存在每个存储库的引用日志中)和后台清理过程。背景清洁器仅在快速浏览时看起来有利可图时才会启动。您可以通过运行 git gc 强制清理。你自己。清洁工会找到所有引用——包括所有 stash 的引用——以查看需要保留哪些提交,以及这些文件使用哪些文件来保留提交。提交和文件以及其他不再需要的内部对象,并且至少有一些特定的年龄(默认情况下为 14 天),然后可以真正删除。

    复制存储库

    最简单的方法是使用您系统拥有的任何文件树复制器,复制整个工作树,包括 .git目录/文件夹:
    cd $HOME/src
    cp -r original copy

    例如。这对 Git 来说效果很好,尽管它还复制了技术上不属于存储库的任何随机内容。 注:如果您使用过 git worktree add ,它不会复制位于 original/ 之外的添加的工作树。区域,但我即将展示的其他技术也没有。

    另一种方法是利用这样一个事实,即存储库的每个克隆都是一个存储库。这里棘手的部分是克隆不会复制一些东西:
  • 默认情况下,原始存储库的任何远程跟踪名称都不会出现在克隆中。 Remote 都没有,所以复制这样的名字是没有意义的。你没有 Remote ,所以这无关紧要。
  • 默认情况下,新克隆将原始存储库作为其唯一的远程存储库。此 Remote 名为 origin .没关系,你可以删除这个origin以后如果你愿意。
  • 默认情况下,新克隆会重命名原始存储库中的所有分支。如果原始仓库有分支 B1 , B2 , B3 , 和 master , 新克隆有 origin/B1 , origin/B2 , origin/B3 , 和 origin/master作为其远程跟踪名称。

  • 远程跟踪名称只是 Git 的内存方式:我在其他 Git 上看到了这个分支!我上次看到它时,它说要使用 commit _____(根据这个 Git 从 origin Git 看到的内容填空)。

    所以,如果你这样做:
    git clone file://$HOME/src/original copy

    然后你的新副本在 ./copyfile://$HOME/src/original作为存储在其 origin 中的 URL ,并已从 original 重命名您的分支至 origin/*copy .

    克隆的最后一步是到 git checkout master ,以便副本现在拥有自己的 master ,但没有自己的 B1 , B2 , 和 B3 .因此,在副本中重写历史记录之前,您需要创建分支。

    您可以非常简单地手动执行此操作,只需运行:
    git checkout B1
    git checkout B2
    git checkout B3

    这些命令使用与 git clone 相同的机制用来制作 mastercopy基于 copyorigin/master那个 copy来自 origin (即原始存储库)。所以,现在,您的副本有五个分支,就像您的原件一样。

    (如果您有很多分支,并且需要经常执行此操作,则您需要编写脚本。但是如果您需要经常执行此操作,那么首先您就做错了。:-))

    关于git - 如何追溯并完全删除添加到 .gitignore 的文件和文件夹的痕迹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57383013/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com