19 — 贮藏与清理:stash 是抽屉,gc 是打包箱
19 — 贮藏与清理stash 是抽屉gc 是打包箱摘要本章介绍 Git 中两个实用工具git stash用于临时贮藏未提交的改动像把桌面物品扫进抽屉方便切换分支处理紧急任务git gc用于垃圾回收和打包像整理档案柜将散落的小对象压缩成 pack 文件以节省空间。通过对比表格、动手实验和真实场景帮助读者掌握 stash 的暂存与恢复流程、gc 的安全清理机制并建立安全使用习惯。写在前面这一章要解决什么你有没有遇到过这种情况正在写功能写到一半突然老师说「先修一下这个紧急 bug」。你想切到别的分支去修 bug但当前分支的代码还没写完、不想提交。怎么办这就是git stash存在的意义——把没写完的代码暂时藏进抽屉里等修完 bug 再拿出来继续写。这一章还讲git gc垃圾回收——仓库用久了会越来越大gc 就像打包箱把散落的小文件打包压缩。学完后你应该能用git stash临时藏起没写完的改动用git stash pop拿回之前藏的改动理解 stash 底层是特殊的 commit知道什么时候该用git gc理解包文件pack是什么读者设定大一同学已经会用分支和基本命令但还没用过 stash 和 gc。1. 定位为什么要学贮藏和清理1.1 一句话先记住stash 把桌面上的东西暂时扫进抽屉等会儿再拿出来gc 把档案柜里散落的文件打包装箱节省空间。1.2 不知道 stash 会怎样没有 stash有 stash写到一半想切分支Git 不让有未提交的改动git stash藏起来随时切只好先提交一个「写了一半」的存档不需要提交半成品保持历史干净或者把改动复制到别的地方保存一条命令搞定不用手动复制忘了复制到哪里了git stash list随时查看所有藏起来的东西1.3 和你已经会的事对比你已经会的和这一章的关系第 04 章的git restorerestore 是丢弃改动stash 是暂时藏起来以后还用第 05 章的分支切分支时经常需要先 stash第 10 章的对象模型stash 底层就是特殊的 commit 对象2. 本质stash 到底做了什么2.1 stash 的底层原理当你执行git stash时Git 做了这些事把工作区和暂存区的差异保存为一个特殊的 commit这个 commit 有两个 parent工作区状态和暂存区状态把它存在refs/stash引用下把工作区和暂存区恢复到 HEAD 的状态白话你把桌面上没做完的作业放进抽屉桌面恢复到上次交作业的状态。抽屉里的作业随时可以拿出来。2.2 stash 的家族命令作用白话git stash藏起当前改动把东西扫进抽屉git stash list查看所有藏起来的东西打开抽屉看看里面有什么git stash pop拿回最近藏的改动从抽屉里拿出最近放进去的东西git stash apply拿回改动但不删除 stash 记录从抽屉里复制一份原件还在git stash drop删除某个 stash 记录把抽屉里的东西扔掉git stash clear删除所有 stash 记录清空整个抽屉2.3 stash 可以多次使用gitstash list输出类似stash{0}: WIP on main: a1b2c3 添加登录页面 stash{1}: WIP on feature: d4e5f6 修改样式 stash{2}: WIP on main: h7i8j9 临时实验白话翻译抽屉里有 3 样东西stash{0}是最近放进去的。3. gc垃圾回收和打包3.1 为什么需要 gc你的仓库用久了.git/objects/里会有很多小文件每次提交都会新增 blob、tree、commit 对象reset、rebase 后可能留下「悬空」的对象没有引用指向的这些对象散落在大量小文件里占空间、读写慢3.2 gc 做了什么git gc做两件事打包pack把大量小对象合并成一个大文件.pack同时生成索引.idx清理删除真正不需要的悬空对象超过 2 周、没有引用指向的白话打包 把散落的文件装进压缩包清理 把确认没人要的废纸扔掉3.3 gc 会丢数据吗不会。gc 只会删除同时满足以下条件的对象没有任何引用指向它reflog 里也没有记录已经超过宽限期默认 2 周如果你刚做了一个reset --hard然后立刻git gc——别担心reflog 里有记录gc 不会删。3.4 git repack 和 git prune命令作用白话git gc打包 清理大扫除git repack只做打包只把文件装箱git prune只做清理丢弃无用对象git gc --aggressive更彻底的打包耗时更长深度清洁4. 动手准备建一个可丢弃的练习目录mkdirlearn-git-19cdlearn-git-19gitinit-bmainecho第一版f.txtgitaddf.txtgitcommit-m第一次提交演示身份Ada Example adaexample.com5. 跟着做实验 1stash 基本流程# 开始写新功能但不提交echo新功能代码feature.txtgitaddfeature.txt# 突然要修 bug先藏起来gitstash# 白话翻译# Saved working directory and index state WIP on main: ... 第一次提交# 查看桌面——改动不见了gitstatus# 输出nothing to commit, working tree clean# 查看抽屉里有什么gitstash list# 输出stash{0}: WIP on main: ... 第一次提交# 修完 bug 后拿回之前的改动gitstash pop# 查看桌面——改动回来了gitstatus# feature.txt 又出现了实验 2带消息的 stashecho另一个功能feature2.txtgitaddfeature2.txt# 给 stash 加个备注方便以后辨认gitstash push-mfeature2 写到一半实验 3观察 gc 的效果# 先看看 .git/objects 有多少文件find.git/objects-typef|wc-l# 运行 gcgitgc# 再看文件数量大幅减少find.git/objects-typef|wc-l# 查看 pack 文件ls.git/objects/pack/# 输出类似pack-xxx.idx pack-xxx.pack6. 命令分组stash 相关命令作用注意git stash藏起改动默认不包括未跟踪的文件git stash -u藏起改动包括未跟踪文件新建的文件也会藏git stash push -m 备注带备注的 stash方便以后找git stash list列出所有 stash最近的在最上面git stash pop取出并删除最近 stash如果有冲突会保留git stash apply stash{n}取出但不删除可以多次 applygit stash drop stash{n}删除某个 stash删了就没了git stash clear清空所有 stash谨慎使用git stash branch 新分支名从 stash 创建新分支适合 stash 冲突时gc 相关命令作用注意git gc打包 清理日常足够git gc --aggressive深度打包大仓库才需要耗时长git prune只清悬空对象gc 的子步骤git repack只打包gc 的子步骤git count-objects查看对象统计看 repo 有多大7. 对照表stash pop vs apply维度stash popstash apply取出改动是是删除 stash 记录是否冲突时stash 记录保留需要手动处理stash 记录保留需要手动处理用哪个取出后不需要再用的取出后还想保留原 stash 的stash vs commit维度git stash临时 commit需要写说明吗不需要可以加 -m需要在 log 里能看到吗不能除非用stash list能适合场景临时存放很快会取出来稍微正式一点的保存点可以跨分支吗可以可以8. 安全习惯规矩为什么stash 前先看git status确认你知道藏了什么不要长期依赖 stashstash 不是长期存储超过 1 周就该提交或删了git stash pop遇到冲突别慌手动解决冲突就行stash 记录还保留着gc 前确认 reflog 里有重要记录gc 不会删有引用的对象但了解原理更安心不要频繁手动git gcGit 会自动 gc手动执行只在仓库很大时需要9. 真实场景场景一写到一半要切分支修 bug# 写到一半echo新功能feature.txt# 突然要修 buggitstash push-mfeature 写了一半gitswitch hotfix-branch# 修 bug……gitadd.gitcommit-m修复紧急 buggitswitch main# 拿回之前的改动gitstash pop场景二stash 跨分支迁移改动你在 wrong-branch 上写了一些代码发现应该写在 right-branch 上gitstashgitswitch right-branchgitstash pop场景三仓库越来越大的处理# 查看仓库大小du-sh.git# 查看对象数量gitcount-objects-v# 如果对象很多运行 gcgitgc# 再次查看大小du-sh.git# 应该变小了10. 进阶补充首读可跳过10.1 stash 的底层实现stash 实际上是 1-3 个 commit 对象stash{0}的第一个 parent 是原分支的 HEAD commit如果暂存区有改动第二个 parent 记录暂存区状态如果用了-u第三个 parent 记录未跟踪文件10.2 部分暂存# 只 stash 某个文件gitstash push-m只藏 style.css-- style.css10.3 pack 文件的增量Git 的 pack 文件采用增量存储如果两个版本的文件只差几个字节pack 只存差异部分非常节省空间。11. 小实验实验 Astash 基本流程修改一个文件但不要提交git stash藏起来确认工作区干净git stash pop取回来确认改动恢复了通过标准改动能完整藏起和取回。实验 B多次 stash做第一组改动git stash push -m 改动1做第二组改动git stash push -m 改动2git stash list看到两条记录git stash apply stash{1}取回第一条git stash drop stash{1}删除第一条通过标准能管理多条 stash 记录。实验 C观察 gc建仓库做 20 次提交git count-objects -v记录对象数量git gc再次git count-objects -v对比变化通过标准理解 gc 把松散对象打包成了 pack 文件。12. 常见问题问stash 会在 push 时推到远程吗不会。stash 是纯本地的不会影响远程仓库。问stash 最多能存多少个没有硬性限制但建议不超过 5-10 个。太多会导致混乱。超过 1 周不用的 stash 应该提交或删除。问stash pop 遇到冲突怎么办和 merge 冲突一样手动解决冲突然后git add标记已解决。stash 记录会保留因为 pop 没有成功完成解决完如果你不需要这个 stash 了手动git stash drop。问gc 会删我还没提交的代码吗不会。gc 只删「没有任何引用指向、reflog 里也没有记录、超过宽限期」的对象。你工作区里的改动不受 gc 影响。问什么时候需要手动 gc通常不需要——Git 会在合适的时机自动执行。只有仓库特别大或者你刚做了大量清理工作时才需要手动执行。问git stash -u和git stash有什么区别git stash只藏已跟踪文件的改动。git stash -u还会藏新建的未跟踪文件。如果你新建了一个文件还没git add普通 stash 不会藏它。13. 总结13.1 一页速记项目要点stash把没写完的代码暂时藏起来等会儿取回来stash pop取出并删除stash apply取出但保留stash list查看所有藏起来的东西gc打包散落对象 清理无用对象不会丢数据pack把很多小文件压缩成一个大文件13.2 本系列中的位置17 拣选与还原 → 18 重置三兄弟 → 19 贮藏与清理你在这里 → 20 远程进阶 ↑ 「暂时放一放」和「打扫卫生」13.3 思维升华stash 是 Git 给你的「等我一下」按钮。写到一半被打断不要慌也不要急着提交半成品——stash 一下等会儿回来继续。13.4 延伸阅读Pro Git — 贮藏与清理git-stash 文档git-gc 文档git-count-objects 文档本仓库图示署名assets/diagrams/ATTRIBUTION.md13.5 检查清单能用 stash 藏起改动并取回知道 stash list / pop / apply / drop 的区别理解 stash 底层是特殊的 commit知道 gc 做了什么打包 清理知道 gc 不会删有用的数据完成了实验 A、B、C

相关新闻

Docker Compose从入门到精通:多容器应用编排实战指南

Docker Compose从入门到精通:多容器应用编排实战指南

1. 项目概述:为什么需要Docker Compose? 如果你已经接触过Docker,大概率经历过这样的场景:为了跑起一个稍微复杂点的应用,比如一个带数据库、缓存和Web服务的项目,你需要在终端里敲下一连串的 docker run …

2026/10/10 18:02:59 阅读更多 →
开源M3U8下载器:多线程加速800%,支持API与批量处理

开源M3U8下载器:多线程加速800%,支持API与批量处理

这次我们来看一个能极大提升 M3U8 视频下载效率的开源工具。对于经常需要处理在线视频素材的开发者、内容创作者或技术爱好者来说,M3U8 格式的流媒体文件下载一直是个痛点:速度慢、容易中断、不支持批量操作。这个项目直接瞄准了这些痛点,通过…

2026/9/27 11:31:58 阅读更多 →
CUDA 10.1与cuDNN安装配置全攻略:从原理到实践,避坑指南与深度学习环境搭建

CUDA 10.1与cuDNN安装配置全攻略:从原理到实践,避坑指南与深度学习环境搭建

1. 项目概述:为什么CUDA与cuDNN的安装如此关键? 如果你正在踏入深度学习、高性能计算或者计算机视觉的领域,那么“CUDA”和“cuDNN”这两个词对你来说,绝对不陌生。它们就像是开启NVIDIA GPU全部潜力的两把钥匙。CUDA是NVIDIA推出…

2026/10/6 7:09:55 阅读更多 →

最新新闻

Agent框架工程化:全插件化设计与可回放会话日志实践

Agent框架工程化:全插件化设计与可回放会话日志实践

做Agent框架开发的人,一定都体会过这种痛苦:模型A下跑得好好的流程,换到模型B就崩了;某一轮对话触发的工具调用,复现时怎么都对不上;线上用户反馈了一个诡异问题,你翻遍了日志也不知道是哪一步出…

2026/10/12 2:30:25 阅读更多 →
专业数据库数据共享策略:库级、表级与接口级共享落地指南

专业数据库数据共享策略:库级、表级与接口级共享落地指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 2:30:25 阅读更多 →
数据库课程设计实战:在线学习系统MySQL表结构与SQL优化

数据库课程设计实战:在线学习系统MySQL表结构与SQL优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 2:30:25 阅读更多 →
看视频就懂《人工智能怎么学》|人工智能是什么

看视频就懂《人工智能怎么学》|人工智能是什么

为了帮助读者更好的理解图书《人工智能怎么学》的精彩内容,通过观看视频就能快速搞懂人工智能应该怎么学,公众号制作了系列视频并进行发布。欢迎读者朋友观看和转发。 本期内容主要对本公众号发布的文章《什么是人工智能?》进行视频讲解&…

2026/10/12 2:30:25 阅读更多 →
树与二叉树:数据结构的核心精髓

树与二叉树:数据结构的核心精髓

一、树型结构 1.基本定义 树形结构是一种非线性的数据结构,用于模拟具有层次关系的数据。它由节点(Node)和边(Edge)组成,其中每个节点可以有零个或多个子节点,但至多只有一个父节点&#xff0…

2026/10/12 2:30:25 阅读更多 →
Python 装饰器:我以为的语法糖,其实是定义时立刻执行的函数调用

Python 装饰器:我以为的语法糖,其实是定义时立刻执行的函数调用

这个坑我是被项目逼着学会的。 有一次产品要求给所有接口加耗时统计,我打开函数,开头写一行 start_time time.time(),return 前再写一行 print。改到第三个函数时我开始怀疑人生——同样的代码复制粘贴几十遍,以后改格式还得逐个…

2026/10/12 2:29:25 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →