Git 高级技巧全攻略:Interactive Rebase、Bisect、Worktree 与钩子自动化

前端工程(更新于 2026年5月18日)

你只用了 Git 20% 的能力

大多数开发者日常只用 addcommitpushpullmerge。Git 的真正威力在于:精确控制历史、快速定位 Bug、并行多任务、自动化工作流


一、Interactive Rebase:重塑提交历史

基本操作

git rebase -i HEAD~5

打开编辑器显示最近 5 个提交:

pick a1b2c3f feat: 添加用户列表页面
pick d4e5f6g fix: 修复列表排序问题
pick h7i8j9k feat: 添加搜索功能
pick l0m1n2o chore: 更新依赖
pick p3q4r5s feat: 添加分页组件

六种操作

命令 作用 使用场景
pick 保留提交 默认
squash 合并到上一个提交 多个小修复合为一个
fixup 合并并丢弃消息 同上,不保留消息
reword 修改提交消息 消息有错别字
edit 暂停并修改提交 拆分或修改内容
drop 丢弃提交 移除错误提交

实战:整理功能分支

# 原始提交
pick abc1234 feat: 用户模块 WIP
pick def5678 fix: 修复空指针
pick ghi9012 fix: 修复类型错误
pick jkl3456 feat: 添加搜索
pick mno7890 chore: 格式化代码

# 整理后
pick abc1234 feat: 添加用户模块
fixup def5678   # 合并到 abc1234
fixup ghi9012   # 合并到 abc1234
pick jkl3456 feat: 添加搜索功能
drop mno7890   # 丢弃格式化提交

自动 fixup

# 创建 fixup 提交(标记目标提交)
git commit --fixup=abc1234

# 自动变基,fixup 提交会找到目标并合并
git rebase -i --autosquash

二、Git Bisect:二分查找 Bug 引入点

当 Bug 出现但不知道哪个提交引入时,bisect 用二分查找快速定位。

手动 Bisect

# 开始二分查找
git bisect start

# 标记当前版本有 Bug
git bisect bad

# 标记已知的好版本
git bisect good v2.0.0

# Git 自动 checkout 中间版本
# 测试后标记
git bisect good   # 或 git bisect bad

# 重复直到找到引入 Bug 的提交
# Git 输出:abc1234 is the first bad commit

# 结束查找
git bisect reset

自动化 Bisect

# 用脚本自动测试每个版本
git bisect start HEAD v2.0.0
git bisect run npm test

# 或自定义脚本
git bisect run ./scripts/test-bug.sh
#!/bin/bash
# scripts/test-bug.sh
npm run build
if curl -s http://localhost:3000/api/health | grep -q "ok"; then
  exit 0  # good
else
  exit 1  # bad
fi

效率:1000 个提交只需 10 次二分(log₂(1000) ≈ 10)。


三、Git Worktree:同时工作在多个分支

问题

正在 feature/A 上开发,突然需要紧急修复 hotfix/B——不想 stash,不想新建 clone。

解决

# 为 hotfix 创建工作树
git worktree add ../hotfix-B hotfix/B

# 在 ../hotfix-B 目录工作,不影响当前分支
cd ../hotfix-B
# 修复、提交、推送
git add . && git commit -m "fix: 紧急修复"
git push

# 回到原工作
cd ../main-project
# 继续开发 feature/A,完全不受影响

# 清理工作树
git worktree remove ../hotfix-B

管理工作树

# 列出所有工作树
git worktree list

# 锁定工作树(防止意外删除)
git worktree lock ../hotfix-B

# 解锁
git worktree unlock ../hotfix-B
对比 git stash git worktree git clone
磁盘占用 0 仅差异文件 全量
切换成本 stash + checkout cd 切目录 cd 切目录
并行工作 不支持 支持 支持
共享 .git

四、Git Hooks:自动化工作流

客户端钩子

钩子 触发时机 用途
pre-commit git commit 代码检查、格式化
prepare-commit-msg 编辑提交消息前 自动添加前缀
commit-msg 提交消息写完后 校验消息格式
pre-push git push 运行测试
post-checkout 切换分支后 安装依赖

服务端钩子

钩子 触发时机 用途
pre-receive 接收推送前 权限校验
update 每个引用更新前 分支保护
post-receive 接收推送后 触发 CI/CD

使用 Husky + lint-staged

npm install husky lint-staged --save-dev
npx husky init
// .husky/pre-commit
npx lint-staged
// package.json
{
  "lint-staged": {
    "*.{js,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.css": [
      "stylelint --fix"
    ]
  }
}

commitlint 校验提交消息

npm install @commitlint/cli @commitlint/config-conventional --save-dev
// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', [
      'feat', 'fix', 'docs', 'style', 'refactor',
      'perf', 'test', 'build', 'ci', 'chore', 'revert',
    ]],
    'subject-max-length': [2, 'always', 100],
  },
};
# .husky/commit-msg
npx --no -- commitlint --edit $1

五、Git Stash 高级用法

多个 Stash

# 带消息的 stash
git stash push -m "WIP: 用户列表搜索功能"

# 列出所有 stash
git stash list
# stash@{0}: On feature/search: WIP: 用户列表搜索功能
# stash@{1}: On feature/order: WIP: 订单详情页

# 应用特定 stash
git stash apply stash@{1}

# 部分暂存
git stash push -m "只暂存 CSS" -- '**/*.css'

从 Stash 创建分支

git stash branch feature/search stash@{0}
# 创建新分支并应用 stash,适合 WIP 变成正式分支

六、Git Log 高级查询

搜索提交内容

# 搜索包含特定字符串的提交
git log -S "function calculateTotal"

# 搜索匹配正则的提交
git log -G "calculate.*Total"

# 搜索特定文件的历史
git log --follow -- src/utils/calc.ts

# 查看每次提交的文件变更统计
git log --stat

# 查看每次提交的具体差异
git log -p -- src/utils/calc.ts

格式化输出

# 自定义格式
git log --format="%h %ad | %s%d [%an]" --date=short

# 输出:
# a1b2c3f 2026-05-30 | feat: 添加搜索功能 (HEAD -> main) [张三]
# d4e5f6g 2026-05-29 | fix: 修复排序问题 [李四]

查看分支合并图

git log --graph --oneline --all --decorate

七、Git Reflog:时光机

reflog 记录 HEAD 的每一次移动,即使提交被"删除"也能找回。

# 查看操作历史
git reflog
# a1b2c3f HEAD@{0}: commit: feat: 新功能
# d4e5f6g HEAD@{1}: rebase: 继续变基
# h7i8j9k HEAD@{2}: reset: moving to HEAD~1
# l0m1n2o HEAD@{3}: commit: 被误删的提交

# 恢复误删的提交
git cherry-pick l0m1n2o

# 或直接回到某个状态
git reset --hard HEAD@{3}

保留期:默认 90 天(gc.reflogExpire),未引用的提交 30 天。


八、实用别名配置

git config --global alias.lg "log --graph --oneline --all --decorate"
git config --global alias.last "log -1 HEAD --stat"
git config --global alias.unstage "reset HEAD --"
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.wip "commit -m 'WIP'"
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.st status

使用:git lggit lastgit unstage file.ts 等。

#Git#版本控制#开发效率