2012/08/13

git命令之git fsck, git prune 和 git repack

这次说几个平时出场率不高的git命令。git fsck,git prune已经git repack。

首先说说fsck这个命令。该命令用来检查object database的完整性。例如是否所有commit均存在在object database中,是否有某个tree对象所引用到的blob对象丢失了,是否存在不被任何branch,tag所引用的"悬空"的commit。
几个常见参数有:
--root 报告当前repo的根节点,也即当前repo的第一个commit。
--tags 报告检查过的tags。
--no-reflog 将那些仅被reflog引用的commit视为unreachable。
--lost-found 根据对象的类型,将"悬空"对象写入到.git/lost-found/commit/ 或 .git/lost-found/other/目录中。
git fsck
dangling blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4
#有一个blob对象,没有被任何commit引用到。但是依旧占用磁盘空间,需要清理。

git fsck --root --tags
tagged commit b40c14f880c04fefcdce1328a2d6a537ed64b182 (test_tag1) in 00311b3f18af6306df2e5843d13a901681b677ef #一个tag
tagged commit f62a94635be5b72c9778a04aea116f6b4349eb61 (test_tag2) in 4de836025102abda82c0fd544a8725c82c46752f #另一个tag
root 63a763ead83edabcadac4f62a08b0d39b0d719b4 #当前repo的历史中第一次commit。
dangling blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4

上个示例中看到了有一个dangling blog,这种对象不被任何commit中的tree引用,但是却存在于object database中浪费磁盘空间,需要被清除。要实现类似object的清除,就需要用到第2个命令,git prune。
此命令没有太多的参数,直接git prune就可以了。如果在实际删除之前想要查看一下哪些object会被影响,可以使用git prune --dry-run来查看,该参数仅会输出将要被删除的object,并不会实际删除。
关于此命令,有一点需要注意:git prune只会删除unpacked object,如果一个对象已经被pack,那么git prune不会删除。

如果想要删除那些被pack的dangling文件要怎么样呢?第三个命令git repack就要出场了。
git repack -a -d
git repack -A -d
两者的区别在于:
-a 会直接删掉pack文件中的dangling对象。
-A 并不会立即删除,而是将pack文件中的dangling object重新以松散对象的形式存储在database中。也就是把dangling object从pack文件中"吐出来"。

关于3个命令的综合示例如下:

示例一
=> git log --oneline -3
b841691 Merge branch 'test' of github.scm.corp.ebay.com:gewang/TryOurInternalGithub
ec55218 1 on test
c1b13cb dd
=> touch test
=> echo test >> test
=> git add test
=> git commit -m "test git fsck"
[master d2d0bfa] test git fsck
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 test
=> git reset --hard HEAD^ #rollback到之前一个commit,制造一个dangling commit。
HEAD is now at b841691 Merge branch 'test' of github.scm.corp.ebay.com:gewang/TryOurInternalGithub
=> git fsck #因为刚刚的commit现在还可以通过reflog引用到,所以fsck并不认为它是unreachable。
=> git fsck --no-reflog #忽略reflog就可以看到
dangling commit d2d0bfa2ee4dfe767862cb441595db9748d8beab
=> git reflog expire --expire=now --all #删除reflog
=> git fsck #成功制造了一个dangling commit。
dangling commit d2d0bfa2ee4dfe767862cb441595db9748d8beab
=> git prune #删掉它!
=> git fsck

示例二
=> git log --oneline -3
b841691 Merge branch 'test' of github.scm.corp.ebay.com:gewang/TryOurInternalGithub
ec55218 1 on test
c1b13cb dd
=> touch test
=> echo test >> test
=> git add test
=> git commit -m "test fsck, prune and repack"
[master 09f3015] test fsck, prune and repack
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 test
=> git repack  #首先将新创建的commit打包。
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0)
=> git reset --hard HEAD^
HEAD is now at b841691 Merge branch 'test' of github.scm.corp.ebay.com:gewang/TryOurInternalGithub
=> git fsck
=> git fsck --no-reflog
dangling commit 09f3015743b00805e100259b9b4b0c230236a891
=> git reflog expire --expire=now --all
=> git fsck #制造了一个dangling commit。
dangling commit 09f3015743b00805e100259b9b4b0c230236a891
=> git prune
=> git fsck #prune无法删除已经pack的object。
dangling commit 09f3015743b00805e100259b9b4b0c230236a891
=> git repack -a -d #reapck -a -d 直接删除。
Counting objects: 173, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (94/94), done.
Writing objects: 100% (173/173), done.
Total 173 (delta 59), reused 173 (delta 59)
=> git fsck

示例三
=> git log --oneline -3
b841691 Merge branch 'test' of github.scm.corp.ebay.com:gewang/TryOurInternalGithub
ec55218 1 on test
c1b13cb dd
=> touch test
=> echo test >> test
=> git add test
=> git commit -m "test fsck, prune and repack -A"
[master 8df4fa5] test fsck, prune and repack -A
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 test
=> git repack
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0)
=> find .git/objects/ # 当前database中的文件。
.git/objects/
.git/objects//8d
.git/objects//8d/f4fa5b683a6c2614d0bb5f6a9bbd0df6e76ebb
.git/objects//9d
.git/objects//9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4
.git/objects//e6
.git/objects//e6/a38484a68f1d818090516266a1fe5115bedb2d
.git/objects//info
.git/objects//info/packs
.git/objects//pack
.git/objects//pack/pack-f82243c549f6e21d59eb4b3cd90c1f7ea4bc2b2f.idx
.git/objects//pack/pack-f82243c549f6e21d59eb4b3cd90c1f7ea4bc2b2f.pack
.git/objects//pack/pack-ff6a31c9b76b7a762bf76eb2500048a55e0e076d.idx
.git/objects//pack/pack-ff6a31c9b76b7a762bf76eb2500048a55e0e076d.pack
=> git gc # 清理一下。
Counting objects: 176, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (96/96), done.
Writing objects: 100% (176/176), done.
Total 176 (delta 60), reused 175 (delta 59)
=> find .git/objects/ #现在干净多了。
.git/objects/
.git/objects//info
.git/objects//info/packs
.git/objects//pack
.git/objects//pack/pack-25320b3227fb4b00d05585542643651019b1a041.idx
.git/objects//pack/pack-25320b3227fb4b00d05585542643651019b1a041.pack
=> git reset --hard HEAD^
HEAD is now at b841691 Merge branch 'test' of github.scm.corp.ebay.com:gewang/TryOurInternalGithub
=> git fsck
=> git fsck --no-reflog
dangling commit 8df4fa5b683a6c2614d0bb5f6a9bbd0df6e76ebb
=> git reflog expire --expire=now --all
=> git fsck #制造dangling commit。
dangling commit 8df4fa5b683a6c2614d0bb5f6a9bbd0df6e76ebb
=> git prune
=> git fsck
dangling commit 8df4fa5b683a6c2614d0bb5f6a9bbd0df6e76ebb
=> git repack -A -d #这次使用-A
Counting objects: 173, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (94/94), done.
Writing objects: 100% (173/173), done.
Total 173 (delta 59), reused 172 (delta 59)
=> git fsck #这货还在
dangling commit 8df4fa5b683a6c2614d0bb5f6a9bbd0df6e76ebb
=> find .git/objects/ #对应的松散对象也出现啦。
.git/objects/
.git/objects//8d
.git/objects//8d/f4fa5b683a6c2614d0bb5f6a9bbd0df6e76ebb
.git/objects//9d
.git/objects//9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4
.git/objects//e6
.git/objects//e6/a38484a68f1d818090516266a1fe5115bedb2d
.git/objects//info
.git/objects//info/packs
.git/objects//pack
.git/objects//pack/pack-ff6a31c9b76b7a762bf76eb2500048a55e0e076d.idx
.git/objects//pack/pack-ff6a31c9b76b7a762bf76eb2500048a55e0e076d.pack

没有评论:

发表评论