liqi9155159 2023-05-25 17:21 采纳率: 25%
浏览 35
已结题

多次Git add 的垃圾对象为什么要保留在暂存区?

比如一个文件readme.txt 。修改一次 git add ,第二次修改,然后 git add ,第三次修改 然后再git add。这时候你会发现以上三次add形成的blod文件都留在硬盘上。不明白Git如此设定的目的是什么?留下前两个版本的blod文件在暂存区有什么作用呢?

暂存区保留第三版blod文件,那么当你在工作区又修改了readme.txt以后,git stauts git diff 都会用到第三版的 blod文件。但是前两版的blod有什么用呢?站在用户需求的角度想不到这两个老版本有什么用?而且commit时会提交两个老版本blod文件么?

如果它们有用,那么git为什么要专门提供 git prune命令去删除前两个版本呢?

如果说它们没用吧,那么git add 时为什么不采用覆盖机制,直接用新版blod替换掉上一版的blod文件呢?

如果是为了回滚,那么在什么场景下回滚代码不用Git库中的,一定要用暂存区的历史版本呢?

  • 写回答

3条回答 默认 最新

  • 断水流大撕兄 HarmonyOS创作领域新星创作者 2023-05-25 17:33
    关注

    这是一个很好的疑问。Git在add后保留多个版本的blob对象的设计固然让人费解。但它有以下几个目的:

    1. 支持 Git stash。Git stash会将工作区的修改暂存起来,等以后恢复使用。这需要保留add后的多个blob对象版本。
    2. 支持交互式rebase。在rebase过程中,Git会暂停,让你解决冲突,然后继续rebase。这也需要保留多个blob对象版本。
    3. 方便DEBUG。有时候想看看某次修改的diff结果,能够查看任意两个版本之间的diff很useful。如果只保留一个blob对象版本,就没法做这件事了。
    4. 方便回滚。虽然正常情况下,回滚代码使用版本库的历史提交记录即可。但在某些复杂的回滚场景下,有老版本的blob对象也能提供帮助。当然,这不是主要目的,更推荐使用git reflog和git reset来回滚。
    5. 降低内存占用。如果每次add都覆盖前一个blob对象,那么工作区的全部修改历史只会保存在一个blob对象内。这个blob对象可能会变得越来越大,占用更多内存。保留多个小的blob对象可以有效避免这个问题。

    所以,可以看出,Git保留多个blob对象版本有一定的意义和作用。但是,为了避免blob对象过多占用空间,Git提供了git gc和git prune来清理不需要的blob对象,这也是很贴心的设计。
    一般来说,可以这么理解:

    1. 添加新文件或重命名文件,新旧版本的blob对象都保留,以支持各种Git操作(stash、rebase、diff等)
    2. 修改文件,只保留最近两个版本的blob对象,足以支持一般的Git操作需求。更老的版本对象会在git gc时清理。
    3. 如果 blob对象过多,会影响仓库体积或内存占用,可以手动执行git prune移除不需要的版本。总之,Git保留多个blob版本有一定好处,但也需适当清理,这两点Git的设计都考虑得很到位。理解Git的设计思想,会让我们更清楚如何高效运用Git。
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月2日
  • 创建了问题 5月25日

悬赏问题

  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥15 帮我写一个c++工程