Git 进阶实战:状态查看、版本回退与修改撤销全攻略

在上一篇文章里,我们搞定了 Git 的基础操作(本地仓库初始化、远程推送),但实际开发中,还会遇到 "不知道当前代码处于什么状态""改崩了想回退版本""不小心加错文件想撤销" 的问题。这篇就结合我的新学习笔记,把 Git 的进阶操作讲透,帮大家避开开发中的 "版本坑"!

一、先记一个铁规则:一个项目只能有一个 Git 仓库

刚开始学 Git 时,我差点犯了一个错 ------ 在同一个lesson_zp项目里,又执行了一次git init,结果生成了两个.git隐藏目录(一个在根目录,一个在子文件夹)。这会导致什么问题?

  • Git 不知道该用哪个仓库管理代码,提交、推送时会报错
  • 代码版本混乱,明明提交了却找不到,后续根本没法回退

正确做法

  1. 初始化仓库前,先检查项目根目录是否有.git文件夹(显示隐藏文件才能看到)
  1. 若已有.git,直接用现有仓库;若没有,再执行git init
  1. 记住:.git目录是 Git 的 "核心大脑",删了就丢了所有版本记录,千万别乱删!

另外,git init后会默认创建一个master分支(现在有些 Git 版本默认是main),后续所有提交都会先放到这个分支上,多人协作也是基于分支来进行的。

二、最常用也最重要的命令:git status(查看仓库状态)

我现在养成了一个习惯:不管是要add、commit还是撤销修改,先执行git status。因为它能清晰告诉你 "当前代码处于什么状态",相当于 Git 的 "状态仪表盘"。

1. 常见的 3 种状态及对应操作

执行git status后,会看到以下几种情况,对应不同的处理方式:

状态描述 含义 该做什么
Untracked files(未跟踪文件) 这些文件是新创建的,Git 还没开始管理它们 用git add 文件名或git add .(添加所有未跟踪文件)加入暂存区
Changes to be committed(已暂存待提交) 文件已经用git add加入暂存区,等待提交到仓库 确认无误后,用git commit -m "备注"提交到当前分支
nothing to commit, working tree clean(工作区干净) 所有修改都已提交到仓库,工作区没有未跟踪、未提交的文件 可以放心进行下一步操作(比如拉取远程代码、创建分支)

2. 提交时的两个关键细节

  • 备注一定要清晰:比如 "修复登录按钮点击无响应""新增用户信息列表接口",别写 "改了点东西""提交一下"------ 不然过几天你自己都忘了这次改了啥,回退版本时更懵。
  • 提交的是 "修改" 而非 "整个文件" :Git 不会存储整个文件的副本,而是记录 "这次比上一版本改了哪些地方"(比如新增 2 行、删除 1 行),所以提交后生成的版本体积很小。
  • 每个提交有唯一 ID:提交后会生成一个 40 位的哈希值(比如笔记里的9bd76c3,实际是更长的串),这是版本的 "身份证"。为什么不用自增 ID(比如 1、2、3)?因为多人协作时,不同人提交会导致自增 ID 冲突,而哈希 ID 通过 SHA1 算法生成,全球唯一,绝不会重复。

三、提交前必做:git diff(查看代码差异)

有时候我们改了代码,却忘了具体改了哪几行,直接commit容易把错误代码提交上去。这时候git diff就派上用场了 ------ 它能显示 "工作区的代码" 和 "仓库里最新版本" 的差异。

怎么用?

直接在项目目录下执行:

bash 复制代码
# 查看所有修改文件的差异
git diff
# 查看某个具体文件的差异(比如只看index.js)
git diff index.js

执行后会看到这样的内容(举个例子):

diff 复制代码
diff --git a/index.js b/index.js
index 1234567..7654321 100644
--- a/index.js
+++ b/index.js
@@ -1,3 +1,5 @@
 // 旧代码
 console.log("hello");
-console.log("world");
+// 新增一行
+console.log("new line");
+console.log("world");
  • 带-的是删除的代码,带+的是新增的代码
  • 建议每次commit前都用git diff检查一遍,确认没有多余的调试代码(比如console.log)或错误再提交,这是个非常好的开发习惯!

四、救急必备:版本回退(git reset --hard)

改崩代码了怎么办?比如刚提交了一个版本,发现有严重 bug,想回到上一个能正常运行的版本 ------ 这时候就需要 "版本回退",核心命令是git reset --hard。

1. 先搞懂 "HEAD 指针"

Git 里有个 "HEAD 指针",它指向 "当前分支的最新提交版本"。比如笔记里的9bd76c3 (HEAD -> master),意思是:当前在master分支,HEAD 指针指向9bd76c3这个版本(最新版本)。版本回退,本质就是 "移动 HEAD 指针,让它指向之前的某个版本"。

2. 两种回退方式

方式 1:按 "版本距离" 回退(适合最近的版本)

用HEAD^表示 "上一个版本",HEAD^^表示 "上上个版本",以此类推(如果回退 10 个版本,也可以写HEAD~10):

perl 复制代码
# 回退到上一个版本(HEAD^ 等价于 HEAD~1)
git reset --hard HEAD^
# 回退到上上个版本
git reset --hard HEAD^^

方式 2:按 "版本 ID" 回退(适合任意版本,推荐)

如果想回退到更早的版本,或者回退之后又想 "反悔" 回到新版本,就需要用版本 ID(哈希值,不用写全,写前 6-8 位就行,Git 会自动识别):

perl 复制代码
# 回退到指定版本(比如回退到9bd76c3这个版本)
git reset --hard 9bd76c3

注意!git reset --hard 有风险

这个命令会 "强制覆盖工作区的代码",也就是说,工作区里未提交的修改会被直接删除,且无法恢复。所以执行前一定要确认:

  • 工作区的修改已经提交(或不需要了)
  • 版本 ID 没写错(可以用git log查看所有版本的 ID 和备注)

五、容易混淆的两个 "撤销" 操作

开发中还会遇到两种场景:"不小心修改了文件想撤销""不小心把文件加入暂存区想移除",这时候需要用两个不同的命令,千万别搞混!

1. 撤销工作区的修改:git checkout -- filename

场景:修改了index.js,但还没执行git add(文件处于 "未跟踪" 或 "已修改未暂存" 状态),现在想把它恢复到和仓库里最新版本一模一样的状态。

bash 复制代码
# 撤销index.js在工作区的所有修改(未暂存的修改会消失)
git checkout -- index.js

注意:命令里的--很重要,少了会变成 "切换分支",一定要写全!

2. 撤销暂存区的修改:git reset HEAD filename

场景:执行了git add index.js(文件已加入暂存区),但后来发现这个文件改得有问题,想把它从暂存区移回工作区(后续可以重新修改或撤销)。

perl 复制代码
# 把index.js从暂存区移除,回到工作区
git reset HEAD index.js

执行后,再用git status会看到index.js变成了 "未暂存" 状态,之后可以用git checkout -- index.js彻底撤销修改,或者重新修改后再git add。

六、我的进阶学习总结

  1. 仓库唯一性:一个项目只留一个.git目录,多了会乱,删了会丢版本。
  1. 状态先查:不管做什么操作,先跑git status,清楚当前状态再动手。
  1. 提交前 diff:避免把错误代码提交,减少后续回退的麻烦。
  1. 回退要谨慎:git reset --hard会删未提交的修改,执行前务必确认。
  1. 撤销分场景:工作区用checkout --,暂存区用reset HEAD,别搞反。

这些操作我练了好几次才完全分清,建议大家也多动手试:比如故意改错代码,用git diff看差异,再用git reset回退,用checkout撤销 ------ 练一遍比看十遍笔记都管用!如果大家有其他 Git 疑问,或者有更顺手的操作技巧,欢迎在评论区交流~

相关推荐
winds~8 小时前
【git】docker中无法进行git命令行补全
git·docker·容器
rit843249918 小时前
Git常用命令的详细指南
大数据·git·elasticsearch
我要升天!19 小时前
Git的原理与使用 -- 分支管理
大数据·git·elasticsearch
聪明努力的积极向上20 小时前
【GIT】VS中图形化页面进行还原和重置的git操作
git
Hermia_yuan21 小时前
【Git】版本更新
git
inx1771 天前
为什么要用Git?如何使用Git?
git
Empty_7771 天前
Keepalived双机热备
linux·git·github
ityangs2 天前
GitLab 私服(基于 Docker)搭建方案
git·docker·容器·gitlab
ZYMFZ2 天前
Redis主从复制与哨兵集群
前端·git·github