Git 本地操作进阶:版本回退、撤销修改与文件删除全攻略


🔥草莓熊Lotso: 个人主页
❄️个人专栏: 《C++知识分享》 《Linux 入门到实践:零基础也能懂》
✨生活是默默的坚持,毅力是永久的享受!


🎬 博主简介:


文章目录

  • 前言:
  • [一. Git关键能力:版本回退与撤销修改](#一. Git关键能力:版本回退与撤销修改)
    • [1.1 版本回退](#1.1 版本回退)
    • [1.2 撤销修改](#1.2 撤销修改)
      • [场景 1:修改仅在工作区,未执行 `git add`](#场景 1:修改仅在工作区,未执行 git add)
      • [场景 2:修改已执行 `git add` 到暂存区,未 `commit`](#场景 2:修改已执行 git add 到暂存区,未 commit)
      • [场景 3:修改已commit到版本库(未推送到远程)](#场景 3:修改已commit到版本库(未推送到远程))
  • [二. Git 文件删除:彻底删除与误删恢复](#二. Git 文件删除:彻底删除与误删恢复)
    • [2.1 误删工作区文件,需恢复](#2.1 误删工作区文件,需恢复)
    • [2.2 确认删除文件,同步到版本库](#2.2 确认删除文件,同步到版本库)
  • 结尾:

前言:

在掌握Git本地仓库的基础操作后,"如何修正错误提交""怎样找回误删文件""版本回退的风险与应对"成为开发者进阶的关键课题。代码开发中,误改配置、提交冗余文件、删除核心代码等情况难以避免,而Git提供的版本回退、撤销修改、文件删除 机制,正是解决这些问题的 "安全网" 。本文将聚焦这些进阶操作,拆解其原理、场景与实操细节,帮你在代码出现偏差时,精准、安全地将版本拉回正轨。


一. Git关键能力:版本回退与撤销修改

开发阶段中,难免会出现代码写错,提交误操作等情况,Git提供了完善达到版本回退和撤销机制,可根据修改所处阶段灵活处理。

1.1 版本回退

通过 git reset 命令实现版本回退,核心是通过 commit id 或 HEAD 指针定位目标版本,命令格式为:git reset 【--soft | --mixed | --hard】【HEAD】

关键参数说明:

参数 作用 风险程度
--mixed 默认参数,仅暂存区回退到指定版本,工作区内容保持不变 低
--soft 仅版本库回退,暂存区和工作区内容均不改变 低
--hard 暂存区、工作区、版本库均回退到指定版本 高(工作区未提交代码会丢失)
  • HEAD 说明:
    • 可直接写成 commit id,表⽰指定退回的版本
    • HEAD 表示当前版本
    • HEAD^ 上一个版本
    • HEAD^^ 上上一个版本
    • 以此类推...
  • 可以使用 〜数字表示:
    • HEAD~0 表示当前版本
    • HEAD~1 上一个版本
    • HEAD^2 上上一个版本
    • 以此类推...

实际使用:

为了便于表述,方便测试回退功能,我们需要先做一下准备工作:更新3个版本的ReadMe,并分别进行3次提交,如下所示:

bash 复制代码
# 第一次修改提交
[root@VM-4-4-centos gitcode]# echo "hello version1" >> ReadMe
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
[root@VM-4-4-centos gitcode]# git add ReadMe
[root@VM-4-4-centos gitcode]# git commit -m "add version1"
[master 40bc6e6] add version1
 1 file changed, 1 insertion(+)

# 第二次修改提交
[root@VM-4-4-centos gitcode]# echo "hello version2" >> ReadMe
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
[root@VM-4-4-centos gitcode]# git add ReadMe
[root@VM-4-4-centos gitcode]# git commit -m "add version2"
[master 1a083cf] add version2
 1 file changed, 1 insertion(+)

# 第三次修改提交
[root@VM-4-4-centos gitcode]# echo "hello version3" >> ReadMe
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3
[root@VM-4-4-centos gitcode]# git add ReadMe
[root@VM-4-4-centos gitcode]# git commit -m "add version3"
[master b592a38] add version3
 1 file changed, 1 insertion(+)

# 查看历史记录
[root@VM-4-4-centos gitcode]# git log --pretty=oneline
b592a387a176cfb00c56cd3cbc1d3faca9ba2cee add version3
1a083cf93e6f21ba0bf5419f32125875aa787255 add version2
40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1
...... #之前的一些这里就不放出来了

现在,如果我们提交完 version3 后,发现 version3 编写错误,想退回到 version2 ,重新基于 version2 开始编写。由于我们这里希望的是将工作区的内容也回退到 version2 版本,所以需要用 --hard 参数,示例如下:

bash 复制代码
[root@VM-4-4-centos gitcode]# git log --pretty=oneline
b592a387a176cfb00c56cd3cbc1d3faca9ba2cee add version3
1a083cf93e6f21ba0bf5419f32125875aa787255 add version2
40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1
............
# 指定 version2 的对应版本号,回退到这个版本
[root@VM-4-4-centos gitcode]# git reset --hard 1a083cf93e6f21ba0bf5419f32125875aa787255
HEAD is now at 1a083cf add version2
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2

我们可以发现,此时 ReadMe 文件的内容,已经回退到 version2 了!,当前,我们再次使用 git log 查看一下提交日志,会发现 HEAD 指向了version2 ,如下所示:

bash 复制代码
[root@VM-4-4-centos gitcode]# git log --pretty=oneline --decorate
1a083cf93e6f21ba0bf5419f32125875aa787255 (HEAD, master) add version2
40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1
............

到这里一般回退功能就演示完毕了,但是如果我后悔了,想再回到 version3 怎么办?我们可以继续使用 git reset 命令,回退到 version3 版本 ,但是我们必须拿到 version3 的 commit id 去指定回退版本。

但是我们看到了 git log 并不能打印出 version3 的 commit id ,运气好的话我们可以从终端上去找找之前的记录,运气不好的话 commit id 就已经被我们搞丢了~~

值得一提的是 Git 还提供了一个 git reflog 命令能补救一下,该命令用来记录本地的每一次指令。

bash 复制代码
[root@VM-4-4-centos gitcode]# git reflog
1a083cf HEAD@{0}: reset: moving to 1a083cf93e6f21ba0bf5419f32125875aa7
b592a38 HEAD@{1}: commit: add version3
1a083cf HEAD@{2}: commit: add version2
40bc6e6 HEAD@{3}: commit: add version1
eb85e67 HEAD@{4}: commit: delete
54cffd0 HEAD@{5}: commit: add 3 file3
1e3f5b8 HEAD@{6}: commit: commit my first file
fcce812 HEAD@{7}: commit (initial): add first file
(END)

这样,你就可以很方便的找到你的所有的操作记录了,但是 b592a38 这个是啥东西?这个是 version3 的 commit id 的部分。Git 版本回退的时候,也可以使用部分的 commit id 来代表目标版本。示例如下:

bash 复制代码
# 回退到 version3
[root@VM-4-4-centos gitcode]# git reset --hard b592a38
HEAD is now at b592a38 add version3

# 查看工作区
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3

# 查看 log
[root@VM-4-4-centos gitcode]# git log --pretty=oneline --decorate
b592a387a176cfb00c56cd3cbc1d3faca9ba2cee (HEAD, master) add version3
1a083cf93e6f21ba0bf5419f32125875aa787255 add version2
40bc6e65bb49713bb9d77e00b62fcd190b461ed7 add version1
............

可往往是理想很丰满,现实很骨感。在实际开发中,由于长时间的开发,很可能会导致 commit id 早就找不到了,可突然某一天,我又想回到 version3 ,那该如何操作呢?貌似现在是不可能了~

补充说明 :

Git 版本的回退速度特别快,因为 Git 在内部有个指向当前分支(此处是master)的HEAD指针,refs/heads/master 文件里保存当前 master 分支的最新的 commit id 。当我们在回退版本的时候。Git 仅仅是给refs/heads/master 中存储一个特定的version ,可以简单理解为如下示意图:

1.2 撤销修改

根据修改所处阶段(工作区 / 暂存区),选择不同的撤销命令:

场景 1:修改仅在工作区,未执行 git add

使用 git checkout -- [file] (这个 - - 很重要,一旦省略会变成别的意思) 丢弃工作区修改,恢复到最近一次git add或git commit时的状态:
友情提示 :千万不要想着用什么 git diff xxx 找到差异去手动删除,那要是改的地方多得删多久啊,这不得累麻了

bash 复制代码
# 向 ReadMe 新增一行内容
[root@VM-4-4-centos gitcode]# echo "It  is shift" >> ReadMe
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3
It  is shift

# 恢复到上一次 add 或 commit
[root@VM-4-4-centos gitcode]# git checkout -- ReadMe
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3

场景 2:修改已执行 git add 到暂存区,未 commit

add 后还是保存到了暂存区,怎么撤销呢?

bash 复制代码
# 向 ReadMe 新增一行内容
[root@VM-4-4-centos gitcode]# echo "It is shit" >> ReadMe
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3
It is shit

# add 存入暂存区
[root@VM-4-4-centos gitcode]# git add ReadMe
# git status 查看一下
[root@VM-4-4-centos gitcode]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   ReadMe
#

那我们该怎么做呢?我们来回忆一下之前学过的 git reset 回退命令。该命令如果使用 --mixed 参数,可以将暂存区的内容回退到指定的版本内容,但工作区文件保持不变,我们再接着用上面场景一的方法解决一下不就好了。
总的来说就是:先将暂存区修改撤销到工作区,再丢弃工作区修改:

bash 复制代码
# 先将暂存区修改撤销到工作区,--mixed 是默认参数,可以省略
[root@VM-4-4-centos gitcode]# git reset HEAD ReadMe
Unstaged changes after reset:
M	ReadMe
# git status 查看一下
[root@VM-4-4-centos gitcode]# git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   ReadMe
#
no changes added to commit (use "git add" and/or "git commit -a")

# 类似于场景一,丢弃工作区的修改
[root@VM-4-4-centos gitcode]# git checkout -- ReadMe
[root@VM-4-4-centos gitcode]# git status
# On branch master
nothing to commit, working directory clean
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3

成功恢复了!!!

场景 3:修改已commit到版本库(未推送到远程)

直接通过 git reset --hard 回退到上一个版本即可。
注意:若已推送(push)到远程仓库,此操作会导致本地与远程版本不一致,需谨慎,这个远程仓库我们在后面会讲的。

bash 复制代码
# 向 ReadMe 中新增一行内容
[root@VM-4-4-centos gitcode]# echo "I like coding" >> ReadMe
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3
I like coding

# 添加 + 提交
[root@VM-4-4-centos gitcode]# git add ReadMe
[root@VM-4-4-centos gitcode]# git commit -m "test quash"
[master 1a0a253] test quash
 1 file changed, 1 insertion(+)

# 回退到上一个版本
[root@VM-4-4-centos gitcode]# git reset --hard HEAD^
HEAD is now at b592a38 add version3
[root@VM-4-4-centos gitcode]# cat ReadMe
hello Lotso
hello version1
hello version2
hello version3

二. Git 文件删除:彻底删除与误删恢复

在 Git 中,删除文件也是一种 "修改操作",需根据需求选择 "彻底删除" 或 "恢复误删文件":

2.1 误删工作区文件,需恢复

bash 复制代码
[root@VM-4-4-centos gitcode]# ls
file1  ReadMe
[root@VM-4-4-centos gitcode]# rm file1
rm: remove regular empty file 'file1'? y

直接这样删除其实是没用的,反而徒增烦恼,git status 命令会立刻告诉你那些文件被删除了;

bash 复制代码
[root@VM-4-4-centos gitcode]# git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	deleted:    file1
#
no changes added to commit (use "git add" and/or "git commit -a")

此时,工作区就和版本库不太一样了,要删文件,目前除了要删工作区的文件以外,还要清除版本库的我文件。当然,我们这里如果是误删 ,可以直接使用 git checkout -- file 来进行恢复,之前讲过(删除也是修改)。

bash 复制代码
[root@VM-4-4-centos gitcode]# ls
ReadMe
[root@VM-4-4-centos gitcode]# git checkout -- file1
[root@VM-4-4-centos gitcode]# ls
file1  ReadMe

2.2 确认删除文件,同步到版本库

这里想要恢复也是可以的哈,上面也讲到过的。

bash 复制代码
# 从工作区和暂存区同时删除file1
[root@VM-4-4-centos gitcode]# git rm file1
rm 'file1'
[root@VM-4-4-centos gitcode]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    file1
#

# 提交删除操作到版本库
[root@VM-4-4-centos gitcode]# git commit -m "deleted file1"
[master c213450] deleted file1
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 file1
[root@VM-4-4-centos gitcode]# git status
# On branch master
nothing to commit, working directory clean

结尾:

html 复制代码
🍓 我是草莓熊 Lotso!若这篇技术干货帮你打通了学习中的卡点:
👀 【关注】跟我一起深耕技术领域,从基础到进阶,见证每一次成长
❤️ 【点赞】让优质内容被更多人看见,让知识传递更有力量
⭐ 【收藏】把核心知识点、实战技巧存好,需要时直接查、随时用
💬 【评论】分享你的经验或疑问(比如曾踩过的技术坑?),一起交流避坑
🗳️ 【投票】用你的选择助力社区内容方向,告诉大家哪个技术点最该重点拆解
技术之路难免有困惑,但同行的人会让前进更有方向~愿我们都能在自己专注的领域里,一步步靠近心中的技术目标!

结语:版本回退、撤销修改与文件删除,是Git赋予开发者的"纠错能力",也是保障代码稳定性的核心手段。它们的本质是对"版本历史"的灵活掌控------既能通过 git reset 在版本树中穿梭,也能通过 git checkout 和 git rm 在工作区、暂存区精准修正。掌握这些操作,你将不再因"误操作"而焦虑,反而能把Git的版本管理能力转化为开发效率的"加速器"。后续学习分支管理时,这些操作的思路也将助你更从容地处理多分支间的版本冲突与合并,真正实现对代码版本的全方位掌控。

✨把这些内容吃透超牛的!放松下吧✨ ʕ˘ᴥ˘ʔ づきらど

相关推荐
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
回眸&啤酒鸭3 天前
【回眸】Minicart 电商购物车核心功能落地指南
人工智能
一隅论数智3 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
默_笙3 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
weilx12343 天前
C++笔记-文件IO-<fcntl.h>
c++
AI的探索之旅3 天前
97 个 OpenCV 实例(三十):双目立体,从标定到点云
人工智能·opencv·计算机视觉
AlbertZein3 天前
Step-5-Preview 上手实测:3D 游戏、金融分析、网页设计一次跑完
人工智能·aigc
俊昭喜喜里3 天前
java中的继承和多态的区别
java