题 从Git提交中删除文件


我正在使用Git,我已经提交了几个文件

git commit -a

后来,我发现错误地将一个文件添加到了提交中。

如何从上次提交中删除文件?


1094
2017-09-18 16:59


起源


此链接非常适合您的问题: stackoverflow.com/questions/307828/... - b3h3m0th
@CharlesB:是的,这是我的最后一次提交 - Mojoy
你把提交推送到服务器? - Paritosh Singh
我只是用它来做: git reset filepath - felipekm


答案:


我认为这里的其他答案是错误的,因为这是一个将错误提交的文件从前一次提交移回暂存区域的问题,而不取消对它们所做的更改。这可以像Paritosh Singh建议的那样完成:

git reset --soft HEAD^ 

要么

git reset --soft HEAD~1

然后重置不需要的文件,以便将它们从提交中删除:

git reset HEAD path/to/unwanted_file

现在再次提交,您甚至可以重用相同的提交消息:

git commit -c ORIG_HEAD  

2104
2018-03-10 10:56



谢谢你。值得补充的是,如果你已经推动了之前的(错误)提交,现在尝试 git push 你修复你的回购,它会抱怨 Updates were rejected because the tip of your current branch is behind its remote counterpart.。如果你确定要推它们(例如它是你的叉子)那么你可以使用 -f 强制推动的选项,例如 git push origin master -f。 (不要对其他人提取的上游回购执行此操作) - andy magoon
git reset --soft HEAD^ 是我最常见的撤消操作 - funroll
@PabloFernandez,首先,接受的答案可能是OP正在寻找的东西(另外,它是几个月前发布的)。其次,无论票数多少,接受的答案总是排在最前面。 - MITjanitor
@PabloFernandez在所有答案的顶部是三个选项卡,允许您控制答案的顺序: 活性, 最老的 和 票。我的猜测是你的 最老的。切换到 票 即使接受的答案仍然是最重要的,这个答案将是第二个。 - ahsteele
我对此非常了解 git reset 但想要一种方法来影响现有的“就地”提交。我刚学会了 git commit -C。所以对我来说,我想要的是你的确切配方还有一步,再说一次“新提交” git commit -C [hash of original HEAD commit from first step]。 - metamatt


注意!如果您只想从之前的提交中删除文件,并且 把它放在磁盘上,读 juzzlin的回答 就在上面。

如果这是你最后一次提交而你想要的话 从本地和远程存储库中完全删除该文件, 您可以:

  1. 删除文件 git rm <file>
  2. 提交修改标志: git commit --amend

修正标志告诉git再次提交,但是“合并”(不是在合并两个分支的意义上)这个提交与最后一次提交。

正如评论中所述,使用 git rm 这就像使用 rm 命令本身!


218
2017-09-18 17:22



你也可以用 git rm --cached 将文件保存在磁盘上 - Arkadiy Kukarkin
向浏览此答案的人发出警告:确保要删除文件(如已经消失!),而不仅仅是从提交列表中删除它。 - Scott Biggs
添加其他人的说法(并且更容易记住不要这样做除非你真的想要): 该 rm 在里面 git 命令 是 做什么 rm 本身呢! - yo'
@CharlesB你能否将Arkadiy Kukarkin评论中的注释添加到你的答案中,以便让它更具可见性? - mopo922
请注意,如果您改变主意,之前的提交仍然可以恢复文件 git commit --amend 仍然在那里,可以找到例如 git reflog。所以它没有其他评论所暗示的那么糟糕。 - Steohan


现有的答案都在谈论从中删除不需要的文件 持续 承诺。

如果要从中删除不需要的文件  提交(甚至推送)并且不希望创建新的提交,这是不必要的,因为操作:

1。

找到您希望文件符合的提交。

git checkout <commit_id> <path_to_file>

如果要删除多个文件,可以多次执行此操作。

2。

git commit -am "remove unwanted files"

3。

找到提交的commit_id 错误地添加了文件,让我们说“35c23c2”

git rebase 35c23c2~1 -i  // notice: "~1" is necessary

此命令根据您的设置打开编辑器。默认的是vim。

将最后一次提交(应该是“删除不需要的文件”)移动到错误提交的下一行(在我们的例子中为“35c23c2”),并将命令设置为 fixup

pick 35c23c2 the first commit
fixup 0d78b28 remove unwanted files

保存文件后你应该很好。

完成 :

git push -f

如果您不幸遇到冲突,则必须手动解决。


107
2018-01-27 15:24



用nano做这件事真是太棒了! Ctrl + K,Ctrl + U,输入'f',Ctrl + X,放'y',瞧! - sequielo
如果你想从repo(而不是文件系统)中实际删除文件,而不是仅仅将它们恢复到以前的版本,那么不要执行步骤1 git rm --cached <file(s)>。 - waldyrious
等等你可以随意移动interactive-rebase文件的提交? - Dan Rosenstark
你完全可以,但你可能(或可能不会)发生冲突。 - Brian
通过添加可以使这个过程更容易一些 --fixup=35c23c2 到了 git commit 命令。这将自动设置提交作为所需提交的修正,因此您不需要在rebase中指定它。另外,如果你添加 --autosquash 到了 git rebase 命令,git会自动将你的提交移动到正确的位置,所以你不需要在交互式rebase中做任何事情 - 只需保存结果(这意味着你甚至不需要 -i 旗帜,虽然我喜欢用它来确保一切看起来像我期望的那样)。 - Guss


如接受的答案所示,您可以通过重置整个提交来完成此操作。但这是一个相当沉重的方法。
更简洁的方法是保持提交,只需从中删除更改的文件即可。

git reset HEAD^ -- path/to/file
git commit --amend --no-edit

git reset 将采用上一次提交中的文件,并将其放在索引中。工作目录中的文件不受影响。
git commit 然后将提交并压缩索引到当前提交。

这基本上采用了先前提交中的文件版本,并将其添加到当前提交中。这导致没有净更改,因此文件有效地从提交中删除。


62
2018-02-25 00:06



对于仅删除单个文件,这是一个更好的解决方案,而不会检修整个提交。 - nimish
这比接受的答案要好 - chet
这与答案完全相同:D stackoverflow.com/a/27340569/1623984 - ThatsAMorais
@ThatsAMorais确实:-)。我想知道这个问题是否与另一个问题合并,这就是为什么我没有看到它。或者也许我只是失明。无论哪种情况,我认为我倾向于将其留在基于投票的基础上,它似乎更受欢迎(也许人们更喜欢短而直接的答案)。 - Patrick
一定要离开吧! :)我们显然有正确的想法,目的是帮助。我认为合并是一个很好的理论。 - ThatsAMorais


如果您尚未在服务器上推送更改,则可以使用

git reset --soft HEAD~1

它将重置所有更改并恢复为一次提交

如果您已推送更改,请按照@CharlesB所述的步骤进行操作


35
2017-09-18 18:28



-1 git reset从暂存区域删除发生的更改文件,此处已提交更改 - CharlesB
@CharlesB sry,编辑了这些变化。 - Paritosh Singh
好的,但我会保留我的downvote,因为它不是OP想要的:)抱歉 - CharlesB
好吧,对我好,但为什么对手不想要这个。问题是什么? - Paritosh Singh
@Aris使用<git diff --cached>来查看更改 - Paritosh Singh


使用rm删除文件将删除它!

你总是在git中添加提交而不是删除,所以在这个实例中将文件返回到第一次提交之前的状态(如果文件是新的,这可能是删除'rm'操作)然后重新提交,文件将继续。

要将文件返回到某个先前的状态:

    git checkout <commit_id> <path_to_file>

或将其返回到远程HEAD的状态:

    git checkout origin/master <path_to_file>

然后修改提交,你应该发现文件已从列表中消失(并且没有从磁盘中删除!)


34
2018-01-28 14:00





git checkout HEAD~ path/to/file
git commit --amend

33
2017-08-23 19:01



这是修改最后一次提交的最佳方法,即未被推送的提交。这将重置一个文件中的更改,从上次提交中有效地删除该文件。 - Alex Bravo


以下将仅展示您想要的文件,这是OP所要求的。

git reset HEAD^ /path/to/file

你会看到类似下面的东西......

要提交的更改:(使用“git reset HEAD ...”取消暂停)

修改:/ path / to / file

未提交更改的更改:(使用“git add ...”进行更新   什么将被承诺)(使用“git checkout - ...”丢弃   工作目录的变化)

修改:/ path / to / file

  • “要提交的更改”是提交之前文件的先前版本。如果文件从不存在,这将看起来像删除。如果您提交此更改,则会有一个修订版本将更改恢复为分支中的文件。
  • “未提交的更改”是您提交的更改以及文件的当前状态

此时,您可以对文件执行任何操作,例如重置为其他版本。

当你准备提交时:

git commit --amend -a

或者(如果你还有其他一些你不想提交的修改)

git commit add /path/to/file
git commit --amend

28
2017-12-07 07:13



juzzlin的答案很棒,但是如果你只是想要取消它的话,那就太过分了整个提交。如果您当前对该提交中的文件进行了非暂停更改而不想丢失,则取消暂存整个提交可能会导致问题。 - ThatsAMorais