The second batch
[git] / t / test-lib-functions.sh
1 # Library of functions shared by all tests scripts, included by
2 # test-lib.sh.
3 #
4 # Copyright (c) 2005 Junio C Hamano
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see http://www.gnu.org/licenses/ .
18
19 # The semantics of the editor variables are that of invoking
20 # sh -c "$EDITOR \"$@\"" files ...
21 #
22 # If our trash directory contains shell metacharacters, they will be
23 # interpreted if we just set $EDITOR directly, so do a little dance with
24 # environment variables to work around this.
25 #
26 # In particular, quoting isn't enough, as the path may contain the same quote
27 # that we're using.
28 test_set_editor () {
29         FAKE_EDITOR="$1"
30         export FAKE_EDITOR
31         EDITOR='"$FAKE_EDITOR"'
32         export EDITOR
33 }
34
35 test_decode_color () {
36         awk '
37                 function name(n) {
38                         if (n == 0) return "RESET";
39                         if (n == 1) return "BOLD";
40                         if (n == 2) return "FAINT";
41                         if (n == 3) return "ITALIC";
42                         if (n == 7) return "REVERSE";
43                         if (n == 30) return "BLACK";
44                         if (n == 31) return "RED";
45                         if (n == 32) return "GREEN";
46                         if (n == 33) return "YELLOW";
47                         if (n == 34) return "BLUE";
48                         if (n == 35) return "MAGENTA";
49                         if (n == 36) return "CYAN";
50                         if (n == 37) return "WHITE";
51                         if (n == 40) return "BLACK";
52                         if (n == 41) return "BRED";
53                         if (n == 42) return "BGREEN";
54                         if (n == 43) return "BYELLOW";
55                         if (n == 44) return "BBLUE";
56                         if (n == 45) return "BMAGENTA";
57                         if (n == 46) return "BCYAN";
58                         if (n == 47) return "BWHITE";
59                 }
60                 {
61                         while (match($0, /\033\[[0-9;]*m/) != 0) {
62                                 printf "%s<", substr($0, 1, RSTART-1);
63                                 codes = substr($0, RSTART+2, RLENGTH-3);
64                                 if (length(codes) == 0)
65                                         printf "%s", name(0)
66                                 else {
67                                         n = split(codes, ary, ";");
68                                         sep = "";
69                                         for (i = 1; i <= n; i++) {
70                                                 printf "%s%s", sep, name(ary[i]);
71                                                 sep = ";"
72                                         }
73                                 }
74                                 printf ">";
75                                 $0 = substr($0, RSTART + RLENGTH, length($0) - RSTART - RLENGTH + 1);
76                         }
77                         print
78                 }
79         '
80 }
81
82 lf_to_nul () {
83         perl -pe 'y/\012/\000/'
84 }
85
86 nul_to_q () {
87         perl -pe 'y/\000/Q/'
88 }
89
90 q_to_nul () {
91         perl -pe 'y/Q/\000/'
92 }
93
94 q_to_cr () {
95         tr Q '\015'
96 }
97
98 q_to_tab () {
99         tr Q '\011'
100 }
101
102 qz_to_tab_space () {
103         tr QZ '\011\040'
104 }
105
106 append_cr () {
107         sed -e 's/$/Q/' | tr Q '\015'
108 }
109
110 remove_cr () {
111         tr '\015' Q | sed -e 's/Q$//'
112 }
113
114 # In some bourne shell implementations, the "unset" builtin returns
115 # nonzero status when a variable to be unset was not set in the first
116 # place.
117 #
118 # Use sane_unset when that should not be considered an error.
119
120 sane_unset () {
121         unset "$@"
122         return 0
123 }
124
125 test_tick () {
126         if test -z "${test_tick+set}"
127         then
128                 test_tick=1112911993
129         else
130                 test_tick=$(($test_tick + 60))
131         fi
132         GIT_COMMITTER_DATE="$test_tick -0700"
133         GIT_AUTHOR_DATE="$test_tick -0700"
134         export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
135 }
136
137 # Stop execution and start a shell. This is useful for debugging tests.
138 #
139 # Be sure to remove all invocations of this command before submitting.
140
141 test_pause () {
142         "$SHELL_PATH" <&6 >&5 2>&7
143 }
144
145 # Wrap git with a debugger. Adding this to a command can make it easier
146 # to understand what is going on in a failing test.
147 #
148 # Examples:
149 #     debug git checkout master
150 #     debug --debugger=nemiver git $ARGS
151 #     debug -d "valgrind --tool=memcheck --track-origins=yes" git $ARGS
152 debug () {
153         case "$1" in
154         -d)
155                 GIT_DEBUGGER="$2" &&
156                 shift 2
157                 ;;
158         --debugger=*)
159                 GIT_DEBUGGER="${1#*=}" &&
160                 shift 1
161                 ;;
162         *)
163                 GIT_DEBUGGER=1
164                 ;;
165         esac &&
166         GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7
167 }
168
169 # Usage: test_commit [options] <message> [<file> [<contents> [<tag>]]]
170 #   -C <dir>:
171 #       Run all git commands in directory <dir>
172 #   --notick
173 #       Do not call test_tick before making a commit
174 #   --append
175 #       Use ">>" instead of ">" when writing "<contents>" to "<file>"
176 #   --printf
177 #       Use "printf" instead of "echo" when writing "<contents>" to
178 #       "<file>", use this to write escape sequences such as "\0", a
179 #       trailing "\n" won't be added automatically. This option
180 #       supports nothing but the FORMAT of printf(1), i.e. no custom
181 #       ARGUMENT(s).
182 #   --signoff
183 #       Invoke "git commit" with --signoff
184 #   --author <author>
185 #       Invoke "git commit" with --author <author>
186 #   --no-tag
187 #       Do not tag the resulting commit
188 #   --annotate
189 #       Create an annotated tag with "--annotate -m <message>". Calls
190 #       test_tick between making the commit and tag, unless --notick
191 #       is given.
192 #
193 # This will commit a file with the given contents and the given commit
194 # message, and tag the resulting commit with the given tag name.
195 #
196 # <file>, <contents>, and <tag> all default to <message>.
197
198 test_commit () {
199         notick= &&
200         echo=echo &&
201         append= &&
202         author= &&
203         signoff= &&
204         indir= &&
205         tag=light &&
206         while test $# != 0
207         do
208                 case "$1" in
209                 --notick)
210                         notick=yes
211                         ;;
212                 --printf)
213                         echo=printf
214                         ;;
215                 --append)
216                         append=yes
217                         ;;
218                 --author)
219                         author="$2"
220                         shift
221                         ;;
222                 --signoff)
223                         signoff="$1"
224                         ;;
225                 --date)
226                         notick=yes
227                         GIT_COMMITTER_DATE="$2"
228                         GIT_AUTHOR_DATE="$2"
229                         shift
230                         ;;
231                 -C)
232                         indir="$2"
233                         shift
234                         ;;
235                 --no-tag)
236                         tag=none
237                         ;;
238                 --annotate)
239                         tag=annotate
240                         ;;
241                 *)
242                         break
243                         ;;
244                 esac
245                 shift
246         done &&
247         indir=${indir:+"$indir"/} &&
248         file=${2:-"$1.t"} &&
249         if test -n "$append"
250         then
251                 $echo "${3-$1}" >>"$indir$file"
252         else
253                 $echo "${3-$1}" >"$indir$file"
254         fi &&
255         git ${indir:+ -C "$indir"} add "$file" &&
256         if test -z "$notick"
257         then
258                 test_tick
259         fi &&
260         git ${indir:+ -C "$indir"} commit \
261             ${author:+ --author "$author"} \
262             $signoff -m "$1" &&
263         case "$tag" in
264         none)
265                 ;;
266         light)
267                 git ${indir:+ -C "$indir"} tag "${4:-$1}"
268                 ;;
269         annotate)
270                 if test -z "$notick"
271                 then
272                         test_tick
273                 fi &&
274                 git ${indir:+ -C "$indir"} tag -a -m "$1" "${4:-$1}"
275                 ;;
276         esac
277 }
278
279 # Call test_merge with the arguments "<message> <commit>", where <commit>
280 # can be a tag pointing to the commit-to-merge.
281
282 test_merge () {
283         label="$1" &&
284         shift &&
285         test_tick &&
286         git merge -m "$label" "$@" &&
287         git tag "$label"
288 }
289
290 # Efficiently create <nr> commits, each with a unique number (from 1 to <nr>
291 # by default) in the commit message.
292 #
293 # Usage: test_commit_bulk [options] <nr>
294 #   -C <dir>:
295 #       Run all git commands in directory <dir>
296 #   --ref=<n>:
297 #       ref on which to create commits (default: HEAD)
298 #   --start=<n>:
299 #       number commit messages from <n> (default: 1)
300 #   --message=<msg>:
301 #       use <msg> as the commit mesasge (default: "commit %s")
302 #   --filename=<fn>:
303 #       modify <fn> in each commit (default: %s.t)
304 #   --contents=<string>:
305 #       place <string> in each file (default: "content %s")
306 #   --id=<string>:
307 #       shorthand to use <string> and %s in message, filename, and contents
308 #
309 # The message, filename, and contents strings are evaluated by printf, with the
310 # first "%s" replaced by the current commit number. So you can do:
311 #
312 #   test_commit_bulk --filename=file --contents="modification %s"
313 #
314 # to have every commit touch the same file, but with unique content.
315 #
316 test_commit_bulk () {
317         tmpfile=.bulk-commit.input
318         indir=.
319         ref=HEAD
320         n=1
321         message='commit %s'
322         filename='%s.t'
323         contents='content %s'
324         while test $# -gt 0
325         do
326                 case "$1" in
327                 -C)
328                         indir=$2
329                         shift
330                         ;;
331                 --ref=*)
332                         ref=${1#--*=}
333                         ;;
334                 --start=*)
335                         n=${1#--*=}
336                         ;;
337                 --message=*)
338                         message=${1#--*=}
339                         ;;
340                 --filename=*)
341                         filename=${1#--*=}
342                         ;;
343                 --contents=*)
344                         contents=${1#--*=}
345                         ;;
346                 --id=*)
347                         message="${1#--*=} %s"
348                         filename="${1#--*=}-%s.t"
349                         contents="${1#--*=} %s"
350                         ;;
351                 -*)
352                         BUG "invalid test_commit_bulk option: $1"
353                         ;;
354                 *)
355                         break
356                         ;;
357                 esac
358                 shift
359         done
360         total=$1
361
362         add_from=
363         if git -C "$indir" rev-parse --quiet --verify "$ref"
364         then
365                 add_from=t
366         fi
367
368         while test "$total" -gt 0
369         do
370                 test_tick &&
371                 echo "commit $ref"
372                 printf 'author %s <%s> %s\n' \
373                         "$GIT_AUTHOR_NAME" \
374                         "$GIT_AUTHOR_EMAIL" \
375                         "$GIT_AUTHOR_DATE"
376                 printf 'committer %s <%s> %s\n' \
377                         "$GIT_COMMITTER_NAME" \
378                         "$GIT_COMMITTER_EMAIL" \
379                         "$GIT_COMMITTER_DATE"
380                 echo "data <<EOF"
381                 printf "$message\n" $n
382                 echo "EOF"
383                 if test -n "$add_from"
384                 then
385                         echo "from $ref^0"
386                         add_from=
387                 fi
388                 printf "M 644 inline $filename\n" $n
389                 echo "data <<EOF"
390                 printf "$contents\n" $n
391                 echo "EOF"
392                 echo
393                 n=$((n + 1))
394                 total=$((total - 1))
395         done >"$tmpfile"
396
397         git -C "$indir" \
398             -c fastimport.unpacklimit=0 \
399             fast-import <"$tmpfile" || return 1
400
401         # This will be left in place on failure, which may aid debugging.
402         rm -f "$tmpfile"
403
404         # If we updated HEAD, then be nice and update the index and working
405         # tree, too.
406         if test "$ref" = "HEAD"
407         then
408                 git -C "$indir" checkout -f HEAD || return 1
409         fi
410
411 }
412
413 # This function helps systems where core.filemode=false is set.
414 # Use it instead of plain 'chmod +x' to set or unset the executable bit
415 # of a file in the working directory and add it to the index.
416
417 test_chmod () {
418         chmod "$@" &&
419         git update-index --add "--chmod=$@"
420 }
421
422 # Get the modebits from a file or directory, ignoring the setgid bit (g+s).
423 # This bit is inherited by subdirectories at their creation. So we remove it
424 # from the returning string to prevent callers from having to worry about the
425 # state of the bit in the test directory.
426 #
427 test_modebits () {
428         ls -ld "$1" | sed -e 's|^\(..........\).*|\1|' \
429                           -e 's|^\(......\)S|\1-|' -e 's|^\(......\)s|\1x|'
430 }
431
432 # Unset a configuration variable, but don't fail if it doesn't exist.
433 test_unconfig () {
434         config_dir=
435         if test "$1" = -C
436         then
437                 shift
438                 config_dir=$1
439                 shift
440         fi
441         git ${config_dir:+-C "$config_dir"} config --unset-all "$@"
442         config_status=$?
443         case "$config_status" in
444         5) # ok, nothing to unset
445                 config_status=0
446                 ;;
447         esac
448         return $config_status
449 }
450
451 # Set git config, automatically unsetting it after the test is over.
452 test_config () {
453         config_dir=
454         if test "$1" = -C
455         then
456                 shift
457                 config_dir=$1
458                 shift
459         fi
460         test_when_finished "test_unconfig ${config_dir:+-C '$config_dir'} '$1'" &&
461         git ${config_dir:+-C "$config_dir"} config "$@"
462 }
463
464 test_config_global () {
465         test_when_finished "test_unconfig --global '$1'" &&
466         git config --global "$@"
467 }
468
469 write_script () {
470         {
471                 echo "#!${2-"$SHELL_PATH"}" &&
472                 cat
473         } >"$1" &&
474         chmod +x "$1"
475 }
476
477 # Use test_set_prereq to tell that a particular prerequisite is available.
478 # The prerequisite can later be checked for in two ways:
479 #
480 # - Explicitly using test_have_prereq.
481 #
482 # - Implicitly by specifying the prerequisite tag in the calls to
483 #   test_expect_{success,failure} and test_external{,_without_stderr}.
484 #
485 # The single parameter is the prerequisite tag (a simple word, in all
486 # capital letters by convention).
487
488 test_unset_prereq () {
489         ! test_have_prereq "$1" ||
490         satisfied_prereq="${satisfied_prereq% $1 *} ${satisfied_prereq#* $1 }"
491 }
492
493 test_set_prereq () {
494         if test -n "$GIT_TEST_FAIL_PREREQS_INTERNAL"
495         then
496                 case "$1" in
497                 # The "!" case is handled below with
498                 # test_unset_prereq()
499                 !*)
500                         ;;
501                 # (Temporary?) whitelist of things we can't easily
502                 # pretend not to support
503                 SYMLINKS)
504                         ;;
505                 # Inspecting whether GIT_TEST_FAIL_PREREQS is on
506                 # should be unaffected.
507                 FAIL_PREREQS)
508                         ;;
509                 *)
510                         return
511                 esac
512         fi
513
514         case "$1" in
515         !*)
516                 test_unset_prereq "${1#!}"
517                 ;;
518         *)
519                 satisfied_prereq="$satisfied_prereq$1 "
520                 ;;
521         esac
522 }
523 satisfied_prereq=" "
524 lazily_testable_prereq= lazily_tested_prereq=
525
526 # Usage: test_lazy_prereq PREREQ 'script'
527 test_lazy_prereq () {
528         lazily_testable_prereq="$lazily_testable_prereq$1 "
529         eval test_prereq_lazily_$1=\$2
530 }
531
532 test_run_lazy_prereq_ () {
533         script='
534 mkdir -p "$TRASH_DIRECTORY/prereq-test-dir-'"$1"'" &&
535 (
536         cd "$TRASH_DIRECTORY/prereq-test-dir-'"$1"'" &&'"$2"'
537 )'
538         say >&3 "checking prerequisite: $1"
539         say >&3 "$script"
540         test_eval_ "$script"
541         eval_ret=$?
542         rm -rf "$TRASH_DIRECTORY/prereq-test-dir-$1"
543         if test "$eval_ret" = 0; then
544                 say >&3 "prerequisite $1 ok"
545         else
546                 say >&3 "prerequisite $1 not satisfied"
547         fi
548         return $eval_ret
549 }
550
551 test_have_prereq () {
552         # prerequisites can be concatenated with ','
553         save_IFS=$IFS
554         IFS=,
555         set -- $*
556         IFS=$save_IFS
557
558         total_prereq=0
559         ok_prereq=0
560         missing_prereq=
561
562         for prerequisite
563         do
564                 case "$prerequisite" in
565                 !*)
566                         negative_prereq=t
567                         prerequisite=${prerequisite#!}
568                         ;;
569                 *)
570                         negative_prereq=
571                 esac
572
573                 case " $lazily_tested_prereq " in
574                 *" $prerequisite "*)
575                         ;;
576                 *)
577                         case " $lazily_testable_prereq " in
578                         *" $prerequisite "*)
579                                 eval "script=\$test_prereq_lazily_$prerequisite" &&
580                                 if test_run_lazy_prereq_ "$prerequisite" "$script"
581                                 then
582                                         test_set_prereq $prerequisite
583                                 fi
584                                 lazily_tested_prereq="$lazily_tested_prereq$prerequisite "
585                         esac
586                         ;;
587                 esac
588
589                 total_prereq=$(($total_prereq + 1))
590                 case "$satisfied_prereq" in
591                 *" $prerequisite "*)
592                         satisfied_this_prereq=t
593                         ;;
594                 *)
595                         satisfied_this_prereq=
596                 esac
597
598                 case "$satisfied_this_prereq,$negative_prereq" in
599                 t,|,t)
600                         ok_prereq=$(($ok_prereq + 1))
601                         ;;
602                 *)
603                         # Keep a list of missing prerequisites; restore
604                         # the negative marker if necessary.
605                         prerequisite=${negative_prereq:+!}$prerequisite
606                         if test -z "$missing_prereq"
607                         then
608                                 missing_prereq=$prerequisite
609                         else
610                                 missing_prereq="$prerequisite,$missing_prereq"
611                         fi
612                 esac
613         done
614
615         test $total_prereq = $ok_prereq
616 }
617
618 test_declared_prereq () {
619         case ",$test_prereq," in
620         *,$1,*)
621                 return 0
622                 ;;
623         esac
624         return 1
625 }
626
627 test_verify_prereq () {
628         test -z "$test_prereq" ||
629         expr >/dev/null "$test_prereq" : '[A-Z0-9_,!]*$' ||
630         BUG "'$test_prereq' does not look like a prereq"
631 }
632
633 test_expect_failure () {
634         test_start_
635         test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
636         test "$#" = 2 ||
637         BUG "not 2 or 3 parameters to test-expect-failure"
638         test_verify_prereq
639         export test_prereq
640         if ! test_skip "$@"
641         then
642                 say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2"
643                 if test_run_ "$2" expecting_failure
644                 then
645                         test_known_broken_ok_ "$1"
646                 else
647                         test_known_broken_failure_ "$1"
648                 fi
649         fi
650         test_finish_
651 }
652
653 test_expect_success () {
654         test_start_
655         test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
656         test "$#" = 2 ||
657         BUG "not 2 or 3 parameters to test-expect-success"
658         test_verify_prereq
659         export test_prereq
660         if ! test_skip "$@"
661         then
662                 say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2"
663                 if test_run_ "$2"
664                 then
665                         test_ok_ "$1"
666                 else
667                         test_failure_ "$@"
668                 fi
669         fi
670         test_finish_
671 }
672
673 # test_external runs external test scripts that provide continuous
674 # test output about their progress, and succeeds/fails on
675 # zero/non-zero exit code.  It outputs the test output on stdout even
676 # in non-verbose mode, and announces the external script with "# run
677 # <n>: ..." before running it.  When providing relative paths, keep in
678 # mind that all scripts run in "trash directory".
679 # Usage: test_external description command arguments...
680 # Example: test_external 'Perl API' perl ../path/to/test.pl
681 test_external () {
682         test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
683         test "$#" = 3 ||
684         BUG "not 3 or 4 parameters to test_external"
685         descr="$1"
686         shift
687         test_verify_prereq
688         export test_prereq
689         if ! test_skip "$descr" "$@"
690         then
691                 # Announce the script to reduce confusion about the
692                 # test output that follows.
693                 say_color "" "# run $test_count: $descr ($*)"
694                 # Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG
695                 # to be able to use them in script
696                 export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG
697                 # Run command; redirect its stderr to &4 as in
698                 # test_run_, but keep its stdout on our stdout even in
699                 # non-verbose mode.
700                 "$@" 2>&4
701                 if test "$?" = 0
702                 then
703                         if test $test_external_has_tap -eq 0; then
704                                 test_ok_ "$descr"
705                         else
706                                 say_color "" "# test_external test $descr was ok"
707                                 test_success=$(($test_success + 1))
708                         fi
709                 else
710                         if test $test_external_has_tap -eq 0; then
711                                 test_failure_ "$descr" "$@"
712                         else
713                                 say_color error "# test_external test $descr failed: $@"
714                                 test_failure=$(($test_failure + 1))
715                         fi
716                 fi
717         fi
718 }
719
720 # Like test_external, but in addition tests that the command generated
721 # no output on stderr.
722 test_external_without_stderr () {
723         # The temporary file has no (and must have no) security
724         # implications.
725         tmp=${TMPDIR:-/tmp}
726         stderr="$tmp/git-external-stderr.$$.tmp"
727         test_external "$@" 4> "$stderr"
728         test -f "$stderr" || error "Internal error: $stderr disappeared."
729         descr="no stderr: $1"
730         shift
731         say >&3 "# expecting no stderr from previous command"
732         if test ! -s "$stderr"
733         then
734                 rm "$stderr"
735
736                 if test $test_external_has_tap -eq 0; then
737                         test_ok_ "$descr"
738                 else
739                         say_color "" "# test_external_without_stderr test $descr was ok"
740                         test_success=$(($test_success + 1))
741                 fi
742         else
743                 if test "$verbose" = t
744                 then
745                         output=$(echo; echo "# Stderr is:"; cat "$stderr")
746                 else
747                         output=
748                 fi
749                 # rm first in case test_failure exits.
750                 rm "$stderr"
751                 if test $test_external_has_tap -eq 0; then
752                         test_failure_ "$descr" "$@" "$output"
753                 else
754                         say_color error "# test_external_without_stderr test $descr failed: $@: $output"
755                         test_failure=$(($test_failure + 1))
756                 fi
757         fi
758 }
759
760 # debugging-friendly alternatives to "test [-f|-d|-e]"
761 # The commands test the existence or non-existence of $1
762 test_path_is_file () {
763         test "$#" -ne 1 && BUG "1 param"
764         if ! test -f "$1"
765         then
766                 echo "File $1 doesn't exist"
767                 false
768         fi
769 }
770
771 test_path_is_dir () {
772         test "$#" -ne 1 && BUG "1 param"
773         if ! test -d "$1"
774         then
775                 echo "Directory $1 doesn't exist"
776                 false
777         fi
778 }
779
780 test_path_exists () {
781         test "$#" -ne 1 && BUG "1 param"
782         if ! test -e "$1"
783         then
784                 echo "Path $1 doesn't exist"
785                 false
786         fi
787 }
788
789 # Check if the directory exists and is empty as expected, barf otherwise.
790 test_dir_is_empty () {
791         test "$#" -ne 1 && BUG "1 param"
792         test_path_is_dir "$1" &&
793         if test -n "$(ls -a1 "$1" | egrep -v '^\.\.?$')"
794         then
795                 echo "Directory '$1' is not empty, it contains:"
796                 ls -la "$1"
797                 return 1
798         fi
799 }
800
801 # Check if the file exists and has a size greater than zero
802 test_file_not_empty () {
803         test "$#" = 2 && BUG "2 param"
804         if ! test -s "$1"
805         then
806                 echo "'$1' is not a non-empty file."
807                 false
808         fi
809 }
810
811 test_path_is_missing () {
812         test "$#" -ne 1 && BUG "1 param"
813         if test -e "$1"
814         then
815                 echo "Path exists:"
816                 ls -ld "$1"
817                 if test $# -ge 1
818                 then
819                         echo "$*"
820                 fi
821                 false
822         fi
823 }
824
825 # test_line_count checks that a file has the number of lines it
826 # ought to. For example:
827 #
828 #       test_expect_success 'produce exactly one line of output' '
829 #               do something >output &&
830 #               test_line_count = 1 output
831 #       '
832 #
833 # is like "test $(wc -l <output) = 1" except that it passes the
834 # output through when the number of lines is wrong.
835
836 test_line_count () {
837         if test $# != 3
838         then
839                 BUG "not 3 parameters to test_line_count"
840         elif ! test $(wc -l <"$3") "$1" "$2"
841         then
842                 echo "test_line_count: line count for $3 !$1 $2"
843                 cat "$3"
844                 return 1
845         fi
846 }
847
848 test_file_size () {
849         test "$#" -ne 1 && BUG "1 param"
850         test-tool path-utils file-size "$1"
851 }
852
853 # Returns success if a comma separated string of keywords ($1) contains a
854 # given keyword ($2).
855 # Examples:
856 # `list_contains "foo,bar" bar` returns 0
857 # `list_contains "foo" bar` returns 1
858
859 list_contains () {
860         case ",$1," in
861         *,$2,*)
862                 return 0
863                 ;;
864         esac
865         return 1
866 }
867
868 # Returns success if the arguments indicate that a command should be
869 # accepted by test_must_fail(). If the command is run with env, the env
870 # and its corresponding variable settings will be stripped before we
871 # test the command being run.
872 test_must_fail_acceptable () {
873         if test "$1" = "env"
874         then
875                 shift
876                 while test $# -gt 0
877                 do
878                         case "$1" in
879                         *?=*)
880                                 shift
881                                 ;;
882                         *)
883                                 break
884                                 ;;
885                         esac
886                 done
887         fi
888
889         case "$1" in
890         git|__git*|test-tool|test_terminal)
891                 return 0
892                 ;;
893         *)
894                 return 1
895                 ;;
896         esac
897 }
898
899 # This is not among top-level (test_expect_success | test_expect_failure)
900 # but is a prefix that can be used in the test script, like:
901 #
902 #       test_expect_success 'complain and die' '
903 #           do something &&
904 #           do something else &&
905 #           test_must_fail git checkout ../outerspace
906 #       '
907 #
908 # Writing this as "! git checkout ../outerspace" is wrong, because
909 # the failure could be due to a segv.  We want a controlled failure.
910 #
911 # Accepts the following options:
912 #
913 #   ok=<signal-name>[,<...>]:
914 #     Don't treat an exit caused by the given signal as error.
915 #     Multiple signals can be specified as a comma separated list.
916 #     Currently recognized signal names are: sigpipe, success.
917 #     (Don't use 'success', use 'test_might_fail' instead.)
918 #
919 # Do not use this to run anything but "git" and other specific testable
920 # commands (see test_must_fail_acceptable()).  We are not in the
921 # business of vetting system supplied commands -- in other words, this
922 # is wrong:
923 #
924 #    test_must_fail grep pattern output
925 #
926 # Instead use '!':
927 #
928 #    ! grep pattern output
929
930 test_must_fail () {
931         case "$1" in
932         ok=*)
933                 _test_ok=${1#ok=}
934                 shift
935                 ;;
936         *)
937                 _test_ok=
938                 ;;
939         esac
940         if ! test_must_fail_acceptable "$@"
941         then
942                 echo >&7 "test_must_fail: only 'git' is allowed: $*"
943                 return 1
944         fi
945         "$@" 2>&7
946         exit_code=$?
947         if test $exit_code -eq 0 && ! list_contains "$_test_ok" success
948         then
949                 echo >&4 "test_must_fail: command succeeded: $*"
950                 return 1
951         elif test_match_signal 13 $exit_code && list_contains "$_test_ok" sigpipe
952         then
953                 return 0
954         elif test $exit_code -gt 129 && test $exit_code -le 192
955         then
956                 echo >&4 "test_must_fail: died by signal $(($exit_code - 128)): $*"
957                 return 1
958         elif test $exit_code -eq 127
959         then
960                 echo >&4 "test_must_fail: command not found: $*"
961                 return 1
962         elif test $exit_code -eq 126
963         then
964                 echo >&4 "test_must_fail: valgrind error: $*"
965                 return 1
966         fi
967         return 0
968 } 7>&2 2>&4
969
970 # Similar to test_must_fail, but tolerates success, too.  This is
971 # meant to be used in contexts like:
972 #
973 #       test_expect_success 'some command works without configuration' '
974 #               test_might_fail git config --unset all.configuration &&
975 #               do something
976 #       '
977 #
978 # Writing "git config --unset all.configuration || :" would be wrong,
979 # because we want to notice if it fails due to segv.
980 #
981 # Accepts the same options as test_must_fail.
982
983 test_might_fail () {
984         test_must_fail ok=success "$@" 2>&7
985 } 7>&2 2>&4
986
987 # Similar to test_must_fail and test_might_fail, but check that a
988 # given command exited with a given exit code. Meant to be used as:
989 #
990 #       test_expect_success 'Merge with d/f conflicts' '
991 #               test_expect_code 1 git merge "merge msg" B master
992 #       '
993
994 test_expect_code () {
995         want_code=$1
996         shift
997         "$@" 2>&7
998         exit_code=$?
999         if test $exit_code = $want_code
1000         then
1001                 return 0
1002         fi
1003
1004         echo >&4 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
1005         return 1
1006 } 7>&2 2>&4
1007
1008 # test_cmp is a helper function to compare actual and expected output.
1009 # You can use it like:
1010 #
1011 #       test_expect_success 'foo works' '
1012 #               echo expected >expected &&
1013 #               foo >actual &&
1014 #               test_cmp expected actual
1015 #       '
1016 #
1017 # This could be written as either "cmp" or "diff -u", but:
1018 # - cmp's output is not nearly as easy to read as diff -u
1019 # - not all diff versions understand "-u"
1020
1021 test_cmp () {
1022         test "$#" -ne 2 && BUG "2 param"
1023         eval "$GIT_TEST_CMP" '"$@"'
1024 }
1025
1026 # Check that the given config key has the expected value.
1027 #
1028 #    test_cmp_config [-C <dir>] <expected-value>
1029 #                    [<git-config-options>...] <config-key>
1030 #
1031 # for example to check that the value of core.bar is foo
1032 #
1033 #    test_cmp_config foo core.bar
1034 #
1035 test_cmp_config () {
1036         local GD &&
1037         if test "$1" = "-C"
1038         then
1039                 shift &&
1040                 GD="-C $1" &&
1041                 shift
1042         fi &&
1043         printf "%s\n" "$1" >expect.config &&
1044         shift &&
1045         git $GD config "$@" >actual.config &&
1046         test_cmp expect.config actual.config
1047 }
1048
1049 # test_cmp_bin - helper to compare binary files
1050
1051 test_cmp_bin () {
1052         test "$#" -ne 2 && BUG "2 param"
1053         cmp "$@"
1054 }
1055
1056 # Wrapper for grep which used to be used for
1057 # GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other
1058 # in-flight changes. Should not be used and will be removed soon.
1059 test_i18ngrep () {
1060         eval "last_arg=\${$#}"
1061
1062         test -f "$last_arg" ||
1063         BUG "test_i18ngrep requires a file to read as the last parameter"
1064
1065         if test $# -lt 2 ||
1066            { test "x!" = "x$1" && test $# -lt 3 ; }
1067         then
1068                 BUG "too few parameters to test_i18ngrep"
1069         fi
1070
1071         if test "x!" = "x$1"
1072         then
1073                 shift
1074                 ! grep "$@" && return 0
1075
1076                 echo >&4 "error: '! grep $@' did find a match in:"
1077         else
1078                 grep "$@" && return 0
1079
1080                 echo >&4 "error: 'grep $@' didn't find a match in:"
1081         fi
1082
1083         if test -s "$last_arg"
1084         then
1085                 cat >&4 "$last_arg"
1086         else
1087                 echo >&4 "<File '$last_arg' is empty>"
1088         fi
1089
1090         return 1
1091 }
1092
1093 # Call any command "$@" but be more verbose about its
1094 # failure. This is handy for commands like "test" which do
1095 # not output anything when they fail.
1096 verbose () {
1097         "$@" && return 0
1098         echo >&4 "command failed: $(git rev-parse --sq-quote "$@")"
1099         return 1
1100 }
1101
1102 # Check if the file expected to be empty is indeed empty, and barfs
1103 # otherwise.
1104
1105 test_must_be_empty () {
1106         test "$#" -ne 1 && BUG "1 param"
1107         test_path_is_file "$1" &&
1108         if test -s "$1"
1109         then
1110                 echo "'$1' is not empty, it contains:"
1111                 cat "$1"
1112                 return 1
1113         fi
1114 }
1115
1116 # Tests that its two parameters refer to the same revision, or if '!' is
1117 # provided first, that its other two parameters refer to different
1118 # revisions.
1119 test_cmp_rev () {
1120         local op='=' wrong_result=different
1121
1122         if test $# -ge 1 && test "x$1" = 'x!'
1123         then
1124             op='!='
1125             wrong_result='the same'
1126             shift
1127         fi
1128         if test $# != 2
1129         then
1130                 BUG "test_cmp_rev requires two revisions, but got $#"
1131         else
1132                 local r1 r2
1133                 r1=$(git rev-parse --verify "$1") &&
1134                 r2=$(git rev-parse --verify "$2") || return 1
1135
1136                 if ! test "$r1" "$op" "$r2"
1137                 then
1138                         cat >&4 <<-EOF
1139                         error: two revisions point to $wrong_result objects:
1140                           '$1': $r1
1141                           '$2': $r2
1142                         EOF
1143                         return 1
1144                 fi
1145         fi
1146 }
1147
1148 # Compare paths respecting core.ignoreCase
1149 test_cmp_fspath () {
1150         if test "x$1" = "x$2"
1151         then
1152                 return 0
1153         fi
1154
1155         if test true != "$(git config --get --type=bool core.ignorecase)"
1156         then
1157                 return 1
1158         fi
1159
1160         test "x$(echo "$1" | tr A-Z a-z)" =  "x$(echo "$2" | tr A-Z a-z)"
1161 }
1162
1163 # Print a sequence of integers in increasing order, either with
1164 # two arguments (start and end):
1165 #
1166 #     test_seq 1 5 -- outputs 1 2 3 4 5 one line at a time
1167 #
1168 # or with one argument (end), in which case it starts counting
1169 # from 1.
1170
1171 test_seq () {
1172         case $# in
1173         1)      set 1 "$@" ;;
1174         2)      ;;
1175         *)      BUG "not 1 or 2 parameters to test_seq" ;;
1176         esac
1177         test_seq_counter__=$1
1178         while test "$test_seq_counter__" -le "$2"
1179         do
1180                 echo "$test_seq_counter__"
1181                 test_seq_counter__=$(( $test_seq_counter__ + 1 ))
1182         done
1183 }
1184
1185 # This function can be used to schedule some commands to be run
1186 # unconditionally at the end of the test to restore sanity:
1187 #
1188 #       test_expect_success 'test core.capslock' '
1189 #               git config core.capslock true &&
1190 #               test_when_finished "git config --unset core.capslock" &&
1191 #               hello world
1192 #       '
1193 #
1194 # That would be roughly equivalent to
1195 #
1196 #       test_expect_success 'test core.capslock' '
1197 #               git config core.capslock true &&
1198 #               hello world
1199 #               git config --unset core.capslock
1200 #       '
1201 #
1202 # except that the greeting and config --unset must both succeed for
1203 # the test to pass.
1204 #
1205 # Note that under --immediate mode, no clean-up is done to help diagnose
1206 # what went wrong.
1207
1208 test_when_finished () {
1209         # We cannot detect when we are in a subshell in general, but by
1210         # doing so on Bash is better than nothing (the test will
1211         # silently pass on other shells).
1212         test "${BASH_SUBSHELL-0}" = 0 ||
1213         BUG "test_when_finished does nothing in a subshell"
1214         test_cleanup="{ $*
1215                 } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
1216 }
1217
1218 # This function can be used to schedule some commands to be run
1219 # unconditionally at the end of the test script, e.g. to stop a daemon:
1220 #
1221 #       test_expect_success 'test git daemon' '
1222 #               git daemon &
1223 #               daemon_pid=$! &&
1224 #               test_atexit 'kill $daemon_pid' &&
1225 #               hello world
1226 #       '
1227 #
1228 # The commands will be executed before the trash directory is removed,
1229 # i.e. the atexit commands will still be able to access any pidfiles or
1230 # socket files.
1231 #
1232 # Note that these commands will be run even when a test script run
1233 # with '--immediate' fails.  Be careful with your atexit commands to
1234 # minimize any changes to the failed state.
1235
1236 test_atexit () {
1237         # We cannot detect when we are in a subshell in general, but by
1238         # doing so on Bash is better than nothing (the test will
1239         # silently pass on other shells).
1240         test "${BASH_SUBSHELL-0}" = 0 ||
1241         BUG "test_atexit does nothing in a subshell"
1242         test_atexit_cleanup="{ $*
1243                 } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_atexit_cleanup"
1244 }
1245
1246 # Deprecated wrapper for "git init", use "git init" directly instead
1247 # Usage: test_create_repo <directory>
1248 test_create_repo () {
1249         git init "$@"
1250 }
1251
1252 # This function helps on symlink challenged file systems when it is not
1253 # important that the file system entry is a symbolic link.
1254 # Use test_ln_s_add instead of "ln -s x y && git add y" to add a
1255 # symbolic link entry y to the index.
1256
1257 test_ln_s_add () {
1258         if test_have_prereq SYMLINKS
1259         then
1260                 ln -s "$1" "$2" &&
1261                 git update-index --add "$2"
1262         else
1263                 printf '%s' "$1" >"$2" &&
1264                 ln_s_obj=$(git hash-object -w "$2") &&
1265                 git update-index --add --cacheinfo 120000 $ln_s_obj "$2" &&
1266                 # pick up stat info from the file
1267                 git update-index "$2"
1268         fi
1269 }
1270
1271 # This function writes out its parameters, one per line
1272 test_write_lines () {
1273         printf "%s\n" "$@"
1274 }
1275
1276 perl () {
1277         command "$PERL_PATH" "$@" 2>&7
1278 } 7>&2 2>&4
1279
1280 # Given the name of an environment variable with a bool value, normalize
1281 # its value to a 0 (true) or 1 (false or empty string) return code.
1282 #
1283 #   test_bool_env GIT_TEST_HTTPD <default-value>
1284 #
1285 # Return with code corresponding to the given default value if the variable
1286 # is unset.
1287 # Abort the test script if either the value of the variable or the default
1288 # are not valid bool values.
1289
1290 test_bool_env () {
1291         if test $# != 2
1292         then
1293                 BUG "test_bool_env requires two parameters (variable name and default value)"
1294         fi
1295
1296         git env--helper --type=bool --default="$2" --exit-code "$1"
1297         ret=$?
1298         case $ret in
1299         0|1)    # unset or valid bool value
1300                 ;;
1301         *)      # invalid bool value or something unexpected
1302                 error >&7 "test_bool_env requires bool values both for \$$1 and for the default fallback"
1303                 ;;
1304         esac
1305         return $ret
1306 }
1307
1308 # Exit the test suite, either by skipping all remaining tests or by
1309 # exiting with an error. If our prerequisite variable $1 falls back
1310 # on a default assume we were opportunistically trying to set up some
1311 # tests and we skip. If it is explicitly "true", then we report a failure.
1312 #
1313 # The error/skip message should be given by $2.
1314 #
1315 test_skip_or_die () {
1316         if ! test_bool_env "$1" false
1317         then
1318                 skip_all=$2
1319                 test_done
1320         fi
1321         error "$2"
1322 }
1323
1324 # The following mingw_* functions obey POSIX shell syntax, but are actually
1325 # bash scripts, and are meant to be used only with bash on Windows.
1326
1327 # A test_cmp function that treats LF and CRLF equal and avoids to fork
1328 # diff when possible.
1329 mingw_test_cmp () {
1330         # Read text into shell variables and compare them. If the results
1331         # are different, use regular diff to report the difference.
1332         local test_cmp_a= test_cmp_b=
1333
1334         # When text came from stdin (one argument is '-') we must feed it
1335         # to diff.
1336         local stdin_for_diff=
1337
1338         # Since it is difficult to detect the difference between an
1339         # empty input file and a failure to read the files, we go straight
1340         # to diff if one of the inputs is empty.
1341         if test -s "$1" && test -s "$2"
1342         then
1343                 # regular case: both files non-empty
1344                 mingw_read_file_strip_cr_ test_cmp_a <"$1"
1345                 mingw_read_file_strip_cr_ test_cmp_b <"$2"
1346         elif test -s "$1" && test "$2" = -
1347         then
1348                 # read 2nd file from stdin
1349                 mingw_read_file_strip_cr_ test_cmp_a <"$1"
1350                 mingw_read_file_strip_cr_ test_cmp_b
1351                 stdin_for_diff='<<<"$test_cmp_b"'
1352         elif test "$1" = - && test -s "$2"
1353         then
1354                 # read 1st file from stdin
1355                 mingw_read_file_strip_cr_ test_cmp_a
1356                 mingw_read_file_strip_cr_ test_cmp_b <"$2"
1357                 stdin_for_diff='<<<"$test_cmp_a"'
1358         fi
1359         test -n "$test_cmp_a" &&
1360         test -n "$test_cmp_b" &&
1361         test "$test_cmp_a" = "$test_cmp_b" ||
1362         eval "diff -u \"\$@\" $stdin_for_diff"
1363 }
1364
1365 # $1 is the name of the shell variable to fill in
1366 mingw_read_file_strip_cr_ () {
1367         # Read line-wise using LF as the line separator
1368         # and use IFS to strip CR.
1369         local line
1370         while :
1371         do
1372                 if IFS=$'\r' read -r -d $'\n' line
1373                 then
1374                         # good
1375                         line=$line$'\n'
1376                 else
1377                         # we get here at EOF, but also if the last line
1378                         # was not terminated by LF; in the latter case,
1379                         # some text was read
1380                         if test -z "$line"
1381                         then
1382                                 # EOF, really
1383                                 break
1384                         fi
1385                 fi
1386                 eval "$1=\$$1\$line"
1387         done
1388 }
1389
1390 # Like "env FOO=BAR some-program", but run inside a subshell, which means
1391 # it also works for shell functions (though those functions cannot impact
1392 # the environment outside of the test_env invocation).
1393 test_env () {
1394         (
1395                 while test $# -gt 0
1396                 do
1397                         case "$1" in
1398                         *=*)
1399                                 eval "${1%%=*}=\${1#*=}"
1400                                 eval "export ${1%%=*}"
1401                                 shift
1402                                 ;;
1403                         *)
1404                                 "$@" 2>&7
1405                                 exit
1406                                 ;;
1407                         esac
1408                 done
1409         )
1410 } 7>&2 2>&4
1411
1412 # Returns true if the numeric exit code in "$2" represents the expected signal
1413 # in "$1". Signals should be given numerically.
1414 test_match_signal () {
1415         if test "$2" = "$((128 + $1))"
1416         then
1417                 # POSIX
1418                 return 0
1419         elif test "$2" = "$((256 + $1))"
1420         then
1421                 # ksh
1422                 return 0
1423         fi
1424         return 1
1425 }
1426
1427 # Read up to "$1" bytes (or to EOF) from stdin and write them to stdout.
1428 test_copy_bytes () {
1429         perl -e '
1430                 my $len = $ARGV[1];
1431                 while ($len > 0) {
1432                         my $s;
1433                         my $nread = sysread(STDIN, $s, $len);
1434                         die "cannot read: $!" unless defined($nread);
1435                         last unless $nread;
1436                         print $s;
1437                         $len -= $nread;
1438                 }
1439         ' - "$1"
1440 }
1441
1442 # run "$@" inside a non-git directory
1443 nongit () {
1444         test -d non-repo ||
1445         mkdir non-repo ||
1446         return 1
1447
1448         (
1449                 GIT_CEILING_DIRECTORIES=$(pwd) &&
1450                 export GIT_CEILING_DIRECTORIES &&
1451                 cd non-repo &&
1452                 "$@" 2>&7
1453         )
1454 } 7>&2 2>&4
1455
1456 # convert function arguments or stdin (if not arguments given) to pktline
1457 # representation. If multiple arguments are given, they are separated by
1458 # whitespace and put in a single packet. Note that data containing NULs must be
1459 # given on stdin, and that empty input becomes an empty packet, not a flush
1460 # packet (for that you can just print 0000 yourself).
1461 packetize () {
1462         if test $# -gt 0
1463         then
1464                 packet="$*"
1465                 printf '%04x%s' "$((4 + ${#packet}))" "$packet"
1466         else
1467                 perl -e '
1468                         my $packet = do { local $/; <STDIN> };
1469                         printf "%04x%s", 4 + length($packet), $packet;
1470                 '
1471         fi
1472 }
1473
1474 # Parse the input as a series of pktlines, writing the result to stdout.
1475 # Sideband markers are removed automatically, and the output is routed to
1476 # stderr if appropriate.
1477 #
1478 # NUL bytes are converted to "\\0" for ease of parsing with text tools.
1479 depacketize () {
1480         perl -e '
1481                 while (read(STDIN, $len, 4) == 4) {
1482                         if ($len eq "0000") {
1483                                 print "FLUSH\n";
1484                         } else {
1485                                 read(STDIN, $buf, hex($len) - 4);
1486                                 $buf =~ s/\0/\\0/g;
1487                                 if ($buf =~ s/^[\x2\x3]//) {
1488                                         print STDERR $buf;
1489                                 } else {
1490                                         $buf =~ s/^\x1//;
1491                                         print $buf;
1492                                 }
1493                         }
1494                 }
1495         '
1496 }
1497
1498 # Converts base-16 data into base-8. The output is given as a sequence of
1499 # escaped octals, suitable for consumption by 'printf'.
1500 hex2oct () {
1501         perl -ne 'printf "\\%03o", hex for /../g'
1502 }
1503
1504 # Set the hash algorithm in use to $1.  Only useful when testing the testsuite.
1505 test_set_hash () {
1506         test_hash_algo="$1"
1507 }
1508
1509 # Detect the hash algorithm in use.
1510 test_detect_hash () {
1511         test_hash_algo="${GIT_TEST_DEFAULT_HASH:-sha1}"
1512 }
1513
1514 # Load common hash metadata and common placeholder object IDs for use with
1515 # test_oid.
1516 test_oid_init () {
1517         test -n "$test_hash_algo" || test_detect_hash &&
1518         test_oid_cache <"$TEST_DIRECTORY/oid-info/hash-info" &&
1519         test_oid_cache <"$TEST_DIRECTORY/oid-info/oid"
1520 }
1521
1522 # Load key-value pairs from stdin suitable for use with test_oid.  Blank lines
1523 # and lines starting with "#" are ignored.  Keys must be shell identifier
1524 # characters.
1525 #
1526 # Examples:
1527 # rawsz sha1:20
1528 # rawsz sha256:32
1529 test_oid_cache () {
1530         local tag rest k v &&
1531
1532         { test -n "$test_hash_algo" || test_detect_hash; } &&
1533         while read tag rest
1534         do
1535                 case $tag in
1536                 \#*)
1537                         continue;;
1538                 ?*)
1539                         # non-empty
1540                         ;;
1541                 *)
1542                         # blank line
1543                         continue;;
1544                 esac &&
1545
1546                 k="${rest%:*}" &&
1547                 v="${rest#*:}" &&
1548
1549                 if ! expr "$k" : '[a-z0-9][a-z0-9]*$' >/dev/null
1550                 then
1551                         BUG 'bad hash algorithm'
1552                 fi &&
1553                 eval "test_oid_${k}_$tag=\"\$v\""
1554         done
1555 }
1556
1557 # Look up a per-hash value based on a key ($1).  The value must have been loaded
1558 # by test_oid_init or test_oid_cache.
1559 test_oid () {
1560         local algo="${test_hash_algo}" &&
1561
1562         case "$1" in
1563         --hash=*)
1564                 algo="${1#--hash=}" &&
1565                 shift;;
1566         *)
1567                 ;;
1568         esac &&
1569
1570         local var="test_oid_${algo}_$1" &&
1571
1572         # If the variable is unset, we must be missing an entry for this
1573         # key-hash pair, so exit with an error.
1574         if eval "test -z \"\${$var+set}\""
1575         then
1576                 BUG "undefined key '$1'"
1577         fi &&
1578         eval "printf '%s' \"\${$var}\""
1579 }
1580
1581 # Insert a slash into an object ID so it can be used to reference a location
1582 # under ".git/objects".  For example, "deadbeef..." becomes "de/adbeef..".
1583 test_oid_to_path () {
1584         local basename=${1#??}
1585         echo "${1%$basename}/$basename"
1586 }
1587
1588 # Choose a port number based on the test script's number and store it in
1589 # the given variable name, unless that variable already contains a number.
1590 test_set_port () {
1591         local var=$1 port
1592
1593         if test $# -ne 1 || test -z "$var"
1594         then
1595                 BUG "test_set_port requires a variable name"
1596         fi
1597
1598         eval port=\$$var
1599         case "$port" in
1600         "")
1601                 # No port is set in the given env var, use the test
1602                 # number as port number instead.
1603                 # Remove not only the leading 't', but all leading zeros
1604                 # as well, so the arithmetic below won't (mis)interpret
1605                 # a test number like '0123' as an octal value.
1606                 port=${this_test#${this_test%%[1-9]*}}
1607                 if test "${port:-0}" -lt 1024
1608                 then
1609                         # root-only port, use a larger one instead.
1610                         port=$(($port + 10000))
1611                 fi
1612                 ;;
1613         *[!0-9]*|0*)
1614                 error >&7 "invalid port number: $port"
1615                 ;;
1616         *)
1617                 # The user has specified the port.
1618                 ;;
1619         esac
1620
1621         # Make sure that parallel '--stress' test jobs get different
1622         # ports.
1623         port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0}))
1624         eval $var=$port
1625 }
1626
1627 # Tests for the hidden file attribute on Windows
1628 test_path_is_hidden () {
1629         test_have_prereq MINGW ||
1630         BUG "test_path_is_hidden can only be used on Windows"
1631
1632         # Use the output of `attrib`, ignore the absolute path
1633         case "$("$SYSTEMROOT"/system32/attrib "$1")" in *H*?:*) return 0;; esac
1634         return 1
1635 }
1636
1637 # Check that the given command was invoked as part of the
1638 # trace2-format trace on stdin.
1639 #
1640 #       test_subcommand [!] <command> <args>... < <trace>
1641 #
1642 # For example, to look for an invocation of "git upload-pack
1643 # /path/to/repo"
1644 #
1645 #       GIT_TRACE2_EVENT=event.log git fetch ... &&
1646 #       test_subcommand git upload-pack "$PATH" <event.log
1647 #
1648 # If the first parameter passed is !, this instead checks that
1649 # the given command was not called.
1650 #
1651 test_subcommand () {
1652         local negate=
1653         if test "$1" = "!"
1654         then
1655                 negate=t
1656                 shift
1657         fi
1658
1659         local expr=$(printf '"%s",' "$@")
1660         expr="${expr%,}"
1661
1662         if test -n "$negate"
1663         then
1664                 ! grep "\[$expr\]"
1665         else
1666                 grep "\[$expr\]"
1667         fi
1668 }
1669
1670 # Check that the given command was invoked as part of the
1671 # trace2-format trace on stdin.
1672 #
1673 #       test_region [!] <category> <label> git <command> <args>...
1674 #
1675 # For example, to look for trace2_region_enter("index", "do_read_index", repo)
1676 # in an invocation of "git checkout HEAD~1", run
1677 #
1678 #       GIT_TRACE2_EVENT="$(pwd)/trace.txt" GIT_TRACE2_EVENT_NESTING=10 \
1679 #               git checkout HEAD~1 &&
1680 #       test_region index do_read_index <trace.txt
1681 #
1682 # If the first parameter passed is !, this instead checks that
1683 # the given region was not entered.
1684 #
1685 test_region () {
1686         local expect_exit=0
1687         if test "$1" = "!"
1688         then
1689                 expect_exit=1
1690                 shift
1691         fi
1692
1693         grep -e '"region_enter".*"category":"'"$1"'","label":"'"$2"\" "$3"
1694         exitcode=$?
1695
1696         if test $exitcode != $expect_exit
1697         then
1698                 return 1
1699         fi
1700
1701         grep -e '"region_leave".*"category":"'"$1"'","label":"'"$2"\" "$3"
1702         exitcode=$?
1703
1704         if test $exitcode != $expect_exit
1705         then
1706                 return 1
1707         fi
1708
1709         return 0
1710 }