Git 删除未提交的更改

本文将指导你如何撤消我们对本地仓库所做的未提交更改。

使用功能时,我们可能首先创建新文件,向现有文件添加更改,然后删除一些文件。最终,我们意识到这一切都错了,需要回到之前的提交。我们应该做什么?

$ echo 'Add new implementation' > feature.txt
$ echo 'Enhance exising feature' >> file.txt
$ git add file.txt
$ rm deprecated_feature.txt
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   file.txt
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	deleted:    deprecated_feature.txt
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	feature.txt

我们有几种方法来完成它。

使用 git checkout 删除 Git 中未提交的更改

此命令将恢复跟踪文件的未提交更改。被跟踪的文件是 git 知道的文件,通常是在被 git add 添加之后

$ git checkout .
Updated 2 paths from the index
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	feature.txt
nothing added to commit but untracked files present (use "git add" to track)

请注意,如果文件已经通过 git add 添加到暂存区,git checkout 将不起作用。

$ echo 'Enhance exising feature' >> file.txt
$ git add file.txt
$ git checkout file.txt
Updated 0 paths from the index
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   file.txt
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	feature.txt

在上面的示例中,对 file.txt 的更改不会恢复,因为该文件位于暂存区域中。

使用 git reset 删除 Git 中未提交的更改

要删除暂存区中未提交的更改,我们需要采取以下步骤。

  1. 使用 git reset 从暂存区取消暂存文件。
  2. 使用 git checkout 撤消更改。
$ git reset file.txt
Unstaged changes after reset:
M	file.txt
$ git checkout file.txt
Updated 1 path from the index
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	feature.txt
nothing added to commit but untracked files present (use "git add" to track)

使用 git reset 删除未提交更改的另一种方法是使用选项 --hard 和参数 HEAD

$ git reset --hard HEAD
HEAD is now at 1e087f5 Make some change to file.txt
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	feature.txt
nothing added to commit but untracked files present (use "git add" to track)
  • --hard 选项指定 Git 抛出当前状态和最后一个参数中的提交之间的所有更改。出于这个原因,这个命令被认为是危险的,应该在你运行 git status 检查工作文件后使用。
  • 最新提交的 HEAD 别名。

使用 git stashgit stash 删除 Git 中未提交的更改

git checkoutgit reset 的缺点是它们无法删除未跟踪的文件。feature.txt 在执行这些命令后仍然存在。

考虑第一个例子。

$ echo 'Add new implementation' > feature.txt
$ echo 'Enhance exising feature' >> file.txt
$ git add file.txt
$ rm deprecated_feature.txt
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   file.txt
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	deleted:    deprecated_feature.txt
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	feature.txt

删除所有未提交的更改,包括暂存文件、已跟踪但未暂存和未跟踪文件。我们将使用巧妙的方法 git stash

git stash 允许我们保存更改,但不需要 git commit;它充当未提交文件的临时存储。

在向临时存储添加更改后,我们将告诉 Git 删除这些存储。因此,所有未提交的更改都将消失。

$ git add .
$ git stash
Saved working directory and index state WIP on main: 16b9767 deprecated_feature.txt
$ git stash drop
Dropped refs/stash@{0} (aebeb2cbdcec917331f5793ef1238f5a525d29ec)
$ git status
On branch main
nothing to commit, working tree clean

总之,我们有几种方法可以删除未提交的更改:

  1. git checkout 仅在文件不在暂存区时有用。
  2. git reset 对暂存区中的更改很有用,但不能删除未跟踪文件的更改,需要与 git checkout 结合使用。
  3. git reset --hard HEAD 可能比上面的短,但有潜在的危险。
  4. git stashgit add . 可以删除所有内容,包括未跟踪的文件。