我见过很多同事,一天工作下来就一条命令:git add .,然后 git commit -m "update"。Git 确实是在用,但等哪天真要回滚、要定位问题、要整理提交记录的时候,就只能干瞪眼。Git 这个工具,“会用”和“精通”之间隔着的不是背命令,而是搞明白每个命令在什么场景下用、用了之后会发生什么、副作用在哪。这篇文章我就挑 12 个我日常工作中真正高频、真正救过命的命令,从提交、急救、整理、排查四个维度拆开讲,每个都带上使用场景、操作示例和踩坑提示。适合所有已经能完成 add/commit/push,但想更进一步把 Git 用顺手的开发者。
1. 提交前把改动捏碎:add -p、amend 和 reset --soft
很多人提交代码的习惯是“攒够了再提交”,一次 commit 里混着三四个逻辑。等代码 review 的时候,别人看不懂你为什么要一起改;等要回滚某个功能的时候,只能把整个提交一起回滚。我自己的经验是:commit 应该小而清晰,一个提交只做一件事。这一章就是围绕这个目标展开的。
1.1 git add -p:不想一次提交全部改动?
场景非常常见:你花了一下午改了一个文件,里面既有“修 bug”的部分,又有“加新功能”的部分,但你想把它们分成两个 commit。这时候 git add . 明显不合适,你需要的是 git add -p。
git add -p 的 -p 是 --patch 的缩写,它会进入交互模式,把文件里的每一块改动(Git 称为 hunk)逐个展示给你,让你决定这一块要不要暂存。交互界面长这样:
bash复制git add -p src/components/Form.js
Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? y
Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? n
每个选项的含义对应如下:
y:暂存当前这块改动n:跳过当前这块改动q:退出,不再处理后续 hunka:暂存当前文件和后续所有 hunkd:跳过当前文件之后的 hunk,跳到下一个文件s:把当前这块 hunk 拆分成更小的 hunke:手动编辑 hunk(最强大,也最容易出错)?:查看所有选项的帮助
我平常最常用的是 y、n 和 s。如果一个大 hunk 里同时包含了两处不相干的改动,先按 s 拆分,拆完再分别回答 y 和 n,就能做到“一个文件里挑着提交”。
如果你遇到拆分后还是不精确的情况,可以用 e 手动编辑 diff。进入编辑器后,你可以删除某些不想要的行,但要非常小心:每一行的前缀(+、- 或空格)都不能乱动,头部那几行 @@ 是 hunk 定位信息,也必须保留。编辑完保存退出,Git 会按你编辑后的内容暂存。
这里有个很多新手不知道的逻辑:git add -p 不会改变你工作区的文件内容,它只决定“哪些改动进入暂存区”。所以你可以放心用,不会丢代码。提交时一旦一个 commit 里只包含某个逻辑的改动,之后 git log 看历史就会清晰很多,revert 时也能精准撤销。
1.2 git commit --amend:后悔药该不该吃?
提交完了才发现漏了一个文件,或者 commit message 写错了,怎么办?不用重新 commit,直接 git commit --amend。
--amend 的意思是“修订上一次提交”,用法很灵活:
bash复制git commit --amend # 修改上次提交的提交信息
git commit --amend --no-edit # 不修改提交信息,只补充文件改动
git commit --amend -m "新的提交信息" # 直接指定新信息,不进入编辑器
比如我经常遇到的情况:
bash复制git add src/api/user.js src/utils/validator.js
git commit -m "feat: 增加用户注册校验"
# 突然发现漏了一个文件
git add src/api/auth.js
git commit --amend --no-edit
这样第二次提交不会产生新的提交记录,而是把 auth.js 直接塞进了上一次 commit 里。从外面的视角看,这个分支上只有一条提交,干净利落。
但这里有个非常关键的点,也是我见过很多人踩坑的地方:--amend 不是“修改”,而是“替换”。Git 会生成一个全新的 commit 对象,虽然它在 log 里的位置没变,但 commit hash 已经不同了。如果你 amend 的是一个已经 push 到共享分支的提交,那相当于重写了历史,其他同事 pull 的时候会得到一堆分叉,得靠 git pull --rebase 去解,严重的时候还会把别人的提交搞乱。
所以我的底线是:只要这个 commit 已经 push 到了公共分支,就绝不动它。只在本地还没推送、或者推送到自己个人 feature 分支时使用 --amend。
1.3 git reset --soft:撤销 commit 但保留工作区
git reset 大概是 Git 里最让人头大的命令之一,因为它有 --soft、--mixed、--hard 三种模式。先记住一个结论:日常整理提交,--soft 最安全。
三种模式的区别可以用一张表看清楚:
| 参数 | HEAD指针 | 暂存区 | 工作区 | 典型场景 |
|---|---|---|---|---|
--soft |
移动 | 保留 | 保留 | 想重新组织提交,但不想丢任何改动 |
--mixed(默认) |
移动 | 重置 | 保留 | 想撤销 add,让改动回到工作区 |
--hard |
移动 | 重置 | 清空 | 彻底丢掉某次提交及其改动 |
具体到 --soft,它的核心价值在于“后悔了想重新来”。比如你连续提交了两次:
bash复制git commit -m "feat: 登录模块"
git commit -m "fix: 登录接口超时"
后来发现这两个提交根本是同一件事,应该合并成一个。这时候:
bash复制git reset --soft HEAD~2
git commit -m "feat: 登录模块(含超时修复)"
HEAD~2 表示回退两个提交,--soft 保证这两次提交的改动都还留在暂存区里,一个都不丢。接下来你直接提交,就得到了一条合并后的干净提交。
这才是 reset --soft 的正确打开方式:它不会碰你的文件和暂存区,只是让 HEAD 指针“退回去”。所以它天然适合“我要重新组织提交历史”的场景。
而 --hard 就不一样了,它会把工作区、暂存区都重置,等于直接丢弃改动。这个命令我建议新手在搞清楚之前尽量别碰,真要清空工作区,也先 git stash 备份一下,或者把当前 commit hash 记下来,万一后悔还能找回。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 误删与交接:reflog、stash 和 clean 组成的急救包
这一章聊事故。Git 用久了,谁都经历过“昨天还能跑的代码,一觉醒来没了”“正写着功能,线上突然要紧急修 bug”“工作区里堆了一堆临时文件,想清干净又怕删错”。这三个命令就是干这个的。
2.1 git reflog:真正的“时间机器”
先说一个真实经历。有一次我在本地分支上 git reset --hard HEAD~3,理完提交才发现里面有两个 commit 其实是有用的。当时第一反应是有点慌,因为 git log 已经看不到那两条记录了。后来靠 git reflog 全部找回来了。
git reflog 记录的是 HEAD 指针每一次移动的历史,包括 commit、reset、rebase、cherry-pick、checkout 等操作。它本质上是一份本地操作日志,存在仓库的 .git/logs 目录里。默认情况下,这些记录会保留 90 天,所以 90 天内误删的提交基本都有救。
先看记录:
bash复制git reflog
c3a9b21 (HEAD -> main) HEAD@{0}: reset: moving to HEAD~2
d9f0a34 HEAD@{1}: commit: fix: 修正登录逻辑
7f2c91e HEAD@{2}: commit: feat: 增加导出功能
aa1e003 HEAD@{3}: commit: feat: 完善表单校验
比如这里,HEAD@{1} 之前有一条 d9f0a34,它正是我 reset 之前的那个提交。想恢复,两种方式:
bash复制git checkout -b recover d9f0a34 # 从丢失的提交新建一个分支,安全
git reset --hard d9f0a34 # 直接把当前分支移回去,简单直接
我倾向于先 checkout -b 新建分支再确认内容,确认没问题后合并或者切换过去。虽然 reflog 找回头提交是常规操作,但 reset --hard 毕竟会动当前分支状态,多一层保险没坏处。
有个知识点很多人不清楚:reflog 是本地仓库特有的,git clone 下来的仓库 reflog 是空的;公共服务器上的分支不会记录你的操作。所以如果你的本地仓库发生了误操作,趁早恢复,别拖着。
还要注意一点,别轻易执行 git reflog expire --all --expire=now,这一跑所有记录立刻清空,到时候真是叫天天不应。
2.2 git stash:临时切换任务的正确姿势
正在 feature 分支写一个新功能,写了三分之一,测试突然说线上有个 bug 必须马上修。这时候最不想做的是 git commit,因为功能没写完,提交之后历史会很丑。正确做法是 git stash。
bash复制git stash # 把当前所有未提交改动暂存起来
git stash -u # 连新增的未跟踪文件一起暂存
git checkout -b hotfix/xxx
# 修 bug,提交,推送
git checkout feature/xxx
git stash pop # 把之前的改动恢复回来
stash 的原理是把工作区和暂存区的改动打包成一个“栈”保存,然后让工作区回到干净状态。你可以用 git stash list 查看当前存了几份改动:
bash复制git stash list
stash@{0}: On feature/login: 登录页样式调整
stash@{1}: WIP on feature/profile: 用户信息接口联调
pop 和 apply 的区别在于:pop 恢复改动后会把这条 stash 从栈里弹出去;apply 则保留 stash。我的习惯是:不确定时用 apply,确认没问题再手动 drop。因为偶尔会碰到 pop 时冲突的情况——当你恢复改动时,当前工作区已经发生了变化,Git 无法自动把两边的改动合并,会提示冲突。这时候 stash 并不会自动删除,你得先解决冲突,再手动 git stash drop,否则它就一直占着一个位置。
还有一个非常常见但容易翻车的细节:默认情况下 stash 只保存已跟踪文件的改动,你新建的文件并不在里面。如果你在功能分支新建了 src/utils/newFeature.js,然后直接 git stash 切走,新文件会一直留在工作区,切到别的分支它会跟着走。所以切分支前如果工作区有新建文件,请一定加 -u 参数。至于 -a 连 .gitignore 里的文件也一起存,我几乎不用,因为它容易误伤一些本地配置。
2.3 git clean:该清理的垃圾一个不留
清理未跟踪文件是很多人不敢碰的操作,因为 Git 没有回收站,删掉就是真没了。而 git clean 就是用来干这个的。
先给一个警告:永远先 -n 预览,再决定要不要 -f 真正执行。
bash复制git clean -nd # 预览会删除哪些文件和目录
git clean -fd # 删除未跟踪的文件和目录
git clean -x # 连同被 .gitignore 忽略的文件一起删除
git clean -fdx # 极度危险,慎用
-n(dry-run)只列出会被删除的内容,不实际删。例如:
bash复制git clean -nd
Would remove dist/
Would remove tmp_cache/
Would remove App.log
看到列出的内容,再判断这些是不是真的不要了。如果确认,再执行 git clean -fd。
-x 参数会连 .gitignore 里忽略的文件也一起删,也就是把本地环境清到和刚 clone 下来一模一样。听起来很爽,但风险极大:比如你的 .env 文件被 gitignore 了,里面存了一堆本地密钥,跑一下 git clean -fdx 就没了。所以要清忽略文件时,最好先看看 -x 会删什么,也可以加 -e 排除某些文件:
bash复制git clean -fdx -e .env
那什么时候会用到 clean?最常见的场景是想彻底重置本地环境。我之前在项目里用:
bash复制git reset --hard && git clean -fd
一条命令让工作区回到某个 commit 的精确状态,编译产物、临时文件夹全清干净。这个组合在切环境、重装依赖之前特别好用。但我也确实见过有人因为没加 -n 预览,把刚写好的还没 git add 的源码文件全删了。所以请一定养成“先预览,再执行”的习惯。
3. 历史不是写死的:rebase -i、cherry-pick 与 revert 的边界
很多人以为 Git 历史一旦产生就不能改,其实不是。Git 允许你在一定范围内重写历史,但这个“范围”非常重要。这一章讲三个“动历史”的命令,重点在于什么情况下能用、什么情况下千万别用。
3.1 git rebase -i:把自己凌乱的提交记录改得清爽
功能分支写了两天,一共 commit 了 10 次,信息全是 “fix”“temp”“update”。这种历史推到远程,review 的人会崩溃。正确做法是在合入主干之前,用 git rebase -i 把这些提交整理成几个有意义的提交。
-i 是 --interactive,进入后 Git 会打开一个编辑器,列出最近 N 次提交:
bash复制git rebase -i HEAD~10
编辑器里每一行是一个提交,前面是操作命令,默认是 pick:
bash复制pick 8f2a9c1 feat: 增加搜索
pick 7d13b8e fix: 搜索关键词为空
pick c0a1b2d fix: 搜索空结果判断
pick a6f3e01 fix: 搜索按钮样式
pick 2b7f3c9 feat: 搜索结果排序
你可以把后几个改掉:
bash复制pick 8f2a9c1 feat: 增加搜索
squash 7d13b8e fix: 搜索关键词为空
fixup c0a1b2d fix: 搜索空结果判断
fixup a6f3e01 fix: 搜索按钮样式
pick 2b7f3c9 feat: 搜索结果排序
pick 表示保留这个提交,squash 表示把这个提交合并到上一个提交里,并弹出编辑器让你重新写提交信息;fixup 和 squash 类似合并,但直接丢弃被合并提交的信息,只保留上面那条的提交信息。所以上面这波操作之后,4 条搜索相关的提交会压缩成 1 条。
除了这几种,还有几个常用操作:
reword:保留提交,但修改提交信息edit:停在这个提交,允许修改内容drop:丢弃这个提交(改动会消失)
整理完保存退出,Git 会逐个应用提交。如果过程中出现冲突,解决方式和普通 merge 不太一样:你需要把冲突文件改好,然后:
bash复制git add 冲突文件
git rebase --continue
如果中途发现改不下去,想回到开始之前的状态:
bash复制git rebase --abort
--abort 会完整撤销这次 rebase,回到操作前的位置。
这里有一个红线:只对还没有 push 到远程的本地提交做 rebase。如果这个分支已经推上去了,其他人可能已经基于它提交了代码,你再 rebase 就是在重写公共历史,会让所有人同步时痛苦不堪。所以我在团队里的约定是:本地分支随便整理,一旦提交到远程,就不再动它的历史。
3.2 git cherry-pick:只挑想要的改动
场景是这样的:你在 release 分支修了一个线上 bug,提交 hash 是 a1b2c3d。现在 main 分支要同步这个修复,但又不能把 release 分支上的一堆发布配置改动一起 merge 过来。这时候用 git cherry-pick。
bash复制git checkout main
git cherry-pick a1b2c3d
它的作用是把一个指定的提交“应用”到当前分支,并且生成一个新的 commit。注意是新 commit,所以新提交的 hash 和原来的不一样。
我早年间用 cherry-pick 踩过一次坑:从另一个分支 cherry-pick 了一个提交,后来那个分支又整体 merge 回当前分支,结果 Git 把同一处改动当成了两个不同补丁,出现了冲突。虽然这种“重复补丁”问题在现代 Git 里已经能靠算法识别,但并不能百分之百保证。所以团队里如果经常用 cherry-pick 同步修复,我建议养成两个习惯:
- cherry-pick 时加
-x,会在新提交信息里记录来源:bash复制
git cherry-pick -x a1b2c3d - 尽量让 cherry-pick 和 merge 的时机错开,避免同一个改动以两条路径进入同一分支。
cherry-pick 也支持一次拿多个提交,比如连续几个 hash:
bash复制git cherry-pick a1b2c3d e5f6a7b
或者范围:
bash复制git cherry-pick A..B
遇到冲突时和 merge 一样,解决后 git add,然后 git cherry-pick --continue 继续。
3.3 git revert:安全回滚的艺术
如果说 rebase 是“改历史”,那 git revert 就是“前进式的撤销”。它不修改已有提交,而是创建一个新提交,把某个提交的改动“反向执行”一遍。
bash复制git revert a1b2c3d
执行完,Git 会把 a1b2c3d 这个提交里新增的代码删掉、删除了的代码加回来,做成一个新的 commit。整个分支历史是线性的,之前的提交一个都没动过。
为什么说它适合线上回滚?因为公共分支上不允许改历史。如果你用 git reset 把线上分支回退,其他人 pull 时直接分叉,还得统一处理。而 revert 只需要所有同事正常 git pull,新提交会自动同步过去,不需要任何强推。
使用 revert 时有个细节最容易踩:要回滚的是一个 merge commit。因为 merge commit 有两个父提交,Git 不知道你希望回到哪一边的状态。这时候要指定 -m 参数:
bash复制git revert -m 1 <merge-commit-hash>
-m 1 表示以合并者的第一个父提交为主干,也就是说,撤销被合并进来的改动、保留主干上已有的提交。
另一个容易忽略的坑是:git revert 撤销了一次修改之后,如果之后你再 merge 那个原始分支,之前被 revert 的改动可能会“复活”,因为 Git 认为那个 commit 已经存在并应用过了,不会自动忽略。这种问题没有银弹,一般靠重新提交一个新的修复,或者在 revert 的提交信息里写清楚原因,方便后来的人理解上下文。
所以我的习惯是:主干分支上回滚一律用 revert,不用 reset;只有自己的本地未推送分支,才用 reset 和 amend 整理。这个界限一旦混淆,协作体验会直线下降。
4. 从线索到凶手:bisect、blame 和 log 高级搜索
前三章都在讲“怎么改”,这一章讲“怎么查”。很多时候 Git 的价值不只是版本控制,更是一个高可用的历史档案库。问题在于,大多数人只会 git log 看提交列表,遇到“这个 bug 是谁引入的”就抓瞎。这一章的三个命令就是干这个的。
4.1 git bisect:二分定位出问题的提交
“上个版本还是好的,这周发布之后就坏了”,这类问题在迭代快的团队里特别常见。如果靠人肉眼去翻 commit,几十上百条记录纯属浪费时间。git bisect 用的是二分查找思想,几十个提交里定位问题只需要几次判断。
使用方法很简单,先指定一个“当前坏”和一个“历史好”的提交:
bash复制git bisect start
git bisect bad # 当前提交不行
git bisect good v1.0.0 # v1.0.0 这个版本是好的
Git 会帮你 checkout 出中间某个提交,然后你跑测试判断这个提交是好是坏:
bash复制git bisect good # 这个提交没问题,说明坏提交在后面的区间
git bisect bad # 这个提交也坏了,说明坏提交在前面的区间
每判断一次,区间就缩小一半。重复几次,Git 会输出:“这是第一个坏提交”。
如果判断过程可以脚本化,还能全自动执行:
bash复制git bisect start
git bisect bad
git bisect good v1.0.0
git bisect run ./check.sh
脚本的退出码有约定:0 表示提交正常,1 到 127(除 125 外)表示提交有问题,125 表示无法测试(比如编译不过),Git 会跳过这个提交测试相邻的。
实际操作中,我一般会先确认一个问题能稳定复现,再 git bisect start,这样每步判断才可靠。跑完后记得收尾:
bash复制git bisect reset
这个命令会把你拉回到开始之前的分支状态。忘了 reset,你可能一直在中间那个提交上工作,找了半天才发现自己“离开”了当前分支。
为什么 bisect 高效?100 个提交只需要约 7 轮判断,1000 个约 10 轮。比起肉眼找,效率差距是数量级的。
4.2 git blame:逐行追责,快速找到修改人
一段代码写得莫名其妙,想看看是谁在哪个提交里写的、当时提交信息是怎么写的,用 git blame。
最基础的用法是整文件看:
bash复制git blame src/utils/validator.js
输出每一行的 commit hash、作者、时间和代码内容。但文件一大就刷屏,所以更常用的是限定行号:
bash复制git blame -L 30,45 src/utils/validator.js
这样只看第 30 到 45 行。看到那一行的 commit hash 之后,再:
bash复制git show 8f2a9c1
就能看到这个提交的全部改动和提交信息,理解当时的上下文。
blame 有几个实用参数:
-C:检测从其他文件复制过来的行(在不同仓库里可能需要-C -C或-M)-w:忽略空白差异,只盯实际代码变更-e:显示邮箱而不是用户名
很多人用 blame 是为了“找人追责”,我反而觉得它最大的价值是“找人问清楚”。代码经过多次重构,blame 显示的不一定是逻辑的原创者,但至少能帮你找到一个可能的起点。如果你发现某一行 blame 到的是一个“上次格式整理”的提交,别停在这儿,继续往这个文件的历史里挖。
VSCode 的 GitLens 插件把 blame 直接显示在行尾,在 IDE 里看非常方便。不过如果你想在终端环境里快速定位,直接敲命令还是最快的方式。
4.3 git log 高级搜索:按内容、按时间、按作者过滤
大多数人用 git log 只敲个 --oneline,其实它是个极其强大的搜索工具,尤其在大型代码库里找历史变更非常有用。
场景一:你记得某段代码里出现过字符串 fetchUser,不知道它在哪几个提交里被改过。
bash复制git log -S "fetchUser" --oneline
-S 会筛选出“新增或删除该字符串”的提交,它有个专门的名字叫 pickaxe。写错参数写成 -G 也可以用,但 -G 接受的是正则表达式,更灵活:
bash复制git log -G "fetch[A-Z]" --oneline
这些命令能直接定位到“哪次提交引入/删除了这段代码”,和 blame 配合起来一起用,查问题效率很高。
场景二:你想看某个文件里某段行号的历史变更。
bash复制git log -L 20,40:src/utils/user.js
-L 会把这个文件第 20 到 40 行在各次提交中的每次修改都列出来,适合追某个函数怎么一步步演变成现在的样子。
场景三:按作者和时间过滤提交记录。
bash复制git log --author="zhangsan" --since="2 weeks ago"
git log --all --oneline --graph --decorate
--all 表示看所有分支,--graph 会把分支图用 ASCII 画出来,--decorate 显示分支和 tag 名称。这个组合在检查仓库全貌时非常常用。
我日常排查问题的固定套路是:先用 git log -S 找到可疑的提交,再用 git show 看改动详情,如果涉及具体行就用 git blame 定位,最后如果还不确定是哪次提交引入的,就上 git bisect。这一套流程下来,大部分“代码怎么就坏了”的悬案都能快速结案。
5. 串起来的一天:一套可复制的 Git 工作流
前四章把 12 个命令拆开了讲,最后我用自己的日常流程把它们串起来,你可以直接照着这个节奏走,慢慢就会形成自己的“肌肉记忆”。
早上上班,先从远程 main 同步到本地:
bash复制git fetch origin
git checkout main
git pull --rebase origin main
git checkout -b feature/xxx
开始写功能,写到中午,来了个紧急线上问题。先把自己的半成品暂存起来,注意加 -u,因为新文件也想带走:
bash复制git stash push -u -m "feature/xxx: 表单联调中"
git checkout -b hotfix/yyy master
# 修 bug,提交
git commit -m "fix: 修复登录接口超时"
git push origin hotfix/yyy
git checkout feature/xxx
git stash pop
功能做完,不想把所有改动放进一个 commit。用 git add -p 把“修了一个校验 bug”和“加了一个新按钮”分开提交。提交完发现第一次提交信息写错了:
bash复制git commit --amend -m "fix: 修正手机号校验规则" --no-edit
本地攒了好几个 commit,push 之前用 git rebase -i HEAD~5 整理成 2 到 3 条结构清晰的提交。确认没问题后:
bash复制git push origin feature/xxx
线上版本出问题,需要回滚某个功能。如果那个改动已经发布了很久,不能直接 reset,用:
bash复制git revert a1b2c3d
某天同事说“这个功能的某个数据统计不对,之前还是好的”,我第一反应不是去翻代码,而是:
bash复制git log -S "user_statistics" --oneline
找到对应 commit 后 git show 看改动。如果提交很多且都不确定,就 git bisect 二分定位。要确认某一行是谁写的,直接 git blame。
这套流程的核心思路是:提交尽量小而清晰,危险操作前先备份,重写历史只在本地私有分支,公共分支全部用前进式操作。只要把这几条原则记在心里,你就已经和“只会 git add .”拉开差距了。
最后整理一份速查表,方便你随时翻阅:
| 命令 | 核心用途 | 一句话提醒 |
|---|---|---|
git add -p |
选择性暂存改动 | 提交前先花 1 分钟分块 |
git commit --amend |
修正上一次提交 | 别用在已推送的提交上 |
git reset --soft |
撤销提交但保留改动 | 整理历史最安全的一种 |
git reflog |
找回丢失的提交 | 90 天内都有救 |
git stash -u |
临时保存工作区 | 新建文件记得加 -u |
git clean -fd |
清未跟踪文件 | 永远先 -n 预览 |
git rebase -i |
交互式整理提交 | 只对未推送提交用 |
git cherry-pick -x |
精选某个提交 | 跨分支同步修复必备 |
git revert |
安全回滚 | 公共分支回滚首选 |
git bisect |
二分定位问题提交 | 准备可复现的好/坏标志 |
git blame |
逐行查看修改历史 | 找上下文,不是找责任人 |
git log -S/-L |
按内容搜索历史 | 大型仓库里的“谷歌” |
这 12 个命令里,有 8 个是我日常几乎每周都会用到的,另外几个虽然不常用,但每次用到都是“救命”级别的场景。你自己在项目里多试几回,不用刻意背,用多了自然就记住了。
