summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/Makefile5
-rw-r--r--t/README73
-rwxr-xr-xt/harness21
-rw-r--r--t/perf/.gitignore2
-rw-r--r--t/perf/Makefile15
-rw-r--r--t/perf/README146
-rwxr-xr-xt/perf/aggregate.perl166
-rwxr-xr-xt/perf/min_time.perl21
-rwxr-xr-xt/perf/p0000-perf-lib-sanity.sh55
-rwxr-xr-xt/perf/p0001-rev-list.sh17
-rwxr-xr-xt/perf/p4000-diff-algorithms.sh29
-rwxr-xr-xt/perf/p7810-grep.sh23
-rw-r--r--t/perf/perf-lib.sh202
-rwxr-xr-xt/perf/run82
-rwxr-xr-xt/t0000-basic.sh563
-rwxr-xr-xt/t0021-conversion.sh37
-rwxr-xr-xt/t0040-parse-options.sh70
-rwxr-xr-xt/t0204-gettext-reencode-sanity.sh37
-rwxr-xr-xt/t0300-credentials.sh5
-rwxr-xr-xt/t1051-large-conversion.sh86
-rwxr-xr-xt/t1200-tutorial.sh2
-rwxr-xr-xt/t1300-repo-config.sh58
-rwxr-xr-xt/t1305-config-include.sh134
-rwxr-xr-xt/t1450-fsck.sh32
-rwxr-xr-xt/t2015-checkout-unborn.sh11
-rwxr-xr-xt/t3200-branch.sh4
-rwxr-xr-xt/t3300-funny-names.sh2
-rwxr-xr-xt/t3400-rebase.sh6
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh14
-rwxr-xr-xt/t3508-cherry-pick-many-commits.sh12
-rwxr-xr-xt/t3700-add.sh15
-rwxr-xr-xt/t3903-stash.sh4
-rwxr-xr-xt/t4011-diff-symlink.sh195
-rw-r--r--t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master2
-rw-r--r--t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side2
-rw-r--r--t/t4013/diff.diff-tree_--cc_--patch-with-stat_master2
-rw-r--r--t/t4013/diff.diff-tree_--cc_--stat_--summary_master2
-rw-r--r--t/t4013/diff.diff-tree_--cc_--stat_--summary_side2
-rw-r--r--t/t4013/diff.diff-tree_--cc_--stat_master2
-rw-r--r--t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial2
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side2
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial2
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial2
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--root_--stat_initial2
-rw-r--r--t/t4013/diff.diff-tree_--root_--patch-with-stat_initial2
-rw-r--r--t/t4013/diff.diff-tree_-c_--stat_--summary_master2
-rw-r--r--t/t4013/diff.diff-tree_-c_--stat_--summary_side2
-rw-r--r--t/t4013/diff.diff-tree_-c_--stat_master2
-rw-r--r--t/t4013/diff.diff_--patch-with-stat_-r_initial..side2
-rw-r--r--t/t4013/diff.diff_--patch-with-stat_initial..side2
-rw-r--r--t/t4013/diff.diff_--stat_initial..side2
-rw-r--r--t/t4013/diff.diff_-r_--stat_initial..side2
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side2
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..master4
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..master^2
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..side2
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master4
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master4
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master4
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master^2
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..side2
-rw-r--r--t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^2
-rw-r--r--t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master4
-rw-r--r--t/t4013/diff.format-patch_--stdout_--numbered_initial..master4
-rw-r--r--t/t4013/diff.format-patch_--stdout_initial..master4
-rw-r--r--t/t4013/diff.format-patch_--stdout_initial..master^2
-rw-r--r--t/t4013/diff.format-patch_--stdout_initial..side2
-rw-r--r--t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_6
-rw-r--r--t/t4013/diff.log_--patch-with-stat_master4
-rw-r--r--t/t4013/diff.log_--patch-with-stat_master_--_dir_6
-rw-r--r--t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master8
-rw-r--r--t/t4013/diff.log_--root_--patch-with-stat_--summary_master6
-rw-r--r--t/t4013/diff.log_--root_--patch-with-stat_master6
-rw-r--r--t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master8
-rw-r--r--t/t4013/diff.show_--patch-with-stat_--summary_side2
-rw-r--r--t/t4013/diff.show_--patch-with-stat_side2
-rw-r--r--t/t4013/diff.show_--stat_--summary_side2
-rw-r--r--t/t4013/diff.show_--stat_side2
-rw-r--r--t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_6
-rw-r--r--t/t4013/diff.whatchanged_--patch-with-stat_master4
-rw-r--r--t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_6
-rw-r--r--t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master8
-rw-r--r--t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master6
-rw-r--r--t/t4013/diff.whatchanged_--root_--patch-with-stat_master6
-rw-r--r--t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master8
-rwxr-xr-xt/t4014-format-patch.sh2
-rwxr-xr-xt/t4030-diff-textconv.sh2
-rwxr-xr-xt/t4045-diff-relative.sh2
-rwxr-xr-xt/t4049-diff-stat-count.sh2
-rwxr-xr-xt/t4052-stat-output.sh220
-rw-r--r--t/t4100/t-apply-8.expect2
-rw-r--r--t/t4100/t-apply-9.expect2
-rwxr-xr-xt/t4150-am.sh27
-rwxr-xr-xt/t4209-log-pickaxe.sh119
-rwxr-xr-xt/t5150-request-pull.sh2
-rwxr-xr-xt/t5300-pack-object.sh4
-rwxr-xr-xt/t5302-pack-index.sh4
-rwxr-xr-xt/t5504-fetch-receive-strict.sh22
-rwxr-xr-xt/t5510-fetch.sh57
-rwxr-xr-xt/t5512-ls-remote.sh27
-rwxr-xr-xt/t5516-fetch-push.sh16
-rwxr-xr-xt/t5523-push-upstream.sh3
-rwxr-xr-xt/t5541-http-push.sh2
-rwxr-xr-xt/t5560-http-backend-noserver.sh6
-rwxr-xr-xt/t5700-clone-reference.sh34
-rwxr-xr-xt/t5704-bundle.sh47
-rwxr-xr-xt/t5900-repo-selection.sh100
-rwxr-xr-xt/t6032-merge-large-rename.sh2
-rwxr-xr-xt/t7004-tag.sh39
-rwxr-xr-xt/t7008-grep-binary.sh24
-rwxr-xr-xt/t7400-submodule-basic.sh22
-rwxr-xr-xt/t7406-submodule-update.sh17
-rwxr-xr-xt/t7602-merge-octopus-many.sh6
-rwxr-xr-xt/t7810-grep.sh23
-rwxr-xr-xt/t9100-git-svn-basic.sh45
-rwxr-xr-xt/t9130-git-svn-authors-file.sh4
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh2
-rwxr-xr-xt/t9300-fast-import.sh39
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh48
-rwxr-xr-xt/t9501-gitweb-standalone-http-status.sh10
-rwxr-xr-xt/t9800-git-p4-basic.sh24
-rwxr-xr-xt/t9804-git-p4-label.sh2
-rwxr-xr-xt/t9808-git-p4-chdir.sh4
-rwxr-xr-xt/t9809-git-p4-client-view.sh161
-rwxr-xr-xt/t9810-git-p4-rcs.sh388
-rw-r--r--t/test-lib-functions.sh565
-rw-r--r--t/test-lib.sh583
127 files changed, 3759 insertions, 1273 deletions
diff --git a/t/Makefile b/t/Makefile
index 66ceefefcc..6091211f10 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -73,6 +73,9 @@ gitweb-test:
valgrind:
$(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"
+perf:
+ $(MAKE) -C perf/ all
+
# Smoke testing targets
-include ../GIT-VERSION-FILE
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo unknown')
@@ -111,4 +114,4 @@ smoke_report: smoke
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
+.PHONY: pre-clean $(T) aggregate-results clean valgrind perf
diff --git a/t/README b/t/README
index c09c582c16..3534f43d01 100644
--- a/t/README
+++ b/t/README
@@ -671,76 +671,3 @@ Then, at the top-level:
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/harness b/t/harness
deleted file mode 100755
index f5c02f49b7..0000000000
--- a/t/harness
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/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/perf/.gitignore b/t/perf/.gitignore
new file mode 100644
index 0000000000..50f5cc1ed9
--- /dev/null
+++ b/t/perf/.gitignore
@@ -0,0 +1,2 @@
+build/
+test-results/
diff --git a/t/perf/Makefile b/t/perf/Makefile
new file mode 100644
index 0000000000..8c47155a7c
--- /dev/null
+++ b/t/perf/Makefile
@@ -0,0 +1,15 @@
+-include ../../config.mak
+export GIT_TEST_OPTIONS
+
+all: perf
+
+perf: pre-clean
+ ./run
+
+pre-clean:
+ rm -rf test-results
+
+clean:
+ rm -rf build "trash directory".* test-results
+
+.PHONY: all perf pre-clean clean
diff --git a/t/perf/README b/t/perf/README
new file mode 100644
index 0000000000..b2dbad4d50
--- /dev/null
+++ b/t/perf/README
@@ -0,0 +1,146 @@
+Git performance tests
+=====================
+
+This directory holds performance testing scripts for git tools. The
+first part of this document describes the various ways in which you
+can run them.
+
+When fixing the tools or adding enhancements, you are strongly
+encouraged to add tests in this directory to cover what you are
+trying to fix or enhance. The later part of this short document
+describes how your test scripts should be organized.
+
+
+Running Tests
+-------------
+
+The easiest way to run tests is to say "make". This runs all
+the tests on the current git repository.
+
+ === Running 2 tests in this tree ===
+ [...]
+ Test this tree
+ ---------------------------------------------------------
+ 0001.1: rev-list --all 0.54(0.51+0.02)
+ 0001.2: rev-list --all --objects 6.14(5.99+0.11)
+ 7810.1: grep worktree, cheap regex 0.16(0.16+0.35)
+ 7810.2: grep worktree, expensive regex 7.90(29.75+0.37)
+ 7810.3: grep --cached, cheap regex 3.07(3.02+0.25)
+ 7810.4: grep --cached, expensive regex 9.39(30.57+0.24)
+
+You can compare multiple repositories and even git revisions with the
+'run' script:
+
+ $ ./run . origin/next /path/to/git-tree p0001-rev-list.sh
+
+where . stands for the current git tree. The full invocation is
+
+ ./run [<revision|directory>...] [--] [<test-script>...]
+
+A '.' argument is implied if you do not pass any other
+revisions/directories.
+
+You can also manually test this or another git build tree, and then
+call the aggregation script to summarize the results:
+
+ $ ./p0001-rev-list.sh
+ [...]
+ $ GIT_BUILD_DIR=/path/to/other/git ./p0001-rev-list.sh
+ [...]
+ $ ./aggregate.perl . /path/to/other/git ./p0001-rev-list.sh
+
+aggregate.perl has the same invocation as 'run', it just does not run
+anything beforehand.
+
+You can set the following variables (also in your config.mak):
+
+ GIT_PERF_REPEAT_COUNT
+ Number of times a test should be repeated for best-of-N
+ measurements. Defaults to 5.
+
+ GIT_PERF_MAKE_OPTS
+ Options to use when automatically building a git tree for
+ performance testing. E.g., -j6 would be useful.
+
+ GIT_PERF_REPO
+ GIT_PERF_LARGE_REPO
+ Repositories to copy for the performance tests. The normal
+ repo should be at least git.git size. The large repo should
+ probably be about linux-2.6.git size for optimal results.
+ Both default to the git.git you are running from.
+
+You can also pass the options taken by ordinary git tests; the most
+useful one is:
+
+--root=<directory>::
+ Create "trash" directories used to store all temporary data during
+ testing under <directory>, instead of the t/ directory.
+ Using this option with a RAM-based filesystem (such as tmpfs)
+ can massively speed up the test suite.
+
+
+Naming Tests
+------------
+
+The performance test files are named as:
+
+ pNNNN-commandname-details.sh
+
+where N is a decimal digit. The same conventions for choosing NNNN as
+for normal tests apply.
+
+
+Writing Tests
+-------------
+
+The perf script starts much like a normal test script, except it
+sources perf-lib.sh:
+
+ #!/bin/sh
+ #
+ # Copyright (c) 2005 Junio C Hamano
+ #
+
+ test_description='xxx performance test'
+ . ./perf-lib.sh
+
+After that you will want to use some of the following:
+
+ test_perf_default_repo # sets up a "normal" repository
+ test_perf_large_repo # sets up a "large" repository
+
+ test_perf_default_repo sub # ditto, in a subdir "sub"
+
+ test_checkout_worktree # if you need the worktree too
+
+At least one of the first two is required!
+
+You can use test_expect_success as usual. For actual performance
+tests, use
+
+ test_perf 'descriptive string' '
+ command1 &&
+ command2
+ '
+
+test_perf spawns a subshell, for lack of better options. This means
+that
+
+* you _must_ export all variables that you need in the subshell
+
+* you _must_ flag all variables that you want to persist from the
+ subshell with 'test_export':
+
+ test_perf 'descriptive string' '
+ foo=$(git rev-parse HEAD) &&
+ test_export foo
+ '
+
+ The so-exported variables are automatically marked for export in the
+ shell executing the perf test. For your convenience, test_export is
+ the same as export in the main shell.
+
+ This feature relies on a bit of magic using 'set' and 'source'.
+ While we have tried to make sure that it can cope with embedded
+ whitespace and other special characters, it will not work with
+ multi-line data.
diff --git a/t/perf/aggregate.perl b/t/perf/aggregate.perl
new file mode 100755
index 0000000000..15f7fc1b80
--- /dev/null
+++ b/t/perf/aggregate.perl
@@ -0,0 +1,166 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Git;
+
+sub get_times {
+ my $name = shift;
+ open my $fh, "<", $name or return undef;
+ my $line = <$fh>;
+ return undef if not defined $line;
+ close $fh or die "cannot close $name: $!";
+ $line =~ /^(?:(\d+):)?(\d+):(\d+(?:\.\d+)?) (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)$/
+ or die "bad input line: $line";
+ my $rt = ((defined $1 ? $1 : 0.0)*60+$2)*60+$3;
+ return ($rt, $4, $5);
+}
+
+sub format_times {
+ my ($r, $u, $s, $firstr) = @_;
+ if (!defined $r) {
+ return "<missing>";
+ }
+ my $out = sprintf "%.2f(%.2f+%.2f)", $r, $u, $s;
+ if (defined $firstr) {
+ if ($firstr > 0) {
+ $out .= sprintf " %+.1f%%", 100.0*($r-$firstr)/$firstr;
+ } elsif ($r == 0) {
+ $out .= " =";
+ } else {
+ $out .= " +inf";
+ }
+ }
+ return $out;
+}
+
+my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests);
+while (scalar @ARGV) {
+ my $arg = $ARGV[0];
+ my $dir;
+ last if -f $arg or $arg eq "--";
+ if (! -d $arg) {
+ my $rev = Git::command_oneline(qw(rev-parse --verify), $arg);
+ $dir = "build/".$rev;
+ } else {
+ $arg =~ s{/*$}{};
+ $dir = $arg;
+ $dirabbrevs{$dir} = $dir;
+ }
+ push @dirs, $dir;
+ $dirnames{$dir} = $arg;
+ my $prefix = $dir;
+ $prefix =~ tr/^a-zA-Z0-9/_/c;
+ $prefixes{$dir} = $prefix . '.';
+ shift @ARGV;
+}
+
+if (not @dirs) {
+ @dirs = ('.');
+}
+$dirnames{'.'} = $dirabbrevs{'.'} = "this tree";
+$prefixes{'.'} = '';
+
+shift @ARGV if scalar @ARGV and $ARGV[0] eq "--";
+
+@tests = @ARGV;
+if (not @tests) {
+ @tests = glob "p????-*.sh";
+}
+
+my @subtests;
+my %shorttests;
+for my $t (@tests) {
+ $t =~ s{(?:.*/)?(p(\d+)-[^/]+)\.sh$}{$1} or die "bad test name: $t";
+ my $n = $2;
+ my $fname = "test-results/$t.subtests";
+ open my $fp, "<", $fname or die "cannot open $fname: $!";
+ for (<$fp>) {
+ chomp;
+ /^(\d+)$/ or die "malformed subtest line: $_";
+ push @subtests, "$t.$1";
+ $shorttests{"$t.$1"} = "$n.$1";
+ }
+ close $fp or die "cannot close $fname: $!";
+}
+
+sub read_descr {
+ my $name = shift;
+ open my $fh, "<", $name or return "<error reading description>";
+ my $line = <$fh>;
+ close $fh or die "cannot close $name";
+ chomp $line;
+ return $line;
+}
+
+my %descrs;
+my $descrlen = 4; # "Test"
+for my $t (@subtests) {
+ $descrs{$t} = $shorttests{$t}.": ".read_descr("test-results/$t.descr");
+ $descrlen = length $descrs{$t} if length $descrs{$t}>$descrlen;
+}
+
+sub have_duplicate {
+ my %seen;
+ for (@_) {
+ return 1 if exists $seen{$_};
+ $seen{$_} = 1;
+ }
+ return 0;
+}
+sub have_slash {
+ for (@_) {
+ return 1 if m{/};
+ }
+ return 0;
+}
+
+my %newdirabbrevs = %dirabbrevs;
+while (!have_duplicate(values %newdirabbrevs)) {
+ %dirabbrevs = %newdirabbrevs;
+ last if !have_slash(values %dirabbrevs);
+ %newdirabbrevs = %dirabbrevs;
+ for (values %newdirabbrevs) {
+ s{^[^/]*/}{};
+ }
+}
+
+my %times;
+my @colwidth = ((0)x@dirs);
+for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ my $w = length (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+ $colwidth[$i] = $w if $w > $colwidth[$i];
+}
+for my $t (@subtests) {
+ my $firstr;
+ for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ $times{$prefixes{$d}.$t} = [get_times("test-results/$prefixes{$d}$t.times")];
+ my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
+ my $w = length format_times($r,$u,$s,$firstr);
+ $colwidth[$i] = $w if $w > $colwidth[$i];
+ $firstr = $r unless defined $firstr;
+ }
+}
+my $totalwidth = 3*@dirs+$descrlen;
+$totalwidth += $_ for (@colwidth);
+
+printf "%-${descrlen}s", "Test";
+for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ printf " %-$colwidth[$i]s", (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+}
+print "\n";
+print "-"x$totalwidth, "\n";
+for my $t (@subtests) {
+ printf "%-${descrlen}s", $descrs{$t};
+ my $firstr;
+ for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
+ printf " %-$colwidth[$i]s", format_times($r,$u,$s,$firstr);
+ $firstr = $r unless defined $firstr;
+ }
+ print "\n";
+}
diff --git a/t/perf/min_time.perl b/t/perf/min_time.perl
new file mode 100755
index 0000000000..c1a2717e07
--- /dev/null
+++ b/t/perf/min_time.perl
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+
+my $minrt = 1e100;
+my $min;
+
+while (<>) {
+ # [h:]m:s.xx U.xx S.xx
+ /^(?:(\d+):)?(\d+):(\d+(?:\.\d+)?) (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)$/
+ or die "bad input line: $_";
+ my $rt = ((defined $1 ? $1 : 0.0)*60+$2)*60+$3;
+ if ($rt < $minrt) {
+ $min = $_;
+ $minrt = $rt;
+ }
+}
+
+if (!defined $min) {
+ die "no input found";
+}
+
+print $min;
diff --git a/t/perf/p0000-perf-lib-sanity.sh b/t/perf/p0000-perf-lib-sanity.sh
new file mode 100755
index 0000000000..cf8e1efce7
--- /dev/null
+++ b/t/perf/p0000-perf-lib-sanity.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+test_description='Tests whether perf-lib facilities work'
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+test_perf 'test_perf_default_repo works' '
+ foo=$(git rev-parse HEAD) &&
+ test_export foo
+'
+
+test_checkout_worktree
+
+test_perf 'test_checkout_worktree works' '
+ wt=$(find . | wc -l) &&
+ idx=$(git ls-files | wc -l) &&
+ test $wt -gt $idx
+'
+
+baz=baz
+test_export baz
+
+test_expect_success 'test_export works' '
+ echo "$foo" &&
+ test "$foo" = "$(git rev-parse HEAD)" &&
+ echo "$baz" &&
+ test "$baz" = baz
+'
+
+test_perf 'export a weird var' '
+ bar="weird # variable" &&
+ test_export bar
+'
+
+test_expect_success 'test_export works with weird vars' '
+ echo "$bar" &&
+ test "$bar" = "weird # variable"
+'
+
+test_perf 'important variables available in subshells' '
+ test -n "$HOME" &&
+ test -n "$TEST_DIRECTORY" &&
+ test -n "$TRASH_DIRECTORY" &&
+ test -n "$GIT_BUILD_DIR"
+'
+
+test_perf 'test-lib-functions correctly loaded in subshells' '
+ : >a &&
+ test_path_is_file a &&
+ : >b &&
+ test_cmp a b
+'
+
+test_done
diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh
new file mode 100755
index 0000000000..4f71a63b0a
--- /dev/null
+++ b/t/perf/p0001-rev-list.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+test_description="Tests history walking performance"
+
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+test_perf 'rev-list --all' '
+ git rev-list --all >/dev/null
+'
+
+test_perf 'rev-list --all --objects' '
+ git rev-list --all --objects >/dev/null
+'
+
+test_done
diff --git a/t/perf/p4000-diff-algorithms.sh b/t/perf/p4000-diff-algorithms.sh
new file mode 100755
index 0000000000..7e00c9da47
--- /dev/null
+++ b/t/perf/p4000-diff-algorithms.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+test_description="Tests diff generation performance"
+
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+test_perf 'log -3000 (baseline)' '
+ git log -3000 >/dev/null
+'
+
+test_perf 'log --raw -3000 (tree-only)' '
+ git log --raw -3000 >/dev/null
+'
+
+test_perf 'log -p -3000 (Myers)' '
+ git log -p -3000 >/dev/null
+'
+
+test_perf 'log -p -3000 --histogram' '
+ git log -p -3000 --histogram >/dev/null
+'
+
+test_perf 'log -p -3000 --patience' '
+ git log -p -3000 --patience >/dev/null
+'
+
+test_done
diff --git a/t/perf/p7810-grep.sh b/t/perf/p7810-grep.sh
new file mode 100755
index 0000000000..9f4ade639f
--- /dev/null
+++ b/t/perf/p7810-grep.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+test_description="git-grep performance in various modes"
+
+. ./perf-lib.sh
+
+test_perf_large_repo
+test_checkout_worktree
+
+test_perf 'grep worktree, cheap regex' '
+ git grep some_nonexistent_string || :
+'
+test_perf 'grep worktree, expensive regex' '
+ git grep "^.* *some_nonexistent_string$" || :
+'
+test_perf 'grep --cached, cheap regex' '
+ git grep --cached some_nonexistent_string || :
+'
+test_perf 'grep --cached, expensive regex' '
+ git grep --cached "^.* *some_nonexistent_string$" || :
+'
+
+test_done
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
new file mode 100644
index 0000000000..5580c22812
--- /dev/null
+++ b/t/perf/perf-lib.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+#
+# Copyright (c) 2011 Thomas Rast
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# do the --tee work early; it otherwise confuses our careful
+# GIT_BUILD_DIR mangling
+case "$GIT_TEST_TEE_STARTED, $* " in
+done,*)
+ # do not redirect again
+ ;;
+*' --tee '*|*' --va'*)
+ mkdir -p test-results
+ BASE=test-results/$(basename "$0" .sh)
+ (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
+ echo $? > $BASE.exit) | tee $BASE.out
+ test "$(cat $BASE.exit)" = 0
+ exit
+ ;;
+esac
+
+TEST_DIRECTORY=$(pwd)/..
+TEST_OUTPUT_DIRECTORY=$(pwd)
+if test -z "$GIT_TEST_INSTALLED"; then
+ perf_results_prefix=
+else
+ perf_results_prefix=$(printf "%s" "${GIT_TEST_INSTALLED%/bin-wrappers}" | tr -c "[a-zA-Z0-9]" "[_*]")"."
+ # make the tested dir absolute
+ GIT_TEST_INSTALLED=$(cd "$GIT_TEST_INSTALLED" && pwd)
+fi
+
+TEST_NO_CREATE_REPO=t
+
+. ../test-lib.sh
+
+# Variables from test-lib that are normally internal to the tests; we
+# need to export them for test_perf subshells
+export TEST_DIRECTORY TRASH_DIRECTORY GIT_BUILD_DIR GIT_TEST_CMP
+
+perf_results_dir=$TEST_OUTPUT_DIRECTORY/test-results
+mkdir -p "$perf_results_dir"
+rm -f "$perf_results_dir"/$(basename "$0" .sh).subtests
+
+if test -z "$GIT_PERF_REPEAT_COUNT"; then
+ GIT_PERF_REPEAT_COUNT=3
+fi
+die_if_build_dir_not_repo () {
+ if ! ( cd "$TEST_DIRECTORY/.." &&
+ git rev-parse --build-dir >/dev/null 2>&1 ); then
+ error "No $1 defined, and your build directory is not a repo"
+ fi
+}
+
+if test -z "$GIT_PERF_REPO"; then
+ die_if_build_dir_not_repo '$GIT_PERF_REPO'
+ GIT_PERF_REPO=$TEST_DIRECTORY/..
+fi
+if test -z "$GIT_PERF_LARGE_REPO"; then
+ die_if_build_dir_not_repo '$GIT_PERF_LARGE_REPO'
+ GIT_PERF_LARGE_REPO=$TEST_DIRECTORY/..
+fi
+
+test_perf_create_repo_from () {
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 parameters to test-create-repo"
+ repo="$1"
+ source="$2"
+ source_git=$source/$(cd "$source" && git rev-parse --git-dir)
+ mkdir -p "$repo/.git"
+ (
+ cd "$repo/.git" &&
+ { cp -Rl "$source_git/objects" . 2>/dev/null ||
+ cp -R "$source_git/objects" .; } &&
+ for stuff in "$source_git"/*; do
+ case "$stuff" in
+ */objects|*/hooks|*/config)
+ ;;
+ *)
+ cp -R "$stuff" . || break
+ ;;
+ esac
+ done &&
+ cd .. &&
+ git init -q &&
+ mv .git/hooks .git/hooks-disabled 2>/dev/null
+ ) || error "failed to copy repository '$source' to '$repo'"
+}
+
+# call at least one of these to establish an appropriately-sized repository
+test_perf_default_repo () {
+ test_perf_create_repo_from "${1:-$TRASH_DIRECTORY}" "$GIT_PERF_REPO"
+}
+test_perf_large_repo () {
+ if test "$GIT_PERF_LARGE_REPO" = "$GIT_BUILD_DIR"; then
+ echo "warning: \$GIT_PERF_LARGE_REPO is \$GIT_BUILD_DIR." >&2
+ echo "warning: This will work, but may not be a sufficiently large repo" >&2
+ echo "warning: for representative measurements." >&2
+ fi
+ test_perf_create_repo_from "${1:-$TRASH_DIRECTORY}" "$GIT_PERF_LARGE_REPO"
+}
+test_checkout_worktree () {
+ git checkout-index -u -a ||
+ error "git checkout-index failed"
+}
+
+# Performance tests should never fail. If they do, stop immediately
+immediate=t
+
+test_run_perf_ () {
+ test_cleanup=:
+ test_export_="test_cleanup"
+ export test_cleanup test_export_
+ /usr/bin/time -f "%E %U %S" -o test_time.$i "$SHELL" -c '
+. '"$TEST_DIRECTORY"/test-lib-functions.sh'
+test_export () {
+ [ $# != 0 ] || return 0
+ test_export_="$test_export_\\|$1"
+ shift
+ test_export "$@"
+}
+'"$1"'
+ret=$?
+set | sed -n "s'"/'/'\\\\''/g"';s/^\\($test_export_\\)/export '"'&'"'/p" >test_vars
+exit $ret' >&3 2>&4
+ eval_ret=$?
+
+ if test $eval_ret = 0 || test -n "$expecting_failure"
+ then
+ test_eval_ "$test_cleanup"
+ . ./test_vars || error "failed to load updated environment"
+ fi
+ if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
+ echo ""
+ fi
+ return "$eval_ret"
+}
+
+
+test_perf () {
+ test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 or 3 parameters to test-expect-success"
+ export test_prereq
+ if ! test_skip "$@"
+ then
+ base=$(basename "$0" .sh)
+ echo "$test_count" >>"$perf_results_dir"/$base.subtests
+ echo "$1" >"$perf_results_dir"/$base.$test_count.descr
+ if test -z "$verbose"; then
+ echo -n "perf $test_count - $1:"
+ else
+ echo "perf $test_count - $1:"
+ fi
+ for i in $(seq 1 $GIT_PERF_REPEAT_COUNT); do
+ say >&3 "running: $2"
+ if test_run_perf_ "$2"
+ then
+ if test -z "$verbose"; then
+ echo -n " $i"
+ else
+ echo "* timing run $i/$GIT_PERF_REPEAT_COUNT:"
+ fi
+ else
+ test -z "$verbose" && echo
+ test_failure_ "$@"
+ break
+ fi
+ done
+ if test -z "$verbose"; then
+ echo " ok"
+ else
+ test_ok_ "$1"
+ fi
+ base="$perf_results_dir"/"$perf_results_prefix$(basename "$0" .sh)"."$test_count"
+ "$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".times
+ fi
+ echo >&3 ""
+}
+
+# We extend test_done to print timings at the end (./run disables this
+# and does it after running everything)
+test_at_end_hook_ () {
+ if test -z "$GIT_PERF_AGGREGATING_LATER"; then
+ ( cd "$TEST_DIRECTORY"/perf && ./aggregate.perl $(basename "$0") )
+ fi
+}
+
+test_export () {
+ export "$@"
+}
diff --git a/t/perf/run b/t/perf/run
new file mode 100755
index 0000000000..cfd70129bb
--- /dev/null
+++ b/t/perf/run
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+case "$1" in
+ --help)
+ echo "usage: $0 [other_git_tree...] [--] [test_scripts]"
+ exit 0
+ ;;
+esac
+
+die () {
+ echo >&2 "error: $*"
+ exit 1
+}
+
+run_one_dir () {
+ if test $# -eq 0; then
+ set -- p????-*.sh
+ fi
+ echo "=== Running $# tests in ${GIT_TEST_INSTALLED:-this tree} ==="
+ for t in "$@"; do
+ ./$t $GIT_TEST_OPTS
+ done
+}
+
+unpack_git_rev () {
+ rev=$1
+ mkdir -p build/$rev
+ (cd "$(git rev-parse --show-cdup)" && git archive --format=tar $rev) |
+ (cd build/$rev && tar x)
+}
+build_git_rev () {
+ rev=$1
+ cp ../../config.mak build/$rev/config.mak
+ (cd build/$rev && make $GIT_PERF_MAKE_OPTS) ||
+ die "failed to build revision '$mydir'"
+}
+
+run_dirs_helper () {
+ mydir=${1%/}
+ shift
+ while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do
+ shift
+ done
+ if test $# -gt 0 -a "$1" = --; then
+ shift
+ fi
+ if [ ! -d "$mydir" ]; then
+ rev=$(git rev-parse --verify "$mydir" 2>/dev/null) ||
+ die "'$mydir' is neither a directory nor a valid revision"
+ if [ ! -d build/$rev ]; then
+ unpack_git_rev $rev
+ fi
+ build_git_rev $rev
+ mydir=build/$rev
+ fi
+ if test "$mydir" = .; then
+ unset GIT_TEST_INSTALLED
+ else
+ GIT_TEST_INSTALLED="$mydir/bin-wrappers"
+ export GIT_TEST_INSTALLED
+ fi
+ run_one_dir "$@"
+}
+
+run_dirs () {
+ while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do
+ run_dirs_helper "$@"
+ shift
+ done
+}
+
+GIT_PERF_AGGREGATING_LATER=t
+export GIT_PERF_AGGREGATING_LATER
+
+cd "$(dirname $0)"
+. ../../GIT-BUILD-OPTIONS
+
+if test $# = 0 -o "$1" = -- -o -f "$1"; then
+ set -- . "$@"
+fi
+run_dirs "$@"
+./aggregate.perl "$@"
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index f4e8f43bae..ccb5435b2a 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -34,69 +34,69 @@ fi
# git init has been done in an empty repository.
# make sure it is empty.
-find .git/objects -type f -print >should-be-empty
-test_expect_success \
- '.git/objects should be empty after git init in an empty repo.' \
- 'cmp -s /dev/null should-be-empty'
+test_expect_success '.git/objects should be empty after git init in an empty repo' '
+ find .git/objects -type f -print >should-be-empty &&
+ test_line_count = 0 should-be-empty
+'
# also it should have 2 subdirectories; no fan-out anymore, pack, and info.
# 3 is counting "objects" itself
-find .git/objects -type d -print >full-of-directories
-test_expect_success \
- '.git/objects should have 3 subdirectories.' \
- 'test $(wc -l < full-of-directories) = 3'
+test_expect_success '.git/objects should have 3 subdirectories' '
+ find .git/objects -type d -print >full-of-directories &&
+ test_line_count = 3 full-of-directories
+'
################################################################
# Test harness
test_expect_success 'success is reported like this' '
- :
+ :
'
test_expect_failure 'pretend we have a known breakage' '
- false
+ 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 &&
-sed -e 's/^> //' >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)
+ 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 &&
+ sed -e 's/^> //' >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' '
- test_have_prereq HAVEIT &&
- haveit=yes
+ test_have_prereq HAVEIT &&
+ haveit=yes
'
donthaveit=yes
test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' '
- donthaveit=no
+ donthaveit=no
'
if test $haveit$donthaveit != yesyes
then
@@ -107,17 +107,17 @@ 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
+ 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
+ donthaveit=no
'
donthaveiteither=yes
test_expect_success DONTHAVEIT,HAVEIT 'unmet prerequisites causes test to be skipped' '
- donthaveiteither=no
+ donthaveiteither=no
'
if test $haveit$donthaveit$donthaveiteither != yesyesyes
then
@@ -127,7 +127,7 @@ fi
clean=no
test_expect_success 'tests clean up after themselves' '
- test_when_finished clean=yes
+ test_when_finished clean=yes
'
if test $clean != yes
@@ -137,106 +137,100 @@ then
fi
test_expect_success 'tests clean up even on failures' "
- mkdir failing-cleanup &&
- (cd failing-cleanup &&
- cat >failing-cleanup.sh <<EOF &&
-#!$SHELL_PATH
-
-test_description='Failing tests with cleanup commands'
-
-# Point to the t/test-lib.sh, which isn't in ../ as usual
-TEST_DIRECTORY=\"$TEST_DIRECTORY\"
-. \"\$TEST_DIRECTORY\"/test-lib.sh
-
-test_expect_success 'tests clean up even after a failure' '
- touch clean-after-failure &&
- test_when_finished rm clean-after-failure &&
- (exit 1)
-'
-
-test_expect_success 'failure to clean up causes the test to fail' '
- test_when_finished \"(exit 2)\"
-'
-
-test_done
-EOF
- chmod +x failing-cleanup.sh &&
- test_must_fail ./failing-cleanup.sh >out 2>err &&
- ! test -s err &&
- ! test -f \"trash directory.failing-cleanup/clean-after-failure\" &&
-sed -e 's/Z$//' -e 's/^> //' >expect <<\EOF &&
-> not ok - 1 tests clean up even after a failure
-> # Z
-> # touch clean-after-failure &&
-> # test_when_finished rm clean-after-failure &&
-> # (exit 1)
-> # Z
-> not ok - 2 failure to clean up causes the test to fail
-> # Z
-> # test_when_finished \"(exit 2)\"
-> # Z
-> # failed 2 among 2 test(s)
-> 1..2
-EOF
- test_cmp expect out)
+ mkdir failing-cleanup &&
+ (
+ cd failing-cleanup &&
+
+ cat >failing-cleanup.sh <<-EOF &&
+ #!$SHELL_PATH
+
+ test_description='Failing tests with cleanup commands'
+
+ # Point to the t/test-lib.sh, which isn't in ../ as usual
+ TEST_DIRECTORY=\"$TEST_DIRECTORY\"
+ . \"\$TEST_DIRECTORY\"/test-lib.sh
+
+ test_expect_success 'tests clean up even after a failure' '
+ touch clean-after-failure &&
+ test_when_finished rm clean-after-failure &&
+ (exit 1)
+ '
+ test_expect_success 'failure to clean up causes the test to fail' '
+ test_when_finished \"(exit 2)\"
+ '
+ test_done
+
+ EOF
+
+ chmod +x failing-cleanup.sh &&
+ test_must_fail ./failing-cleanup.sh >out 2>err &&
+ ! test -s err &&
+ ! test -f \"trash directory.failing-cleanup/clean-after-failure\" &&
+ sed -e 's/Z$//' -e 's/^> //' >expect <<-\\EOF &&
+ > not ok - 1 tests clean up even after a failure
+ > # Z
+ > # touch clean-after-failure &&
+ > # test_when_finished rm clean-after-failure &&
+ > # (exit 1)
+ > # Z
+ > not ok - 2 failure to clean up causes the test to fail
+ > # Z
+ > # test_when_finished \"(exit 2)\"
+ > # Z
+ > # failed 2 among 2 test(s)
+ > 1..2
+ EOF
+ test_cmp expect out
+ )
"
################################################################
# Basics of the basics
# updating a new file without --add should fail.
-test_expect_success 'git update-index without --add should fail adding.' '
- test_must_fail git update-index should-be-empty
+test_expect_success 'git update-index without --add should fail adding' '
+ test_must_fail git update-index should-be-empty
'
# and with --add it should succeed, even if it is empty (it used to fail).
-test_expect_success \
- 'git update-index with --add should succeed.' \
- 'git update-index --add should-be-empty'
+test_expect_success 'git update-index with --add should succeed' '
+ git update-index --add should-be-empty
+'
-test_expect_success \
- 'writing tree out with git write-tree' \
- 'tree=$(git write-tree)'
+test_expect_success 'writing tree out with git write-tree' '
+ tree=$(git write-tree)
+'
# we know the shape and contents of the tree and know the object ID for it.
-test_expect_success \
- 'validate object ID of a known tree.' \
- 'test "$tree" = 7bb943559a305bdd6bdee2cef6e5df2413c3d30a'
+test_expect_success 'validate object ID of a known tree' '
+ test "$tree" = 7bb943559a305bdd6bdee2cef6e5df2413c3d30a
+ '
# Removing paths.
-rm -f should-be-empty full-of-directories
-test_expect_success 'git update-index without --remove should fail removing.' '
- test_must_fail git update-index should-be-empty
+test_expect_success 'git update-index without --remove should fail removing' '
+ rm -f should-be-empty full-of-directories &&
+ test_must_fail git update-index should-be-empty
'
-test_expect_success \
- 'git update-index with --remove should be able to remove.' \
- 'git update-index --remove should-be-empty'
+test_expect_success 'git update-index with --remove should be able to remove' '
+ git update-index --remove should-be-empty
+'
# Empty tree can be written with recent write-tree.
-test_expect_success \
- 'git write-tree should be able to write an empty tree.' \
- 'tree=$(git write-tree)'
+test_expect_success 'git write-tree should be able to write an empty tree' '
+ tree=$(git write-tree)
+'
-test_expect_success \
- 'validate object ID of a known tree.' \
- 'test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904'
+test_expect_success 'validate object ID of a known tree' '
+ test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904
+'
# Various types of objects
+
# Some filesystems do not support symblic links; on such systems
# some expected values are different
-mkdir path2 path3 path3/subp3
-paths='path0 path2/file2 path3/file3 path3/subp3/file3'
-for p in $paths
-do
- echo "hello $p" >$p
-done
if test_have_prereq SYMLINKS
then
- for p in $paths
- do
- ln -s "hello $p" ${p}sym
- done
expectfilter=cat
expectedtree=087704a96baf1c2d1c869a8b084481e121c88b5b
expectedptree1=21ae8269cacbe57ae09138dcc3a2887f904d02b3
@@ -248,135 +242,154 @@ else
expectedptree2=ce580448f0148b985a513b693fdf7d802cacb44f
fi
-test_expect_success \
- 'adding various types of objects with git update-index --add.' \
- 'find path* ! -type d -print | xargs git update-index --add'
+
+test_expect_success 'adding various types of objects with git update-index --add' '
+ mkdir path2 path3 path3/subp3 &&
+ paths="path0 path2/file2 path3/file3 path3/subp3/file3" &&
+ (
+ for p in $paths
+ do
+ echo "hello $p" >$p || exit 1
+ if test_have_prereq SYMLINKS
+ then
+ ln -s "hello $p" ${p}sym || exit 1
+ fi
+ done
+ ) &&
+ find path* ! -type d -print | xargs git update-index --add
+'
# Show them and see that matches what we expect.
-test_expect_success \
- 'showing stage with git ls-files --stage' \
- 'git ls-files --stage >current'
-
-$expectfilter >expected <<\EOF
-100644 f87290f8eb2cbbea7857214459a0739927eab154 0 path0
-120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0 path0sym
-100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0 path2/file2
-120000 d8ce161addc5173867a3c3c730924388daedbc38 0 path2/file2sym
-100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0 path3/file3
-120000 8599103969b43aff7e430efea79ca4636466794f 0 path3/file3sym
-100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0 path3/subp3/file3
-120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0 path3/subp3/file3sym
-EOF
-test_expect_success \
- 'validate git ls-files output for a known tree.' \
- 'test_cmp expected current'
-
-test_expect_success \
- 'writing tree out with git write-tree.' \
- 'tree=$(git write-tree)'
-test_expect_success \
- 'validate object ID for a known tree.' \
- 'test "$tree" = "$expectedtree"'
-
-test_expect_success \
- 'showing tree with git ls-tree' \
- 'git ls-tree $tree >current'
-cat >expected <<\EOF
-100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
-120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
-040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2
-040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3
-EOF
-test_expect_success SYMLINKS \
- 'git ls-tree output for a known tree.' \
- 'test_cmp expected current'
+test_expect_success 'showing stage with git ls-files --stage' '
+ git ls-files --stage >current
+'
+
+test_expect_success 'validate git ls-files output for a known tree' '
+ $expectfilter >expected <<-\EOF &&
+ 100644 f87290f8eb2cbbea7857214459a0739927eab154 0 path0
+ 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0 path0sym
+ 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0 path2/file2
+ 120000 d8ce161addc5173867a3c3c730924388daedbc38 0 path2/file2sym
+ 100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0 path3/file3
+ 120000 8599103969b43aff7e430efea79ca4636466794f 0 path3/file3sym
+ 100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0 path3/subp3/file3
+ 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0 path3/subp3/file3sym
+ EOF
+ test_cmp expected current
+'
+
+test_expect_success 'writing tree out with git write-tree' '
+ tree=$(git write-tree)
+'
+
+test_expect_success 'validate object ID for a known tree' '
+ test "$tree" = "$expectedtree"
+'
+
+test_expect_success 'showing tree with git ls-tree' '
+ git ls-tree $tree >current
+'
+
+test_expect_success SYMLINKS 'git ls-tree output for a known tree' '
+ cat >expected <<-\EOF &&
+ 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
+ 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
+ 040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2
+ 040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3
+ EOF
+ test_cmp expected current
+'
# This changed in ls-tree pathspec change -- recursive does
# not show tree nodes anymore.
-test_expect_success \
- 'showing tree with git ls-tree -r' \
- 'git ls-tree -r $tree >current'
-$expectfilter >expected <<\EOF
-100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
-120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
-100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2
-120000 blob d8ce161addc5173867a3c3c730924388daedbc38 path2/file2sym
-100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376 path3/file3
-120000 blob 8599103969b43aff7e430efea79ca4636466794f path3/file3sym
-100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3
-120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym
-EOF
-test_expect_success \
- 'git ls-tree -r output for a known tree.' \
- 'test_cmp expected current'
+test_expect_success 'showing tree with git ls-tree -r' '
+ git ls-tree -r $tree >current
+'
+
+test_expect_success 'git ls-tree -r output for a known tree' '
+ $expectfilter >expected <<-\EOF &&
+ 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
+ 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
+ 100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2
+ 120000 blob d8ce161addc5173867a3c3c730924388daedbc38 path2/file2sym
+ 100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376 path3/file3
+ 120000 blob 8599103969b43aff7e430efea79ca4636466794f path3/file3sym
+ 100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3
+ 120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym
+ EOF
+ test_cmp expected current
+'
# But with -r -t we can have both.
-test_expect_success \
- 'showing tree with git ls-tree -r -t' \
- 'git ls-tree -r -t $tree >current'
-cat >expected <<\EOF
-100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
-120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
-040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2
-100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2
-120000 blob d8ce161addc5173867a3c3c730924388daedbc38 path2/file2sym
-040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3
-100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376 path3/file3
-120000 blob 8599103969b43aff7e430efea79ca4636466794f path3/file3sym
-040000 tree 3c5e5399f3a333eddecce7a9b9465b63f65f51e2 path3/subp3
-100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3
-120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym
-EOF
-test_expect_success SYMLINKS \
- 'git ls-tree -r output for a known tree.' \
- 'test_cmp expected current'
-
-test_expect_success \
- 'writing partial tree out with git write-tree --prefix.' \
- 'ptree=$(git write-tree --prefix=path3)'
-test_expect_success \
- 'validate object ID for a known tree.' \
- 'test "$ptree" = "$expectedptree1"'
-
-test_expect_success \
- 'writing partial tree out with git write-tree --prefix.' \
- 'ptree=$(git write-tree --prefix=path3/subp3)'
-test_expect_success \
- 'validate object ID for a known tree.' \
- 'test "$ptree" = "$expectedptree2"'
-
-cat >badobjects <<EOF
-100644 blob 1000000000000000000000000000000000000000 dir/file1
-100644 blob 2000000000000000000000000000000000000000 dir/file2
-100644 blob 3000000000000000000000000000000000000000 dir/file3
-100644 blob 4000000000000000000000000000000000000000 dir/file4
-100644 blob 5000000000000000000000000000000000000000 dir/file5
-EOF
+test_expect_success 'showing tree with git ls-tree -r -t' '
+ git ls-tree -r -t $tree >current
+'
-rm .git/index
-test_expect_success \
- 'put invalid objects into the index.' \
- 'git update-index --index-info < badobjects'
+test_expect_success SYMLINKS 'git ls-tree -r output for a known tree' '
+ cat >expected <<-\EOF &&
+ 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
+ 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
+ 040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2
+ 100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2
+ 120000 blob d8ce161addc5173867a3c3c730924388daedbc38 path2/file2sym
+ 040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3
+ 100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376 path3/file3
+ 120000 blob 8599103969b43aff7e430efea79ca4636466794f path3/file3sym
+ 040000 tree 3c5e5399f3a333eddecce7a9b9465b63f65f51e2 path3/subp3
+ 100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3
+ 120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym
+ EOF
+ test_cmp expected current
+'
-test_expect_success 'writing this tree without --missing-ok.' '
- test_must_fail git write-tree
+test_expect_success 'writing partial tree out with git write-tree --prefix' '
+ ptree=$(git write-tree --prefix=path3)
'
-test_expect_success \
- 'writing this tree with --missing-ok.' \
- 'git write-tree --missing-ok'
+test_expect_success 'validate object ID for a known tree' '
+ test "$ptree" = "$expectedptree1"
+'
+
+test_expect_success 'writing partial tree out with git write-tree --prefix' '
+ ptree=$(git write-tree --prefix=path3/subp3)
+'
+
+test_expect_success 'validate object ID for a known tree' '
+ test "$ptree" = "$expectedptree2"
+'
+
+test_expect_success 'put invalid objects into the index' '
+ rm -f .git/index &&
+ cat >badobjects <<-\EOF &&
+ 100644 blob 1000000000000000000000000000000000000000 dir/file1
+ 100644 blob 2000000000000000000000000000000000000000 dir/file2
+ 100644 blob 3000000000000000000000000000000000000000 dir/file3
+ 100644 blob 4000000000000000000000000000000000000000 dir/file4
+ 100644 blob 5000000000000000000000000000000000000000 dir/file5
+ EOF
+ git update-index --index-info <badobjects
+'
+
+test_expect_success 'writing this tree without --missing-ok' '
+ test_must_fail git write-tree
+'
+
+test_expect_success 'writing this tree with --missing-ok' '
+ git write-tree --missing-ok
+'
################################################################
-rm .git/index
-test_expect_success \
- 'git read-tree followed by write-tree should be idempotent.' \
- 'git read-tree $tree &&
- test -f .git/index &&
- newtree=$(git write-tree) &&
- test "$newtree" = "$tree"'
-
-$expectfilter >expected <<\EOF
+test_expect_success 'git read-tree followed by write-tree should be idempotent' '
+ rm -f .git/index
+ git read-tree $tree &&
+ test -f .git/index &&
+ newtree=$(git write-tree) &&
+ test "$newtree" = "$tree"
+'
+
+test_expect_success 'validate git diff-files output for a know cache/work tree state' '
+ $expectfilter >expected <<\EOF &&
:100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M path0
:120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M path0sym
:100644 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0000000000000000000000000000000000000000 M path2/file2
@@ -386,45 +399,47 @@ $expectfilter >expected <<\EOF
:100644 100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0000000000000000000000000000000000000000 M path3/subp3/file3
:120000 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0000000000000000000000000000000000000000 M path3/subp3/file3sym
EOF
-test_expect_success \
- 'validate git diff-files output for a know cache/work tree state.' \
- 'git diff-files >current && test_cmp current expected >/dev/null'
+ git diff-files >current &&
+ test_cmp current expected
+'
-test_expect_success \
- 'git update-index --refresh should succeed.' \
- 'git update-index --refresh'
+test_expect_success 'git update-index --refresh should succeed' '
+ git update-index --refresh
+'
-test_expect_success \
- 'no diff after checkout and git update-index --refresh.' \
- 'git diff-files >current && cmp -s current /dev/null'
+test_expect_success 'no diff after checkout and git update-index --refresh' '
+ git diff-files >current &&
+ cmp -s current /dev/null
+'
################################################################
P=$expectedtree
-test_expect_success \
- 'git commit-tree records the correct tree in a commit.' \
- 'commit0=$(echo NO | git commit-tree $P) &&
- tree=$(git show --pretty=raw $commit0 |
- sed -n -e "s/^tree //p" -e "/^author /q") &&
- test "z$tree" = "z$P"'
-
-test_expect_success \
- 'git commit-tree records the correct parent in a commit.' \
- 'commit1=$(echo NO | git commit-tree $P -p $commit0) &&
- parent=$(git show --pretty=raw $commit1 |
- sed -n -e "s/^parent //p" -e "/^author /q") &&
- test "z$commit0" = "z$parent"'
-
-test_expect_success \
- 'git commit-tree omits duplicated parent in a commit.' \
- 'commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) &&
- parent=$(git show --pretty=raw $commit2 |
- sed -n -e "s/^parent //p" -e "/^author /q" |
- sort -u) &&
- test "z$commit0" = "z$parent" &&
- numparent=$(git show --pretty=raw $commit2 |
- sed -n -e "s/^parent //p" -e "/^author /q" |
- wc -l) &&
- test $numparent = 1'
+
+test_expect_success 'git commit-tree records the correct tree in a commit' '
+ commit0=$(echo NO | git commit-tree $P) &&
+ tree=$(git show --pretty=raw $commit0 |
+ sed -n -e "s/^tree //p" -e "/^author /q") &&
+ test "z$tree" = "z$P"
+'
+
+test_expect_success 'git commit-tree records the correct parent in a commit' '
+ commit1=$(echo NO | git commit-tree $P -p $commit0) &&
+ parent=$(git show --pretty=raw $commit1 |
+ sed -n -e "s/^parent //p" -e "/^author /q") &&
+ test "z$commit0" = "z$parent"
+'
+
+test_expect_success 'git commit-tree omits duplicated parent in a commit' '
+ commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) &&
+ parent=$(git show --pretty=raw $commit2 |
+ sed -n -e "s/^parent //p" -e "/^author /q" |
+ sort -u) &&
+ test "z$commit0" = "z$parent" &&
+ numparent=$(git show --pretty=raw $commit2 |
+ sed -n -e "s/^parent //p" -e "/^author /q" |
+ wc -l) &&
+ test $numparent = 1
+'
test_expect_success 'update-index D/F conflict' '
mv path0 tmp &&
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index f19e6510d0..e50f0f742f 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -153,4 +153,41 @@ test_expect_success 'filter shell-escaped filenames' '
:
'
+test_expect_success 'required filter success' '
+ git config filter.required.smudge cat &&
+ git config filter.required.clean cat &&
+ git config filter.required.required true &&
+
+ echo "*.r filter=required" >.gitattributes &&
+
+ echo test >test.r &&
+ git add test.r &&
+ rm -f test.r &&
+ git checkout -- test.r
+'
+
+test_expect_success 'required filter smudge failure' '
+ git config filter.failsmudge.smudge false &&
+ git config filter.failsmudge.clean cat &&
+ git config filter.failsmudge.required true &&
+
+ echo "*.fs filter=failsmudge" >.gitattributes &&
+
+ echo test >test.fs &&
+ git add test.fs &&
+ rm -f test.fs &&
+ test_must_fail git checkout -- test.fs
+'
+
+test_expect_success 'required filter clean failure' '
+ git config filter.failclean.smudge cat &&
+ git config filter.failclean.clean false &&
+ git config filter.failclean.required true &&
+
+ echo "*.fc filter=failclean" >.gitattributes &&
+
+ echo test >test.fc &&
+ test_must_fail git add test.fc
+'
+
test_done
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index a1e4616feb..e3f354a45e 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -10,7 +10,10 @@ test_description='our own option parser'
cat > expect << EOF
usage: test-parse-options <options>
- -b, --boolean get a boolean
+ --yes get a boolean
+ -D, --no-doubt begins with 'no-'
+ -B, --no-fear be brave
+ -b, --boolean increment by one
-4, --or4 bitwise-or boolean with ...0100
--neg-or4 same as --no-or4
@@ -53,6 +56,59 @@ test_expect_success 'test help' '
mv expect expect.err
+cat >expect.template <<EOF
+boolean: 0
+integer: 0
+timestamp: 0
+string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+file: (not set)
+EOF
+
+check() {
+ what="$1" &&
+ shift &&
+ expect="$1" &&
+ shift &&
+ sed "s/^$what .*/$what $expect/" <expect.template >expect &&
+ test-parse-options $* >output 2>output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+}
+
+check_unknown() {
+ case "$1" in
+ --*)
+ echo error: unknown option \`${1#--}\' >expect ;;
+ -*)
+ echo error: unknown switch \`${1#-}\' >expect ;;
+ esac &&
+ cat expect.err >>expect &&
+ test_must_fail test-parse-options $* >output 2>output.err &&
+ test ! -s output &&
+ test_cmp expect output.err
+}
+
+test_expect_success 'OPT_BOOL() #1' 'check boolean: 1 --yes'
+test_expect_success 'OPT_BOOL() #2' 'check boolean: 1 --no-doubt'
+test_expect_success 'OPT_BOOL() #3' 'check boolean: 1 -D'
+test_expect_success 'OPT_BOOL() #4' 'check boolean: 1 --no-fear'
+test_expect_success 'OPT_BOOL() #5' 'check boolean: 1 -B'
+
+test_expect_success 'OPT_BOOL() is idempotent #1' 'check boolean: 1 --yes --yes'
+test_expect_success 'OPT_BOOL() is idempotent #2' 'check boolean: 1 -DB'
+
+test_expect_success 'OPT_BOOL() negation #1' 'check boolean: 0 -D --no-yes'
+test_expect_success 'OPT_BOOL() negation #2' 'check boolean: 0 -D --no-no-doubt'
+
+test_expect_success 'OPT_BOOL() no negation #1' 'check_unknown --fear'
+test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown --no-no-fear'
+
+test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
+
cat > expect << EOF
boolean: 2
integer: 1729
@@ -180,6 +236,16 @@ test_expect_success 'detect possible typos' '
test_cmp typo.err output.err
'
+cat > typo.err << EOF
+error: did you mean \`--ambiguous\` (with two dashes ?)
+EOF
+
+test_expect_success 'detect possible typos' '
+ test_must_fail test-parse-options -ambiguous > output 2> output.err &&
+ test ! -s output &&
+ test_cmp typo.err output.err
+'
+
cat > expect <<EOF
boolean: 0
integer: 0
@@ -296,7 +362,7 @@ test_expect_success 'OPT_NEGBIT() works' '
test_cmp expect output
'
-test_expect_success 'OPT_BOOLEAN() with PARSE_OPT_NODASH works' '
+test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' '
test-parse-options + + + + + + > output 2> output.err &&
test ! -s output.err &&
test_cmp expect output
diff --git a/t/t0204-gettext-reencode-sanity.sh b/t/t0204-gettext-reencode-sanity.sh
index 189af90c02..8437e51eb5 100755
--- a/t/t0204-gettext-reencode-sanity.sh
+++ b/t/t0204-gettext-reencode-sanity.sh
@@ -7,6 +7,10 @@ test_description="Gettext reencoding of our *.po/*.mo files works"
. ./lib-gettext.sh
+# The constants used in a tricky observation for undefined behaviour
+RUNES="TILRAUN: ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ"
+PUNTS="TILRAUN: ?? ???? ??? ?? ???? ?? ??? ????? ??????????? ??? ?? ????"
+MSGKEY="TEST: Old English Runes"
test_expect_success GETTEXT_LOCALE 'gettext: Emitting UTF-8 from our UTF-8 *.mo files / Icelandic' '
printf "TILRAUN: Halló Heimur!" >expect &&
@@ -15,8 +19,8 @@ test_expect_success GETTEXT_LOCALE 'gettext: Emitting UTF-8 from our UTF-8 *.mo
'
test_expect_success GETTEXT_LOCALE 'gettext: Emitting UTF-8 from our UTF-8 *.mo files / Runes' '
- printf "TILRAUN: ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ" >expect &&
- LANGUAGE=is LC_ALL="$is_IS_locale" gettext "TEST: Old English Runes" >actual &&
+ printf "%s" "$RUNES" >expect &&
+ LANGUAGE=is LC_ALL="$is_IS_locale" gettext "$MSGKEY" >actual &&
test_cmp expect actual
'
@@ -26,18 +30,23 @@ test_expect_success GETTEXT_ISO_LOCALE 'gettext: Emitting ISO-8859-1 from our UT
test_cmp expect actual
'
-test_expect_success GETTEXT_ISO_LOCALE 'gettext: Emitting ISO-8859-1 from our UTF-8 *.mo files / Runes' '
- LANGUAGE=is LC_ALL="$is_IS_iso_locale" gettext "TEST: Old English Runes" >runes &&
-
- if grep "^TEST: Old English Runes$" runes
- then
- say "Your system can not handle this complexity and returns the string as-is"
- else
- # Both Solaris and GNU libintl will return this stream of
- # question marks, so it is s probably portable enough
- printf "TILRAUN: ?? ???? ??? ?? ???? ?? ??? ????? ??????????? ??? ?? ????" >runes-expect &&
- test_cmp runes-expect runes
- fi
+test_expect_success GETTEXT_ISO_LOCALE 'gettext: impossible ISO-8859-1 output' '
+ LANGUAGE=is LC_ALL="$is_IS_iso_locale" gettext "$MSGKEY" >runes &&
+ case "$(cat runes)" in
+ "$MSGKEY")
+ say "Your system gives back the key to message catalog"
+ ;;
+ "$PUNTS")
+ say "Your system replaces an impossible character with ?"
+ ;;
+ "$RUNES")
+ say "Your system gives back the raw message for an impossible request"
+ ;;
+ *)
+ say "We never saw the error behaviour your system exhibits"
+ false
+ ;;
+ esac
'
test_expect_success GETTEXT_LOCALE 'gettext: Fetching a UTF-8 msgid -> UTF-8' '
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
index 8621ab036f..20e28e34e7 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -8,10 +8,13 @@ test_expect_success 'setup helper scripts' '
cat >dump <<-\EOF &&
whoami=`echo $0 | sed s/.*git-credential-//`
echo >&2 "$whoami: $*"
- while IFS== read key value; do
+ OIFS=$IFS
+ IFS==
+ while read key value; do
echo >&2 "$whoami: $key=$value"
eval "$key=$value"
done
+ IFS=$OIFS
EOF
write_script git-credential-useless <<-\EOF &&
diff --git a/t/t1051-large-conversion.sh b/t/t1051-large-conversion.sh
new file mode 100755
index 0000000000..8b7640b3ba
--- /dev/null
+++ b/t/t1051-large-conversion.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+test_description='test conversion filters on large files'
+. ./test-lib.sh
+
+set_attr() {
+ test_when_finished 'rm -f .gitattributes' &&
+ echo "* $*" >.gitattributes
+}
+
+check_input() {
+ git read-tree --empty &&
+ git add small large &&
+ git cat-file blob :small >small.index &&
+ git cat-file blob :large | head -n 1 >large.index &&
+ test_cmp small.index large.index
+}
+
+check_output() {
+ rm -f small large &&
+ git checkout small large &&
+ head -n 1 large >large.head &&
+ test_cmp small large.head
+}
+
+test_expect_success 'setup input tests' '
+ printf "\$Id: foo\$\\r\\n" >small &&
+ cat small small >large &&
+ git config core.bigfilethreshold 20 &&
+ git config filter.test.clean "sed s/.*/CLEAN/"
+'
+
+test_expect_success 'autocrlf=true converts on input' '
+ test_config core.autocrlf true &&
+ check_input
+'
+
+test_expect_success 'eol=crlf converts on input' '
+ set_attr eol=crlf &&
+ check_input
+'
+
+test_expect_success 'ident converts on input' '
+ set_attr ident &&
+ check_input
+'
+
+test_expect_success 'user-defined filters convert on input' '
+ set_attr filter=test &&
+ check_input
+'
+
+test_expect_success 'setup output tests' '
+ echo "\$Id\$" >small &&
+ cat small small >large &&
+ git add small large &&
+ git config core.bigfilethreshold 7 &&
+ git config filter.test.smudge "sed s/.*/SMUDGE/"
+'
+
+test_expect_success 'autocrlf=true converts on output' '
+ test_config core.autocrlf true &&
+ check_output
+'
+
+test_expect_success 'eol=crlf converts on output' '
+ set_attr eol=crlf &&
+ check_output
+'
+
+test_expect_success 'user-defined filters convert on output' '
+ set_attr filter=test &&
+ check_output
+'
+
+test_expect_success 'ident converts on output' '
+ set_attr ident &&
+ rm -f small large &&
+ git checkout small large &&
+ sed -n "s/Id: .*/Id: SHA/p" <small >small.clean &&
+ head -n 1 large >large.head &&
+ sed -n "s/Id: .*/Id: SHA/p" <large.head >large.clean &&
+ test_cmp small.clean large.clean
+'
+
+test_done
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index 5e29e13782..9356beaf4b 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -156,7 +156,7 @@ Updating VARIABLE..VARIABLE
FASTFORWARD (no commit created; -m option ignored)
example | 1 +
hello | 1 +
- 2 files changed, 2 insertions(+), 0 deletions(-)
+ 2 files changed, 2 insertions(+)
EOF
test_expect_success 'git resolve' '
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 0690e0edf4..36e227b3bb 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -451,13 +451,21 @@ test_expect_success 'refer config from subdirectory' '
mkdir x &&
(
cd x &&
- echo strasse >expect
+ echo strasse >expect &&
git config --get --file ../other-config ein.bahn >actual &&
test_cmp expect actual
)
'
+test_expect_success 'refer config from subdirectory via GIT_CONFIG' '
+ (
+ cd x &&
+ GIT_CONFIG=../other-config git config --get ein.bahn >actual &&
+ test_cmp expect actual
+ )
+'
+
cat > expect << EOF
[ein]
bahn = strasse
@@ -960,4 +968,52 @@ test_expect_success 'git -c complains about empty key and value' '
test_must_fail git -c "" rev-parse
'
+test_expect_success 'git config --edit works' '
+ git config -f tmp test.value no &&
+ echo test.value=yes >expect &&
+ GIT_EDITOR="echo [test]value=yes >" git config -f tmp --edit &&
+ git config -f tmp --list >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git config --edit respects core.editor' '
+ git config -f tmp test.value no &&
+ echo test.value=yes >expect &&
+ test_config core.editor "echo [test]value=yes >" &&
+ git config -f tmp --edit &&
+ git config -f tmp --list >actual &&
+ test_cmp expect actual
+'
+
+# malformed configuration files
+test_expect_success 'barf on syntax error' '
+ cat >.git/config <<-\EOF &&
+ # broken section line
+ [section]
+ key garbage
+ EOF
+ test_must_fail git config --get section.key >actual 2>error &&
+ grep " line 3 " error
+'
+
+test_expect_success 'barf on incomplete section header' '
+ cat >.git/config <<-\EOF &&
+ # broken section line
+ [section
+ key = value
+ EOF
+ test_must_fail git config --get section.key >actual 2>error &&
+ grep " line 2 " error
+'
+
+test_expect_success 'barf on incomplete string' '
+ cat >.git/config <<-\EOF &&
+ # broken section line
+ [section]
+ key = "value string
+ EOF
+ test_must_fail git config --get section.key >actual 2>error &&
+ grep " line 3 " error
+'
+
test_done
diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
new file mode 100755
index 0000000000..4b1cbaa028
--- /dev/null
+++ b/t/t1305-config-include.sh
@@ -0,0 +1,134 @@
+#!/bin/sh
+
+test_description='test config file include directives'
+. ./test-lib.sh
+
+test_expect_success 'include file by absolute path' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = \"$(pwd)/one\"" >.gitconfig &&
+ echo 1 >expect &&
+ git config test.one >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'include file by relative path' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = one" >.gitconfig &&
+ echo 1 >expect &&
+ git config test.one >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'chained relative paths' '
+ mkdir subdir &&
+ echo "[test]three = 3" >subdir/three &&
+ echo "[include]path = three" >subdir/two &&
+ echo "[include]path = subdir/two" >.gitconfig &&
+ echo 3 >expect &&
+ git config test.three >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'include options can still be examined' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = one" >.gitconfig &&
+ echo one >expect &&
+ git config include.path >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'listing includes option and expansion' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = one" >.gitconfig &&
+ cat >expect <<-\EOF &&
+ include.path=one
+ test.one=1
+ EOF
+ git config --list >actual.full &&
+ grep -v ^core actual.full >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'single file lookup does not expand includes by default' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = one" >.gitconfig &&
+ test_must_fail git config -f .gitconfig test.one &&
+ test_must_fail git config --global test.one &&
+ echo 1 >expect &&
+ git config --includes -f .gitconfig test.one >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'single file list does not expand includes by default' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = one" >.gitconfig &&
+ echo "include.path=one" >expect &&
+ git config -f .gitconfig --list >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'writing config file does not expand includes' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = one" >.gitconfig &&
+ git config test.two 2 &&
+ echo 2 >expect &&
+ git config --no-includes test.two >actual &&
+ test_cmp expect actual &&
+ test_must_fail git config --no-includes test.one
+'
+
+test_expect_success 'config modification does not affect includes' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = one" >.gitconfig &&
+ git config test.one 2 &&
+ echo 1 >expect &&
+ git config -f one test.one >actual &&
+ test_cmp expect actual &&
+ cat >expect <<-\EOF &&
+ 1
+ 2
+ EOF
+ git config --get-all test.one >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'missing include files are ignored' '
+ cat >.gitconfig <<-\EOF &&
+ [include]path = foo
+ [test]value = yes
+ EOF
+ echo yes >expect &&
+ git config test.value >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'absolute includes from command line work' '
+ echo "[test]one = 1" >one &&
+ echo 1 >expect &&
+ git -c include.path="$PWD/one" config test.one >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'relative includes from command line fail' '
+ echo "[test]one = 1" >one &&
+ test_must_fail git -c include.path=one config test.one
+'
+
+test_expect_success 'include cycles are detected' '
+ cat >.gitconfig <<-\EOF &&
+ [test]value = gitconfig
+ [include]path = cycle
+ EOF
+ cat >cycle <<-\EOF &&
+ [test]value = cycle
+ [include]path = .gitconfig
+ EOF
+ cat >expect <<-\EOF &&
+ gitconfig
+ cycle
+ EOF
+ test_must_fail git config --get-all test.value 2>stderr &&
+ grep "exceeded maximum include depth" stderr
+'
+
+test_done
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 523ce9c45b..5b79c51b8c 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -27,12 +27,8 @@ 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 2>&1
+ git fsck --no-dangling >../actual 2>&1
) &&
- {
- grep -v dangling out >actual ||
- :
- } &&
test_cmp empty actual
'
@@ -191,4 +187,30 @@ test_expect_success 'cleaned up' '
test_cmp empty actual
'
+test_expect_success 'rev-list --verify-objects' '
+ git rev-list --verify-objects --all >/dev/null 2>out &&
+ test_cmp empty out
+'
+
+test_expect_success 'rev-list --verify-objects with bad sha1' '
+ sha=$(echo blob | git hash-object -w --stdin) &&
+ 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 &&
+ test_when_finished "git update-ref -d refs/heads/bogus" &&
+
+ test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out &&
+ cat out &&
+ grep -q "error: sha1 mismatch 63ffffffffffffffffffffffffffffffffffffff" out
+'
+
test_done
diff --git a/t/t2015-checkout-unborn.sh b/t/t2015-checkout-unborn.sh
index c551d39a66..6352b74e2e 100755
--- a/t/t2015-checkout-unborn.sh
+++ b/t/t2015-checkout-unborn.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='checkout from unborn branch protects contents'
+test_description='checkout from unborn branch'
. ./test-lib.sh
test_expect_success 'setup' '
@@ -37,4 +37,13 @@ test_expect_success 'checkout from unborn merges identical index contents' '
git checkout -b new origin
'
+test_expect_success 'checking out another branch from unborn state' '
+ git checkout --orphan newroot &&
+ git checkout -b anothername &&
+ test_must_fail git show-ref --verify refs/heads/newroot &&
+ git symbolic-ref HEAD >actual &&
+ echo refs/heads/anothername >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index dd1acebd88..9fe1d8feab 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -653,4 +653,8 @@ test_expect_success 'refuse --edit-description on unborn branch for now' '
)
'
+test_expect_success '--merged catches invalid object names' '
+ test_must_fail git branch --merged 0000000000000000000000000000000000000000
+'
+
test_done
diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh
index 5e29a05259..9f00ada5f7 100755
--- a/t/t3300-funny-names.sh
+++ b/t/t3300-funny-names.sh
@@ -167,7 +167,7 @@ test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \
test_expect_success TABS_IN_FILENAMES 'setup expect' '
cat >expected <<\EOF
"tabs\t,\" (dq) and spaces"
- 1 files changed, 0 insertions(+), 0 deletions(-)
+ 1 file changed, 0 insertions(+), 0 deletions(-)
EOF
'
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index e647272a01..7788ae02ad 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -160,14 +160,12 @@ rm -f B
test_expect_success 'fail when upstream arg is missing and not on branch' '
git checkout topic &&
- test_must_fail git rebase >output.out &&
- grep "You are not currently on a branch" output.out
+ test_must_fail git rebase
'
test_expect_success 'fail when upstream arg is missing and not configured' '
git checkout -b no-config topic &&
- test_must_fail git rebase >output.out &&
- grep "branch.no-config.merge" output.out
+ test_must_fail git rebase
'
test_expect_success 'default to @{upstream} when upstream arg is missing' '
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index ee1659c178..0c81b3c427 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -59,6 +59,20 @@ test_expect_success 'advice from failed cherry-pick' "
test_i18ncmp expected actual
"
+test_expect_success 'advice from failed cherry-pick --no-commit' "
+ pristine_detach initial &&
+
+ 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>'
+ EOF
+ test_must_fail git cherry-pick --no-commit picked 2>actual &&
+
+ test_i18ncmp expected actual
+"
+
test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
pristine_detach initial &&
test_must_fail git cherry-pick picked &&
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index 8e09fd0319..1b3a344158 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -38,13 +38,13 @@ test_expect_success 'cherry-pick first..fourth works' '
cat <<-\EOF >expected &&
[master OBJID] second
Author: A U Thor <author@example.com>
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
[master OBJID] third
Author: A U Thor <author@example.com>
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
[master OBJID] fourth
Author: A U Thor <author@example.com>
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
EOF
git checkout -f master &&
@@ -64,15 +64,15 @@ test_expect_success 'cherry-pick --strategy resolve first..fourth works' '
Trying simple merge.
[master OBJID] second
Author: A U Thor <author@example.com>
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
Trying simple merge.
[master OBJID] third
Author: A U Thor <author@example.com>
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
Trying simple merge.
[master OBJID] fourth
Author: A U Thor <author@example.com>
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
EOF
git checkout -f master &&
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 575d9508a0..874b3a6444 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -179,6 +179,21 @@ test_expect_success 'git add --refresh' '
test -z "`git diff-index HEAD -- foo`"
'
+test_expect_success 'git add --refresh with pathspec' '
+ git reset --hard &&
+ echo >foo && echo >bar && echo >baz &&
+ git add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo &&
+ echo "100644 $H 3 foo" | git update-index --index-info &&
+ test-chmtime -60 bar baz &&
+ >expect &&
+ git add --refresh bar >actual &&
+ test_cmp expect actual &&
+
+ git diff-files --name-only >actual &&
+ ! grep bar actual&&
+ grep baz actual
+'
+
test_expect_success POSIXPERM,SANITY 'git add should fail atomically upon an unreadable file' '
git reset --hard &&
date >foo1 &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index dbe2ac179d..663c60a12e 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -444,7 +444,7 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' '
git reset --hard &&
cat >expected <<-EOF &&
file | 1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
EOF
git stash show ${STASH_ID} >actual &&
test_cmp expected actual
@@ -482,7 +482,7 @@ test_expect_success 'stash show - no stashes on stack, stash-like argument' '
git reset --hard &&
cat >expected <<-EOF &&
file | 1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
EOF
git stash show ${STASH_ID} >actual &&
test_cmp expected actual
diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh
index 408a19c4c2..f0d5041c11 100755
--- a/t/t4011-diff-symlink.sh
+++ b/t/t4011-diff-symlink.sh
@@ -9,85 +9,110 @@ test_description='Test diff of symlinks.
. ./test-lib.sh
. "$TEST_DIRECTORY"/diff-lib.sh
-cat > expected << EOF
-diff --git a/frotz b/frotz
-new file mode 120000
-index 0000000..7c465af
---- /dev/null
-+++ b/frotz
-@@ -0,0 +1 @@
-+xyzzy
-\ No newline at end of file
-EOF
-
-test_expect_success SYMLINKS \
- 'diff new symlink' \
- 'ln -s xyzzy frotz &&
- git update-index &&
- tree=$(git write-tree) &&
- git update-index --add frotz &&
- GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree > current &&
- compare_diff_patch current expected'
-
-test_expect_success SYMLINKS \
- 'diff unchanged symlink' \
- 'tree=$(git write-tree) &&
- git update-index frotz &&
- test -z "$(git diff-index --name-only $tree)"'
-
-cat > expected << EOF
-diff --git a/frotz b/frotz
-deleted file mode 120000
-index 7c465af..0000000
---- a/frotz
-+++ /dev/null
-@@ -1 +0,0 @@
--xyzzy
-\ No newline at end of file
-EOF
+test_expect_success SYMLINKS 'diff new symlink and file' '
+ cat >expected <<-\EOF &&
+ diff --git a/frotz b/frotz
+ new file mode 120000
+ index 0000000..7c465af
+ --- /dev/null
+ +++ b/frotz
+ @@ -0,0 +1 @@
+ +xyzzy
+ \ No newline at end of file
+ diff --git a/nitfol b/nitfol
+ new file mode 100644
+ index 0000000..7c465af
+ --- /dev/null
+ +++ b/nitfol
+ @@ -0,0 +1 @@
+ +xyzzy
+ EOF
+ ln -s xyzzy frotz &&
+ echo xyzzy >nitfol &&
+ git update-index &&
+ tree=$(git write-tree) &&
+ git update-index --add frotz nitfol &&
+ GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current &&
+ compare_diff_patch expected current
+'
-test_expect_success SYMLINKS \
- 'diff removed symlink' \
- 'mv frotz frotz2 &&
- git diff-index -M -p $tree > current &&
- compare_diff_patch current expected'
+test_expect_success SYMLINKS 'diff unchanged symlink and file' '
+ tree=$(git write-tree) &&
+ git update-index frotz nitfol &&
+ test -z "$(git diff-index --name-only $tree)"
+'
-cat > expected << EOF
-diff --git a/frotz b/frotz
-EOF
+test_expect_success SYMLINKS 'diff removed symlink and file' '
+ cat >expected <<-\EOF &&
+ diff --git a/frotz b/frotz
+ deleted file mode 120000
+ index 7c465af..0000000
+ --- a/frotz
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -xyzzy
+ \ No newline at end of file
+ diff --git a/nitfol b/nitfol
+ deleted file mode 100644
+ index 7c465af..0000000
+ --- a/nitfol
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -xyzzy
+ EOF
+ mv frotz frotz2 &&
+ mv nitfol nitfol2 &&
+ git diff-index -M -p $tree >current &&
+ compare_diff_patch expected current
+'
-test_expect_success SYMLINKS \
- 'diff identical, but newly created symlink' \
- 'ln -s xyzzy frotz &&
- git diff-index -M -p $tree > current &&
- compare_diff_patch current expected'
+test_expect_success SYMLINKS 'diff identical, but newly created symlink and file' '
+ >expected &&
+ rm -f frotz nitfol &&
+ echo xyzzy >nitfol &&
+ test-chmtime +10 nitfol &&
+ ln -s xyzzy frotz &&
+ git diff-index -M -p $tree >current &&
+ compare_diff_patch expected current &&
-cat > expected << EOF
-diff --git a/frotz b/frotz
-index 7c465af..df1db54 120000
---- a/frotz
-+++ b/frotz
-@@ -1 +1 @@
--xyzzy
-\ No newline at end of file
-+yxyyz
-\ No newline at end of file
-EOF
+ >expected &&
+ git diff-index -M -p -w $tree >current &&
+ compare_diff_patch expected current
+'
-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 SYMLINKS 'diff different symlink and file' '
+ cat >expected <<-\EOF &&
+ diff --git a/frotz b/frotz
+ index 7c465af..df1db54 120000
+ --- a/frotz
+ +++ b/frotz
+ @@ -1 +1 @@
+ -xyzzy
+ \ No newline at end of file
+ +yxyyz
+ \ No newline at end of file
+ diff --git a/nitfol b/nitfol
+ index 7c465af..df1db54 100644
+ --- a/nitfol
+ +++ b/nitfol
+ @@ -1 +1 @@
+ -xyzzy
+ +yxyyz
+ EOF
+ rm -f frotz &&
+ ln -s yxyyz frotz &&
+ echo yxyyz >nitfol &&
+ git diff-index -M -p $tree >current &&
+ compare_diff_patch expected current
+'
-test_expect_success SYMLINKS \
- 'diff symlinks with non-existing targets' \
- 'ln -s narf pinky &&
- ln -s take\ over brain &&
- test_must_fail git diff --no-index pinky brain > output 2> output.err &&
- grep narf output &&
- ! grep error output.err'
+test_expect_success SYMLINKS 'diff symlinks with non-existing targets' '
+ ln -s narf pinky &&
+ ln -s take\ over brain &&
+ test_must_fail git diff --no-index pinky brain >output 2>output.err &&
+ grep narf output &&
+ ! test -s output.err
+'
test_expect_success SYMLINKS 'setup symlinks with attributes' '
echo "*.bin diff=bin" >>.gitattributes &&
@@ -96,19 +121,19 @@ test_expect_success SYMLINKS 'setup symlinks with attributes' '
git add -N file.bin link.bin
'
-cat >expect <<'EOF'
-diff --git a/file.bin b/file.bin
-index e69de29..d95f3ad 100644
-Binary files a/file.bin and b/file.bin differ
-diff --git a/link.bin b/link.bin
-index e69de29..dce41ec 120000
---- a/link.bin
-+++ b/link.bin
-@@ -0,0 +1 @@
-+file.bin
-\ No newline at end of file
-EOF
test_expect_success SYMLINKS 'symlinks do not respect userdiff config by path' '
+ cat >expect <<-\EOF &&
+ diff --git a/file.bin b/file.bin
+ index e69de29..d95f3ad 100644
+ Binary files a/file.bin and b/file.bin differ
+ diff --git a/link.bin b/link.bin
+ index e69de29..dce41ec 120000
+ --- a/link.bin
+ +++ b/link.bin
+ @@ -0,0 +1 @@
+ +file.bin
+ \ No newline at end of file
+ EOF
git config diff.bin.binary true &&
git diff file.bin link.bin >actual &&
test_cmp expect actual
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
index 3a9f78a09d..2f8560c369 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
@@ -2,7 +2,7 @@ $ git diff-tree --cc --patch-with-stat --summary master
59d314ad6f356dd08601a4cd5e530381da3e3c64
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --cc dir/sub
index cead32e,7289e35..992913c
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
index a61ad8cb13..72e03c14fb 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
@@ -3,7 +3,7 @@ c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
index 49f23b9215..8b357d964b 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
@@ -2,7 +2,7 @@ $ git diff-tree --cc --patch-with-stat master
59d314ad6f356dd08601a4cd5e530381da3e3c64
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --cc dir/sub
index cead32e,7289e35..992913c
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
index cc6eb3b3d5..e0568d6883 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
@@ -2,5 +2,5 @@ $ git diff-tree --cc --stat --summary master
59d314ad6f356dd08601a4cd5e530381da3e3c64
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
$
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
index 50362be7bf..5afc8239a1 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
@@ -3,6 +3,6 @@ c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
$
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_master b/t/t4013/diff.diff-tree_--cc_--stat_master
index fae7f33255..f48367a89a 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_master
@@ -2,5 +2,5 @@ $ git diff-tree --cc --stat master
59d314ad6f356dd08601a4cd5e530381da3e3c64
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
$
diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
index d5c333a378..590864c2d7 100644
--- a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
@@ -3,7 +3,7 @@ $ git diff-tree --pretty=oneline --root --patch-with-stat initial
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
new file mode 100644
diff --git a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
index 4d30e7eddc..e05e77875c 100644
--- a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
+++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
index 7dfa6af3c9..0e2c956633 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
new file mode 100644
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
index 43bfce253e..384fa44ddd 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
create mode 100644 file2
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
index 9154aa4d47..10384a83d3 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
@@ -8,5 +8,5 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
$
diff --git a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
index 1562b62708..f57062ea07 100644
--- a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
@@ -3,7 +3,7 @@ $ git diff-tree --root --patch-with-stat initial
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
new file mode 100644
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_master b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
index ac9f641fb4..7088683444 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
@@ -2,5 +2,5 @@ $ git diff-tree -c --stat --summary master
59d314ad6f356dd08601a4cd5e530381da3e3c64
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
$
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_side b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
index 2afcca11f4..ef216abb1d 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
@@ -3,6 +3,6 @@ c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
$
diff --git a/t/t4013/diff.diff-tree_-c_--stat_master b/t/t4013/diff.diff-tree_-c_--stat_master
index c2fe6a98c5..ad19f103eb 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_master
@@ -2,5 +2,5 @@ $ git diff-tree -c --stat master
59d314ad6f356dd08601a4cd5e530381da3e3c64
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
$
diff --git a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
index 9ed317a198..ddad917ae8 100644
--- a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
@@ -2,7 +2,7 @@ $ git diff --patch-with-stat -r initial..side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.diff_--patch-with-stat_initial..side b/t/t4013/diff.diff_--patch-with-stat_initial..side
index 8b50629e66..bdbd114d8e 100644
--- a/t/t4013/diff.diff_--patch-with-stat_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_initial..side
@@ -2,7 +2,7 @@ $ git diff --patch-with-stat initial..side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.diff_--stat_initial..side b/t/t4013/diff.diff_--stat_initial..side
index 0517b5d631..6d08f3d355 100644
--- a/t/t4013/diff.diff_--stat_initial..side
+++ b/t/t4013/diff.diff_--stat_initial..side
@@ -2,5 +2,5 @@ $ git diff --stat initial..side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
$
diff --git a/t/t4013/diff.diff_-r_--stat_initial..side b/t/t4013/diff.diff_-r_--stat_initial..side
index 245220d3f9..2ddb2540e6 100644
--- a/t/t4013/diff.diff_-r_--stat_initial..side
+++ b/t/t4013/diff.diff_-r_--stat_initial..side
@@ -2,5 +2,5 @@ $ git diff -r --stat initial..side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
$
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
index 52116d3ead..3cab049f7d 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
@@ -15,7 +15,7 @@ Content-Transfer-Encoding: 8bit
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
index ce49bd676e..564a4d38f2 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
index 5f1b23863b..4f28460b83 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
index 4a2364abc2..b10cc2e251 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
@@ -15,7 +15,7 @@ Content-Transfer-Encoding: 8bit
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
index 43b81eba54..a976a8aaf4 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
index ca3f60bf0e..b4fd66477a 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
index 08f23014bc..0d31036e7f 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
index 07f1230d31..18d4714423 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..side b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
index 67633d424a..3572f20b5d 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
@@ -15,7 +15,7 @@ Content-Transfer-Encoding: 8bit
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
index 3b4e113012..54cdcdab40 100644
--- a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
@@ -75,7 +75,7 @@ Subject: [DIFFERENT_PREFIX 2/2] Third
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
index f7752ebbea..23194ebdaa 100644
--- a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
@@ -53,7 +53,7 @@ Subject: [PATCH] Third
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -88,7 +88,7 @@ Subject: [PATCH] Side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
index 8e67dbf76f..78f1a80a97 100644
--- a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
@@ -53,7 +53,7 @@ Subject: [PATCH 2/3] Third
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -88,7 +88,7 @@ Subject: [PATCH 3/3] Side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master b/t/t4013/diff.format-patch_--stdout_initial..master
index 7b89978e32..a3dab7f773 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_initial..master
@@ -53,7 +53,7 @@ Subject: [PATCH 2/3] Third
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -88,7 +88,7 @@ Subject: [PATCH 3/3] Side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master^ b/t/t4013/diff.format-patch_--stdout_initial..master^
index b7f9725dc4..39f4a3f2d1 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_initial..master^
@@ -53,7 +53,7 @@ Subject: [PATCH 2/2] Third
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_initial..side b/t/t4013/diff.format-patch_--stdout_initial..side
index e765088475..88109209db 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--stdout_initial..side
@@ -8,7 +8,7 @@ Subject: [PATCH] Side
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
index bd7f5c0f70..4085bbde87 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -13,7 +13,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -32,7 +32,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -54,7 +54,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index 14595a614c..458627953e 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -15,7 +15,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -56,7 +56,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index 5a4e72765d..6e172cfadd 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -13,7 +13,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -32,7 +32,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -54,7 +54,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
diff --git a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
index df0aaa9f2c..48b0d4b91d 100644
--- a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:04:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --cc dir/sub
index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
create mode 100644 file2
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
index c11b5f2c7f..f9dc5122e2 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -15,7 +15,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
@@ -57,7 +57,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -133,7 +133,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
create mode 100644 file2
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 5f0c98f9ce..0807ece234 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -15,7 +15,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -56,7 +56,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -130,7 +130,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
new file mode 100644
diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
index e62c368dc6..84f5ef6911 100644
--- a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:04:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --combined dir/sub
index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
create mode 100644 file2
diff --git a/t/t4013/diff.show_--patch-with-stat_--summary_side b/t/t4013/diff.show_--patch-with-stat_--summary_side
index 377f2b7b7a..e60384d24d 100644
--- a/t/t4013/diff.show_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.show_--patch-with-stat_--summary_side
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.show_--patch-with-stat_side b/t/t4013/diff.show_--patch-with-stat_side
index fb14c530d2..a3a3255fd3 100644
--- a/t/t4013/diff.show_--patch-with-stat_side
+++ b/t/t4013/diff.show_--patch-with-stat_side
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.show_--stat_--summary_side b/t/t4013/diff.show_--stat_--summary_side
index 5bd5977628..d16f464aca 100644
--- a/t/t4013/diff.show_--stat_--summary_side
+++ b/t/t4013/diff.show_--stat_--summary_side
@@ -8,6 +8,6 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
$
diff --git a/t/t4013/diff.show_--stat_side b/t/t4013/diff.show_--stat_side
index 3b22327e48..6300c0535f 100644
--- a/t/t4013/diff.show_--stat_side
+++ b/t/t4013/diff.show_--stat_side
@@ -8,5 +8,5 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
$
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
index 6a467cccc1..16ae54345f 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
@@ -6,7 +6,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -25,7 +25,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -47,7 +47,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master b/t/t4013/diff.whatchanged_--patch-with-stat_master
index 1e1bbe1963..f3e45ec270 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -49,7 +49,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
index 13789f169b..c77f0bc320 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
@@ -6,7 +6,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -25,7 +25,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -47,7 +47,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
dir/sub | 2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
diff --git a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
index e96ff1fb8c..8d03efea6c 100644
--- a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:04:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --cc dir/sub
index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
create mode 100644 file2
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
index 0291153587..1874d0616c 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
@@ -50,7 +50,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -126,7 +126,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
create mode 100644 file2
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
index 9b0349cd55..5211ff2a75 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
@@ -49,7 +49,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -123,7 +123,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
new file mode 100644
diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
index c0aff68ef6..ad30245a59 100644
--- a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
@@ -8,7 +8,7 @@ Date: Mon Jun 26 00:04:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
diff --combined dir/sub
index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file3 | 4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
---
dir/sub | 2 ++
file1 | 3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date: Mon Jun 26 00:00:00 2006 +0000
dir/sub | 2 ++
file0 | 3 +++
file2 | 3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
create mode 100644 file2
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 67975129bc..7dfe716cf9 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -520,7 +520,7 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
cat > expect << EOF
---
file | 16 ++++++++++++++++
- 1 files changed, 16 insertions(+), 0 deletions(-)
+ 1 file changed, 16 insertions(+)
diff --git a/file b/file
index 40f36c6..2dc5c23 100644
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index 88c5619ae7..4ac162cfcf 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -86,7 +86,7 @@ test_expect_success 'status -v produces text' '
cat >expect.stat <<'EOF'
file | Bin 2 -> 4 bytes
- 1 files changed, 0 insertions(+), 0 deletions(-)
+ 1 file changed, 0 insertions(+), 0 deletions(-)
EOF
test_expect_success 'diffstat does not run textconv' '
echo file diff=fail >.gitattributes &&
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 8a3c63b9e2..bd119be106 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -33,7 +33,7 @@ check_stat() {
expect=$1; shift
cat >expected <<EOF
$expect | 1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
EOF
test_expect_success "--stat $*" "
git diff --stat $* HEAD^ >actual &&
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
index 641e70d14d..a6d1887536 100755
--- a/t/t4049-diff-stat-count.sh
+++ b/t/t4049-diff-stat-count.sh
@@ -16,7 +16,7 @@ test_expect_success setup '
cat >expect <<-\EOF
a | 1 +
b | 1 +
- 2 files changed, 2 insertions(+), 0 deletions(-)
+ 2 files changed, 2 insertions(+)
EOF
git diff --stat --stat-count=2 >actual &&
test_cmp expect actual
diff --git a/t/t4052-stat-output.sh b/t/t4052-stat-output.sh
new file mode 100755
index 0000000000..328aa8f398
--- /dev/null
+++ b/t/t4052-stat-output.sh
@@ -0,0 +1,220 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Zbigniew Jędrzejewski-Szmek
+#
+
+test_description='test --stat output of various commands'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-terminal.sh
+
+# 120 character name
+name=aaaaaaaaaa
+name=$name$name$name$name$name$name$name$name$name$name$name$name
+test_expect_success 'preparation' '
+ >"$name" &&
+ git add "$name" &&
+ git commit -m message &&
+ echo a >"$name" &&
+ git commit -m message "$name"
+'
+
+while read cmd args
+do
+ cat >expect <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ EOF
+ test_expect_success "$cmd: small change with long name gives more space to the name" '
+ git $cmd $args >output &&
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+
+ cat >expect <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ EOF
+ test_expect_success "$cmd --stat=width: a long name is given more room when the bar is short" '
+ git $cmd $args --stat=40 >output &&
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "$cmd --stat-width=width with long name" '
+ git $cmd $args --stat-width=40 >output &&
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+
+ cat >expect <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ EOF
+ test_expect_success "$cmd --stat=...,name-width with long name" '
+ git $cmd $args --stat=60,30 >output &&
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "$cmd --stat-name-width with long name" '
+ git $cmd $args --stat-name-width=30 >output &&
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+done <<\EOF
+format-patch -1 --stdout
+diff HEAD^ HEAD --stat
+show --stat
+log -1 --stat
+EOF
+
+
+test_expect_success 'preparation for big change tests' '
+ >abcd &&
+ git add abcd &&
+ git commit -m message &&
+ i=0 &&
+ while test $i -lt 1000
+ do
+ echo $i && i=$(($i + 1))
+ done >abcd &&
+ git commit -m message abcd
+'
+
+cat >expect80 <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
+
+cat >expect200 <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
+
+while read verb expect cmd args
+do
+ test_expect_success "$cmd $verb COLUMNS (big change)" '
+ COLUMNS=200 git $cmd $args >output
+ grep " | " output >actual &&
+ test_cmp "$expect" actual
+ '
+done <<\EOF
+ignores expect80 format-patch -1 --stdout
+respects expect200 diff HEAD^ HEAD --stat
+respects expect200 show --stat
+respects expect200 log -1 --stat
+EOF
+
+cat >expect40 <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++
+EOF
+
+while read verb expect cmd args
+do
+ test_expect_success "$cmd $verb not enough COLUMNS (big change)" '
+ COLUMNS=40 git $cmd $args >output
+ grep " | " output >actual &&
+ test_cmp "$expect" actual
+ '
+
+ test_expect_success "$cmd $verb statGraphWidth config" '
+ git -c diff.statGraphWidth=26 $cmd $args >output
+ grep " | " output >actual &&
+ test_cmp "$expect" actual
+ '
+done <<\EOF
+ignores expect80 format-patch -1 --stdout
+respects expect40 diff HEAD^ HEAD --stat
+respects expect40 show --stat
+respects expect40 log -1 --stat
+EOF
+
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++
+EOF
+while read cmd args
+do
+ test_expect_success "$cmd --stat=width with big change" '
+ git $cmd $args --stat=40 >output
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "$cmd --stat-width=width with big change" '
+ git $cmd $args --stat-width=40 >output
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "$cmd --stat-graph--width with big change" '
+ git $cmd $args --stat-graph-width=26 >output
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+done <<\EOF
+format-patch -1 --stdout
+diff HEAD^ HEAD --stat
+show --stat
+log -1 --stat
+EOF
+
+test_expect_success 'preparation for long filename tests' '
+ cp abcd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+ git add aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+ git commit -m message
+'
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
+EOF
+while read cmd args
+do
+ test_expect_success "$cmd --stat=width with big change is more balanced" '
+ git $cmd $args --stat-width=60 >output &&
+ grep " | " output >actual &&
+ test_cmp expect actual
+ '
+done <<\EOF
+format-patch -1 --stdout
+diff HEAD^ HEAD --stat
+show --stat
+log -1 --stat
+EOF
+
+cat >expect80 <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++++++++++
+EOF
+cat >expect200 <<'EOF'
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
+while read verb expect cmd args
+do
+ test_expect_success "$cmd $verb COLUMNS (long filename)" '
+ COLUMNS=200 git $cmd $args >output
+ grep " | " output >actual &&
+ test_cmp "$expect" actual
+ '
+done <<\EOF
+ignores expect80 format-patch -1 --stdout
+respects expect200 diff HEAD^ HEAD --stat
+respects expect200 show --stat
+respects expect200 log -1 --stat
+EOF
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success 'merge --stat respects COLUMNS (big change)' '
+ git checkout -b branch HEAD^^ &&
+ COLUMNS=100 git merge --stat --no-ff master^ >output &&
+ grep " | " output >actual
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success 'merge --stat respects COLUMNS (long filename)' '
+ COLUMNS=100 git merge --stat --no-ff master >output &&
+ grep " | " output >actual
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t4100/t-apply-8.expect b/t/t4100/t-apply-8.expect
index eef7f2e65c..55a55c3cc7 100644
--- a/t/t4100/t-apply-8.expect
+++ b/t/t4100/t-apply-8.expect
@@ -1,2 +1,2 @@
t/t4100-apply-stat.sh | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/t/t4100/t-apply-9.expect b/t/t4100/t-apply-9.expect
index eef7f2e65c..55a55c3cc7 100644
--- a/t/t4100/t-apply-9.expect
+++ b/t/t4100/t-apply-9.expect
@@ -1,2 +1,2 @@
t/t4100-apply-stat.sh | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 8807b602a5..ccc0280f52 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -123,6 +123,7 @@ test_expect_success setup '
git commit -m "added another file" &&
git format-patch --stdout master >lorem-move.patch &&
+ git format-patch --no-prefix --stdout master >lorem-zero.patch &&
git checkout -b rename &&
git mv file renamed &&
@@ -136,7 +137,7 @@ test_expect_success setup '
git format-patch -M --stdout lorem^ >rename-add.patch &&
# reset time
- unset test_tick &&
+ sane_unset test_tick &&
test_tick
'
@@ -286,6 +287,20 @@ test_expect_success 'am -3 falls back to 3-way merge' '
git diff --exit-code lorem
'
+test_expect_success 'am -3 -p0 can read --no-prefix patch' '
+ rm -fr .git/rebase-apply &&
+ git reset --hard &&
+ git checkout -b lorem3 master2 &&
+ 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 -p0 lorem-zero.patch &&
+ ! test -d .git/rebase-apply &&
+ git diff --exit-code lorem
+'
+
test_expect_success 'am can rename a file' '
grep "^rename from" rename.patch &&
rm -fr .git/rebase-apply &&
@@ -505,4 +520,14 @@ test_expect_success 'am -q is quiet' '
! test -s output.out
'
+test_expect_success 'am empty-file does not infloop' '
+ rm -fr .git/rebase-apply &&
+ git reset --hard &&
+ touch empty-file &&
+ test_tick &&
+ { git am empty-file > actual 2>&1 && false || :; } &&
+ echo Patch format detection failed. >expected &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t4209-log-pickaxe.sh b/t/t4209-log-pickaxe.sh
new file mode 100755
index 0000000000..eed727341d
--- /dev/null
+++ b/t/t4209-log-pickaxe.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+test_description='log --grep/--author/--regexp-ignore-case/-S/-G'
+. ./test-lib.sh
+
+test_expect_success setup '
+ >file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+
+ echo Picked >file &&
+ test_tick &&
+ git commit -a --author="Another Person <another@example.com>" -m second
+'
+
+test_expect_success 'log --grep' '
+ git log --grep=initial --format=%H >actual &&
+ git rev-parse --verify HEAD^ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep --regexp-ignore-case' '
+ git log --regexp-ignore-case --grep=InItial --format=%H >actual &&
+ git rev-parse --verify HEAD^ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep -i' '
+ git log -i --grep=InItial --format=%H >actual &&
+ git rev-parse --verify HEAD^ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --author --regexp-ignore-case' '
+ git log --regexp-ignore-case --author=person --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --author -i' '
+ git log -i --author=person --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -G (nomatch)' '
+ git log -Gpicked --format=%H >actual &&
+ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -G (match)' '
+ git log -GPicked --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -G --regexp-ignore-case (nomatch)' '
+ git log --regexp-ignore-case -Gpickle --format=%H >actual &&
+ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -G -i (nomatch)' '
+ git log -i -Gpickle --format=%H >actual &&
+ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -G --regexp-ignore-case (match)' '
+ git log --regexp-ignore-case -Gpicked --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -G -i (match)' '
+ git log -i -Gpicked --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -S (nomatch)' '
+ git log -Spicked --format=%H >actual &&
+ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -S (match)' '
+ git log -SPicked --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -S --regexp-ignore-case (match)' '
+ git log --regexp-ignore-case -Spicked --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -S -i (match)' '
+ git log -i -Spicked --format=%H >actual &&
+ git rev-parse --verify HEAD >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -S --regexp-ignore-case (nomatch)' '
+ git log --regexp-ignore-case -Spickle --format=%H >actual &&
+ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log -S -i (nomatch)' '
+ git log -i -Spickle --format=%H >actual &&
+ >expect &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index 7c1dc641de..2af8947eeb 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -95,7 +95,7 @@ test_expect_success 'setup: two scripts for reading pull requests' '
b
: diffstat
n
- / [0-9]* files changed/ {
+ / [0-9]* files* changed/ {
a\\
DIFFSTAT
b
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 602806d09c..d9d856b87b 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -38,6 +38,10 @@ test_expect_success \
'pack without delta' \
'packname_1=$(git pack-objects --window=0 test-1 <obj-list)'
+test_expect_success \
+ 'pack-objects with bogus arguments' \
+ 'test_must_fail git pack-objects --window=0 test-1 blah blah <obj-list'
+
rm -fr .git2
mkdir .git2
diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh
index f8fa92446c..fe82025d4a 100755
--- a/t/t5302-pack-index.sh
+++ b/t/t5302-pack-index.sh
@@ -74,6 +74,10 @@ test_expect_success 'index-pack --verify on index version 2' '
'
test_expect_success \
+ 'pack-objects --index-version=2, is not accepted' \
+ 'test_must_fail git pack-objects --index-version=2, test-3 <obj-list'
+
+test_expect_success \
'index v2: force some 64-bit offsets with pack-objects' \
'pack3=$(git pack-objects --index-version=2,0x40000 test-3 <obj-list)'
diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh
index 8341fc4d15..35ec294d9a 100755
--- a/t/t5504-fetch-receive-strict.sh
+++ b/t/t5504-fetch-receive-strict.sh
@@ -58,6 +58,11 @@ test_expect_success 'fetch with transfer.fsckobjects' '
)
'
+cat >exp <<EOF
+To dst
+! refs/heads/master:refs/heads/test [remote rejected] (missing necessary objects)
+EOF
+
test_expect_success 'push without strict' '
rm -rf dst &&
git init dst &&
@@ -66,7 +71,8 @@ test_expect_success 'push without strict' '
git config fetch.fsckobjects false &&
git config transfer.fsckobjects false
) &&
- git push dst master:refs/heads/test
+ test_must_fail git push --porcelain dst master:refs/heads/test >act &&
+ test_cmp exp act
'
test_expect_success 'push with !receive.fsckobjects' '
@@ -77,9 +83,15 @@ test_expect_success 'push with !receive.fsckobjects' '
git config receive.fsckobjects false &&
git config transfer.fsckobjects true
) &&
- git push dst master:refs/heads/test
+ test_must_fail git push --porcelain dst master:refs/heads/test >act &&
+ test_cmp exp act
'
+cat >exp <<EOF
+To dst
+! refs/heads/master:refs/heads/test [remote rejected] (n/a (unpacker error))
+EOF
+
test_expect_success 'push with receive.fsckobjects' '
rm -rf dst &&
git init dst &&
@@ -88,7 +100,8 @@ test_expect_success 'push with receive.fsckobjects' '
git config receive.fsckobjects true &&
git config transfer.fsckobjects false
) &&
- test_must_fail git push dst master:refs/heads/test
+ test_must_fail git push --porcelain dst master:refs/heads/test >act &&
+ test_cmp exp act
'
test_expect_success 'push with transfer.fsckobjects' '
@@ -98,7 +111,8 @@ test_expect_success 'push with transfer.fsckobjects' '
cd dst &&
git config transfer.fsckobjects true
) &&
- test_must_fail git push dst master:refs/heads/test
+ test_must_fail git push --porcelain dst master:refs/heads/test >act &&
+ test_cmp exp act
'
test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 79ee913130..308c02ea75 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -14,6 +14,14 @@ test_bundle_object_count () {
test "$2" = $(grep '^[0-9a-f]\{40\} ' verify.out | wc -l)
}
+convert_bundle_to_pack () {
+ while read x && test -n "$x"
+ do
+ :;
+ done
+ cat
+}
+
test_expect_success setup '
echo >file original &&
git add file &&
@@ -206,13 +214,7 @@ test_expect_success 'unbundle 1' '
test_expect_success 'bundle 1 has only 3 files ' '
cd "$D" &&
- (
- while read x && test -n "$x"
- do
- :;
- done
- cat
- ) <bundle1 >bundle.pack &&
+ convert_bundle_to_pack <bundle1 >bundle.pack &&
git index-pack bundle.pack &&
test_bundle_object_count bundle.pack 3
'
@@ -229,13 +231,7 @@ test_expect_success 'bundle does not prerequisite objects' '
git add file2 &&
git commit -m add.file2 file2 &&
git bundle create bundle3 -1 HEAD &&
- (
- while read x && test -n "$x"
- do
- :;
- done
- cat
- ) <bundle3 >bundle.pack &&
+ convert_bundle_to_pack <bundle3 >bundle.pack &&
git index-pack bundle.pack &&
test_bundle_object_count bundle.pack 3
'
@@ -433,14 +429,31 @@ test_expect_success 'fetch --dry-run' '
'
test_expect_success "should be able to fetch with duplicate refspecs" '
- mkdir dups &&
- cd dups &&
- git init &&
- git config branch.master.remote three &&
- git config remote.three.url ../three/.git &&
- git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
- git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
- git fetch three
+ mkdir dups &&
+ (
+ cd dups &&
+ git init &&
+ git config branch.master.remote three &&
+ git config remote.three.url ../three/.git &&
+ git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
+ git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
+ git fetch three
+ )
+'
+
+test_expect_success 'all boundary commits are excluded' '
+ test_commit base &&
+ test_commit oneside &&
+ git checkout HEAD^ &&
+ test_commit otherside &&
+ git checkout master &&
+ test_tick &&
+ git merge otherside &&
+ ad=$(git log --no-walk --format=%ad HEAD) &&
+ git bundle create twoside-boundary.bdl master --since="$ad" &&
+ convert_bundle_to_pack <twoside-boundary.bdl >twoside-boundary.pack &&
+ pack=$(git index-pack --fix-thin --stdin <twoside-boundary.pack) &&
+ test_bundle_object_count .git/objects/pack/pack-${pack##pack }.pack 3
'
test_done
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 5c546c99a5..6764d511ce 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -5,7 +5,6 @@ test_description='git ls-remote'
. ./test-lib.sh
test_expect_success setup '
-
>file &&
git add file &&
test_tick &&
@@ -18,45 +17,33 @@ test_expect_success setup '
) >expected.all &&
git remote add self "$(pwd)/.git"
-
'
test_expect_success 'ls-remote --tags .git' '
-
git ls-remote --tags .git >actual &&
test_cmp expected.tag actual
-
'
test_expect_success 'ls-remote .git' '
-
git ls-remote .git >actual &&
test_cmp expected.all actual
-
'
test_expect_success 'ls-remote --tags self' '
-
git ls-remote --tags self >actual &&
test_cmp expected.tag actual
-
'
test_expect_success 'ls-remote self' '
-
git ls-remote self >actual &&
test_cmp expected.all actual
-
'
test_expect_success 'dies when no remote specified and no default remotes found' '
-
test_must_fail git ls-remote
-
'
test_expect_success 'use "origin" when no remote specified' '
-
URL="$(pwd)/.git" &&
echo "From $URL" >exp_err &&
@@ -65,18 +52,14 @@ test_expect_success 'use "origin" when no remote specified' '
test_cmp exp_err actual_err &&
test_cmp expected.all actual
-
'
test_expect_success 'suppress "From <url>" with -q' '
-
git ls-remote -q 2>actual_err &&
test_must_fail test_cmp exp_err actual_err
-
'
test_expect_success 'use branch.<name>.remote if possible' '
-
#
# Test that we are indeed using branch.<name>.remote, not "origin", even
# though the "origin" remote has been set.
@@ -99,14 +82,13 @@ test_expect_success 'use branch.<name>.remote if possible' '
git ls-remote 2>actual_err >actual &&
test_cmp exp_err actual_err &&
test_cmp exp actual
-
'
-cat >exp <<EOF
-fatal: 'refs*master' does not appear to be a git repository
-fatal: The remote end hung up unexpectedly
-EOF
test_expect_success 'confuses pattern as remote when no remote specified' '
+ cat >exp <<-\EOF &&
+ fatal: '\''refs*master'\'' does not appear to be a git repository
+ fatal: The remote end hung up unexpectedly
+ EOF
#
# Do not expect "git ls-remote <pattern>" to work; ls-remote, correctly,
# confuses <pattern> for <remote>. Although ugly, this behaviour is akin
@@ -120,7 +102,6 @@ test_expect_success 'confuses pattern as remote when no remote specified' '
# role as a pattern.
test_must_fail git ls-remote refs*master >actual 2>&1 &&
test_cmp exp actual
-
'
test_expect_success 'die with non-2 for wrong repository even with --exit-code' '
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index b69cf574d7..b5417cc951 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -979,4 +979,20 @@ test_expect_success 'push --porcelain --dry-run rejected' '
test_cmp .git/foo .git/bar
'
+test_expect_success 'push --prune' '
+ mk_test heads/master heads/second heads/foo heads/bar &&
+ git push --prune testrepo &&
+ check_push_result $the_commit heads/master &&
+ check_push_result $the_first_commit heads/second &&
+ ! check_push_result $the_first_commit heads/foo heads/bar
+'
+
+test_expect_success 'push --prune refspec' '
+ mk_test tmp/master tmp/second tmp/foo tmp/bar &&
+ git push --prune testrepo "refs/heads/*:refs/tmp/*" &&
+ check_push_result $the_commit tmp/master &&
+ check_push_result $the_first_commit tmp/second &&
+ ! check_push_result $the_first_commit tmp/foo tmp/bar
+'
+
test_done
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
index 9ee52cfc45..3683df13a6 100755
--- a/t/t5523-push-upstream.sh
+++ b/t/t5523-push-upstream.sh
@@ -101,10 +101,11 @@ test_expect_success TTY 'push -q suppresses progress' '
! grep "Writing objects" err
'
-test_expect_failure TTY 'push --no-progress suppresses progress' '
+test_expect_success TTY 'push --no-progress suppresses progress' '
ensure_fresh_upstream &&
test_terminal git push -u --no-progress upstream master >out 2>err &&
+ ! grep "Unpacking objects" err &&
! grep "Writing objects" err
'
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh
index d66ed24508..cc6f081711 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push.sh
@@ -106,7 +106,7 @@ cat >exp <<EOF
remote: error: hook declined to update refs/heads/dev2
To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
! [remote rejected] dev2 -> dev2 (hook declined)
-error: failed to push some refs to 'http://127.0.0.1:5541/smart/test_repo.git'
+error: failed to push some refs to 'http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'
EOF
test_expect_success 'rejected update prints status' '
diff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh
index 0ad7ce07c4..ef98d95e00 100755
--- a/t/t5560-http-backend-noserver.sh
+++ b/t/t5560-http-backend-noserver.sh
@@ -17,7 +17,7 @@ run_backend() {
GET() {
REQUEST_METHOD="GET" && export REQUEST_METHOD &&
run_backend "/repo.git/$1" &&
- unset REQUEST_METHOD &&
+ sane_unset REQUEST_METHOD &&
if ! grep "Status" act.out >act
then
printf "Status: 200 OK\r\n" >act
@@ -30,8 +30,8 @@ POST() {
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 &&
+ sane_unset REQUEST_METHOD &&
+ sane_unset CONTENT_TYPE &&
if ! grep "Status" act.out >act
then
printf "Status: 200 OK\r\n" >act
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index c4c375ac04..bbc4691bd7 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -52,13 +52,13 @@ test_cmp expected current'
cd "$base_dir"
-rm -f "$U"
+rm -f "$U.D"
test_expect_success 'cloning with reference (no -l -s)' \
-'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U"'
+'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U.D"'
test_expect_success 'fetched no objects' \
-'! grep "^want" "$U"'
+'! grep "^want" "$U.D"'
cd "$base_dir"
@@ -153,4 +153,32 @@ test_expect_success 'clone with reference from a tagged repository' '
git clone --reference=A A I
'
+test_expect_success 'prepare branched repository' '
+ git clone A J &&
+ (
+ cd J &&
+ git checkout -b other master^ &&
+ echo other >otherfile &&
+ git add otherfile &&
+ git commit -m other &&
+ git checkout master
+ )
+'
+
+rm -f "$U.K"
+
+test_expect_success 'fetch with incomplete alternates' '
+ git init K &&
+ echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates &&
+ (
+ cd K &&
+ git remote add J "file://$base_dir/J" &&
+ GIT_DEBUG_SEND_PACK=3 git fetch J 3>"$U.K"
+ ) &&
+ master_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/master) &&
+ ! grep "^want $master_object" "$U.K" &&
+ tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) &&
+ ! grep "^want $tag_object" "$U.K"
+'
+
test_done
diff --git a/t/t5704-bundle.sh b/t/t5704-bundle.sh
index 4ae127d106..9e43731fe5 100755
--- a/t/t5704-bundle.sh
+++ b/t/t5704-bundle.sh
@@ -4,59 +4,58 @@ test_description='some bundle related tests'
. ./test-lib.sh
test_expect_success 'setup' '
-
- : > file &&
- git add file &&
- test_tick &&
- git commit -m initial &&
+ test_commit initial &&
test_tick &&
git tag -m tag tag &&
- : > file2 &&
- git add file2 &&
- : > file3 &&
- test_tick &&
- git commit -m second &&
- git add file3 &&
- test_tick &&
- git commit -m third
-
+ test_commit second &&
+ test_commit third &&
+ git tag -d initial &&
+ git tag -d second &&
+ git tag -d third
'
test_expect_success 'tags can be excluded by rev-list options' '
-
git bundle create bundle --all --since=7.Apr.2005.15:16:00.-0700 &&
git ls-remote bundle > output &&
! grep tag output
-
'
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 &&
git ls-remote stdin-bundle.bdl >output &&
grep master output
-
'
test_expect_failure 'bundle --stdin <rev-list options>' '
-
echo master | git bundle create hybrid-bundle.bdl --stdin tag &&
git ls-remote hybrid-bundle.bdl >output &&
grep master output
-
'
test_expect_success 'empty bundle file is rejected' '
+ : >empty-bundle &&
+ test_must_fail git fetch empty-bundle
+'
- >empty-bundle && test_must_fail git fetch empty-bundle
-
+# This triggers a bug in older versions where the resulting line (with
+# --pretty=oneline) was longer than a 1024-char buffer.
+test_expect_success 'ridiculously long subject in boundary' '
+ : >file4 &&
+ test_tick &&
+ git add file4 &&
+ printf "%01200d\n" 0 | git commit -F - &&
+ test_commit fifth &&
+ git bundle create long-subject-bundle.bdl HEAD^..HEAD &&
+ git bundle list-heads long-subject-bundle.bdl >heads &&
+ test -s heads &&
+ git fetch long-subject-bundle.bdl &&
+ sed -n "/^-/{p;q;}" long-subject-bundle.bdl >boundary &&
+ grep "^-[0-9a-f]\\{40\\} " boundary
'
test_done
diff --git a/t/t5900-repo-selection.sh b/t/t5900-repo-selection.sh
new file mode 100755
index 0000000000..3d5b418bb4
--- /dev/null
+++ b/t/t5900-repo-selection.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+test_description='selecting remote repo in ambiguous cases'
+. ./test-lib.sh
+
+reset() {
+ rm -rf foo foo.git fetch clone
+}
+
+make_tree() {
+ git init "$1" &&
+ (cd "$1" && test_commit "$1")
+}
+
+make_bare() {
+ git init --bare "$1" &&
+ (cd "$1" &&
+ tree=`git hash-object -w -t tree /dev/null` &&
+ commit=$(echo "$1" | git commit-tree $tree) &&
+ git update-ref HEAD $commit
+ )
+}
+
+get() {
+ git init --bare fetch &&
+ (cd fetch && git fetch "../$1") &&
+ git clone "$1" clone
+}
+
+check() {
+ echo "$1" >expect &&
+ (cd fetch && git log -1 --format=%s FETCH_HEAD) >actual.fetch &&
+ (cd clone && git log -1 --format=%s HEAD) >actual.clone &&
+ test_cmp expect actual.fetch &&
+ test_cmp expect actual.clone
+}
+
+test_expect_success 'find .git dir in worktree' '
+ reset &&
+ make_tree foo &&
+ get foo &&
+ check foo
+'
+
+test_expect_success 'automagically add .git suffix' '
+ reset &&
+ make_bare foo.git &&
+ get foo &&
+ check foo.git
+'
+
+test_expect_success 'automagically add .git suffix to worktree' '
+ reset &&
+ make_tree foo.git &&
+ get foo &&
+ check foo.git
+'
+
+test_expect_success 'prefer worktree foo over bare foo.git' '
+ reset &&
+ make_tree foo &&
+ make_bare foo.git &&
+ get foo &&
+ check foo
+'
+
+test_expect_success 'prefer bare foo over bare foo.git' '
+ reset &&
+ make_bare foo &&
+ make_bare foo.git &&
+ get foo &&
+ check foo
+'
+
+test_expect_success 'disambiguate with full foo.git' '
+ reset &&
+ make_bare foo &&
+ make_bare foo.git &&
+ get foo.git &&
+ check foo.git
+'
+
+test_expect_success 'we are not fooled by non-git foo directory' '
+ reset &&
+ make_bare foo.git &&
+ mkdir foo &&
+ get foo &&
+ check foo.git
+'
+
+test_expect_success 'prefer inner .git over outer bare' '
+ reset &&
+ make_tree foo &&
+ make_bare foo.git &&
+ mv foo/.git foo.git &&
+ get foo.git &&
+ check foo
+'
+
+test_done
diff --git a/t/t6032-merge-large-rename.sh b/t/t6032-merge-large-rename.sh
index fdb6c25371..94f010be8a 100755
--- a/t/t6032-merge-large-rename.sh
+++ b/t/t6032-merge-large-rename.sh
@@ -95,7 +95,7 @@ test_expect_success 'setup large simple rename' '
'
test_expect_success 'massive simple rename does not spam added files' '
- unset GIT_MERGE_VERBOSITY &&
+ sane_unset GIT_MERGE_VERBOSITY &&
git merge --no-stat simple-rename | grep -v Removing >output &&
test 5 -gt "$(wc -l < output)"
'
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 4ef79aabc4..f8c247a750 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1282,4 +1282,43 @@ test_expect_success 'mixing incompatibles modes and options is forbidden' '
test_must_fail git tag -v -s
'
+# check points-at
+
+test_expect_success '--points-at cannot be used in non-list mode' '
+ test_must_fail git tag --points-at=v4.0 foo
+'
+
+test_expect_success '--points-at finds lightweight tags' '
+ echo v4.0 >expect &&
+ git tag --points-at v4.0 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '--points-at finds annotated tags of commits' '
+ git tag -m "v4.0, annotated" annotated-v4.0 v4.0 &&
+ echo annotated-v4.0 >expect &&
+ git tag -l --points-at v4.0 "annotated*" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '--points-at finds annotated tags of tags' '
+ git tag -m "describing the v4.0 tag object" \
+ annotated-again-v4.0 annotated-v4.0 &&
+ cat >expect <<-\EOF &&
+ annotated-again-v4.0
+ annotated-v4.0
+ EOF
+ git tag --points-at=annotated-v4.0 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'multiple --points-at are OR-ed together' '
+ cat >expect <<-\EOF &&
+ v2.0
+ v3.0
+ EOF
+ git tag --points-at=v2.0 --points-at=v3.0 >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh
index 917a264eea..fd6410fc71 100755
--- a/t/t7008-grep-binary.sh
+++ b/t/t7008-grep-binary.sh
@@ -99,4 +99,28 @@ test_expect_success 'git grep y<NUL>x a' "
test_must_fail git grep -f f a
"
+test_expect_success 'grep respects binary diff attribute' '
+ echo text >t &&
+ git add t &&
+ echo t:text >expect &&
+ git grep text t >actual &&
+ test_cmp expect actual &&
+ echo "t -diff" >.gitattributes &&
+ echo "Binary file t matches" >expect &&
+ git grep text t >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep respects not-binary diff attribute' '
+ echo binQary | q_to_nul >b &&
+ git add b &&
+ echo "Binary file b matches" >expect &&
+ git grep bin b >actual &&
+ test_cmp expect actual &&
+ echo "b diff" >.gitattributes &&
+ echo "b:binQary" >expect &&
+ git grep bin b | nul_to_q >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 695f7afdf3..b377a7af28 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -79,6 +79,15 @@ test_expect_success 'submodule add' '
cd addtest &&
git submodule add -q "$submodurl" submod >actual &&
test ! -s actual &&
+ echo "gitdir: ../.git/modules/submod" >expect &&
+ test_cmp expect submod/.git &&
+ (
+ cd submod &&
+ git config core.worktree >actual &&
+ echo "../../../submod" >expect &&
+ test_cmp expect actual &&
+ rm -f actual expect
+ ) &&
git submodule init
) &&
@@ -498,4 +507,17 @@ test_expect_success 'relative path works with user@host:path' '
)
'
+test_expect_success 'moving the superproject does not break submodules' '
+ (
+ cd addtest &&
+ git submodule status >expect
+ )
+ mv addtest addtest2 &&
+ (
+ cd addtest2 &&
+ git submodule status >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 5b97222c48..dcb195b4cf 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -619,4 +619,21 @@ test_expect_success 'submodule add properly re-creates deeper level submodules'
)
'
+test_expect_success 'submodule update properly revives a moved submodule' '
+ (cd super &&
+ git commit -am "pre move" &&
+ git status >expect&&
+ H=$(cd submodule2; git rev-parse HEAD) &&
+ git rm --cached submodule2 &&
+ rm -rf submodule2 &&
+ mkdir -p "moved/sub module" &&
+ git update-index --add --cacheinfo 160000 $H "moved/sub module" &&
+ git config -f .gitmodules submodule.submodule2.path "moved/sub module"
+ git commit -am "post move" &&
+ git submodule update &&
+ git status >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh
index 61f36baa1f..5783ebf3ab 100755
--- a/t/t7602-merge-octopus-many.sh
+++ b/t/t7602-merge-octopus-many.sh
@@ -57,7 +57,7 @@ Merge made by the 'octopus' strategy.
c2.c | 1 +
c3.c | 1 +
c4.c | 1 +
- 3 files changed, 3 insertions(+), 0 deletions(-)
+ 3 files changed, 3 insertions(+)
create mode 100644 c2.c
create mode 100644 c3.c
create mode 100644 c4.c
@@ -74,7 +74,7 @@ Already up-to-date with c4
Trying simple merge with c5
Merge made by the 'octopus' strategy.
c5.c | 1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
create mode 100644 c5.c
EOF
@@ -89,7 +89,7 @@ Trying simple merge with c2
Merge made by the 'octopus' strategy.
c1.c | 1 +
c2.c | 1 +
- 2 files changed, 2 insertions(+), 0 deletions(-)
+ 2 files changed, 2 insertions(+)
create mode 100644 c1.c
create mode 100644 c2.c
EOF
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 75f4716d8c..d9ad633310 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -47,6 +47,13 @@ test_expect_success setup '
echo vvv >t/v &&
mkdir t/a &&
echo vvv >t/a/v &&
+ {
+ echo "line without leading space1"
+ echo " line with leading space1"
+ echo " line with leading space2"
+ echo " line with leading space3"
+ echo "line without leading space2"
+ } >space &&
git add . &&
test_tick &&
git commit -m initial
@@ -893,4 +900,20 @@ test_expect_success 'mimic ack-grep --group' '
test_cmp expected actual
'
+cat >expected <<EOF
+space: line with leading space1
+space: line with leading space2
+space: line with leading space3
+EOF
+
+test_expect_success LIBPCRE 'grep -E "^ "' '
+ git grep -E "^ " space >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success LIBPCRE 'grep -P "^ "' '
+ git grep -P "^ " space >actual &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index b041516a1d..749b75e8d4 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -65,7 +65,8 @@ test_expect_success "$name" "
git update-index --add dir/file/file &&
git commit -m '$name' &&
test_must_fail git svn set-tree --find-copies-harder --rmdir \
- ${remotes_git_svn}..mybranch" || true
+ ${remotes_git_svn}..mybranch
+"
name='detect node change from directory to file #1'
@@ -79,7 +80,8 @@ test_expect_success "$name" '
git update-index --add -- bar &&
git commit -m "$name" &&
test_must_fail git svn set-tree --find-copies-harder --rmdir \
- ${remotes_git_svn}..mybranch2' || true
+ ${remotes_git_svn}..mybranch2
+'
name='detect node change from file to directory #2'
@@ -92,9 +94,12 @@ test_expect_success "$name" '
echo yyy > bar/zzz/yyy &&
git update-index --add bar/zzz/yyy &&
git commit -m "$name" &&
- test_must_fail git svn set-tree --find-copies-harder --rmdir \
- ${remotes_git_svn}..mybranch3' || true
-
+ git svn set-tree --find-copies-harder --rmdir \
+ ${remotes_git_svn}..mybranch3 &&
+ svn_cmd up "$SVN_TREE" &&
+ test -d "$SVN_TREE"/bar/zzz &&
+ test -e "$SVN_TREE"/bar/zzz/yyy
+'
name='detect node change from directory to file #2'
test_expect_success "$name" '
@@ -107,7 +112,8 @@ test_expect_success "$name" '
git update-index --add -- dir &&
git commit -m "$name" &&
test_must_fail git svn set-tree --find-copies-harder --rmdir \
- ${remotes_git_svn}..mybranch4' || true
+ ${remotes_git_svn}..mybranch4
+'
name='remove executable bit from a file'
@@ -134,10 +140,10 @@ test_expect_success "$name" '
test -x "$SVN_TREE"/exec.sh'
-name='executable file becomes a symlink to bar/zzz (file)'
+name='executable file becomes a symlink to file'
test_expect_success "$name" '
rm exec.sh &&
- ln -s bar/zzz exec.sh &&
+ ln -s file exec.sh &&
git update-index exec.sh &&
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
@@ -148,19 +154,19 @@ test_expect_success "$name" '
name='new symlink is added to a file that was also just made executable'
test_expect_success "$name" '
- chmod +x bar/zzz &&
- ln -s bar/zzz exec-2.sh &&
- git update-index --add bar/zzz exec-2.sh &&
+ chmod +x file &&
+ ln -s file exec-2.sh &&
+ git update-index --add file exec-2.sh &&
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
${remotes_git_svn}..mybranch5 &&
svn_cmd up "$SVN_TREE" &&
- test -x "$SVN_TREE"/bar/zzz &&
+ test -x "$SVN_TREE"/file &&
test -h "$SVN_TREE"/exec-2.sh'
name='modify a symlink to become a file'
test_expect_success "$name" '
- echo git help > help || true &&
+ echo git help >help &&
rm exec-2.sh &&
cp help exec-2.sh &&
git update-index exec-2.sh &&
@@ -195,14 +201,15 @@ name='check imported tree checksums expected tree checksums'
rm -f expected
if test_have_prereq UTF8
then
- echo tree bf522353586b1b883488f2bc73dab0d9f774b9a9 > expected
+ echo tree dc68b14b733e4ec85b04ab6f712340edc5dc936e > expected
fi
cat >> expected <<\EOF
-tree 83654bb36f019ae4fe77a0171f81075972087624
-tree 031b8d557afc6fea52894eaebb45bec52f1ba6d1
-tree 0b094cbff17168f24c302e297f55bfac65eb8bd3
-tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e
-tree 56a30b966619b863674f5978696f4a3594f2fca9
+tree c3322890dcf74901f32d216f05c5044f670ce632
+tree d3ccd5035feafd17b030c5732e7808cc49122853
+tree d03e1630363d4881e68929d532746b20b0986b83
+tree 149d63cd5878155c846e8c55d7d8487de283f89e
+tree 312b76e4f64ce14893aeac8591eb3960b065e247
+tree 149d63cd5878155c846e8c55d7d8487de283f89e
tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e
tree 8f51f74cf0163afc9ad68a4b1537288c4558b5a4
EOF
diff --git a/t/t9130-git-svn-authors-file.sh b/t/t9130-git-svn-authors-file.sh
index b324c491c5..c3443ceb25 100755
--- a/t/t9130-git-svn-authors-file.sh
+++ b/t/t9130-git-svn-authors-file.sh
@@ -96,8 +96,8 @@ test_expect_success 'fresh clone with svn.authors-file in config' '
rm -r "$GIT_DIR" &&
test x = x"$(git config svn.authorsfile)" &&
test_config="$HOME"/.gitconfig &&
- unset GIT_DIR &&
- unset GIT_CONFIG &&
+ sane_unset GIT_DIR &&
+ sane_unset GIT_CONFIG &&
git config --global \
svn.authorsfile "$HOME"/svn-authors &&
test x"$HOME"/svn-authors = x"$(git config svn.authorsfile)" &&
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 518358aa64..b59be9a894 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -321,7 +321,7 @@ test_expect_success 'use the same checkout for Git and CVS' '
(mkdir shared &&
cd shared &&
- unset GIT_DIR &&
+ sane_unset GIT_DIR &&
cvs co . &&
git init &&
git add " space" &&
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 438aaf6b14..0f5b5e5964 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1307,6 +1307,45 @@ test_expect_success \
INPUT_END'
test_expect_success \
+ 'N: reject foo/ syntax in copy source' \
+ 'test_must_fail git fast-import <<-INPUT_END
+ commit refs/heads/N5C
+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data <<COMMIT
+ copy with invalid syntax
+ COMMIT
+
+ from refs/heads/branch^0
+ C file2/ file3
+ INPUT_END'
+
+test_expect_success \
+ 'N: reject foo/ syntax in rename source' \
+ 'test_must_fail git fast-import <<-INPUT_END
+ commit refs/heads/N5D
+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data <<COMMIT
+ rename with invalid syntax
+ COMMIT
+
+ from refs/heads/branch^0
+ R file2/ file3
+ INPUT_END'
+
+test_expect_success \
+ 'N: reject foo/ syntax in ls argument' \
+ 'test_must_fail git fast-import <<-INPUT_END
+ commit refs/heads/N5E
+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data <<COMMIT
+ copy with invalid syntax
+ COMMIT
+
+ from refs/heads/branch^0
+ ls "file2/"
+ INPUT_END'
+
+test_expect_success \
'N: copy to root by id and modify' \
'echo "hello, world" >expect.foo &&
echo hello >expect.bar &&
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 0f771c673d..90bb6050c1 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -638,6 +638,45 @@ test_expect_success \
'gitweb_run "p=.git;a=tree"'
# ----------------------------------------------------------------------
+# searching
+
+cat >>gitweb_config.perl <<\EOF
+
+# enable search
+$feature{'search'}{'default'} = [1];
+$feature{'grep'}{'default'} = [1];
+$feature{'pickaxe'}{'default'} = [1];
+EOF
+
+test_expect_success \
+ 'search: preparation' \
+ 'echo "1st MATCH" >>file &&
+ echo "2nd MATCH" >>file &&
+ echo "MATCH" >>bar &&
+ git add file bar &&
+ git commit -m "Added MATCH word"'
+
+test_expect_success \
+ 'search: commit author' \
+ 'gitweb_run "p=.git;a=search;h=HEAD;st=author;s=A+U+Thor"'
+
+test_expect_success \
+ 'search: commit message' \
+ 'gitweb_run "p=.git;a=search;h=HEAD;st=commitr;s=MATCH"'
+
+test_expect_success \
+ 'search: grep' \
+ 'gitweb_run "p=.git;a=search;h=HEAD;st=grep;s=MATCH"'
+
+test_expect_success \
+ 'search: pickaxe' \
+ 'gitweb_run "p=.git;a=search;h=HEAD;st=pickaxe;s=MATCH"'
+
+test_expect_success \
+ 'search: projects' \
+ 'gitweb_run "a=project_list;s=.git"'
+
+# ----------------------------------------------------------------------
# non-ASCII in README.html
test_expect_success \
@@ -739,4 +778,13 @@ test_expect_success \
'echo "\$projects_list_group_categories = 1;" >>gitweb_config.perl &&
gitweb_run'
+# ----------------------------------------------------------------------
+# unborn branches
+
+test_expect_success \
+ 'unborn HEAD: "summary" page (with "heads" subview)' \
+ 'git checkout orphan_branch || git checkout --orphan orphan_branch &&
+ test_when_finished "git checkout master" &&
+ gitweb_run "p=.git;a=summary"'
+
test_done
diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh
index 26102ee9b0..31076edc5b 100755
--- a/t/t9501-gitweb-standalone-http-status.sh
+++ b/t/t9501-gitweb-standalone-http-status.sh
@@ -134,4 +134,14 @@ our $maxload = undef;
EOF
+# ----------------------------------------------------------------------
+# invalid arguments
+
+test_expect_success 'invalid arguments: invalid regexp (in project search)' '
+ gitweb_run "a=project_list;s=*\.git;sr=1" &&
+ grep "Status: 400" gitweb.headers &&
+ grep "400 - Invalid.*regexp" gitweb.body
+'
+test_debug 'cat gitweb.headers'
+
test_done
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 04ee20e642..486c8eeb7e 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -234,8 +234,10 @@ test_expect_success 'refuse to preserve users without perms' '
git config git-p4.skipSubmitEditCheck true &&
echo "username-noperms: a change by alice" >>file1 &&
git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 &&
- P4EDITOR=touch P4USER=bob P4PASSWD=secret test_must_fail "$GITP4" commit --preserve-user &&
- test_must_fail git diff --exit-code HEAD..p4/master
+ P4EDITOR=touch P4USER=bob P4PASSWD=secret &&
+ export P4EDITOR P4USER P4PASSWD &&
+ test_must_fail "$GITP4" commit --preserve-user &&
+ ! git diff --exit-code HEAD..p4/master
)
'
@@ -250,13 +252,15 @@ test_expect_success 'preserve user where author is unknown to p4' '
git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 &&
echo "username-unknown: a change by charlie" >>file1 &&
git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 &&
- P4EDITOR=touch P4USER=alice P4PASSWD=secret test_must_fail "$GITP4" commit --preserve-user &&
- test_must_fail git diff --exit-code HEAD..p4/master &&
+ P4EDITOR=touch P4USER=alice P4PASSWD=secret &&
+ export P4EDITOR P4USER P4PASSWD &&
+ test_must_fail "$GITP4" commit --preserve-user &&
+ ! git diff --exit-code HEAD..p4/master &&
echo "$0: repeat with allowMissingP4Users enabled" &&
git config git-p4.allowMissingP4Users true &&
git config git-p4.preserveUser true &&
- P4EDITOR=touch P4USER=alice P4PASSWD=secret "$GITP4" commit &&
+ "$GITP4" commit &&
git diff --exit-code HEAD..p4/master &&
p4_check_commit_author file1 alice
)
@@ -275,20 +279,22 @@ test_expect_success 'not preserving user with mixed authorship' '
p4_add_user derek Derek &&
make_change_by_user usernamefile3 Derek derek@localhost &&
- P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\
+ P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
+ export P4EDITOR P4USER P4PASSWD &&
+ "$GITP4" commit |\
grep "git author derek@localhost does not match" &&
make_change_by_user usernamefile3 Charlie charlie@localhost &&
- P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\
+ "$GITP4" commit |\
grep "git author charlie@localhost does not match" &&
make_change_by_user usernamefile3 alice alice@localhost &&
- P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" |\
+ "$GITP4" commit |\
test_must_fail grep "git author.*does not match" &&
git config git-p4.skipUserNameCheck true &&
make_change_by_user usernamefile3 Charlie charlie@localhost &&
- P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\
+ "$GITP4" commit |\
test_must_fail grep "git author.*does not match" &&
p4_check_commit_author usernamefile3 alice
diff --git a/t/t9804-git-p4-label.sh b/t/t9804-git-p4-label.sh
index 80d01ea438..a9e04efb88 100755
--- a/t/t9804-git-p4-label.sh
+++ b/t/t9804-git-p4-label.sh
@@ -1,3 +1,5 @@
+#!/bin/sh
+
test_description='git-p4 p4 label tests'
. ./lib-git-p4.sh
diff --git a/t/t9808-git-p4-chdir.sh b/t/t9808-git-p4-chdir.sh
index eb8cc9523e..f0022839c7 100755
--- a/t/t9808-git-p4-chdir.sh
+++ b/t/t9808-git-p4-chdir.sh
@@ -25,7 +25,7 @@ test_expect_success 'P4CONFIG and absolute dir clone' '
test_when_finished cleanup_git &&
(
P4CONFIG=p4config && export P4CONFIG &&
- unset P4PORT P4CLIENT &&
+ sane_unset P4PORT P4CLIENT &&
"$GITP4" clone --verbose --dest="$git" //depot
)
'
@@ -37,7 +37,7 @@ test_expect_success 'P4CONFIG and relative dir clone' '
test_when_finished cleanup_git &&
(
P4CONFIG=p4config && export P4CONFIG &&
- unset P4PORT P4CLIENT &&
+ sane_unset P4PORT P4CLIENT &&
"$GITP4" clone --verbose --dest="git" //depot
)
'
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index ae9145e307..773a516ff0 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -31,7 +31,7 @@ client_view() {
#
check_files_exist() {
ok=0 &&
- num=${#@} &&
+ num=$# &&
for arg ; do
test_path_is_file "$arg" &&
ok=$(($ok + 1))
@@ -71,20 +71,24 @@ git_verify() {
# - dir2
# - file21
# - file22
+init_depot() {
+ for d in 1 2 ; do
+ mkdir -p dir$d &&
+ for f in 1 2 ; do
+ echo dir$d/file$d$f >dir$d/file$d$f &&
+ p4 add dir$d/file$d$f &&
+ p4 submit -d "dir$d/file$d$f"
+ done
+ done &&
+ find . -type f ! -name files >files &&
+ check_files_exist dir1/file11 dir1/file12 \
+ dir2/file21 dir2/file22
+}
+
test_expect_success 'init depot' '
(
cd "$cli" &&
- for d in 1 2 ; do
- mkdir -p dir$d &&
- for f in 1 2 ; do
- echo dir$d/file$d$f >dir$d/file$d$f &&
- p4 add dir$d/file$d$f &&
- p4 submit -d "dir$d/file$d$f"
- done
- done &&
- find . -type f ! -name files >files &&
- check_files_exist dir1/file11 dir1/file12 \
- dir2/file21 dir2/file22
+ init_depot
)
'
@@ -247,6 +251,139 @@ test_expect_success 'quotes on rhs only' '
'
#
+# Submit tests
+#
+
+# clone sets variable
+test_expect_success 'clone --use-client-spec sets useClientSpec' '
+ client_view "//depot/... //client/..." &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config --bool git-p4.useClientSpec >actual &&
+ echo true >true &&
+ test_cmp actual true
+ )
+'
+
+# clone just a subdir of the client spec
+test_expect_success 'subdir clone' '
+ client_view "//depot/... //client/..." &&
+ files="dir1/file11 dir1/file12 dir2/file21 dir2/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 &&
+ git_verify dir1/file11 dir1/file12
+'
+
+#
+# submit back, see what happens: five cases
+#
+test_expect_success 'subdir clone, submit modify' '
+ client_view "//depot/... //client/..." &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ echo line >>dir1/file12 &&
+ git add dir1/file12 &&
+ git commit -m dir1/file12 &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file dir1/file12 &&
+ test_line_count = 2 dir1/file12
+ )
+'
+
+test_expect_success 'subdir clone, submit add' '
+ client_view "//depot/... //client/..." &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ echo file13 >dir1/file13 &&
+ git add dir1/file13 &&
+ git commit -m dir1/file13 &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file dir1/file13
+ )
+'
+
+test_expect_success 'subdir clone, submit delete' '
+ client_view "//depot/... //client/..." &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git rm dir1/file12 &&
+ git commit -m "delete dir1/file12" &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing dir1/file12
+ )
+'
+
+test_expect_success 'subdir clone, submit copy' '
+ client_view "//depot/... //client/..." &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.detectCopies true &&
+ cp dir1/file11 dir1/file11a &&
+ git add dir1/file11a &&
+ git commit -m "copy to dir1/file11a" &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file dir1/file11a
+ )
+'
+
+test_expect_success 'subdir clone, submit rename' '
+ client_view "//depot/... //client/..." &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot/dir1 &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.detectRenames true &&
+ git mv dir1/file13 dir1/file13a &&
+ git commit -m "rename dir1/file13 to dir1/file13a" &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing dir1/file13 &&
+ test_path_is_file dir1/file13a
+ )
+'
+
+test_expect_success 'reinit depot' '
+ (
+ cd "$cli" &&
+ p4 sync -f &&
+ rm files &&
+ p4 delete */* &&
+ p4 submit -d "delete all files" &&
+ init_depot
+ )
+'
+
+#
# What happens when two files of the same name are overlayed together?
# The last-listed file should take preference.
#
diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh
new file mode 100755
index 0000000000..49dfde0616
--- /dev/null
+++ b/t/t9810-git-p4-rcs.sh
@@ -0,0 +1,388 @@
+#!/bin/sh
+
+test_description='git-p4 rcs keywords'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+#
+# Make one file with keyword lines at the top, and
+# enough plain text to be able to test modifications
+# far away from the keywords.
+#
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+ cat <<-\EOF >filek &&
+ $Id$
+ /* $Revision$ */
+ # $Change$
+ line4
+ line5
+ line6
+ line7
+ line8
+ EOF
+ cp filek fileko &&
+ sed -i "s/Revision/Revision: do not scrub me/" fileko
+ cp fileko file_text &&
+ sed -i "s/Id/Id: do not scrub me/" file_text
+ p4 add -t text+k filek &&
+ p4 submit -d "filek" &&
+ p4 add -t text+ko fileko &&
+ p4 submit -d "fileko" &&
+ p4 add -t text file_text &&
+ p4 submit -d "file_text"
+ )
+'
+
+#
+# Generate these in a function to make it easy to use single quote marks.
+#
+write_scrub_scripts () {
+ cat >"$TRASH_DIRECTORY/scrub_k.py" <<-\EOF &&
+ import re, sys
+ sys.stdout.write(re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$', r'$\1$', sys.stdin.read()))
+ EOF
+ cat >"$TRASH_DIRECTORY/scrub_ko.py" <<-\EOF
+ import re, sys
+ sys.stdout.write(re.sub(r'(?i)\$(Id|Header):[^$]*\$', r'$\1$', sys.stdin.read()))
+ EOF
+}
+
+test_expect_success 'scrub scripts' '
+ write_scrub_scripts
+'
+
+#
+# Compare $cli/file to its scrubbed version, should be different.
+# Compare scrubbed $cli/file to $git/file, should be same.
+#
+scrub_k_check () {
+ file="$1" &&
+ scrub="$TRASH_DIRECTORY/$file" &&
+ "$PYTHON_PATH" "$TRASH_DIRECTORY/scrub_k.py" <"$git/$file" >"$scrub" &&
+ ! test_cmp "$cli/$file" "$scrub" &&
+ test_cmp "$git/$file" "$scrub" &&
+ rm "$scrub"
+}
+scrub_ko_check () {
+ file="$1" &&
+ scrub="$TRASH_DIRECTORY/$file" &&
+ "$PYTHON_PATH" "$TRASH_DIRECTORY/scrub_ko.py" <"$git/$file" >"$scrub" &&
+ ! test_cmp "$cli/$file" "$scrub" &&
+ test_cmp "$git/$file" "$scrub" &&
+ rm "$scrub"
+}
+
+#
+# Modify far away from keywords. If no RCS lines show up
+# in the diff, there is no conflict.
+#
+test_expect_success 'edit far away from RCS lines' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ sed -i "s/^line7/line7 edit/" filek &&
+ git commit -m "filek line7 edit" filek &&
+ "$GITP4" submit &&
+ scrub_k_check filek
+ )
+'
+
+#
+# Modify near the keywords. This will require RCS scrubbing.
+#
+test_expect_success 'edit near RCS lines' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ sed -i "s/^line4/line4 edit/" filek &&
+ git commit -m "filek line4 edit" filek &&
+ "$GITP4" submit &&
+ scrub_k_check filek
+ )
+'
+
+#
+# Modify the keywords themselves. This also will require RCS scrubbing.
+#
+test_expect_success 'edit keyword lines' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ sed -i "/Revision/d" filek &&
+ git commit -m "filek remove Revision line" filek &&
+ "$GITP4" submit &&
+ scrub_k_check filek
+ )
+'
+
+#
+# Scrubbing text+ko files should not alter all keywords, just Id, Header.
+#
+test_expect_success 'scrub ko files differently' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ sed -i "s/^line4/line4 edit/" fileko &&
+ git commit -m "fileko line4 edit" fileko &&
+ "$GITP4" submit &&
+ scrub_ko_check fileko &&
+ ! scrub_k_check fileko
+ )
+'
+
+# hack; git-p4 submit should do it on its own
+test_expect_success 'cleanup after failure' '
+ (
+ cd "$cli" &&
+ p4 revert ...
+ )
+'
+
+#
+# Do not scrub anything but +k or +ko files. Sneak a change into
+# the cli file so that submit will get a conflict. Make sure that
+# scrubbing doesn't make a mess of things.
+#
+# Assumes that git-p4 exits leaving the p4 file open, with the
+# conflict-generating patch unapplied.
+#
+# This might happen only if the git repo is behind the p4 repo at
+# submit time, and there is a conflict.
+#
+test_expect_success 'do not scrub plain text' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ sed -i "s/^line4/line4 edit/" file_text &&
+ git commit -m "file_text line4 edit" file_text &&
+ (
+ cd "$cli" &&
+ p4 open file_text &&
+ sed -i "s/^line5/line5 p4 edit/" file_text &&
+ p4 submit -d "file5 p4 edit"
+ ) &&
+ ! "$GITP4" submit &&
+ (
+ # exepct something like:
+ # file_text - file(s) not opened on this client
+ # but not copious diff output
+ cd "$cli" &&
+ p4 diff file_text >wc &&
+ test_line_count = 1 wc
+ )
+ )
+'
+
+# hack; git-p4 submit should do it on its own
+test_expect_success 'cleanup after failure 2' '
+ (
+ cd "$cli" &&
+ p4 revert ...
+ )
+'
+
+create_kw_file () {
+ cat <<\EOF >"$1"
+/* A file
+ Id: $Id$
+ Revision: $Revision$
+ File: $File$
+ */
+int main(int argc, const char **argv) {
+ return 0;
+}
+EOF
+}
+
+test_expect_success 'add kwfile' '
+ (
+ cd "$cli" &&
+ echo file1 >file1 &&
+ p4 add file1 &&
+ p4 submit -d "file 1" &&
+ create_kw_file kwfile1.c &&
+ p4 add kwfile1.c &&
+ p4 submit -d "Add rcw kw file" kwfile1.c
+ )
+'
+
+p4_append_to_file () {
+ f="$1" &&
+ p4 edit -t ktext "$f" &&
+ echo "/* $(date) */" >>"$f" &&
+ p4 submit -d "appending a line in p4"
+}
+
+# Create some files with RCS keywords. If they get modified
+# elsewhere then the version number gets bumped which then
+# results in a merge conflict if we touch the RCS kw lines,
+# even though the change itself would otherwise apply cleanly.
+test_expect_success 'cope with rcs keyword expansion damage' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ (cd ../cli && p4_append_to_file kwfile1.c) &&
+ old_lines=$(wc -l <kwfile1.c) &&
+ perl -n -i -e "print unless m/Revision:/" kwfile1.c &&
+ new_lines=$(wc -l <kwfile1.c) &&
+ test $new_lines = $(($old_lines - 1)) &&
+
+ git add kwfile1.c &&
+ git commit -m "Zap an RCS kw line" &&
+ "$GITP4" submit &&
+ "$GITP4" rebase &&
+ git diff p4/master &&
+ "$GITP4" commit &&
+ echo "try modifying in both" &&
+ cd "$cli" &&
+ p4 edit kwfile1.c &&
+ echo "line from p4" >>kwfile1.c &&
+ p4 submit -d "add a line in p4" kwfile1.c &&
+ cd "$git" &&
+ echo "line from git at the top" | cat - kwfile1.c >kwfile1.c.new &&
+ mv kwfile1.c.new kwfile1.c &&
+ git commit -m "Add line in git at the top" kwfile1.c &&
+ "$GITP4" rebase &&
+ "$GITP4" submit
+ )
+'
+
+test_expect_success 'cope with rcs keyword file deletion' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$cli" &&
+ echo "\$Revision\$" >kwdelfile.c &&
+ p4 add -t ktext kwdelfile.c &&
+ p4 submit -d "Add file to be deleted" &&
+ cat kwdelfile.c &&
+ grep 1 kwdelfile.c
+ ) &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ grep Revision kwdelfile.c &&
+ git rm -f kwdelfile.c &&
+ git commit -m "Delete a file containing RCS keywords" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ ! test -f kwdelfile.c
+ )
+'
+
+# If you add keywords in git of the form $Header$ then everything should
+# work fine without any special handling.
+test_expect_success 'Add keywords in git which match the default p4 values' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo "NewKW: \$Revision\$" >>kwfile1.c &&
+ git add kwfile1.c &&
+ git commit -m "Adding RCS keywords in git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ test -f kwfile1.c &&
+ grep "NewKW.*Revision.*[0-9]" kwfile1.c
+
+ )
+'
+
+# If you add keywords in git of the form $Header:#1$ then things will fail
+# unless git-p4 takes steps to scrub the *git* commit.
+#
+test_expect_failure 'Add keywords in git which do not match the default p4 values' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo "NewKW2: \$Revision:1\$" >>kwfile1.c &&
+ git add kwfile1.c &&
+ git commit -m "Adding RCS keywords in git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ "$GITP4" submit
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ grep "NewKW2.*Revision.*[0-9]" kwfile1.c
+
+ )
+'
+
+# Check that the existing merge conflict handling still works.
+# Modify kwfile1.c in git, and delete in p4. We should be able
+# to skip the git commit.
+#
+test_expect_success 'merge conflict handling still works' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$cli" &&
+ echo "Hello:\$Id\$" >merge2.c &&
+ echo "World" >>merge2.c &&
+ p4 add -t ktext merge2.c &&
+ p4 submit -d "add merge test file"
+ ) &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ sed -e "/Hello/d" merge2.c >merge2.c.tmp &&
+ mv merge2.c.tmp merge2.c &&
+ git add merge2.c &&
+ git commit -m "Modifying merge2.c"
+ ) &&
+ (
+ cd "$cli" &&
+ p4 delete merge2.c &&
+ p4 submit -d "remove merge test file"
+ ) &&
+ (
+ cd "$git" &&
+ test -f merge2.c &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.attemptRCSCleanup true &&
+ !(echo "s" | "$GITP4" submit) &&
+ git rebase --skip &&
+ ! test -f merge2.c
+ )
+'
+
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
new file mode 100644
index 0000000000..7b3b4bef30
--- /dev/null
+++ b/t/test-lib-functions.sh
@@ -0,0 +1,565 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# The semantics of the editor variables are that of invoking
+# sh -c "$EDITOR \"$@\"" files ...
+#
+# If our trash directory contains shell metacharacters, they will be
+# interpreted if we just set $EDITOR directly, so do a little dance with
+# environment variables to work around this.
+#
+# In particular, quoting isn't enough, as the path may contain the same quote
+# that we're using.
+test_set_editor () {
+ FAKE_EDITOR="$1"
+ export FAKE_EDITOR
+ EDITOR='"$FAKE_EDITOR"'
+ export EDITOR
+}
+
+test_decode_color () {
+ awk '
+ function name(n) {
+ if (n == 0) return "RESET";
+ if (n == 1) return "BOLD";
+ if (n == 30) return "BLACK";
+ if (n == 31) return "RED";
+ if (n == 32) return "GREEN";
+ if (n == 33) return "YELLOW";
+ if (n == 34) return "BLUE";
+ if (n == 35) return "MAGENTA";
+ if (n == 36) return "CYAN";
+ if (n == 37) return "WHITE";
+ if (n == 40) return "BLACK";
+ if (n == 41) return "BRED";
+ if (n == 42) return "BGREEN";
+ if (n == 43) return "BYELLOW";
+ if (n == 44) return "BBLUE";
+ if (n == 45) return "BMAGENTA";
+ if (n == 46) return "BCYAN";
+ if (n == 47) return "BWHITE";
+ }
+ {
+ while (match($0, /\033\[[0-9;]*m/) != 0) {
+ printf "%s<", substr($0, 1, RSTART-1);
+ codes = substr($0, RSTART+2, RLENGTH-3);
+ if (length(codes) == 0)
+ printf "%s", name(0)
+ else {
+ n = split(codes, ary, ";");
+ sep = "";
+ for (i = 1; i <= n; i++) {
+ printf "%s%s", sep, name(ary[i]);
+ sep = ";"
+ }
+ }
+ printf ">";
+ $0 = substr($0, RSTART + RLENGTH, length($0) - RSTART - RLENGTH + 1);
+ }
+ print
+ }
+ '
+}
+
+nul_to_q () {
+ perl -pe 'y/\000/Q/'
+}
+
+q_to_nul () {
+ perl -pe 'y/Q/\000/'
+}
+
+q_to_cr () {
+ tr Q '\015'
+}
+
+q_to_tab () {
+ tr Q '\011'
+}
+
+append_cr () {
+ sed -e 's/$/Q/' | tr Q '\015'
+}
+
+remove_cr () {
+ tr '\015' Q | sed -e 's/Q$//'
+}
+
+# In some bourne shell implementations, the "unset" builtin returns
+# nonzero status when a variable to be unset was not set in the first
+# place.
+#
+# Use sane_unset when that should not be considered an error.
+
+sane_unset () {
+ unset "$@"
+ return 0
+}
+
+test_tick () {
+ if test -z "${test_tick+set}"
+ then
+ test_tick=1112911993
+ else
+ test_tick=$(($test_tick + 60))
+ fi
+ GIT_COMMITTER_DATE="$test_tick -0700"
+ GIT_AUTHOR_DATE="$test_tick -0700"
+ export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
+}
+
+# Stop execution and start a shell. This is useful for debugging tests and
+# only makes sense together with "-v".
+#
+# Be sure to remove all invocations of this command before submitting.
+
+test_pause () {
+ if test "$verbose" = t; then
+ "$SHELL_PATH" <&6 >&3 2>&4
+ else
+ error >&5 "test_pause requires --verbose"
+ fi
+}
+
+# Call test_commit with the arguments "<message> [<file> [<contents>]]"
+#
+# This will commit a file with the given contents and the given commit
+# message. It will also add a tag with <message> as name.
+#
+# Both <file> and <contents> default to <message>.
+
+test_commit () {
+ file=${2:-"$1.t"}
+ echo "${3-$1}" > "$file" &&
+ git add "$file" &&
+ test_tick &&
+ git commit -m "$1" &&
+ git tag "$1"
+}
+
+# Call test_merge with the arguments "<message> <commit>", where <commit>
+# can be a tag pointing to the commit-to-merge.
+
+test_merge () {
+ test_tick &&
+ git merge -m "$1" "$2" &&
+ git tag "$1"
+}
+
+# This function helps systems where core.filemode=false is set.
+# Use it instead of plain 'chmod +x' to set or unset the executable bit
+# of a file in the working directory and add it to the index.
+
+test_chmod () {
+ chmod "$@" &&
+ git update-index --add "--chmod=$@"
+}
+
+# Unset a configuration variable, but don't fail if it doesn't exist.
+test_unconfig () {
+ git config --unset-all "$@"
+ config_status=$?
+ case "$config_status" in
+ 5) # ok, nothing to unset
+ config_status=0
+ ;;
+ esac
+ return $config_status
+}
+
+# Set git config, automatically unsetting it after the test is over.
+test_config () {
+ test_when_finished "test_unconfig '$1'" &&
+ git config "$@"
+}
+
+test_config_global () {
+ test_when_finished "test_unconfig --global '$1'" &&
+ git config --global "$@"
+}
+
+write_script () {
+ {
+ echo "#!${2-"$SHELL_PATH"}" &&
+ cat
+ } >"$1" &&
+ chmod +x "$1"
+}
+
+# Use test_set_prereq to tell that a particular prerequisite is available.
+# The prerequisite can later be checked for in two ways:
+#
+# - Explicitly using test_have_prereq.
+#
+# - Implicitly by specifying the prerequisite tag in the calls to
+# test_expect_{success,failure,code}.
+#
+# The single parameter is the prerequisite tag (a simple word, in all
+# capital letters by convention).
+
+test_set_prereq () {
+ satisfied="$satisfied$1 "
+}
+satisfied=" "
+
+test_have_prereq () {
+ # 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
+}
+
+test_declared_prereq () {
+ case ",$test_prereq," in
+ *,$1,*)
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+test_expect_failure () {
+ test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
+ export test_prereq
+ if ! test_skip "$@"
+ then
+ say >&3 "checking known breakage: $2"
+ if test_run_ "$2" expecting_failure
+ then
+ test_known_broken_ok_ "$1"
+ else
+ test_known_broken_failure_ "$1"
+ fi
+ fi
+ echo >&3 ""
+}
+
+test_expect_success () {
+ test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 or 3 parameters to test-expect-success"
+ export test_prereq
+ if ! test_skip "$@"
+ then
+ say >&3 "expecting success: $2"
+ if test_run_ "$2"
+ then
+ test_ok_ "$1"
+ else
+ test_failure_ "$@"
+ fi
+ fi
+ echo >&3 ""
+}
+
+# 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
+# <n>: ..." before running it. When providing relative paths, keep in
+# mind that all scripts run in "trash directory".
+# Usage: test_external description command arguments...
+# Example: test_external 'Perl API' perl ../path/to/test.pl
+test_external () {
+ test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
+ test "$#" = 3 ||
+ error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
+ descr="$1"
+ shift
+ export test_prereq
+ if ! test_skip "$descr" "$@"
+ then
+ # Announce the script to reduce confusion about the
+ # test output that follows.
+ 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
+ # Run command; redirect its stderr to &4 as in
+ # test_run_, but keep its stdout on our stdout even in
+ # non-verbose mode.
+ "$@" 2>&4
+ if [ "$?" = 0 ]
+ then
+ 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
+ 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
+}
+
+# Like test_external, but in addition tests that the command generated
+# no output on stderr.
+test_external_without_stderr () {
+ # The temporary file has no (and must have no) security
+ # implications.
+ tmp=${TMPDIR:-/tmp}
+ stderr="$tmp/git-external-stderr.$$.tmp"
+ test_external "$@" 4> "$stderr"
+ [ -f "$stderr" ] || error "Internal error: $stderr disappeared."
+ descr="no stderr: $1"
+ shift
+ say >&3 "# expecting no stderr from previous command"
+ if [ ! -s "$stderr" ]; then
+ rm "$stderr"
+
+ 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"`
+ else
+ output=
+ fi
+ # rm first in case test_failure exits.
+ rm "$stderr"
+ 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
+}
+
+# test_line_count checks that a file has the number of lines it
+# ought to. For example:
+#
+# test_expect_success 'produce exactly one line of output' '
+# do something >output &&
+# test_line_count = 1 output
+# '
+#
+# is like "test $(wc -l <output) = 1" except that it passes the
+# output through when the number of lines is wrong.
+
+test_line_count () {
+ if test $# != 3
+ then
+ error "bug in the test script: not 3 parameters to test_line_count"
+ elif ! test $(wc -l <"$3") "$1" "$2"
+ then
+ echo "test_line_count: line count for $3 !$1 $2"
+ cat "$3"
+ return 1
+ 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:
+#
+# test_expect_success 'complain and die' '
+# do something &&
+# do something else &&
+# test_must_fail git checkout ../outerspace
+# '
+#
+# Writing this as "! git checkout ../outerspace" is wrong, because
+# the failure could be due to a segv. We want a controlled failure.
+
+test_must_fail () {
+ "$@"
+ 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
+# meant to be used in contexts like:
+#
+# test_expect_success 'some command works without configuration' '
+# test_might_fail git config --unset all.configuration &&
+# do something
+# '
+#
+# Writing "git config --unset all.configuration || :" would be wrong,
+# because we want to notice if it fails due to segv.
+
+test_might_fail () {
+ "$@"
+ 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
+}
+
+# Similar to test_must_fail and test_might_fail, but check that a
+# given command exited with a given exit code. Meant to be used as:
+#
+# test_expect_success 'Merge with d/f conflicts' '
+# test_expect_code 1 git merge "merge msg" B master
+# '
+
+test_expect_code () {
+ want_code=$1
+ shift
+ "$@"
+ exit_code=$?
+ if test $exit_code = $want_code
+ then
+ return 0
+ fi
+
+ echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
+ return 1
+}
+
+# test_cmp is a helper function to compare actual and expected output.
+# You can use it like:
+#
+# test_expect_success 'foo works' '
+# echo expected >expected &&
+# foo >actual &&
+# test_cmp expected actual
+# '
+#
+# This could be written as either "cmp" or "diff -u", but:
+# - cmp's output is not nearly as easy to read as diff -u
+# - not all diff versions understand "-u"
+
+test_cmp() {
+ $GIT_TEST_CMP "$@"
+}
+
+# This function can be used to schedule some commands to be run
+# unconditionally at the end of the test to restore sanity:
+#
+# test_expect_success 'test core.capslock' '
+# git config core.capslock true &&
+# test_when_finished "git config --unset core.capslock" &&
+# hello world
+# '
+#
+# That would be roughly equivalent to
+#
+# test_expect_success 'test core.capslock' '
+# git config core.capslock true &&
+# hello world
+# git config --unset core.capslock
+# '
+#
+# except that the greeting and config --unset must both succeed for
+# the test to pass.
+#
+# Note that under --immediate mode, no clean-up is done to help diagnose
+# what went wrong.
+
+test_when_finished () {
+ test_cleanup="{ $*
+ } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
+}
+
+# Most tests can use the created repository, but some may need to create more.
+# Usage: test_create_repo <directory>
+test_create_repo () {
+ test "$#" = 1 ||
+ error "bug in the test script: not 1 parameter to test-create-repo"
+ repo="$1"
+ mkdir -p "$repo"
+ (
+ 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
+}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index e28d5fdebe..30ed4d74bb 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -42,10 +42,11 @@ TZ=UTC
TERM=dumb
export LANG LC_ALL PAGER TERM TZ
EDITOR=:
-unset VISUAL
-unset EMAIL
-unset LANGUAGE
-unset $(perl -e '
+# A call to "unset" with no arguments causes at least Solaris 10
+# /usr/xpg4/bin/sh and /bin/ksh to bail out. So keep the unsets
+# deriving from the command substitution clustered with the other
+# ones.
+unset VISUAL EMAIL LANGUAGE $(perl -e '
my @env = keys %ENV;
my $ok = join("|", qw(
TRACE
@@ -55,6 +56,7 @@ unset $(perl -e '
.*_TEST
PROVE
VALGRIND
+ PERF_AGGREGATING_LATER
));
my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
print join("\n", @vars);
@@ -98,6 +100,8 @@ _z40=0000000000000000000000000000000000000000
LF='
'
+export _x05 _x40 _z40 LF
+
# Each test should start with something like this, after copyright notices:
#
# test_description='Description of this test...
@@ -223,248 +227,9 @@ die () {
GIT_EXIT_OK=
trap 'die' EXIT
-# The semantics of the editor variables are that of invoking
-# sh -c "$EDITOR \"$@\"" files ...
-#
-# If our trash directory contains shell metacharacters, they will be
-# interpreted if we just set $EDITOR directly, so do a little dance with
-# environment variables to work around this.
-#
-# In particular, quoting isn't enough, as the path may contain the same quote
-# that we're using.
-test_set_editor () {
- FAKE_EDITOR="$1"
- export FAKE_EDITOR
- EDITOR='"$FAKE_EDITOR"'
- export EDITOR
-}
-
-test_decode_color () {
- awk '
- function name(n) {
- if (n == 0) return "RESET";
- if (n == 1) return "BOLD";
- if (n == 30) return "BLACK";
- if (n == 31) return "RED";
- if (n == 32) return "GREEN";
- if (n == 33) return "YELLOW";
- if (n == 34) return "BLUE";
- if (n == 35) return "MAGENTA";
- if (n == 36) return "CYAN";
- if (n == 37) return "WHITE";
- if (n == 40) return "BLACK";
- if (n == 41) return "BRED";
- if (n == 42) return "BGREEN";
- if (n == 43) return "BYELLOW";
- if (n == 44) return "BBLUE";
- if (n == 45) return "BMAGENTA";
- if (n == 46) return "BCYAN";
- if (n == 47) return "BWHITE";
- }
- {
- while (match($0, /\033\[[0-9;]*m/) != 0) {
- printf "%s<", substr($0, 1, RSTART-1);
- codes = substr($0, RSTART+2, RLENGTH-3);
- if (length(codes) == 0)
- printf "%s", name(0)
- else {
- n = split(codes, ary, ";");
- sep = "";
- for (i = 1; i <= n; i++) {
- printf "%s%s", sep, name(ary[i]);
- sep = ";"
- }
- }
- printf ">";
- $0 = substr($0, RSTART + RLENGTH, length($0) - RSTART - RLENGTH + 1);
- }
- print
- }
- '
-}
-
-nul_to_q () {
- perl -pe 'y/\000/Q/'
-}
-
-q_to_nul () {
- perl -pe 'y/Q/\000/'
-}
-
-q_to_cr () {
- tr Q '\015'
-}
-
-q_to_tab () {
- tr Q '\011'
-}
-
-append_cr () {
- sed -e 's/$/Q/' | tr Q '\015'
-}
-
-remove_cr () {
- tr '\015' Q | sed -e 's/Q$//'
-}
-
-# In some bourne shell implementations, the "unset" builtin returns
-# nonzero status when a variable to be unset was not set in the first
-# place.
-#
-# Use sane_unset when that should not be considered an error.
-
-sane_unset () {
- unset "$@"
- return 0
-}
-
-test_tick () {
- if test -z "${test_tick+set}"
- then
- test_tick=1112911993
- else
- test_tick=$(($test_tick + 60))
- fi
- GIT_COMMITTER_DATE="$test_tick -0700"
- GIT_AUTHOR_DATE="$test_tick -0700"
- export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
-}
-
-# Stop execution and start a shell. This is useful for debugging tests and
-# only makes sense together with "-v".
-#
-# Be sure to remove all invocations of this command before submitting.
-
-test_pause () {
- if test "$verbose" = t; then
- "$SHELL_PATH" <&6 >&3 2>&4
- else
- error >&5 "test_pause requires --verbose"
- fi
-}
-
-# Call test_commit with the arguments "<message> [<file> [<contents>]]"
-#
-# This will commit a file with the given contents and the given commit
-# message. It will also add a tag with <message> as name.
-#
-# Both <file> and <contents> default to <message>.
-
-test_commit () {
- file=${2:-"$1.t"}
- echo "${3-$1}" > "$file" &&
- git add "$file" &&
- test_tick &&
- git commit -m "$1" &&
- git tag "$1"
-}
-
-# Call test_merge with the arguments "<message> <commit>", where <commit>
-# can be a tag pointing to the commit-to-merge.
-
-test_merge () {
- test_tick &&
- git merge -m "$1" "$2" &&
- git tag "$1"
-}
-
-# This function helps systems where core.filemode=false is set.
-# Use it instead of plain 'chmod +x' to set or unset the executable bit
-# of a file in the working directory and add it to the index.
-
-test_chmod () {
- chmod "$@" &&
- git update-index --add "--chmod=$@"
-}
-
-# Unset a configuration variable, but don't fail if it doesn't exist.
-test_unconfig () {
- git config --unset-all "$@"
- config_status=$?
- case "$config_status" in
- 5) # ok, nothing to unset
- config_status=0
- ;;
- esac
- return $config_status
-}
-
-# Set git config, automatically unsetting it after the test is over.
-test_config () {
- test_when_finished "test_unconfig '$1'" &&
- git config "$@"
-}
-
-
-test_config_global () {
- test_when_finished "test_unconfig --global '$1'" &&
- git config --global "$@"
-}
-
-write_script () {
- {
- echo "#!${2-"$SHELL_PATH"}" &&
- cat
- } >"$1" &&
- chmod +x "$1"
-}
-
-# Use test_set_prereq to tell that a particular prerequisite is available.
-# The prerequisite can later be checked for in two ways:
-#
-# - Explicitly using test_have_prereq.
-#
-# - Implicitly by specifying the prerequisite tag in the calls to
-# test_expect_{success,failure,code}.
-#
-# The single parameter is the prerequisite tag (a simple word, in all
-# capital letters by convention).
-
-test_set_prereq () {
- satisfied="$satisfied$1 "
-}
-satisfied=" "
-
-test_have_prereq () {
- # 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
-}
-
-test_declared_prereq () {
- case ",$test_prereq," in
- *,$1,*)
- return 0
- ;;
- esac
- return 1
-}
+# The user-facing functions are loaded from a separate file so that
+# test_perf subshells can have them too
+. "${TEST_DIRECTORY:-.}"/test-lib-functions.sh
# You are not expected to call test_ok_ and test_failure_ directly, use
# the text_expect_* functions instead.
@@ -552,318 +317,16 @@ test_skip () {
esac
}
-test_expect_failure () {
- test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
- test "$#" = 2 ||
- error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
- export test_prereq
- if ! test_skip "$@"
- then
- say >&3 "checking known breakage: $2"
- if test_run_ "$2" expecting_failure
- then
- test_known_broken_ok_ "$1"
- else
- test_known_broken_failure_ "$1"
- fi
- fi
- echo >&3 ""
-}
-
-test_expect_success () {
- test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
- test "$#" = 2 ||
- error "bug in the test script: not 2 or 3 parameters to test-expect-success"
- export test_prereq
- if ! test_skip "$@"
- then
- say >&3 "expecting success: $2"
- if test_run_ "$2"
- then
- test_ok_ "$1"
- else
- test_failure_ "$@"
- fi
- fi
- echo >&3 ""
-}
-
-# 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
-# <n>: ..." before running it. When providing relative paths, keep in
-# mind that all scripts run in "trash directory".
-# Usage: test_external description command arguments...
-# Example: test_external 'Perl API' perl ../path/to/test.pl
-test_external () {
- test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
- test "$#" = 3 ||
- error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
- descr="$1"
- shift
- export test_prereq
- if ! test_skip "$descr" "$@"
- then
- # Announce the script to reduce confusion about the
- # test output that follows.
- 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
- # Run command; redirect its stderr to &4 as in
- # test_run_, but keep its stdout on our stdout even in
- # non-verbose mode.
- "$@" 2>&4
- if [ "$?" = 0 ]
- then
- 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
- 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
-}
-
-# Like test_external, but in addition tests that the command generated
-# no output on stderr.
-test_external_without_stderr () {
- # The temporary file has no (and must have no) security
- # implications.
- tmp=${TMPDIR:-/tmp}
- stderr="$tmp/git-external-stderr.$$.tmp"
- test_external "$@" 4> "$stderr"
- [ -f "$stderr" ] || error "Internal error: $stderr disappeared."
- descr="no stderr: $1"
- shift
- say >&3 "# expecting no stderr from previous command"
- if [ ! -s "$stderr" ]; then
- rm "$stderr"
-
- 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"`
- else
- output=
- fi
- # rm first in case test_failure exits.
- rm "$stderr"
- 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
-}
-
-# test_line_count checks that a file has the number of lines it
-# ought to. For example:
-#
-# test_expect_success 'produce exactly one line of output' '
-# do something >output &&
-# test_line_count = 1 output
-# '
-#
-# is like "test $(wc -l <output) = 1" except that it passes the
-# output through when the number of lines is wrong.
-
-test_line_count () {
- if test $# != 3
- then
- error "bug in the test script: not 3 parameters to test_line_count"
- elif ! test $(wc -l <"$3") "$1" "$2"
- then
- echo "test_line_count: line count for $3 !$1 $2"
- cat "$3"
- return 1
- 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:
-#
-# test_expect_success 'complain and die' '
-# do something &&
-# do something else &&
-# test_must_fail git checkout ../outerspace
-# '
-#
-# Writing this as "! git checkout ../outerspace" is wrong, because
-# the failure could be due to a segv. We want a controlled failure.
-
-test_must_fail () {
- "$@"
- 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
-# meant to be used in contexts like:
-#
-# test_expect_success 'some command works without configuration' '
-# test_might_fail git config --unset all.configuration &&
-# do something
-# '
-#
-# Writing "git config --unset all.configuration || :" would be wrong,
-# because we want to notice if it fails due to segv.
-
-test_might_fail () {
- "$@"
- 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
-}
-
-# Similar to test_must_fail and test_might_fail, but check that a
-# given command exited with a given exit code. Meant to be used as:
-#
-# test_expect_success 'Merge with d/f conflicts' '
-# test_expect_code 1 git merge "merge msg" B master
-# '
-
-test_expect_code () {
- want_code=$1
- shift
- "$@"
- exit_code=$?
- if test $exit_code = $want_code
- then
- return 0
- fi
-
- echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
- return 1
-}
-
-# test_cmp is a helper function to compare actual and expected output.
-# You can use it like:
-#
-# test_expect_success 'foo works' '
-# echo expected >expected &&
-# foo >actual &&
-# test_cmp expected actual
-# '
-#
-# This could be written as either "cmp" or "diff -u", but:
-# - cmp's output is not nearly as easy to read as diff -u
-# - not all diff versions understand "-u"
-
-test_cmp() {
- $GIT_TEST_CMP "$@"
-}
-
-# This function can be used to schedule some commands to be run
-# unconditionally at the end of the test to restore sanity:
-#
-# test_expect_success 'test core.capslock' '
-# git config core.capslock true &&
-# test_when_finished "git config --unset core.capslock" &&
-# hello world
-# '
-#
-# That would be roughly equivalent to
-#
-# test_expect_success 'test core.capslock' '
-# git config core.capslock true &&
-# hello world
-# git config --unset core.capslock
-# '
-#
-# except that the greeting and config --unset must both succeed for
-# the test to pass.
-#
-# Note that under --immediate mode, no clean-up is done to help diagnose
-# what went wrong.
-
-test_when_finished () {
- test_cleanup="{ $*
- } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
-}
-
-# Most tests can use the created repository, but some may need to create more.
-# Usage: test_create_repo <directory>
-test_create_repo () {
- test "$#" = 1 ||
- error "bug in the test script: not 1 parameter to test-create-repo"
- repo="$1"
- mkdir -p "$repo"
- (
- 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
+# stub; perf-lib overrides it
+test_at_end_hook_ () {
+ :
}
test_done () {
GIT_EXIT_OK=t
if test -z "$HARNESS_ACTIVE"; then
- test_results_dir="$TEST_DIRECTORY/test-results"
+ test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
test_results_path="$test_results_dir/${0%.sh}-$$.counts"
@@ -902,6 +365,8 @@ test_done () {
cd "$(dirname "$remove_trash")" &&
rm -rf "$(basename "$remove_trash")"
+ test_at_end_hook_
+
exit 0 ;;
*)
@@ -924,6 +389,12 @@ then
# itself.
TEST_DIRECTORY=$(pwd)
fi
+if test -z "$TEST_OUTPUT_DIRECTORY"
+then
+ # Similarly, override this to store the test-results subdir
+ # elsewhere
+ TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY
+fi
GIT_BUILD_DIR="$TEST_DIRECTORY"/..
if test -n "$valgrind"
@@ -1059,7 +530,7 @@ test="trash directory.$(basename "$0" .sh)"
test -n "$root" && test="$root/$test"
case "$test" in
/*) TRASH_DIRECTORY="$test" ;;
- *) TRASH_DIRECTORY="$TEST_DIRECTORY/$test" ;;
+ *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$test" ;;
esac
test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY
rm -fr "$test" || {
@@ -1071,7 +542,11 @@ rm -fr "$test" || {
HOME="$TRASH_DIRECTORY"
export HOME
-test_create_repo "$test"
+if test -z "$TEST_NO_CREATE_REPO"; then
+ test_create_repo "$test"
+else
+ mkdir -p "$test"
+fi
# Use -P to resolve symlinks in our working directory so that the cwd
# in subprocesses like git equals our $PWD (for pathname comparisons).
cd -P "$test" || exit 1