]> git.ipfire.org Git - thirdparty/git.git/blame - t/t5320-delta-islands.sh
hashmap: use *_entry APIs for iteration
[thirdparty/git.git] / t / t5320-delta-islands.sh
CommitLineData
9eb0986f
JK
1#!/bin/sh
2
3test_description='exercise delta islands'
4. ./test-lib.sh
5
6# returns true iff $1 is a delta based on $2
7is_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.
17commit() {
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
27test_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.
34test_expect_success 'vanilla repack deltas one against two' '
35 git repack -adf &&
36 is_delta_base $one $two
37'
38
39test_expect_success 'island repack with no island definition is vanilla' '
40 git repack -adfi &&
41 is_delta_base $one $two
42'
43
44test_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
49test_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
55test_expect_success 'same island allows delta' '
56 git -c "pack.island=refs/heads" repack -adfi &&
57 is_delta_base $one $two
58'
59
60test_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
68test_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
76test_expect_success 'island regexes are left-anchored' '
77 git -c "pack.island=heads/(.*)" repack -adfi &&
78 is_delta_base $one $two
79'
80
81test_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
89test_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.
99test_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).
113test_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.
125test_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
139test_expect_success 'unmatched island core is not fatal' '
140 git -c "pack.islandcore=one" repack -adfi
141'
142
143test_done