diff options
Diffstat (limited to 't')
217 files changed, 7789 insertions, 2584 deletions
diff --git a/t/.gitignore b/t/.gitignore index 7dcbb232c..4e731dc1e 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -1,2 +1,3 @@ /trash directory* /test-results +/.prove diff --git a/t/Makefile b/t/Makefile index f9de24b4d..c7baefb7e 100644 --- a/t/Makefile +++ b/t/Makefile @@ -8,6 +8,7 @@ #GIT_TEST_OPTS=--verbose --debug SHELL_PATH ?= $(SHELL) +PERL_PATH ?= /usr/bin/perl TAR ?= $(TAR) RM ?= rm -f @@ -28,15 +29,15 @@ pre-clean: clean: $(RM) -r 'trash directory'.* test-results - $(RM) t????/cvsroot/CVSROOT/?* $(RM) -r valgrind/bin + $(RM) .prove aggregate-results-and-cleanup: $(T) $(MAKE) aggregate-results $(MAKE) clean aggregate-results: - for f in test-results/t*-*; do \ + for f in test-results/t*-*.counts; do \ echo "$$f"; \ done | '$(SHELL_PATH_SQ)' ./aggregate-results.sh @@ -48,4 +49,42 @@ full-svn-test: valgrind: GIT_TEST_OPTS=--valgrind $(MAKE) -.PHONY: pre-clean $(T) aggregate-results clean valgrind +# Smoke testing targets +-include ../GIT-VERSION-FILE +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo unknown') +uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo unknown') + +test-results: + mkdir -p test-results + +test-results/git-smoke.tar.gz: test-results + $(PERL_PATH) ./harness \ + --archive="test-results/git-smoke.tar.gz" \ + $(T) + +smoke: test-results/git-smoke.tar.gz + +SMOKE_UPLOAD_FLAGS = +ifdef SMOKE_USERNAME + SMOKE_UPLOAD_FLAGS += -F username="$(SMOKE_USERNAME)" -F password="$(SMOKE_PASSWORD)" +endif +ifdef SMOKE_COMMENT + SMOKE_UPLOAD_FLAGS += -F comments="$(SMOKE_COMMENT)" +endif +ifdef SMOKE_TAGS + SMOKE_UPLOAD_FLAGS += -F tags="$(SMOKE_TAGS)" +endif + +smoke_report: smoke + curl \ + -H "Expect: " \ + -F project=Git \ + -F architecture="$(uname_M)" \ + -F platform="$(uname_S)" \ + -F revision="$(GIT_VERSION)" \ + -F report_file=@test-results/git-smoke.tar.gz \ + $(SMOKE_UPLOAD_FLAGS) \ + http://smoke.git.nix.is/app/projects/process_add_report/1 \ + | grep -v ^Redirecting + +.PHONY: pre-clean $(T) aggregate-results clean valgrind smoke smoke_report @@ -18,25 +18,48 @@ The easiest way to run tests is to say "make". This runs all the tests. *** t0000-basic.sh *** - * ok 1: .git/objects should be empty after git-init in an empty repo. - * ok 2: .git/objects should have 256 subdirectories. - * ok 3: git-update-index without --add should fail adding. + ok 1 - .git/objects should be empty after git init in an empty repo. + ok 2 - .git/objects should have 3 subdirectories. + ok 3 - success is reported like this ... - * ok 23: no diff after checkout and git-update-index --refresh. - * passed all 23 test(s) - *** t0100-environment-names.sh *** - * ok 1: using old names should issue warnings. - * ok 2: using old names but having new names should not issue warnings. - ... - -Or you can run each test individually from command line, like -this: - - $ sh ./t3001-ls-files-killed.sh - * ok 1: git-update-index --add to add various paths. - * ok 2: git-ls-files -k to show killed files. - * ok 3: validate git-ls-files -k output. - * passed all 3 test(s) + ok 43 - very long name in the index handled sanely + # fixed 1 known breakage(s) + # still have 1 known breakage(s) + # passed all remaining 42 test(s) + 1..43 + *** t0001-init.sh *** + ok 1 - plain + ok 2 - plain with GIT_WORK_TREE + ok 3 - plain bare + +Since the tests all output TAP (see http://testanything.org) they can +be run with any TAP harness. Here's an example of parallel testing +powered by a recent version of prove(1): + + $ prove --timer --jobs 15 ./t[0-9]*.sh + [19:17:33] ./t0005-signals.sh ................................... ok 36 ms + [19:17:33] ./t0022-crlf-rename.sh ............................... ok 69 ms + [19:17:33] ./t0024-crlf-archive.sh .............................. ok 154 ms + [19:17:33] ./t0004-unwritable.sh ................................ ok 289 ms + [19:17:33] ./t0002-gitfile.sh ................................... ok 480 ms + ===( 102;0 25/? 6/? 5/? 16/? 1/? 4/? 2/? 1/? 3/? 1... )=== + +prove and other harnesses come with a lot of useful options. The +--state option in particular is very useful: + + # Repeat until no more failures + $ prove -j 15 --state=failed,save ./t[0-9]*.sh + +You can also run each test individually from command line, like this: + + $ sh ./t3010-ls-files-killed-modified.sh + ok 1 - git update-index --add to add various paths. + ok 2 - git ls-files -k to show killed files. + ok 3 - validate git ls-files -k output. + ok 4 - git ls-files -m to show modified files. + ok 5 - validate git ls-files -m output. + # passed all 5 test(s) + 1..5 You can pass --verbose (or -v), --debug (or -d), and --immediate (or -i) command line argument to the test, or by setting GIT_TEST_OPTS @@ -198,15 +221,128 @@ This test harness library does the following things: - If the script is invoked with command line argument --help (or -h), it shows the test_description and exits. - - Creates an empty test directory with an empty .git/objects - database and chdir(2) into it. This directory is 't/trash directory' - if you must know, but I do not think you care. + - Creates an empty test directory with an empty .git/objects database + and chdir(2) into it. This directory is 't/trash + directory.$test_name_without_dotsh', with t/ subject to change by + the --root option documented above. - Defines standard test helper functions for your scripts to use. These functions are designed to make all scripts behave consistently when command line arguments --verbose (or -v), --debug (or -d), and --immediate (or -i) is given. +Do's, don'ts & things to keep in mind +------------------------------------- + +Here are a few examples of things you probably should and shouldn't do +when writing tests. + +Do: + + - Put all code inside test_expect_success and other assertions. + + Even code that isn't a test per se, but merely some setup code + should be inside a test assertion. + + - Chain your test assertions + + Write test code like this: + + git merge foo && + git push bar && + test ... + + Instead of: + + git merge hla + git push gh + test ... + + That way all of the commands in your tests will succeed or fail. If + you must ignore the return value of something (e.g., the return + after unsetting a variable that was already unset is unportable) it's + best to indicate so explicitly with a semicolon: + + unset HLAGH; + git merge hla && + git push gh && + test ... + + - Check the test coverage for your tests. See the "Test coverage" + below. + + Don't blindly follow test coverage metrics, they're a good way to + spot if you've missed something. If a new function you added + doesn't have any coverage you're probably doing something wrong, + but having 100% coverage doesn't necessarily mean that you tested + everything. + + Tests that are likely to smoke out future regressions are better + than tests that just inflate the coverage metrics. + +Don't: + + - exit() within a <script> part. + + The harness will catch this as a programming error of the test. + Use test_done instead if you need to stop the tests early (see + "Skipping tests" below). + + - Break the TAP output + + The raw output from your test may be interpreted by a TAP harness. TAP + harnesses will ignore everything they don't know about, but don't step + on their toes in these areas: + + - Don't print lines like "$x..$y" where $x and $y are integers. + + - Don't print lines that begin with "ok" or "not ok". + + TAP harnesses expect a line that begins with either "ok" and "not + ok" to signal a test passed or failed (and our harness already + produces such lines), so your script shouldn't emit such lines to + their output. + + You can glean some further possible issues from the TAP grammar + (see http://search.cpan.org/perldoc?TAP::Parser::Grammar#TAP_Grammar) + but the best indication is to just run the tests with prove(1), + it'll complain if anything is amiss. + +Keep in mind: + + - Inside <script> part, the standard output and standard error + streams are discarded, and the test harness only reports "ok" or + "not ok" to the end user running the tests. Under --verbose, they + are shown to help debugging the tests. + + +Skipping tests +-------------- + +If you need to skip tests you should do so be using the three-arg form +of the test_* functions (see the "Test harness library" section +below), e.g.: + + test_expect_success PERL 'I need Perl' " + '$PERL_PATH' -e 'hlagh() if unf_unf()' + " + +The advantage of skipping tests like this is that platforms that don't +have the PERL and other optional dependencies get an indication of how +many tests they're missing. + +If the test code is too hairy for that (i.e. does a lot of setup work +outside test assertions) you can also skip all remaining tests by +setting skip_all and immediately call test_done: + + if ! test_have_prereq PERL + then + skip_all='skipping perl interface tests, perl not available' + test_done + fi + +The string you give to skip_all will be used as an explanation for why +the test was skipped. End with test_done ------------------ @@ -222,9 +358,9 @@ Test harness library There are a handful helper functions defined in the test harness library for your script to use. - - test_expect_success <message> <script> + - test_expect_success [<prereq>] <message> <script> - This takes two strings as parameter, and evaluates the + Usually takes two strings as parameter, and evaluates the <script>. If it yields success, test is considered successful. <message> should state what it is testing. @@ -234,7 +370,20 @@ library for your script to use. 'git-write-tree should be able to write an empty tree.' \ 'tree=$(git-write-tree)' - - test_expect_failure <message> <script> + If you supply three parameters the first will be taken to be a + prerequisite, see the test_set_prereq and test_have_prereq + documentation below: + + test_expect_success TTY 'git --paginate rev-list uses a pager' \ + ' ... ' + + You can also supply a comma-separated list of prerequisites, in the + rare case where your test depends on more than one: + + test_expect_success PERL,PYTHON 'yo dawg' \ + ' test $(perl -E 'print eval "1 +" . qx[python -c "print 2"]') == "4" ' + + - test_expect_failure [<prereq>] <message> <script> This is NOT the opposite of test_expect_success, but is used to mark a test that demonstrates a known breakage. Unlike @@ -243,6 +392,16 @@ library for your script to use. success and "still broken" on failure. Failures from these tests won't cause -i (immediate) to stop. + Like test_expect_success this function can optionally use a three + argument invocation with a prerequisite as the first argument. + + - test_expect_code [<prereq>] <code> <message> <script> + + Analogous to test_expect_success, but pass the test if it exits + with a given exit <code> + + test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master' + - test_debug <script> This takes a single argument, <script>, and evaluates it only @@ -275,6 +434,134 @@ library for your script to use. Merges the given rev using the given message. Like test_commit, creates a tag and calls test_tick before committing. + - test_set_prereq SOME_PREREQ + + Set a test prerequisite to be used later with test_have_prereq. The + test-lib will set some prerequisites for you, see the + "Prerequisites" section below for a full list of these. + + Others you can set yourself and use later with either + test_have_prereq directly, or the three argument invocation of + test_expect_success and test_expect_failure. + + - test_have_prereq SOME PREREQ + + Check if we have a prerequisite previously set with + test_set_prereq. The most common use of this directly is to skip + all the tests if we don't have some essential prerequisite: + + if ! test_have_prereq PERL + then + skip_all='skipping perl interface tests, perl not available' + test_done + fi + + - test_external [<prereq>] <message> <external> <script> + + Execute a <script> with an <external> interpreter (like perl). This + was added for tests like t9700-perl-git.sh which do most of their + work in an external test script. + + test_external \ + 'GitwebCache::*FileCache*' \ + "$PERL_PATH" "$TEST_DIRECTORY"/t9503/test_cache_interface.pl + + If the test is outputting its own TAP you should set the + test_external_has_tap variable somewhere before calling the first + test_external* function. See t9700-perl-git.sh for an example. + + # The external test will outputs its own plan + test_external_has_tap=1 + + - test_external_without_stderr [<prereq>] <message> <external> <script> + + Like test_external but fail if there's any output on stderr, + instead of checking the exit code. + + test_external_without_stderr \ + 'Perl API' \ + "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl + + - test_must_fail <git-command> + + Run a git command and ensure it fails in a controlled way. Use + this instead of "! <git-command>". When git-command dies due to a + segfault, test_must_fail diagnoses it as an error; "! <git-command>" + treats it as just another expected failure, which would let such a + bug go unnoticed. + + - test_might_fail <git-command> + + Similar to test_must_fail, but tolerate success, too. Use this + instead of "<git-command> || :" to catch failures due to segv. + + - test_cmp <expected> <actual> + + Check whether the content of the <actual> file matches the + <expected> file. This behaves like "cmp" but produces more + helpful output when the test is run with "-v" option. + + - test_path_is_file <file> [<diagnosis>] + test_path_is_dir <dir> [<diagnosis>] + test_path_is_missing <path> [<diagnosis>] + + Check whether a file/directory exists or doesn't. <diagnosis> will + be displayed if the test fails. + + - test_when_finished <script> + + Prepend <script> to a list of commands to run to clean up + at the end of the current test. If some clean-up command + fails, the test will not pass. + + Example: + + test_expect_success 'branch pointing to non-commit' ' + git rev-parse HEAD^{tree} >.git/refs/heads/invalid && + test_when_finished "git update-ref -d refs/heads/invalid" && + ... + ' + +Prerequisites +------------- + +These are the prerequisites that the test library predefines with +test_have_prereq. + +See the prereq argument to the test_* functions in the "Test harness +library" section above and the "test_have_prereq" function for how to +use these, and "test_set_prereq" for how to define your own. + + - PERL & PYTHON + + Git wasn't compiled with NO_PERL=YesPlease or + NO_PYTHON=YesPlease. Wrap any tests that need Perl or Python in + these. + + - POSIXPERM + + The filesystem supports POSIX style permission bits. + + - BSLASHPSPEC + + Backslashes in pathspec are not directory separators. This is not + set on Windows. See 6fd1106a for details. + + - EXECKEEPSPID + + The process retains the same pid across exec(2). See fb9a2bea for + details. + + - SYMLINKS + + The filesystem we're on supports symbolic links. E.g. a FAT + filesystem doesn't support these. See 704a3143 for details. + + - SANITY + + Test is not run by root user, and an attempt to write to an + unwritable file is expected to fail correctly. + Tips for Writing Tests ---------------------- @@ -301,3 +588,115 @@ the purpose of t0000-basic.sh, which is to isolate that level of validation in one place. Your test also ends up needing updating when such a change to the internal happens, so do _not_ do it and leave the low level of validation to t0000-basic.sh. + +Test coverage +------------- + +You can use the coverage tests to find code paths that are not being +used or properly exercised yet. + +To do that, run the coverage target at the top-level (not in the t/ +directory): + + make coverage + +That'll compile Git with GCC's coverage arguments, and generate a test +report with gcov after the tests finish. Running the coverage tests +can take a while, since running the tests in parallel is incompatible +with GCC's coverage mode. + +After the tests have run you can generate a list of untested +functions: + + make coverage-untested-functions + +You can also generate a detailed per-file HTML report using the +Devel::Cover module. To install it do: + + # On Debian or Ubuntu: + sudo aptitude install libdevel-cover-perl + + # From the CPAN with cpanminus + curl -L http://cpanmin.us | perl - --sudo --self-upgrade + cpanm --sudo Devel::Cover + +Then, at the top-level: + + make cover_db_html + +That'll generate a detailed cover report in the "cover_db_html" +directory, which you can then copy to a webserver, or inspect locally +in a browser. + +Smoke testing +------------- + +The Git test suite has support for smoke testing. Smoke testing is +when you submit the results of a test run to a central server for +analysis and aggregation. + +Running a smoke tester is an easy and valuable way of contributing to +Git development, particularly if you have access to an uncommon OS on +obscure hardware. + +After building Git you can generate a smoke report like this in the +"t" directory: + + make clean smoke + +You can also pass arguments via the environment. This should make it +faster: + + GIT_TEST_OPTS='--root=/dev/shm' TEST_JOBS=10 make clean smoke + +The "smoke" target will run the Git test suite with Perl's +"TAP::Harness" module, and package up the results in a .tar.gz archive +with "TAP::Harness::Archive". The former is included with Perl v5.10.1 +or later, but you'll need to install the latter from the CPAN. See the +"Test coverage" section above for how you might do that. + +Once the "smoke" target finishes you'll see a message like this: + + TAP Archive created at <path to git>/t/test-results/git-smoke.tar.gz + +To upload the smoke report you need to have curl(1) installed, then +do: + + make smoke_report + +To upload the report anonymously. Hopefully that'll return something +like "Reported #7 added.". + +If you're going to be uploading reports frequently please request a +user account by E-Mailing gitsmoke@v.nix.is. Once you have a username +and password you'll be able to do: + + SMOKE_USERNAME=<username> SMOKE_PASSWORD=<password> make smoke_report + +You can also add an additional comment to attach to the report, and/or +a comma separated list of tags: + + SMOKE_USERNAME=<username> SMOKE_PASSWORD=<password> \ + SMOKE_COMMENT=<comment> SMOKE_TAGS=<tags> \ + make smoke_report + +Once the report is uploaded it'll be made available at +http://smoke.git.nix.is, here's an overview of Recent Smoke Reports +for Git: + + http://smoke.git.nix.is/app/projects/smoke_reports/1 + +The reports will also be mirrored to GitHub every few hours: + + http://github.com/gitsmoke/smoke-reports + +The Smolder SQLite database is also mirrored and made available for +download: + + http://github.com/gitsmoke/smoke-database + +Note that the database includes hashed (with crypt()) user passwords +and E-Mail addresses. Don't use a valuable password for the smoke +service if you have an account, or an E-Mail address you don't want to +be publicly known. The user accounts are just meant to be convenient +labels, they're not meant to be secure. diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index 396b9653a..141b60cdc 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -8,27 +8,27 @@ check_count () { $PROG file $head >.result || return 1 cat .result | perl -e ' my %expect = (@ARGV); - my %count = (); + my %count = map { $_ => 0 } keys %expect; while (<STDIN>) { if (/^[0-9a-f]+\t\(([^\t]+)\t/) { my $author = $1; for ($author) { s/^\s*//; s/\s*$//; } - if (exists $expect{$author}) { - $count{$author}++; - } + $count{$author}++; } } my $bad = 0; while (my ($author, $count) = each %count) { my $ok; - if ($expect{$author} != $count) { + my $value = 0; + $value = $expect{$author} if defined $expect{$author}; + if ($value != $count) { $bad = 1; $ok = "bad"; } else { $ok = "good"; } - print STDERR "Author $author (expected $expect{$author}, attributed $count) $ok\n"; + print STDERR "Author $author (expected $value, attributed $count) $ok\n"; } exit($bad); ' "$@" diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh index b70b891b6..8c490c870 100644 --- a/t/gitweb-lib.sh +++ b/t/gitweb-lib.sh @@ -19,9 +19,9 @@ our \$site_name = '[localhost]'; our \$site_header = ''; our \$site_footer = ''; our \$home_text = 'indextext.html'; -our @stylesheets = ('file:///$TEST_DIRECTORY/../gitweb/static/gitweb.css'); -our \$logo = 'file:///$TEST_DIRECTORY/../gitweb/static/git-logo.png'; -our \$favicon = 'file:///$TEST_DIRECTORY/../gitweb/static/git-favicon.png'; +our @stylesheets = ('file:///$GIT_BUILD_DIR/gitweb/static/gitweb.css'); +our \$logo = 'file:///$GIT_BUILD_DIR/gitweb/static/git-logo.png'; +our \$favicon = 'file:///$GIT_BUILD_DIR/gitweb/static/git-favicon.png'; our \$projects_list = ''; our \$export_ok = ''; our \$strict_export = ''; @@ -38,7 +38,7 @@ gitweb_run () { GATEWAY_INTERFACE='CGI/1.1' HTTP_ACCEPT='*/*' REQUEST_METHOD='GET' - SCRIPT_NAME="$TEST_DIRECTORY/../gitweb/gitweb.perl" + SCRIPT_NAME="$GIT_BUILD_DIR/gitweb/gitweb.perl" QUERY_STRING=""$1"" PATH_INFO=""$2"" export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD \ @@ -76,13 +76,13 @@ gitweb_run () { . ./test-lib.sh if ! test_have_prereq PERL; then - say 'skipping gitweb tests, perl not available' + skip_all='skipping gitweb tests, perl not available' test_done fi perl -MEncode -e 'decode_utf8("", Encode::FB_CROAK)' >/dev/null 2>&1 || { - say 'skipping gitweb tests, perl version is too old' - test_done + skip_all='skipping gitweb tests, perl version is too old' + test_done } gitweb_init diff --git a/t/harness b/t/harness new file mode 100755 index 000000000..f5c02f49b --- /dev/null +++ b/t/harness @@ -0,0 +1,21 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Getopt::Long (); +use TAP::Harness::Archive; + +Getopt::Long::Parser->new( + config => [ qw/ pass_through / ], +)->getoptions( + 'jobs:1' => \(my $jobs = $ENV{TEST_JOBS}), + 'archive=s' => \my $archive, +) or die "$0: Couldn't getoptions()"; + +TAP::Harness::Archive->new({ + jobs => $jobs, + archive => $archive, + ($ENV{GIT_TEST_OPTS} + ? (test_args => [ split /\s+/, $ENV{GIT_TEST_OPTS} ]) + : ()), + extra_properties => {}, +})->runtests(@ARGV); diff --git a/t/lib-cvs.sh b/t/lib-cvs.sh index 4b3b79373..44263ade2 100644 --- a/t/lib-cvs.sh +++ b/t/lib-cvs.sh @@ -3,13 +3,10 @@ . ./test-lib.sh unset CVS_SERVER -# for clean cvsps cache -HOME=$(pwd) -export HOME if ! type cvs >/dev/null 2>&1 then - say 'skipping cvsimport tests, cvs not found' + skip_all='skipping cvsimport tests, cvs not found' test_done fi @@ -21,15 +18,21 @@ case "$cvsps_version" in 2.1 | 2.2*) ;; '') - say 'skipping cvsimport tests, cvsps not found' + skip_all='skipping cvsimport tests, cvsps not found' test_done ;; *) - say 'skipping cvsimport tests, unsupported cvsps version' + skip_all='skipping cvsimport tests, unsupported cvsps version' test_done ;; esac +setup_cvs_test_repository () { + CVSROOT="$(pwd)/.cvsroot" && + cp -r "$TEST_DIRECTORY/$1/cvsroot" "$CVSROOT" && + export CVSROOT +} + test_cvs_co () { # Usage: test_cvs_co BRANCH_NAME rm -rf module-cvs-"$1" diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index 0f7f35ccc..92d6d3194 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -5,23 +5,22 @@ git_svn_id=git""-svn-id if test -n "$NO_SVN_TESTS" then - say 'skipping git svn tests, NO_SVN_TESTS defined' + skip_all='skipping git svn tests, NO_SVN_TESTS defined' test_done fi if ! test_have_prereq PERL; then - say 'skipping git svn tests, perl not available' + skip_all='skipping git svn tests, perl not available' test_done fi GIT_DIR=$PWD/.git GIT_SVN_DIR=$GIT_DIR/svn/refs/remotes/git-svn SVN_TREE=$GIT_SVN_DIR/svn-tree -PERL=${PERL:-perl} svn >/dev/null 2>&1 if test $? -ne 1 then - say 'skipping git svn tests, svn not found' + skip_all='skipping git svn tests, svn not found' test_done fi @@ -30,7 +29,7 @@ export svnrepo svnconf=$PWD/svnconf export svnconf -$PERL -w -e " +"$PERL_PATH" -w -e " use SVN::Core; use SVN::Repos; \$SVN::Core::VERSION gt '1.1.0' or exit(42); @@ -40,13 +39,12 @@ x=$? if test $x -ne 0 then if test $x -eq 42; then - err='Perl SVN libraries must be >= 1.1.0' + skip_all='Perl SVN libraries must be >= 1.1.0' elif test $x -eq 41; then - err='svnadmin failed to create fsfs repository' + skip_all='svnadmin failed to create fsfs repository' else - err='Perl SVN libraries not found or unusable, skipping test' + skip_all='Perl SVN libraries not found or unusable' fi - say "$err" test_done fi @@ -131,7 +129,7 @@ stop_httpd () { } convert_to_rev_db () { - $PERL -w -- - "$@" <<\EOF + "$PERL_PATH" -w -- - "$@" <<\EOF use strict; @ARGV == 2 or die "Usage: convert_to_rev_db <input> <output>"; open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]"; @@ -159,7 +157,7 @@ EOF require_svnserve () { if test -z "$SVNSERVE_PORT" then - say 'skipping svnserve test. (set $SVNSERVE_PORT to enable)' + skip_all='skipping svnserve test. (set $SVNSERVE_PORT to enable)' test_done fi } diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index da4b8d5a6..e733f6516 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -5,8 +5,7 @@ if test -z "$GIT_TEST_HTTPD" then - say "skipping test, network testing disabled by default" - say "(define GIT_TEST_HTTPD to enable)" + skip_all="Network testing disabled (define GIT_TEST_HTTPD to enable)" test_done fi @@ -46,7 +45,7 @@ HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www if ! test -x "$LIB_HTTPD_PATH" then - say "skipping test, no web server found at '$LIB_HTTPD_PATH'" + skip_all="skipping test, no web server found at '$LIB_HTTPD_PATH'" test_done fi @@ -59,12 +58,12 @@ then then if ! test $HTTPD_VERSION -ge 2 then - say "skipping test, at least Apache version 2 is required" + skip_all="skipping test, at least Apache version 2 is required" test_done fi if ! test -d "$DEFAULT_HTTPD_MODULE_PATH" then - say "Apache module directory not found. Skipping tests." + skip_all="Apache module directory not found. Skipping tests." test_done fi @@ -119,7 +118,7 @@ start_httpd() { >&3 2>&4 if test $? -ne 0 then - say "skipping test, web server setup failed" + skip_all="skipping test, web server setup failed" trap 'die' EXIT test_done fi @@ -146,7 +145,7 @@ test_http_push_nonff() { echo "changed" > path2 && git commit -a -m path2 --amend && - !(git push -v origin >output 2>&1) && + test_must_fail git push -v origin >output 2>&1 && (cd "$REMOTE_REPO" && test $HEAD = $(git rev-parse --verify HEAD)) ' diff --git a/t/lib-pager.sh b/t/lib-pager.sh new file mode 100644 index 000000000..ba03eab14 --- /dev/null +++ b/t/lib-pager.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +test_expect_success 'determine default pager' ' + test_might_fail git config --unset core.pager && + less=$( + unset PAGER GIT_PAGER; + git var GIT_PAGER + ) && + test -n "$less" +' + +if expr "$less" : '[a-z][a-z]*$' >/dev/null +then + test_set_prereq SIMPLEPAGER +fi diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh index ce36f34d0..06c3c9176 100644 --- a/t/lib-patch-mode.sh +++ b/t/lib-patch-mode.sh @@ -2,11 +2,6 @@ . ./test-lib.sh -if ! test_have_prereq PERL; then - say 'skipping --patch tests, perl not available' - test_done -fi - set_state () { echo "$3" > "$1" && git add "$1" && diff --git a/t/lib-prereq-FILEMODE.sh b/t/lib-prereq-FILEMODE.sh new file mode 100644 index 000000000..bce5a4c8b --- /dev/null +++ b/t/lib-prereq-FILEMODE.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# Copyright (c) 2010 Ævar Arnfjörð Bjarmason +# + +if test "$(git config --bool core.filemode)" = false +then + say 'filemode disabled on the filesystem' +else + test_set_prereq FILEMODE +fi diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 6aefe2759..6ccf79709 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -47,6 +47,8 @@ for line in $FAKE_LINES; do case $line in squash|fixup|edit|reword) action="$line";; + exec*) + echo "$line" | sed 's/_/ /g' >> "$1";; "#") echo '# comment' >> "$1";; ">") diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index f2c73369a..f688bd3ef 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -54,9 +54,40 @@ test_expect_success 'success is reported like this' ' test_expect_failure 'pretend we have a known breakage' ' false ' + +test_expect_success 'pretend we have fixed a known breakage (run in sub test-lib)' " + mkdir passing-todo && + (cd passing-todo && + cat >passing-todo.sh <<EOF && +#!$SHELL_PATH + +test_description='A passing TODO test + +This is run in a sub test-lib so that we do not get incorrect passing +metrics +' + +# Point to the t/test-lib.sh, which isn't in ../ as usual +TEST_DIRECTORY=\"$TEST_DIRECTORY\" +. \"\$TEST_DIRECTORY\"/test-lib.sh + test_expect_failure 'pretend we have fixed a known breakage' ' : ' + +test_done +EOF + chmod +x passing-todo.sh && + ./passing-todo.sh >out 2>err && + ! test -s err && +cat >expect <<EOF && +ok 1 - pretend we have fixed a known breakage # TODO known breakage +# fixed 1 known breakage(s) +# passed all 1 test(s) +1..1 +EOF + test_cmp expect out) +" test_set_prereq HAVEIT haveit=no test_expect_success HAVEIT 'test runs if prerequisite is satisfied' ' @@ -73,6 +104,27 @@ then exit 1 fi +test_set_prereq HAVETHIS +haveit=no +test_expect_success HAVETHIS,HAVEIT 'test runs if prerequisites are satisfied' ' + test_have_prereq HAVEIT && + test_have_prereq HAVETHIS && + haveit=yes +' +donthaveit=yes +test_expect_success HAVEIT,DONTHAVEIT 'unmet prerequisites causes test to be skipped' ' + donthaveit=no +' +donthaveiteither=yes +test_expect_success DONTHAVEIT,HAVEIT 'unmet prerequisites causes test to be skipped' ' + donthaveiteither=no +' +if test $haveit$donthaveit$donthaveiteither != yesyesyes +then + say "bug in test framework: multiple prerequisite tags do not work reliably" + exit 1 +fi + clean=no test_expect_success 'tests clean up after themselves' ' test_when_finished clean=yes diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 7c0a698b9..7fe8883ae 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -171,8 +171,6 @@ test_expect_success 'init with init.templatedir set' ' mkdir templatedir-source && echo Content >templatedir-source/file && ( - HOME="`pwd`" && - export HOME && test_config="${HOME}/.gitconfig" && git config -f "$test_config" init.templatedir "${HOME}/templatedir-source" && mkdir templatedir-set && @@ -188,8 +186,6 @@ test_expect_success 'init with init.templatedir set' ' test_expect_success 'init --bare/--shared overrides system/global config' ' ( - HOME="`pwd`" && - export HOME && test_config="$HOME"/.gitconfig && unset GIT_CONFIG_NOGLOBAL && git config -f "$test_config" core.bare false && @@ -205,8 +201,6 @@ test_expect_success 'init --bare/--shared overrides system/global config' ' test_expect_success 'init honors global core.sharedRepository' ' ( - HOME="`pwd`" && - export HOME && test_config="$HOME"/.gitconfig && unset GIT_CONFIG_NOGLOBAL && git config -f "$test_config" core.sharedRepository 0666 && @@ -301,7 +295,7 @@ test_expect_success 'init notices EEXIST (2)' ' ) ' -test_expect_success POSIXPERM 'init notices EPERM' ' +test_expect_success POSIXPERM,SANITY 'init notices EPERM' ' rm -fr newdir && ( mkdir newdir && diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 53bd7fcc4..25205ac0e 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -36,6 +36,9 @@ test_expect_success 'setup' ' echo "d/* test=a/b/d/*" echo "d/yes notest" ) >a/b/.gitattributes + ( + echo "global test=global" + ) >$HOME/global-gitattributes ' @@ -48,15 +51,25 @@ test_expect_success 'attribute test' ' attr_check a/b/g a/b/g && attr_check b/g unspecified && attr_check a/b/h a/b/h && - attr_check a/b/d/g "a/b/d/*" - attr_check onoff unset - attr_check offon set - attr_check no unspecified - attr_check a/b/d/no "a/b/d/*" + attr_check a/b/d/g "a/b/d/*" && + attr_check onoff unset && + attr_check offon set && + attr_check no unspecified && + attr_check a/b/d/no "a/b/d/*" && attr_check a/b/d/yes unspecified ' +test_expect_success 'core.attributesfile' ' + attr_check global unspecified && + git config core.attributesfile "$HOME/global-gitattributes" && + attr_check global global && + git config core.attributesfile "~/global-gitattributes" && + attr_check global global && + echo "global test=precedence" >> .gitattributes && + attr_check global precedence +' + test_expect_success 'attribute test: read paths from stdin' ' cat <<EOF > expect diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh index 2342ac578..e3137d638 100755 --- a/t/t0004-unwritable.sh +++ b/t/t0004-unwritable.sh @@ -15,54 +15,30 @@ test_expect_success setup ' ' -test_expect_success POSIXPERM 'write-tree should notice unwritable repository' ' - - ( - chmod a-w .git/objects .git/objects/?? && - test_must_fail git write-tree - ) - status=$? - chmod 775 .git/objects .git/objects/?? - (exit $status) - +test_expect_success POSIXPERM,SANITY 'write-tree should notice unwritable repository' ' + test_when_finished "chmod 775 .git/objects .git/objects/??" && + chmod a-w .git/objects .git/objects/?? && + test_must_fail git write-tree ' -test_expect_success POSIXPERM 'commit should notice unwritable repository' ' - - ( - chmod a-w .git/objects .git/objects/?? && - test_must_fail git commit -m second - ) - status=$? - chmod 775 .git/objects .git/objects/?? - (exit $status) - +test_expect_success POSIXPERM,SANITY 'commit should notice unwritable repository' ' + test_when_finished "chmod 775 .git/objects .git/objects/??" && + chmod a-w .git/objects .git/objects/?? && + test_must_fail git commit -m second ' -test_expect_success POSIXPERM 'update-index should notice unwritable repository' ' - - ( - echo 6O >file && - chmod a-w .git/objects .git/objects/?? && - test_must_fail git update-index file - ) - status=$? - chmod 775 .git/objects .git/objects/?? - (exit $status) - +test_expect_success POSIXPERM,SANITY 'update-index should notice unwritable repository' ' + test_when_finished "chmod 775 .git/objects .git/objects/??" && + echo 6O >file && + chmod a-w .git/objects .git/objects/?? && + test_must_fail git update-index file ' -test_expect_success POSIXPERM 'add should notice unwritable repository' ' - - ( - echo b >file && - chmod a-w .git/objects .git/objects/?? && - test_must_fail git add file - ) - status=$? - chmod 775 .git/objects .git/objects/?? - (exit $status) - +test_expect_success POSIXPERM,SANITY 'add should notice unwritable repository' ' + test_when_finished "chmod 775 .git/objects .git/objects/??" && + echo b >file && + chmod a-w .git/objects .git/objects/?? && + test_must_fail git add file ' test_done diff --git a/t/t0005-signals.sh b/t/t0005-signals.sh index 09f855af3..93e58c00e 100755 --- a/t/t0005-signals.sh +++ b/t/t0005-signals.sh @@ -13,6 +13,7 @@ test_expect_success 'sigchain works' ' test-sigchain >actual case "$?" in 143) true ;; # POSIX w/ SIGTERM=15 + 271) true ;; # ksh w/ SIGTERM=15 3) true ;; # Windows *) false ;; esac && diff --git a/t/t0006-date.sh b/t/t0006-date.sh index 75b02af86..1d4d0a5c7 100755 --- a/t/t0006-date.sh +++ b/t/t0006-date.sh @@ -28,8 +28,8 @@ check_show 31449600 '12 months ago' check_parse() { echo "$1 -> $2" >expect - test_expect_${3:-success} "parse date ($1)" " - test-date parse '$1' >actual && + test_expect_${4:-success} "parse date ($1${3:+ TZ=$3})" " + TZ=${3:-$TZ} test-date parse '$1' >actual && test_cmp expect actual " } @@ -38,6 +38,8 @@ check_parse 2008 bad check_parse 2008-02 bad check_parse 2008-02-14 bad check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 +0000' +check_parse '2008-02-14 20:30:45 -0500' '2008-02-14 20:30:45 -0500' +check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' EST5 check_approxidate() { echo "$1 -> $2 +0000" >expect diff --git a/t/t0080-vcs-svn.sh b/t/t0080-vcs-svn.sh new file mode 100755 index 000000000..d3225ada6 --- /dev/null +++ b/t/t0080-vcs-svn.sh @@ -0,0 +1,171 @@ +#!/bin/sh + +test_description='check infrastructure for svn importer' + +. ./test-lib.sh +uint32_max=4294967295 + +test_expect_success 'obj pool: store data' ' + cat <<-\EOF >expected && + 0 + 1 + EOF + + test-obj-pool <<-\EOF >actual && + alloc one 16 + set one 13 + test one 13 + reset one + EOF + test_cmp expected actual +' + +test_expect_success 'obj pool: NULL is offset ~0' ' + echo "$uint32_max" >expected && + echo null one | test-obj-pool >actual && + test_cmp expected actual +' + +test_expect_success 'obj pool: out-of-bounds access' ' + cat <<-EOF >expected && + 0 + 0 + $uint32_max + $uint32_max + 16 + 20 + $uint32_max + EOF + + test-obj-pool <<-\EOF >actual && + alloc one 16 + alloc two 16 + offset one 20 + offset two 20 + alloc one 5 + offset one 20 + free one 1 + offset one 20 + reset one + reset two + EOF + test_cmp expected actual +' + +test_expect_success 'obj pool: high-water mark' ' + cat <<-\EOF >expected && + 0 + 0 + 10 + 20 + 20 + 20 + EOF + + test-obj-pool <<-\EOF >actual && + alloc one 10 + committed one + alloc one 10 + commit one + committed one + alloc one 10 + free one 20 + committed one + reset one + EOF + test_cmp expected actual +' + +test_expect_success 'line buffer' ' + echo HELLO >expected1 && + printf "%s\n" "" HELLO >expected2 && + echo >expected3 && + printf "%s\n" "" Q | q_to_nul >expected4 && + printf "%s\n" foo "" >expected5 && + printf "%s\n" "" foo >expected6 && + + test-line-buffer <<-\EOF >actual1 && + 5 + HELLO + EOF + + test-line-buffer <<-\EOF >actual2 && + 0 + + 5 + HELLO + EOF + + q_to_nul <<-\EOF | + 1 + Q + EOF + test-line-buffer >actual3 && + + q_to_nul <<-\EOF | + 0 + + 1 + Q + EOF + test-line-buffer >actual4 && + + test-line-buffer <<-\EOF >actual5 && + 5 + foo + EOF + + test-line-buffer <<-\EOF >actual6 && + 0 + + 5 + foo + EOF + + test_cmp expected1 actual1 && + test_cmp expected2 actual2 && + test_cmp expected3 actual3 && + test_cmp expected4 actual4 && + test_cmp expected5 actual5 && + test_cmp expected6 actual6 +' + +test_expect_success 'string pool' ' + echo a does not equal b >expected.differ && + echo a equals a >expected.match && + echo equals equals equals >expected.matchmore && + + test-string-pool "a,--b" >actual.differ && + test-string-pool "a,a" >actual.match && + test-string-pool "equals-equals" >actual.matchmore && + test_must_fail test-string-pool a,a,a && + test_must_fail test-string-pool a && + + test_cmp expected.differ actual.differ && + test_cmp expected.match actual.match && + test_cmp expected.matchmore actual.matchmore +' + +test_expect_success 'treap sort' ' + cat <<-\EOF >unsorted && + 68 + 12 + 13 + 13 + 68 + 13 + 13 + 21 + 10 + 11 + 12 + 13 + 13 + EOF + sort unsorted >expected && + + test-treap <unsorted >actual && + test_cmp expected actual +' + +test_done diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 6327d205c..93ca84f9e 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -359,7 +359,7 @@ test_expect_success \ test_expect_success \ 'a/b (untracked) vs a, plus c/d case test.' \ - '! git read-tree -u -m "$treeH" "$treeM" && + 'test_must_fail git read-tree -u -m "$treeH" "$treeM" && git ls-files --stage && test -f a/b' @@ -390,4 +390,20 @@ test_expect_success \ git ls-files --stage | tee >treeMcheck.out && test_cmp treeM.out treeMcheck.out' +test_expect_success '-m references the correct modified tree' ' + echo >file-a && + echo >file-b && + git add file-a file-b && + git commit -a -m "test for correct modified tree" + git branch initial-mod && + echo b >file-b && + git commit -a -m "B" && + echo a >file-a && + git add file-a && + git ls-tree $(git write-tree) file-a >expect && + git read-tree -m HEAD initial-mod && + git ls-tree $(git write-tree) file-a >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh index f19b4a2a4..eb8e3d447 100755 --- a/t/t1004-read-tree-m-u-wf.sh +++ b/t/t1004-read-tree-m-u-wf.sh @@ -177,7 +177,7 @@ test_expect_success SYMLINKS 'funny symlink in work tree' ' ' -test_expect_success SYMLINKS 'funny symlink in work tree, un-unlink-able' ' +test_expect_success SYMLINKS,SANITY 'funny symlink in work tree, un-unlink-able' ' rm -fr a b && git reset --hard && diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index 62246dbf9..9a07de1a5 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -1,16 +1,30 @@ #!/bin/sh -test_description='sparse checkout tests' +test_description='sparse checkout tests + +* (tag: removed, master) removed +| D sub/added +* (HEAD, tag: top) modified and added +| M init.t +| A sub/added +* (tag: init) init + A init.t +' . ./test-lib.sh -cat >expected <<EOF -100644 77f0ba1734ed79d12881f81b36ee134de6a3327b 0 init.t -100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 sub/added -EOF test_expect_success 'setup' ' + cat >expected <<-\EOF && + 100644 77f0ba1734ed79d12881f81b36ee134de6a3327b 0 init.t + 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 sub/added + EOF + cat >expected.swt <<-\EOF && + H init.t + H sub/added + EOF + test_commit init && - echo modified >> init.t && + echo modified >>init.t && mkdir sub && touch sub/added && git add init.t sub/added && @@ -20,26 +34,22 @@ test_expect_success 'setup' ' git commit -m removed && git tag removed && git checkout top && - git ls-files --stage > result && + git ls-files --stage >result && test_cmp expected result ' -cat >expected.swt <<EOF -H init.t -H sub/added -EOF test_expect_success 'read-tree without .git/info/sparse-checkout' ' git read-tree -m -u HEAD && - git ls-files --stage > result && + git ls-files --stage >result && test_cmp expected result && - git ls-files -t > result && + git ls-files -t >result && test_cmp expected.swt result ' test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' ' - echo > .git/info/sparse-checkout + echo >.git/info/sparse-checkout git read-tree -m -u HEAD && - git ls-files -t > result && + git ls-files -t >result && test_cmp expected.swt result && test -f init.t && test -f sub/added @@ -47,9 +57,9 @@ test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' ' test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-checkout and enabled' ' git config core.sparsecheckout true && - echo > .git/info/sparse-checkout && + echo >.git/info/sparse-checkout && git read-tree --no-sparse-checkout -m -u HEAD && - git ls-files -t > result && + git ls-files -t >result && test_cmp expected.swt result && test -f init.t && test -f sub/added @@ -57,94 +67,113 @@ test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse- test_expect_success 'read-tree with empty .git/info/sparse-checkout' ' git config core.sparsecheckout true && - echo > .git/info/sparse-checkout && + echo >.git/info/sparse-checkout && test_must_fail git read-tree -m -u HEAD && - git ls-files --stage > result && + git ls-files --stage >result && test_cmp expected result && - git ls-files -t > result && + git ls-files -t >result && test_cmp expected.swt result && test -f init.t && test -f sub/added ' -cat >expected.swt <<EOF -S init.t -H sub/added -EOF test_expect_success 'match directories with trailing slash' ' + cat >expected.swt-noinit <<-\EOF && + S init.t + H sub/added + EOF + echo sub/ > .git/info/sparse-checkout && git read-tree -m -u HEAD && git ls-files -t > result && - test_cmp expected.swt result && + test_cmp expected.swt-noinit result && test ! -f init.t && test -f sub/added ' -cat >expected.swt <<EOF -H init.t -H sub/added -EOF test_expect_failure 'match directories without trailing slash' ' - echo init.t > .git/info/sparse-checkout && - echo sub >> .git/info/sparse-checkout && + echo init.t >.git/info/sparse-checkout && + echo sub >>.git/info/sparse-checkout && git read-tree -m -u HEAD && - git ls-files -t > result && + git ls-files -t >result && test_cmp expected.swt result && test ! -f init.t && test -f sub/added ' -cat >expected.swt <<EOF -H init.t -S sub/added -EOF test_expect_success 'checkout area changes' ' - echo init.t > .git/info/sparse-checkout && + cat >expected.swt-nosub <<-\EOF && + H init.t + S sub/added + EOF + + echo init.t >.git/info/sparse-checkout && git read-tree -m -u HEAD && - git ls-files -t > result && - test_cmp expected.swt result && + git ls-files -t >result && + test_cmp expected.swt-nosub result && test -f init.t && test ! -f sub/added ' test_expect_success 'read-tree updates worktree, absent case' ' - echo sub/added > .git/info/sparse-checkout && + echo sub/added >.git/info/sparse-checkout && git checkout -f top && git read-tree -m -u HEAD^ && test ! -f init.t ' test_expect_success 'read-tree updates worktree, dirty case' ' - echo sub/added > .git/info/sparse-checkout && + echo sub/added >.git/info/sparse-checkout && git checkout -f top && - echo dirty > init.t && + echo dirty >init.t && git read-tree -m -u HEAD^ && grep -q dirty init.t && rm init.t ' test_expect_success 'read-tree removes worktree, dirty case' ' - echo init.t > .git/info/sparse-checkout && + echo init.t >.git/info/sparse-checkout && git checkout -f top && - echo dirty > added && + echo dirty >added && git read-tree -m -u HEAD^ && grep -q dirty added ' test_expect_success 'read-tree adds to worktree, absent case' ' - echo init.t > .git/info/sparse-checkout && + echo init.t >.git/info/sparse-checkout && git checkout -f removed && git read-tree -u -m HEAD^ && test ! -f sub/added ' test_expect_success 'read-tree adds to worktree, dirty case' ' - echo init.t > .git/info/sparse-checkout && + echo init.t >.git/info/sparse-checkout && git checkout -f removed && mkdir sub && - echo dirty > sub/added && + echo dirty >sub/added && git read-tree -u -m HEAD^ && grep -q dirty sub/added ' +test_expect_success 'index removal and worktree narrowing at the same time' ' + >empty && + echo init.t >.git/info/sparse-checkout && + echo sub/added >>.git/info/sparse-checkout && + git checkout -f top && + echo init.t >.git/info/sparse-checkout && + git checkout removed && + git ls-files sub/added >result && + test ! -f sub/added && + test_cmp empty result +' + +test_expect_success 'read-tree --reset removes outside worktree' ' + >empty && + echo init.t >.git/info/sparse-checkout && + git checkout -f top && + git reset --hard removed && + git ls-files sub/added >result && + test_cmp empty result +' + test_done diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh index 210e594f6..a3ac33801 100755 --- a/t/t1020-subdirectory.sh +++ b/t/t1020-subdirectory.sh @@ -16,123 +16,133 @@ test_expect_success setup ' cp one original.one && cp dir/two original.two ' -HERE=`pwd` LF=' ' test_expect_success 'update-index and ls-files' ' - cd "$HERE" && git update-index --add one && case "`git ls-files`" in - one) echo ok one ;; + one) echo pass one ;; *) echo bad one; exit 1 ;; esac && - cd dir && - git update-index --add two && + ( + cd dir && + git update-index --add two && + case "`git ls-files`" in + two) echo pass two ;; + *) echo bad two; exit 1 ;; + esac + ) && case "`git ls-files`" in - two) echo ok two ;; - *) echo bad two; exit 1 ;; - esac && - cd .. && - case "`git ls-files`" in - dir/two"$LF"one) echo ok both ;; + dir/two"$LF"one) echo pass both ;; *) echo bad; exit 1 ;; esac ' test_expect_success 'cat-file' ' - cd "$HERE" && two=`git ls-files -s dir/two` && two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` && echo "$two" && git cat-file -p "$two" >actual && cmp dir/two actual && - cd dir && - git cat-file -p "$two" >actual && - cmp two actual + ( + cd dir && + git cat-file -p "$two" >actual && + cmp two actual + ) ' rm -f actual dir/actual test_expect_success 'diff-files' ' - cd "$HERE" && echo a >>one && echo d >>dir/two && case "`git diff-files --name-only`" in - dir/two"$LF"one) echo ok top ;; + dir/two"$LF"one) echo pass top ;; *) echo bad top; exit 1 ;; esac && # diff should not omit leading paths - cd dir && - case "`git diff-files --name-only`" in - dir/two"$LF"one) echo ok subdir ;; - *) echo bad subdir; exit 1 ;; - esac && - case "`git diff-files --name-only .`" in - dir/two) echo ok subdir limited ;; - *) echo bad subdir limited; exit 1 ;; - esac + ( + cd dir && + case "`git diff-files --name-only`" in + dir/two"$LF"one) echo pass subdir ;; + *) echo bad subdir; exit 1 ;; + esac && + case "`git diff-files --name-only .`" in + dir/two) echo pass subdir limited ;; + *) echo bad subdir limited; exit 1 ;; + esac + ) ' test_expect_success 'write-tree' ' - cd "$HERE" && top=`git write-tree` && echo $top && - cd dir && - sub=`git write-tree` && - echo $sub && - test "z$top" = "z$sub" + ( + cd dir && + sub=`git write-tree` && + echo $sub && + test "z$top" = "z$sub" + ) ' test_expect_success 'checkout-index' ' - cd "$HERE" && git checkout-index -f -u one && cmp one original.one && - cd dir && - git checkout-index -f -u two && - cmp two ../original.two + ( + cd dir && + git checkout-index -f -u two && + cmp two ../original.two + ) ' test_expect_success 'read-tree' ' - cd "$HERE" && rm -f one dir/two && tree=`git write-tree` && git read-tree --reset -u "$tree" && cmp one original.one && cmp dir/two original.two && - cd dir && - rm -f two && - git read-tree --reset -u "$tree" && - cmp two ../original.two && - cmp ../one ../original.one + ( + cd dir && + rm -f two && + git read-tree --reset -u "$tree" && + cmp two ../original.two && + cmp ../one ../original.one + ) ' test_expect_success 'no file/rev ambiguity check inside .git' ' - cd "$HERE" && git commit -a -m 1 && - cd "$HERE"/.git && - git show -s HEAD + ( + cd .git && + git show -s HEAD + ) ' test_expect_success 'no file/rev ambiguity check inside a bare repo' ' - cd "$HERE" && git clone -s --bare .git foo.git && - cd foo.git && GIT_DIR=. git show -s HEAD + ( + cd foo.git && + GIT_DIR=. git show -s HEAD + ) ' # This still does not work as it should... : test_expect_success 'no file/rev ambiguity check inside a bare repo' ' - cd "$HERE" && git clone -s --bare .git foo.git && - cd foo.git && git show -s HEAD + ( + cd foo.git && + git show -s HEAD + ) ' test_expect_success SYMLINKS 'detection should not be fooled by a symlink' ' - cd "$HERE" && rm -fr foo.git && git clone -s .git another && ln -s another yetanother && - cd yetanother/.git && - git show -s HEAD + ( + cd yetanother/.git && + git show -s HEAD + ) ' test_done diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 64f05080b..d0ab8ffe1 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -701,25 +701,47 @@ cat >expect <<\EOF trailingtilde = foo~ EOF -test_expect_success 'set --path' ' +test_expect_success NOT_MINGW 'set --path' ' git config --path path.home "~/" && git config --path path.normal "/dev/null" && git config --path path.trailingtilde "foo~" && test_cmp expect .git/config' +if test_have_prereq NOT_MINGW && test "${HOME+set}" +then + test_set_prereq HOMEVAR +fi + cat >expect <<EOF $HOME/ /dev/null foo~ EOF -test_expect_success 'get --path' ' +test_expect_success HOMEVAR 'get --path' ' git config --get --path path.home > result && git config --get --path path.normal >> result && git config --get --path path.trailingtilde >> result && test_cmp expect result ' +cat >expect <<\EOF +/dev/null +foo~ +EOF + +test_expect_success NOT_MINGW 'get --path copes with unset $HOME' ' + ( + unset HOME; + test_must_fail git config --get --path path.home \ + >result 2>msg && + git config --get --path path.normal >>result && + git config --get --path path.trailingtilde >>result + ) && + grep "[Ff]ailed to expand.*~/" msg && + test_cmp expect result +' + rm .git/config git config quote.leading " test" diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh index 8d305b437..a6bf1bf4d 100755 --- a/t/t1302-repo-version.sh +++ b/t/t1302-repo-version.sh @@ -7,41 +7,64 @@ test_description='Test repository version check' . ./test-lib.sh -cat >test.patch <<EOF -diff --git a/test.txt b/test.txt -new file mode 100644 ---- /dev/null -+++ b/test.txt -@@ -0,0 +1 @@ -+123 -EOF +test_expect_success 'setup' ' + cat >test.patch <<-\EOF && + diff --git a/test.txt b/test.txt + new file mode 100644 + --- /dev/null + +++ b/test.txt + @@ -0,0 +1 @@ + +123 + EOF -test_create_repo "test" -test_create_repo "test2" - -GIT_CONFIG=test2/.git/config git config core.repositoryformatversion 99 || exit 1 + test_create_repo "test" && + test_create_repo "test2" && + GIT_CONFIG=test2/.git/config git config core.repositoryformatversion 99 +' test_expect_success 'gitdir selection on normal repos' ' - (test "$(git config core.repositoryformatversion)" = 0 && - cd test && - test "$(git config core.repositoryformatversion)" = 0)' + echo 0 >expect && + git config core.repositoryformatversion >actual && + ( + cd test && + git config core.repositoryformatversion >../actual2 + ) && + test_cmp expect actual && + test_cmp expect actual2 +' -# Make sure it would stop at test2, not trash test_expect_success 'gitdir selection on unsupported repo' ' - (cd test2 && - test "$(git config core.repositoryformatversion)" = 99)' + # Make sure it would stop at test2, not trash + echo 99 >expect && + ( + cd test2 && + git config core.repositoryformatversion >../actual + ) + test_cmp expect actual +' test_expect_success 'gitdir not required mode' ' - (git apply --stat test.patch && - cd test && git apply --stat ../test.patch && - cd ../test2 && git apply --stat ../test.patch)' - -test_expect_success 'gitdir required mode on normal repos' ' - (git apply --check --index test.patch && - cd test && git apply --check --index ../test.patch)' + git apply --stat test.patch && + ( + cd test && + git apply --stat ../test.patch + ) && + ( + cd test2 && + git apply --stat ../test.patch + ) +' -test_expect_success 'gitdir required mode on unsupported repo' ' - (cd test2 && test_must_fail git apply --check --index ../test.patch) +test_expect_success 'gitdir required mode' ' + git apply --check --index test.patch && + ( + cd test && + git apply --check --index ../test.patch + ) && + ( + cd test2 && + test_must_fail git apply --check --index ../test.patch + ) ' test_done diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh index 055ad00f7..b5d89a225 100755 --- a/t/t1304-default-acl.sh +++ b/t/t1304-default-acl.sh @@ -15,9 +15,14 @@ umask 077 # is a good candidate: exists on all unices, and it has permission # anyway, so we don't create a security hole running the testsuite. -if ! setfacl -m u:root:rwx .; then - say "Skipping ACL tests: unable to use setfacl" - test_done +setfacl_out="$(setfacl -m u:root:rwx . 2>&1)" +setfacl_ret=$? + +if test $setfacl_ret != 0 +then + say "Unable to use setfacl (output: '$setfacl_out'; return code: '$setfacl_ret')" +else + test_set_prereq SETFACL fi check_perms_and_acl () { @@ -31,7 +36,7 @@ check_perms_and_acl () { dirs_to_set="./ .git/ .git/objects/ .git/objects/pack/" -test_expect_success 'Setup test repo' ' +test_expect_success SETFACL 'Setup test repo' ' setfacl -m d:u::rwx,d:g::---,d:o:---,d:m:rwx $dirs_to_set && setfacl -m m:rwx $dirs_to_set && setfacl -m u:root:rwx $dirs_to_set && @@ -43,12 +48,12 @@ test_expect_success 'Setup test repo' ' git commit -m "init" ' -test_expect_success 'Objects creation does not break ACLs with restrictive umask' ' +test_expect_success SETFACL 'Objects creation does not break ACLs with restrictive umask' ' # SHA1 for empty blob check_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 ' -test_expect_success 'git gc does not break ACLs with restrictive umask' ' +test_expect_success SETFACL 'git gc does not break ACLs with restrictive umask' ' git gc && check_perms_and_acl .git/objects/pack/*.pack ' diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh index eb45afb01..782e75d00 100755 --- a/t/t1402-check-ref-format.sh +++ b/t/t1402-check-ref-format.sh @@ -41,6 +41,23 @@ test_expect_success "check-ref-format --branch @{-1}" ' refname2=$(git check-ref-format --branch @{-2}) && test "$refname2" = master' +test_expect_success 'check-ref-format --branch from subdir' ' + mkdir subdir && + + T=$(git write-tree) && + sha1=$(echo A | git commit-tree $T) && + git update-ref refs/heads/master $sha1 && + git update-ref refs/remotes/origin/master $sha1 + git checkout master && + git checkout origin/master && + git checkout master && + refname=$( + cd subdir && + git check-ref-format --branch @{-1} + ) && + test "$refname" = "$sha1" +' + valid_ref_normalized() { test_expect_success "ref name '$1' simplifies to '$2'" " refname=\$(git check-ref-format --print '$1') && diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 759cf12e1..1be415e33 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -1,21 +1,23 @@ #!/bin/sh -test_description='git fsck random collection of tests' +test_description='git fsck random collection of tests + +* (HEAD) B +* (master) A +' . ./test-lib.sh test_expect_success setup ' + git config gc.auto 0 && git config i18n.commitencoding ISO-8859-1 && test_commit A fileA one && git config --unset i18n.commitencoding && git checkout HEAD^0 && test_commit B fileB two && git tag -d A B && - git reflog expire --expire=now --all -' - -test_expect_success 'HEAD is part of refs' ' - test 0 = $(git fsck | wc -l) + git reflog expire --expire=now --all && + >empty ' test_expect_success 'loose objects borrowed from alternate are not missing' ' @@ -25,110 +27,132 @@ test_expect_success 'loose objects borrowed from alternate are not missing' ' git init && echo ../../../.git/objects >.git/objects/info/alternates && test_commit C fileC one && - git fsck >out && - ! grep "missing blob" out - ) + git fsck >../out 2>&1 + ) && + { + grep -v dangling out >actual || + : + } && + test_cmp empty actual ' -test_expect_success 'valid objects appear valid' ' - { git fsck 2>out; true; } && - ! grep error out && - ! grep fatal out +test_expect_success 'HEAD is part of refs, valid objects appear valid' ' + git fsck >actual 2>&1 && + test_cmp empty actual ' # Corruption tests follow. Make sure to remove all traces of the # specific corruption you test afterwards, lest a later test trip over # it. +test_expect_success 'setup: helpers for corruption tests' ' + sha1_file() { + echo "$*" | sed "s#..#.git/objects/&/#" + } && + + remove_object() { + file=$(sha1_file "$*") && + test -e "$file" && + rm -f "$file" + } +' + test_expect_success 'object with bad sha1' ' sha=$(echo blob | git hash-object -w --stdin) && - echo $sha && old=$(echo $sha | sed "s+^..+&/+") && new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff && sha="$(dirname $new)$(basename $new)" mv .git/objects/$old .git/objects/$new && + test_when_finished "remove_object $sha" && git update-index --add --cacheinfo 100644 $sha foo && + test_when_finished "git read-tree -u --reset HEAD" && tree=$(git write-tree) && + test_when_finished "remove_object $tree" && cmt=$(echo bogus | git commit-tree $tree) && + test_when_finished "remove_object $cmt" && git update-ref refs/heads/bogus $cmt && - (git fsck 2>out; true) && - grep "$sha.*corrupt" out && - rm -f .git/objects/$new && - git update-ref -d refs/heads/bogus && - git read-tree -u --reset HEAD + test_when_finished "git update-ref -d refs/heads/bogus" && + + test_might_fail git fsck 2>out && + cat out && + grep "$sha.*corrupt" out ' test_expect_success 'branch pointing to non-commit' ' - git rev-parse HEAD^{tree} > .git/refs/heads/invalid && + git rev-parse HEAD^{tree} >.git/refs/heads/invalid && + test_when_finished "git update-ref -d refs/heads/invalid" && git fsck 2>out && - grep "not a commit" out && - git update-ref -d refs/heads/invalid + cat out && + grep "not a commit" out ' -new=nothing test_expect_success 'email without @ is okay' ' git cat-file commit HEAD >basis && sed "s/@/AT/" basis >okay && new=$(git hash-object -t commit -w --stdin <okay) && - echo "$new" && + test_when_finished "remove_object $new" && git update-ref refs/heads/bogus "$new" && + test_when_finished "git update-ref -d refs/heads/bogus" && git fsck 2>out && cat out && - ! grep "error in commit $new" out + ! grep "commit $new" out ' -git update-ref -d refs/heads/bogus -rm -f ".git/objects/$new" -new=nothing test_expect_success 'email with embedded > is not okay' ' git cat-file commit HEAD >basis && sed "s/@[a-z]/&>/" basis >bad-email && new=$(git hash-object -t commit -w --stdin <bad-email) && - echo "$new" && + test_when_finished "remove_object $new" && git update-ref refs/heads/bogus "$new" && + test_when_finished "git update-ref -d refs/heads/bogus" && git fsck 2>out && cat out && grep "error in commit $new" out ' -git update-ref -d refs/heads/bogus -rm -f ".git/objects/$new" - -cat > invalid-tag <<EOF -object ffffffffffffffffffffffffffffffffffffffff -type commit -tag invalid -tagger T A Gger <tagger@example.com> 1234567890 -0000 - -This is an invalid tag. -EOF test_expect_success 'tag pointing to nonexistent' ' - tag=$(git hash-object -t tag -w --stdin < invalid-tag) && - echo $tag > .git/refs/tags/invalid && + cat >invalid-tag <<-\EOF + object ffffffffffffffffffffffffffffffffffffffff + type commit + tag invalid + tagger T A Gger <tagger@example.com> 1234567890 -0000 + + This is an invalid tag. + EOF + + tag=$(git hash-object -t tag -w --stdin <invalid-tag) && + test_when_finished "remove_object $tag" && + echo $tag >.git/refs/tags/invalid && + test_when_finished "git update-ref -d refs/tags/invalid" && test_must_fail git fsck --tags >out && cat out && - grep "broken link" out && - rm .git/refs/tags/invalid + grep "broken link" out ' -cat > wrong-tag <<EOF -object $(echo blob | git hash-object -w --stdin) -type commit -tag wrong -tagger T A Gger <tagger@example.com> 1234567890 -0000 - -This is an invalid tag. -EOF - test_expect_success 'tag pointing to something else than its type' ' - tag=$(git hash-object -t tag -w --stdin < wrong-tag) && - echo $tag > .git/refs/tags/wrong && + sha=$(echo blob | git hash-object -w --stdin) && + test_when_finished "remove_object $sha" && + cat >wrong-tag <<-EOF && + object $sha + type commit + tag wrong + tagger T A Gger <tagger@example.com> 1234567890 -0000 + + This is an invalid tag. + EOF + + tag=$(git hash-object -t tag -w --stdin <wrong-tag) && + test_when_finished "remove_object $tag" && + echo $tag >.git/refs/tags/wrong && + test_when_finished "git update-ref -d refs/tags/wrong" && test_must_fail git fsck --tags 2>out && cat out && - grep "error in tag.*broken links" out && - rm .git/refs/tags/wrong + grep "error in tag.*broken links" out ' - +test_expect_success 'cleaned up' ' + git fsck >actual 2>&1 && + test_cmp empty actual +' test_done diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index bd8b60732..2c8f01f66 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh @@ -3,183 +3,320 @@ test_description='test separate work tree' . ./test-lib.sh -test_rev_parse() { - name=$1 - shift - - test_expect_success "$name: is-bare-repository" \ - "test '$1' = \"\$(git rev-parse --is-bare-repository)\"" - shift - [ $# -eq 0 ] && return - - test_expect_success "$name: is-inside-git-dir" \ - "test '$1' = \"\$(git rev-parse --is-inside-git-dir)\"" - shift - [ $# -eq 0 ] && return - - test_expect_success "$name: is-inside-work-tree" \ - "test '$1' = \"\$(git rev-parse --is-inside-work-tree)\"" - shift - [ $# -eq 0 ] && return - - test_expect_success "$name: prefix" \ - "test '$1' = \"\$(git rev-parse --show-prefix)\"" - shift - [ $# -eq 0 ] && return -} - -EMPTY_TREE=$(git write-tree) -mkdir -p work/sub/dir || exit 1 -mkdir -p work2 || exit 1 -mv .git repo.git || exit 1 - -say "core.worktree = relative path" -GIT_DIR=repo.git -GIT_CONFIG="$(pwd)"/$GIT_DIR/config -export GIT_DIR GIT_CONFIG -unset GIT_WORK_TREE -git config core.worktree ../work -test_rev_parse 'outside' false false false -cd work || exit 1 -GIT_DIR=../repo.git -GIT_CONFIG="$(pwd)"/$GIT_DIR/config -test_rev_parse 'inside' false false true '' -cd sub/dir || exit 1 -GIT_DIR=../../../repo.git -GIT_CONFIG="$(pwd)"/$GIT_DIR/config -test_rev_parse 'subdirectory' false false true sub/dir/ -cd ../../.. || exit 1 - -say "core.worktree = absolute path" -GIT_DIR=$(pwd)/repo.git -GIT_CONFIG=$GIT_DIR/config -git config core.worktree "$(pwd)/work" -test_rev_parse 'outside' false false false -cd work2 -test_rev_parse 'outside2' false false false -cd ../work || exit 1 -test_rev_parse 'inside' false false true '' -cd sub/dir || exit 1 -test_rev_parse 'subdirectory' false false true sub/dir/ -cd ../../.. || exit 1 - -say "GIT_WORK_TREE=relative path (override core.worktree)" -GIT_DIR=$(pwd)/repo.git -GIT_CONFIG=$GIT_DIR/config -git config core.worktree non-existent -GIT_WORK_TREE=work -export GIT_WORK_TREE -test_rev_parse 'outside' false false false -cd work2 -test_rev_parse 'outside' false false false -cd ../work || exit 1 -GIT_WORK_TREE=. -test_rev_parse 'inside' false false true '' -cd sub/dir || exit 1 -GIT_WORK_TREE=../.. -test_rev_parse 'subdirectory' false false true sub/dir/ -cd ../../.. || exit 1 - -mv work repo.git/work -mv work2 repo.git/work2 - -say "GIT_WORK_TREE=absolute path, work tree below git dir" -GIT_DIR=$(pwd)/repo.git -GIT_CONFIG=$GIT_DIR/config -GIT_WORK_TREE=$(pwd)/repo.git/work -test_rev_parse 'outside' false false false -cd repo.git || exit 1 -test_rev_parse 'in repo.git' false true false -cd objects || exit 1 -test_rev_parse 'in repo.git/objects' false true false -cd ../work2 || exit 1 -test_rev_parse 'in repo.git/work2' false true false -cd ../work || exit 1 -test_rev_parse 'in repo.git/work' false true true '' -cd sub/dir || exit 1 -test_rev_parse 'in repo.git/sub/dir' false true true sub/dir/ -cd ../../../.. || exit 1 - -test_expect_success 'repo finds its work tree' ' - (cd repo.git && - : > work/sub/dir/untracked && - test sub/dir/untracked = "$(git ls-files --others)") -' - -test_expect_success 'repo finds its work tree from work tree, too' ' - (cd repo.git/work/sub/dir && - : > tracked && - git --git-dir=../../.. add tracked && - cd ../../.. && - test sub/dir/tracked = "$(git ls-files)") +test_expect_success 'setup' ' + EMPTY_TREE=$(git write-tree) && + EMPTY_BLOB=$(git hash-object -t blob --stdin </dev/null) && + CHANGED_BLOB=$(echo changed | git hash-object -t blob --stdin) && + ZEROES=0000000000000000000000000000000000000000 && + EMPTY_BLOB7=$(echo $EMPTY_BLOB | sed "s/\(.......\).*/\1/") && + CHANGED_BLOB7=$(echo $CHANGED_BLOB | sed "s/\(.......\).*/\1/") && + + mkdir -p work/sub/dir && + mkdir -p work2 && + mv .git repo.git +' + +test_expect_success 'setup: helper for testing rev-parse' ' + test_rev_parse() { + echo $1 >expected.bare && + echo $2 >expected.inside-git && + echo $3 >expected.inside-worktree && + if test $# -ge 4 + then + echo $4 >expected.prefix + fi && + + git rev-parse --is-bare-repository >actual.bare && + git rev-parse --is-inside-git-dir >actual.inside-git && + git rev-parse --is-inside-work-tree >actual.inside-worktree && + if test $# -ge 4 + then + git rev-parse --show-prefix >actual.prefix + fi && + + test_cmp expected.bare actual.bare && + test_cmp expected.inside-git actual.inside-git && + test_cmp expected.inside-worktree actual.inside-worktree && + if test $# -ge 4 + then + # rev-parse --show-prefix should output + # a single newline when at the top of the work tree, + # but we test for that separately. + test -z "$4" && ! test -s actual.prefix || + test_cmp expected.prefix actual.prefix + fi + } +' + +test_expect_success 'setup: core.worktree = relative path' ' + unset GIT_WORK_TREE; + GIT_DIR=repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + export GIT_DIR GIT_CONFIG && + git config core.worktree ../work +' + +test_expect_success 'outside' ' + test_rev_parse false false false +' + +test_expect_success 'inside work tree' ' + ( + cd work && + GIT_DIR=../repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + test_rev_parse false false true "" + ) +' + +test_expect_failure 'empty prefix is actually written out' ' + echo >expected && + ( + cd work && + GIT_DIR=../repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + git rev-parse --show-prefix >../actual + ) && + test_cmp expected actual +' + +test_expect_success 'subdir of work tree' ' + ( + cd work/sub/dir && + GIT_DIR=../../../repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + test_rev_parse false false true sub/dir/ + ) +' + +test_expect_success 'setup: core.worktree = absolute path' ' + unset GIT_WORK_TREE; + GIT_DIR=$(pwd)/repo.git && + GIT_CONFIG=$GIT_DIR/config && + export GIT_DIR GIT_CONFIG && + git config core.worktree "$(pwd)/work" +' + +test_expect_success 'outside' ' + test_rev_parse false false false && + ( + cd work2 && + test_rev_parse false false false + ) +' + +test_expect_success 'inside work tree' ' + ( + cd work && + test_rev_parse false false true "" + ) +' + +test_expect_success 'subdir of work tree' ' + ( + cd work/sub/dir && + test_rev_parse false false true sub/dir/ + ) +' + +test_expect_success 'setup: GIT_WORK_TREE=relative (override core.worktree)' ' + GIT_DIR=$(pwd)/repo.git && + GIT_CONFIG=$GIT_DIR/config && + git config core.worktree non-existent && + GIT_WORK_TREE=work && + export GIT_DIR GIT_CONFIG GIT_WORK_TREE +' + +test_expect_success 'outside' ' + test_rev_parse false false false && + ( + cd work2 && + test_rev_parse false false false + ) +' + +test_expect_success 'inside work tree' ' + ( + cd work && + GIT_WORK_TREE=. && + test_rev_parse false false true "" + ) +' + +test_expect_success 'subdir of work tree' ' + ( + cd work/sub/dir && + GIT_WORK_TREE=../.. && + test_rev_parse false false true sub/dir/ + ) +' + +test_expect_success 'setup: GIT_WORK_TREE=absolute, below git dir' ' + mv work repo.git/work && + mv work2 repo.git/work2 && + GIT_DIR=$(pwd)/repo.git && + GIT_CONFIG=$GIT_DIR/config && + GIT_WORK_TREE=$(pwd)/repo.git/work && + export GIT_DIR GIT_CONFIG GIT_WORK_TREE +' + +test_expect_success 'outside' ' + echo outside && + test_rev_parse false false false +' + +test_expect_success 'in repo.git' ' + ( + cd repo.git && + test_rev_parse false true false + ) && + ( + cd repo.git/objects && + test_rev_parse false true false + ) && + ( + cd repo.git/work2 && + test_rev_parse false true false + ) +' + +test_expect_success 'inside work tree' ' + ( + cd repo.git/work && + test_rev_parse false true true "" + ) +' + +test_expect_success 'subdir of work tree' ' + ( + cd repo.git/work/sub/dir && + test_rev_parse false true true sub/dir/ + ) +' + +test_expect_success 'find work tree from repo' ' + echo sub/dir/untracked >expected && + cat <<-\EOF >repo.git/work/.gitignore && + expected.* + actual.* + .gitignore + EOF + >repo.git/work/sub/dir/untracked && + ( + cd repo.git && + git ls-files --others --exclude-standard >../actual + ) && + test_cmp expected actual +' + +test_expect_success 'find work tree from work tree' ' + echo sub/dir/tracked >expected && + >repo.git/work/sub/dir/tracked && + ( + cd repo.git/work/sub/dir && + git --git-dir=../../.. add tracked + ) && + ( + cd repo.git && + git ls-files >../actual + ) && + test_cmp expected actual ' test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' ' - (cd repo.git/work/sub/dir && - GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \ + ( + cd repo.git/work/sub/dir && + GIT_DIR=../../.. && + GIT_WORK_TREE=../.. && + GIT_PAGER= && + export GIT_DIR GIT_WORK_TREE GIT_PAGER && + git diff --exit-code tracked && - echo changed > tracked && - ! GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \ - git diff --exit-code tracked) -' -cat > diff-index-cached.expected <<\EOF -:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A sub/dir/tracked -EOF -cat > diff-index.expected <<\EOF -:000000 100644 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 A sub/dir/tracked -EOF - - -test_expect_success 'git diff-index' ' - GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff-index $EMPTY_TREE > result && - test_cmp diff-index.expected result && - GIT_DIR=repo.git git diff-index --cached $EMPTY_TREE > result && - test_cmp diff-index-cached.expected result -' -cat >diff-files.expected <<\EOF -:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 M sub/dir/tracked -EOF - -test_expect_success 'git diff-files' ' - GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff-files > result && - test_cmp diff-files.expected result -' - -cat >diff-TREE.expected <<\EOF -diff --git a/sub/dir/tracked b/sub/dir/tracked -new file mode 100644 -index 0000000..5ea2ed4 ---- /dev/null -+++ b/sub/dir/tracked -@@ -0,0 +1 @@ -+changed -EOF -cat >diff-TREE-cached.expected <<\EOF -diff --git a/sub/dir/tracked b/sub/dir/tracked -new file mode 100644 -index 0000000..e69de29 -EOF -cat >diff-FILES.expected <<\EOF -diff --git a/sub/dir/tracked b/sub/dir/tracked -index e69de29..5ea2ed4 100644 ---- a/sub/dir/tracked -+++ b/sub/dir/tracked -@@ -0,0 +1 @@ -+changed -EOF - -test_expect_success 'git diff' ' - GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff $EMPTY_TREE > result && - test_cmp diff-TREE.expected result && - GIT_DIR=repo.git git diff --cached $EMPTY_TREE > result && - test_cmp diff-TREE-cached.expected result && - GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff > result && - test_cmp diff-FILES.expected result + echo changed >tracked && + test_must_fail git diff --exit-code tracked + ) +' + +test_expect_success 'diff-index respects work tree under .git dir' ' + cat >diff-index-cached.expected <<-EOF && + :000000 100644 $ZEROES $EMPTY_BLOB A sub/dir/tracked + EOF + cat >diff-index.expected <<-EOF && + :000000 100644 $ZEROES $ZEROES A sub/dir/tracked + EOF + + ( + GIT_DIR=repo.git && + GIT_WORK_TREE=repo.git/work && + export GIT_DIR GIT_WORK_TREE && + git diff-index $EMPTY_TREE >diff-index.actual && + git diff-index --cached $EMPTY_TREE >diff-index-cached.actual + ) && + test_cmp diff-index.expected diff-index.actual && + test_cmp diff-index-cached.expected diff-index-cached.actual +' + +test_expect_success 'diff-files respects work tree under .git dir' ' + cat >diff-files.expected <<-EOF && + :100644 100644 $EMPTY_BLOB $ZEROES M sub/dir/tracked + EOF + + ( + GIT_DIR=repo.git && + GIT_WORK_TREE=repo.git/work && + export GIT_DIR GIT_WORK_TREE && + git diff-files >diff-files.actual + ) && + test_cmp diff-files.expected diff-files.actual +' + +test_expect_success 'git diff respects work tree under .git dir' ' + cat >diff-TREE.expected <<-EOF && + diff --git a/sub/dir/tracked b/sub/dir/tracked + new file mode 100644 + index 0000000..$CHANGED_BLOB7 + --- /dev/null + +++ b/sub/dir/tracked + @@ -0,0 +1 @@ + +changed + EOF + cat >diff-TREE-cached.expected <<-EOF && + diff --git a/sub/dir/tracked b/sub/dir/tracked + new file mode 100644 + index 0000000..$EMPTY_BLOB7 + EOF + cat >diff-FILES.expected <<-EOF && + diff --git a/sub/dir/tracked b/sub/dir/tracked + index $EMPTY_BLOB7..$CHANGED_BLOB7 100644 + --- a/sub/dir/tracked + +++ b/sub/dir/tracked + @@ -0,0 +1 @@ + +changed + EOF + + ( + GIT_DIR=repo.git && + GIT_WORK_TREE=repo.git/work && + export GIT_DIR GIT_WORK_TREE && + git diff $EMPTY_TREE >diff-TREE.actual && + git diff --cached $EMPTY_TREE >diff-TREE-cached.actual && + git diff >diff-FILES.actual + ) && + test_cmp diff-TREE.expected diff-TREE.actual && + test_cmp diff-TREE-cached.expected diff-TREE-cached.actual && + test_cmp diff-FILES.expected diff-FILES.actual ' test_expect_success 'git grep' ' - (cd repo.git/work/sub && - GIT_DIR=../.. GIT_WORK_TREE=.. git grep -l changed | grep dir/tracked) + echo dir/tracked >expected.grep && + ( + cd repo.git/work/sub && + GIT_DIR=../.. && + GIT_WORK_TREE=.. && + export GIT_DIR GIT_WORK_TREE && + git grep -l changed >../../../actual.grep + ) && + test_cmp expected.grep actual.grep ' test_expect_success 'git commit' ' @@ -191,14 +328,14 @@ test_expect_success 'git commit' ' test_expect_success 'absolute pathspec should fail gracefully' ' ( - cd repo.git || exit 1 - git config --unset core.worktree + cd repo.git && + test_might_fail git config --unset core.worktree && test_must_fail git log HEAD -- /home ) ' test_expect_success 'make_relative_path handles double slashes in GIT_DIR' ' - : > dummy_file + >dummy_file echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file && git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file ' diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index 434679585..b3195c470 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -81,4 +81,22 @@ test_expect_success 'test --parseopt --keep-dashdash' ' test_cmp expect output ' +cat >expect <<EOF +set -- --foo -- '--' 'arg' '--spam=ham' +EOF + +test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option with --' ' + git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo -- arg --spam=ham <optionspec >output && + test_cmp expect output +' + +cat > expect <<EOF +set -- --foo -- 'arg' '--spam=ham' +EOF + +test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option without --' ' + git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo arg --spam=ham <optionspec >output && + test_cmp expect output +' + test_done diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index cc6539494..813cc1b3e 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -104,4 +104,15 @@ test_expect_success 'use --default' ' test_must_fail git rev-parse --verify --default bar ' +test_expect_success 'master@{n} for various n' ' + N=$(git reflog | wc -l) && + Nm1=$(($N-1)) && + Np1=$(($N+1)) && + git rev-parse --verify master@{0} && + git rev-parse --verify master@{1} && + git rev-parse --verify master@{$Nm1} && + test_must_fail git rev-parse --verify master@{$N} && + test_must_fail git rev-parse --verify master@{$Np1} +' + test_done diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index af721f971..0eeeb0e45 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -66,4 +66,13 @@ test_expect_success 'incorrect file in :path and :N:path' ' grep "fatal: Path '"'"'disk-only.txt'"'"' exists on disk, but not in the index." error ' +test_expect_success 'invalid @{n} reference' ' + test_must_fail git rev-parse master@{99999} >output 2>error && + test -z "$(cat output)" && + grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error && + test_must_fail git rev-parse --verify master@{99999} >output 2>error && + test -z "$(cat output)" && + grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error +' + test_done diff --git a/t/t1509-root-worktree.sh b/t/t1509-root-worktree.sh index 5322a3bf9..335420fd8 100755 --- a/t/t1509-root-worktree.sh +++ b/t/t1509-root-worktree.sh @@ -99,17 +99,17 @@ test_foobar_foobar() { } if ! test_have_prereq POSIXPERM || ! [ -w / ]; then - say "Dangerous test skipped. Read this test if you want to execute it" + skip_all="Dangerous test skipped. Read this test if you want to execute it" test_done fi if [ "$IKNOWWHATIAMDOING" != "YES" ]; then - say "You must set env var IKNOWWHATIAMDOING=YES in order to run this test" + skip_all="You must set env var IKNOWWHATIAMDOING=YES in order to run this test" test_done fi if [ "$UID" = 0 ]; then - say "No you can't run this with root" + skip_all="No you can't run this with root" test_done fi @@ -134,8 +134,8 @@ cat >ls.expected <<EOF 100644 $ONE_SHA1 0 me EOF -export GIT_DIR="$TRASH_DIRECTORY/.git" -export GIT_WORK_TREE=/ +GIT_DIR="$TRASH_DIRECTORY/.git" && export GIT_DIR +GIT_WORK_TREE=/ && export GIT_WORK_TREE test_vars 'abs gitdir, root' "$GIT_DIR" "/" "" test_foobar_root @@ -154,24 +154,24 @@ say "GIT_DIR relative, GIT_WORK_TREE set" test_expect_success 'go to /' 'cd /' -export GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git" -export GIT_WORK_TREE=/ +GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git" && export GIT_DIR +GIT_WORK_TREE=/ && export GIT_WORK_TREE test_vars 'rel gitdir, root' "$GIT_DIR" "/" "" test_foobar_root test_expect_success 'go to /foo' 'cd /foo' -export GIT_DIR="../$TRASH_DIRECTORY/.git" -export GIT_WORK_TREE=/ +GIT_DIR="../$TRASH_DIRECTORY/.git" && export GIT_DIR +GIT_WORK_TREE=/ && export GIT_WORK_TREE test_vars 'rel gitdir, foo' "$TRASH_DIRECTORY/.git" "/" "foo/" test_foobar_foo test_expect_success 'go to /foo/bar' 'cd /foo/bar' -export GIT_DIR="../../$TRASH_DIRECTORY/.git" -export GIT_WORK_TREE=/ +GIT_DIR="../../$TRASH_DIRECTORY/.git" && export GIT_DIR +GIT_WORK_TREE=/ && export GIT_WORK_TREE test_vars 'rel gitdir, foo/bar' "$TRASH_DIRECTORY/.git" "/" "foo/bar/" test_foobar_foobar @@ -180,24 +180,24 @@ say "GIT_DIR relative, GIT_WORK_TREE relative" test_expect_success 'go to /' 'cd /' -export GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git" -export GIT_WORK_TREE=. +GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git" && export GIT_DIR +GIT_WORK_TREE=. && export GIT_WORK_TREE test_vars 'rel gitdir, root' "$GIT_DIR" "/" "" test_foobar_root test_expect_success 'go to /' 'cd /foo' -export GIT_DIR="../$TRASH_DIRECTORY/.git" -export GIT_WORK_TREE=.. +GIT_DIR="../$TRASH_DIRECTORY/.git" && export GIT_DIR +GIT_WORK_TREE=.. && export GIT_WORK_TREE test_vars 'rel gitdir, foo' "$TRASH_DIRECTORY/.git" "/" "foo/" test_foobar_foo test_expect_success 'go to /foo/bar' 'cd /foo/bar' -export GIT_DIR="../../$TRASH_DIRECTORY/.git" -export GIT_WORK_TREE=../.. +GIT_DIR="../../$TRASH_DIRECTORY/.git" && export GIT_DIR +GIT_WORK_TREE=../.. && export GIT_WORK_TREE test_vars 'rel gitdir, foo/bar' "$TRASH_DIRECTORY/.git" "/" "foo/bar/" test_foobar_foobar diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh index 27e2127af..a74ee227b 100755 --- a/t/t2007-checkout-symlink.sh +++ b/t/t2007-checkout-symlink.sh @@ -6,13 +6,7 @@ test_description='git checkout to switch between branches with symlink<->dir' . ./test-lib.sh -if ! test_have_prereq SYMLINKS -then - say "symbolic links not supported - skipping tests" - test_done -fi - -test_expect_success setup ' +test_expect_success SYMLINKS setup ' mkdir frotz && echo hello >frotz/filfre && @@ -38,18 +32,18 @@ test_expect_success setup ' ' -test_expect_success 'switch from symlink to dir' ' +test_expect_success SYMLINKS 'switch from symlink to dir' ' git checkout master ' -test_expect_success 'Remove temporary directories & switch to master' ' +test_expect_success SYMLINKS 'Remove temporary directories & switch to master' ' rm -fr frotz xyzzy nitfol && git checkout -f master ' -test_expect_success 'switch from dir to symlink' ' +test_expect_success SYMLINKS 'switch from dir to symlink' ' git checkout side diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh index fda3f0af7..70edbb33e 100755 --- a/t/t2013-checkout-submodule.sh +++ b/t/t2013-checkout-submodule.sh @@ -39,4 +39,27 @@ test_expect_success '"checkout <submodule>" updates the index only' ' git diff-files --quiet ' +test_expect_success '"checkout <submodule>" honors diff.ignoreSubmodules' ' + git config diff.ignoreSubmodules dirty && + echo x> submodule/untracked && + git checkout HEAD >actual 2>&1 && + ! test -s actual +' + +test_expect_success '"checkout <submodule>" honors submodule.*.ignore from .gitmodules' ' + git config diff.ignoreSubmodules none && + git config -f .gitmodules submodule.submodule.path submodule && + git config -f .gitmodules submodule.submodule.ignore untracked && + git checkout HEAD >actual 2>&1 && + ! test -s actual +' + +test_expect_success '"checkout <submodule>" honors submodule.*.ignore from .git/config' ' + git config -f .gitmodules submodule.submodule.ignore none && + git config submodule.submodule.path submodule && + git config submodule.submodule.ignore all && + git checkout HEAD >actual 2>&1 && + ! test -s actual +' + test_done diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh index 2144184d7..a463b13b2 100755 --- a/t/t2016-checkout-patch.sh +++ b/t/t2016-checkout-patch.sh @@ -4,7 +4,7 @@ test_description='git checkout --patch' . ./lib-patch-mode.sh -test_expect_success 'setup' ' +test_expect_success PERL 'setup' ' mkdir dir && echo parent > dir/foo && echo dummy > bar && @@ -18,55 +18,55 @@ test_expect_success 'setup' ' # note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar' -test_expect_success 'saying "n" does nothing' ' +test_expect_success PERL 'saying "n" does nothing' ' set_and_save_state dir/foo work head && (echo n; echo n) | git checkout -p && verify_saved_state bar && verify_saved_state dir/foo ' -test_expect_success 'git checkout -p' ' +test_expect_success PERL 'git checkout -p' ' (echo n; echo y) | git checkout -p && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success 'git checkout -p with staged changes' ' +test_expect_success PERL 'git checkout -p with staged changes' ' set_state dir/foo work index (echo n; echo y) | git checkout -p && verify_saved_state bar && verify_state dir/foo index index ' -test_expect_success 'git checkout -p HEAD with NO staged changes: abort' ' +test_expect_success PERL 'git checkout -p HEAD with NO staged changes: abort' ' set_and_save_state dir/foo work head && (echo n; echo y; echo n) | git checkout -p HEAD && verify_saved_state bar && verify_saved_state dir/foo ' -test_expect_success 'git checkout -p HEAD with NO staged changes: apply' ' +test_expect_success PERL 'git checkout -p HEAD with NO staged changes: apply' ' (echo n; echo y; echo y) | git checkout -p HEAD && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success 'git checkout -p HEAD with change already staged' ' - set_state dir/foo index index +test_expect_success PERL 'git checkout -p HEAD with change already staged' ' + set_state dir/foo index index && # the third n is to get out in case it mistakenly does not apply (echo n; echo y; echo n) | git checkout -p HEAD && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success 'git checkout -p HEAD^' ' +test_expect_success PERL 'git checkout -p HEAD^' ' # the third n is to get out in case it mistakenly does not apply (echo n; echo y; echo n) | git checkout -p HEAD^ && verify_saved_state bar && verify_state dir/foo parent parent ' -test_expect_success 'git checkout -p handles deletion' ' +test_expect_success PERL 'git checkout -p handles deletion' ' set_state dir/foo work index && rm dir/foo && (echo n; echo y) | git checkout -p && @@ -79,28 +79,28 @@ test_expect_success 'git checkout -p handles deletion' ' # dir/foo. There's always an extra 'n' to reject edits to dir/foo in # the failure case (and thus get out of the loop). -test_expect_success 'path limiting works: dir' ' +test_expect_success PERL 'path limiting works: dir' ' set_state dir/foo work head && (echo y; echo n) | git checkout -p dir && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success 'path limiting works: -- dir' ' +test_expect_success PERL 'path limiting works: -- dir' ' set_state dir/foo work head && (echo y; echo n) | git checkout -p -- dir && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success 'path limiting works: HEAD^ -- dir' ' +test_expect_success PERL 'path limiting works: HEAD^ -- dir' ' # the third n is to get out in case it mistakenly does not apply (echo y; echo n; echo n) | git checkout -p HEAD^ -- dir && verify_saved_state bar && verify_state dir/foo parent parent ' -test_expect_success 'path limiting works: foo inside dir' ' +test_expect_success PERL 'path limiting works: foo inside dir' ' set_state dir/foo work head && # the third n is to get out in case it mistakenly does not apply (echo y; echo n; echo n) | (cd dir && git checkout -p foo) && @@ -108,7 +108,7 @@ test_expect_success 'path limiting works: foo inside dir' ' verify_state dir/foo head head ' -test_expect_success 'none of this moved HEAD' ' +test_expect_success PERL 'none of this moved HEAD' ' verify_saved_head ' diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh index be88d4b5e..2d2f63f22 100755 --- a/t/t2017-checkout-orphan.sh +++ b/t/t2017-checkout-orphan.sh @@ -68,41 +68,34 @@ test_expect_success '--orphan makes reflog by default' ' git checkout master && git config --unset core.logAllRefUpdates && git checkout --orphan delta && - ! test -f .git/logs/refs/heads/delta && - test_must_fail PAGER= git reflog show delta && + test_must_fail git rev-parse --verify delta@{0} && git commit -m Delta && - test -f .git/logs/refs/heads/delta && - PAGER= git reflog show delta + git rev-parse --verify delta@{0} ' test_expect_success '--orphan does not make reflog when core.logAllRefUpdates = false' ' git checkout master && git config core.logAllRefUpdates false && git checkout --orphan epsilon && - ! test -f .git/logs/refs/heads/epsilon && - test_must_fail PAGER= git reflog show epsilon && + test_must_fail git rev-parse --verify epsilon@{0} && git commit -m Epsilon && - ! test -f .git/logs/refs/heads/epsilon && - test_must_fail PAGER= git reflog show epsilon + test_must_fail git rev-parse --verify epsilon@{0} ' test_expect_success '--orphan with -l makes reflog when core.logAllRefUpdates = false' ' git checkout master && git checkout -l --orphan zeta && - test -f .git/logs/refs/heads/zeta && - test_must_fail PAGER= git reflog show zeta && + test_must_fail git rev-parse --verify zeta@{0} && git commit -m Zeta && - PAGER= git reflog show zeta + git rev-parse --verify zeta@{0} ' test_expect_success 'giving up --orphan not committed when -l and core.logAllRefUpdates = false deletes reflog' ' git checkout master && git checkout -l --orphan eta && - test -f .git/logs/refs/heads/eta && - test_must_fail PAGER= git reflog show eta && + test_must_fail git rev-parse --verify eta@{0} && git checkout master && - ! test -f .git/logs/refs/heads/eta && - test_must_fail PAGER= git reflog show eta + test_must_fail git rev-parse --verify eta@{0} ' test_expect_success '--orphan is rejected with an existing name' ' diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh new file mode 100755 index 000000000..fa6901638 --- /dev/null +++ b/t/t2018-checkout-branch.sh @@ -0,0 +1,172 @@ +#!/bin/sh + +test_description='checkout ' + +. ./test-lib.sh + +# Arguments: <branch> <sha> [<checkout options>] +# +# Runs "git checkout" to switch to <branch>, testing that +# +# 1) we are on the specified branch, <branch>; +# 2) HEAD is <sha>; if <sha> is not specified, the old HEAD is used. +# +# If <checkout options> is not specified, "git checkout" is run with -b. +do_checkout() { + exp_branch=$1 && + exp_ref="refs/heads/$exp_branch" && + + # if <sha> is not specified, use HEAD. + exp_sha=${2:-$(git rev-parse --verify HEAD)} && + + # default options for git checkout: -b + if [ -z "$3" ]; then + opts="-b" + else + opts="$3" + fi + + git checkout $opts $exp_branch $exp_sha && + + test $exp_ref = $(git rev-parse --symbolic-full-name HEAD) && + test $exp_sha = $(git rev-parse --verify HEAD) +} + +test_dirty_unmergeable() { + ! git diff --exit-code >/dev/null +} + +setup_dirty_unmergeable() { + echo >>file1 change2 +} + +test_dirty_mergeable() { + ! git diff --cached --exit-code >/dev/null +} + +setup_dirty_mergeable() { + echo >file2 file2 && + git add file2 +} + +test_expect_success 'setup' ' + test_commit initial file1 && + HEAD1=$(git rev-parse --verify HEAD) && + + test_commit change1 file1 && + HEAD2=$(git rev-parse --verify HEAD) && + + git branch -m branch1 +' + +test_expect_success 'checkout -b to a new branch, set to HEAD' ' + do_checkout branch2 +' + +test_expect_success 'checkout -b to a new branch, set to an explicit ref' ' + git checkout branch1 && + git branch -D branch2 && + + do_checkout branch2 $HEAD1 +' + +test_expect_success 'checkout -b to a new branch with unmergeable changes fails' ' + git checkout branch1 && + + # clean up from previous test + git branch -D branch2 && + + setup_dirty_unmergeable && + test_must_fail do_checkout branch2 $HEAD1 && + test_dirty_unmergeable +' + +test_expect_success 'checkout -f -b to a new branch with unmergeable changes discards changes' ' + # still dirty and on branch1 + do_checkout branch2 $HEAD1 "-f -b" && + test_must_fail test_dirty_unmergeable +' + +test_expect_success 'checkout -b to a new branch preserves mergeable changes' ' + git checkout branch1 && + + # clean up from previous test + git branch -D branch2 && + + setup_dirty_mergeable && + do_checkout branch2 $HEAD1 && + test_dirty_mergeable +' + +test_expect_success 'checkout -f -b to a new branch with mergeable changes discards changes' ' + # clean up from previous test + git reset --hard && + + git checkout branch1 && + + # clean up from previous test + git branch -D branch2 && + + setup_dirty_mergeable && + do_checkout branch2 $HEAD1 "-f -b" && + test_must_fail test_dirty_mergeable +' + +test_expect_success 'checkout -b to an existing branch fails' ' + git reset --hard HEAD && + + test_must_fail do_checkout branch2 $HEAD2 +' + +test_expect_success 'checkout -B to an existing branch resets branch to HEAD' ' + git checkout branch1 && + + do_checkout branch2 "" -B +' + +test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' ' + git checkout $(git rev-parse --verify HEAD) && + + do_checkout branch2 "" -B +' + +test_expect_success 'checkout -B to an existing branch with an explicit ref resets branch to that ref' ' + git checkout branch1 && + + do_checkout branch2 $HEAD1 -B +' + +test_expect_success 'checkout -B to an existing branch with unmergeable changes fails' ' + git checkout branch1 && + + setup_dirty_unmergeable && + test_must_fail do_checkout branch2 $HEAD1 -B && + test_dirty_unmergeable +' + +test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' ' + # still dirty and on branch1 + do_checkout branch2 $HEAD1 "-f -B" && + test_must_fail test_dirty_unmergeable +' + +test_expect_success 'checkout -B to an existing branch preserves mergeable changes' ' + git checkout branch1 && + + setup_dirty_mergeable && + do_checkout branch2 $HEAD1 -B && + test_dirty_mergeable +' + +test_expect_success 'checkout -f -B to an existing branch with mergeable changes discards changes' ' + # clean up from previous test + git reset --hard && + + git checkout branch1 && + + setup_dirty_mergeable && + do_checkout branch2 $HEAD1 "-f -B" && + test_must_fail test_dirty_mergeable +' + +test_done diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh index 648184fd9..76ad7c344 100755 --- a/t/t2101-update-index-reupdate.sh +++ b/t/t2101-update-index-reupdate.sh @@ -63,10 +63,10 @@ cat > expected <<\EOF EOF test_expect_success 'update-index --update from subdir' \ 'echo not so happy >file2 && - cd dir1 && + (cd dir1 && cat ../file2 >file3 && - git update-index --again && - cd .. && + git update-index --again + ) && git ls-files -s >current && cmp current expected' diff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh index 1ed44ee50..4d0d0a351 100755 --- a/t/t2102-update-index-symlinks.sh +++ b/t/t2102-update-index-symlinks.sh @@ -24,7 +24,7 @@ git update-index symlink' test_expect_success \ 'the index entry must still be a symbolic link' ' case "`git ls-files --stage --cached symlink`" in -120000" "*symlink) echo ok;; +120000" "*symlink) echo pass;; *) echo fail; git ls-files --stage --cached symlink; (exit 1);; esac' diff --git a/t/t2105-update-index-gitfile.sh b/t/t2105-update-index-gitfile.sh index 641607d89..a7f3d47ae 100755 --- a/t/t2105-update-index-gitfile.sh +++ b/t/t2105-update-index-gitfile.sh @@ -13,7 +13,7 @@ test_expect_success 'submodule with absolute .git file' ' (cd sub1 && git init && REAL="$(pwd)/.real" && - mv .git "$REAL" + mv .git "$REAL" && echo "gitdir: $REAL" >.git && test_commit first) ' diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh index 86291e839..2eec0118c 100755 --- a/t/t3000-ls-files-others.sh +++ b/t/t3000-ls-files-others.sh @@ -17,57 +17,52 @@ filesystem. ' . ./test-lib.sh -date >path0 -if test_have_prereq SYMLINKS -then - ln -s xyzzy path1 -else - date > path1 -fi -mkdir path2 path3 path4 -date >path2/file2 -date >path2-junk -date >path3/file3 -date >path3-junk -git update-index --add path3-junk path3/file3 - -cat >expected1 <<EOF -expected1 -expected2 -expected3 -output -path0 -path1 -path2-junk -path2/file2 -EOF -sed -e 's|path2/file2|path2/|' <expected1 >expected2 -cat <expected2 >expected3 -echo path4/ >>expected2 - -test_expect_success \ - 'git ls-files --others to show output.' \ - 'git ls-files --others >output' - -test_expect_success \ - 'git ls-files --others should pick up symlinks.' \ - 'test_cmp expected1 output' +test_expect_success 'setup ' ' + date >path0 && + if test_have_prereq SYMLINKS + then + ln -s xyzzy path1 + else + date >path1 + fi && + mkdir path2 path3 path4 && + date >path2/file2 && + date >path2-junk && + date >path3/file3 && + date >path3-junk && + git update-index --add path3-junk path3/file3 +' -test_expect_success \ - 'git ls-files --others --directory to show output.' \ - 'git ls-files --others --directory >output' +test_expect_success 'setup: expected output' ' + cat >expected1 <<-\EOF && + expected1 + expected2 + expected3 + output + path0 + path1 + path2-junk + path2/file2 + EOF + sed -e "s|path2/file2|path2/|" <expected1 >expected2 && + cp expected2 expected3 && + echo path4/ >>expected2 +' -test_expect_success \ - 'git ls-files --others --directory should not get confused.' \ - 'test_cmp expected2 output' +test_expect_success 'ls-files --others' ' + git ls-files --others >output && + test_cmp expected1 output +' -test_expect_success \ - 'git ls-files --others --directory --no-empty-directory to show output.' \ - 'git ls-files --others --directory --no-empty-directory >output' +test_expect_success 'ls-files --others --directory' ' + git ls-files --others --directory >output && + test_cmp expected2 output +' -test_expect_success \ - '--no-empty-directory hides empty directory' \ - 'test_cmp expected3 output' +test_expect_success '--no-empty-directory hides empty directory' ' + git ls-files --others --directory --no-empty-directory >output && + test_cmp expected3 output +' test_done diff --git a/t/t3020-ls-files-error-unmatch.sh b/t/t3020-ls-files-error-unmatch.sh index a7d818716..ca01053bc 100755 --- a/t/t3020-ls-files-error-unmatch.sh +++ b/t/t3020-ls-files-error-unmatch.sh @@ -26,4 +26,3 @@ test_expect_success \ 'git ls-files --error-unmatch foo bar' test_done -1 diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index d54154453..e66e550b2 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -23,6 +23,8 @@ test_expect_success 'setup 1' ' git branch df-3 && git branch remove && git branch submod && + git branch copy && + git branch rename && echo hello >>a && cp a d/e && @@ -248,6 +250,22 @@ test_expect_success 'setup 7' ' git commit -m "make d/ a submodule" ' +test_expect_success 'setup 8' ' + git checkout rename && + git mv a e && + git add e && + test_tick && + git commit -m "rename a->e" +' + +test_expect_success 'setup 9' ' + git checkout copy && + cp a e && + git add e && + test_tick && + git commit -m "copy a->e" +' + test_expect_success 'merge-recursive simple' ' rm -fr [abcd] && @@ -294,7 +312,7 @@ test_expect_success 'fail if the index has unresolved entries' ' grep "You have not concluded your merge" out && rm -f .git/MERGE_HEAD && test_must_fail git merge "$c5" 2> out && - grep "Your local changes to .* would be overwritten by merge." out + grep "Your local changes to the following files would be overwritten by merge:" out ' test_expect_success 'merge-recursive remove conflict' ' @@ -580,4 +598,21 @@ test_expect_failure 'merge-recursive simple w/submodule result' ' test_cmp expected actual ' +test_expect_success 'merge-recursive copy vs. rename' ' + git checkout -f copy && + git merge rename && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && + ( + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 blob $o0 e" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + echo "100644 $o0 0 e" + ) >expected && + test_cmp expected actual +' + test_done diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh index 3ce501bb9..61c1f53d1 100755 --- a/t/t3060-ls-files-with-tree.sh +++ b/t/t3060-ls-files-with-tree.sh @@ -53,17 +53,15 @@ test_expect_success setup ' git add . ' -# We have to run from a sub-directory to trigger prune_path -# Then we finally get to run our --with-tree test -cd sub - test_expect_success 'git -ls-files --with-tree should succeed from subdir' ' - - git ls-files --with-tree=HEAD~1 >../output - + # We have to run from a sub-directory to trigger prune_path + # Then we finally get to run our --with-tree test + ( + cd sub && + git ls-files --with-tree=HEAD~1 >../output + ) ' -cd .. test_expect_success \ 'git -ls-files --with-tree should add entries from named tree.' \ 'test_cmp expected output' diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh index eee0d344d..81d90b66c 100755 --- a/t/t3100-ls-tree-restrict.sh +++ b/t/t3100-ls-tree-restrict.sh @@ -165,4 +165,13 @@ test_expect_success \ EOF test_output' +test_expect_success \ + 'ls-tree with one path a prefix of the other' \ + 'git ls-tree $tree path2/baz path2/bazbo >current && + make_expected <<\EOF && +040000 tree X path2/baz +120000 blob X path2/bazbo +EOF + test_output' + test_done diff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh index 06654c6f8..026f9f89d 100755 --- a/t/t3101-ls-tree-dirname.sh +++ b/t/t3101-ls-tree-dirname.sh @@ -21,33 +21,32 @@ entries. Also test odd filename and missing entries handling. ' . ./test-lib.sh -test_expect_success \ - 'setup' \ - 'echo 111 >1.txt && - echo 222 >2.txt && - mkdir path0 path0/a path0/a/b path0/a/b/c && - echo 111 >path0/a/b/c/1.txt && - mkdir path1 path1/b path1/b/c && - echo 111 >path1/b/c/1.txt && - mkdir path2 && - echo 111 >path2/1.txt && - mkdir path3 && - echo 111 >path3/1.txt && - echo 222 >path3/2.txt && - find *.txt path* \( -type f -o -type l \) -print | - xargs git update-index --add && - tree=`git write-tree` && - echo $tree' +test_expect_success 'setup' ' + echo 111 >1.txt && + echo 222 >2.txt && + mkdir path0 path0/a path0/a/b path0/a/b/c && + echo 111 >path0/a/b/c/1.txt && + mkdir path1 path1/b path1/b/c && + echo 111 >path1/b/c/1.txt && + mkdir path2 && + echo 111 >path2/1.txt && + mkdir path3 && + echo 111 >path3/1.txt && + echo 222 >path3/2.txt && + find *.txt path* \( -type f -o -type l \) -print | + xargs git update-index --add && + tree=`git write-tree` && + echo $tree +' test_output () { - sed -e "s/ $_x40 / X /" <current >check - test_cmp expected check + sed -e "s/ $_x40 / X /" <current >check && + test_cmp expected check } -test_expect_success \ - 'ls-tree plain' \ - 'git ls-tree $tree >current && - cat >expected <<\EOF && +test_expect_success 'ls-tree plain' ' + git ls-tree $tree >current && + cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X 2.txt 040000 tree X path0 @@ -55,13 +54,13 @@ test_expect_success \ 040000 tree X path2 040000 tree X path3 EOF - test_output' + test_output +' # Recursive does not show tree nodes anymore... -test_expect_success \ - 'ls-tree recursive' \ - 'git ls-tree -r $tree >current && - cat >expected <<\EOF && +test_expect_success 'ls-tree recursive' ' + git ls-tree -r $tree >current && + cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X 2.txt 100644 blob X path0/a/b/c/1.txt @@ -70,68 +69,71 @@ test_expect_success \ 100644 blob X path3/1.txt 100644 blob X path3/2.txt EOF - test_output' + test_output +' -test_expect_success \ - 'ls-tree filter 1.txt' \ - 'git ls-tree $tree 1.txt >current && - cat >expected <<\EOF && +test_expect_success 'ls-tree filter 1.txt' ' + git ls-tree $tree 1.txt >current && + cat >expected <<\EOF && 100644 blob X 1.txt EOF - test_output' + test_output +' -test_expect_success \ - 'ls-tree filter path1/b/c/1.txt' \ - 'git ls-tree $tree path1/b/c/1.txt >current && - cat >expected <<\EOF && +test_expect_success 'ls-tree filter path1/b/c/1.txt' ' + git ls-tree $tree path1/b/c/1.txt >current && + cat >expected <<\EOF && 100644 blob X path1/b/c/1.txt EOF - test_output' + test_output +' -test_expect_success \ - 'ls-tree filter all 1.txt files' \ - 'git ls-tree $tree 1.txt path0/a/b/c/1.txt path1/b/c/1.txt path2/1.txt path3/1.txt >current && - cat >expected <<\EOF && +test_expect_success 'ls-tree filter all 1.txt files' ' + git ls-tree $tree 1.txt path0/a/b/c/1.txt \ + path1/b/c/1.txt path2/1.txt path3/1.txt >current && + cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X path0/a/b/c/1.txt 100644 blob X path1/b/c/1.txt 100644 blob X path2/1.txt 100644 blob X path3/1.txt EOF - test_output' + test_output +' # I am not so sure about this one after ls-tree doing pathspec match. # Having both path0/a and path0/a/b/c makes path0/a redundant, and # it behaves as if path0/a/b/c, path1/b/c, path2 and path3 are specified. -test_expect_success \ - 'ls-tree filter directories' \ - 'git ls-tree $tree path3 path2 path0/a/b/c path1/b/c path0/a >current && - cat >expected <<\EOF && +test_expect_success 'ls-tree filter directories' ' + git ls-tree $tree path3 path2 path0/a/b/c path1/b/c path0/a >current && + cat >expected <<\EOF && 040000 tree X path0/a/b/c 040000 tree X path1/b/c 040000 tree X path2 040000 tree X path3 EOF - test_output' + test_output +' # Again, duplicates are filtered away so this is equivalent to # having 1.txt and path3 -test_expect_success \ - 'ls-tree filter odd names' \ - 'git ls-tree $tree 1.txt ./1.txt .//1.txt path3/1.txt path3/./1.txt path3 path3// >current && - cat >expected <<\EOF && +test_expect_success 'ls-tree filter odd names' ' + git ls-tree $tree 1.txt ./1.txt .//1.txt \ + path3/1.txt path3/./1.txt path3 path3// >current && + cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X path3/1.txt 100644 blob X path3/2.txt EOF - test_output' + test_output +' -test_expect_success \ - 'ls-tree filter missing files and extra slashes' \ - 'git ls-tree $tree 1.txt/ abc.txt path3//23.txt path3/2.txt/// >current && - cat >expected <<\EOF && -EOF - test_output' +test_expect_success 'ls-tree filter missing files and extra slashes' ' + git ls-tree $tree 1.txt/ abc.txt \ + path3//23.txt path3/2.txt/// >current && + >expected && + test_output +' test_expect_success 'ls-tree filter is leading path match' ' git ls-tree $tree pa path3/a >current && @@ -198,7 +200,7 @@ EOF ' test_expect_success 'ls-tree --name-only' ' - git ls-tree --name-only $tree >current + git ls-tree --name-only $tree >current && cat >expected <<\EOF && 1.txt 2.txt @@ -211,7 +213,7 @@ EOF ' test_expect_success 'ls-tree --name-only -r' ' - git ls-tree --name-only -r $tree >current + git ls-tree --name-only -r $tree >current && cat >expected <<\EOF && 1.txt 2.txt diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 859b99abf..f54a53345 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -228,24 +228,21 @@ test_expect_success 'checkout -b makes reflog by default' ' git checkout master && git config --unset core.logAllRefUpdates && git checkout -b alpha && - test -f .git/logs/refs/heads/alpha && - PAGER= git reflog show alpha + git rev-parse --verify alpha@{0} ' test_expect_success 'checkout -b does not make reflog when core.logAllRefUpdates = false' ' git checkout master && git config core.logAllRefUpdates false && git checkout -b beta && - ! test -f .git/logs/refs/heads/beta && - test_must_fail PAGER= git reflog show beta + test_must_fail git rev-parse --verify beta@{0} ' test_expect_success 'checkout -b with -l makes reflog when core.logAllRefUpdates = false' ' git checkout master && git checkout -lb gamma && git config --unset core.logAllRefUpdates && - test -f .git/logs/refs/heads/gamma && - PAGER= git reflog show gamma + git rev-parse --verify gamma@{0} ' test_expect_success 'avoid ambiguous track' ' diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 525174013..cd04361df 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -60,6 +60,12 @@ test_expect_success 'see if git pack-refs --prune remove ref files' ' ! test -f .git/refs/heads/f ' +test_expect_success 'see if git pack-refs --prune removes empty dirs' ' + git branch r/s/t && + git pack-refs --all --prune && + ! test -e .git/refs/heads/r +' + test_expect_success \ 'git branch g should work when git branch g/h has been deleted' \ 'git branch g/h && diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index db46d53e8..f39a261d8 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -24,19 +24,25 @@ EOF cat 2>/dev/null >"$p1" "$p0" echo 'Foo Bar Baz' >"$p2" -test -f "$p1" && cmp "$p0" "$p1" || { +if test -f "$p1" && cmp "$p0" "$p1" +then + test_set_prereq TABS_IN_FILENAMES +else # since FAT/NTFS does not allow tabs in filenames, skip this test - say 'Your filesystem does not allow tabs in filenames, test skipped.' - test_done -} + say 'Your filesystem does not allow tabs in filenames' +fi +test_expect_success TABS_IN_FILENAMES 'setup expect' " echo 'just space no-funny' >expected -test_expect_success 'git ls-files no-funny' \ +" + +test_expect_success TABS_IN_FILENAMES 'git ls-files no-funny' \ 'git update-index --add "$p0" "$p2" && git ls-files >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' t0=`git write-tree` echo "$t0" >t0 @@ -45,18 +51,24 @@ just space no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git ls-files with-funny' \ +' + +test_expect_success TABS_IN_FILENAMES 'git ls-files with-funny' \ 'git update-index --add "$p1" && git ls-files >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' " echo 'just space no-funny -tabs ," (dq) and spaces' >expected -test_expect_success 'git ls-files -z with-funny' \ +tabs ,\" (dq) and spaces' >expected +" + +test_expect_success TABS_IN_FILENAMES 'git ls-files -z with-funny' \ 'git ls-files -z | perl -pe y/\\000/\\012/ >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' t1=`git write-tree` echo "$t1" >t1 @@ -65,60 +77,78 @@ just space no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git ls-tree with funny' \ +' + +test_expect_success TABS_IN_FILENAMES 'git ls-tree with funny' \ 'git ls-tree -r $t1 | sed -e "s/^[^ ]* //" >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' cat > expected <<\EOF A "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git diff-index with-funny' \ +' + +test_expect_success TABS_IN_FILENAMES 'git diff-index with-funny' \ 'git diff-index --name-status $t0 >current && test_cmp expected current' -test_expect_success 'git diff-tree with-funny' \ +test_expect_success TABS_IN_FILENAMES 'git diff-tree with-funny' \ 'git diff-tree --name-status $t0 $t1 >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' " echo 'A -tabs ," (dq) and spaces' >expected -test_expect_success 'git diff-index -z with-funny' \ +tabs ,\" (dq) and spaces' >expected +" + +test_expect_success TABS_IN_FILENAMES 'git diff-index -z with-funny' \ 'git diff-index -z --name-status $t0 | perl -pe y/\\000/\\012/ >current && test_cmp expected current' -test_expect_success 'git diff-tree -z with-funny' \ +test_expect_success TABS_IN_FILENAMES 'git diff-tree -z with-funny' \ 'git diff-tree -z --name-status $t0 $t1 | perl -pe y/\\000/\\012/ >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' cat > expected <<\EOF CNUM no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git diff-tree -C with-funny' \ +' + +test_expect_success TABS_IN_FILENAMES 'git diff-tree -C with-funny' \ 'git diff-tree -C --find-copies-harder --name-status \ $t0 $t1 | sed -e 's/^C[0-9]*/CNUM/' >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' cat > expected <<\EOF RNUM no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git diff-tree delete with-funny' \ +' + +test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \ 'git update-index --force-remove "$p0" && git diff-index -M --name-status \ $t0 | sed -e 's/^R[0-9]*/RNUM/' >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' cat > expected <<\EOF diff --git a/no-funny "b/tabs\t,\" (dq) and spaces" similarity index NUM% rename from no-funny rename to "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git diff-tree delete with-funny' \ +' + +test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \ 'git diff-index -M -p $t0 | sed -e "s/index [0-9]*%/index NUM%/" >current && test_cmp expected current' -chmod +x "$p1" +test_expect_success TABS_IN_FILENAMES 'setup expect' ' +chmod +x "$p1" && cat > expected <<\EOF diff --git a/no-funny "b/tabs\t,\" (dq) and spaces" old mode 100644 @@ -127,31 +157,39 @@ similarity index NUM% rename from no-funny rename to "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git diff-tree delete with-funny' \ +' + +test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \ 'git diff-index -M -p $t0 | sed -e "s/index [0-9]*%/index NUM%/" >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' cat >expected <<\EOF "tabs\t,\" (dq) and spaces" 1 files changed, 0 insertions(+), 0 deletions(-) EOF -test_expect_success 'git diff-tree rename with-funny applied' \ +' + +test_expect_success TABS_IN_FILENAMES 'git diff-tree rename with-funny applied' \ 'git diff-index -M -p $t0 | git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && test_cmp expected current' +test_expect_success TABS_IN_FILENAMES 'setup expect' ' cat > expected <<\EOF no-funny "tabs\t,\" (dq) and spaces" 2 files changed, 3 insertions(+), 3 deletions(-) EOF -test_expect_success 'git diff-tree delete with-funny applied' \ +' + +test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny applied' \ 'git diff-index -p $t0 | git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && test_cmp expected current' -test_expect_success 'git apply non-git diff' \ +test_expect_success TABS_IN_FILENAMES 'git apply non-git diff' \ 'git diff-index -p $t0 | sed -ne "/^[-+@]/p" | git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 64f32ad94..a2b79a043 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -299,7 +299,7 @@ cat expect-F >> expect-rm-F test_expect_success 'verify note removal with -F /dev/null' ' git log -4 > output && test_cmp expect-rm-F output && - ! git notes show + test_must_fail git notes show ' test_expect_success 'do not create empty note with -m "" (setup)' ' @@ -309,7 +309,7 @@ test_expect_success 'do not create empty note with -m "" (setup)' ' test_expect_success 'verify non-creation of note with -m ""' ' git log -4 > output && test_cmp expect-rm-F output && - ! git notes show + test_must_fail git notes show ' cat > expect-combine_m_and_F << EOF @@ -357,7 +357,7 @@ cat expect-multiline >> expect-rm-remove test_expect_success 'verify note removal with "git notes remove"' ' git log -4 > output && test_cmp expect-rm-remove output && - ! git notes show HEAD^ + test_must_fail git notes show HEAD^ ' cat > expect << EOF @@ -365,6 +365,13 @@ c18dc024e14f08d18d14eea0d747ff692d66d6a3 1584215f1d29c65e99c6c6848626553fdd07fd7 c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 268048bfb8a1fb38e703baceb8ab235421bf80c5 EOF +test_expect_success 'removing non-existing note should not create new commit' ' + git rev-parse --verify refs/notes/commits > before_commit && + test_must_fail git notes remove HEAD^ && + git rev-parse --verify refs/notes/commits > after_commit && + test_cmp before_commit after_commit +' + test_expect_success 'list notes with "git notes list"' ' git notes list > output && test_cmp expect output @@ -693,7 +700,11 @@ test_expect_success 'create note from non-existing note with "git notes add -c" git add a10 && test_tick && git commit -m 10th && - test_must_fail MSG="yet another note" git notes add -c deadbeef && + ( + MSG="yet another note" && + export MSG && + test_must_fail git notes add -c deadbeef + ) && test_must_fail git notes list HEAD ' @@ -1044,4 +1055,10 @@ test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' ' git log -1 > output && test_cmp expect output ' + +test_expect_success 'git notes copy diagnoses too many or too few parameters' ' + test_must_fail git notes copy && + test_must_fail git notes copy one two three +' + test_done diff --git a/t/t3302-notes-index-expensive.sh b/t/t3302-notes-index-expensive.sh index ee84fc488..e35d7811a 100755 --- a/t/t3302-notes-index-expensive.sh +++ b/t/t3302-notes-index-expensive.sh @@ -7,11 +7,9 @@ test_description='Test commit notes index (expensive!)' . ./test-lib.sh -test -z "$GIT_NOTES_TIMING_TESTS" && { - say Skipping timing tests - test_done - exit -} +test_set_prereq NOT_EXPENSIVE +test -n "$GIT_NOTES_TIMING_TESTS" && test_set_prereq EXPENSIVE +test -x /usr/bin/time && test_set_prereq USR_BIN_TIME create_repo () { number_of_commits=$1 @@ -98,21 +96,31 @@ time_notes () { for mode in no-notes notes do echo $mode - /usr/bin/time sh ../time_notes $mode $1 + /usr/bin/time "$SHELL_PATH" ../time_notes $mode $1 done } -for count in 10 100 1000 10000; do +do_tests () { + pr=$1 + count=$2 + + test_expect_success $pr 'setup / mkdir' ' + mkdir $count && + cd $count + ' - mkdir $count - (cd $count; + test_expect_success $pr "setup $count" "create_repo $count" - test_expect_success "setup $count" "create_repo $count" + test_expect_success $pr 'notes work' "test_notes $count" - test_expect_success 'notes work' "test_notes $count" + test_expect_success USR_BIN_TIME,$pr 'notes timing with /usr/bin/time' "time_notes 100" + + test_expect_success $pr 'teardown / cd ..' 'cd ..' +} - test_expect_success 'notes timing' "time_notes 100" - ) +do_tests NOT_EXPENSIVE 10 +for count in 100 1000 10000; do + do_tests EXPENSIVE $count done test_done diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh index b4554041b..c4282179b 100755 --- a/t/t3306-notes-prune.sh +++ b/t/t3306-notes-prune.sh @@ -67,7 +67,7 @@ test_expect_success 'remove some commits' ' test_expect_success 'verify that commits are gone' ' - ! git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && + test_must_fail git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 && git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f ' @@ -106,7 +106,7 @@ test_expect_success 'prune notes' ' test_expect_success 'verify that notes are gone' ' - ! git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && + test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 && git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f ' @@ -130,8 +130,8 @@ test_expect_success 'prune -v notes' ' test_expect_success 'verify that notes are gone' ' - ! git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && - ! git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 && + test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && + test_must_fail git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 && git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f ' diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index d98c7b557..349eebd54 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -14,140 +14,165 @@ GIT_AUTHOR_NAME=author@name GIT_AUTHOR_EMAIL=bogus@email@address export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL -test_expect_success \ - 'prepare repository with topic branches' \ - 'git config core.logAllRefUpdates true && - echo First > A && - git update-index --add A && - git commit -m "Add A." && - git checkout -b my-topic-branch && - echo Second > B && - git update-index --add B && - git commit -m "Add B." && - git checkout -f master && - echo Third >> A && - git update-index A && - git commit -m "Modify A." && - git checkout -b side my-topic-branch && - echo Side >> C && - git add C && - git commit -m "Add C" && - git checkout -b nonlinear my-topic-branch && - echo Edit >> B && - git add B && - git commit -m "Modify B" && - git merge side && - git checkout -b upstream-merged-nonlinear && - git merge master && - git checkout -f my-topic-branch && - git tag topic +test_expect_success 'prepare repository with topic branches' ' + git config core.logAllRefUpdates true && + echo First >A && + git update-index --add A && + git commit -m "Add A." && + git checkout -b force-3way && + echo Dummy >Y && + git update-index --add Y && + git commit -m "Add Y." && + git checkout -b filemove && + git reset --soft master && + mkdir D && + git mv A D/A && + git commit -m "Move A." && + git checkout -b my-topic-branch master && + echo Second >B && + git update-index --add B && + git commit -m "Add B." && + git checkout -f master && + echo Third >>A && + git update-index A && + git commit -m "Modify A." && + git checkout -b side my-topic-branch && + echo Side >>C && + git add C && + git commit -m "Add C" && + git checkout -b nonlinear my-topic-branch && + echo Edit >>B && + git add B && + git commit -m "Modify B" && + git merge side && + git checkout -b upstream-merged-nonlinear && + git merge master && + git checkout -f my-topic-branch && + git tag topic ' test_expect_success 'rebase on dirty worktree' ' - echo dirty >> A && - test_must_fail git rebase master' + echo dirty >>A && + test_must_fail git rebase master +' test_expect_success 'rebase on dirty cache' ' - git add A && - test_must_fail git rebase master' + git add A && + test_must_fail git rebase master +' test_expect_success 'rebase against master' ' - git reset --hard HEAD && - git rebase master' + git reset --hard HEAD && + git rebase master +' test_expect_success 'rebase against master twice' ' - git rebase master >out && - grep "Current branch my-topic-branch is up to date" out + git rebase master >out && + grep "Current branch my-topic-branch is up to date" out ' test_expect_success 'rebase against master twice with --force' ' - git rebase --force-rebase master >out && - grep "Current branch my-topic-branch is up to date, rebase forced" out + git rebase --force-rebase master >out && + grep "Current branch my-topic-branch is up to date, rebase forced" out ' test_expect_success 'rebase against master twice from another branch' ' - git checkout my-topic-branch^ && - git rebase master my-topic-branch >out && - grep "Current branch my-topic-branch is up to date" out + git checkout my-topic-branch^ && + git rebase master my-topic-branch >out && + grep "Current branch my-topic-branch is up to date" out ' test_expect_success 'rebase fast-forward to master' ' - git checkout my-topic-branch^ && - git rebase my-topic-branch >out && - grep "Fast-forwarded HEAD to my-topic-branch" out + git checkout my-topic-branch^ && + git rebase my-topic-branch >out && + grep "Fast-forwarded HEAD to my-topic-branch" out ' -test_expect_success \ - 'the rebase operation should not have destroyed author information' \ - '! (git log | grep "Author:" | grep "<>")' +test_expect_success 'the rebase operation should not have destroyed author information' ' + ! (git log | grep "Author:" | grep "<>") +' -test_expect_success \ - 'the rebase operation should not have destroyed author information (2)' \ - "git log -1 | grep 'Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>'" +test_expect_success 'the rebase operation should not have destroyed author information (2)' " + git log -1 | + grep 'Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>' +" test_expect_success 'HEAD was detached during rebase' ' - test $(git rev-parse HEAD@{1}) != $(git rev-parse my-topic-branch@{1}) + test $(git rev-parse HEAD@{1}) != $(git rev-parse my-topic-branch@{1}) ' test_expect_success 'rebase after merge master' ' - git reset --hard topic && - git merge master && - git rebase master && - ! (git show | grep "^Merge:") + git reset --hard topic && + git merge master && + git rebase master && + ! (git show | grep "^Merge:") ' test_expect_success 'rebase of history with merges is linearized' ' - git checkout nonlinear && - test 4 = $(git rev-list master.. | wc -l) && - git rebase master && - test 3 = $(git rev-list master.. | wc -l) + git checkout nonlinear && + test 4 = $(git rev-list master.. | wc -l) && + git rebase master && + test 3 = $(git rev-list master.. | wc -l) ' -test_expect_success \ - 'rebase of history with merges after upstream merge is linearized' ' - git checkout upstream-merged-nonlinear && - test 5 = $(git rev-list master.. | wc -l) && - git rebase master && - test 3 = $(git rev-list master.. | wc -l) +test_expect_success 'rebase of history with merges after upstream merge is linearized' ' + git checkout upstream-merged-nonlinear && + test 5 = $(git rev-list master.. | wc -l) && + git rebase master && + test 3 = $(git rev-list master.. | wc -l) ' test_expect_success 'rebase a single mode change' ' - git checkout master && - echo 1 > X && - git add X && - test_tick && - git commit -m prepare && - git checkout -b modechange HEAD^ && - echo 1 > X && - git add X && - test_chmod +x A && - test_tick && - git commit -m modechange && - GIT_TRACE=1 git rebase master + git checkout master && + echo 1 >X && + git add X && + test_tick && + git commit -m prepare && + git checkout -b modechange HEAD^ && + echo 1 >X && + git add X && + test_chmod +x A && + test_tick && + git commit -m modechange && + GIT_TRACE=1 git rebase master +' + +test_expect_success 'rebase is not broken by diff.renames' ' + git config diff.renames copies && + test_when_finished "git config --unset diff.renames" && + git checkout filemove && + GIT_TRACE=1 git rebase force-3way +' + +test_expect_success 'setup: recover' ' + test_might_fail git rebase --abort && + git reset --hard && + git checkout modechange ' test_expect_success 'Show verbose error when HEAD could not be detached' ' - : > B && - test_must_fail git rebase topic 2> output.err > output.out && - grep "Untracked working tree file .B. would be overwritten" output.err + >B && + test_must_fail git rebase topic 2>output.err >output.out && + grep "The following untracked working tree files would be overwritten by checkout:" output.err && + grep B output.err ' rm -f B test_expect_success 'dump usage when upstream arg is missing' ' - git checkout -b usage topic && - test_must_fail git rebase 2>error1 && - grep "[Uu]sage" error1 && - test_must_fail git rebase --abort 2>error2 && - grep "No rebase in progress" error2 && - test_must_fail git rebase --onto master 2>error3 && - grep "[Uu]sage" error3 && - ! grep "can.t shift" error3 + git checkout -b usage topic && + test_must_fail git rebase 2>error1 && + grep "[Uu]sage" error1 && + test_must_fail git rebase --abort 2>error2 && + grep "No rebase in progress" error2 && + test_must_fail git rebase --onto master 2>error3 && + grep "[Uu]sage" error3 && + ! grep "can.t shift" error3 ' test_expect_success 'rebase -q is quiet' ' - git checkout -b quiet topic && - git rebase -q master > output.out 2>&1 && - test ! -s output.out + git checkout -b quiet topic && + git rebase -q master >output.out 2>&1 && + test ! -s output.out ' test_expect_success 'Rebase a commit that sprinkles CRs in' ' diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh index 7b7d07269..2bea65634 100755 --- a/t/t3402-rebase-merge.sh +++ b/t/t3402-rebase-merge.sh @@ -74,6 +74,15 @@ test_expect_success 'rebase the other way' ' git rebase --merge side ' +test_expect_success 'rebase -Xtheirs' ' + git checkout -b conflicting master~2 && + echo "AB $T" >> original && + git commit -mconflicting original && + git rebase -Xtheirs master && + grep AB original && + ! grep 11 original +' + test_expect_success 'merge and rebase should match' ' git diff-tree -r test-rebase test-merge >difference && if test -s difference diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index ee9a1b25e..7d20a74c5 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -64,6 +64,67 @@ test_expect_success 'setup' ' done ' +# "exec" commands are ran with the user shell by default, but this may +# be non-POSIX. For example, if SHELL=zsh then ">file" doesn't work +# to create a file. Unseting SHELL avoids such non-portable behavior +# in tests. +SHELL= + +test_expect_success 'rebase -i with the exec command' ' + git checkout master && + ( + FAKE_LINES="1 exec_>touch-one + 2 exec_>touch-two exec_false exec_>touch-three + 3 4 exec_>\"touch-file__name_with_spaces\";_>touch-after-semicolon 5" && + export FAKE_LINES && + test_must_fail git rebase -i A + ) && + test_path_is_file touch-one && + test_path_is_file touch-two && + test_path_is_missing touch-three " (should have stopped before)" && + test $(git rev-parse C) = $(git rev-parse HEAD) || { + echo "Stopped at wrong revision:" + echo "($(git describe --tags HEAD) instead of C)" + false + } && + git rebase --continue && + test_path_is_file touch-three && + test_path_is_file "touch-file name with spaces" && + test_path_is_file touch-after-semicolon && + test $(git rev-parse master) = $(git rev-parse HEAD) || { + echo "Stopped at wrong revision:" + echo "($(git describe --tags HEAD) instead of master)" + false + } && + rm -f touch-* +' + +test_expect_success 'rebase -i with the exec command runs from tree root' ' + git checkout master && + mkdir subdir && (cd subdir && + FAKE_LINES="1 exec_>touch-subdir" \ + git rebase -i HEAD^ + ) && + test_path_is_file touch-subdir && + rm -fr subdir +' + +test_expect_success 'rebase -i with the exec command checks tree cleanness' ' + git checkout master && + ( + FAKE_LINES="exec_echo_foo_>file1 1" && + export FAKE_LINES && + test_must_fail git rebase -i HEAD^ + ) && + test $(git rev-parse master^) = $(git rev-parse HEAD) || { + echo "Stopped at wrong revision:" + echo "($(git describe --tags HEAD) instead of master^)" + false + } && + git reset --hard && + git rebase --continue +' + test_expect_success 'no changes are a nop' ' git checkout branch2 && git rebase -i F && @@ -143,16 +204,17 @@ test_expect_success 'abort' ' git rebase --abort && test $(git rev-parse new-branch1) = $(git rev-parse HEAD) && test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" && - ! test -d .git/rebase-merge + test_path_is_missing .git/rebase-merge ' test_expect_success 'abort with error when new base cannot be checked out' ' git rm --cached file1 && git commit -m "remove file in base" && test_must_fail git rebase -i master > output 2>&1 && - grep "Untracked working tree file .file1. would be overwritten" \ + grep "The following untracked working tree files would be overwritten by checkout:" \ output && - ! test -d .git/rebase-merge && + grep "file1" output && + test_path_is_missing .git/rebase-merge && git reset --hard HEAD^ ' @@ -630,4 +692,28 @@ test_expect_success 'always cherry-pick with --no-ff' ' test_cmp empty out ' +test_expect_success 'set up commits with funny messages' ' + git checkout -b funny A && + echo >>file1 && + test_tick && + git commit -a -m "end with slash\\" && + echo >>file1 && + test_tick && + git commit -a -m "something (\000) that looks like octal" && + echo >>file1 && + test_tick && + git commit -a -m "something (\n) that looks like a newline" && + echo >>file1 && + test_tick && + git commit -a -m "another commit" +' + +test_expect_success 'rebase-i history with funny messages' ' + git rev-list A..funny >expect && + test_tick && + FAKE_LINES="1 2 3 4" git rebase -i A && + git rev-list A.. >actual && + test_cmp expect actual +' + test_done diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh index 2999e7893..fbb3f2e0d 100755 --- a/t/t3407-rebase-abort.sh +++ b/t/t3407-rebase-abort.sh @@ -38,7 +38,7 @@ testrebase() { # Clean up the state from the previous one git reset --hard pre-rebase && test_must_fail git rebase$type master && - test -d "$dotest" && + test_path_is_dir "$dotest" && git rebase --abort && test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) && test ! -d "$dotest" @@ -49,7 +49,7 @@ testrebase() { # Clean up the state from the previous one git reset --hard pre-rebase && test_must_fail git rebase$type master && - test -d "$dotest" && + test_path_is_dir "$dotest" && test_must_fail git rebase --skip && test $(git rev-parse HEAD) = $(git rev-parse master) && git rebase --abort && @@ -62,7 +62,7 @@ testrebase() { # Clean up the state from the previous one git reset --hard pre-rebase && test_must_fail git rebase$type master && - test -d "$dotest" && + test_path_is_dir "$dotest" && echo c > a && echo d >> a && git add a && diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh index 8f785e795..74161a42e 100755 --- a/t/t3409-rebase-preserve-merges.sh +++ b/t/t3409-rebase-preserve-merges.sh @@ -42,23 +42,24 @@ test_expect_success 'setup for merge-preserving rebase' \ git commit -a -m "Modify A2" && git clone ./. clone1 && - cd clone1 && + (cd clone1 && git checkout -b topic origin/topic && - git merge origin/master && - cd .. && + git merge origin/master + ) && echo Fifth > B && git add B && git commit -m "Add different B" && git clone ./. clone2 && - cd clone2 && - git checkout -b topic origin/topic && - test_must_fail git merge origin/master && - echo Resolved > B && - git add B && - git commit -m "Merge origin/master into topic" && - cd .. && + ( + cd clone2 && + git checkout -b topic origin/topic && + test_must_fail git merge origin/master && + echo Resolved >B && + git add B && + git commit -m "Merge origin/master into topic" + ) && git checkout topic && echo Fourth >> B && diff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh index c49143a1a..6f73b9555 100755 --- a/t/t3410-rebase-preserve-dropped-merges.sh +++ b/t/t3410-rebase-preserve-dropped-merges.sh @@ -43,11 +43,11 @@ test_expect_success 'setup' ' # G2 = same changes as G test_expect_success 'skip same-resolution merges with -p' ' git checkout H && - ! git merge E && + test_must_fail git merge E && test_commit L file1 23 && git checkout I && test_commit G2 file1 3 && - ! git merge E && + test_must_fail git merge E && test_commit J file1 23 && test_commit K file7 file7 && git rebase -i -p L && @@ -65,11 +65,11 @@ test_expect_success 'skip same-resolution merges with -p' ' # G2 = different changes as G test_expect_success 'keep different-resolution merges with -p' ' git checkout H && - ! git merge E && + test_must_fail git merge E && test_commit L2 file1 23 && git checkout I && test_commit G3 file1 4 && - ! git merge E && + test_must_fail git merge E && test_commit J2 file1 24 && test_commit K2 file7 file7 && test_must_fail git rebase -i -p L2 && diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index b63f4e2d6..fd2184ce7 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -21,38 +21,62 @@ test_expect_success setup ' git tag base ' -test_expect_success 'auto fixup' ' +test_auto_fixup() { git reset --hard base && echo 1 >file1 && git add -u && test_tick && - git commit -m "fixup! first" + git commit -m "fixup! first" && - git tag final-fixup && + git tag $1 && test_tick && - git rebase --autosquash -i HEAD^^^ && + git rebase $2 -i HEAD^^^ && git log --oneline >actual && test 3 = $(wc -l <actual) && - git diff --exit-code final-fixup && + git diff --exit-code $1 && test 1 = "$(git cat-file blob HEAD^:file1)" && test 1 = $(git cat-file commit HEAD^ | grep first | wc -l) +} + +test_expect_success 'auto fixup (option)' ' + test_auto_fixup final-fixup-option --autosquash +' + +test_expect_success 'auto fixup (config)' ' + git config rebase.autosquash true && + test_auto_fixup final-fixup-config-true && + test_must_fail test_auto_fixup fixup-config-true-no --no-autosquash && + git config rebase.autosquash false && + test_must_fail test_auto_fixup final-fixup-config-false ' -test_expect_success 'auto squash' ' +test_auto_squash() { git reset --hard base && echo 1 >file1 && git add -u && test_tick && - git commit -m "squash! first" + git commit -m "squash! first" && - git tag final-squash && + git tag $1 && test_tick && - git rebase --autosquash -i HEAD^^^ && + git rebase $2 -i HEAD^^^ && git log --oneline >actual && test 3 = $(wc -l <actual) && - git diff --exit-code final-squash && + git diff --exit-code $1 && test 1 = "$(git cat-file blob HEAD^:file1)" && test 2 = $(git cat-file commit HEAD^ | grep first | wc -l) +} + +test_expect_success 'auto squash (option)' ' + test_auto_squash final-squash --autosquash +' + +test_expect_success 'auto squash (config)' ' + git config rebase.autosquash true && + test_auto_squash final-squash-config-true && + test_must_fail test_auto_squash squash-config-true-no --no-autosquash && + git config rebase.autosquash false && + test_must_fail test_auto_squash final-squash-config-false ' test_expect_success 'misspelled auto squash' ' @@ -60,7 +84,7 @@ test_expect_success 'misspelled auto squash' ' echo 1 >file1 && git add -u && test_tick && - git commit -m "squash! forst" + git commit -m "squash! forst" && git tag final-missquash && test_tick && git rebase --autosquash -i HEAD^^^ && diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh new file mode 100755 index 000000000..3b0d27350 --- /dev/null +++ b/t/t3418-rebase-continue.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +test_description='git rebase --continue tests' + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/lib-rebase.sh + +set_fake_editor + +test_expect_success 'setup' ' + test_commit "commit-new-file-F1" F1 1 && + test_commit "commit-new-file-F2" F2 2 && + + git checkout -b topic HEAD^ && + test_commit "commit-new-file-F2-on-topic-branch" F2 22 && + + git checkout master +' + +test_expect_success 'interactive rebase --continue works with touched file' ' + rm -fr .git/rebase-* && + git reset --hard && + git checkout master && + + FAKE_LINES="edit 1" git rebase -i HEAD^ && + test-chmtime =-60 F1 && + git rebase --continue +' + +test_expect_success 'non-interactive rebase --continue works with touched file' ' + rm -fr .git/rebase-* && + git reset --hard && + git checkout master && + + test_must_fail git rebase --onto master master topic && + echo "Resolved" >F2 && + git add F2 && + test-chmtime =-60 F1 && + git rebase --continue +' + +test_done diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index e4fbf7a21..bc7aedd04 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -41,6 +41,24 @@ test_expect_success setup ' git tag rename2 ' +test_expect_success 'cherry-pick --nonsense' ' + + pos=$(git rev-parse HEAD) && + git diff --exit-code HEAD && + test_must_fail git cherry-pick --nonsense 2>msg && + git diff --exit-code HEAD "$pos" && + grep '[Uu]sage:' msg +' + +test_expect_success 'revert --nonsense' ' + + pos=$(git rev-parse HEAD) && + git diff --exit-code HEAD && + test_must_fail git revert --nonsense 2>msg && + git diff --exit-code HEAD "$pos" && + grep '[Uu]sage:' msg +' + test_expect_success 'cherry-pick after renaming branch' ' git checkout rename2 && diff --git a/t/t3505-cherry-pick-empty.sh b/t/t3505-cherry-pick-empty.sh index e51e505a9..c10b28cf5 100755 --- a/t/t3505-cherry-pick-empty.sh +++ b/t/t3505-cherry-pick-empty.sh @@ -13,12 +13,30 @@ test_expect_success setup ' git checkout -b empty-branch && test_tick && - git commit --allow-empty -m "empty" + git commit --allow-empty -m "empty" && + + echo third >> file1 && + git add file1 && + test_tick && + git commit --allow-empty-message -m "" ' test_expect_success 'cherry-pick an empty commit' ' git checkout master && { + git cherry-pick empty-branch^ + test "$?" = 1 + } +' + +test_expect_success 'index lockfile was removed' ' + + test ! -f .git/index.lock + +' + +test_expect_success 'cherry-pick a commit with an empty message' ' + git checkout master && { git cherry-pick empty-branch test "$?" = 1 } diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh index e17ae712b..51ca391e4 100755 --- a/t/t3506-cherry-pick-ff.sh +++ b/t/t3506-cherry-pick-ff.sh @@ -95,4 +95,14 @@ test_expect_success 'cherry pick a merge relative to nonexistent parent with --f test_must_fail git cherry-pick --ff -m 3 C ' +test_expect_success 'cherry pick a root commit with --ff' ' + git reset --hard first -- && + git rm file1 && + echo first >file2 && + git add file2 && + git commit --amend -m "file2" && + git cherry-pick --ff first && + test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1" +' + test_done diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index e25cf8039..607bf25d8 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -38,6 +38,26 @@ test_expect_success 'failed cherry-pick does not advance HEAD' ' test "$head" = "$newhead" ' +test_expect_success 'advice from failed cherry-pick' " + git checkout -f initial^0 && + git read-tree -u --reset HEAD && + git clean -d -f -f -q -x && + + git update-index --refresh && + git diff-index --exit-code HEAD && + + picked=\$(git rev-parse --short picked) && + cat <<-EOF >expected && + error: could not apply \$picked... picked + hint: after resolving the conflicts, mark the corrected paths + hint: with 'git add <paths>' or 'git rm <paths>' + hint: and commit the result with 'git commit -c \$picked' + EOF + test_must_fail git cherry-pick picked 2>actual && + + test_cmp expected actual +" + test_expect_success 'failed cherry-pick produces dirty index' ' git checkout -f initial^0 && diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh index 3b87efe3a..8e09fd031 100755 --- a/t/t3508-cherry-pick-many-commits.sh +++ b/t/t3508-cherry-pick-many-commits.sh @@ -4,6 +4,18 @@ test_description='test cherry-picking many commits' . ./test-lib.sh +check_head_differs_from() { + head=$(git rev-parse --verify HEAD) && + arg=$(git rev-parse --verify "$1") && + test "$head" != "$arg" +} + +check_head_equals() { + head=$(git rev-parse --verify HEAD) && + arg=$(git rev-parse --verify "$1") && + test "$head" = "$arg" +} + test_expect_success setup ' echo first > file1 && git add file1 && @@ -23,27 +35,69 @@ test_expect_success setup ' ' test_expect_success 'cherry-pick first..fourth works' ' - git checkout master && + cat <<-\EOF >expected && + [master OBJID] second + Author: A U Thor <author@example.com> + 1 files changed, 1 insertions(+), 0 deletions(-) + [master OBJID] third + Author: A U Thor <author@example.com> + 1 files changed, 1 insertions(+), 0 deletions(-) + [master OBJID] fourth + Author: A U Thor <author@example.com> + 1 files changed, 1 insertions(+), 0 deletions(-) + EOF + + git checkout -f master && git reset --hard first && test_tick && - git cherry-pick first..fourth && + git cherry-pick first..fourth >actual && git diff --quiet other && git diff --quiet HEAD other && - test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)" + + sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy && + test_cmp expected actual.fuzzy && + check_head_differs_from fourth +' + +test_expect_success 'cherry-pick --strategy resolve first..fourth works' ' + cat <<-\EOF >expected && + Trying simple merge. + [master OBJID] second + Author: A U Thor <author@example.com> + 1 files changed, 1 insertions(+), 0 deletions(-) + Trying simple merge. + [master OBJID] third + Author: A U Thor <author@example.com> + 1 files changed, 1 insertions(+), 0 deletions(-) + Trying simple merge. + [master OBJID] fourth + Author: A U Thor <author@example.com> + 1 files changed, 1 insertions(+), 0 deletions(-) + EOF + + git checkout -f master && + git reset --hard first && + test_tick && + git cherry-pick --strategy resolve first..fourth >actual && + git diff --quiet other && + git diff --quiet HEAD other && + sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy && + test_cmp expected actual.fuzzy && + check_head_differs_from fourth ' test_expect_success 'cherry-pick --ff first..fourth works' ' - git checkout master && + git checkout -f master && git reset --hard first && test_tick && git cherry-pick --ff first..fourth && git diff --quiet other && git diff --quiet HEAD other && - test "$(git rev-parse --verify HEAD)" = "$(git rev-parse --verify fourth)" + check_head_equals fourth ' test_expect_success 'cherry-pick -n first..fourth works' ' - git checkout master && + git checkout -f master && git reset --hard first && test_tick && git cherry-pick -n first..fourth && @@ -53,7 +107,7 @@ test_expect_success 'cherry-pick -n first..fourth works' ' ' test_expect_success 'revert first..fourth works' ' - git checkout master && + git checkout -f master && git reset --hard fourth && test_tick && git revert first..fourth && @@ -63,7 +117,7 @@ test_expect_success 'revert first..fourth works' ' ' test_expect_success 'revert ^first fourth works' ' - git checkout master && + git checkout -f master && git reset --hard fourth && test_tick && git revert ^first fourth && @@ -73,7 +127,7 @@ test_expect_success 'revert ^first fourth works' ' ' test_expect_success 'revert fourth fourth~1 fourth~2 works' ' - git checkout master && + git checkout -f master && git reset --hard fourth && test_tick && git revert fourth fourth~1 fourth~2 && @@ -82,14 +136,24 @@ test_expect_success 'revert fourth fourth~1 fourth~2 works' ' git diff --quiet HEAD first ' -test_expect_failure 'cherry-pick -3 fourth works' ' - git checkout master && +test_expect_success 'cherry-pick -3 fourth works' ' + git checkout -f master && git reset --hard first && test_tick && git cherry-pick -3 fourth && git diff --quiet other && git diff --quiet HEAD other && - test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)" + check_head_differs_from fourth +' + +test_expect_success 'cherry-pick --stdin works' ' + git checkout -f master && + git reset --hard first && + test_tick && + git rev-list --reverse first..fourth | git cherry-pick --stdin && + git diff --quiet other && + git diff --quiet HEAD other && + check_head_differs_from fourth ' test_done diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh new file mode 100755 index 000000000..a5ccdbf8f --- /dev/null +++ b/t/t3509-cherry-pick-merge-df.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +test_description='Test cherry-pick with directory/file conflicts' +. ./test-lib.sh + +test_expect_success SYMLINKS 'Setup rename across paths each below D/F conflicts' ' + mkdir a && + >a/f && + git add a && + git commit -m a && + + mkdir b && + ln -s ../a b/a && + git add b && + git commit -m b && + + git checkout -b branch && + rm b/a && + mv a b/a && + ln -s b/a a && + git add . && + git commit -m swap && + + >f1 && + git add f1 && + git commit -m f1 +' + +test_expect_success SYMLINKS 'Cherry-pick succeeds with rename across D/F conflicts' ' + git reset --hard && + git checkout master^0 && + git cherry-pick branch +' + +test_done diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 0aaf0ad84..b26cabd57 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -28,22 +28,6 @@ embedded' && git commit -m 'add files with tabs and newlines' " -# Determine rm behavior -# Later we will try removing an unremovable path to make sure -# git rm barfs, but if the test is run as root that cannot be -# arranged. -: >test-file -chmod a-w . -rm -f test-file 2>/dev/null -if test -f test-file -then - test_set_prereq RO_DIR -else - say 'skipping removal failure test (perhaps running as root?)' -fi -chmod 775 . -rm -f test-file - test_expect_success \ 'Pre-check that foo exists and is in index before git rm foo' \ '[ -f foo ] && git ls-files --error-unmatch foo' diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 525c9a8fd..ec7108358 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -26,7 +26,7 @@ test_expect_success \ chmod 755 xfoo1 && git add xfoo1 && case "`git ls-files --stage xfoo1`" in - 100644" "*xfoo1) echo ok;; + 100644" "*xfoo1) echo pass;; *) echo fail; git ls-files --stage xfoo1; (exit 1);; esac' @@ -35,7 +35,7 @@ test_expect_success SYMLINKS 'git add: filemode=0 should not get confused by sym ln -s foo xfoo1 && git add xfoo1 && case "`git ls-files --stage xfoo1`" in - 120000" "*xfoo1) echo ok;; + 120000" "*xfoo1) echo pass;; *) echo fail; git ls-files --stage xfoo1; (exit 1);; esac ' @@ -47,7 +47,7 @@ test_expect_success \ chmod 755 xfoo2 && git update-index --add xfoo2 && case "`git ls-files --stage xfoo2`" in - 100644" "*xfoo2) echo ok;; + 100644" "*xfoo2) echo pass;; *) echo fail; git ls-files --stage xfoo2; (exit 1);; esac' @@ -56,7 +56,7 @@ test_expect_success SYMLINKS 'git add: filemode=0 should not get confused by sym ln -s foo xfoo2 && git update-index --add xfoo2 && case "`git ls-files --stage xfoo2`" in - 120000" "*xfoo2) echo ok;; + 120000" "*xfoo2) echo pass;; *) echo fail; git ls-files --stage xfoo2; (exit 1);; esac ' @@ -67,7 +67,7 @@ test_expect_success SYMLINKS \ ln -s xfoo2 xfoo3 && git update-index --add xfoo3 && case "`git ls-files --stage xfoo3`" in - 120000" "*xfoo3) echo ok;; + 120000" "*xfoo3) echo pass;; *) echo fail; git ls-files --stage xfoo3; (exit 1);; esac' @@ -172,14 +172,14 @@ test_expect_success 'git add --refresh' ' test -z "`git diff-index HEAD -- foo`" && git read-tree HEAD && case "`git diff-index HEAD -- foo`" in - :100644" "*"M foo") echo ok;; + :100644" "*"M foo") echo pass;; *) echo fail; (exit 1);; esac && git add --refresh -- foo && test -z "`git diff-index HEAD -- foo`" ' -test_expect_success POSIXPERM 'git add should fail atomically upon an unreadable file' ' +test_expect_success POSIXPERM,SANITY 'git add should fail atomically upon an unreadable file' ' git reset --hard && date >foo1 && date >foo2 && @@ -190,7 +190,7 @@ test_expect_success POSIXPERM 'git add should fail atomically upon an unreadable rm -f foo2 -test_expect_success POSIXPERM 'git add --ignore-errors' ' +test_expect_success POSIXPERM,SANITY 'git add --ignore-errors' ' git reset --hard && date >foo1 && date >foo2 && @@ -201,7 +201,7 @@ test_expect_success POSIXPERM 'git add --ignore-errors' ' rm -f foo2 -test_expect_success POSIXPERM 'git add (add.ignore-errors)' ' +test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors)' ' git config add.ignore-errors 1 && git reset --hard && date >foo1 && @@ -212,7 +212,7 @@ test_expect_success POSIXPERM 'git add (add.ignore-errors)' ' ' rm -f foo2 -test_expect_success POSIXPERM 'git add (add.ignore-errors = false)' ' +test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors = false)' ' git config add.ignore-errors 0 && git reset --hard && date >foo1 && @@ -223,7 +223,7 @@ test_expect_success POSIXPERM 'git add (add.ignore-errors = false)' ' ' rm -f foo2 -test_expect_success POSIXPERM '--no-ignore-errors overrides config' ' +test_expect_success POSIXPERM,SANITY '--no-ignore-errors overrides config' ' git config add.ignore-errors 1 && git reset --hard && date >foo1 && @@ -260,4 +260,32 @@ test_expect_success '"add non-existent" should fail' ' ! (git ls-files | grep "non-existent") ' +test_expect_success 'git add --dry-run of existing changed file' " + echo new >>track-this && + git add --dry-run track-this >actual 2>&1 && + echo \"add 'track-this'\" | test_cmp - actual +" + +test_expect_success 'git add --dry-run of non-existing file' " + echo ignored-file >>.gitignore && + test_must_fail git add --dry-run track-this ignored-file >actual 2>&1 && + echo \"fatal: pathspec 'ignored-file' did not match any files\" | test_cmp - actual +" + +cat >expect.err <<\EOF +The following paths are ignored by one of your .gitignore files: +ignored-file +Use -f if you really want to add them. +fatal: no files added +EOF +cat >expect.out <<\EOF +add 'track-this' +EOF + +test_expect_success 'git add --dry-run --ignore-missing of non-existing file' ' + test_must_fail git add --dry-run --ignore-missing track-this ignored-file >actual.out 2>actual.err && + test_cmp expect.out actual.out && + test_cmp expect.err actual.err +' + test_done diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b6eba6a83..d6327e7c7 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -2,22 +2,20 @@ test_description='add -i basic tests' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh -if ! test_have_prereq PERL; then - say 'skipping git add -i tests, perl not available' - test_done -fi - -test_expect_success 'setup (initial)' ' +test_expect_success PERL 'setup (initial)' ' echo content >file && git add file && echo more >>file && echo lines >>file ' -test_expect_success 'status works (initial)' ' +test_expect_success PERL 'status works (initial)' ' git add -i </dev/null >output && grep "+1/-0 *+2/-0 file" output ' + +test_expect_success PERL 'setup expected' ' cat >expected <<EOF new file mode 100644 index 0000000..d95f3ad @@ -26,19 +24,21 @@ index 0000000..d95f3ad @@ -0,0 +1 @@ +content EOF -test_expect_success 'diff works (initial)' ' +' + +test_expect_success PERL 'diff works (initial)' ' (echo d; echo 1) | git add -i >output && sed -ne "/new file/,/content/p" <output >diff && test_cmp expected diff ' -test_expect_success 'revert works (initial)' ' +test_expect_success PERL 'revert works (initial)' ' git add file && (echo r; echo 1) | git add -i && git ls-files >output && ! grep . output ' -test_expect_success 'setup (commit)' ' +test_expect_success PERL 'setup (commit)' ' echo baseline >file && git add file && git commit -m commit && @@ -47,10 +47,12 @@ test_expect_success 'setup (commit)' ' echo more >>file && echo lines >>file ' -test_expect_success 'status works (commit)' ' +test_expect_success PERL 'status works (commit)' ' git add -i </dev/null >output && grep "+1/-0 *+2/-0 file" output ' + +test_expect_success PERL 'setup expected' ' cat >expected <<EOF index 180b47c..b6f2c08 100644 --- a/file @@ -59,60 +61,79 @@ index 180b47c..b6f2c08 100644 baseline +content EOF -test_expect_success 'diff works (commit)' ' +' + +test_expect_success PERL 'diff works (commit)' ' (echo d; echo 1) | git add -i >output && sed -ne "/^index/,/content/p" <output >diff && test_cmp expected diff ' -test_expect_success 'revert works (commit)' ' +test_expect_success PERL 'revert works (commit)' ' git add file && (echo r; echo 1) | git add -i && git add -i </dev/null >output && grep "unchanged *+3/-0 file" output ' + +test_expect_success PERL 'setup expected' ' cat >expected <<EOF EOF -cat >fake_editor.sh <<EOF -EOF -chmod a+x fake_editor.sh -test_set_editor "$(pwd)/fake_editor.sh" -test_expect_success 'dummy edit works' ' +' + +test_expect_success PERL 'setup fake editor' ' + cat >fake_editor.sh <<EOF + EOF + chmod a+x fake_editor.sh && + test_set_editor "$(pwd)/fake_editor.sh" && +' + +test_expect_success PERL 'dummy edit works' ' (echo e; echo a) | git add -p && git diff > diff && test_cmp expected diff ' +test_expect_success PERL 'setup patch' ' cat >patch <<EOF @@ -1,1 +1,4 @@ this +patch --doesn't +-does not apply EOF -echo "#!$SHELL_PATH" >fake_editor.sh -cat >>fake_editor.sh <<\EOF +' + +test_expect_success PERL 'setup fake editor' ' + echo "#!$SHELL_PATH" >fake_editor.sh && + cat >>fake_editor.sh <<\EOF && mv -f "$1" oldpatch && mv -f patch "$1" EOF -chmod a+x fake_editor.sh -test_set_editor "$(pwd)/fake_editor.sh" -test_expect_success 'bad edit rejected' ' + chmod a+x fake_editor.sh && + test_set_editor "$(pwd)/fake_editor.sh" +' + +test_expect_success PERL 'bad edit rejected' ' git reset && (echo e; echo n; echo d) | git add -p >output && grep "hunk does not apply" output ' +test_expect_success PERL 'setup patch' ' cat >patch <<EOF this patch is garbage EOF -test_expect_success 'garbage edit rejected' ' +' + +test_expect_success PERL 'garbage edit rejected' ' git reset && (echo e; echo n; echo d) | git add -p >output && grep "hunk does not apply" output ' +test_expect_success PERL 'setup patch' ' cat >patch <<EOF @@ -1,0 +1,0 @@ baseline @@ -120,6 +141,9 @@ cat >patch <<EOF +newcontent +lines EOF +' + +test_expect_success PERL 'setup expected' ' cat >expected <<EOF diff --git a/file b/file index b5dd6c9..f910ae9 100644 @@ -132,13 +156,15 @@ index b5dd6c9..f910ae9 100644 +more lines EOF -test_expect_success 'real edit works' ' +' + +test_expect_success PERL 'real edit works' ' (echo e; echo n; echo d) | git add -p && git diff >output && test_cmp expected output ' -test_expect_success 'skip files similarly as commit -a' ' +test_expect_success PERL 'skip files similarly as commit -a' ' git reset && echo file >.gitignore && echo changed >file && @@ -152,14 +178,7 @@ test_expect_success 'skip files similarly as commit -a' ' ' rm -f .gitignore -if test "$(git config --bool core.filemode)" = false -then - say 'skipping filemode tests (filesystem does not properly support modes)' -else - test_set_prereq FILEMODE -fi - -test_expect_success FILEMODE 'patch does not affect mode' ' +test_expect_success PERL,FILEMODE 'patch does not affect mode' ' git reset --hard && echo content >>file && chmod +x file && @@ -168,7 +187,7 @@ test_expect_success FILEMODE 'patch does not affect mode' ' git diff file | grep "new mode" ' -test_expect_success FILEMODE 'stage mode but not hunk' ' +test_expect_success PERL,FILEMODE 'stage mode but not hunk' ' git reset --hard && echo content >>file && chmod +x file && @@ -178,7 +197,7 @@ test_expect_success FILEMODE 'stage mode but not hunk' ' ' -test_expect_success FILEMODE 'stage mode and hunk' ' +test_expect_success PERL,FILEMODE 'stage mode and hunk' ' git reset --hard && echo content >>file && chmod +x file && @@ -190,13 +209,14 @@ test_expect_success FILEMODE 'stage mode and hunk' ' # end of tests disabled when filemode is not usable -test_expect_success 'setup again' ' +test_expect_success PERL 'setup again' ' git reset --hard && test_chmod +x file && echo content >>file ' # Write the patch file with a new line at the top and bottom +test_expect_success PERL 'setup patch' ' cat >patch <<EOF index 180b47c..b6f2c08 100644 --- a/file @@ -207,7 +227,10 @@ index 180b47c..b6f2c08 100644 content +lastline EOF +' + # Expected output, similar to the patch but w/ diff at the top +test_expect_success PERL 'setup expected' ' cat >expected <<EOF diff --git a/file b/file index b6f2c08..61b9053 100755 @@ -219,8 +242,10 @@ index b6f2c08..61b9053 100755 content +lastline EOF +' + # Test splitting the first patch, then adding both -test_expect_success 'add first line works' ' +test_expect_success PERL 'add first line works' ' git commit -am "clear local changes" && git apply patch && (echo s; echo y; echo y) | git add -p file && @@ -228,6 +253,7 @@ test_expect_success 'add first line works' ' test_cmp expected diff ' +test_expect_success PERL 'setup expected' ' cat >expected <<EOF diff --git a/non-empty b/non-empty deleted file mode 100644 @@ -237,7 +263,9 @@ index d95f3ad..0000000 @@ -1 +0,0 @@ -content EOF -test_expect_success 'deleting a non-empty file' ' +' + +test_expect_success PERL 'deleting a non-empty file' ' git reset --hard && echo content >non-empty && git add non-empty && @@ -248,13 +276,15 @@ test_expect_success 'deleting a non-empty file' ' test_cmp expected diff ' +test_expect_success PERL 'setup expected' ' cat >expected <<EOF diff --git a/empty b/empty deleted file mode 100644 index e69de29..0000000 EOF +' -test_expect_success 'deleting an empty file' ' +test_expect_success PERL 'deleting an empty file' ' git reset --hard && > empty && git add empty && diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh index 29103f65d..7d4946984 100755 --- a/t/t3902-quoted.sh +++ b/t/t3902-quoted.sh @@ -15,11 +15,13 @@ LF=' DQ='"' echo foo 2>/dev/null > "Name and an${HT}HT" -test -f "Name and an${HT}HT" || { - # since FAT/NTFS does not allow tabs in filenames, skip this test - say 'Your filesystem does not allow tabs in filenames, test skipped.' - test_done -} +if ! test -f "Name and an${HT}HT" +then + # FAT/NTFS does not allow tabs in filenames + say 'Your filesystem does not allow tabs in filenames' +else + test_set_prereq TABS_IN_FILENAMES +fi for_each_name () { for name in \ @@ -31,7 +33,7 @@ for_each_name () { done } -test_expect_success setup ' +test_expect_success TABS_IN_FILENAMES 'setup' ' mkdir "$FN" && for_each_name "echo initial >\"\$name\"" @@ -45,6 +47,7 @@ test_expect_success setup ' ' +test_expect_success TABS_IN_FILENAMES 'setup expected files' ' cat >expect.quoted <<\EOF Name "Name and a\nLF" @@ -72,75 +75,76 @@ With SP in it 濱野/file 濱野純 EOF +' -test_expect_success 'check fully quoted output from ls-files' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-files' ' git ls-files >current && test_cmp expect.quoted current ' -test_expect_success 'check fully quoted output from diff-files' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-files' ' git diff --name-only >current && test_cmp expect.quoted current ' -test_expect_success 'check fully quoted output from diff-index' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-index' ' git diff --name-only HEAD >current && test_cmp expect.quoted current ' -test_expect_success 'check fully quoted output from diff-tree' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-tree' ' git diff --name-only HEAD^ HEAD >current && test_cmp expect.quoted current ' -test_expect_success 'check fully quoted output from ls-tree' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-tree' ' git ls-tree --name-only -r HEAD >current && test_cmp expect.quoted current ' -test_expect_success 'setting core.quotepath' ' +test_expect_success TABS_IN_FILENAMES 'setting core.quotepath' ' git config --bool core.quotepath false ' -test_expect_success 'check fully quoted output from ls-files' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-files' ' git ls-files >current && test_cmp expect.raw current ' -test_expect_success 'check fully quoted output from diff-files' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-files' ' git diff --name-only >current && test_cmp expect.raw current ' -test_expect_success 'check fully quoted output from diff-index' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-index' ' git diff --name-only HEAD >current && test_cmp expect.raw current ' -test_expect_success 'check fully quoted output from diff-tree' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-tree' ' git diff --name-only HEAD^ HEAD >current && test_cmp expect.raw current ' -test_expect_success 'check fully quoted output from ls-tree' ' +test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-tree' ' git ls-tree --name-only -r HEAD >current && test_cmp expect.raw current diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 62e208aad..903a122ef 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -69,9 +69,10 @@ test_expect_success 'apply stashed changes (including index)' ' test_expect_success 'unstashing in a subdirectory' ' git reset --hard HEAD && mkdir subdir && - cd subdir && - git stash apply && - cd .. + ( + cd subdir && + git stash apply + ) ' test_expect_success 'drop top stash' ' @@ -378,4 +379,181 @@ test_expect_failure 'stash file to directory' ' test foo = "$(cat file/file)" ' +test_expect_success 'stash branch - no stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + STASH_ID=$(git stash create) && + git reset --hard && + git stash branch stash-branch ${STASH_ID} && + test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" && + test $(git ls-files --modified | wc -l) -eq 1 +' + +test_expect_success 'stash branch - stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + git stash && + test_when_finished "git stash drop" && + echo bar >> file && + STASH_ID=$(git stash create) && + git reset --hard && + git stash branch stash-branch ${STASH_ID} && + test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" && + test $(git ls-files --modified | wc -l) -eq 1 +' + +test_expect_success 'stash show - stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + git stash && + test_when_finished "git stash drop" && + echo bar >> file && + STASH_ID=$(git stash create) && + git reset --hard && + cat >expected <<-EOF && + file | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + EOF + git stash show ${STASH_ID} >actual && + test_cmp expected actual +' + +test_expect_success 'stash show -p - stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + git stash && + test_when_finished "git stash drop" && + echo bar >> file && + STASH_ID=$(git stash create) && + git reset --hard && + cat >expected <<-EOF && + diff --git a/file b/file + index 7601807..935fbd3 100644 + --- a/file + +++ b/file + @@ -1 +1,2 @@ + baz + +bar + EOF + git stash show -p ${STASH_ID} >actual && + test_cmp expected actual +' + +test_expect_success 'stash show - no stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + STASH_ID=$(git stash create) && + git reset --hard && + cat >expected <<-EOF && + file | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + EOF + git stash show ${STASH_ID} >actual && + test_cmp expected actual +' + +test_expect_success 'stash show -p - no stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + STASH_ID=$(git stash create) && + git reset --hard && + cat >expected <<-EOF && + diff --git a/file b/file + index 7601807..71b52c4 100644 + --- a/file + +++ b/file + @@ -1 +1,2 @@ + baz + +foo + EOF + git stash show -p ${STASH_ID} >actual && + test_cmp expected actual +' + +test_expect_success 'stash drop - fail early if specified stash is not a stash reference' ' + git stash clear && + test_when_finished "git reset --hard HEAD && git stash clear" && + git reset --hard && + echo foo > file && + git stash && + echo bar > file && + git stash && + test_must_fail git stash drop $(git rev-parse stash@{0}) && + git stash pop && + test bar = "$(cat file)" && + git reset --hard HEAD +' + +test_expect_success 'stash pop - fail early if specified stash is not a stash reference' ' + git stash clear && + test_when_finished "git reset --hard HEAD && git stash clear" && + git reset --hard && + echo foo > file && + git stash && + echo bar > file && + git stash && + test_must_fail git stash pop $(git rev-parse stash@{0}) && + git stash pop && + test bar = "$(cat file)" && + git reset --hard HEAD +' + +test_expect_success 'ref with non-existant reflog' ' + git stash clear && + echo bar5 > file && + echo bar6 > file2 && + git add file2 && + git stash && + ! "git rev-parse --quiet --verify does-not-exist" && + test_must_fail git stash drop does-not-exist && + test_must_fail git stash drop does-not-exist@{0} && + test_must_fail git stash pop does-not-exist && + test_must_fail git stash pop does-not-exist@{0} && + test_must_fail git stash apply does-not-exist && + test_must_fail git stash apply does-not-exist@{0} && + test_must_fail git stash show does-not-exist && + test_must_fail git stash show does-not-exist@{0} && + test_must_fail git stash branch tmp does-not-exist && + test_must_fail git stash branch tmp does-not-exist@{0} && + git stash drop +' + +test_expect_success 'invalid ref of the form stash@{n}, n >= N' ' + git stash clear && + test_must_fail git stash drop stash@{0} && + echo bar5 > file && + echo bar6 > file2 && + git add file2 && + git stash && + test_must_fail git drop stash@{1} && + test_must_fail git pop stash@{1} && + test_must_fail git apply stash@{1} && + test_must_fail git show stash@{1} && + test_must_fail git branch tmp stash@{1} && + git stash drop +' + +test_expect_success 'stash branch should not drop the stash if the branch exists' ' + git stash clear && + echo foo >file && + git add file && + git commit -m initial && + echo bar >file && + git stash && + test_must_fail git stash branch master stash@{0} && + git rev-parse stash@{0} -- +' + test_done diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh index f37e3bc6e..d1819ca23 100755 --- a/t/t3904-stash-patch.sh +++ b/t/t3904-stash-patch.sh @@ -3,7 +3,7 @@ test_description='git checkout --patch' . ./lib-patch-mode.sh -test_expect_success 'setup' ' +test_expect_success PERL 'setup' ' mkdir dir && echo parent > dir/foo && echo dummy > bar && @@ -19,14 +19,14 @@ test_expect_success 'setup' ' # note: bar sorts before dir, so the first 'n' is always to skip 'bar' -test_expect_success 'saying "n" does nothing' ' +test_expect_success PERL 'saying "n" does nothing' ' set_state dir/foo work index (echo n; echo n) | test_must_fail git stash save -p && verify_state dir/foo work index && verify_saved_state bar ' -test_expect_success 'git stash -p' ' +test_expect_success PERL 'git stash -p' ' (echo n; echo y) | git stash save -p && verify_state dir/foo head index && verify_saved_state bar && @@ -36,7 +36,7 @@ test_expect_success 'git stash -p' ' verify_state bar dummy dummy ' -test_expect_success 'git stash -p --no-keep-index' ' +test_expect_success PERL 'git stash -p --no-keep-index' ' set_state dir/foo work index && set_state bar bar_work bar_index && (echo n; echo y) | git stash save -p --no-keep-index && @@ -48,7 +48,7 @@ test_expect_success 'git stash -p --no-keep-index' ' verify_state bar dummy bar_index ' -test_expect_success 'none of this moved HEAD' ' +test_expect_success PERL 'none of this moved HEAD' ' verify_saved_head ' diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh index a4da1196a..92a65f485 100755 --- a/t/t4004-diff-rename-symlink.sh +++ b/t/t4004-diff-rename-symlink.sh @@ -12,13 +12,7 @@ by an edit for them. . ./test-lib.sh . "$TEST_DIRECTORY"/diff-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - -test_expect_success \ +test_expect_success SYMLINKS \ 'prepare reference tree' \ 'echo xyzzy | tr -d '\\\\'012 >yomin && ln -s xyzzy frotz && @@ -26,7 +20,7 @@ test_expect_success \ tree=$(git write-tree) && echo $tree' -test_expect_success \ +test_expect_success SYMLINKS \ 'prepare work tree' \ 'mv frotz rezrov && rm -f yomin && @@ -40,8 +34,9 @@ test_expect_success \ # rezrov and nitfol are rename/copy of frotz and bozbar should be # a new creation. -GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current -cat >expected <<\EOF +test_expect_success SYMLINKS 'setup diff output' " + GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current && + cat >expected <<\EOF diff --git a/bozbar b/bozbar new file mode 120000 --- /dev/null @@ -65,8 +60,9 @@ deleted file mode 100644 -xyzzy \ No newline at end of file EOF +" -test_expect_success \ +test_expect_success SYMLINKS \ 'validate diff output' \ 'compare_diff_patch current expected' diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index e12fbea1b..6f6948925 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -9,12 +9,6 @@ test_description='Test diff of symlinks. . ./test-lib.sh . "$TEST_DIRECTORY"/diff-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - cat > expected << EOF diff --git a/frotz b/frotz new file mode 120000 @@ -26,7 +20,7 @@ index 0000000..7c465af \ No newline at end of file EOF -test_expect_success \ +test_expect_success SYMLINKS \ 'diff new symlink' \ 'ln -s xyzzy frotz && git update-index && @@ -35,7 +29,7 @@ test_expect_success \ GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree > current && compare_diff_patch current expected' -test_expect_success \ +test_expect_success SYMLINKS \ 'diff unchanged symlink' \ 'tree=$(git write-tree) && git update-index frotz && @@ -52,7 +46,7 @@ index 7c465af..0000000 \ No newline at end of file EOF -test_expect_success \ +test_expect_success SYMLINKS \ 'diff removed symlink' \ 'mv frotz frotz2 && git diff-index -M -p $tree > current && @@ -62,7 +56,7 @@ cat > expected << EOF diff --git a/frotz b/frotz EOF -test_expect_success \ +test_expect_success SYMLINKS \ 'diff identical, but newly created symlink' \ 'ln -s xyzzy frotz && git diff-index -M -p $tree > current && @@ -80,14 +74,14 @@ index 7c465af..df1db54 120000 \ No newline at end of file EOF -test_expect_success \ +test_expect_success SYMLINKS \ 'diff different symlink' \ 'rm frotz && ln -s yxyyz frotz && git diff-index -M -p $tree > current && compare_diff_patch current expected' -test_expect_success \ +test_expect_success SYMLINKS \ 'diff symlinks with non-existing targets' \ 'ln -s narf pinky && ln -s take\ over brain && diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index dae635851..9a6652058 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -208,7 +208,11 @@ log -p --first-parent master log -m -p --first-parent master log -m -p master log -SF master +log -S F master log -SF -p master +log -GF master +log -GF -p master +log -GF -p --pickaxe-all master log --decorate --all log --decorate=full --all @@ -282,4 +286,8 @@ diff master master^ side diff --dirstat master~1 master~2 EOF +test_expect_success 'log -S requires an argument' ' + test_must_fail git log -S +' + test_done diff --git a/t/t4013/diff.log_-GF_-p_--pickaxe-all_master b/t/t4013/diff.log_-GF_-p_--pickaxe-all_master new file mode 100644 index 000000000..d36f88098 --- /dev/null +++ b/t/t4013/diff.log_-GF_-p_--pickaxe-all_master @@ -0,0 +1,27 @@ +$ git log -GF -p --pickaxe-all master +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C +$ diff --git a/t/t4013/diff.log_-GF_-p_master b/t/t4013/diff.log_-GF_-p_master new file mode 100644 index 000000000..9d93f2c23 --- /dev/null +++ b/t/t4013/diff.log_-GF_-p_master @@ -0,0 +1,18 @@ +$ git log -GF -p master +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +$ diff --git a/t/t4013/diff.log_-GF_master b/t/t4013/diff.log_-GF_master new file mode 100644 index 000000000..4c6708d2d --- /dev/null +++ b/t/t4013/diff.log_-GF_master @@ -0,0 +1,7 @@ +$ git log -GF master +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third +$ diff --git a/t/t4013/diff.log_-S_F_master b/t/t4013/diff.log_-S_F_master new file mode 100644 index 000000000..978d2b411 --- /dev/null +++ b/t/t4013/diff.log_-S_F_master @@ -0,0 +1,7 @@ +$ git log -S F master +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third +$ diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index f87434b9f..07bf6eb49 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -12,24 +12,29 @@ test_expect_success setup ' for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file && cat file >elif && git add file elif && + test_tick && git commit -m Initial && git checkout -b side && for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file && test_chmod +x elif && + test_tick && git commit -m "Side changes #1" && for i in D E F; do echo "$i"; done >>file && git update-index file && + test_tick && git commit -m "Side changes #2" && git tag C2 && for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file && git update-index file && + test_tick && git commit -m "Side changes #3 with \\n backslash-n in it." && git checkout master && git diff-tree -p C2 | git apply --index && + test_tick && git commit -m "Master accepts moral equivalent of #2" ' @@ -51,6 +56,22 @@ test_expect_success "format-patch --ignore-if-in-upstream" ' ' +test_expect_success "format-patch doesn't consider merge commits" ' + + git checkout -b slave master && + echo "Another line" >>file && + test_tick && + git commit -am "Slave change #1" && + echo "Yet another line" >>file && + test_tick && + git commit -am "Slave change #2" && + git checkout -b merger master && + test_tick && + git merge --no-ff slave && + cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` && + test $cnt = 3 +' + test_expect_success "format-patch result applies" ' git checkout -b rebuild-0 master && diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh index 55eb5f83f..ab0c2f057 100755 --- a/t/t4016-diff-quote.sh +++ b/t/t4016-diff-quote.sh @@ -13,12 +13,14 @@ P1='pathname with HT' P2='pathname with SP' P3='pathname with LF' -: 2>/dev/null >"$P1" && test -f "$P1" && rm -f "$P1" || { - say 'Your filesystem does not allow tabs in filenames, test skipped.' - test_done -} +if : 2>/dev/null >"$P1" && test -f "$P1" && rm -f "$P1" +then + test_set_prereq TABS_IN_FILENAMES +else + say 'Your filesystem does not allow tabs in filenames' +fi -test_expect_success setup ' +test_expect_success TABS_IN_FILENAMES setup ' echo P0.0 >"$P0.0" && echo P0.1 >"$P0.1" && echo P0.2 >"$P0.2" && @@ -38,6 +40,7 @@ test_expect_success setup ' : ' +test_expect_success TABS_IN_FILENAMES 'setup expected files' ' cat >expect <<\EOF rename pathname.1 => "Rpathname\twith HT.0" (100%) rename pathname.3 => "Rpathname\nwith LF.0" (100%) @@ -47,11 +50,14 @@ cat >expect <<\EOF rename pathname.0 => Rpathname.0 (100%) rename "pathname\twith HT.0" => Rpathname.1 (100%) EOF -test_expect_success 'git diff --summary -M HEAD' ' +' + +test_expect_success TABS_IN_FILENAMES 'git diff --summary -M HEAD' ' git diff --summary -M HEAD >actual && test_cmp expect actual ' +test_expect_success TABS_IN_FILENAMES 'setup expected files' ' cat >expect <<\EOF pathname.1 => "Rpathname\twith HT.0" | 0 pathname.3 => "Rpathname\nwith LF.0" | 0 @@ -62,7 +68,9 @@ cat >expect <<\EOF "pathname\twith HT.0" => Rpathname.1 | 0 7 files changed, 0 insertions(+), 0 deletions(-) EOF -test_expect_success 'git diff --stat -M HEAD' ' +' + +test_expect_success TABS_IN_FILENAMES 'git diff --stat -M HEAD' ' git diff --stat -M HEAD >actual && test_cmp expect actual ' diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 5b10e976a..0a61b57b5 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -32,13 +32,18 @@ EOF sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java -builtin_patterns="bibtex cpp html java objc pascal php python ruby tex" +builtin_patterns="bibtex cpp csharp fortran html java objc pascal php python ruby tex" for p in $builtin_patterns do test_expect_success "builtin $p pattern compiles" ' echo "*.java diff=$p" > .gitattributes && - ! ( git diff --no-index Beer.java Beer-correct.java 2>&1 | - grep "fatal" > /dev/null ) + ! { git diff --no-index Beer.java Beer-correct.java 2>&1 | + grep "fatal" > /dev/null; } + ' + test_expect_success "builtin $p wordRegex pattern compiles" ' + ! { git diff --no-index --word-diff \ + Beer.java Beer-correct.java 2>&1 | + grep "fatal" > /dev/null; } ' done diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh index 9bdf6596d..5d20acf43 100755 --- a/t/t4023-diff-rename-typechange.sh +++ b/t/t4023-diff-rename-typechange.sh @@ -4,13 +4,7 @@ test_description='typechange rename detection' . ./test-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - -test_expect_success setup ' +test_expect_success SYMLINKS setup ' rm -f foo bar && cat "$TEST_DIRECTORY"/../COPYING >foo && @@ -56,7 +50,7 @@ test_expect_success setup ' ' -test_expect_success 'cross renames to be detected for regular files' ' +test_expect_success SYMLINKS 'cross renames to be detected for regular files' ' git diff-tree five six -r --name-status -B -M | sort >actual && { @@ -67,7 +61,7 @@ test_expect_success 'cross renames to be detected for regular files' ' ' -test_expect_success 'cross renames to be detected for typechange' ' +test_expect_success SYMLINKS 'cross renames to be detected for typechange' ' git diff-tree one two -r --name-status -B -M | sort >actual && { @@ -78,7 +72,7 @@ test_expect_success 'cross renames to be detected for typechange' ' ' -test_expect_success 'moves and renames' ' +test_expect_success SYMLINKS 'moves and renames' ' git diff-tree three four -r --name-status -B -M | sort >actual && { diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 83c191477..d99814ac6 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -103,7 +103,78 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)' git diff HEAD >actual && sed -e "1,/^@@/d" actual >actual.body && expect_from_to >expect.body $subprev $subprev-dirty && - test_cmp expect.body actual.body + test_cmp expect.body actual.body && + git diff --ignore-submodules HEAD >actual2 && + ! test -s actual2 && + git diff --ignore-submodules=untracked HEAD >actual3 && + sed -e "1,/^@@/d" actual3 >actual3.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual3.body && + git diff --ignore-submodules=dirty HEAD >actual4 && + ! test -s actual4 +' + +test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match) [.git/config]' ' + git config diff.ignoreSubmodules all && + git diff HEAD >actual && + ! test -s actual && + git config submodule.subname.ignore none && + git config submodule.subname.path sub && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body && + git config submodule.subname.ignore all && + git diff HEAD >actual2 && + ! test -s actual2 && + git config submodule.subname.ignore untracked && + git diff HEAD >actual3 && + sed -e "1,/^@@/d" actual3 >actual3.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual3.body && + git config submodule.subname.ignore dirty && + git diff HEAD >actual4 && + ! test -s actual4 && + git diff HEAD --ignore-submodules=none >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body && + git config --remove-section submodule.subname && + git config --unset diff.ignoreSubmodules +' + +test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match) [.gitmodules]' ' + git config diff.ignoreSubmodules dirty && + git diff HEAD >actual && + ! test -s actual && + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sub && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body && + git config -f .gitmodules submodule.subname.ignore all && + git config -f .gitmodules submodule.subname.path sub && + git diff HEAD >actual2 && + ! test -s actual2 && + git config -f .gitmodules submodule.subname.ignore untracked && + git diff HEAD >actual3 && + sed -e "1,/^@@/d" actual3 >actual3.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual3.body && + git config -f .gitmodules submodule.subname.ignore dirty && + git diff HEAD >actual4 && + ! test -s actual4 && + git config submodule.subname.ignore none && + git config submodule.subname.path sub && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body && + git config --remove-section submodule.subname && + git config --remove-section -f .gitmodules submodule.subname && + git config --unset diff.ignoreSubmodules && + rm .gitmodules ' test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' ' @@ -129,7 +200,110 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)' git diff HEAD >actual && sed -e "1,/^@@/d" actual >actual.body && expect_from_to >expect.body $subprev $subprev-dirty && - test_cmp expect.body actual.body + test_cmp expect.body actual.body && + git diff --ignore-submodules=all HEAD >actual2 && + ! test -s actual2 && + git diff --ignore-submodules=untracked HEAD >actual3 && + ! test -s actual3 && + git diff --ignore-submodules=dirty HEAD >actual4 && + ! test -s actual4 +' + +test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match) [.git/config]' ' + git config submodule.subname.ignore all && + git config submodule.subname.path sub && + git diff HEAD >actual2 && + ! test -s actual2 && + git config submodule.subname.ignore untracked && + git diff HEAD >actual3 && + ! test -s actual3 && + git config submodule.subname.ignore dirty && + git diff HEAD >actual4 && + ! test -s actual4 && + git diff --ignore-submodules=none HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body && + git config --remove-section submodule.subname +' + +test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match) [.gitmodules]' ' + git config --add -f .gitmodules submodule.subname.ignore all && + git config --add -f .gitmodules submodule.subname.path sub && + git diff HEAD >actual2 && + ! test -s actual2 && + git config -f .gitmodules submodule.subname.ignore untracked && + git diff HEAD >actual3 && + ! test -s actual3 && + git config -f .gitmodules submodule.subname.ignore dirty && + git diff HEAD >actual4 && + ! test -s actual4 && + git config submodule.subname.ignore none && + git config submodule.subname.path sub && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body && + git config --remove-section submodule.subname && + git config --remove-section -f .gitmodules submodule.subname && + rm .gitmodules +' + +test_expect_success 'git diff between submodule commits' ' + git diff HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + test_cmp expect.body actual.body && + git diff --ignore-submodules=dirty HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + test_cmp expect.body actual.body && + git diff --ignore-submodules HEAD^..HEAD >actual && + ! test -s actual +' + +test_expect_success 'git diff between submodule commits [.git/config]' ' + git diff HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + test_cmp expect.body actual.body && + git config submodule.subname.ignore dirty && + git config submodule.subname.path sub && + git diff HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + test_cmp expect.body actual.body && + git config submodule.subname.ignore all && + git diff HEAD^..HEAD >actual && + ! test -s actual && + git diff --ignore-submodules=dirty HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + git config --remove-section submodule.subname +' + +test_expect_success 'git diff between submodule commits [.gitmodules]' ' + git diff HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + test_cmp expect.body actual.body && + git config --add -f .gitmodules submodule.subname.ignore dirty && + git config --add -f .gitmodules submodule.subname.path sub && + git diff HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + test_cmp expect.body actual.body && + git config -f .gitmodules submodule.subname.ignore all && + git diff HEAD^..HEAD >actual && + ! test -s actual && + git config submodule.subname.ignore dirty && + git config submodule.subname.path sub && + git diff HEAD^..HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + git config --remove-section submodule.subname && + git config --remove-section -f .gitmodules submodule.subname && + rm .gitmodules ' test_expect_success 'git diff (empty submodule dir)' ' diff --git a/t/t4041-diff-submodule.sh b/t/t4041-diff-submodule-option.sh index 019acb926..995bdfafe 100755 --- a/t/t4041-diff-submodule.sh +++ b/t/t4041-diff-submodule-option.sh @@ -85,10 +85,11 @@ EOF " commit_file sm1 && -cd sm1 && -git reset --hard HEAD~2 >/dev/null && -head3=$(git rev-parse --verify HEAD | cut -c1-7) && -cd .. +head3=$( + cd sm1 && + git reset --hard HEAD~2 >/dev/null && + git rev-parse --verify HEAD | cut -c1-7 +) test_expect_success 'modified submodule(backward)' " git diff-index -p --submodule=log HEAD >actual && @@ -205,6 +206,21 @@ Submodule sm1 contains untracked content EOF " +test_expect_success 'submodule contains untracked content (untracked ignored)' " + git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && + ! test -s actual +" + +test_expect_success 'submodule contains untracked content (dirty ignored)' " + git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && + ! test -s actual +" + +test_expect_success 'submodule contains untracked content (all ignored)' " + git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual && + ! test -s actual +" + test_expect_success 'submodule contains untracked and modifed content' " echo new > sm1/foo6 && git diff-index -p --submodule=log HEAD >actual && @@ -214,6 +230,26 @@ Submodule sm1 contains modified content EOF " +test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' " + echo new > sm1/foo6 && + git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 contains modified content +EOF +" + +test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' " + echo new > sm1/foo6 && + git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && + ! test -s actual +" + +test_expect_success 'submodule contains untracked and modifed content (all ignored)' " + echo new > sm1/foo6 && + git diff-index -p --ignore-submodules --submodule=log HEAD >actual && + ! test -s actual +" + test_expect_success 'submodule contains modifed content' " rm -f sm1/new-file && git diff-index -p --submodule=log HEAD >actual && @@ -242,6 +278,27 @@ Submodule sm1 $head6..$head8: EOF " +test_expect_success 'modified submodule contains untracked content (untracked ignored)' " + git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head8: + > change +EOF +" + +test_expect_success 'modified submodule contains untracked content (dirty ignored)' " + git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head8: + > change +EOF +" + +test_expect_success 'modified submodule contains untracked content (all ignored)' " + git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual && + ! test -s actual +" + test_expect_success 'modified submodule contains untracked and modifed content' " echo modification >> sm1/foo6 && git diff-index -p --submodule=log HEAD >actual && @@ -253,6 +310,31 @@ Submodule sm1 $head6..$head8: EOF " +test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' " + echo modification >> sm1/foo6 && + git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 contains modified content +Submodule sm1 $head6..$head8: + > change +EOF +" + +test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' " + echo modification >> sm1/foo6 && + git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head8: + > change +EOF +" + +test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' " + echo modification >> sm1/foo6 && + git diff-index -p --ignore-submodules --submodule=log HEAD >actual && + ! test -s actual +" + test_expect_success 'modified submodule contains modifed content' " rm -f sm1/new-file && git diff-index -p --submodule=log HEAD >actual && diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh new file mode 100755 index 000000000..8a3c63b9e --- /dev/null +++ b/t/t4045-diff-relative.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +test_description='diff --relative tests' +. ./test-lib.sh + +test_expect_success 'setup' ' + git commit --allow-empty -m empty && + echo content >file1 && + mkdir subdir && + echo other content >subdir/file2 && + git add . && + git commit -m one +' + +check_diff() { +expect=$1; shift +cat >expected <<EOF +diff --git a/$expect b/$expect +new file mode 100644 +index 0000000..25c05ef +--- /dev/null ++++ b/$expect +@@ -0,0 +1 @@ ++other content +EOF +test_expect_success "-p $*" " + git diff -p $* HEAD^ >actual && + test_cmp expected actual +" +} + +check_stat() { +expect=$1; shift +cat >expected <<EOF + $expect | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) +EOF +test_expect_success "--stat $*" " + git diff --stat $* HEAD^ >actual && + test_cmp expected actual +" +} + +check_raw() { +expect=$1; shift +cat >expected <<EOF +:000000 100644 0000000000000000000000000000000000000000 25c05ef3639d2d270e7fe765a67668f098092bc5 A $expect +EOF +test_expect_success "--raw $*" " + git diff --no-abbrev --raw $* HEAD^ >actual && + test_cmp expected actual +" +} + +for type in diff stat raw; do + check_$type file2 --relative=subdir/ + check_$type file2 --relative=subdir + check_$type dir/file2 --relative=sub +done + +test_done diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh index 159796524..e3ea3d511 100755 --- a/t/t4102-apply-rename.sh +++ b/t/t4102-apply-rename.sh @@ -7,6 +7,7 @@ test_description='git apply handling copy/rename patch. ' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh # setup @@ -31,13 +32,6 @@ test_expect_success setup \ test_expect_success apply \ 'git apply --index --stat --summary --apply test-patch' -if test "$(git config --bool core.filemode)" = false -then - say 'filemode disabled on the filesystem' -else - test_set_prereq FILEMODE -fi - test_expect_success FILEMODE validate \ 'test -f bar && ls -l bar | grep "^-..x......"' diff --git a/t/t4111-apply-subdir.sh b/t/t4111-apply-subdir.sh new file mode 100755 index 000000000..a52d94ae2 --- /dev/null +++ b/t/t4111-apply-subdir.sh @@ -0,0 +1,142 @@ +#!/bin/sh + +test_description='patching from inconvenient places' + +. ./test-lib.sh + +test_expect_success 'setup' ' + cat >patch <<-\EOF && + diff file.orig file + --- a/file.orig + +++ b/file + @@ -1 +1,2 @@ + 1 + +2 + EOF + patch="$(pwd)/patch" && + + echo 1 >preimage && + printf "%s\n" 1 2 >postimage && + echo 3 >other && + + test_tick && + git commit --allow-empty -m basis +' + +test_expect_success 'setup: subdir' ' + reset_subdir() { + git reset && + mkdir -p sub/dir/b && + mkdir -p objects && + cp "$1" file && + cp "$1" objects/file && + cp "$1" sub/dir/file && + cp "$1" sub/dir/b/file && + git add file sub/dir/file sub/dir/b/file objects/file && + cp "$2" file && + cp "$2" sub/dir/file && + cp "$2" sub/dir/b/file && + cp "$2" objects/file && + test_might_fail git update-index --refresh -q + } +' + +test_expect_success 'apply from subdir of toplevel' ' + cp postimage expected && + reset_subdir other preimage && + ( + cd sub/dir && + git apply "$patch" + ) && + test_cmp expected sub/dir/file +' + +test_expect_success 'apply --cached from subdir of toplevel' ' + cp postimage expected && + cp other expected.working && + reset_subdir preimage other && + ( + cd sub/dir && + git apply --cached "$patch" + ) && + git show :sub/dir/file >actual && + test_cmp expected actual && + test_cmp expected.working sub/dir/file +' + +test_expect_success 'apply --index from subdir of toplevel' ' + cp postimage expected && + reset_subdir preimage other && + ( + cd sub/dir && + test_must_fail git apply --index "$patch" + ) && + reset_subdir other preimage && + ( + cd sub/dir && + test_must_fail git apply --index "$patch" + ) && + reset_subdir preimage preimage && + ( + cd sub/dir && + git apply --index "$patch" + ) && + git show :sub/dir/file >actual && + test_cmp expected actual && + test_cmp expected sub/dir/file +' + +test_expect_success 'apply from .git dir' ' + cp postimage expected && + cp preimage .git/file && + cp preimage .git/objects/file + ( + cd .git && + git apply "$patch" + ) && + test_cmp expected .git/file +' + +test_expect_success 'apply from subdir of .git dir' ' + cp postimage expected && + cp preimage .git/file && + cp preimage .git/objects/file + ( + cd .git/objects && + git apply "$patch" + ) && + test_cmp expected .git/objects/file +' + +test_expect_success 'apply --cached from .git dir' ' + cp postimage expected && + cp other expected.working && + cp other .git/file && + reset_subdir preimage other && + ( + cd .git && + git apply --cached "$patch" + ) && + git show :file >actual && + test_cmp expected actual && + test_cmp expected.working file && + test_cmp expected.working .git/file +' + +test_expect_success 'apply --cached from subdir of .git dir' ' + cp postimage expected && + cp preimage expected.subdir && + cp other .git/file && + cp other .git/objects/file && + reset_subdir preimage other && + ( + cd .git/objects && + git apply --cached "$patch" + ) && + git show :file >actual && + git show :objects/file >actual.subdir && + test_cmp expected actual && + test_cmp expected.subdir actual.subdir +' + +test_done diff --git a/t/t4114-apply-typechange.sh b/t/t4114-apply-typechange.sh index 99ec13dd5..f12826fb0 100755 --- a/t/t4114-apply-typechange.sh +++ b/t/t4114-apply-typechange.sh @@ -9,13 +9,7 @@ test_description='git apply should not get confused with type changes. . ./test-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - -test_expect_success 'setup repository and commits' ' +test_expect_success SYMLINKS 'setup repository and commits' ' echo "hello world" > foo && echo "hi planet" > bar && git update-index --add foo bar && @@ -48,7 +42,7 @@ test_expect_success 'setup repository and commits' ' git branch foo-baz-renamed-from-foo ' -test_expect_success 'file renamed from foo to foo/baz' ' +test_expect_success SYMLINKS 'file renamed from foo to foo/baz' ' git checkout -f initial && git diff-tree -M -p HEAD foo-baz-renamed-from-foo > patch && git apply --index < patch @@ -56,7 +50,7 @@ test_expect_success 'file renamed from foo to foo/baz' ' test_debug 'cat patch' -test_expect_success 'file renamed from foo/baz to foo' ' +test_expect_success SYMLINKS 'file renamed from foo/baz to foo' ' git checkout -f foo-baz-renamed-from-foo && git diff-tree -M -p HEAD initial > patch && git apply --index < patch @@ -64,7 +58,7 @@ test_expect_success 'file renamed from foo/baz to foo' ' test_debug 'cat patch' -test_expect_success 'directory becomes file' ' +test_expect_success SYMLINKS 'directory becomes file' ' git checkout -f foo-becomes-a-directory && git diff-tree -p HEAD initial > patch && git apply --index < patch @@ -72,7 +66,7 @@ test_expect_success 'directory becomes file' ' test_debug 'cat patch' -test_expect_success 'file becomes directory' ' +test_expect_success SYMLINKS 'file becomes directory' ' git checkout -f initial && git diff-tree -p HEAD foo-becomes-a-directory > patch && git apply --index < patch @@ -80,7 +74,7 @@ test_expect_success 'file becomes directory' ' test_debug 'cat patch' -test_expect_success 'file becomes symlink' ' +test_expect_success SYMLINKS 'file becomes symlink' ' git checkout -f initial && git diff-tree -p HEAD foo-symlinked-to-bar > patch && git apply --index < patch @@ -88,21 +82,21 @@ test_expect_success 'file becomes symlink' ' test_debug 'cat patch' -test_expect_success 'symlink becomes file' ' +test_expect_success SYMLINKS 'symlink becomes file' ' git checkout -f foo-symlinked-to-bar && git diff-tree -p HEAD foo-back-to-file > patch && git apply --index < patch ' test_debug 'cat patch' -test_expect_success 'binary file becomes symlink' ' +test_expect_success SYMLINKS 'binary file becomes symlink' ' git checkout -f foo-becomes-binary && git diff-tree -p --binary HEAD foo-symlinked-to-bar > patch && git apply --index < patch ' test_debug 'cat patch' -test_expect_success 'symlink becomes binary file' ' +test_expect_success SYMLINKS 'symlink becomes binary file' ' git checkout -f foo-symlinked-to-bar && git diff-tree -p --binary HEAD foo-becomes-binary > patch && git apply --index < patch @@ -110,7 +104,7 @@ test_expect_success 'symlink becomes binary file' ' test_debug 'cat patch' -test_expect_success 'symlink becomes directory' ' +test_expect_success SYMLINKS 'symlink becomes directory' ' git checkout -f foo-symlinked-to-bar && git diff-tree -p HEAD foo-becomes-a-directory > patch && git apply --index < patch @@ -118,7 +112,7 @@ test_expect_success 'symlink becomes directory' ' test_debug 'cat patch' -test_expect_success 'directory becomes symlink' ' +test_expect_success SYMLINKS 'directory becomes symlink' ' git checkout -f foo-becomes-a-directory && git diff-tree -p HEAD foo-symlinked-to-bar > patch && git apply --index < patch diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh index b852e5898..7674dd2ec 100755 --- a/t/t4115-apply-symlink.sh +++ b/t/t4115-apply-symlink.sh @@ -9,13 +9,7 @@ test_description='git apply symlinks and partial files . ./test-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - -test_expect_success setup ' +test_expect_success SYMLINKS setup ' ln -s path1/path2/path3/path4/path5 link1 && git add link? && @@ -34,7 +28,7 @@ test_expect_success setup ' ' -test_expect_success 'apply symlink patch' ' +test_expect_success SYMLINKS 'apply symlink patch' ' git checkout side && git apply patch && @@ -43,7 +37,7 @@ test_expect_success 'apply symlink patch' ' ' -test_expect_success 'apply --index symlink patch' ' +test_expect_success SYMLINKS 'apply --index symlink patch' ' git checkout -f side && git apply --index patch && diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh index b463b4f05..2b2d00b33 100755 --- a/t/t4120-apply-popt.sh +++ b/t/t4120-apply-popt.sh @@ -10,21 +10,50 @@ test_description='git apply -p handling.' test_expect_success setup ' mkdir sub && echo A >sub/file1 && - cp sub/file1 file1 && + cp sub/file1 file1.saved && git add sub/file1 && echo B >sub/file1 && git diff >patch.file && - rm sub/file1 && - rmdir sub + git checkout -- sub/file1 && + git mv sub süb && + echo B >süb/file1 && + git diff >patch.escaped && + grep "[\]" patch.escaped && + rm süb/file1 && + rmdir süb ' test_expect_success 'apply git diff with -p2' ' + cp file1.saved file1 && git apply -p2 patch.file ' test_expect_success 'apply with too large -p' ' + cp file1.saved file1 && test_must_fail git apply --stat -p3 patch.file 2>err && grep "removing 3 leading" err ' +test_expect_success 'apply (-p2) traditional diff with funny filenames' ' + cat >patch.quotes <<-\EOF && + diff -u "a/"sub/file1 "b/"sub/file1 + --- "a/"sub/file1 + +++ "b/"sub/file1 + @@ -1 +1 @@ + -A + +B + EOF + echo B >expected && + + cp file1.saved file1 && + git apply -p2 patch.quotes && + test_cmp expected file1 +' + +test_expect_success 'apply with too large -p and fancy filename' ' + cp file1.saved file1 && + test_must_fail git apply --stat -p3 patch.escaped 2>err && + grep "removing 3 leading" err +' + test_done diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh index 0d3c1d5dd..39407376b 100755 --- a/t/t4122-apply-symlink-inside.sh +++ b/t/t4122-apply-symlink-inside.sh @@ -3,12 +3,6 @@ test_description='apply to deeper directory without getting fooled with symlink' . ./test-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - lecho () { for l_ do @@ -16,7 +10,7 @@ lecho () { done } -test_expect_success setup ' +test_expect_success SYMLINKS setup ' mkdir -p arch/i386/boot arch/x86_64 && lecho 1 2 3 4 5 >arch/i386/boot/Makefile && @@ -37,7 +31,7 @@ test_expect_success setup ' ' -test_expect_success apply ' +test_expect_success SYMLINKS apply ' git checkout test && git diff --exit-code test && @@ -46,7 +40,7 @@ test_expect_success apply ' ' -test_expect_success 'check result' ' +test_expect_success SYMLINKS 'check result' ' git diff --exit-code master && git diff --exit-code --cached master && diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index fc7af0493..0d36ebdc8 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -3,13 +3,7 @@ test_description='applying patch with mode bits' . ./test-lib.sh - -if test "$(git config --bool core.filemode)" = false -then - say 'filemode disabled on the filesystem' -else - test_set_prereq FILEMODE -fi +. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh test_expect_success setup ' echo original >file && diff --git a/t/t4135-apply-weird-filenames.sh b/t/t4135-apply-weird-filenames.sh new file mode 100755 index 000000000..1e5aad57a --- /dev/null +++ b/t/t4135-apply-weird-filenames.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +test_description='git apply with weird postimage filenames' + +. ./test-lib.sh + +test_expect_success 'setup' ' + vector=$TEST_DIRECTORY/t4135 && + + test_tick && + git commit --allow-empty -m preimage && + git tag preimage && + + reset_preimage() { + git checkout -f preimage^0 && + git read-tree -u --reset HEAD && + git update-index --refresh + } && + + test_when_finished "rm -f \"tab embedded.txt\"" && + test_when_finished "rm -f '\''\"quoteembedded\".txt'\''" && + if touch -- "tab embedded.txt" '\''"quoteembedded".txt'\'' + then + test_set_prereq FUNNYNAMES + fi +' + +try_filename() { + desc=$1 + postimage=$2 + prereq=${3:-} + exp1=${4:-success} + exp2=${5:-success} + exp3=${6:-success} + + test_expect_$exp1 $prereq "$desc, git-style file creation patch" " + echo postimage >expected && + reset_preimage && + rm -f '$postimage' && + git apply -v \"\$vector\"/'git-$desc.diff' && + test_cmp expected '$postimage' + " + + test_expect_$exp2 $prereq "$desc, traditional patch" " + echo postimage >expected && + reset_preimage && + echo preimage >'$postimage' && + git apply -v \"\$vector\"/'diff-$desc.diff' && + test_cmp expected '$postimage' + " + + test_expect_$exp3 $prereq "$desc, traditional file creation patch" " + echo postimage >expected && + reset_preimage && + rm -f '$postimage' && + git apply -v \"\$vector\"/'add-$desc.diff' && + test_cmp expected '$postimage' + " +} + +try_filename 'plain' 'postimage.txt' +try_filename 'with spaces' 'post image.txt' +try_filename 'with tab' 'post image.txt' FUNNYNAMES +try_filename 'with backslash' 'post\image.txt' BSLASHPSPEC +try_filename 'with quote' '"postimage".txt' FUNNYNAMES success failure success + +test_expect_success 'whitespace-damaged traditional patch' ' + echo postimage >expected && + reset_preimage && + rm -f postimage.txt && + git apply -v "$vector/damaged.diff" && + test_cmp expected postimage.txt +' + +test_done diff --git a/t/t4135/.gitignore b/t/t4135/.gitignore new file mode 100644 index 000000000..3e58e65f5 --- /dev/null +++ b/t/t4135/.gitignore @@ -0,0 +1,3 @@ +/file-creation/ +/trad-creation/ +/trad-modification/ diff --git a/t/t4135/add-plain.diff b/t/t4135/add-plain.diff new file mode 100644 index 000000000..cf5970a08 --- /dev/null +++ b/t/t4135/add-plain.diff @@ -0,0 +1,5 @@ +diff -pruN a/postimage.txt b/postimage.txt +--- a/postimage.txt 1969-12-31 18:00:00.000000000 -0600 ++++ b/postimage.txt 2010-08-18 20:13:31.484002255 -0500 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/add-with backslash.diff b/t/t4135/add-with backslash.diff new file mode 100644 index 000000000..c6861e196 --- /dev/null +++ b/t/t4135/add-with backslash.diff @@ -0,0 +1,5 @@ +diff -pruN a/post\image.txt b/post\image.txt +--- a/post\image.txt 1969-12-31 18:00:00.000000000 -0600 ++++ b/post\image.txt 2010-08-18 20:13:31.692002255 -0500 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/add-with quote.diff b/t/t4135/add-with quote.diff new file mode 100644 index 000000000..866de78ca --- /dev/null +++ b/t/t4135/add-with quote.diff @@ -0,0 +1,5 @@ +diff -pruN a/"postimage".txt b/"postimage".txt +--- a/"postimage".txt 1969-12-31 18:00:00.000000000 -0600 ++++ b/"postimage".txt 2010-08-18 20:13:31.756002255 -0500 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/add-with spaces.diff b/t/t4135/add-with spaces.diff new file mode 100644 index 000000000..a9a1212a2 --- /dev/null +++ b/t/t4135/add-with spaces.diff @@ -0,0 +1,5 @@ +diff -pruN a/post image.txt b/post image.txt +--- a/post image.txt 1969-12-31 18:00:00.000000000 -0600 ++++ b/post image.txt 2010-08-18 20:13:31.556002255 -0500 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/add-with tab.diff b/t/t4135/add-with tab.diff new file mode 100644 index 000000000..bb67cb793 --- /dev/null +++ b/t/t4135/add-with tab.diff @@ -0,0 +1,5 @@ +diff -pruN a/post image.txt b/post image.txt +--- a/post image.txt 1969-12-31 18:00:00.000000000 -0600 ++++ b/post image.txt 2010-08-18 20:13:31.628002255 -0500 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/damaged.diff b/t/t4135/damaged.diff new file mode 100644 index 000000000..68f7ededf --- /dev/null +++ b/t/t4135/damaged.diff @@ -0,0 +1,5 @@ +diff -pruN a/postimage.txt b/postimage.txt +--- a/postimage.txt 1969-12-31 18:00:00.000000000 -0600 ++++ b/postimage.txt 2010-08-18 20:13:31.484002255 -0500 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/diff-plain.diff b/t/t4135/diff-plain.diff new file mode 100644 index 000000000..acedcfa61 --- /dev/null +++ b/t/t4135/diff-plain.diff @@ -0,0 +1,5 @@ +--- postimage.txt.orig 2010-08-18 20:13:31.432002255 -0500 ++++ postimage.txt 2010-08-18 20:13:31.432002255 -0500 +@@ -1 +1 @@ +-preimage ++postimage diff --git a/t/t4135/diff-with backslash.diff b/t/t4135/diff-with backslash.diff new file mode 100644 index 000000000..9068a61bd --- /dev/null +++ b/t/t4135/diff-with backslash.diff @@ -0,0 +1,5 @@ +--- post\image.txt.orig 2010-08-18 20:13:31.680002255 -0500 ++++ post\image.txt 2010-08-18 20:13:31.680002255 -0500 +@@ -1 +1 @@ +-preimage ++postimage diff --git a/t/t4135/diff-with quote.diff b/t/t4135/diff-with quote.diff new file mode 100644 index 000000000..c8e8cc1a8 --- /dev/null +++ b/t/t4135/diff-with quote.diff @@ -0,0 +1,5 @@ +--- "postimage".txt.orig 2010-08-18 20:13:31.744002255 -0500 ++++ "postimage".txt 2010-08-18 20:13:31.744002255 -0500 +@@ -1 +1 @@ +-preimage ++postimage diff --git a/t/t4135/diff-with spaces.diff b/t/t4135/diff-with spaces.diff new file mode 100644 index 000000000..3512056f2 --- /dev/null +++ b/t/t4135/diff-with spaces.diff @@ -0,0 +1,5 @@ +--- post image.txt.orig 2010-08-18 20:13:31.544002255 -0500 ++++ post image.txt 2010-08-18 20:13:31.544002255 -0500 +@@ -1 +1 @@ +-preimage ++postimage diff --git a/t/t4135/diff-with tab.diff b/t/t4135/diff-with tab.diff new file mode 100644 index 000000000..4e6d9b294 --- /dev/null +++ b/t/t4135/diff-with tab.diff @@ -0,0 +1,5 @@ +--- post image.txt.orig 2010-08-18 20:13:31.616002255 -0500 ++++ post image.txt 2010-08-18 20:13:31.616002255 -0500 +@@ -1 +1 @@ +-preimage ++postimage diff --git a/t/t4135/git-plain.diff b/t/t4135/git-plain.diff new file mode 100644 index 000000000..db47d1a69 --- /dev/null +++ b/t/t4135/git-plain.diff @@ -0,0 +1,7 @@ +diff --git a/postimage.txt b/postimage.txt +new file mode 100644 +index 0000000..eff0c54 +--- /dev/null ++++ b/postimage.txt +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/git-with backslash.diff b/t/t4135/git-with backslash.diff new file mode 100644 index 000000000..0e84a10e9 --- /dev/null +++ b/t/t4135/git-with backslash.diff @@ -0,0 +1,7 @@ +diff --git "a/post\\image.txt" "b/post\\image.txt" +new file mode 100644 +index 0000000..eff0c54 +--- /dev/null ++++ "b/post\\image.txt" +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/git-with quote.diff b/t/t4135/git-with quote.diff new file mode 100644 index 000000000..bdbea8af3 --- /dev/null +++ b/t/t4135/git-with quote.diff @@ -0,0 +1,7 @@ +diff --git "a/\"postimage\".txt" "b/\"postimage\".txt" +new file mode 100644 +index 0000000..eff0c54 +--- /dev/null ++++ "b/\"postimage\".txt" +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/git-with spaces.diff b/t/t4135/git-with spaces.diff new file mode 100644 index 000000000..baaa810de --- /dev/null +++ b/t/t4135/git-with spaces.diff @@ -0,0 +1,7 @@ +diff --git a/post image.txt b/post image.txt +new file mode 100644 +index 0000000..eff0c54 +--- /dev/null ++++ b/post image.txt +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/git-with tab.diff b/t/t4135/git-with tab.diff new file mode 100644 index 000000000..cca3c9287 --- /dev/null +++ b/t/t4135/git-with tab.diff @@ -0,0 +1,7 @@ +diff --git "a/post\timage.txt" "b/post\timage.txt" +new file mode 100644 +index 0000000..eff0c54 +--- /dev/null ++++ "b/post\timage.txt" +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/make-patches b/t/t4135/make-patches new file mode 100755 index 000000000..f5f45ddd0 --- /dev/null +++ b/t/t4135/make-patches @@ -0,0 +1,45 @@ +#!/bin/sh + +do_filename() { + desc=$1 + postimage=$2 + + rm -fr file-creation && + git init file-creation && + ( + cd file-creation && + git commit --allow-empty -m init && + echo postimage >"$postimage" && + git add -N "$postimage" && + git diff HEAD >"../git-$desc.diff" + ) && + + rm -fr trad-modification && + mkdir trad-modification && + ( + cd trad-modification && + echo preimage >"$postimage.orig" && + echo postimage >"$postimage" && + ! diff -u "$postimage.orig" "$postimage" >"../diff-$desc.diff" + ) && + + rm -fr trad-creation && + mkdir trad-creation && + ( + cd trad-creation && + mkdir a b && + echo postimage >"b/$postimage" && + ! diff -pruN a b >"../add-$desc.diff" + ) +} + +do_filename plain postimage.txt && +do_filename 'with spaces' 'post image.txt' && +do_filename 'with tab' 'post image.txt' && +do_filename 'with backslash' 'post\image.txt' && +do_filename 'with quote' '"postimage".txt' && +expand add-plain.diff >damaged.diff || +{ + echo >&2 Failed. && + exit 1 +} diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 810b04b81..1c3d8ed54 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -4,66 +4,71 @@ test_description='git am running' . ./test-lib.sh -cat >msg <<EOF -second - -Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy -eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam -voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita -kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem -ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod -tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At -vero eos et accusam et justo duo dolores et ea rebum. - - Duis autem vel eum iriure dolor in hendrerit in vulputate velit - esse molestie consequat, vel illum dolore eu feugiat nulla facilisis - at vero eros et accumsan et iusto odio dignissim qui blandit - praesent luptatum zzril delenit augue duis dolore te feugait nulla - facilisi. - - -Lorem ipsum dolor sit amet, -consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut -laoreet dolore magna aliquam erat volutpat. - - git - --- - +++ - -Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit -lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure -dolor in hendrerit in vulputate velit esse molestie consequat, vel illum -dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio -dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te -feugait nulla facilisi. -EOF - -cat >failmail <<EOF -From foo@example.com Fri May 23 10:43:49 2008 -From: foo@example.com -To: bar@example.com -Subject: Re: [RFC/PATCH] git-foo.sh -Date: Fri, 23 May 2008 05:23:42 +0200 - -Sometimes we have to find out that there's nothing left. - -EOF - -cat >pine <<EOF -From MAILER-DAEMON Fri May 23 10:43:49 2008 -Date: 23 May 2008 05:23:42 +0200 -From: Mail System Internal Data <MAILER-DAEMON@example.com> -Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA -Message-ID: <foo-0001@example.com> - -This text is part of the internal format of your mail folder, and is not -a real message. It is created automatically by the mail system software. -If deleted, important folder data will be lost, and it will be re-created -with the data reset to initial values. - -EOF - -echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected +test_expect_success 'setup: messages' ' + cat >msg <<-\EOF && + second + + Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita + kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem + ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod + tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At + vero eos et accusam et justo duo dolores et ea rebum. + + EOF + q_to_tab <<-\EOF >>msg && + QDuis autem vel eum iriure dolor in hendrerit in vulputate velit + Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis + Qat vero eros et accumsan et iusto odio dignissim qui blandit + Qpraesent luptatum zzril delenit augue duis dolore te feugait nulla + Qfacilisi. + EOF + cat >>msg <<-\EOF && + + Lorem ipsum dolor sit amet, + consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut + laoreet dolore magna aliquam erat volutpat. + + git + --- + +++ + + Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure + dolor in hendrerit in vulputate velit esse molestie consequat, vel illum + dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio + dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te + feugait nulla facilisi. + EOF + + cat >failmail <<-\EOF && + From foo@example.com Fri May 23 10:43:49 2008 + From: foo@example.com + To: bar@example.com + Subject: Re: [RFC/PATCH] git-foo.sh + Date: Fri, 23 May 2008 05:23:42 +0200 + + Sometimes we have to find out that there'\''s nothing left. + + EOF + + cat >pine <<-\EOF && + From MAILER-DAEMON Fri May 23 10:43:49 2008 + Date: 23 May 2008 05:23:42 +0200 + From: Mail System Internal Data <MAILER-DAEMON@example.com> + Subject: DON'\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA + Message-ID: <foo-0001@example.com> + + This text is part of the internal format of your mail folder, and is not + a real message. It is created automatically by the mail system software. + If deleted, important folder data will be lost, and it will be re-created + with the data reset to initial values. + + EOF + + signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" +' test_expect_success setup ' echo hello >file && @@ -71,11 +76,13 @@ test_expect_success setup ' test_tick && git commit -m first && git tag first && + echo world >>file && git add file && test_tick && git commit -s -F msg && git tag second && + git format-patch --stdout first >patch1 && { echo "X-Fake-Field: Line One" && @@ -89,74 +96,101 @@ test_expect_success setup ' echo "X-Fake-Field: Line Three" && git format-patch --stdout first | sed -e "1d" } | append_cr >patch1-crlf.eml && + sed -n -e "3,\$p" msg >file && git add file && test_tick && git commit -m third && + git format-patch --stdout first >patch2 && + git checkout -b lorem && sed -n -e "11,\$p" msg >file && head -n 9 msg >>file && test_tick && git commit -a -m "moved stuff" && + echo goodbye >another && git add another && test_tick && git commit -m "added another file" && - git format-patch --stdout master >lorem-move.patch -' -# reset time -unset test_tick -test_tick + git format-patch --stdout master >lorem-move.patch && + + git checkout -b rename && + git mv file renamed && + git commit -m "renamed a file" && + + git format-patch -M --stdout lorem >rename.patch && + + git reset --soft lorem^ && + git commit -m "renamed a file and added another" && + + git format-patch -M --stdout lorem^ >rename-add.patch && + + # reset time + unset test_tick && + test_tick +' test_expect_success 'am applies patch correctly' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && test_tick && git am <patch1 && ! test -d .git/rebase-apply && - test -z "$(git diff second)" && + git diff --exit-code second && test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" ' test_expect_success 'am applies patch e-mail not in a mbox' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && git am patch1.eml && ! test -d .git/rebase-apply && - test -z "$(git diff second)" && + git diff --exit-code second && test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" ' test_expect_success 'am applies patch e-mail not in a mbox with CRLF' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && git am patch1-crlf.eml && ! test -d .git/rebase-apply && - test -z "$(git diff second)" && + git diff --exit-code second && test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" ' -GIT_AUTHOR_NAME="Another Thor" -GIT_AUTHOR_EMAIL="a.thor@example.com" -GIT_COMMITTER_NAME="Co M Miter" -GIT_COMMITTER_EMAIL="c.miter@example.com" -export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL +test_expect_success 'setup: new author and committer' ' + GIT_AUTHOR_NAME="Another Thor" && + GIT_AUTHOR_EMAIL="a.thor@example.com" && + GIT_COMMITTER_NAME="Co M Miter" && + GIT_COMMITTER_EMAIL="c.miter@example.com" && + export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL +' compare () { - test "$(git cat-file commit "$2" | grep "^$1 ")" = \ - "$(git cat-file commit "$3" | grep "^$1 ")" + a=$(git cat-file commit "$2" | grep "^$1 ") && + b=$(git cat-file commit "$3" | grep "^$1 ") && + test "$a" = "$b" } test_expect_success 'am changes committer and keeps author' ' test_tick && + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && git am patch2 && ! test -d .git/rebase-apply && test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" && - test -z "$(git diff master..HEAD)" && - test -z "$(git diff master^..HEAD^)" && + git diff --exit-code master..HEAD && + git diff --exit-code master^..HEAD^ && compare author master HEAD && compare author master^ HEAD^ && test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \ @@ -164,41 +198,55 @@ test_expect_success 'am changes committer and keeps author' ' ' test_expect_success 'am --signoff adds Signed-off-by: line' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout -b master2 first && git am --signoff <patch2 && + printf "%s\n" "$signoff" >expected && echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected && git cat-file commit HEAD^ | grep "Signed-off-by:" >actual && - test_cmp actual expected && + test_cmp expected actual && echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected && git cat-file commit HEAD | grep "Signed-off-by:" >actual && - test_cmp actual expected + test_cmp expected actual ' test_expect_success 'am stays in branch' ' - test "refs/heads/master2" = "$(git symbolic-ref HEAD)" + echo refs/heads/master2 >expected && + git symbolic-ref HEAD >actual && + test_cmp expected actual ' test_expect_success 'am --signoff does not add Signed-off-by: line if already there' ' git format-patch --stdout HEAD^ >patch3 && sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4 + rm -fr .git/rebase-apply && + git reset --hard && git checkout HEAD^ && git am --signoff patch4 && - test "$(git cat-file commit HEAD | grep -c "^Signed-off-by:")" -eq 1 + git cat-file commit HEAD >actual && + test $(grep -c "^Signed-off-by:" actual) -eq 1 ' test_expect_success 'am without --keep removes Re: and [PATCH] stuff' ' - test "$(git rev-parse HEAD)" = "$(git rev-parse master2)" + git rev-parse HEAD >expected && + git rev-parse master2 >actual && + test_cmp expected actual ' test_expect_success 'am --keep really keeps the subject' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout HEAD^ && git am --keep patch4 && ! test -d .git/rebase-apply && - git cat-file commit HEAD | - fgrep "Re: Re: Re: [PATCH 1/5 v2] third" + git cat-file commit HEAD >actual && + grep "Re: Re: Re: \[PATCH 1/5 v2\] third" actual ' test_expect_success 'am -3 falls back to 3-way merge' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout -b lorem2 master2 && sed -n -e "3,\$p" msg >file && head -n 9 msg >>file && @@ -207,34 +255,75 @@ test_expect_success 'am -3 falls back to 3-way merge' ' git commit -m "copied stuff" && git am -3 lorem-move.patch && ! test -d .git/rebase-apply && - test -z "$(git diff lorem)" + git diff --exit-code lorem +' + +test_expect_success 'am can rename a file' ' + grep "^rename from" rename.patch && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout lorem^0 && + git am rename.patch && + ! test -d .git/rebase-apply && + git update-index --refresh && + git diff --exit-code rename +' + +test_expect_success 'am -3 can rename a file' ' + grep "^rename from" rename.patch && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout lorem^0 && + git am -3 rename.patch && + ! test -d .git/rebase-apply && + git update-index --refresh && + git diff --exit-code rename +' + +test_expect_success 'am -3 can rename a file after falling back to 3-way merge' ' + grep "^rename from" rename-add.patch && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout lorem^0 && + git am -3 rename-add.patch && + ! test -d .git/rebase-apply && + git update-index --refresh && + git diff --exit-code rename ' test_expect_success 'am -3 -q is quiet' ' + rm -fr .git/rebase-apply && + git checkout -f lorem2 && git reset master2 --hard && sed -n -e "3,\$p" msg >file && head -n 9 msg >>file && git add file && test_tick && git commit -m "copied stuff" && - git am -3 -q lorem-move.patch > output.out 2>&1 && + git am -3 -q lorem-move.patch >output.out 2>&1 && ! test -s output.out ' test_expect_success 'am pauses on conflict' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout lorem2^^ && test_must_fail git am lorem-move.patch && test -d .git/rebase-apply ' test_expect_success 'am --skip works' ' + echo goodbye >expected && git am --skip && ! test -d .git/rebase-apply && - test -z "$(git diff lorem2^^ -- file)" && - test goodbye = "$(cat another)" + git diff --exit-code lorem2^^ -- file && + test_cmp expected another ' test_expect_success 'am --resolved works' ' + echo goodbye >expected && + rm -fr .git/rebase-apply && + git reset --hard && git checkout lorem2^^ && test_must_fail git am lorem-move.patch && test -d .git/rebase-apply && @@ -242,22 +331,29 @@ test_expect_success 'am --resolved works' ' git add file && git am --resolved && ! test -d .git/rebase-apply && - test goodbye = "$(cat another)" + test_cmp expected another ' test_expect_success 'am takes patches from a Pine mailbox' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && cat pine patch1 | git am && ! test -d .git/rebase-apply && - test -z "$(git diff master^..HEAD)" + git diff --exit-code master^..HEAD ' test_expect_success 'am fails on mail without patch' ' + rm -fr .git/rebase-apply && + git reset --hard && test_must_fail git am <failmail && - rm -r .git/rebase-apply/ + git am --abort && + ! test -d .git/rebase-apply ' test_expect_success 'am fails on empty patch' ' + rm -fr .git/rebase-apply && + git reset --hard && echo "---" >>failmail && test_must_fail git am <failmail && git am --skip && @@ -266,28 +362,34 @@ test_expect_success 'am fails on empty patch' ' test_expect_success 'am works from stdin in subdirectory' ' rm -fr subdir && + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && ( mkdir -p subdir && cd subdir && git am <../patch1 ) && - test -z "$(git diff second)" + git diff --exit-code second ' test_expect_success 'am works from file (relative path given) in subdirectory' ' rm -fr subdir && + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && ( mkdir -p subdir && cd subdir && git am ../patch1 ) && - test -z "$(git diff second)" + git diff --exit-code second ' test_expect_success 'am works from file (absolute path given) in subdirectory' ' rm -fr subdir && + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && P=$(pwd) && ( @@ -295,27 +397,31 @@ test_expect_success 'am works from file (absolute path given) in subdirectory' ' cd subdir && git am "$P/patch1" ) && - test -z "$(git diff second)" + git diff --exit-code second ' test_expect_success 'am --committer-date-is-author-date' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && test_tick && git am --committer-date-is-author-date patch1 && git cat-file commit HEAD | sed -e "/^\$/q" >head1 && - at=$(sed -ne "/^author /s/.*> //p" head1) && - ct=$(sed -ne "/^committer /s/.*> //p" head1) && - test "$at" = "$ct" + sed -ne "/^author /s/.*> //p" head1 >at && + sed -ne "/^committer /s/.*> //p" head1 >ct && + test_cmp at ct ' test_expect_success 'am without --committer-date-is-author-date' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && test_tick && git am patch1 && git cat-file commit HEAD | sed -e "/^\$/q" >head1 && - at=$(sed -ne "/^author /s/.*> //p" head1) && - ct=$(sed -ne "/^committer /s/.*> //p" head1) && - test "$at" != "$ct" + sed -ne "/^author /s/.*> //p" head1 >at && + sed -ne "/^committer /s/.*> //p" head1 >ct && + ! test_cmp at ct ' # This checks for +0000 because TZ is set to UTC and that should @@ -323,41 +429,51 @@ test_expect_success 'am without --committer-date-is-author-date' ' # by test_tick that uses -0700 timezone; if this feature does not # work, we will see that instead of +0000. test_expect_success 'am --ignore-date' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && test_tick && git am --ignore-date patch1 && git cat-file commit HEAD | sed -e "/^\$/q" >head1 && - at=$(sed -ne "/^author /s/.*> //p" head1) && - echo "$at" | grep "+0000" + sed -ne "/^author /s/.*> //p" head1 >at && + grep "+0000" at ' test_expect_success 'am into an unborn branch' ' + git rev-parse first^{tree} >expected && + rm -fr .git/rebase-apply && + git reset --hard && rm -fr subdir && - mkdir -p subdir && + mkdir subdir && git format-patch --numbered-files -o subdir -1 first && ( cd subdir && git init && git am 1 ) && - result=$( - cd subdir && git rev-parse HEAD^{tree} + ( + cd subdir && + git rev-parse HEAD^{tree} >../actual ) && - test "z$result" = "z$(git rev-parse first^{tree})" + test_cmp expected actual ' test_expect_success 'am newline in subject' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && test_tick && - sed -e "s/second/second \\\n foo/" patch1 > patchnl && - git am < patchnl > output.out 2>&1 && + sed -e "s/second/second \\\n foo/" patch1 >patchnl && + git am <patchnl >output.out 2>&1 && grep "^Applying: second \\\n foo$" output.out ' test_expect_success 'am -q is quiet' ' + rm -fr .git/rebase-apply && + git reset --hard && git checkout first && test_tick && - git am -q < patch1 > output.out 2>&1 && + git am -q <patch1 >output.out 2>&1 && ! test -s output.out ' diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index 2b912d772..b55c41178 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -47,7 +47,7 @@ do test_must_fail git am$with3 --skip >output && test "$(grep "^Applying" output)" = "Applying: 6" && test_cmp file-2-expect file-2 && - test ! -f .git/rr-cache/MERGE_RR + test ! -f .git/MERGE_RR ' test_expect_success "am --abort goes back after failed am$with3" ' @@ -57,7 +57,7 @@ do test_cmp expect actual && test_cmp file-2-expect file-2 && git diff-index --exit-code --cached HEAD && - test ! -f .git/rr-cache/MERGE_RR + test ! -f .git/MERGE_RR ' done diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 876f09a6f..36255d608 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -166,6 +166,8 @@ test_expect_success 'first postimage wins' ' git commit -q -a -m "prefer first over second" && test -f $rr/postimage && + oldmtimepost=$(test-chmtime -v -60 $rr/postimage | cut -f 1) && + git checkout -b third master && git show second^:a1 | sed "s/To die: t/To die! T/" >a1 && git commit -q -a -m third && @@ -176,6 +178,11 @@ test_expect_success 'first postimage wins' ' test_cmp expect a1 ' +test_expect_success 'rerere updates postimage timestamp' ' + newmtimepost=$(test-chmtime -v +0 $rr/postimage | cut -f 1) && + test $oldmtimepost -lt $newmtimepost +' + test_expect_success 'rerere clear' ' rm $rr/postimage && echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR && @@ -198,18 +205,19 @@ test_expect_success 'set up for garbage collection tests' ' almost_60_days_ago=$((60-60*86400)) && just_over_60_days_ago=$((-1-60*86400)) && - test-chmtime =$almost_60_days_ago $rr/preimage && + test-chmtime =$just_over_60_days_ago $rr/preimage && + test-chmtime =$almost_60_days_ago $rr/postimage && test-chmtime =$almost_15_days_ago $rr2/preimage ' -test_expect_success 'garbage collection preserves young records' ' +test_expect_success 'gc preserves young or recently used records' ' git rerere gc && test -f $rr/preimage && test -f $rr2/preimage ' test_expect_success 'old records rest in peace' ' - test-chmtime =$just_over_60_days_ago $rr/preimage && + test-chmtime =$just_over_60_days_ago $rr/postimage && test-chmtime =$just_over_15_days_ago $rr2/preimage && git rerere gc && ! test -f $rr/preimage && diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 2230e606e..2e5135694 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -100,13 +100,11 @@ test_expect_success 'oneline' ' test_expect_success 'diff-filter=A' ' - actual=$(git log --pretty="format:%s" --diff-filter=A HEAD) && - expect=$(echo fifth ; echo fourth ; echo third ; echo initial) && - test "$actual" = "$expect" || { - echo Oops - echo "Actual: $actual" - false - } + git log --pretty="format:%s" --diff-filter=A HEAD > actual && + git log --pretty="format:%s" --diff-filter A HEAD > actual-separate && + printf "fifth\nfourth\nthird\ninitial" > expect && + test_cmp expect actual && + test_cmp expect actual-separate ' @@ -203,6 +201,13 @@ test_expect_success 'log --grep' ' test_cmp expect actual ' +test_expect_success 'log --grep option parsing' ' + echo second >expect && + git log -1 --pretty="tformat:%s" --grep sec >actual && + test_cmp expect actual && + test_must_fail git log -1 --pretty="tformat:%s" --grep +' + test_expect_success 'log -i --grep' ' echo Second >expect && git log -1 --pretty="tformat:%s" -i --grep=sec >actual && @@ -436,5 +441,17 @@ test_expect_success 'log.decorate configuration' ' ' -test_done +test_expect_success 'show added path under "--follow -M"' ' + # This tests for a regression introduced in v1.7.2-rc0~103^2~2 + test_create_repo regression && + ( + cd regression && + test_commit needs-another-commit && + test_commit foo.bar && + git log -M --follow -p foo.bar.t && + git log -M --follow --stat foo.bar.t && + git log -M --follow --name-only foo.bar.t + ) +' +test_done diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh new file mode 100755 index 000000000..bbde31b01 --- /dev/null +++ b/t/t4207-log-decoration-colors.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# +# Copyright (c) 2010 Nazri Ramliy +# + +test_description='Test for "git log --decorate" colors' + +. ./test-lib.sh + +get_color () +{ + git config --get-color no.such.slot "$1" +} + +test_expect_success setup ' + git config diff.color.commit yellow && + git config color.decorate.branch green && + git config color.decorate.remoteBranch red && + git config color.decorate.tag "reverse bold yellow" && + git config color.decorate.stash magenta && + git config color.decorate.HEAD cyan && + + c_reset=$(get_color reset) && + + c_commit=$(get_color yellow) && + c_branch=$(get_color green) && + c_remoteBranch=$(get_color red) && + c_tag=$(get_color "reverse bold yellow") && + c_stash=$(get_color magenta) && + c_HEAD=$(get_color cyan) && + + test_commit A && + git clone . other && + ( + cd other && + test_commit A1 + ) && + + git remote add -f other ./other && + test_commit B && + git tag v1.0 && + echo >>A.t && + git stash save Changes to A.t +' + +cat >expected <<EOF +${c_commit}COMMIT_ID (${c_HEAD}HEAD${c_reset}${c_commit},\ + ${c_tag}tag: v1.0${c_reset}${c_commit},\ + ${c_tag}tag: B${c_reset}${c_commit},\ + ${c_branch}master${c_reset}${c_commit})${c_reset} B +${c_commit}COMMIT_ID (${c_tag}tag: A1${c_reset}${c_commit},\ + ${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1 +${c_commit}COMMIT_ID (${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\ + On master: Changes to A.t +${c_commit}COMMIT_ID (${c_tag}tag: A${c_reset}${c_commit})${c_reset} A +EOF + +# We want log to show all, but the second parent to refs/stash is irrelevant +# to this test since it does not contain any decoration, hence --first-parent +test_expect_success 'Commit Decorations Colored Correctly' ' + git log --first-parent --abbrev=10 --all --decorate --oneline --color=always | + sed "s/[0-9a-f]\{10,10\}/COMMIT_ID/" >out && + test_cmp expected out +' + +test_done diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh new file mode 100755 index 000000000..46c3fe76d --- /dev/null +++ b/t/t4300-merge-tree.sh @@ -0,0 +1,257 @@ +#!/bin/sh +# +# Copyright (c) 2010 Will Palmer +# + +test_description='git merge-tree' +. ./test-lib.sh + +test_expect_success setup ' + test_commit "initial" "initial-file" "initial" +' + +test_expect_success 'file add A, !B' ' + cat >expected <<\EXPECTED && +added in remote + their 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE +@@ -0,0 +1 @@ ++AAA +EXPECTED + + git reset --hard initial && + test_commit "add-a-not-b" "ONE" "AAA" && + git merge-tree initial initial add-a-not-b >actual && + test_cmp expected actual +' + +test_expect_success 'file add !A, B' ' + cat >expected <<\EXPECTED && +added in local + our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE +EXPECTED + + git reset --hard initial && + test_commit "add-not-a-b" "ONE" "AAA" && + git merge-tree initial add-not-a-b initial >actual && + test_cmp expected actual +' + +test_expect_success 'file add A, B (same)' ' + cat >expected <<\EXPECTED && +added in both + our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE + their 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE +EXPECTED + + git reset --hard initial && + test_commit "add-a-b-same-A" "ONE" "AAA" && + git reset --hard initial && + test_commit "add-a-b-same-B" "ONE" "AAA" && + git merge-tree initial add-a-b-same-A add-a-b-same-B >actual && + test_cmp expected actual +' + +test_expect_success 'file add A, B (different)' ' + cat >expected <<\EXPECTED && +added in both + our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE + their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE +@@ -1 +1,5 @@ ++<<<<<<< .our + AAA ++======= ++BBB ++>>>>>>> .their +EXPECTED + + git reset --hard initial && + test_commit "add-a-b-diff-A" "ONE" "AAA" && + git reset --hard initial && + test_commit "add-a-b-diff-B" "ONE" "BBB" && + git merge-tree initial add-a-b-diff-A add-a-b-diff-B >actual && + test_cmp expected actual +' + +test_expect_success 'file change A, !B' ' + cat >expected <<\EXPECTED && +EXPECTED + + git reset --hard initial && + test_commit "change-a-not-b" "initial-file" "BBB" && + git merge-tree initial change-a-not-b initial >actual && + test_cmp expected actual +' + +test_expect_success 'file change !A, B' ' + cat >expected <<\EXPECTED && +merged + result 100644 ba629238ca89489f2b350e196ca445e09d8bb834 initial-file + our 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file +@@ -1 +1 @@ +-initial ++BBB +EXPECTED + + git reset --hard initial && + test_commit "change-not-a-b" "initial-file" "BBB" && + git merge-tree initial initial change-not-a-b >actual && + test_cmp expected actual +' + +test_expect_success 'file change A, B (same)' ' + cat >expected <<\EXPECTED && +EXPECTED + + git reset --hard initial && + test_commit "change-a-b-same-A" "initial-file" "AAA" && + git reset --hard initial && + test_commit "change-a-b-same-B" "initial-file" "AAA" && + git merge-tree initial change-a-b-same-A change-a-b-same-B >actual && + test_cmp expected actual +' + +test_expect_success 'file change A, B (different)' ' + cat >expected <<\EXPECTED && +changed in both + base 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file + our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d initial-file + their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 initial-file +@@ -1 +1,5 @@ ++<<<<<<< .our + AAA ++======= ++BBB ++>>>>>>> .their +EXPECTED + + git reset --hard initial && + test_commit "change-a-b-diff-A" "initial-file" "AAA" && + git reset --hard initial && + test_commit "change-a-b-diff-B" "initial-file" "BBB" && + git merge-tree initial change-a-b-diff-A change-a-b-diff-B >actual && + test_cmp expected actual +' + +test_expect_success 'file change A, B (mixed)' ' + cat >expected <<\EXPECTED && +changed in both + base 100644 f4f1f998c7776568c4ff38f516d77fef9399b5a7 ONE + our 100644 af14c2c3475337c73759d561ef70b59e5c731176 ONE + their 100644 372d761493f524d44d59bd24700c3bdf914c973c ONE +@@ -7,7 +7,11 @@ + AAA + AAA + AAA ++<<<<<<< .our + BBB ++======= ++CCC ++>>>>>>> .their + AAA + AAA + AAA +EXPECTED + + git reset --hard initial && + test_commit "change-a-b-mix-base" "ONE" " +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA +AAA" && + test_commit "change-a-b-mix-A" "ONE" \ + "$(sed -e "1{s/AAA/BBB/;}" -e "10{s/AAA/BBB/;}" <ONE)" && + git reset --hard change-a-b-mix-base && + test_commit "change-a-b-mix-B" "ONE" \ + "$(sed -e "1{s/AAA/BBB/;}" -e "10{s/AAA/CCC/;}" <ONE)" && + git merge-tree change-a-b-mix-base change-a-b-mix-A change-a-b-mix-B \ + >actual && + test_cmp expected actual +' + +test_expect_success 'file remove A, !B' ' + cat >expected <<\EXPECTED && +removed in local + base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE + their 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE +EXPECTED + + git reset --hard initial && + test_commit "rm-a-not-b-base" "ONE" "AAA" && + git rm ONE && + git commit -m "rm-a-not-b" && + git tag "rm-a-not-b" && + git merge-tree rm-a-not-b-base rm-a-not-b rm-a-not-b-base >actual && + test_cmp expected actual +' + +test_expect_success 'file remove !A, B' ' + cat >expected <<\EXPECTED && +removed in remote + base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE + our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE +@@ -1 +0,0 @@ +-AAA +EXPECTED + + git reset --hard initial && + test_commit "rm-not-a-b-base" "ONE" "AAA" && + git rm ONE && + git commit -m "rm-not-a-b" && + git tag "rm-not-a-b" && + git merge-tree rm-a-not-b-base rm-a-not-b-base rm-a-not-b >actual && + test_cmp expected actual +' + +test_expect_success 'file change A, remove B' ' + cat >expected <<\EXPECTED && +removed in remote + base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE + our 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE +@@ -1 +0,0 @@ +-BBB +EXPECTED + + git reset --hard initial && + test_commit "change-a-rm-b-base" "ONE" "AAA" && + test_commit "change-a-rm-b-A" "ONE" "BBB" && + git reset --hard change-a-rm-b-base && + git rm ONE && + git commit -m "change-a-rm-b-B" && + git tag "change-a-rm-b-B" && + git merge-tree change-a-rm-b-base change-a-rm-b-A change-a-rm-b-B \ + >actual && + test_cmp expected actual +' + +test_expect_success 'file remove A, change B' ' + cat >expected <<\EXPECTED && +removed in local + base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE + their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE +EXPECTED + + git reset --hard initial && + test_commit "rm-a-change-b-base" "ONE" "AAA" && + + git rm ONE && + git commit -m "rm-a-change-b-A" && + git tag "rm-a-change-b-A" && + git reset --hard rm-a-change-b-base && + test_commit "rm-a-change-b-B" "ONE" "BBB" && + git merge-tree rm-a-change-b-base rm-a-change-b-A rm-a-change-b-B \ + >actual && + test_cmp expected actual +' + +test_done diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index 27bfba55b..cff1b3e05 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -94,7 +94,7 @@ test_expect_success 'git archive with --output' \ 'git archive --output=b4.tar HEAD && test_cmp b.tar b4.tar' -test_expect_success 'git archive --remote' \ +test_expect_success NOT_MINGW 'git archive --remote' \ 'git archive --remote=. HEAD >b5.tar && test_cmp b.tar b5.tar' diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh index 426b319bd..02d4d2284 100755 --- a/t/t5001-archive-attr.sh +++ b/t/t5001-archive-attr.sh @@ -4,7 +4,7 @@ test_description='git archive attribute tests' . ./test-lib.sh -SUBSTFORMAT=%H%n +SUBSTFORMAT='%H (%h)%n' test_expect_exists() { test_expect_success " $1 exists" "test -e $1" diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 4360e77d3..fb3a27082 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -74,7 +74,7 @@ if msg=$(git verify-pack -v "test-3-${pack3}.pack" 2>&1) || then test_set_prereq OFF64_T else - say "skipping tests concerning 64-bit offsets" + say "# skipping tests concerning 64-bit offsets" fi test_expect_success OFF64_T \ diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index c71825367..5bcf0b867 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -94,6 +94,29 @@ test_expect_success 'refuse deleting push with denyDeletes' ' test_must_fail git send-pack ./victim :extra master ' +test_expect_success 'cannot override denyDeletes with git -c send-pack' ' + ( + cd victim && + test_might_fail git branch -D extra && + git config receive.denyDeletes true && + git branch extra master + ) && + test_must_fail git -c receive.denyDeletes=false \ + send-pack ./victim :extra master +' + +test_expect_success 'override denyDeletes with git -c receive-pack' ' + ( + cd victim && + test_might_fail git branch -D extra && + git config receive.denyDeletes true && + git branch extra master + ) && + git send-pack \ + --receive-pack="git -c receive.denyDeletes=false receive-pack" \ + ./victim :extra master +' + test_expect_success 'denyNonFastforwards trumps --force' ' ( cd victim && diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh index d5db75d82..aa0ada014 100755 --- a/t/t5503-tagfollow.sh +++ b/t/t5503-tagfollow.sh @@ -4,11 +4,9 @@ test_description='test automatic tag following' . ./test-lib.sh -case $(uname -s) in -*MINGW*) +if ! test_have_prereq NOT_MINGW; then say "GIT_DEBUG_SEND_PACK not supported - skipping tests" - test_done -esac +fi # End state of the repository: # @@ -19,7 +17,7 @@ esac # \ C - origin/cat \ # origin/master master -test_expect_success setup ' +test_expect_success NOT_MINGW setup ' test_tick && echo ichi >file && git add file && @@ -42,12 +40,15 @@ test_expect_success setup ' U=UPLOAD_LOG +test_expect_success NOT_MINGW 'setup expect' ' cat - <<EOF >expect #S want $A #E EOF -test_expect_success 'fetch A (new commit : 1 connection)' ' +' + +test_expect_success NOT_MINGW 'fetch A (new commit : 1 connection)' ' rm -f $U ( cd cloned && @@ -59,7 +60,7 @@ test_expect_success 'fetch A (new commit : 1 connection)' ' test_cmp expect actual ' -test_expect_success "create tag T on A, create C on branch cat" ' +test_expect_success NOT_MINGW "create tag T on A, create C on branch cat" ' git tag -a -m tag1 tag1 $A && T=$(git rev-parse --verify tag1) && @@ -71,13 +72,16 @@ test_expect_success "create tag T on A, create C on branch cat" ' git checkout master ' +test_expect_success NOT_MINGW 'setup expect' ' cat - <<EOF >expect #S want $C want $T #E EOF -test_expect_success 'fetch C, T (new branch, tag : 1 connection)' ' +' + +test_expect_success NOT_MINGW 'fetch C, T (new branch, tag : 1 connection)' ' rm -f $U ( cd cloned && @@ -91,7 +95,7 @@ test_expect_success 'fetch C, T (new branch, tag : 1 connection)' ' test_cmp expect actual ' -test_expect_success "create commits O, B, tag S on B" ' +test_expect_success NOT_MINGW "create commits O, B, tag S on B" ' test_tick && echo O >file && git add file && @@ -107,13 +111,16 @@ test_expect_success "create commits O, B, tag S on B" ' S=$(git rev-parse --verify tag2) ' +test_expect_success NOT_MINGW 'setup expect' ' cat - <<EOF >expect #S want $B want $S #E EOF -test_expect_success 'fetch B, S (commit and tag : 1 connection)' ' +' + +test_expect_success NOT_MINGW 'fetch B, S (commit and tag : 1 connection)' ' rm -f $U ( cd cloned && @@ -127,13 +134,16 @@ test_expect_success 'fetch B, S (commit and tag : 1 connection)' ' test_cmp expect actual ' +test_expect_success NOT_MINGW 'setup expect' ' cat - <<EOF >expect #S want $B want $S #E EOF -test_expect_success 'new clone fetch master and tags' ' +' + +test_expect_success NOT_MINGW 'new clone fetch master and tags' ' git branch -D cat rm -f $U ( diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 4c498b190..5d1c66ea7 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -435,7 +435,7 @@ test_expect_success 'update --prune' ' git branch -m side2 side3) && (cd test && git remote update --prune && - (cd ../one && git branch -m side3 side2) + (cd ../one && git branch -m side3 side2) && git rev-parse refs/remotes/origin/side3 && test_must_fail git rev-parse refs/remotes/origin/side2) ' diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 4eb10f602..9a884751e 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -21,27 +21,30 @@ test_expect_success setup ' test_expect_success "clone and setup child repos" ' git clone . one && - cd one && - echo >file updated by one && - git commit -a -m "updated by one" && - cd .. && + ( + cd one && + echo >file updated by one && + git commit -a -m "updated by one" + ) && git clone . two && - cd two && - git config branch.master.remote one && - git config remote.one.url ../one/.git/ && - git config remote.one.fetch refs/heads/master:refs/heads/one && - cd .. && + ( + cd two && + git config branch.master.remote one && + git config remote.one.url ../one/.git/ && + git config remote.one.fetch refs/heads/master:refs/heads/one + ) && git clone . three && - cd three && - git config branch.master.remote two && - git config branch.master.merge refs/heads/one && - mkdir -p .git/remotes && - { - echo "URL: ../two/.git/" - echo "Pull: refs/heads/master:refs/heads/two" - echo "Pull: refs/heads/one:refs/heads/one" - } >.git/remotes/two && - cd .. && + ( + cd three && + git config branch.master.remote two && + git config branch.master.merge refs/heads/one && + mkdir -p .git/remotes && + { + echo "URL: ../two/.git/" + echo "Pull: refs/heads/master:refs/heads/two" + echo "Pull: refs/heads/one:refs/heads/one" + } >.git/remotes/two + ) && git clone . bundle && git clone . seven ' @@ -240,6 +243,38 @@ test_expect_success 'fetch with a non-applying branch.<name>.merge' ' git fetch blub ' +# URL supplied to fetch does not match the url of the configured branch's remote +test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [1]' ' + one_head=$(cd one && git rev-parse HEAD) && + this_head=$(git rev-parse HEAD) && + git update-ref -d FETCH_HEAD && + git fetch one && + test $one_head = "$(git rev-parse --verify FETCH_HEAD)" && + test $this_head = "$(git rev-parse --verify HEAD)" +' + +# URL supplied to fetch matches the url of the configured branch's remote and +# the merge spec matches the branch the remote HEAD points to +test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [2]' ' + one_ref=$(cd one && git symbolic-ref HEAD) && + git config branch.master.remote blub && + git config branch.master.merge "$one_ref" && + git update-ref -d FETCH_HEAD && + git fetch one && + test $one_head = "$(git rev-parse --verify FETCH_HEAD)" && + test $this_head = "$(git rev-parse --verify HEAD)" +' + +# URL supplied to fetch matches the url of the configured branch's remote, but +# the merge spec does not match the branch the remote HEAD points to +test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge [3]' ' + git config branch.master.merge "${one_ref}_not" && + git update-ref -d FETCH_HEAD && + git fetch one && + test $one_head = "$(git rev-parse --verify FETCH_HEAD)" && + test $this_head = "$(git rev-parse --verify HEAD)" +' + # the strange name is: a\!'b test_expect_success 'quoting of a strangely named repo' ' test_must_fail git fetch "a\\!'\''b" > result 2>&1 && diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 319e389ed..0b489f5b1 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -4,6 +4,11 @@ test_description='pulling into void' . ./test-lib.sh +modify () { + sed -e "$1" <"$2" >"$2.x" && + mv "$2.x" "$2" +} + D=`pwd` test_expect_success setup ' @@ -160,4 +165,61 @@ test_expect_success 'pull --rebase works on branch yet to be born' ' test_cmp expect actual ' +test_expect_success 'setup for detecting upstreamed changes' ' + mkdir src && + (cd src && + git init && + printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff && + git add stuff && + git commit -m "Initial revision" + ) && + git clone src dst && + (cd src && + modify s/5/43/ stuff && + git commit -a -m "5->43" && + modify s/6/42/ stuff && + git commit -a -m "Make it bigger" + ) && + (cd dst && + modify s/5/43/ stuff && + git commit -a -m "Independent discovery of 5->43" + ) +' + +test_expect_success 'git pull --rebase detects upstreamed changes' ' + (cd dst && + git pull --rebase && + test -z "$(git ls-files -u)" + ) +' + +test_expect_success 'setup for avoiding reapplying old patches' ' + (cd dst && + test_might_fail git rebase --abort && + git reset --hard origin/master + ) && + git clone --bare src src-replace.git && + rm -rf src && + mv src-replace.git src && + (cd dst && + modify s/2/22/ stuff && + git commit -a -m "Change 2" && + modify s/3/33/ stuff && + git commit -a -m "Change 3" && + modify s/4/44/ stuff && + git commit -a -m "Change 4" && + git push && + + modify s/44/55/ stuff && + git commit --amend -a -m "Modified Change 4" + ) +' + +test_expect_success 'git pull --rebase does not reapply old patches' ' + (cd dst && + test_must_fail git pull --rebase && + test 1 = $(find .git/rebase-apply -name "000*" | wc -l) + ) +' + test_done diff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh index 7206817ca..8e9b204e0 100755 --- a/t/t5522-pull-symlink.sh +++ b/t/t5522-pull-symlink.sh @@ -4,12 +4,6 @@ test_description='pulling from symlinked subdir' . ./test-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - # The scenario we are building: # # trash\ directory/ @@ -20,7 +14,7 @@ fi # # The working directory is subdir-link. -test_expect_success setup ' +test_expect_success SYMLINKS setup ' mkdir subdir && echo file >subdir/file && git add subdir/file && @@ -36,7 +30,7 @@ test_expect_success setup ' # Demonstrate that things work if we just avoid the symlink # -test_expect_success 'pulling from real subdir' ' +test_expect_success SYMLINKS 'pulling from real subdir' ' ( echo real >subdir/file && git commit -m real subdir/file && @@ -64,7 +58,7 @@ test_expect_success 'pulling from real subdir' ' # directory. A POSIX shell's "cd" works a little differently # than chdir() in C; "cd -P" is much closer to chdir(). # -test_expect_success 'pulling from symlinked subdir' ' +test_expect_success SYMLINKS 'pulling from symlinked subdir' ' ( echo link >subdir/file && git commit -m link subdir/file && @@ -77,7 +71,7 @@ test_expect_success 'pulling from symlinked subdir' ' # Prove that the remote end really is a repo, and other commands # work fine in this context. It's just that "git pull" breaks. # -test_expect_success 'pushing from symlinked subdir' ' +test_expect_success SYMLINKS 'pushing from symlinked subdir' ' ( cd subdir-link/ && echo push >file && diff --git a/t/t5525-fetch-tagopt.sh b/t/t5525-fetch-tagopt.sh new file mode 100755 index 000000000..4fbf7a120 --- /dev/null +++ b/t/t5525-fetch-tagopt.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +test_description='tagopt variable affects "git fetch" and is overridden by commandline.' + +. ./test-lib.sh + +setup_clone () { + git clone --mirror . $1 && + git remote add remote_$1 $1 && + (cd $1 && + git tag tag_$1) +} + +test_expect_success setup ' + test_commit test && + setup_clone one && + git config remote.remote_one.tagopt --no-tags && + setup_clone two && + git config remote.remote_two.tagopt --tags + ' + +test_expect_success "fetch with tagopt=--no-tags does not get tag" ' + git fetch remote_one && + test_must_fail git show-ref tag_one + ' + +test_expect_success "fetch --tags with tagopt=--no-tags gets tag" ' + git fetch --tags remote_one && + git show-ref tag_one + ' + +test_expect_success "fetch --no-tags with tagopt=--tags does not get tag" ' + git fetch --no-tags remote_two && + test_must_fail git show-ref tag_two + ' + +test_expect_success "fetch with tagopt=--tags gets tag" ' + git fetch remote_two && + git show-ref tag_two + ' +test_done diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index 044603c26..6b2a5f4a6 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -60,6 +60,15 @@ test_expect_success 'upload-pack fails due to error in rev-list' ' grep "bad tree object" output.err ' +test_expect_success 'upload-pack error message when bad ref requested' ' + + printf "0045want %s multi_ack_detailed\n00000009done\n0000" \ + "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" >input && + test_must_fail git upload-pack . <input >output 2>output.err && + grep -q "not our ref" output.err && + ! grep -q multi_ack_detailed output.err +' + test_expect_success 'upload-pack fails due to error in pack-objects enumeration' ' printf "0032want %s\n00000009done\n0000" \ diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh index 37fe87541..a266ca563 100755 --- a/t/t5540-http-push.sh +++ b/t/t5540-http-push.sh @@ -11,7 +11,7 @@ This test runs various sanity checks on http-push.' if git http-push > /dev/null 2>&1 || [ $? -eq 128 ] then - say "skipping test, USE_CURL_MULTI is not defined" + skip_all="skipping test, USE_CURL_MULTI is not defined" test_done fi diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh index 17e1bdc5a..b0c2a2c3a 100755 --- a/t/t5541-http-push.sh +++ b/t/t5541-http-push.sh @@ -7,7 +7,7 @@ test_description='test smart pushing over http via http-backend' . ./test-lib.sh if test -n "$NO_CURL"; then - say 'skipping test, git built without http support' + skip_all='skipping test, git built without http support' test_done fi @@ -128,7 +128,7 @@ test_expect_success 'push fails for non-fast-forward refs unmatched by remote he # push master too; this ensures there is at least one '"'push'"' command to # the remote helper and triggers interaction with the helper. - !(git push -v origin +master master:retsam >output 2>&1) && + test_must_fail git push -v origin +master master:retsam >output 2>&1 && grep "^ + [a-f0-9]*\.\.\.[a-f0-9]* *master -> master (forced update)$" output && grep "^ ! \[rejected\] *master -> retsam (non-fast-forward)$" output && diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh index fc675b50a..2fb48d09e 100755 --- a/t/t5550-http-fetch.sh +++ b/t/t5550-http-fetch.sh @@ -4,7 +4,7 @@ test_description='test dumb fetching over http via static file' . ./test-lib.sh if test -n "$NO_CURL"; then - say 'skipping test, git built without http support' + skip_all='skipping test, git built without http support' test_done fi diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh index 7faa31a29..fd1912137 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@ -4,7 +4,7 @@ test_description='test smart fetching over http via http-backend' . ./test-lib.sh if test -n "$NO_CURL"; then - say 'skipping test, git built without http support' + skip_all='skipping test, git built without http support' test_done fi diff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh index 44885b850..0ad7ce07c 100755 --- a/t/t5560-http-backend-noserver.sh +++ b/t/t5560-http-backend-noserver.sh @@ -5,16 +5,17 @@ test_description='test git-http-backend-noserver' HTTPD_DOCUMENT_ROOT_PATH="$TRASH_DIRECTORY" +test_have_prereq MINGW && export GREP_OPTIONS=-U + run_backend() { echo "$2" | QUERY_STRING="${1#*\?}" \ - GIT_PROJECT_ROOT="$HTTPD_DOCUMENT_ROOT_PATH" \ - PATH_INFO="${1%%\?*}" \ + PATH_TRANSLATED="$HTTPD_DOCUMENT_ROOT_PATH/${1%%\?*}" \ git http-backend >act.out 2>act.err } GET() { - export REQUEST_METHOD="GET" && + REQUEST_METHOD="GET" && export REQUEST_METHOD && run_backend "/repo.git/$1" && unset REQUEST_METHOD && if ! grep "Status" act.out >act @@ -26,8 +27,8 @@ GET() { } POST() { - export REQUEST_METHOD="POST" && - export CONTENT_TYPE="application/x-$1-request" && + REQUEST_METHOD="POST" && export REQUEST_METHOD && + CONTENT_TYPE="application/x-$1-request" && export CONTENT_TYPE && run_backend "/repo.git/$1" "$2" && unset REQUEST_METHOD && unset CONTENT_TYPE && @@ -46,7 +47,7 @@ log_div() { . "$TEST_DIRECTORY"/t556x_common expect_aliased() { - export REQUEST_METHOD="GET" && + REQUEST_METHOD="GET" && export REQUEST_METHOD && if test $1 = 0; then run_backend "$2" else diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh index 8c6d0b2f2..b5d7fbc38 100755 --- a/t/t5561-http-backend.sh +++ b/t/t5561-http-backend.sh @@ -4,7 +4,7 @@ test_description='test git-http-backend' . ./test-lib.sh if test -n "$NO_CURL"; then - say 'skipping test, git built without http support' + skip_all='skipping test, git built without http support' test_done fi diff --git a/t/t556x_common b/t/t556x_common index be024e551..51287d89d 100755 --- a/t/t556x_common +++ b/t/t556x_common @@ -50,7 +50,7 @@ get_static_files() { } SMART=smart -export GIT_HTTP_EXPORT_ALL=1 +GIT_HTTP_EXPORT_ALL=1 && export GIT_HTTP_EXPORT_ALL test_expect_success 'direct refs/heads/master not found' ' log_div "refs/heads/master" GET refs/heads/master "404 Not Found" @@ -73,7 +73,7 @@ test_expect_success 'export if git-daemon-export-ok' ' get_static_files "200 OK" ' SMART=smart -export GIT_HTTP_EXPORT_ALL=1 +GIT_HTTP_EXPORT_ALL=1 && export GIT_HTTP_EXPORT_ALL test_expect_success 'static file if http.getanyfile true is ok' ' log_div "getanyfile true" config http.getanyfile true && diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 8abb71afc..987e0c846 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -163,8 +163,6 @@ test_expect_success 'clone a void' ' test_expect_success 'clone respects global branch.autosetuprebase' ' ( - HOME=$(pwd) && - export HOME && test_config="$HOME/.gitconfig" && unset GIT_CONFIG_NOGLOBAL && git config -f "$test_config" branch.autosetuprebase remote && @@ -178,8 +176,14 @@ test_expect_success 'clone respects global branch.autosetuprebase' ' test_expect_success 'respect url-encoding of file://' ' git init x+y && - test_must_fail git clone "file://$PWD/x+y" xy-url && - git clone "file://$PWD/x%2By" xy-url + git clone "file://$PWD/x+y" xy-url-1 && + git clone "file://$PWD/x%2By" xy-url-2 +' + +test_expect_success 'do not query-string-decode + in URLs' ' + rm -rf x+y && + git init "x y" && + test_must_fail git clone "file://$PWD/x+y" xy-no-plus ' test_expect_success 'do not respect url-encoding of non-url path' ' diff --git a/t/t5704-bundle.sh b/t/t5704-bundle.sh index ddc3dc52f..728ccd88c 100755 --- a/t/t5704-bundle.sh +++ b/t/t5704-bundle.sh @@ -30,6 +30,13 @@ test_expect_success 'tags can be excluded by rev-list options' ' ' +test_expect_success 'die if bundle file cannot be created' ' + + mkdir adir && + test_must_fail git bundle create adir --all + +' + test_expect_failure 'bundle --stdin' ' echo master | git bundle create stdin-bundle.bdl --stdin && diff --git a/t/t5705-clone-2gb.sh b/t/t5705-clone-2gb.sh index 8afbdd4de..e9783c341 100755 --- a/t/t5705-clone-2gb.sh +++ b/t/t5705-clone-2gb.sh @@ -3,12 +3,14 @@ test_description='Test cloning a repository larger than 2 gigabyte' . ./test-lib.sh -test -z "$GIT_TEST_CLONE_2GB" && -say "Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t" && -test_done && -exit +if test -z "$GIT_TEST_CLONE_2GB" +then + say 'Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t' +else + test_set_prereq CLONE_2GB +fi -test_expect_success 'setup' ' +test_expect_success CLONE_2GB 'setup' ' git config pack.compression 0 && git config pack.depth 0 && @@ -36,13 +38,13 @@ test_expect_success 'setup' ' ' -test_expect_success 'clone - bare' ' +test_expect_success CLONE_2GB 'clone - bare' ' git clone --bare --no-hardlinks . clone-bare ' -test_expect_success 'clone - with worktree, file:// protocol' ' +test_expect_success CLONE_2GB 'clone - with worktree, file:// protocol' ' git clone file://. clone-wt diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-helpers.sh index 4ee7b65ce..1fb6380fc 100755 --- a/t/t5800-remote-helpers.sh +++ b/t/t5800-remote-helpers.sh @@ -13,13 +13,11 @@ if sys.hexversion < 0x02040000: sys.exit(1) ' then - : -else - say 'skipping git remote-testgit tests: requires Python 2.4 or newer' - test_done + # Requires Python 2.4 or newer + test_set_prereq PYTHON_24 fi -test_expect_success 'setup repository' ' +test_expect_success PYTHON_24 'setup repository' ' git init --bare server/.git && git clone server public && (cd public && @@ -29,34 +27,34 @@ test_expect_success 'setup repository' ' git push origin master) ' -test_expect_success 'cloning from local repo' ' +test_expect_success PYTHON_24 'cloning from local repo' ' git clone "testgit::${PWD}/server" localclone && test_cmp public/file localclone/file ' -test_expect_success 'cloning from remote repo' ' +test_expect_success PYTHON_24 'cloning from remote repo' ' git clone "testgit::file://${PWD}/server" clone && test_cmp public/file clone/file ' -test_expect_success 'create new commit on remote' ' +test_expect_success PYTHON_24 'create new commit on remote' ' (cd public && echo content >>file && git commit -a -m two && git push) ' -test_expect_success 'pulling from local repo' ' +test_expect_success PYTHON_24 'pulling from local repo' ' (cd localclone && git pull) && test_cmp public/file localclone/file ' -test_expect_success 'pulling from remote remote' ' +test_expect_success PYTHON_24 'pulling from remote remote' ' (cd clone && git pull) && test_cmp public/file clone/file ' -test_expect_success 'pushing to local repo' ' +test_expect_success PYTHON_24 'pushing to local repo' ' (cd localclone && echo content >>file && git commit -a -m three && @@ -65,12 +63,12 @@ test_expect_success 'pushing to local repo' ' test $HEAD = $(git --git-dir=server/.git rev-parse --verify HEAD) ' -test_expect_success 'synch with changes from localclone' ' +test_expect_success PYTHON_24 'synch with changes from localclone' ' (cd clone && git pull) ' -test_expect_success 'pushing remote local repo' ' +test_expect_success PYTHON_24 'pushing remote local repo' ' (cd clone && echo content >>file && git commit -a -m four && diff --git a/t/t6007-rev-list-cherry-pick-file.sh b/t/t6007-rev-list-cherry-pick-file.sh index 4b8611ce2..b565638e9 100755 --- a/t/t6007-rev-list-cherry-pick-file.sh +++ b/t/t6007-rev-list-cherry-pick-file.sh @@ -32,6 +32,23 @@ test_expect_success setup ' git tag B ' +cat >expect <<EOF +<tags/B +>tags/C +EOF + +test_expect_success '--left-right' ' + git rev-list --left-right B...C > actual && + git name-rev --stdin --name-only --refs="*tags/*" \ + < actual > actual.named && + test_cmp actual.named expect +' + +test_expect_success '--count' ' + git rev-list --count B...C > actual && + test "$(cat actual)" = 2 +' + test_expect_success '--cherry-pick foo comes up empty' ' test -z "$(git rev-list --left-right --cherry-pick B...C -- foo)" ' @@ -54,4 +71,16 @@ test_expect_success '--cherry-pick with independent, but identical branches' ' HEAD...master -- foo)" ' +cat >expect <<EOF +1 2 +EOF + +# Insert an extra commit to break the symmetry +test_expect_success '--count --left-right' ' + git checkout branch && + test_commit D && + git rev-list --count --left-right B...D > actual && + test_cmp expect actual +' + test_done diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh index 0144d9e85..62197a3d3 100755 --- a/t/t6010-merge-base.sh +++ b/t/t6010-merge-base.sh @@ -3,175 +3,231 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='Merge base computation. +test_description='Merge base and parent list computation. ' . ./test-lib.sh -T=$(git write-tree) - -M=1130000000 -Z=+0000 - -GIT_COMMITTER_EMAIL=git@comm.iter.xz -GIT_COMMITTER_NAME='C O Mmiter' -GIT_AUTHOR_NAME='A U Thor' -GIT_AUTHOR_EMAIL=git@au.thor.xz -export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL - -doit() { - OFFSET=$1; shift - NAME=$1; shift - PARENTS= - for P - do - PARENTS="${PARENTS}-p $P " - done - GIT_COMMITTER_DATE="$(($M + $OFFSET)) $Z" - GIT_AUTHOR_DATE=$GIT_COMMITTER_DATE - export GIT_COMMITTER_DATE GIT_AUTHOR_DATE - commit=$(echo $NAME | git commit-tree $T $PARENTS) - echo $commit >.git/refs/tags/$NAME - echo $commit -} - -# E---D---C---B---A -# \'-_ \ \ -# \ `---------G \ -# \ \ -# F----------------H - -# Setup... -E=$(doit 5 E) -D=$(doit 4 D $E) -F=$(doit 6 F $E) -C=$(doit 3 C $D) -B=$(doit 2 B $C) -A=$(doit 1 A $B) -G=$(doit 7 G $B $E) -H=$(doit 8 H $A $F) - -test_expect_success 'compute merge-base (single)' \ - 'MB=$(git merge-base G H) && - expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' - -test_expect_success 'compute merge-base (all)' \ - 'MB=$(git merge-base --all G H) && - expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' - -test_expect_success 'compute merge-base with show-branch' \ - 'MB=$(git show-branch --merge-base G H) && - expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' - -# Setup for second test to demonstrate that relying on timestamps in a -# distributed SCM to provide a _consistent_ partial ordering of commits -# leads to insanity. -# -# Relative -# Structure timestamps -# -# PL PR +4 +4 -# / \/ \ / \/ \ -# L2 C2 R2 +3 -1 +3 -# | | | | | | -# L1 C1 R1 +2 -2 +2 -# | | | | | | -# L0 C0 R0 +1 -3 +1 -# \ | / \ | / -# S 0 -# -# The left and right chains of commits can be of any length and complexity as -# long as all of the timestamps are greater than that of S. +test_expect_success 'setup' ' + T=$(git write-tree) && -S=$(doit 0 S) + M=1130000000 && + Z=+0000 && -C0=$(doit -3 C0 $S) -C1=$(doit -2 C1 $C0) -C2=$(doit -1 C2 $C1) + GIT_COMMITTER_EMAIL=git@comm.iter.xz && + GIT_COMMITTER_NAME="C O Mmiter" && + GIT_AUTHOR_NAME="A U Thor" && + GIT_AUTHOR_EMAIL=git@au.thor.xz && + export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL && -L0=$(doit 1 L0 $S) -L1=$(doit 2 L1 $L0) -L2=$(doit 3 L2 $L1) + doit() { + OFFSET=$1 && + NAME=$2 && + shift 2 && -R0=$(doit 1 R0 $S) -R1=$(doit 2 R1 $R0) -R2=$(doit 3 R2 $R1) + PARENTS= && + for P + do + PARENTS="${PARENTS}-p $P " + done && -PL=$(doit 4 PL $L2 $C2) -PR=$(doit 4 PR $C2 $R2) + GIT_COMMITTER_DATE="$(($M + $OFFSET)) $Z" && + GIT_AUTHOR_DATE=$GIT_COMMITTER_DATE && + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE && -test_expect_success 'compute merge-base (single)' \ - 'MB=$(git merge-base PL PR) && - expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/C2"' + commit=$(echo $NAME | git commit-tree $T $PARENTS) && -test_expect_success 'compute merge-base (all)' \ - 'MB=$(git merge-base --all PL PR) && - expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/C2"' + echo $commit >.git/refs/tags/$NAME && + echo $commit + } +' -# Another set to demonstrate base between one commit and a merge -# in the documentation. -# -# * C (MMC) * B (MMB) * A (MMA) -# * o * o * o -# * o * o * o -# * o * o * o -# * o | _______/ -# | |/ -# | * 1 (MM1) -# | _______/ -# |/ -# * root (MMR) +test_expect_success 'set up G and H' ' + # E---D---C---B---A + # \"-_ \ \ + # \ `---------G \ + # \ \ + # F----------------H + E=$(doit 5 E) && + D=$(doit 4 D $E) && + F=$(doit 6 F $E) && + C=$(doit 3 C $D) && + B=$(doit 2 B $C) && + A=$(doit 1 A $B) && + G=$(doit 7 G $B $E) && + H=$(doit 8 H $A $F) +' + +test_expect_success 'merge-base G H' ' + git name-rev $B >expected && + + MB=$(git merge-base G H) && + git name-rev "$MB" >actual.single && + + MB=$(git merge-base --all G H) && + git name-rev "$MB" >actual.all && + + MB=$(git show-branch --merge-base G H) && + git name-rev "$MB" >actual.sb && + + test_cmp expected actual.single && + test_cmp expected actual.all && + test_cmp expected actual.sb +' +test_expect_success 'merge-base/show-branch --independent' ' + git name-rev "$H" >expected1 && + git name-rev "$H" "$G" >expected2 && + + parents=$(git merge-base --independent H) && + git name-rev $parents >actual1.mb && + parents=$(git merge-base --independent A H G) && + git name-rev $parents >actual2.mb && + + parents=$(git show-branch --independent H) && + git name-rev $parents >actual1.sb && + parents=$(git show-branch --independent A H G) && + git name-rev $parents >actual2.sb && + + test_cmp expected1 actual1.mb && + test_cmp expected2 actual2.mb && + test_cmp expected1 actual1.sb && + test_cmp expected2 actual2.sb +' + +test_expect_success 'unsynchronized clocks' ' + # This test is to demonstrate that relying on timestamps in a distributed + # SCM to provide a _consistent_ partial ordering of commits leads to + # insanity. + # + # Relative + # Structure timestamps + # + # PL PR +4 +4 + # / \/ \ / \/ \ + # L2 C2 R2 +3 -1 +3 + # | | | | | | + # L1 C1 R1 +2 -2 +2 + # | | | | | | + # L0 C0 R0 +1 -3 +1 + # \ | / \ | / + # S 0 + # + # The left and right chains of commits can be of any length and complexity as + # long as all of the timestamps are greater than that of S. + + S=$(doit 0 S) && + + C0=$(doit -3 C0 $S) && + C1=$(doit -2 C1 $C0) && + C2=$(doit -1 C2 $C1) && + + L0=$(doit 1 L0 $S) && + L1=$(doit 2 L1 $L0) && + L2=$(doit 3 L2 $L1) && + + R0=$(doit 1 R0 $S) && + R1=$(doit 2 R1 $R0) && + R2=$(doit 3 R2 $R1) && + + PL=$(doit 4 PL $L2 $C2) && + PR=$(doit 4 PR $C2 $R2) + + git name-rev $C2 >expected && + + MB=$(git merge-base PL PR) && + git name-rev "$MB" >actual.single && + + MB=$(git merge-base --all PL PR) && + git name-rev "$MB" >actual.all && + + test_cmp expected actual.single && + test_cmp expected actual.all +' + +test_expect_success '--independent with unsynchronized clocks' ' + IB=$(doit 0 IB) && + I1=$(doit -10 I1 $IB) && + I2=$(doit -9 I2 $I1) && + I3=$(doit -8 I3 $I2) && + I4=$(doit -7 I4 $I3) && + I5=$(doit -6 I5 $I4) && + I6=$(doit -5 I6 $I5) && + I7=$(doit -4 I7 $I6) && + I8=$(doit -3 I8 $I7) && + IH=$(doit -2 IH $I8) && + + echo $IH >expected && + git merge-base --independent IB IH >actual && + test_cmp expected actual +' test_expect_success 'merge-base for octopus-step (setup)' ' - test_tick && git commit --allow-empty -m root && git tag MMR && - test_tick && git commit --allow-empty -m 1 && git tag MM1 && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m A && git tag MMA && + # Another set to demonstrate base between one commit and a merge + # in the documentation. + # + # * C (MMC) * B (MMB) * A (MMA) + # * o * o * o + # * o * o * o + # * o * o * o + # * o | _______/ + # | |/ + # | * 1 (MM1) + # | _______/ + # |/ + # * root (MMR) + + test_commit MMR && + test_commit MM1 && + test_commit MM-o && + test_commit MM-p && + test_commit MM-q && + test_commit MMA && git checkout MM1 && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m B && git tag MMB && + test_commit MM-r && + test_commit MM-s && + test_commit MM-t && + test_commit MMB && git checkout MMR && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m C && git tag MMC + test_commit MM-u && + test_commit MM-v && + test_commit MM-w && + test_commit MM-x && + test_commit MMC ' test_expect_success 'merge-base A B C' ' - MB=$(git merge-base --all MMA MMB MMC) && - MM1=$(git rev-parse --verify MM1) && - test "$MM1" = "$MB" -' + git rev-parse --verify MM1 >expected && + git rev-parse --verify MMR >expected.sb && -test_expect_success 'merge-base A B C using show-branch' ' - MB=$(git show-branch --merge-base MMA MMB MMC) && - MMR=$(git rev-parse --verify MMR) && - test "$MMR" = "$MB" + git merge-base --all MMA MMB MMC >actual && + git merge-base --all --octopus MMA MMB MMC >actual.common && + git show-branch --merge-base MMA MMB MMC >actual.sb && + + test_cmp expected actual && + test_cmp expected.sb actual.common && + test_cmp expected.sb actual.sb ' -test_expect_success 'criss-cross merge-base for octopus-step (setup)' ' +test_expect_success 'criss-cross merge-base for octopus-step' ' git reset --hard MMR && - test_tick && git commit --allow-empty -m 1 && git tag CC1 && + test_commit CC1 && git reset --hard E && - test_tick && git commit --allow-empty -m 2 && git tag CC2 && - test_tick && git merge -s ours CC1 && - test_tick && git commit --allow-empty -m o && - test_tick && git commit --allow-empty -m B && git tag CCB && + test_commit CC2 && + test_tick && + git merge -s ours CC1 && + test_commit CC-o && + test_commit CCB && git reset --hard CC1 && - test_tick && git merge -s ours CC2 && - test_tick && git commit --allow-empty -m A && git tag CCA -' + git merge -s ours CC2 && + test_commit CCA && + + git rev-parse CC1 CC2 >expected && + git merge-base --all CCB CCA^^ CCA^^2 >actual && -test_expect_success 'merge-base B A^^ A^^2' ' - MB0=$(git merge-base --all CCB CCA^^ CCA^^2 | sort) && - MB1=$(git rev-parse CC1 CC2 | sort) && - test "$MB0" = "$MB1" + sort expected >expected.sorted && + sort actual >actual.sorted && + test_cmp expected.sorted actual.sorted ' test_done diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index 8d3fa7d01..fb8291c81 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -34,7 +34,9 @@ test_expect_success 'setup' ' git checkout master && commit master2 && git tag foo/bar master && - git update-ref refs/remotes/foo/baz master + commit master3 && + git update-ref refs/remotes/foo/baz master && + commit master4 ' test_expect_success 'rev-parse --glob=refs/heads/subspace/*' ' @@ -121,6 +123,12 @@ test_expect_success 'rev-list --glob=refs/heads/subspace/*' ' ' +test_expect_success 'rev-list --glob refs/heads/subspace/*' ' + + compare rev-list "subspace/one subspace/two" "--glob refs/heads/subspace/*" + +' + test_expect_success 'rev-list --glob=heads/subspace/*' ' compare rev-list "subspace/one subspace/two" "--glob=heads/subspace/*" @@ -162,6 +170,13 @@ test_expect_success 'rev-list --branches=subspace' ' compare rev-list "subspace/one subspace/two" "--branches=subspace" ' + +test_expect_success 'rev-list --branches' ' + + compare rev-list "master subspace-x someref other/three subspace/one subspace/two" "--branches" + +' + test_expect_success 'rev-list --glob=heads/someref/* master' ' compare rev-list "master" "--glob=heads/someref/* master" @@ -186,6 +201,12 @@ test_expect_success 'rev-list --tags=foo' ' ' +test_expect_success 'rev-list --tags' ' + + compare rev-list "foo/bar" "--tags" + +' + test_expect_success 'rev-list --remotes=foo' ' compare rev-list "foo/baz" "--remotes=foo" diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh index e71c687f2..490d39711 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6020-merge-df.sh @@ -22,7 +22,7 @@ git commit -m "File: dir"' test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master' -test_expect_failure 'F/D conflict' ' +test_expect_success 'F/D conflict' ' git reset --hard && git checkout master && rm .git/index && diff --git a/t/t6031-merge-recursive.sh b/t/t6031-merge-recursive.sh index 8a3304fb0..1cd649e24 100755 --- a/t/t6031-merge-recursive.sh +++ b/t/t6031-merge-recursive.sh @@ -2,11 +2,7 @@ test_description='merge-recursive: handle file mode' . ./test-lib.sh - -if ! test "$(git config --bool core.filemode)" = false -then - test_set_prereq FILEMODE -fi +. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh test_expect_success 'mode change in one branch: keep changed version' ' : >file1 && @@ -57,4 +53,35 @@ test_expect_success FILEMODE 'verify executable bit on file' ' test -x file2 ' +test_expect_success 'merging with triple rename across D/F conflict' ' + git reset --hard HEAD && + git checkout -b main && + git rm -rf . && + + echo "just a file" >sub1 && + mkdir -p sub2 && + echo content1 >sub2/file1 && + echo content2 >sub2/file2 && + echo content3 >sub2/file3 && + mkdir simple && + echo base >simple/bar && + git add -A && + test_tick && + git commit -m base && + + git checkout -b other && + echo more >>simple/bar && + test_tick && + git commit -a -m changesimplefile && + + git checkout main && + git rm sub1 && + git mv sub2 sub1 && + test_tick && + git commit -m changefiletodir && + + test_tick && + git merge other +' + test_done diff --git a/t/t6035-merge-dir-to-symlink.sh b/t/t6035-merge-dir-to-symlink.sh index 3202e1de6..92e02d5d7 100755 --- a/t/t6035-merge-dir-to-symlink.sh +++ b/t/t6035-merge-dir-to-symlink.sh @@ -3,13 +3,7 @@ test_description='merging when a directory was replaced with a symlink' . ./test-lib.sh -if ! test_have_prereq SYMLINKS -then - say 'Symbolic links not supported, skipping tests.' - test_done -fi - -test_expect_success 'create a commit where dir a/b changed to symlink' ' +test_expect_success SYMLINKS 'create a commit where dir a/b changed to symlink' ' mkdir -p a/b/c a/b-2/c && > a/b/c/d && > a/b-2/c/d && @@ -23,7 +17,7 @@ test_expect_success 'create a commit where dir a/b changed to symlink' ' git commit -m "dir to symlink" ' -test_expect_success 'keep a/b-2/c/d across checkout' ' +test_expect_success SYMLINKS 'keep a/b-2/c/d across checkout' ' git checkout HEAD^0 && git reset --hard master && git rm --cached a/b && @@ -32,14 +26,14 @@ test_expect_success 'keep a/b-2/c/d across checkout' ' test -f a/b-2/c/d ' -test_expect_success 'checkout should not have deleted a/b-2/c/d' ' +test_expect_success SYMLINKS 'checkout should not have deleted a/b-2/c/d' ' git checkout HEAD^0 && git reset --hard master && git checkout start^0 && test -f a/b-2/c/d ' -test_expect_success 'setup for merge test' ' +test_expect_success SYMLINKS 'setup for merge test' ' git reset --hard && test -f a/b-2/c/d && echo x > a/x && @@ -48,7 +42,7 @@ test_expect_success 'setup for merge test' ' git tag baseline ' -test_expect_success 'do not lose a/b-2/c/d in merge (resolve)' ' +test_expect_success SYMLINKS 'Handle D/F conflict, do not lose a/b-2/c/d in merge (resolve)' ' git reset --hard && git checkout baseline^0 && git merge -s resolve master && @@ -56,7 +50,7 @@ test_expect_success 'do not lose a/b-2/c/d in merge (resolve)' ' test -f a/b-2/c/d ' -test_expect_failure 'do not lose a/b-2/c/d in merge (recursive)' ' +test_expect_success SYMLINKS 'Handle D/F conflict, do not lose a/b-2/c/d in merge (recursive)' ' git reset --hard && git checkout baseline^0 && git merge -s recursive master && @@ -64,7 +58,55 @@ test_expect_failure 'do not lose a/b-2/c/d in merge (recursive)' ' test -f a/b-2/c/d ' -test_expect_success 'setup a merge where dir a/b-2 changed to symlink' ' +test_expect_success SYMLINKS 'Handle F/D conflict, do not lose a/b-2/c/d in merge (resolve)' ' + git reset --hard && + git checkout master^0 && + git merge -s resolve baseline^0 && + test -h a/b && + test -f a/b-2/c/d +' + +test_expect_success SYMLINKS 'Handle F/D conflict, do not lose a/b-2/c/d in merge (recursive)' ' + git reset --hard && + git checkout master^0 && + git merge -s recursive baseline^0 && + test -h a/b && + test -f a/b-2/c/d +' + +test_expect_failure SYMLINKS 'do not lose untracked in merge (resolve)' ' + git reset --hard && + git checkout baseline^0 && + >a/b/c/e && + test_must_fail git merge -s resolve master && + test -f a/b/c/e && + test -f a/b-2/c/d +' + +test_expect_success SYMLINKS 'do not lose untracked in merge (recursive)' ' + git reset --hard && + git checkout baseline^0 && + >a/b/c/e && + test_must_fail git merge -s recursive master && + test -f a/b/c/e && + test -f a/b-2/c/d +' + +test_expect_success SYMLINKS 'do not lose modifications in merge (resolve)' ' + git reset --hard && + git checkout baseline^0 && + echo more content >>a/b/c/d && + test_must_fail git merge -s resolve master +' + +test_expect_success SYMLINKS 'do not lose modifications in merge (recursive)' ' + git reset --hard && + git checkout baseline^0 && + echo more content >>a/b/c/d && + test_must_fail git merge -s recursive master +' + +test_expect_success SYMLINKS 'setup a merge where dir a/b-2 changed to symlink' ' git reset --hard && git checkout start^0 && rm -rf a/b-2 && @@ -74,7 +116,7 @@ test_expect_success 'setup a merge where dir a/b-2 changed to symlink' ' git tag test2 ' -test_expect_success 'merge should not have conflicts (resolve)' ' +test_expect_success SYMLINKS 'merge should not have D/F conflicts (resolve)' ' git reset --hard && git checkout baseline^0 && git merge -s resolve test2 && @@ -82,7 +124,7 @@ test_expect_success 'merge should not have conflicts (resolve)' ' test -f a/b/c/d ' -test_expect_failure 'merge should not have conflicts (recursive)' ' +test_expect_success SYMLINKS 'merge should not have D/F conflicts (recursive)' ' git reset --hard && git checkout baseline^0 && git merge -s recursive test2 && @@ -90,4 +132,12 @@ test_expect_failure 'merge should not have conflicts (recursive)' ' test -f a/b/c/d ' +test_expect_success SYMLINKS 'merge should not have F/D conflicts (recursive)' ' + git reset --hard && + git checkout -b foo test2 && + git merge -s recursive baseline^0 && + test -h a/b-2 && + test -f a/b/c/d +' + test_done diff --git a/t/t6037-merge-ours-theirs.sh b/t/t6037-merge-ours-theirs.sh index 8ab3d61f4..2cf42c73f 100755 --- a/t/t6037-merge-ours-theirs.sh +++ b/t/t6037-merge-ours-theirs.sh @@ -58,7 +58,7 @@ test_expect_success 'pull with -X' ' git reset --hard master && git pull -s recursive -X ours . side && git reset --hard master && git pull -s recursive -Xtheirs . side && git reset --hard master && git pull -s recursive -X theirs . side && - git reset --hard master && ! git pull -s recursive -X bork . side + git reset --hard master && test_must_fail git pull -s recursive -X bork . side ' test_done diff --git a/t/t6038-merge-text-auto.sh b/t/t6038-merge-text-auto.sh index 52d0dc4bb..460bf741b 100755 --- a/t/t6038-merge-text-auto.sh +++ b/t/t6038-merge-text-auto.sh @@ -14,6 +14,8 @@ test_description='CRLF merge conflict across text=auto change . ./test-lib.sh +test_have_prereq MINGW && SED_OPTIONS=-b + test_expect_success setup ' git config core.autocrlf false && @@ -60,7 +62,7 @@ test_expect_success setup ' test_expect_success 'set up fuzz_conflict() helper' ' fuzz_conflict() { - sed -e "s/^\([<>=]......\) .*/\1/" "$@" + sed $SED_OPTIONS -e "s/^\([<>=]......\) .*/\1/" "$@" } ' diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index 203ffdb17..95b180f46 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -104,17 +104,18 @@ test_expect_success '"git fsck" works' ' test_expect_success 'repack, clone and fetch work' ' git repack -a -d && git clone --no-hardlinks . clone_dir && - cd clone_dir && - git show HEAD~5 | grep "A U Thor" && - git show $HASH2 | grep "A U Thor" && - git cat-file commit $R && - git repack -a -d && - test_must_fail git cat-file commit $R && - git fetch ../ "refs/replace/*:refs/replace/*" && - git show HEAD~5 | grep "O Thor" && - git show $HASH2 | grep "O Thor" && - git cat-file commit $R && - cd .. + ( + cd clone_dir && + git show HEAD~5 | grep "A U Thor" && + git show $HASH2 | grep "A U Thor" && + git cat-file commit $R && + git repack -a -d && + test_must_fail git cat-file commit $R && + git fetch ../ "refs/replace/*:refs/replace/*" && + git show HEAD~5 | grep "O Thor" && + git show $HASH2 | grep "O Thor" && + git cat-file commit $R + ) ' test_expect_success '"git replace" listing and deleting' ' @@ -177,10 +178,11 @@ test_expect_success 'create parallel branch without the bug' ' test_expect_success 'push to cloned repo' ' git push cloned $HASH6^:refs/heads/parallel && - cd clone_dir && - git checkout parallel && - git log --pretty=oneline | grep $PARA2 && - cd .. + ( + cd clone_dir && + git checkout parallel && + git log --pretty=oneline | grep $PARA2 + ) ' test_expect_success 'push branch with replacement' ' @@ -191,25 +193,34 @@ test_expect_success 'push branch with replacement' ' git show $HASH6~2 | grep "O Thor" && git show $PARA3 | grep "O Thor" && git push cloned $HASH6^:refs/heads/parallel2 && - cd clone_dir && - git checkout parallel2 && - git log --pretty=oneline | grep $PARA3 && - git show $PARA3 | grep "A U Thor" && - cd .. + ( + cd clone_dir && + git checkout parallel2 && + git log --pretty=oneline | grep $PARA3 && + git show $PARA3 | grep "A U Thor" + ) ' test_expect_success 'fetch branch with replacement' ' git branch tofetch $HASH6 && - cd clone_dir && - git fetch origin refs/heads/tofetch:refs/heads/parallel3 - git log --pretty=oneline parallel3 | grep $PARA3 - git show $PARA3 | grep "A U Thor" - cd .. + ( + cd clone_dir && + git fetch origin refs/heads/tofetch:refs/heads/parallel3 && + git log --pretty=oneline parallel3 > output.txt && + ! grep $PARA3 output.txt && + git show $PARA3 > para3.txt && + grep "A U Thor" para3.txt && + git fetch origin "refs/replace/*:refs/replace/*" && + git log --pretty=oneline parallel3 > output.txt && + grep $PARA3 output.txt && + git show $PARA3 > para3.txt && + grep "O Thor" para3.txt + ) ' test_expect_success 'bisect and replacements' ' git bisect start $HASH7 $HASH1 && - test "$S" = "$(git rev-parse --verify HEAD)" && + test "$PARA3" = "$(git rev-parse --verify HEAD)" && git bisect reset && GIT_NO_REPLACE_OBJECTS=1 git bisect start $HASH7 $HASH1 && test "$HASH4" = "$(git rev-parse --verify HEAD)" && @@ -219,6 +230,12 @@ test_expect_success 'bisect and replacements' ' git bisect reset ' +test_expect_success 'index-pack and replacements' ' + git --no-replace-objects rev-list --objects HEAD | + git --no-replace-objects pack-objects test- && + git index-pack test-*.pack +' + # # test_done diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index 42f8ece09..9a1680692 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -70,14 +70,13 @@ test_expect_success setup ' i=$(($i+1)) done && - git show-branch -' + git show-branch && -cat >expected <<\EOF -Merge branch 'left' -EOF + apos="'\''" +' -test_expect_success 'merge-msg test #1' ' +test_expect_success 'message for merging local branch' ' + echo "Merge branch ${apos}left${apos}" >expected && git checkout master && git fetch . left && @@ -86,11 +85,8 @@ test_expect_success 'merge-msg test #1' ' test_cmp expected actual ' -cat >expected <<EOF -Merge branch 'left' of $(pwd) -EOF - -test_expect_success 'merge-msg test #2' ' +test_expect_success 'message for merging external branch' ' + echo "Merge branch ${apos}left${apos} of $(pwd)" >expected && git checkout master && git fetch "$(pwd)" left && @@ -99,139 +95,231 @@ test_expect_success 'merge-msg test #2' ' test_cmp expected actual ' -cat >expected <<\EOF -Merge branch 'left' +test_expect_success '[merge] summary/log configuration' ' + cat >expected <<-EOF && + Merge branch ${apos}left${apos} -* left: - Left #5 - Left #4 - Left #3 - Common #2 - Common #1 -EOF + * left: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + EOF -test_expect_success 'merge-msg test #3-1' ' - - git config --unset-all merge.log - git config --unset-all merge.summary git config merge.log true && + test_might_fail git config --unset-all merge.summary && git checkout master && test_tick && git fetch . left && - git fmt-merge-msg <.git/FETCH_HEAD >actual && - test_cmp expected actual -' - -test_expect_success 'merge-msg test #3-2' ' + git fmt-merge-msg <.git/FETCH_HEAD >actual1 && - git config --unset-all merge.log - git config --unset-all merge.summary + test_might_fail git config --unset-all merge.log && git config merge.summary true && git checkout master && test_tick && git fetch . left && - git fmt-merge-msg <.git/FETCH_HEAD >actual && + git fmt-merge-msg <.git/FETCH_HEAD >actual2 && + + test_cmp expected actual1 && + test_cmp expected actual2 +' + +test_expect_success 'setup: clear [merge] configuration' ' + test_might_fail git config --unset-all merge.log && + test_might_fail git config --unset-all merge.summary +' + +test_expect_success 'setup FETCH_HEAD' ' + git checkout master && + test_tick && + git fetch . left +' + +test_expect_success 'merge.log=3 limits shortlog length' ' + cat >expected <<-EOF && + Merge branch ${apos}left${apos} + + * left: (5 commits) + Left #5 + Left #4 + Left #3 + ... + EOF + + git -c merge.log=3 fmt-merge-msg <.git/FETCH_HEAD >actual && test_cmp expected actual ' -cat >expected <<\EOF -Merge branches 'left' and 'right' +test_expect_success 'merge.log=5 shows all 5 commits' ' + cat >expected <<-EOF && + Merge branch ${apos}left${apos} -* left: - Left #5 - Left #4 - Left #3 - Common #2 - Common #1 + * left: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + EOF -* right: - Right #5 - Right #4 - Right #3 - Common #2 - Common #1 -EOF + git -c merge.log=5 fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' -test_expect_success 'merge-msg test #4-1' ' +test_expect_success 'merge.log=0 disables shortlog' ' + echo "Merge branch ${apos}left${apos}" >expected + git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' - git config --unset-all merge.log - git config --unset-all merge.summary - git config merge.log true && +test_expect_success '--log=3 limits shortlog length' ' + cat >expected <<-EOF && + Merge branch ${apos}left${apos} - git checkout master && - test_tick && - git fetch . left right && + * left: (5 commits) + Left #5 + Left #4 + Left #3 + ... + EOF - git fmt-merge-msg <.git/FETCH_HEAD >actual && + git fmt-merge-msg --log=3 <.git/FETCH_HEAD >actual && test_cmp expected actual ' -test_expect_success 'merge-msg test #4-2' ' +test_expect_success '--log=5 shows all 5 commits' ' + cat >expected <<-EOF && + Merge branch ${apos}left${apos} - git config --unset-all merge.log - git config --unset-all merge.summary - git config merge.summary true && + * left: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + EOF - git checkout master && - test_tick && - git fetch . left right && + git fmt-merge-msg --log=5 <.git/FETCH_HEAD >actual && + test_cmp expected actual +' - git fmt-merge-msg <.git/FETCH_HEAD >actual && +test_expect_success '--no-log disables shortlog' ' + echo "Merge branch ${apos}left${apos}" >expected && + git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual ' -test_expect_success 'merge-msg test #5-1' ' +test_expect_success '--log=0 disables shortlog' ' + echo "Merge branch ${apos}left${apos}" >expected && + git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && + test_cmp expected actual +' - git config --unset-all merge.log - git config --unset-all merge.summary - git config merge.log yes && +test_expect_success 'fmt-merge-msg -m' ' + echo "Sync with left" >expected && + cat >expected.log <<-EOF && + Sync with left + + * ${apos}left${apos} of $(pwd): + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + EOF + + test_might_fail git config --unset merge.log && + test_might_fail git config --unset merge.summary && + git checkout master && + git fetch "$(pwd)" left && + git fmt-merge-msg -m "Sync with left" <.git/FETCH_HEAD >actual && + git fmt-merge-msg --log -m "Sync with left" \ + <.git/FETCH_HEAD >actual.log && + git config merge.log true && + git fmt-merge-msg -m "Sync with left" \ + <.git/FETCH_HEAD >actual.log-config && + git fmt-merge-msg --no-log -m "Sync with left" \ + <.git/FETCH_HEAD >actual.nolog && + + test_cmp expected actual && + test_cmp expected.log actual.log && + test_cmp expected.log actual.log-config && + test_cmp expected actual.nolog +' + +test_expect_success 'setup: expected shortlog for two branches' ' + cat >expected <<-EOF + Merge branches ${apos}left${apos} and ${apos}right${apos} + + * left: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + + * right: + Right #5 + Right #4 + Right #3 + Common #2 + Common #1 + EOF +' +test_expect_success 'shortlog for two branches' ' + git config merge.log true && + test_might_fail git config --unset-all merge.summary && git checkout master && test_tick && git fetch . left right && + git fmt-merge-msg <.git/FETCH_HEAD >actual1 && - git fmt-merge-msg <.git/FETCH_HEAD >actual && - test_cmp expected actual -' + test_might_fail git config --unset-all merge.log && + git config merge.summary true && + git checkout master && + test_tick && + git fetch . left right && + git fmt-merge-msg <.git/FETCH_HEAD >actual2 && -test_expect_success 'merge-msg test #5-2' ' + git config merge.log yes && + test_might_fail git config --unset-all merge.summary && + git checkout master && + test_tick && + git fetch . left right && + git fmt-merge-msg <.git/FETCH_HEAD >actual3 && - git config --unset-all merge.log - git config --unset-all merge.summary + test_might_fail git config --unset-all merge.log && git config merge.summary yes && - git checkout master && test_tick && git fetch . left right && + git fmt-merge-msg <.git/FETCH_HEAD >actual4 && - git fmt-merge-msg <.git/FETCH_HEAD >actual && - test_cmp expected actual + test_cmp expected actual1 && + test_cmp expected actual2 && + test_cmp expected actual3 && + test_cmp expected actual4 ' test_expect_success 'merge-msg -F' ' - - git config --unset-all merge.log - git config --unset-all merge.summary + test_might_fail git config --unset-all merge.log && git config merge.summary yes && - git checkout master && test_tick && git fetch . left right && - git fmt-merge-msg -F .git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success 'merge-msg -F in subdirectory' ' - - git config --unset-all merge.log - git config --unset-all merge.summary + test_might_fail git config --unset-all merge.log && git config merge.summary yes && - git checkout master && test_tick && git fetch . left right && @@ -245,11 +333,11 @@ test_expect_success 'merge-msg -F in subdirectory' ' ' test_expect_success 'merge-msg with nothing to merge' ' - - git config --unset-all merge.log - git config --unset-all merge.summary + test_might_fail git config --unset-all merge.log && git config merge.summary yes && + >empty && + ( cd remote && git checkout -b unrelated && @@ -258,22 +346,20 @@ test_expect_success 'merge-msg with nothing to merge' ' git fmt-merge-msg <.git/FETCH_HEAD >../actual ) && - test_cmp /dev/null actual + test_cmp empty actual ' -cat >expected <<\EOF -Merge tag 'tag-r3' - -* tag 'tag-r3': - Right #3 - Common #2 - Common #1 -EOF - test_expect_success 'merge-msg tag' ' + cat >expected <<-EOF && + Merge tag ${apos}tag-r3${apos} + + * tag ${apos}tag-r3${apos}: + Right #3 + Common #2 + Common #1 + EOF - git config --unset-all merge.log - git config --unset-all merge.summary + test_might_fail git config --unset-all merge.log && git config merge.summary yes && git checkout master && @@ -284,26 +370,24 @@ test_expect_success 'merge-msg tag' ' test_cmp expected actual ' -cat >expected <<\EOF -Merge tags 'tag-r3' and 'tag-l5' - -* tag 'tag-r3': - Right #3 - Common #2 - Common #1 - -* tag 'tag-l5': - Left #5 - Left #4 - Left #3 - Common #2 - Common #1 -EOF - test_expect_success 'merge-msg two tags' ' - - git config --unset-all merge.log - git config --unset-all merge.summary + cat >expected <<-EOF && + Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} + + * tag ${apos}tag-r3${apos}: + Right #3 + Common #2 + Common #1 + + * tag ${apos}tag-l5${apos}: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + EOF + + test_might_fail git config --unset-all merge.log && git config merge.summary yes && git checkout master && @@ -314,26 +398,24 @@ test_expect_success 'merge-msg two tags' ' test_cmp expected actual ' -cat >expected <<\EOF -Merge branch 'left', tag 'tag-r3' - -* tag 'tag-r3': - Right #3 - Common #2 - Common #1 - -* left: - Left #5 - Left #4 - Left #3 - Common #2 - Common #1 -EOF - test_expect_success 'merge-msg tag and branch' ' - - git config --unset-all merge.log - git config --unset-all merge.summary + cat >expected <<-EOF && + Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} + + * tag ${apos}tag-r3${apos}: + Right #3 + Common #2 + Common #1 + + * left: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + EOF + + test_might_fail git config --unset-all merge.log && git config merge.summary yes && git checkout master && @@ -344,26 +426,27 @@ test_expect_success 'merge-msg tag and branch' ' test_cmp expected actual ' -cat >expected <<\EOF -Merge branch 'long' - -* long: (35 commits) -EOF - test_expect_success 'merge-msg lots of commits' ' + { + cat <<-EOF && + Merge branch ${apos}long${apos} + + * long: (35 commits) + EOF + + i=29 && + while test $i -gt 9 + do + echo " $i" && + i=$(($i-1)) + done && + echo " ..." + } >expected && git checkout master && test_tick && git fetch . long && - i=29 && - while test $i -gt 9 - do - echo " $i" && - i=$(($i-1)) - done >>expected && - echo " ..." >>expected - git fmt-merge-msg <.git/FETCH_HEAD >actual && test_cmp expected actual ' diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 0da13a8d6..e0227730d 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -3,31 +3,34 @@ test_description='git filter-branch' . ./test-lib.sh -make_commit () { - lower=$(echo $1 | tr '[A-Z]' '[a-z]') - echo $lower > $lower - git add $lower - test_tick - git commit -m $1 - git tag $1 -} - test_expect_success 'setup' ' - make_commit A - make_commit B - git checkout -b branch B - make_commit D - mkdir dir - make_commit dir/D - make_commit E - git checkout master - make_commit C - git checkout branch - git merge C - git tag F - make_commit G - make_commit H -' + test_commit A && + test_commit B && + git checkout -b branch B && + test_commit D && + mkdir dir && + test_commit dir/D && + test_commit E && + git checkout master && + test_commit C && + git checkout branch && + git merge C && + git tag F && + test_commit G && + test_commit H +' +# * (HEAD, branch) H +# * G +# * Merge commit 'C' into branch +# |\ +# | * (master) C +# * | E +# * | dir/D +# * | D +# |/ +# * B +# * A + H=$(git rev-parse H) @@ -65,14 +68,14 @@ test_expect_success 'Fail if commit filter fails' ' ' test_expect_success 'rewrite, renaming a specific file' ' - git filter-branch -f --tree-filter "mv d doh || :" HEAD + git filter-branch -f --tree-filter "mv D.t doh || :" HEAD ' test_expect_success 'test that the file was renamed' ' - test d = "$(git show HEAD:doh --)" && - ! test -f d && + test D = "$(git show HEAD:doh --)" && + ! test -f D.t && test -f doh && - test d = "$(cat doh)" + test D = "$(cat doh)" ' test_expect_success 'rewrite, renaming a specific directory' ' @@ -80,18 +83,18 @@ test_expect_success 'rewrite, renaming a specific directory' ' ' test_expect_success 'test that the directory was renamed' ' - test dir/d = "$(git show HEAD:diroh/d --)" && + test dir/D = "$(git show HEAD:diroh/D.t --)" && ! test -d dir && test -d diroh && ! test -d diroh/dir && - test -f diroh/d && - test dir/d = "$(cat diroh/d)" + test -f diroh/D.t && + test dir/D = "$(cat diroh/D.t)" ' git tag oldD HEAD~4 test_expect_success 'rewrite one branch, keeping a side branch' ' git branch modD oldD && - git filter-branch -f --tree-filter "mv b boh || :" D..modD + git filter-branch -f --tree-filter "mv B.t boh || :" D..modD ' test_expect_success 'common ancestor is still common (unchanged)' ' @@ -104,13 +107,13 @@ test_expect_success 'filter subdirectory only' ' git add subdir/new && test_tick && git commit -m "subdir" && - echo H > a && + echo H > A.t && test_tick && - git commit -m "not subdir" a && + git commit -m "not subdir" A.t && echo A > subdir/new && test_tick && git commit -m "again subdir" subdir/new && - git rm a && + git rm A.t && test_tick && git commit -m "again not subdir" && git branch sub && @@ -134,7 +137,7 @@ test_expect_success 'more setup' ' git add subdir/new && test_tick && git commit -m "subdir on master" subdir/new && - git rm a && + git rm A.t && test_tick && git commit -m "again subdir on master" && git merge branch @@ -143,11 +146,12 @@ test_expect_success 'more setup' ' test_expect_success 'use index-filter to move into a subdirectory' ' git branch directorymoved && git filter-branch -f --index-filter \ - "git ls-files -s | sed \"s-\\t-&newsubdir/-\" | + "git ls-files -s | sed \"s- -&newsubdir/-\" | GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \ git update-index --index-info && mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved && - test -z "$(git diff HEAD directorymoved:newsubdir)"' + git diff --exit-code HEAD directorymoved:newsubdir +' test_expect_success 'stops when msg filter fails' ' old=$(git rev-parse HEAD) && @@ -282,8 +286,8 @@ test_expect_success 'Tag name filtering allows slashes in tag names' ' test_expect_success 'Prune empty commits' ' git rev-list HEAD > expect && - make_commit to_remove && - git filter-branch -f --index-filter "git update-index --remove to_remove" --prune-empty HEAD && + test_commit to_remove && + git filter-branch -f --index-filter "git update-index --remove to_remove.t" --prune-empty HEAD && git rev-list HEAD > actual && test_cmp expect actual ' @@ -306,6 +310,24 @@ test_expect_success '--remap-to-ancestor with filename filters' ' test $orig_invariant = $(git rev-parse invariant) ' +test_expect_success 'automatic remapping to ancestor with filename filters' ' + git checkout master && + git reset --hard A && + test_commit add-foo2 foo 1 && + git branch moved-foo2 && + test_commit add-bar2 bar a && + git branch invariant2 && + orig_invariant=$(git rev-parse invariant2) && + git branch moved-bar2 && + test_commit change-foo2 foo 2 && + git filter-branch -f \ + moved-foo2 moved-bar2 A..master \ + -- -- foo && + test $(git rev-parse moved-foo2) = $(git rev-parse moved-bar2) && + test $(git rev-parse moved-foo2) = $(git rev-parse master^) && + test $orig_invariant = $(git rev-parse invariant2) +' + test_expect_success 'setup submodule' ' rm -fr ?* .git && git init && diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 73dbc4360..ac943f5ee 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -583,7 +583,7 @@ test_expect_success \ # subsequent tests require gpg; check if it is available gpg --version >/dev/null 2>/dev/null if [ $? -eq 127 ]; then - say "gpg not found - skipping tag signing and verification tests" + say "# gpg not found - skipping tag signing and verification tests" else # As said here: http://www.gnupg.org/documentation/faqs.html#q6.19 # the gpg version 1.0.6 didn't parse trust packets correctly, so for diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh index fe60d699a..1b530b502 100755 --- a/t/t7005-editor.sh +++ b/t/t7005-editor.sh @@ -111,13 +111,13 @@ do ' done -if ! echo 'echo space > "$1"' > "e space.sh" +if echo 'echo space > "$1"' > "e space.sh" then - say "Skipping; FS does not support spaces in filenames" - test_done + # FS supports spaces in filenames + test_set_prereq SPACES_IN_FILENAMES fi -test_expect_success 'editor with a space' ' +test_expect_success SPACES_IN_FILENAMES 'editor with a space' ' chmod a+x "e space.sh" && GIT_EDITOR="./e\ space.sh" git commit --amend && @@ -126,7 +126,7 @@ test_expect_success 'editor with a space' ' ' unset GIT_EDITOR -test_expect_success 'core.editor with a space' ' +test_expect_success SPACES_IN_FILENAMES 'core.editor with a space' ' git config core.editor \"./e\ space.sh\" && git commit --amend && diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index 9a83241c9..fb744e3c4 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -3,6 +3,7 @@ test_description='Test automatic use of a pager.' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-pager.sh cleanup_fail() { echo >&2 cleanup failed @@ -36,7 +37,7 @@ then } test_set_prereq TTY else - say no usable terminal, so skipping some tests + say "# no usable terminal, so skipping some tests" fi test_expect_success 'setup' ' @@ -57,6 +58,21 @@ test_expect_success TTY 'some commands use a pager' ' test -e paginated.out ' +test_expect_failure TTY 'pager runs from subdir' ' + echo subdir/paginated.out >expected && + mkdir -p subdir && + rm -f paginated.out subdir/paginated.out && + ( + cd subdir && + test_terminal git log + ) && + { + ls paginated.out subdir/paginated.out || + : + } >actual && + test_cmp expected actual +' + test_expect_success TTY 'some commands do not use a pager' ' rm -f paginated.out || cleanup_fail && @@ -105,6 +121,45 @@ test_expect_success TTY 'no pager with --no-pager' ' ! test -e paginated.out ' +test_expect_success TTY 'configuration can disable pager' ' + rm -f paginated.out && + test_might_fail git config --unset pager.grep && + test_terminal git grep initial && + test -e paginated.out && + + rm -f paginated.out && + git config pager.grep false && + test_when_finished "git config --unset pager.grep" && + test_terminal git grep initial && + ! test -e paginated.out +' + +test_expect_success TTY 'git config uses a pager if configured to' ' + rm -f paginated.out && + git config pager.config true && + test_when_finished "git config --unset pager.config" && + test_terminal git config --list && + test -e paginated.out +' + +test_expect_success TTY 'configuration can enable pager (from subdir)' ' + rm -f paginated.out && + mkdir -p subdir && + git config pager.bundle true && + test_when_finished "git config --unset pager.bundle" && + + git bundle create test.bundle --all && + rm -f paginated.out subdir/paginated.out && + ( + cd subdir && + test_terminal git bundle unbundle ../test.bundle + ) && + { + test -e paginated.out || + test -e subdir/paginated.out + } +' + # A colored commit log will begin with an appropriate ANSI escape # for the first color; the text "commit" comes later. colorful() { @@ -158,72 +213,226 @@ test_expect_success 'color when writing to a file intended for a pager' ' colorful colorful.log ' -test_expect_success 'determine default pager' ' - unset PAGER GIT_PAGER; - test_might_fail git config --unset core.pager || - cleanup_fail && - - less=$(git var GIT_PAGER) && - test -n "$less" -' - -if expr "$less" : '[a-z][a-z]*$' >/dev/null && test_have_prereq TTY +if test_have_prereq SIMPLEPAGER && test_have_prereq TTY then - test_set_prereq SIMPLEPAGER + test_set_prereq SIMPLEPAGERTTY fi -test_expect_success SIMPLEPAGER 'default pager is used by default' ' - unset PAGER GIT_PAGER; - test_might_fail git config --unset core.pager && - rm -f default_pager_used || - cleanup_fail && +# Use this helper to make it easy for the caller of your +# terminal-using function to specify whether it should fail. +# If you write +# +# your_test() { +# parse_args "$@" +# +# $test_expectation "$cmd - behaves well" " +# ... +# $full_command && +# ... +# " +# } +# +# then your test can be used like this: +# +# your_test expect_(success|failure) [test_must_fail] 'git foo' +# +parse_args() { + test_expectation="test_$1" + shift + if test "$1" = test_must_fail + then + full_command="test_must_fail test_terminal " + shift + else + full_command="test_terminal " + fi + cmd=$1 + full_command="$full_command $1" +} - cat >$less <<-\EOF && - #!/bin/sh - wc >default_pager_used - EOF - chmod +x $less && - ( - PATH=.:$PATH && - export PATH && - test_terminal git log - ) && - test -e default_pager_used -' +test_default_pager() { + parse_args "$@" + + $test_expectation SIMPLEPAGERTTY "$cmd - default pager is used by default" " + unset PAGER GIT_PAGER; + test_might_fail git config --unset core.pager && + rm -f default_pager_used || + cleanup_fail && + + cat >\$less <<-\EOF && + #!/bin/sh + wc >default_pager_used + EOF + chmod +x \$less && + ( + PATH=.:\$PATH && + export PATH && + $full_command + ) && + test -e default_pager_used + " +} -test_expect_success TTY 'PAGER overrides default pager' ' - unset GIT_PAGER; - test_might_fail git config --unset core.pager && - rm -f PAGER_used || - cleanup_fail && +test_PAGER_overrides() { + parse_args "$@" - PAGER="wc >PAGER_used" && - export PAGER && - test_terminal git log && - test -e PAGER_used -' + $test_expectation TTY "$cmd - PAGER overrides default pager" " + unset GIT_PAGER; + test_might_fail git config --unset core.pager && + rm -f PAGER_used || + cleanup_fail && -test_expect_success TTY 'core.pager overrides PAGER' ' - unset GIT_PAGER; - rm -f core.pager_used || - cleanup_fail && + PAGER='wc >PAGER_used' && + export PAGER && + $full_command && + test -e PAGER_used + " +} - PAGER=wc && - export PAGER && - git config core.pager "wc >core.pager_used" && - test_terminal git log && - test -e core.pager_used -' +test_core_pager_overrides() { + if_local_config= + used_if_wanted='overrides PAGER' + test_core_pager "$@" +} -test_expect_success TTY 'GIT_PAGER overrides core.pager' ' - rm -f GIT_PAGER_used || - cleanup_fail && +test_local_config_ignored() { + if_local_config='! ' + used_if_wanted='is not used' + test_core_pager "$@" +} - git config core.pager wc && - GIT_PAGER="wc >GIT_PAGER_used" && - export GIT_PAGER && - test_terminal git log && - test -e GIT_PAGER_used +test_core_pager() { + parse_args "$@" + + $test_expectation TTY "$cmd - repository-local core.pager setting $used_if_wanted" " + unset GIT_PAGER; + rm -f core.pager_used || + cleanup_fail && + + PAGER=wc && + export PAGER && + git config core.pager 'wc >core.pager_used' && + $full_command && + ${if_local_config}test -e core.pager_used + " +} + +test_core_pager_subdir() { + if_local_config= + used_if_wanted='overrides PAGER' + test_pager_subdir_helper "$@" +} + +test_no_local_config_subdir() { + if_local_config='! ' + used_if_wanted='is not used' + test_pager_subdir_helper "$@" +} + +test_pager_subdir_helper() { + parse_args "$@" + + $test_expectation TTY "$cmd - core.pager $used_if_wanted from subdirectory" " + unset GIT_PAGER; + rm -f core.pager_used && + rm -fr sub || + cleanup_fail && + + PAGER=wc && + stampname=\$(pwd)/core.pager_used && + export PAGER stampname && + git config core.pager 'wc >\"\$stampname\"' && + mkdir sub && + ( + cd sub && + $full_command + ) && + ${if_local_config}test -e core.pager_used + " +} + +test_GIT_PAGER_overrides() { + parse_args "$@" + + $test_expectation TTY "$cmd - GIT_PAGER overrides core.pager" " + rm -f GIT_PAGER_used || + cleanup_fail && + + git config core.pager wc && + GIT_PAGER='wc >GIT_PAGER_used' && + export GIT_PAGER && + $full_command && + test -e GIT_PAGER_used + " +} + +test_doesnt_paginate() { + parse_args "$@" + + $test_expectation TTY "no pager for '$cmd'" " + rm -f GIT_PAGER_used || + cleanup_fail && + + GIT_PAGER='wc >GIT_PAGER_used' && + export GIT_PAGER && + $full_command && + ! test -e GIT_PAGER_used + " +} + +test_pager_choices() { + test_default_pager expect_success "$@" + test_PAGER_overrides expect_success "$@" + test_core_pager_overrides expect_success "$@" + test_core_pager_subdir expect_success "$@" + test_GIT_PAGER_overrides expect_success "$@" +} + +test_expect_success 'setup: some aliases' ' + git config alias.aliasedlog log && + git config alias.true "!true" +' + +test_pager_choices 'git log' +test_pager_choices 'git -p log' +test_pager_choices 'git aliasedlog' + +test_default_pager expect_success 'git -p aliasedlog' +test_PAGER_overrides expect_success 'git -p aliasedlog' +test_core_pager_overrides expect_success 'git -p aliasedlog' +test_core_pager_subdir expect_failure 'git -p aliasedlog' +test_GIT_PAGER_overrides expect_success 'git -p aliasedlog' + +test_default_pager expect_success 'git -p true' +test_PAGER_overrides expect_success 'git -p true' +test_core_pager_overrides expect_success 'git -p true' +test_core_pager_subdir expect_failure 'git -p true' +test_GIT_PAGER_overrides expect_success 'git -p true' + +test_default_pager expect_success test_must_fail 'git -p request-pull' +test_PAGER_overrides expect_success test_must_fail 'git -p request-pull' +test_core_pager_overrides expect_success test_must_fail 'git -p request-pull' +test_core_pager_subdir expect_failure test_must_fail 'git -p request-pull' +test_GIT_PAGER_overrides expect_success test_must_fail 'git -p request-pull' + +test_default_pager expect_success test_must_fail 'git -p' +test_PAGER_overrides expect_success test_must_fail 'git -p' +test_local_config_ignored expect_failure test_must_fail 'git -p' +test_no_local_config_subdir expect_success test_must_fail 'git -p' +test_GIT_PAGER_overrides expect_success test_must_fail 'git -p' + +test_doesnt_paginate expect_failure test_must_fail 'git -p nonsense' + +test_pager_choices 'git shortlog' +test_expect_success 'setup: configure shortlog not to paginate' ' + git config pager.shortlog false ' +test_doesnt_paginate expect_success 'git shortlog' +test_no_local_config_subdir expect_success 'git shortlog' +test_default_pager expect_success 'git -p shortlog' +test_core_pager_subdir expect_success 'git -p shortlog' + +test_core_pager_subdir expect_success test_must_fail \ + 'git -p apply </dev/null' test_done diff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh index eb8ca88cc..e058d184d 100755 --- a/t/t7008-grep-binary.sh +++ b/t/t7008-grep-binary.sh @@ -5,7 +5,7 @@ test_description='git grep in binary files' . ./test-lib.sh test_expect_success 'setup' " - printf 'binary\000file\n' >a && + echo 'binaryQfile' | q_to_nul >a && git add a && git commit -m. " @@ -61,7 +61,7 @@ test_expect_success 'git grep -Fi iLE a' ' # This test actually passes on platforms where regexec() supports the # flag REG_STARTEND. -test_expect_failure 'git grep ile a' ' +test_expect_success 'git grep ile a' ' git grep ile a ' @@ -70,32 +70,32 @@ test_expect_failure 'git grep .fi a' ' ' test_expect_success 'git grep -F y<NUL>f a' " - printf 'y\000f' >f && + printf 'yQf' | q_to_nul >f && git grep -f f -F a " test_expect_success 'git grep -F y<NUL>x a' " - printf 'y\000x' >f && + printf 'yQx' | q_to_nul >f && test_must_fail git grep -f f -F a " test_expect_success 'git grep -Fi Y<NUL>f a' " - printf 'Y\000f' >f && + printf 'YQf' | q_to_nul >f && git grep -f f -Fi a " test_expect_failure 'git grep -Fi Y<NUL>x a' " - printf 'Y\000x' >f && + printf 'YQx' | q_to_nul >f && test_must_fail git grep -f f -Fi a " test_expect_success 'git grep y<NUL>f a' " - printf 'y\000f' >f && + printf 'yQf' | q_to_nul >f && git grep -f f a " test_expect_failure 'git grep y<NUL>x a' " - printf 'y\000x' >f && + printf 'yQx' | q_to_nul >f && test_must_fail git grep -f f a " diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh index c1f4fc3c6..9891e2c1f 100755 --- a/t/t7105-reset-patch.sh +++ b/t/t7105-reset-patch.sh @@ -3,7 +3,7 @@ test_description='git reset --patch' . ./lib-patch-mode.sh -test_expect_success 'setup' ' +test_expect_success PERL 'setup' ' mkdir dir && echo parent > dir/foo && echo dummy > bar && @@ -17,20 +17,20 @@ test_expect_success 'setup' ' # note: bar sorts before foo, so the first 'n' is always to skip 'bar' -test_expect_success 'saying "n" does nothing' ' +test_expect_success PERL 'saying "n" does nothing' ' set_and_save_state dir/foo work work (echo n; echo n) | git reset -p && verify_saved_state dir/foo && verify_saved_state bar ' -test_expect_success 'git reset -p' ' +test_expect_success PERL 'git reset -p' ' (echo n; echo y) | git reset -p && verify_state dir/foo work head && verify_saved_state bar ' -test_expect_success 'git reset -p HEAD^' ' +test_expect_success PERL 'git reset -p HEAD^' ' (echo n; echo y) | git reset -p HEAD^ && verify_state dir/foo work parent && verify_saved_state bar @@ -41,27 +41,27 @@ test_expect_success 'git reset -p HEAD^' ' # dir/foo. There's always an extra 'n' to reject edits to dir/foo in # the failure case (and thus get out of the loop). -test_expect_success 'git reset -p dir' ' +test_expect_success PERL 'git reset -p dir' ' set_state dir/foo work work (echo y; echo n) | git reset -p dir && verify_state dir/foo work head && verify_saved_state bar ' -test_expect_success 'git reset -p -- foo (inside dir)' ' +test_expect_success PERL 'git reset -p -- foo (inside dir)' ' set_state dir/foo work work (echo y; echo n) | (cd dir && git reset -p -- foo) && verify_state dir/foo work head && verify_saved_state bar ' -test_expect_success 'git reset -p HEAD^ -- dir' ' +test_expect_success PERL 'git reset -p HEAD^ -- dir' ' (echo y; echo n) | git reset -p HEAD^ -- dir && verify_state dir/foo work parent && verify_saved_state bar ' -test_expect_success 'none of this moved HEAD' ' +test_expect_success PERL 'none of this moved HEAD' ' verify_saved_head ' diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 7d8ed68be..6c776e9be 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -388,16 +388,15 @@ test_expect_success 'core.excludesfile' ' ' -test_expect_success 'removal failure' ' +test_expect_success SANITY 'removal failure' ' mkdir foo && touch foo/bar && (exec <foo/bar && chmod 0 foo && - test_must_fail git clean -f -d) - + test_must_fail git clean -f -d && + chmod 755 foo) ' -chmod 755 foo test_expect_success 'nested git work tree' ' rm -fr foo bar && @@ -438,4 +437,20 @@ test_expect_success 'force removal of nested git work tree' ' ! test -d bar ' +test_expect_success 'git clean -e' ' + rm -fr repo && + mkdir repo && + ( + cd repo && + git init && + touch known 1 2 3 && + git add known && + git clean -f -e 1 -e 2 && + test -e 1 && + test -e 2 && + ! (test -e 3) && + test -e known + ) +' + test_done diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 97ff074da..782b0a3ec 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -42,7 +42,8 @@ test_expect_success 'setup - hide init subdirectory' ' ' test_expect_success 'setup - repository to add submodules to' ' - git init addtest + git init addtest && + git init addtest-ignore ' # The 'submodule add' tests need some repository to add as a submodule. @@ -85,6 +86,30 @@ test_expect_success 'submodule add' ' test_cmp empty untracked ' +test_expect_success 'submodule add to .gitignored path fails' ' + ( + cd addtest-ignore && + cat <<-\EOF >expect && + The following path is ignored by one of your .gitignore files: + submod + Use -f if you really want to add it. + EOF + # Does not use test_commit due to the ignore + echo "*" > .gitignore && + git add --force .gitignore && + git commit -m"Ignore everything" && + ! git submodule add "$submodurl" submod >actual 2>&1 && + test_cmp expect actual + ) +' + +test_expect_success 'submodule add to .gitignored path with --force' ' + ( + cd addtest-ignore && + git submodule add --force "$submodurl" submod + ) +' + test_expect_success 'submodule add --branch' ' echo "refs/heads/initial" >expect-head && cat <<-\EOF >expect-heads && @@ -388,12 +413,13 @@ test_expect_success 'submodule <invalid-path> warns' ' test_expect_success 'add submodules without specifying an explicit path' ' mkdir repo && - cd repo && - git init && - echo r >r && - git add r && - git commit -m "repo commit 1" && - cd .. && + ( + cd repo && + git init && + echo r >r && + git add r && + git commit -m "repo commit 1" + ) && git clone --bare repo/ bare.git && cd addtest && git submodule add "$submodurl/repo" && diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index cee319da0..294584452 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -66,10 +66,11 @@ EOF " commit_file sm1 && -cd sm1 && -git reset --hard HEAD~2 >/dev/null && -head3=$(git rev-parse --verify HEAD | cut -c1-7) && -cd .. +head3=$( + cd sm1 && + git reset --hard HEAD~2 >/dev/null && + git rev-parse --verify HEAD | cut -c1-7 +) test_expect_success 'modified submodule(backward)' " git submodule summary >actual && diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh index 753875648..02522f962 100755 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@ -14,7 +14,7 @@ test_expect_success setup ' echo file > file && git add file && test_tick && - git commit -m upstream + git commit -m upstream && git clone . super && git clone super submodule && (cd super && @@ -42,7 +42,7 @@ test_expect_success 'change submodule url' ' ) && mv submodule moved-submodule && (cd super && - git config -f .gitmodules submodule.submodule.url ../moved-submodule + git config -f .gitmodules submodule.submodule.url ../moved-submodule && test_tick && git commit -a -m moved-submodule ) @@ -58,6 +58,9 @@ test_expect_success '"git submodule sync" should update submodule URLs' ' (cd super-clone/submodule && git checkout master && git pull + ) && + (cd super-clone && + test -d "$(git config submodule.submodule.url)" ) ' diff --git a/t/t7405-submodule-merge.sh b/t/t7405-submodule-merge.sh index 9a21f783d..7e2e25895 100755 --- a/t/t7405-submodule-merge.sh +++ b/t/t7405-submodule-merge.sh @@ -45,7 +45,7 @@ test_expect_success setup ' git commit -m sub-b) && git add sub && test_tick && - git commit -m b + git commit -m b && git checkout -b c a && git merge -s ours b && @@ -54,21 +54,132 @@ test_expect_success setup ' git merge -s ours a ' -test_expect_success 'merging with modify/modify conflict' ' +# History setup +# +# b +# / \ +# a d +# \ / +# c +# +# a in the main repository records to sub-a in the submodule and +# analogous b and c. d should be automatically found by merging c into +# b in the main repository. +test_expect_success 'setup for merge search' ' + mkdir merge-search && + (cd merge-search && + git init && + mkdir sub && + (cd sub && + git init && + echo "file-a" > file-a && + git add file-a && + git commit -m "sub-a" && + git branch sub-a) && + git add sub && + git commit -m "a" && + git branch a && + + git checkout -b b && + (cd sub && + git checkout -b sub-b && + echo "file-b" > file-b && + git add file-b && + git commit -m "sub-b") && + git commit -a -m "b" && + + git checkout -b c a && + (cd sub && + git checkout -b sub-c sub-a && + echo "file-c" > file-c && + git add file-c && + git commit -m "sub-c") && + git commit -a -m "c" && - git checkout -b test1 a && - test_must_fail git merge b && - test -f .git/MERGE_MSG && - git diff && - test -n "$(git ls-files -u)" + git checkout -b d a && + (cd sub && + git checkout -b sub-d sub-b && + git merge sub-c) && + git commit -a -m "d" && + git branch test b) ' -test_expect_success 'merging with a modify/modify conflict between merge bases' ' +test_expect_success 'merge with one side as a fast-forward of the other' ' + (cd merge-search && + git checkout -b test-forward b && + git merge d && + git ls-tree test-forward sub | cut -f1 | cut -f3 -d" " > actual && + (cd sub && + git rev-parse sub-d > ../expect) && + test_cmp actual expect) +' +test_expect_success 'merging should conflict for non fast-forward' ' + (cd merge-search && + git checkout -b test-nonforward b && + (cd sub && + git rev-parse sub-d > ../expect) && + test_must_fail git merge c 2> actual && + grep $(cat expect) actual > /dev/null && + git reset --hard) +' + +test_expect_success 'merging should fail for ambiguous common parent' ' + (cd merge-search && + git checkout -b test-ambiguous b && + (cd sub && + git checkout -b ambiguous sub-b && + git merge sub-c && + git rev-parse sub-d > ../expect1 && + git rev-parse ambiguous > ../expect2) && + test_must_fail git merge c 2> actual && + grep $(cat expect1) actual > /dev/null && + grep $(cat expect2) actual > /dev/null && + git reset --hard) +' + +# in a situation like this +# +# submodule tree: +# +# sub-a --- sub-b --- sub-d +# +# main tree: +# +# e (sub-a) +# / +# bb (sub-b) +# \ +# f (sub-d) +# +# A merge between e and f should fail because one of the submodule +# commits (sub-a) does not descend from the submodule merge-base (sub-b). +# +test_expect_success 'merging should fail for changes that are backwards' ' + (cd merge-search && + git checkout -b bb a && + (cd sub && + git checkout sub-b) && + git commit -a -m "bb" && + + git checkout -b e bb && + (cd sub && + git checkout sub-a) && + git commit -a -m "e" && + + git checkout -b f bb && + (cd sub && + git checkout sub-d) && + git commit -a -m "f" && + + git checkout -b test-backward e && + test_must_fail git merge f) +' + +test_expect_success 'merging with a modify/modify conflict between merge bases' ' git reset --hard HEAD && git checkout -b test2 c && git merge d - ' test_done diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 1382a8e58..bfb4975e9 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -25,7 +25,7 @@ test_expect_success 'setup a submodule tree' ' echo file > file && git add file && test_tick && - git commit -m upstream + git commit -m upstream && git clone . super && git clone super submodule && git clone super rebasing && diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index db9365b64..905a8baae 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -16,7 +16,7 @@ test_expect_success 'setup a submodule tree' ' echo file > file && git add file && test_tick && - git commit -m upstream + git commit -m upstream && git clone . super && git clone super submodule && ( @@ -30,7 +30,7 @@ test_expect_success 'setup a submodule tree' ' submodule.sub2 submodule.foo2 && git config -f .gitmodules --rename-section \ submodule.sub3 submodule.foo3 && - git add .gitmodules + git add .gitmodules && test_tick && git commit -m "submodules" && git submodule init sub1 && diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 9e081073f..c9300f3c8 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -793,7 +793,7 @@ test_expect_success 'commit --dry-run submodule summary (--amend)' ' test_cmp expect output ' -test_expect_success POSIXPERM 'status succeeds in a read-only repository' ' +test_expect_success POSIXPERM,SANITY 'status succeeds in a read-only repository' ' ( chmod a-w .git && # make dir1/tracked stat-dirty @@ -808,4 +808,306 @@ test_expect_success POSIXPERM 'status succeeds in a read-only repository' ' (exit $status) ' +(cd sm && echo > bar && git add bar && git commit -q -m 'Add bar') && git add sm +new_head=$(cd sm && git rev-parse --short=7 --verify HEAD) +touch .gitmodules + +cat > expect << EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# modified: sm +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) +# +# modified: dir1/modified +# +# Submodule changes to be committed: +# +# * sm $head...$new_head (1): +# > Add bar +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# .gitmodules +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +test_expect_success '--ignore-submodules=untracked suppresses submodules with untracked content' ' + echo modified > sm/untracked && + git status --ignore-submodules=untracked > output && + test_cmp expect output +' + +test_expect_success '.gitmodules ignore=untracked suppresses submodules with untracked content' ' + git config diff.ignoreSubmodules dirty && + git status >output && + test_cmp expect output && + git config --add -f .gitmodules submodule.subname.ignore untracked && + git config --add -f .gitmodules submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config -f .gitmodules --remove-section submodule.subname && + git config --unset diff.ignoreSubmodules +' + +test_expect_success '.git/config ignore=untracked suppresses submodules with untracked content' ' + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sm && + git config --add submodule.subname.ignore untracked && + git config --add submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config --remove-section submodule.subname && + git config --remove-section -f .gitmodules submodule.subname +' + +test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' ' + git status --ignore-submodules=dirty > output && + test_cmp expect output +' + +test_expect_success '.gitmodules ignore=dirty suppresses submodules with untracked content' ' + git config diff.ignoreSubmodules dirty && + git status >output && + ! test -s actual && + git config --add -f .gitmodules submodule.subname.ignore dirty && + git config --add -f .gitmodules submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config -f .gitmodules --remove-section submodule.subname && + git config --unset diff.ignoreSubmodules +' + +test_expect_success '.git/config ignore=dirty suppresses submodules with untracked content' ' + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sm && + git config --add submodule.subname.ignore dirty && + git config --add submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config --remove-section submodule.subname && + git config -f .gitmodules --remove-section submodule.subname +' + +test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' ' + echo modified > sm/foo && + git status --ignore-submodules=dirty > output && + test_cmp expect output +' + +test_expect_success '.gitmodules ignore=dirty suppresses submodules with modified content' ' + git config --add -f .gitmodules submodule.subname.ignore dirty && + git config --add -f .gitmodules submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config -f .gitmodules --remove-section submodule.subname +' + +test_expect_success '.git/config ignore=dirty suppresses submodules with modified content' ' + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sm && + git config --add submodule.subname.ignore dirty && + git config --add submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config --remove-section submodule.subname && + git config -f .gitmodules --remove-section submodule.subname +' + +cat > expect << EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# modified: sm +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) +# (commit or discard the untracked or modified content in submodules) +# +# modified: dir1/modified +# modified: sm (modified content) +# +# Submodule changes to be committed: +# +# * sm $head...$new_head (1): +# > Add bar +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# .gitmodules +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +test_expect_success "--ignore-submodules=untracked doesn't suppress submodules with modified content" ' + git status --ignore-submodules=untracked > output && + test_cmp expect output +' + +test_expect_success ".gitmodules ignore=untracked doesn't suppress submodules with modified content" ' + git config --add -f .gitmodules submodule.subname.ignore untracked && + git config --add -f .gitmodules submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config -f .gitmodules --remove-section submodule.subname +' + +test_expect_success ".git/config ignore=untracked doesn't suppress submodules with modified content" ' + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sm && + git config --add submodule.subname.ignore untracked && + git config --add submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config --remove-section submodule.subname && + git config -f .gitmodules --remove-section submodule.subname +' + +head2=$(cd sm && git commit -q -m "2nd commit" foo && git rev-parse --short=7 --verify HEAD) + +cat > expect << EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# modified: sm +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) +# +# modified: dir1/modified +# modified: sm (new commits) +# +# Submodule changes to be committed: +# +# * sm $head...$new_head (1): +# > Add bar +# +# Submodules changed but not updated: +# +# * sm $new_head...$head2 (1): +# > 2nd commit +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# .gitmodules +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +test_expect_success "--ignore-submodules=untracked doesn't suppress submodule summary" ' + git status --ignore-submodules=untracked > output && + test_cmp expect output +' + +test_expect_success ".gitmodules ignore=untracked doesn't suppress submodule summary" ' + git config --add -f .gitmodules submodule.subname.ignore untracked && + git config --add -f .gitmodules submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config -f .gitmodules --remove-section submodule.subname +' + +test_expect_success ".git/config ignore=untracked doesn't suppress submodule summary" ' + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sm && + git config --add submodule.subname.ignore untracked && + git config --add submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config --remove-section submodule.subname && + git config -f .gitmodules --remove-section submodule.subname +' + +test_expect_success "--ignore-submodules=dirty doesn't suppress submodule summary" ' + git status --ignore-submodules=dirty > output && + test_cmp expect output +' +test_expect_success ".gitmodules ignore=dirty doesn't suppress submodule summary" ' + git config --add -f .gitmodules submodule.subname.ignore dirty && + git config --add -f .gitmodules submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config -f .gitmodules --remove-section submodule.subname +' + +test_expect_success ".git/config ignore=dirty doesn't suppress submodule summary" ' + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sm && + git config --add submodule.subname.ignore dirty && + git config --add submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config --remove-section submodule.subname && + git config -f .gitmodules --remove-section submodule.subname +' + +cat > expect << EOF +# On branch master +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# .gitmodules +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +no changes added to commit (use "git add" and/or "git commit -a") +EOF + +test_expect_success "--ignore-submodules=all suppresses submodule summary" ' + git status --ignore-submodules=all > output && + test_cmp expect output +' + +test_expect_failure '.gitmodules ignore=all suppresses submodule summary' ' + git config --add -f .gitmodules submodule.subname.ignore all && + git config --add -f .gitmodules submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config -f .gitmodules --remove-section submodule.subname +' + +test_expect_failure '.git/config ignore=all suppresses submodule summary' ' + git config --add -f .gitmodules submodule.subname.ignore none && + git config --add -f .gitmodules submodule.subname.path sm && + git config --add submodule.subname.ignore all && + git config --add submodule.subname.path sm && + git status > output && + test_cmp expect output && + git config --remove-section submodule.subname && + git config -f .gitmodules --remove-section submodule.subname +' + test_done diff --git a/t/t7509-commit.sh b/t/t7509-commit.sh index 3ea33db6c..643ab03f9 100755 --- a/t/t7509-commit.sh +++ b/t/t7509-commit.sh @@ -111,7 +111,7 @@ test_expect_success '--amend option with empty author' ' test_when_finished "git checkout Initial" && echo "Empty author test" >>foo && test_tick && - ! git commit -a -m "empty author" --amend 2>err && + test_must_fail git commit -a -m "empty author" --amend 2>err && grep "empty ident" err ' @@ -125,7 +125,7 @@ test_expect_success '--amend option with missing author' ' test_when_finished "git checkout Initial" && echo "Missing author test" >>foo && test_tick && - ! git commit -a -m "malformed author" --amend 2>err && + test_must_fail git commit -a -m "malformed author" --amend 2>err && grep "empty ident" err ' diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index cde8390c1..b4f40e4c3 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -5,189 +5,103 @@ test_description='git merge -Testing basic merge operations/option parsing.' +Testing basic merge operations/option parsing. + +! [c0] commit 0 + ! [c1] commit 1 + ! [c2] commit 2 + ! [c3] commit 3 + ! [c4] c4 + ! [c5] c5 + ! [c6] c6 + * [master] Merge commit 'c1' +-------- + - [master] Merge commit 'c1' + + * [c1] commit 1 + + [c6] c6 + + [c5] c5 + ++ [c4] c4 + ++++ [c3] commit 3 + + [c2] commit 2 ++++++++* [c0] commit 0 +' . ./test-lib.sh -cat >file <<EOF -1 -2 -3 -4 -5 -6 -7 -8 -9 -EOF - -cat >file.1 <<EOF -1 X -2 -3 -4 -5 -6 -7 -8 -9 -EOF - -cat >file.5 <<EOF -1 -2 -3 -4 -5 X -6 -7 -8 -9 -EOF - -cat >file.9 <<EOF -1 -2 -3 -4 -5 -6 -7 -8 -9 X -EOF - -cat >result.1 <<EOF -1 X -2 -3 -4 -5 -6 -7 -8 -9 -EOF - -cat >result.1-5 <<EOF -1 X -2 -3 -4 -5 X -6 -7 -8 -9 -EOF - -cat >result.1-5-9 <<EOF -1 X -2 -3 -4 -5 X -6 -7 -8 -9 X -EOF - -create_merge_msgs() { - echo "Merge commit 'c2'" >msg.1-5 && - echo "Merge commit 'c2'; commit 'c3'" >msg.1-5-9 && - echo "Squashed commit of the following:" >squash.1 && - echo >>squash.1 && - git log --no-merges ^HEAD c1 >>squash.1 && - echo "Squashed commit of the following:" >squash.1-5 && - echo >>squash.1-5 && - git log --no-merges ^HEAD c2 >>squash.1-5 && - echo "Squashed commit of the following:" >squash.1-5-9 && - echo >>squash.1-5-9 && - git log --no-merges ^HEAD c2 c3 >>squash.1-5-9 && - echo > msg.nolog && - echo "* commit 'c3':" >msg.log && - echo " commit 3" >>msg.log && - echo >>msg.log -} - -verify_diff() { - if ! test_cmp "$1" "$2" - then - echo "$3" - false - fi -} - -verify_merge() { - verify_diff "$2" "$1" "[OOPS] bad merge result" && - if test $(git ls-files -u | wc -l) -gt 0 - then - echo "[OOPS] unmerged files" - false - fi && - if test_must_fail git diff --exit-code - then - echo "[OOPS] working tree != index" - false - fi && - if test -n "$3" - then - git show -s --pretty=format:%s HEAD >msg.act && - verify_diff "$3" msg.act "[OOPS] bad merge message" - fi -} - -verify_head() { - if test "$1" != "$(git rev-parse HEAD)" - then - echo "[OOPS] HEAD != $1" - false - fi -} - -verify_parents() { - i=1 - while test $# -gt 0 - do - if test "$1" != "$(git rev-parse HEAD^$i)" +test_expect_success 'set up test data and helpers' ' + printf "%s\n" 1 2 3 4 5 6 7 8 9 >file && + printf "%s\n" "1 X" 2 3 4 5 6 7 8 9 >file.1 && + printf "%s\n" 1 2 3 4 "5 X" 6 7 8 9 >file.5 && + printf "%s\n" 1 2 3 4 5 6 7 8 "9 X" >file.9 && + printf "%s\n" "1 X" 2 3 4 5 6 7 8 9 >result.1 && + printf "%s\n" "1 X" 2 3 4 "5 X" 6 7 8 9 >result.1-5 && + printf "%s\n" "1 X" 2 3 4 "5 X" 6 7 8 "9 X" >result.1-5-9 && + + create_merge_msgs() { + echo "Merge commit '\''c2'\''" >msg.1-5 && + echo "Merge commit '\''c2'\''; commit '\''c3'\''" >msg.1-5-9 && + { + echo "Squashed commit of the following:" && + echo && + git log --no-merges ^HEAD c1 + } >squash.1 && + { + echo "Squashed commit of the following:" && + echo && + git log --no-merges ^HEAD c2 + } >squash.1-5 && + { + echo "Squashed commit of the following:" && + echo && + git log --no-merges ^HEAD c2 c3 + } >squash.1-5-9 && + echo >msg.nolog && + { + echo "* commit '\''c3'\'':" && + echo " commit 3" && + echo + } >msg.log + } && + + verify_merge() { + test_cmp "$2" "$1" && + git update-index --refresh && + git diff --exit-code && + if test -n "$3" then - echo "[OOPS] HEAD^$i != $1" - return 1 + git show -s --pretty=format:%s HEAD >msg.act && + test_cmp "$3" msg.act fi - i=$(expr $i + 1) - shift - done -} - -verify_mergeheads() { - i=1 - if ! test -f .git/MERGE_HEAD - then - echo "[OOPS] MERGE_HEAD is missing" - false - fi && - while test $# -gt 0 - do - head=$(head -n $i .git/MERGE_HEAD | sed -ne \$p) - if test "$1" != "$head" - then - echo "[OOPS] MERGE_HEAD $i != $1" + } && + + verify_head() { + echo "$1" >head.expected && + git rev-parse HEAD >head.actual && + test_cmp head.expected head.actual + } && + + verify_parents() { + printf "%s\n" "$@" >parents.expected && + >parents.actual && + i=1 && + while test $i -le $# + do + git rev-parse HEAD^$i >>parents.actual && + i=$(expr $i + 1) || return 1 - fi - i=$(expr $i + 1) - shift - done -} + done && + test_cmp parents.expected parents.actual + } && -verify_no_mergehead() { - if test -f .git/MERGE_HEAD - then - echo "[OOPS] MERGE_HEAD exists" - false - fi -} + verify_mergeheads() { + printf "%s\n" "$@" >mergehead.expected && + test_cmp mergehead.expected .git/MERGE_HEAD + } && + verify_no_mergehead() { + ! test -e .git/MERGE_HEAD + } +' test_expect_success 'setup' ' git add file && @@ -219,7 +133,7 @@ test_expect_success 'setup' ' create_merge_msgs ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'test option parsing' ' test_must_fail git merge -$ c1 && @@ -235,13 +149,19 @@ test_expect_success 'reject non-strategy with a git-merge-foo name' ' ' test_expect_success 'merge c0 with c1' ' + echo "OBJID HEAD@{0}: merge c1: Fast-forward" >reflog.expected && + git reset --hard c0 && git merge c1 && verify_merge file result.1 && - verify_head "$c1" + verify_head "$c1" && + + git reflog -1 >reflog.actual && + sed "s/$_x05[0-9a-f]*/OBJID/g" reflog.actual >reflog.fuzzy && + test_cmp reflog.expected reflog.fuzzy ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c0 with c1 with --ff-only' ' git reset --hard c0 && @@ -251,7 +171,28 @@ test_expect_success 'merge c0 with c1 with --ff-only' ' verify_head "$c1" ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' + +test_expect_success 'merge from unborn branch' ' + git checkout -f master && + test_might_fail git branch -D kid && + + echo "OBJID HEAD@{0}: initial pull" >reflog.expected && + + git checkout --orphan kid && + test_when_finished "git checkout -f master" && + git rm -fr . && + test_tick && + git merge --ff-only c1 && + verify_merge file result.1 && + verify_head "$c1" && + + git reflog -1 >reflog.actual && + sed "s/$_x05[0-9a-f][0-9a-f]/OBJID/g" reflog.actual >reflog.fuzzy && + test_cmp reflog.expected reflog.fuzzy +' + +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2' ' git reset --hard c1 && @@ -261,7 +202,7 @@ test_expect_success 'merge c1 with c2' ' verify_parents $c1 $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 and c3' ' git reset --hard c1 && @@ -271,7 +212,7 @@ test_expect_success 'merge c1 with c2 and c3' ' verify_parents $c1 $c2 $c3 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'failing merges with --ff-only' ' git reset --hard c1 && @@ -288,7 +229,7 @@ test_expect_success 'merge c0 with c1 (no-commit)' ' verify_head $c1 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (no-commit)' ' git reset --hard c1 && @@ -298,7 +239,7 @@ test_expect_success 'merge c1 with c2 (no-commit)' ' verify_mergeheads $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 and c3 (no-commit)' ' git reset --hard c1 && @@ -308,7 +249,7 @@ test_expect_success 'merge c1 with c2 and c3 (no-commit)' ' verify_mergeheads $c2 $c3 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c0 with c1 (squash)' ' git reset --hard c0 && @@ -316,10 +257,10 @@ test_expect_success 'merge c0 with c1 (squash)' ' verify_merge file result.1 && verify_head $c0 && verify_no_mergehead && - verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message" + test_cmp squash.1 .git/SQUASH_MSG ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c0 with c1 (squash, ff-only)' ' git reset --hard c0 && @@ -327,10 +268,10 @@ test_expect_success 'merge c0 with c1 (squash, ff-only)' ' verify_merge file result.1 && verify_head $c0 && verify_no_mergehead && - verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message" + test_cmp squash.1 .git/SQUASH_MSG ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (squash)' ' git reset --hard c1 && @@ -338,17 +279,17 @@ test_expect_success 'merge c1 with c2 (squash)' ' verify_merge file result.1-5 && verify_head $c1 && verify_no_mergehead && - verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message" + test_cmp squash.1-5 .git/SQUASH_MSG ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'unsuccesful merge of c1 with c2 (squash, ff-only)' ' git reset --hard c1 && test_must_fail git merge --squash --ff-only c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 and c3 (squash)' ' git reset --hard c1 && @@ -356,10 +297,10 @@ test_expect_success 'merge c1 with c2 and c3 (squash)' ' verify_merge file result.1-5-9 && verify_head $c1 && verify_no_mergehead && - verify_diff squash.1-5-9 .git/SQUASH_MSG "[OOPS] bad squash message" + test_cmp squash.1-5-9 .git/SQUASH_MSG ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (no-commit in config)' ' git reset --hard c1 && @@ -370,7 +311,7 @@ test_expect_success 'merge c1 with c2 (no-commit in config)' ' verify_mergeheads $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (squash in config)' ' git reset --hard c1 && @@ -379,10 +320,10 @@ test_expect_success 'merge c1 with c2 (squash in config)' ' verify_merge file result.1-5 && verify_head $c1 && verify_no_mergehead && - verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message" + test_cmp squash.1-5 .git/SQUASH_MSG ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'override config option -n with --summary' ' git reset --hard c1 && @@ -412,7 +353,7 @@ test_expect_success 'override config option -n with --stat' ' fi ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'override config option --stat' ' git reset --hard c1 && @@ -428,7 +369,7 @@ test_expect_success 'override config option --stat' ' fi ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (override --no-commit)' ' git reset --hard c1 && @@ -439,7 +380,7 @@ test_expect_success 'merge c1 with c2 (override --no-commit)' ' verify_parents $c1 $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (override --squash)' ' git reset --hard c1 && @@ -450,7 +391,7 @@ test_expect_success 'merge c1 with c2 (override --squash)' ' verify_parents $c1 $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c0 with c1 (no-ff)' ' git reset --hard c0 && @@ -461,7 +402,7 @@ test_expect_success 'merge c0 with c1 (no-ff)' ' verify_parents $c0 $c1 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'combining --squash and --no-ff is refused' ' test_must_fail git merge --squash --no-ff c1 && @@ -485,20 +426,20 @@ test_expect_success 'merge log message' ' git reset --hard c0 && git merge --no-log c2 && git show -s --pretty=format:%b HEAD >msg.act && - verify_diff msg.nolog msg.act "[OOPS] bad merge log message" && + test_cmp msg.nolog msg.act && git merge --log c3 && git show -s --pretty=format:%b HEAD >msg.act && - verify_diff msg.log msg.act "[OOPS] bad merge log message" && + test_cmp msg.log msg.act && git reset --hard HEAD^ && git config merge.log yes && git merge c3 && git show -s --pretty=format:%b HEAD >msg.act && - verify_diff msg.log msg.act "[OOPS] bad merge log message" + test_cmp msg.log msg.act ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c0, c2, c0, and c1' ' git reset --hard c1 && @@ -509,7 +450,7 @@ test_expect_success 'merge c1 with c0, c2, c0, and c1' ' verify_parents $c1 $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c0, c2, c0, and c1' ' git reset --hard c1 && @@ -520,7 +461,7 @@ test_expect_success 'merge c1 with c0, c2, c0, and c1' ' verify_parents $c1 $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c1 and c2' ' git reset --hard c1 && @@ -531,7 +472,7 @@ test_expect_success 'merge c1 with c1 and c2' ' verify_parents $c1 $c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge fast-forward in a dirty tree' ' git reset --hard c0 && @@ -541,16 +482,16 @@ test_expect_success 'merge fast-forward in a dirty tree' ' git merge c2 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'in-index merge' ' git reset --hard c0 && - git merge --no-ff -s resolve c1 > out && + git merge --no-ff -s resolve c1 >out && grep "Wonderful." out && verify_parents $c0 $c1 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'refresh the index before merging' ' git reset --hard c1 && @@ -558,31 +499,39 @@ test_expect_success 'refresh the index before merging' ' git merge c3 ' -cat >expected <<EOF -Merge branch 'c5' (early part) +cat >expected.branch <<\EOF +Merge branch 'c5-branch' (early part) +EOF +cat >expected.tag <<\EOF +Merge commit 'c5~1' EOF test_expect_success 'merge early part of c2' ' git reset --hard c3 && - echo c4 > c4.c && + echo c4 >c4.c && git add c4.c && git commit -m c4 && git tag c4 && - echo c5 > c5.c && + echo c5 >c5.c && git add c5.c && git commit -m c5 && git tag c5 && git reset --hard c3 && - echo c6 > c6.c && + echo c6 >c6.c && git add c6.c && git commit -m c6 && git tag c6 && + git branch -f c5-branch c5 && + git merge c5-branch~1 && + git show -s --pretty=format:%s HEAD >actual.branch && + git reset --keep HEAD^ && git merge c5~1 && - git show -s --pretty=format:%s HEAD > actual && - test_cmp actual expected + git show -s --pretty=format:%s HEAD >actual.tag && + test_cmp expected.branch actual.branch && + test_cmp expected.tag actual.tag ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge --no-ff --no-commit && commit' ' git reset --hard c0 && @@ -591,13 +540,13 @@ test_expect_success 'merge --no-ff --no-commit && commit' ' verify_parents $c0 $c1 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'amending no-ff merge commit' ' EDITOR=: git commit --amend && verify_parents $c0 $c1 ' -test_debug 'gitk --all' +test_debug 'git log --graph --decorate --oneline --all' test_done diff --git a/t/t7606-merge-custom.sh b/t/t7606-merge-custom.sh index 52a451dd5..8e8c4d724 100755 --- a/t/t7606-merge-custom.sh +++ b/t/t7606-merge-custom.sh @@ -1,49 +1,93 @@ #!/bin/sh -test_description='git merge +test_description="git merge -Testing a custom strategy.' +Testing a custom strategy. + +* (HEAD, master) Merge commit 'c3' +|\ +| * (tag: c3) c3 +* | (tag: c1) c1 +|/ +| * tag: c2) c2 +|/ +* (tag: c0) c0 +" . ./test-lib.sh -cat >git-merge-theirs <<EOF -#!$SHELL_PATH -eval git read-tree --reset -u \\\$\$# -EOF -chmod +x git-merge-theirs -PATH=.:$PATH -export PATH +test_expect_success 'set up custom strategy' ' + cat >git-merge-theirs <<-EOF && + #!$SHELL_PATH + eval git read-tree --reset -u \\\$\$# + EOF + + chmod +x git-merge-theirs && + PATH=.:$PATH && + export PATH +' test_expect_success 'setup' ' - echo c0 >c0.c && - git add c0.c && - git commit -m c0 && - git tag c0 && - echo c1 >c1.c && - git add c1.c && - git commit -m c1 && - git tag c1 && - git reset --hard c0 && + test_commit c0 c0.c && + test_commit c1 c1.c && + git reset --keep c0 && echo c1c1 >c1.c && - echo c2 >c2.c && - git add c1.c c2.c && - git commit -m c2 && - git tag c2 + git add c1.c && + test_commit c2 c2.c && + git reset --keep c0 && + test_commit c3 c3.c ' test_expect_success 'merge c2 with a custom strategy' ' git reset --hard c1 && + + git rev-parse c1 >head.old && + git rev-parse c2 >second-parent.expected && + git rev-parse c2^{tree} >tree.expected && git merge -s theirs c2 && - test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && - test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" && - test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" && - test "$(git rev-parse c2^{tree})" = "$(git rev-parse HEAD^{tree})" && + + git rev-parse HEAD >head.new && + git rev-parse HEAD^1 >first-parent && + git rev-parse HEAD^2 >second-parent && + git rev-parse HEAD^{tree} >tree && + git update-index --refresh && git diff --exit-code && git diff --exit-code c2 HEAD && git diff --exit-code c2 && + + ! test_cmp head.old head.new && + test_cmp head.old first-parent && + test_cmp second-parent.expected second-parent && + test_cmp tree.expected tree && test -f c0.c && grep c1c1 c1.c && test -f c2.c ' +test_expect_success 'trivial merge with custom strategy' ' + git reset --hard c1 && + + git rev-parse c1 >head.old && + git rev-parse c3 >second-parent.expected && + git rev-parse c3^{tree} >tree.expected && + git merge -s theirs c3 && + + git rev-parse HEAD >head.new && + git rev-parse HEAD^1 >first-parent && + git rev-parse HEAD^2 >second-parent && + git rev-parse HEAD^{tree} >tree && + git update-index --refresh && + git diff --exit-code && + git diff --exit-code c3 HEAD && + git diff --exit-code c3 && + + ! test_cmp head.old head.new && + test_cmp head.old first-parent && + test_cmp second-parent.expected second-parent && + test_cmp tree.expected tree && + test -f c0.c && + ! test -e c1.c && + test -f c3.c +' + test_done diff --git a/t/t7607-merge-overwrite.sh b/t/t7607-merge-overwrite.sh index 49f4e1599..d82349a6a 100755 --- a/t/t7607-merge-overwrite.sh +++ b/t/t7607-merge-overwrite.sh @@ -31,7 +31,7 @@ test_expect_success 'setup' ' test_expect_success 'will not overwrite untracked file' ' git reset --hard c1 && cat important > c2.c && - ! git merge c2 && + test_must_fail git merge c2 && test_cmp important c2.c ' @@ -39,7 +39,7 @@ test_expect_success 'will not overwrite new file' ' git reset --hard c1 && cat important > c2.c && git add c2.c && - ! git merge c2 && + test_must_fail git merge c2 && test_cmp important c2.c ' @@ -48,7 +48,7 @@ test_expect_success 'will not overwrite staged changes' ' cat important > c2.c && git add c2.c && rm c2.c && - ! git merge c2 && + test_must_fail git merge c2 && git checkout c2.c && test_cmp important c2.c ' @@ -58,7 +58,7 @@ test_expect_success 'will not overwrite removed file' ' git rm c1.c && git commit -m "rm c1.c" && cat important > c1.c && - ! git merge c1a && + test_must_fail git merge c1a && test_cmp important c1.c ' @@ -68,7 +68,7 @@ test_expect_success 'will not overwrite re-added file' ' git commit -m "rm c1.c" && cat important > c1.c && git add c1.c && - ! git merge c1a && + test_must_fail git merge c1a && test_cmp important c1.c ' @@ -79,7 +79,7 @@ test_expect_success 'will not overwrite removed file with staged changes' ' cat important > c1.c && git add c1.c && rm c1.c && - ! git merge c1a && + test_must_fail git merge c1a && git checkout c1.c && test_cmp important c1.c ' diff --git a/t/t7609-merge-co-error-msgs.sh b/t/t7609-merge-co-error-msgs.sh new file mode 100755 index 000000000..114d2bd78 --- /dev/null +++ b/t/t7609-merge-co-error-msgs.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +test_description='unpack-trees error messages' + +. ./test-lib.sh + + +test_expect_success 'setup' ' + echo one >one && + git add one && + git commit -a -m First && + + git checkout -b branch && + echo two >two && + echo three >three && + echo four >four && + echo five >five && + git add two three four five && + git commit -m Second && + + git checkout master && + echo other >two && + echo other >three && + echo other >four && + echo other >five +' + +cat >expect <<\EOF +error: The following untracked working tree files would be overwritten by merge: + two + three + four + five +Please move or remove them before you can merge. +EOF + +test_expect_success 'untracked files overwritten by merge (fast and non-fast forward)' ' + test_must_fail git merge branch 2>out && + test_cmp out expect && + git commit --allow-empty -m empty && + ( + GIT_MERGE_VERBOSITY=0 && + export GIT_MERGE_VERBOSITY && + test_must_fail git merge branch 2>out2 + ) && + test_cmp out2 expect && + git reset --hard HEAD^ +' + +cat >expect <<\EOF +error: Your local changes to the following files would be overwritten by merge: + two + three + four +Please, commit your changes or stash them before you can merge. +error: The following untracked working tree files would be overwritten by merge: + five +Please move or remove them before you can merge. +EOF + +test_expect_success 'untracked files or local changes ovewritten by merge' ' + git add two && + git add three && + git add four && + test_must_fail git merge branch 2>out && + test_cmp out expect +' + +cat >expect <<\EOF +error: Your local changes to the following files would be overwritten by checkout: + rep/two + rep/one +Please, commit your changes or stash them before you can switch branches. +EOF + +test_expect_success 'cannot switch branches because of local changes' ' + git add five && + mkdir rep && + echo one >rep/one && + echo two >rep/two && + git add rep/one rep/two && + git commit -m Fourth && + git checkout master && + echo uno >rep/one && + echo dos >rep/two && + test_must_fail git checkout branch 2>out && + test_cmp out expect +' + +cat >expect <<\EOF +error: Your local changes to the following files would be overwritten by checkout: + rep/two + rep/one +Please, commit your changes or stash them before you can switch branches. +EOF + +test_expect_success 'not uptodate file porcelain checkout error' ' + git add rep/one rep/two && + test_must_fail git checkout branch 2>out && + test_cmp out expect +' + +cat >expect <<\EOF +error: Updating the following directories would lose untracked files in it: + rep2 + rep + +EOF + +test_expect_success 'not_uptodate_dir porcelain checkout error' ' + git init uptodate && + cd uptodate && + mkdir rep && + mkdir rep2 && + touch rep/foo && + touch rep2/foo && + git add rep/foo rep2/foo && + git commit -m init && + git checkout -b branch && + git rm rep -r && + git rm rep2 -r && + >rep && + >rep2 && + git add rep rep2&& + git commit -m "added test as a file" && + git checkout master && + >rep/untracked-file && + >rep2/untracked-file && + test_must_fail git checkout branch 2>out && + test_cmp out ../expect +' + +test_done diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index e768c3eb2..3bd74042e 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -14,6 +14,7 @@ Testing basic merge tool invocation' # running mergetool test_expect_success 'setup' ' + git config rerere.enabled true && echo master >file1 && mkdir subdir && echo master sub >subdir/file3 && @@ -67,23 +68,47 @@ test_expect_success 'mergetool crlf' ' ' test_expect_success 'mergetool in subdir' ' - git checkout -b test3 branch1 - cd subdir && ( - test_must_fail git merge master >/dev/null 2>&1 && - ( yes "" | git mergetool file3 >/dev/null 2>&1 ) && - test "$(cat file3)" = "master new sub" ) + git checkout -b test3 branch1 && + ( + cd subdir && + test_must_fail git merge master >/dev/null 2>&1 && + ( yes "" | git mergetool file3 >/dev/null 2>&1 ) && + test "$(cat file3)" = "master new sub" + ) ' -# We can't merge files from parent directories when running mergetool -# from a subdir. Is this a bug? -# -#test_expect_failure 'mergetool in subdir' ' -# cd subdir && ( -# ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) && -# ( yes "" | git mergetool ../file2 >/dev/null 2>&1 ) && -# test "$(cat ../file1)" = "master updated" && -# test "$(cat ../file2)" = "master new" && -# git commit -m "branch1 resolved with mergetool - subdir" ) -#' +test_expect_success 'mergetool on file in parent dir' ' + ( + cd subdir && + ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) && + ( yes "" | git mergetool ../file2 >/dev/null 2>&1 ) && + test "$(cat ../file1)" = "master updated" && + test "$(cat ../file2)" = "master new" && + git commit -m "branch1 resolved with mergetool - subdir" + ) +' + +test_expect_success 'mergetool skips autoresolved' ' + git checkout -b test4 branch1 && + test_must_fail git merge master && + test -n "$(git ls-files -u)" && + output="$(git mergetool --no-prompt)" && + test "$output" = "No files need merging" && + git reset --hard +' + +test_expect_success 'mergetool merges all from subdir' ' + ( + cd subdir && + git config rerere.enabled false && + test_must_fail git merge master && + git mergetool --no-prompt && + test "$(cat ../file1)" = "master updated" && + test "$(cat ../file2)" = "master new" && + test "$(cat file3)" = "master new sub" && + git add ../file1 ../file2 file3 && + git commit -m "branch2 resolved by mergetool from subdir" + ) +' test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 1de83ef98..58dc6f645 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -10,11 +10,6 @@ Testing basic diff tool invocation . ./test-lib.sh -if ! test_have_prereq PERL; then - say 'skipping difftool tests, perl not available' - test_done -fi - LF=' ' @@ -50,7 +45,7 @@ prompt_given() } # Create a file on master and change it on branch -test_expect_success 'setup' ' +test_expect_success PERL 'setup' ' echo master >file && git add file && git commit -m "added file" && @@ -62,7 +57,7 @@ test_expect_success 'setup' ' ' # Configure a custom difftool.<tool>.cmd and use it -test_expect_success 'custom commands' ' +test_expect_success PERL 'custom commands' ' restore_test_defaults && git config difftool.test-tool.cmd "cat \$REMOTE" && @@ -75,13 +70,13 @@ test_expect_success 'custom commands' ' ' # Ensures that git-difftool ignores bogus --tool values -test_expect_success 'difftool ignores bad --tool values' ' +test_expect_success PERL 'difftool ignores bad --tool values' ' diff=$(git difftool --no-prompt --tool=bad-tool branch) test "$?" = 1 && test "$diff" = "" ' -test_expect_success 'difftool honors --gui' ' +test_expect_success PERL 'difftool honors --gui' ' git config merge.tool bogus-tool && git config diff.tool bogus-tool && git config diff.guitool test-tool && @@ -92,7 +87,7 @@ test_expect_success 'difftool honors --gui' ' restore_test_defaults ' -test_expect_success 'difftool --gui works without configured diff.guitool' ' +test_expect_success PERL 'difftool --gui works without configured diff.guitool' ' git config diff.tool test-tool && diff=$(git difftool --no-prompt --gui branch) && @@ -102,7 +97,7 @@ test_expect_success 'difftool --gui works without configured diff.guitool' ' ' # Specify the diff tool using $GIT_DIFF_TOOL -test_expect_success 'GIT_DIFF_TOOL variable' ' +test_expect_success PERL 'GIT_DIFF_TOOL variable' ' git config --unset diff.tool GIT_DIFF_TOOL=test-tool && export GIT_DIFF_TOOL && @@ -115,7 +110,7 @@ test_expect_success 'GIT_DIFF_TOOL variable' ' # Test the $GIT_*_TOOL variables and ensure # that $GIT_DIFF_TOOL always wins unless --tool is specified -test_expect_success 'GIT_DIFF_TOOL overrides' ' +test_expect_success PERL 'GIT_DIFF_TOOL overrides' ' git config diff.tool bogus-tool && git config merge.tool bogus-tool && @@ -136,7 +131,7 @@ test_expect_success 'GIT_DIFF_TOOL overrides' ' # Test that we don't have to pass --no-prompt to difftool # when $GIT_DIFFTOOL_NO_PROMPT is true -test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' ' +test_expect_success PERL 'GIT_DIFFTOOL_NO_PROMPT variable' ' GIT_DIFFTOOL_NO_PROMPT=true && export GIT_DIFFTOOL_NO_PROMPT && @@ -148,7 +143,7 @@ test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' ' # git-difftool supports the difftool.prompt variable. # Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false -test_expect_success 'GIT_DIFFTOOL_PROMPT variable' ' +test_expect_success PERL 'GIT_DIFFTOOL_PROMPT variable' ' git config difftool.prompt false && GIT_DIFFTOOL_PROMPT=true && export GIT_DIFFTOOL_PROMPT && @@ -160,7 +155,7 @@ test_expect_success 'GIT_DIFFTOOL_PROMPT variable' ' ' # Test that we don't have to pass --no-prompt when difftool.prompt is false -test_expect_success 'difftool.prompt config variable is false' ' +test_expect_success PERL 'difftool.prompt config variable is false' ' git config difftool.prompt false && diff=$(git difftool branch) && @@ -170,7 +165,7 @@ test_expect_success 'difftool.prompt config variable is false' ' ' # Test that we don't have to pass --no-prompt when mergetool.prompt is false -test_expect_success 'difftool merge.prompt = false' ' +test_expect_success PERL 'difftool merge.prompt = false' ' git config --unset difftool.prompt git config mergetool.prompt false && @@ -181,7 +176,7 @@ test_expect_success 'difftool merge.prompt = false' ' ' # Test that the -y flag can override difftool.prompt = true -test_expect_success 'difftool.prompt can overridden with -y' ' +test_expect_success PERL 'difftool.prompt can overridden with -y' ' git config difftool.prompt true && diff=$(git difftool -y branch) && @@ -191,7 +186,7 @@ test_expect_success 'difftool.prompt can overridden with -y' ' ' # Test that the --prompt flag can override difftool.prompt = false -test_expect_success 'difftool.prompt can overridden with --prompt' ' +test_expect_success PERL 'difftool.prompt can overridden with --prompt' ' git config difftool.prompt false && prompt=$(echo | git difftool --prompt branch | tail -1) && @@ -201,7 +196,7 @@ test_expect_success 'difftool.prompt can overridden with --prompt' ' ' # Test that the last flag passed on the command-line wins -test_expect_success 'difftool last flag wins' ' +test_expect_success PERL 'difftool last flag wins' ' diff=$(git difftool --prompt --no-prompt branch) && test "$diff" = "branch" && @@ -215,7 +210,7 @@ test_expect_success 'difftool last flag wins' ' # git-difftool falls back to git-mergetool config variables # so test that behavior here -test_expect_success 'difftool + mergetool config variables' ' +test_expect_success PERL 'difftool + mergetool config variables' ' remove_config_vars git config merge.tool test-tool && git config mergetool.test-tool.cmd "cat \$LOCAL" && @@ -233,7 +228,7 @@ test_expect_success 'difftool + mergetool config variables' ' restore_test_defaults ' -test_expect_success 'difftool.<tool>.path' ' +test_expect_success PERL 'difftool.<tool>.path' ' git config difftool.tkdiff.path echo && diff=$(git difftool --tool=tkdiff --no-prompt branch) && git config --unset difftool.tkdiff.path && @@ -243,32 +238,32 @@ test_expect_success 'difftool.<tool>.path' ' restore_test_defaults ' -test_expect_success 'difftool --extcmd=cat' ' +test_expect_success PERL 'difftool --extcmd=cat' ' diff=$(git difftool --no-prompt --extcmd=cat branch) && test "$diff" = branch"$LF"master ' -test_expect_success 'difftool --extcmd cat' ' +test_expect_success PERL 'difftool --extcmd cat' ' diff=$(git difftool --no-prompt --extcmd cat branch) && test "$diff" = branch"$LF"master ' -test_expect_success 'difftool -x cat' ' +test_expect_success PERL 'difftool -x cat' ' diff=$(git difftool --no-prompt -x cat branch) && test "$diff" = branch"$LF"master ' -test_expect_success 'difftool --extcmd echo arg1' ' +test_expect_success PERL 'difftool --extcmd echo arg1' ' diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"echo\ \$1\" branch) test "$diff" = file ' -test_expect_success 'difftool --extcmd cat arg1' ' +test_expect_success PERL 'difftool --extcmd cat arg1' ' diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$1\" branch) test "$diff" = master ' -test_expect_success 'difftool --extcmd cat arg2' ' +test_expect_success PERL 'difftool --extcmd cat arg2' ' diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$2\" branch) test "$diff" = branch ' diff --git a/t/t7002-grep.sh b/t/t7810-grep.sh index 8a6322765..50658845c 100755 --- a/t/t7002-grep.sh +++ b/t/t7810-grep.sh @@ -65,7 +65,7 @@ do test_expect_success "grep -w $L (w)" ' : >expected && - ! git grep -n -w -e "^w" >actual && + test_must_fail git grep -n -w -e "^w" >actual && test_cmp expected actual ' @@ -324,8 +324,13 @@ test_expect_success 'log grep setup' ' echo a >>file && test_tick && - git commit -a -m "third" + git commit -a -m "third" && + echo a >>file && + test_tick && + GIT_AUTHOR_NAME="Night Fall" \ + GIT_AUTHOR_EMAIL="nitfol@frobozz.com" \ + git commit -a -m "fourth" ' test_expect_success 'log grep (1)' ' @@ -372,6 +377,28 @@ test_expect_success 'log --grep --author implicitly uses all-match' ' test_cmp expect actual ' +test_expect_success 'log with multiple --author uses union' ' + git log --author="Thor" --author="Aster" --format=%s >actual && + { + echo third && echo second && echo initial + } >expect && + test_cmp expect actual +' + +test_expect_success 'log with --grep and multiple --author uses all-match' ' + git log --author="Thor" --author="Night" --grep=i --format=%s >actual && + { + echo third && echo initial + } >expect && + test_cmp expect actual +' + +test_expect_success 'log with --grep and multiple --author uses all-match' ' + git log --author="Thor" --author="Night" --grep=q --format=%s >actual && + >expect && + test_cmp expect actual +' + test_expect_success 'grep with CE_VALID file' ' git update-index --assume-unchanged t/t && rm t/t && diff --git a/t/t7811-grep-open.sh b/t/t7811-grep-open.sh new file mode 100755 index 000000000..568a6f2b6 --- /dev/null +++ b/t/t7811-grep-open.sh @@ -0,0 +1,168 @@ +#!/bin/sh + +test_description='git grep --open-files-in-pager +' + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-pager.sh +unset PAGER GIT_PAGER + +test_expect_success 'setup' ' + test_commit initial grep.h " +enum grep_pat_token { + GREP_PATTERN, + GREP_PATTERN_HEAD, + GREP_PATTERN_BODY, + GREP_AND, + GREP_OPEN_PAREN, + GREP_CLOSE_PAREN, + GREP_NOT, + GREP_OR, +};" && + + test_commit add-user revision.c " + } + if (seen_dashdash) + read_pathspec_from_stdin(revs, &sb, prune); + strbuf_release(&sb); +} + +static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what) +{ + append_grep_pattern(&revs->grep_filter, ptn, \"command line\", 0, what); +" && + + mkdir subdir && + test_commit subdir subdir/grep.c "enum grep_pat_token" && + + test_commit uninteresting unrelated "hello, world" && + + echo GREP_PATTERN >untracked +' + +test_expect_success SIMPLEPAGER 'git grep -O' ' + cat >$less <<-\EOF && + #!/bin/sh + printf "%s\n" "$@" >pager-args + EOF + chmod +x $less && + cat >expect.less <<-\EOF && + +/*GREP_PATTERN + grep.h + EOF + echo grep.h >expect.notless && + >empty && + + PATH=.:$PATH git grep -O GREP_PATTERN >out && + { + test_cmp expect.less pager-args || + test_cmp expect.notless pager-args + } && + test_cmp empty out +' + +test_expect_success 'git grep -O --cached' ' + test_must_fail git grep --cached -O GREP_PATTERN >out 2>msg && + grep open-files-in-pager msg +' + +test_expect_success 'git grep -O --no-index' ' + rm -f expect.less pager-args out && + cat >expect <<-\EOF && + grep.h + untracked + EOF + >empty && + + ( + GIT_PAGER='\''printf "%s\n" >pager-args'\'' && + export GIT_PAGER && + git grep --no-index -O GREP_PATTERN >out + ) && + test_cmp expect pager-args && + test_cmp empty out +' + +test_expect_success 'setup: fake "less"' ' + cat >less <<-\EOF && + #!/bin/sh + printf "%s\n" "$@" >actual + EOF + chmod +x less +' + +test_expect_success 'git grep -O jumps to line in less' ' + cat >expect <<-\EOF && + +/*GREP_PATTERN + grep.h + EOF + >empty && + + GIT_PAGER=./less git grep -O GREP_PATTERN >out && + test_cmp expect actual && + test_cmp empty out && + + git grep -O./less GREP_PATTERN >out2 && + test_cmp expect actual && + test_cmp empty out2 +' + +test_expect_success 'modified file' ' + rm -f actual && + cat >expect <<-\EOF && + +/*enum grep_pat_token + grep.h + revision.c + subdir/grep.c + unrelated + EOF + >empty && + + echo "enum grep_pat_token" >unrelated && + test_when_finished "git checkout HEAD unrelated" && + GIT_PAGER=./less git grep -F -O "enum grep_pat_token" >out && + test_cmp expect actual && + test_cmp empty out +' + +test_config() { + git config "$1" "$2" && + test_when_finished "git config --unset $1" +} + +test_expect_success 'copes with color settings' ' + rm -f actual && + echo grep.h >expect && + test_config color.grep always && + test_config color.grep.filename yellow && + test_config color.grep.separator green && + git grep -O'\''printf "%s\n" >actual'\'' GREP_AND && + test_cmp expect actual +' + +test_expect_success 'run from subdir' ' + rm -f actual && + echo grep.c >expect && + >empty && + + ( + cd subdir && + export GIT_PAGER && + GIT_PAGER='\''printf "%s\n" >../args'\'' && + git grep -O "enum grep_pat_token" >../out && + git grep -O"pwd >../dir; :" "enum grep_pat_token" >../out2 + ) && + case $(cat dir) in + *subdir) + : good + ;; + *) + false + ;; + esac && + test_cmp expect args && + test_cmp empty out && + test_cmp empty out2 +' + +test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 0b8a59150..a298eb043 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -3,20 +3,17 @@ test_description='git send-email' . ./test-lib.sh -if ! test_have_prereq PERL; then - say 'skipping git send-email tests, perl not available' - test_done -fi +# May be altered later in the test +PREREQ="PERL" -PROG='git send-email' -test_expect_success \ +test_expect_success $PREREQ \ 'prepare reference tree' \ 'echo "1A quick brown fox jumps over the" >file && echo "lazy dog" >>file && git add file && GIT_AUTHOR_NAME="A" git commit -a -m "Initial."' -test_expect_success \ +test_expect_success $PREREQ \ 'Setup helper tool' \ '(echo "#!$SHELL_PATH" echo shift @@ -36,7 +33,7 @@ clean_fake_sendmail() { rm -f commandline* msgtxt* } -test_expect_success 'Extract patches' ' +test_expect_success $PREREQ 'Extract patches' ' patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1` ' @@ -57,49 +54,56 @@ test_no_confirm () { # Exit immediately to prevent hang if a no-confirm test fails check_no_confirm () { - test -f no_confirm_okay || { - say 'No confirm test failed; skipping remaining tests to prevent hanging' - test_done - } + if ! test -f no_confirm_okay + then + say 'confirm test failed; skipping remaining tests to prevent hanging' + PREREQ="$PREREQ,CHECK_NO_CONFIRM" + fi + return 0 } -test_expect_success 'No confirm with --suppress-cc' ' - test_no_confirm --suppress-cc=sob +test_expect_success $PREREQ 'No confirm with --suppress-cc' ' + test_no_confirm --suppress-cc=sob && + check_no_confirm ' -check_no_confirm -test_expect_success 'No confirm with --confirm=never' ' - test_no_confirm --confirm=never + +test_expect_success $PREREQ 'No confirm with --confirm=never' ' + test_no_confirm --confirm=never && + check_no_confirm ' -check_no_confirm # leave sendemail.confirm set to never after this so that none of the # remaining tests prompt unintentionally. -test_expect_success 'No confirm with sendemail.confirm=never' ' +test_expect_success $PREREQ 'No confirm with sendemail.confirm=never' ' git config sendemail.confirm never && - test_no_confirm --compose --subject=foo + test_no_confirm --compose --subject=foo && + check_no_confirm ' -check_no_confirm -test_expect_success 'Send patches' ' +test_expect_success $PREREQ 'Send patches' ' git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors ' +test_expect_success $PREREQ 'setup expect' ' cat >expected <<\EOF !nobody@example.com! !author@example.com! !one@example.com! !two@example.com! EOF -test_expect_success \ +' + +test_expect_success $PREREQ \ 'Verify commandline' \ 'test_cmp expected commandline1' -test_expect_success 'Send patches with --envelope-sender' ' +test_expect_success $PREREQ 'Send patches with --envelope-sender' ' clean_fake_sendmail && git send-email --envelope-sender="Patch Contributer <patch@example.com>" --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors ' +test_expect_success $PREREQ 'setup expect' ' cat >expected <<\EOF !patch@example.com! !-i! @@ -108,15 +112,18 @@ cat >expected <<\EOF !one@example.com! !two@example.com! EOF -test_expect_success \ +' + +test_expect_success $PREREQ \ 'Verify commandline' \ 'test_cmp expected commandline1' -test_expect_success 'Send patches with --envelope-sender=auto' ' +test_expect_success $PREREQ 'Send patches with --envelope-sender=auto' ' clean_fake_sendmail && git send-email --envelope-sender=auto --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors ' +test_expect_success $PREREQ 'setup expect' ' cat >expected <<\EOF !nobody@example.com! !-i! @@ -125,10 +132,13 @@ cat >expected <<\EOF !one@example.com! !two@example.com! EOF -test_expect_success \ +' + +test_expect_success $PREREQ \ 'Verify commandline' \ 'test_cmp expected commandline1' +test_expect_success $PREREQ 'setup expect' " cat >expected-show-all-headers <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -158,8 +168,9 @@ References: <unique-message-id@example.com> Result: OK EOF +" -test_expect_success 'Show all headers' ' +test_expect_success $PREREQ 'Show all headers' ' git send-email \ --dry-run \ --suppress-cc=sob \ @@ -177,7 +188,7 @@ test_expect_success 'Show all headers' ' test_cmp expected-show-all-headers actual-show-all-headers ' -test_expect_success 'Prompting works' ' +test_expect_success $PREREQ 'Prompting works' ' clean_fake_sendmail && (echo "Example <from@example.com>" echo "to@example.com" @@ -190,7 +201,7 @@ test_expect_success 'Prompting works' ' grep "^To: to@example.com\$" msgtxt1 ' -test_expect_success 'cccmd works' ' +test_expect_success $PREREQ 'cccmd works' ' clean_fake_sendmail && cp $patches cccmd.patch && echo cccmd--cccmd@example.com >>cccmd.patch && @@ -209,10 +220,10 @@ test_expect_success 'cccmd works' ' grep "^ cccmd@example.com" msgtxt1 ' -z8=zzzzzzzz -z64=$z8$z8$z8$z8$z8$z8$z8$z8 -z512=$z64$z64$z64$z64$z64$z64$z64$z64 -test_expect_success 'reject long lines' ' +test_expect_success $PREREQ 'reject long lines' ' + z8=zzzzzzzz && + z64=$z8$z8$z8$z8$z8$z8$z8$z8 && + z512=$z64$z64$z64$z64$z64$z64$z64$z64 && clean_fake_sendmail && cp $patches longline.patch && echo $z512$z512 >>longline.patch && @@ -225,11 +236,11 @@ test_expect_success 'reject long lines' ' grep longline.patch errors ' -test_expect_success 'no patch was sent' ' +test_expect_success $PREREQ 'no patch was sent' ' ! test -e commandline1 ' -test_expect_success 'Author From: in message body' ' +test_expect_success $PREREQ 'Author From: in message body' ' clean_fake_sendmail && git send-email \ --from="Example <nobody@example.com>" \ @@ -240,7 +251,7 @@ test_expect_success 'Author From: in message body' ' grep "From: A <author@example.com>" msgbody1 ' -test_expect_success 'Author From: not in message body' ' +test_expect_success $PREREQ 'Author From: not in message body' ' clean_fake_sendmail && git send-email \ --from="A <author@example.com>" \ @@ -251,7 +262,7 @@ test_expect_success 'Author From: not in message body' ' ! grep "From: A <author@example.com>" msgbody1 ' -test_expect_success 'allow long lines with --no-validate' ' +test_expect_success $PREREQ 'allow long lines with --no-validate' ' git send-email \ --from="Example <nobody@example.com>" \ --to=nobody@example.com \ @@ -261,19 +272,19 @@ test_expect_success 'allow long lines with --no-validate' ' 2>errors ' -test_expect_success 'Invalid In-Reply-To' ' +test_expect_success $PREREQ 'Invalid In-Reply-To' ' clean_fake_sendmail && git send-email \ --from="Example <nobody@example.com>" \ --to=nobody@example.com \ --in-reply-to=" " \ --smtp-server="$(pwd)/fake.sendmail" \ - $patches + $patches \ 2>errors ! grep "^In-Reply-To: < *>" msgtxt1 ' -test_expect_success 'Valid In-Reply-To when prompting' ' +test_expect_success $PREREQ 'Valid In-Reply-To when prompting' ' clean_fake_sendmail && (echo "From Example <from@example.com>" echo "To Example <to@example.com>" @@ -284,7 +295,7 @@ test_expect_success 'Valid In-Reply-To when prompting' ' ! grep "^In-Reply-To: < *>" msgtxt1 ' -test_expect_success 'setup fake editor' ' +test_expect_success $PREREQ 'setup fake editor' ' (echo "#!$SHELL_PATH" && echo "echo fake edit >>\"\$1\"" ) >fake-editor && @@ -293,7 +304,7 @@ test_expect_success 'setup fake editor' ' test_set_editor "$(pwd)/fake-editor" -test_expect_success '--compose works' ' +test_expect_success $PREREQ '--compose works' ' clean_fake_sendmail && git send-email \ --compose --subject foo \ @@ -304,14 +315,15 @@ test_expect_success '--compose works' ' 2>errors ' -test_expect_success 'first message is compose text' ' +test_expect_success $PREREQ 'first message is compose text' ' grep "^fake edit" msgtxt1 ' -test_expect_success 'second message is patch' ' +test_expect_success $PREREQ 'second message is patch' ' grep "Subject:.*Second" msgtxt2 ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-sob <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -338,6 +350,7 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" test_suppression () { git send-email \ @@ -354,11 +367,12 @@ test_suppression () { test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"} } -test_expect_success 'sendemail.cc set' ' +test_expect_success $PREREQ 'sendemail.cc set' ' git config sendemail.cc cc@example.com && test_suppression sob ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-sob <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -383,12 +397,14 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" -test_expect_success 'sendemail.cc unset' ' +test_expect_success $PREREQ 'sendemail.cc unset' ' git config --unset sendemail.cc && test_suppression sob ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-cccmd <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -416,14 +432,16 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" -test_expect_success 'sendemail.cccmd' ' +test_expect_success $PREREQ 'sendemail.cccmd' ' echo echo cc-cmd@example.com > cccmd && chmod +x cccmd && git config sendemail.cccmd ./cccmd && test_suppression cccmd ' +test_expect_success $PREREQ 'setup expect' ' cat >expected-suppress-all <<\EOF 0001-Second.patch Dry-OK. Log says: @@ -439,11 +457,13 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +' -test_expect_success '--suppress-cc=all' ' +test_expect_success $PREREQ '--suppress-cc=all' ' test_suppression all ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-body <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -471,11 +491,13 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" -test_expect_success '--suppress-cc=body' ' +test_expect_success $PREREQ '--suppress-cc=body' ' test_suppression body ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-body-cccmd <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -500,11 +522,13 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" -test_expect_success '--suppress-cc=body --suppress-cc=cccmd' ' +test_expect_success $PREREQ '--suppress-cc=body --suppress-cc=cccmd' ' test_suppression body cccmd ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-sob <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -529,12 +553,14 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" -test_expect_success '--suppress-cc=sob' ' +test_expect_success $PREREQ '--suppress-cc=sob' ' git config --unset sendemail.cccmd test_suppression sob ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-bodycc <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -562,11 +588,13 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" -test_expect_success '--suppress-cc=bodycc' ' +test_expect_success $PREREQ '--suppress-cc=bodycc' ' test_suppression bodycc ' +test_expect_success $PREREQ 'setup expect' " cat >expected-suppress-cc <<\EOF 0001-Second.patch (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' @@ -588,8 +616,9 @@ X-Mailer: X-MAILER-STRING Result: OK EOF +" -test_expect_success '--suppress-cc=cc' ' +test_expect_success $PREREQ '--suppress-cc=cc' ' test_suppression cc ' @@ -604,23 +633,23 @@ test_confirm () { grep "Send this email" stdout } -test_expect_success '--confirm=always' ' +test_expect_success $PREREQ '--confirm=always' ' test_confirm --confirm=always --suppress-cc=all ' -test_expect_success '--confirm=auto' ' +test_expect_success $PREREQ '--confirm=auto' ' test_confirm --confirm=auto ' -test_expect_success '--confirm=cc' ' +test_expect_success $PREREQ '--confirm=cc' ' test_confirm --confirm=cc ' -test_expect_success '--confirm=compose' ' +test_expect_success $PREREQ '--confirm=compose' ' test_confirm --confirm=compose --compose ' -test_expect_success 'confirm by default (due to cc)' ' +test_expect_success $PREREQ 'confirm by default (due to cc)' ' CONFIRM=$(git config --get sendemail.confirm) && git config --unset sendemail.confirm && test_confirm @@ -629,7 +658,7 @@ test_expect_success 'confirm by default (due to cc)' ' test $ret = "0" ' -test_expect_success 'confirm by default (due to --compose)' ' +test_expect_success $PREREQ 'confirm by default (due to --compose)' ' CONFIRM=$(git config --get sendemail.confirm) && git config --unset sendemail.confirm && test_confirm --suppress-cc=all --compose @@ -638,7 +667,7 @@ test_expect_success 'confirm by default (due to --compose)' ' test $ret = "0" ' -test_expect_success 'confirm detects EOF (inform assumes y)' ' +test_expect_success $PREREQ 'confirm detects EOF (inform assumes y)' ' CONFIRM=$(git config --get sendemail.confirm) && git config --unset sendemail.confirm && rm -fr outdir && @@ -654,7 +683,7 @@ test_expect_success 'confirm detects EOF (inform assumes y)' ' test $ret = "0" ' -test_expect_success 'confirm detects EOF (auto causes failure)' ' +test_expect_success $PREREQ 'confirm detects EOF (auto causes failure)' ' CONFIRM=$(git config --get sendemail.confirm) && git config sendemail.confirm auto && GIT_SEND_EMAIL_NOTTY=1 && @@ -669,7 +698,7 @@ test_expect_success 'confirm detects EOF (auto causes failure)' ' test $ret = "0" ' -test_expect_success 'confirm doesnt loop forever' ' +test_expect_success $PREREQ 'confirm doesnt loop forever' ' CONFIRM=$(git config --get sendemail.confirm) && git config sendemail.confirm auto && GIT_SEND_EMAIL_NOTTY=1 && @@ -684,7 +713,7 @@ test_expect_success 'confirm doesnt loop forever' ' test $ret = "0" ' -test_expect_success 'utf8 Cc is rfc2047 encoded' ' +test_expect_success $PREREQ 'utf8 Cc is rfc2047 encoded' ' clean_fake_sendmail && rm -fr outdir && git format-patch -1 -o outdir --cc="à éìöú <utf8@example.com>" && @@ -697,7 +726,7 @@ test_expect_success 'utf8 Cc is rfc2047 encoded' ' grep "=?UTF-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>" ' -test_expect_success '--compose adds MIME for utf8 body' ' +test_expect_success $PREREQ '--compose adds MIME for utf8 body' ' clean_fake_sendmail && (echo "#!$SHELL_PATH" && echo "echo utf8 body: à éìöú >>\"\$1\"" @@ -714,7 +743,7 @@ test_expect_success '--compose adds MIME for utf8 body' ' grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1 ' -test_expect_success '--compose respects user mime type' ' +test_expect_success $PREREQ '--compose respects user mime type' ' clean_fake_sendmail && (echo "#!$SHELL_PATH" && echo "(echo MIME-Version: 1.0" @@ -737,7 +766,7 @@ test_expect_success '--compose respects user mime type' ' ! grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1 ' -test_expect_success '--compose adds MIME for utf8 subject' ' +test_expect_success $PREREQ '--compose adds MIME for utf8 subject' ' clean_fake_sendmail && GIT_EDITOR="\"$(pwd)/fake-editor\"" \ git send-email \ @@ -750,7 +779,7 @@ test_expect_success '--compose adds MIME for utf8 subject' ' grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1 ' -test_expect_success 'detects ambiguous reference/file conflict' ' +test_expect_success $PREREQ 'detects ambiguous reference/file conflict' ' echo master > master && git add master && git commit -m"add master" && @@ -758,7 +787,7 @@ test_expect_success 'detects ambiguous reference/file conflict' ' grep disambiguate errors ' -test_expect_success 'feed two files' ' +test_expect_success $PREREQ 'feed two files' ' rm -fr outdir && git format-patch -2 -o outdir && git send-email \ @@ -771,7 +800,7 @@ test_expect_success 'feed two files' ' test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master" ' -test_expect_success 'in-reply-to but no threading' ' +test_expect_success $PREREQ 'in-reply-to but no threading' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -782,7 +811,7 @@ test_expect_success 'in-reply-to but no threading' ' grep "In-Reply-To: <in-reply-id@example.com>" ' -test_expect_success 'no in-reply-to and no threading' ' +test_expect_success $PREREQ 'no in-reply-to and no threading' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -792,7 +821,7 @@ test_expect_success 'no in-reply-to and no threading' ' ! grep "In-Reply-To: " stdout ' -test_expect_success 'threading but no chain-reply-to' ' +test_expect_success $PREREQ 'threading but no chain-reply-to' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -803,7 +832,7 @@ test_expect_success 'threading but no chain-reply-to' ' grep "In-Reply-To: " stdout ' -test_expect_success 'warning with an implicit --chain-reply-to' ' +test_expect_success $PREREQ 'warning with an implicit --chain-reply-to' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -812,7 +841,7 @@ test_expect_success 'warning with an implicit --chain-reply-to' ' grep "no-chain-reply-to" errors ' -test_expect_success 'no warning with an explicit --chain-reply-to' ' +test_expect_success $PREREQ 'no warning with an explicit --chain-reply-to' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -822,7 +851,7 @@ test_expect_success 'no warning with an explicit --chain-reply-to' ' ! grep "no-chain-reply-to" errors ' -test_expect_success 'no warning with an explicit --no-chain-reply-to' ' +test_expect_success $PREREQ 'no warning with an explicit --no-chain-reply-to' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -832,7 +861,7 @@ test_expect_success 'no warning with an explicit --no-chain-reply-to' ' ! grep "no-chain-reply-to" errors ' -test_expect_success 'no warning with sendemail.chainreplyto = false' ' +test_expect_success $PREREQ 'no warning with sendemail.chainreplyto = false' ' git config sendemail.chainreplyto false && git send-email \ --dry-run \ @@ -842,7 +871,7 @@ test_expect_success 'no warning with sendemail.chainreplyto = false' ' ! grep "no-chain-reply-to" errors ' -test_expect_success 'no warning with sendemail.chainreplyto = true' ' +test_expect_success $PREREQ 'no warning with sendemail.chainreplyto = true' ' git config sendemail.chainreplyto true && git send-email \ --dry-run \ @@ -852,7 +881,7 @@ test_expect_success 'no warning with sendemail.chainreplyto = true' ' ! grep "no-chain-reply-to" errors ' -test_expect_success 'sendemail.to works' ' +test_expect_success $PREREQ 'sendemail.to works' ' git config --replace-all sendemail.to "Somebody <somebody@ex.com>" && git send-email \ --dry-run \ @@ -861,7 +890,7 @@ test_expect_success 'sendemail.to works' ' grep "To: Somebody <somebody@ex.com>" stdout ' -test_expect_success '--no-to overrides sendemail.to' ' +test_expect_success $PREREQ '--no-to overrides sendemail.to' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -872,7 +901,7 @@ test_expect_success '--no-to overrides sendemail.to' ' ! grep "To: Somebody <somebody@ex.com>" stdout ' -test_expect_success 'sendemail.cc works' ' +test_expect_success $PREREQ 'sendemail.cc works' ' git config --replace-all sendemail.cc "Somebody <somebody@ex.com>" && git send-email \ --dry-run \ @@ -882,7 +911,7 @@ test_expect_success 'sendemail.cc works' ' grep "Cc: Somebody <somebody@ex.com>" stdout ' -test_expect_success '--no-cc overrides sendemail.cc' ' +test_expect_success $PREREQ '--no-cc overrides sendemail.cc' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -894,7 +923,7 @@ test_expect_success '--no-cc overrides sendemail.cc' ' ! grep "Cc: Somebody <somebody@ex.com>" stdout ' -test_expect_success 'sendemail.bcc works' ' +test_expect_success $PREREQ 'sendemail.bcc works' ' git config --replace-all sendemail.bcc "Other <other@ex.com>" && git send-email \ --dry-run \ @@ -905,7 +934,7 @@ test_expect_success 'sendemail.bcc works' ' grep "RCPT TO:<other@ex.com>" stdout ' -test_expect_success '--no-bcc overrides sendemail.bcc' ' +test_expect_success $PREREQ '--no-bcc overrides sendemail.bcc' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ @@ -918,6 +947,7 @@ test_expect_success '--no-bcc overrides sendemail.bcc' ' ! grep "RCPT TO:<other@ex.com>" stdout ' +test_expect_success $PREREQ 'setup expect' ' cat >email-using-8bit <<EOF From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001 Message-Id: <bogus-message-id@example.com> @@ -927,14 +957,17 @@ Subject: subject goes here Dieser deutsche Text enthält einen Umlaut! EOF +' +test_expect_success $PREREQ 'setup expect' ' cat >content-type-decl <<EOF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EOF +' -test_expect_success 'asks about and fixes 8bit encodings' ' +test_expect_success $PREREQ 'asks about and fixes 8bit encodings' ' clean_fake_sendmail && echo | git send-email --from=author@example.com --to=nobody@example.com \ @@ -943,22 +976,22 @@ test_expect_success 'asks about and fixes 8bit encodings' ' grep "do not declare a Content-Transfer-Encoding" stdout && grep email-using-8bit stdout && grep "Which 8bit encoding" stdout && - grep "Content\\|MIME" msgtxt1 >actual && + egrep "Content|MIME" msgtxt1 >actual && test_cmp actual content-type-decl ' -test_expect_success 'sendemail.8bitEncoding works' ' +test_expect_success $PREREQ 'sendemail.8bitEncoding works' ' clean_fake_sendmail && git config sendemail.assume8bitEncoding UTF-8 && echo bogus | git send-email --from=author@example.com --to=nobody@example.com \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit >stdout && - grep "Content\\|MIME" msgtxt1 >actual && + egrep "Content|MIME" msgtxt1 >actual && test_cmp actual content-type-decl ' -test_expect_success '--8bit-encoding overrides sendemail.8bitEncoding' ' +test_expect_success $PREREQ '--8bit-encoding overrides sendemail.8bitEncoding' ' clean_fake_sendmail && git config sendemail.assume8bitEncoding "bogus too" && echo bogus | @@ -966,10 +999,11 @@ test_expect_success '--8bit-encoding overrides sendemail.8bitEncoding' ' --smtp-server="$(pwd)/fake.sendmail" \ --8bit-encoding=UTF-8 \ email-using-8bit >stdout && - grep "Content\\|MIME" msgtxt1 >actual && + egrep "Content|MIME" msgtxt1 >actual && test_cmp actual content-type-decl ' +test_expect_success $PREREQ 'setup expect' ' cat >email-using-8bit <<EOF From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001 Message-Id: <bogus-message-id@example.com> @@ -979,12 +1013,15 @@ Subject: Dieser Betreff enthält auch einen Umlaut! Nothing to see here. EOF +' +test_expect_success $PREREQ 'setup expect' ' cat >expected <<EOF Subject: =?UTF-8?q?Dieser=20Betreff=20enth=C3=A4lt=20auch=20einen=20Umlaut!?= EOF +' -test_expect_success '--8bit-encoding also treats subject' ' +test_expect_success $PREREQ '--8bit-encoding also treats subject' ' clean_fake_sendmail && echo bogus | git send-email --from=author@example.com --to=nobody@example.com \ @@ -995,4 +1032,40 @@ test_expect_success '--8bit-encoding also treats subject' ' test_cmp expected actual ' +# Note that the patches in this test are deliberately out of order; we +# want to make sure it works even if the cover-letter is not in the +# first mail. +test_expect_success 'refusing to send cover letter template' ' + clean_fake_sendmail && + rm -fr outdir && + git format-patch --cover-letter -2 -o outdir && + test_must_fail git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + outdir/0002-*.patch \ + outdir/0000-*.patch \ + outdir/0001-*.patch \ + 2>errors >out && + grep "SUBJECT HERE" errors && + test -z "$(ls msgtxt*)" +' + +test_expect_success '--force sends cover letter template anyway' ' + clean_fake_sendmail && + rm -fr outdir && + git format-patch --cover-letter -2 -o outdir && + git send-email \ + --force \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + outdir/0002-*.patch \ + outdir/0000-*.patch \ + outdir/0001-*.patch \ + 2>errors >out && + ! grep "SUBJECT HERE" errors && + test -n "$(ls msgtxt*)" +' + test_done diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh new file mode 100755 index 000000000..a713dfc50 --- /dev/null +++ b/t/t9010-svn-fe.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +test_description='check svn dumpfile importer' + +. ./lib-git-svn.sh + +test_dump() { + label=$1 + dump=$2 + test_expect_success "$dump" ' + svnadmin create "$label-svn" && + svnadmin load "$label-svn" < "$TEST_DIRECTORY/$dump" && + svn_cmd export "file://$PWD/$label-svn" "$label-svnco" && + git init "$label-git" && + test-svn-fe "$TEST_DIRECTORY/$dump" >"$label.fe" && + ( + cd "$label-git" && + git fast-import < ../"$label.fe" + ) && + ( + cd "$label-svnco" && + git init && + git add . && + git fetch "../$label-git" master && + git diff --exit-code FETCH_HEAD + ) + ' +} + +test_dump simple t9135/svn.dump + +test_done diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 570e0359e..b041516a1 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -15,24 +15,25 @@ case "$GIT_SVN_LC_ALL" in test_set_prereq UTF8 ;; *) - say "UTF-8 locale not set, some tests skipped ($GIT_SVN_LC_ALL)" + say "# UTF-8 locale not set, some tests skipped ($GIT_SVN_LC_ALL)" ;; esac test_expect_success \ 'initialize git svn' ' mkdir import && - cd import && - echo foo > foo && - ln -s foo foo.link - mkdir -p dir/a/b/c/d/e && - echo "deep dir" > dir/a/b/c/d/e/file && - mkdir bar && - echo "zzz" > bar/zzz && - echo "#!/bin/sh" > exec.sh && - chmod +x exec.sh && - svn_cmd import -m "import for git svn" . "$svnrepo" >/dev/null && - cd .. && + ( + cd import && + echo foo >foo && + ln -s foo foo.link + mkdir -p dir/a/b/c/d/e && + echo "deep dir" >dir/a/b/c/d/e/file && + mkdir bar && + echo "zzz" >bar/zzz && + echo "#!/bin/sh" >exec.sh && + chmod +x exec.sh && + svn_cmd import -m "import for git svn" . "$svnrepo" >/dev/null + ) && rm -rf import && git svn init "$svnrepo"' @@ -142,7 +143,7 @@ test_expect_success "$name" ' git svn set-tree --find-copies-harder --rmdir \ ${remotes_git_svn}..mybranch5 && svn_cmd up "$SVN_TREE" && - test -L "$SVN_TREE"/exec.sh' + test -h "$SVN_TREE"/exec.sh' name='new symlink is added to a file that was also just made executable' @@ -155,7 +156,7 @@ test_expect_success "$name" ' ${remotes_git_svn}..mybranch5 && svn_cmd up "$SVN_TREE" && test -x "$SVN_TREE"/bar/zzz && - test -L "$SVN_TREE"/exec-2.sh' + test -h "$SVN_TREE"/exec-2.sh' name='modify a symlink to become a file' test_expect_success "$name" ' @@ -168,7 +169,7 @@ test_expect_success "$name" ' ${remotes_git_svn}..mybranch5 && svn_cmd up "$SVN_TREE" && test -f "$SVN_TREE"/exec-2.sh && - test ! -L "$SVN_TREE"/exec-2.sh && + test ! -h "$SVN_TREE"/exec-2.sh && test_cmp help "$SVN_TREE"/exec-2.sh' name="commit with UTF-8 message: locale: $GIT_SVN_LC_ALL" @@ -271,6 +272,17 @@ test_expect_success 'able to dcommit to a subdirectory' " test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" " +test_expect_success 'dcommit should not fail with a touched file' ' + test_commit "commit-new-file-foo2" foo2 && + test-chmtime =-60 foo && + git svn dcommit +' + +test_expect_success 'rebase should not fail with a touched file' ' + test-chmtime =-60 foo && + git svn rebase +' + test_expect_success 'able to set-tree to a subdirectory' " echo cba > d && git update-index d && diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index 929499e99..8869f5018 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -53,8 +53,9 @@ cd .. rm -rf import test_expect_success 'checkout working copy from svn' 'svn co "$svnrepo" test_wc' -test_expect_success 'setup some commits to svn' \ - 'cd test_wc && +test_expect_success 'setup some commits to svn' ' + ( + cd test_wc && echo Greetings >> kw.c && poke kw.c && svn_cmd commit -m "Not yet an Id" && @@ -63,8 +64,9 @@ test_expect_success 'setup some commits to svn' \ svn_cmd commit -m "Modified file, but still not yet an Id" && svn_cmd propset svn:keywords Id kw.c && poke kw.c && - svn_cmd commit -m "Propset Id" && - cd ..' + svn_cmd commit -m "Propset Id" + ) +' test_expect_success 'initialize git svn' 'git svn init "$svnrepo"' test_expect_success 'fetch revisions from svn' 'git svn fetch' @@ -81,13 +83,15 @@ expect='/* $Id$ */' got="`sed -ne 2p kw.c`" test_expect_success 'raw $Id$ found in kw.c' "test '$expect' = '$got'" -test_expect_success "propset CR on crlf files" \ - 'cd test_wc && +test_expect_success "propset CR on crlf files" ' + ( + cd test_wc && svn_cmd propset svn:eol-style CR empty && svn_cmd propset svn:eol-style CR crlf && svn_cmd propset svn:eol-style CR ne_crlf && - svn_cmd commit -m "propset CR on crlf files" && - cd ..' + svn_cmd commit -m "propset CR on crlf files" + ) +' test_expect_success 'fetch and pull latest from svn and checkout a new wc' \ 'git svn fetch && @@ -137,19 +141,20 @@ cat > show-ignore.expect <<\EOF EOF test_expect_success 'test show-ignore' " - cd test_wc && - mkdir -p deeply/nested/directory && - touch deeply/nested/directory/.keep && - svn_cmd add deeply && - svn_cmd up && - svn_cmd propset -R svn:ignore ' + ( + cd test_wc && + mkdir -p deeply/nested/directory && + touch deeply/nested/directory/.keep && + svn_cmd add deeply && + svn_cmd up && + svn_cmd propset -R svn:ignore ' no-such-file* ' . - svn_cmd commit -m 'propset svn:ignore' - cd .. && + svn_cmd commit -m 'propset svn:ignore' + ) && git svn show-ignore > show-ignore.got && cmp show-ignore.expect show-ignore.got - " +" cat >create-ignore.expect <<\EOF /no-such-file* diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh index 028fb19e0..eb70f4839 100755 --- a/t/t9102-git-svn-deep-rmdir.sh +++ b/t/t9102-git-svn-deep-rmdir.sh @@ -4,13 +4,14 @@ test_description='git svn rmdir' test_expect_success 'initialize repo' ' mkdir import && - cd import && - mkdir -p deeply/nested/directory/number/1 && - mkdir -p deeply/nested/directory/number/2 && - echo foo > deeply/nested/directory/number/1/file && - echo foo > deeply/nested/directory/number/2/another && - svn_cmd import -m "import for git svn" . "$svnrepo" && - cd .. + ( + cd import && + mkdir -p deeply/nested/directory/number/1 && + mkdir -p deeply/nested/directory/number/2 && + echo foo >deeply/nested/directory/number/1/file && + echo foo >deeply/nested/directory/number/2/another && + svn_cmd import -m "import for git svn" . "$svnrepo" + ) ' test_expect_success 'mirror via git svn' ' diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index bbfd7f479..f7f3c5ab8 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -8,22 +8,24 @@ test_description='git svn fetching' test_expect_success 'initialize repo' ' mkdir import && - cd import && - mkdir -p trunk && - echo hello > trunk/readme && - svn_cmd import -m "initial" . "$svnrepo" && - cd .. && + ( + cd import && + mkdir -p trunk && + echo hello >trunk/readme && + svn_cmd import -m "initial" . "$svnrepo" + ) && svn_cmd co "$svnrepo" wc && - cd wc && - echo world >> trunk/readme && - poke trunk/readme && - svn_cmd commit -m "another commit" && - svn_cmd up && - svn_cmd mv trunk thunk && - echo goodbye >> thunk/readme && - poke thunk/readme && - svn_cmd commit -m "bye now" && - cd .. + ( + cd wc && + echo world >>trunk/readme && + poke trunk/readme && + svn_cmd commit -m "another commit" && + svn_cmd up && + svn_cmd mv trunk thunk && + echo goodbye >>thunk/readme && + poke thunk/readme && + svn_cmd commit -m "bye now" + ) ' test_expect_success 'init and fetch a moved directory' ' @@ -83,16 +85,17 @@ test_expect_success 'follow larger parent' ' ' test_expect_success 'follow higher-level parent' ' - svn mkdir -m "follow higher-level parent" "$svnrepo"/blob && - svn co "$svnrepo"/blob blob && - cd blob && - echo hi > hi && - svn add hi && - svn commit -m "hihi" && - cd .. - svn mkdir -m "new glob at top level" "$svnrepo"/glob && - svn mv -m "move blob down a level" "$svnrepo"/blob "$svnrepo"/glob/blob && - git svn init --minimize-url -i blob "$svnrepo"/glob/blob && + svn mkdir -m "follow higher-level parent" "$svnrepo"/blob && + svn co "$svnrepo"/blob blob && + ( + cd blob && + echo hi > hi && + svn add hi && + svn commit -m "hihi" + ) && + svn mkdir -m "new glob at top level" "$svnrepo"/glob && + svn mv -m "move blob down a level" "$svnrepo"/blob "$svnrepo"/glob/blob && + git svn init --minimize-url -i blob "$svnrepo"/glob/blob && git svn fetch -i blob ' @@ -117,18 +120,23 @@ test_expect_success 'follow-parent avoids deleting relevant info' ' import/trunk/subversion/bindings/swig/perl/t/larger-parent && echo "bad delete test 2" > \ import/trunk/subversion/bindings/swig/perl/another-larger && - cd import && - svn import -m "r9270 test" . "$svnrepo"/r9270 && - cd .. && + ( + cd import && + svn import -m "r9270 test" . "$svnrepo"/r9270 + ) && svn_cmd co "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl r9270 && - cd r9270 && - svn mkdir native && - svn mv t native/t && - for i in a b c; do svn mv $i.pm native/$i.pm; done && - echo z >> native/t/c.t && - poke native/t/c.t && - svn commit -m "reorg test" && - cd .. && + ( + cd r9270 && + svn mkdir native && + svn mv t native/t && + for i in a b c + do + svn mv $i.pm native/$i.pm + done && + echo z >>native/t/c.t && + poke native/t/c.t && + svn commit -m "reorg test" + ) && git svn init --minimize-url -i r9270-t \ "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl/native/t && git svn fetch -i r9270-t && diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh index dd48e9cba..5d0afeae6 100755 --- a/t/t9105-git-svn-commit-diff.sh +++ b/t/t9105-git-svn-commit-diff.sh @@ -6,10 +6,11 @@ test_description='git svn commit-diff' test_expect_success 'initialize repo' ' mkdir import && - cd import && - echo hello > readme && - svn_cmd import -m "initial" . "$svnrepo" && - cd .. && + ( + cd import && + echo hello >readme && + svn_cmd import -m "initial" . "$svnrepo" + ) && echo hello > readme && git update-index --add readme && git commit -a -m "initial" && diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh index 12f21b700..f6d7ac7c5 100755 --- a/t/t9106-git-svn-commit-diff-clobber.sh +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -6,21 +6,23 @@ test_description='git svn commit-diff clobber' test_expect_success 'initialize repo' ' mkdir import && - cd import && - echo initial > file && - svn_cmd import -m "initial" . "$svnrepo" && - cd .. && + ( + cd import && + echo initial >file && + svn_cmd import -m "initial" . "$svnrepo" + ) && echo initial > file && git update-index --add file && git commit -a -m "initial" ' test_expect_success 'commit change from svn side' ' svn_cmd co "$svnrepo" t.svn && - cd t.svn && - echo second line from svn >> file && - poke file && - svn_cmd commit -m "second line from svn" && - cd .. && + ( + cd t.svn && + echo second line from svn >>file && + poke file && + svn_cmd commit -m "second line from svn" + ) && rm -rf t.svn ' @@ -44,11 +46,12 @@ test_expect_success 'dcommit fails to commit because of conflict' ' git svn fetch && git reset --hard refs/${remotes_git_svn} && svn_cmd co "$svnrepo" t.svn && - cd t.svn && - echo fourth line from svn >> file && - poke file && - svn_cmd commit -m "fourth line from svn" && - cd .. && + ( + cd t.svn && + echo fourth line from svn >>file && + poke file && + svn_cmd commit -m "fourth line from svn" + ) && rm -rf t.svn && echo "fourth line from git" >> file && git commit -a -m "fourth line from git" && @@ -68,11 +71,12 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' " test_expect_success 'commit another change from svn side' ' svn_cmd co "$svnrepo" t.svn && - cd t.svn && - echo third line from svn >> file && + ( + cd t.svn && + echo third line from svn >>file && poke file && - svn_cmd commit -m "third line from svn" && - cd .. && + svn_cmd commit -m "third line from svn" + ) && rm -rf t.svn ' diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh index 901b8e09f..289fc313f 100755 --- a/t/t9107-git-svn-migrate.sh +++ b/t/t9107-git-svn-migrate.sh @@ -6,14 +6,16 @@ test_description='git svn metadata migrations from previous versions' test_expect_success 'setup old-looking metadata' ' cp "$GIT_DIR"/config "$GIT_DIR"/config-old-git-svn && mkdir import && - cd import && - for i in trunk branches/a branches/b \ - tags/0.1 tags/0.2 tags/0.3; do - mkdir -p $i && \ - echo hello >> $i/README || exit 1 - done && \ + ( + cd import && + for i in trunk branches/a branches/b tags/0.1 tags/0.2 tags/0.3 + do + mkdir -p $i && + echo hello >>$i/README || + exit 1 + done && svn_cmd import -m test . "$svnrepo" - cd .. && + ) && git svn init "$svnrepo" && git svn fetch && rm -rf "$GIT_DIR"/svn && diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh index 84f7c9b4b..307785101 100755 --- a/t/t9114-git-svn-dcommit-merge.sh +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -37,11 +37,12 @@ EOF test_expect_success 'setup svn repository' ' svn_cmd co "$svnrepo" mysvnwork && mkdir -p mysvnwork/trunk && - cd mysvnwork && - big_text_block >> trunk/README && + ( + cd mysvnwork && + big_text_block >>trunk/README && svn_cmd add trunk && - svn_cmd ci -m "first commit" trunk && - cd .. + svn_cmd ci -m "first commit" trunk + ) ' test_expect_success 'setup git mirror and merge' ' diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh index 767799e7a..6a48e4042 100755 --- a/t/t9115-git-svn-dcommit-funky-renames.sh +++ b/t/t9115-git-svn-dcommit-funky-renames.sh @@ -61,11 +61,12 @@ test_expect_success 'add a file with plus signs' ' test_expect_success 'clone the repository to test rebase' ' git svn clone "$svnrepo" test-rebase && - cd test-rebase && - echo test-rebase > test-rebase && + ( + cd test-rebase && + echo test-rebase >test-rebase && git add test-rebase && - git commit -m test-rebase && - cd .. + git commit -m test-rebase + ) ' test_expect_success 'make a commit to test rebase' ' diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh index 0374a7476..5d477e4bd 100755 --- a/t/t9116-git-svn-log.sh +++ b/t/t9116-git-svn-log.sh @@ -8,14 +8,16 @@ test_description='git svn log tests' test_expect_success 'setup repository and import' ' mkdir import && - cd import && - for i in trunk branches/a branches/b \ - tags/0.1 tags/0.2 tags/0.3; do - mkdir -p $i && \ - echo hello >> $i/README || exit 1 - done && \ + ( + cd import && + for i in trunk branches/a branches/b tags/0.1 tags/0.2 tags/0.3 + do + mkdir -p $i && + echo hello >>$i/README || + exit 1 + done && svn_cmd import -m test . "$svnrepo" - cd .. && + ) && git svn init "$svnrepo" -T trunk -b branches -t tags && git svn fetch && git reset --hard trunk && diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh index 7d7acc30b..63fc982c8 100755 --- a/t/t9118-git-svn-funky-branch-names.sh +++ b/t/t9118-git-svn-funky-branch-names.sh @@ -28,48 +28,52 @@ test_expect_success 'setup svnrepo' ' svn_cmd cp -m "trailing .lock" "$svnrepo/pr ject/trunk" \ "$svnrepo/pr ject/branches/trailing_dotlock.lock" && svn_cmd cp -m "reflog" "$svnrepo/pr ject/trunk" \ - "$svnrepo/pr ject/branches/not-a@{0}reflog" && + "$svnrepo/pr ject/branches/not-a%40{0}reflog" && start_httpd ' test_expect_success 'test clone with funky branch names' ' git svn clone -s "$svnrepo/pr ject" project && - cd project && + ( + cd project && git rev-parse "refs/remotes/fun%20plugin" && git rev-parse "refs/remotes/more%20fun%20plugin!" && git rev-parse "refs/remotes/$scary_ref" && git rev-parse "refs/remotes/%2Eleading_dot" && git rev-parse "refs/remotes/trailing_dot%2E" && git rev-parse "refs/remotes/trailing_dotlock%2Elock" && - git rev-parse "refs/remotes/not-a%40{0}reflog" && - cd .. + git rev-parse "refs/remotes/not-a%40{0}reflog" + ) ' test_expect_success 'test dcommit to funky branch' " - cd project && - git reset --hard 'refs/remotes/more%20fun%20plugin!' && - echo hello >> foo && - git commit -m 'hello' -- foo && - git svn dcommit && - cd .. + ( + cd project && + git reset --hard 'refs/remotes/more%20fun%20plugin!' && + echo hello >> foo && + git commit -m 'hello' -- foo && + git svn dcommit + ) " test_expect_success 'test dcommit to scary branch' ' - cd project && - git reset --hard "refs/remotes/$scary_ref" && - echo urls are scary >> foo && - git commit -m "eep" -- foo && - git svn dcommit && - cd .. + ( + cd project && + git reset --hard "refs/remotes/$scary_ref" && + echo urls are scary >> foo && + git commit -m "eep" -- foo && + git svn dcommit + ) ' test_expect_success 'test dcommit to trailing_dotlock branch' ' - cd project && - git reset --hard "refs/remotes/trailing_dotlock%2Elock" && - echo who names branches like this anyway? >> foo && - git commit -m "bar" -- foo && - git svn dcommit && - cd .. + ( + cd project && + git reset --hard "refs/remotes/trailing_dotlock%2Elock" && + echo who names branches like this anyway? >> foo && + git commit -m "bar" -- foo && + git svn dcommit + ) ' stop_httpd diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh index a9a558d29..f3f397cdd 100755 --- a/t/t9119-git-svn-info.sh +++ b/t/t9119-git-svn-info.sh @@ -13,7 +13,7 @@ case $v in 1.[456].*) ;; *) - say "skipping svn-info test (SVN version: $v not supported)" + skip_all="skipping svn-info test (SVN version: $v not supported)" test_done ;; esac @@ -39,27 +39,30 @@ quoted_svnrepo="$(echo $svnrepo | sed 's/ /%20/')" test_expect_success 'setup repository and import' ' mkdir info && - cd info && - echo FIRST > A && - echo one > file && + ( + cd info && + echo FIRST >A && + echo one >file && ln -s file symlink-file && mkdir directory && touch directory/.placeholder && ln -s directory symlink-directory && - svn_cmd import -m "initial" . "$svnrepo" && - cd .. && + svn_cmd import -m "initial" . "$svnrepo" + ) && svn_cmd co "$svnrepo" svnwc && - cd svnwc && - echo foo > foo && + ( + cd svnwc && + echo foo >foo && svn_cmd add foo && svn_cmd commit -m "change outside directory" && - svn_cmd update && - cd .. && + svn_cmd update + ) && mkdir gitwc && - cd gitwc && + ( + cd gitwc && git svn init "$svnrepo" && - git svn fetch && - cd .. && + git svn fetch + ) && ptouch gitwc/file svnwc/file && ptouch gitwc/directory svnwc/directory && ptouch gitwc/symlink-file svnwc/symlink-file && @@ -138,14 +141,16 @@ test_expect_success 'info --url symlink-directory' ' test_expect_success 'info added-file' " echo two > gitwc/added-file && - cd gitwc && - git add added-file && - cd .. && + ( + cd gitwc && + git add added-file + ) && cp gitwc/added-file svnwc/added-file && ptouch gitwc/added-file svnwc/added-file && - cd svnwc && - svn_cmd add added-file > /dev/null && - cd .. && + ( + cd svnwc && + svn_cmd add added-file > /dev/null + ) && (cd svnwc; svn info added-file) > expected.info-added-file && (cd gitwc; git svn info added-file) > actual.info-added-file && test_cmp expected.info-added-file actual.info-added-file @@ -160,12 +165,14 @@ test_expect_success 'info added-directory' " mkdir gitwc/added-directory svnwc/added-directory && ptouch gitwc/added-directory svnwc/added-directory && touch gitwc/added-directory/.placeholder && - cd svnwc && - svn_cmd add added-directory > /dev/null && - cd .. && - cd gitwc && - git add added-directory && - cd .. && + ( + cd svnwc && + svn_cmd add added-directory > /dev/null + ) && + ( + cd gitwc && + git add added-directory + ) && (cd svnwc; svn info added-directory) \ > expected.info-added-directory && (cd gitwc; git svn info added-directory) \ @@ -179,14 +186,16 @@ test_expect_success 'info --url added-directory' ' ' test_expect_success 'info added-symlink-file' " - cd gitwc && + ( + cd gitwc && ln -s added-file added-symlink-file && - git add added-symlink-file && - cd .. && - cd svnwc && + git add added-symlink-file + ) && + ( + cd svnwc && ln -s added-file added-symlink-file && - svn_cmd add added-symlink-file > /dev/null && - cd .. && + svn_cmd add added-symlink-file > /dev/null + ) && ptouch gitwc/added-symlink-file svnwc/added-symlink-file && (cd svnwc; svn info added-symlink-file) \ > expected.info-added-symlink-file && @@ -202,14 +211,16 @@ test_expect_success 'info --url added-symlink-file' ' ' test_expect_success 'info added-symlink-directory' " - cd gitwc && + ( + cd gitwc && ln -s added-directory added-symlink-directory && - git add added-symlink-directory && - cd .. && - cd svnwc && + git add added-symlink-directory + ) && + ( + cd svnwc && ln -s added-directory added-symlink-directory && - svn_cmd add added-symlink-directory > /dev/null && - cd .. && + svn_cmd add added-symlink-directory > /dev/null + ) && ptouch gitwc/added-symlink-directory svnwc/added-symlink-directory && (cd svnwc; svn info added-symlink-directory) \ > expected.info-added-symlink-directory && @@ -230,12 +241,14 @@ test_expect_success 'info --url added-symlink-directory' ' # simply reuses the Last Changed Date. test_expect_success 'info deleted-file' " - cd gitwc && - git rm -f file > /dev/null && - cd .. && - cd svnwc && - svn_cmd rm --force file > /dev/null && - cd .. && + ( + cd gitwc && + git rm -f file > /dev/null + ) && + ( + cd svnwc && + svn_cmd rm --force file > /dev/null + ) && (cd svnwc; svn info file) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-file && @@ -251,12 +264,14 @@ test_expect_success 'info --url file (deleted)' ' ' test_expect_success 'info deleted-directory' " - cd gitwc && - git rm -r -f directory > /dev/null && - cd .. && - cd svnwc && - svn_cmd rm --force directory > /dev/null && - cd .. && + ( + cd gitwc && + git rm -r -f directory > /dev/null + ) && + ( + cd svnwc && + svn_cmd rm --force directory > /dev/null + ) && (cd svnwc; svn info directory) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-directory && @@ -272,12 +287,14 @@ test_expect_success 'info --url directory (deleted)' ' ' test_expect_success 'info deleted-symlink-file' " - cd gitwc && - git rm -f symlink-file > /dev/null && - cd .. && - cd svnwc && - svn_cmd rm --force symlink-file > /dev/null && - cd .. && + ( + cd gitwc && + git rm -f symlink-file > /dev/null + ) && + ( + cd svnwc && + svn_cmd rm --force symlink-file > /dev/null + ) && (cd svnwc; svn info symlink-file) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-symlink-file && @@ -294,12 +311,14 @@ test_expect_success 'info --url symlink-file (deleted)' ' ' test_expect_success 'info deleted-symlink-directory' " - cd gitwc && - git rm -f symlink-directory > /dev/null && - cd .. && - cd svnwc && - svn_cmd rm --force symlink-directory > /dev/null && - cd .. && + ( + cd gitwc && + git rm -f symlink-directory > /dev/null + ) && + ( + cd svnwc && + svn_cmd rm --force symlink-directory > /dev/null + ) && (cd svnwc; svn info symlink-directory) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-symlink-directory && @@ -346,9 +365,10 @@ test_expect_success 'info --url unknown-directory' ' ' test_expect_success 'info unknown-symlink-file' " - cd gitwc && - ln -s unknown-file unknown-symlink-file && - cd .. && + ( + cd gitwc && + ln -s unknown-file unknown-symlink-file + ) && (cd gitwc; test_must_fail git svn info unknown-symlink-file) \ 2> actual.info-unknown-symlink-file && grep unknown-symlink-file actual.info-unknown-symlink-file @@ -361,9 +381,10 @@ test_expect_success 'info --url unknown-symlink-file' ' ' test_expect_success 'info unknown-symlink-directory' " - cd gitwc && - ln -s unknown-directory unknown-symlink-directory && - cd .. && + ( + cd gitwc && + ln -s unknown-directory unknown-symlink-directory + ) && (cd gitwc; test_must_fail git svn info unknown-symlink-directory) \ 2> actual.info-unknown-symlink-directory && grep unknown-symlink-directory actual.info-unknown-symlink-directory diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh index 9d9ebd533..1d92c0503 100755 --- a/t/t9120-git-svn-clone-with-percent-escapes.sh +++ b/t/t9120-git-svn-clone-with-percent-escapes.sh @@ -20,9 +20,10 @@ test_expect_success 'setup svnrepo' ' test_expect_success 'test clone with percent escapes' ' git svn clone "$svnrepo/pr%20ject" clone && - cd clone && - git rev-parse refs/${remotes_git_svn} && - cd .. + ( + cd clone && + git rev-parse refs/${remotes_git_svn} + ) ' # SVN works either way, so should we... diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh index 045521615..0ed90d982 100755 --- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -8,10 +8,10 @@ test_description='git svn respects rewriteRoot during rebuild' . ./lib-git-svn.sh mkdir import -cd import +(cd import touch foo svn_cmd import -m 'import for git svn' . "$svnrepo" >/dev/null -cd .. +) rm -rf import test_expect_success 'init, fetch and checkout repository' ' diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh index c19418614..096abd1fe 100755 --- a/t/t9125-git-svn-multi-glob-branch-names.sh +++ b/t/t9125-git-svn-multi-glob-branch-names.sh @@ -19,19 +19,19 @@ test_expect_success 'setup svnrepo' ' test_expect_success 'test clone with multi-glob in branch names' ' git svn clone -T trunk -b branches/*/* -t tags \ "$svnrepo/project" project && - cd project && + (cd project && git rev-parse "refs/remotes/v14.1/beta" && - git rev-parse "refs/remotes/v14.1/gold" && - cd .. + git rev-parse "refs/remotes/v14.1/gold" + ) ' test_expect_success 'test dcommit to multi-globbed branch' " - cd project && + (cd project && git reset --hard 'refs/remotes/v14.1/gold' && echo hello >> foo && git commit -m 'hello' -- foo && - git svn dcommit && - cd .. + git svn dcommit + ) " test_done diff --git a/t/t9127-git-svn-partial-rebuild.sh b/t/t9127-git-svn-partial-rebuild.sh index 4aab8ecc1..2e4789d06 100755 --- a/t/t9127-git-svn-partial-rebuild.sh +++ b/t/t9127-git-svn-partial-rebuild.sh @@ -9,27 +9,27 @@ test_description='git svn partial-rebuild tests' test_expect_success 'initialize svnrepo' ' mkdir import && ( - cd import && + (cd import && mkdir trunk branches tags && - cd trunk && - echo foo > foo && - cd .. && + (cd trunk && + echo foo > foo + ) && svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null && svn_cmd copy "$svnrepo"/trunk "$svnrepo"/branches/a \ - -m "created branch a" && - cd .. && + -m "created branch a" + ) && rm -rf import && svn_cmd co "$svnrepo"/trunk trunk && - cd trunk && + (cd trunk && echo bar >> foo && - svn_cmd ci -m "updated trunk" && - cd .. && + svn_cmd ci -m "updated trunk" + ) && svn_cmd co "$svnrepo"/branches/a a && - cd a && + (cd a && echo baz >> a && svn_cmd add a && - svn_cmd ci -m "updated a" && - cd .. && + svn_cmd ci -m "updated a" + ) && git svn init --stdlayout "$svnrepo" ) ' @@ -41,11 +41,11 @@ test_expect_success 'import an early SVN revision into git' ' test_expect_success 'make full git mirror of SVN' ' mkdir mirror && ( - cd mirror && + (cd mirror && git init && git svn init --stdlayout "$svnrepo" && - git svn fetch && - cd .. + git svn fetch + ) ) ' diff --git a/t/t9128-git-svn-cmd-branch.sh b/t/t9128-git-svn-cmd-branch.sh index 807e494a3..4b034a67f 100755 --- a/t/t9128-git-svn-cmd-branch.sh +++ b/t/t9128-git-svn-cmd-branch.sh @@ -9,19 +9,19 @@ test_description='git svn partial-rebuild tests' test_expect_success 'initialize svnrepo' ' mkdir import && ( - cd import && + (cd import && mkdir trunk branches tags && - cd trunk && - echo foo > foo && - cd .. && - svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null && - cd .. && + (cd trunk && + echo foo > foo + ) && + svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null + ) && rm -rf import && svn_cmd co "$svnrepo"/trunk trunk && - cd trunk && + (cd trunk && echo bar >> foo && - svn_cmd ci -m "updated trunk" && - cd .. && + svn_cmd ci -m "updated trunk" + ) && rm -rf trunk ) ' diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 1e9a2eb12..8cfdfe790 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -23,7 +23,7 @@ if test -n "$a_utf8_locale" then test_set_prereq UTF8 else - say "UTF-8 locale not available, some tests are skipped" + say "# UTF-8 locale not available, some tests are skipped" fi compare_svn_head_with () { diff --git a/t/t9130-git-svn-authors-file.sh b/t/t9130-git-svn-authors-file.sh index 134411e0a..ec0a10661 100755 --- a/t/t9130-git-svn-authors-file.sh +++ b/t/t9130-git-svn-authors-file.sh @@ -20,7 +20,7 @@ test_expect_success 'setup svnrepo' ' ' test_expect_success 'start import with incomplete authors file' ' - ! git svn clone --authors-file=svn-authors "$svnrepo" x + test_must_fail git svn clone --authors-file=svn-authors "$svnrepo" x ' test_expect_success 'imported 2 revisions successfully' ' @@ -63,7 +63,7 @@ test_expect_success 'authors-file against globs' ' ' test_expect_success 'fetch fails on ee' ' - ( cd aa-work && ! git svn fetch --authors-file=../svn-authors ) + ( cd aa-work && test_must_fail git svn fetch --authors-file=../svn-authors ) ' tmp_config_get () { @@ -95,8 +95,6 @@ test_expect_success 'fresh clone with svn.authors-file in config' ' ( rm -r "$GIT_DIR" && test x = x"$(git config svn.authorsfile)" && - HOME="`pwd`" && - export HOME && test_config="$HOME"/.gitconfig && unset GIT_CONFIG_NOGLOBAL && unset GIT_DIR && diff --git a/t/t9131-git-svn-empty-symlink.sh b/t/t9131-git-svn-empty-symlink.sh index 9a24a65b6..f762038f0 100755 --- a/t/t9131-git-svn-empty-symlink.sh +++ b/t/t9131-git-svn-empty-symlink.sh @@ -88,7 +88,7 @@ test_expect_success 'enable broken symlink workaround' \ test_expect_success '"bar" is an empty file' 'test -f x/bar && ! test -s x/bar' test_expect_success 'get "bar" => symlink fix from svn' \ '(cd x && git svn rebase)' -test_expect_success SYMLINKS '"bar" becomes a symlink' 'test -L x/bar' +test_expect_success SYMLINKS '"bar" becomes a symlink' 'test -h x/bar' test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" y' diff --git a/t/t9137-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh index 636ca0abb..d60da63f7 100755 --- a/t/t9137-git-svn-dcommit-clobber-series.sh +++ b/t/t9137-git-svn-dcommit-clobber-series.sh @@ -6,10 +6,10 @@ test_description='git svn dcommit clobber series' test_expect_success 'initialize repo' ' mkdir import && - cd import && + (cd import && awk "BEGIN { for (i = 1; i < 64; i++) { print i } }" > file - svn_cmd import -m "initial" . "$svnrepo" && - cd .. && + svn_cmd import -m "initial" . "$svnrepo" + ) && git svn init "$svnrepo" && git svn fetch && test -e file @@ -19,14 +19,14 @@ test_expect_success '(supposedly) non-conflicting change from SVN' ' test x"`sed -n -e 58p < file`" = x58 && test x"`sed -n -e 61p < file`" = x61 && svn_cmd co "$svnrepo" tmp && - cd tmp && + (cd tmp && perl -i.bak -p -e "s/^58$/5588/" file && perl -i.bak -p -e "s/^61$/6611/" file && poke file && test x"`sed -n -e 58p < file`" = x5588 && test x"`sed -n -e 61p < file`" = x6611 && - svn_cmd commit -m "58 => 5588, 61 => 6611" && - cd .. + svn_cmd commit -m "58 => 5588, 61 => 6611" + ) ' test_expect_success 'some unrelated changes to git' " diff --git a/t/t9139-git-svn-non-utf8-commitencoding.sh b/t/t9139-git-svn-non-utf8-commitencoding.sh index f337959cc..22d80b0be 100755 --- a/t/t9139-git-svn-non-utf8-commitencoding.sh +++ b/t/t9139-git-svn-non-utf8-commitencoding.sh @@ -39,7 +39,7 @@ do ( cd $H && git config --unset i18n.commitencoding && - ! git svn dcommit + test_must_fail git svn dcommit ) ' done diff --git a/t/t9140-git-svn-reset.sh b/t/t9140-git-svn-reset.sh index 0735526d4..e85590462 100755 --- a/t/t9140-git-svn-reset.sh +++ b/t/t9140-git-svn-reset.sh @@ -41,7 +41,7 @@ test_expect_success 'modify hidden file in SVN repo' ' test_expect_success 'fetch fails on modified hidden file' ' ( cd g && git svn find-rev refs/remotes/git-svn > ../expect && - ! git svn fetch 2> ../errors && + test_must_fail git svn fetch 2> ../errors && git svn find-rev refs/remotes/git-svn > ../expect2 ) && fgrep "not found in commit" errors && test_cmp expect expect2 diff --git a/t/t9143-git-svn-gc.sh b/t/t9143-git-svn-gc.sh index 99f69c6a0..337ea5971 100755 --- a/t/t9143-git-svn-gc.sh +++ b/t/t9143-git-svn-gc.sh @@ -43,7 +43,7 @@ then gunzip .git/svn/refs/remotes/git-svn/unhandled.log.gz ' else - say "Perl Compress::Zlib unavailable, skipping gunzip test" + say "# Perl Compress::Zlib unavailable, skipping gunzip test" fi test_expect_success 'git svn gc does not change unhandled.log files' ' diff --git a/t/t9155-git-svn-fetch-deleted-tag.sh b/t/t9155-git-svn-fetch-deleted-tag.sh new file mode 100755 index 000000000..a486a98f8 --- /dev/null +++ b/t/t9155-git-svn-fetch-deleted-tag.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +test_description='git svn fetch deleted tag' + +. ./lib-git-svn.sh + +test_expect_success 'setup svn repo' ' + mkdir -p import/trunk/subdir && + mkdir -p import/branches && + mkdir -p import/tags && + echo "base" >import/trunk/subdir/file && + svn_cmd import -m "import for git svn" import "$svnrepo" && + rm -rf import && + + svn_cmd mkdir -m "create mybranch directory" "$svnrepo/branches/mybranch" && + svn_cmd cp -m "create branch mybranch" "$svnrepo/trunk" "$svnrepo/branches/mybranch/trunk" && + + svn_cmd co "$svnrepo/trunk" svn_project && + (cd svn_project && + echo "trunk change" >>subdir/file && + svn_cmd ci -m "trunk change" subdir/file && + + svn_cmd switch "$svnrepo/branches/mybranch/trunk" && + echo "branch change" >>subdir/file && + svn_cmd ci -m "branch change" subdir/file + ) && + + svn_cmd cp -m "create mytag attempt 1" -r5 "$svnrepo/trunk/subdir" "$svnrepo/tags/mytag" && + svn_cmd rm -m "delete mytag attempt 1" "$svnrepo/tags/mytag" && + svn_cmd cp -m "create mytag attempt 2" -r5 "$svnrepo/branches/mybranch/trunk/subdir" "$svnrepo/tags/mytag" +' + +test_expect_success 'fetch deleted tags from same revision with checksum error' ' + git svn init --stdlayout "$svnrepo" git_project && + cd git_project && + git svn fetch && + + git diff --exit-code mybranch:trunk/subdir/file tags/mytag:file && + git diff --exit-code master:subdir/file tags/mytag^:file +' + +test_done diff --git a/t/t9156-git-svn-fetch-deleted-tag-2.sh b/t/t9156-git-svn-fetch-deleted-tag-2.sh new file mode 100755 index 000000000..5ce7e2f3b --- /dev/null +++ b/t/t9156-git-svn-fetch-deleted-tag-2.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +test_description='git svn fetch deleted tag 2' + +. ./lib-git-svn.sh + +test_expect_success 'setup svn repo' ' + mkdir -p import/branches && + mkdir -p import/tags && + mkdir -p import/trunk/subdir1 && + mkdir -p import/trunk/subdir2 && + mkdir -p import/trunk/subdir3 && + echo "file1" >import/trunk/subdir1/file && + echo "file2" >import/trunk/subdir2/file && + echo "file3" >import/trunk/subdir3/file && + svn_cmd import -m "import for git svn" import "$svnrepo" && + rm -rf import && + + svn_cmd co "$svnrepo/trunk" svn_project && + (cd svn_project && + echo "change1" >>subdir1/file && + echo "change2" >>subdir2/file && + echo "change3" >>subdir3/file && + svn_cmd ci -m "change" . + ) && + + svn_cmd cp -m "create mytag 1" -r2 "$svnrepo/trunk/subdir1" "$svnrepo/tags/mytag" && + svn_cmd rm -m "delete mytag 1" "$svnrepo/tags/mytag" && + svn_cmd cp -m "create mytag 2" -r2 "$svnrepo/trunk/subdir2" "$svnrepo/tags/mytag" && + svn_cmd rm -m "delete mytag 2" "$svnrepo/tags/mytag" && + svn_cmd cp -m "create mytag 3" -r2 "$svnrepo/trunk/subdir3" "$svnrepo/tags/mytag" +' + +test_expect_success 'fetch deleted tags from same revision with no checksum error' ' + git svn init --stdlayout "$svnrepo" git_project && + cd git_project && + git svn fetch && + + git diff --exit-code master:subdir3/file tags/mytag:file && + git diff --exit-code master:subdir2/file tags/mytag^:file && + git diff --exit-code master:subdir1/file tags/mytag^^:file +' + +test_done diff --git a/t/t9157-git-svn-fetch-merge.sh b/t/t9157-git-svn-fetch-merge.sh new file mode 100755 index 000000000..da582c538 --- /dev/null +++ b/t/t9157-git-svn-fetch-merge.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Copyright (c) 2010 Steven Walter +# + +test_description='git svn merge detection' +. ./lib-git-svn.sh + +test_expect_success 'initialize source svn repo' ' + svn_cmd mkdir -m x "$svnrepo"/trunk && + svn_cmd mkdir -m x "$svnrepo"/branches && + svn_cmd co "$svnrepo"/trunk "$SVN_TREE" && + ( + cd "$SVN_TREE" && + touch foo && + svn add foo && + svn commit -m "initial commit" && + svn cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 && + touch bar && + svn add bar && + svn commit -m x && + svn cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch2 && + svn switch "$svnrepo"/branches/branch1 && + touch baz && + svn add baz && + svn commit -m x && + svn switch "$svnrepo"/trunk && + svn merge "$svnrepo"/branches/branch1 && + svn commit -m "merge" && + svn switch "$svnrepo"/branches/branch1 && + svn commit -m x && + svn switch "$svnrepo"/branches/branch2 && + svn merge "$svnrepo"/branches/branch1 && + svn commit -m "merge branch1" && + svn switch "$svnrepo"/trunk && + svn merge "$svnrepo"/branches/branch2 && + svn resolved baz && + svn commit -m "merge branch2" + ) && + rm -rf "$SVN_TREE" +' + +test_expect_success 'clone svn repo' ' + git svn init -s "$svnrepo" && + git svn fetch +' + +test_expect_success 'verify merge commit' 'git rev-parse HEAD^2' + +test_done diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index 61bcb8fc8..e5da65b99 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -5,16 +5,17 @@ test_description='Test export of commits to CVS' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh if ! test_have_prereq PERL; then - say 'skipping git cvsexportcommit tests, perl not available' + skip_all='skipping git cvsexportcommit tests, perl not available' test_done fi cvs >/dev/null 2>&1 if test $? -ne 1 then - say 'skipping git cvsexportcommit tests, cvs not found' + skip_all='skipping git cvsexportcommit tests, cvs not found' test_done fi @@ -229,11 +230,6 @@ test_expect_success \ test_must_fail git cvsexportcommit -c $id )' -if ! test "$(git config --bool core.filemode)" = false -then - test_set_prereq FILEMODE -fi - test_expect_success FILEMODE \ 'Retain execute bit' \ 'mkdir G && diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 131f03298..3c0cf0509 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -166,6 +166,63 @@ test_expect_success \ test `git rev-parse --verify master:file2` \ = `git rev-parse --verify verify--import-marks:copy-of-file2`' +test_tick +mt=$(git hash-object --stdin < /dev/null) +: >input.blob +: >marks.exp +: >tree.exp + +cat >input.commit <<EOF +commit refs/heads/verify--dump-marks +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +test the sparse array dumping routines with exponentially growing marks +COMMIT +EOF + +i=0 +l=4 +m=6 +n=7 +while test "$i" -lt 27; do + cat >>input.blob <<EOF +blob +mark :$l +data 0 +blob +mark :$m +data 0 +blob +mark :$n +data 0 +EOF + echo "M 100644 :$l l$i" >>input.commit + echo "M 100644 :$m m$i" >>input.commit + echo "M 100644 :$n n$i" >>input.commit + + echo ":$l $mt" >>marks.exp + echo ":$m $mt" >>marks.exp + echo ":$n $mt" >>marks.exp + + printf "100644 blob $mt\tl$i\n" >>tree.exp + printf "100644 blob $mt\tm$i\n" >>tree.exp + printf "100644 blob $mt\tn$i\n" >>tree.exp + + l=$(($l + $l)) + m=$(($m + $m)) + n=$(($l + $n)) + + i=$((1 + $i)) +done + +sort tree.exp > tree.exp_s + +test_expect_success 'A: export marks with large values' ' + cat input.blob input.commit | git fast-import --export-marks=marks.large && + git ls-tree refs/heads/verify--dump-marks >tree.out && + test_cmp tree.exp_s tree.out && + test_cmp marks.exp marks.large' + ### ### series B ### @@ -796,6 +853,81 @@ test_expect_success \ 'git fast-import <input && test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}`' +test_expect_success \ + 'N: copy directory by id' \ + 'cat >expect <<-\EOF && + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf + :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + EOF + subdir=$(git rev-parse refs/heads/branch^0:file2) && + cat >input <<-INPUT_END && + commit refs/heads/N4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + copy by tree hash + COMMIT + + from refs/heads/branch^0 + M 040000 $subdir file3 + INPUT_END + git fast-import <input && + git diff-tree -C --find-copies-harder -r N4^ N4 >actual && + compare_diff_raw expect actual' + +test_expect_success \ + 'N: copy root directory by tree hash' \ + 'cat >expect <<-\EOF && + :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file3/newf + :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file3/oldf + EOF + root=$(git rev-parse refs/heads/branch^0^{tree}) && + cat >input <<-INPUT_END && + commit refs/heads/N6 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + copy root directory by tree hash + COMMIT + + from refs/heads/branch^0 + M 040000 $root "" + INPUT_END + git fast-import <input && + git diff-tree -C --find-copies-harder -r N4 N6 >actual && + compare_diff_raw expect actual' + +test_expect_success \ + 'N: modify copied tree' \ + 'cat >expect <<-\EOF && + :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf + :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + EOF + subdir=$(git rev-parse refs/heads/branch^0:file2) && + cat >input <<-INPUT_END && + commit refs/heads/N5 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + copy by tree hash + COMMIT + + from refs/heads/branch^0 + M 040000 $subdir file3 + + commit refs/heads/N5 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + modify directory copy + COMMIT + + M 644 inline file3/file5 + data <<EOF + $file5_data + EOF + INPUT_END + git fast-import <input && + git diff-tree -C --find-copies-harder -r N5^^ N5 >actual && + compare_diff_raw expect actual' + ### ### series O ### @@ -999,11 +1131,10 @@ test_expect_success \ 'P: supermodule & submodule mix' \ 'git fast-import <input && git checkout subuse1 && - rm -rf sub && mkdir sub && cd sub && + rm -rf sub && mkdir sub && (cd sub && git init && git fetch --update-head-ok .. refs/heads/sub:refs/heads/master && - git checkout master && - cd .. && + git checkout master) && git submodule init && git submodule update' diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index d43f37cca..8c8e67946 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -355,6 +355,20 @@ test_expect_failure 'no exact-ref revisions included' ' ) ' +test_expect_success 'path limiting with import-marks does not lose unmodified files' ' + git checkout -b simple marks~2 && + git fast-export --export-marks=marks simple -- file > /dev/null && + echo more content >> file && + test_tick && + git commit -mnext file && + git fast-export --import-marks=marks simple -- file file0 | grep file0 +' + +test_expect_success 'full-tree re-shows unmodified files' ' + git checkout -f simple && + test $(git fast-export --full-tree simple | grep -c file0) -eq 3 +' + test_expect_success 'set-up a few more tags for tag export tests' ' git checkout -f master && HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` && @@ -376,4 +390,28 @@ test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj' test_expect_success 'tag-obj_tag' 'git fast-export tag-obj_tag' test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj' +test_expect_success SYMLINKS 'directory becomes symlink' ' + git init dirtosymlink && + git init result && + ( + cd dirtosymlink && + mkdir foo && + mkdir bar && + echo hello > foo/world && + echo hello > bar/world && + git add foo/world bar/world && + git commit -q -mone && + git rm -r foo && + ln -s bar foo && + git add foo && + git commit -q -mtwo + ) && + ( + cd dirtosymlink && + git fast-export master -- foo | + (cd ../result && git fast-import --quiet) + ) && + (cd result && git show master:foo) +' + test_done diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 86395065c..36c457e7f 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -11,17 +11,17 @@ cvs CLI client via git-cvsserver server' . ./test-lib.sh if ! test_have_prereq PERL; then - say 'skipping git cvsserver tests, perl not available' + skip_all='skipping git cvsserver tests, perl not available' test_done fi cvs >/dev/null 2>&1 if test $? -ne 1 then - say 'skipping git-cvsserver tests, cvs not found' + skip_all='skipping git-cvsserver tests, cvs not found' test_done fi "$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { - say 'skipping git-cvsserver tests, Perl SQLite interface unavailable' + skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable' test_done } diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index ed7b513f3..1bbfd824e 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -41,16 +41,16 @@ not_present() { cvs >/dev/null 2>&1 if test $? -ne 1 then - say 'skipping git-cvsserver tests, cvs not found' + skip_all='skipping git-cvsserver tests, cvs not found' test_done fi if ! test_have_prereq PERL then - say 'skipping git-cvsserver tests, perl not available' + skip_all='skipping git-cvsserver tests, perl not available' test_done fi "$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { - say 'skipping git-cvsserver tests, Perl SQLite interface unavailable' + skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable' test_done } @@ -129,21 +129,22 @@ test_expect_success 'cvs co (use attributes)' ' ' test_expect_success 'adding files' ' - cd cvswork/subdir && + (cd cvswork && + (cd subdir && echo "more text" > src.c && GIT_CONFIG="$git_config" cvs -Q add src.c >cvs.log 2>&1 && marked_as . src.c "" && - echo "psuedo-binary" > temp.bin && - cd .. && + echo "psuedo-binary" > temp.bin + ) && GIT_CONFIG="$git_config" cvs -Q add subdir/temp.bin >cvs.log 2>&1 && marked_as subdir temp.bin "-kb" && cd subdir && GIT_CONFIG="$git_config" cvs -Q ci -m "adding files" >cvs.log 2>&1 && marked_as . temp.bin "-kb" && marked_as . src.c "" + ) ' -cd "$WORKDIR" test_expect_success 'updating' ' git pull gitcvs.git && echo 'hi' > subdir/newfile.bin && @@ -153,9 +154,9 @@ test_expect_success 'updating' ' git add subdir/newfile.bin subdir/file.h subdir/newfile.c binfile.bin && git commit -q -m "Add and change some files" && git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - cd .. && + (cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update + ) && marked_as cvswork textfile.c "" && marked_as cvswork binfile.bin -kb && marked_as cvswork .gitattributes "" && @@ -233,35 +234,35 @@ test_expect_success 'cvs co another copy (guess)' ' ' test_expect_success 'add text (guess)' ' - cd cvswork && + (cd cvswork && echo "simpleText" > simpleText.c && - GIT_CONFIG="$git_config" cvs -Q add simpleText.c && - cd .. && + GIT_CONFIG="$git_config" cvs -Q add simpleText.c + ) && marked_as cvswork simpleText.c "" ' test_expect_success 'add bin (guess)' ' - cd cvswork && + (cd cvswork && echo "simpleBin: NUL: Q <- there" | q_to_nul > simpleBin.bin && - GIT_CONFIG="$git_config" cvs -Q add simpleBin.bin && - cd .. && + GIT_CONFIG="$git_config" cvs -Q add simpleBin.bin + ) && marked_as cvswork simpleBin.bin -kb ' test_expect_success 'remove files (guess)' ' - cd cvswork && + (cd cvswork && GIT_CONFIG="$git_config" cvs -Q rm -f subdir/file.h && - cd subdir && - GIT_CONFIG="$git_config" cvs -Q rm -f withCr.bin && - cd ../.. && + (cd subdir && + GIT_CONFIG="$git_config" cvs -Q rm -f withCr.bin + )) && marked_as cvswork/subdir withCr.bin -kb && marked_as cvswork/subdir file.h "" ' test_expect_success 'cvs ci (guess)' ' - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q ci -m "add/rm files" >cvs.log 2>&1 && - cd .. && + (cd cvswork && + GIT_CONFIG="$git_config" cvs -Q ci -m "add/rm files" >cvs.log 2>&1 + ) && marked_as cvswork textfile.c "" && marked_as cvswork binfile.bin -kb && marked_as cvswork .gitattributes "" && @@ -278,9 +279,9 @@ test_expect_success 'cvs ci (guess)' ' ' test_expect_success 'update subdir of other copy (guess)' ' - cd cvswork2/subdir && - GIT_CONFIG="$git_config" cvs -Q update && - cd ../.. && + (cd cvswork2/subdir && + GIT_CONFIG="$git_config" cvs -Q update + ) && marked_as cvswork2 textfile.c "" && marked_as cvswork2 binfile.bin -kb && marked_as cvswork2 .gitattributes "" && @@ -304,11 +305,11 @@ test_expect_success 'update/merge full other copy (guess)' ' git add multilineTxt.c && git commit -q -m "modify multiline file" >> "${WORKDIR}/marked.log" && git push gitcvs.git >/dev/null && - cd cvswork2 && + (cd cvswork2 && sed "s/1/replaced_1/" < multilineTxt.c > ml.temp && mv ml.temp multilineTxt.c && - GIT_CONFIG="$git_config" cvs update > cvs.log 2>&1 && - cd .. && + GIT_CONFIG="$git_config" cvs update > cvs.log 2>&1 + ) && marked_as cvswork2 textfile.c "" && marked_as cvswork2 binfile.bin -kb && marked_as cvswork2 .gitattributes "" && diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 4f2b9b062..21cd286bb 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -650,25 +650,26 @@ test_debug 'cat gitweb.log' # ---------------------------------------------------------------------- # syntax highlighting -cat >>gitweb_config.perl <<\EOF -$feature{'highlight'}{'override'} = 1; -EOF highlight --version >/dev/null 2>&1 if [ $? -eq 127 ]; then say "Skipping syntax highlighting test, because 'highlight' was not found" else test_set_prereq HIGHLIGHT + cat >>gitweb_config.perl <<-\EOF + our $highlight_bin = "highlight"; + $feature{'highlight'}{'override'} = 1; + EOF fi test_expect_success HIGHLIGHT \ - 'syntax highlighting (no highlight)' \ + 'syntax highlighting (no highlight, unknown syntax)' \ 'git config gitweb.highlight yes && gitweb_run "p=.git;a=blob;f=file"' test_debug 'cat gitweb.log' test_expect_success HIGHLIGHT \ - 'syntax highlighting (highlighted)' \ + 'syntax highlighting (highlighted, shell script)' \ 'git config gitweb.highlight yes && echo "#!/usr/bin/sh" > test.sh && git add test.sh && diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh index b572ce3ab..432b82e3d 100755 --- a/t/t9600-cvsimport.sh +++ b/t/t9600-cvsimport.sh @@ -3,21 +3,18 @@ test_description='git cvsimport basic tests' . ./lib-cvs.sh -if ! test_have_prereq PERL; then - say 'skipping git cvsimport tests, perl not available' - test_done -fi - -CVSROOT=$(pwd)/cvsroot -export CVSROOT +test_expect_success PERL 'setup cvsroot environment' ' + CVSROOT=$(pwd)/cvsroot && + export CVSROOT +' -test_expect_success 'setup cvsroot' '$CVS init' +test_expect_success PERL 'setup cvsroot' '$CVS init' -test_expect_success 'setup a cvs module' ' +test_expect_success PERL 'setup a cvs module' ' mkdir "$CVSROOT/module" && $CVS co -d module-cvs module && - cd module-cvs && + (cd module-cvs && cat <<EOF >o_fortuna && O Fortuna velut luna @@ -41,29 +38,28 @@ add "O Fortuna" lyrics These public domain lyrics make an excellent sample text. EOF - $CVS commit -F message && - cd .. + $CVS commit -F message + ) ' -test_expect_success 'import a trivial module' ' +test_expect_success PERL 'import a trivial module' ' git cvsimport -a -R -z 0 -C module-git module && test_cmp module-cvs/o_fortuna module-git/o_fortuna ' -test_expect_success 'pack refs' 'cd module-git && git gc && cd ..' +test_expect_success PERL 'pack refs' '(cd module-git && git gc)' -test_expect_success 'initial import has correct .git/cvs-revisions' ' +test_expect_success PERL 'initial import has correct .git/cvs-revisions' ' (cd module-git && git log --format="o_fortuna 1.1 %H" -1) > expected && test_cmp expected module-git/.git/cvs-revisions ' -test_expect_success 'update cvs module' ' - - cd module-cvs && +test_expect_success PERL 'update cvs module' ' + (cd module-cvs && cat <<EOF >o_fortuna && O Fortune, like the moon @@ -86,21 +82,21 @@ translate to English My Latin is terrible. EOF - $CVS commit -F message && - cd .. + $CVS commit -F message + ) ' -test_expect_success 'update git module' ' +test_expect_success PERL 'update git module' ' - cd module-git && + (cd module-git && git cvsimport -a -R -z 0 module && - git merge origin && - cd .. && + git merge origin + ) && test_cmp module-cvs/o_fortuna module-git/o_fortuna ' -test_expect_success 'update has correct .git/cvs-revisions' ' +test_expect_success PERL 'update has correct .git/cvs-revisions' ' (cd module-git && git log --format="o_fortuna 1.1 %H" -1 HEAD^ && @@ -108,28 +104,27 @@ test_expect_success 'update has correct .git/cvs-revisions' ' test_cmp expected module-git/.git/cvs-revisions ' -test_expect_success 'update cvs module' ' +test_expect_success PERL 'update cvs module' ' - cd module-cvs && + (cd module-cvs && echo 1 >tick && $CVS add tick && $CVS commit -m 1 - cd .. - + ) ' -test_expect_success 'cvsimport.module config works' ' +test_expect_success PERL 'cvsimport.module config works' ' - cd module-git && + (cd module-git && git config cvsimport.module module && git cvsimport -a -R -z0 && - git merge origin && - cd .. && + git merge origin + ) && test_cmp module-cvs/tick module-git/tick ' -test_expect_success 'second update has correct .git/cvs-revisions' ' +test_expect_success PERL 'second update has correct .git/cvs-revisions' ' (cd module-git && git log --format="o_fortuna 1.1 %H" -1 HEAD^^ && @@ -138,24 +133,24 @@ test_expect_success 'second update has correct .git/cvs-revisions' ' test_cmp expected module-git/.git/cvs-revisions ' -test_expect_success 'import from a CVS working tree' ' +test_expect_success PERL 'import from a CVS working tree' ' $CVS co -d import-from-wt module && - cd import-from-wt && + (cd import-from-wt && git cvsimport -a -z0 && echo 1 >expect && git log -1 --pretty=format:%s%n >actual && - test_cmp actual expect && - cd .. + test_cmp actual expect + ) ' -test_expect_success 'no .git/cvs-revisions created by default' ' +test_expect_success PERL 'no .git/cvs-revisions created by default' ' ! test -e import-from-wt/.git/cvs-revisions ' -test_expect_success 'test entire HEAD' 'test_cmp_branch_tree master' +test_expect_success PERL 'test entire HEAD' 'test_cmp_branch_tree master' test_done diff --git a/t/t9601-cvsimport-vendor-branch.sh b/t/t9601-cvsimport-vendor-branch.sh index 3afaf5652..827d39f5b 100755 --- a/t/t9601-cvsimport-vendor-branch.sh +++ b/t/t9601-cvsimport-vendor-branch.sh @@ -34,50 +34,49 @@ test_description='git cvsimport handling of vendor branches' . ./lib-cvs.sh -CVSROOT="$TEST_DIRECTORY"/t9601/cvsroot -export CVSROOT +setup_cvs_test_repository t9601 -test_expect_success 'import a module with a vendor branch' ' +test_expect_success PERL 'import a module with a vendor branch' ' git cvsimport -C module-git module ' -test_expect_success 'check HEAD out of cvs repository' 'test_cvs_co master' +test_expect_success PERL 'check HEAD out of cvs repository' 'test_cvs_co master' -test_expect_success 'check master out of git repository' 'test_git_co master' +test_expect_success PERL 'check master out of git repository' 'test_git_co master' -test_expect_success 'check a file that was imported once' ' +test_expect_success PERL 'check a file that was imported once' ' test_cmp_branch_file master imported-once.txt ' -test_expect_failure 'check a file that was imported twice' ' +test_expect_failure PERL 'check a file that was imported twice' ' test_cmp_branch_file master imported-twice.txt ' -test_expect_success 'check a file that was imported then modified on HEAD' ' +test_expect_success PERL 'check a file that was imported then modified on HEAD' ' test_cmp_branch_file master imported-modified.txt ' -test_expect_success 'check a file that was imported, modified, then imported again' ' +test_expect_success PERL 'check a file that was imported, modified, then imported again' ' test_cmp_branch_file master imported-modified-imported.txt ' -test_expect_success 'check a file that was added to HEAD then imported' ' +test_expect_success PERL 'check a file that was added to HEAD then imported' ' test_cmp_branch_file master added-imported.txt ' -test_expect_success 'a vendor branch whose tag has been removed' ' +test_expect_success PERL 'a vendor branch whose tag has been removed' ' test_cmp_branch_file master imported-anonymously.txt diff --git a/t/t9602-cvsimport-branches-tags.sh b/t/t9602-cvsimport-branches-tags.sh index 67878b2d0..e1db323f5 100755 --- a/t/t9602-cvsimport-branches-tags.sh +++ b/t/t9602-cvsimport-branches-tags.sh @@ -6,70 +6,69 @@ test_description='git cvsimport handling of branches and tags' . ./lib-cvs.sh -CVSROOT="$TEST_DIRECTORY"/t9602/cvsroot -export CVSROOT +setup_cvs_test_repository t9602 -test_expect_success 'import module' ' +test_expect_success PERL 'import module' ' git cvsimport -C module-git module ' -test_expect_success 'test branch master' ' +test_expect_success PERL 'test branch master' ' test_cmp_branch_tree master ' -test_expect_success 'test branch vendorbranch' ' +test_expect_success PERL 'test branch vendorbranch' ' test_cmp_branch_tree vendorbranch ' -test_expect_failure 'test branch B_FROM_INITIALS' ' +test_expect_failure PERL 'test branch B_FROM_INITIALS' ' test_cmp_branch_tree B_FROM_INITIALS ' -test_expect_failure 'test branch B_FROM_INITIALS_BUT_ONE' ' +test_expect_failure PERL 'test branch B_FROM_INITIALS_BUT_ONE' ' test_cmp_branch_tree B_FROM_INITIALS_BUT_ONE ' -test_expect_failure 'test branch B_MIXED' ' +test_expect_failure PERL 'test branch B_MIXED' ' test_cmp_branch_tree B_MIXED ' -test_expect_success 'test branch B_SPLIT' ' +test_expect_success PERL 'test branch B_SPLIT' ' test_cmp_branch_tree B_SPLIT ' -test_expect_failure 'test tag vendortag' ' +test_expect_failure PERL 'test tag vendortag' ' test_cmp_branch_tree vendortag ' -test_expect_success 'test tag T_ALL_INITIAL_FILES' ' +test_expect_success PERL 'test tag T_ALL_INITIAL_FILES' ' test_cmp_branch_tree T_ALL_INITIAL_FILES ' -test_expect_failure 'test tag T_ALL_INITIAL_FILES_BUT_ONE' ' +test_expect_failure PERL 'test tag T_ALL_INITIAL_FILES_BUT_ONE' ' test_cmp_branch_tree T_ALL_INITIAL_FILES_BUT_ONE ' -test_expect_failure 'test tag T_MIXED' ' +test_expect_failure PERL 'test tag T_MIXED' ' test_cmp_branch_tree T_MIXED diff --git a/t/t9603-cvsimport-patchsets.sh b/t/t9603-cvsimport-patchsets.sh index 958bdce4d..52034c8f7 100755 --- a/t/t9603-cvsimport-patchsets.sh +++ b/t/t9603-cvsimport-patchsets.sh @@ -14,18 +14,17 @@ test_description='git cvsimport testing for correct patchset estimation' . ./lib-cvs.sh -CVSROOT="$TEST_DIRECTORY"/t9603/cvsroot -export CVSROOT +setup_cvs_test_repository t9603 test_expect_failure 'import with criss cross times on revisions' ' git cvsimport -p"-x" -C module-git module && - cd module-git && + (cd module-git && git log --pretty=format:%s > ../actual-master && git log A~2..A --pretty="format:%s %ad" -- > ../actual-A && echo "" >> ../actual-master && - echo "" >> ../actual-A && - cd .. && + echo "" >> ../actual-A + ) && echo "Rev 4 Rev 3 Rev 2 diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh index 8686086dd..378718670 100755 --- a/t/t9700-perl-git.sh +++ b/t/t9700-perl-git.sh @@ -7,12 +7,12 @@ test_description='perl interface (Git.pm)' . ./test-lib.sh if ! test_have_prereq PERL; then - say 'skipping perl interface tests, perl not available' + skip_all='skipping perl interface tests, perl not available' test_done fi "$PERL_PATH" -MTest::More -e 0 2>/dev/null || { - say "Perl Test::More unavailable, skipping test" + skip_all="Perl Test::More unavailable, skipping test" test_done } @@ -46,6 +46,9 @@ test_expect_success \ git config --add test.int 2k ' +# The external test will outputs its own plan +test_external_has_tap=1 + test_external_without_stderr \ 'Perl API' \ "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 666722d9b..671f38db2 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -7,6 +7,13 @@ use strict; use Test::More qw(no_plan); +BEGIN { + # t9700-perl-git.sh kicks off our testing, so we have to go from + # there. + Test::More->builder->current_test(1); + Test::More->builder->no_ending(1); +} + use Cwd; use File::Basename; @@ -105,3 +112,8 @@ my $last_commit = $r2->command_oneline(qw(rev-parse --verify HEAD)); like($last_commit, qr/^[0-9a-fA-F]{40}$/, 'rev-parse returned hash'); my $dir_commit = $r2->command_oneline('log', '-n1', '--pretty=format:%H', '.'); isnt($last_commit, $dir_commit, 'log . does not show last commit'); + +printf "1..%d\n", Test::More->builder->current_test; + +my $is_passing = eval { Test::More->is_passing }; +exit($is_passing ? 0 : 1) unless $@ =~ /Can't locate object method/; diff --git a/t/test-lib.sh b/t/test-lib.sh index 367f0537c..2af8f10c8 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -127,14 +127,13 @@ do -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) verbose=t; shift ;; -q|--q|--qu|--qui|--quie|--quiet) - quiet=t; shift ;; + # Ignore --quiet under a TAP::Harness. Saying how many tests + # passed without the ok/not ok details is always an error. + test -z "$HARNESS_ACTIVE" && quiet=t; shift ;; --with-dashes) with_dashes=t; shift ;; --no-color) color=; shift ;; - --no-python) - # noop now... - shift ;; --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind) valgrind=t; verbose=t; shift ;; --tee) @@ -160,7 +159,7 @@ if test -n "$color"; then *) test -n "$quiet" && return;; esac shift - printf "* %s" "$*" + printf "%s" "$*" tput sgr0 echo ) @@ -169,7 +168,7 @@ else say_color() { test -z "$1" && test -n "$quiet" && return shift - echo "* $*" + echo "$*" } fi @@ -206,6 +205,8 @@ test_fixed=0 test_broken=0 test_success=0 +test_external_has_tap=0 + die () { code=$? if test -n "$GIT_EXIT_OK" @@ -255,6 +256,10 @@ q_to_cr () { tr Q '\015' } +q_to_tab () { + tr Q '\011' +} + append_cr () { sed -e 's/$/Q/' | tr Q '\015' } @@ -326,12 +331,35 @@ test_set_prereq () { satisfied=" " test_have_prereq () { - case $satisfied in - *" $1 "*) - : yes, have it ;; - *) - ! : nope ;; - esac + # prerequisites can be concatenated with ',' + save_IFS=$IFS + IFS=, + set -- $* + IFS=$save_IFS + + total_prereq=0 + ok_prereq=0 + missing_prereq= + + for prerequisite + do + total_prereq=$(($total_prereq + 1)) + case $satisfied in + *" $prerequisite "*) + ok_prereq=$(($ok_prereq + 1)) + ;; + *) + # Keep a list of missing prerequisites + if test -z "$missing_prereq" + then + missing_prereq=$prerequisite + else + missing_prereq="$prerequisite,$missing_prereq" + fi + esac + done + + test $total_prereq = $ok_prereq } # You are not expected to call test_ok_ and test_failure_ directly, use @@ -339,25 +367,25 @@ test_have_prereq () { test_ok_ () { test_success=$(($test_success + 1)) - say_color "" " ok $test_count: $@" + say_color "" "ok $test_count - $@" } test_failure_ () { test_failure=$(($test_failure + 1)) - say_color error "FAIL $test_count: $1" + say_color error "not ok - $test_count $1" shift - echo "$@" | sed -e 's/^/ /' + echo "$@" | sed -e 's/^/# /' test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; } } test_known_broken_ok_ () { test_fixed=$(($test_fixed+1)) - say_color "" " FIXED $test_count: $@" + say_color "" "ok $test_count - $@ # TODO known breakage" } test_known_broken_failure_ () { test_broken=$(($test_broken+1)) - say_color skip " still broken $test_count: $@" + say_color skip "not ok $test_count - $@ # TODO known breakage" } test_debug () { @@ -369,6 +397,9 @@ test_run_ () { eval >&3 2>&4 "$1" eval_ret=$? eval >&3 2>&4 "$test_cleanup" + if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then + echo "" + fi return 0 } @@ -380,6 +411,7 @@ test_skip () { case $this_test.$test_count in $skp) to_skip=t + break esac done if test -z "$to_skip" && test -n "$prereq" && @@ -389,8 +421,14 @@ test_skip () { fi case "$to_skip" in t) + of_prereq= + if test "$missing_prereq" != "$prereq" + then + of_prereq=" of $prereq" + fi + say_color skip >&3 "skipping test: $@" - say_color skip "skip $test_count: $1" + say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})" : true ;; *) @@ -456,7 +494,7 @@ test_expect_code () { # test_external runs external test scripts that provide continuous # test output about their progress, and succeeds/fails on # zero/non-zero exit code. It outputs the test output on stdout even -# in non-verbose mode, and announces the external script with "* run +# in non-verbose mode, and announces the external script with "# run # <n>: ..." before running it. When providing relative paths, keep in # mind that all scripts run in "trash directory". # Usage: test_external description command arguments... @@ -471,7 +509,7 @@ test_external () { then # Announce the script to reduce confusion about the # test output that follows. - say_color "" " run $test_count: $descr ($*)" + say_color "" "# run $test_count: $descr ($*)" # Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG # to be able to use them in script export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG @@ -481,9 +519,19 @@ test_external () { "$@" 2>&4 if [ "$?" = 0 ] then - test_ok_ "$descr" + if test $test_external_has_tap -eq 0; then + test_ok_ "$descr" + else + say_color "" "# test_external test $descr was ok" + test_success=$(($test_success + 1)) + fi else - test_failure_ "$descr" "$@" + if test $test_external_has_tap -eq 0; then + test_failure_ "$descr" "$@" + else + say_color error "# test_external test $descr failed: $@" + test_failure=$(($test_failure + 1)) + fi fi fi } @@ -499,22 +547,65 @@ test_external_without_stderr () { [ -f "$stderr" ] || error "Internal error: $stderr disappeared." descr="no stderr: $1" shift - say >&3 "expecting no stderr from previous command" + say >&3 "# expecting no stderr from previous command" if [ ! -s "$stderr" ]; then rm "$stderr" - test_ok_ "$descr" + + if test $test_external_has_tap -eq 0; then + test_ok_ "$descr" + else + say_color "" "# test_external_without_stderr test $descr was ok" + test_success=$(($test_success + 1)) + fi else if [ "$verbose" = t ]; then - output=`echo; echo Stderr is:; cat "$stderr"` + output=`echo; echo "# Stderr is:"; cat "$stderr"` else output= fi # rm first in case test_failure exits. rm "$stderr" - test_failure_ "$descr" "$@" "$output" + if test $test_external_has_tap -eq 0; then + test_failure_ "$descr" "$@" "$output" + else + say_color error "# test_external_without_stderr test $descr failed: $@: $output" + test_failure=$(($test_failure + 1)) + fi + fi +} + +# debugging-friendly alternatives to "test [-f|-d|-e]" +# The commands test the existence or non-existence of $1. $2 can be +# given to provide a more precise diagnosis. +test_path_is_file () { + if ! [ -f "$1" ] + then + echo "File $1 doesn't exist. $*" + false fi } +test_path_is_dir () { + if ! [ -d "$1" ] + then + echo "Directory $1 doesn't exist. $*" + false + fi +} + +test_path_is_missing () { + if [ -e "$1" ] + then + echo "Path exists:" + ls -ld "$1" + if [ $# -ge 1 ]; then + echo "$*" + fi + false + fi +} + + # This is not among top-level (test_expect_success | test_expect_failure) # but is a prefix that can be used in the test script, like: # @@ -529,7 +620,18 @@ test_external_without_stderr () { test_must_fail () { "$@" - test $? -gt 0 -a $? -le 129 -o $? -gt 192 + exit_code=$? + if test $exit_code = 0; then + echo >&2 "test_must_fail: command succeeded: $*" + return 1 + elif test $exit_code -gt 129 -a $exit_code -le 192; then + echo >&2 "test_must_fail: died by signal: $*" + return 1 + elif test $exit_code = 127; then + echo >&2 "test_must_fail: command not found: $*" + return 1 + fi + return 0 } # Similar to test_must_fail, but tolerates success, too. This is @@ -545,7 +647,15 @@ test_must_fail () { test_might_fail () { "$@" - test $? -ge 0 -a $? -le 129 -o $? -gt 192 + exit_code=$? + if test $exit_code -gt 129 -a $exit_code -le 192; then + echo >&2 "test_might_fail: died by signal: $*" + return 1 + elif test $exit_code = 127; then + echo >&2 "test_might_fail: command not found: $*" + return 1 + fi + return 0 } # test_cmp is a helper function to compare actual and expected output. @@ -595,43 +705,52 @@ test_when_finished () { test_create_repo () { test "$#" = 1 || error "bug in the test script: not 1 parameter to test-create-repo" - owd=`pwd` repo="$1" mkdir -p "$repo" - cd "$repo" || error "Cannot setup test environment" - "$GIT_EXEC_PATH/git-init" "--template=$TEST_DIRECTORY/../templates/blt/" >&3 2>&4 || - error "cannot run git init -- have you built things yet?" - mv .git/hooks .git/hooks-disabled - cd "$owd" + ( + cd "$repo" || error "Cannot setup test environment" + "$GIT_EXEC_PATH/git-init" "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 || + error "cannot run git init -- have you built things yet?" + mv .git/hooks .git/hooks-disabled + ) || exit } test_done () { GIT_EXIT_OK=t - test_results_dir="$TEST_DIRECTORY/test-results" - mkdir -p "$test_results_dir" - test_results_path="$test_results_dir/${0%.sh}-$$" - echo "total $test_count" >> $test_results_path - echo "success $test_success" >> $test_results_path - echo "fixed $test_fixed" >> $test_results_path - echo "broken $test_broken" >> $test_results_path - echo "failed $test_failure" >> $test_results_path - echo "" >> $test_results_path + if test -z "$HARNESS_ACTIVE"; then + test_results_dir="$TEST_DIRECTORY/test-results" + mkdir -p "$test_results_dir" + test_results_path="$test_results_dir/${0%.sh}-$$.counts" + + echo "total $test_count" >> $test_results_path + echo "success $test_success" >> $test_results_path + echo "fixed $test_fixed" >> $test_results_path + echo "broken $test_broken" >> $test_results_path + echo "failed $test_failure" >> $test_results_path + echo "" >> $test_results_path + fi if test "$test_fixed" != 0 then - say_color pass "fixed $test_fixed known breakage(s)" + say_color pass "# fixed $test_fixed known breakage(s)" fi if test "$test_broken" != 0 then - say_color error "still have $test_broken known breakage(s)" + say_color error "# still have $test_broken known breakage(s)" msg="remaining $(($test_count-$test_broken)) test(s)" else msg="$test_count test(s)" fi case "$test_failure" in 0) - say_color pass "passed all $msg" + # Maybe print SKIP message + [ -z "$skip_all" ] || skip_all=" # SKIP $skip_all" + + if test $test_external_has_tap -eq 0; then + say_color pass "# passed all $msg" + say "1..$test_count$skip_all" + fi test -d "$remove_trash" && cd "$(dirname "$remove_trash")" && @@ -640,7 +759,11 @@ test_done () { exit 0 ;; *) - say_color error "failed $test_failure among $msg" + if test $test_external_has_tap -eq 0; then + say_color error "# failed $test_failure among $msg" + say "1..$test_count" + fi + exit 1 ;; esac @@ -648,7 +771,15 @@ test_done () { # Test the binaries we have just built. The tests are kept in # t/ subdirectory and are run in 'trash directory' subdirectory. -TEST_DIRECTORY=$(pwd) +if test -z "$TEST_DIRECTORY" +then + # We allow tests to override this, in case they want to run tests + # outside of t/, e.g. for running tests on the test library + # itself. + TEST_DIRECTORY=$(pwd) +fi +GIT_BUILD_DIR="$TEST_DIRECTORY"/.. + if test -n "$valgrind" then make_symlink () { @@ -675,7 +806,7 @@ then test -x "$1" || return base=$(basename "$1") - symlink_target=$TEST_DIRECTORY/../$base + symlink_target=$GIT_BUILD_DIR/$base # do not override scripts if test -x "$symlink_target" && test ! -d "$symlink_target" && @@ -694,7 +825,7 @@ then # override all git executables in TEST_DIRECTORY/.. GIT_VALGRIND=$TEST_DIRECTORY/valgrind mkdir -p "$GIT_VALGRIND"/bin - for file in $TEST_DIRECTORY/../git* $TEST_DIRECTORY/../test-* + for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-* do make_valgrind_symlink $file done @@ -715,10 +846,10 @@ then elif test -n "$GIT_TEST_INSTALLED" ; then GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) || error "Cannot run git from $GIT_TEST_INSTALLED." - PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH + PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH} else # normal case, use ../bin-wrappers only unless $with_dashes: - git_bin_dir="$TEST_DIRECTORY/../bin-wrappers" + git_bin_dir="$GIT_BUILD_DIR/bin-wrappers" if ! test -x "$git_bin_dir/git" ; then if test -z "$with_dashes" ; then say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH" @@ -726,18 +857,18 @@ else # normal case, use ../bin-wrappers only unless $with_dashes: with_dashes=t fi PATH="$git_bin_dir:$PATH" - GIT_EXEC_PATH=$TEST_DIRECTORY/.. + GIT_EXEC_PATH=$GIT_BUILD_DIR if test -n "$with_dashes" ; then - PATH="$TEST_DIRECTORY/..:$PATH" + PATH="$GIT_BUILD_DIR:$PATH" fi fi -GIT_TEMPLATE_DIR=$(pwd)/../templates/blt +GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt unset GIT_CONFIG GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_NOGLOBAL=1 export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL -. ../GIT-BUILD-OPTIONS +. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS if test -z "$GIT_TEST_CMP" then @@ -749,22 +880,22 @@ then fi fi -GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git +GITPERLLIB="$GIT_BUILD_DIR"/perl/blib/lib:"$GIT_BUILD_DIR"/perl/blib/arch/auto/Git export GITPERLLIB -test -d ../templates/blt || { +test -d "$GIT_BUILD_DIR"/templates/blt || { error "You haven't built things yet, have you?" } if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON" then - GITPYTHONLIB="$(pwd)/../git_remote_helpers/build/lib" + GITPYTHONLIB="$GIT_BUILD_DIR/git_remote_helpers/build/lib" export GITPYTHONLIB - test -d ../git_remote_helpers/build || { + test -d "$GIT_BUILD_DIR"/git_remote_helpers/build || { error "You haven't built git_remote_helpers yet, have you?" } fi -if ! test -x ../test-chmtime; then +if ! test -x "$GIT_BUILD_DIR"/test-chmtime; then echo >&2 'You need to build test-chmtime:' echo >&2 'Run "make test-chmtime" in the source (toplevel) directory' exit 1 @@ -789,22 +920,17 @@ test_create_repo "$test" # in subprocesses like git equals our $PWD (for pathname comparisons). cd -P "$test" || exit 1 +HOME=$(pwd) +export HOME + this_test=${0##*/} this_test=${this_test%%-*} for skp in $GIT_SKIP_TESTS do - to_skip= - for skp in $GIT_SKIP_TESTS - do - case "$this_test" in - $skp) - to_skip=t - esac - done - case "$to_skip" in - t) + case "$this_test" in + $skp) say_color skip >&3 "skipping test $this_test altogether" - say_color skip "skip all tests in $this_test" + skip_all="skip all tests in $this_test" test_done esac done @@ -844,11 +970,13 @@ case $(uname -s) in # no POSIX permissions # backslashes in pathspec are converted to '/' # exec does not inherit the PID + test_set_prereq MINGW ;; *) test_set_prereq POSIXPERM test_set_prereq BSLASHPSPEC test_set_prereq EXECKEEPSPID + test_set_prereq NOT_MINGW ;; esac @@ -858,3 +986,7 @@ test -z "$NO_PYTHON" && test_set_prereq PYTHON # test whether the filesystem supports symbolic links ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS rm -f y + +# When the tests are run as root, permission tests will report that +# things are writable when they shouldn't be. +test -w / || test_set_prereq SANITY |