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