Answers:
Git不会自行丢弃信息 *。每个文件的所有先前版本始终可用于还原,差异,检查等。
您可能想调和的是访问单个文件的旧版本的想法,而不是Git的历史记录模型专注于整个树的事实。整树的版本控制确实需要做更多的工作才能看到(例如)十个更改前与十个完整树更改前foo.c
存在的版本foo.c
:
# 10 foo.c-changes ago
git show $(git rev-list -n 10 --reverse HEAD -- foo.c | head -1):foo.c
# 10 whole-tree-changes ago
git show HEAD~10:foo.c
面向树的好处,主要是将提交作为对整个树的各个部分进行的相互依赖更改的单位进行查看的能力,通常大大超过了额外的键入(可以通过别名,脚本等减轻)和CPU时间花在挖掘过去的提交上。
当一个新对象(例如,一个以前看不见的文件)进入系统时,它将以普通(zlib)压缩方式存储为“松散对象”。当积累了足够多的松散对象(基于gc.auto
配置选项;或者当用户运行git gc或较低级别的打包命令之一)时,Git会将许多松散对象收集到一个“打包文件”中。
打包文件中的对象可以存储为纯压缩数据(与松散对象相同,只是与其他对象捆绑在一起),也可以存储为针对其他对象的压缩增量。可以将Delta链接到可配置的深度(pack.depth
),并可以针对任何合适的对象制作pack.window
Delta (控制Git搜索最佳delta底数的范围;如果这样做会产生良好的增量压缩)。深度和窗口大小配置赋予增量压缩引擎的纬度通常会导致比CVS样式的简单单版本对下一个/上一个版本的“差异”压缩更好的增量压缩。
正是这种主动的增量压缩(与常规zlib压缩相结合)通常可以使Git存储库(具有完整的历史记录和未压缩的工作树)比单个SVN检出(具有未压缩的工作树和原始副本)占用更少的空间。
请参阅《Git如何存储对象》和《 Git社区手册》的Packfile部分。也是git pack-objects手册页。
*您可以通过“重写历史记录”和git reset之类的命令告诉Git丢弃提交,但是即使在这种情况下,Git也会“挂在”新丢弃的提交上一段时间,以防万一您决定需要它们。参见git reflog和git prune。
可以在同一页面上阅读:
...
因此,Git不会在源代码树下的任何级别显式记录文件修订版本关系。
...
检查单个文件的更改历史记录比整个项目要贵一些。为了获得影响给定文件的更改历史,Git必须遍历全局历史,然后确定每个更改是否修改了该文件。但是,这种检查历史记录的方法的确可以让Git以相同的效率生成单个历史记录,以显示对任意文件集的更改。例如,源树的子目录加上相关的全局头文件是很常见的情况。
...
因此,您可以返回文件的先前版本并比较两个文件。
git实际上确实保存了文件增量,但是将它们另存为整个文件树的增量。
要查看版本之间的差异,请执行以下一项操作:
git add
运行的文件之间的差异。git add
运行但尚未提交的所有文件之间的差异