1.9. Git 垃圾回收

未匹配的标注

回收垃圾

随着仓库的增长 git 它可能会自动地将你的对象文件转换成一种更紧密的方式。这种形式被称作 "pack" 文件。

手动回收

你也可以手动运行一个命令去进行这个垃圾回收操作。但是注意这个命令是不可逆的。一旦运行了这个命令之后, Git 就会将这些文件压缩成一个更快更小的打包文件,并且删除掉所有 dangling commits —— 比如从一个已经删除的分支或者没有 merge 的分支。

我们以前学过,是可以通过 git reflog 这个命令来查找我们要恢复的删除的 commit 但是一旦你执行了这个命令之后,这些 dangling commits 就不再能够恢复了。

如何手动回收

好,我们现在来看一下,在那个 demo 这个仓库的根目录下运行 git gc

➜  plumbing-demo git:(main) git gc
Enumerating objects: 104, done.
Counting objects: 100% (104/104), done.
Delta compression using up to 4 threads
Compressing objects: 100% (101/101), done.
Writing objects: 100% (104/104), done.
Total 104 (delta 49), reused 0 (delta 0), pack-reused 0

回收效果分析

好,现在就出现了压缩写入之类的操作提示。我们现在再看我们刚才所说的那个 .git/objects 这个目录。你可以看到就跟上一节有很大的差别了,对不对?

➜  plumbing-demo git:(main) ls .git/objects
06   14   23   2d   31   38   47   59   60   71   78   84   8d   95   9b   9f   ac   b3   ca   cf   d4   e3   ed   f2   fb   pack
0a   16   28   2e   34   3e   56   5a   69   73   7f   86   91   96   9c   a2   b0   b6   cd   d2   d8   e6   ee   f3   ff
0b   21   29   30   37   45   57   5f   6c   75   80   88   92   9a   9e   a4   b1   b8   ce   d3   dc   e7   f1   f9   info

这就说明了我们压缩起效果了。

比如我们要找我们上一节提到的 04 那个文件夹。就会发现怎么也找不到了,对不对?就证明这个对象已经被删除掉了或者被压缩掉了,他到底去了哪里呢?我们可以研究一下。

在 object 这个文件夹里面有一个 pack 的文件夹,我们进入这个 pack 的文件夹。

➜  pack git:(main) ls
pack-29cf6365eb4d782ca6954ef7909111f794405ed0.idx  pack-29cf6365eb4d782ca6954ef7909111f794405ed0.pack

看到了有两个文件,一个是 idx 后缀,一个是 pack 后缀。我们用 cat 命令来看一看,可以看到是一个二进制的文件。我们再看另外一个文件,也是用 cat 命令可以看到也是一个二进制的文件。因为是二进制文件,这样是查看不了的,但我们可以暂时认为就是压缩到了这里。

而且进行了这个垃圾回收之后,可以看到不仅是我们的这个 .git/objects 文件进行了压缩,还将我们的分支引用也进行了压缩。比如说我们可以看到这个 .git 根目录下有一个 packed-refs 这个 file 产生。

用 cat 命令看一下它的内容。

➜  .git git:(main) cat packed-refs
# pack-refs with: peeled fully-peeled sorted
8f809e04a436df0fccab26ac40cdfc8b32d6ee3d refs/heads/main
f37d6c37d7a2f2d0443b839dac7c13e10ac84239 refs/tags/v1.0
^51871d3a84bb13eccd06022e4962ace4b4d02a62
e8d9ca0d12ce5b17be6e9037507835cd9fdf3abc refs/tags/v2.0
^6423242d1225237121d732f1643038ec94f0eaeb

看到我们的 main head 已经到了这里面。然后我们看一下我们原来的 .git/refs/head 这个目录,发现里面没有东西,

➜  .git git:(main) ls refs/heads/
# nothing

就说明 main head 已经被压缩到这里了。tag 也是如此。

建议

虽然我们的对象被压缩了,但是所有的对象 ID 仍然可用。git gc这个 命令 只是改变了存储机制,而不是仓库本身的内容。 时不时地运行一下 git gc 通常是一个好主意,可以让你的仓库保持优化。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~