14.3 重置操作引入的对象

上一节用git prune命令清除暂存区操作时引入的临时对象,但是如果是用重置命令抛弃的提交和文件就不会轻易地被清除。下面用同样的大文件提交到版本库中试验一下。


$cd/path/to/my/workspace/i-am-admin

$cp/tmp/bigfile bigfile

$cp/tmp/bigfile bigfile.dup


将这两个大文件提交到版本库中。

添加到暂存区。


$git add bigfile bigfile.dup


提交到版本库。


$git commit-m "add bigfiles."

[master 51519c7]add bigfiles.

2 files changed,0 insertions(+),0 deletions(-)

create mode 100644 bigfile

create mode 100644 bigfile.dup


查看版本库的空间占用。


$du-sh.git/

11M.git/


做一个重置操作,抛弃刚刚针对两个大文件做的提交。


$git reset—hard HEAD^


重置之后,看看版本库的变化。

版本库的空间占用没有变化,还是那么“庞大”。


$du-sh.git/

11M.git/


查看对象库,看到三个松散对象。


$find.git/objects/-type f

.git/objects/info/packs

.git/objects/2e/bcd92d0dda2bad50c775dc662c6cb700477aff

.git/objects/d9/38dee8fde4e5053b12406c66a19183a24238e1

.git/objects/51/519c7d8d60e0f958e135e8b989a78e84122591

.git/objects/pack/pack-969329578b95057b7ea1208379a22c250c3b992a.idx

.git/objects/pack/pack-969329578b95057b7ea1208379a22c250c3b992a.pack


这三个松散对象分别对应于撤销的提交、目录树,以及大文件对应的blob对象。


$git cat-file-t 51519c7

commit

$git cat-file-t d938dee

tree

$git cat-file-t 2ebcd92

blob


向上一节一样,执行git prune命令,期待版本库空间占用会变小。可是:

版本库空间占用没有变化!


$git prune

$du-sh.git/

11M.git/


执行git fsck也看不到未被关联到的对象。


$git fsck


除非像下面这样执行。


$git fsck—no-reflogs

dangling commit 51519c7d8d60e0f958e135e8b989a78e84122591


还记得前面章节中介绍的reflog吗?reflog是防止误操作的最后一道闸门。


$git reflog

6652a0d HEAD@{0}:HEAD^:updating HEAD

51519c7 HEAD@{1}:commit:add bigfiles.


可以看到撤销的操作仍然记录在reflog中,正因为如此,Git认为撤销的提交和大文件都可以被追踪到,还在使用着,所以无法用git prune命令删除。

如果确认真的要丢弃不想要的对象,需要对版本库的reflog做过期操作,相当于将.git/logs/下的文件清空。

使用下面的reflog过期命令做不到让刚刚撤销的提交过期,因为reflog的过期操作默认只会让90天前的数据过期。


$git reflog expire—all

$git reflog

6652a0d HEAD@{0}:HEAD^:updating HEAD

51519c7 HEAD@{1}:commit:add bigfiles.


需要为git reflog命令提供—expire=<date>参数,强制让<date>之前的记录全部过期。


$git reflog expire—expire=now—all

$git reflog


使用now作为时间参数,让reflog的全部记录都过期。没有了reflog,即从reflog中看不到回滚的添加大文件的提交后,该提交对应的commit对象、tree对象和blob对象就会成为未被关联的dangling对象,可以用git prune命令清理。下面可以看到清理后,版本库变小了。


$git prune

$du-sh.git/

244K.git/