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