--- /dev/null
+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