从Git提交中删除文件

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

git commit -a 

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

我怎样才能删除最后一次提交的文件?

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

 git reset --soft HEAD^ 

要么

 git reset --soft HEAD~1 

然后重置不需要的文件,以使其不在提交之列:

 git reset HEAD path/to/unwanted_file 

现在再次提交,你甚至可以重复使用相同的提交信息:

 git commit -c ORIG_HEAD 

注意 ! 如果你只想从你以前的提交中删除一个文件,并保存在磁盘上 ,请阅读上面的juzzlin的答案 。

如果这是您最后一次提交,并且想要从本地和远程存储库中彻底删除文件 ,则可以:

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

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

而且要说哟,git命令中的rm正在做自己做的事!

现有的答案都是在讨论从上次提交中删除不需要的文件。

如果您想从提交(甚至是推送)中移除不需要的文件,并且不想创build新的提交(这是不必要的),因为该操作:

1。

find您希望文件符合的提交。

 git checkout <commit_id> <path_to_file> 

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

2。

 git commit -am "remove unwanted files" 

3。

find错误添加文件的提交的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 

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

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

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

要将文件返回到以前的状态:

  git checkout <commit_id> <path_to_file> 

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

  git checkout origin/master <path_to_file> 

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

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

 git reset --soft HEAD~1 

它将重置所有更改并恢复到一个提交

如果您推送了更改,请按照@CharlesB回答的步骤操作

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

正如接受的答案所示,您可以通过重置整个提交来完成此操作。 但这是一个相当严厉的做法。
一个更干净的方法是保持提交,并从中删除已更改的文件。

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

git reset将会把原来的文件保存下来,然后将它放在索引中。 工作目录中的文件是不变的。
然后git commit将提交并压缩到当前提交的索引。

这本质上取得了前一个提交中的文件版本,并将其添加到当前的提交中。 这导致没有净变化,所以文件被有效地从提交中删除。

以下内容将取消您想要的文件,这是OP所要求的。

 git reset HEAD^ /path/to/file 

你会看到如下的东西…

要提交的更改:(使用“git reset HEAD …”来取消)

修改:/ path / to / file

没有为commit提交的更改:(使用“git add …”更新将提交的内容)(使用“git checkout – …”放弃工作目录中的更改)

修改:/ path / to / file

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

在这一点上,你可以做任何你喜欢的文件,如重置为不同的版本。

当你准备好提交时:

 git commit --amend -a 

或者(如果您还有其他更改正在进行,您不想提交)

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

如果你想保留你的提交(也许你已经花了一些时间写一个详细的提交信息,不想失去它),你只想从提交中删除文件,但不是完全从存储库中删除:

 git checkout origin/<remote-branch> <filename> git commit --amend 

使用git GUI可以简化从先前的提交中删除文件。

假设这不是一个共享分支,你不介意重写历史 ,然后运行:

 git gui citool --amend 

您可以取消选中错误提交的文件,然后点击“提交”。

在这里输入图像描述

该文件从提交中删除,但将保存在磁盘上 。 因此,如果在错误地添加文件之后取消了对文件的检查,文件将显示在未跟踪的文件列表中(如果在错误地修改文件后未检查文件,它将显示在未更改的提交列表中)。

 git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file> git commit -m "removed unwanted file from git" 

将仍然留给你本地文件。 如果您不需要本地文件,则可以跳过–cached选项。

如果所有的工作都在你的本地分支上,那么你需要在稍后的提交中保存这个文件,并且想要一个清晰的历史logging,我认为一个简单的方法可以做到这一点:

 git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file> git commit --squash <commit_id> git add <file_to_remove_from_commit_<commit_id>_which_added_file> git commit -m "brand new file!" git rebase --interactive <commit_id>^ 

然后您可以轻松完成重新绑定,而无需记住更复杂的命令或提交消息或键入更多。

执行以下命令的一个序列:

 //to remove the last commit, but preserve changes git reset --soft HEAD~1 //to remove unneded file from the staging area git reset HEAD `<your file>` //finally make a new commit git commit -m 'Your message' 

只是想补充最重要的答案,因为我不得不运行一个额外的命令:

 git reset --soft HEAD^ git checkout origin/master <filepath> 

干杯!

我会用例子向你解释让A,B,C连续3次提交。 提交B包含一个不应该被提交的文件。

  • $ git log#take一个commmit_id
  • $ git rebase -i“A_ID”
  • 在rebase vim中将提交更改为'e'
  • $ git rm unwanted_file
  • $ git rebase继续
  • $ git push –force

一些为我工作,但仍然认为应该有一个更好的解决scheme:

 $ git revert <commit_id> $ git reset HEAD~1 --hard 

在其他提交中只保留要丢弃的更改,检查其他人

 $ git commit --amend // or stash and rebase to <commit_id> to amend changes 

其实我觉得更快更简单的方法就是使用git rebase交互模式。

 git rebase -i head~1 

(或者头〜4,你想走多远)

然后,而不是“挑选”,使用“编辑”。 我不知道“编辑”有多强大。

https://www.youtube.com/watch?v=2dQosJaLN18

希望你会发现它有帮助。

有同样的问题,我有一个本地分支的变化,我只想恢复一个文件。 对我有效的是 –

特性/ target_branch下面是我所有的变化,包括我想撤消特定文件)

origin / feature / target_branch是我想要将更改推送到的远程分支)

function/分期是我的临时分期分支,我将推动从我所需的所有更改,不包括对该文件的更改)

  1. 从我的origin / feature / target_branch创build一个本地分支 – 称之为function/分段

  2. 将我工作的本地分支feature / target_branch合并feature / staging分支

  3. 检出function/分期,然后git重置 – 软ORIG_HEAD (现在所有更改从function/舞台'将上演,但未提交。)

  4. 取消了我以前检查过的文件,并进行了不必要的更改

  5. 特征/分段的上游分支更改为origin / feature / target_branch

  6. 承诺其余的阶段性变化,并推到上游到我的远程origin / feature / target_branch

如果你还没有推送提交,GitHub桌面很容易解决这个问题:

  1. select存储库 – >撤消最近的提交
  2. 取消select您错误添加的文件。 你以前的提交信息已经在对话框中。
  3. 按提交button!

如果你不再需要这个文件,你可以做

 git rm file git commit --amend git push origin branch