正在加载,请稍候…

Git 高级工作流:Rebase、Cherry-Pick、Bisect 与 Stash 精通

掌握专业开发中的高级 Git 工作流,包括交互式 rebase、cherry-pick、git bisect 调试、stash 管理及 Git 内部机制。

Git 高级工作流:Rebase、Cherry-Pick、Bisect 与 Stash 精通

Git 高级工作流

交互式 Rebase

# 在 PR 前清理最近 5 个提交
git rebase -i HEAD~5

# 在编辑器中:
# pick abc1234 Add user model
# squash def5678 Fix typo in user model
# reword ghi9012 Add authentication
# fixup jkl3456 Fix auth bug
# drop mno7890 Debugging code

# 变基到 main
git fetch origin
git rebase -i origin/main

# 使用 autosquash 变基(squash! 和 fixup! 提交)
git commit --fixup HEAD~2  # 创建 "fixup! Original commit message"
git rebase -i --autosquash origin/main

Git 高级工作流:Rebase、Cherry-Pick、Bisect 与 Stash 精通 插图

Cherry-Pick 策略

# 挑选单个提交
git cherry-pick abc1234

# 挑选一个范围
git cherry-pick abc1234..def5678

# 挑选但不提交(用于检查)
git cherry-pick --no-commit abc1234

# 挑选并解决冲突
git cherry-pick abc1234
# ... 解决冲突 ...
git add .
git cherry-pick --continue

# 保留原始作者的挑选
git cherry-pick -x abc1234  # 添加 "(cherry picked from commit...)" 注释

Git Bisect 调试

# 查找引入 bug 的提交
git bisect start
git bisect bad HEAD           # 当前状态有问题
git bisect good v2.0.0        # v2.0.0 正常

# Git 检出中间提交 - 测试并标记
git bisect good  # 或 'bad'

# 使用测试脚本自动二分查找
git bisect start HEAD v2.0.0
git bisect run npm test -- --testNamePattern "auth.test"

# Git 会自动找到第一个坏提交
# 完成后重置
git bisect reset

Git 高级工作流:Rebase、Cherry-Pick、Bisect 与 Stash 精通 插图

Stash 高级用法

# 带描述存储
git stash push -m "WIP: user auth feature"

# 存储特定文件
git stash push -p  # 交互式补丁模式
git stash push src/auth.ts src/user.ts

# 列出存储
git stash list
# stash@{0}: WIP: user auth feature
# stash@{1}: On main: temp fix

# 应用特定存储但不删除
git stash apply stash@{1}

# 弹出特定存储
git stash pop stash@{0}

# 从存储创建分支
git stash branch feature/auth stash@{0}

# 显示存储差异
git stash show -p stash@{0}

Worktree 并行工作

# 同时处理多个分支
git worktree add ../hotfix-branch hotfix/critical-bug
git worktree add ../feature-branch feature/new-ui

# 列出 worktree
git worktree list

# 完成后移除 worktree
git worktree remove ../hotfix-branch

Git 高级工作流:Rebase、Cherry-Pick、Bisect 与 Stash 精通 插图

Git Hooks 保证质量

#!/bin/bash
# .git/hooks/pre-commit(或使用 husky)

# 运行 lint
npm run lint
if [ $? -ne 0 ]; then
  echo "Lint 失败,提交中止。"
  exit 1
fi

# 运行类型检查
npm run type-check
if [ $? -ne 0 ]; then
  echo "类型检查失败,提交中止。"
  exit 1
fi

# 运行相关测试
npm run test -- --findRelatedTests $(git diff --cached --name-only | tr '\n' ' ')
// husky + lint-staged 配置
// package.json
{
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{js,jsx}": ["eslint --fix"],
    "*.css": ["prettier --write"],
    "*.json": ["prettier --write"]
  }
}

实用 Git 别名

# ~/.gitconfig
[alias]
  lg = log --oneline --graph --decorate --all
  co = checkout
  br = branch
  st = status -sb
  undo = reset HEAD~1 --mixed
  amend = commit --amend --no-edit
  pushf = push --force-with-lease  # 安全强制推送
  recent = branch --sort=-committerdate
  unstage = reset HEAD --
  aliases = config --get-regexp alias

# 带颜色的单行历史
git log --oneline --graph --decorate --all --color=always | head -20

# 查找修改某个函数的提交
git log -L :functionName:path/to/file.ts

# 按作者显示提交
git log --author="John" --since="1 month ago" --oneline

Git Reflog 恢复

# 查看所有最近的 HEAD 位置
git reflog

# 恢复丢失的 stash
git reflog stash

# 恢复已删除的分支
git checkout -b recovered-branch abc1234  # 来自 reflog 的 SHA

# 撤销错误的 rebase
git reflog  # 找到 rebase 前的 SHA
git reset --hard HEAD@{5}  # 回到 rebase 前的状态

仓库维护

# 垃圾回收
git gc --prune=now --aggressive

# 查找大文件
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sort -k3 -rn | head -20

# 从历史中删除大文件(BFG)
bfg --strip-blobs-bigger-than 1M
git reflog expire --expire=now --all
git gc --prune=now --aggressive