目录
[Git 学习笔记整理链接:](#Git 学习笔记整理链接:)
[二、Git 的三个核心区域:工作区 / 暂存区 / 本地仓库](#二、Git 的三个核心区域:工作区 / 暂存区 / 本地仓库)
[2.1 Git 三个区域的介绍及结构示意图](#2.1 Git 三个区域的介绍及结构示意图)
[1)工作区(Working Tree)](#1)工作区(Working Tree))
[2)暂存区(Index / Staging Area)](#2)暂存区(Index / Staging Area))
[3)本地仓库(Local Repository)](#3)本地仓库(Local Repository))
[2.2 git 命令对比](#2.2 git 命令对比)
[2.3 三大分区的好处](#2.3 三大分区的好处)
[三、远端引用:origin/feature/driver 到底是什么?](#三、远端引用:origin/feature/driver 到底是什么?)
[3.1 origin 是什么?](#3.1 origin 是什么?)
[2)为什么要区分 fetch 和 push?](#2)为什么要区分 fetch 和 push?)
[3)多远端(origin + upstream)](#3)多远端(origin + upstream))
[3.2 git fetch origin 详细解析:](#3.2 git fetch origin 详细解析:)
[1)git fetch origin 会把什么拉到本地?是所有分支吗?](#1)git fetch origin 会把什么拉到本地?是所有分支吗?)
[2)git fetch origin它是不是"拉取远端所有分支的代码到本地"?](#2)git fetch origin它是不是“拉取远端所有分支的代码到本地”?)
[3.3 git pull origin xxx ------ fetch + merge/rebase(本地分支会变)](#3.3 git pull origin xxx —— fetch + merge/rebase(本地分支会变))
[3.4 git push origin feature/driver ------ 改远端仓库](#3.4 git push origin feature/driver —— 改远端仓库)
[3.5 本地分支 vs 远端分支关系图](#3.5 本地分支 vs 远端分支关系图)
[1) 用一个真实场景解释](#1) 用一个真实场景解释)
[3.6 表格总结](#3.6 表格总结)
[四、VSCode 左侧"三圆圈 / 源代码管理"到底什么时候变化?](#四、VSCode 左侧“三圆圈 / 源代码管理”到底什么时候变化?)
[4.1 你刚改完代码(未 add / commit)](#4.1 你刚改完代码(未 add / commit))
[4.2 执行了 git add](#4.2 执行了 git add)
[4.3 执行了 git commit](#4.3 执行了 git commit)
[4.4 执行 git push](#4.4 执行 git push)
Git 学习笔记整理链接:
Git分支实操指南:本地学习分支创建+远程同步避坑全解析-CSDN博客
https://blog.csdn.net/m0_58954356/article/details/155935939Git 中新建学习分支 + 暂存修改 + VSCode 可视化查看改动(超详细教程)_vscode git暂存的内容在哪里可以看到-CSDN博客
https://blog.csdn.net/m0_58954356/article/details/154744622VSCode + Git 全流程可视化操作指南(超详细保姆级)_vscode git-CSDN博客
https://blog.csdn.net/m0_58954356/article/details/154545616Git 指令速查(含常见工作流 + 易错点)_git指令速查-CSDN博客
https://blog.csdn.net/m0_58954356/article/details/154072623
一、前言
在真实的团队开发中,最常见的不是"不会写代码",而是:
-
自己在本地分支上已经改了一堆代码
-
公司远端分支(同事)也提交了新代码
-
这时你需要 既保留自己的修改,又同步公司的更新
很多人 Git 用了很久,却仍然在下面几个问题上反复踩坑:
-
工作区、暂存区、本地仓库到底有什么区别?
-
origin/feature/driver到底是什么?是不是一个分支? -
为什么
git commit之后 VSCode 就显示"领先远端"? -
git fetch、git pull、git merge、git rebase到底怎么选?
本文用一个真实工程分支 feature/driver 贯穿全文 ,从最底层的 Git 模型开始,带你一步步建立清晰、可控、不翻车的 Git 心智模型。
二、Git 的三个核心区域:工作区 / 暂存区 / 本地仓库
理解这三者,是理解一切 Git 行为的前提。
2.1 Git 三个区域的介绍及结构示意图
工作区、暂存区、版本库
Git 本地数据管理,大概可以分为三个区,工作区,暂存区和版本库。
- 工作区(Working Directory): 是直接编辑的地方,肉眼可见,直接操作。
- 暂存区(Stage 或 Index): 数据暂时存放的区域。
- 版本库(commit History): 存放已经提交的数据,push 的时候,就是把这个区的数据 push 到远程git仓库了。

1)工作区(Working Tree)
你正在 VSCode 里编辑的文件
假设你当前所在分支是:
bash
feature/driver
你在 VSCode 中修改了:
bash
src/driver/driver_node.cpp
此时执行:
bash
git status
会看到:
bash
modified: src/driver/driver_node.cpp
含义:
代码只存在于你的工作区
Git 只是"发现你改了"
还没决定是否要保存这次修改
2)暂存区(Index / Staging Area)
你"决定要提交"的改动集合
bash
git add src/driver/driver_node.cpp
再次查看状态:
bash
git status
bash
Changes to be committed:
modified: src/driver/driver_node.cpp
含义:
-
Git 已经记住:
「下一次 commit,我要把这个文件算进去」
-
但还没有形成提交记录
3)本地仓库(Local Repository)
一次真正的 Git 提交(commit)
bash
git commit -m "feat(driver): 优化控制逻辑"
此时发生了三件非常关键的事:
-
生成了一个 commit(有 commit id)
-
提交属于 本地分支
feature/driver -
公司远端仓库完全不知道这件事
总计:
git commit ≠ 公司已经收到你的代码
git commit 只是把修改保存到了"本地仓库"。
2.2 git 命令对比
bash
git diff 工作区 vs 暂存区
git diff head 工作区 vs 版本库
git diff --cached 暂存区 vs 版本库
- 起初刚开始,什么操作都没有,三个区的数据是一致的,执行 git diff 命令都为空
- 编辑文件增加代码,现在
工作区内容发生变化,暂存区和版本库内容不变。- 执行git add 操作后,修改同步到
暂存区,现在工作区和暂存区数据一致。- 执行git commit 操作后,修改已经同步到
版本库,三区数据再次保持一致。
2.3 三大分区的好处

1)开发例子
通过 checkout / stash / reset 等命令,通过不同的参数搭配使用,可以在工作区,暂存区和版本库之间,轻松进行数据的来回切换。
bash
1. 修改了多个文件,在不放弃任何修改的情况下,其中一个文件不想提交,如何操作?
(没add操作 : git add 想提交的文件
已经add: git reset --soft 将文件从暂存区回滚到工作区,重新add)
2. 修改到一半的文件,突然间不需要或者放弃修改了,怎么恢复未修改前文件?
(git checkout)
3. 代码写一半,被打断去做其他功能开发,未完成代码保存?
(git stash 提交到缓存区)
4. 代码写一半,发现忘记切换分支了?
(git stash & git checkout)
5. 代码需要回滚了?------ 含义就是撤销之前的 git commit
(git reset)
2)命令作用
bash
1. git reset --soft commit_xxid
暂存区->工作区
将commit_xxid提交从暂存区回滚到工作区
2. git reset --mixed commit_xxid
版本库->暂存区
将commit_xxid提交从版本库回滚到暂存区
3. git reset --hard commit_xxid
版本库->暂存区->工作区
三个区都清除commit_xxid提交
三、远端引用:origin/feature/driver 到底是什么?
这是 Git 新手和中级开发者最容易混淆的概念。
3.1 origin 是什么?
origin不是"固定关键字",它只是 你本地对某个远端仓库起的名字(remote 名称)。你
git clone ...的时候,Git 默认把远端仓库命名为origin。所以大家写
git fetch origin,本质是:
"从名为 origin 的远端仓库,把最新状态同步到本地"
1)查看远端:
你可以用下面命令看自己有哪些远端:
bash
git remote -v
通常会看到:
bash
origin git@gitee.com:xxx/robot_driver.git (fetch)
origin git@gitee.com:xxx/robot_driver.git (push)
这并不是两个仓库,而是:
| 字段 | 含义 |
|---|---|
origin |
远端仓库的名字(remote name) |
git@...git |
远端仓库的地址 |
(fetch) |
从这个地址拉代码 |
(push) |
向这个地址推代码 |
2)为什么要区分 fetch 和 push?
因为 Git 允许你"拉"和"推"用不同的地址。
虽然大多数人这两个地址是一样的,但在工程里这是一个非常重要的设计。
当然也有可能只有拉或者推一个功能,具体看 git remote -v 显示的结果
3)多远端(origin + upstream)
常见于 GitHub / Gitee fork 模型:
bash
origin git@github.com:yourname/project.git (fetch)
origin git@github.com:yourname/project.git (push)
upstream git@github.com:company/project.git (fetch)
upstream git@github.com:company/project.git (push)
含义:
origin:你自己的仓库
upstream:公司/官方仓库通常:
从
upstreamfetch向
originpush
4)总结
fetch和push并不是命令,而是 远端仓库地址的使用方向。Git 允许为同一个远端仓库配置不同的"拉取地址"和"推送地址",
以适应 fork、多仓库、权限隔离等复杂协作场景。
因此,当我们执行git fetch origin时,Git 实际上是使用
origin标记的 fetch 地址 ,从远端仓库同步最新状态到本地的
origin/xxx跟踪分支;而当我们执行
git push origin feature/driver时,Git 使用的是
origin对应的 push 地址 ,把本地提交推送到远端仓库。
origin是远端仓库的名字,
(fetch)和(push)表示 这个远端仓库地址被用于"拉"还是"推"。两者可以相同,也可以不同,这是 Git 支持复杂团队协作的基础能力。
3.2 git fetch origin 详细解析:
1)git fetch origin 会把什么拉到本地?是所有分支吗?
默认行为:更新"远端跟踪引用"(remote-tracking branches)
执行:
bash
git fetch origin
他所做的事情:
bash
远端仓库(只读)
↓ 拉取
本地的 origin/xxx(远端跟踪分支)
可以理解为:
"我本地刷新一下对公司仓库的认知"
Git 会做的是:
去远端
origin看哪些分支有新提交然后更新你本地的这些引用:
origin/dev
origin/feature/driver
origin/main......
注意:它更新的是这些 origin/xxx 引用(快照),不是直接改你的本地分支。

2)git fetch origin它是不是"拉取远端所有分支的代码到本地"?
严格来说分两层理解:
(1)它会更新"所有远端分支的引用"吗?
- 通常是会的 (取决于你 remote 的
fetch配置,默认是匹配所有分支)。
你可以看配置:
bash
git remote show origin
里面会有类似:
-
"Remote branches: ..."
-
"Local branches configured for 'git pull' ..."
-
以及 fetch 的映射规则
(2)它会把所有分支都变成本地分支吗?
-
不会。
git fetch origin只会更新origin/xxx这些"远端跟踪分支",并不会自动创建本地分支xxx。
比如远端有 feature/A:
-
fetch 后你会有
origin/feature/A -
但你本地不一定有
feature/A这个可切换开发的分支
要创建本地分支,一般这样:
bash
git switch -c feature/A origin/feature/A
3)只想更新一个分支行不行?
当然可以(更省流量、更明确):
bash
git fetch origin feature/driver
这会更新:
origin/feature/driver但不会(特意)更新其它
origin/xxx。
4)总结
origin只是远端仓库的默认名字。
git fetch只会更新本地的远端跟踪分支(如origin/feature/A),并不会修改本地分支。
git fetch origin的作用是:从远端仓库同步最新状态到本地的origin/xxx跟踪引用(快照),通常会更新远端的多个分支引用,但不会直接修改你的本地分支,更不会自动生成所有本地分支。本地分支是否与远端分支产生关系,取决于你是否显式执行
merge或rebase操作。
3.3 git pull origin xxx ------ fetch + merge/rebase(本地分支会变)
bash
git pull origin feature/driver
等价于:
bash
git fetch origin
git merge origin/feature/driver
📌 特点:
-
❌ 不直接改远端仓库
-
✅ 会改你的本地分支(merge / rebase)
-
⚠️ 是否产生新提交,取决于 merge 还是 rebase
可以理解为:
"先看看公司改了啥,再把它合进我当前分支"
3.4 git push origin feature/driver ------ 改远端仓库
bash
git push origin feature/driver
📌 特点:
-
❌ 不修改你的远端跟踪分支(它们是本地的)
-
✅ 真正把你的提交发送到远端仓库
-
❌ 不会自动帮别人合代码
可以理解为:
"把我本地的提交,推送给公司服务器"
3.5 本地分支 vs 远端分支关系图

1) 用一个真实场景解释
现在我们有三种"driver 分支":
| 名称 | 含义 |
|---|---|
feature/driver |
你正在开发的 本地分支 |
origin/feature/driver |
远端分支在你本地的只读快照 |
远端仓库的 feature/driver |
公司服务器上的真实分支 |
2)关键结论
origin/feature/driver不是一个你能直接开发的分支它只是:
「公司远端feature/driver分支,在你本地的一份快照引用」
3)那它什么时候会更新?
只有当你执行下面命令之一时:
bash
git fetch origin
或
bash
git pull
Git 才会做这件事:
bash
远端仓库 feature/driver
↓
更新本地的 origin/feature/driver
如果你没有 fetch / pull:
origin/feature/driver可能是几小时前、甚至昨天的状态你看到的并不是公司最新代码
3.6 表格总结
| 命令 | 是否改本地 | 是否改远端 |
|---|---|---|
git fetch |
✅ 更新 origin/xxx | ❌ |
git pull |
✅ 更新当前分支 | ❌ |
git push |
❌ | ✅ |
四、VSCode 左侧"三圆圈 / 源代码管理"到底什么时候变化?
这是你问的一个非常关键的问题。
结论先给(可以直接写博客):
VSCode 左侧的 Git 状态提示,
基于的是「本地分支 vs 远端跟踪分支(origin/xxx)」的差异,而不是"是否已经 git push"。
4.1 你刚改完代码(未 add / commit)
-
VSCode 显示文件变更数量
-
表示:工作区有改动
4.2 执行了 git add
-
VSCode 显示:
-
"已暂存的更改"
-
"更改"
-
-
此时仍然没有提交
4.3 执行了 git commit
bash
git commit -m "xxx"
此时 VSCode 会显示:
- ⬆️ 向上箭头 + 数字
📌 含义是:
本地
feature/driver分支
比origin/feature/driver领先 N 个提交
⚠️ 注意:
-
这一步就已经有"分支差异"了
-
即使你还没
git push,VSCode 也已经知道你领先远端
4.4 执行 git push
bash
git push origin feature/driver
-
⬆️ 提示消失
-
本地与远端完全对齐
五、总结
Git 是分层的,而不是一步到位的
-
VSCode 改代码 → 工作区
-
git add → 暂存区
-
git commit → 本地仓库(已经领先远端)
-
git push → 远端仓库(公司才真正看到)
origin/xxx永远只是远端的"快照",
fetch 是认知同步,merge/rebase 才是代码合并。
总结git基本的工作流程如下:
- 在工作目录中修改(此处修改包含了创建和删除)文件;
- 暂存文件,将文件add放入暂存区域;
- 提交更新,找到暂存区域的文件,将暂存区的文件commit到版本库;
- 如果工作区的文件改乱了(包括了误删、误改),想回到上一版本,就可以使用git checkout 命令将版本库中的文件检出到工作区将本次更改discard(覆盖)掉。