Git 工作区、暂存区、仓库、远端同步完全指南:从 restore、reset 到 fetch、pull 的正确使用姿势

一、为什么需要理解 Git 状态?

很多开发人员日常使用 Git:

复制代码
git add .
git commit
git pull

但是遇到问题:

  • 修改代码想撤销;

  • add 后想取消;

  • commit 提错想回滚;

  • 分支乱了想恢复;

  • 本地和远端不一致;

经常不知道该用:

复制代码
git checkout .

还是:

复制代码
git reset --hard

还是:

复制代码
git fetch

还是:

复制代码
git pull

原因是:

Git 实际管理的是多个状态区域。


二、理解 Git 四个核心区域

Git 可以理解为:

复制代码
                git commit

暂存区 -----------------> 本地仓库
(Index)                  (Repository)

   ^
   |
git add

   ^
   |
工作区
(Working Tree)


本地仓库

   |
   |
git fetch

   v

远程跟踪分支
(origin/master)

   |
   |
merge/rebase

   v

本地分支
(master)

1. 工作区 Working Tree

就是你正在编辑的代码。

例如:

复制代码
chrome/browser/foo.cc

修改:

复制代码
xxx();

此时:

复制代码
git status

看到:

复制代码
modified: foo.cc

代码只存在工作区。


2. 暂存区 Index

执行:

复制代码
git add foo.cc

代码进入暂存区。

表示:

下一次 commit 我要提交这个版本。


3. 本地仓库 Repository

执行:

复制代码
git commit -m "fix xxx"

生成 commit。

例如:

复制代码
A---B---C

4. 远程跟踪分支 origin/master

执行:

复制代码
git fetch

Git 更新:

复制代码
origin/master

它代表:

Git 当前知道的远端状态。


三、git status:查看当前状态

所有操作前:

先:

复制代码
git status

例如:

复制代码
On branch master

Changes not staged:

 modified:
   foo.cc

表示:

工作区修改。


如果:

复制代码
Changes to be committed:

 modified:
   foo.cc

表示:

已经 git add。


如果:

复制代码
nothing to commit

表示:

当前干净。


四、git diff:查看修改内容

查看工作区修改

复制代码
git diff

例如:

复制代码
+ new code
- old code

查看暂存区修改

复制代码
git diff --cached

查看:

复制代码
git add

后的内容。


五、git add:把修改放入暂存区

例如:

复制代码
git add foo.cc

或者:

复制代码
git add .

含义:

复制代码
工作区

   |
   |
   v

暂存区

注意:

add 不会提交。


六、git restore:撤销文件修改

新版 Git 推荐:

替代:

复制代码
git checkout .

1. 恢复工作区

例如:

修改:

复制代码
foo.cc

执行:

复制代码
git restore foo.cc

效果:

复制代码
工作区恢复到暂存区状态

全部恢复:

复制代码
git restore .

七、git checkout .:旧版恢复方式

以前常用:

复制代码
git checkout .

作用:

恢复工作区。

例如:

复制代码
commit:

A---B---C


修改:

foo.cc

执行:

复制代码
git checkout .

恢复:

复制代码
A---B---C

但是:

它不能删除 commit。

例如:

复制代码
A---B---C---D

D 已经提交。

执行:

复制代码
git checkout .

没有效果。


八、git reset:移动 HEAD 和恢复状态

reset 是 Git 最重要命令。

形式:

复制代码
git reset [模式] [目标]

三个模式:

复制代码
soft
mixed
hard

九、git reset --soft

用途:

撤销 commit,但是保留修改。

例如:

复制代码
A---B---C
        ^
      错误commit

执行:

复制代码
git reset --soft HEAD~1

结果:

复制代码
A---B

但是:

修改仍然在暂存区。

适合:

  • commit message 写错;

  • 想重新提交。


十、git reset --mixed(默认)

例如:

复制代码
git reset HEAD~1

等价:

复制代码
git reset --mixed HEAD~1

效果:

撤销 commit。

但是:

代码回到工作区。

结果:

复制代码
commit:

A---B


working tree:

修改存在

适合:

想重新 add。


十一、git reset --hard

最强恢复。

执行:

复制代码
git reset --hard

会恢复:

复制代码
HEAD
+
Index
+
Working Tree

全部清空。

例如:

复制代码
A---B---C

修改:

复制代码
foo.cc

执行:

复制代码
git reset --hard

恢复:

复制代码
A---B---C

删除最后一次 commit

复制代码
git reset --hard HEAD~1

例如:

复制代码
A---B---C---D

变:

复制代码
A---B---C

D 消失。


十二、git stash:临时保存修改

开发中经常:

正在改代码:

复制代码
feature A

突然需要切分支。

可以:

复制代码
git stash

保存。

恢复:

复制代码
git stash pop

查看:

复制代码
git stash list

十三、git clean:删除未跟踪文件

例如:

编译产生:

复制代码
out/
tmp/
xxx.log

Git 不管理。

查看:

复制代码
git clean -n

预览。

删除:

复制代码
git clean -f

删除未跟踪文件。


十四、git branch:备份分支

危险操作前:

推荐:

复制代码
git branch backup_before_reset

例如:

当前:

复制代码
master

A---B---C---D

创建:

复制代码
backup_before_reset

A---B---C---D


master

A---B---C---D

之后:

复制代码
git reset --hard HEAD~1

即使后悔:

还有备份。


十五、git reflog:找回误删 commit

很多人以为:

复制代码
git reset --hard

之后 commit 永久消失。

实际上:

Git 保存 HEAD 移动历史。

查看:

复制代码
git reflog

例如:

复制代码
HEAD@{0}: reset
HEAD@{1}: commit D

恢复:

复制代码
git reset --hard HEAD@{1}

这是 Git 的后悔药。


十六、git fetch:只同步远端信息

这是很多人最容易误解的命令。

执行:

复制代码
git fetch origin

不会:

  • 修改代码;

  • 合并分支;

  • 改 HEAD。

只更新:

复制代码
origin/master

例如:

远端:

复制代码
A---B---C---D

本地:

复制代码
A---B---C

fetch 后:

复制代码
origin/master:

A---B---C---D


master:

A---B---C

十七、git merge:合并代码

例如:

复制代码
master:

A---B


feature:

A---B---C

切回 master:

复制代码
git merge feature

结果:

复制代码
A---B---M
       \
        C

产生 merge commit。


十八、git rebase:重新整理历史

例如:

复制代码
master:

A---B---C


feature:

A---B---D

rebase:

复制代码
git rebase master

变:

复制代码
A---B---C---D'

历史更线性。


十九、git pull:fetch + merge/rebase

默认:

复制代码
git pull

等价:

复制代码
git fetch

+

git merge

如果配置:

复制代码
git pull --rebase

则:

复制代码
fetch

+

rebase

二十、如何让本地完全和远端一致?

这是开发中最常见场景。

例如:

本地:

复制代码
A---B---C---D

远端:

复制代码
A---B---C---E

目标:

丢弃 D。

正确:

第一步

复制代码
git fetch origin

得到:

复制代码
origin/master

A---B---C---E

第二步

复制代码
git reset --hard origin/master

结果:

复制代码
master:

A---B---C---E


origin/master:

A---B---C---E

完全一致。


二十一、Chromium 大仓库实际使用建议

Chromium:

复制代码
src/
chrome/
content/
third_party/

提交和回滚频繁。

场景1:刚改几个 cpp,发现错了

使用:

复制代码
git restore .

场景2:已经 git add

使用:

复制代码
git reset

取消 add。

如果全部不要:

复制代码
git reset --hard

场景3:实验 commit 错了

先:

复制代码
git branch backup_bad_commit

然后:

复制代码
git reset --hard HEAD~1

场景4:分支完全乱掉

例如:

复制代码
zero_132

A---B---C---D


origin/zero_132

A---B---C

执行:

复制代码
git fetch origin

git reset --hard origin/zero_132

二十二、Git 常用恢复命令速查表

目的 命令
查看状态 git status
查看修改 git diff
加入暂存区 git add
提交 git commit
撤销文件修改 git restore .
旧版撤销 git checkout .
取消 add git reset
撤销commit保留代码 git reset --soft HEAD~1
撤销commit代码不要 git reset --hard HEAD~1
临时保存修改 git stash
删除未跟踪文件 git clean -f
同步远端状态 git fetch
拉取并合并 git pull
合并分支 git merge
整理历史 git rebase
查看历史移动 git reflog
完全同步远端 git fetch + git reset --hard origin/xxx

总结

Git 命令不要死记,要理解它操作哪个区域:

复制代码
git restore
        ↓
恢复文件


git add
        ↓
工作区 → 暂存区


git commit
        ↓
暂存区 → 本地仓库


git fetch
        ↓
远端 → origin分支


git merge/rebase
        ↓
origin分支 → 本地分支


git reset
        ↓
移动HEAD,调整状态

最终记住:

  • restore 管文件

  • add 管暂存

  • commit 管历史

  • fetch 管远端状态

  • pull 管同步合并

  • reset 管回滚

  • reflog 管后悔

掌握这些命令,基本可以解决日常开发(包括 Chromium 大型项目开发)中绝大多数 Git 恢复、回滚、同步问题。

相关推荐
炸膛坦客13 小时前
Git 和 GitHub:(九)修改本地仓库内容并推送到远程仓库(关联/克隆)
git·github
To_OC15 小时前
一次 git reset 翻车,让我彻底分清了 hard 和 soft,也想通了 Vibe Coding 的本质
git·程序员·vibecoding
Ai拆代码的曹操15 小时前
Git 集成:AI 代理中的版本控制工作流设计
大数据·git·elasticsearch
lazy H16 小时前
Git clone 怎么用?克隆项目及常见问题完整教程
大数据·git·后端·学习·搜索引擎·github
m0_7436975918 小时前
关于ftp与SELinux的冲突问题
git·github
前进的程序员18 小时前
VS Code Git 工作树:多分支并行开发体验
git·vs code·git工作树
半夜修仙19 小时前
二.Git分支管理
git
六bring个六1 天前
git使用笔记
笔记·git
最后冰吻free1 天前
git 不新增commit修改中间commit对应的文件
git