midx: fix bug that skips midx with alternates
[git] / t / t5319-multi-pack-index.sh
1 #!/bin/sh
2
3 test_description='multi-pack-indexes'
4 . ./test-lib.sh
5
6 objdir=.git/objects
7
8 midx_read_expect () {
9         NUM_PACKS=$1
10         NUM_OBJECTS=$2
11         NUM_CHUNKS=$3
12         OBJECT_DIR=$4
13         EXTRA_CHUNKS="$5"
14         {
15                 cat <<-EOF &&
16                 header: 4d494458 1 $NUM_CHUNKS $NUM_PACKS
17                 chunks: pack-names oid-fanout oid-lookup object-offsets$EXTRA_CHUNKS
18                 num_objects: $NUM_OBJECTS
19                 packs:
20                 EOF
21                 if test $NUM_PACKS -ge 1
22                 then
23                         ls $OBJECT_DIR/pack/ | grep idx | sort
24                 fi &&
25                 printf "object-dir: $OBJECT_DIR\n"
26         } >expect &&
27         test-tool read-midx $OBJECT_DIR >actual &&
28         test_cmp expect actual
29 }
30
31 test_expect_success 'write midx with no packs' '
32         test_when_finished rm -f pack/multi-pack-index &&
33         git multi-pack-index --object-dir=. write &&
34         midx_read_expect 0 0 4 .
35 '
36
37 generate_objects () {
38         i=$1
39         iii=$(printf '%03i' $i)
40         {
41                 test-tool genrandom "bar" 200 &&
42                 test-tool genrandom "baz $iii" 50
43         } >wide_delta_$iii &&
44         {
45                 test-tool genrandom "foo"$i 100 &&
46                 test-tool genrandom "foo"$(( $i + 1 )) 100 &&
47                 test-tool genrandom "foo"$(( $i + 2 )) 100
48         } >deep_delta_$iii &&
49         {
50                 echo $iii &&
51                 test-tool genrandom "$iii" 8192
52         } >file_$iii &&
53         git update-index --add file_$iii deep_delta_$iii wide_delta_$iii
54 }
55
56 commit_and_list_objects () {
57         {
58                 echo 101 &&
59                 test-tool genrandom 100 8192;
60         } >file_101 &&
61         git update-index --add file_101 &&
62         tree=$(git write-tree) &&
63         commit=$(git commit-tree $tree -p HEAD</dev/null) &&
64         {
65                 echo $tree &&
66                 git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\)        .*/\\1/"
67         } >obj-list &&
68         git reset --hard $commit
69 }
70
71 test_expect_success 'create objects' '
72         test_commit initial &&
73         for i in $(test_seq 1 5)
74         do
75                 generate_objects $i
76         done &&
77         commit_and_list_objects
78 '
79
80 test_expect_success 'write midx with one v1 pack' '
81         pack=$(git pack-objects --index-version=1 $objdir/pack/test <obj-list) &&
82         test_when_finished rm $objdir/pack/test-$pack.pack \
83                 $objdir/pack/test-$pack.idx $objdir/pack/multi-pack-index &&
84         git multi-pack-index --object-dir=$objdir write &&
85         midx_read_expect 1 18 4 $objdir
86 '
87
88 midx_git_two_modes () {
89         git -c core.multiPackIndex=false $1 >expect &&
90         git -c core.multiPackIndex=true $1 >actual &&
91         test_cmp expect actual
92 }
93
94 compare_results_with_midx () {
95         MSG=$1
96         test_expect_success "check normal git operations: $MSG" '
97                 midx_git_two_modes "rev-list --objects --all" &&
98                 midx_git_two_modes "log --raw"
99         '
100 }
101
102 test_expect_success 'write midx with one v2 pack' '
103         git pack-objects --index-version=2,0x40 $objdir/pack/test <obj-list &&
104         git multi-pack-index --object-dir=$objdir write &&
105         midx_read_expect 1 18 4 $objdir
106 '
107
108 compare_results_with_midx "one v2 pack"
109
110 test_expect_success 'add more objects' '
111         for i in $(test_seq 6 10)
112         do
113                 generate_objects $i
114         done &&
115         commit_and_list_objects
116 '
117
118 test_expect_success 'write midx with two packs' '
119         git pack-objects --index-version=1 $objdir/pack/test-2 <obj-list &&
120         git multi-pack-index --object-dir=$objdir write &&
121         midx_read_expect 2 34 4 $objdir
122 '
123
124 compare_results_with_midx "two packs"
125
126 test_expect_success 'add more packs' '
127         for j in $(test_seq 11 20)
128         do
129                 generate_objects $j &&
130                 commit_and_list_objects &&
131                 git pack-objects --index-version=2 $objdir/pack/test-pack <obj-list
132         done
133 '
134
135 compare_results_with_midx "mixed mode (two packs + extra)"
136
137 test_expect_success 'write midx with twelve packs' '
138         git multi-pack-index --object-dir=$objdir write &&
139         midx_read_expect 12 74 4 $objdir
140 '
141
142 compare_results_with_midx "twelve packs"
143
144 test_expect_success 'repack removes multi-pack-index' '
145         test_path_is_file $objdir/pack/multi-pack-index &&
146         git repack -adf &&
147         test_path_is_missing $objdir/pack/multi-pack-index
148 '
149
150 compare_results_with_midx "after repack"
151
152 test_expect_success 'multi-pack-index and alternates' '
153         git init --bare alt.git &&
154         echo $(pwd)/alt.git/objects >.git/objects/info/alternates &&
155         echo content1 >file1 &&
156         altblob=$(GIT_DIR=alt.git git hash-object -w file1) &&
157         git cat-file blob $altblob &&
158         git rev-list --all
159 '
160
161 compare_results_with_midx "with alternate (local midx)"
162
163 test_expect_success 'multi-pack-index in an alternate' '
164         mv .git/objects/pack/* alt.git/objects/pack
165 '
166
167 compare_results_with_midx "with alternate (remote midx)"
168
169
170 # usage: corrupt_data <file> <pos> [<data>]
171 corrupt_data () {
172         file=$1
173         pos=$2
174         data="${3:-\0}"
175         printf "$data" | dd of="$file" bs=1 seek="$pos" conv=notrunc
176 }
177
178 # Force 64-bit offsets by manipulating the idx file.
179 # This makes the IDX file _incorrect_ so be careful to clean up after!
180 test_expect_success 'force some 64-bit offsets with pack-objects' '
181         mkdir objects64 &&
182         mkdir objects64/pack &&
183         for i in $(test_seq 1 11)
184         do
185                 generate_objects 11
186         done &&
187         commit_and_list_objects &&
188         pack64=$(git pack-objects --index-version=2,0x40 objects64/pack/test-64 <obj-list) &&
189         idx64=objects64/pack/test-64-$pack64.idx &&
190         chmod u+w $idx64 &&
191         corrupt_data $idx64 2999 "\02" &&
192         midx64=$(git multi-pack-index --object-dir=objects64 write) &&
193         midx_read_expect 1 63 5 objects64 " large-offsets"
194 '
195
196 test_done