generaldeltaを有効にしてmercurialのリポジトリサイズを減らす
Mercurialのリポジトリの履歴のフォーマットは通常のフォーマット以外にgeneraldeltaというものが有ります。
と偉そうに言ってみましたが、NetBSDリポジトリに関するMLのツイートをtwitterで見て初めて知りました。
NetBSD の git/mercurial Repository 作ろうとしている人がいるのか。
http://t.co/JgAYsvynUu
— 山本 茂 (@BsdHacker) April 10, 2014
通常のフォーマットと比べるとリポジトリサイズが小さくなるらしい*1ので、pypyのリポジトリで試してみました。
有効にする
.hgrcに次の設定をしてください。
[format] generaldelta = true
クローンしてみる
- generaldeltaを無効にした場合(通常)
% time (hg clone -U --config format.generaldelta=0 --pull pypy pypy-non-generaldelta)
requesting all changes
adding changesets
adding manifests
adding file changes
added 70529 changesets with 223487 changes to 44701 files (+124 heads)
( hg clone -U --config format.generaldelta=0 --pull pypy pypy-non-generaldelt) 152.55s user 19.13s system 61% cpu 4:38.12 total
% du -sh pypy-non-generaldelta
617M pypy-non-generaldelta
% hg debugrevlog -m -R pypy-non-generaldelta
format : 1
flags : (none)
revisions : 70061
merges : 4767 ( 6.80%)
normal : 65294 (93.20%)
revisions : 70061
full : 394 ( 0.56%)
deltas : 69667 (99.44%)
revision size : 288714045
full : 55492796 (19.22%)
deltas : 233221249 (80.78%)
avg chain length : 505
compression ratio : 88
uncompressed data size (min/max/avg) : 0 / 916642 / 364444
full revision size (min/max/avg) : 0 / 222686 / 140844
delta size (min/max/avg) : 0 / 217544 / 3347
deltas against prev : 69667 (100.00%)
where prev = p1 : 58075 (83.36%)
where prev = p2 : 1057 ( 1.52%)
other : 10535 (15.12%)
- generaldeltaを有効にした場合
% time (hg clone -U --config format.generaldelta=1 --pull pypy pypy-generaldelta)
requesting all changes
adding changesets
adding manifests
adding file changes
added 70529 changesets with 223487 changes to 44701 files (+124 heads)
( hg clone -U --config format.generaldelta=1 --pull pypy pypy-generaldelta; ) 297.99s user 30.27s system 69% cpu 7:53.03 total
% du -sh pypy-generaldelta
398M pypy-generaldelta
% hg debugrevlog -m -R pypy-generaldelta
format : 1
flags : generaldelta
revisions : 70061
merges : 4767 ( 6.80%)
normal : 65294 (93.20%)
revisions : 70061
full : 124 ( 0.18%)
deltas : 69937 (99.82%)
revision size : 65592031
full : 10731965 (16.36%)
deltas : 54860066 (83.64%)
avg chain length : 491
compression ratio : 389
uncompressed data size (min/max/avg) : 0 / 916642 / 364444
full revision size (min/max/avg) : 0 / 214457 / 86548
delta size (min/max/avg) : 0 / 217544 / 784
deltas against prev : 58927 (84.26%)
where prev = p1 : 58076 (98.56%)
where prev = p2 : 90 ( 0.15%)
other : 761 ( 1.29%)
deltas against p1 : 10881 (15.56%)
deltas against p2 : 129 ( 0.18%)
deltas against other : 0 ( 0.00%)
ちなみに、リポジトリがgeneraldeltaで保存されているかどうかは.hg/requiresでわかります。
% diff -u pypy-non-generaldelta/.hg/requires pypy-generaldelta/.hg/requires --- pypy-non-generaldelta/.hg/requires 2014-04-10 11:06:25.000000000 +0900 +++ pypy-generaldelta/.hg/requires 2014-04-10 10:56:47.000000000 +0900 @@ -1,4 +1,5 @@ dotencode fncache +generaldelta revlogv1 store
結果
| generaldelta | enable | disable |
|---|---|---|
| リポジトリサイズ | 398M | 617M |
| 通常リポジトリからのcloneにかかる時間 | 7:53.03 | 4:38.12 |
今回の例ではリポジトリサイズは40%削減、通常リポジトリからのcloneにかかる時間は70%増加しました。
これくらいなら、サイズが大きくて困っている場合に奥の手として利用できそうです。