[git] 如何丢弃对一个文件的改动?

背景

当我们进行日常开发时,有时候需要丢弃对一个文件的改动。为了便于描述,我们假设这个文件是 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt。会有两种情况 ⬇️

  • 仅丢弃 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 尚未暂存 的改动
  • 丢弃 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 已暂存 的改动 + 尚未暂存 的改动

本文会对这两种情况分别进行介绍

要点

仅丢弃尚未暂存的改动

执行以下两个命令中的 任何一个 都可以丢弃 尚未暂存 的改动

bash 复制代码
git restore <file>
## 或者
git checkout <file>

注意事项

  • 执行命令时,需要将 <file> 替换为您想指定的文件(例如 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt)
  • 如果您是第一次使用它们,请不要用重要的项目来进行试验,以防误操作(尚未暂存 的改动被丢弃之后就找不回来了)

丢弃 已暂存 的改动 + 尚未暂存 的改动

执行以下两个命令中的 任何一个 都可以丢弃 已暂存 的改动 + 尚未暂存 的改动

bash 复制代码
git restore --staged --worktree <file>
## 或者
git checkout HEAD <file>

注意事项

  • 执行命令时,需要将 <file> 替换为您想指定的文件(例如 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt)
  • 如果您是第一次使用它们,请不要用重要的项目来进行试验,以防误操作(已暂存/尚未暂存 的改动被丢弃之后就找不回来了)

正文

示例

准备工作

请将以下代码保存为 main.sh (具体的名称并不重要)

bash 复制代码
## Prepare a temp dir for our test
mkdir temp
cd temp

## Prepare for the initial commit
git init
echo "Content commited" >> f.txt
git add f.txt
git commit -m "initial commit"

## Stage some content in f.txt
echo "Staged content in f.txt" >> f.txt
git add f.txt

## Add some content to be staged in f.txt
echo "Content to be staged ..." >> f.txt

通过执行下方的命令就可以运行 main.sh ⬇️

bash 复制代码
bash main.sh

运行完 main.sh 之后,当前目录中会多出一个 temp 目录。在当前目录执行 tree temp 命令后,应该可以看到如下的内容

text 复制代码
temp
└── f.txt

1 directory, 1 file

通过执行如下命令,可以切换到 temp 目录中 ⬇️

bash 复制代码
cd temp

temp 目录中,我们执行如下命令就可以看到 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 的状态

bash 复制代码
git status

执行该命令后,可以看到 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 中既有 已暂存 的改动(如下图绿色框所示),也有 尚未暂存 的改动(如下图红色框所示)

各个状态的 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 的内容列举如下 ⬇️

内容
已 <math xmlns="http://www.w3.org/1998/Math/MathML"> commit \text{commit} </math>commit 的 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt Content commited
已暂存的 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt Content commited Staged content in f.txt
当前的 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt Content commited Staged content in f.txt Content to be staged ...

如果我们想让 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 变回下图红框里的这个样子,那么只需要丢弃 尚未暂存 的改动

如果我们想让 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 变回下图绿框里的这个样子,那么需要丢弃 已暂存 的改动 + 尚未暂存 的改动

我们分别来看

情形一:仅丢弃尚未暂存的改动

请注意:尚未暂存 的改动被丢弃之后就找不回来了

第一种方式:基于 <math xmlns="http://www.w3.org/1998/Math/MathML"> git restore \text{git restore} </math>git restore 命令

我们可以用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git restore \text{git restore} </math>git restore 命令来丢弃 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 中尚未暂存的改动 ⬇️

bash 复制代码
git restore f.txt

执行该命令后,我们再用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git status \text{git status} </math>git status 命令和 <math xmlns="http://www.w3.org/1998/Math/MathML"> cat f.txt \text{cat f.txt} </math>cat f.txt 命令验证一下 ⬇️

从红色框的内容可以看出, <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 的变化符合预期。

第二种方式:基于 <math xmlns="http://www.w3.org/1998/Math/MathML"> git checkout \text{git checkout} </math>git checkout 命令

我们也可以用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git checkout \text{git checkout} </math>git checkout 命令来丢弃 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 中尚未暂存的改动 ⬇️

bash 复制代码
git checkout f.txt

执行该命令后,可以再用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git status \text{git status} </math>git status 命令和 <math xmlns="http://www.w3.org/1998/Math/MathML"> cat f.txt \text{cat f.txt} </math>cat f.txt 命令验证一下 ⬇️

从红色框的内容可以看出, <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 的变化符合预期。

情形二:丢弃 已暂存 与 尚未暂存 的改动

请注意:已暂存/尚未暂存 的改动被丢弃之后就找不回来了

第一种方式:基于 <math xmlns="http://www.w3.org/1998/Math/MathML"> git restore \text{git restore} </math>git restore 命令

我们可以用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git restore \text{git restore} </math>git restore 命令来丢弃 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 中 已暂存 的改动 + 尚未暂存 的改动 ⬇️

bash 复制代码
git restore --staged --worktree f.txt

执行该命令后,我们再用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git status \text{git status} </math>git status 命令和 <math xmlns="http://www.w3.org/1998/Math/MathML"> cat f.txt \text{cat f.txt} </math>cat f.txt 命令验证一下 ⬇️

从红色框的内容可以看出, <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 的变化符合预期。

第二种方式:基于 <math xmlns="http://www.w3.org/1998/Math/MathML"> git checkout \text{git checkout} </math>git checkout 命令

我们也可以用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git checkout \text{git checkout} </math>git checkout 命令来丢弃 <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 中 已暂存 的改动 + 尚未暂存 的改动 ⬇️

bash 复制代码
git checkout HEAD f.txt

执行该命令后,我们再用 <math xmlns="http://www.w3.org/1998/Math/MathML"> git status \text{git status} </math>git status 命令和 <math xmlns="http://www.w3.org/1998/Math/MathML"> cat f.txt \text{cat f.txt} </math>cat f.txt 命令验证一下 ⬇️

从红色框的内容可以看出, <math xmlns="http://www.w3.org/1998/Math/MathML"> f.txt \text{f.txt} </math>f.txt 的变化符合预期。

参考资料

Git Cheat Sheet 中的以下内容

相关推荐
来尔君20 小时前
Git Bash 提示符简化(就是每次敲命令时上面显示的那一行信息)
git·命令行
AskHarries20 小时前
为什么大多数人创业第一步就错了
人工智能·后端
tyung20 小时前
Go 手写二叉堆优先队列:避开 container/heap 的性能陷阱
数据结构·后端·go
Nirvana在掘金20 小时前
MySQL 事务隔离级别 锁 高并发场景优化经验
后端·mysql
李小狼lee20 小时前
《spring如此简单》第二节--IOC思想的实现,容器是什么
后端·面试
GetcharZp20 小时前
深入浅出 etcd:从 K8s 灵魂到 Golang 实战,分布式系统的“定海神针”!
后端
我叫张小白。20 小时前
PyCharm 集成 Git 与 Gitee
git·pycharm·gitee
小雨青年20 小时前
Git Bisect 实战:用二分法快速找到引入 Bug 的提交
git·bug
hikktn21 小时前
企业级Spring Boot应用管理:从零打造生产级启动脚本
java·spring boot·后端
SimonKing21 小时前
别再死磕 Elasticsearch 了,这个轻量级搜索引擎更香
java·后端·程序员