慣性聚合 高效追蹤和閱讀你感興趣的部落格、新聞、科技資訊
閱讀原文 在慣性聚合中打開

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

阮一峰的网络日志

科技爱好者周刊(第 396 期):互联网通信的替代方案 科技爱好者周刊(第 396 期):互联网通信的替代方案 - 阮一峰的网络日志 科技爱好者周刊(第 395 期):软件开发的第三种方式 科技爱好者周刊(第 395 期):软件开发的第三种方式 - 阮一峰的网络日志 科技爱好者周刊(第 393 期):脑腐状态 科技爱好者周刊(第 392 期):axios 投毒与好莱坞式骗术 科技爱好者周刊(第 391 期):AI 的贫富分化 科技爱好者周刊(第 390 期):没有语料,大模型就是智障 套壳中国大模型撑起500亿美元估值?扒一扒 Cursor 的"套壳"疑云 科技爱好者周刊(第 389 期):未来如何招聘程序员 科技爱好者周刊(第 388 期):测试是新的护城河 零安装的"云养虾":ArkClaw 使用指南 科技爱好者周刊(第 387 期):你是领先的 科技爱好者周刊(第 386 期):当外卖员接入 AI 字节全家桶 Seed 2.0 + TRAE 玩转 Skill 科技爱好者周刊(第 385 期):马斯克害怕中国车企吗? 智谱旗舰 GLM-5 实测:对比 Opus 4.6 和 GPT-5.3-Codex 科技爱好者周刊(第 384 期):为什么软件股下跌 科技爱好者周刊(第 383 期):你是第几级 AI 编程 Kimi 的一体化,Manus 的分层 科技爱好者周刊(第 382 期):独立软件的黄昏 AI native Workspace 也许是智能体的下一阶段 科技爱好者周刊(第 381 期):中国 AI 大模型领导者在想什么 科技爱好者周刊(第 380 期):为什么人们拥抱"不对称收益" 科技爱好者周刊(第 379 期):《硅谷钢铁侠》摘录 我如何用 AI 处理历史遗留代码:MiniMax M2.1 升级体验 科技爱好者周刊(第 378 期):预测是新的互联网热点 科技爱好者周刊(第 377 期):14万美元的贫困线 科技爱好者周刊(第 376 期):太空数据中心的争议 科技爱好者周刊(第 375 期):一扇门的 Bug 终于有人做了 Subagent,TRAE 国内版 SOLO 模式来了 科技爱好者周刊(第 374 期):6GHz 的问题 VS Code 使用国产大模型 MiniMax M2 教程 科技爱好者周刊(第 373 期):数据模型是新产品的核心 国产大模型接入 Claude Code 教程:以 Doubao-Seed-Code 为例 科技爱好者周刊(第 372 期):软件界面如何设计 大模型比拼:MiniMax M2 vs GLM 4.6 vs Claude Sonnet 4.5 科技爱好者周刊(第 371 期):一个乐观主义者的专访 科技爱好者周刊(第 370 期):正确的代码高亮 错误处理:异常好于状态码 科技爱好者周刊(第 369 期):Tim 与罗永浩的对谈 科技爱好者周刊(第 368 期):不要这样管理软件团队 一天之内,智谱和 Anthropic 都发了最强编程模型 科技爱好者周刊(第 367 期):Nano Banana 的几个妙用 科技爱好者周刊(第 366 期):旧金山疯狂的 AI 广告 科技爱好者周刊(第 365 期):流量变现正在崩塌 科技爱好者周刊(第 364 期):最难还原的魔方 科技爱好者周刊(第 363 期):最好懂的神经网络解释 科技爱好者周刊(第 362 期):GitHub 工程师谈系统设计 科技爱好者周刊(第 361 期):暗网 Tor 安全吗?
如何撤銷 Git 操作?
阮一峰 · 2019-12-24 · via 阮一峰的网络日志

Git 版本管理時,往往需要撤銷某些操作。

本文介紹幾種最主要的情況,給出詳細的解釋。更多的命令可以參考《常用 Git 命令清單》一文。

一、撤銷提交

一種常見的場景是,提交代碼以後,你突然意識到這個提交有問題,應該撤銷掉,這時執行下面的命令就可以了。


$ git revert HEAD

上面命令的原理是,在當前提交後面,新增一次提交,抵消掉上一次提交導致的所有變化。它不會改變過去的歷史,所以是首選方式,沒有任何丟失代碼的風險。

git revert 命令只能抵消上一個提交,如果想抵消多個提交,必須在命令行依次指定這些提交。比如,抵消前兩個提交,要像下面這樣寫。


$ git revert [倒數第一個提交] [倒數第二個提交]

git revert命令還有兩個參數。

  • --no-edit:執行時不打開默認編輯器,直接使用 Git 自動生成的提交信息。
  • --no-commit:只抵消暫存區和工作區的文件變化,不產生新的提交。

二、丟棄提交

如果希望以前的提交在歷史中徹底消失,而不是被抵消掉,可以使用git reset命令,丟棄掉某個提交之後的所有提交。


$ git reset [last good SHA]

git reset的原理是,讓最新提交的指針回到以前某個時點,該時點之後的提交都從歷史中消失。

默認情況下,git reset不改變工作區的文件(但會改變暫存區),--hard參數可以讓工作區裡面的文件也回到以前的狀態。


$ git reset --hard [last good SHA]

執行git reset命令之後,如果想找回那些丟棄掉的提交,可以使用git reflog命令,具體做法參考這裡。不過,這種做法有時效性,時間長了可能找不回來。

三、替換上一次提交

提交以後,發現提交信息寫錯了,這時可以使用git commit命令的--amend參數,可以修改上一次的提交信息。


$ git commit --amend -m "Fixes bug #42"

它的原理是產生一個新的提交對象,替換掉上一次提交產生的提交對象。

這時如果暫存區有發生變化的文件,會一起提交到倉庫。所以,--amend不僅可以修改提交信息,還可以整個把上一次提交替換掉。

四、撤銷工作區的文件修改

如果工作區的某個文件被改亂了,但還沒有提交,可以用git checkout命令找回本次修改之前的文件。


$ git checkout -- [filename]

它的原理是先找暫存區,如果該文件有暫存的版本,則恢復該版本,否則恢復上一次提交的版本。

注意,工作區的文件變化一旦被撤銷,就無法找回了。

五、從暫存區撤銷文件

如果不小心把一個文件添加到暫存區,可以用下面的命令撤銷。


$ git rm --cached [filename]

上面的命令不影響已經提交的內容。

六、撤銷當前分支的變化

你在當前分支上做了幾次提交,突然發現放錯了分支,這幾個提交本應該放到另一個分支。


# 新建一個 feature 分支,指向當前最新的提交
# 注意,這時依然停留在當前分支
$ git branch feature

# 切換到這幾次提交之前的狀態
$ git reset --hard [當前分支此前的最後一次提交]

# 切換到 feature 分支
$ git checkout feature

上面的操作等於是撤銷當前分支的變化,將這些變化放到一個新建的分支。

(完)