Raw
1 #!/bin/sh
2
3 test_description='Test reference backend URIs'
4
5 . ./test-lib.sh
6
7 # Run a git command with the provided reference storage. Reset the backend
8 # post running the command.
9 # Usage: run_with_uri <repo> <backend> <uri> <cmd>
10 # <repo> is the relative path to the repo to run the command in.
11 # <backend> is the original ref storage of the repo.
12 # <uri> is the new URI to be set for the ref storage.
13 # <cmd> is the git subcommand to be run in the repository.
14 # <via> if 'config', set the backend via the 'extensions.refStorage' config.
15 # if 'env', set the backend via the 'GIT_REFERENCE_BACKEND' env.
16 run_with_uri () {
17 repo=$1 &&
18 backend=$2 &&
19 uri=$3 &&
20 cmd=$4 &&
21 via=$5 &&
22
23 git -C "$repo" config set core.repositoryformatversion 1 &&
24 if test "$via" = "env"
25 then
26 test_env GIT_REFERENCE_BACKEND="$uri" git -C "$repo" $cmd
27 elif test "$via" = "config"
28 then
29 git -C "$repo" config set extensions.refStorage "$uri" &&
30 git -C "$repo" $cmd &&
31 git -C "$repo" config set extensions.refStorage "$backend"
32 fi
33 }
34
35 # Test a repository with a given reference storage by running and comparing
36 # 'git refs list' before and after setting the new reference backend. If
37 # err_msg is set, expect the command to fail and grep for the provided err_msg.
38 # Usage: run_with_uri <repo> <backend> <uri> <cmd>
39 # <repo> is the relative path to the repo to run the command in.
40 # <backend> is the original ref storage of the repo.
41 # <uri> is the new URI to be set for the ref storage.
42 # <via> if 'config', set the backend via the 'extensions.refStorage' config.
43 # if 'env', set the backend via the 'GIT_REFERENCE_BACKEND' env.
44 # <err_msg> (optional) if set, check if 'git-refs(1)' failed with the provided msg.
45 test_refs_backend () {
46 repo=$1 &&
47 backend=$2 &&
48 uri=$3 &&
49 via=$4 &&
50 err_msg=$5 &&
51
52
53 if test -n "$err_msg";
54 then
55 if test "$via" = "env"
56 then
57 test_env GIT_REFERENCE_BACKEND="$uri" test_must_fail git -C "$repo" refs list 2>err
58 elif test "$via" = "config"
59 then
60 git -C "$repo" config set extensions.refStorage "$uri" &&
61 test_must_fail git -C "$repo" refs list 2>err &&
62 test_grep "$err_msg" err
63 fi
64 else
65 git -C "$repo" refs list >expect &&
66 run_with_uri "$repo" "$backend" "$uri" "refs list" "$via">actual &&
67 test_cmp expect actual
68 fi
69 }
70
71 # Verify that the expected files are present in the gitdir and the refsdir.
72 # Usage: verify_files_exist <gitdir> <refdir>
73 # <gitdir> is the path for the gitdir.
74 # <refdir> is the path for the refdir.
75 verify_files_exist () {
76 gitdir=$1 &&
77 refdir=$2 &&
78
79 # verify that the stubs were added to the $GITDIR.
80 echo "repository uses alternate refs storage" >expect &&
81 test_cmp expect $gitdir/refs/heads &&
82 echo "ref: refs/heads/.invalid" >expect &&
83 test_cmp expect $gitdir/HEAD
84
85 # verify that backend specific files exist.
86 case "$GIT_DEFAULT_REF_FORMAT" in
87 files)
88 test_path_is_dir $refdir/refs/heads &&
89 test_path_is_file $refdir/HEAD;;
90 reftable)
91 test_path_is_dir $refdir/reftable &&
92 test_path_is_file $refdir/reftable/tables.list;;
93 *)
94 BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";;
95 esac
96 }
97
98 methods="config env"
99 for method in $methods
100 do
101
102 test_expect_success "$method: URI is invalid" '
103 test_when_finished "rm -rf repo" &&
104 git init repo &&
105 test_refs_backend repo files "reftable@/home/reftable" "$method" \
106 "invalid value for ${SQ}extensions.refstorage${SQ}"
107 '
108
109 test_expect_success "$method: URI ends with colon" '
110 test_when_finished "rm -rf repo" &&
111 git init repo &&
112 test_refs_backend repo files "reftable:" "$method" \
113 "invalid value for ${SQ}extensions.refstorage${SQ}"
114 '
115
116 test_expect_success "$method: unknown reference backend" '
117 test_when_finished "rm -rf repo" &&
118 git init repo &&
119 test_refs_backend repo files "db://.git" "$method" \
120 "invalid value for ${SQ}extensions.refstorage${SQ}"
121 '
122
123 ref_formats="files reftable"
124 for from_format in $ref_formats
125 do
126
127 for to_format in $ref_formats
128 do
129 if test "$from_format" = "$to_format"
130 then
131 continue
132 fi
133
134
135 for dir in "$(pwd)/repo/.git" "."
136 do
137
138 test_expect_success "$method: read from $to_format backend, $dir dir" '
139 test_when_finished "rm -rf repo" &&
140 git init --ref-format=$from_format repo &&
141 (
142 cd repo &&
143 test_commit 1 &&
144 test_commit 2 &&
145 test_commit 3 &&
146
147 git refs migrate --dry-run --ref-format=$to_format >out &&
148 BACKEND_PATH="$dir/$(sed "s/.* ${SQ}.git\/\(.*\)${SQ}/\1/" out)" &&
149 test_refs_backend . $from_format "$to_format://$BACKEND_PATH" "$method"
150 )
151 '
152
153 test_expect_success "$method: write to $to_format backend, $dir dir" '
154 test_when_finished "rm -rf repo" &&
155 git init --ref-format=$from_format repo &&
156 (
157 cd repo &&
158 test_commit 1 &&
159 test_commit 2 &&
160 test_commit 3 &&
161
162 git refs migrate --dry-run --ref-format=$to_format >out &&
163 BACKEND_PATH="$dir/$(sed "s/.* ${SQ}.git\/\(.*\)${SQ}/\1/" out)" &&
164
165 test_refs_backend . $from_format "$to_format://$BACKEND_PATH" "$method" &&
166
167 git refs list >expect &&
168 run_with_uri . "$from_format" "$to_format://$BACKEND_PATH" \
169 "tag -d 1" "$method" &&
170 git refs list >actual &&
171 test_cmp expect actual &&
172
173 git refs list | grep -v "refs/tags/1" >expect &&
174 run_with_uri . "$from_format" "$to_format://$BACKEND_PATH" \
175 "refs list" "$method" >actual &&
176 test_cmp expect actual
177 )
178 '
179
180 test_expect_success "$method: with worktree and $to_format backend, $dir dir" '
181 test_when_finished "rm -rf repo wt" &&
182 git init --ref-format=$from_format repo &&
183 (
184 cd repo &&
185 test_commit 1 &&
186 test_commit 2 &&
187 test_commit 3 &&
188
189 git refs migrate --dry-run --ref-format=$to_format >out &&
190 BACKEND_PATH="$dir/$(sed "s/.* ${SQ}.git\/\(.*\)${SQ}/\1/" out)" &&
191
192 run_with_uri . "$from_format" "$to_format://$BACKEND_PATH" \
193 "worktree add ../wt 2" "$method" &&
194
195 run_with_uri . "$from_format" "$to_format://$BACKEND_PATH" \
196 "for-each-ref --include-root-refs" "$method" >actual &&
197 run_with_uri ../wt "$from_format" "$to_format://$BACKEND_PATH" \
198 "for-each-ref --include-root-refs" "$method" >expect &&
199 ! test_cmp expect actual &&
200
201 run_with_uri . "$from_format" "$to_format://$BACKEND_PATH" \
202 "rev-parse 2" "$method" >actual &&
203 run_with_uri ../wt "$from_format" "$to_format://$BACKEND_PATH" \
204 "rev-parse HEAD" "$method" >expect &&
205 test_cmp expect actual
206 )
207 '
208 done # closes dir
209
210 test_expect_success "migrating repository to $to_format with alternate refs directory" '
211 test_when_finished "rm -rf repo refdir" &&
212 mkdir refdir &&
213 GIT_REFERENCE_BACKEND="${from_format}://$(pwd)/refdir" git init repo &&
214 (
215 cd repo &&
216
217 test_commit 1 &&
218 test_commit 2 &&
219 test_commit 3 &&
220
221 git refs migrate --ref-format=$to_format &&
222 git refs list >out &&
223 test_grep "refs/tags/1" out &&
224 test_grep "refs/tags/2" out &&
225 test_grep "refs/tags/3" out
226 )
227 '
228
229 done # closes to_format
230 done # closes from_format
231
232 done # closes method
233
234 test_expect_success 'initializing repository with alt ref directory' '
235 test_when_finished "rm -rf repo refdir" &&
236 mkdir refdir &&
237 BACKEND="$(test_detect_ref_format)://$(pwd)/refdir" &&
238 GIT_REFERENCE_BACKEND=$BACKEND git init repo &&
239 verify_files_exist repo/.git refdir &&
240 (
241 cd repo &&
242
243 git config get extensions.refstorage >actual &&
244 echo $BACKEND >expect &&
245 test_cmp expect actual &&
246
247 test_commit 1 &&
248 test_commit 2 &&
249 test_commit 3 &&
250 git refs list >out &&
251 test_grep "refs/tags/1" out &&
252 test_grep "refs/tags/2" out &&
253 test_grep "refs/tags/3" out
254 )
255 '
256
257 test_expect_success 'cloning repository with alt ref directory' '
258 test_when_finished "rm -rf source repo refdir" &&
259 mkdir refdir &&
260
261 git init source &&
262 test_commit -C source 1 &&
263 test_commit -C source 2 &&
264 test_commit -C source 3 &&
265
266 BACKEND="$(test_detect_ref_format)://$(pwd)/refdir" &&
267 GIT_REFERENCE_BACKEND=$BACKEND git clone source repo &&
268
269 git -C repo config get extensions.refstorage >actual &&
270 echo $BACKEND >expect &&
271 test_cmp expect actual &&
272
273 verify_files_exist repo/.git refdir &&
274
275 git -C source for-each-ref refs/tags/ >expect &&
276 git -C repo for-each-ref refs/tags/ >actual &&
277 test_cmp expect actual
278 '
279
280 test_done