1886 字
9 分钟

Git 进阶实战完全指南 2026:rebase / cherry-pick / bisect / stash / 钩子 / 团队工作流

会用 git add/commit/push 只是起点。真正的 Git 熟练度体现在:能用 rebase 整理出清晰的提交历史,能用 bisect 在几分钟内定位引入 Bug 的提交,能用 reflog 从各种误操作中救回数据。

本文聚焦日常开发中高频但被忽视的 Git 进阶功能,所有命令均为实战场景驱动。


一、git rebase:让提交历史保持线性#

1.1 基础变基:将功能分支整合到主分支#

初始状态:
main: A - B - C
feature: D - E - F (从 B 分出来)
执行 git rebase main 后:
main: A - B - C
feature: D'- E'- F' (D/E/F 重新应用在 C 之后)
Terminal window
# 在 feature 分支上执行 rebase
git checkout feature
git rebase main
# 解决可能的冲突后继续
git add .
git rebase --continue
# 或放弃 rebase
git rebase --abort
# 变基完成后,切回主分支(此时是快进合并,无 merge commit)
git checkout main
git merge feature # Fast-forward,历史保持线性

1.2 交互式 rebase(-i):整理提交历史#

Terminal window
# 整理最近 3 个提交
git rebase -i HEAD~3
# 会打开编辑器,显示:
# pick a1b2c3d 修复登录 bug
# pick e4f5g6h WIP: 还没写完
# pick i7j8k9l 添加测试用例
#
# 可用操作:
# pick = 保留此提交(默认)
# reword = 保留提交,但修改 commit message
# edit = 暂停在此提交,允许修改文件内容
# squash = 将此提交合并到上一个提交(合并 message)
# fixup = 将此提交合并到上一个提交(丢弃此 message)
# drop = 删除此提交

场景 1:将多个 WIP 提交合并为一个

Terminal window
# 修改编辑器中的内容:
# pick a1b2c3d feat: 用户注册功能
# fixup e4f5g6h fix typo
# fixup i7j8k9l add missing import
# fixup m1n2o3p 补充注释
# 结果:只剩一个整洁的 commit

场景 2:修改历史 commit message

Terminal window
git rebase -i HEAD~5
# 将目标提交的 pick 改为 reword,保存后 Git 弹出 message 编辑界面

场景 3:将一个大提交拆分成多个

Terminal window
git rebase -i HEAD~3
# 将目标提交的 pick 改为 edit,保存
git reset HEAD^ # 撤销此提交,保留文件修改
git add 文件A && git commit -m "功能A"
git add 文件B && git commit -m "功能B"
git rebase --continue

二、git cherry-pick:精准摘取指定提交#

Terminal window
# 摘取单个提交
git cherry-pick a1b2c3d
# 摘取多个提交(按顺序)
git cherry-pick a1b2c3d e4f5g6h
# 摘取一个范围(不含起点,包含终点)
git cherry-pick abc123..def456
# 只应用改动,不自动 commit(方便修改后再提交)
git cherry-pick -n a1b2c3d
# 遇到冲突时
git add .
git cherry-pick --continue
# 或放弃
git cherry-pick --abort

典型场景

  • ✅ 将 bug 修复从 develop 分支移植到 hotfix 分支快速发版
  • ✅ 只需要某分支的部分功能,不想全部合并
  • ✅ 误在错误分支提交,需要移到正确分支

三、git bisect:二分法定位 Bug#

Terminal window
# 场景:v2.0 有 Bug,v1.5 没有,不知道是哪次提交引入的
git bisect start
git bisect bad # 当前版本有 Bug
git bisect good v1.5 # 已知的好版本
# Git 自动 checkout 中间某次提交,你测试后:
git bisect bad # 或
git bisect good
# 重复几次(100次提交只需约 7 步)
# Git 最终输出:
# "abc1234 is the first bad commit"
# 结束 bisect
git bisect reset
# ── 自动化 bisect ─────────────────────────────────────────────
cat > test.sh << 'EOF'
#!/bin/bash
npm test -- --grep "登录功能"
exit $?
EOF
chmod +x test.sh
git bisect start
git bisect bad HEAD
git bisect good v1.5
git bisect run ./test.sh # 全自动!几秒内找到引入 Bug 的提交
git bisect reset

四、git stash:工作区临时存储#

Terminal window
# 基本用法
git stash push -m "WIP: 用户模块功能开发中"
# 同时保存未追踪的新文件
git stash push --include-untracked -m "包含新文件"
# 查看所有 stash
git stash list
# 应用并删除(pop = apply + drop)
git stash pop
# 应用指定的 stash(不删除)
git stash apply stash@{1}
# 从 stash 创建新分支(避免冲突)
git stash branch new-branch stash@{0}
# 只 stash 部分文件
git stash push -m "部分修改" -- src/utils.py src/config.py
# 清空所有 stash(不可恢复!)
git stash clear

五、git reflog:误操作救命神器#

reflog 记录所有 HEAD 移动历史,有效期默认 90 天:

Terminal window
# 查看 reflog
git reflog
# HEAD@{0} reset: moving to HEAD~1
# HEAD@{1} commit: feat: 添加搜索功能 ← 想恢复的 commit!
# HEAD@{2} commit: fix: 修复登录 bug
# 场景 1:git reset --hard 后悔了
git reset --hard HEAD@{1}
# 场景 2:恢复误删的分支
git branch -D feature/user # 误删!
git reflog | grep feature # 找到最后的 commit hash
git checkout -b feature/user abc1234 # 用 hash 恢复
# 场景 3:rebase 搞乱了,回到 rebase 前
git reflog | grep "rebase"
git reset --hard HEAD@{5} # 回到 rebase 开始前的状态
# 查看特定时间范围
git reflog --after="2 days ago"

六、git hooks:自动化质量门控#

6.1 pre-commit:提交前格式化 + lint#

#!/bin/bash
# .git/hooks/pre-commit(需要 chmod +x)
set -e
echo "Running code checks..."
if git diff --cached --name-only | grep -q "\.py$"; then
ruff check $(git diff --cached --name-only | grep "\.py$")
ruff format --check $(git diff --cached --name-only | grep "\.py$")
fi
if git diff --cached --name-only | grep -qE "\.(js|ts|jsx|tsx)$"; then
npx eslint $(git diff --cached --name-only | grep -E "\.(js|ts|jsx|tsx)$")
fi
echo "Checks passed!"

6.2 commit-msg:强制 Conventional Commits 格式#

.git/hooks/commit-msg
#!/bin/bash
commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,100}$'
if ! echo "$(cat $1)" | grep -qE "$commit_regex"; then
echo "❌ Commit message 格式错误!"
echo "正确格式:<type>(<scope>): <description>"
echo "示例:feat(auth): 添加 JWT 认证功能"
exit 1
fi

6.3 pre-push:推送前运行测试#

.git/hooks/pre-push
#!/bin/bash
set -e
echo "Running tests before push..."
uv run pytest tests/ -x -q
echo "All tests passed, pushing..."

6.4 pre-commit 框架(团队共享,推荐)#

Terminal window
uv add --dev pre-commit
# .pre-commit-config.yaml(提交到 git 仓库,团队共享)
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.7
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-json
- id: check-yaml
- id: check-merge-conflict
- id: no-commit-to-branch
args: [--branch, main, --branch, master]
Terminal window
pre-commit install # 每个开发者克隆后执行一次
pre-commit run --all-files # 手动对所有文件运行
git commit --no-verify -m "紧急修复" # 跳过 hooks(紧急情况)

七、团队工作流对比#

工作流核心原则适合场景复杂度
GitHub Flow从 main 拉分支,PR 合并回 main,立即部署小团队、持续部署、SaaS⭐⭐
Git Flowmain/develop/feature/release/hotfix 多分支有明确版本号的产品⭐⭐⭐⭐
Trunk-Based所有人直接向 main 提交,Feature Flag 控制发布大型团队、高频发布⭐⭐⭐

八、实用命令速查#

Terminal window
# ── 查找相关 ──────────────────────────────────────────────────
git log --oneline --graph --all # 图形化提交历史
git log --author="Alice" --since="1 week ago"
git log -S "function_name" # 查找引入/删除特定代码的提交
git log --diff-filter=D -- filename.py # 查看文件是哪次提交删除的
# ── 比较相关 ──────────────────────────────────────────────────
git diff HEAD~3..HEAD -- src/
git diff main..feature --stat
git show abc1234:path/to/file # 查看某提交中某文件的内容
# ── 修改最后一次提交 ──────────────────────────────────────────
git commit --amend -m "新的 message"
git commit --amend --no-edit # 追加文件,不改 message
# ── 撤销相关 ──────────────────────────────────────────────────
git revert abc1234 # 用新提交撤销(安全)
git reset --soft HEAD~1 # 撤销提交,保留到暂存区
git reset --mixed HEAD~1 # 撤销提交,保留到工作区
git reset --hard HEAD~1 # 撤销提交,丢弃改动(危险!)
git restore --staged filename # 从暂存区取消某文件
# ── 常用 alias(添加到 ~/.gitconfig)────────────────────────
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.st "status -sb"
git config --global alias.undo "reset --mixed HEAD~1"
git config --global alias.last "log -1 HEAD --stat"

相关文章

本文命令基于 Git 2.45.x 验证。旧版(< 2.23)部分命令语法略有差异,如 git restore 需用 git checkout --

Git 进阶实战完全指南 2026:rebase / cherry-pick / bisect / stash / 钩子 / 团队工作流
https://971918.xyz/posts/docs/git-advanced-guide/
作者
九所长
发布于
2026-07-26
许可协议
CC BY-NC-SA 4.0