📌 声明:本文由作者独立整理编写,内容涵盖 Git 核心概念与日常操作指南,旨在为开发者提供一份清晰实用的 Git 速查手册。文章结构清晰、示例详实,适合从零开始的初学者,也适合需要随时查阅的熟手。
为什么你需要 Git?
想象一下这个场景:你正在写一个项目,今天加了个功能,跑得挺好。明天改了个配置,突然全崩了。你疯狂地 Ctrl+Z,发现回不去了……😭
或者更经典的——你和同事同时改一个文件,他改完上传,你改完上传,后上传的那个人把前一个人的覆盖了。俩人一整天白干。
Git 就是来解决这些问题的。
一句话概括:Git 是给代码做"存档"和"时间旅行"的工具 —— 让你随时可以回到任意历史版本,让多人协作变得井然有序。
🎯 Git 到底能做什么?
- ✅ 版本控制 —— 每一次提交都是一次存档,随时可以回退
- ✅ 备份同步 —— 推送到云端(GitHub/GitLab/Gitee),不怕本地硬盘坏了
- ✅ 多人协作 —— 各改各的,合并时有冲突也能清晰解决
- ✅ 分支管理 —— 并行开发多个功能,互不干扰
- ✅ 追踪修改记录 —— 每一行代码谁写的、什么时候写的、为什么写的,清清楚楚
🧭 学习路线建议
别想一口吃成胖子。Git 命令很多,但日常用的就那几个。
按照这个顺序学,效率最高:
- 先看「基本工作流程」+「查看历史」 —— 这两块够你日常开发用了
- 再看「分支用法」 —— 独立开发新功能时必须会
- 「撤销操作」只遇到问题时再翻 —— 不用提前背,知道有这些功能就行
📌 标 ⭐ 的是天天用的,其他遇到再查。
🧱 核心概念(先混个脸熟)
| 概念 | 解释 | 🍳 生活比喻 |
|---|---|---|
| 仓库(Repository) | Git 管理的项目文件夹 | 📦 档案室 |
| 工作区(Working Directory) | 你正在修改的文件 | 📝 书桌 |
| 暂存区(Staging Area) | git add 后的文件,准备提交 | 🎒 书包 |
| 提交(Commit) | 一次正式存档,记录谁、什么时候、改了什么 | 📸 存档快照 |
| 分支(Branch) | 从主线分叉的独立开发线 | 🌌 平行宇宙 |
| HEAD | 当前指向哪个版本的指针 | 🧭 "你站在哪里" |
⭐ 基本工作流程(天天用)
日常开发就这四步。第一步只在项目开始时做一次,后面三步每天循环。
# ========== 第0步:初始化仓库(只做一次)==========
git init # 在当前文件夹初始化一个 Git 仓库
# ========== 日常循环(天天做)==========
# 1. 改代码 ✏️
# 2. 添加到暂存区
git add . # . 表示添加所有改动,也可以指定具体文件名
# 3. 提交存档
git commit -m"feat: 添加用户登录功能" # -m 是 message 缩写
# 不加 -m 会弹出一个文本编辑器让你写提交信息
# ========== 首次推送到云端(只做一次)==========
git remote add origin https://github.com/你的用户名/仓库名.git
git push -u origin master # -u 是记住关联,以后直接 git push 就行
# ========== 之后推送(日常用)==========
git push # 因为 -u 记住了关联,直接敲
# ========== 从云端拉取最新代码(每天开始工作前)==========
git pull # 把队友的更新拉到本地
⭐ 查看历史和状态(救命用的)
当你忘了改了什么、想确认当前状态时:
git log --oneline # 一行一条,简洁查看提交历史
# 输出示例:
# cf478d2 (HEAD -> master) feat: 添加 GPL 协议
# 40a5731 fix: 修复登录超时问题
# 2837804 init: 项目初始化
git log --oneline -5 # 只显示最近5条
git status # 查看当前状态:哪些改了、哪些暂存了
⚠️ 重要提醒:
git log只显示从 HEAD 往历史方向能追溯到的提交。如果你用git reset回到了旧版本,被跳过的提交不会再出现在git log里——但提交本身还在,30 天内可以用提交 ID 找回。
🧭 HEAD 与版本导航(跳转必备)
当需要回到旧版本看看、或在版本间跳转时,先看这张图:
提交历史(从旧到新):
2837804 40a5731 cf478d2
○ ← ○ ← ○ ← HEAD → master
(第1次) (第2次) (第3次,你在这里)
↑ ↑ ↑
HEAD~2 HEAD~1 HEAD(当前位置)
HEAD^^ HEAD^
📌 关键概念速览
| 写法 | 含义 |
|---|---|
HEAD | 当前所在位置 |
HEAD^ | 上一个版本(父提交) |
HEAD^^ | 上上个版本 |
HEAD~2 | 和 HEAD^^ 等价,数字更直观 |
HEAD~5 | 往前数第 5 个版本 |
🔀 切换版本
# 切换到某个分支(正常开发)
git switch 分支名 # ✅ 推荐(Git 2.23+)
git checkout 分支名 # 旧版写法
# 切换到某个具体提交(进入"游离状态")
git checkout 提交ID # 比如 git checkout cf478d2
⚠️ 游离 HEAD(detached HEAD)是什么?
当你 git checkout 提交ID 跳到某个具体提交时,HEAD 直接指向提交而不是分支。这时候你可以浏览旧代码,但不要在这里做新提交——否则新提交没有挂在任何分支上,很容易"迷路"。
# ❌ 不推荐:在游离状态下做新提交
git checkout cf478d2
git add .
git commit -m"在旧版本上改了点东西" # 这个提交不在任何分支上!
# ✅ 正确姿势:基于旧版本创建新分支
git switch -c 新分支名 提交ID # 基于旧提交建新分支,安全!
git switch master # 回到最新正常状态
🌿 分支基本用法(独立开发必备)
当你想尝试新功能又不想影响主线代码时,开个分支就对了。
# ========== 创建分支 ==========
git branch 分支名 # 只创建,不切换
git switch -c 功能名 # ✅ 创建并切换过去(推荐)
# ========== 查看所有分支 ==========
git branch # 当前分支前有 * 标记
# ========== 切换分支 ==========
git switch 分支名
# ========== 合并分支 ==========
git switch master # 先切到目标分支(比如 master)
git merge 要合并的分支名 # 把其他分支的改动合并进来
# ========== 删除分支(合并完后清理)==========
git branch -d 分支名
📌 分支命名建议
| 分支名 | 用途 |
|---|---|
main / master | 稳定版本,随时能跑 |
dev | 日常开发分支 |
feature/xxx | 某个具体功能(如 feature/login) |
fix/xxx | 修复某个 bug(如 fix/overflow) |
💡 工作流:新功能开新分支 → 写完测试通过 → 合并回 master → 最后删掉分支。这样 master 始终保持稳定。
↩️ 撤销操作(出问题了再翻)
撤销操作不要按"命令名"学,要按 "我想干嘛" 来找。
⚠️ 但在动手之前,先搞清楚这些命令都偷偷依赖了什么。
🔑 关键前提(必读!)
每个撤销命令背后都藏着一个**"恢复到哪"**的逻辑:
git restore 文件 / git checkout -- 文件
→ Git:好,找一下这个文件的最新版本……
→ 暂存区里有 → 恢复到暂存区里的版本(不是 HEAD!)
→ 暂存区没有 → 退而求其次,恢复到 HEAD 版本
→ HEAD 还没指向任何提交(项目还没 commit 过)→ 报错!
git restore --staged 文件
→ Git:把暂存区恢复到 HEAD 版本
(这个才是从 HEAD 恢复)
📋 前提速查表
| 前提 | 影响的命令 | 后果 |
|---|---|---|
| 至少有一次 commit | git checkout --、git restore(丢弃模式)、git reset、git log | 没有 commit = 没有"旧版本"可恢复,全部报错 |
| 暂存区还未清空 | git restore 文件、git checkout -- 文件 | 恢复到的是暂存区版本,不是 HEAD! |
| HEAD 指向的位置 | git reset 的移动基准、git restore --staged 恢复来源 | HEAD 指向哪,这些就"撤到哪" |
| 暂存区没有东西 | restore --staged、git reset 文件 | 暂存区空的,撤了也白撤 |
| 文件曾经提交过 | git checkout -- 文件、git restore 文件 | 新建后从未 commit 的文件,Git 没有它的旧版本 |
🔥 每次操作前,先
git status看一眼! 它能告诉你:当前在哪个分支、什么文件改了、什么文件暂存了。
第一层:撤销暂存(git add 后悔了)
你已经 git add 了文件,但还没提交,想拿出来重新改。文件内容不变,只是撤出暂存区。
# ✅ 新版(推荐)
git restore --staged 文件名 # 撤销单个文件
git restore --staged . # 撤销全部
# 旧版写法
git reset 文件名 # 单文件
git reset HEAD # 全部清空暂存区
前提:暂存区里确实有这个文件。如果暂存区是空的,执行也不会有任何变化。
第二层:丢弃工作区修改(文件改坏了)
文件改了半天发现不对,想扔掉修改。⚠️ 修改无法找回!
# ✅ 新版(推荐)
git restore 文件名
# restore 不加 --staged,默认就是作用于工作区(文件本身)
# 旧版写法
git checkout -- 文件名
# ↑ -- 是分隔符,强制告诉 Git "后面是文件名"
为什么需要
--? 因为checkout有双重身份:
git checkout 分支名→ 切换分支git checkout -- 文件名→ 恢复文件如果不加
--,Git 会优先匹配分支名,匹配不到才当文件名。
🔥 常见坑
| 场景 | 结果 |
|---|---|
暂存区有东西,直接 git restore 文件 | 恢复到的是刚刚 add 的版本,等于白干 ❌ |
| 正确做法 | 先 git restore --staged 文件 清暂存区,再 git restore 文件 |
| 一步到位 | git restore --source=HEAD 文件 |
| 新建的文件(从未 commit 过) | restore / checkout -- 全部报错 ❌ |
| 已删除的文件 | 可以从 HEAD 版本恢复回来 ✅ |
第三层:撤销提交(commit 后悔了)
已经 git commit 了,想撤回。这里需要 git reset,它有三个模式:
改文件 → git add → git commit
↑ ↑
--mixed --soft
撤到这 撤到这
--hard → 全回退,代码也变回旧版本
| 模式 | HEAD | 暂存区 | 工作区 | 适用场景 |
|---|---|---|---|---|
--soft | 后移 | 保留 | 保留 | 只撤 commit,代码还在暂存区,随时重交 |
--mixed(默认) | 后移 | 清空→掉回工作区 | 保留 | 撤 commit+add,代码还在文件里 |
--hard | 后移 | 销毁 | 还原旧版 | 全部回退,代码也被干掉 ⚠️ |
git reset --soft HEAD^ # 方案1:撤但保留一切,适合合并多个零碎提交
git reset --mixed HEAD^ # 方案2:撤 commit+add,从头整理(可省略 --mixed)
git reset --hard HEAD^ # 方案3:全撤,慎用!
🔥 常见坑
- 只有1次提交时,
HEAD^不存在:项目的第一个提交没有父提交,git reset HEAD^会报错 git reset不加参数 =git reset --mixed HEAD:跟版本时等于原地不动;跟文件名时只操作该文件--soft必须跟目标:不跟会报错,没有默认值- reset 回旧版本后,
git log只显示当前位置往前的提交:被跳过的提交不显示,但还在(30天内可用 ID 找回)
💡 --hard 能找回来吗?
能! 如果你记得被删版本的提交ID,可以用 git reset --hard 提交ID 找回。
原理:
reset --hard只是"拔掉指针",珠子还在。只有 Git 垃圾回收(约30天后)才会真正清理。
reset 的两种用法对比
| 怎么用 | HEAD | 效果 |
|---|---|---|
git reset 目标版本 | 后移 | 撤销提交(上面三种模式) |
git reset 文件名 | 不动 | 只撤销该文件的 add |
git reset --soft 文件名 | ❌ | 不允许!--soft 不能跟文件 |
git reset --hard 文件名 | 不动 | ⚠️ 直接覆盖该文件,慎用! |
第四层:从历史版本恢复
不同于第二层(恢复到 HEAD),这一步可以恢复到任意历史提交的版本。
# ✅ 新版
git restore --source=提交ID 文件名
# 旧版写法
git checkout 提交ID -- 文件名
和第二层的区别:第二层默认从暂存区/HEAD 恢复,而这层明确指定
--source/提交ID,不受暂存区干扰,直接恢复到任意历史版本。注意:这个操作只改工作区的文件内容,不改暂存区、不改 HEAD。文件变成旧版本后,你可以
git add+git commit把旧版本当作新提交。
📊 撤销速查总表
| 我想干嘛 | ✅ 推荐(新版) | 旧版等价 |
|---|---|---|
| 撤销单个文件 add | git restore --staged 文件 | git reset 文件 |
| 撤销全部 add | git restore --staged . | git reset HEAD |
| 丢弃文件修改 | git restore 文件 | git checkout -- 文件 |
| 双重还原(add+修改都撤) | git restore --staged --worktree 文件 | git checkout HEAD -- 文件 |
| 撤 commit,代码保留 | git reset --soft HEAD^ | — |
| 撤 commit+add,代码保留 | git reset --mixed HEAD^ | — |
| 彻底回退 | git reset --hard HEAD^ | — |
| 从旧版本取回文件 | git restore --source=ID 文件 | git checkout ID -- 文件 |
📝 规律总结:
reset管"提交层面"(动 HEAD)restore管"文件层面"(不动 HEAD)- 新版用
switch(换分支)+restore(恢复文件),职责清晰- 旧版
checkout两个都管,容易混淆
✨ 好习惯(少踩坑)
- ✅ 小步提交 —— 每改一个小功能就交一次,不要攒一大堆
- ✅ Commit Message 写清楚 —— 好:"feat: 修复登录闪退" / 差:"修bug"
- ✅ 新功能开新分支 —— 不在 master 上直接改
- ✅ 每天开始先
git pull—— 避免冲突堆积 - ✅ 用
.gitignore排除不需要管理的文件
📄 .gitignore 示例
在项目根目录新建 .gitignore 文件,写入:
node_modules/ # 第三方依赖包(太大,不用管)
.env # 环境变量(可能含密码,不能上传)
*.log # 日志文件
dist/ # 编译输出
.DS_Store # macOS 系统文件
这样 git add . 时会自动跳过这些文件 🎉
🗺️ 场景速查总表
学完了记不住?遇到问题回来翻这个表:
| 我遇到了什么 | 怎么办 | 频率 | 去哪查 |
|---|---|---|---|
| 想用 Git 管项目 | git init | ⭐ | 工作流程 |
| 写好了,想存档 | git add . → git commit -m"xxx" | ⭐ | 工作流程 |
| 忘了改了什么 | git status / git log --oneline | ⭐ | 查看历史 |
| 想试新功能,又怕搞砸 | git switch -c feature/xxx | 常用 | 分支用法 |
| 分支写好了,合回去 | git switch master → git merge feature/xxx | 常用 | 分支用法 |
| 文件改坏了,想扔掉 | git restore 文件 | 偶尔 | 撤销-第二层 |
| add 多了,想拿几个出来 | git restore --staged 文件 | 偶尔 | 撤销-第一层 |
| commit 了才发现有 bug | git reset --soft HEAD^ | 偶尔 | 撤销-第三层 |
| 彻底不想要最近的修改 | git reset --hard 提交ID | 罕见⚠️ | 撤销-第三层 |
| 从旧版本抄代码回来 | git restore --source=ID 文件 | 罕见 | 撤销-第四层 |
| 备份到云端 | git push | 常用 | 工作流程 |
| 换电脑继续写 | git clone 仓库地址 | 罕见 | — |
| 拉取队友更新 | git pull | 常用 | 工作流程 |
📚 写在最后
Git 是一个工具,不是考试。没有人能背下所有命令,连用了十年的老手也经常 git --help。
💡 核心心法:记住
add→commit→push这个流程,记住status和log可以帮你查状态,剩下的遇到问题再查就好。
把这篇文章收藏起来,遇到问题回来翻翻,比死记硬背管用一万倍 🚀
有什么问题欢迎评论区交流,我会持续补充完善!