cat-file: provide %(deltabase) batch format
It can be useful for debugging or analysis to see which objects are stored as delta bases on top of others. This information is available by running `git verify-pack`, but that is extremely expensive (and is harder than necessary to parse). Instead, let's make it available as a cat-file query format, which makes it fast and simple to get the bases for a subset of the objects. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Dec 21, 2013 at 09:25 UTC
65ea9c3c3d0e74b1f8c0c1d9fea6988550133dba
3 files changed
+49
-3
Documentation/git-cat-file.txt
+9
-3
@@ -109,6 +109,11 @@ newline. The available atoms are:
109
The size, in bytes, that the object takes up on disk. See the
110
note about on-disk sizes in the `CAVEATS` section below.
111
112
+`deltabase`::
113
+ If the object is stored as a delta on-disk, this expands to the
114
+ 40-hex sha1 of the delta base object. Otherwise, expands to the
115
+ null sha1 (40 zeroes). See `CAVEATS` below.
116
+
117
`rest`::
118
If this atom is used in the output string, input lines are split
119
at the first whitespace boundary. All characters before that
@@ -152,10 +157,11 @@ should be taken in drawing conclusions about which refs or objects are
157
responsible for disk usage. The size of a packed non-delta object may be
158
much larger than the size of objects which delta against it, but the
159
choice of which object is the base and which is the delta is arbitrary
155
-and is subject to change during a repack. Note also that multiple copies
156
-of an object may be present in the object database; in this case, it is
157
-undefined which copy's size will be reported.
160
+and is subject to change during a repack.
161
162
+Note also that multiple copies of an object may be present in the object
163
+database; in this case, it is undefined which copy's size or delta base
164
+will be reported.
165
166
GIT
167
---
builtin/cat-file.c
+6
@@ -118,6 +118,7 @@ struct expand_data {
118
unsigned long size;
119
unsigned long disk_size;
120
const char *rest;
121
+ unsigned char delta_base_sha1[20];
122
123
/*
124
* If mark_query is true, we do not expand anything, but rather
@@ -174,6 +175,11 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
175
data->split_on_whitespace = 1;
176
else if (data->rest)
177
strbuf_addstr(sb, data->rest);
178
+ } else if (is_atom("deltabase", atom, len)) {
179
+ if (data->mark_query)
180
+ data->info.delta_base_sha1 = data->delta_base_sha1;
181
+ else
182
+ strbuf_addstr(sb, sha1_to_hex(data->delta_base_sha1));
183
} else
184
die("unknown format element: %.*s", len, atom);
185
}
t/t1006-cat-file.sh
+34
@@ -240,4 +240,38 @@ test_expect_success "--batch-check with multiple sha1s gives correct format" '
240
"$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)"
241
'
242
243
+test_expect_success 'setup blobs which are likely to delta' '
244
+ test-genrandom foo 10240 >foo &&
245
+ { cat foo; echo plus; } >foo-plus &&
246
+ git add foo foo-plus &&
247
+ git commit -m foo &&
248
+ cat >blobs <<-\EOF
249
+ HEAD:foo
250
+ HEAD:foo-plus
251
+ EOF
252
+'
253
+
254
+test_expect_success 'confirm that neither loose blob is a delta' '
255
+ cat >expect <<-EOF
256
+ $_z40
257
+ $_z40
258
+ EOF
259
+ git cat-file --batch-check="%(deltabase)" <blobs >actual &&
260
+ test_cmp expect actual
261
+'
262
+
263
+# To avoid relying too much on the current delta heuristics,
264
+# we will check only that one of the two objects is a delta
265
+# against the other, but not the order. We can do so by just
266
+# asking for the base of both, and checking whether either
267
+# sha1 appears in the output.
268
+test_expect_success '%(deltabase) reports packed delta bases' '
269
+ git repack -ad &&
270
+ git cat-file --batch-check="%(deltabase)" <blobs >actual &&
271
+ {
272
+ grep "$(git rev-parse HEAD:foo)" actual ||
273
+ grep "$(git rev-parse HEAD:foo-plus)" actual
274
+ }
275
+'
276
+
277
test_done