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