git进阶07_Git 高级技巧与故障排查 06 - Git 高级技巧与故障排查本章目标掌握企业实战中的高级 Git 技巧能独立排查和解决各种 Git 故障。一、git reflog — 救命神器这是 Git 最被低估的功能关键时刻能救你的命。# 查看所有操作记录包括已经 reset 掉的 commitgitreflog# 输出示例# abc1234 HEAD{0}: reset: moving to HEAD~3# def5678 HEAD{1}: commit: feat: add login# ghi9012 HEAD{2}: commit: feat: add register# jkl3456 HEAD{3}: commit: feat: add dashboard常见救命场景# 场景1误删了分支gitbranch-Dfeature/important# 没关系gitreflog# 找到分支最后的 commitgitcheckout-bfeature/important abc1234# 恢复# 场景2误执行了 git reset --hardgitreflog# 找到 reset 前的 commitgitreset--hardabc1234# 恢复# 场景3push 后发现代码有问题gitreflog# 找到 push 前的 commitgitreset--hardabc1234# 回退gitpush --force-with-lease# 强制推送回退远程二、git reset 的三种模式# 模式对比 # --soft只撤销 commit保留暂存区和工作区gitreset--softHEAD~1# 效果commit 被撤销改动仍在暂存区绿色# --mixed默认撤销 commit 暂存区保留工作区gitreset HEAD~1# 效果commit 被撤销改动在工作区红色# --hard全部撤销危险不可恢复gitreset--hardHEAD~1# 效果commit、暂存区、工作区全部撤销--soft --mixed --hard ┌──────────┐ ┌──────────┐ ┌──────────┐ 暂存区Staged │ 保留 ✅ │ │ 清空 ❌ │ │ 清空 ❌ │ ├──────────┤ ├──────────┤ ├──────────┤ 工作区Working │ 保留 ✅ │ │ 保留 ✅ │ │ 清空 ❌ │ └──────────┘ └──────────┘ └──────────┘使用场景# 修改最近一次 commit 的内容gitaddforgotten-file.jsgitcommit--amend--no-edit# 或者gitaddforgotten-file.jsgitreset--softHEAD~1gitcommit-mfeat: add login (with forgotten file)# 撤销最近一次 commit保留改动gitreset HEAD~1# 彻底回退到某个版本危险操作慎用gitreset--hardv1.0.0三、git revert — 安全回滚与reset不同revert会创建一个新的 commit 来撤销指定的 commit不会改变历史。# 回滚最近一次 commitgitrevert HEAD# 回滚指定 commitgitrevert abc1234# 回滚多个 commitgitrevert abc1234..def5678# 回滚合并 commit需要指定主线gitrevert-m1merge-commit-hashreset vs revert 对比场景已 push 到远程的 commit 有问题 git reset --hard HEAD~1 ✅ 直接回退 ❌ 改变了历史其他人需要重新 clone ❌ 如果有其他人在基于你的代码开发会造成灾难 git revert HEAD ✅ 创建新 commit 撤销不改变历史 ✅ 安全其他人可以正常 pull ❌ 历史中会多一个 revert commit企业规则已 push 的代码用 revert未 push 的代码用 reset。四、git rebase 深入4.1 rebase vs merge 的本质区别merge合并 * merge commit |\ | * feature commit 2 | * feature commit 1 |/ * develop commit rebase变基 * feature commit 2 * feature commit 1 * develop commit 2 * develop commit 14.2 交互式 rebase最强大的功能# 修改最近 5 次 commitgitrebase-iHEAD~5# 编辑器显示pick abc1234 feat:addlogin form pick def5678 feat:addlogin API pick ghi9012 fix: fix typoinlogin pick jkl3456 feat:addlogoutbutton pick mno7890 fix: fixlogoutbug# 命令说明# pick 保留这个 commit# reword 保留但修改 commit message# edit 保留但修改内容# squash 合并到上一个 commit保留 message# fixup 合并到上一个 commit丢弃 message# drop 删除这个 commit# 示例把 fixup 合并到对应的 feat commitpick abc1234 feat:addlogin form pick def5678 feat:addlogin API fixup ghi9012 fix: fix typoinlogin pick jkl3456 feat:addlogoutbutton fixup mno7890 fix: fixlogoutbug4.3 rebase 的黄金法则不要对公共分支main/develop执行 rebase不要对已经 push 到远程且别人正在使用的分支执行 rebase为什么 因为 rebase 会重写 commit hash 如果别人基于旧的 commit 继续开发 他们的代码和你的代码就会产生冲突。五、git bisect — 二分查找 Bug# 启动二分查找gitbisect start# 标记当前版本有 Buggitbisect bad# 标记一个已知好的版本gitbisect good v1.0.0# Git 会自动 checkout 中间的 commit# 测试后告诉 Git 好坏gitbisect good# 这个版本没问题gitbisect bad# 这个版本有问题# 重复几次后Git 会找到引入 Bug 的第一个 commit# 结束后gitbisect reset自动化 bisect# 用脚本自动测试gitbisect start HEAD v1.0.0gitbisect runnpmtest# Git 会自动运行 npm test根据返回值判断好坏# 0 good, 非 0 bad六、git worktree — 多分支并行开发场景你在开发功能 A需要紧急修 Bug但不想 stash 当前工作。# 在另一个目录 checkout 另一个分支gitworktreeadd../hotfix-branch hotfix/fix-bug# 现在你有两个工作目录# 1. 原目录feature/user-login继续开发功能 A# 2. ../hotfix-branchhotfix/fix-bug修 Bug# 修完 Bug 后cd../hotfix-branchgitadd.gitcommit-mfix: critical buggitpush origin hotfix/fix-bug# 删除 worktreegitworktree remove../hotfix-branch# 查看所有 worktreegitworktree list七、git archive — 导出代码快照# 导出当前分支的代码不包含 .git 目录gitarchive-olatest.zip HEAD# 导出指定 taggitarchive-ov1.0.0.zip v1.0.0# 导出指定目录gitarchive-osrc.zip HEAD src/八、git clean — 清理工作区# 查看哪些未跟踪文件会被删除dry rungitclean-fd--dry-run# 删除未跟踪的文件和目录gitclean-fd# 删除被 .gitignore 忽略的文件gitclean-fdx# 删除所有未跟踪的文件危险gitclean-fdX九、故障排查手册9.1 “我的代码去哪了”# 查看所有操作记录gitreflog# 查看 HEAD 指向gitlog-1# 查看分支图gitlog--oneline--graph--all# 查看某个 commit 的详细信息gitshow abc12349.2 “我误删了文件/分支”# 恢复删除的文件gitcheckout HEAD --file# 或者gitrestorefile# 恢复删除的分支gitreflog# 找到最后的 commitgitcheckout-bbranch-namecommit-hash9.3 “我 push 了错误的代码”# 方案1撤回 push需要 force push危险gitreset--hardHEAD~1gitpush --force-with-lease# 方案2revert安全推荐gitrevert HEADgitpush9.4 “rebase 冲突太多了”# 放弃本次 rebasegitrebase--abort# 或者用 merge 代替gitmerge origin/develop9.5 “git pull 有冲突”# 方案1先 rebase 再 pullgitpull--rebaseorigin main# 方案2先 stash 再 pullgitstashgitpull origin maingitstash pop# 方案3放弃本地修改gitreset--hardorigin/main9.6 “detached HEAD 是什么”# 你 checkout 了一个 commit 而不是分支gitcheckout abc1234# 提示You are in detached HEAD state.# 解决创建一个新分支gitcheckout-btemp-branch# 或者回到之前的分支gitcheckout main9.7 “大文件不小心提交了”# 从 Git 历史中彻底删除大文件# 安装 git-filter-repopipinstallgit-filter-repo# 删除指定文件的所有历史gitfilter-repo --invert-paths--pathlarge-file.zip# 或者用 BFG Repo-Cleanerjava-jarbfg.jar --strip-blobs-bigger-than 10M repo.git十、Git 配置速查# 查看配置 gitconfig--list# 所有配置gitconfig--global--list# 全局配置gitconfig--local--list# 仓库配置# 设置配置 gitconfig--globalkeyvalue# 全局gitconfig--localkeyvalue# 仓库级# 删除配置 gitconfig--global--unsetkeygitconfig--local--unsetkey# 常用配置项 core.autocrlf# 换行符处理core.editor# 默认编辑器pull.rebase# pull 时是否 rebasepush.default# push 默认行为init.defaultBranch# 默认分支名十一、Git 别名配置# 常用别名gitconfig--globalalias.st statusgitconfig--globalalias.co checkoutgitconfig--globalalias.br branchgitconfig--globalalias.cm commitgitconfig--globalalias.lglog --oneline --graph --all --decorategitconfig--globalalias.lastlog -1 --statgitconfig--globalalias.unstagereset HEAD --gitconfig--globalalias.amendcommit --amend --no-editgitconfig--globalalias.wip!git add -A git commit -m WIP: work in progressgitconfig--globalalias.undoreset --soft HEAD~1十二、练习清单学完本章请完成以下操作用git reflog找回一个被git reset --hard删除的 commit用git revert回滚一个已 push 的 commit用git rebase -i把 3 个 commit 压缩成 1 个用git bisect定位一个引入 Bug 的 commit用git worktree同时在两个分支上工作制造一个 “detached HEAD” 并安全恢复上一章05-企业级CI-CD与代码质量下一章07-完整实战场景演练