我知道这个问题已经被问过了,但是在每一个答案中,我发现情况和我的略有不同,我不知道如何适应它。
所以问题就在这里:
我克隆了一个存储库,并添加了一个文件夹来使用它。在这个文件夹中,我添加了.csv文件和使用csv文件的.py文件。我试图推动这一点,但意识到它需要很长时间,因为2个csv文件非常大。所以我
git rm files
然后提交。我尝试再次推送,直到那时才意识到删除一个文件并不会将其从git历史中删除。//所以现在,从上次完成的推送开始,我有2次提交:1我添加了文件,1我删除了一些. csv。
我想请你帮忙删除最后两个提交。可行吗?谢谢
3条答案
按热度按时间zujrkrfu1#
我发现
git filter-branch
文档中的第一个例子非常适合您的上下文。假设您想从所有提交中删除一个文件(包含机密信息或版权侵犯):
(see文档页面上的详细信息,我没有复制粘贴整个事情在这里)
hs1ihplo2#
filter-branch,就像之前建议的那样,如果我们讨论的是billiig历史记录,就可以了。如果我们讨论的只是少数的修订版本,你可以通过修改你添加文件的修订版本,然后选择,或者交互式重定基来完成(删除文件)。
举个例子.....假设我在master~2上添加了文件a.txt。我不想再在历史记录上显示它。
git checkout master~2 git rm --cached a.txt git commit --amend --no-edit git cherry-pick master~2..master git branch -f master # point master in this revision git checkout master
应该够了。
rsl1atfo3#
......我想......删除最后2个提交,是否可行?
你不能完全删除提交,但是你可以很容易地告诉Git忘记它们。
最后,这个方法非常简单,我们首先注意到每个提交保存了一个快照,并且保存了它的 * 父 * 提交的哈希ID(沿着你的提交日志信息和你的作者名等等),这就形成了一个向后指向的提交链。
如果我们用一个大写字母代替提交哈希ID,我们可以画出这样的链:
注意,* 分支name*,在这里是
master
,存储了链中 last 提交的哈希ID(当某个东西存储了提交的哈希ID时,我们说它 * 指向 * 提交,因此有箭头,名称master
指向H
,H
指向G
,以此类推)。Git查找这些提交的方法是从
master
中读取H
的哈希ID,master
定位提交H
,然后读取提交H
并显示它。然后,在读取了H
之后,Git拥有了提交G
的哈希ID,所以Git可以读取G
并显示它,依此类推。当我们提交一个新的提交时,Git实际上是这样做的:
因此,如果我们有:
我们加上了
--I
:那么Git已经改变了 name
master
来存储提交I
的哈希ID。如果我们做了几次不想要的提交,我们可以告诉Git:* 重新设置名称
master
以指向提交H
,而不是提交J
。* 有多种方法可以实现这一点,但在本例中,第一种方法是git reset --hard
(虽然我们已经 checkout 了master
,并且确保你没有任何你担心丢失的东西,因为git reset --hard
告诉Git把所有东西都扔出去):后缀
~2
告诉Git倒计时两步--技术上讲,两个 * 第一个父 * 步,当我们的链中有合并提交时,这很重要,但在这里,我们没有,所以它不重要。如果master
当前指向J
,Git倒计时两次:J
到I
,然后I
到H
。Git用提交H
* 的内容替换我们的工作,* 使名称master
指向H
而不是J
:既然
J
很难"找到“,它”似乎“被删除了。这样做的缺点是,如果我们让自己的Git告诉其他Git:* 在这里,复制提交
I
和J
,* 其他Git拥有这两个提交,并会将它们重新引入到我们自己的Git中,即使我们的Git已经忘记了它们。但是如果我们从未成功地将这两个提交发送到其他任何地方,我们是唯一拥有它们的人,所以如果我们忘记了它们,它们就等于消失了。(If我们 * 已经 * 推了他们,我们可以拥有我们的Git,和 * 他们的Git,以及从那以后 * 每一个其他的Git*,* 都 * 忘记他们,然后 * 他们就会离开。但显然这很快就变得困难了。