t: use git-show-ref(1) to check for ref existence

Convert tests that use `test_path_is_file` and `test_path_is_missing` to instead use a set of helpers `test_ref_exists` and `test_ref_missing`. These helpers are implemented via the newly introduced `git show-ref --exists` command. Thus, we can avoid intimate knowledge of how the ref backend stores references on disk. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Oct 31, 2023 at 09:16 UTC 0497e6c61172faabf412e013f2fc30a05054a46d
5 files changed +94 -27
t/t1430-bad-ref-name.sh
+18 -9
@@ -205,8 +205,9 @@ test_expect_success 'update-ref --no-deref -d can delete symref to broken name'
205 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
206 test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg &&
207 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" &&
208 + test_ref_exists refs/heads/badname &&
209 git update-ref --no-deref -d refs/heads/badname >output 2>error &&
209 - test_path_is_missing .git/refs/heads/badname &&
210 + test_ref_missing refs/heads/badname &&
211 test_must_be_empty output &&
212 test_must_be_empty error
213 '
@@ -216,8 +217,9 @@ test_expect_success 'branch -d can delete symref to broken name' '
217 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
218 test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg &&
219 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" &&
220 + test_ref_exists refs/heads/badname &&
221 git branch -d badname >output 2>error &&
220 - test_path_is_missing .git/refs/heads/badname &&
222 + test_ref_missing refs/heads/badname &&
223 test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output &&
224 test_must_be_empty error
225 '
@@ -225,8 +227,9 @@ test_expect_success 'branch -d can delete symref to broken name' '
227 test_expect_success 'update-ref --no-deref -d can delete dangling symref to broken name' '
228 test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg &&
229 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" &&
230 + test_ref_exists refs/heads/badname &&
231 git update-ref --no-deref -d refs/heads/badname >output 2>error &&
229 - test_path_is_missing .git/refs/heads/badname &&
232 + test_ref_missing refs/heads/badname &&
233 test_must_be_empty output &&
234 test_must_be_empty error
235 '
@@ -234,8 +237,9 @@ test_expect_success 'update-ref --no-deref -d can delete dangling symref to brok
237 test_expect_success 'branch -d can delete dangling symref to broken name' '
238 test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg &&
239 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" &&
240 + test_ref_exists refs/heads/badname &&
241 git branch -d badname >output 2>error &&
238 - test_path_is_missing .git/refs/heads/badname &&
242 + test_ref_missing refs/heads/badname &&
243 test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output &&
244 test_must_be_empty error
245 '
@@ -245,8 +249,9 @@ test_expect_success 'update-ref -d can delete broken name through symref' '
249 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
250 test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg &&
251 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" &&
252 + test_ref_exists refs/heads/broken...ref &&
253 git update-ref -d refs/heads/badname >output 2>error &&
249 - test_path_is_missing .git/refs/heads/broken...ref &&
254 + test_ref_missing refs/heads/broken...ref &&
255 test_must_be_empty output &&
256 test_must_be_empty error
257 '
@@ -254,8 +259,9 @@ test_expect_success 'update-ref -d can delete broken name through symref' '
259 test_expect_success 'update-ref --no-deref -d can delete symref with broken name' '
260 printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref &&
261 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" &&
262 + test_ref_exists refs/heads/broken...symref &&
263 git update-ref --no-deref -d refs/heads/broken...symref >output 2>error &&
258 - test_path_is_missing .git/refs/heads/broken...symref &&
264 + test_ref_missing refs/heads/broken...symref &&
265 test_must_be_empty output &&
266 test_must_be_empty error
267 '
@@ -263,8 +269,9 @@ test_expect_success 'update-ref --no-deref -d can delete symref with broken name
269 test_expect_success 'branch -d can delete symref with broken name' '
270 printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref &&
271 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" &&
272 + test_ref_exists refs/heads/broken...symref &&
273 git branch -d broken...symref >output 2>error &&
267 - test_path_is_missing .git/refs/heads/broken...symref &&
274 + test_ref_missing refs/heads/broken...symref &&
275 test_i18ngrep "Deleted branch broken...symref (was refs/heads/main)" output &&
276 test_must_be_empty error
277 '
@@ -272,8 +279,9 @@ test_expect_success 'branch -d can delete symref with broken name' '
279 test_expect_success 'update-ref --no-deref -d can delete dangling symref with broken name' '
280 printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref &&
281 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" &&
282 + test_ref_exists refs/heads/broken...symref &&
283 git update-ref --no-deref -d refs/heads/broken...symref >output 2>error &&
276 - test_path_is_missing .git/refs/heads/broken...symref &&
284 + test_ref_missing refs/heads/broken...symref &&
285 test_must_be_empty output &&
286 test_must_be_empty error
287 '
@@ -281,8 +289,9 @@ test_expect_success 'update-ref --no-deref -d can delete dangling symref with br
289 test_expect_success 'branch -d can delete dangling symref with broken name' '
290 printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref &&
291 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" &&
292 + test_ref_exists refs/heads/broken...symref &&
293 git branch -d broken...symref >output 2>error &&
285 - test_path_is_missing .git/refs/heads/broken...symref &&
294 + test_ref_missing refs/heads/broken...symref &&
295 test_i18ngrep "Deleted branch broken...symref (was refs/heads/idonotexist)" output &&
296 test_must_be_empty error
297 '
t/t3200-branch.sh
+18 -15
@@ -25,7 +25,7 @@ test_expect_success 'prepare a trivial repository' '
25
26 test_expect_success 'git branch --help should not have created a bogus branch' '
27 test_might_fail git branch --man --help </dev/null >/dev/null 2>&1 &&
28 - test_path_is_missing .git/refs/heads/--help
28 + test_ref_missing refs/heads/--help
29 '
30
31 test_expect_success 'branch -h in broken repository' '
@@ -40,7 +40,8 @@ test_expect_success 'branch -h in broken repository' '
40 '
41
42 test_expect_success 'git branch abc should create a branch' '
43 - git branch abc && test_path_is_file .git/refs/heads/abc
43 + git branch abc &&
44 + test_ref_exists refs/heads/abc
45 '
46
47 test_expect_success 'git branch abc should fail when abc exists' '
@@ -61,11 +62,13 @@ test_expect_success 'git branch --force abc should succeed when abc exists' '
62 '
63
64 test_expect_success 'git branch a/b/c should create a branch' '
64 - git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c
65 + git branch a/b/c &&
66 + test_ref_exists refs/heads/a/b/c
67 '
68
69 test_expect_success 'git branch mb main... should create a branch' '
68 - git branch mb main... && test_path_is_file .git/refs/heads/mb
70 + git branch mb main... &&
71 + test_ref_exists refs/heads/mb
72 '
73
74 test_expect_success 'git branch HEAD should fail' '
@@ -78,14 +81,14 @@ EOF
81 test_expect_success 'git branch --create-reflog d/e/f should create a branch and a log' '
82 GIT_COMMITTER_DATE="2005-05-26 23:30" \
83 git -c core.logallrefupdates=false branch --create-reflog d/e/f &&
81 - test_path_is_file .git/refs/heads/d/e/f &&
84 + test_ref_exists refs/heads/d/e/f &&
85 test_path_is_file .git/logs/refs/heads/d/e/f &&
86 test_cmp expect .git/logs/refs/heads/d/e/f
87 '
88
89 test_expect_success 'git branch -d d/e/f should delete a branch and a log' '
90 git branch -d d/e/f &&
88 - test_path_is_missing .git/refs/heads/d/e/f &&
91 + test_ref_missing refs/heads/d/e/f &&
92 test_must_fail git reflog exists refs/heads/d/e/f
93 '
94
@@ -213,7 +216,7 @@ test_expect_success 'git branch -M should leave orphaned HEAD alone' '
216 test_commit initial &&
217 git checkout --orphan lonely &&
218 grep lonely .git/HEAD &&
216 - test_path_is_missing .git/refs/head/lonely &&
219 + test_ref_missing refs/head/lonely &&
220 git branch -M main mistress &&
221 grep lonely .git/HEAD
222 )
@@ -799,8 +802,8 @@ test_expect_success 'deleting a symref' '
802 git symbolic-ref refs/heads/symref refs/heads/target &&
803 echo "Deleted branch symref (was refs/heads/target)." >expect &&
804 git branch -d symref >actual &&
802 - test_path_is_file .git/refs/heads/target &&
803 - test_path_is_missing .git/refs/heads/symref &&
805 + test_ref_exists refs/heads/target &&
806 + test_ref_missing refs/heads/symref &&
807 test_cmp expect actual
808 '
809
@@ -809,16 +812,16 @@ test_expect_success 'deleting a dangling symref' '
812 test_path_is_file .git/refs/heads/dangling-symref &&
813 echo "Deleted branch dangling-symref (was nowhere)." >expect &&
814 git branch -d dangling-symref >actual &&
812 - test_path_is_missing .git/refs/heads/dangling-symref &&
815 + test_ref_missing refs/heads/dangling-symref &&
816 test_cmp expect actual
817 '
818
819 test_expect_success 'deleting a self-referential symref' '
820 git symbolic-ref refs/heads/self-reference refs/heads/self-reference &&
818 - test_path_is_file .git/refs/heads/self-reference &&
821 + test_ref_exists refs/heads/self-reference &&
822 echo "Deleted branch self-reference (was refs/heads/self-reference)." >expect &&
823 git branch -d self-reference >actual &&
821 - test_path_is_missing .git/refs/heads/self-reference &&
824 + test_ref_missing refs/heads/self-reference &&
825 test_cmp expect actual
826 '
827
@@ -826,8 +829,8 @@ test_expect_success 'renaming a symref is not allowed' '
829 git symbolic-ref refs/heads/topic refs/heads/main &&
830 test_must_fail git branch -m topic new-topic &&
831 git symbolic-ref refs/heads/topic &&
829 - test_path_is_file .git/refs/heads/main &&
830 - test_path_is_missing .git/refs/heads/new-topic
832 + test_ref_exists refs/heads/main &&
833 + test_ref_missing refs/heads/new-topic
834 '
835
836 test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' '
@@ -1142,7 +1145,7 @@ EOF
1145 test_expect_success 'git checkout -b g/h/i -l should create a branch and a log' '
1146 GIT_COMMITTER_DATE="2005-05-26 23:30" \
1147 git checkout -b g/h/i -l main &&
1145 - test_path_is_file .git/refs/heads/g/h/i &&
1148 + test_ref_exists refs/heads/g/h/i &&
1149 test_path_is_file .git/logs/refs/heads/g/h/i &&
1150 test_cmp expect .git/logs/refs/heads/g/h/i
1151 '
t/t5521-pull-options.sh
+2 -2
@@ -143,7 +143,7 @@ test_expect_success 'git pull --dry-run' '
143 cd clonedry &&
144 git pull --dry-run ../parent &&
145 test_path_is_missing .git/FETCH_HEAD &&
146 - test_path_is_missing .git/refs/heads/main &&
146 + test_ref_missing refs/heads/main &&
147 test_path_is_missing .git/index &&
148 test_path_is_missing file
149 )
@@ -157,7 +157,7 @@ test_expect_success 'git pull --all --dry-run' '
157 git remote add origin ../parent &&
158 git pull --all --dry-run &&
159 test_path_is_missing .git/FETCH_HEAD &&
160 - test_path_is_missing .git/refs/remotes/origin/main &&
160 + test_ref_missing refs/remotes/origin/main &&
161 test_path_is_missing .git/index &&
162 test_path_is_missing file
163 )
t/t5605-clone-local.sh
+1 -1
@@ -69,7 +69,7 @@ test_expect_success 'local clone of repo with nonexistent ref in HEAD' '
69 git clone a d &&
70 (cd d &&
71 git fetch &&
72 - test ! -e .git/refs/remotes/origin/HEAD)
72 + test_ref_missing refs/remotes/origin/HEAD)
73 '
74
75 test_expect_success 'bundle clone without .bundle suffix' '
t/test-lib-functions.sh
+55
@@ -251,6 +251,61 @@ debug () {
251 done
252 }
253
254 +# Usage: test_ref_exists [options] <ref>
255 +#
256 +# -C <dir>:
257 +# Run all git commands in directory <dir>
258 +#
259 +# This helper function checks whether a reference exists. Symrefs or object IDs
260 +# will not be resolved. Can be used to check references with bad names.
261 +test_ref_exists () {
262 + local indir=
263 +
264 + while test $# != 0
265 + do
266 + case "$1" in
267 + -C)
268 + indir="$2"
269 + shift
270 + ;;
271 + *)
272 + break
273 + ;;
274 + esac
275 + shift
276 + done &&
277 +
278 + indir=${indir:+"$indir"/} &&
279 +
280 + if test "$#" != 1
281 + then
282 + BUG "expected exactly one reference"
283 + fi &&
284 +
285 + git ${indir:+ -C "$indir"} show-ref --exists "$1"
286 +}
287 +
288 +# Behaves the same as test_ref_exists, except that it checks for the absence of
289 +# a reference. This is preferable to `! test_ref_exists` as this function is
290 +# able to distinguish actually-missing references from other, generic errors.
291 +test_ref_missing () {
292 + test_ref_exists "$@"
293 + case "$?" in
294 + 2)
295 + # This is the good case.
296 + return 0
297 + ;;
298 + 0)
299 + echo >&4 "test_ref_missing: reference exists"
300 + return 1
301 + ;;
302 + *)
303 + echo >&4 "test_ref_missing: generic error"
304 + return 1
305 + ;;
306 + esac
307 +}
308 +
309 # Usage: test_commit [options] <message> [<file> [<contents> [<tag>]]]
310 # -C <dir>:
311 # Run all git commands in directory <dir>