从整个git历史记录中删除一个文件

从整个git历史记录中删除一个文件,git,commit,git-rm,Git,Commit,Git Rm,我知道这个问题已经被问过了,但在每一个答案中,我发现情况与我的略有不同,我不知道如何适应它 问题是: 我克隆了一个存储库,并在其中添加了一个文件夹。在这个文件夹中,我添加了.csv文件和使用csv文件的.py文件。 我试图推动这一点,但意识到它需要很长的时间,因为2个csv文件是非常大的。所以我 git rm files 然后提交。我再次尝试推送,直到那时才意识到删除文件并不能将其从git历史记录中删除// 现在,从上一次完成的推送中,我有两次提交:1次添加了文件,1次删除了一些.csv文件

我知道这个问题已经被问过了,但在每一个答案中,我发现情况与我的略有不同,我不知道如何适应它

问题是:

我克隆了一个存储库,并在其中添加了一个文件夹。在这个文件夹中,我添加了.csv文件和使用csv文件的.py文件。 我试图推动这一点,但意识到它需要很长的时间,因为2个csv文件是非常大的。所以我

git rm files
然后提交。我再次尝试推送,直到那时才意识到删除文件并不能将其从git历史记录中删除// 现在,从上一次完成的推送中,我有两次提交:1次添加了文件,1次删除了一些.csv文件

我希望您帮助删除最后2次提交。这可行吗?
谢谢

我发现git filter branch文档中的第一个示例非常适合您的上下文。看一看:

假设您要从所有提交中删除包含机密信息或侵犯版权的文件:


查看文档页面上的详细信息,我没有在这里复制粘贴整个内容

我发现git filter branch文档中的第一个示例非常适合您的上下文。看一看:

假设您要从所有提交中删除包含机密信息或侵犯版权的文件:


查看文档页面上的详细信息,我没有将整个内容复制粘贴到这里

过滤器分支,如果我们讨论的是biiiig历史,建议这样做。如果我们讨论的只是少数几个修订,那么您可以通过修改添加文件的修订并进行cherry pick,或者重新设置交互基础来删除文件

一个例子。。。。。假设我在master~2上添加了文件a.txt。我不想再把它写在历史上了

git签出主机~2 git rm-缓存的a.txt git提交-修改-无编辑 git cherry pick master~2..master git branch-此版本中的f主控点主控点 切换到主分支


这应该足够了。

如果我们讨论的是biiiig历史,那么正如我们所建议的那样,过滤器分支就可以了。如果我们讨论的只是少数几个修订,那么您可以通过修改添加文件的修订并进行cherry pick,或者重新设置交互基础来删除文件

一个例子。。。。。假设我在master~2上添加了文件a.txt。我不想再把它写在历史上了

git签出主机~2 git rm-缓存的a.txt git提交-修改-无编辑 git cherry pick master~2..master git branch-此版本中的f主控点主控点 切换到主分支

这应该足够了

。。。我想。。。删除最后2次提交。这可行吗

您不能完全删除提交,但可以很容易地告诉Git忘记它们

最终,这种方法非常简单。我们首先注意到,每次提交都会保存一个快照,并且还会存储其父提交的哈希ID、提交日志消息和作者姓名等。这形成了一个向后的提交链

如果我们让单个大写字母代表提交哈希ID,我们可以绘制以下链:

... <-F  <-G  <-H   <--master
我们还补充了-I:

然后Git更改了名称master以存储commit I的散列ID。最终我们有:

...--F--G--H--I--J   <-- master
~2后缀告诉Git技术上倒计时两个步骤,两个第一父级步骤,当我们的链中有一些合并提交时,这很重要,但在这里,我们不这样做,所以这并不重要。如果master当前指向J,那么Git会倒数两次:J到I,然后I到H。Git然后用commit H中的内容替换我们的工作,并使名称master指向H而不是J:

现在很难找到J,它似乎被删除了

这样做的缺点是,如果我们让我们的Git告诉其他Git:在这里,复制提交I和J,其他Git有两个提交,即使我们的Git忘记了它们,也会将它们重新引入我们自己的Git。但是,如果我们从未成功地将这两个承诺发送到其他任何地方,那么我们是唯一拥有它们的人,因此如果我们忘记了它们,它们就一去不返了

如果我们推了他们,我们可以拥有我们的Git,他们的Git,以及从那时起捡到他们的每一个Git,都忘记他们,然后他们就会消失。但显然,这很快就会变得困难

。。。我想。。。删除最后2次提交。这可行吗

您不能完全删除提交,但可以很容易地告诉Git忘记它们

最终,这种方法非常简单。我们首先注意到,每次提交都会保存一个快照,并且还会存储其父提交的哈希ID、提交日志消息和作者姓名等。这形成了一个向后的提交链

如果我们让单个大写字母代表提交哈希ID,我们可以绘制以下链:

... <-F  <-G  <-H   <--master
我们还补充了-I:

然后Git更改了名称master以存储commit I的散列ID。最终我们有:

...--F--G--H--I--J   <-- master
~2后缀告诉Git倒数两步 首先,两个第一父级步骤,当我们的链中有一些合并提交时,这很重要,但在这里,我们没有,所以这并不重要。如果master当前指向J,那么Git会倒数两次:J到I,然后I到H。Git然后用commit H中的内容替换我们的工作,并使名称master指向H而不是J:

现在很难找到J,它似乎被删除了

这样做的缺点是,如果我们让我们的Git告诉其他Git:在这里,复制提交I和J,其他Git有两个提交,即使我们的Git忘记了它们,也会将它们重新引入我们自己的Git。但是,如果我们从未成功地将这两个承诺发送到其他任何地方,那么我们是唯一拥有它们的人,因此如果我们忘记了它们,它们就一去不返了

如果我们推了他们,我们可以拥有我们的Git,他们的Git,以及从那时起捡到他们的每一个Git,都忘记他们,然后他们就会消失。但显然,这很快就会变得困难

...--F--G--H--I--J   <-- master
git checkout master
git reset --hard HEAD~2
             I--J
            /
...--F--G--H   <-- master