Git 进阶技巧
基础用法见 Git 安装与配置,本文介绍进阶操作。
这些技巧不需要一次性全掌握。更好的方式是:先知道“遇到什么问题,该想到哪类 Git 能力”,等实际碰到场景时再用。
先按问题找工具
- 同时并行改多个分支:用
worktree - 只摘一个提交过来:用
cherry-pick - 不知道哪次提交引入了 bug:用
bisect - 误操作后想回到之前状态:先看
reflog - 想整理提交历史:用交互式
rebase
Worktree(工作树)
同时在多个分支上工作,无需 stash 或切换:
# 创建工作树
git worktree add ../feature-branch feature/xxx
# 查看所有工作树
git worktree list
# 删除工作树
git worktree remove ../feature-branch
# 清理已删除的工作树引用
git worktree prune
worktree 非常适合代码评审、热修复和多分支并行开发,比频繁 stash / checkout 更干净。
Cherry-pick
将其他分支的某个提交应用到当前分支:
# 应用单个提交
git cherry-pick <commit-hash>
# 应用多个提交
git cherry-pick <hash1> <hash2>
# 应用但不自动提交
git cherry-pick --no-commit <hash>
适合热修复同步、从实验分支摘取单点改动,但不适合拿来长期替代正常分支合并。
Bisect(二分查找)
快速定位引入 bug 的提交:
git bisect start
git bisect bad # 当前版本有 bug
git bisect good v1.0 # 这个版本没有 bug
# Git 会自动切换到中间提交,测试后标记:
git bisect good # 或 git bisect bad
# 重复直到找到问题提交
git bisect reset # 结束
如果你的项目有自动化测试,bisect 的威力会非常大,因为可以把“人工一点点猜”变成“半自动定位”。
Reflog(引用日志)
恢复误删的提交或分支:
# 查看所有操作历史
git reflog
# 恢复到某个状态
git reset --hard HEAD@{3}
# 恢复误删的分支
git branch recovered-branch HEAD@{5}
很多“我把分支搞没了”的场景,第一反应都应该先看 reflog,而不是慌着重写。
子模块(Submodule)
在项目中引用其他 Git 仓库:
# 添加子模块
git submodule add https://github.com/user/repo.git libs/repo
# 克隆含子模块的项目
git clone --recurse-submodules <url>
# 更新子模块
git submodule update --remote
# 初始化子模块(克隆后忘记 --recurse)
git submodule init
git submodule update
子模块功能强,但团队协作成本也高。只有在“必须保留独立仓库边界”时才建议用;否则很多场景更适合 monorepo 或包管理方案。
交互式 Rebase
整理提交历史:
# 修改最近 5 次提交
git rebase -i HEAD~5
常用操作:
pick— 保留提交squash— 合并到上一个提交reword— 修改提交信息drop— 删除提交edit— 暂停以修改内容
使用前要注意:如果这些提交已经推到共享分支,重写历史会影响其他协作者。
高级日志
# 搜索提交内容
git log -S "function_name" --oneline
# 查看某文件的修改历史
git log --follow -p -- path/to/file
# 查看某行的修改历史
git log -L 10,20:src/main.ts
# 统计每人提交数
git shortlog -sn --no-merges
这些日志命令非常适合排查“谁改过这里”“这个函数何时变的”“某一行是谁引入的”。
清理与维护
# 清理未跟踪文件
git clean -fd
# 预览将被清理的文件
git clean -fdn
# 压缩仓库
git gc --aggressive
# 查看仓库大小
git count-objects -vH
高风险操作提醒
reset --hardclean -fd- 已推送提交上的
rebase - 对不熟悉的子模块仓库直接批量更新
这些操作不是不能用,而是执行前最好先确认是否还有别人依赖当前状态。
推荐学习顺序
reflogworktreecherry-pickrebase -ibisect
这样会比从最复杂的历史重写开始更稳。
常见问题
rebase 后提交没了
先别慌,优先看 git reflog。大多数“丢了”的提交其实还在,只是引用变了。
cherry-pick 冲突很多
通常说明这次改动并不适合被当成“单点摘取”。这时重新合并分支,或者把改动拆小,往往更省时间。
子模块总是状态混乱
如果团队里不止你一个人维护仓库,优先重新评估是不是非用子模块不可。很多混乱不是使用姿势问题,而是方案本身不适合团队。
参考链接
- Pro Git 中文版 — 免费电子书
- Git Worktree 文档 — 官方文档
- Git Bisect 文档 — 官方文档
- Git 安装与配置 — 如果你还没把基础别名、用户信息和 SSH 配好