[PATCH v3 1/5] Copy test framework from Git
authorMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 10 Jun 2010 06:48:00 +0000 (08:48 +0200)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:37:08 +0000 (09:37 -0800)
c2/ac31fc3eddcb2d79a54da989a0d8173356b70b [new file with mode: 0644]

diff --git a/c2/ac31fc3eddcb2d79a54da989a0d8173356b70b b/c2/ac31fc3eddcb2d79a54da989a0d8173356b70b
new file mode 100644 (file)
index 0000000..df6870d
--- /dev/null
@@ -0,0 +1,1713 @@
+Return-Path: <sojkam1@fel.cvut.cz>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id DA99B431FC1\r
+       for <notmuch@notmuchmail.org>; Wed,  9 Jun 2010 23:49:13 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -1.9\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5\r
+       tests=[BAYES_00=-1.9] autolearn=ham\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id 1tZOu9XUoNtJ for <notmuch@notmuchmail.org>;\r
+       Wed,  9 Jun 2010 23:48:51 -0700 (PDT)\r
+Received: from max.feld.cvut.cz (max.feld.cvut.cz [147.32.192.36])\r
+       by olra.theworths.org (Postfix) with ESMTP id B5C964196F2\r
+       for <notmuch@notmuchmail.org>; Wed,  9 Jun 2010 23:48:35 -0700 (PDT)\r
+Received: from localhost (unknown [192.168.200.4])\r
+       by max.feld.cvut.cz (Postfix) with ESMTP id 1341A19F33E1;\r
+       Thu, 10 Jun 2010 08:48:35 +0200 (CEST)\r
+X-Virus-Scanned: IMAP AMAVIS\r
+Received: from max.feld.cvut.cz ([192.168.200.1])\r
+       by localhost (styx.feld.cvut.cz [192.168.200.4]) (amavisd-new,\r
+       port 10044)\r
+       with ESMTP id yG24X6-oD+hX; Thu, 10 Jun 2010 08:48:31 +0200 (CEST)\r
+Received: from imap.feld.cvut.cz (imap.feld.cvut.cz [147.32.192.34])\r
+       by max.feld.cvut.cz (Postfix) with ESMTP id E111B19F35C9;\r
+       Thu, 10 Jun 2010 08:48:31 +0200 (CEST)\r
+Received: from steelpick.2x.cz (k335-30.felk.cvut.cz [147.32.86.30])\r
+       (Authenticated sender: sojkam1)\r
+       by imap.feld.cvut.cz (Postfix) with ESMTPSA id C374B15C062;\r
+       Thu, 10 Jun 2010 08:48:31 +0200 (CEST)\r
+Received: from wsh by steelpick.2x.cz with local (Exim 4.72)\r
+       (envelope-from <sojkam1@fel.cvut.cz>)\r
+       id 1OMbZ1-0000JU-6J; Thu, 10 Jun 2010 08:48:31 +0200\r
+From: Michal Sojka <sojkam1@fel.cvut.cz>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH v3 1/5] Copy test framework from Git\r
+Date: Thu, 10 Jun 2010 08:48:00 +0200\r
+Message-Id: <1276152484-1164-2-git-send-email-sojkam1@fel.cvut.cz>\r
+X-Mailer: git-send-email 1.7.1.3.g75e44\r
+In-Reply-To: <1276152484-1164-1-git-send-email-sojkam1@fel.cvut.cz>\r
+References: <1276152484-1164-1-git-send-email-sojkam1@fel.cvut.cz>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Thu, 10 Jun 2010 06:49:14 -0000\r
+\r
+Git uses a simple and yet powerful test framework, written in shell.\r
+The framework is easy to use for both users and developers so I think\r
+it would help if it is used in notmuch as well.\r
+\r
+This is a copy of Git's test framework from commit\r
+b6b0afdc30e066788592ca07c9a6c6936c68cc11 in git repository.\r
+\r
+Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>\r
+---\r
+ test/Makefile             |   48 +++\r
+ test/README               |  297 ++++++++++++++++\r
+ test/aggregate-results.sh |   34 ++\r
+ test/t0000-basic.sh       |  389 +++++++++++++++++++++\r
+ test/test-lib.sh          |  832 +++++++++++++++++++++++++++++++++++++++++++++\r
+ 5 files changed, 1600 insertions(+), 0 deletions(-)\r
+ create mode 100644 test/Makefile\r
+ create mode 100644 test/README\r
+ create mode 100755 test/aggregate-results.sh\r
+ create mode 100755 test/t0000-basic.sh\r
+ create mode 100644 test/test-lib.sh\r
+\r
+diff --git a/test/Makefile b/test/Makefile\r
+new file mode 100644\r
+index 0000000..25c559b\r
+--- /dev/null\r
++++ b/test/Makefile\r
+@@ -0,0 +1,48 @@\r
++# Run tests\r
++#\r
++# Copyright (c) 2005 Junio C Hamano\r
++#\r
++\r
++-include ../config.mak\r
++\r
++#GIT_TEST_OPTS=--verbose --debug\r
++SHELL_PATH ?= $(SHELL)\r
++TAR ?= $(TAR)\r
++RM ?= rm -f\r
++\r
++# Shell quote;\r
++SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))\r
++\r
++T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)\r
++TSVN = $(wildcard t91[0-9][0-9]-*.sh)\r
++\r
++all: pre-clean\r
++      $(MAKE) aggregate-results-and-cleanup\r
++\r
++$(T):\r
++      @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)\r
++\r
++pre-clean:\r
++      $(RM) -r test-results\r
++\r
++clean:\r
++      $(RM) -r 'trash directory'.* test-results\r
++      $(RM) t????/cvsroot/CVSROOT/?*\r
++      $(RM) -r valgrind/bin\r
++\r
++aggregate-results-and-cleanup: $(T)\r
++      $(MAKE) aggregate-results\r
++      $(MAKE) clean\r
++\r
++aggregate-results:\r
++      '$(SHELL_PATH_SQ)' ./aggregate-results.sh test-results/t*-*\r
++\r
++# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL\r
++full-svn-test:\r
++      $(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C\r
++      $(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=0 LC_ALL=en_US.UTF-8\r
++\r
++valgrind:\r
++      GIT_TEST_OPTS=--valgrind $(MAKE)\r
++\r
++.PHONY: pre-clean $(T) aggregate-results clean valgrind\r
+diff --git a/test/README b/test/README\r
+new file mode 100644\r
+index 0000000..dcd3ebb\r
+--- /dev/null\r
++++ b/test/README\r
+@@ -0,0 +1,297 @@\r
++Core GIT Tests\r
++==============\r
++\r
++This directory holds many test scripts for core GIT tools.  The\r
++first part of this short document describes how to run the tests\r
++and read their output.\r
++\r
++When fixing the tools or adding enhancements, you are strongly\r
++encouraged to add tests in this directory to cover what you are\r
++trying to fix or enhance.  The later part of this short document\r
++describes how your test scripts should be organized.\r
++\r
++\r
++Running Tests\r
++-------------\r
++\r
++The easiest way to run tests is to say "make".  This runs all\r
++the tests.\r
++\r
++    *** t0000-basic.sh ***\r
++    *   ok 1: .git/objects should be empty after git-init in an empty repo.\r
++    *   ok 2: .git/objects should have 256 subdirectories.\r
++    *   ok 3: git-update-index without --add should fail adding.\r
++    ...\r
++    *   ok 23: no diff after checkout and git-update-index --refresh.\r
++    * passed all 23 test(s)\r
++    *** t0100-environment-names.sh ***\r
++    *   ok 1: using old names should issue warnings.\r
++    *   ok 2: using old names but having new names should not issue warnings.\r
++    ...\r
++\r
++Or you can run each test individually from command line, like\r
++this:\r
++\r
++    $ sh ./t3001-ls-files-killed.sh\r
++    *   ok 1: git-update-index --add to add various paths.\r
++    *   ok 2: git-ls-files -k to show killed files.\r
++    *   ok 3: validate git-ls-files -k output.\r
++    * passed all 3 test(s)\r
++\r
++You can pass --verbose (or -v), --debug (or -d), and --immediate\r
++(or -i) command line argument to the test, or by setting GIT_TEST_OPTS\r
++appropriately before running "make".\r
++\r
++--verbose::\r
++      This makes the test more verbose.  Specifically, the\r
++      command being run and their output if any are also\r
++      output.\r
++\r
++--debug::\r
++      This may help the person who is developing a new test.\r
++      It causes the command defined with test_debug to run.\r
++\r
++--immediate::\r
++      This causes the test to immediately exit upon the first\r
++      failed test.\r
++\r
++--long-tests::\r
++      This causes additional long-running tests to be run (where\r
++      available), for more exhaustive testing.\r
++\r
++--valgrind::\r
++      Execute all Git binaries with valgrind and exit with status\r
++      126 on errors (just like regular tests, this will only stop\r
++      the test script when running under -i).  Valgrind errors\r
++      go to stderr, so you might want to pass the -v option, too.\r
++\r
++      Since it makes no sense to run the tests with --valgrind and\r
++      not see any output, this option implies --verbose.  For\r
++      convenience, it also implies --tee.\r
++\r
++--tee::\r
++      In addition to printing the test output to the terminal,\r
++      write it to files named 't/test-results/$TEST_NAME.out'.\r
++      As the names depend on the tests' file names, it is safe to\r
++      run the tests with this option in parallel.\r
++\r
++--with-dashes::\r
++      By default tests are run without dashed forms of\r
++      commands (like git-commit) in the PATH (it only uses\r
++      wrappers from ../bin-wrappers).  Use this option to include\r
++      the build directory (..) in the PATH, which contains all\r
++      the dashed forms of commands.  This option is currently\r
++      implied by other options like --valgrind and\r
++      GIT_TEST_INSTALLED.\r
++\r
++You can also set the GIT_TEST_INSTALLED environment variable to\r
++the bindir of an existing git installation to test that installation.\r
++You still need to have built this git sandbox, from which various\r
++test-* support programs, templates, and perl libraries are used.\r
++If your installed git is incomplete, it will silently test parts of\r
++your built version instead.\r
++\r
++When using GIT_TEST_INSTALLED, you can also set GIT_TEST_EXEC_PATH to\r
++override the location of the dashed-form subcommands (what\r
++GIT_EXEC_PATH would be used for during normal operation).\r
++GIT_TEST_EXEC_PATH defaults to `$GIT_TEST_INSTALLED/git --exec-path`.\r
++\r
++\r
++Skipping Tests\r
++--------------\r
++\r
++In some environments, certain tests have no way of succeeding\r
++due to platform limitation, such as lack of 'unzip' program, or\r
++filesystem that do not allow arbitrary sequence of non-NUL bytes\r
++as pathnames.\r
++\r
++You should be able to say something like\r
++\r
++    $ GIT_SKIP_TESTS=t9200.8 sh ./t9200-git-cvsexport-commit.sh\r
++\r
++and even:\r
++\r
++    $ GIT_SKIP_TESTS='t[0-4]??? t91?? t9200.8' make\r
++\r
++to omit such tests.  The value of the environment variable is a\r
++SP separated list of patterns that tells which tests to skip,\r
++and either can match the "t[0-9]{4}" part to skip the whole\r
++test, or t[0-9]{4} followed by ".$number" to say which\r
++particular test to skip.\r
++\r
++Note that some tests in the existing test suite rely on previous\r
++test item, so you cannot arbitrarily disable one and expect the\r
++remainder of test to check what the test originally was intended\r
++to check.\r
++\r
++\r
++Naming Tests\r
++------------\r
++\r
++The test files are named as:\r
++\r
++      tNNNN-commandname-details.sh\r
++\r
++where N is a decimal digit.\r
++\r
++First digit tells the family:\r
++\r
++      0 - the absolute basics and global stuff\r
++      1 - the basic commands concerning database\r
++      2 - the basic commands concerning the working tree\r
++      3 - the other basic commands (e.g. ls-files)\r
++      4 - the diff commands\r
++      5 - the pull and exporting commands\r
++      6 - the revision tree commands (even e.g. merge-base)\r
++      7 - the porcelainish commands concerning the working tree\r
++      8 - the porcelainish commands concerning forensics\r
++      9 - the git tools\r
++\r
++Second digit tells the particular command we are testing.\r
++\r
++Third digit (optionally) tells the particular switch or group of switches\r
++we are testing.\r
++\r
++If you create files under t/ directory (i.e. here) that is not\r
++the top-level test script, never name the file to match the above\r
++pattern.  The Makefile here considers all such files as the\r
++top-level test script and tries to run all of them.  A care is\r
++especially needed if you are creating a common test library\r
++file, similar to test-lib.sh, because such a library file may\r
++not be suitable for standalone execution.\r
++\r
++\r
++Writing Tests\r
++-------------\r
++\r
++The test script is written as a shell script.  It should start\r
++with the standard "#!/bin/sh" with copyright notices, and an\r
++assignment to variable 'test_description', like this:\r
++\r
++      #!/bin/sh\r
++      #\r
++      # Copyright (c) 2005 Junio C Hamano\r
++      #\r
++\r
++      test_description='xxx test (option --frotz)\r
++\r
++      This test registers the following structure in the cache\r
++      and tries to run git-ls-files with option --frotz.'\r
++\r
++\r
++Source 'test-lib.sh'\r
++--------------------\r
++\r
++After assigning test_description, the test script should source\r
++test-lib.sh like this:\r
++\r
++      . ./test-lib.sh\r
++\r
++This test harness library does the following things:\r
++\r
++ - If the script is invoked with command line argument --help\r
++   (or -h), it shows the test_description and exits.\r
++\r
++ - Creates an empty test directory with an empty .git/objects\r
++   database and chdir(2) into it.  This directory is 't/trash directory'\r
++   if you must know, but I do not think you care.\r
++\r
++ - Defines standard test helper functions for your scripts to\r
++   use.  These functions are designed to make all scripts behave\r
++   consistently when command line arguments --verbose (or -v),\r
++   --debug (or -d), and --immediate (or -i) is given.\r
++\r
++\r
++End with test_done\r
++------------------\r
++\r
++Your script will be a sequence of tests, using helper functions\r
++from the test harness library.  At the end of the script, call\r
++'test_done'.\r
++\r
++\r
++Test harness library\r
++--------------------\r
++\r
++There are a handful helper functions defined in the test harness\r
++library for your script to use.\r
++\r
++ - test_expect_success <message> <script>\r
++\r
++   This takes two strings as parameter, and evaluates the\r
++   <script>.  If it yields success, test is considered\r
++   successful.  <message> should state what it is testing.\r
++\r
++   Example:\r
++\r
++      test_expect_success \\r
++          'git-write-tree should be able to write an empty tree.' \\r
++          'tree=$(git-write-tree)'\r
++\r
++ - test_expect_failure <message> <script>\r
++\r
++   This is NOT the opposite of test_expect_success, but is used\r
++   to mark a test that demonstrates a known breakage.  Unlike\r
++   the usual test_expect_success tests, which say "ok" on\r
++   success and "FAIL" on failure, this will say "FIXED" on\r
++   success and "still broken" on failure.  Failures from these\r
++   tests won't cause -i (immediate) to stop.\r
++\r
++ - test_debug <script>\r
++\r
++   This takes a single argument, <script>, and evaluates it only\r
++   when the test script is started with --debug command line\r
++   argument.  This is primarily meant for use during the\r
++   development of a new test script.\r
++\r
++ - test_done\r
++\r
++   Your test script must have test_done at the end.  Its purpose\r
++   is to summarize successes and failures in the test script and\r
++   exit with an appropriate error code.\r
++\r
++ - test_tick\r
++\r
++   Make commit and tag names consistent by setting the author and\r
++   committer times to defined stated.  Subsequent calls will\r
++   advance the times by a fixed amount.\r
++\r
++ - test_commit <message> [<filename> [<contents>]]\r
++\r
++   Creates a commit with the given message, committing the given\r
++   file with the given contents (default for both is to reuse the\r
++   message string), and adds a tag (again reusing the message\r
++   string as name).  Calls test_tick to make the SHA-1s\r
++   reproducible.\r
++\r
++ - test_merge <message> <commit-or-tag>\r
++\r
++   Merges the given rev using the given message.  Like test_commit,\r
++   creates a tag and calls test_tick before committing.\r
++\r
++Tips for Writing Tests\r
++----------------------\r
++\r
++As with any programming projects, existing programs are the best\r
++source of the information.  However, do _not_ emulate\r
++t0000-basic.sh when writing your tests.  The test is special in\r
++that it tries to validate the very core of GIT.  For example, it\r
++knows that there will be 256 subdirectories under .git/objects/,\r
++and it knows that the object ID of an empty tree is a certain\r
++40-byte string.  This is deliberately done so in t0000-basic.sh\r
++because the things the very basic core test tries to achieve is\r
++to serve as a basis for people who are changing the GIT internal\r
++drastically.  For these people, after making certain changes,\r
++not seeing failures from the basic test _is_ a failure.  And\r
++such drastic changes to the core GIT that even changes these\r
++otherwise supposedly stable object IDs should be accompanied by\r
++an update to t0000-basic.sh.\r
++\r
++However, other tests that simply rely on basic parts of the core\r
++GIT working properly should not have that level of intimate\r
++knowledge of the core GIT internals.  If all the test scripts\r
++hardcoded the object IDs like t0000-basic.sh does, that defeats\r
++the purpose of t0000-basic.sh, which is to isolate that level of\r
++validation in one place.  Your test also ends up needing\r
++updating when such a change to the internal happens, so do _not_\r
++do it and leave the low level of validation to t0000-basic.sh.\r
+diff --git a/test/aggregate-results.sh b/test/aggregate-results.sh\r
+new file mode 100755\r
+index 0000000..d5bab75\r
+--- /dev/null\r
++++ b/test/aggregate-results.sh\r
+@@ -0,0 +1,34 @@\r
++#!/bin/sh\r
++\r
++fixed=0\r
++success=0\r
++failed=0\r
++broken=0\r
++total=0\r
++\r
++for file\r
++do\r
++      while read type value\r
++      do\r
++              case $type in\r
++              '')\r
++                      continue ;;\r
++              fixed)\r
++                      fixed=$(($fixed + $value)) ;;\r
++              success)\r
++                      success=$(($success + $value)) ;;\r
++              failed)\r
++                      failed=$(($failed + $value)) ;;\r
++              broken)\r
++                      broken=$(($broken + $value)) ;;\r
++              total)\r
++                      total=$(($total + $value)) ;;\r
++              esac\r
++      done <"$file"\r
++done\r
++\r
++printf "%-8s%d\n" fixed $fixed\r
++printf "%-8s%d\n" success $success\r
++printf "%-8s%d\n" failed $failed\r
++printf "%-8s%d\n" broken $broken\r
++printf "%-8s%d\n" total $total\r
+diff --git a/test/t0000-basic.sh b/test/t0000-basic.sh\r
+new file mode 100755\r
+index 0000000..3ec9cbe\r
+--- /dev/null\r
++++ b/test/t0000-basic.sh\r
+@@ -0,0 +1,389 @@\r
++#!/bin/sh\r
++#\r
++# Copyright (c) 2005 Junio C Hamano\r
++#\r
++\r
++test_description='Test the very basics part #1.\r
++\r
++The rest of the test suite does not check the basic operation of git\r
++plumbing commands to work very carefully.  Their job is to concentrate\r
++on tricky features that caused bugs in the past to detect regression.\r
++\r
++This test runs very basic features, like registering things in cache,\r
++writing tree, etc.\r
++\r
++Note that this test *deliberately* hard-codes many expected object\r
++IDs.  When object ID computation changes, like in the previous case of\r
++swapping compression and hashing order, the person who is making the\r
++modification *should* take notice and update the test vectors here.\r
++'\r
++\r
++################################################################\r
++# It appears that people try to run tests without building...\r
++\r
++../git >/dev/null\r
++if test $? != 1\r
++then\r
++      echo >&2 'You do not seem to have built git yet.'\r
++      exit 1\r
++fi\r
++\r
++. ./test-lib.sh\r
++\r
++################################################################\r
++# git init has been done in an empty repository.\r
++# make sure it is empty.\r
++\r
++find .git/objects -type f -print >should-be-empty\r
++test_expect_success \\r
++    '.git/objects should be empty after git init in an empty repo.' \\r
++    'cmp -s /dev/null should-be-empty'\r
++\r
++# also it should have 2 subdirectories; no fan-out anymore, pack, and info.\r
++# 3 is counting "objects" itself\r
++find .git/objects -type d -print >full-of-directories\r
++test_expect_success \\r
++    '.git/objects should have 3 subdirectories.' \\r
++    'test $(wc -l < full-of-directories) = 3'\r
++\r
++################################################################\r
++# Test harness\r
++test_expect_success 'success is reported like this' '\r
++    :\r
++'\r
++test_expect_failure 'pretend we have a known breakage' '\r
++    false\r
++'\r
++test_expect_failure 'pretend we have fixed a known breakage' '\r
++    :\r
++'\r
++test_set_prereq HAVEIT\r
++haveit=no\r
++test_expect_success HAVEIT 'test runs if prerequisite is satisfied' '\r
++    test_have_prereq HAVEIT &&\r
++    haveit=yes\r
++'\r
++donthaveit=yes\r
++test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' '\r
++    donthaveit=no\r
++'\r
++if test $haveit$donthaveit != yesyes\r
++then\r
++      say "bug in test framework: prerequisite tags do not work reliably"\r
++      exit 1\r
++fi\r
++\r
++clean=no\r
++test_expect_success 'tests clean up after themselves' '\r
++    test_when_finished clean=yes\r
++'\r
++\r
++cleaner=no\r
++test_expect_code 1 'tests clean up even after a failure' '\r
++    test_when_finished cleaner=yes &&\r
++    (exit 1)\r
++'\r
++\r
++if test $clean$cleaner != yesyes\r
++then\r
++      say "bug in test framework: cleanup commands do not work reliably"\r
++      exit 1\r
++fi\r
++\r
++test_expect_code 2 'failure to clean up causes the test to fail' '\r
++    test_when_finished "(exit 2)"\r
++'\r
++\r
++################################################################\r
++# Basics of the basics\r
++\r
++# updating a new file without --add should fail.\r
++test_expect_success 'git update-index without --add should fail adding.' '\r
++    test_must_fail git update-index should-be-empty\r
++'\r
++\r
++# and with --add it should succeed, even if it is empty (it used to fail).\r
++test_expect_success \\r
++    'git update-index with --add should succeed.' \\r
++    'git update-index --add should-be-empty'\r
++\r
++test_expect_success \\r
++    'writing tree out with git write-tree' \\r
++    'tree=$(git write-tree)'\r
++\r
++# we know the shape and contents of the tree and know the object ID for it.\r
++test_expect_success \\r
++    'validate object ID of a known tree.' \\r
++    'test "$tree" = 7bb943559a305bdd6bdee2cef6e5df2413c3d30a'\r
++\r
++# Removing paths.\r
++rm -f should-be-empty full-of-directories\r
++test_expect_success 'git update-index without --remove should fail removing.' '\r
++    test_must_fail git update-index should-be-empty\r
++'\r
++\r
++test_expect_success \\r
++    'git update-index with --remove should be able to remove.' \\r
++    'git update-index --remove should-be-empty'\r
++\r
++# Empty tree can be written with recent write-tree.\r
++test_expect_success \\r
++    'git write-tree should be able to write an empty tree.' \\r
++    'tree=$(git write-tree)'\r
++\r
++test_expect_success \\r
++    'validate object ID of a known tree.' \\r
++    'test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904'\r
++\r
++# Various types of objects\r
++# Some filesystems do not support symblic links; on such systems\r
++# some expected values are different\r
++mkdir path2 path3 path3/subp3\r
++paths='path0 path2/file2 path3/file3 path3/subp3/file3'\r
++for p in $paths\r
++do\r
++    echo "hello $p" >$p\r
++done\r
++if test_have_prereq SYMLINKS\r
++then\r
++      for p in $paths\r
++      do\r
++              ln -s "hello $p" ${p}sym\r
++      done\r
++      expectfilter=cat\r
++      expectedtree=087704a96baf1c2d1c869a8b084481e121c88b5b\r
++      expectedptree1=21ae8269cacbe57ae09138dcc3a2887f904d02b3\r
++      expectedptree2=3c5e5399f3a333eddecce7a9b9465b63f65f51e2\r
++else\r
++      expectfilter='grep -v sym'\r
++      expectedtree=8e18edf7d7edcf4371a3ac6ae5f07c2641db7c46\r
++      expectedptree1=cfb8591b2f65de8b8cc1020cd7d9e67e7793b325\r
++      expectedptree2=ce580448f0148b985a513b693fdf7d802cacb44f\r
++fi\r
++\r
++test_expect_success \\r
++    'adding various types of objects with git update-index --add.' \\r
++    'find path* ! -type d -print | xargs git update-index --add'\r
++\r
++# Show them and see that matches what we expect.\r
++test_expect_success \\r
++    'showing stage with git ls-files --stage' \\r
++    'git ls-files --stage >current'\r
++\r
++$expectfilter >expected <<\EOF\r
++100644 f87290f8eb2cbbea7857214459a0739927eab154 0     path0\r
++120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0     path0sym\r
++100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0     path2/file2\r
++120000 d8ce161addc5173867a3c3c730924388daedbc38 0     path2/file2sym\r
++100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0     path3/file3\r
++120000 8599103969b43aff7e430efea79ca4636466794f 0     path3/file3sym\r
++100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0     path3/subp3/file3\r
++120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0     path3/subp3/file3sym\r
++EOF\r
++test_expect_success \\r
++    'validate git ls-files output for a known tree.' \\r
++    'test_cmp expected current'\r
++\r
++test_expect_success \\r
++    'writing tree out with git write-tree.' \\r
++    'tree=$(git write-tree)'\r
++test_expect_success \\r
++    'validate object ID for a known tree.' \\r
++    'test "$tree" = "$expectedtree"'\r
++\r
++test_expect_success \\r
++    'showing tree with git ls-tree' \\r
++    'git ls-tree $tree >current'\r
++cat >expected <<\EOF\r
++100644 blob f87290f8eb2cbbea7857214459a0739927eab154  path0\r
++120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01  path0sym\r
++040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe  path2\r
++040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3  path3\r
++EOF\r
++test_expect_success SYMLINKS \\r
++    'git ls-tree output for a known tree.' \\r
++    'test_cmp expected current'\r
++\r
++# This changed in ls-tree pathspec change -- recursive does\r
++# not show tree nodes anymore.\r
++test_expect_success \\r
++    'showing tree with git ls-tree -r' \\r
++    'git ls-tree -r $tree >current'\r
++$expectfilter >expected <<\EOF\r
++100644 blob f87290f8eb2cbbea7857214459a0739927eab154  path0\r
++120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01  path0sym\r
++100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7  path2/file2\r
++120000 blob d8ce161addc5173867a3c3c730924388daedbc38  path2/file2sym\r
++100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376  path3/file3\r
++120000 blob 8599103969b43aff7e430efea79ca4636466794f  path3/file3sym\r
++100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f  path3/subp3/file3\r
++120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c  path3/subp3/file3sym\r
++EOF\r
++test_expect_success \\r
++    'git ls-tree -r output for a known tree.' \\r
++    'test_cmp expected current'\r
++\r
++# But with -r -t we can have both.\r
++test_expect_success \\r
++    'showing tree with git ls-tree -r -t' \\r
++    'git ls-tree -r -t $tree >current'\r
++cat >expected <<\EOF\r
++100644 blob f87290f8eb2cbbea7857214459a0739927eab154  path0\r
++120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01  path0sym\r
++040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe  path2\r
++100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7  path2/file2\r
++120000 blob d8ce161addc5173867a3c3c730924388daedbc38  path2/file2sym\r
++040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3  path3\r
++100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376  path3/file3\r
++120000 blob 8599103969b43aff7e430efea79ca4636466794f  path3/file3sym\r
++040000 tree 3c5e5399f3a333eddecce7a9b9465b63f65f51e2  path3/subp3\r
++100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f  path3/subp3/file3\r
++120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c  path3/subp3/file3sym\r
++EOF\r
++test_expect_success SYMLINKS \\r
++    'git ls-tree -r output for a known tree.' \\r
++    'test_cmp expected current'\r
++\r
++test_expect_success \\r
++    'writing partial tree out with git write-tree --prefix.' \\r
++    'ptree=$(git write-tree --prefix=path3)'\r
++test_expect_success \\r
++    'validate object ID for a known tree.' \\r
++    'test "$ptree" = "$expectedptree1"'\r
++\r
++test_expect_success \\r
++    'writing partial tree out with git write-tree --prefix.' \\r
++    'ptree=$(git write-tree --prefix=path3/subp3)'\r
++test_expect_success \\r
++    'validate object ID for a known tree.' \\r
++    'test "$ptree" = "$expectedptree2"'\r
++\r
++cat >badobjects <<EOF\r
++100644 blob 1000000000000000000000000000000000000000  dir/file1\r
++100644 blob 2000000000000000000000000000000000000000  dir/file2\r
++100644 blob 3000000000000000000000000000000000000000  dir/file3\r
++100644 blob 4000000000000000000000000000000000000000  dir/file4\r
++100644 blob 5000000000000000000000000000000000000000  dir/file5\r
++EOF\r
++\r
++rm .git/index\r
++test_expect_success \\r
++    'put invalid objects into the index.' \\r
++    'git update-index --index-info < badobjects'\r
++\r
++test_expect_success 'writing this tree without --missing-ok.' '\r
++    test_must_fail git write-tree\r
++'\r
++\r
++test_expect_success \\r
++    'writing this tree with --missing-ok.' \\r
++    'git write-tree --missing-ok'\r
++\r
++\r
++################################################################\r
++rm .git/index\r
++test_expect_success \\r
++    'git read-tree followed by write-tree should be idempotent.' \\r
++    'git read-tree $tree &&\r
++     test -f .git/index &&\r
++     newtree=$(git write-tree) &&\r
++     test "$newtree" = "$tree"'\r
++\r
++$expectfilter >expected <<\EOF\r
++:100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M    path0\r
++:120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M    path0sym\r
++:100644 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0000000000000000000000000000000000000000 M    path2/file2\r
++:120000 120000 d8ce161addc5173867a3c3c730924388daedbc38 0000000000000000000000000000000000000000 M    path2/file2sym\r
++:100644 100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0000000000000000000000000000000000000000 M    path3/file3\r
++:120000 120000 8599103969b43aff7e430efea79ca4636466794f 0000000000000000000000000000000000000000 M    path3/file3sym\r
++:100644 100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0000000000000000000000000000000000000000 M    path3/subp3/file3\r
++:120000 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0000000000000000000000000000000000000000 M    path3/subp3/file3sym\r
++EOF\r
++test_expect_success \\r
++    'validate git diff-files output for a know cache/work tree state.' \\r
++    'git diff-files >current && diff >/dev/null -b current expected'\r
++\r
++test_expect_success \\r
++    'git update-index --refresh should succeed.' \\r
++    'git update-index --refresh'\r
++\r
++test_expect_success \\r
++    'no diff after checkout and git update-index --refresh.' \\r
++    'git diff-files >current && cmp -s current /dev/null'\r
++\r
++################################################################\r
++P=$expectedtree\r
++test_expect_success \\r
++    'git commit-tree records the correct tree in a commit.' \\r
++    'commit0=$(echo NO | git commit-tree $P) &&\r
++     tree=$(git show --pretty=raw $commit0 |\r
++       sed -n -e "s/^tree //p" -e "/^author /q") &&\r
++     test "z$tree" = "z$P"'\r
++\r
++test_expect_success \\r
++    'git commit-tree records the correct parent in a commit.' \\r
++    'commit1=$(echo NO | git commit-tree $P -p $commit0) &&\r
++     parent=$(git show --pretty=raw $commit1 |\r
++       sed -n -e "s/^parent //p" -e "/^author /q") &&\r
++     test "z$commit0" = "z$parent"'\r
++\r
++test_expect_success \\r
++    'git commit-tree omits duplicated parent in a commit.' \\r
++    'commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) &&\r
++     parent=$(git show --pretty=raw $commit2 |\r
++       sed -n -e "s/^parent //p" -e "/^author /q" |\r
++       sort -u) &&\r
++     test "z$commit0" = "z$parent" &&\r
++     numparent=$(git show --pretty=raw $commit2 |\r
++       sed -n -e "s/^parent //p" -e "/^author /q" |\r
++       wc -l) &&\r
++     test $numparent = 1'\r
++\r
++test_expect_success 'update-index D/F conflict' '\r
++      mv path0 tmp &&\r
++      mv path2 path0 &&\r
++      mv tmp path2 &&\r
++      git update-index --add --replace path2 path0/file2 &&\r
++      numpath0=$(git ls-files path0 | wc -l) &&\r
++      test $numpath0 = 1\r
++'\r
++\r
++test_expect_success SYMLINKS 'absolute path works as expected' '\r
++      mkdir first &&\r
++      ln -s ../.git first/.git &&\r
++      mkdir second &&\r
++      ln -s ../first second/other &&\r
++      mkdir third &&\r
++      dir="$(cd .git; pwd -P)" &&\r
++      dir2=third/../second/other/.git &&\r
++      test "$dir" = "$(test-path-utils make_absolute_path $dir2)" &&\r
++      file="$dir"/index &&\r
++      test "$file" = "$(test-path-utils make_absolute_path $dir2/index)" &&\r
++      basename=blub &&\r
++      test "$dir/$basename" = "$(cd .git && test-path-utils make_absolute_path "$basename")" &&\r
++      ln -s ../first/file .git/syml &&\r
++      sym="$(cd first; pwd -P)"/file &&\r
++      test "$sym" = "$(test-path-utils make_absolute_path "$dir2/syml")"\r
++'\r
++\r
++test_expect_success 'very long name in the index handled sanely' '\r
++\r
++      a=a && # 1\r
++      a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 16\r
++      a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 256\r
++      a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 4096\r
++      a=${a}q &&\r
++\r
++      >path4 &&\r
++      git update-index --add path4 &&\r
++      (\r
++              git ls-files -s path4 |\r
++              sed -e "s/      .*/     /" |\r
++              tr -d "\012"\r
++              echo "$a"\r
++      ) | git update-index --index-info &&\r
++      len=$(git ls-files "a*" | wc -c) &&\r
++      test $len = 4098\r
++'\r
++\r
++test_done\r
+diff --git a/test/test-lib.sh b/test/test-lib.sh\r
+new file mode 100644\r
+index 0000000..7422bba\r
+--- /dev/null\r
++++ b/test/test-lib.sh\r
+@@ -0,0 +1,832 @@\r
++#!/bin/sh\r
++#\r
++# Copyright (c) 2005 Junio C Hamano\r
++#\r
++# This program is free software: you can redistribute it and/or modify\r
++# it under the terms of the GNU General Public License as published by\r
++# the Free Software Foundation, either version 2 of the License, or\r
++# (at your option) any later version.\r
++#\r
++# This program is distributed in the hope that it will be useful,\r
++# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
++# GNU General Public License for more details.\r
++#\r
++# You should have received a copy of the GNU General Public License\r
++# along with this program.  If not, see http://www.gnu.org/licenses/ .\r
++\r
++# if --tee was passed, write the output not only to the terminal, but\r
++# additionally to the file test-results/$BASENAME.out, too.\r
++case "$GIT_TEST_TEE_STARTED, $* " in\r
++done,*)\r
++      # do not redirect again\r
++      ;;\r
++*' --tee '*|*' --va'*)\r
++      mkdir -p test-results\r
++      BASE=test-results/$(basename "$0" .sh)\r
++      (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;\r
++       echo $? > $BASE.exit) | tee $BASE.out\r
++      test "$(cat $BASE.exit)" = 0\r
++      exit\r
++      ;;\r
++esac\r
++\r
++# Keep the original TERM for say_color\r
++ORIGINAL_TERM=$TERM\r
++\r
++# For repeatability, reset the environment to known value.\r
++LANG=C\r
++LC_ALL=C\r
++PAGER=cat\r
++TZ=UTC\r
++TERM=dumb\r
++export LANG LC_ALL PAGER TERM TZ\r
++EDITOR=:\r
++unset VISUAL\r
++unset GIT_EDITOR\r
++unset AUTHOR_DATE\r
++unset AUTHOR_EMAIL\r
++unset AUTHOR_NAME\r
++unset COMMIT_AUTHOR_EMAIL\r
++unset COMMIT_AUTHOR_NAME\r
++unset EMAIL\r
++unset GIT_ALTERNATE_OBJECT_DIRECTORIES\r
++unset GIT_AUTHOR_DATE\r
++GIT_AUTHOR_EMAIL=author@example.com\r
++GIT_AUTHOR_NAME='A U Thor'\r
++unset GIT_COMMITTER_DATE\r
++GIT_COMMITTER_EMAIL=committer@example.com\r
++GIT_COMMITTER_NAME='C O Mitter'\r
++unset GIT_DIFF_OPTS\r
++unset GIT_DIR\r
++unset GIT_WORK_TREE\r
++unset GIT_EXTERNAL_DIFF\r
++unset GIT_INDEX_FILE\r
++unset GIT_OBJECT_DIRECTORY\r
++unset GIT_CEILING_DIRECTORIES\r
++unset SHA1_FILE_DIRECTORIES\r
++unset SHA1_FILE_DIRECTORY\r
++unset GIT_NOTES_REF\r
++unset GIT_NOTES_DISPLAY_REF\r
++unset GIT_NOTES_REWRITE_REF\r
++unset GIT_NOTES_REWRITE_MODE\r
++GIT_MERGE_VERBOSITY=5\r
++export GIT_MERGE_VERBOSITY\r
++export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME\r
++export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME\r
++export EDITOR\r
++GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}\r
++\r
++# Protect ourselves from common misconfiguration to export\r
++# CDPATH into the environment\r
++unset CDPATH\r
++\r
++unset GREP_OPTIONS\r
++\r
++case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in\r
++      1|2|true)\r
++              echo "* warning: Some tests will not work if GIT_TRACE" \\r
++                      "is set as to trace on STDERR ! *"\r
++              echo "* warning: Please set GIT_TRACE to something" \\r
++                      "other than 1, 2 or true ! *"\r
++              ;;\r
++esac\r
++\r
++# Convenience\r
++#\r
++# A regexp to match 5 and 40 hexdigits\r
++_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\r
++_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"\r
++\r
++# Each test should start with something like this, after copyright notices:\r
++#\r
++# test_description='Description of this test...\r
++# This test checks if command xyzzy does the right thing...\r
++# '\r
++# . ./test-lib.sh\r
++[ "x$ORIGINAL_TERM" != "xdumb" ] && (\r
++              TERM=$ORIGINAL_TERM &&\r
++              export TERM &&\r
++              [ -t 1 ] &&\r
++              tput bold >/dev/null 2>&1 &&\r
++              tput setaf 1 >/dev/null 2>&1 &&\r
++              tput sgr0 >/dev/null 2>&1\r
++      ) &&\r
++      color=t\r
++\r
++while test "$#" -ne 0\r
++do\r
++      case "$1" in\r
++      -d|--d|--de|--deb|--debu|--debug)\r
++              debug=t; shift ;;\r
++      -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)\r
++              immediate=t; shift ;;\r
++      -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)\r
++              GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;;\r
++      -h|--h|--he|--hel|--help)\r
++              help=t; shift ;;\r
++      -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)\r
++              verbose=t; shift ;;\r
++      -q|--q|--qu|--qui|--quie|--quiet)\r
++              quiet=t; shift ;;\r
++      --with-dashes)\r
++              with_dashes=t; shift ;;\r
++      --no-color)\r
++              color=; shift ;;\r
++      --no-python)\r
++              # noop now...\r
++              shift ;;\r
++      --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)\r
++              valgrind=t; verbose=t; shift ;;\r
++      --tee)\r
++              shift ;; # was handled already\r
++      --root=*)\r
++              root=$(expr "z$1" : 'z[^=]*=\(.*\)')\r
++              shift ;;\r
++      *)\r
++              echo "error: unknown test option '$1'" >&2; exit 1 ;;\r
++      esac\r
++done\r
++\r
++if test -n "$color"; then\r
++      say_color () {\r
++              (\r
++              TERM=$ORIGINAL_TERM\r
++              export TERM\r
++              case "$1" in\r
++                      error) tput bold; tput setaf 1;; # bold red\r
++                      skip)  tput bold; tput setaf 2;; # bold green\r
++                      pass)  tput setaf 2;;            # green\r
++                      info)  tput setaf 3;;            # brown\r
++                      *) test -n "$quiet" && return;;\r
++              esac\r
++              shift\r
++              printf "* %s" "$*"\r
++              tput sgr0\r
++              echo\r
++              )\r
++      }\r
++else\r
++      say_color() {\r
++              test -z "$1" && test -n "$quiet" && return\r
++              shift\r
++              echo "* $*"\r
++      }\r
++fi\r
++\r
++error () {\r
++      say_color error "error: $*"\r
++      GIT_EXIT_OK=t\r
++      exit 1\r
++}\r
++\r
++say () {\r
++      say_color info "$*"\r
++}\r
++\r
++test "${test_description}" != "" ||\r
++error "Test script did not set test_description."\r
++\r
++if test "$help" = "t"\r
++then\r
++      echo "$test_description"\r
++      exit 0\r
++fi\r
++\r
++exec 5>&1\r
++if test "$verbose" = "t"\r
++then\r
++      exec 4>&2 3>&1\r
++else\r
++      exec 4>/dev/null 3>/dev/null\r
++fi\r
++\r
++test_failure=0\r
++test_count=0\r
++test_fixed=0\r
++test_broken=0\r
++test_success=0\r
++\r
++die () {\r
++      code=$?\r
++      if test -n "$GIT_EXIT_OK"\r
++      then\r
++              exit $code\r
++      else\r
++              echo >&5 "FATAL: Unexpected exit with code $code"\r
++              exit 1\r
++      fi\r
++}\r
++\r
++GIT_EXIT_OK=\r
++trap 'die' EXIT\r
++\r
++# The semantics of the editor variables are that of invoking\r
++# sh -c "$EDITOR \"$@\"" files ...\r
++#\r
++# If our trash directory contains shell metacharacters, they will be\r
++# interpreted if we just set $EDITOR directly, so do a little dance with\r
++# environment variables to work around this.\r
++#\r
++# In particular, quoting isn't enough, as the path may contain the same quote\r
++# that we're using.\r
++test_set_editor () {\r
++      FAKE_EDITOR="$1"\r
++      export FAKE_EDITOR\r
++      EDITOR='"$FAKE_EDITOR"'\r
++      export EDITOR\r
++}\r
++\r
++test_decode_color () {\r
++      sed     -e 's/.\[1m/<WHITE>/g' \\r
++              -e 's/.\[31m/<RED>/g' \\r
++              -e 's/.\[32m/<GREEN>/g' \\r
++              -e 's/.\[33m/<YELLOW>/g' \\r
++              -e 's/.\[34m/<BLUE>/g' \\r
++              -e 's/.\[35m/<MAGENTA>/g' \\r
++              -e 's/.\[36m/<CYAN>/g' \\r
++              -e 's/.\[m/<RESET>/g'\r
++}\r
++\r
++q_to_nul () {\r
++      perl -pe 'y/Q/\000/'\r
++}\r
++\r
++q_to_cr () {\r
++      tr Q '\015'\r
++}\r
++\r
++append_cr () {\r
++      sed -e 's/$/Q/' | tr Q '\015'\r
++}\r
++\r
++remove_cr () {\r
++      tr '\015' Q | sed -e 's/Q$//'\r
++}\r
++\r
++test_tick () {\r
++      if test -z "${test_tick+set}"\r
++      then\r
++              test_tick=1112911993\r
++      else\r
++              test_tick=$(($test_tick + 60))\r
++      fi\r
++      GIT_COMMITTER_DATE="$test_tick -0700"\r
++      GIT_AUTHOR_DATE="$test_tick -0700"\r
++      export GIT_COMMITTER_DATE GIT_AUTHOR_DATE\r
++}\r
++\r
++# Call test_commit with the arguments "<message> [<file> [<contents>]]"\r
++#\r
++# This will commit a file with the given contents and the given commit\r
++# message.  It will also add a tag with <message> as name.\r
++#\r
++# Both <file> and <contents> default to <message>.\r
++\r
++test_commit () {\r
++      file=${2:-"$1.t"}\r
++      echo "${3-$1}" > "$file" &&\r
++      git add "$file" &&\r
++      test_tick &&\r
++      git commit -m "$1" &&\r
++      git tag "$1"\r
++}\r
++\r
++# Call test_merge with the arguments "<message> <commit>", where <commit>\r
++# can be a tag pointing to the commit-to-merge.\r
++\r
++test_merge () {\r
++      test_tick &&\r
++      git merge -m "$1" "$2" &&\r
++      git tag "$1"\r
++}\r
++\r
++# This function helps systems where core.filemode=false is set.\r
++# Use it instead of plain 'chmod +x' to set or unset the executable bit\r
++# of a file in the working directory and add it to the index.\r
++\r
++test_chmod () {\r
++      chmod "$@" &&\r
++      git update-index --add "--chmod=$@"\r
++}\r
++\r
++# Use test_set_prereq to tell that a particular prerequisite is available.\r
++# The prerequisite can later be checked for in two ways:\r
++#\r
++# - Explicitly using test_have_prereq.\r
++#\r
++# - Implicitly by specifying the prerequisite tag in the calls to\r
++#   test_expect_{success,failure,code}.\r
++#\r
++# The single parameter is the prerequisite tag (a simple word, in all\r
++# capital letters by convention).\r
++\r
++test_set_prereq () {\r
++      satisfied="$satisfied$1 "\r
++}\r
++satisfied=" "\r
++\r
++test_have_prereq () {\r
++      case $satisfied in\r
++      *" $1 "*)\r
++              : yes, have it ;;\r
++      *)\r
++              ! : nope ;;\r
++      esac\r
++}\r
++\r
++# You are not expected to call test_ok_ and test_failure_ directly, use\r
++# the text_expect_* functions instead.\r
++\r
++test_ok_ () {\r
++      test_success=$(($test_success + 1))\r
++      say_color "" "  ok $test_count: $@"\r
++}\r
++\r
++test_failure_ () {\r
++      test_failure=$(($test_failure + 1))\r
++      say_color error "FAIL $test_count: $1"\r
++      shift\r
++      echo "$@" | sed -e 's/^/        /'\r
++      test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }\r
++}\r
++\r
++test_known_broken_ok_ () {\r
++      test_fixed=$(($test_fixed+1))\r
++      say_color "" "  FIXED $test_count: $@"\r
++}\r
++\r
++test_known_broken_failure_ () {\r
++      test_broken=$(($test_broken+1))\r
++      say_color skip "  still broken $test_count: $@"\r
++}\r
++\r
++test_debug () {\r
++      test "$debug" = "" || eval "$1"\r
++}\r
++\r
++test_run_ () {\r
++      test_cleanup=:\r
++      eval >&3 2>&4 "$1"\r
++      eval_ret=$?\r
++      eval >&3 2>&4 "$test_cleanup"\r
++      return 0\r
++}\r
++\r
++test_skip () {\r
++      test_count=$(($test_count+1))\r
++      to_skip=\r
++      for skp in $GIT_SKIP_TESTS\r
++      do\r
++              case $this_test.$test_count in\r
++              $skp)\r
++                      to_skip=t\r
++              esac\r
++      done\r
++      if test -z "$to_skip" && test -n "$prereq" &&\r
++         ! test_have_prereq "$prereq"\r
++      then\r
++              to_skip=t\r
++      fi\r
++      case "$to_skip" in\r
++      t)\r
++              say_color skip >&3 "skipping test: $@"\r
++              say_color skip "skip $test_count: $1"\r
++              : true\r
++              ;;\r
++      *)\r
++              false\r
++              ;;\r
++      esac\r
++}\r
++\r
++test_expect_failure () {\r
++      test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
++      test "$#" = 2 ||\r
++      error "bug in the test script: not 2 or 3 parameters to test-expect-failure"\r
++      if ! test_skip "$@"\r
++      then\r
++              say >&3 "checking known breakage: $2"\r
++              test_run_ "$2"\r
++              if [ "$?" = 0 -a "$eval_ret" = 0 ]\r
++              then\r
++                      test_known_broken_ok_ "$1"\r
++              else\r
++                      test_known_broken_failure_ "$1"\r
++              fi\r
++      fi\r
++      echo >&3 ""\r
++}\r
++\r
++test_expect_success () {\r
++      test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
++      test "$#" = 2 ||\r
++      error "bug in the test script: not 2 or 3 parameters to test-expect-success"\r
++      if ! test_skip "$@"\r
++      then\r
++              say >&3 "expecting success: $2"\r
++              test_run_ "$2"\r
++              if [ "$?" = 0 -a "$eval_ret" = 0 ]\r
++              then\r
++                      test_ok_ "$1"\r
++              else\r
++                      test_failure_ "$@"\r
++              fi\r
++      fi\r
++      echo >&3 ""\r
++}\r
++\r
++test_expect_code () {\r
++      test "$#" = 4 && { prereq=$1; shift; } || prereq=\r
++      test "$#" = 3 ||\r
++      error "bug in the test script: not 3 or 4 parameters to test-expect-code"\r
++      if ! test_skip "$@"\r
++      then\r
++              say >&3 "expecting exit code $1: $3"\r
++              test_run_ "$3"\r
++              if [ "$?" = 0 -a "$eval_ret" = "$1" ]\r
++              then\r
++                      test_ok_ "$2"\r
++              else\r
++                      test_failure_ "$@"\r
++              fi\r
++      fi\r
++      echo >&3 ""\r
++}\r
++\r
++# test_external runs external test scripts that provide continuous\r
++# test output about their progress, and succeeds/fails on\r
++# zero/non-zero exit code.  It outputs the test output on stdout even\r
++# in non-verbose mode, and announces the external script with "* run\r
++# <n>: ..." before running it.  When providing relative paths, keep in\r
++# mind that all scripts run in "trash directory".\r
++# Usage: test_external description command arguments...\r
++# Example: test_external 'Perl API' perl ../path/to/test.pl\r
++test_external () {\r
++      test "$#" = 4 && { prereq=$1; shift; } || prereq=\r
++      test "$#" = 3 ||\r
++      error >&5 "bug in the test script: not 3 or 4 parameters to test_external"\r
++      descr="$1"\r
++      shift\r
++      if ! test_skip "$descr" "$@"\r
++      then\r
++              # Announce the script to reduce confusion about the\r
++              # test output that follows.\r
++              say_color "" " run $test_count: $descr ($*)"\r
++              # Run command; redirect its stderr to &4 as in\r
++              # test_run_, but keep its stdout on our stdout even in\r
++              # non-verbose mode.\r
++              "$@" 2>&4\r
++              if [ "$?" = 0 ]\r
++              then\r
++                      test_ok_ "$descr"\r
++              else\r
++                      test_failure_ "$descr" "$@"\r
++              fi\r
++      fi\r
++}\r
++\r
++# Like test_external, but in addition tests that the command generated\r
++# no output on stderr.\r
++test_external_without_stderr () {\r
++      # The temporary file has no (and must have no) security\r
++      # implications.\r
++      tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi\r
++      stderr="$tmp/git-external-stderr.$$.tmp"\r
++      test_external "$@" 4> "$stderr"\r
++      [ -f "$stderr" ] || error "Internal error: $stderr disappeared."\r
++      descr="no stderr: $1"\r
++      shift\r
++      say >&3 "expecting no stderr from previous command"\r
++      if [ ! -s "$stderr" ]; then\r
++              rm "$stderr"\r
++              test_ok_ "$descr"\r
++      else\r
++              if [ "$verbose" = t ]; then\r
++                      output=`echo; echo Stderr is:; cat "$stderr"`\r
++              else\r
++                      output=\r
++              fi\r
++              # rm first in case test_failure exits.\r
++              rm "$stderr"\r
++              test_failure_ "$descr" "$@" "$output"\r
++      fi\r
++}\r
++\r
++# This is not among top-level (test_expect_success | test_expect_failure)\r
++# but is a prefix that can be used in the test script, like:\r
++#\r
++#     test_expect_success 'complain and die' '\r
++#           do something &&\r
++#           do something else &&\r
++#         test_must_fail git checkout ../outerspace\r
++#     '\r
++#\r
++# Writing this as "! git checkout ../outerspace" is wrong, because\r
++# the failure could be due to a segv.  We want a controlled failure.\r
++\r
++test_must_fail () {\r
++      "$@"\r
++      test $? -gt 0 -a $? -le 129 -o $? -gt 192\r
++}\r
++\r
++# test_cmp is a helper function to compare actual and expected output.\r
++# You can use it like:\r
++#\r
++#     test_expect_success 'foo works' '\r
++#             echo expected >expected &&\r
++#             foo >actual &&\r
++#             test_cmp expected actual\r
++#     '\r
++#\r
++# This could be written as either "cmp" or "diff -u", but:\r
++# - cmp's output is not nearly as easy to read as diff -u\r
++# - not all diff versions understand "-u"\r
++\r
++test_cmp() {\r
++      $GIT_TEST_CMP "$@"\r
++}\r
++\r
++# This function can be used to schedule some commands to be run\r
++# unconditionally at the end of the test to restore sanity:\r
++#\r
++#     test_expect_success 'test core.capslock' '\r
++#             git config core.capslock true &&\r
++#             test_when_finished "git config --unset core.capslock" &&\r
++#             hello world\r
++#     '\r
++#\r
++# That would be roughly equivalent to\r
++#\r
++#     test_expect_success 'test core.capslock' '\r
++#             git config core.capslock true &&\r
++#             hello world\r
++#             git config --unset core.capslock\r
++#     '\r
++#\r
++# except that the greeting and config --unset must both succeed for\r
++# the test to pass.\r
++\r
++test_when_finished () {\r
++      test_cleanup="{ $*\r
++              } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"\r
++}\r
++\r
++# Most tests can use the created repository, but some may need to create more.\r
++# Usage: test_create_repo <directory>\r
++test_create_repo () {\r
++      test "$#" = 1 ||\r
++      error "bug in the test script: not 1 parameter to test-create-repo"\r
++      owd=`pwd`\r
++      repo="$1"\r
++      mkdir -p "$repo"\r
++      cd "$repo" || error "Cannot setup test environment"\r
++      "$GIT_EXEC_PATH/git-init" "--template=$TEST_DIRECTORY/../templates/blt/" >&3 2>&4 ||\r
++      error "cannot run git init -- have you built things yet?"\r
++      mv .git/hooks .git/hooks-disabled\r
++      cd "$owd"\r
++}\r
++\r
++test_done () {\r
++      GIT_EXIT_OK=t\r
++      test_results_dir="$TEST_DIRECTORY/test-results"\r
++      mkdir -p "$test_results_dir"\r
++      test_results_path="$test_results_dir/${0%.sh}-$$"\r
++\r
++      echo "total $test_count" >> $test_results_path\r
++      echo "success $test_success" >> $test_results_path\r
++      echo "fixed $test_fixed" >> $test_results_path\r
++      echo "broken $test_broken" >> $test_results_path\r
++      echo "failed $test_failure" >> $test_results_path\r
++      echo "" >> $test_results_path\r
++\r
++      if test "$test_fixed" != 0\r
++      then\r
++              say_color pass "fixed $test_fixed known breakage(s)"\r
++      fi\r
++      if test "$test_broken" != 0\r
++      then\r
++              say_color error "still have $test_broken known breakage(s)"\r
++              msg="remaining $(($test_count-$test_broken)) test(s)"\r
++      else\r
++              msg="$test_count test(s)"\r
++      fi\r
++      case "$test_failure" in\r
++      0)\r
++              say_color pass "passed all $msg"\r
++\r
++              test -d "$remove_trash" &&\r
++              cd "$(dirname "$remove_trash")" &&\r
++              rm -rf "$(basename "$remove_trash")"\r
++\r
++              exit 0 ;;\r
++\r
++      *)\r
++              say_color error "failed $test_failure among $msg"\r
++              exit 1 ;;\r
++\r
++      esac\r
++}\r
++\r
++# Test the binaries we have just built.  The tests are kept in\r
++# t/ subdirectory and are run in 'trash directory' subdirectory.\r
++TEST_DIRECTORY=$(pwd)\r
++if test -n "$valgrind"\r
++then\r
++      make_symlink () {\r
++              test -h "$2" &&\r
++              test "$1" = "$(readlink "$2")" || {\r
++                      # be super paranoid\r
++                      if mkdir "$2".lock\r
++                      then\r
++                              rm -f "$2" &&\r
++                              ln -s "$1" "$2" &&\r
++                              rm -r "$2".lock\r
++                      else\r
++                              while test -d "$2".lock\r
++                              do\r
++                                      say "Waiting for lock on $2."\r
++                                      sleep 1\r
++                              done\r
++                      fi\r
++              }\r
++      }\r
++\r
++      make_valgrind_symlink () {\r
++              # handle only executables\r
++              test -x "$1" || return\r
++\r
++              base=$(basename "$1")\r
++              symlink_target=$TEST_DIRECTORY/../$base\r
++              # do not override scripts\r
++              if test -x "$symlink_target" &&\r
++                  test ! -d "$symlink_target" &&\r
++                  test "#!" != "$(head -c 2 < "$symlink_target")"\r
++              then\r
++                      symlink_target=../valgrind.sh\r
++              fi\r
++              case "$base" in\r
++              *.sh|*.perl)\r
++                      symlink_target=../unprocessed-script\r
++              esac\r
++              # create the link, or replace it if it is out of date\r
++              make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit\r
++      }\r
++\r
++      # override all git executables in TEST_DIRECTORY/..\r
++      GIT_VALGRIND=$TEST_DIRECTORY/valgrind\r
++      mkdir -p "$GIT_VALGRIND"/bin\r
++      for file in $TEST_DIRECTORY/../git* $TEST_DIRECTORY/../test-*\r
++      do\r
++              make_valgrind_symlink $file\r
++      done\r
++      OLDIFS=$IFS\r
++      IFS=:\r
++      for path in $PATH\r
++      do\r
++              ls "$path"/git-* 2> /dev/null |\r
++              while read file\r
++              do\r
++                      make_valgrind_symlink "$file"\r
++              done\r
++      done\r
++      IFS=$OLDIFS\r
++      PATH=$GIT_VALGRIND/bin:$PATH\r
++      GIT_EXEC_PATH=$GIT_VALGRIND/bin\r
++      export GIT_VALGRIND\r
++elif test -n "$GIT_TEST_INSTALLED" ; then\r
++      GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||\r
++      error "Cannot run git from $GIT_TEST_INSTALLED."\r
++      PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH\r
++      GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}\r
++else # normal case, use ../bin-wrappers only unless $with_dashes:\r
++      git_bin_dir="$TEST_DIRECTORY/../bin-wrappers"\r
++      if ! test -x "$git_bin_dir/git" ; then\r
++              if test -z "$with_dashes" ; then\r
++                      say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"\r
++              fi\r
++              with_dashes=t\r
++      fi\r
++      PATH="$git_bin_dir:$PATH"\r
++      GIT_EXEC_PATH=$TEST_DIRECTORY/..\r
++      if test -n "$with_dashes" ; then\r
++              PATH="$TEST_DIRECTORY/..:$PATH"\r
++      fi\r
++fi\r
++GIT_TEMPLATE_DIR=$(pwd)/../templates/blt\r
++unset GIT_CONFIG\r
++GIT_CONFIG_NOSYSTEM=1\r
++GIT_CONFIG_NOGLOBAL=1\r
++export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL\r
++\r
++. ../GIT-BUILD-OPTIONS\r
++\r
++GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git\r
++export GITPERLLIB\r
++test -d ../templates/blt || {\r
++      error "You haven't built things yet, have you?"\r
++}\r
++\r
++if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON"\r
++then\r
++      GITPYTHONLIB="$(pwd)/../git_remote_helpers/build/lib"\r
++      export GITPYTHONLIB\r
++      test -d ../git_remote_helpers/build || {\r
++              error "You haven't built git_remote_helpers yet, have you?"\r
++      }\r
++fi\r
++\r
++if ! test -x ../test-chmtime; then\r
++      echo >&2 'You need to build test-chmtime:'\r
++      echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'\r
++      exit 1\r
++fi\r
++\r
++# Test repository\r
++test="trash directory.$(basename "$0" .sh)"\r
++test -n "$root" && test="$root/$test"\r
++case "$test" in\r
++/*) TRASH_DIRECTORY="$test" ;;\r
++ *) TRASH_DIRECTORY="$TEST_DIRECTORY/$test" ;;\r
++esac\r
++test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY\r
++rm -fr "$test" || {\r
++      GIT_EXIT_OK=t\r
++      echo >&5 "FATAL: Cannot prepare test area"\r
++      exit 1\r
++}\r
++\r
++test_create_repo "$test"\r
++# Use -P to resolve symlinks in our working directory so that the cwd\r
++# in subprocesses like git equals our $PWD (for pathname comparisons).\r
++cd -P "$test" || exit 1\r
++\r
++this_test=${0##*/}\r
++this_test=${this_test%%-*}\r
++for skp in $GIT_SKIP_TESTS\r
++do\r
++      to_skip=\r
++      for skp in $GIT_SKIP_TESTS\r
++      do\r
++              case "$this_test" in\r
++              $skp)\r
++                      to_skip=t\r
++              esac\r
++      done\r
++      case "$to_skip" in\r
++      t)\r
++              say_color skip >&3 "skipping test $this_test altogether"\r
++              say_color skip "skip all tests in $this_test"\r
++              test_done\r
++      esac\r
++done\r
++\r
++# Provide an implementation of the 'yes' utility\r
++yes () {\r
++      if test $# = 0\r
++      then\r
++              y=y\r
++      else\r
++              y="$*"\r
++      fi\r
++\r
++      while echo "$y"\r
++      do\r
++              :\r
++      done\r
++}\r
++\r
++# Fix some commands on Windows\r
++case $(uname -s) in\r
++*MINGW*)\r
++      # Windows has its own (incompatible) sort and find\r
++      sort () {\r
++              /usr/bin/sort "$@"\r
++      }\r
++      find () {\r
++              /usr/bin/find "$@"\r
++      }\r
++      sum () {\r
++              md5sum "$@"\r
++      }\r
++      # git sees Windows-style pwd\r
++      pwd () {\r
++              builtin pwd -W\r
++      }\r
++      # no POSIX permissions\r
++      # backslashes in pathspec are converted to '/'\r
++      # exec does not inherit the PID\r
++      ;;\r
++*)\r
++      test_set_prereq POSIXPERM\r
++      test_set_prereq BSLASHPSPEC\r
++      test_set_prereq EXECKEEPSPID\r
++      ;;\r
++esac\r
++\r
++test -z "$NO_PERL" && test_set_prereq PERL\r
++test -z "$NO_PYTHON" && test_set_prereq PYTHON\r
++\r
++# test whether the filesystem supports symbolic links\r
++ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS\r
++rm -f y\r
+-- \r
+1.7.1.3.g75e44\r
+\r