Git 命令行指南:日常流程、分支策略与急救
适用场景:日常提交、分支管理、代码回退、冲突解决、协作流程。
适用版本:Git 2.43+;
switch、restore、worktree和bisect均使用当前官方语法。最后核对:2026-07-30
30 秒快速路径
git status --short
git diff
git log --oneline --graph -10
目录
- 核心概念
- 日常工作流
- 分支管理
- worktree — 同时处理多个分支
- 查看历史
- bisect — 二分定位问题提交
- 撤销与回退
- stash — 临时保存
- rebase — 变基
- 冲突解决
- 远程操作
- reflog — 终极急救
- .gitignore 速查
- Git 配置
核心概念
三个区域
工作区 (Working Directory) 暂存区 (Staging/Index) 仓库 (Repository)
你编辑的文件 ──add──→ 准备提交的 ──commit──→ 永久记录
←─restore── ←──reset──
文件状态
| 状态 | 含义 |
|---|---|
| Untracked | 新文件,Git 不跟踪 |
| Modified | 已跟踪文件被修改 |
| Staged | 已 add 到暂存区,等待 commit |
| Committed | 已提交到仓库 |
日常工作流
# ═══ 最常用的 5 个命令 ═══
git status # 查看当前状态(必须养成的习惯)
git add . # 暂存所有修改
git diff --cached # 提交前检查暂存内容,避免带入密钥或无关文件
git commit -m "feat: 描述" # 提交
git pull # 拉取远程更新
git push # 推送到远程
# ═══ 精细化 add ═══
git add file.ts # 暂存指定文件
git add src/ # 暂存整个目录
git add -p # 交互式暂存(逐块选择,最精细)
git add -u # 只暂存已跟踪文件的修改(不含新文件)
# ═══ commit 技巧 ═══
git commit -m "fix: 修复登录跳转" # 一行消息
git commit # 打开编辑器写详细消息
git commit -am "quick fix" # add + commit 合并(只对已跟踪文件)
git commit --amend # 修改上一次提交的消息或内容
git commit --amend --no-edit # 把新暂存的文件追加到上次提交
# amend 会重写提交 ID;已经推送或被他人基于其开发时不要直接使用
Commit 消息规范
<type>: <description>
type 常用值:
feat 新功能
fix 修复 bug
docs 文档变更
style 格式调整(不影响逻辑)
refactor 重构
perf 性能优化
test 测试
chore 杂务(构建、依赖等)
分支管理
# ═══ 基础操作 ═══
git branch # 列出本地分支
git branch -a # 列出所有分支(含远程)
git branch feature/login # 创建分支
git switch feature/login # 切换分支
git switch -c feature/login # 创建 + 切换
# 旧版 Git / 旧文档中常见,仍可用
git checkout feature/login
git checkout -b feature/login
# ═══ 合并 ═══
git switch main # 先切到目标分支
git merge feature/login # 把 feature/login 合并进来
git merge --no-ff feature/x # 强制产生合并提交(保留分支历史)
# ═══ 删除 ═══
git branch -d feature/login # 删除已合并的分支
git branch -D feature/login # 强制删除(未合并也删)
git push origin --delete feature/login # 删除远程分支
# ═══ 重命名 ═══
git branch -m old-name new-name
分支命名规范
feature/login-page # 新功能
fix/header-overflow # 修复
hotfix/prod-crash # 紧急修复
refactor/api-layer # 重构
chore/update-deps # 杂务
worktree — 同时处理多个分支
git worktree 可以让同一仓库同时拥有多个工作目录,适合当前分支做到一半时紧急修复、并行跑测试,避免频繁 stash 和切换。
git worktree list
# 从 origin/main 创建 hotfix 分支,并检出到相邻目录
git worktree add -b hotfix ../project-hotfix origin/main
# 已存在的分支可直接指定
git worktree add ../project-release release/1.2
# 完成后先确认目录内没有需要保留的修改
git -C ../project-hotfix status
git worktree remove ../project-hotfix
# 清理已经被手工删除的失效记录
git worktree prune --dry-run
git worktree prune
同一个本地分支通常不能同时检出到两个 worktree。不要直接删除 worktree 目录;优先使用 git worktree remove,以便同步清理 Git 元数据。
查看历史
# ═══ log ═══
git log # 完整日志
git log --oneline # 单行简洁模式
git log --oneline -10 # 最近 10 条
git log --oneline --graph # 带分支图
git log --stat # 显示每次提交修改了哪些文件
git log -p # 显示具体 diff
# ═══ 过滤 ═══
git log --author="Example User" # 按作者
git log --since="2024-01-01" # 按日期
git log --grep="fix" # 按提交消息搜索
git log -- src/App.tsx # 某个文件的历史
git log -S "functionName" # 搜索引入/删除某字符串的提交
# ═══ diff ═══
git diff # 工作区 vs 暂存区
git diff --staged # 暂存区 vs 上次提交
git diff main..feature # 两个分支端点的快照差异
git diff main...feature # feature 相对共同祖先引入的修改(评审分支常用)
git diff HEAD~3 # 当前 vs 3 次提交前
git diff --stat # 只看文件名和行数变化
# ═══ blame ═══
git blame src/App.tsx # 每行是谁写的
git blame -L 10,20 file.ts # 只看 10-20 行
bisect — 二分定位问题提交
已知一个正常版本和一个异常版本时,git bisect 会用二分搜索缩小范围。开始前先提交或暂存无关修改,并确保每次测试结果稳定。
# 当前 HEAD 有问题,v1.2.0 已知正常
git bisect start HEAD v1.2.0 --
# Git 检出中间提交;测试后标记
git bisect good # 当前提交正常
git bisect bad # 当前提交异常
# 找到首个异常提交后回到开始前的位置
git bisect reset
测试可以稳定返回退出码时可自动执行:
git bisect start HEAD v1.2.0 --
git bisect run npm test # 0=good,1–127=bad;125=无法测试,跳过
git bisect reset
撤销与回退
# ═══ 撤销工作区修改(还没 add)═══
git checkout -- file.ts # 恢复单个文件(旧语法)
git restore file.ts # 恢复单个文件(新语法)
git diff # 丢弃前先检查未暂存修改
git restore . # 丢弃所有未暂存修改(不可恢复)
# ═══ 撤销暂存(已 add,还没 commit)═══
git reset HEAD file.ts # 取消暂存(旧语法)
git restore --staged file.ts # 取消暂存(新语法)
git restore --staged . # 全部取消暂存
# ═══ 撤销提交 ═══
git reset --soft HEAD~1 # 撤销上次提交,修改保留在暂存区
git reset --mixed HEAD~1 # 撤销上次提交,修改回到工作区(默认)
git reset --hard HEAD~1 # 撤销上次提交,修改全部丢弃(危险!)
git revert HEAD # 创建一个"反向提交"来撤销(安全,适合已推送的)
git revert abc1234 # 撤销指定提交
# ═══ 恢复已删除的文件 ═══
git checkout HEAD -- deleted-file.ts # 从最近一次提交恢复
reset 三种模式对比
| 模式 | 提交历史 | 暂存区 | 工作区 |
|---|---|---|---|
--soft |
↩️ 回退 | 保留 | 保留 |
--mixed |
↩️ 回退 | ↩️ 清空 | 保留 |
--hard |
↩️ 回退 | ↩️ 清空 | ↩️ 清空 |
stash — 临时保存
场景:写到一半需要切分支,但不想 commit 半成品。
git stash # 保存当前修改到栈
git stash push -m "WIP login" # 带备注
git stash list # 查看所有 stash
git stash pop # 恢复最近的 stash;仅成功应用时才从栈中删除
git stash apply # 恢复但不删除(可以多次 apply)
git stash drop stash@{0} # 删除指定 stash
git stash clear # 清空所有 stash(不可恢复,先用 stash list 确认)
# 只 stash 部分文件
git stash push -m "partial" -- src/App.tsx src/utils.ts
# stash 包含未跟踪文件
git stash -u # -u = --include-untracked
rebase — 变基
rebase = 把你的提交"搬到"另一个分支的最新位置上,让历史成一条直线。
# ═══ 基础 rebase ═══
git switch feature
git rebase main # 把 feature 的提交移到 main 最新之后
# 等价于:我的修改好像是在 main 最新状态上做的
# ═══ 交互式 rebase(整理提交历史)═══
git rebase -i HEAD~5 # 编辑最近 5 次提交
# 在编辑器中可以:
# pick 保留
# squash 合并到上一个
# reword 修改消息
# drop 删除
# edit 暂停让你修改
# fixup 合并且丢弃消息
# ═══ rebase vs merge ═══
# merge:保留分支历史,产生合并提交
git merge feature # 历史有分叉+合并点
# rebase:线性历史,没有合并提交
git rebase main # 历史是一条直线
rebase 黄金规则
不要擅自 rebase 已经共享给他人的提交。 默认只 rebase 自己尚未共享的提交;团队确实需要重写协作分支时,必须先协调并明确后续强制推送策略。
冲突解决
# 1. 合并/rebase 产生冲突
git merge feature
# CONFLICT (content): Merge conflict in src/App.tsx
# 2. 查看冲突文件
git status # 显示 "both modified" 的文件
# 3. 打开文件,冲突标记长这样:
<<<<<<< HEAD
你的代码
=======
对方的代码
>>>>>>> feature
# 4. 手动编辑,保留正确的代码,删掉标记
# 5. 标记为已解决
git add src/App.tsx
# 6. 继续
git merge --continue # 如果是 merge
git rebase --continue # 如果是 rebase
# ═══ 放弃 ═══
git merge --abort # 放弃合并,回到合并前
git rebase --abort # 放弃 rebase
远程操作
# ═══ 基础 ═══
git remote -v # 查看远程仓库地址
git remote add origin URL # 添加远程
git remote set-url origin URL # 修改地址
git fetch # 拉取远程更新(不合并)
git pull # fetch + merge
git pull --rebase # fetch + rebase(更干净)
git push # 推送
git push -u origin feature # 推送新分支并设置上游
# ═══ 强制操作(危险!)═══
git fetch origin
git push --force-with-lease # 比 --force 多一层远程状态检查,但仍会重写历史
# 推送前确认分支和远程更新;公共分支应由保护规则阻止强制推送
# ═══ 跟踪 ═══
git branch -vv # 查看本地分支跟踪的远程分支
git branch -u origin/main # 设置当前分支跟踪远程 main
reflog — 终极急救
reflog 记录本地引用(例如 HEAD)的移动历史,可以帮助找回曾经提交、切换或 reset 到过的提交。它不能保证恢复从未 commit、stash 或以其他方式被 Git 记录的工作区内容,记录也会按配置过期。
git reflog # 查看所有 HEAD 移动记录
# 输出示例:
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: feat: add login
# ghi9012 HEAD@{2}: checkout: moving from main to feature
# 找到想恢复的提交 hash 后,先创建分支,不要立刻再次 hard reset
git switch -c recovery def5678
# ═══ 常见急救场景 ═══
# "我 reset --hard 了,之前的内容已经提交过!"
git reflog # 找到 reset 之前的提交 hash
git branch recovery def5678 # 用实际找到的 hash 替换 def5678
# "我删了一个分支!"
git reflog # 找到那个分支最后一次提交
git checkout -b recovered abc1234
# "rebase 搞炸了!"
git rebase --abort # 如果还在 rebase 中
# 或者
git reflog # 找到 rebase 之前的 HEAD
git branch before-rebase def5678 # 用实际找到的 hash 替换 def5678
.gitignore 速查
# 基础语法
node_modules/ # 忽略整个目录
*.log # 忽略所有 .log 文件
dist/ # 忽略构建产物
.env # 忽略环境变量文件
.env.local # 本地环境变量
# 例外(! 取反)
!.env.example # 不忽略示例文件
# 通配符
*.min.js # 所有压缩 JS
**/*.test.ts # 所有目录下的测试文件
/build # 只忽略根目录的 build(不含子目录的)
# 前端项目常见 .gitignore
node_modules/
dist/
.next/
.astro/
.cache/
*.log
.env
.env.local
.DS_Store
Thumbs.db
# 查看哪些文件被忽略了
git status --ignored
# 已经被跟踪的文件加入 .gitignore 后需要:
git rm --cached file.txt # 从 Git 移除跟踪但保留文件
git rm -r --cached dist/ # 目录同理
Git 配置
# ═══ 用户信息 ═══
git config --global user.name "Your Name"
git config --global user.email "you@email.com"
# ═══ 常用配置 ═══
git config --global init.defaultBranch main # 默认分支名
git config --global pull.rebase true # pull 默认用 rebase
git config --show-origin --get core.autocrlf # 先查看当前换行配置
git config --global core.editor "code --wait" # 用 VS Code 当编辑器
# ═══ 别名(提效)═══
git config --global alias.co checkout
git config --global alias.sw switch
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --all"
git config --global alias.unstage "restore --staged"
# ═══ 查看配置 ═══
git config --list --show-origin # 显示所有配置及来源文件
跨平台项目不要机械套用全局 core.autocrlf。优先在仓库中提交 .gitattributes,由项目明确规定 LF/CRLF;修改全局设置前确认编辑器、CI 和现有仓库的约定。