尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Git常用命令进阶:撤销回滚、历史整理、故障救援与仓库清理
Git 常用命令这东西学会和用对完全是两码事。这些年带人上手版本管理我观察到一个特别普遍的现象新人花半天就能背下 add、commit、push 这套三件套一旦遇到“我提交了不该提交的文件”“我 reset 之后分支好像没了”“我改写了别人已经拉下去的提交”这类情况立刻就卡住只能现场去搜搜完照抄一遍下次再遇到还是不会。这一篇是系列随笔的第四篇前三篇把日常提交流程、分支操作、远程协作这些基础盘铺完了这次换个角度专门聊那些平时用得少、关键时刻能救命的部分包括撤销、回滚、历史整理、故障救援和仓库清理五类 Git 常用命令。适合已经能独立提交代码、但一遇到“历史出问题”就慌的读者也适合想把自己那套零散命令整理成体系的人。1. 这一篇要解决的核心问题1.1 命令背下来了场景却对不上号我把新手卡壳的原因归成一句话把 Git 当成一个“有状态的文件备份工具”来理解而不是一个“不可变提交链 可移动指针”的系统。前者会让你以为reset是删除revert是撤销checkout是切换其实它们动的东西完全不同。真正让人踩坑的从来不是命令拼写而是你不知道这条命令动的是工作区、暂存区还是提交历史动完之后原来的东西还在不在。举个我自己踩过的例子。早些年我在一个模拟项目里做实验本地有三个提交没有推其中一个提交里混进了一个几百兆的日志文件。当时的想法很简单git reset --hard HEAD~3回到干净状态重来一遍。结果三个提交里的代码改动全没了因为--hard会连同工作区一起重置。那次之后我才老老实实去把 reset 的三种模式一个一个试明白也才理解为什么老手总是先reset --soft再决定下一步。所以这一篇不会按字母顺序罗列命令而是按“你想达成什么”来组织。每一组命令我都会说清楚三件事它动了哪一层、执行后原来的东西还在不在、什么情况下绝对不能用。搞清楚这三点命令表就不用背了遇到问题你自己能推出来该用哪条。1.2 三条主线撤销、整理、救援整篇内容我按三条主线来铺。第一条是撤销线回答“我提交错了、暂存错了、工作区改乱了怎么退回去退到哪一层才安全”。这条线的核心是restore、reset、revert三个命令的边界划分也是最容易混淆的地方第 2 章专门拆。第二条是整理线回答“提交太碎、提交信息写错、想把某个分支上的一个提交搬到另一个分支怎么在不制造混乱的前提下把历史弄干净”。这条线涉及commit --amend、rebase -i、cherry-pick第 3 章和第 4 章分别讲暂存区的精细操作和历史改写。这里有个前提必须提前说清楚历史整理只对还没推送、或者只有你自己在用的分支做一旦别人基于你的提交继续开发改写历史就是在给别人制造事故。第三条是救援线回答“我已经把东西弄丢了还能不能找回来”。这条线的核心是reflog它是 Git 里最被低估的命令没有之一。配合bisect和log -S基本能覆盖“找不回提交”“不知道哪次改动引入的 bug”“不知道这行代码是谁写的为什么这么写”这三类高频困境第 5 章展开。最后第 6 章收尾讲清理类的命令包括删分支、清远程引用、仓库瘦身以及一份我自己常用的场景速查表。这些命令平时不起眼但仓库跑久了体积膨胀、远程分支列表堆成山的时候它们能让你的日常操作重新变得利索。2. 撤销三兄弟restore、reset、revert 的边界在哪2.1 先把三个区域在心里摆好讲撤销之前必须先把 Git 的三层结构摆明白否则后面全是糊涂账。第一层是工作区就是你编辑器里看到的那些文件第二层是暂存区也叫索引是git add之后、git commit之前的那块中间地带第三层是提交历史是git commit之后进入的那条链。三层是从下往上单向流动的工作区改动 → add 进暂存区 → commit 进历史。理解这三层之后很多命令的差异就自解释了。git restore只在工作区和暂存区之间倒腾压根不碰提交历史git reset会把提交历史的指针往回拨然后根据模式决定要不要顺带重置暂存区和工作区git revert则是往前走一步用一个新的提交去抵消旧提交的效果历史一条都不删。这就是为什么团队协作里公开回滚只能用revert——它不改写任何已有提交别人拉下去不会有任何冲突。我习惯用一个类比跟人解释提交历史像一摞已经装订好的账本reset是把账本撕掉最后几页重新写revert是在账本最后再补一页写着“前面某页记错了以此页为准”。前者干净但要求这几页没别人看过后者啰嗦但谁都能看懂。提示判断用哪个命令先问自己一句“这些提交有没有别人在用”。有就只能 revert没有才轮到 reset。2.2 restore 的两个方向别搞反git restore是 Git 2.23 之后引入的用来替代过去那个语义混乱的git checkout -- file。它有两个方向方向搞反是最常见的低级错误。第一个方向是从暂存区恢复到工作区命令是git restore file。效果是把工作区里这个文件改回暂存区里的版本你在编辑器里手改的内容就没了。这个操作用在“我改乱了想回到上次 add 的状态”。第二个方向是从 HEAD 恢复到暂存区命令是git restore --staged file。这个操作只把文件从暂存区里撤出来工作区里的改动原样保留等价于老写法git reset HEAD file。它用在“我 add 多了想把某个文件从这次提交里拿出去”。这两个方向的差别我用一句话记不带--staged是丢工作区的改动带--staged是丢暂存区的登记。前者丢的是你刚敲的代码后者丢的只是“准备提交”这个标记。危险程度完全不同前者一旦执行编辑器里没保存的内容就真没了除非你用 IDE 的本地历史功能兜底。还有一个实用变体git restore --sourceHEAD~2 file可以从任意一个历史提交里把某个文件取回到工作区。这个场景在排查“这个配置文件上个版本是什么样”时特别好用比git show HEAD~2:path/to/file再手动复制粘贴快得多。我处理线上配置回滚的时候经常用这一手先取回旧版本对照确认没问题再改。2.3 reset 的三种模式各自留下什么git reset是争议最大的命令因为它有三种模式效果差别巨大而默认模式又不是最安全的那个。它的基本语法是git reset [--soft | --mixed | --hard] 目标提交作用是先把当前分支的 HEAD 指针移到目标提交然后按模式决定暂存区和工作区怎么处理。--soft只移动 HEAD 指针暂存区和工作区一个字节都不动。效果是目标提交之后的所有改动全部变成“已暂存待提交”的状态。这个模式最安全我几乎只在一种场景用它几个零碎提交想合并成一个。比如我连着提交了三次“改一点”“再改一点”“忘了改这个”用git reset --soft HEAD~3三次改动就都回到暂存区重新写一条像样的提交信息提交一次历史立刻清爽。--mixed是默认模式移动 HEAD 指针同时把暂存区重置成目标提交的样子但工作区保留。效果是那些改动变成了“未暂存”状态需要重新 add。这个模式适合“我想重新组织这次提交的内容”比如原来一次提交混了三个不相关的改动reset --mixed HEAD~1之后用add -p拆成三次提交。因为它是默认值所以裸敲git reset HEAD~1就是这个行为很多人以为它是--hard其实是误会。--hard是最狠的HEAD 指针、暂存区、工作区三者全部重置到目标提交的状态。工作区里所有未提交的改动直接消失而且不进 reflog 能直接找到的地方——未提交的改动本身就不在任何提交里reflog 也救不了。所以我对这条命令的态度是执行前必须先git status看清楚有没有未提交的改动有就先 stash 一下再动手。这个习惯救过我至少两次。模式HEAD 指针暂存区工作区典型用途风险--soft移动保留保留合并多个提交极低--mixed默认移动重置保留重新拆分提交内容低--hard移动重置重置彻底放弃本地改动高未提交内容不可恢复2.4 revert 是团队协作里唯一能公开用的回滚git revert commit的机制前面提过它不删除任何历史而是生成一个新提交内容是指定提交的逆操作。比如某次提交加了一行代码revert 那个提交就会生成一个删掉这行代码的新提交。历史是一条直线往前走的谁拉下去都不会冲突。它最常见的用法是针对已经推送到共享分支的提交。假设某个改动上线后发现问题直接reset再强推会把所有人的本地分支搞乱正确做法是git revert 出问题的提交哈希然后正常推送。这样提交历史里同时保留了“改了什么”和“为什么改回来”对事后复盘其实是好事。有几个细节值得记一下。第一revert 一个合并提交需要加-m 1指定保留哪个父提交-m 1表示保留第一个父提交也就是合并前所在分支的那条线这个参数不指定会直接报错。第二git revert --no-commit hash可以只应用逆操作但不自动提交方便你连续 revert 多个提交后一次性提交或者在中途调整冲突。第三revert 也会有冲突尤其是被 revert 的提交之后同一片代码又被改过这时候按普通冲突处理流程解决就行不用慌。我个人有个习惯revert 的提交信息里会补一句原因比如“revert: 回滚配置项默认值原因是该值在灰度环境导致超时”。默认生成的Revert xxx信息太干过两个月自己都想不起来为什么回滚。2.5 场景对照表什么问题用哪条命令把上面这些揉成一张表遇到问题时对号入座比翻文档快。你遇到的情况该用的命令备注工作区文件改乱了想还原git restore file未保存的改动会丢add 多了想把文件撤出暂存区git restore --staged file工作区改动保留最近三个提交想合并成一个git reset --soft HEAD~3安全改动回到暂存区最后一次提交信息写错了git commit --amend未推送才用想彻底放弃本地所有未提交改动git reset --hard或git restore .高危先 stash已推送的提交要撤销git revert hash唯一公开安全的做法回滚一个合并提交git revert -m 1 hash必须指定父提交这里额外说一个容易忽略的点git reset --hard之后如果想找回其实是有机会的因为 HEAD 的移动记录在 reflog 里只要那个提交曾经存在过git reset --hard HEAD{1}就能回去。但如果你 reset 掉的是从未提交过的改动那就真的没了。所以我在团队里推的一条规矩是动手改历史之前先git stash push -m before-reset多这一步成本几秒钟能省掉一整天。3. 暂存区的手上功夫stash 与 add -p3.1 stash 不只是敲一下那么简单很多人对git stash的理解停留在“临时存一下”用的时候就是裸敲git stash取的时候git stash pop中间发生了什么一概不知。这个用法在简单场景够用但 stash 其实是个栈能存多份能带注释能包含未跟踪文件还能只存一部分。先说最基本的形态。git stash等价于git stash push它会把当前工作区和暂存区的改动打包存进栈里然后把工作区恢复到 HEAD 的干净状态。这里有个容易踩的坑默认情况下未跟踪的新文件不会被 stash。你新建了一个文件还没 add敲git stash之后git status还是能看到它很多人以为 stash 失败了。要包含未跟踪文件得加-u即git stash push -u要连被忽略的文件一起存比如临时改了个.env得用-a。带注释是我强烈建议养成的习惯git stash push -m 调试支付回调的临时改动。因为 stash 栈一多git stash list出来全是WIP on main: 3a4b5c6根本分不清哪个是哪个。我见过有人攒了十几个 stash最后不敢 pop 也不敢 drop干脆整个仓库重新 clone 一遍纯属自己给自己挖坑。查看和清理的配套命令也记一下git stash list看列表git stash show -p stash{0}看某一条的具体 diffgit stash drop stash{0}删掉某一条git stash clear清空整个栈。clear是不可逆的敲之前确认一下列表里没有还需要的东西。3.2 stash 恢复的两种方式与冲突处理恢复有pop和apply两个命令差别只有一个pop恢复之后会把这条 stash 从栈里删掉apply恢复之后保留。我个人的习惯是优先用 apply确认没问题再手动 drop。原因很实际apply 之后如果解决冲突时搞砸了stash 还在可以再来一次pop 一旦冲突处理失败那条 stash 就没了只能靠 reflog 碰运气。冲突是 stash 恢复时的常客。典型场景是你 stash 了改动然后切到别的分支干了点活回来发现原来那几个文件已经被别人改过了pop 的时候就会冲突。处理方式和普通合并冲突一样文件里会出现冲突标记手动改完git add一下然后git stash drop清掉那条记录。这里要注意冲突状态下 stash 是不会自动删除的得手动 drop不然栈里会一直挂着一条已经应用过的记录。还有一个进阶玩法值得知道git stash branch 新分支名 stash{0}。它会把某条 stash 的内容直接应用到一个从 stash 创建点拉出来的新分支上。这个命令解决的是“stash 放了太久当前分支已经变太多pop 必然大面积冲突”的困境。我处理过一个放了两个多月的 stash直接在原分支 pop 冲突几十个文件用 stash branch 拉出独立分支慢慢合效率高得多。3.3 add -p 把一次提交切干净git add -p是我认为最被低估的 Git 命令。它的作用是把一个文件的改动拆成若干个块逐块问你要不要暂存。交互界面里每块会问你Stage this hunk [y,n,q,a,d,s,e,?]最常用的几个y暂存这块n跳过这块s把大块拆成更小的块q退出?看帮助。e是手动编辑一般用不上。这个命令解决的是什么问题假设你改一个文件的时候顺手把旁边的格式问题也修了还加了个调试用的console.log。这时候一次性git add会把三件事混进一个提交review 的人看着难受将来要回滚其中一件也回滚不干净。用add -p逐块挑选只把真正的功能改动暂存进去格式调整和调试代码另外处理提交粒度立刻就对了。我一般的工作流是这样改完代码先git diff整体过一遍心里有数分成几块然后git add -p逐块暂存只挑跟这次任务相关的暂存完git diff --staged再确认一遍暂存内容最后提交。多花两三分钟但提交历史会干净很多。这套流程我坚持了几年最大的收益是半年后回头看某个提交能一眼看出它到底做了什么而不是一堆混在一起的噪音。注意add -p的拆分是按上下文行来的如果你的改动太密集可能拆不开。这时候可以先手动把不相关的部分改回去做完这次提交再重新改别硬拆。4. 历史整理amend、rebase、cherry-pick4.1 amend 的适用边界比想象中窄git commit --amend的作用是修改最后一次提交。最常见的两个场景提交信息写错了要改或者提交完发现漏了一个文件。前者用git commit --amend -m 新的提交信息后者先git add 漏掉的文件再git commit --amend --no-edit--no-edit表示沿用原来的提交信息。它的边界在哪只在最后一次提交还没推送到共享分支的时候用。因为 amend 本质上是把旧提交删了、生成一个新提交哈希完全不同。如果这个提交已经推上去你需要 force push 才能覆盖远程而 force push 会影响到所有基于这个提交继续开发的人。我见过最典型的翻车现场某人 amend 了自己已经推的提交然后强推第二天同事拉代码发现本地多出来一堆莫名其妙的冲突排查半天才发现是历史被改写了。如果你确实需要修改已经推送的提交标准流程是改完之后用git push --force-with-lease而不是--force。加--with-lease的好处是它会在推送前检查远程分支有没有别人的新提交如果有就拒绝推送避免你覆盖掉同事的工作。这个参数是我在团队规范里强制要求的比裸--force安全一个数量级。顺带说个使用频率很高的组合git commit --amend --author名字 邮箱用来修正作者信息。有些人在共享机器上提交或者本地 Git 配置没配对提交上去作者是错的用这个可以改最后一次。至于改更早的提交作者就得进 rebase 了。4.2 rebase -i 压缩提交的完整走法git rebase -i是历史整理的主力交互式界面出来是一列提交每行前面有个动作指令。最常用的三个pick保留squash合并到上一个提交并把两条提交信息拼起来fixup合并到上一个提交但丢弃这条的提交信息。另外reword改提交信息drop删掉提交edit停下来让你改内容。完整走一遍压缩的流程。假设当前分支比主分支多了四个提交想把后三个压成一个git rebase -i HEAD~4。编辑器打开后第一行保持pick后三行的pick改成squash保存退出。Git 会依次把后三个提交合进第一个中途弹出编辑器让你编辑合并后的提交信息把不要的行删掉留一条清晰的保存退出。最后git log --oneline确认一下四个提交变成了两个。这里有几个实操中的细节。第一rebase 过程中如果冲突Git 会停下来你解决完冲突后git add相关文件然后git rebase --continue如果想放弃git rebase --abort会回到 rebase 开始前的状态这个 abort 是新手的安全绳别怕用。第二squash和fixup的区别很多人搞混简单记想保留提交信息用 squash想丢掉用 fixup。日常修 bug 的碎提交我基本全用 fixup因为它们的信息毫无保留价值。第三点也是最重要的一点rebase 会改写提交哈希整条链上从改动点开始往后的所有提交哈希都会变。所以在你 rebase 之前先确认这条分支只有你在用。我一般的判断标准是看远程分支上有没有别人的提交git log origin/feature --not --author我的邮箱有输出就说明有别人在推这种情况老老实实用 merge别碰 rebase。4.3 cherry-pick 挑提交的坑比想象中多git cherry-pick hash的作用是把另一个分支上的某个提交单独应用到当前分支。典型场景是修 bug 的时候在开发分支上改好了需要把这个修复也同步到发布分支但不想带上开发分支上其他还没完成的改动。这时候 cherry-pick 就派上用场了。它的基本用法很简单git cherry-pick hash直接应用git cherry-pick hash1 hash2连续应用多个git cherry-pick hash1..hash2应用一个区间。加-x参数会在提交信息里追加一行“cherry picked from commit xxx”记录来源这个参数我强烈建议默认带上因为过几个月谁也记不清这个提交是从哪挑过来的。加--no-commit可以只应用改动不自动提交方便你连续挑多个提交后合并成一次提交。坑主要在冲突上。cherry-pick 是“重放”某个提交的改动如果目标分支上对应的上下文已经变了冲突就不可避免。这时候处理方式和普通合并一样改完git add然后git cherry-pick --continue。如果发现挑错了git cherry-pick --abort可以整体放弃。另外一个隐蔽的坑是cherry-pick 一个合并提交需要-m参数和 revert 一样不指定会报错而且挑完之后合并关系就丢了历史变成一条直线将来想追溯原始的合并关系会很难。我个人的使用原则是cherry-pick 只用于“把修复同步到多个长期分支”这种明确的场景不用它替代正常的分支合并。因为挑得越多两条分支的提交内容就越像但不完全一样将来合并的时候冲突会非常难解。这个感受只有真正踩过才懂——两条分支上有一堆内容相同但哈希不同的提交合并时 Git 根本认不出来它们是同一份改动。4.4 rebase 和 merge 怎么选别听口号关于 rebase 还是 merge网上有很多口号式的说法比如“团队协作永远用 merge”“个人分支永远用 rebase”。这些说法有道理但不完整我的实际判断标准只有两条这条分支有没有别人在用以及你要的是线性历史还是完整的分支拓扑。如果分支只有你自己用或者是一次性的功能分支rebase 能让历史保持线性git log看起来清爽。如果分支是共享的长期分支或者你需要保留“这个功能是从哪个点分出去的、中间合并过几次主干”这类信息merge 更合适。还有一个实际考量merge 会产生合并提交回滚整个功能的时候只需要 revert 那个合并提交一次搞定而 rebase 出来的线性历史要回滚整个功能得 revert 一堆提交或者整体 reset麻烦得多。我在实际项目里通常是这么搭配的本地开发阶段随便提交用 rebase -i 整理成逻辑清晰的几条推送到远程的功能分支后就不再 rebase用 merge 同步主干最终合并回主干的时候看团队习惯如果是小功能就直接 squash merge 成一个提交如果是大功能就保留 merge 提交。这套组合用下来历史既不会乱成一团也不会因为过度追求线性而给协作添麻烦。5. 出事了怎么救reflog、bisect、log -S5.1 reflog 找回你以为丢掉的提交git reflog是我最想在每个新人的第一课上讲的命令。它记录的是 HEAD 的每一次移动包括 commit、reset、checkout、rebase、merge、pull甚至包括你切换分支。每一条记录都有对应的哈希和一个HEAD{n}的引用n 是移动的序号。默认保留 90 天也就是说只要提交存在过90 天内基本都能找回来。最典型的救援场景是reset --hard之后发现 reset 多了。操作很简单先git reflog看列表找到 reset 之前那条记录的哈希或者HEAD{n}然后git reset --hard HEAD{n}回去。整个过程两秒钟但如果你不知道 reflog可能就得重新写一遍代码。第二个常见场景是 rebase 搞砸了。rebase 会改写一串提交如果压缩错了或者中途 abort 失败用git reflog找到 rebase 开始前的那个点reset 回去就行。我有一次 rebase -i 的时候手滑把pick改成了drop一个提交直接消失了当时心里一沉然后想起来 refloggit reflog一看rebase 之前的 HEAD 就在上面一条命令搞定。第三个场景稍微绕一点误删的分支。git branch -D删掉一个分支之后如果那个分支上的提交没有合并到任何其他分支分支名是没了但提交对象还在git reflog里能找到那个分支最后一次指向的提交哈希然后git branch 分支名 哈希就能把分支重新建出来。这个技巧我用过一次救回了一条废弃了但突然又需要参考的老分支。提示reflog 只记录本地仓库的 HEAD 移动不记录远程分支的变化也不跨机器。换一台电脑 clone 下来reflog 是空的。5.2 bisect 用二分法定位问题提交git bisect解决的问题是你知道某个版本是好的某个版本坏了中间隔了几百个提交不知道是哪个引入的问题。手动一个个 checkout 试几百次下来人就麻了。bisect 用二分查找理论上 1000 个提交只需要约 10 次验证就能定位到具体那一个。基本流程是这样git bisect start开始git bisect bad标当前版本有问题git bisect good 一个好的提交哈希标一个已知正常的版本。Git 会自动 checkout 到中间的某个提交你测试一下有问题就git bisect bad没问题就git bisect good它继续缩小范围直到定位到第一个坏提交输出那个提交的哈希和信息。最后git bisect reset回到原来的分支。如果每次验证是跑一个自动化脚本可以用git bisect run 命令比如git bisect run npm test让它全自动跑完。这个组合在排查“某个测试从哪次提交开始失败的”时效率极高。不过要注意脚本的退出码语义0 表示 good1-127除 125表示 bad125 表示这个提交没法测要跳过。写 run 脚本的时候别搞反了。实际用的时候有个经验值得分享bisect 的准确性完全取决于你标记的 good 和 bad 是否可靠。如果那个“好版本”其实本身就有问题整个二分路径都是错的最后定位出来的提交毫无意义。所以开始之前务必手动验证一下两端的版本确认判断标准清晰。另外 bisect 过程中会频繁切换工作区有未提交的改动记得先 stash不然可能切不过去。5.3 blame 与 log -S 追溯代码的来历git blame file会把文件的每一行标上最后一次修改它的提交、作者和时间。它最直接的用途是看某行奇怪的代码是谁写的、什么时候写的、在哪个提交里。但要强调一点blame 是找上下文不是找人追责。我在团队里明确说过blame 出来的结果只用于理解代码谁要是拿它去质询同事下次没人愿意写有价值的提交信息了。blame 有个很实用的参数-L可以只看文件的某几行比如git blame -L 120,160 path/to/file文件几千行的时候省时间。另一个参数-w会忽略空白改动避免因为一次全局格式化把真正的逻辑作者冲掉。这个参数在处理“有人跑了一遍格式化工具所有行都变成他写的”这种历史时特别有用。git log -S关键词是另一个大杀器它按“某个字符串的出现和消失”来筛提交官方叫 pickaxe。典型场景是你想知道某个函数是什么时候加进来的、什么时候被删掉的。比如某个配置项在某次上线后突然失效你想找它是什么时候被改的git log -Sconfig.timeout --oneline会列出所有增加或删除过这个字符串的提交直接锁定范围。还有一个变体-G是按正则匹配改动内容比-S更灵活但速度慢一些。这三个命令配合起来用基本能回答“这行代码为什么长这样”的所有问题blame 找到具体提交git show hash看那次提交的完整改动git log -S往前追这个模式的历史演变。我用这套组合排查过一个困扰了很久的配置覆盖问题最后发现是三个月前一次临时改动忘了还原全程不到十分钟。6. 收尾清理分支、远程引用与仓库瘦身6.1 删分支和清远程引用的差别git branch -d 分支名删除本地分支前提是它已经被合并到当前分支没合并会拒绝删除并提示。要强制删就-D但强制删之前最好用git log 分支名 --not --all看一眼这个分支上有没有独有提交有的话删掉就只能靠 reflog 捞了。远程分支的处理是另一回事。你在网页上或者别人删了远程分支之后本地的git branch -r里那个origin/xxx还在这是正常现象因为本地保存的远程引用不会自动同步。清理方式有两种git fetch --prune在拉取的同时清理已经消失的远程引用git remote prune origin单独执行清理。我习惯把fetch.prune配成 true也就是git config --global fetch.prune true这样每次 fetch 和 pull 都自动清理不用记着加参数。这个配置建议所有人都开成本为零。还有一个组合用法值得记git branch -vv会列出本地分支及其对应的远程分支和领先落后情况。输出里如果某个分支的 upstream 显示[origin/xxx: gone]说明远程分支已经被删了这个本地分支就可以考虑清理。我一般每隔一两周跑一次git branch -vv把 gone 的分支和被合并的分支清一遍本地分支列表保持在十条以内切分支的时候好找。6.2 仓库体积膨胀了怎么办用久了的仓库会慢慢变大尤其是历史里误提交过大文件的那种。排查第一步是git count-objects -vH看size-pack这一项这是压缩后仓库的实际体积。如果发现体积远超预期通常是历史里某个大文件在作祟。定位历史大文件可以用git rev-list --objects --all配合git cat-file --batch-check排序但命令太长了不好记。更简单的做法是装个git-sizer之类的辅助工具或者直接用git verify-pack -v .git/objects/pack/*.idx | sort -k3 -n | tail -5找出最大的几个对象。找到了之后如果那个文件确实不该进仓库处理方式是重写历史把它剔掉这就又回到了第 4 章的原则只有在你确认没有别人基于这段历史开发时才能做否则所有人得重新 clone。日常维护的常规手段是git gc它会打包松散对象、清理不可达对象。默认 Git 会在对象数量达到阈值时自动触发一般不用手动跑。如果确实需要彻底清理git gc --prunenow --aggressive会更彻底但耗时长大仓库可能要跑十几分钟建议放在下班前跑。另外一个容易忽略的点是.gitignore的维护日志文件、构建产物、本地配置、依赖目录这几类一定要提前排除等到提交进去了再来清理成本高十倍。6.3 高频问题速查表最后整理一份我自己常年贴在便签上的速查表按症状查方案。症状排查或解决命令说明提交错了文件git reset --soft HEAD~1后重新 add未推送才用提交信息写错git commit --amend -m 新信息未推送才用想找回 reset 掉的提交git reflog找点后git reset --hard HEAD{n}90 天内有效分支删了想恢复git reflog找哈希后git branch 名字 哈希需提交未被清理暂存区加多了git restore --staged file工作区不动工作区改乱了git restore file未保存内容会丢远程分支显示 gonegit fetch --prune建议配置自动不知道哪次提交引入的 buggit bisect start配合 good/bad两端要验证准确想看某行代码来历git blame -L 起,止 文件名用于理解不是追责找字符串何时增删git log -S关键词 --onelinepickaxe 模式仓库体积异常git count-objects -vH重点看 size-pack用这张表的时候有个前提要反复强调凡是带--hard、-D、--force的操作执行前先跑一次git status和git stash push -m 保险。这两步加起来不到五秒但在我自己的经历里它至少救回过三次半天的活。命令记得再熟也不如留一条退路实在。我个人在实际操作中的体会是Git 这些命令真正难的不是记参数而是建立一个稳定的判断顺序先看这三层哪一层出了问题再看这些提交有没有别人在用最后才选命令。顺序对了你甚至不需要背具体的参数敲之前git xxx --help翻一眼就够。反过来顺序错了命令背得再全也只是在赌运气。
RELATED

相关推荐

kkFileView 4.4.0-beta 部署实战:从解压到前端对接的避坑指南

kkFileView 4.4.0-beta 部署实战:从解压到前端对接的避坑指南

简介:kkFileView-4.4.0-beta 压缩包面向需要在浏览器端统一预览各类办公文档与媒体文件的开发者及运维人员,可用于搭建在线文件预览服务、集成到自有业务系统或研究其实现思路。包内共约 2000 个文件,以 properties 配置、Python 脚本、txt 说…

📅 2026/10/27 5:36:33
marketingskills:从知识到肌肉记忆的市场响应力训练

marketingskills:从知识到肌肉记忆的市场响应力训练

1. 这不是“学营销”,而是重建你和钱的关系:一个干了12年一线营销的老兵,为什么把“marketingskills”当成本能训练“marketingskills”——这个词在搜索引擎里每天被搜超过23万次,但90%的人点进去看到的,是PPT模板、话…

📅 2026/10/27 5:36:33
前端开发者如何应对技术焦虑与信息过载

前端开发者如何应对技术焦虑与信息过载

1. 从一次需求评审会说起那天产品经理甩出一份竞品分析报告,指着某个交互效果说"这个必须下周三上线"。我盯着那个酷炫的3D卡片翻转动画,手指无意识地在键盘上敲击——上次用CSS 3D Transform还是两年前毕业设计的时候。会议室里后端同事已经掏…

📅 2026/10/27 5:36:33
MORE NEWS

更多资讯

📰

Windows本地AI智能体OpenClaw一键部署与优化指南

1. OpenClaw 小龙虾:Windows 本地 AI 智能体部署全攻略最近在折腾本地 AI 智能体的朋友应该都听说过 OpenClaw 这个项目,它就像一只灵活的小龙虾,能帮你快速搭建起功能强大的 AI 智能体开发环境。作为一个在 Windows 平台实测过多次的老玩家&…

📰

昇腾AI处理器与ComfyUI适配实战指南

1. 昇腾与ComfyUI适配的核心价值昇腾AI处理器作为国产算力代表,其与ComfyUI的适配打破了传统AI创作工具对NVIDIA显卡的依赖。实测表明,昇腾310P在Stable Diffusion推理任务中可实现8-12it/s的生成速度,与RTX 3060ti性能相当。这种适配不仅意味…

📰

VSCode远程连接WSL开发环境配置指南

1. 为什么需要VSCode远程连接WSL虚拟机?作为Windows系统下的开发者,我们经常面临一个尴尬局面:既需要Windows的办公便利性,又依赖Linux的开发环境。传统解决方案要么是双系统切换(影响工作效率)&#xff0c…

📰

扫地机器人技术演进与家庭物联网应用

1. 从吸尘器到机器人革命:一场家庭清洁工具的进化史2002年,当第一台Roomba扫地机器人出现在美国CES展会上时,大多数人都把它当作一个有趣的玩具。谁能想到,这个圆盘状的自动吸尘器会成为开启服务机器人时代的钥匙?如今…

📰

Docker容器化AI工具链:环境一致性与生产实践

1. 为什么要在Docker中运行AI CLI工具?在AI工具链快速迭代的今天,开发者和研究人员常常面临环境配置的噩梦。以Stable Diffusion CLI为例,原生安装需要处理CUDA驱动、Python版本、依赖冲突等一系列问题。而Docker通过以下特性完美解决了这些痛…

📰

性能调优实战:从原理到参数优化的黄金方法论

1. 性能调优的本质与核心逻辑性能调优从来不是简单的参数堆砌,而是一场针对系统瓶颈的精准外科手术。我见过太多团队在性能问题上陷入"参数迷信"的误区——盲目套用网上搜来的配置模板,把JVM堆内存调到8GB却发现GC更加频繁,给MySQL…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬