t5320: tests for delta islands

Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Aug 16, 2018 at 08:13 UTC 9eb0986fa0b417911ed126e0d6d12028b9c2044f
1 file changed +143
t/t5320-delta-islands.sh new
+143
@@ -0,0 +1,143 @@
1 +#!/bin/sh
2 +
3 +test_description='exercise delta islands'
4 +. ./test-lib.sh
5 +
6 +# returns true iff $1 is a delta based on $2
7 +is_delta_base () {
8 + delta_base=$(echo "$1" | git cat-file --batch-check='%(deltabase)') &&
9 + echo >&2 "$1 has base $delta_base" &&
10 + test "$delta_base" = "$2"
11 +}
12 +
13 +# generate a commit on branch $1 with a single file, "file", whose
14 +# content is mostly based on the seed $2, but with a unique bit
15 +# of content $3 appended. This should allow us to see whether
16 +# blobs of different refs delta against each other.
17 +commit() {
18 + blob=$({ test-tool genrandom "$2" 10240 && echo "$3"; } |
19 + git hash-object -w --stdin) &&
20 + tree=$(printf '100644 blob %s\tfile\n' "$blob" | git mktree) &&
21 + commit=$(echo "$2-$3" | git commit-tree "$tree" ${4:+-p "$4"}) &&
22 + git update-ref "refs/heads/$1" "$commit" &&
23 + eval "$1"'=$(git rev-parse $1:file)' &&
24 + eval "echo >&2 $1=\$$1"
25 +}
26 +
27 +test_expect_success 'setup commits' '
28 + commit one seed 1 &&
29 + commit two seed 12
30 +'
31 +
32 +# Note: This is heavily dependent on the "prefer larger objects as base"
33 +# heuristic.
34 +test_expect_success 'vanilla repack deltas one against two' '
35 + git repack -adf &&
36 + is_delta_base $one $two
37 +'
38 +
39 +test_expect_success 'island repack with no island definition is vanilla' '
40 + git repack -adfi &&
41 + is_delta_base $one $two
42 +'
43 +
44 +test_expect_success 'island repack with no matches is vanilla' '
45 + git -c "pack.island=refs/foo" repack -adfi &&
46 + is_delta_base $one $two
47 +'
48 +
49 +test_expect_success 'separate islands disallows delta' '
50 + git -c "pack.island=refs/heads/(.*)" repack -adfi &&
51 + ! is_delta_base $one $two &&
52 + ! is_delta_base $two $one
53 +'
54 +
55 +test_expect_success 'same island allows delta' '
56 + git -c "pack.island=refs/heads" repack -adfi &&
57 + is_delta_base $one $two
58 +'
59 +
60 +test_expect_success 'coalesce same-named islands' '
61 + git \
62 + -c "pack.island=refs/(.*)/one" \
63 + -c "pack.island=refs/(.*)/two" \
64 + repack -adfi &&
65 + is_delta_base $one $two
66 +'
67 +
68 +test_expect_success 'island restrictions drop reused deltas' '
69 + git repack -adfi &&
70 + is_delta_base $one $two &&
71 + git -c "pack.island=refs/heads/(.*)" repack -adi &&
72 + ! is_delta_base $one $two &&
73 + ! is_delta_base $two $one
74 +'
75 +
76 +test_expect_success 'island regexes are left-anchored' '
77 + git -c "pack.island=heads/(.*)" repack -adfi &&
78 + is_delta_base $one $two
79 +'
80 +
81 +test_expect_success 'island regexes follow last-one-wins scheme' '
82 + git \
83 + -c "pack.island=refs/heads/(.*)" \
84 + -c "pack.island=refs/heads/" \
85 + repack -adfi &&
86 + is_delta_base $one $two
87 +'
88 +
89 +test_expect_success 'setup shared history' '
90 + commit root shared root &&
91 + commit one shared 1 root &&
92 + commit two shared 12-long root
93 +'
94 +
95 +# We know that $two will be preferred as a base from $one,
96 +# because we can transform it with a pure deletion.
97 +#
98 +# We also expect $root as a delta against $two by the "longest is base" rule.
99 +test_expect_success 'vanilla delta goes between branches' '
100 + git repack -adf &&
101 + is_delta_base $one $two &&
102 + is_delta_base $root $two
103 +'
104 +
105 +# Here we should allow $one to base itself on $root; even though
106 +# they are in different islands, the objects in $root are in a superset
107 +# of islands compared to those in $one.
108 +#
109 +# Similarly, $two can delta against $root by our rules. And unlike $one,
110 +# in which we are just allowing it, the island rules actually put $root
111 +# as a possible base for $two, which it would not otherwise be (due to the size
112 +# sorting).
113 +test_expect_success 'deltas allowed against superset islands' '
114 + git -c "pack.island=refs/heads/(.*)" repack -adfi &&
115 + is_delta_base $one $root &&
116 + is_delta_base $two $root
117 +'
118 +
119 +# We are going to test the packfile order here, so we again have to make some
120 +# assumptions. We assume that "$root", as part of our core "one", must come
121 +# before "$two". This should be guaranteed by the island code. However, for
122 +# this test to fail without islands, we are also assuming that it would not
123 +# otherwise do so. This is true by the current write order, which will put
124 +# commits (and their contents) before their parents.
125 +test_expect_success 'island core places core objects first' '
126 + cat >expect <<-EOF &&
127 + $root
128 + $two
129 + EOF
130 + git -c "pack.island=refs/heads/(.*)" \
131 + -c "pack.islandcore=one" \
132 + repack -adfi &&
133 + git verify-pack -v .git/objects/pack/*.pack |
134 + cut -d" " -f1 |
135 + egrep "$root|$two" >actual &&
136 + test_cmp expect actual
137 +'
138 +
139 +test_expect_success 'unmatched island core is not fatal' '
140 + git -c "pack.islandcore=one" repack -adfi
141 +'
142 +
143 +test_done