1. 概述

在 Git 中,我们的工作目录中可能包含多种状态的文件,比如已暂存(staged)、未暂存(unstaged)和未追踪(untracked)的文件。

本文将介绍如何安全地丢弃那些尚未加入暂存区(index)的改动内容。适用于清理本地开发过程中产生的临时修改或测试代码。


2. 分析工作目录状态

为了演示,我们假设已经 fork 并 clone 了某个 Git 仓库(比如:https://github.com/eugenp/tutorials),并对其部分文件进行了修改。

首先,我们查看当前工作目录的状态:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md
        modified:   gradle/maven-to-gradle/src/main/java/com/sample/javacode/DisplayTime.java

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        gradle/maven-to-gradle/src/main/java/com/sample/javacode/TimeZones.java

no changes added to commit (use "git add" and/or "git commit -a")

可以看到当前目录中有三类文件:

  • 已修改但未暂存的文件(README.md、DisplayTime.java)
  • 未追踪的新文件(TimeZones.java)

接下来我们先暂存其中一个已修改的 Java 文件:

$ git add gradle/maven-to-gradle/src/main/java/com/sample/javacode/DisplayTime.java
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   gradle/maven-to-gradle/src/main/java/com/sample/javacode/DisplayTime.java

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        gradle/maven-to-gradle/src/main/java/com/sample/javacode/TimeZones.java

现在目录中包含三种状态的文件:

已暂存(staged):DisplayTime.java
未暂存(unstaged):README.md
未追踪(untracked):TimeZones.java


3. 删除未追踪的文件

要删除未追踪的文件(如 TimeZones.java),可以使用 git clean 命令:

$ git clean -df

参数说明:

  • -d:同时删除未追踪的目录
  • -f:强制删除

执行后输出如下:

Removing gradle/maven-to-gradle/src/main/java/com/sample/javacode/TimeZones.java

再次查看状态,确认该文件已被移除:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   gradle/maven-to-gradle/src/main/java/com/sample/javacode/DisplayTime.java

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md

git clean -df 是清理未追踪文件的常用方式,但要小心使用,因为操作不可逆。


4. 删除未暂存的修改

现在只剩下未暂存的 README.md 和已暂存的 DisplayTime.java。

如果我们想丢弃未暂存的修改(即 README.md 的改动),可以使用以下命令:

$ git checkout -- .

⚠️ 注意:这个命令会丢弃当前工作目录中所有未暂存的修改,且无法恢复!

再次查看状态:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   gradle/maven-to-gradle/src/main/java/com/sample/javacode/DisplayTime.java

此时工作目录中只剩下已暂存的修改。

git checkout -- <file> 是丢弃单个文件未暂存修改的标准方式
git checkout -- . 会丢弃所有未暂存修改,慎用!


5. 总结

通过本文我们了解到:

  • Git 工作目录中的文件可以分为:已暂存、未暂存、未追踪三种状态
  • 使用 git clean -df 可以删除所有未追踪的文件
  • 使用 git checkout -- . 可以丢弃所有未暂存的修改

这两个命令组合使用,可以快速清理本地工作目录,非常适合在 rebase、merge 或切换分支前使用。


建议:操作前最好确认当前状态(使用 git status),避免误删重要改动
不要随意在多人协作分支上使用这些命令,容易导致协作混乱
⚠️ 这些操作不可逆,请务必确认无误后再执行


原始标题:How to Discard Unstaged Changes in Git