t3431: add rebase --fork-point tests
[gitweb.git] / t / test-lib-functions.sh
index 27b81276fc22569249bb5e83dcf4ba95e9823a57..87bf3a2287381be4586eccd94cce35c0a3b3d60f 100644 (file)
@@ -233,6 +233,129 @@ test_merge () {
        git tag "$1"
 }
 
+# Efficiently create <nr> commits, each with a unique number (from 1 to <nr>
+# by default) in the commit message.
+#
+# Usage: test_commit_bulk [options] <nr>
+#   -C <dir>:
+#      Run all git commands in directory <dir>
+#   --ref=<n>:
+#      ref on which to create commits (default: HEAD)
+#   --start=<n>:
+#      number commit messages from <n> (default: 1)
+#   --message=<msg>:
+#      use <msg> as the commit mesasge (default: "commit %s")
+#   --filename=<fn>:
+#      modify <fn> in each commit (default: %s.t)
+#   --contents=<string>:
+#      place <string> in each file (default: "content %s")
+#   --id=<string>:
+#      shorthand to use <string> and %s in message, filename, and contents
+#
+# The message, filename, and contents strings are evaluated by printf, with the
+# first "%s" replaced by the current commit number. So you can do:
+#
+#   test_commit_bulk --filename=file --contents="modification %s"
+#
+# to have every commit touch the same file, but with unique content.
+#
+test_commit_bulk () {
+       tmpfile=.bulk-commit.input
+       indir=.
+       ref=HEAD
+       n=1
+       message='commit %s'
+       filename='%s.t'
+       contents='content %s'
+       while test $# -gt 0
+       do
+               case "$1" in
+               -C)
+                       indir=$2
+                       shift
+                       ;;
+               --ref=*)
+                       ref=${1#--*=}
+                       ;;
+               --start=*)
+                       n=${1#--*=}
+                       ;;
+               --message=*)
+                       message=${1#--*=}
+                       ;;
+               --filename=*)
+                       filename=${1#--*=}
+                       ;;
+               --contents=*)
+                       contents=${1#--*=}
+                       ;;
+               --id=*)
+                       message="${1#--*=} %s"
+                       filename="${1#--*=}-%s.t"
+                       contents="${1#--*=} %s"
+                       ;;
+               -*)
+                       BUG "invalid test_commit_bulk option: $1"
+                       ;;
+               *)
+                       break
+                       ;;
+               esac
+               shift
+       done
+       total=$1
+
+       add_from=
+       if git -C "$indir" rev-parse --verify "$ref"
+       then
+               add_from=t
+       fi
+
+       while test "$total" -gt 0
+       do
+               test_tick &&
+               echo "commit $ref"
+               printf 'author %s <%s> %s\n' \
+                       "$GIT_AUTHOR_NAME" \
+                       "$GIT_AUTHOR_EMAIL" \
+                       "$GIT_AUTHOR_DATE"
+               printf 'committer %s <%s> %s\n' \
+                       "$GIT_COMMITTER_NAME" \
+                       "$GIT_COMMITTER_EMAIL" \
+                       "$GIT_COMMITTER_DATE"
+               echo "data <<EOF"
+               printf "$message\n" $n
+               echo "EOF"
+               if test -n "$add_from"
+               then
+                       echo "from $ref^0"
+                       add_from=
+               fi
+               printf "M 644 inline $filename\n" $n
+               echo "data <<EOF"
+               printf "$contents\n" $n
+               echo "EOF"
+               echo
+               n=$((n + 1))
+               total=$((total - 1))
+       done >"$tmpfile"
+
+       git -C "$indir" \
+           -c fastimport.unpacklimit=0 \
+           fast-import <"$tmpfile" || return 1
+
+       # This will be left in place on failure, which may aid debugging.
+       rm -f "$tmpfile"
+
+       # If we updated HEAD, then be nice and update the index and working
+       # tree, too.
+       if test "$ref" = "HEAD"
+       then
+               git -C "$indir" checkout -f HEAD || return 1
+       fi
+
+}
+
 # This function helps systems where core.filemode=false is set.
 # Use it instead of plain 'chmod +x' to set or unset the executable bit
 # of a file in the working directory and add it to the index.
@@ -457,7 +580,7 @@ test_expect_failure () {
        export test_prereq
        if ! test_skip "$@"
        then
-               say >&3 "checking known breakage: $2"
+               say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2"
                if test_run_ "$2" expecting_failure
                then
                        test_known_broken_ok_ "$1"
@@ -477,7 +600,7 @@ test_expect_success () {
        export test_prereq
        if ! test_skip "$@"
        then
-               say >&3 "expecting success: $2"
+               say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2"
                if test_run_ "$2"
                then
                        test_ok_ "$1"
@@ -1307,6 +1430,13 @@ test_oid () {
        eval "printf '%s' \"\${$var}\""
 }
 
+# Insert a slash into an object ID so it can be used to reference a location
+# under ".git/objects".  For example, "deadbeef..." becomes "de/adbeef..".
+test_oid_to_path () {
+       local basename=${1#??}
+       echo "${1%$basename}/$basename"
+}
+
 # Choose a port number based on the test script's number and store it in
 # the given variable name, unless that variable already contains a number.
 test_set_port () {