Git 回退操作详解:带示例的“小白”指南

前言

在日常开发中,我们难免会遇到:

  • 改错代码:推送之前才发现某些行根本就不该动
  • 提交错误:commit 信息打错、提交到错误分支
  • 想回到之前版本:测试时发现之前版本是好的,需要回去查看

这就需要用到 Git 的回退操作。Git 提供多种回退方式,比如:checkoutresetrevertreflog 等。下面会从最常见的场景入手,一步步解释 怎么做 + 为什么这样做


1. 概念简单区分

为了后面理解更顺畅,先做最简要的概念区分:

  • 工作区(Working Directory):就是你平时编辑文件所在的那一层文件夹。
  • 暂存区(Staging Area):你用 git add 之后,文件的修改就放到这里,等待下一次提交。
  • 本地仓库(Local Repository):你执行 git commit 后,才真正存到本地仓库里。
  • 远程仓库(Remote Repository)git push 后,修改才会传到远程,比如 GitHub、GitLab 等。

不同的回退命令,操作作用在不同的阶段。


2. 撤销尚未提交的修改(还在工作区)

场景示例

你刚写完一段代码,突然发现完全写错了,还没来得及用 git add。你想丢弃掉这一切。

命令

# 撤销当前工作区所有未提交的更改
git checkout -- .

或者,如果只想丢弃某个文件的更改:

git checkout -- <filename>

详解

  • checkout -- <文件> 会用最近一次提交中的版本覆盖你的工作区文件,达成“把文件回滚到上次提交状态”的效果。
  • 这时候,如果你还没有 git add,那么这个命令就是最简单的丢弃本地改动方式。

3. 撤销已 git add 但未 commit 的修改

场景示例

你已经执行了 git add somefile.py,但没执行 git commit。突然发现有些改动是不想提交的。

命令

  1. 先把文件从暂存区移回工作区:
    git reset HEAD <filename>
    
  2. 再丢弃该文件在工作区的改动(如果还要丢弃的话):
    git checkout -- <filename>
    

详解

  • git reset HEAD <filename>:把 <filename>暂存区撤回到工作区
  • git checkout -- <filename>:丢弃工作区中的改动,回到上一次提交的状态。

如果你只是想取消暂存,但是保留文件的编辑(也许还想再改),那就只执行第一步即可。


4. 撤销最近一次提交:git reset 的用法

当你已经提交了 (commit),但你后悔了,比如提交漏写了某些文件、或者发现了语法错误,想重新来。

4.1 保留改动到工作区:--soft

“我想把最新一次提交退回,但代码还留着(我想再改改,之后重新提交)。”

git reset --soft HEAD~1
  • HEAD~1 表示上一个提交(也可以用 commit ID 的前几位代替)。
  • --soft 会把那次提交的所有改动放回到“暂存区”,让你可以继续进行修改或重新提交。

4.2 完全丢弃改动:--hard

“我想彻底删除最近一次提交里的所有更改,干干净净回到上一个版本。”

git reset --hard HEAD~1
  • 这会永久删除那次提交及其工作区更改,除非你通过 reflog 找回。
  • 请谨慎操作:如果你需要的内容都没了,可能得不到恢复。

示例场景

  1. 你写了一个新功能,git commit -m \"add new feature\"
  2. 结果发现写错功能逻辑,决定先回到不带该功能的旧版本去调试。
    • 如果你还想保留这段代码,可以改良后再提交:
      git reset --soft HEAD~1
      # 现在那次提交的改动还在暂存区,你可以用编辑器继续修改
      git commit -m \"fix new feature\"
      
    • 如果你完全不想要那次提交,干脆删掉:
      git reset --hard HEAD~1
      # 彻底回到之前的版本
      

5. 撤销某一次特定提交:git revert

场景示例

你在历史上第 10 个提交里改了数据库配置,影响到现在的运行。想把那次提交撤销,但又不想影响中间其他 commits。

命令

git revert <具体的commit_id>

执行后,会自动开启一个编辑器让你写“撤销 xx 提交”的说明,然后自动生成一个新的提交,用以反向撤销指定版本的改动。

详解

  • git revert 不会改变原来的提交历史,而是生成一个“负向补丁”把之前提交的内容给抵消掉。
  • 这种做法最安全:不会打乱别人的历史,也不需要强制推送。团队协作中非常常用。

6. 想把本地回退同步到远程:强制推送 git push -f

场景示例

你在本地用 git reset --hard 回退到了一个老版本,然后希望远程仓库也回退。此时,如果直接 git push,Git 会拒绝,因为本地分支历史“比远程版本更旧”。

命令

git push origin <branch_name> --force
  • 这会把远程仓库对应分支的提交历史整体替换成你本地的版本。

风险提示

  • 一旦你强制推送,之前在远程的提交记录将被覆盖。
  • 如果有其他人基于那几个被覆盖的提交做了工作,会引起冲突或混乱。
  • 因此,强制推送前,一定先跟团队沟通

7. 误操作后的救命绳:git reflog

场景示例

你一激动用 git reset --hard HEAD~2 结果发现需要的东西被删了。或者你已经 push -f 把远程也覆盖了……

命令

git reflog

会列出所有操作记录,包括 checkoutcommitresetmergerebase 等。你会看到一串记录,如:

a1b2c3d HEAD@{0}: reset: moving to HEAD~2
f6g7h8i HEAD@{1}: commit: add new feature
...
  • 你可以找到需要的提交 ID,然后用:
    git reset --hard <提交ID>
    
    或者
    git checkout <提交ID>
    
    把那个版本再取出来。

详解

  • reflog 相当于 Git 的本地“操作历史日志”。只要本地没有执行更深度的清理(比如 git gc --prune=now),通常都能在 reflog 找到过往的 commit。
  • 这是你“最后的后悔药”,别轻易乱删本地仓库!

8. 你可能关心的常见问题

  1. 已经 push 到远程的提交,能不能用 reset 撤销?
    • 可以,但要用 push -f 强制推送,会影响其他人。所以一般用 git revert 而不是 reset
  2. git revertgit reset 有啥区别?
    • reset 是改变历史本身,“抹掉”提交;revert 是做一个新的提交来“抵消”之前提交的变化。revert 更安全,协作中更推荐。
  3. 能不能同时撤销多个提交?
    • 可以:git revert a1b2c3d..f6g7h8i (如果中间需要处理冲突,也要人工处理)。不过要对 git revert 比较熟悉才行。
  4. 回退后发现我又需要那段代码,怎么办?
    • 看看 reflog 能不能救。因为 reset --hard 并不是真正销毁,除非被垃圾回收 (git gc) 清理。

总结:回退操作一览表

需求场景操作风险性
工作区未暂存的改动想丢弃git checkout -- <file>
已暂存(但未提交)的改动想丢弃git reset HEAD <file> + git checkout -- <file>
撤销本地最后一次提交,保留改动到工作区git reset --soft HEAD~1相对可控
彻底删除最后一次提交,不保留改动git reset --hard HEAD~1高,无法轻易恢复
撤销历史中某个特定提交(留下回滚记录)git revert <commit_id>
强制把回退操作更新到远程git push -f origin <branch>高,需沟通
查看所有本地操作日志,从中找到想恢复的 commitgit reflog无风险(只读)

结束语

以上就是 Git 回退最常用的几种操作,结合了具体的使用场景和示例流程。作为新手,最重要的是:

  1. 明白回退命令改动的是哪些区(工作区、暂存区、本地仓库、远程仓库)
  2. 回退前先想清楚:自己是否真的要破坏历史?能不能用 git revert?
  3. 一旦强制推送,一定要先沟通
  4. 误操作之后,别忘了 git reflog

希望这篇指南能帮助你在回退操作时更加从容,避免一些“万劫不复”的失误。祝你在开发中“一骑绝尘”、少踩坑、多出成果!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35543.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件需求分类、需求获取(高软46)

系列文章目录 软件需求分类&#xff0c;需求获取 文章目录 系列文章目录前言一、软件需求二、获取需求三、真题总结 前言 本节讲明软件需求分类、需求获取的相关知识。 一、软件需求 二、获取需求 三、真题 总结 就是高软笔记&#xff0c;大佬请略过&#xff01;

10、基于osg引擎生成热力图高度图实现3D热力图可视化、3D热力图实时更新(带过渡效果)

1、结果 2、完整C代码 #include <sstream> #include <iomanip> #include <iostream> #include <vector> #include <random> #include <cmath> #include <functional> #include <osgViewer/viewer> #include <osgDB/Read…

鸿蒙应用程序包HAP的开发与使用

1、HAP是什么&#xff1f; HAP&#xff08;Harmony Ability Package&#xff09;是应用安装和运行的基本单元。HAP包是由代码、资源、第三方库、配置文件等打包生成的模块包&#xff0c;其主要分为两种类型&#xff1a;entry和feature。 entry&#xff1a;应用的主模块&#x…

【Mac】安装 Parallels Desktop、Windows、Rocky Linux

一、安装PD 理论上&#xff0c;PD只支持试用15天&#xff01;当然&#xff0c;你懂的。 第一步&#xff0c;在 Parallels Desktop for Mac 官网 下载 Install Parallels Desktop.dmg第二步&#xff0c;双击 Install Parallels Desktop.dmg 第三步&#xff0c;双击安装Paralle…

matlab 自适应模糊PID在反应釜温度控制中的应用

1、内容简介 matlab163-自适应模糊PID在反应釜温度控制中的应用 可以交流、咨询、答疑 2、内容说明 略摘要:针对工业过程控制具有时变、滞后、非线性等特点,在传统 PID 控制中融入模糊控制的功能,形成了新的参数自 适应模糊 PID 控制器,并把它应用在化工制药中常用的反应釜温度…

基于FPGA的3U机箱温度采集板PT100,应用于轨道交通/电力储能等

板卡简介&#xff1a; 本板为温度采集板&#xff08;PT100&#xff09;&#xff0c;对目标进行测温&#xff0c;然后将温度转换成处理器可识别的电流信号。 性能规格&#xff1a; 电源&#xff1a;DC5V&#xff0c;DC15V 4线制PT100&#xff1a;7路&#xff08;标称测温范围…

管家婆实用贴-如何设置打印机共享

很多商家在使用管家婆软件经营日常业务时会有多个操作员多台电脑需要打印&#xff0c;但是不想每台电脑配置一台打印机&#xff0c;一台电脑专门用来打印又浪费设备。遇到这种情况时可以将插线电脑上的打印机共享给其他的电脑一起使用&#xff0c;方便又高效。今天来和小编一起…

Qt QML实现视频帧提取

## 前言 视频帧率&#xff08;Frame Rate&#xff09;是指视频播放时每秒显示的画面帧数&#xff0c;通常用fps&#xff08;Frames Per Second&#xff09;来表示。视频是由一系列静止的图像帧组成的&#xff0c;而视频帧率则决定了这些图像帧在单位时间内播放的速度。较高的视…

LabVIEW压比调节器动态试验台

本案介绍了一种基于LabVIEW的压比调节器动态试验台的设计&#xff0c;通过实用的LabVIEW图形化编程语言&#xff0c;优化了数据采集与处理的整个流程。案例通过实际应用展示了设计的专业性与高效性&#xff0c;以及如何通过系统化的方法实现精确的动态测试和结果分析。 ​ 项目…

3.17学习总结 java数组

地址值&#xff1a; D&#xff1a;表示当前数组内元素元素是double类型的 索引>下标&#xff0c;从0开始 最大索引&#xff1a;数组长度-1 把数据存储到数组中&#xff0c;一旦覆盖之后&#xff0c;原来的数据就不存在了 数组的遍历&#xff1a; 遍历&#xff1a;是取…

Linux-数据结构-线性表-单链表

一.链表的概念 【1】线性表的链式存储 解决顺序存储的缺点&#xff0c;插入和删除&#xff0c;动态存储问题。 【2】特点&#xff1a; 线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素&#xff0c;存储单元可以是连续的&#xff0c;也可以不连续。可以被存…

Apifox Helper 自动生成API接口文档

在我们开发过程中我们在编写请求地址和编写请求参数的时候特别花费时间耗费了我们很多时间&#xff0c;作为一个程序员&#xff0c;更应该把精力时间集中在开发上&#xff0c; Apifox Helper 是 Apifox 团队针对 IntelliJ IDEA 环境所推出的插件&#xff0c;可以在 IDEA 环境中…

【软考-架构】13.1、软件架构概述-构件技术

✨资料&文章更新✨ GitHub地址&#xff1a;https://github.com/tyronczt/system_architect 文章目录 ✨【重点】系统架构设计软件架构概述软件架构设计与生命周期构件&#x1f31f;软件架构风格数据流风格调用/返回风格独立构件风格虚拟机风格仓库风格闭环控制风格C2体系结…

C++特性——智能指针

为什么需要智能指针 对于定义的局部变量&#xff0c;当作用域结束之后&#xff0c;就会自动回收&#xff0c;这没有什么问题。 当时用new delete的时候&#xff0c;就是动态分配对象的时候&#xff0c;如果new了一个变量&#xff0c;但却没有delete&#xff0c;这会造成内存泄…

基于SpringBoot+Vue的幼儿园管理系统+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、教师、普通用户功能模块&#xff1a;用户管理、教师管理、班级管理、幼儿信息管理、会议记录管理、待办事项、职工考核、请假信息、缴费信息、体检管理、资源管理、原料管理、菜品信息管理等技术选型&#xff1a;SpringBoot&#xff0…

网络通信(传输层协议:TCP/IP ,UDP):

Socket是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端&#xff0c;提供了应用层进程利用网络协议交换数据的机制。 网络协议&#xff1a;一台电脑的数据怎么传递给另一台电脑&#xff0c;是由网络协议来规定的 端口号&#…

Qt之自定义界面组件 一

通过qt中的painter绘图事件绘制一个电池电量图的变化。效果如下图 创建一个基于界面widget工程&#xff0c;在wdiget界面添加一个widget界面,将添加的widget界面的类提升为Tbattery.在Tbattery类中重写painEvent电池电量代码 文件目录结构 主要部分代码 //Tbattery.cpp #inc…

AP AR

混淆矩阵 真实值正例真实值负例预测值正例TPFP预测值负例FNTN &#xff08;根据阈值预测&#xff09; P精确度计算&#xff1a;TP/(TPFP) R召回率计算&#xff1a;TP/(TPFN) AP 综合考虑P R 根据不同的阈值计算出不同的PR组合&#xff0c; 画出PR曲线&#xff0c;计算曲线…

学习单片机需要多长时间才能进行简单的项目开发?

之前有老铁问我&#xff0c;学单片机到底要多久&#xff0c;才能进行简单的项目开发&#xff1f;是三个月速成&#xff0c;还是三年磨一剑&#xff1f; 今天咱们就来聊聊这个话题&#xff0c;我不是什么高高在上的专家&#xff0c;就是个踩过无数坑、烧过几块板子的“技术老友”…

数学建模:MATLAB循环神经网络

一、简述 1.循环神经网络 循环神经网络&#xff08;RNN&#xff09;是一种用于处理序列数据的神经网络。不同于传统的前馈神经网络&#xff0c;RNN在隐藏层中加入了自反馈连接&#xff0c;使得网络能够对序列中的每个元素执行相同的操作&#xff0c;同时保持一个“记忆”状态…