Git 存储模型全解¶
一、三个核心区域¶
| 区域 | 别名 | 触发命令 | 存储位置 |
|---|---|---|---|
| 工作区 | Working Directory | 直接编辑文件 | 硬盘上的项目目录 |
| 暂存区 | Staging Area / Index | git add |
.git/index |
| 本地仓库 | Local Repository | git commit |
.git/objects/ |
二、标准流程图¶
flowchart LR
A[🖊️ 工作区\nWorking Directory] -->|git add| B[📋 暂存区\nStaging Area]
B -->|git commit| C[🗄️ 本地仓库\nLocal Repository]
C -->|git push| D[☁️ 远程仓库\nRemote]
C -->|git checkout / git restore| A
B -->|git restore --staged| A
D -->|git pull / git fetch| C
三、各区域详解¶
1. 工作区(Working Directory)¶
你在磁盘上直接看到、编辑的文件。
# 查看工作区与暂存区的差异
git diff
# 丢弃工作区的修改(危险!不可恢复)
git restore <file>
2. 暂存区(Staging Area)¶
git add 之后,改动进入暂存区,等待被 commit。
# 将文件加入暂存区
git add <file>
git add . # 所有改动
# 查看暂存区与上次 commit 的差异
git diff --cached
# 将文件从暂存区撤回工作区(保留改动)
git restore --staged <file>
3. 本地仓库(Local Repository)¶
git commit 之后,改动生成一个不可变的 commit 对象。
# 提交
git commit -m "feat: 新增登录功能"
# 修改最近一次 commit(未 push 前)
git commit --amend
# 回退到某个 commit,保留改动在工作区
git reset --soft HEAD~1
# 回退到某个 commit,保留改动在工作区(不保留暂存)
git reset --mixed HEAD~1 # 默认行为
# 回退到某个 commit,丢弃所有改动(危险!)
git reset --hard HEAD~1
四、git status 看懂三个区域¶
git status
On branch main
Changes to be committed: ← 暂存区(已 git add,待 commit)
modified: src/app.py
Changes not staged for commit: ← 工作区(已修改,未 git add)
modified: README.md
Untracked files: ← 工作区(新文件,从未 git add)
temp.log
五、特殊情况:git stash¶
是什么?¶
git stash 将工作区 + 暂存区的改动临时打包成一个游离的 commit,
塞入本地 .git/ 中一个独立的栈结构,不属于任何分支。
stash 流程图¶
flowchart LR
A[🖊️ 工作区] --"git stash"--> S
B[📋 暂存区] --"git stash"--> S
S["📦 Stash 栈\n.git/refs/stash\n游离于所有分支之外"]
S --"git stash pop\ngit stash apply"--> A
stash 存储位置¶
.git/
├── refs/stash ← 指向最新一条 stash
├── logs/refs/stash ← 所有 stash 的历史记录
└── objects/ ← stash 的实际内容(commit 对象)
注意事项¶
| 特性 | 说明 |
|---|---|
| 是否属于分支 | ❌ 不属于任何分支 |
| git push 会带走吗 | ❌ 不会,仅存本地 |
| 默认包含 untracked 文件吗 | ❌ 不包含 |
| 数据结构 | 栈(后进先出) |
常用命令¶
git stash # 存储工作区+暂存区改动
git stash -u # 同上,额外包含 untracked 文件
git stash -a # 同上,额外包含 .gitignore 的文件
git stash list # 查看所有 stash
# stash@{0}: WIP on main: abc1234 上次的提交信息
# stash@{1}: WIP on dev: def5678 ...
git stash pop # 取出最新一条(取出后从栈中删除)
git stash apply stash@{1} # 取出指定一条(保留在栈中)
git stash drop stash@{0} # 删除指定一条
git stash clear # 清空所有 stash
六、完整区域总览¶
flowchart TB
W[🖊️ 工作区]
S[📋 暂存区]
L[🗄️ 本地仓库]
R[☁️ 远程仓库]
ST[📦 Stash 栈]
W -->|"git add"| S
S -->|"git commit"| L
L -->|"git push"| R
R -->|"git fetch"| L
R -->|"git pull"| W
L -->|"git restore / checkout"| W
S -->|"git restore --staged"| W
W -->|"git stash"| ST
S -->|"git stash"| ST
ST -->|"git stash pop/apply"| W
style ST fill:#f5a623,color:#000
style W fill:#4a90d9,color:#fff
style S fill:#7ed321,color:#000
style L fill:#9b59b6,color:#fff
style R fill:#e74c3c,color:#fff
七、速查记忆卡¶
改了文件 → 工作区 (git diff)
git add → 暂存区 (git diff --cached)
git commit → 本地仓库 (git log)
git push → 远程仓库
git stash → 游离的临时栈(不属于任何分支,push 带不走!)