Git 四大区
Git 内部有 4 个工作区域:
| 区域 | 英文 | 说明 |
|---|
| 工作区 | Working Directory | 本地写代码的目录 |
| 暂存区 | Staging Area / Index | git add 后的"准备提交"区 |
| 本地仓库 | Local Repository | git commit 后的本地历史 |
| 远程仓库 | Remote Repository | git push 后的云端历史 |
1
2
3
4
| 工作区(写代码)
→ git add → 暂存区(准备提交) git stash 隐藏更改
→ git commit → 本地仓库(本地保存)
→ git push → 远程仓库(云端保存)
|
git stash 是隐藏工作区的更改到栈里(不提交到任何区),方便你拉最新代码或者切换任务。
git stash:紧急任务切换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 当前正在改功能 A,写了一半
# 突然来了 bugB 要修
# 1. 把功能 A 暂存起来
git stash
# 2. 拉最新代码
git pull origin master
# 3. 切到 bug 分支修
git checkout -b fix-bugB
# ... 改完、commit、push、merge ...
# 4. 切回功能 A 分支
git checkout feature-A
# 5. 恢复暂存
git stash pop
# 6. 继续功能 A 开发
|
stash 是栈结构,支持多个:
1
2
3
4
5
| git stash # 暂存当前
git stash list # 查看所有 stash
git stash apply stash@{0} # 应用指定 stash
git stash drop stash@{0} # 删除指定 stash
git stash pop # 应用并删除最近一个
|
git restore:撤销本地的编辑
1
2
3
4
5
6
7
8
| # 撤销工作区的修改(未 add)
git restore 文件1 文件2
# 撤销暂存(已 add,但未 commit)
git restore --staged 文件1 文件2
# 撤销工作区 + 暂存
git restore --staged --worktree 文件1
|
IDEA 中的回滚:
- VCS → Git → Restore File:相当于
git restore - Local History → Show History:IDEA 自动保存的本地历史
- VCS → Git → Reset HEAD:回滚所有未提交修改
IDEA 的 reset 默认不删除"已提交"的文件副本,所以回滚不删除文件——已跟踪的文件从绿变红。
git HEAD:指针机制
HEAD 是当前分支最新提交的"指针"。
HEAD^:上一个提交(HEAD~1)HEAD^^:上上一个(HEAD~2)HEAD@{2}:reflog 中第 3 个 HEAD 位置(用于找回 reset 掉的 commit)
1
2
3
4
5
6
7
8
9
10
| # 查看 reflog
git reflog
# 把 HEAD 切到上一个提交
git checkout HEAD^
# 恢复误删的分支
git reflog
# 找到 commit SHA
git checkout -b recovered-branch <SHA>
|
git restore vs git checkout vs git reset 三者区别
| 命令 | 作用 |
|---|
git restore <file> | 撤销工作区/暂存区的修改(Git 2.23+ 新命令) |
git checkout -- <file> | 同上(旧语法) |
git reset --soft HEAD^ | 撤销 commit,保留暂存 |
git reset --mixed HEAD^ | 撤销 commit + 暂存,保留工作区 |
git reset --hard HEAD^ | 撤销 commit + 暂存 + 工作区(危险,慎用) |
IDEA 的 Shelve 搁置
什么是 Shelve
IDEA 的 Shelve(搁置) 是 JetBrains IDE 独有的功能,定位:
【任务切换神器】
不是为了拉代码,是为了 把写一半的功能收起来,去干别的事。
它像一个临时的、私有的、微型补丁分支——不污染 git 历史,跨分支切换时不被带走。
使用场景
1
2
3
4
5
6
7
8
| 正在写【功能 A】,写了一半
突然来了【紧急 bugB】要修!
不想提交 A,也不想删 A
→ 把 A 搁置(Shelve)起来
→ 工作区变干净
→ 去修 bugB
→ 修完把 A 恢复回来继续
|
操作步骤
- Git → Uncommitted Changes → Shelve Changes…
- 命名(建议"功能A-2026-06-04")
- 工作区立刻变干净
- 切到 bugB 分支修
- 修完提交
- Git → Uncommitted Changes → Unshelve… 选之前搁置的名字
- 恢复继续功能 A
与 git stash 的区别:Shelve 是 IDE 本地的,跨电脑不共享;stash 是 git 仓库级别的,commit 后可推送。
git-crypt:透明加密
团队项目经常需要提交敏感配置(.env、数据库密码),但又怕直接 push 到公网。git-crypt 是 Git 的透明加密插件:
- 文件本地是明文
git push 后云端是密文- 团队成员对称加密:每个有 GPG key 的人都能解密
1
2
3
4
5
6
7
8
| # Linux 下载
wget https://github.com/AGWA/git-crypt/releases/download/0.7.0/git-crypt-0.7.0-linux-x86_64
# Windows 下载
wget https://github.com/AGWA/git-crypt/releases/download/0.7.0/git-crypt-0.7.0-x86_64.exe
# 放到 PATH
mv git-crypt-0.7.0-x86_64 /usr/local/bin/git-crypt
|
配置 .gitattributes
1
2
3
4
5
| # .gitattributes
.env filter=git-crypt diff=git-crypt
config/prod.yaml filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt
*.pem filter=git-crypt diff=git-crypt
|
初始化
1
2
3
| git-crypt init
git add .gitattributes
git commit -m "Add git-crypt config"
|
添加 GPG 协作者
1
2
3
4
5
6
7
8
9
10
| # 协作者生成 GPG key
gpg --gen-key
# 上传公钥到 keyserver
gpg --keyserver keys.openpgp.org --send-keys <KEY_ID>
# 信任他
git-crypt add-gpg-user <GPG_USER_ID>
# 协作者 clone 后 unlock
git-crypt unlock
|
常用命令速查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # 远程分支
git branch -r
# 检出远程分支
git checkout release_V3.1.4
# 关联分支
git branch --set-upstream-to=origin/master master
# 查看单个文件的历史
git log -p -- path/to/file
# 暂存部分文件
git add -p
# y/n/q/a/d 等交互式命令
# 撤销合并
git revert -m 1 <merge_commit_sha>
# 修改最后一次 commit
git commit --amend
# 改作者邮箱(全局)
git filter-branch --env-filter 'GIT_AUTHOR_EMAIL=xxx'
|
下一步
- 想用 GitHub Actions 自动化 CI,看 2017-12-08《K8s Ingress 实战》
- 想用 monorepo 工具(pnpm + turbo)管理多项目,看 2020-04-15《FSS 全栈脚手架》
参考资料
- Pro Git 简体中文:https://git-scm.com/book/zh/v2
- git-crypt:https://github.com/AGWA/git-crypt
- IDEA Shelve 文档:https://www.jetbrains.com/help/idea/shelving-and-unshelving-changes.html