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 之后)# 在 feature 分支上执行 rebasegit checkout featuregit rebase main
# 解决可能的冲突后继续git add .git rebase --continue# 或放弃 rebasegit rebase --abort
# 变基完成后,切回主分支(此时是快进合并,无 merge commit)git checkout maingit merge feature # Fast-forward,历史保持线性1.2 交互式 rebase(-i):整理提交历史
# 整理最近 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 提交合并为一个
# 修改编辑器中的内容:# pick a1b2c3d feat: 用户注册功能# fixup e4f5g6h fix typo# fixup i7j8k9l add missing import# fixup m1n2o3p 补充注释# 结果:只剩一个整洁的 commit场景 2:修改历史 commit message
git rebase -i HEAD~5# 将目标提交的 pick 改为 reword,保存后 Git 弹出 message 编辑界面场景 3:将一个大提交拆分成多个
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:精准摘取指定提交
# 摘取单个提交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
# 场景:v2.0 有 Bug,v1.5 没有,不知道是哪次提交引入的
git bisect startgit bisect bad # 当前版本有 Buggit bisect good v1.5 # 已知的好版本
# Git 自动 checkout 中间某次提交,你测试后:git bisect bad # 或git bisect good# 重复几次(100次提交只需约 7 步)
# Git 最终输出:# "abc1234 is the first bad commit"
# 结束 bisectgit bisect reset
# ── 自动化 bisect ─────────────────────────────────────────────cat > test.sh << 'EOF'#!/bin/bashnpm test -- --grep "登录功能"exit $?EOFchmod +x test.sh
git bisect startgit bisect bad HEADgit bisect good v1.5git bisect run ./test.sh # 全自动!几秒内找到引入 Bug 的提交git bisect reset四、git stash:工作区临时存储
# 基本用法git stash push -m "WIP: 用户模块功能开发中"
# 同时保存未追踪的新文件git stash push --include-untracked -m "包含新文件"
# 查看所有 stashgit 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 天:
# 查看 refloggit 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 hashgit 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 -eecho "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 格式
#!/bin/bashcommit_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 1fi6.3 pre-push:推送前运行测试
#!/bin/bashset -eecho "Running tests before push..."uv run pytest tests/ -x -qecho "All tests passed, pushing..."6.4 pre-commit 框架(团队共享,推荐)
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]pre-commit install # 每个开发者克隆后执行一次pre-commit run --all-files # 手动对所有文件运行git commit --no-verify -m "紧急修复" # 跳过 hooks(紧急情况)七、团队工作流对比
| 工作流 | 核心原则 | 适合场景 | 复杂度 |
|---|---|---|---|
| GitHub Flow | 从 main 拉分支,PR 合并回 main,立即部署 | 小团队、持续部署、SaaS | ⭐⭐ |
| Git Flow | main/develop/feature/release/hotfix 多分支 | 有明确版本号的产品 | ⭐⭐⭐⭐ |
| Trunk-Based | 所有人直接向 main 提交,Feature Flag 控制发布 | 大型团队、高频发布 | ⭐⭐⭐ |
八、实用命令速查
# ── 查找相关 ──────────────────────────────────────────────────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 --statgit 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"相关文章:
- Linux 服务器初始化安全配置:买完 VPS 必做的 12 件事
- GitHub 打不开/访问慢?2026年最新解决方法
- Python 项目工程化实战(一):pyproject.toml + uv + Ruff
- Docker 完全指南 2026:Compose 多服务编排与生产部署
- FastAPI 完全指南 2026:从零构建高性能异步 Python API
本文命令基于 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/