Merge branch 'jk/test-commit-bulk'
authorJunio C Hamano <gitster@pobox.com>
Thu, 25 Jul 2019 20:59:24 +0000 (13:59 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 25 Jul 2019 20:59:25 +0000 (13:59 -0700)
A test helper has been introduced to optimize preparation of test
repositories with many simple commits, and a handful of test
scripts have been updated to use it.

* jk/test-commit-bulk:
t6200: use test_commit_bulk
t5703: use test_commit_bulk
t5702: use test_commit_bulk
t3311: use test_commit_bulk
t5310: increase the number of bitmapped commits
test-lib: introduce test_commit_bulk

t/t3311-notes-merge-fanout.sh
t/t5310-pack-bitmaps.sh
t/t5702-protocol-v2.sh
t/t5703-upload-pack-ref-in-want.sh
t/t6200-fmt-merge-msg.sh
t/test-lib-functions.sh
index 93516ef67ce0b6efb0cd111422ac356b40140257..37151a3adc3971b8bc0e83ae1c762aa2bc91001e 100755 (executable)
@@ -114,12 +114,12 @@ cp expect_log_x expect_log_y
 test_expect_success 'Add a few hundred commits w/notes to trigger fanout (x -> y)' '
        git update-ref refs/notes/y refs/notes/x &&
        git config core.notesRef refs/notes/y &&
-       i=5 &&
-       while test $i -lt $num
+       test_commit_bulk --start=6 --id=commit $((num - 5)) &&
+       i=0 &&
+       while test $i -lt $((num - 5))
        do
-               i=$(($i + 1)) &&
-               test_commit "commit$i" >/dev/null &&
-               git notes add -m "notes for commit$i" || return 1
+               git notes add -m "notes for commit$i" HEAD~$i || return 1
+               i=$((i + 1))
        done &&
        test "$(git rev-parse refs/notes/y)" != "$(git rev-parse refs/notes/x)" &&
        # Expected number of commits and notes
index a26c8ba9a2b1b815e1917f703cb3520a7608d624..6640329ebf609c5054a6f97919005855790571a6 100755 (executable)
@@ -21,15 +21,9 @@ has_any () {
 }
 
 test_expect_success 'setup repo with moderate-sized history' '
-       for i in $(test_seq 1 10)
-       do
-               test_commit $i
-       done &&
+       test_commit_bulk --id=file 100 &&
        git checkout -b other HEAD~5 &&
-       for i in $(test_seq 1 10)
-       do
-               test_commit side-$i
-       done &&
+       test_commit_bulk --id=side 10 &&
        git checkout master &&
        bitmaptip=$(git rev-parse master) &&
        blob=$(echo tagged-blob | git hash-object -w --stdin) &&
@@ -106,10 +100,7 @@ test_expect_success 'clone from bitmapped repository' '
 '
 
 test_expect_success 'setup further non-bitmapped commits' '
-       for i in $(test_seq 1 10)
-       do
-               test_commit further-$i
-       done
+       test_commit_bulk --id=further 10
 '
 
 rev_list_tests 'partial bitmap'
index 5b33f625dddeccce7ecd68b45f115a46f7fbe93a..011b81d4fc27805c90f5371632c3844011f707af 100755 (executable)
@@ -499,10 +499,7 @@ test_expect_success 'upload-pack respects client shallows' '
 
        # Add extra commits to the client so that the whole fetch takes more
        # than 1 request (due to negotiation)
-       for i in $(test_seq 1 32)
-       do
-               test_commit -C client c$i
-       done &&
+       test_commit_bulk -C client --id=c 32 &&
 
        git -C server checkout -b newbranch base &&
        test_commit -C server client_wants &&
@@ -711,10 +708,7 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
        # Create many commits to extend the negotiation phase across multiple
        # requests, so that the server does not send "ready" in the first
        # request.
-       for i in $(test_seq 1 32)
-       do
-               test_commit -C http_child c$i
-       done &&
+       test_commit_bulk -C http_child --id=c 32 &&
 
        # After the acknowledgments section, pretend that a DELIM
        # (0001) was sent instead of a FLUSH (0000).
index 0951d1bbdc26d998cdca7ed491eca557d53b2ddf..de4b6106ef4a7cafc5af5a4cf886b7009fa9d517 100755 (executable)
@@ -176,7 +176,7 @@ test_expect_success 'setup repos for change-while-negotiating test' '
                git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
                cd "$LOCAL_PRISTINE" &&
                git checkout -b side &&
-               for i in $(test_seq 1 33); do test_commit s$i; done &&
+               test_commit_bulk --id=s 33 &&
 
                # Add novel commits to upstream
                git checkout master &&
@@ -287,7 +287,7 @@ test_expect_success 'setup repos for fetching with ref-in-want tests' '
                git clone "file://$REPO" "$LOCAL_PRISTINE" &&
                cd "$LOCAL_PRISTINE" &&
                git checkout -b side &&
-               for i in $(test_seq 1 33); do test_commit s$i; done &&
+               test_commit_bulk --id=s 33 &&
 
                # Add novel commits to upstream
                git checkout master &&
index 93f23cfa8279ccc093ca332b1eb718c515dd41aa..8a72b4c43a4ff5ba2e2aeb99121ba8ba054dc396 100755 (executable)
@@ -66,12 +66,7 @@ test_expect_success setup '
        git commit -a -m "Right #5" &&
 
        git checkout -b long &&
-       i=0 &&
-       while test $i -lt 30
-       do
-               test_commit $i one &&
-               i=$(($i+1))
-       done &&
+       test_commit_bulk --start=0 --message=%s --filename=one 30 &&
 
        git show-branch &&
 
index 27b81276fc22569249bb5e83dcf4ba95e9823a57..d4f199391f1abe839e55d5abab8a9476fbfc1d35 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.