summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/Git-SVN/00compile.t14
-rw-r--r--t/Git-SVN/Utils/add_path_to_url.t27
-rw-r--r--t/Git-SVN/Utils/can_compress.t11
-rw-r--r--t/Git-SVN/Utils/canonicalize_url.t26
-rw-r--r--t/Git-SVN/Utils/collapse_dotdot.t23
-rw-r--r--t/Git-SVN/Utils/fatal.t34
-rw-r--r--t/Git-SVN/Utils/join_paths.t32
-rw-r--r--t/Makefile17
-rw-r--r--t/README34
-rwxr-xr-xt/check-non-portable-shell.pl27
-rw-r--r--t/gitweb-lib.sh2
-rw-r--r--t/lib-bash.sh18
-rwxr-xr-xt/lib-credential.sh43
-rw-r--r--t/lib-gettext.sh6
-rw-r--r--t/lib-git-p4.sh83
-rw-r--r--t/lib-httpd.sh43
-rw-r--r--t/lib-httpd/apache.conf37
-rw-r--r--t/perf/.gitignore5
-rwxr-xr-xt/perf/p5302-pack-index.sh40
-rw-r--r--t/perf/perf-lib.sh3
-rwxr-xr-xt/t0000-basic.sh274
-rwxr-xr-xt/t0003-attributes.sh57
-rwxr-xr-xt/t0006-date.sh2
-rwxr-xr-xt/t0007-git-var.sh49
-rwxr-xr-xt/t0023-crlf-am.sh2
-rwxr-xr-xt/t0024-crlf-archive.sh16
-rwxr-xr-xt/t0040-parse-options.sh34
-rwxr-xr-xt/t0050-filesystem.sh64
-rwxr-xr-xt/t0060-path-utils.sh100
-rwxr-xr-xt/t0063-string-list.sh91
-rwxr-xr-xt/t0070-fundamental.sh5
-rwxr-xr-xt/t0201-gettext-fallbacks.sh8
-rwxr-xr-xt/t0300-credentials.sh14
-rwxr-xr-xt/t1010-mktree.sh4
-rwxr-xr-xt/t1020-subdirectory.sh12
-rwxr-xr-xt/t1050-large.sh29
-rwxr-xr-xt/t1100-commit-tree-options.sh18
-rwxr-xr-xt/t1200-tutorial.sh4
-rwxr-xr-xt/t1300-repo-config.sh323
-rwxr-xr-xt/t1304-default-acl.sh19
-rwxr-xr-xt/t1306-xdg-files.sh197
-rwxr-xr-xt/t1400-update-ref.sh18
-rwxr-xr-xt/t1401-symbolic-ref.sh30
-rwxr-xr-xt/t1402-check-ref-format.sh6
-rwxr-xr-xt/t1411-reflog-show.sh61
-rwxr-xr-xt/t1450-fsck.sh61
-rwxr-xr-xt/t1502-rev-parse-parseopt.sh2
-rwxr-xr-xt/t1505-rev-parse-last.sh18
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh25
-rwxr-xr-xt/t1512-rev-parse-disambiguation.sh264
-rwxr-xr-xt/t2006-checkout-index-basic.sh4
-rwxr-xr-xt/t2015-checkout-unborn.sh11
-rwxr-xr-xt/t2017-checkout-orphan.sh6
-rwxr-xr-xt/t2020-checkout-detach.sh22
-rwxr-xr-xt/t2107-update-index-basic.sh23
-rwxr-xr-xt/t2203-add-intent.sh20
-rwxr-xr-xt/t3001-ls-files-others-exclude.sh24
-rwxr-xr-xt/t3004-ls-files-basic.sh4
-rwxr-xr-xt/t3006-ls-files-long.sh39
-rwxr-xr-xt/t3070-wildmatch.sh195
-rwxr-xr-xt/t3200-branch.sh170
-rwxr-xr-xt/t3300-funny-names.sh30
-rwxr-xr-xt/t3400-rebase.sh8
-rwxr-xr-xt/t3401-rebase-partial.sh24
-rwxr-xr-xt/t3404-rebase-interactive.sh194
-rwxr-xr-xt/t3405-rebase-malformed.sh32
-rwxr-xr-xt/t3406-rebase-message.sh12
-rwxr-xr-xt/t3411-rebase-preserve-around-merges.sh1
-rwxr-xr-xt/t3412-rebase-root.sh7
-rwxr-xr-xt/t3501-revert-cherry-pick.sh13
-rwxr-xr-xt/t3505-cherry-pick-empty.sh35
-rwxr-xr-xt/t3506-cherry-pick-ff.sh8
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh38
-rwxr-xr-xt/t3508-cherry-pick-many-commits.sh23
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh14
-rwxr-xr-xt/t3600-rm.sh360
-rwxr-xr-xt/t3902-quoted.sh31
-rwxr-xr-xt/t3903-stash.sh4
-rwxr-xr-xt/t3910-mac-os-precompose.sh153
-rwxr-xr-xt/t4006-diff-mode.sh65
-rwxr-xr-xt/t4012-diff-binary.sh119
-rw-r--r--t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master4
-rw-r--r--t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side6
-rw-r--r--t/t4013/diff.diff-tree_--cc_--patch-with-stat_master4
-rw-r--r--t/t4013/diff.diff-tree_--cc_--stat_--summary_master4
-rw-r--r--t/t4013/diff.diff-tree_--cc_--stat_--summary_side6
-rw-r--r--t/t4013/diff.diff-tree_--cc_--stat_master4
-rw-r--r--t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial6
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side6
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial6
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial6
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--root_--stat_initial6
-rw-r--r--t/t4013/diff.diff-tree_--root_--patch-with-stat_initial6
-rw-r--r--t/t4013/diff.diff-tree_-c_--stat_--summary_master4
-rw-r--r--t/t4013/diff.diff-tree_-c_--stat_--summary_side6
-rw-r--r--t/t4013/diff.diff-tree_-c_--stat_master4
-rw-r--r--t/t4013/diff.diff_--patch-with-stat_-r_initial..side6
-rw-r--r--t/t4013/diff.diff_--patch-with-stat_initial..side6
-rw-r--r--t/t4013/diff.diff_--stat_initial..side6
-rw-r--r--t/t4013/diff.diff_-r_--stat_initial..side6
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side6
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..master16
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..master^10
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..side6
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master16
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master16
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master16
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master^10
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master^^6
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..side6
-rw-r--r--t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^18
-rw-r--r--t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master16
-rw-r--r--t/t4013/diff.format-patch_--stdout_--numbered_initial..master16
-rw-r--r--t/t4013/diff.format-patch_--stdout_initial..master16
-rw-r--r--t/t4013/diff.format-patch_--stdout_initial..master^10
-rw-r--r--t/t4013/diff.format-patch_--stdout_initial..side6
-rw-r--r--t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_6
-rw-r--r--t/t4013/diff.log_--patch-with-stat_master16
-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_master26
-rw-r--r--t/t4013/diff.log_--root_--patch-with-stat_--summary_master22
-rw-r--r--t/t4013/diff.log_--root_--patch-with-stat_master22
-rw-r--r--t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master26
-rw-r--r--t/t4013/diff.show_--patch-with-stat_--summary_side6
-rw-r--r--t/t4013/diff.show_--patch-with-stat_side6
-rw-r--r--t/t4013/diff.show_--stat_--summary_side6
-rw-r--r--t/t4013/diff.show_--stat_side6
-rw-r--r--t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_6
-rw-r--r--t/t4013/diff.whatchanged_--patch-with-stat_master16
-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_master26
-rw-r--r--t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master22
-rw-r--r--t/t4013/diff.whatchanged_--root_--patch-with-stat_master22
-rw-r--r--t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master26
-rwxr-xr-xt/t4014-format-patch.sh306
-rwxr-xr-xt/t4016-diff-quote.sh34
-rwxr-xr-xt/t4018-diff-funcname.sh2
-rwxr-xr-xt/t4020-diff-external.sh61
-rwxr-xr-xt/t4022-diff-rewrite.sh30
-rwxr-xr-xt/t4029-diff-trailing-space.sh2
-rwxr-xr-xt/t4030-diff-textconv.sh28
-rwxr-xr-xt/t4031-diff-rewrite-binary.sh2
-rwxr-xr-xt/t4034-diff-words.sh1
-rw-r--r--t/t4034/ada/expect27
-rw-r--r--t/t4034/ada/post13
-rw-r--r--t/t4034/ada/pre13
-rwxr-xr-xt/t4035-diff-quiet.sh73
-rwxr-xr-xt/t4041-diff-submodule-option.sh543
-rwxr-xr-xt/t4045-diff-relative.sh2
-rwxr-xr-xt/t4049-diff-stat-count.sh53
-rwxr-xr-xt/t4052-stat-output.sh130
-rwxr-xr-xt/t4053-diff-no-index.sh32
-rwxr-xr-xt/t4054-diff-bogus-tree.sh83
-rwxr-xr-xt/t4055-diff-context.sh92
-rwxr-xr-xt/t4103-apply-binary.sh54
-rwxr-xr-xt/t4108-apply-threeway.sh157
-rwxr-xr-xt/t4116-apply-reverse.sh4
-rwxr-xr-xt/t4117-apply-reject.sh8
-rwxr-xr-xt/t4120-apply-popt.sh4
-rwxr-xr-xt/t4133-apply-filenames.sh4
-rwxr-xr-xt/t4200-rerere.sh12
-rwxr-xr-xt/t4201-shortlog.sh24
-rwxr-xr-xt/t4202-log.sh69
-rwxr-xr-xt/t4203-mailmap.sh154
-rwxr-xr-xt/t4205-log-pretty-formats.sh28
-rwxr-xr-xt/t4253-am-keep-cr-dos.sh4
-rwxr-xr-xt/t4300-merge-tree.sh44
-rwxr-xr-xt/t5000-tar-tree.sh65
-rwxr-xr-xt/t5002-archive-attr-pattern.sh57
-rwxr-xr-xt/t5003-archive-zip.sh131
-rw-r--r--t/t5003/infozip-symlinks.zipbin0 -> 328 bytes
-rwxr-xr-xt/t5100-mailinfo.sh2
-rw-r--r--t/t5100/info00175
-rw-r--r--t/t5100/msg00172
-rw-r--r--t/t5100/patch00012
-rw-r--r--t/t5100/patch00022
-rw-r--r--t/t5100/patch00032
-rw-r--r--t/t5100/patch00054
-rw-r--r--t/t5100/patch00062
-rw-r--r--t/t5100/patch00102
-rw-r--r--t/t5100/patch00112
-rw-r--r--t/t5100/patch00142
-rw-r--r--t/t5100/patch0014--scissors2
-rw-r--r--t/t5100/patch00176
-rw-r--r--t/t5100/sample.mbox34
-rwxr-xr-xt/t5300-pack-object.sh15
-rwxr-xr-xt/t5303-pack-corruption-resilience.sh4
-rwxr-xr-xt/t5400-send-pack.sh34
-rwxr-xr-xt/t5500-fetch-pack.sh54
-rwxr-xr-xt/t5504-fetch-receive-strict.sh2
-rwxr-xr-xt/t5505-remote.sh32
-rwxr-xr-xt/t5512-ls-remote.sh16
-rwxr-xr-xt/t5514-fetch-multiple.sh30
-rwxr-xr-xt/t5516-fetch-push.sh44
-rwxr-xr-xt/t5528-push-default.sh78
-rwxr-xr-xt/t5530-upload-pack-error.sh4
-rwxr-xr-xt/t5532-fetch-proxy.sh2
-rwxr-xr-xt/t5535-fetch-push-symref.sh42
-rwxr-xr-xt/t5540-http-push.sh19
-rwxr-xr-xt/t5541-http-push.sh58
-rwxr-xr-xt/t5550-http-fetch.sh77
-rwxr-xr-xt/t5551-http-fetch.sh54
-rwxr-xr-xt/t5570-git-daemon.sh30
-rwxr-xr-xt/t5600-clone-fail-cleanup.sh12
-rwxr-xr-xt/t5701-clone-local.sh83
-rwxr-xr-xt/t5709-clone-refspec.sh156
-rwxr-xr-xt/t5800-remote-testpy.sh (renamed from t/t5800-remote-helpers.sh)37
-rwxr-xr-xt/t5801-remote-helpers.sh169
-rwxr-xr-xt/t6006-rev-list-format.sh70
-rwxr-xr-xt/t6011-rev-list-with-bad-commit.sh2
-rwxr-xr-xt/t6013-rev-list-reverse-parents.sh4
-rwxr-xr-xt/t6022-merge-rename.sh16
-rwxr-xr-xt/t6030-bisect-porcelain.sh4
-rwxr-xr-xt/t6037-merge-ours-theirs.sh14
-rwxr-xr-xt/t6042-merge-rename-corner-cases.sh2
-rwxr-xr-xt/t6050-replace.sh11
-rwxr-xr-xt/t6130-pathspec-noglob.sh68
-rwxr-xr-xt/t6200-fmt-merge-msg.sh36
-rwxr-xr-xt/t6300-for-each-ref.sh10
-rwxr-xr-xt/t6500-gc.sh4
-rwxr-xr-xt/t7003-filter-branch.sh8
-rwxr-xr-xt/t7004-tag.sh49
-rwxr-xr-xt/t7007-show.sh103
-rwxr-xr-xt/t7008-grep-binary.sh22
-rwxr-xr-xt/t7060-wtstatus.sh96
-rwxr-xr-xt/t7061-wtstatus-ignore.sh146
-rwxr-xr-xt/t7400-submodule-basic.sh253
-rwxr-xr-xt/t7403-submodule-sync.sh143
-rwxr-xr-xt/t7406-submodule-update.sh74
-rwxr-xr-xt/t7407-submodule-foreach.sh4
-rwxr-xr-xt/t7408-submodule-reference.sh4
-rwxr-xr-xt/t7409-submodule-detached-worktree.sh78
-rwxr-xr-xt/t7500/add-content-and-comment5
-rwxr-xr-xt/t7501-commit.sh37
-rwxr-xr-xt/t7502-commit.sh149
-rwxr-xr-xt/t7505-prepare-commit-msg-hook.sh14
-rwxr-xr-xt/t7508-status.sh42
-rwxr-xr-xt/t7512-status-help.sh649
-rwxr-xr-xt/t7600-merge.sh2
-rwxr-xr-xt/t7602-merge-octopus-many.sh12
-rwxr-xr-xt/t7610-mergetool.sh51
-rwxr-xr-xt/t7800-difftool.sh68
-rwxr-xr-xt/t7810-grep.sh329
-rwxr-xr-xt/t8004-blame-with-conflicts.sh2
-rwxr-xr-xt/t8006-blame-textconv.sh2
-rwxr-xr-xt/t9001-send-email.sh132
-rwxr-xr-xt/t9002-column.sh180
-rwxr-xr-xt/t9020-remote-svn.sh88
-rwxr-xr-xt/t9107-git-svn-migrate.sh6
-rwxr-xr-xt/t9118-git-svn-funky-branch-names.sh9
-rwxr-xr-xt/t9129-git-svn-i18n-commitencoding.sh2
-rwxr-xr-xt/t9137-git-svn-dcommit-clobber-series.sh8
-rwxr-xr-xt/t9154-git-svn-fancy-glob.sh9
-rwxr-xr-xt/t9163-git-svn-reset-clears-caches.sh78
-rwxr-xr-xt/t9164-git-svn-dcommit-concurrent.sh216
-rwxr-xr-xt/t9165-git-svn-fetch-merge-branch-of-branch.sh60
-rwxr-xr-xt/t9166-git-svn-fetch-merge-branch-of-branch2.sh53
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh5
-rwxr-xr-xt/t9300-fast-import.sh6
-rwxr-xr-xt/t9350-fast-export.sh69
-rwxr-xr-xt/t9400-git-cvsserver-server.sh72
-rwxr-xr-xt/t9401-git-cvsserver-crlf.sh35
-rwxr-xr-xt/t9501-gitweb-standalone-http-status.sh21
-rwxr-xr-xt/t9502-gitweb-standalone-parse-output.sh17
-rwxr-xr-xt/t9604-cvsimport-timestamps.sh71
-rw-r--r--t/t9604/cvsroot/.gitattributes1
-rw-r--r--t/t9604/cvsroot/CVSROOT/.gitignore2
-rw-r--r--t/t9604/cvsroot/module/a,v264
-rwxr-xr-xt/t9700/test.pl3
-rwxr-xr-xt/t9800-git-p4-basic.sh324
-rwxr-xr-xt/t9801-git-p4-branch.sh187
-rwxr-xr-xt/t9805-git-p4-skip-submit-edit.sh11
-rwxr-xr-xt/t9806-git-p4-options.sh17
-rwxr-xr-xt/t9807-git-p4-submit.sh321
-rwxr-xr-xt/t9808-git-p4-chdir.sh4
-rwxr-xr-xt/t9809-git-p4-client-view.sh57
-rwxr-xr-xt/t9810-git-p4-rcs.sh103
-rwxr-xr-xt/t9811-git-p4-label-import.sh222
-rwxr-xr-xt/t9812-git-p4-wildcards.sh147
-rwxr-xr-xt/t9813-git-p4-preserve-users.sh153
-rwxr-xr-xt/t9814-git-p4-rename.sh241
-rwxr-xr-xt/t9815-git-p4-submit-fail.sh429
-rwxr-xr-xt/t9902-completion.sh169
-rwxr-xr-xt/t9903-bash-prompt.sh456
-rw-r--r--t/test-lib-functions.sh127
-rw-r--r--t/test-lib.sh216
-rwxr-xr-xt/test-terminal.perl2
287 files changed, 12998 insertions, 2230 deletions
diff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t
new file mode 100644
index 0000000000..c92fee453f
--- /dev/null
+++ b/t/Git-SVN/00compile.t
@@ -0,0 +1,14 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 7;
+
+require_ok 'Git::SVN';
+require_ok 'Git::SVN::Utils';
+require_ok 'Git::SVN::Ra';
+require_ok 'Git::SVN::Log';
+require_ok 'Git::SVN::Migration';
+require_ok 'Git::IndexInfo';
+require_ok 'Git::SVN::GlobSpec';
diff --git a/t/Git-SVN/Utils/add_path_to_url.t b/t/Git-SVN/Utils/add_path_to_url.t
new file mode 100644
index 0000000000..bfbd87845f
--- /dev/null
+++ b/t/Git-SVN/Utils/add_path_to_url.t
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils qw(
+ add_path_to_url
+);
+
+# A reference cannot be a hash key, so we use an array.
+my @tests = (
+ ["http://x.com", "bar"] => 'http://x.com/bar',
+ ["http://x.com", ""] => 'http://x.com',
+ ["http://x.com/foo/", undef] => 'http://x.com/foo/',
+ ["http://x.com/foo/", "/bar/baz/"] => 'http://x.com/foo/bar/baz/',
+ ["http://x.com", 'per%cent'] => 'http://x.com/per%25cent',
+);
+
+while(@tests) {
+ my($have, $want) = splice @tests, 0, 2;
+
+ my $args = join ", ", map { qq['$_'] } map { defined($_) ? $_ : 'undef' } @$have;
+ my $name = "add_path_to_url($args) eq $want";
+ is add_path_to_url(@$have), $want, $name;
+}
diff --git a/t/Git-SVN/Utils/can_compress.t b/t/Git-SVN/Utils/can_compress.t
new file mode 100644
index 0000000000..d7b49b8d54
--- /dev/null
+++ b/t/Git-SVN/Utils/can_compress.t
@@ -0,0 +1,11 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils qw(can_compress);
+
+# !! is the "convert this to boolean" operator.
+is !!can_compress(), !!eval { require Compress::Zlib };
diff --git a/t/Git-SVN/Utils/canonicalize_url.t b/t/Git-SVN/Utils/canonicalize_url.t
new file mode 100644
index 0000000000..05795ab636
--- /dev/null
+++ b/t/Git-SVN/Utils/canonicalize_url.t
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+
+# Test our own home rolled URL canonicalizer. Test the private one
+# directly because we can't predict what the SVN API is doing to do.
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils;
+my $canonicalize_url = \&Git::SVN::Utils::_canonicalize_url_ourselves;
+
+my %tests = (
+ "http://x.com" => "http://x.com",
+ "http://x.com/" => "http://x.com",
+ "http://x.com/foo/bar" => "http://x.com/foo/bar",
+ "http://x.com//foo//bar//" => "http://x.com/foo/bar",
+ "http://x.com/ /%/" => "http://x.com/%20%20/%25",
+);
+
+for my $arg (keys %tests) {
+ my $want = $tests{$arg};
+
+ is $canonicalize_url->($arg), $want, "canonicalize_url('$arg') => $want";
+}
diff --git a/t/Git-SVN/Utils/collapse_dotdot.t b/t/Git-SVN/Utils/collapse_dotdot.t
new file mode 100644
index 0000000000..1da1cce156
--- /dev/null
+++ b/t/Git-SVN/Utils/collapse_dotdot.t
@@ -0,0 +1,23 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils;
+my $collapse_dotdot = \&Git::SVN::Utils::_collapse_dotdot;
+
+my %tests = (
+ "foo/bar/baz" => "foo/bar/baz",
+ ".." => "..",
+ "foo/.." => "",
+ "/foo/bar/../../baz" => "/baz",
+ "deeply/.././deeply/nested" => "./deeply/nested",
+);
+
+for my $arg (keys %tests) {
+ my $want = $tests{$arg};
+
+ is $collapse_dotdot->($arg), $want, "_collapse_dotdot('$arg') => $want";
+}
diff --git a/t/Git-SVN/Utils/fatal.t b/t/Git-SVN/Utils/fatal.t
new file mode 100644
index 0000000000..49e1438295
--- /dev/null
+++ b/t/Git-SVN/Utils/fatal.t
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+BEGIN {
+ # Override exit at BEGIN time before Git::SVN::Utils is loaded
+ # so it will see our local exit later.
+ *CORE::GLOBAL::exit = sub(;$) {
+ return @_ ? CORE::exit($_[0]) : CORE::exit();
+ };
+}
+
+use Git::SVN::Utils qw(fatal);
+
+# fatal()
+{
+ # Capture the exit code and prevent exit.
+ my $exit_status;
+ no warnings 'redefine';
+ local *CORE::GLOBAL::exit = sub { $exit_status = $_[0] || 0 };
+
+ # Trap fatal's message to STDERR
+ my $stderr;
+ close STDERR;
+ ok open STDERR, ">", \$stderr;
+
+ fatal "Some", "Stuff", "Happened";
+
+ is $stderr, "Some Stuff Happened\n";
+ is $exit_status, 1;
+}
diff --git a/t/Git-SVN/Utils/join_paths.t b/t/Git-SVN/Utils/join_paths.t
new file mode 100644
index 0000000000..d4488e7162
--- /dev/null
+++ b/t/Git-SVN/Utils/join_paths.t
@@ -0,0 +1,32 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils qw(
+ join_paths
+);
+
+# A reference cannot be a hash key, so we use an array.
+my @tests = (
+ [] => '',
+ ["/x.com", "bar"] => '/x.com/bar',
+ ["x.com", ""] => 'x.com',
+ ["/x.com/foo/", undef, "bar"] => '/x.com/foo/bar',
+ ["x.com/foo/", "/bar/baz/"] => 'x.com/foo/bar/baz/',
+ ["foo", "bar"] => 'foo/bar',
+ ["/foo/bar", "baz", "/biff"] => '/foo/bar/baz/biff',
+ ["", undef, "."] => '.',
+ [] => '',
+
+);
+
+while(@tests) {
+ my($have, $want) = splice @tests, 0, 2;
+
+ my $args = join ", ", map { qq['$_'] } map { defined($_) ? $_ : 'undef' } @$have;
+ my $name = "join_paths($args) eq '$want'";
+ is join_paths(@$have), $want, $name;
+}
diff --git a/t/Makefile b/t/Makefile
index 6091211f10..1923cc104b 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -6,16 +6,18 @@
-include ../config.mak.autogen
-include ../config.mak
-#GIT_TEST_OPTS=--verbose --debug
+#GIT_TEST_OPTS = --verbose --debug
SHELL_PATH ?= $(SHELL)
PERL_PATH ?= /usr/bin/perl
TAR ?= $(TAR)
RM ?= rm -f
PROVE ?= prove
DEFAULT_TEST_TARGET ?= test
+TEST_LINT ?= test-lint-duplicates test-lint-executable
# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh))
@@ -28,7 +30,7 @@ test: pre-clean $(TEST_LINT)
prove: pre-clean $(TEST_LINT)
@echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
- $(MAKE) clean
+ $(MAKE) clean-except-prove-cache
$(T):
@echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
@@ -36,12 +38,14 @@ $(T):
pre-clean:
$(RM) -r test-results
-clean:
+clean-except-prove-cache:
$(RM) -r 'trash directory'.* test-results
$(RM) -r valgrind/bin
+
+clean: clean-except-prove-cache
$(RM) .prove
-test-lint: test-lint-duplicates test-lint-executable
+test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax
test-lint-duplicates:
@dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
@@ -53,6 +57,9 @@ test-lint-executable:
test -z "$$bad" || { \
echo >&2 "non-executable tests:" $$bad; exit 1; }
+test-lint-shell-syntax:
+ @'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T)
+
aggregate-results-and-cleanup: $(T)
$(MAKE) aggregate-results
$(MAKE) clean
@@ -85,7 +92,7 @@ test-results:
mkdir -p test-results
test-results/git-smoke.tar.gz: test-results
- $(PERL_PATH) ./harness \
+ '$(PERL_PATH_SQ)' ./harness \
--archive="test-results/git-smoke.tar.gz" \
$(T)
diff --git a/t/README b/t/README
index 3534f43d01..e4128e5769 100644
--- a/t/README
+++ b/t/README
@@ -307,6 +307,25 @@ Don't:
Use test_done instead if you need to stop the tests early (see
"Skipping tests" below).
+ - use '! git cmd' when you want to make sure the git command exits
+ with failure in a controlled way by calling "die()". Instead,
+ use 'test_must_fail git cmd'. This will signal a failure if git
+ dies in an unexpected way (e.g. segfault).
+
+ - use perl without spelling it as "$PERL_PATH". This is to help our
+ friends on Windows where the platform Perl often adds CR before
+ the end of line, and they bundle Git with a version of Perl that
+ does not do so, whose path is specified with $PERL_PATH.
+
+ - use sh without spelling it as "$SHELL_PATH", when the script can
+ be misinterpreted by broken platform shell (e.g. Solaris).
+
+ - chdir around in tests. It is not sufficient to chdir to
+ somewhere and then chdir back to the original location later in
+ the test, as any intermediate step can fail and abort the test,
+ causing the next test to start in an unexpected directory. Do so
+ inside a subshell if necessary.
+
- Break the TAP output
The raw output from your test may be interpreted by a TAP harness. TAP
@@ -342,9 +361,9 @@ If you need to skip tests you should do so by using the three-arg form
of the test_* functions (see the "Test harness library" section
below), e.g.:
- test_expect_success PERL 'I need Perl' "
- '$PERL_PATH' -e 'hlagh() if unf_unf()'
- "
+ test_expect_success PERL 'I need Perl' '
+ "$PERL_PATH" -e "hlagh() if unf_unf()"
+ '
The advantage of skipping tests like this is that platforms that don't
have the PERL and other optional dependencies get an indication of how
@@ -606,6 +625,15 @@ use these, and "test_set_prereq" for how to define your own.
Git was compiled with USE_LIBPCRE=YesPlease. Wrap any tests
that use git-grep --perl-regexp or git-grep -P in these.
+ - CASE_INSENSITIVE_FS
+
+ Test is run on a case insensitive file system.
+
+ - UTF8_NFD_TO_NFC
+
+ Test is run on a filesystem which converts decomposed utf-8 (nfd)
+ to precomposed utf-8 (nfc).
+
Tips for Writing Tests
----------------------
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
new file mode 100755
index 0000000000..8b5a71dc05
--- /dev/null
+++ b/t/check-non-portable-shell.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+# Test t0000..t9999.sh for non portable shell scripts
+# This script can be called with one or more filenames as parameters
+
+use strict;
+use warnings;
+
+my $exit_code=0;
+
+sub err {
+ my $msg = shift;
+ print "$ARGV:$.: error: $msg: $_\n";
+ $exit_code = 1;
+}
+
+while (<>) {
+ chomp;
+ /^\s*sed\s+-i/ and err 'sed -i is not portable';
+ /^\s*echo\s+-n/ and err 'echo -n is not portable (please use printf)';
+ /^\s*declare\s+/ and err 'arrays/declare not portable';
+ /^\s*[^#]\s*which\s/ and err 'which is not portable (please use type)';
+ /test\s+[^=]*==/ and err '"test a == b" is not portable (please use =)';
+ # this resets our $. for each file
+ close ARGV if eof;
+}
+exit $exit_code;
diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh
index 21d11d6c2d..ae2dc4604f 100644
--- a/t/gitweb-lib.sh
+++ b/t/gitweb-lib.sh
@@ -69,7 +69,7 @@ gitweb_run () {
# written to web server logs, so we are not interested in that:
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
- perl -- "$SCRIPT_NAME" \
+ "$PERL_PATH" -- "$SCRIPT_NAME" \
>gitweb.output 2>gitweb.log &&
perl -w -e '
open O, ">gitweb.headers";
diff --git a/t/lib-bash.sh b/t/lib-bash.sh
new file mode 100644
index 0000000000..11397f747b
--- /dev/null
+++ b/t/lib-bash.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Ensures that tests are run under Bash; primarily intended for running tests
+# of the completion script.
+
+if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then
+ # we are in full-on bash mode
+ true
+elif type bash >/dev/null 2>&1; then
+ # execute in full-on bash mode
+ unset POSIXLY_CORRECT
+ exec bash "$0" "$@"
+else
+ echo '1..0 #SKIP skipping bash completion tests; bash not available'
+ exit 0
+fi
+
+. ./test-lib.sh
diff --git a/t/lib-credential.sh b/t/lib-credential.sh
index 4a37cd79e5..3c43ff11b3 100755
--- a/t/lib-credential.sh
+++ b/t/lib-credential.sh
@@ -4,10 +4,24 @@
# stdout and stderr should be provided on stdin,
# separated by "--".
check() {
+ credential_opts=
+ credential_cmd=$1
+ shift
+ for arg in "$@"; do
+ credential_opts="$credential_opts -c credential.helper='$arg'"
+ done
read_chunk >stdin &&
read_chunk >expect-stdout &&
read_chunk >expect-stderr &&
- test-credential "$@" <stdin >stdout 2>stderr &&
+ if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then
+ echo "git credential failed with code $?" &&
+ cat stderr &&
+ false
+ fi &&
+ if test_have_prereq MINGW
+ then
+ dos2unix -q stderr
+ fi &&
test_cmp expect-stdout stdout &&
test_cmp expect-stderr stderr
}
@@ -41,7 +55,7 @@ reject() {
echo protocol=$2
echo host=$3
echo username=$4
- ) | test-credential reject $1
+ ) | git -c credential.helper=$1 credential reject
}
helper_test() {
@@ -52,6 +66,8 @@ helper_test() {
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=askpass-username
password=askpass-password
--
@@ -74,6 +90,8 @@ helper_test() {
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=store-user
password=store-pass
--
@@ -85,6 +103,8 @@ helper_test() {
protocol=http
host=example.com
--
+ protocol=http
+ host=example.com
username=askpass-username
password=askpass-password
--
@@ -98,6 +118,8 @@ helper_test() {
protocol=https
host=other.tld
--
+ protocol=https
+ host=other.tld
username=askpass-username
password=askpass-password
--
@@ -112,6 +134,8 @@ helper_test() {
host=example.com
username=other
--
+ protocol=https
+ host=example.com
username=other
password=askpass-password
--
@@ -133,6 +157,9 @@ helper_test() {
host=path.tld
path=bar.git
--
+ protocol=http
+ host=path.tld
+ path=bar.git
username=askpass-username
password=askpass-password
--
@@ -150,6 +177,8 @@ helper_test() {
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=askpass-username
password=askpass-password
--
@@ -176,6 +205,8 @@ helper_test() {
host=example.com
username=user1
--
+ protocol=https
+ host=example.com
username=user1
password=pass1
EOF
@@ -184,6 +215,8 @@ helper_test() {
host=example.com
username=user2
--
+ protocol=https
+ host=example.com
username=user2
password=pass2
EOF
@@ -200,6 +233,8 @@ helper_test() {
host=example.com
username=user1
--
+ protocol=https
+ host=example.com
username=user1
password=askpass-password
--
@@ -213,6 +248,8 @@ helper_test() {
host=example.com
username=user2
--
+ protocol=https
+ host=example.com
username=user2
password=pass2
EOF
@@ -234,6 +271,8 @@ helper_test_timeout() {
protocol=https
host=timeout.tld
--
+ protocol=https
+ host=timeout.tld
username=askpass-username
password=askpass-password
--
diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index 0f76f6cdc0..ae8883a075 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -14,12 +14,14 @@ export GIT_TEXTDOMAINDIR GIT_PO_PATH
if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON
then
# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
- is_IS_locale=$(locale -a | sed -n '/^is_IS\.[uU][tT][fF]-*8$/{
+ is_IS_locale=$(locale -a 2>/dev/null |
+ sed -n '/^is_IS\.[uU][tT][fF]-*8$/{
p
q
}')
# is_IS.ISO8859-1 on Solaris and FreeBSD, is_IS.iso88591 on Debian
- is_IS_iso_locale=$(locale -a | sed -n '/^is_IS\.[iI][sS][oO]8859-*1$/{
+ is_IS_iso_locale=$(locale -a 2>/dev/null |
+ sed -n '/^is_IS\.[iI][sS][oO]8859-*1$/{
p
q
}')
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index b90986c2c9..7061dce7e5 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -2,6 +2,10 @@
# Library code for git p4 tests
#
+# p4 tests never use the top-level repo; always build/clone into
+# a subdirectory called "$git"
+TEST_NO_CREATE_REPO=NoThanks
+
. ./test-lib.sh
if ! test_have_prereq PYTHON; then
@@ -22,27 +26,54 @@ testid=${this_test#t}
git_p4_test_start=9800
P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
-export P4PORT=localhost:$P4DPORT
-export P4CLIENT=client
+P4PORT=localhost:$P4DPORT
+P4CLIENT=client
+P4EDITOR=:
+export P4PORT P4CLIENT P4EDITOR
db="$TRASH_DIRECTORY/db"
-cli="$TRASH_DIRECTORY/cli"
+cli=$(test-path-utils real_path "$TRASH_DIRECTORY/cli")
git="$TRASH_DIRECTORY/git"
pidfile="$TRASH_DIRECTORY/p4d.pid"
start_p4d() {
mkdir -p "$db" "$cli" "$git" &&
+ rm -f "$pidfile" &&
(
p4d -q -r "$db" -p $P4DPORT &
echo $! >"$pidfile"
) &&
- for i in 1 2 3 4 5 ; do
- p4 info >/dev/null 2>&1 && break || true &&
- echo waiting for p4d to start &&
+
+ # This gives p4d a long time to start up, as it can be
+ # quite slow depending on the machine. Set this environment
+ # variable to something smaller to fail faster in, say,
+ # an automated test setup. If the p4d process dies, that
+ # will be caught with the "kill -0" check below.
+ i=${P4D_START_PATIENCE:-300}
+ pid=$(cat "$pidfile")
+ ready=
+ while test $i -gt 0
+ do
+ # succeed when p4 client commands start to work
+ if p4 info >/dev/null 2>&1
+ then
+ ready=true
+ break
+ fi
+ # fail if p4d died
+ kill -0 $pid 2>/dev/null || break
+ echo waiting for p4d to start
sleep 1
- done &&
- # complain if it never started
- p4 info >/dev/null &&
+ i=$(( $i - 1 ))
+ done
+
+ if test -z "$ready"
+ then
+ # p4d failed to start
+ return 1
+ fi
+
+ # build a client
(
cd "$cli" &&
p4 client -i <<-EOF
@@ -52,6 +83,7 @@ start_p4d() {
View: //depot/... //client/...
EOF
)
+ return 0
}
kill_p4d() {
@@ -68,5 +100,36 @@ kill_p4d() {
}
cleanup_git() {
- rm -rf "$git"
+ rm -rf "$git" &&
+ mkdir "$git"
+}
+
+marshal_dump() {
+ what=$1 &&
+ line=${2:-1} &&
+ cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF &&
+ import marshal
+ import sys
+ for i in range($line):
+ d = marshal.load(sys.stdin)
+ print d['$what']
+ EOF
+ "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py"
+}
+
+#
+# Construct a client with this list of View lines
+#
+client_view() {
+ (
+ cat <<-EOF &&
+ Client: client
+ Description: client
+ Root: $cli
+ View:
+ EOF
+ for arg ; do
+ printf "\t$arg\n"
+ done
+ ) | p4 client -i
}
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 094d490893..02f442bfad 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -43,6 +43,10 @@ TEST_PATH="$TEST_DIRECTORY"/lib-httpd
HTTPD_ROOT_PATH="$PWD"/httpd
HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www
+# hack to suppress apache PassEnv warnings
+GIT_VALGRIND=$GIT_VALGRIND; export GIT_VALGRIND
+GIT_VALGRIND_OPTIONS=$GIT_VALGRIND_OPTIONS; export GIT_VALGRIND_OPTIONS
+
if ! test -x "$LIB_HTTPD_PATH"
then
skip_all="skipping test, no web server found at '$LIB_HTTPD_PATH'"
@@ -163,3 +167,42 @@ test_http_push_nonff() {
test_i18ngrep "Updates were rejected because" output
'
}
+
+setup_askpass_helper() {
+ test_expect_success 'setup askpass helper' '
+ write_script "$TRASH_DIRECTORY/askpass" <<-\EOF &&
+ echo >>"$TRASH_DIRECTORY/askpass-query" "askpass: $*" &&
+ cat "$TRASH_DIRECTORY/askpass-response"
+ EOF
+ GIT_ASKPASS="$TRASH_DIRECTORY/askpass" &&
+ export GIT_ASKPASS &&
+ export TRASH_DIRECTORY
+ '
+}
+
+set_askpass() {
+ >"$TRASH_DIRECTORY/askpass-query" &&
+ echo "$*" >"$TRASH_DIRECTORY/askpass-response"
+}
+
+expect_askpass() {
+ dest=$HTTPD_DEST
+ {
+ case "$1" in
+ none)
+ ;;
+ pass)
+ echo "askpass: Password for 'http://$2@$dest': "
+ ;;
+ both)
+ echo "askpass: Username for 'http://$dest': "
+ echo "askpass: Password for 'http://$2@$dest': "
+ ;;
+ *)
+ false
+ ;;
+ esac
+ } >"$TRASH_DIRECTORY/askpass-expect" &&
+ test_cmp "$TRASH_DIRECTORY/askpass-expect" \
+ "$TRASH_DIRECTORY/askpass-query"
+}
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index de3762e247..fe76e84b74 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -42,27 +42,28 @@ ErrorLog error.log
</IfModule>
</IfVersion>
+PassEnv GIT_VALGRIND
+PassEnv GIT_VALGRIND_OPTIONS
+
Alias /dumb/ www/
-Alias /auth/ www/auth/
+Alias /auth/dumb/ www/auth/dumb/
-<Location /smart/>
+<LocationMatch /smart/>
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
-</Location>
-<Location /smart_noexport/>
+</LocationMatch>
+<LocationMatch /smart_noexport/>
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
-</Location>
-<Location /smart_custom_env/>
+</LocationMatch>
+<LocationMatch /smart_custom_env/>
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
SetEnv GIT_COMMITTER_NAME "Custom User"
SetEnv GIT_COMMITTER_EMAIL custom@example.com
-</Location>
-ScriptAlias /smart/ ${GIT_EXEC_PATH}/git-http-backend/
-ScriptAlias /smart_noexport/ ${GIT_EXEC_PATH}/git-http-backend/
-ScriptAlias /smart_custom_env/ ${GIT_EXEC_PATH}/git-http-backend/
+</LocationMatch>
+ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
<Directory ${GIT_EXEC_PATH}>
- Options None
+ Options FollowSymlinks
</Directory>
<Files ${GIT_EXEC_PATH}/git-http-backend>
Options ExecCGI
@@ -91,6 +92,20 @@ SSLEngine On
Require valid-user
</Location>
+<LocationMatch "^/auth-push/.*/git-receive-pack$">
+ AuthType Basic
+ AuthName "git-auth"
+ AuthUserFile passwd
+ Require valid-user
+</LocationMatch>
+
+<LocationMatch "^/auth-fetch/.*/git-upload-pack$">
+ AuthType Basic
+ AuthName "git-auth"
+ AuthUserFile passwd
+ Require valid-user
+</LocationMatch>
+
<IfDefine DAV>
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
diff --git a/t/perf/.gitignore b/t/perf/.gitignore
index 50f5cc1ed9..982eb8e3a9 100644
--- a/t/perf/.gitignore
+++ b/t/perf/.gitignore
@@ -1,2 +1,3 @@
-build/
-test-results/
+/build/
+/test-results/
+/trash directory*/
diff --git a/t/perf/p5302-pack-index.sh b/t/perf/p5302-pack-index.sh
new file mode 100755
index 0000000000..6cb5b0d55b
--- /dev/null
+++ b/t/perf/p5302-pack-index.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+test_description="Tests index-pack performance"
+
+. ./perf-lib.sh
+
+test_perf_large_repo
+
+test_expect_success 'repack' '
+ git repack -ad &&
+ PACK=`ls .git/objects/pack/*.pack | head -n1` &&
+ test -f "$PACK" &&
+ export PACK
+'
+
+test_perf 'index-pack 0 threads' '
+ GIT_DIR=t1 git index-pack --threads=1 --stdin < $PACK
+'
+
+test_perf 'index-pack 1 thread ' '
+ GIT_DIR=t2 GIT_FORCE_THREADS=1 git index-pack --threads=1 --stdin < $PACK
+'
+
+test_perf 'index-pack 2 threads' '
+ GIT_DIR=t3 git index-pack --threads=2 --stdin < $PACK
+'
+
+test_perf 'index-pack 4 threads' '
+ GIT_DIR=t4 git index-pack --threads=4 --stdin < $PACK
+'
+
+test_perf 'index-pack 8 threads' '
+ GIT_DIR=t5 git index-pack --threads=8 --stdin < $PACK
+'
+
+test_perf 'index-pack default number of threads' '
+ GIT_DIR=t6 git index-pack --stdin < $PACK
+'
+
+test_done
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index 5580c22812..a816fbcb76 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -42,6 +42,7 @@ else
fi
TEST_NO_CREATE_REPO=t
+TEST_NO_MALLOC_CHECK=t
. ../test-lib.sh
@@ -163,7 +164,7 @@ test_perf () {
else
echo "perf $test_count - $1:"
fi
- for i in $(seq 1 $GIT_PERF_REPEAT_COUNT); do
+ for i in $(test_seq 1 $GIT_PERF_REPEAT_COUNT); do
say >&3 "running: $2"
if test_run_perf_ "$2"
then
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index ccb5435b2a..cefe33d6d1 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -18,16 +18,6 @@ swapping compression and hashing order, the person who is making the
modification *should* take notice and update the test vectors here.
'
-################################################################
-# It appears that people try to run tests without building...
-
-../git >/dev/null
-if test $? != 1
-then
- echo >&2 'You do not seem to have built git yet.'
- exit 1
-fi
-
. ./test-lib.sh
################################################################
@@ -55,39 +45,176 @@ test_expect_failure 'pretend we have a known breakage' '
false
'
-test_expect_success 'pretend we have fixed a known breakage (run in sub test-lib)' "
- mkdir passing-todo &&
- (cd passing-todo &&
- cat >passing-todo.sh <<-EOF &&
- #!$SHELL_PATH
-
- test_description='A passing TODO test
+run_sub_test_lib_test () {
+ name="$1" descr="$2" # stdin is the body of the test code
+ mkdir "$name" &&
+ (
+ cd "$name" &&
+ cat >"$name.sh" <<-EOF &&
+ #!$SHELL_PATH
+
+ test_description='$descr (run in sub test-lib)
+
+ 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-lib.sh
+ EOF
+ cat >>"$name.sh" &&
+ chmod +x "$name.sh" &&
+ export TEST_DIRECTORY &&
+ ./"$name.sh" >out 2>err
+ )
+}
- This is run in a sub test-lib so that we do not get incorrect
- passing metrics
- '
+check_sub_test_lib_test () {
+ name="$1" # stdin is the expected output from the test
+ (
+ cd "$name" &&
+ ! test -s err &&
+ sed -e 's/^> //' -e 's/Z$//' >expect &&
+ test_cmp expect out
+ )
+}
+
+test_expect_success 'pretend we have a fully passing test suite' "
+ run_sub_test_lib_test full-pass '3 passing tests' <<-\\EOF &&
+ for i in 1 2 3
+ do
+ test_expect_success \"passing test #\$i\" 'true'
+ done
+ test_done
+ EOF
+ check_sub_test_lib_test full-pass <<-\\EOF
+ > ok 1 - passing test #1
+ > ok 2 - passing test #2
+ > ok 3 - passing test #3
+ > # passed all 3 test(s)
+ > 1..3
+ EOF
+"
- # 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 'pretend we have a partially passing test suite' "
+ test_must_fail run_sub_test_lib_test \
+ partial-pass '2/3 tests passing' <<-\\EOF &&
+ test_expect_success 'passing test #1' 'true'
+ test_expect_success 'failing test #2' 'false'
+ test_expect_success 'passing test #3' 'true'
+ test_done
+ EOF
+ check_sub_test_lib_test partial-pass <<-\\EOF
+ > ok 1 - passing test #1
+ > not ok 2 - failing test #2
+ # false
+ > ok 3 - passing test #3
+ > # failed 1 among 3 test(s)
+ > 1..3
+ EOF
+"
- test_expect_failure 'pretend we have fixed a known breakage' '
- :
- '
+test_expect_success 'pretend we have a known breakage' "
+ run_sub_test_lib_test failing-todo 'A failing TODO test' <<-\\EOF &&
+ test_expect_success 'passing test' 'true'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_done
+ EOF
+ check_sub_test_lib_test failing-todo <<-\\EOF
+ > ok 1 - passing test
+ > not ok 2 - pretend we have a known breakage # TODO known breakage
+ > # still have 1 known breakage(s)
+ > # passed all remaining 1 test(s)
+ > 1..2
+ EOF
+"
+test_expect_success 'pretend we have fixed a known breakage' "
+ run_sub_test_lib_test passing-todo 'A passing TODO test' <<-\\EOF &&
+ test_expect_failure 'pretend we have fixed a known breakage' 'true'
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)
+ check_sub_test_lib_test passing-todo <<-\\EOF
+ > ok 1 - pretend we have fixed a known breakage # TODO known breakage vanished
+ > # 1 known breakage(s) vanished; please update test(s)
> 1..1
EOF
- test_cmp expect out)
"
+
+test_expect_success 'pretend we have fixed one of two known breakages (run in sub test-lib)' "
+ run_sub_test_lib_test partially-passing-todos \
+ '2 TODO tests, one passing' <<-\\EOF &&
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_expect_success 'pretend we have a passing test' 'true'
+ test_expect_failure 'pretend we have fixed another known breakage' 'true'
+ test_done
+ EOF
+ check_sub_test_lib_test partially-passing-todos <<-\\EOF
+ > not ok 1 - pretend we have a known breakage # TODO known breakage
+ > ok 2 - pretend we have a passing test
+ > ok 3 - pretend we have fixed another known breakage # TODO known breakage vanished
+ > # 1 known breakage(s) vanished; please update test(s)
+ > # still have 1 known breakage(s)
+ > # passed all remaining 1 test(s)
+ > 1..3
+ EOF
+"
+
+test_expect_success 'pretend we have a pass, fail, and known breakage' "
+ test_must_fail run_sub_test_lib_test \
+ mixed-results1 'mixed results #1' <<-\\EOF &&
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'failing test' 'false'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_done
+ EOF
+ check_sub_test_lib_test mixed-results1 <<-\\EOF
+ > ok 1 - passing test
+ > not ok 2 - failing test
+ > # false
+ > not ok 3 - pretend we have a known breakage # TODO known breakage
+ > # still have 1 known breakage(s)
+ > # failed 1 among remaining 2 test(s)
+ > 1..3
+ EOF
+"
+
+test_expect_success 'pretend we have a mix of all possible results' "
+ test_must_fail run_sub_test_lib_test \
+ mixed-results2 'mixed results #2' <<-\\EOF &&
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'failing test' 'false'
+ test_expect_success 'failing test' 'false'
+ test_expect_success 'failing test' 'false'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_expect_failure 'pretend we have fixed a known breakage' 'true'
+ test_done
+ EOF
+ check_sub_test_lib_test mixed-results2 <<-\\EOF
+ > ok 1 - passing test
+ > ok 2 - passing test
+ > ok 3 - passing test
+ > ok 4 - passing test
+ > not ok 5 - failing test
+ > # false
+ > not ok 6 - failing test
+ > # false
+ > not ok 7 - failing test
+ > # false
+ > not ok 8 - pretend we have a known breakage # TODO known breakage
+ > not ok 9 - pretend we have a known breakage # TODO known breakage
+ > ok 10 - pretend we have fixed a known breakage # TODO known breakage vanished
+ > # 1 known breakage(s) vanished; please update test(s)
+ > # still have 2 known breakage(s)
+ > # failed 3 among remaining 7 test(s)
+ > 1..10
+ EOF
+"
+
test_set_prereq HAVEIT
haveit=no
test_expect_success HAVEIT 'test runs if prerequisite is satisfied' '
@@ -125,6 +252,38 @@ then
exit 1
fi
+test_lazy_prereq LAZY_TRUE true
+havetrue=no
+test_expect_success LAZY_TRUE 'test runs if lazy prereq is satisfied' '
+ havetrue=yes
+'
+donthavetrue=yes
+test_expect_success !LAZY_TRUE 'missing lazy prereqs skip tests' '
+ donthavetrue=no
+'
+
+if test "$havetrue$donthavetrue" != yesyes
+then
+ say 'bug in test framework: lazy prerequisites do not work'
+ exit 1
+fi
+
+test_lazy_prereq LAZY_FALSE false
+nothavefalse=no
+test_expect_success !LAZY_FALSE 'negative lazy prereqs checked' '
+ nothavefalse=yes
+'
+havefalse=yes
+test_expect_success LAZY_FALSE 'missing negative lazy prereqs will skip' '
+ havefalse=no
+'
+
+if test "$nothavefalse$havefalse" != yesyes
+then
+ say 'bug in test framework: negative lazy prerequisites do not work'
+ exit 1
+fi
+
clean=no
test_expect_success 'tests clean up after themselves' '
test_when_finished clean=yes
@@ -137,19 +296,8 @@ 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_must_fail run_sub_test_lib_test \
+ failing-cleanup 'Failing tests with cleanup commands' <<-\\EOF &&
test_expect_success 'tests clean up even after a failure' '
touch clean-after-failure &&
test_when_finished rm clean-after-failure &&
@@ -159,29 +307,21 @@ test_expect_success 'tests clean up even on failures' "
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
+ check_sub_test_lib_test failing-cleanup <<-\\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
+ > 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
- )
"
################################################################
@@ -450,24 +590,6 @@ test_expect_success 'update-index D/F conflict' '
test $numpath0 = 1
'
-test_expect_success SYMLINKS 'real path works as expected' '
- mkdir first &&
- ln -s ../.git first/.git &&
- mkdir second &&
- ln -s ../first second/other &&
- mkdir third &&
- dir="$(cd .git; pwd -P)" &&
- dir2=third/../second/other/.git &&
- test "$dir" = "$(test-path-utils real_path $dir2)" &&
- file="$dir"/index &&
- test "$file" = "$(test-path-utils real_path $dir2/index)" &&
- basename=blub &&
- test "$dir/$basename" = "$(cd .git && test-path-utils real_path "$basename")" &&
- ln -s ../first/file .git/syml &&
- sym="$(cd first; pwd -P)"/file &&
- test "$sym" = "$(test-path-utils real_path "$dir2/syml")"
-'
-
test_expect_success 'very long name in the index handled sanely' '
a=a && # 1
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 51f3045ba4..43b25137e9 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -123,16 +123,6 @@ test_expect_success 'attribute matching is case insensitive when core.ignorecase
'
-test_expect_success 'check whether FS is case-insensitive' '
- mkdir junk &&
- echo good >junk/CamelCase &&
- echo bad >junk/camelcase &&
- if test "$(cat junk/CamelCase)" != good
- then
- test_set_prereq CASE_INSENSITIVE_FS
- fi
-'
-
test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
@@ -206,6 +196,53 @@ test_expect_success 'root subdir attribute test' '
attr_check subdir/a/i unspecified
'
+test_expect_success 'negative patterns' '
+ echo "!f test=bar" >.gitattributes &&
+ test_must_fail git check-attr test -- f
+'
+
+test_expect_success 'patterns starting with exclamation' '
+ echo "\!f test=foo" >.gitattributes &&
+ attr_check "!f" foo
+'
+
+test_expect_success '"**" test' '
+ echo "**/f foo=bar" >.gitattributes &&
+ cat <<\EOF >expect &&
+f: foo: bar
+a/f: foo: bar
+a/b/f: foo: bar
+a/b/c/f: foo: bar
+EOF
+ git check-attr foo -- "f" >actual 2>err &&
+ git check-attr foo -- "a/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
+ test_cmp expect actual &&
+ test_line_count = 0 err
+'
+
+test_expect_success '"**" with no slashes test' '
+ echo "a**f foo=bar" >.gitattributes &&
+ git check-attr foo -- "f" >actual &&
+ cat <<\EOF >expect &&
+f: foo: unspecified
+af: foo: bar
+axf: foo: bar
+a/f: foo: unspecified
+a/b/f: foo: unspecified
+a/b/c/f: foo: unspecified
+EOF
+ git check-attr foo -- "f" >actual 2>err &&
+ git check-attr foo -- "af" >>actual 2>err &&
+ git check-attr foo -- "axf" >>actual 2>err &&
+ git check-attr foo -- "a/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
+ test_cmp expect actual &&
+ test_line_count = 0 err
+'
+
test_expect_success 'setup bare' '
git clone --bare . bare.git &&
cd bare.git
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 1d29810a7a..e53cf6d36d 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -11,7 +11,7 @@ check_show() {
echo "$t -> $2" >expect
test_expect_${3:-success} "relative date ($2)" "
test-date show $t >actual &&
- test_cmp expect actual
+ test_i18ncmp expect actual
"
}
diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh
new file mode 100755
index 0000000000..5868a87352
--- /dev/null
+++ b/t/t0007-git-var.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='basic sanity checks for git var'
+. ./test-lib.sh
+
+test_expect_success 'get GIT_AUTHOR_IDENT' '
+ test_tick &&
+ echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" >expect &&
+ git var GIT_AUTHOR_IDENT >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'get GIT_COMMITTER_IDENT' '
+ test_tick &&
+ echo "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" >expect &&
+ git var GIT_COMMITTER_IDENT >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success !AUTOIDENT 'requested identites are strict' '
+ (
+ sane_unset GIT_COMMITTER_NAME &&
+ sane_unset GIT_COMMITTER_EMAIL &&
+ test_must_fail git var GIT_COMMITTER_IDENT
+ )
+'
+
+# For git var -l, we check only a representative variable;
+# testing the whole output would make our test too brittle with
+# respect to unrelated changes in the test suite's environment.
+test_expect_success 'git var -l lists variables' '
+ git var -l >actual &&
+ echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" >expect &&
+ sed -n s/GIT_AUTHOR_IDENT=//p <actual >actual.author &&
+ test_cmp expect actual.author
+'
+
+test_expect_success 'git var -l lists config' '
+ git var -l >actual &&
+ echo false >expect &&
+ sed -n s/core\\.bare=//p <actual >actual.bare &&
+ test_cmp expect actual.bare
+'
+
+test_expect_success 'listing and asking for variables are exclusive' '
+ test_must_fail git var -l GIT_COMMITTER_IDENT
+'
+
+test_done
diff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh
index aaed725402..f9bbb91f64 100755
--- a/t/t0023-crlf-am.sh
+++ b/t/t0023-crlf-am.sh
@@ -11,7 +11,7 @@ Date: Thu, 23 Aug 2007 13:00:00 +0200
Subject: test1
---
- foo | 1 +
+ foo | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh
index ec6c1b3f8a..5378787e1b 100755
--- a/t/t0024-crlf-archive.sh
+++ b/t/t0024-crlf-archive.sh
@@ -3,7 +3,12 @@
test_description='respect crlf in git archive'
. ./test-lib.sh
-UNZIP=${UNZIP:-unzip}
+GIT_UNZIP=${GIT_UNZIP:-unzip}
+
+test_lazy_prereq UNZIP '
+ "$GIT_UNZIP" -v
+ test $? -ne 127
+'
test_expect_success setup '
@@ -26,18 +31,11 @@ test_expect_success 'tar archive' '
'
-"$UNZIP" -v >/dev/null 2>&1
-if [ $? -eq 127 ]; then
- say "Skipping ZIP test, because unzip was not found"
-else
- test_set_prereq UNZIP
-fi
-
test_expect_success UNZIP 'zip archive' '
git archive --format=zip HEAD >test.zip &&
- ( mkdir unzipped && cd unzipped && unzip ../test.zip ) &&
+ ( mkdir unzipped && cd unzipped && "$GIT_UNZIP" ../test.zip ) &&
test_cmp sample unzipped/sample
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index e3f354a45e..244a43c920 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -51,7 +51,7 @@ EOF
test_expect_success 'test help' '
test_must_fail test-parse-options -h > output 2> output.err &&
test ! -s output.err &&
- test_cmp expect output
+ test_i18ncmp expect output
'
mv expect expect.err
@@ -79,6 +79,17 @@ check() {
test_cmp expect output
}
+check_i18n() {
+ 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_i18ncmp expect output
+}
+
check_unknown() {
case "$1" in
--*)
@@ -92,6 +103,19 @@ check_unknown() {
test_cmp expect output.err
}
+check_unknown_i18n() {
+ 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_i18ncmp 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'
@@ -104,8 +128,8 @@ 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() no negation #1' 'check_unknown_i18n --fear'
+test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear'
test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
@@ -310,8 +334,8 @@ EOF
test_expect_success 'OPT_CALLBACK() and callback errors work' '
test_must_fail test-parse-options --no-length > output 2> output.err &&
- test_cmp expect output &&
- test_cmp expect.err output.err
+ test_i18ncmp expect output &&
+ test_i18ncmp expect.err output.err
'
cat > expect <<EOF
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 1542cf6a13..78816d9d93 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -7,48 +7,26 @@ test_description='Various filesystem issues'
auml=$(printf '\303\244')
aumlcdiar=$(printf '\141\314\210')
-case_insensitive=
-unibad=
-no_symlinks=
-test_expect_success 'see what we expect' '
-
- test_case=test_expect_success &&
- test_unicode=test_expect_success &&
- mkdir junk &&
- echo good >junk/CamelCase &&
- echo bad >junk/camelcase &&
- if test "$(cat junk/CamelCase)" != good
- then
- test_case=test_expect_failure &&
- case_insensitive=t
- fi &&
- rm -fr junk &&
- mkdir junk &&
- >junk/"$auml" &&
- case "$(cd junk && echo *)" in
- "$aumlcdiar")
- test_unicode=test_expect_failure &&
- unibad=t
- ;;
- *) ;;
- esac &&
- rm -fr junk &&
- {
- ln -s x y 2> /dev/null &&
- test -h y 2> /dev/null ||
- no_symlinks=1 &&
- rm -f y
- }
-'
-
-test "$case_insensitive" &&
+if test_have_prereq CASE_INSENSITIVE_FS
+then
say "will test on a case insensitive filesystem"
-test "$unibad" &&
+ test_case=test_expect_failure
+else
+ test_case=test_expect_success
+fi
+
+if test_have_prereq UTF8_NFD_TO_NFC
+then
say "will test on a unicode corrupting filesystem"
-test "$no_symlinks" &&
+ test_unicode=test_expect_failure
+else
+ test_unicode=test_expect_success
+fi
+
+test_have_prereq SYMLINKS ||
say "will test on a filesystem lacking symbolic links"
-if test "$case_insensitive"
+if test_have_prereq CASE_INSENSITIVE_FS
then
test_expect_success "detection of case insensitive filesystem during repo init" '
@@ -62,18 +40,18 @@ test_expect_success "detection of case insensitive filesystem during repo init"
'
fi
-if test "$no_symlinks"
+if test_have_prereq SYMLINKS
then
test_expect_success "detection of filesystem w/o symlink support during repo init" '
- v=$(git config --bool core.symlinks) &&
- test "$v" = false
+ test_must_fail git config --bool core.symlinks ||
+ test "$(git config --bool core.symlinks)" = true
'
else
test_expect_success "detection of filesystem w/o symlink support during repo init" '
- test_must_fail git config --bool core.symlinks ||
- test "$(git config --bool core.symlinks)" = true
+ v=$(git config --bool core.symlinks) &&
+ test "$v" = false
'
fi
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 53cf1f8dc4..09a42a428e 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -93,50 +93,94 @@ norm_path /d1/s1//../s2/../../d2 /d2 POSIX
norm_path /d1/.../d2 /d1/.../d2 POSIX
norm_path /d1/..././../d2 /d1/d2 POSIX
-ancestor / "" -1
ancestor / / -1
-ancestor /foo "" -1
-ancestor /foo : -1
-ancestor /foo ::. -1
-ancestor /foo ::..:: -1
ancestor /foo / 0
ancestor /foo /fo -1
ancestor /foo /foo -1
-ancestor /foo /foo/ -1
ancestor /foo /bar -1
-ancestor /foo /bar/ -1
ancestor /foo /foo/bar -1
-ancestor /foo /foo:/bar/ -1
-ancestor /foo /foo/:/bar/ -1
-ancestor /foo /foo::/bar/ -1
-ancestor /foo /:/foo:/bar/ 0
-ancestor /foo /foo:/:/bar/ 0
-ancestor /foo /:/bar/:/foo 0
-ancestor /foo/bar "" -1
+ancestor /foo /foo:/bar -1
+ancestor /foo /:/foo:/bar 0
+ancestor /foo /foo:/:/bar 0
+ancestor /foo /:/bar:/foo 0
ancestor /foo/bar / 0
ancestor /foo/bar /fo -1
-ancestor /foo/bar foo -1
ancestor /foo/bar /foo 4
-ancestor /foo/bar /foo/ 4
ancestor /foo/bar /foo/ba -1
ancestor /foo/bar /:/fo 0
ancestor /foo/bar /foo:/foo/ba 4
ancestor /foo/bar /bar -1
-ancestor /foo/bar /bar/ -1
-ancestor /foo/bar /fo: -1
-ancestor /foo/bar :/fo -1
-ancestor /foo/bar /foo:/bar/ 4
-ancestor /foo/bar /:/foo:/bar/ 4
-ancestor /foo/bar /foo:/:/bar/ 4
-ancestor /foo/bar /:/bar/:/fo 0
-ancestor /foo/bar /:/bar/ 0
-ancestor /foo/bar .:/foo/. 4
-ancestor /foo/bar .:/foo/.:.: 4
-ancestor /foo/bar /foo/./:.:/bar 4
-ancestor /foo/bar .:/bar -1
+ancestor /foo/bar /fo -1
+ancestor /foo/bar /foo:/bar 4
+ancestor /foo/bar /:/foo:/bar 4
+ancestor /foo/bar /foo:/:/bar 4
+ancestor /foo/bar /:/bar:/fo 0
+ancestor /foo/bar /:/bar 0
+ancestor /foo/bar /foo 4
+ancestor /foo/bar /foo:/bar 4
+ancestor /foo/bar /bar -1
test_expect_success 'strip_path_suffix' '
test c:/msysgit = $(test-path-utils strip_path_suffix \
c:/msysgit/libexec//git-core libexec/git-core)
'
+
+test_expect_success 'absolute path rejects the empty string' '
+ test_must_fail test-path-utils absolute_path ""
+'
+
+test_expect_success 'real path rejects the empty string' '
+ test_must_fail test-path-utils real_path ""
+'
+
+test_expect_success POSIX 'real path works on absolute paths 1' '
+ nopath="hopefully-absent-path" &&
+ test "/" = "$(test-path-utils real_path "/")" &&
+ test "/$nopath" = "$(test-path-utils real_path "/$nopath")"
+'
+
+test_expect_success 'real path works on absolute paths 2' '
+ nopath="hopefully-absent-path" &&
+ # Find an existing top-level directory for the remaining tests:
+ d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
+ test "$d" = "$(test-path-utils real_path "$d")" &&
+ test "$d/$nopath" = "$(test-path-utils real_path "$d/$nopath")"
+'
+
+test_expect_success POSIX 'real path removes extra leading slashes' '
+ nopath="hopefully-absent-path" &&
+ test "/" = "$(test-path-utils real_path "///")" &&
+ test "/$nopath" = "$(test-path-utils real_path "///$nopath")" &&
+ # Find an existing top-level directory for the remaining tests:
+ d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
+ test "$d" = "$(test-path-utils real_path "//$d")" &&
+ test "$d/$nopath" = "$(test-path-utils real_path "//$d/$nopath")"
+'
+
+test_expect_success 'real path removes other extra slashes' '
+ nopath="hopefully-absent-path" &&
+ # Find an existing top-level directory for the remaining tests:
+ d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
+ test "$d" = "$(test-path-utils real_path "$d///")" &&
+ test "$d/$nopath" = "$(test-path-utils real_path "$d///$nopath")"
+'
+
+test_expect_success SYMLINKS 'real path works on symlinks' '
+ mkdir first &&
+ ln -s ../.git first/.git &&
+ mkdir second &&
+ ln -s ../first second/other &&
+ mkdir third &&
+ dir="$(cd .git; pwd -P)" &&
+ dir2=third/../second/other/.git &&
+ test "$dir" = "$(test-path-utils real_path $dir2)" &&
+ file="$dir"/index &&
+ test "$file" = "$(test-path-utils real_path $dir2/index)" &&
+ basename=blub &&
+ test "$dir/$basename" = "$(cd .git && test-path-utils real_path "$basename")" &&
+ ln -s ../first/file .git/syml &&
+ sym="$(cd first; pwd -P)"/file &&
+ test "$sym" = "$(test-path-utils real_path "$dir2/syml")"
+'
+
test_done
diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh
new file mode 100755
index 0000000000..dbfc05ebdc
--- /dev/null
+++ b/t/t0063-string-list.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Michael Haggerty
+#
+
+test_description='Test string list functionality'
+
+. ./test-lib.sh
+
+test_split () {
+ cat >expected &&
+ test_expect_success "split $1 at $2, max $3" "
+ test-string-list split '$1' '$2' '$3' >actual &&
+ test_cmp expected actual &&
+ test-string-list split_in_place '$1' '$2' '$3' >actual &&
+ test_cmp expected actual
+ "
+}
+
+test_split "foo:bar:baz" ":" "-1" <<EOF
+3
+[0]: "foo"
+[1]: "bar"
+[2]: "baz"
+EOF
+
+test_split "foo:bar:baz" ":" "0" <<EOF
+1
+[0]: "foo:bar:baz"
+EOF
+
+test_split "foo:bar:baz" ":" "1" <<EOF
+2
+[0]: "foo"
+[1]: "bar:baz"
+EOF
+
+test_split "foo:bar:baz" ":" "2" <<EOF
+3
+[0]: "foo"
+[1]: "bar"
+[2]: "baz"
+EOF
+
+test_split "foo:bar:" ":" "-1" <<EOF
+3
+[0]: "foo"
+[1]: "bar"
+[2]: ""
+EOF
+
+test_split "" ":" "-1" <<EOF
+1
+[0]: ""
+EOF
+
+test_split ":" ":" "-1" <<EOF
+2
+[0]: ""
+[1]: ""
+EOF
+
+test_expect_success "test filter_string_list" '
+ test "x-" = "x$(test-string-list filter - y)" &&
+ test "x-" = "x$(test-string-list filter no y)" &&
+ test yes = "$(test-string-list filter yes y)" &&
+ test yes = "$(test-string-list filter no:yes y)" &&
+ test yes = "$(test-string-list filter yes:no y)" &&
+ test y1:y2 = "$(test-string-list filter y1:y2 y)" &&
+ test y2:y1 = "$(test-string-list filter y2:y1 y)" &&
+ test "x-" = "x$(test-string-list filter x1:x2 y)"
+'
+
+test_expect_success "test remove_duplicates" '
+ test "x-" = "x$(test-string-list remove_duplicates -)" &&
+ test "x" = "x$(test-string-list remove_duplicates "")" &&
+ test a = "$(test-string-list remove_duplicates a)" &&
+ test a = "$(test-string-list remove_duplicates a:a)" &&
+ test a = "$(test-string-list remove_duplicates a:a:a:a:a)" &&
+ test a:b = "$(test-string-list remove_duplicates a:b)" &&
+ test a:b = "$(test-string-list remove_duplicates a:a:b)" &&
+ test a:b = "$(test-string-list remove_duplicates a:b:b)" &&
+ test a:b:c = "$(test-string-list remove_duplicates a:b:c)" &&
+ test a:b:c = "$(test-string-list remove_duplicates a:a:b:c)" &&
+ test a:b:c = "$(test-string-list remove_duplicates a:b:b:c)" &&
+ test a:b:c = "$(test-string-list remove_duplicates a:b:c:c)" &&
+ test a:b:c = "$(test-string-list remove_duplicates a:a:b:b:c:c)" &&
+ test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
+'
+
+test_done
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
index 9bee8bfd2e..da2c504e53 100755
--- a/t/t0070-fundamental.sh
+++ b/t/t0070-fundamental.sh
@@ -25,4 +25,9 @@ test_expect_success POSIXPERM 'mktemp to unwritable directory prints filename' '
grep "cannotwrite/test" err
'
+test_expect_success 'check for a bug in the regex routines' '
+ # if this test fails, re-build git with NO_REGEX=1
+ test-regex
+'
+
test_done
diff --git a/t/t0201-gettext-fallbacks.sh b/t/t0201-gettext-fallbacks.sh
index 52b1c27c2c..5d80a985fb 100755
--- a/t/t0201-gettext-fallbacks.sh
+++ b/t/t0201-gettext-fallbacks.sh
@@ -51,16 +51,16 @@ test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate v
test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces' '
cmdline="git am" &&
export cmdline;
- printf "When you have resolved this problem run git am --resolved." >expect &&
- eval_gettext "When you have resolved this problem run \$cmdline --resolved." >actual
+ printf "When you have resolved this problem, run git am --resolved." >expect &&
+ eval_gettext "When you have resolved this problem, run \$cmdline --resolved." >actual
test_i18ncmp expect actual
'
test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces and quotes' '
cmdline="git am" &&
export cmdline;
- printf "When you have resolved this problem run \"git am --resolved\"." >expect &&
- eval_gettext "When you have resolved this problem run \"\$cmdline --resolved\"." >actual
+ printf "When you have resolved this problem, run \"git am --resolved\"." >expect &&
+ eval_gettext "When you have resolved this problem, run \"\$cmdline --resolved\"." >actual
test_i18ncmp expect actual
'
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
index 20e28e34e7..538ea5fb1c 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -82,6 +82,9 @@ test_expect_success 'credential_fill passes along metadata' '
host=example.com
path=foo.git
--
+ protocol=ftp
+ host=example.com
+ path=foo.git
username=one
password=two
--
@@ -213,6 +216,8 @@ test_expect_success 'match configured credential' '
host=example.com
path=repo.git
--
+ protocol=https
+ host=example.com
username=foo
password=bar
--
@@ -225,6 +230,8 @@ test_expect_success 'do not match configured credential' '
protocol=https
host=bar
--
+ protocol=https
+ host=bar
username=askpass-username
password=askpass-password
--
@@ -239,6 +246,8 @@ test_expect_success 'pull username from config' '
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=foo
password=askpass-password
--
@@ -252,6 +261,8 @@ test_expect_success 'http paths can be part of context' '
host=example.com
path=foo.git
--
+ protocol=https
+ host=example.com
username=foo
password=bar
--
@@ -265,6 +276,9 @@ test_expect_success 'http paths can be part of context' '
host=example.com
path=foo.git
--
+ protocol=https
+ host=example.com
+ path=foo.git
username=foo
password=bar
--
diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh
index b946f87686..df573c4978 100755
--- a/t/t1010-mktree.sh
+++ b/t/t1010-mktree.sh
@@ -42,13 +42,13 @@ test_expect_success 'ls-tree piped to mktree (2)' '
'
test_expect_success 'ls-tree output in wrong order given to mktree (1)' '
- perl -e "print reverse <>" <top |
+ "$PERL_PATH" -e "print reverse <>" <top |
git mktree >actual &&
test_cmp tree actual
'
test_expect_success 'ls-tree output in wrong order given to mktree (2)' '
- perl -e "print reverse <>" <top.withsub |
+ "$PERL_PATH" -e "print reverse <>" <top.withsub |
git mktree >actual &&
test_cmp tree.withsub actual
'
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index e23ac0e69d..1e2945ec7e 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -111,19 +111,19 @@ test_expect_success 'read-tree' '
test_expect_success 'alias expansion' '
(
- git config alias.ss status &&
+ git config alias.test-status-alias status &&
cd dir &&
git status &&
- git ss
+ git test-status-alias
)
'
test_expect_success NOT_MINGW '!alias expansion' '
pwd >expect &&
(
- git config alias.test !pwd &&
+ git config alias.test-alias-directory !pwd &&
cd dir &&
- git test >../actual
+ git test-alias-directory >../actual
) &&
test_cmp expect actual
'
@@ -131,9 +131,9 @@ test_expect_success NOT_MINGW '!alias expansion' '
test_expect_success 'GIT_PREFIX for !alias' '
printf "dir/" >expect &&
(
- git config alias.test "!sh -c \"printf \$GIT_PREFIX\"" &&
+ git config alias.test-alias-directory "!sh -c \"printf \$GIT_PREFIX\"" &&
cd dir &&
- git test >../actual
+ git test-alias-directory >../actual
) &&
test_cmp expect actual
'
diff --git a/t/t1050-large.sh b/t/t1050-large.sh
index 4d127f19b7..fd10528009 100755
--- a/t/t1050-large.sh
+++ b/t/t1050-large.sh
@@ -130,8 +130,37 @@ test_expect_success 'git-show a large file' '
'
+test_expect_success 'index-pack' '
+ git clone file://"`pwd`"/.git foo &&
+ GIT_DIR=non-existent git index-pack --strict --verify foo/.git/objects/pack/*.pack
+'
+
test_expect_success 'repack' '
git repack -ad
'
+test_expect_success 'pack-objects with large loose object' '
+ SHA1=`git hash-object huge` &&
+ test_create_repo loose &&
+ echo $SHA1 | git pack-objects --stdout |
+ GIT_ALLOC_LIMIT=0 GIT_DIR=loose/.git git unpack-objects &&
+ echo $SHA1 | GIT_DIR=loose/.git git pack-objects pack &&
+ test_create_repo packed &&
+ mv pack-* packed/.git/objects/pack &&
+ GIT_DIR=packed/.git git cat-file blob $SHA1 >actual &&
+ cmp huge actual
+'
+
+test_expect_success 'tar achiving' '
+ git archive --format=tar HEAD >/dev/null
+'
+
+test_expect_success 'zip achiving, store only' '
+ git archive --format=zip -0 HEAD >/dev/null
+'
+
+test_expect_success 'zip achiving, deflate' '
+ git archive --format=zip HEAD >/dev/null
+'
+
test_done
diff --git a/t/t1100-commit-tree-options.sh b/t/t1100-commit-tree-options.sh
index c4414ff576..f8457f9d14 100755
--- a/t/t1100-commit-tree-options.sh
+++ b/t/t1100-commit-tree-options.sh
@@ -7,6 +7,9 @@ test_description='git commit-tree options test
This test checks that git commit-tree can create a specific commit
object by defining all environment variables that it understands.
+
+Also make sure that command line parser understands the normal
+"flags first and then non flag arguments" command line.
'
. ./test-lib.sh
@@ -42,4 +45,19 @@ test_expect_success \
'compare commit' \
'test_cmp expected commit'
+
+test_expect_success 'flags and then non flags' '
+ test_tick &&
+ echo comment text |
+ git commit-tree $(cat treeid) >commitid &&
+ echo comment text |
+ git commit-tree $(cat treeid) -p $(cat commitid) >childid-1 &&
+ echo comment text |
+ git commit-tree -p $(cat commitid) $(cat treeid) >childid-2 &&
+ test_cmp childid-1 childid-2 &&
+ git commit-tree $(cat treeid) -m foo >childid-3 &&
+ git commit-tree -m foo $(cat treeid) >childid-4 &&
+ test_cmp childid-3 childid-4
+'
+
test_done
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index 9356beaf4b..397ccb6909 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -154,8 +154,8 @@ test_expect_success 'git show-branch' '
cat > resolve.expect << EOF
Updating VARIABLE..VARIABLE
FASTFORWARD (no commit created; -m option ignored)
- example | 1 +
- hello | 1 +
+ example | 1 +
+ hello | 1 +
2 files changed, 2 insertions(+)
EOF
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index a477453e2e..3c96fda548 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -55,11 +55,13 @@ test_expect_success 'uppercase section' '
test_cmp expect .git/config
'
-test_expect_success 'replace with non-match' \
- 'git config core.penguin kingpin !blue'
+test_expect_success 'replace with non-match' '
+ git config core.penguin kingpin !blue
+'
-test_expect_success 'replace with non-match (actually matching)' \
- 'git config core.penguin "very blue" !kingpin'
+test_expect_success 'replace with non-match (actually matching)' '
+ git config core.penguin "very blue" !kingpin
+'
cat > expect << EOF
[core]
@@ -108,8 +110,9 @@ baz = multiple \
lines
EOF
-test_expect_success 'unset with cont. lines' \
- 'git config --unset beta.baz'
+test_expect_success 'unset with cont. lines' '
+ git config --unset beta.baz
+'
cat > expect <<\EOF
[alpha]
@@ -133,8 +136,9 @@ EOF
cp .git/config .git/config2
-test_expect_success 'multiple unset' \
- 'git config --unset-all beta.haha'
+test_expect_success 'multiple unset' '
+ git config --unset-all beta.haha
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -145,7 +149,9 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch
EOF
-test_expect_success 'multiple unset is correct' 'test_cmp expect .git/config'
+test_expect_success 'multiple unset is correct' '
+ test_cmp expect .git/config
+'
cp .git/config2 .git/config
@@ -156,8 +162,9 @@ test_expect_success '--replace-all missing value' '
rm .git/config2
-test_expect_success '--replace-all' \
- 'git config --replace-all beta.haha gamma'
+test_expect_success '--replace-all' '
+ git config --replace-all beta.haha gamma
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -169,7 +176,9 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch
EOF
-test_expect_success 'all replaced' 'test_cmp expect .git/config'
+test_expect_success 'all replaced' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -200,7 +209,11 @@ test_expect_success 'really really mean test' '
test_cmp expect .git/config
'
-test_expect_success 'get value' 'test alpha = $(git config beta.haha)'
+test_expect_success 'get value' '
+ echo alpha >expect &&
+ git config beta.haha >actual &&
+ test_cmp expect actual
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -231,18 +244,30 @@ test_expect_success 'multivar' '
test_cmp expect .git/config
'
-test_expect_success 'non-match' \
- 'git config --get nextsection.nonewline !for'
+test_expect_success 'non-match' '
+ git config --get nextsection.nonewline !for
+'
-test_expect_success 'non-match value' \
- 'test wow = $(git config --get nextsection.nonewline !for)'
+test_expect_success 'non-match value' '
+ echo wow >expect &&
+ git config --get nextsection.nonewline !for >actual &&
+ test_cmp expect actual
+'
-test_expect_success 'ambiguous get' '
- test_must_fail git config --get nextsection.nonewline
+test_expect_success 'multi-valued get returns final one' '
+ echo "wow2 for me" >expect &&
+ git config --get nextsection.nonewline >actual &&
+ test_cmp expect actual
'
-test_expect_success 'get multivar' \
- 'git config --get-all nextsection.nonewline'
+test_expect_success 'multi-valued get-all returns all' '
+ cat >expect <<-\EOF &&
+ wow
+ wow2 for me
+ EOF
+ git config --get-all nextsection.nonewline >actual &&
+ test_cmp expect actual
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -259,10 +284,6 @@ test_expect_success 'multivar replace' '
test_cmp expect .git/config
'
-test_expect_success 'ambiguous value' '
- test_must_fail git config nextsection.nonewline
-'
-
test_expect_success 'ambiguous unset' '
test_must_fail git config --unset nextsection.nonewline
'
@@ -290,8 +311,9 @@ test_expect_success 'invalid key' 'test_must_fail git config inval.2key blabla'
test_expect_success 'correct key' 'git config 123456.a123 987'
-test_expect_success 'hierarchical section' \
- 'git config Version.1.2.3eX.Alpha beta'
+test_expect_success 'hierarchical section' '
+ git config Version.1.2.3eX.Alpha beta
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -307,7 +329,9 @@ noIndent= sillyValue ; 'nother silly comment
Alpha = beta
EOF
-test_expect_success 'hierarchical section value' 'test_cmp expect .git/config'
+test_expect_success 'hierarchical section value' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
beta.noindent=sillyValue
@@ -316,9 +340,10 @@ nextsection.nonewline=wow2 for me
version.1.2.3eX.alpha=beta
EOF
-test_expect_success 'working --list' \
- 'git config --list > output && cmp output expect'
-
+test_expect_success 'working --list' '
+ git config --list > output &&
+ test_cmp expect output
+'
cat > expect << EOF
EOF
@@ -332,8 +357,10 @@ beta.noindent sillyValue
nextsection.nonewline wow2 for me
EOF
-test_expect_success '--get-regexp' \
- 'git config --get-regexp in > output && cmp output expect'
+test_expect_success '--get-regexp' '
+ git config --get-regexp in >output &&
+ test_cmp expect output
+'
cat > expect << EOF
wow2 for me
@@ -353,45 +380,52 @@ cat > .git/config << EOF
variable =
EOF
-test_expect_success 'get variable with no value' \
- 'git config --get novalue.variable ^$'
+test_expect_success 'get variable with no value' '
+ git config --get novalue.variable ^$
+'
-test_expect_success 'get variable with empty value' \
- 'git config --get emptyvalue.variable ^$'
+test_expect_success 'get variable with empty value' '
+ git config --get emptyvalue.variable ^$
+'
echo novalue.variable > expect
-test_expect_success 'get-regexp variable with no value' \
- 'git config --get-regexp novalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp variable with no value' '
+ git config --get-regexp novalue > output &&
+ test_cmp expect output
+'
echo 'novalue.variable true' > expect
-test_expect_success 'get-regexp --bool variable with no value' \
- 'git config --bool --get-regexp novalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp --bool variable with no value' '
+ git config --bool --get-regexp novalue > output &&
+ test_cmp expect output
+'
echo 'emptyvalue.variable ' > expect
-test_expect_success 'get-regexp variable with empty value' \
- 'git config --get-regexp emptyvalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp variable with empty value' '
+ git config --get-regexp emptyvalue > output &&
+ test_cmp expect output
+'
echo true > expect
-test_expect_success 'get bool variable with no value' \
- 'git config --bool novalue.variable > output &&
- cmp output expect'
+test_expect_success 'get bool variable with no value' '
+ git config --bool novalue.variable > output &&
+ test_cmp expect output
+'
echo false > expect
-test_expect_success 'get bool variable with empty value' \
- 'git config --bool emptyvalue.variable > output &&
- cmp output expect'
+test_expect_success 'get bool variable with empty value' '
+ git config --bool emptyvalue.variable > output &&
+ test_cmp expect output
+'
test_expect_success 'no arguments, but no crash' '
test_must_fail git config >output 2>&1 &&
- grep usage output
+ test_i18ngrep usage output
'
cat > .git/config << EOF
@@ -427,8 +461,9 @@ test_expect_success 'new variable inserts into proper section' '
test_cmp expect .git/config
'
-test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \
- 'test_must_fail git config --file non-existing-config -l'
+test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' '
+ test_must_fail git config --file non-existing-config -l
+'
cat > other-config << EOF
[ein]
@@ -444,8 +479,10 @@ test_expect_success 'alternative GIT_CONFIG' '
test_cmp expect output
'
-test_expect_success 'alternative GIT_CONFIG (--file)' \
- 'git config --file other-config -l > output && cmp output expect'
+test_expect_success 'alternative GIT_CONFIG (--file)' '
+ git config --file other-config -l > output &&
+ test_cmp expect output
+'
test_expect_success 'refer config from subdirectory' '
mkdir x &&
@@ -489,8 +526,9 @@ cat > .git/config << EOF
weird
EOF
-test_expect_success "rename section" \
- "git config --rename-section branch.eins branch.zwei"
+test_expect_success 'rename section' '
+ git config --rename-section branch.eins branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -503,17 +541,22 @@ cat > expect << EOF
weird
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
-test_expect_success "rename non-existing section" '
+test_expect_success 'rename non-existing section' '
test_must_fail git config --rename-section \
branch."world domination" branch.drei
'
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
-test_expect_success "rename another section" \
- 'git config --rename-section branch."1 234 blabl/a" branch.drei'
+test_expect_success 'rename another section' '
+ git config --rename-section branch."1 234 blabl/a" branch.drei
+'
cat > expect << EOF
# Hallo
@@ -526,14 +569,17 @@ cat > expect << EOF
weird
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
cat >> .git/config << EOF
[branch "vier"] z = 1
EOF
-test_expect_success "rename a section with a var on the same line" \
- 'git config --rename-section branch.vier branch.zwei'
+test_expect_success 'rename a section with a var on the same line' '
+ git config --rename-section branch.vier branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -548,7 +594,9 @@ weird
z = 1
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
test_expect_success 'renaming empty section name is rejected' '
test_must_fail git config --rename-section branch.zwei ""
@@ -562,7 +610,9 @@ cat >> .git/config << EOF
[branch "zwei"] a = 1 [branch "vier"]
EOF
-test_expect_success "remove section" "git config --remove-section branch.zwei"
+test_expect_success 'remove section' '
+ git config --remove-section branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -571,8 +621,9 @@ cat > expect << EOF
weird
EOF
-test_expect_success "section was removed properly" \
- "test_cmp expect .git/config"
+test_expect_success 'section was removed properly' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
[gitcvs]
@@ -583,7 +634,6 @@ cat > expect << EOF
EOF
test_expect_success 'section ending' '
-
rm -f .git/config &&
git config gitcvs.enabled true &&
git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
@@ -593,30 +643,25 @@ test_expect_success 'section ending' '
'
test_expect_success numbers '
-
git config kilo.gram 1k &&
git config mega.ton 1m &&
- k=$(git config --int --get kilo.gram) &&
- test z1024 = "z$k" &&
- m=$(git config --int --get mega.ton) &&
- test z1048576 = "z$m"
+ echo 1024 >expect &&
+ echo 1048576 >>expect &&
+ git config --int --get kilo.gram >actual &&
+ git config --int --get mega.ton >>actual &&
+ test_cmp expect actual
'
-cat > expect <<EOF
-fatal: bad config value for 'aninvalid.unit' in .git/config
-EOF
-
test_expect_success 'invalid unit' '
-
git config aninvalid.unit "1auto" &&
- s=$(git config aninvalid.unit) &&
- test "z1auto" = "z$s" &&
- if git config --int --get aninvalid.unit 2>actual
- then
- echo config should have failed
- false
- fi &&
- cmp actual expect
+ echo 1auto >expect &&
+ git config aninvalid.unit >actual &&
+ test_cmp expect actual &&
+ cat > expect <<-\EOF
+ fatal: bad config value for '\''aninvalid.unit'\'' in .git/config
+ EOF
+ test_must_fail git config --int --get aninvalid.unit 2>actual &&
+ test_cmp actual expect
'
cat > expect << EOF
@@ -646,7 +691,7 @@ test_expect_success bool '
git config --bool --get bool.true$i >>result
git config --bool --get bool.false$i >>result
done &&
- cmp expect result'
+ test_cmp expect result'
test_expect_success 'invalid bool (--get)' '
@@ -680,7 +725,7 @@ test_expect_success 'set --bool' '
git config --bool bool.false2 "" &&
git config --bool bool.false3 nO &&
git config --bool bool.false4 FALSE &&
- cmp expect .git/config'
+ test_cmp expect .git/config'
cat > expect <<\EOF
[int]
@@ -695,39 +740,37 @@ test_expect_success 'set --int' '
git config --int int.val1 01 &&
git config --int int.val2 -1 &&
git config --int int.val3 5m &&
- cmp expect .git/config'
+ test_cmp expect .git/config
+'
-cat >expect <<\EOF
-[bool]
- true1 = true
+test_expect_success 'get --bool-or-int' '
+ cat >.git/config <<-\EOF &&
+ [bool]
+ true1
true2 = true
- false1 = false
- false2 = false
-[int]
+ false = false
+ [int]
int1 = 0
int2 = 1
int3 = -1
-EOF
-
-test_expect_success 'get --bool-or-int' '
- rm -f .git/config &&
- (
- echo "[bool]"
- echo true1
- echo true2 = true
- echo false = false
- echo "[int]"
- echo int1 = 0
- echo int2 = 1
- echo int3 = -1
- ) >>.git/config &&
- test $(git config --bool-or-int bool.true1) = true &&
- test $(git config --bool-or-int bool.true2) = true &&
- test $(git config --bool-or-int bool.false) = false &&
- test $(git config --bool-or-int int.int1) = 0 &&
- test $(git config --bool-or-int int.int2) = 1 &&
- test $(git config --bool-or-int int.int3) = -1
-
+ EOF
+ cat >expect <<-\EOF &&
+ true
+ true
+ false
+ 0
+ 1
+ -1
+ EOF
+ {
+ git config --bool-or-int bool.true1 &&
+ git config --bool-or-int bool.true2 &&
+ git config --bool-or-int bool.false &&
+ git config --bool-or-int int.int1 &&
+ git config --bool-or-int int.int2 &&
+ git config --bool-or-int int.int3
+ } >actual &&
+ test_cmp expect actual
'
cat >expect <<\EOF
@@ -803,6 +846,11 @@ test_expect_success NOT_MINGW 'get --path copes with unset $HOME' '
test_cmp expect result
'
+test_expect_success 'get --path barfs on boolean variable' '
+ echo "[path]bool" >.git/config &&
+ test_must_fail git config --get --path path.bool
+'
+
cat > expect << EOF
[quote]
leading = " test"
@@ -844,7 +892,7 @@ EOF
test_expect_success 'value continued on next line' '
git config --list > result &&
- cmp result expect
+ test_cmp result expect
'
cat > .git/config <<\EOF
@@ -880,11 +928,12 @@ test_expect_success '--null --get-regexp' '
test_expect_success 'inner whitespace kept verbatim' '
git config section.val "foo bar" &&
- test "z$(git config section.val)" = "zfoo bar"
+ echo "foo bar" >expect &&
+ git config section.val >actual &&
+ test_cmp expect actual
'
test_expect_success SYMLINKS 'symlinked configuration' '
-
ln -s notyet myconfig &&
GIT_CONFIG=myconfig git config test.frotz nitfol &&
test -h myconfig &&
@@ -893,9 +942,15 @@ test_expect_success SYMLINKS 'symlinked configuration' '
GIT_CONFIG=myconfig git config test.xyzzy rezrov &&
test -h myconfig &&
test -f notyet &&
- test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol &&
- test "z$(GIT_CONFIG=notyet git config test.xyzzy)" = zrezrov
-
+ cat >expect <<-\EOF &&
+ nitfol
+ rezrov
+ EOF
+ {
+ GIT_CONFIG=notyet git config test.frotz &&
+ GIT_CONFIG=notyet git config test.xyzzy
+ } >actual &&
+ test_cmp expect actual
'
test_expect_success 'nonexistent configuration' '
@@ -927,12 +982,20 @@ test_expect_success 'check split_cmdline return' "
git commit -m 'initial commit' &&
git config branch.master.mergeoptions 'echo \"' &&
test_must_fail git merge master
- "
+"
test_expect_success 'git -c "key=value" support' '
- test "z$(git -c core.name=value config core.name)" = zvalue &&
- test "z$(git -c foo.CamelCase=value config foo.camelcase)" = zvalue &&
- test "z$(git -c foo.flag config --bool foo.flag)" = ztrue &&
+ cat >expect <<-\EOF &&
+ value
+ value
+ true
+ EOF
+ {
+ git -c core.name=value config core.name &&
+ git -c foo.CamelCase=value config foo.camelcase &&
+ git -c foo.flag config --bool foo.flag
+ } >actual &&
+ test_cmp expect actual &&
test_must_fail git -c name=value config core.name
'
diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh
index 2b962cfda7..79045abb51 100755
--- a/t/t1304-default-acl.sh
+++ b/t/t1304-default-acl.sh
@@ -14,16 +14,15 @@ umask 077
# We need an arbitrary other user give permission to using ACLs. root
# is a good candidate: exists on all unices, and it has permission
# anyway, so we don't create a security hole running the testsuite.
-
-setfacl_out="$(setfacl -m u:root:rwx . 2>&1)"
-setfacl_ret=$?
-
-if test $setfacl_ret != 0
-then
- say "Unable to use setfacl (output: '$setfacl_out'; return code: '$setfacl_ret')"
-else
- test_set_prereq SETFACL
-fi
+test_expect_success 'checking for a working acl setup' '
+ if setfacl -m d:m:rwx -m u:root:rwx . &&
+ getfacl . | grep user:root:rwx &&
+ touch should-have-readable-acl &&
+ getfacl should-have-readable-acl | egrep "mask::?rw-"
+ then
+ test_set_prereq SETFACL
+ fi
+'
if test -z "$LOGNAME"
then
diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh
new file mode 100755
index 0000000000..8b14ab187c
--- /dev/null
+++ b/t/t1306-xdg-files.sh
@@ -0,0 +1,197 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,
+# Thomas Nguy, Khoi Nguyen
+# Grenoble INP Ensimag
+#
+
+test_description='Compatibility with $XDG_CONFIG_HOME/git/ files'
+
+. ./test-lib.sh
+
+test_expect_success 'read config: xdg file exists and ~/.gitconfig doesn'\''t' '
+ mkdir -p .config/git &&
+ echo "[alias]" >.config/git/config &&
+ echo " myalias = !echo in_config" >>.config/git/config &&
+ echo in_config >expected &&
+ git myalias >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read config: xdg file exists and ~/.gitconfig exists' '
+ >.gitconfig &&
+ echo "[alias]" >.gitconfig &&
+ echo " myalias = !echo in_gitconfig" >>.gitconfig &&
+ echo in_gitconfig >expected &&
+ git myalias >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read with --get: xdg file exists and ~/.gitconfig doesn'\''t' '
+ rm .gitconfig &&
+ echo "[user]" >.config/git/config &&
+ echo " name = read_config" >>.config/git/config &&
+ echo read_config >expected &&
+ git config --get user.name >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '"$XDG_CONFIG_HOME overrides $HOME/.config/git' '
+ mkdir -p "$HOME"/xdg/git &&
+ echo "[user]name = in_xdg" >"$HOME"/xdg/git/config &&
+ echo in_xdg >expected &&
+ XDG_CONFIG_HOME="$HOME"/xdg git config --get-all user.name >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'read with --get: xdg file exists and ~/.gitconfig exists' '
+ >.gitconfig &&
+ echo "[user]" >.gitconfig &&
+ echo " name = read_gitconfig" >>.gitconfig &&
+ echo read_gitconfig >expected &&
+ git config --get user.name >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read with --list: xdg file exists and ~/.gitconfig doesn'\''t' '
+ rm .gitconfig &&
+ echo user.name=read_config >expected &&
+ git config --global --list >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read with --list: xdg file exists and ~/.gitconfig exists' '
+ >.gitconfig &&
+ echo "[user]" >.gitconfig &&
+ echo " name = read_gitconfig" >>.gitconfig &&
+ echo user.name=read_gitconfig >expected &&
+ git config --global --list >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'Setup' '
+ git init git &&
+ cd git &&
+ echo foo >to_be_excluded
+'
+
+
+test_expect_success 'Exclusion of a file in the XDG ignore file' '
+ mkdir -p "$HOME"/.config/git/ &&
+ echo to_be_excluded >"$HOME"/.config/git/ignore &&
+ test_must_fail git add to_be_excluded
+'
+
+test_expect_success '$XDG_CONFIG_HOME overrides $HOME/.config/git/ignore' '
+ mkdir -p "$HOME"/xdg/git &&
+ echo content >excluded_by_xdg_only &&
+ echo excluded_by_xdg_only >"$HOME"/xdg/git/ignore &&
+ test_when_finished "git read-tree --empty" &&
+ (XDG_CONFIG_HOME="$HOME/xdg" &&
+ export XDG_CONFIG_HOME &&
+ git add to_be_excluded &&
+ test_must_fail git add excluded_by_xdg_only
+ )
+'
+
+test_expect_success 'Exclusion in both XDG and local ignore files' '
+ echo to_be_excluded >.gitignore &&
+ test_must_fail git add to_be_excluded
+'
+
+
+test_expect_success 'Exclusion in a non-XDG global ignore file' '
+ rm .gitignore &&
+ echo >"$HOME"/.config/git/ignore &&
+ echo to_be_excluded >"$HOME"/my_gitignore &&
+ git config core.excludesfile "$HOME"/my_gitignore &&
+ test_must_fail git add to_be_excluded
+'
+
+test_expect_success 'Checking XDG ignore file when HOME is unset' '
+ >expected &&
+ (sane_unset HOME &&
+ git config --unset core.excludesfile &&
+ git ls-files --exclude-standard --ignored >actual) &&
+ test_cmp expected actual
+'
+
+test_expect_success 'Checking attributes in the XDG attributes file' '
+ echo foo >f &&
+ git check-attr -a f >actual &&
+ test_line_count -eq 0 actual &&
+ echo "f attr_f" >"$HOME"/.config/git/attributes &&
+ echo "f: attr_f: set" >expected &&
+ git check-attr -a f >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'Checking XDG attributes when HOME is unset' '
+ >expected &&
+ (sane_unset HOME &&
+ git check-attr -a f >actual) &&
+ test_cmp expected actual
+'
+
+test_expect_success '$XDG_CONFIG_HOME overrides $HOME/.config/git/attributes' '
+ mkdir -p "$HOME"/xdg/git &&
+ echo "f attr_f=xdg" >"$HOME"/xdg/git/attributes &&
+ echo "f: attr_f: xdg" >expected &&
+ XDG_CONFIG_HOME="$HOME/xdg" git check-attr -a f >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'Checking attributes in both XDG and local attributes files' '
+ echo "f -attr_f" >.gitattributes &&
+ echo "f: attr_f: unset" >expected &&
+ git check-attr -a f >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'Checking attributes in a non-XDG global attributes file' '
+ test_might_fail rm .gitattributes &&
+ echo "f attr_f=test" >"$HOME"/my_gitattributes &&
+ git config core.attributesfile "$HOME"/my_gitattributes &&
+ echo "f: attr_f: test" >expected &&
+ git check-attr -a f >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'write: xdg file exists and ~/.gitconfig doesn'\''t' '
+ mkdir -p "$HOME"/.config/git &&
+ >"$HOME"/.config/git/config &&
+ test_might_fail rm "$HOME"/.gitconfig &&
+ git config --global user.name "write_config" &&
+ echo "[user]" >expected &&
+ echo " name = write_config" >>expected &&
+ test_cmp expected "$HOME"/.config/git/config
+'
+
+
+test_expect_success 'write: xdg file exists and ~/.gitconfig exists' '
+ >"$HOME"/.gitconfig &&
+ git config --global user.name "write_gitconfig" &&
+ echo "[user]" >expected &&
+ echo " name = write_gitconfig" >>expected &&
+ test_cmp expected "$HOME"/.gitconfig
+'
+
+
+test_expect_success 'write: ~/.config/git/ exists and config file doesn'\''t' '
+ test_might_fail rm "$HOME"/.gitconfig &&
+ test_might_fail rm "$HOME"/.config/git/config &&
+ git config --global user.name "write_gitconfig" &&
+ echo "[user]" >expected &&
+ echo " name = write_gitconfig" >>expected &&
+ test_cmp expected "$HOME"/.gitconfig
+'
+
+
+test_done
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 4fd83a667a..e415ee0bbf 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -74,6 +74,24 @@ test_expect_success "delete $m (by HEAD)" '
'
rm -f .git/$m
+test_expect_success \
+ "create $m (by HEAD)" \
+ "git update-ref HEAD $A &&
+ test $A"' = $(cat .git/'"$m"')'
+test_expect_success \
+ "pack refs" \
+ "git pack-refs --all"
+test_expect_success \
+ "move $m (by HEAD)" \
+ "git update-ref HEAD $B $A &&
+ test $B"' = $(cat .git/'"$m"')'
+test_expect_success "delete $m (by HEAD) should remove both packed and loose $m" '
+ git update-ref -d HEAD $B &&
+ ! grep "$m" .git/packed-refs &&
+ ! test -f .git/$m
+'
+rm -f .git/$m
+
cp -f .git/HEAD .git/HEAD.orig
test_expect_success "delete symref without dereference" '
git update-ref --no-deref -d HEAD &&
diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index 2c96551ed0..36378b0e3f 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -33,4 +33,34 @@ test_expect_success 'symbolic-ref refuses bare sha1' '
'
reset_to_sane
+test_expect_success 'symbolic-ref deletes HEAD' '
+ git symbolic-ref -d HEAD &&
+ test_path_is_file .git/refs/heads/foo &&
+ test_path_is_missing .git/HEAD
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref deletes dangling HEAD' '
+ git symbolic-ref HEAD refs/heads/missing &&
+ git symbolic-ref -d HEAD &&
+ test_path_is_missing .git/refs/heads/missing &&
+ test_path_is_missing .git/HEAD
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref fails to delete missing FOO' '
+ echo "fatal: Cannot delete FOO, not a symbolic ref" >expect &&
+ test_must_fail git symbolic-ref -d FOO >actual 2>&1 &&
+ test_cmp expect actual
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref fails to delete real ref' '
+ echo "fatal: Cannot delete refs/heads/foo, not a symbolic ref" >expect &&
+ test_must_fail git symbolic-ref -d refs/heads/foo >actual 2>&1 &&
+ test_path_is_file .git/refs/heads/foo &&
+ test_cmp expect actual
+'
+reset_to_sane
+
test_done
diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
index 1ae4d87c92..1a5a5f39fd 100755
--- a/t/t1402-check-ref-format.sh
+++ b/t/t1402-check-ref-format.sh
@@ -11,7 +11,8 @@ valid_ref() {
prereq=$1
shift
esac
- test_expect_success $prereq "ref name '$1' is valid${2:+ with options $2}" "
+ desc="ref name '$1' is valid${2:+ with options $2}"
+ test_expect_success $prereq "$desc" "
git check-ref-format $2 '$1'
"
}
@@ -22,7 +23,8 @@ invalid_ref() {
prereq=$1
shift
esac
- test_expect_success $prereq "ref name '$1' is invalid${2:+ with options $2}" "
+ desc="ref name '$1' is invalid${2:+ with options $2}"
+ test_expect_success $prereq "$desc" "
test_must_fail git check-ref-format $2 '$1'
"
}
diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh
index caa687b5b4..9a105fe21f 100755
--- a/t/t1411-reflog-show.sh
+++ b/t/t1411-reflog-show.sh
@@ -65,20 +65,73 @@ test_expect_success 'using @{now} syntax shows reflog date (oneline)' '
'
cat >expect <<'EOF'
-Reflog: HEAD@{1112911993 -0700} (C O Mitter <committer@example.com>)
+HEAD@{Thu Apr 7 15:13:13 2005 -0700}
+EOF
+test_expect_success 'using @{now} syntax shows reflog date (format=%gd)' '
+ git log -g -1 --format=%gd HEAD@{now} >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Reflog: HEAD@{Thu Apr 7 15:13:13 2005 -0700} (C O Mitter <committer@example.com>)
Reflog message: commit (initial): one
EOF
test_expect_success 'using --date= shows reflog date (multiline)' '
- git log -g -1 --date=raw >tmp &&
+ git log -g -1 --date=default >tmp &&
grep ^Reflog <tmp >actual &&
test_cmp expect actual
'
cat >expect <<'EOF'
-e46513e HEAD@{1112911993 -0700}: commit (initial): one
+e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
EOF
test_expect_success 'using --date= shows reflog date (oneline)' '
- git log -g -1 --oneline --date=raw >actual &&
+ git log -g -1 --oneline --date=default >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+HEAD@{1112911993 -0700}
+EOF
+test_expect_success 'using --date= shows reflog date (format=%gd)' '
+ git log -g -1 --format=%gd --date=raw >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
+Reflog message: commit (initial): one
+EOF
+test_expect_success 'log.date does not invoke "--date" magic (multiline)' '
+ test_config log.date raw &&
+ git log -g -1 >tmp &&
+ grep ^Reflog <tmp >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+e46513e HEAD@{0}: commit (initial): one
+EOF
+test_expect_success 'log.date does not invoke "--date" magic (oneline)' '
+ test_config log.date raw &&
+ git log -g -1 --oneline >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+HEAD@{0}
+EOF
+test_expect_success 'log.date does not invoke "--date" magic (format=%gd)' '
+ test_config log.date raw &&
+ git log -g -1 --format=%gd >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+HEAD@{0}
+EOF
+test_expect_success '--date magic does not override explicit @{0} syntax' '
+ git log -g -1 --format=%gd --date=raw HEAD@{0} >actual &&
test_cmp expect actual
'
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 5b79c51b8c..d730734fde 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -177,9 +177,7 @@ test_expect_success 'tag pointing to something else than its type' '
test_when_finished "remove_object $tag" &&
echo $tag >.git/refs/tags/wrong &&
test_when_finished "git update-ref -d refs/tags/wrong" &&
- test_must_fail git fsck --tags 2>out &&
- cat out &&
- grep "error in tag.*broken links" out
+ test_must_fail git fsck --tags
'
test_expect_success 'cleaned up' '
@@ -213,4 +211,61 @@ test_expect_success 'rev-list --verify-objects with bad sha1' '
grep -q "error: sha1 mismatch 63ffffffffffffffffffffffffffffffffffffff" out
'
+_bz='\0'
+_bz5="$_bz$_bz$_bz$_bz$_bz"
+_bz20="$_bz5$_bz5$_bz5$_bz5"
+
+test_expect_success 'fsck notices blob entry pointing to null sha1' '
+ (git init null-blob &&
+ cd null-blob &&
+ sha=$(printf "100644 file$_bz$_bz20" |
+ git hash-object -w --stdin -t tree) &&
+ git fsck 2>out &&
+ cat out &&
+ grep "warning.*null sha1" out
+ )
+'
+
+test_expect_success 'fsck notices submodule entry pointing to null sha1' '
+ (git init null-commit &&
+ cd null-commit &&
+ sha=$(printf "160000 submodule$_bz$_bz20" |
+ git hash-object -w --stdin -t tree) &&
+ git fsck 2>out &&
+ cat out &&
+ grep "warning.*null sha1" out
+ )
+'
+
+test_expect_success 'fsck notices "." and ".." in trees' '
+ (
+ git init dots &&
+ cd dots &&
+ blob=$(echo foo | git hash-object -w --stdin) &&
+ tab=$(printf "\\t") &&
+ git mktree <<-EOF &&
+ 100644 blob $blob$tab.
+ 100644 blob $blob$tab..
+ EOF
+ git fsck 2>out &&
+ cat out &&
+ grep "warning.*\\." out
+ )
+'
+
+test_expect_success 'fsck notices ".git" in trees' '
+ (
+ git init dotgit &&
+ cd dotgit &&
+ blob=$(echo foo | git hash-object -w --stdin) &&
+ tab=$(printf "\\t") &&
+ git mktree <<-EOF &&
+ 100644 blob $blob$tab.git
+ EOF
+ git fsck 2>out &&
+ cat out &&
+ grep "warning.*\\.git" out
+ )
+'
+
test_done
diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh
index 1efd7f76dd..13c88c9aae 100755
--- a/t/t1502-rev-parse-parseopt.sh
+++ b/t/t1502-rev-parse-parseopt.sh
@@ -41,7 +41,7 @@ EOF
test_expect_success 'test --parseopt help output' '
test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec &&
- test_cmp expect output
+ test_i18ncmp expect output
'
cat > expect <<EOF
diff --git a/t/t1505-rev-parse-last.sh b/t/t1505-rev-parse-last.sh
index d709ecf8df..4969edb314 100755
--- a/t/t1505-rev-parse-last.sh
+++ b/t/t1505-rev-parse-last.sh
@@ -32,32 +32,24 @@ test_expect_success 'setup' '
#
# and 'side' should be the last branch
-test_rev_equivalent () {
-
- git rev-parse "$1" > expect &&
- git rev-parse "$2" > output &&
- test_cmp expect output
-
-}
-
test_expect_success '@{-1} works' '
- test_rev_equivalent side @{-1}
+ test_cmp_rev side @{-1}
'
test_expect_success '@{-1}~2 works' '
- test_rev_equivalent side~2 @{-1}~2
+ test_cmp_rev side~2 @{-1}~2
'
test_expect_success '@{-1}^2 works' '
- test_rev_equivalent side^2 @{-1}^2
+ test_cmp_rev side^2 @{-1}^2
'
test_expect_success '@{-1}@{1} works' '
- test_rev_equivalent side@{1} @{-1}@{1}
+ test_cmp_rev side@{1} @{-1}@{1}
'
test_expect_success '@{-2} works' '
- test_rev_equivalent master @{-2}
+ test_cmp_rev master @{-2}
'
test_expect_success '@{-3} fails' '
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index 0843a1c13b..f950c10128 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -171,4 +171,29 @@ test_expect_success 'relative path when startup_info is NULL' '
grep "BUG: startup_info struct is not initialized." error
'
+test_expect_success '<commit>:file correctly diagnosed after a pathname' '
+ test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&
+ test_i18ngrep ! "exists on disk" error &&
+ test_i18ngrep "no such path in the working tree" error &&
+ cat >expect <<-\EOF &&
+ file.txt
+ HEAD:file.txt
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'dotdot is not an empty set' '
+ ( H=$(git rev-parse HEAD) && echo $H && echo ^$H ) >expect &&
+
+ git rev-parse HEAD.. >actual &&
+ test_cmp expect actual &&
+
+ git rev-parse ..HEAD >actual &&
+ test_cmp expect actual &&
+
+ echo .. >expect &&
+ git rev-parse .. >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh
new file mode 100755
index 0000000000..6b3d797cea
--- /dev/null
+++ b/t/t1512-rev-parse-disambiguation.sh
@@ -0,0 +1,264 @@
+#!/bin/sh
+
+test_description='object name disambiguation
+
+Create blobs, trees, commits and a tag that all share the same
+prefix, and make sure "git rev-parse" can take advantage of
+type information to disambiguate short object names that are
+not necessarily unique.
+
+The final history used in the test has five commits, with the bottom
+one tagged as v1.0.0. They all have one regular file each.
+
+ +-------------------------------------------+
+ | |
+ | .-------b3wettvi---- ad2uee |
+ | / / |
+ | a2onsxbvj---czy8f73t--ioiley5o |
+ | |
+ +-------------------------------------------+
+
+'
+
+. ./test-lib.sh
+
+test_expect_success 'blob and tree' '
+ test_tick &&
+ (
+ for i in 0 1 2 3 4 5 6 7 8 9
+ do
+ echo $i
+ done
+ echo
+ echo b1rwzyc3
+ ) >a0blgqsjc &&
+
+ # create one blob 0000000000b36
+ git add a0blgqsjc &&
+
+ # create one tree 0000000000cdc
+ git write-tree
+'
+
+test_expect_success 'warn ambiguity when no candidate matches type hint' '
+ test_must_fail git rev-parse --verify 000000000^{commit} 2>actual &&
+ grep "short SHA1 000000000 is ambiguous" actual
+'
+
+test_expect_success 'disambiguate tree-ish' '
+ # feed tree-ish in an unambiguous way
+ git rev-parse --verify 0000000000cdc:a0blgqsjc &&
+
+ # ambiguous at the object name level, but there is only one
+ # such tree-ish (the other is a blob)
+ git rev-parse --verify 000000000:a0blgqsjc
+'
+
+test_expect_success 'disambiguate blob' '
+ sed -e "s/|$//" >patch <<-EOF &&
+ diff --git a/frotz b/frotz
+ index 000000000..ffffff 100644
+ --- a/frotz
+ +++ b/frotz
+ @@ -10,3 +10,4 @@
+ 9
+ |
+ b1rwzyc3
+ +irwry
+ EOF
+ (
+ GIT_INDEX_FILE=frotz &&
+ export GIT_INDEX_FILE &&
+ git apply --build-fake-ancestor frotz patch &&
+ git cat-file blob :frotz >actual
+ ) &&
+ test_cmp a0blgqsjc actual
+'
+
+test_expect_success 'disambiguate tree' '
+ commit=$(echo "d7xm" | git commit-tree 000000000) &&
+ test $(git rev-parse $commit^{tree}) = $(git rev-parse 0000000000cdc)
+'
+
+test_expect_success 'first commit' '
+ # create one commit 0000000000e4f
+ git commit -m a2onsxbvj
+'
+
+test_expect_success 'disambiguate commit-ish' '
+ # feed commit-ish in an unambiguous way
+ git rev-parse --verify 0000000000e4f^{commit} &&
+
+ # ambiguous at the object name level, but there is only one
+ # such commit (the others are tree and blob)
+ git rev-parse --verify 000000000^{commit} &&
+
+ # likewise
+ git rev-parse --verify 000000000^0
+'
+
+test_expect_success 'disambiguate commit' '
+ commit=$(echo "hoaxj" | git commit-tree 0000000000cdc -p 000000000) &&
+ test $(git rev-parse $commit^) = $(git rev-parse 0000000000e4f)
+'
+
+test_expect_success 'log name1..name2 takes only commit-ishes on both ends' '
+ git log 000000000..000000000 &&
+ git log ..000000000 &&
+ git log 000000000.. &&
+ git log 000000000...000000000 &&
+ git log ...000000000 &&
+ git log 000000000...
+'
+
+test_expect_success 'rev-parse name1..name2 takes only commit-ishes on both ends' '
+ git rev-parse 000000000..000000000 &&
+ git rev-parse ..000000000 &&
+ git rev-parse 000000000..
+'
+
+test_expect_success 'git log takes only commit-ish' '
+ git log 000000000
+'
+
+test_expect_success 'git reset takes only commit-ish' '
+ git reset 000000000
+'
+
+test_expect_success 'first tag' '
+ # create one tag 0000000000f8f
+ git tag -a -m j7cp83um v1.0.0
+'
+
+test_expect_failure 'two semi-ambiguous commit-ish' '
+ # Once the parser becomes ultra-smart, it could notice that
+ # 110282 before ^{commit} name many different objects, but
+ # that only two (HEAD and v1.0.0 tag) can be peeled to commit,
+ # and that peeling them down to commit yield the same commit
+ # without ambiguity.
+ git rev-parse --verify 110282^{commit} &&
+
+ # likewise
+ git log 000000000..000000000 &&
+ git log ..000000000 &&
+ git log 000000000.. &&
+ git log 000000000...000000000 &&
+ git log ...000000000 &&
+ git log 000000000...
+'
+
+test_expect_failure 'three semi-ambiguous tree-ish' '
+ # Likewise for tree-ish. HEAD, v1.0.0 and HEAD^{tree} share
+ # the prefix but peeling them to tree yields the same thing
+ git rev-parse --verify 000000000^{tree}
+'
+
+test_expect_success 'parse describe name' '
+ # feed an unambiguous describe name
+ git rev-parse --verify v1.0.0-0-g0000000000e4f &&
+
+ # ambiguous at the object name level, but there is only one
+ # such commit (others are blob, tree and tag)
+ git rev-parse --verify v1.0.0-0-g000000000
+'
+
+test_expect_success 'more history' '
+ # commit 0000000000043
+ git mv a0blgqsjc d12cr3h8t &&
+ echo h62xsjeu >>d12cr3h8t &&
+ git add d12cr3h8t &&
+
+ test_tick &&
+ git commit -m czy8f73t &&
+
+ # commit 00000000008ec
+ git mv d12cr3h8t j000jmpzn &&
+ echo j08bekfvt >>j000jmpzn &&
+ git add j000jmpzn &&
+
+ test_tick &&
+ git commit -m ioiley5o &&
+
+ # commit 0000000005b0
+ git checkout v1.0.0^0 &&
+ git mv a0blgqsjc f5518nwu &&
+
+ for i in h62xsjeu j08bekfvt kg7xflhm
+ do
+ echo $i
+ done >>f5518nwu &&
+ git add f5518nwu &&
+
+ test_tick &&
+ git commit -m b3wettvi &&
+ side=$(git rev-parse HEAD) &&
+
+ # commit 000000000066
+ git checkout master &&
+
+ # If you use recursive, merge will fail and you will need to
+ # clean up a0blgqsjc as well. If you use resolve, merge will
+ # succeed.
+ test_might_fail git merge --no-commit -s recursive $side &&
+ git rm -f f5518nwu j000jmpzn &&
+
+ test_might_fail git rm -f a0blgqsjc &&
+ (
+ git cat-file blob $side:f5518nwu
+ echo j3l0i9s6
+ ) >ab2gs879 &&
+ git add ab2gs879 &&
+
+ test_tick &&
+ git commit -m ad2uee
+
+'
+
+test_expect_failure 'parse describe name taking advantage of generation' '
+ # ambiguous at the object name level, but there is only one
+ # such commit at generation 0
+ git rev-parse --verify v1.0.0-0-g000000000 &&
+
+ # likewise for generation 2 and 4
+ git rev-parse --verify v1.0.0-2-g000000000 &&
+ git rev-parse --verify v1.0.0-4-g000000000
+'
+
+# Note: because rev-parse does not even try to disambiguate based on
+# the generation number, this test currently succeeds for a wrong
+# reason. When it learns to use the generation number, the previous
+# test should succeed, and also this test should fail because the
+# describe name used in the test with generation number can name two
+# commits. Make sure that such a future enhancement does not randomly
+# pick one.
+test_expect_success 'parse describe name not ignoring ambiguity' '
+ # ambiguous at the object name level, and there are two such
+ # commits at generation 1
+ test_must_fail git rev-parse --verify v1.0.0-1-g000000000
+'
+
+test_expect_success 'ambiguous commit-ish' '
+ # Now there are many commits that begin with the
+ # common prefix, none of these should pick one at
+ # random. They all should result in ambiguity errors.
+ test_must_fail git rev-parse --verify 110282^{commit} &&
+
+ # likewise
+ test_must_fail git log 000000000..000000000 &&
+ test_must_fail git log ..000000000 &&
+ test_must_fail git log 000000000.. &&
+ test_must_fail git log 000000000...000000000 &&
+ test_must_fail git log ...000000000 &&
+ test_must_fail git log 000000000...
+'
+
+test_expect_success 'rev-parse --disambiguate' '
+ # The test creates 16 objects that share the prefix and two
+ # commits created by commit-tree in earlier tests share a
+ # different prefix.
+ git rev-parse --disambiguate=000000000 >actual &&
+ test $(wc -l <actual) = 16 &&
+ test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000
+'
+
+test_done
diff --git a/t/t2006-checkout-index-basic.sh b/t/t2006-checkout-index-basic.sh
index b8559838b1..57cbdfe9bc 100755
--- a/t/t2006-checkout-index-basic.sh
+++ b/t/t2006-checkout-index-basic.sh
@@ -7,7 +7,7 @@ test_description='basic checkout-index tests
test_expect_success 'checkout-index --gobbledegook' '
test_expect_code 129 git checkout-index --gobbledegook 2>err &&
- grep "[Uu]sage" err
+ test_i18ngrep "[Uu]sage" err
'
test_expect_success 'checkout-index -h in broken repository' '
@@ -18,7 +18,7 @@ test_expect_success 'checkout-index -h in broken repository' '
>.git/index &&
test_expect_code 129 git checkout-index -h >usage 2>&1
) &&
- grep "[Uu]sage" broken/usage
+ test_i18ngrep "[Uu]sage" broken/usage
'
test_done
diff --git a/t/t2015-checkout-unborn.sh b/t/t2015-checkout-unborn.sh
index 6352b74e2e..37bdcedcc9 100755
--- a/t/t2015-checkout-unborn.sh
+++ b/t/t2015-checkout-unborn.sh
@@ -46,4 +46,15 @@ test_expect_success 'checking out another branch from unborn state' '
test_cmp expect actual
'
+test_expect_success 'checking out in a newly created repo' '
+ test_create_repo empty &&
+ (
+ cd empty &&
+ git symbolic-ref HEAD >expect &&
+ test_must_fail git checkout &&
+ git symbolic-ref HEAD >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh
index 0e3b8582f2..655f278c5f 100755
--- a/t/t2017-checkout-orphan.sh
+++ b/t/t2017-checkout-orphan.sh
@@ -116,4 +116,10 @@ test_expect_success '--orphan refuses to switch if a merge is needed' '
git reset --hard
'
+test_expect_success 'cannot --detach on an unborn branch' '
+ git checkout master &&
+ git checkout --orphan new &&
+ test_must_fail git checkout --detach
+'
+
test_done
diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh
index b37ce25c42..5d68729d7a 100755
--- a/t/t2020-checkout-detach.sh
+++ b/t/t2020-checkout-detach.sh
@@ -11,14 +11,13 @@ check_not_detached () {
git symbolic-ref -q HEAD >/dev/null
}
-ORPHAN_WARNING='you are leaving .* commit.*behind'
PREV_HEAD_DESC='Previous HEAD position was'
check_orphan_warning() {
- test_i18ngrep "$ORPHAN_WARNING" "$1" &&
+ test_i18ngrep "you are leaving $2 behind" "$1" &&
test_i18ngrep ! "$PREV_HEAD_DESC" "$1"
}
check_no_orphan_warning() {
- test_i18ngrep ! "$ORPHAN_WARNING" "$1" &&
+ test_i18ngrep ! "you are leaving .* commit.*behind" "$1" &&
test_i18ngrep "$PREV_HEAD_DESC" "$1"
}
@@ -110,12 +109,24 @@ test_expect_success 'checkout warns on orphan commits' '
git checkout --detach two &&
echo content >orphan &&
git add orphan &&
- git commit -a -m orphan &&
+ git commit -a -m orphan1 &&
+ echo new content >orphan &&
+ git commit -a -m orphan2 &&
+ orphan2=$(git rev-parse HEAD) &&
git checkout master 2>stderr
'
test_expect_success 'checkout warns on orphan commits: output' '
- check_orphan_warning stderr
+ check_orphan_warning stderr "2 commits"
+'
+
+test_expect_success 'checkout warns orphaning 1 of 2 commits' '
+ git checkout "$orphan2" &&
+ git checkout HEAD^ 2>stderr
+'
+
+test_expect_success 'checkout warns orphaning 1 of 2 commits: output' '
+ check_orphan_warning stderr "1 commit"
'
test_expect_success 'checkout does not warn leaving ref tip' '
@@ -140,6 +151,7 @@ test_expect_success 'checkout does not warn leaving reachable commit' '
cat >expect <<'EOF'
Your branch is behind 'master' by 1 commit, and can be fast-forwarded.
+ (use "git pull" to update your local branch)
EOF
test_expect_success 'tracking count is accurate after orphan check' '
reset &&
diff --git a/t/t2107-update-index-basic.sh b/t/t2107-update-index-basic.sh
index 809fafe208..a6405d318d 100755
--- a/t/t2107-update-index-basic.sh
+++ b/t/t2107-update-index-basic.sh
@@ -15,7 +15,7 @@ test_expect_success 'update-index --nonsense fails' '
test_expect_success 'update-index --nonsense dumps usage' '
test_expect_code 129 git update-index --nonsense 2>err &&
- grep "[Uu]sage: git update-index" err
+ test_i18ngrep "[Uu]sage: git update-index" err
'
test_expect_success 'update-index -h with corrupt index' '
@@ -26,7 +26,26 @@ test_expect_success 'update-index -h with corrupt index' '
>.git/index &&
test_expect_code 129 git update-index -h >usage 2>&1
) &&
- grep "[Uu]sage: git update-index" broken/usage
+ test_i18ngrep "[Uu]sage: git update-index" broken/usage
+'
+
+test_expect_success '--cacheinfo does not accept blob null sha1' '
+ echo content >file &&
+ git add file &&
+ git rev-parse :file >expect &&
+ test_must_fail git update-index --cacheinfo 100644 $_z40 file &&
+ git rev-parse :file >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '--cacheinfo does not accept gitlink null sha1' '
+ git init submodule &&
+ (cd submodule && test_commit foo) &&
+ git add submodule &&
+ git rev-parse :submodule >expect &&
+ test_must_fail git update-index --cacheinfo 160000 $_z40 submodule &&
+ git rev-parse :submodule >actual &&
+ test_cmp expect actual
'
test_done
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index ec35409f9c..2a4a749b4f 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -62,5 +62,25 @@ test_expect_success 'can "commit -a" with an i-t-a entry' '
git commit -a -m all
'
+test_expect_success 'cache-tree invalidates i-t-a paths' '
+ git reset --hard &&
+ mkdir dir &&
+ : >dir/foo &&
+ git add dir/foo &&
+ git commit -m foo &&
+
+ : >dir/bar &&
+ git add -N dir/bar &&
+ git diff --cached --name-only >actual &&
+ echo dir/bar >expect &&
+ test_cmp expect actual &&
+
+ git write-tree >/dev/null &&
+
+ git diff --cached --name-only >actual &&
+ echo dir/bar >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index c8fe978267..efb7ebc91f 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -214,4 +214,28 @@ test_expect_success 'subdirectory ignore (l1)' '
test_cmp expect actual
'
+test_expect_success 'pattern matches prefix completely' '
+ : >expect &&
+ git ls-files -i -o --exclude "/three/a.3[abc]" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'ls-files with "**" patterns' '
+ cat <<\EOF >expect &&
+a.1
+one/a.1
+one/two/a.1
+three/a.1
+EOF
+ git ls-files -o -i --exclude "**/a.1" >actual
+ test_cmp expect actual
+'
+
+
+test_expect_success 'ls-files with "**" patterns and no slashes' '
+ : >expect &&
+ git ls-files -o -i --exclude "one**a.1" >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh
index 490e052875..8d9bc3c2af 100755
--- a/t/t3004-ls-files-basic.sh
+++ b/t/t3004-ls-files-basic.sh
@@ -22,7 +22,7 @@ test_expect_success 'ls-files with nonexistent path' '
test_expect_success 'ls-files with nonsense option' '
test_expect_code 129 git ls-files --nonsense 2>actual &&
- grep "[Uu]sage: git ls-files" actual
+ test_i18ngrep "[Uu]sage: git ls-files" actual
'
test_expect_success 'ls-files -h in corrupt repository' '
@@ -33,7 +33,7 @@ test_expect_success 'ls-files -h in corrupt repository' '
>.git/index &&
test_expect_code 129 git ls-files -h >usage 2>&1
) &&
- grep "[Uu]sage: git ls-files " broken/usage
+ test_i18ngrep "[Uu]sage: git ls-files " broken/usage
'
test_done
diff --git a/t/t3006-ls-files-long.sh b/t/t3006-ls-files-long.sh
new file mode 100755
index 0000000000..202ad658b8
--- /dev/null
+++ b/t/t3006-ls-files-long.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+test_description='overly long paths'
+. ./test-lib.sh
+
+test_expect_success setup '
+ p=filefilefilefilefilefilefilefile &&
+ p=$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p &&
+ p=$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p &&
+
+ path_a=${p}_a &&
+ path_z=${p}_z &&
+
+ blob_a=$(echo frotz | git hash-object -w --stdin) &&
+ blob_z=$(echo nitfol | git hash-object -w --stdin) &&
+
+ pat="100644 %s 0\t%s\n"
+'
+
+test_expect_success 'overly-long path by itself is not a problem' '
+ printf "$pat" "$blob_a" "$path_a" |
+ git update-index --add --index-info &&
+ echo "$path_a" >expect &&
+ git ls-files >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'overly-long path does not replace another by mistake' '
+ printf "$pat" "$blob_a" "$path_a" "$blob_z" "$path_z" |
+ git update-index --add --index-info &&
+ (
+ echo "$path_a"
+ echo "$path_z"
+ ) >expect &&
+ git ls-files >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
new file mode 100755
index 0000000000..af54c83111
--- /dev/null
+++ b/t/t3070-wildmatch.sh
@@ -0,0 +1,195 @@
+#!/bin/sh
+
+test_description='wildmatch tests'
+
+. ./test-lib.sh
+
+match() {
+ if [ $1 = 1 ]; then
+ test_expect_success "wildmatch: match '$3' '$4'" "
+ test-wildmatch wildmatch '$3' '$4'
+ "
+ else
+ test_expect_success "wildmatch: no match '$3' '$4'" "
+ ! test-wildmatch wildmatch '$3' '$4'
+ "
+ fi
+ if [ $2 = 1 ]; then
+ test_expect_success "fnmatch: match '$3' '$4'" "
+ test-wildmatch fnmatch '$3' '$4'
+ "
+ elif [ $2 = 0 ]; then
+ test_expect_success "fnmatch: no match '$3' '$4'" "
+ ! test-wildmatch fnmatch '$3' '$4'
+ "
+# else
+# test_expect_success BROKEN_FNMATCH "fnmatch: '$3' '$4'" "
+# ! test-wildmatch fnmatch '$3' '$4'
+# "
+ fi
+}
+
+# Basic wildmat features
+match 1 1 foo foo
+match 0 0 foo bar
+match 1 1 '' ""
+match 1 1 foo '???'
+match 0 0 foo '??'
+match 1 1 foo '*'
+match 1 1 foo 'f*'
+match 0 0 foo '*f'
+match 1 1 foo '*foo*'
+match 1 1 foobar '*ob*a*r*'
+match 1 1 aaaaaaabababab '*ab'
+match 1 1 'foo*' 'foo\*'
+match 0 0 foobar 'foo\*bar'
+match 1 1 'f\oo' 'f\\oo'
+match 1 1 ball '*[al]?'
+match 0 0 ten '[ten]'
+match 0 1 ten '**[!te]'
+match 0 0 ten '**[!ten]'
+match 1 1 ten 't[a-g]n'
+match 0 0 ten 't[!a-g]n'
+match 1 1 ton 't[!a-g]n'
+match 1 1 ton 't[^a-g]n'
+match 1 x 'a]b' 'a[]]b'
+match 1 x a-b 'a[]-]b'
+match 1 x 'a]b' 'a[]-]b'
+match 0 x aab 'a[]-]b'
+match 1 x aab 'a[]a-]b'
+match 1 1 ']' ']'
+
+# Extended slash-matching features
+match 0 0 'foo/baz/bar' 'foo*bar'
+match 0 0 'foo/baz/bar' 'foo**bar'
+match 0 1 'foobazbar' 'foo**bar'
+match 1 1 'foo/baz/bar' 'foo/**/bar'
+match 1 0 'foo/baz/bar' 'foo/**/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/**/bar'
+match 1 0 'foo/bar' 'foo/**/bar'
+match 1 0 'foo/bar' 'foo/**/**/bar'
+match 0 0 'foo/bar' 'foo?bar'
+match 0 0 'foo/bar' 'foo[/]bar'
+match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
+match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
+match 1 0 'foo' '**/foo'
+match 1 x 'XXX/foo' '**/foo'
+match 1 0 'bar/baz/foo' '**/foo'
+match 0 0 'bar/baz/foo' '*/foo'
+match 0 0 'foo/bar/baz' '**/bar*'
+match 1 0 'deep/foo/bar/baz' '**/bar/*'
+match 0 0 'deep/foo/bar/baz/' '**/bar/*'
+match 1 0 'deep/foo/bar/baz/' '**/bar/**'
+match 0 0 'deep/foo/bar' '**/bar/*'
+match 1 0 'deep/foo/bar/' '**/bar/**'
+match 0 0 'foo/bar/baz' '**/bar**'
+match 1 0 'foo/bar/baz/x' '*/bar/**'
+match 0 0 'deep/foo/bar/baz/x' '*/bar/**'
+match 1 0 'deep/foo/bar/baz/x' '**/bar/*/*'
+
+# Various additional tests
+match 0 0 'acrt' 'a[c-c]st'
+match 1 1 'acrt' 'a[c-c]rt'
+match 0 0 ']' '[!]-]'
+match 1 x 'a' '[!]-]'
+match 0 0 '' '\'
+match 0 x '\' '\'
+match 0 x 'XXX/\' '*/\'
+match 1 x 'XXX/\' '*/\\'
+match 1 1 'foo' 'foo'
+match 1 1 '@foo' '@foo'
+match 0 0 'foo' '@foo'
+match 1 1 '[ab]' '\[ab]'
+match 1 1 '[ab]' '[[]ab]'
+match 1 x '[ab]' '[[:]ab]'
+match 0 x '[ab]' '[[::]ab]'
+match 1 x '[ab]' '[[:digit]ab]'
+match 1 x '[ab]' '[\[:]ab]'
+match 1 1 '?a?b' '\??\?b'
+match 1 1 'abc' '\a\b\c'
+match 0 0 'foo' ''
+match 1 0 'foo/bar/baz/to' '**/t[o]'
+
+# Character class tests
+match 1 x 'a1B' '[[:alpha:]][[:digit:]][[:upper:]]'
+match 0 x 'a' '[[:digit:][:upper:][:space:]]'
+match 1 x 'A' '[[:digit:][:upper:][:space:]]'
+match 1 x '1' '[[:digit:][:upper:][:space:]]'
+match 0 x '1' '[[:digit:][:upper:][:spaci:]]'
+match 1 x ' ' '[[:digit:][:upper:][:space:]]'
+match 0 x '.' '[[:digit:][:upper:][:space:]]'
+match 1 x '.' '[[:digit:][:punct:][:space:]]'
+match 1 x '5' '[[:xdigit:]]'
+match 1 x 'f' '[[:xdigit:]]'
+match 1 x 'D' '[[:xdigit:]]'
+match 1 x '_' '[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
+match 1 x '_' '[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
+match 1 x '.' '[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]'
+match 1 x '5' '[a-c[:digit:]x-z]'
+match 1 x 'b' '[a-c[:digit:]x-z]'
+match 1 x 'y' '[a-c[:digit:]x-z]'
+match 0 x 'q' '[a-c[:digit:]x-z]'
+
+# Additional tests, including some malformed wildmats
+match 1 x ']' '[\\-^]'
+match 0 0 '[' '[\\-^]'
+match 1 x '-' '[\-_]'
+match 1 x ']' '[\]]'
+match 0 0 '\]' '[\]]'
+match 0 0 '\' '[\]]'
+match 0 0 'ab' 'a[]b'
+match 0 x 'a[]b' 'a[]b'
+match 0 x 'ab[' 'ab['
+match 0 0 'ab' '[!'
+match 0 0 'ab' '[-'
+match 1 1 '-' '[-]'
+match 0 0 '-' '[a-'
+match 0 0 '-' '[!a-'
+match 1 x '-' '[--A]'
+match 1 x '5' '[--A]'
+match 1 1 ' ' '[ --]'
+match 1 1 '$' '[ --]'
+match 1 1 '-' '[ --]'
+match 0 0 '0' '[ --]'
+match 1 x '-' '[---]'
+match 1 x '-' '[------]'
+match 0 0 'j' '[a-e-n]'
+match 1 x '-' '[a-e-n]'
+match 1 x 'a' '[!------]'
+match 0 0 '[' '[]-a]'
+match 1 x '^' '[]-a]'
+match 0 0 '^' '[!]-a]'
+match 1 x '[' '[!]-a]'
+match 1 1 '^' '[a^bc]'
+match 1 x '-b]' '[a-]b]'
+match 0 0 '\' '[\]'
+match 1 1 '\' '[\\]'
+match 0 0 '\' '[!\\]'
+match 1 1 'G' '[A-\\]'
+match 0 0 'aaabbb' 'b*a'
+match 0 0 'aabcaa' '*ba*'
+match 1 1 ',' '[,]'
+match 1 1 ',' '[\\,]'
+match 1 1 '\' '[\\,]'
+match 1 1 '-' '[,-.]'
+match 0 0 '+' '[,-.]'
+match 0 0 '-.]' '[,-.]'
+match 1 1 '2' '[\1-\3]'
+match 1 1 '3' '[\1-\3]'
+match 0 0 '4' '[\1-\3]'
+match 1 1 '\' '[[-\]]'
+match 1 1 '[' '[[-\]]'
+match 1 1 ']' '[[-\]]'
+match 0 0 '-' '[[-\]]'
+
+# Test recursion and the abort code (use "wildtest -i" to see iteration counts)
+match 1 1 '-adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'
+match 0 0 '-adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'
+match 0 0 '-adobe-courier-bold-o-normal--12-120-75-75-/-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'
+match 1 1 'XXX/adobe/courier/bold/o/normal//12/120/75/75/m/70/iso8859/1' 'XXX/*/*/*/*/*/*/12/*/*/*/m/*/*/*'
+match 0 0 'XXX/adobe/courier/bold/o/normal//12/120/75/75/X/70/iso8859/1' 'XXX/*/*/*/*/*/*/12/*/*/*/m/*/*/*'
+match 1 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt' '**/*a*b*g*n*t'
+match 0 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txtz' '**/*a*b*g*n*t'
+
+test_done
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 9fe1d8feab..80e6be39d7 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -31,7 +31,7 @@ test_expect_success 'branch -h in broken repository' '
>.git/refs/heads/master &&
test_expect_code 129 git branch -h >usage 2>&1
) &&
- grep "[Uu]sage" broken/usage
+ test_i18ngrep "[Uu]sage" broken/usage
'
test_expect_success \
@@ -74,7 +74,7 @@ test_expect_success \
test_expect_success \
'git branch -m dumps usage' \
'test_expect_code 129 git branch -m 2>err &&
- grep "[Uu]sage: git branch" err'
+ test_i18ngrep "[Uu]sage: git branch" err'
test_expect_success \
'git branch -m m m/m should work' \
@@ -160,6 +160,83 @@ test_expect_success 'git branch --list -d t should fail' '
test_path_is_missing .git/refs/heads/t
'
+test_expect_success 'git branch --column' '
+ COLUMNS=81 git branch --column=column >actual &&
+ cat >expected <<\EOF &&
+ a/b/c bam foo l * master n o/p r
+ abc bar j/k m/m master2 o/o q
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'git branch --column with an extremely long branch name' '
+ long=this/is/a/part/of/long/branch/name &&
+ long=z$long/$long/$long/$long &&
+ test_when_finished "git branch -d $long" &&
+ git branch $long &&
+ COLUMNS=80 git branch --column=column >actual &&
+ cat >expected <<EOF &&
+ a/b/c
+ abc
+ bam
+ bar
+ foo
+ j/k
+ l
+ m/m
+* master
+ master2
+ n
+ o/o
+ o/p
+ q
+ r
+ $long
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'git branch with column.*' '
+ git config column.ui column &&
+ git config column.branch "dense" &&
+ COLUMNS=80 git branch >actual &&
+ git config --unset column.branch &&
+ git config --unset column.ui &&
+ cat >expected <<\EOF &&
+ a/b/c bam foo l * master n o/p r
+ abc bar j/k m/m master2 o/o q
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'git branch --column -v should fail' '
+ test_must_fail git branch --column -v
+'
+
+test_expect_success 'git branch -v with column.ui ignored' '
+ git config column.ui column &&
+ COLUMNS=80 git branch -v | cut -c -10 | sed "s/ *$//" >actual &&
+ git config --unset column.ui &&
+ cat >expected <<\EOF &&
+ a/b/c
+ abc
+ bam
+ bar
+ foo
+ j/k
+ l
+ m/m
+* master
+ master2
+ n
+ o/o
+ o/p
+ q
+ r
+EOF
+ test_cmp expected actual
+'
+
mv .git/config .git/config-saved
test_expect_success 'git branch -m q q2 without config should succeed' '
@@ -185,6 +262,25 @@ test_expect_success 'config information was renamed, too' \
"test $(git config branch.s.dummy) = Hello &&
test_must_fail git config branch.s/s/dummy"
+test_expect_success 'deleting a symref' '
+ git branch target &&
+ git symbolic-ref refs/heads/symref refs/heads/target &&
+ echo "Deleted branch symref (was refs/heads/target)." >expect &&
+ git branch -d symref >actual &&
+ test_path_is_file .git/refs/heads/target &&
+ test_path_is_missing .git/refs/heads/symref &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'deleting a dangling symref' '
+ git symbolic-ref refs/heads/dangling-symref nowhere &&
+ test_path_is_file .git/refs/heads/dangling-symref &&
+ echo "Deleted branch dangling-symref (was nowhere)." >expect &&
+ git branch -d dangling-symref >actual &&
+ test_path_is_missing .git/refs/heads/dangling-symref &&
+ test_i18ncmp expect actual
+'
+
test_expect_success 'renaming a symref is not allowed' \
'
git symbolic-ref refs/heads/master2 refs/heads/master &&
@@ -292,6 +388,76 @@ test_expect_success \
'git tag foobar &&
test_must_fail git branch --track my11 foobar'
+test_expect_success 'use --set-upstream-to modify HEAD' \
+ 'test_config branch.master.remote foo &&
+ test_config branch.master.merge foo &&
+ git branch my12
+ git branch --set-upstream-to my12 &&
+ test "$(git config branch.master.remote)" = "." &&
+ test "$(git config branch.master.merge)" = "refs/heads/my12"'
+
+test_expect_success 'use --set-upstream-to modify a particular branch' \
+ 'git branch my13
+ git branch --set-upstream-to master my13 &&
+ test "$(git config branch.my13.remote)" = "." &&
+ test "$(git config branch.my13.merge)" = "refs/heads/master"'
+
+test_expect_success '--unset-upstream should fail if given a non-existent branch' \
+ 'test_must_fail git branch --unset-upstream i-dont-exist'
+
+test_expect_success 'test --unset-upstream on HEAD' \
+ 'git branch my14
+ test_config branch.master.remote foo &&
+ test_config branch.master.merge foo &&
+ git branch --set-upstream-to my14 &&
+ git branch --unset-upstream &&
+ test_must_fail git config branch.master.remote &&
+ test_must_fail git config branch.master.merge &&
+ # fail for a branch without upstream set
+ test_must_fail git branch --unset-upstream
+'
+
+test_expect_success 'test --unset-upstream on a particular branch' \
+ 'git branch my15
+ git branch --set-upstream-to master my14 &&
+ git branch --unset-upstream my14 &&
+ test_must_fail git config branch.my14.remote &&
+ test_must_fail git config branch.my14.merge'
+
+test_expect_success '--set-upstream shows message when creating a new branch that exists as remote-tracking' \
+ 'git update-ref refs/remotes/origin/master HEAD &&
+ git branch --set-upstream origin/master 2>actual &&
+ test_when_finished git update-ref -d refs/remotes/origin/master &&
+ test_when_finished git branch -d origin/master &&
+ cat >expected <<EOF &&
+The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
+
+If you wanted to make '"'master'"' track '"'origin/master'"', do this:
+
+ git branch -d origin/master
+ git branch --set-upstream-to origin/master
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success '--set-upstream with two args only shows the deprecation message' \
+ 'git branch --set-upstream master my13 2>actual &&
+ test_when_finished git branch --unset-upstream master &&
+ cat >expected <<EOF &&
+The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success '--set-upstream with one arg only shows the deprecation message if the branch existed' \
+ 'git branch --set-upstream my13 2>actual &&
+ test_when_finished git branch --unset-upstream my13 &&
+ cat >expected <<EOF &&
+The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
+EOF
+ test_cmp expected actual
+'
+
# Keep this test last, as it changes the current branch
cat >expect <<EOF
$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh
index c53c9f65eb..7480d6e7c2 100755
--- a/t/t3300-funny-names.sh
+++ b/t/t3300-funny-names.sh
@@ -11,6 +11,16 @@ tree, index, and tree objects.
. ./test-lib.sh
+HT=' '
+
+echo 2>/dev/null > "Name with an${HT}HT"
+if ! test -f "Name with an${HT}HT"
+then
+ # since FAT/NTFS does not allow tabs in filenames, skip this test
+ skip_all='Your filesystem does not allow tabs in filenames'
+ test_done
+fi
+
p0='no-funny'
p1='tabs ," (dq) and spaces'
p2='just space'
@@ -23,21 +33,9 @@ test_expect_success 'setup' '
EOF
{ cat "$p0" >"$p1" || :; } &&
- { echo "Foo Bar Baz" >"$p2" || :; } &&
-
- if test -f "$p1" && cmp "$p0" "$p1"
- then
- test_set_prereq TABS_IN_FILENAMES
- fi
+ { echo "Foo Bar Baz" >"$p2" || :; }
'
-if ! test_have_prereq TABS_IN_FILENAMES
-then
- # since FAT/NTFS does not allow tabs in filenames, skip this test
- skip_all='Your filesystem does not allow tabs in filenames'
- test_done
-fi
-
test_expect_success 'setup: populate index and tree' '
git update-index --add "$p0" "$p2" &&
t0=$(git write-tree)
@@ -71,7 +69,7 @@ test_expect_success 'ls-files -z does not quote funny filename' '
tabs ," (dq) and spaces
EOF
git ls-files -z >ls-files.z &&
- perl -pe "y/\000/\012/" <ls-files.z >current &&
+ "$PERL_PATH" -pe "y/\000/\012/" <ls-files.z >current &&
test_cmp expected current
'
@@ -108,7 +106,7 @@ test_expect_success 'diff-index -z does not quote funny filename' '
tabs ," (dq) and spaces
EOF
git diff-index -z --name-status $t0 >diff-index.z &&
- perl -pe "y/\000/\012/" <diff-index.z >current &&
+ "$PERL_PATH" -pe "y/\000/\012/" <diff-index.z >current &&
test_cmp expected current
'
@@ -118,7 +116,7 @@ test_expect_success 'diff-tree -z does not quote funny filename' '
tabs ," (dq) and spaces
EOF
git diff-tree -z --name-status $t0 $t1 >diff-tree.z &&
- perl -pe y/\\000/\\012/ <diff-tree.z >current &&
+ "$PERL_PATH" -pe y/\\000/\\012/ <diff-tree.z >current &&
test_cmp expected current
'
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 7788ae02ad..1de0ebda25 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -68,24 +68,24 @@ test_expect_success 'rebase against master' '
test_expect_success 'rebase against master twice' '
git rebase master >out &&
- grep "Current branch my-topic-branch is up to date" out
+ test_i18ngrep "Current branch my-topic-branch is up to date" out
'
test_expect_success 'rebase against master twice with --force' '
git rebase --force-rebase master >out &&
- grep "Current branch my-topic-branch is up to date, rebase forced" out
+ test_i18ngrep "Current branch my-topic-branch is up to date, rebase forced" out
'
test_expect_success 'rebase against master twice from another branch' '
git checkout my-topic-branch^ &&
git rebase master my-topic-branch >out &&
- grep "Current branch my-topic-branch is up to date" out
+ test_i18ngrep "Current branch my-topic-branch is up to date" out
'
test_expect_success 'rebase fast-forward to master' '
git checkout my-topic-branch^ &&
git rebase my-topic-branch >out &&
- grep "Fast-forwarded HEAD to my-topic-branch" out
+ test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out
'
test_expect_success 'the rebase operation should not have destroyed author information' '
diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
index 7ba17974c5..58f4823783 100755
--- a/t/t3401-rebase-partial.sh
+++ b/t/t3401-rebase-partial.sh
@@ -42,4 +42,28 @@ test_expect_success 'rebase --merge topic branch that was partially merged upstr
test_path_is_missing .git/rebase-merge
'
+test_expect_success 'rebase ignores empty commit' '
+ git reset --hard A &&
+ git commit --allow-empty -m empty &&
+ test_commit D &&
+ git rebase C &&
+ test "$(git log --format=%s C..)" = "D"
+'
+
+test_expect_success 'rebase --keep-empty' '
+ git reset --hard D &&
+ git rebase --keep-empty C &&
+ test "$(git log --format=%s C..)" = "D
+empty"
+'
+
+test_expect_success 'rebase --keep-empty keeps empty even if already in upstream' '
+ git reset --hard A &&
+ git commit --allow-empty -m also-empty &&
+ git rebase --keep-empty D &&
+ test "$(git log --format=%s A..)" = "also-empty
+D
+empty"
+'
+
test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 7fd2127625..8462be1db6 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -29,12 +29,6 @@ Initial setup:
. "$TEST_DIRECTORY"/lib-rebase.sh
-test_cmp_rev () {
- git rev-parse --verify "$1" >expect.rev &&
- git rev-parse --verify "$2" >actual.rev &&
- test_cmp expect.rev actual.rev
-}
-
set_fake_editor
# WARNING: Modifications to the initial repository can change the SHA ID used
@@ -118,6 +112,17 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' '
git rebase --continue
'
+test_expect_success 'rebase -i with exec of inexistent command' '
+ git checkout master &&
+ test_when_finished "git rebase --abort" &&
+ (
+ FAKE_LINES="exec_this-command-does-not-exist 1" &&
+ export FAKE_LINES &&
+ test_must_fail git rebase -i HEAD^ >actual 2>&1
+ ) &&
+ ! grep "Maybe git-rebase is broken" actual
+'
+
test_expect_success 'no changes are a nop' '
git checkout branch2 &&
git rebase -i F &&
@@ -247,6 +252,7 @@ test_expect_success '-p handles "no changes" gracefully' '
'
test_expect_failure 'exchange two commits with -p' '
+ git checkout H &&
FAKE_LINES="2 1" git rebase -i -p HEAD~2 &&
test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test G = $(git cat-file commit HEAD | sed -ne \$p)
@@ -323,7 +329,7 @@ test_expect_success 'verbose flag is heeded, even after --continue' '
echo resolved > file1 &&
git add file1 &&
git rebase --continue > output &&
- grep "^ file1 | 2 +-$" output
+ grep "^ file1 | 2 +-$" output
'
test_expect_success 'multi-squash only fires up editor once' '
@@ -754,4 +760,178 @@ test_expect_success 'rebase-i history with funny messages' '
test_cmp expect actual
'
+
+test_expect_success 'prepare for rebase -i --exec' '
+ git checkout master &&
+ git checkout -b execute &&
+ test_commit one_exec main.txt one_exec &&
+ test_commit two_exec main.txt two_exec &&
+ test_commit three_exec main.txt three_exec
+'
+
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+ git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+ git reset --hard execute &&
+ git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+ git reset --hard execute &&
+ git rebase -ix "git show HEAD" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+ git reset --hard execute &&
+ git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+ git reset --hard execute &&
+ git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+ exec_git_show_HEAD exec_pwd" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,11d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with --autosquash' '
+ git reset --hard execute &&
+ git checkout -b autosquash &&
+ echo second >second.txt &&
+ git add second.txt &&
+ git commit -m "fixup! two_exec" &&
+ echo bis >bis.txt &&
+ git add bis.txt &&
+ git commit -m "fixup! two_exec" &&
+ (
+ git checkout -b autosquash_actual &&
+ git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
+ ) &&
+ git checkout autosquash &&
+ (
+ git checkout -b autosquash_expected &&
+ FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~4 >expect
+ ) &&
+ sed -e "1,13d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message' '
+ git reset --hard execute &&
+ test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
+ echo "The --exec option must be used with the --interactive option" >expected &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD>' '
+ git reset --hard execute &&
+ test_must_fail git rebase -i --exec 2>tmp &&
+ sed -e "1d" tmp >actual &&
+ test_must_fail git rebase -h >expected &&
+ test_cmp expected actual &&
+ git checkout master
+'
+
+test_expect_success 'rebase -i --root re-order and drop commits' '
+ git checkout E &&
+ FAKE_LINES="3 1 2 5" git rebase -i --root &&
+ test E = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test B = $(git cat-file commit HEAD^ | sed -ne \$p) &&
+ test A = $(git cat-file commit HEAD^^ | sed -ne \$p) &&
+ test C = $(git cat-file commit HEAD^^^ | sed -ne \$p) &&
+ test 0 = $(git cat-file commit HEAD^^^ | grep -c ^parent\ )
+'
+
+test_expect_success 'rebase -i --root retain root commit author and message' '
+ git checkout A &&
+ echo B >file7 &&
+ git add file7 &&
+ GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
+ FAKE_LINES="2" git rebase -i --root &&
+ git cat-file commit HEAD | grep -q "^author Twerp Snog" &&
+ git cat-file commit HEAD | grep -q "^different author$"
+'
+
+test_expect_success 'rebase -i --root temporary sentinel commit' '
+ git checkout B &&
+ (
+ FAKE_LINES="2" &&
+ export FAKE_LINES &&
+ test_must_fail git rebase -i --root
+ ) &&
+ git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
+ git rebase --abort
+'
+
+test_expect_success 'rebase -i --root fixup root commit' '
+ git checkout B &&
+ FAKE_LINES="1 fixup 2" git rebase -i --root &&
+ test A = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test B = $(git show HEAD:file1) &&
+ test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
+'
+
+test_expect_success 'rebase --edit-todo does not works on non-interactive rebase' '
+ git reset --hard &&
+ git checkout conflict-branch &&
+ test_must_fail git rebase --onto HEAD~2 HEAD~ &&
+ test_must_fail git rebase --edit-todo &&
+ git rebase --abort
+'
+
+test_expect_success 'rebase --edit-todo can be used to modify todo' '
+ git reset --hard &&
+ git checkout no-conflict-branch^0 &&
+ FAKE_LINES="edit 1 2 3" git rebase -i HEAD~3 &&
+ FAKE_LINES="2 1" git rebase --edit-todo &&
+ git rebase --continue
+ test M = $(git cat-file commit HEAD^ | sed -ne \$p) &&
+ test L = $(git cat-file commit HEAD | sed -ne \$p)
+'
+
test_done
diff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh
index e5ad67c643..19eddadcf7 100755
--- a/t/t3405-rebase-malformed.sh
+++ b/t/t3405-rebase-malformed.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='rebase should not insist on git message convention'
+test_description='rebase should handle arbitrary git message'
. ./test-lib.sh
@@ -12,6 +12,11 @@ It has two paragraphs, but its first paragraph is not friendly
to oneline summary format.
EOF
+cat >G <<\EOF
+commit log message containing a diff
+EOF
+
+
test_expect_success setup '
>file1 &&
@@ -19,8 +24,9 @@ test_expect_success setup '
git add file1 file2 &&
test_tick &&
git commit -m "Initial commit" &&
+ git branch diff-in-message
- git checkout -b side &&
+ git checkout -b multi-line-subject &&
cat F >file2 &&
git add file2 &&
test_tick &&
@@ -28,6 +34,17 @@ test_expect_success setup '
git cat-file commit HEAD | sed -e "1,/^\$/d" >F0 &&
+ git checkout diff-in-message &&
+ echo "commit log message containing a diff" >G &&
+ echo "" >>G
+ cat G >file2 &&
+ git add file2 &&
+ git diff --cached >>G &&
+ test_tick &&
+ git commit -F G &&
+
+ git cat-file commit HEAD | sed -e "1,/^\$/d" >G0 &&
+
git checkout master &&
echo One >file1 &&
@@ -36,13 +53,20 @@ test_expect_success setup '
git commit -m "Second commit"
'
-test_expect_success rebase '
+test_expect_success 'rebase commit with multi-line subject' '
- git rebase master side &&
+ git rebase master multi-line-subject &&
git cat-file commit HEAD | sed -e "1,/^\$/d" >F1 &&
test_cmp F0 F1 &&
test_cmp F F0
'
+test_expect_success 'rebase commit with diff in message' '
+ git rebase master diff-in-message &&
+ git cat-file commit HEAD | sed -e "1,/^$/d" >G1 &&
+ test_cmp G0 G1 &&
+ test_cmp G G0
+'
+
test_done
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index fe5f936988..e6a9a0d436 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -62,4 +62,16 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
! grep "^ fileX | *1 +$" diffstat.txt
'
+# Output to stderr:
+#
+# "Does not point to a valid commit: invalid-ref"
+#
+# NEEDSWORK: This "grep" is fine in real non-C locales, but
+# GETTEXT_POISON poisons the refname along with the enclosing
+# error message.
+test_expect_success 'rebase --onto outputs the invalid ref' '
+ test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
+ test_i18ngrep "invalid-ref" err
+'
+
test_done
diff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh
index ace8e54e9b..dc81bf27eb 100755
--- a/t/t3411-rebase-preserve-around-merges.sh
+++ b/t/t3411-rebase-preserve-around-merges.sh
@@ -56,6 +56,7 @@ test_expect_success 'squash F1 into D1' '
# And rebase G1..M1 onto E2
test_expect_success 'rebase two levels of merge' '
+ git checkout A1 &&
test_commit G1 &&
test_commit H1 &&
test_commit I1 &&
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 086c91c7b4..0b52105728 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -22,8 +22,9 @@ test_expect_success 'prepare repository' '
test_commit 4 B
'
-test_expect_success 'rebase --root expects --onto' '
- test_must_fail git rebase --root
+test_expect_success 'rebase --root fails with too many args' '
+ git checkout -B fail other &&
+ test_must_fail git rebase --onto master --root fail fail
'
test_expect_success 'setup pre-rebase hook' '
@@ -42,7 +43,7 @@ cat > expect <<EOF
EOF
test_expect_success 'rebase --root --onto <newbase>' '
- git checkout -b work &&
+ git checkout -b work other &&
git rebase --root --onto master &&
git log --pretty=tformat:"%s" > rebased &&
test_cmp expect rebased
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 595d2ff990..6f489e20ee 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -47,7 +47,7 @@ test_expect_success 'cherry-pick --nonsense' '
git diff --exit-code HEAD &&
test_must_fail git cherry-pick --nonsense 2>msg &&
git diff --exit-code HEAD "$pos" &&
- grep '[Uu]sage:' msg
+ test_i18ngrep '[Uu]sage:' msg
'
test_expect_success 'revert --nonsense' '
@@ -56,7 +56,7 @@ test_expect_success 'revert --nonsense' '
git diff --exit-code HEAD &&
test_must_fail git revert --nonsense 2>msg &&
git diff --exit-code HEAD "$pos" &&
- grep '[Uu]sage:' msg
+ test_i18ngrep '[Uu]sage:' msg
'
test_expect_success 'cherry-pick after renaming branch' '
@@ -100,4 +100,13 @@ test_expect_success 'revert forbidden on dirty working tree' '
'
+test_expect_success 'chery-pick on unborn branch' '
+ git checkout --orphan unborn &&
+ git rm --cached -r . &&
+ rm -rf * &&
+ git cherry-pick initial &&
+ git diff --quiet initial &&
+ ! test_cmp_rev initial HEAD
+'
+
test_done
diff --git a/t/t3505-cherry-pick-empty.sh b/t/t3505-cherry-pick-empty.sh
index 92f00cdf84..a0c6e30d80 100755
--- a/t/t3505-cherry-pick-empty.sh
+++ b/t/t3505-cherry-pick-empty.sh
@@ -53,6 +53,11 @@ test_expect_success 'index lockfile was removed' '
'
+test_expect_success 'cherry-pick a commit with an empty message with --allow-empty-message' '
+ git checkout -f master &&
+ git cherry-pick --allow-empty-message empty-branch
+'
+
test_expect_success 'cherry pick an empty non-ff commit without --allow-empty' '
git checkout master &&
echo fourth >>file2 &&
@@ -71,4 +76,34 @@ test_expect_success 'cherry pick with --keep-redundant-commits' '
git cherry-pick --keep-redundant-commits HEAD^
'
+test_expect_success 'cherry-pick a commit that becomes no-op (prep)' '
+ git checkout master &&
+ git branch fork &&
+ echo foo >file2 &&
+ git add file2 &&
+ test_tick &&
+ git commit -m "add file2 on master" &&
+
+ git checkout fork &&
+ echo foo >file2 &&
+ git add file2 &&
+ test_tick &&
+ git commit -m "add file2 on the side"
+'
+
+test_expect_success 'cherry-pick a no-op without --keep-redundant' '
+ git reset --hard &&
+ git checkout fork^0 &&
+ test_must_fail git cherry-pick master
+'
+
+test_expect_success 'cherry-pick a no-op with --keep-redundant' '
+ git reset --hard &&
+ git checkout fork^0 &&
+ git cherry-pick --keep-redundant-commits master &&
+ git show -s --format='%s' >actual &&
+ echo "add file2 on master" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index 51ca391e47..373aad623c 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -105,4 +105,12 @@ test_expect_success 'cherry pick a root commit with --ff' '
test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
'
+test_expect_success 'chery-pick --ff on unborn branch' '
+ git checkout --orphan unborn &&
+ git rm --cached -r . &&
+ rm -rf * &&
+ git cherry-pick --ff first &&
+ test_cmp_rev first HEAD
+'
+
test_done
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 0c81b3c427..223b98433c 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -11,12 +11,6 @@ test_description='test cherry-pick and revert with conflicts
. ./test-lib.sh
-test_cmp_rev () {
- git rev-parse --verify "$1" >expect.rev &&
- git rev-parse --verify "$2" >actual.rev &&
- test_cmp expect.rev actual.rev
-}
-
pristine_detach () {
git checkout -f "$1^0" &&
git read-tree -u --reset HEAD &&
@@ -30,6 +24,7 @@ test_expect_success setup '
test_commit initial foo a &&
test_commit base foo b &&
test_commit picked foo c &&
+ test_commit --signoff picked-signed foo d &&
git config advice.detachedhead false
'
@@ -340,4 +335,35 @@ test_expect_success 'revert conflict, diff3 -m style' '
test_cmp expected actual
'
+test_expect_success 'failed cherry-pick does not forget -s' '
+ pristine_detach initial &&
+ test_must_fail git cherry-pick -s picked &&
+ test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
+'
+
+test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
+ pristine_detach initial &&
+ test_must_fail git cherry-pick -s picked-signed &&
+ git commit -a -s &&
+ test $(git show -s |grep -c "Signed-off-by") = 1
+'
+
+test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
+ pristine_detach initial &&
+ test_must_fail git cherry-pick picked &&
+ git commit -a -s &&
+ pwd &&
+ cat <<EOF > expected &&
+picked
+
+Signed-off-by: C O Mitter <committer@example.com>
+
+Conflicts:
+ foo
+EOF
+
+ git show -s --pretty=format:%B > actual &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index 75f7ff4f2f..4e7136b837 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -5,15 +5,11 @@ test_description='test cherry-picking many commits'
. ./test-lib.sh
check_head_differs_from() {
- head=$(git rev-parse --verify HEAD) &&
- arg=$(git rev-parse --verify "$1") &&
- test "$head" != "$arg"
+ ! test_cmp_rev HEAD "$1"
}
check_head_equals() {
- head=$(git rev-parse --verify HEAD) &&
- arg=$(git rev-parse --verify "$1") &&
- test "$head" = "$arg"
+ test_cmp_rev HEAD "$1"
}
test_expect_success setup '
@@ -44,6 +40,21 @@ test_expect_success 'cherry-pick first..fourth works' '
check_head_differs_from fourth
'
+test_expect_success 'cherry-pick three one two works' '
+ git checkout -f first &&
+ test_commit one &&
+ test_commit two &&
+ test_commit three &&
+ git checkout -f master &&
+ git reset --hard first &&
+ git cherry-pick three one two &&
+ git diff --quiet three &&
+ git diff --quiet HEAD three &&
+ test "$(git log --reverse --format=%s first..)" = "three
+one
+two"
+'
+
test_expect_success 'output to keep user entertained during multi-pick' '
cat <<-\EOF >expected &&
[master OBJID] second
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index 97f3710700..7b7a89dbd5 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -24,14 +24,8 @@ pristine_detach () {
git clean -d -f -f -q -x
}
-test_cmp_rev () {
- git rev-parse --verify "$1" >expect.rev &&
- git rev-parse --verify "$2" >actual.rev &&
- test_cmp expect.rev actual.rev
-}
-
test_expect_success setup '
- git config advice.detachedhead false
+ git config advice.detachedhead false &&
echo unrelated >unrelated &&
git add unrelated &&
test_commit initial foo a &&
@@ -410,7 +404,7 @@ test_expect_success '--continue respects -x in first commit in multi-pick' '
grep "cherry picked from.*$picked" msg
'
-test_expect_success '--signoff is not automatically propagated to resolved conflict' '
+test_expect_failure '--signoff is automatically propagated to resolved conflict' '
pristine_detach initial &&
test_expect_code 1 git cherry-pick --signoff base..anotherpick &&
echo "c" >foo &&
@@ -428,7 +422,7 @@ test_expect_success '--signoff is not automatically propagated to resolved confl
grep "Signed-off-by:" anotherpick_msg
'
-test_expect_success '--signoff dropped for implicit commit of resolution, multi-pick case' '
+test_expect_failure '--signoff dropped for implicit commit of resolution, multi-pick case' '
pristine_detach initial &&
test_must_fail git cherry-pick -s picked anotherpick &&
echo c >foo &&
@@ -441,7 +435,7 @@ test_expect_success '--signoff dropped for implicit commit of resolution, multi-
! grep Signed-off-by: msg
'
-test_expect_success 'sign-off needs to be reaffirmed after conflict resolution, single-pick case' '
+test_expect_failure 'sign-off needs to be reaffirmed after conflict resolution, single-pick case' '
pristine_detach initial &&
test_must_fail git cherry-pick -s picked &&
echo c >foo &&
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 9fd28bcf34..37bf5f13b0 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -262,4 +262,364 @@ test_expect_success 'rm removes subdirectories recursively' '
! test -d dir
'
+cat >expect <<EOF
+D submod
+EOF
+
+cat >expect.modified <<EOF
+ M submod
+EOF
+
+test_expect_success 'rm removes empty submodules from work tree' '
+ mkdir submod &&
+ git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) submod &&
+ git config -f .gitmodules submodule.sub.url ./. &&
+ git config -f .gitmodules submodule.sub.path submod &&
+ git submodule init &&
+ git add .gitmodules &&
+ git commit -m "add submodule" &&
+ git rm submod &&
+ test ! -e submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm removes removed submodule from index' '
+ git reset --hard &&
+ git submodule update &&
+ rm -rf submod &&
+ git rm submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm removes work tree of unmodified submodules' '
+ git reset --hard &&
+ git submodule update &&
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm removes a submodule with a trailing /' '
+ git reset --hard &&
+ git submodule update &&
+ git rm submod/ &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm fails when given a file with a trailing /' '
+ test_must_fail git rm empty/
+'
+
+test_expect_success 'rm succeeds when given a directory with a trailing /' '
+ git rm -r frotz/
+'
+
+test_expect_success 'rm of a populated submodule with different HEAD fails unless forced' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ git checkout HEAD^
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with modifications fails unless forced' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >empty
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with untracked files fails unless forced' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >untracked
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'setup submodule conflict' '
+ git reset --hard &&
+ git submodule update &&
+ git checkout -b branch1 &&
+ echo 1 >nitfol &&
+ git add nitfol &&
+ git commit -m "added nitfol 1" &&
+ git checkout -b branch2 master &&
+ echo 2 >nitfol &&
+ git add nitfol &&
+ git commit -m "added nitfol 2" &&
+ git checkout -b conflict1 master &&
+ (cd submod &&
+ git fetch &&
+ git checkout branch1
+ ) &&
+ git add submod &&
+ git commit -m "submod 1" &&
+ git checkout -b conflict2 master &&
+ (cd submod &&
+ git checkout branch2
+ ) &&
+ git add submod &&
+ git commit -m "submod 2"
+'
+
+cat >expect.conflict <<EOF
+UU submod
+EOF
+
+test_expect_success 'rm removes work tree of unmodified conflicted submodule' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ test_must_fail git merge conflict2 &&
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with different HEAD fails unless forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ git checkout HEAD^
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with modifications fails unless forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >empty
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with untracked files fails unless forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >untracked
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with a .git directory fails even when forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ rm .git &&
+ cp -R ../.git/modules/sub .git &&
+ GIT_WORK_TREE=. git config --unset core.worktree
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ test_must_fail git rm -f submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git merge --abort &&
+ rm -rf submod
+'
+
+test_expect_success 'rm of a conflicted unpopulated submodule succeeds' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ test_must_fail git merge conflict2 &&
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with a .git directory fails even when forced' '
+ git checkout -f master &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ rm .git &&
+ cp -R ../.git/modules/sub .git &&
+ GIT_WORK_TREE=. git config --unset core.worktree
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ test_must_fail git rm -f submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ rm -rf submod
+'
+
+cat >expect.deepmodified <<EOF
+ M submod/subsubmod
+EOF
+
+test_expect_success 'setup subsubmodule' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) subsubmod &&
+ git config -f .gitmodules submodule.sub.url ../. &&
+ git config -f .gitmodules submodule.sub.path subsubmod &&
+ git submodule init &&
+ git add .gitmodules &&
+ git commit -m "add subsubmodule" &&
+ git submodule update subsubmod
+ ) &&
+ git commit -a -m "added deep submodule"
+'
+
+test_expect_success 'rm recursively removes work tree of unmodified submodules' '
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with different nested HEAD fails unless forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ git checkout HEAD^
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with nested modifications fails unless forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ echo X >empty
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with nested untracked files fails unless forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ echo X >untracked
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with a nested .git directory fails even when forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ rm .git &&
+ cp -R ../../.git/modules/sub/modules/sub .git &&
+ GIT_WORK_TREE=. git config --unset core.worktree
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -d submod/subsubmod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ test_must_fail git rm -f submod &&
+ test -d submod &&
+ test -d submod/subsubmod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ rm -rf submod
+'
+
test_done
diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh
index 534ee08a44..892f567844 100755
--- a/t/t3902-quoted.sh
+++ b/t/t3902-quoted.sh
@@ -16,9 +16,8 @@ echo foo 2>/dev/null > "Name and an${HT}HT"
if ! test -f "Name and an${HT}HT"
then
# FAT/NTFS does not allow tabs in filenames
- say 'Your filesystem does not allow tabs in filenames'
-else
- test_set_prereq TABS_IN_FILENAMES
+ skip_all='Your filesystem does not allow tabs in filenames'
+ test_done
fi
for_each_name () {
@@ -31,7 +30,7 @@ for_each_name () {
done
}
-test_expect_success TABS_IN_FILENAMES 'setup' '
+test_expect_success 'setup' '
mkdir "$FN" &&
for_each_name "echo initial >\"\$name\"" &&
@@ -45,7 +44,7 @@ test_expect_success TABS_IN_FILENAMES 'setup' '
'
-test_expect_success TABS_IN_FILENAMES 'setup expected files' '
+test_expect_success 'setup expected files' '
cat >expect.quoted <<\EOF &&
Name
"Name and a\nLF"
@@ -75,74 +74,74 @@ With SP in it
EOF
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-files' '
+test_expect_success 'check fully quoted output from ls-files' '
git ls-files >current && test_cmp expect.quoted current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-files' '
+test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
test_cmp expect.quoted current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-index' '
+test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
test_cmp expect.quoted current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-tree' '
+test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
test_cmp expect.quoted current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-tree' '
+test_expect_success 'check fully quoted output from ls-tree' '
git ls-tree --name-only -r HEAD >current &&
test_cmp expect.quoted current
'
-test_expect_success TABS_IN_FILENAMES 'setting core.quotepath' '
+test_expect_success 'setting core.quotepath' '
git config --bool core.quotepath false
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-files' '
+test_expect_success 'check fully quoted output from ls-files' '
git ls-files >current && test_cmp expect.raw current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-files' '
+test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
test_cmp expect.raw current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-index' '
+test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
test_cmp expect.raw current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from diff-tree' '
+test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
test_cmp expect.raw current
'
-test_expect_success TABS_IN_FILENAMES 'check fully quoted output from ls-tree' '
+test_expect_success 'check fully quoted output from ls-tree' '
git ls-tree --name-only -r HEAD >current &&
test_cmp expect.raw current
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 3addb804d5..5dfbda7491 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -443,7 +443,7 @@ test_expect_success 'stash show format defaults to --stat' '
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
- file | 1 +
+ file | 1 +
1 file changed, 1 insertion(+)
EOF
git stash show ${STASH_ID} >actual &&
@@ -610,7 +610,7 @@ test_expect_success 'stash apply shows status same as git status (relative to cu
git stash apply
) |
sed -e 1,2d >actual && # drop "Saved..." and "HEAD is now..."
- test_cmp expect actual
+ test_i18ncmp expect actual
'
cat > expect << EOF
diff --git a/t/t3910-mac-os-precompose.sh b/t/t3910-mac-os-precompose.sh
new file mode 100755
index 0000000000..5fe57c5438
--- /dev/null
+++ b/t/t3910-mac-os-precompose.sh
@@ -0,0 +1,153 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Torsten Bögershausen
+#
+
+test_description='utf-8 decomposed (nfd) converted to precomposed (nfc)'
+
+. ./test-lib.sh
+
+if ! test_have_prereq UTF8_NFD_TO_NFC
+then
+ skip_all="filesystem does not corrupt utf-8"
+ test_done
+fi
+
+# create utf-8 variables
+Adiarnfc=`printf '\303\204'`
+Adiarnfd=`printf 'A\314\210'`
+
+Odiarnfc=`printf '\303\226'`
+Odiarnfd=`printf 'O\314\210'`
+AEligatu=`printf '\303\206'`
+Invalidu=`printf '\303\377'`
+
+
+#Create a string with 255 bytes (decomposed)
+Alongd=$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd #21 Byte
+Alongd=$Alongd$Alongd$Alongd #63 Byte
+Alongd=$Alongd$Alongd$Alongd$Alongd$Adiarnfd #255 Byte
+
+#Create a string with 254 bytes (precomposed)
+Alongc=$AEligatu$AEligatu$AEligatu$AEligatu$AEligatu #10 Byte
+Alongc=$Alongc$Alongc$Alongc$Alongc$Alongc #50 Byte
+Alongc=$Alongc$Alongc$Alongc$Alongc$Alongc #250 Byte
+Alongc=$Alongc$AEligatu$AEligatu #254 Byte
+
+test_expect_success "detect if nfd needed" '
+ precomposeunicode=`git config core.precomposeunicode` &&
+ test "$precomposeunicode" = false &&
+ git config core.precomposeunicode true
+'
+test_expect_success "setup" '
+ >x &&
+ git add x &&
+ git commit -m "1st commit" &&
+ git rm x &&
+ git commit -m "rm x"
+'
+test_expect_success "setup case mac" '
+ git checkout -b mac_os
+'
+# This will test nfd2nfc in readdir()
+test_expect_success "add file Adiarnfc" '
+ echo f.Adiarnfc >f.$Adiarnfc &&
+ git add f.$Adiarnfc &&
+ git commit -m "add f.$Adiarnfc"
+'
+# This will test nfd2nfc in git stage()
+test_expect_success "stage file d.Adiarnfd/f.Adiarnfd" '
+ mkdir d.$Adiarnfd &&
+ echo d.$Adiarnfd/f.$Adiarnfd >d.$Adiarnfd/f.$Adiarnfd &&
+ git stage d.$Adiarnfd/f.$Adiarnfd &&
+ git commit -m "add d.$Adiarnfd/f.$Adiarnfd"
+'
+test_expect_success "add link Adiarnfc" '
+ ln -s d.$Adiarnfd/f.$Adiarnfd l.$Adiarnfc &&
+ git add l.$Adiarnfc &&
+ git commit -m "add l.Adiarnfc"
+'
+# This will test git log
+test_expect_success "git log f.Adiar" '
+ git log f.$Adiarnfc > f.Adiarnfc.log &&
+ git log f.$Adiarnfd > f.Adiarnfd.log &&
+ test -s f.Adiarnfc.log &&
+ test -s f.Adiarnfd.log &&
+ test_cmp f.Adiarnfc.log f.Adiarnfd.log &&
+ rm f.Adiarnfc.log f.Adiarnfd.log
+'
+# This will test git ls-files
+test_expect_success "git lsfiles f.Adiar" '
+ git ls-files f.$Adiarnfc > f.Adiarnfc.log &&
+ git ls-files f.$Adiarnfd > f.Adiarnfd.log &&
+ test -s f.Adiarnfc.log &&
+ test -s f.Adiarnfd.log &&
+ test_cmp f.Adiarnfc.log f.Adiarnfd.log &&
+ rm f.Adiarnfc.log f.Adiarnfd.log
+'
+# This will test git mv
+test_expect_success "git mv" '
+ git mv f.$Adiarnfd f.$Odiarnfc &&
+ git mv d.$Adiarnfd d.$Odiarnfc &&
+ git mv l.$Adiarnfd l.$Odiarnfc &&
+ git commit -m "mv Adiarnfd Odiarnfc"
+'
+# Files can be checked out as nfc
+# And the link has been corrected from nfd to nfc
+test_expect_success "git checkout nfc" '
+ rm f.$Odiarnfc &&
+ git checkout f.$Odiarnfc
+'
+# Make it possible to checkout files with their NFD names
+test_expect_success "git checkout file nfd" '
+ rm -f f.* &&
+ git checkout f.$Odiarnfd
+'
+# Make it possible to checkout links with their NFD names
+test_expect_success "git checkout link nfd" '
+ rm l.* &&
+ git checkout l.$Odiarnfd
+'
+test_expect_success "setup case mac2" '
+ git checkout master &&
+ git reset --hard &&
+ git checkout -b mac_os_2
+'
+# This will test nfd2nfc in git commit
+test_expect_success "commit file d2.Adiarnfd/f.Adiarnfd" '
+ mkdir d2.$Adiarnfd &&
+ echo d2.$Adiarnfd/f.$Adiarnfd >d2.$Adiarnfd/f.$Adiarnfd &&
+ git add d2.$Adiarnfd/f.$Adiarnfd &&
+ git commit -m "add d2.$Adiarnfd/f.$Adiarnfd" -- d2.$Adiarnfd/f.$Adiarnfd
+'
+test_expect_success "setup for long decomposed filename" '
+ git checkout master &&
+ git reset --hard &&
+ git checkout -b mac_os_long_nfd_fn
+'
+test_expect_success "Add long decomposed filename" '
+ echo longd >$Alongd &&
+ git add * &&
+ git commit -m "Long filename"
+'
+test_expect_success "setup for long precomposed filename" '
+ git checkout master &&
+ git reset --hard &&
+ git checkout -b mac_os_long_nfc_fn
+'
+test_expect_success "Add long precomposed filename" '
+ echo longc >$Alongc &&
+ git add * &&
+ git commit -m "Long filename"
+'
+# Test if the global core.precomposeunicode stops autosensing
+# Must be the last test case
+test_expect_success "respect git config --global core.precomposeunicode" '
+ git config --global core.precomposeunicode true &&
+ rm -rf .git &&
+ git init &&
+ precomposeunicode=`git config core.precomposeunicode` &&
+ test "$precomposeunicode" = "true"
+'
+
+test_done
diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh
index ff8c2f7532..05911492ca 100755
--- a/t/t4006-diff-mode.sh
+++ b/t/t4006-diff-mode.sh
@@ -8,23 +8,52 @@ test_description='Test mode change diffs.
'
. ./test-lib.sh
-test_expect_success \
- 'setup' \
- 'echo frotz >rezrov &&
- git update-index --add rezrov &&
- tree=`git write-tree` &&
- echo $tree'
-
-test_expect_success \
- 'chmod' \
- 'test_chmod +x rezrov &&
- git diff-index $tree >current'
-
-sed -e 's/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /' <current >check
-echo ":100644 100755 X X M rezrov" >expected
-
-test_expect_success \
- 'verify' \
- 'test_cmp expected check'
+sed_script='s/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /'
+
+test_expect_success 'setup' '
+ echo frotz >rezrov &&
+ git update-index --add rezrov &&
+ tree=`git write-tree` &&
+ echo $tree
+'
+
+test_expect_success 'chmod' '
+ test_chmod +x rezrov &&
+ git diff-index $tree >current &&
+ sed -e "$sed_script" <current >check &&
+ echo ":100644 100755 X X M rezrov" >expected &&
+ test_cmp expected check
+'
+
+test_expect_success 'prepare binary file' '
+ git commit -m rezrov &&
+ printf "\00\01\02\03\04\05\06" >binbin &&
+ git add binbin &&
+ git commit -m binbin
+'
+
+# test_expect_success '--stat output after text chmod' '
+# test_chmod -x rezrov &&
+# echo " 0 files changed" >expect &&
+# git diff HEAD --stat >actual &&
+# test_i18ncmp expect actual
+# '
+#
+# test_expect_success '--shortstat output after text chmod' '
+# git diff HEAD --shortstat >actual &&
+# test_i18ncmp expect actual
+# '
+#
+# test_expect_success '--stat output after binary chmod' '
+# test_chmod +x binbin &&
+# echo " 0 files changed" >expect &&
+# git diff HEAD --stat >actual &&
+# test_i18ncmp expect actual
+# '
+#
+# test_expect_success '--shortstat output after binary chmod' '
+# git diff HEAD --shortstat >actual &&
+# test_i18ncmp expect actual
+# '
test_done
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index ed24ddd88a..1215ae544b 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -15,13 +15,14 @@ cat >expect.binary-numstat <<\EOF
- - d
EOF
-test_expect_success 'prepare repository' \
- 'echo AIT >a && echo BIT >b && echo CIT >c && echo DIT >d &&
- git update-index --add a b c d &&
- echo git >a &&
- cat "$TEST_DIRECTORY"/test-binary-1.png >b &&
- echo git >c &&
- cat b b >d'
+test_expect_success 'prepare repository' '
+ echo AIT >a && echo BIT >b && echo CIT >c && echo DIT >d &&
+ git update-index --add a b c d &&
+ echo git >a &&
+ cat "$TEST_DIRECTORY"/test-binary-1.png >b &&
+ echo git >c &&
+ cat b b >d
+'
cat > expected <<\EOF
a | 2 +-
@@ -30,12 +31,24 @@ cat > expected <<\EOF
d | Bin
4 files changed, 2 insertions(+), 2 deletions(-)
EOF
-test_expect_success '"apply --stat" output for binary file change' '
+test_expect_success 'apply --stat output for binary file change' '
git diff >diff &&
git apply --stat --summary <diff >current &&
test_i18ncmp expected current
'
+test_expect_success 'diff --shortstat output for binary file change' '
+ tail -n 1 expected >expect &&
+ git diff --shortstat >current &&
+ test_i18ncmp expect current
+'
+
+test_expect_success 'diff --shortstat output for binary file change only' '
+ echo " 1 file changed, 0 insertions(+), 0 deletions(-)" >expected &&
+ git diff --shortstat -- b >current &&
+ test_i18ncmp expected current
+'
+
test_expect_success 'apply --numstat notices binary file change' '
git diff >diff &&
git apply --numstat <diff >current &&
@@ -50,49 +63,42 @@ test_expect_success 'apply --numstat understands diff --binary format' '
# apply needs to be able to skip the binary material correctly
# in order to report the line number of a corrupt patch.
-test_expect_success 'apply detecting corrupt patch correctly' \
- 'git diff | sed -e 's/-CIT/xCIT/' >broken &&
- if git apply --stat --summary broken 2>detected
- then
- echo unhappy - should have detected an error
- (exit 1)
- else
- echo happy
- fi &&
- detected=`cat detected` &&
- detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
- detected=`sed -ne "${detected}p" broken` &&
- test "$detected" = xCIT'
-
-test_expect_success 'apply detecting corrupt patch correctly' \
- 'git diff --binary | sed -e 's/-CIT/xCIT/' >broken &&
- if git apply --stat --summary broken 2>detected
- then
- echo unhappy - should have detected an error
- (exit 1)
- else
- echo happy
- fi &&
- detected=`cat detected` &&
- detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
- detected=`sed -ne "${detected}p" broken` &&
- test "$detected" = xCIT'
+test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
+ git diff >output &&
+ sed -e "s/-CIT/xCIT/" <output >broken &&
+ test_must_fail git apply --stat --summary broken 2>detected &&
+ detected=`cat detected` &&
+ detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
+ detected=`sed -ne "${detected}p" broken` &&
+ test "$detected" = xCIT
+'
+
+test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
+ git diff --binary | sed -e "s/-CIT/xCIT/" >broken &&
+ test_must_fail git apply --stat --summary broken 2>detected &&
+ detected=`cat detected` &&
+ detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
+ detected=`sed -ne "${detected}p" broken` &&
+ test "$detected" = xCIT
+'
test_expect_success 'initial commit' 'git commit -a -m initial'
# Try removal (b), modification (d), and creation (e).
-test_expect_success 'diff-index with --binary' \
- 'echo AIT >a && mv b e && echo CIT >c && cat e >d &&
- git update-index --add --remove a b c d e &&
- tree0=`git write-tree` &&
- git diff --cached --binary >current &&
- git apply --stat --summary current'
-
-test_expect_success 'apply binary patch' \
- 'git reset --hard &&
- git apply --binary --index <current &&
- tree1=`git write-tree` &&
- test "$tree1" = "$tree0"'
+test_expect_success 'diff-index with --binary' '
+ echo AIT >a && mv b e && echo CIT >c && cat e >d &&
+ git update-index --add --remove a b c d e &&
+ tree0=`git write-tree` &&
+ git diff --cached --binary >current &&
+ git apply --stat --summary current
+'
+
+test_expect_success 'apply binary patch' '
+ git reset --hard &&
+ git apply --binary --index <current &&
+ tree1=`git write-tree` &&
+ test "$tree1" = "$tree0"
+'
test_expect_success 'diff --no-index with binary creation' '
echo Q | q_to_nul >binary &&
@@ -107,4 +113,23 @@ test_expect_success 'diff --no-index with binary creation' '
test_cmp expected actual
'
+cat >expect <<EOF
+ binfile | Bin 0 -> 1026 bytes
+ textfile | 10000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
+
+test_expect_success 'diff --stat with binary files and big change count' '
+ printf "\01\00%1024d" 1 >binfile &&
+ git add binfile &&
+ i=0 &&
+ while test $i -lt 10000; do
+ echo $i &&
+ i=$(($i + 1))
+ done >textfile &&
+ git add textfile &&
+ git diff --cached --stat binfile textfile >output &&
+ grep " | " output >actual &&
+ test_cmp expect actual
+'
+
test_done
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 2f8560c369..9951e3677d 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
@@ -1,7 +1,7 @@
$ git diff-tree --cc --patch-with-stat --summary master
59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
2 files changed, 5 insertions(+)
diff --cc dir/sub
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 72e03c14fb..cec33fa3f0 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
@@ -1,8 +1,8 @@
$ git diff-tree --cc --patch-with-stat --summary side
c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
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 8b357d964b..db3c0a7b2c 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
@@ -1,7 +1,7 @@
$ git diff-tree --cc --patch-with-stat master
59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
2 files changed, 5 insertions(+)
diff --cc dir/sub
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
index e0568d6883..d019867dd9 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
@@ -1,6 +1,6 @@
$ git diff-tree --cc --stat --summary master
59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
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 5afc8239a1..12b2eee17e 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
@@ -1,8 +1,8 @@
$ git diff-tree --cc --stat --summary side
c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 f48367a89a..40b91796b3 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_master
@@ -1,6 +1,6 @@
$ git diff-tree --cc --stat master
59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
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 590864c2d7..817ed06f82 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
@@ -1,8 +1,8 @@
$ git diff-tree --pretty=oneline --root --patch-with-stat initial
444ac553ac7612cc88969031b02b3767fb8a353a Initial
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
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 e05e77875c..fe3f6b7c7e 100644
--- a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
+++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
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 0e2c956633..06eb77e386 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
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
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 384fa44ddd..680eab5f27 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
index 10384a83d3..9722d1b3a7 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
@@ -5,8 +5,8 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
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 f57062ea07..ad69ffe647 100644
--- a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
@@ -1,8 +1,8 @@
$ git diff-tree --root --patch-with-stat initial
444ac553ac7612cc88969031b02b3767fb8a353a
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_master b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
index 7088683444..81c3021541 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
@@ -1,6 +1,6 @@
$ git diff-tree -c --stat --summary master
59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
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 ef216abb1d..e8dc12bfbf 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
@@ -1,8 +1,8 @@
$ git diff-tree -c --stat --summary side
c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 ad19f103eb..89d59b1548 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_master
@@ -1,6 +1,6 @@
$ git diff-tree -c --stat master
59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
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 ddad917ae8..be8d1ea1bd 100644
--- a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
@@ -1,7 +1,7 @@
$ git diff --patch-with-stat -r initial..side
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff_--patch-with-stat_initial..side b/t/t4013/diff.diff_--patch-with-stat_initial..side
index bdbd114d8e..5424e6d566 100644
--- a/t/t4013/diff.diff_--patch-with-stat_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_initial..side
@@ -1,7 +1,7 @@
$ git diff --patch-with-stat initial..side
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff_--stat_initial..side b/t/t4013/diff.diff_--stat_initial..side
index 6d08f3d355..b7741e2b83 100644
--- a/t/t4013/diff.diff_--stat_initial..side
+++ b/t/t4013/diff.diff_--stat_initial..side
@@ -1,6 +1,6 @@
$ git diff --stat initial..side
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 2ddb2540e6..5d514f55b9 100644
--- a/t/t4013/diff.diff_-r_--stat_initial..side
+++ b/t/t4013/diff.diff_-r_--stat_initial..side
@@ -1,6 +1,6 @@
$ git diff -r --stat initial..side
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 3cab049f7d..547ca065a5 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
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 564a4d38f2..52fedc179e 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 4f28460b83..1c3cde251b 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
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 b10cc2e251..4717bd8313 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 a976a8aaf4..02c4db7ec5 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
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 b4fd66477a..c7677c5951 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
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 0d31036e7f..5b3e34e2c0 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 18d4714423..d13f8a8128 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
index 29e00ab8af..caec5537de 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..side b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
index 3572f20b5d..d3a6762130 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 54cdcdab40..244d964fc6 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^
@@ -10,10 +10,10 @@ A U Thor (2):
Second
Third
- dir/sub | 4 ++++
- file0 | 3 +++
- file1 | 3 +++
- file2 | 3 ---
+ dir/sub | 4 ++++
+ file0 | 3 +++
+ file1 | 3 +++
+ file2 | 3 ---
4 files changed, 10 insertions(+), 3 deletions(-)
create mode 100644 file1
delete mode 100644 file2
@@ -28,9 +28,9 @@ Subject: [DIFFERENT_PREFIX 1/2] Second
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -73,8 +73,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
Subject: [DIFFERENT_PREFIX 2/2] Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
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 23194ebdaa..bfc287a147 100644
--- a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH] Second
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
Subject: [PATCH] Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
Subject: [PATCH] Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
index 78f1a80a97..568f6f584e 100644
--- a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH 1/3] Second
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
Subject: [PATCH 2/3] Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
Subject: [PATCH 3/3] Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master b/t/t4013/diff.format-patch_--stdout_initial..master
index a3dab7f773..5f0352f9f7 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH 1/3] Second
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
Subject: [PATCH 2/3] Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
Subject: [PATCH 3/3] Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master^ b/t/t4013/diff.format-patch_--stdout_initial..master^
index 39f4a3f2d1..2ae454d807 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_initial..master^
@@ -6,9 +6,9 @@ Subject: [PATCH 1/2] Second
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
Subject: [PATCH 2/2] Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
diff --git a/t/t4013/diff.format-patch_--stdout_initial..side b/t/t4013/diff.format-patch_--stdout_initial..side
index 88109209db..a7d52fbeea 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--stdout_initial..side
@@ -5,9 +5,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
Subject: [PATCH] Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
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 4085bbde87..a18f1472a9 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -12,7 +12,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -31,7 +31,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -53,7 +53,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index 458627953e..ae425c4672 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -12,9 +12,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -54,8 +54,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -86,9 +86,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index 6e172cfadd..d5207cadf4 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -12,7 +12,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -31,7 +31,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -53,7 +53,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
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 48b0d4b91d..0fc1e8cd71 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
@@ -6,8 +6,8 @@ Date: Mon Jun 26 00:04:00 2006 +0000
Merge branch 'side'
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
2 files changed, 5 insertions(+)
diff --cc dir/sub
@@ -44,9 +44,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
@@ -87,8 +87,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -120,9 +120,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -162,9 +162,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
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 f9dc5122e2..dffc09dde9 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -12,9 +12,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
@@ -55,8 +55,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -88,9 +88,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -130,9 +130,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 0807ece234..55aa98012d 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -12,9 +12,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -54,8 +54,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -86,9 +86,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dir/sub b/dir/sub
@@ -127,9 +127,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
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 84f5ef6911..019d85f7de 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
@@ -6,8 +6,8 @@ Date: Mon Jun 26 00:04:00 2006 +0000
Merge branch 'side'
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
2 files changed, 5 insertions(+)
diff --combined dir/sub
@@ -44,9 +44,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
@@ -87,8 +87,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -120,9 +120,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -162,9 +162,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
diff --git a/t/t4013/diff.show_--patch-with-stat_--summary_side b/t/t4013/diff.show_--patch-with-stat_--summary_side
index e60384d24d..95a474ef1d 100644
--- a/t/t4013/diff.show_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.show_--patch-with-stat_--summary_side
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
diff --git a/t/t4013/diff.show_--patch-with-stat_side b/t/t4013/diff.show_--patch-with-stat_side
index a3a3255fd3..974e99be82 100644
--- a/t/t4013/diff.show_--patch-with-stat_side
+++ b/t/t4013/diff.show_--patch-with-stat_side
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.show_--stat_--summary_side b/t/t4013/diff.show_--stat_--summary_side
index d16f464aca..a71492f9bf 100644
--- a/t/t4013/diff.show_--stat_--summary_side
+++ b/t/t4013/diff.show_--stat_--summary_side
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 6300c0535f..9be712458f 100644
--- a/t/t4013/diff.show_--stat_side
+++ b/t/t4013/diff.show_--stat_side
@@ -5,8 +5,8 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
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 16ae54345f..c8b6af2f43 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -24,7 +24,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -46,7 +46,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master b/t/t4013/diff.whatchanged_--patch-with-stat_master
index f3e45ec270..1ac431ba92 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -47,8 +47,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -79,9 +79,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
index c77f0bc320..b30c28588f 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -24,7 +24,7 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -46,7 +46,7 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
+ dir/sub | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dir/sub b/dir/sub
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 8d03efea6c..30aae7817b 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
@@ -6,8 +6,8 @@ Date: Mon Jun 26 00:04:00 2006 +0000
Merge branch 'side'
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
2 files changed, 5 insertions(+)
diff --cc dir/sub
@@ -44,9 +44,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
@@ -87,8 +87,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -120,9 +120,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -162,9 +162,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
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 1874d0616c..db90e51525 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
@@ -48,8 +48,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -81,9 +81,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -123,9 +123,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
index 5211ff2a75..9a6cc92ce7 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
@@ -5,9 +5,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -47,8 +47,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
diff --git a/dir/sub b/dir/sub
@@ -79,9 +79,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dir/sub b/dir/sub
@@ -120,9 +120,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
diff --git a/dir/sub b/dir/sub
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 ad30245a59..d1d32bd34c 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
@@ -6,8 +6,8 @@ Date: Mon Jun 26 00:04:00 2006 +0000
Merge branch 'side'
- dir/sub | 2 ++
- file0 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
2 files changed, 5 insertions(+)
diff --combined dir/sub
@@ -44,9 +44,9 @@ Date: Mon Jun 26 00:03:00 2006 +0000
Side
---
- dir/sub | 2 ++
- file0 | 3 +++
- file3 | 4 ++++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
3 files changed, 9 insertions(+)
create mode 100644 file3
@@ -87,8 +87,8 @@ Date: Mon Jun 26 00:02:00 2006 +0000
Third
---
- dir/sub | 2 ++
- file1 | 3 +++
+ dir/sub | 2 ++
+ file1 | 3 +++
2 files changed, 5 insertions(+)
create mode 100644 file1
@@ -120,9 +120,9 @@ Date: Mon Jun 26 00:01:00 2006 +0000
This is the second commit.
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 ---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
3 files changed, 5 insertions(+), 3 deletions(-)
delete mode 100644 file2
@@ -162,9 +162,9 @@ Date: Mon Jun 26 00:00:00 2006 +0000
Initial
---
- dir/sub | 2 ++
- file0 | 3 +++
- file2 | 3 +++
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 +++
3 files changed, 8 insertions(+)
create mode 100644 dir/sub
create mode 100644 file0
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index b473b6d6eb..7fa3647514 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -110,73 +110,107 @@ test_expect_success 'replay did not screw up the log message' '
test_expect_success 'extra headers' '
- git config format.headers "To: R. E. Cipient <rcipient@example.com>
+ git config format.headers "To: R E Cipient <rcipient@example.com>
" &&
- git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>
+ git config --add format.headers "Cc: S E Cipient <scipient@example.com>
" &&
git format-patch --stdout master..side > patch2 &&
sed -e "/^\$/q" patch2 > hdrs2 &&
- grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs2 &&
- grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs2
+ grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
+ grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
'
test_expect_success 'extra headers without newlines' '
- git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
- git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" &&
+ git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
+ git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
git format-patch --stdout master..side >patch3 &&
sed -e "/^\$/q" patch3 > hdrs3 &&
- grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs3 &&
- grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs3
+ grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
+ grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
'
test_expect_success 'extra headers with multiple To:s' '
- git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
- git config --add format.headers "To: S. E. Cipient <scipient@example.com>" &&
+ git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
+ git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
git format-patch --stdout master..side > patch4 &&
sed -e "/^\$/q" patch4 > hdrs4 &&
- grep "^To: R. E. Cipient <rcipient@example.com>,\$" hdrs4 &&
- grep "^ *S. E. Cipient <scipient@example.com>\$" hdrs4
+ grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
+ grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
'
-test_expect_success 'additional command line cc' '
+test_expect_success 'additional command line cc (ascii)' '
- git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
+ git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
+ git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
+ grep "^ *S E Cipient <scipient@example.com>\$" patch5
+'
+
+test_expect_failure 'additional command line cc (rfc822)' '
+
+ git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
- grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch5 &&
- grep "^ *S. E. Cipient <scipient@example.com>\$" patch5
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
+ grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
'
test_expect_success 'command line headers' '
git config --unset-all format.headers &&
- git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
- grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6
+ git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
'
test_expect_success 'configuration headers and command line headers' '
- git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
- git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
- grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 &&
- grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
+ git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
+ git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
+ grep "^ *S E Cipient <scipient@example.com>\$" patch7
'
-test_expect_success 'command line To: header' '
+test_expect_success 'command line To: header (ascii)' '
git config --unset-all format.headers &&
+ git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
+ grep "^To: R E Cipient <rcipient@example.com>\$" patch8
+'
+
+test_expect_failure 'command line To: header (rfc822)' '
+
git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
+'
+
+test_expect_failure 'command line To: header (rfc2047)' '
+
+ git format-patch --to="R Ă„ Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
+ grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
+'
+
+test_expect_success 'configuration To: header (ascii)' '
+
+ git config format.to "R E Cipient <rcipient@example.com>" &&
+ git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
+ grep "^To: R E Cipient <rcipient@example.com>\$" patch9
'
-test_expect_success 'configuration To: header' '
+test_expect_failure 'configuration To: header (rfc822)' '
git config format.to "R. E. Cipient <rcipient@example.com>" &&
git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
+'
+
+test_expect_failure 'configuration To: header (rfc2047)' '
+
+ git config format.to "R Ă„ Cipient <rcipient@example.com>" &&
+ git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
+ grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
'
# check_patch <patch>: Verify that <patch> looks like a half-sane
@@ -190,11 +224,11 @@ check_patch () {
test_expect_success '--no-to overrides config.to' '
git config --replace-all format.to \
- "R. E. Cipient <rcipient@example.com>" &&
+ "R E Cipient <rcipient@example.com>" &&
git format-patch --no-to --stdout master..side |
sed -e "/^\$/q" >patch10 &&
check_patch patch10 &&
- ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
+ ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
'
test_expect_success '--no-to and --to replaces config.to' '
@@ -212,21 +246,21 @@ test_expect_success '--no-to and --to replaces config.to' '
test_expect_success '--no-cc overrides config.cc' '
git config --replace-all format.cc \
- "C. E. Cipient <rcipient@example.com>" &&
+ "C E Cipient <rcipient@example.com>" &&
git format-patch --no-cc --stdout master..side |
sed -e "/^\$/q" >patch12 &&
check_patch patch12 &&
- ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
+ ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
'
test_expect_success '--no-add-header overrides config.headers' '
git config --replace-all format.headers \
- "Header1: B. E. Cipient <rcipient@example.com>" &&
+ "Header1: B E Cipient <rcipient@example.com>" &&
git format-patch --no-add-header --stdout master..side |
sed -e "/^\$/q" >patch13 &&
check_patch patch13 &&
- ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
+ ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
'
test_expect_success 'multiple files' '
@@ -237,13 +271,29 @@ test_expect_success 'multiple files' '
ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
'
+test_expect_success 'reroll count' '
+ rm -fr patches &&
+ git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
+ ! grep -v "^patches/v4-000[0-3]-" list &&
+ sed -n -e "/^Subject: /p" $(cat list) >subjects &&
+ ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
+'
+
+test_expect_success 'reroll count (-v)' '
+ rm -fr patches &&
+ git format-patch -o patches --cover-letter -v4 master..side >list &&
+ ! grep -v "^patches/v4-000[0-3]-" list &&
+ sed -n -e "/^Subject: /p" $(cat list) >subjects &&
+ ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
+'
+
check_threading () {
expect="$1" &&
shift &&
(git format-patch --stdout "$@"; echo $? > status.out) |
# Prints everything between the Message-ID and In-Reply-To,
# and replaces all Message-ID-lookalikes by a sequence number
- perl -ne '
+ "$PERL_PATH" -ne '
if (/^(message-id|references|in-reply-to)/i) {
$printing = 1;
} elsif (/^\S/) {
@@ -616,8 +666,19 @@ test_expect_success 'format-patch --in-reply-to' '
'
test_expect_success 'format-patch --signoff' '
- git format-patch -1 --signoff --stdout |
- grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+ git format-patch -1 --signoff --stdout >out &&
+ grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
+'
+
+test_expect_success 'format-patch --notes --signoff' '
+ git notes --ref test add -m "test message" HEAD &&
+ git format-patch -1 --signoff --stdout --notes=test >out &&
+ # Three dashes must come after S-o-b
+ ! sed "/^Signed-off-by: /q" out | grep "test message" &&
+ sed "1,/^Signed-off-by: /d" out | grep "test message" &&
+ # Notes message must come after three dashes
+ ! sed "/^---$/q" out | grep "test message" &&
+ sed "1,/^---$/d" out | grep "test message"
'
echo "fatal: --name-only does not make sense" > expect.name-only
@@ -752,16 +813,14 @@ M64=$M8$M8$M8$M8$M8$M8$M8$M8
M512=$M64$M64$M64$M64$M64$M64$M64$M64
cat >expect <<'EOF'
Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
- bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
- foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
- bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
- foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
- bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
- foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
- bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
- foo bar foo bar foo bar foo bar
+ bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
+ foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
+ bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
+ foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
+ bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
+ foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
EOF
-test_expect_success 'format-patch wraps extremely long headers (ascii)' '
+test_expect_success 'format-patch wraps extremely long subject (ascii)' '
echo content >>file &&
git add file &&
git commit -m "$M512" &&
@@ -774,30 +833,31 @@ M8="föö bar "
M64=$M8$M8$M8$M8$M8$M8$M8$M8
M512=$M64$M64$M64$M64$M64$M64$M64$M64
cat >expect <<'EOF'
-Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
+ =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
+ =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
+ =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
+ =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
+ =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
+ =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
+ =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
+ =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
+ =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
EOF
-test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
+test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
rm -rf patches/ &&
echo content >>file &&
git add file &&
@@ -807,52 +867,80 @@ test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
test_cmp expect subject
'
-M8="foo_bar_"
-M64=$M8$M8$M8$M8$M8$M8$M8$M8
-cat >expect <<EOF
-From: $M64
- <foobar@foo.bar>
-EOF
-test_expect_success 'format-patch wraps non-quotable headers' '
- rm -rf patches/ &&
- echo content >>file &&
- git add file &&
- git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
- git format-patch --stdout -1 >patch &&
- sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
- test_cmp expect from
-'
-
check_author() {
echo content >>file &&
git add file &&
GIT_AUTHOR_NAME=$1 git commit -m author-check &&
git format-patch --stdout -1 >patch &&
- grep ^From: patch >actual &&
+ sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
test_cmp expect actual
}
cat >expect <<'EOF'
From: "Foo B. Bar" <author@example.com>
EOF
-test_expect_success 'format-patch quotes dot in headers' '
+test_expect_success 'format-patch quotes dot in from-headers' '
check_author "Foo B. Bar"
'
cat >expect <<'EOF'
From: "Foo \"The Baz\" Bar" <author@example.com>
EOF
-test_expect_success 'format-patch quotes double-quote in headers' '
+test_expect_success 'format-patch quotes double-quote in from-headers' '
check_author "Foo \"The Baz\" Bar"
'
cat >expect <<'EOF'
-From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
+From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
EOF
-test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
+test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
+ check_author "Föo Bar"
+'
+
+cat >expect <<'EOF'
+From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
+EOF
+test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
check_author "Föo B. Bar"
'
+cat >expect <<EOF
+From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
+ <author@example.com>
+EOF
+test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
+ check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
+'
+
+cat >expect <<'EOF'
+From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
+ Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
+ Bar Foo Bar Foo Bar Foo Bar <author@example.com>
+EOF
+test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
+ check_author "Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
+'
+
+cat >expect <<'EOF'
+From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
+ Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
+ Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
+EOF
+test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
+ check_author "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
+'
+
+cat >expect <<'EOF'
+From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
+ =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
+ =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
+ =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
+ =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
+EOF
+test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
+ check_author "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
+'
+
cat >expect <<'EOF'
Subject: header with . in it
EOF
@@ -891,4 +979,46 @@ test_expect_success 'format patch ignores color.ui' '
test_cmp expect actual
'
+test_expect_success 'cover letter using branch description (1)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (2)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (3)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (4)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter master.. >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (5)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter -2 HEAD >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (6)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter -2 >actual &&
+ grep hello actual >/dev/null
+'
+
test_done
diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh
index 3ec71184ba..cd543ecc54 100755
--- a/t/t4016-diff-quote.sh
+++ b/t/t4016-diff-quote.sh
@@ -13,14 +13,12 @@ P1='pathname with HT'
P2='pathname with SP'
P3='pathname
with LF'
-if : 2>/dev/null >"$P1" && test -f "$P1" && rm -f "$P1"
-then
- test_set_prereq TABS_IN_FILENAMES
-else
- say 'Your filesystem does not allow tabs in filenames'
-fi
+echo 2>/dev/null >"$P1" && test -f "$P1" && rm -f "$P1" || {
+ skip_all='Your filesystem does not allow tabs in filenames'
+ test_done
+}
-test_expect_success TABS_IN_FILENAMES setup '
+test_expect_success setup '
echo P0.0 >"$P0.0" &&
echo P0.1 >"$P0.1" &&
echo P0.2 >"$P0.2" &&
@@ -40,7 +38,7 @@ test_expect_success TABS_IN_FILENAMES setup '
:
'
-test_expect_success TABS_IN_FILENAMES 'setup expected files' '
+test_expect_success 'setup expected files' '
cat >expect <<\EOF
rename pathname.1 => "Rpathname\twith HT.0" (100%)
rename pathname.3 => "Rpathname\nwith LF.0" (100%)
@@ -52,12 +50,12 @@ cat >expect <<\EOF
EOF
'
-test_expect_success TABS_IN_FILENAMES 'git diff --summary -M HEAD' '
+test_expect_success 'git diff --summary -M HEAD' '
git diff --summary -M HEAD >actual &&
test_cmp expect actual
'
-test_expect_success TABS_IN_FILENAMES 'git diff --numstat -M HEAD' '
+test_expect_success 'git diff --numstat -M HEAD' '
cat >expect <<-\EOF &&
0 0 pathname.1 => "Rpathname\twith HT.0"
0 0 pathname.3 => "Rpathname\nwith LF.0"
@@ -71,15 +69,15 @@ test_expect_success TABS_IN_FILENAMES 'git diff --numstat -M HEAD' '
test_cmp expect actual
'
-test_expect_success TABS_IN_FILENAMES 'git diff --stat -M HEAD' '
+test_expect_success 'git diff --stat -M HEAD' '
cat >expect <<-\EOF &&
- pathname.1 => "Rpathname\twith HT.0" | 0
- pathname.3 => "Rpathname\nwith LF.0" | 0
- "pathname\twith HT.3" => "Rpathname\nwith LF.1" | 0
- pathname.2 => Rpathname with SP.0 | 0
- "pathname\twith HT.2" => Rpathname with SP.1 | 0
- pathname.0 => Rpathname.0 | 0
- "pathname\twith HT.0" => Rpathname.1 | 0
+ pathname.1 => "Rpathname\twith HT.0" | 0
+ pathname.3 => "Rpathname\nwith LF.0" | 0
+ "pathname\twith HT.3" => "Rpathname\nwith LF.1" | 0
+ pathname.2 => Rpathname with SP.0 | 0
+ "pathname\twith HT.2" => Rpathname with SP.1 | 0
+ pathname.0 => Rpathname.0 | 0
+ "pathname\twith HT.0" => Rpathname.1 | 0
7 files changed, 0 insertions(+), 0 deletions(-)
EOF
git diff --stat -M HEAD >actual &&
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index 4bd2a1c838..082d3e83bd 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -105,7 +105,7 @@ test_expect_funcname () {
grep "^@@.*@@ $1" diff
}
-for p in bibtex cpp csharp fortran html java matlab objc pascal perl php python ruby tex
+for p in ada bibtex cpp csharp fortran html java matlab objc pascal perl php python ruby tex
do
test_expect_success "builtin $p pattern compiles" '
echo "*.java diff=$p" >.gitattributes &&
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index 083f62d1d6..2e7d73f090 100755
--- a/t/t4020-diff-external.sh
+++ b/t/t4020-diff-external.sh
@@ -48,7 +48,53 @@ test_expect_success 'GIT_EXTERNAL_DIFF environment and --no-ext-diff' '
'
+test_expect_success SYMLINKS 'typechange diff' '
+ rm -f file &&
+ ln -s elif file &&
+ GIT_EXTERNAL_DIFF=echo git diff | {
+ read path oldfile oldhex oldmode newfile newhex newmode &&
+ test "z$path" = zfile &&
+ test "z$oldmode" = z100644 &&
+ test "z$newhex" = "z$_z40" &&
+ test "z$newmode" = z120000 &&
+ oh=$(git rev-parse --verify HEAD:file) &&
+ test "z$oh" = "z$oldhex"
+ } &&
+ GIT_EXTERNAL_DIFF=echo git diff --no-ext-diff >actual &&
+ git diff >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'diff.external' '
+ git reset --hard &&
+ echo third >file &&
+ test_config diff.external echo &&
+ git diff | {
+ read path oldfile oldhex oldmode newfile newhex newmode &&
+ test "z$path" = zfile &&
+ test "z$oldmode" = z100644 &&
+ test "z$newhex" = "z$_z40" &&
+ test "z$newmode" = z100644 &&
+ oh=$(git rev-parse --verify HEAD:file) &&
+ test "z$oh" = "z$oldhex"
+ }
+'
+
+test_expect_success 'diff.external should apply only to diff' '
+ test_config diff.external echo &&
+ git log -p -1 HEAD |
+ grep "^diff --git a/file b/file"
+'
+
+test_expect_success 'diff.external and --no-ext-diff' '
+ test_config diff.external echo &&
+ git diff --no-ext-diff |
+ grep "^diff --git a/file b/file"
+'
+
test_expect_success 'diff attribute' '
+ git reset --hard &&
+ echo third >file &&
git config diff.parrot.command echo &&
@@ -113,12 +159,25 @@ test_expect_success 'diff attribute and --no-ext-diff' '
'
+test_expect_success 'GIT_EXTERNAL_DIFF trumps diff.external' '
+ >.gitattributes &&
+ test_config diff.external "echo ext-global" &&
+ GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-env
+'
+
+test_expect_success 'attributes trump GIT_EXTERNAL_DIFF and diff.external' '
+ test_config diff.foo.command "echo ext-attribute" &&
+ test_config diff.external "echo ext-global" &&
+ echo "file diff=foo" >.gitattributes &&
+ GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-attribute
+'
+
test_expect_success 'no diff with -diff' '
echo >.gitattributes "file -diff" &&
git diff | grep Binary
'
-echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file
+echo NULZbetweenZwords | "$PERL_PATH" -pe 'y/Z/\000/' > file
test_expect_success 'force diff with "diff"' '
echo >.gitattributes "file diff" &&
diff --git a/t/t4022-diff-rewrite.sh b/t/t4022-diff-rewrite.sh
index c00a94b9ba..2d030a4ec3 100755
--- a/t/t4022-diff-rewrite.sh
+++ b/t/t4022-diff-rewrite.sh
@@ -66,5 +66,35 @@ test_expect_success 'suppress deletion diff with -B -D' '
grep -v "Linus Torvalds" actual
'
+test_expect_success 'prepare a file that ends with an incomplete line' '
+ test_seq 1 99 >seq &&
+ printf 100 >>seq &&
+ git add seq &&
+ git commit seq -m seq
+'
+
+test_expect_success 'rewrite the middle 90% of sequence file and terminate with newline' '
+ test_seq 1 5 >seq &&
+ test_seq 9331 9420 >>seq &&
+ test_seq 96 100 >>seq
+'
+
+test_expect_success 'confirm that sequence file is considered a rewrite' '
+ git diff -B seq >res &&
+ grep "dissimilarity index" res
+'
+
+test_expect_success 'no newline at eof is on its own line without -B' '
+ git diff seq >res &&
+ grep "^\\\\ " res &&
+ ! grep "^..*\\\\ " res
+'
+
+test_expect_success 'no newline at eof is on its own line with -B' '
+ git diff -B seq >res &&
+ grep "^\\\\ " res &&
+ ! grep "^..*\\\\ " res
+'
+
test_done
diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh
index 3ccc237a8d..36e2f075c9 100755
--- a/t/t4029-diff-trailing-space.sh
+++ b/t/t4029-diff-trailing-space.sh
@@ -27,7 +27,7 @@ test_expect_success \
git config --bool diff.suppressBlankEmpty true &&
git diff f > actual &&
test_cmp exp actual &&
- perl -i.bak -p -e "s/^\$/ /" exp &&
+ "$PERL_PATH" -i.bak -p -e "s/^\$/ /" exp &&
git config --bool diff.suppressBlankEmpty false &&
git diff f > actual &&
test_cmp exp actual &&
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index 06b05df848..53ec330ce8 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -21,7 +21,7 @@ EOF
cat >hexdump <<'EOF'
#!/bin/sh
-perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
+"$PERL_PATH" -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
EOF
chmod +x hexdump
@@ -84,8 +84,32 @@ test_expect_success 'status -v produces text' '
git reset --soft HEAD@{1}
'
+test_expect_success 'grep-diff (-G) operates on textconv data (add)' '
+ echo one >expect &&
+ git log --root --format=%s -G0 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep-diff (-G) operates on textconv data (modification)' '
+ echo two >expect &&
+ git log --root --format=%s -G1 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'pickaxe (-S) operates on textconv data (add)' '
+ echo one >expect &&
+ git log --root --format=%s -S0 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'pickaxe (-S) operates on textconv data (modification)' '
+ echo two >expect &&
+ git log --root --format=%s -S1 >actual &&
+ test_cmp expect actual
+'
+
cat >expect.stat <<'EOF'
- file | Bin 2 -> 4 bytes
+ file | Bin 2 -> 4 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
EOF
test_expect_success 'diffstat does not run textconv' '
diff --git a/t/t4031-diff-rewrite-binary.sh b/t/t4031-diff-rewrite-binary.sh
index c8296fa4fc..eacc6694f7 100755
--- a/t/t4031-diff-rewrite-binary.sh
+++ b/t/t4031-diff-rewrite-binary.sh
@@ -60,7 +60,7 @@ test_expect_success 'diff --stat counts binary rewrite as 0 lines' '
{
echo "#!$SHELL_PATH"
cat <<'EOF'
-perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
+"$PERL_PATH" -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
EOF
} >dump
chmod +x dump
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
index 30d42cb3bf..40ab333a8a 100755
--- a/t/t4034-diff-words.sh
+++ b/t/t4034-diff-words.sh
@@ -298,6 +298,7 @@ test_expect_success 'unset default driver' '
test_unconfig diff.wordregex
'
+test_language_driver ada
test_language_driver bibtex
test_language_driver cpp
test_language_driver csharp
diff --git a/t/t4034/ada/expect b/t/t4034/ada/expect
new file mode 100644
index 0000000000..be2376e904
--- /dev/null
+++ b/t/t4034/ada/expect
@@ -0,0 +1,27 @@
+<BOLD>diff --git a/pre b/post<RESET>
+<BOLD>index d96fdd1..df21bb0 100644<RESET>
+<BOLD>--- a/pre<RESET>
+<BOLD>+++ b/post<RESET>
+<CYAN>@@ -1,13 +1,13 @@<RESET>
+Ada.Text_IO.Put_Line("Hello World<RED>!<RESET><GREEN>?<RESET>");
+1 1e<RED>-<RESET>10 16#FE12#E2 3.141_592 '<RED>x<RESET><GREEN>y<RESET>'
+<RED>a<RESET><GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET>**<RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET>(<RED>b<RESET><GREEN>y<RESET>)
+<RED>a<RESET><GREEN>x<RESET>:=<RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>/= <RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET>,<RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET>=><RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET>..<RED>b<RESET>
+<RED>a<RESET><GREEN>y<RESET>
+<GREEN>x<RESET><><RED>b<RESET><GREEN>y<RESET>
diff --git a/t/t4034/ada/post b/t/t4034/ada/post
new file mode 100644
index 0000000000..df21bb044f
--- /dev/null
+++ b/t/t4034/ada/post
@@ -0,0 +1,13 @@
+Ada.Text_IO.Put_Line("Hello World?");
+1 1e10 16#FE12#E2 3.141_592 'y'
+x+y x-y
+x*y x/y
+x**y
+x(y)
+x:=y
+x=y x/= y
+x<y x<=y x>y x>=y
+x,y
+x=>y
+x..y
+x<>y
diff --git a/t/t4034/ada/pre b/t/t4034/ada/pre
new file mode 100644
index 0000000000..d96fdd1e8e
--- /dev/null
+++ b/t/t4034/ada/pre
@@ -0,0 +1,13 @@
+Ada.Text_IO.Put_Line("Hello World!");
+1 1e-10 16#FE12#E2 3.141_592 'x'
+a+b a-b
+a*b a/b
+a**b
+a(b)
+a:=b
+a=b a/= b
+a<b a<=b a>b a>=b
+a,b
+a=>b
+a..b
+a<>b
diff --git a/t/t4035-diff-quiet.sh b/t/t4035-diff-quiet.sh
index cdb9202f57..231412d100 100755
--- a/t/t4035-diff-quiet.sh
+++ b/t/t4035-diff-quiet.sh
@@ -10,7 +10,22 @@ test_expect_success 'setup' '
git commit -m first &&
echo 2 >b &&
git add . &&
- git commit -a -m second
+ git commit -a -m second &&
+ mkdir -p test-outside/repo && (
+ cd test-outside/repo &&
+ git init &&
+ echo "1 1" >a &&
+ git add . &&
+ git commit -m 1
+ ) &&
+ mkdir -p test-outside/non/git && (
+ cd test-outside/non/git &&
+ echo "1 1" >a &&
+ echo "1 1" >matching-file &&
+ echo "1 1 " >trailing-space &&
+ echo "1 1" >extra-space &&
+ echo "2" >never-match
+ )
'
test_expect_success 'git diff-tree HEAD^ HEAD' '
@@ -77,4 +92,60 @@ test_expect_success 'git diff-index --cached HEAD' '
}
'
+test_expect_success 'git diff, one file outside repo' '
+ (
+ cd test-outside/repo &&
+ test_expect_code 0 git diff --quiet a ../non/git/matching-file &&
+ test_expect_code 1 git diff --quiet a ../non/git/extra-space
+ )
+'
+
+test_expect_success 'git diff, both files outside repo' '
+ (
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd test-outside/non/git &&
+ test_expect_code 0 git diff --quiet a matching-file &&
+ test_expect_code 1 git diff --quiet a extra-space
+ )
+'
+
+test_expect_success 'git diff --ignore-space-at-eol, one file outside repo' '
+ (
+ cd test-outside/repo &&
+ test_expect_code 0 git diff --quiet --ignore-space-at-eol a ../non/git/trailing-space &&
+ test_expect_code 1 git diff --quiet --ignore-space-at-eol a ../non/git/extra-space
+ )
+'
+
+test_expect_success 'git diff --ignore-space-at-eol, both files outside repo' '
+ (
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd test-outside/non/git &&
+ test_expect_code 0 git diff --quiet --ignore-space-at-eol a trailing-space &&
+ test_expect_code 1 git diff --quiet --ignore-space-at-eol a extra-space
+ )
+'
+
+test_expect_success 'git diff --ignore-all-space, one file outside repo' '
+ (
+ cd test-outside/repo &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a ../non/git/trailing-space &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a ../non/git/extra-space &&
+ test_expect_code 1 git diff --quiet --ignore-all-space a ../non/git/never-match
+ )
+'
+
+test_expect_success 'git diff --ignore-all-space, both files outside repo' '
+ (
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd test-outside/non/git &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a trailing-space &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a extra-space &&
+ test_expect_code 1 git diff --quiet --ignore-all-space a never-match
+ )
+'
+
test_done
diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh
index bf9a7526bd..32d4a60425 100755
--- a/t/t4041-diff-submodule-option.sh
+++ b/t/t4041-diff-submodule-option.sh
@@ -11,18 +11,18 @@ This test tries to verify the sanity of the --submodule option of git diff.
. ./test-lib.sh
add_file () {
- sm=$1
- shift
- owd=$(pwd)
- cd "$sm"
- for name; do
- echo "$name" > "$name" &&
- git add "$name" &&
- test_tick &&
- git commit -m "Add $name"
- done >/dev/null
- git rev-parse --verify HEAD | cut -c1-7
- cd "$owd"
+ (
+ cd "$1" &&
+ shift &&
+ for name
+ do
+ echo "$name" >"$name" &&
+ git add "$name" &&
+ test_tick &&
+ git commit -m "Add $name" || exit
+ done >/dev/null &&
+ git rev-parse --short --verify HEAD
+ )
}
commit_file () {
test_tick &&
@@ -33,92 +33,133 @@ test_create_repo sm1 &&
add_file . foo >/dev/null
head1=$(add_file sm1 foo1 foo2)
+fullhead1=$(cd sm1; git rev-parse --verify HEAD)
-test_expect_success 'added submodule' "
+test_expect_success 'added submodule' '
git add sm1 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 0000000...$head1 (new submodule)
-EOF
+ Submodule sm1 0000000...$head1 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
+
+test_expect_success 'added submodule, set diff.submodule' '
+ git config diff.submodule log &&
+ git add sm1 &&
+ git diff --cached >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 0000000...$head1 (new submodule)
+ EOF
+ git config --unset diff.submodule &&
+ test_cmp expected actual
+'
+
+test_expect_success '--submodule=short overrides diff.submodule' '
+ test_config diff.submodule log &&
+ git add sm1 &&
+ git diff --submodule=short --cached >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ new file mode 160000
+ index 0000000..$head1
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead1
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'diff.submodule does not affect plumbing' '
+ test_config diff.submodule log &&
+ git diff-index -p HEAD >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ new file mode 160000
+ index 0000000..$head1
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead1
+ EOF
+ test_cmp expected actual
+'
commit_file sm1 &&
head2=$(add_file sm1 foo3)
-test_expect_success 'modified submodule(forward)' "
+test_expect_success 'modified submodule(forward)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head1..$head2:
- > Add foo3
-EOF
+ Submodule sm1 $head1..$head2:
+ > Add foo3
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule(forward)' "
+test_expect_success 'modified submodule(forward)' '
git diff --submodule=log >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head1..$head2:
- > Add foo3
-EOF
+ Submodule sm1 $head1..$head2:
+ > Add foo3
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule(forward) --submodule' "
+test_expect_success 'modified submodule(forward) --submodule' '
git diff --submodule >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head1..$head2:
- > Add foo3
-EOF
+ Submodule sm1 $head1..$head2:
+ > Add foo3
+ EOF
test_cmp expected actual
-"
+'
-fullhead1=$(cd sm1; git rev-list --max-count=1 $head1)
-fullhead2=$(cd sm1; git rev-list --max-count=1 $head2)
-test_expect_success 'modified submodule(forward) --submodule=short' "
+fullhead2=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'modified submodule(forward) --submodule=short' '
git diff --submodule=short >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-index $head1..$head2 160000
---- a/sm1
-+++ b/sm1
-@@ -1 +1 @@
--Subproject commit $fullhead1
-+Subproject commit $fullhead2
-EOF
+ diff --git a/sm1 b/sm1
+ index $head1..$head2 160000
+ --- a/sm1
+ +++ b/sm1
+ @@ -1 +1 @@
+ -Subproject commit $fullhead1
+ +Subproject commit $fullhead2
+ EOF
test_cmp expected actual
-"
+'
commit_file sm1 &&
head3=$(
cd sm1 &&
git reset --hard HEAD~2 >/dev/null &&
- git rev-parse --verify HEAD | cut -c1-7
+ git rev-parse --short --verify HEAD
)
-test_expect_success 'modified submodule(backward)' "
+test_expect_success 'modified submodule(backward)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head2..$head3 (rewind):
- < Add foo3
- < Add foo2
-EOF
+ Submodule sm1 $head2..$head3 (rewind):
+ < Add foo3
+ < Add foo2
+ EOF
test_cmp expected actual
-"
+'
-head4=$(add_file sm1 foo4 foo5) &&
-head4_full=$(GIT_DIR=sm1/.git git rev-parse --verify HEAD)
-test_expect_success 'modified submodule(backward and forward)' "
+head4=$(add_file sm1 foo4 foo5)
+test_expect_success 'modified submodule(backward and forward)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head2...$head4:
- > Add foo5
- > Add foo4
- < Add foo3
- < Add foo2
-EOF
+ Submodule sm1 $head2...$head4:
+ > Add foo5
+ > Add foo4
+ < Add foo3
+ < Add foo2
+ EOF
test_cmp expected actual
-"
+'
commit_file sm1 &&
mv sm1 sm1-bak &&
@@ -128,319 +169,319 @@ git add sm1 &&
rm -f sm1 &&
mv sm1-bak sm1
-test_expect_success 'typechanged submodule(submodule->blob), --cached' "
+test_expect_success 'typechanged submodule(submodule->blob), --cached' '
git diff --submodule=log --cached >actual &&
cat >expected <<-EOF &&
-Submodule sm1 41fbea9...0000000 (submodule deleted)
-diff --git a/sm1 b/sm1
-new file mode 100644
-index 0000000..9da5fb8
---- /dev/null
-+++ b/sm1
-@@ -0,0 +1 @@
-+sm1
-EOF
+ Submodule sm1 $head4...0000000 (submodule deleted)
+ diff --git a/sm1 b/sm1
+ new file mode 100644
+ index 0000000..$head5
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +sm1
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'typechanged submodule(submodule->blob)' "
+test_expect_success 'typechanged submodule(submodule->blob)' '
git diff --submodule=log >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-deleted file mode 100644
-index 9da5fb8..0000000
---- a/sm1
-+++ /dev/null
-@@ -1 +0,0 @@
--sm1
-Submodule sm1 0000000...$head4 (new submodule)
-EOF
+ diff --git a/sm1 b/sm1
+ deleted file mode 100644
+ index $head5..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -sm1
+ Submodule sm1 0000000...$head4 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
rm -rf sm1 &&
git checkout-index sm1
-test_expect_success 'typechanged submodule(submodule->blob)' "
+test_expect_success 'typechanged submodule(submodule->blob)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head4...0000000 (submodule deleted)
-diff --git a/sm1 b/sm1
-new file mode 100644
-index 0000000..$head5
---- /dev/null
-+++ b/sm1
-@@ -0,0 +1 @@
-+sm1
-EOF
+ Submodule sm1 $head4...0000000 (submodule deleted)
+ diff --git a/sm1 b/sm1
+ new file mode 100644
+ index 0000000..$head5
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +sm1
+ EOF
test_cmp expected actual
-"
+'
rm -f sm1 &&
test_create_repo sm1 &&
head6=$(add_file sm1 foo6 foo7)
-fullhead6=$(cd sm1; git rev-list --max-count=1 $head6)
-test_expect_success 'nonexistent commit' "
+fullhead6=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'nonexistent commit' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head4...$head6 (commits not present)
-EOF
+ Submodule sm1 $head4...$head6 (commits not present)
+ EOF
test_cmp expected actual
-"
+'
commit_file
-test_expect_success 'typechanged submodule(blob->submodule)' "
+test_expect_success 'typechanged submodule(blob->submodule)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-deleted file mode 100644
-index $head5..0000000
---- a/sm1
-+++ /dev/null
-@@ -1 +0,0 @@
--sm1
-Submodule sm1 0000000...$head6 (new submodule)
-EOF
+ diff --git a/sm1 b/sm1
+ deleted file mode 100644
+ index $head5..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -sm1
+ Submodule sm1 0000000...$head6 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
commit_file sm1 &&
-test_expect_success 'submodule is up to date' "
+test_expect_success 'submodule is up to date' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-EOF
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked content' "
+test_expect_success 'submodule contains untracked content' '
echo new > sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-EOF
+ Submodule sm1 contains untracked content
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked content (untracked ignored)' "
+test_expect_success 'submodule contains untracked content (untracked ignored)' '
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked content (dirty ignored)' "
+test_expect_success 'submodule contains untracked content (dirty ignored)' '
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked content (all ignored)' "
+test_expect_success 'submodule contains untracked content (all ignored)' '
git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content' "
+test_expect_success 'submodule contains untracked and modifed content' '
echo new > sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-Submodule sm1 contains modified content
-EOF
+ Submodule sm1 contains untracked content
+ Submodule sm1 contains modified content
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' "
+test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-EOF
+ Submodule sm1 contains modified content
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' "
+test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content (all ignored)' "
+test_expect_success 'submodule contains untracked and modifed content (all ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains modifed content' "
+test_expect_success 'submodule contains modifed content' '
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-EOF
+ Submodule sm1 contains modified content
+ EOF
test_cmp expected actual
-"
+'
(cd sm1; git commit -mchange foo6 >/dev/null) &&
-head8=$(cd sm1; git rev-parse --verify HEAD | cut -c1-7) &&
-test_expect_success 'submodule is modified' "
+head8=$(cd sm1; git rev-parse --short --verify HEAD) &&
+test_expect_success 'submodule is modified' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content' "
+test_expect_success 'modified submodule contains untracked content' '
echo new > sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains untracked content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content (untracked ignored)' "
+test_expect_success 'modified submodule contains untracked content (untracked ignored)' '
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content (dirty ignored)' "
+test_expect_success 'modified submodule contains untracked content (dirty ignored)' '
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content (all ignored)' "
+test_expect_success 'modified submodule contains untracked content (all ignored)' '
git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content' "
+test_expect_success 'modified submodule contains untracked and modifed content' '
echo modification >> sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-Submodule sm1 contains modified content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains untracked content
+ Submodule sm1 contains modified content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' "
+test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains modified content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' "
+test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' "
+test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'modified submodule contains modifed content' "
+test_expect_success 'modified submodule contains modifed content' '
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains modified content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
rm -rf sm1
-test_expect_success 'deleted submodule' "
+test_expect_success 'deleted submodule' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ EOF
test_cmp expected actual
-"
+'
test_create_repo sm2 &&
head7=$(add_file sm2 foo8 foo9) &&
git add sm2
-test_expect_success 'multiple submodules' "
+test_expect_success 'multiple submodules' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'path filter' "
+test_expect_success 'path filter' '
git diff-index -p --submodule=log HEAD sm2 >actual &&
cat >expected <<-EOF &&
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
commit_file sm2
-test_expect_success 'given commit' "
+test_expect_success 'given commit' '
git diff-index -p --submodule=log HEAD^ >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'given commit --submodule' "
+test_expect_success 'given commit --submodule' '
git diff-index -p --submodule HEAD^ >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
-fullhead7=$(cd sm2; git rev-list --max-count=1 $head7)
+fullhead7=$(cd sm2; git rev-parse --verify HEAD)
-test_expect_success 'given commit --submodule=short' "
+test_expect_success 'given commit --submodule=short' '
git diff-index -p --submodule=short HEAD^ >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-deleted file mode 160000
-index $head6..0000000
---- a/sm1
-+++ /dev/null
-@@ -1 +0,0 @@
--Subproject commit $fullhead6
-diff --git a/sm2 b/sm2
-new file mode 160000
-index 0000000..$head7
---- /dev/null
-+++ b/sm2
-@@ -0,0 +1 @@
-+Subproject commit $fullhead7
-EOF
- test_cmp expected actual
-"
+ diff --git a/sm1 b/sm1
+ deleted file mode 160000
+ index $head6..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -Subproject commit $fullhead6
+ diff --git a/sm2 b/sm2
+ new file mode 160000
+ index 0000000..$head7
+ --- /dev/null
+ +++ b/sm2
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead7
+ EOF
+ test_cmp expected actual
+'
test_expect_success 'setup .git file for sm2' '
(cd sm2 &&
@@ -452,9 +493,43 @@ test_expect_success 'setup .git file for sm2' '
test_expect_success 'diff --submodule with .git file' '
git diff --submodule HEAD^ >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'diff --submodule with objects referenced by alternates' '
+ mkdir sub_alt &&
+ (cd sub_alt &&
+ git init &&
+ echo a >a &&
+ git add a &&
+ git commit -m a
+ ) &&
+ mkdir super &&
+ (cd super &&
+ git clone -s ../sub_alt sub &&
+ git init &&
+ git add sub &&
+ git commit -m "sub a"
+ ) &&
+ (cd sub_alt &&
+ sha1_before=$(git rev-parse --short HEAD)
+ echo b >b &&
+ git add b &&
+ git commit -m b
+ sha1_after=$(git rev-parse --short HEAD)
+ echo "Submodule sub $sha1_before..$sha1_after:
+ > b" >../expected
+ ) &&
+ (cd super &&
+ (cd sub &&
+ git fetch &&
+ git checkout origin/master
+ ) &&
+ git diff --submodule > ../actual
+ )
test_cmp expected actual
'
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 18fadcf06e..3950f5034d 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -44,7 +44,7 @@ test_expect_success "--numstat $*" "
check_stat() {
expect=$1; shift
cat >expected <<EOF
- $expect | 1 +
+ $expect | 1 +
1 file changed, 1 insertion(+)
EOF
test_expect_success "--stat $*" "
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
index 591ffbc075..5b594e878f 100755
--- a/t/t4049-diff-stat-count.sh
+++ b/t/t4049-diff-stat-count.sh
@@ -4,19 +4,62 @@
test_description='diff --stat-count'
. ./test-lib.sh
-test_expect_success setup '
+test_expect_success 'setup' '
>a &&
>b &&
>c &&
>d &&
git add a b c d &&
- chmod +x c d &&
+ git commit -m initial
+'
+
+test_expect_success 'mode-only change show as a 0-line change' '
+ git reset --hard &&
+ test_chmod +x b d &&
+ echo a >a &&
+ echo c >c &&
+ cat >expect <<-\EOF
+ a | 1 +
+ b | 0
+ ...
+ 4 files changed, 2 insertions(+)
+ EOF
+ git diff --stat --stat-count=2 HEAD >actual &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'binary changes do not count in lines' '
+ git reset --hard &&
+ echo a >a &&
+ echo c >c &&
+ cat "$TEST_DIRECTORY"/test-binary-1.png >d &&
+ cat >expect <<-\EOF
+ a | 1 +
+ c | 1 +
+ ...
+ 3 files changed, 2 insertions(+)
+ EOF
+ git diff --stat --stat-count=2 >actual &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'exclude unmerged entries from total file count' '
+ git reset --hard &&
echo a >a &&
echo b >b &&
+ git ls-files -s a >x &&
+ git rm -f d &&
+ for stage in 1 2 3
+ do
+ sed -e "s/ 0 a/ $stage d/" x
+ done |
+ git update-index --index-info &&
+ echo d >d &&
cat >expect <<-\EOF
- a | 1 +
- b | 1 +
- 2 files changed, 2 insertions(+)
+ a | 1 +
+ b | 1 +
+ ...
+ 3 files changed, 3 insertions(+)
EOF
git diff --stat --stat-count=2 >actual &&
test_i18ncmp expect actual
diff --git a/t/t4052-stat-output.sh b/t/t4052-stat-output.sh
index 328aa8f398..b68afefa3c 100755
--- a/t/t4052-stat-output.sh
+++ b/t/t4052-stat-output.sh
@@ -22,7 +22,7 @@ test_expect_success 'preparation' '
while read cmd args
do
cat >expect <<-'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
EOF
test_expect_success "$cmd: small change with long name gives more space to the name" '
git $cmd $args >output &&
@@ -31,7 +31,7 @@ do
'
cat >expect <<-'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 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 &&
@@ -46,7 +46,7 @@ do
'
cat >expect <<-'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
EOF
test_expect_success "$cmd --stat=...,name-width with long name" '
git $cmd $args --stat=60,30 >output &&
@@ -82,11 +82,15 @@ test_expect_success 'preparation for big change tests' '
cat >expect80 <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
-
+cat >expect80-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
cat >expect200 <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
-
+cat >expect200-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
while read verb expect cmd args
do
test_expect_success "$cmd $verb COLUMNS (big change)" '
@@ -94,6 +98,14 @@ do
grep " | " output >actual &&
test_cmp "$expect" actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb COLUMNS (big change)" '
+ COLUMNS=200 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
done <<\EOF
ignores expect80 format-patch -1 --stdout
respects expect200 diff HEAD^ HEAD --stat
@@ -104,7 +116,9 @@ EOF
cat >expect40 <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++
EOF
-
+cat >expect40-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++
+EOF
while read verb expect cmd args
do
test_expect_success "$cmd $verb not enough COLUMNS (big change)" '
@@ -113,11 +127,41 @@ do
test_cmp "$expect" actual
'
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb not enough COLUMNS (big change)" '
+ COLUMNS=40 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" 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 >expect40 <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++
+EOF
+cat >expect40-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++
+EOF
+while read verb expect cmd args
+do
test_expect_success "$cmd $verb statGraphWidth config" '
git -c diff.statGraphWidth=26 $cmd $args >output
grep " | " output >actual &&
test_cmp "$expect" actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb statGraphWidth config" '
+ git -c diff.statGraphWidth=26 $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
done <<\EOF
ignores expect80 format-patch -1 --stdout
respects expect40 diff HEAD^ HEAD --stat
@@ -129,6 +173,9 @@ EOF
cat >expect <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++
EOF
+cat >expect-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++
+EOF
while read cmd args
do
test_expect_success "$cmd --stat=width with big change" '
@@ -143,11 +190,25 @@ do
test_cmp expect actual
'
- test_expect_success "$cmd --stat-graph--width with big change" '
+ 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
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --stat-width=width --graph with big change" '
+ git $cmd $args --stat-width=40 --graph >output
+ grep " | " output >actual &&
+ test_cmp expect-graph actual
+ '
+
+ test_expect_success "$cmd --stat-graph-width --graph with big change" '
+ git $cmd $args --stat-graph-width=26 --graph >output
+ grep " | " output >actual &&
+ test_cmp expect-graph actual
+ '
done <<\EOF
format-patch -1 --stdout
diff HEAD^ HEAD --stat
@@ -164,6 +225,9 @@ test_expect_success 'preparation for long filename tests' '
cat >expect <<'EOF'
...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
EOF
+cat >expect-graph <<'EOF'
+| ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
+EOF
while read cmd args
do
test_expect_success "$cmd --stat=width with big change is more balanced" '
@@ -171,6 +235,14 @@ do
grep " | " output >actual &&
test_cmp expect actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --stat=width --graph with big change is balanced" '
+ git $cmd $args --stat-width=60 --graph >output &&
+ grep " | " output >actual &&
+ test_cmp expect-graph actual
+ '
done <<\EOF
format-patch -1 --stdout
diff HEAD^ HEAD --stat
@@ -181,9 +253,15 @@ EOF
cat >expect80 <<'EOF'
...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++++++++++
EOF
+cat >expect80-graph <<'EOF'
+| ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++++++++++
+EOF
cat >expect200 <<'EOF'
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
+cat >expect200-graph <<'EOF'
+| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
while read verb expect cmd args
do
test_expect_success "$cmd $verb COLUMNS (long filename)" '
@@ -191,6 +269,14 @@ do
grep " | " output >actual &&
test_cmp "$expect" actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb COLUMNS (long filename)" '
+ COLUMNS=200 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
done <<\EOF
ignores expect80 format-patch -1 --stdout
respects expect200 diff HEAD^ HEAD --stat
@@ -198,6 +284,36 @@ respects expect200 show --stat
respects expect200 log -1 --stat
EOF
+cat >expect1 <<'EOF'
+ ...aaaaaaa | 1000 ++++++
+EOF
+cat >expect1-graph <<'EOF'
+| ...aaaaaaa | 1000 ++++++
+EOF
+while read verb expect cmd args
+do
+ test_expect_success COLUMNS_CAN_BE_1 \
+ "$cmd $verb prefix greater than COLUMNS (big change)" '
+ COLUMNS=1 git $cmd $args >output
+ grep " | " output >actual &&
+ test_cmp "$expect" actual
+ '
+
+ test "$cmd" != diff || continue
+
+ test_expect_success COLUMNS_CAN_BE_1 \
+ "$cmd --graph $verb prefix greater than COLUMNS (big change)" '
+ COLUMNS=1 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
+done <<\EOF
+ignores expect80 format-patch -1 --stdout
+respects expect1 diff HEAD^ HEAD --stat
+respects expect1 show --stat
+respects expect1 log -1 --stat
+EOF
+
cat >expect <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
new file mode 100755
index 0000000000..979e98398b
--- /dev/null
+++ b/t/t4053-diff-no-index.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+test_description='diff --no-index'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir a &&
+ mkdir b &&
+ echo 1 >a/1 &&
+ echo 2 >a/2 &&
+ git init repo &&
+ echo 1 >repo/a &&
+ mkdir -p non/git &&
+ echo 1 >non/git/a &&
+ echo 1 >non/git/b
+'
+
+test_expect_success 'git diff --no-index directories' '
+ git diff --no-index a b >cnt
+ test $? = 1 && test_line_count = 14 cnt
+'
+
+test_expect_success 'git diff --no-index relative path outside repo' '
+ (
+ cd repo &&
+ test_expect_code 0 git diff --no-index a ../non/git/a &&
+ test_expect_code 0 git diff --no-index ../non/git/a ../non/git/b
+ )
+'
+
+test_done
diff --git a/t/t4054-diff-bogus-tree.sh b/t/t4054-diff-bogus-tree.sh
new file mode 100755
index 0000000000..0843c87890
--- /dev/null
+++ b/t/t4054-diff-bogus-tree.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+test_description='test diff with a bogus tree containing the null sha1'
+. ./test-lib.sh
+
+empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+
+test_expect_success 'create bogus tree' '
+ bogus_tree=$(
+ printf "100644 fooQQQQQQQQQQQQQQQQQQQQQ" |
+ q_to_nul |
+ git hash-object -w --stdin -t tree
+ )
+'
+
+test_expect_success 'create tree with matching file' '
+ echo bar >foo &&
+ git add foo &&
+ good_tree=$(git write-tree)
+ blob=$(git rev-parse :foo)
+'
+
+test_expect_success 'raw diff shows null sha1 (addition)' '
+ echo ":000000 100644 $_z40 $_z40 A foo" >expect &&
+ git diff-tree $empty_tree $bogus_tree >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'raw diff shows null sha1 (removal)' '
+ echo ":100644 000000 $_z40 $_z40 D foo" >expect &&
+ git diff-tree $bogus_tree $empty_tree >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'raw diff shows null sha1 (modification)' '
+ echo ":100644 100644 $blob $_z40 M foo" >expect &&
+ git diff-tree $good_tree $bogus_tree >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'raw diff shows null sha1 (other direction)' '
+ echo ":100644 100644 $_z40 $blob M foo" >expect &&
+ git diff-tree $bogus_tree $good_tree >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'raw diff shows null sha1 (reverse)' '
+ echo ":100644 100644 $_z40 $blob M foo" >expect &&
+ git diff-tree -R $good_tree $bogus_tree >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'raw diff shows null sha1 (index)' '
+ echo ":100644 100644 $_z40 $blob M foo" >expect &&
+ git diff-index $bogus_tree >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'patch fails due to bogus sha1 (addition)' '
+ test_must_fail git diff-tree -p $empty_tree $bogus_tree
+'
+
+test_expect_success 'patch fails due to bogus sha1 (removal)' '
+ test_must_fail git diff-tree -p $bogus_tree $empty_tree
+'
+
+test_expect_success 'patch fails due to bogus sha1 (modification)' '
+ test_must_fail git diff-tree -p $good_tree $bogus_tree
+'
+
+test_expect_success 'patch fails due to bogus sha1 (other direction)' '
+ test_must_fail git diff-tree -p $bogus_tree $good_tree
+'
+
+test_expect_success 'patch fails due to bogus sha1 (reverse)' '
+ test_must_fail git diff-tree -R -p $good_tree $bogus_tree
+'
+
+test_expect_success 'patch fails due to bogus sha1 (index)' '
+ test_must_fail git diff-index -p $bogus_tree
+'
+
+test_done
diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh
new file mode 100755
index 0000000000..97172b46b2
--- /dev/null
+++ b/t/t4055-diff-context.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Mozilla Foundation
+#
+
+test_description='diff.context configuration'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ cat >template <<-\EOF &&
+ firstline
+ b
+ c
+ d
+ e
+ f
+ preline
+ TARGET
+ postline
+ i
+ j
+ k
+ l
+ m
+ n
+ EOF
+ sed "/TARGET/d" >x <template &&
+ git update-index --add x &&
+ git commit -m initial &&
+
+ sed "s/TARGET/ADDED/" >x <template &&
+ git update-index --add x &&
+ git commit -m next &&
+
+ sed "s/TARGET/MODIFIED/" >x <template
+'
+
+test_expect_success 'the default number of context lines is 3' '
+ git diff >output &&
+ ! grep "^ d" output &&
+ grep "^ e" output &&
+ grep "^ j" output &&
+ ! grep "^ k" output
+'
+
+test_expect_success 'diff.context honored by "log"' '
+ git log -1 -p >output &&
+ ! grep firstline output &&
+ git config diff.context 8 &&
+ git log -1 -p >output &&
+ grep "^ firstline" output
+'
+
+test_expect_success 'The -U option overrides diff.context' '
+ git config diff.context 8 &&
+ git log -U4 -1 >output &&
+ ! grep "^ firstline" output
+'
+
+test_expect_success 'diff.context honored by "diff"' '
+ git config diff.context 8 &&
+ git diff >output &&
+ grep "^ firstline" output
+'
+
+test_expect_success 'plumbing not affected' '
+ git config diff.context 8 &&
+ git diff-files -p >output &&
+ ! grep "^ firstline" output
+'
+
+test_expect_success 'non-integer config parsing' '
+ git config diff.context no &&
+ test_must_fail git diff 2>output &&
+ test_i18ngrep "bad config value" output
+'
+
+test_expect_success 'negative integer config parsing' '
+ git config diff.context -1 &&
+ test_must_fail git diff 2>output &&
+ test_i18ngrep "bad config file" output
+'
+
+test_expect_success '-U0 is valid, so is diff.context=0' '
+ git config diff.context 0 &&
+ git diff >output &&
+ grep "^-ADDED" output &&
+ grep "^+MODIFIED" output
+'
+
+test_done
diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh
index dbbf56cba9..b1b906b1bb 100755
--- a/t/t4103-apply-binary.sh
+++ b/t/t4103-apply-binary.sh
@@ -8,30 +8,28 @@ test_description='git apply handling binary patches
'
. ./test-lib.sh
-# setup
-
-cat >file1 <<EOF
-A quick brown fox jumps over the lazy dog.
-A tiny little penguin runs around in circles.
-There is a flag with Linux written on it.
-A slow black-and-white panda just sits there,
-munching on his bamboo.
-EOF
-cat file1 >file2
-cat file1 >file4
-
-test_expect_success 'setup' "
+test_expect_success 'setup' '
+ cat >file1 <<-\EOF &&
+ A quick brown fox jumps over the lazy dog.
+ A tiny little penguin runs around in circles.
+ There is a flag with Linux written on it.
+ A slow black-and-white panda just sits there,
+ munching on his bamboo.
+ EOF
+ cat file1 >file2 &&
+ cat file1 >file4 &&
+
git update-index --add --remove file1 file2 file4 &&
- git commit -m 'Initial Version' 2>/dev/null &&
+ git commit -m "Initial Version" 2>/dev/null &&
git checkout -b binary &&
- perl -pe 'y/x/\000/' <file1 >file3 &&
+ "$PERL_PATH" -pe "y/x/\000/" <file1 >file3 &&
cat file3 >file4 &&
git add file2 &&
- perl -pe 'y/\000/v/' <file3 >file1 &&
+ "$PERL_PATH" -pe "y/\000/v/" <file3 >file1 &&
rm -f file2 &&
git update-index --add --remove file1 file2 file3 file4 &&
- git commit -m 'Second Version' &&
+ git commit -m "Second Version" &&
git diff-tree -p master binary >B.diff &&
git diff-tree -p -C master binary >C.diff &&
@@ -42,17 +40,25 @@ test_expect_success 'setup' "
git diff-tree -p --full-index master binary >B-index.diff &&
git diff-tree -p -C --full-index master binary >C-index.diff &&
+ git diff-tree -p --binary --no-prefix master binary -- file3 >B0.diff &&
+
git init other-repo &&
- (cd other-repo &&
- git fetch .. master &&
- git reset --hard FETCH_HEAD
+ (
+ cd other-repo &&
+ git fetch .. master &&
+ git reset --hard FETCH_HEAD
)
-"
+'
test_expect_success 'stat binary diff -- should not fail.' \
'git checkout master &&
git apply --stat --summary B.diff'
+test_expect_success 'stat binary -p0 diff -- should not fail.' '
+ git checkout master &&
+ git apply --stat -p0 B0.diff
+'
+
test_expect_success 'stat binary diff (copy) -- should not fail.' \
'git checkout master &&
git apply --stat --summary C.diff'
@@ -143,4 +149,10 @@ test_expect_success 'apply binary diff (copy).' \
git apply --allow-binary-replacement --index CF.diff &&
test -z "$(git diff --name-status binary)"'
+test_expect_success 'apply binary -p0 diff' '
+ do_reset &&
+ git apply -p0 --index B0.diff &&
+ test -z "$(git diff --name-status binary -- file3)"
+'
+
test_done
diff --git a/t/t4108-apply-threeway.sh b/t/t4108-apply-threeway.sh
new file mode 100755
index 0000000000..fa5d4efb89
--- /dev/null
+++ b/t/t4108-apply-threeway.sh
@@ -0,0 +1,157 @@
+#!/bin/sh
+
+test_description='git apply --3way'
+
+. ./test-lib.sh
+
+create_file () {
+ for i
+ do
+ echo "$i"
+ done
+}
+
+sanitize_conflicted_diff () {
+ sed -e '
+ /^index /d
+ s/^\(+[<>][<>][<>][<>]*\) .*/\1/
+ '
+}
+
+test_expect_success setup '
+ test_tick &&
+ create_file >one 1 2 3 4 5 6 7 &&
+ cat one >two &&
+ git add one two &&
+ git commit -m initial &&
+
+ git branch side &&
+
+ test_tick &&
+ create_file >one 1 two 3 4 5 six 7 &&
+ create_file >two 1 two 3 4 5 6 7 &&
+ git commit -a -m master &&
+
+ git checkout side &&
+ create_file >one 1 2 3 4 five 6 7 &&
+ create_file >two 1 2 3 4 five 6 7 &&
+ git commit -a -m side &&
+
+ git checkout master
+'
+
+test_expect_success 'apply without --3way' '
+ git diff side^ side >P.diff &&
+
+ # should fail to apply
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git apply --index P.diff &&
+ # should leave things intact
+ git diff-files --exit-code &&
+ git diff-index --exit-code --cached HEAD
+'
+
+test_expect_success 'apply with --3way' '
+ # Merging side should be similar to applying this patch
+ git diff ...side >P.diff &&
+
+ # The corresponding conflicted merge
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git merge --no-commit side &&
+ git ls-files -s >expect.ls &&
+ git diff HEAD | sanitize_conflicted_diff >expect.diff &&
+
+ # should fail to apply
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git apply --index --3way P.diff &&
+ git ls-files -s >actual.ls &&
+ git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+
+ # The result should resemble the corresponding merge
+ test_cmp expect.ls actual.ls &&
+ test_cmp expect.diff actual.diff
+'
+
+test_expect_success 'apply with --3way with rerere enabled' '
+ git config rerere.enabled true &&
+
+ # Merging side should be similar to applying this patch
+ git diff ...side >P.diff &&
+
+ # The corresponding conflicted merge
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git merge --no-commit side &&
+
+ # Manually resolve and record the resolution
+ create_file 1 two 3 4 five six 7 >one &&
+ git rerere &&
+ cat one >expect &&
+
+ # should fail to apply
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git apply --index --3way P.diff &&
+
+ # but rerere should have replayed the recorded resolution
+ test_cmp expect one
+'
+
+test_expect_success 'apply -3 with add/add conflict setup' '
+ git reset --hard &&
+
+ git checkout -b adder &&
+ create_file 1 2 3 4 5 6 7 >three &&
+ create_file 1 2 3 4 5 6 7 >four &&
+ git add three four &&
+ git commit -m "add three and four" &&
+
+ git checkout -b another adder^ &&
+ create_file 1 2 3 4 5 6 7 >three &&
+ create_file 1 2 3 four 5 6 7 >four &&
+ git add three four &&
+ git commit -m "add three and four" &&
+
+ # Merging another should be similar to applying this patch
+ git diff adder...another >P.diff &&
+
+ git checkout adder^0 &&
+ test_must_fail git merge --no-commit another &&
+ git ls-files -s >expect.ls &&
+ git diff HEAD | sanitize_conflicted_diff >expect.diff
+'
+
+test_expect_success 'apply -3 with add/add conflict' '
+ # should fail to apply ...
+ git reset --hard &&
+ git checkout adder^0 &&
+ test_must_fail git apply --index --3way P.diff &&
+ # ... and leave conflicts in the index and in the working tree
+ git ls-files -s >actual.ls &&
+ git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+
+ # The result should resemble the corresponding merge
+ test_cmp expect.ls actual.ls &&
+ test_cmp expect.diff actual.diff
+'
+
+test_expect_success 'apply -3 with add/add conflict (dirty working tree)' '
+ # should fail to apply ...
+ git reset --hard &&
+ git checkout adder^0 &&
+ echo >>four &&
+ cat four >four.save &&
+ cat three >three.save &&
+ git ls-files -s >expect.ls &&
+ test_must_fail git apply --index --3way P.diff &&
+ # ... and should not touch anything
+ git ls-files -s >actual.ls &&
+ test_cmp expect.ls actual.ls &&
+ test_cmp four.save four &&
+ test_cmp three.save three
+'
+
+test_done
diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh
index 2298ece801..fca815392e 100755
--- a/t/t4116-apply-reverse.sh
+++ b/t/t4116-apply-reverse.sh
@@ -12,14 +12,14 @@ test_description='git apply in reverse
test_expect_success setup '
for i in a b c d e f g h i j k l m n; do echo $i; done >file1 &&
- perl -pe "y/ijk/\\000\\001\\002/" <file1 >file2 &&
+ "$PERL_PATH" -pe "y/ijk/\\000\\001\\002/" <file1 >file2 &&
git add file1 file2 &&
git commit -m initial &&
git tag initial &&
for i in a b c g h i J K L m o n p q; do echo $i; done >file1 &&
- perl -pe "y/mon/\\000\\001\\002/" <file1 >file2 &&
+ "$PERL_PATH" -pe "y/mon/\\000\\001\\002/" <file1 >file2 &&
git commit -a -m second &&
git tag second &&
diff --git a/t/t4117-apply-reject.sh b/t/t4117-apply-reject.sh
index e9ccd161ee..8e15ecbdfd 100755
--- a/t/t4117-apply-reject.sh
+++ b/t/t4117-apply-reject.sh
@@ -46,6 +46,14 @@ test_expect_success setup '
cat file1 >saved.file1
'
+test_expect_success 'apply --reject is incompatible with --3way' '
+ test_when_finished "cat saved.file1 >file1" &&
+ git diff >patch.0 &&
+ git checkout file1 &&
+ test_must_fail git apply --reject --3way patch.0 &&
+ git diff --exit-code
+'
+
test_expect_success 'apply without --reject should fail' '
if git apply patch.1
diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh
index a33d510bf6..c5fecdfed4 100755
--- a/t/t4120-apply-popt.sh
+++ b/t/t4120-apply-popt.sh
@@ -32,7 +32,7 @@ test_expect_success 'apply git diff with -p2' '
test_expect_success 'apply with too large -p' '
cp file1.saved file1 &&
test_must_fail git apply --stat -p3 patch.file 2>err &&
- grep "removing 3 leading" err
+ test_i18ngrep "removing 3 leading" err
'
test_expect_success 'apply (-p2) traditional diff with funny filenames' '
@@ -54,7 +54,7 @@ test_expect_success 'apply (-p2) traditional diff with funny filenames' '
test_expect_success 'apply with too large -p and fancy filename' '
cp file1.saved file1 &&
test_must_fail git apply --stat -p3 patch.escaped 2>err &&
- grep "removing 3 leading" err
+ test_i18ngrep "removing 3 leading" err
'
test_expect_success 'apply (-p2) diff, mode change only' '
diff --git a/t/t4133-apply-filenames.sh b/t/t4133-apply-filenames.sh
index 94da99075c..2ecb4216b7 100755
--- a/t/t4133-apply-filenames.sh
+++ b/t/t4133-apply-filenames.sh
@@ -30,9 +30,9 @@ EOF
test_expect_success 'apply diff with inconsistent filenames in headers' '
test_must_fail git apply bad1.patch 2>err &&
- grep "inconsistent new filename" err &&
+ test_i18ngrep "inconsistent new filename" err &&
test_must_fail git apply bad2.patch 2>err &&
- grep "inconsistent old filename" err
+ test_i18ngrep "inconsistent old filename" err
'
test_done
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index 36255d608a..7f6666fcd3 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -78,7 +78,7 @@ test_expect_success 'activate rerere, old style (conflicting merge)' '
test_might_fail git config --unset rerere.enabled &&
test_must_fail git merge first &&
- sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) &&
+ sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) &&
rr=.git/rr-cache/$sha1 &&
grep "^=======\$" $rr/preimage &&
! test -f $rr/postimage &&
@@ -91,7 +91,7 @@ test_expect_success 'rerere.enabled works, too' '
git reset --hard &&
test_must_fail git merge first &&
- sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) &&
+ sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) &&
rr=.git/rr-cache/$sha1 &&
grep ^=======$ $rr/preimage
'
@@ -101,7 +101,7 @@ test_expect_success 'set up rr-cache' '
git config rerere.enabled true &&
git reset --hard &&
test_must_fail git merge first &&
- sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) &&
+ sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) &&
rr=.git/rr-cache/$sha1
'
@@ -185,7 +185,7 @@ test_expect_success 'rerere updates postimage timestamp' '
test_expect_success 'rerere clear' '
rm $rr/postimage &&
- echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR &&
+ echo "$sha1 a1" | "$PERL_PATH" -pe "y/\012/\000/" >.git/MERGE_RR &&
git rerere clear &&
! test -d $rr
'
@@ -382,13 +382,13 @@ test_expect_success 'rerere --no-no-rerere-autoupdate' '
git update-index --index-info <failedmerge &&
cp file3.conflict file3 &&
test_must_fail git rerere --no-no-rerere-autoupdate 2>err &&
- grep [Uu]sage err &&
+ test_i18ngrep [Uu]sage err &&
test_must_fail git update-index --refresh
'
test_expect_success 'rerere -h' '
test_must_fail git rerere -h >help &&
- grep [Uu]sage help
+ test_i18ngrep [Uu]sage help
'
test_done
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index 6872ba1a42..5493500ef1 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -120,6 +120,30 @@ test_expect_success 'shortlog from non-git directory' '
test_cmp expect out
'
+test_expect_success 'shortlog should add newline when input line matches wraplen' '
+ cat >expect <<\EOF &&
+A U Thor (2):
+ bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb
+ aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa
+
+EOF
+ git shortlog -w >out <<\EOF &&
+commit 0000000000000000000000000000000000000001
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:14:13 2005 -0700
+
+ aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa
+
+commit 0000000000000000000000000000000000000002
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:14:13 2005 -0700
+
+ bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb
+
+EOF
+ test_cmp expect out
+'
+
iconvfromutf8toiso88591() {
printf "%s" "$*" | iconv -f UTF-8 -t ISO8859-1
}
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 32cf0bd218..fa686b887d 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -72,9 +72,9 @@ cat > expect << EOF
commit.
EOF
-test_expect_success 'format %w(12,1,2)' '
+test_expect_success 'format %w(11,1,2)' '
- git log -2 --format="%w(12,1,2)This is the %s commit." > actual &&
+ git log -2 --format="%w(11,1,2)This is the %s commit." > actual &&
test_cmp expect actual
'
@@ -178,11 +178,21 @@ test_expect_success 'git log --no-walk <commits> sorts by commit time' '
test_cmp expect actual
'
+test_expect_success 'git log --no-walk=sorted <commits> sorts by commit time' '
+ git log --no-walk=sorted --oneline 5d31159 804a787 394ef78 > actual &&
+ test_cmp expect actual
+'
+
cat > expect << EOF
5d31159 fourth
804a787 sixth
394ef78 fifth
EOF
+test_expect_success 'git log --no-walk=unsorted <commits> leaves list of commits as given' '
+ git log --no-walk=unsorted --oneline 5d31159 804a787 394ef78 > actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'git show <commits> leaves list of commits as given' '
git show --oneline -s 5d31159 804a787 394ef78 > actual &&
test_cmp expect actual
@@ -220,6 +230,12 @@ test_expect_success 'log --grep -i' '
test_cmp expect actual
'
+test_expect_success 'log -F -E --grep=<ere> uses ere' '
+ echo second >expect &&
+ git log -1 --pretty="tformat:%s" -F -E --grep=s.c.nd >actual &&
+ test_cmp expect actual
+'
+
cat > expect <<EOF
* Second
* sixth
@@ -264,6 +280,16 @@ test_expect_success 'log --graph with merge' '
test_cmp expect actual
'
+test_expect_success 'log --raw --graph -m with merge' '
+ git log --raw --graph --oneline -m master | head -n 500 >actual &&
+ grep "initial" actual
+'
+
+test_expect_success 'diff-tree --graph' '
+ git diff-tree --graph master^ | head -n 500 >actual &&
+ grep "one" actual
+'
+
cat > expect <<\EOF
* commit master
|\ Merge: A B
@@ -528,7 +554,7 @@ cat >expect <<\EOF
| |
| | reach
| | ---
-| | reach.t | 1 +
+| | reach.t | 1 +
| | 1 file changed, 1 insertion(+)
| |
| | diff --git a/reach.t b/reach.t
@@ -551,7 +577,7 @@ cat >expect <<\EOF
| | |
| | | octopus-b
| | | ---
-| | | octopus-b.t | 1 +
+| | | octopus-b.t | 1 +
| | | 1 file changed, 1 insertion(+)
| | |
| | | diff --git a/octopus-b.t b/octopus-b.t
@@ -567,7 +593,7 @@ cat >expect <<\EOF
| |
| | octopus-a
| | ---
-| | octopus-a.t | 1 +
+| | octopus-a.t | 1 +
| | 1 file changed, 1 insertion(+)
| |
| | diff --git a/octopus-a.t b/octopus-a.t
@@ -583,7 +609,7 @@ cat >expect <<\EOF
|
| seventh
| ---
-| seventh.t | 1 +
+| seventh.t | 1 +
| 1 file changed, 1 insertion(+)
|
| diff --git a/seventh.t b/seventh.t
@@ -617,7 +643,7 @@ cat >expect <<\EOF
| | | |
| | | | tangle-a
| | | | ---
-| | | | tangle-a | 1 +
+| | | | tangle-a | 1 +
| | | | 1 file changed, 1 insertion(+)
| | | |
| | | | diff --git a/tangle-a b/tangle-a
@@ -639,7 +665,7 @@ cat >expect <<\EOF
| |/| |
| | | | side-2
| | | | ---
-| | | | 2 | 1 +
+| | | | 2 | 1 +
| | | | 1 file changed, 1 insertion(+)
| | | |
| | | | diff --git a/2 b/2
@@ -655,7 +681,7 @@ cat >expect <<\EOF
| | | |
| | | | side-1
| | | | ---
-| | | | 1 | 1 +
+| | | | 1 | 1 +
| | | | 1 file changed, 1 insertion(+)
| | | |
| | | | diff --git a/1 b/1
@@ -671,7 +697,7 @@ cat >expect <<\EOF
| | | |
| | | | Second
| | | | ---
-| | | | one | 1 +
+| | | | one | 1 +
| | | | 1 file changed, 1 insertion(+)
| | | |
| | | | diff --git a/one b/one
@@ -687,7 +713,7 @@ cat >expect <<\EOF
|/| |
| | | sixth
| | | ---
-| | | a/two | 1 -
+| | | a/two | 1 -
| | | 1 file changed, 1 deletion(-)
| | |
| | | diff --git a/a/two b/a/two
@@ -703,7 +729,7 @@ cat >expect <<\EOF
| | |
| | | fifth
| | | ---
-| | | a/two | 1 +
+| | | a/two | 1 +
| | | 1 file changed, 1 insertion(+)
| | |
| | | diff --git a/a/two b/a/two
@@ -719,7 +745,7 @@ cat >expect <<\EOF
| |
| | fourth
| | ---
-| | ein | 1 +
+| | ein | 1 +
| | 1 file changed, 1 insertion(+)
| |
| | diff --git a/ein b/ein
@@ -735,8 +761,8 @@ cat >expect <<\EOF
|
| third
| ---
-| ichi | 1 +
-| one | 1 -
+| ichi | 1 +
+| one | 1 -
| 2 files changed, 1 insertion(+), 1 deletion(-)
|
| diff --git a/ichi b/ichi
@@ -759,7 +785,7 @@ cat >expect <<\EOF
|
| second
| ---
-| one | 2 +-
+| one | 2 +-
| 1 file changed, 1 insertion(+), 1 deletion(-)
|
| diff --git a/one b/one
@@ -775,7 +801,7 @@ cat >expect <<\EOF
initial
---
- one | 1 +
+ one | 1 +
1 file changed, 1 insertion(+)
diff --git a/one b/one
@@ -803,7 +829,14 @@ sanitize_output () {
test_expect_success 'log --graph with diff and stats' '
git log --graph --pretty=short --stat -p >actual &&
sanitize_output >actual.sanitized <actual &&
- test_cmp expect actual.sanitized
+ test_i18ncmp expect actual.sanitized
+'
+
+test_expect_success 'dotdot is a parent directory' '
+ mkdir -p a/b &&
+ ( echo sixth && echo fifth ) >expect &&
+ ( cd a/b && git log --format=%s .. ) >actual &&
+ test_cmp expect actual
'
test_done
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 1f182f612c..842b7549ec 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -149,6 +149,104 @@ test_expect_success 'No mailmap files, but configured' '
test_cmp expect actual
'
+test_expect_success 'setup mailmap blob tests' '
+ git checkout -b map &&
+ test_when_finished "git checkout master" &&
+ cat >just-bugs <<-\EOF &&
+ Blob Guy <bugs@company.xx>
+ EOF
+ cat >both <<-\EOF &&
+ Blob Guy <author@example.com>
+ Blob Guy <bugs@company.xx>
+ EOF
+ git add just-bugs both &&
+ git commit -m "my mailmaps" &&
+ echo "Repo Guy <author@example.com>" >.mailmap &&
+ echo "Internal Guy <author@example.com>" >internal.map
+'
+
+test_expect_success 'mailmap.blob set' '
+ cat >expect <<-\EOF &&
+ Blob Guy (1):
+ second
+
+ Repo Guy (1):
+ initial
+
+ EOF
+ git -c mailmap.blob=map:just-bugs shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.blob overrides .mailmap' '
+ cat >expect <<-\EOF &&
+ Blob Guy (2):
+ initial
+ second
+
+ EOF
+ git -c mailmap.blob=map:both shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.file overrides mailmap.blob' '
+ cat >expect <<-\EOF &&
+ Blob Guy (1):
+ second
+
+ Internal Guy (1):
+ initial
+
+ EOF
+ git \
+ -c mailmap.blob=map:both \
+ -c mailmap.file=internal.map \
+ shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.blob can be missing' '
+ cat >expect <<-\EOF &&
+ Repo Guy (1):
+ initial
+
+ nick1 (1):
+ second
+
+ EOF
+ git -c mailmap.blob=map:nonexistent shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.blob defaults to off in non-bare repo' '
+ git init non-bare &&
+ (
+ cd non-bare &&
+ test_commit one .mailmap "Fake Name <author@example.com>" &&
+ echo " 1 Fake Name" >expect &&
+ git shortlog -ns HEAD >actual &&
+ test_cmp expect actual &&
+ rm .mailmap &&
+ echo " 1 A U Thor" >expect &&
+ git shortlog -ns HEAD >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'mailmap.blob defaults to HEAD:.mailmap in bare repo' '
+ git clone --bare non-bare bare &&
+ (
+ cd bare &&
+ echo " 1 Fake Name" >expect &&
+ git shortlog -ns HEAD >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'cleanup after mailmap.blob tests' '
+ rm -f .mailmap
+'
+
# Extended mailmap configurations should give us the following output for shortlog
cat >expect <<\EOF
A U Thor <author@example.com> (1):
@@ -239,6 +337,62 @@ test_expect_success 'Log output (complex mapping)' '
test_cmp expect actual
'
+cat >expect <<\EOF
+Author: CTO <cto@company.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Other Author <other@author.xx>
+Author: Other Author <other@author.xx>
+Author: Some Dude <some@dude.xx>
+Author: A U Thor <author@example.com>
+EOF
+
+test_expect_success 'Log output with --use-mailmap' '
+ git log --use-mailmap | grep Author >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+Author: CTO <cto@company.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Other Author <other@author.xx>
+Author: Other Author <other@author.xx>
+Author: Some Dude <some@dude.xx>
+Author: A U Thor <author@example.com>
+EOF
+
+test_expect_success 'Log output with log.mailmap' '
+ git -c log.mailmap=True log | grep Author >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+EOF
+
+test_expect_success 'Grep author with --use-mailmap' '
+ git log --use-mailmap --author Santa | grep Author >actual &&
+ test_cmp expect actual
+'
+cat >expect <<\EOF
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+EOF
+
+test_expect_success 'Grep author with log.mailmap' '
+ git -c log.mailmap=True log --author Santa | grep Author >actual &&
+ test_cmp expect actual
+'
+
+>expect
+
+test_expect_success 'Only grep replaced author with --use-mailmap' '
+ git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
+ test_cmp expect actual
+'
+
# git blame
cat >expect <<\EOF
^OBJI (A U Thor DATE 1) one
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 2ae9faa8b3..98a43d457a 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -71,4 +71,32 @@ test_expect_success 'alias loop' '
test_must_fail git log --pretty=test-foo
'
+test_expect_success 'NUL separation' '
+ printf "add bar\0initial" >expected &&
+ git log -z --pretty="format:%s" >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'NUL termination' '
+ printf "add bar\0initial\0" >expected &&
+ git log -z --pretty="tformat:%s" >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'NUL separation with --stat' '
+ stat0_part=$(git diff --stat HEAD^ HEAD) &&
+ stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
+ printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n" >expected &&
+ git log -z --stat --pretty="format:%s" >actual &&
+ test_i18ncmp expected actual
+'
+
+test_expect_failure 'NUL termination with --stat' '
+ stat0_part=$(git diff --stat HEAD^ HEAD) &&
+ stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
+ printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n\0" >expected &&
+ git log -z --stat --pretty="tformat:%s" >actual &&
+ test_i18ncmp expected actual
+'
+
test_done
diff --git a/t/t4253-am-keep-cr-dos.sh b/t/t4253-am-keep-cr-dos.sh
index 735e55d77c..553fe3e88e 100755
--- a/t/t4253-am-keep-cr-dos.sh
+++ b/t/t4253-am-keep-cr-dos.sh
@@ -62,7 +62,7 @@ test_expect_success 'am with dos files config am.keepcr' '
git diff --exit-code master
'
-test_expect_success 'am with dos files config am.keepcr overriden by --no-keep-cr' '
+test_expect_success 'am with dos files config am.keepcr overridden by --no-keep-cr' '
git config am.keepcr 1 &&
git checkout -b dosfiles-conf-keepcr-override initial &&
git format-patch -k initial..master &&
@@ -83,7 +83,7 @@ test_expect_success 'am with dos files with --keep-cr continue' '
git diff --exit-code master
'
-test_expect_success 'am with unix files config am.keepcr overriden by --no-keep-cr' '
+test_expect_success 'am with unix files config am.keepcr overridden by --no-keep-cr' '
git config am.keepcr 1 &&
git checkout -b unixfiles-conf-keepcr-override initial &&
cp -f file1 file &&
diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh
index 46c3fe76d3..d0b2a457b8 100755
--- a/t/t4300-merge-tree.sh
+++ b/t/t4300-merge-tree.sh
@@ -254,4 +254,48 @@ EXPECTED
test_cmp expected actual
'
+test_expect_success 'turn file to tree' '
+ git reset --hard initial &&
+ rm initial-file &&
+ mkdir initial-file &&
+ test_commit "turn-file-to-tree" "initial-file/ONE" "CCC" &&
+ git merge-tree initial initial turn-file-to-tree >actual &&
+ cat >expect <<-\EOF &&
+ added in remote
+ their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 initial-file/ONE
+ @@ -0,0 +1 @@
+ +CCC
+ removed in remote
+ base 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
+ our 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
+ @@ -1 +0,0 @@
+ -initial
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'turn tree to file' '
+ git reset --hard initial &&
+ mkdir dir &&
+ test_commit "add-tree" "dir/path" "AAA" &&
+ test_commit "add-another-tree" "dir/another" "BBB" &&
+ rm -fr dir &&
+ test_commit "make-file" "dir" "CCC" &&
+ git merge-tree add-tree add-another-tree make-file >actual &&
+ cat >expect <<-\EOF &&
+ added in local
+ our 100644 ba629238ca89489f2b350e196ca445e09d8bb834 dir/another
+ removed in remote
+ base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path
+ our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path
+ @@ -1 +0,0 @@
+ -AAA
+ added in remote
+ their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 dir
+ @@ -0,0 +1 @@
+ +CCC
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 527c9e7548..e7c240fc1f 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -25,7 +25,6 @@ commit id embedding:
'
. ./test-lib.sh
-UNZIP=${UNZIP:-unzip}
GZIP=${GZIP:-gzip}
GUNZIP=${GUNZIP:-gzip -d}
@@ -84,6 +83,12 @@ test_expect_success \
'git archive vs. git tar-tree' \
'test_cmp b.tar b2.tar'
+test_expect_success 'git archive on large files' '
+ test_config core.bigfilethreshold 1 &&
+ git archive HEAD >b3.tar &&
+ test_cmp b.tar b3.tar
+'
+
test_expect_success \
'git archive in a bare repo' \
'(cd bare.git && git archive HEAD) >b3.tar'
@@ -175,69 +180,11 @@ test_expect_success \
test_cmp a/substfile2 g/prefix/a/substfile2
'
-test_expect_success \
- 'git archive --format=zip' \
- 'git archive --format=zip HEAD >d.zip'
-
-test_expect_success \
- 'git archive --format=zip in a bare repo' \
- '(cd bare.git && git archive --format=zip HEAD) >d1.zip'
-
-test_expect_success \
- 'git archive --format=zip vs. the same in a bare repo' \
- 'test_cmp d.zip d1.zip'
-
-test_expect_success 'git archive --format=zip with --output' \
- 'git archive --format=zip --output=d2.zip HEAD &&
- test_cmp d.zip d2.zip'
-
-test_expect_success 'git archive with --output, inferring format' '
- git archive --output=d3.zip HEAD &&
- test_cmp d.zip d3.zip
-'
-
test_expect_success 'git archive with --output, override inferred format' '
git archive --format=tar --output=d4.zip HEAD &&
test_cmp b.tar d4.zip
'
-$UNZIP -v >/dev/null 2>&1
-if [ $? -eq 127 ]; then
- say "Skipping ZIP tests, because unzip was not found"
-else
- test_set_prereq UNZIP
-fi
-
-test_expect_success UNZIP \
- 'extract ZIP archive' \
- '(mkdir d && cd d && $UNZIP ../d.zip)'
-
-test_expect_success UNZIP \
- 'validate filenames' \
- '(cd d/a && find .) | sort >d.lst &&
- test_cmp a.lst d.lst'
-
-test_expect_success UNZIP \
- 'validate file contents' \
- 'diff -r a d/a'
-
-test_expect_success \
- 'git archive --format=zip with prefix' \
- 'git archive --format=zip --prefix=prefix/ HEAD >e.zip'
-
-test_expect_success UNZIP \
- 'extract ZIP archive with prefix' \
- '(mkdir e && cd e && $UNZIP ../e.zip)'
-
-test_expect_success UNZIP \
- 'validate filenames with prefix' \
- '(cd e/prefix/a && find .) | sort >e.lst &&
- test_cmp a.lst e.lst'
-
-test_expect_success UNZIP \
- 'validate file contents with prefix' \
- 'diff -r a e/prefix/a'
-
test_expect_success \
'git archive --list outside of a git repo' \
'GIT_DIR=some/non-existing/directory git archive --list'
diff --git a/t/t5002-archive-attr-pattern.sh b/t/t5002-archive-attr-pattern.sh
new file mode 100755
index 0000000000..0c847fb454
--- /dev/null
+++ b/t/t5002-archive-attr-pattern.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+test_description='git archive attribute pattern tests'
+
+. ./test-lib.sh
+
+test_expect_exists() {
+ test_expect_success " $1 exists" "test -e $1"
+}
+
+test_expect_missing() {
+ test_expect_success " $1 does not exist" "test ! -e $1"
+}
+
+test_expect_success 'setup' '
+ echo ignored >ignored &&
+ echo ignored export-ignore >>.git/info/attributes &&
+ git add ignored &&
+
+ mkdir not-ignored-dir &&
+ echo ignored-in-tree >not-ignored-dir/ignored &&
+ echo not-ignored-in-tree >not-ignored-dir/ignored-only-if-dir &&
+ git add not-ignored-dir &&
+
+ mkdir ignored-only-if-dir &&
+ echo ignored by ignored dir >ignored-only-if-dir/ignored-by-ignored-dir &&
+ echo ignored-only-if-dir/ export-ignore >>.git/info/attributes &&
+ git add ignored-only-if-dir &&
+
+
+ mkdir -p one-level-lower/two-levels-lower/ignored-only-if-dir &&
+ echo ignored by ignored dir >one-level-lower/two-levels-lower/ignored-only-if-dir/ignored-by-ignored-dir &&
+ git add one-level-lower &&
+
+ git commit -m. &&
+
+ git clone --bare . bare &&
+ cp .git/info/attributes bare/info/attributes
+'
+
+test_expect_success 'git archive' '
+ git archive HEAD >archive.tar &&
+ (mkdir archive && cd archive && "$TAR" xf -) <archive.tar
+'
+
+test_expect_missing archive/ignored
+test_expect_missing archive/not-ignored-dir/ignored
+test_expect_exists archive/not-ignored-dir/ignored-only-if-dir
+test_expect_exists archive/not-ignored-dir/
+test_expect_missing archive/ignored-only-if-dir/
+test_expect_missing archive/ignored-ony-if-dir/ignored-by-ignored-dir
+test_expect_exists archive/one-level-lower/
+test_expect_missing archive/one-level-lower/two-levels-lower/ignored-only-if-dir/
+test_expect_missing archive/one-level-lower/two-levels-lower/ignored-ony-if-dir/ignored-by-ignored-dir
+
+
+test_done
diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh
new file mode 100755
index 0000000000..7cfe9ca3da
--- /dev/null
+++ b/t/t5003-archive-zip.sh
@@ -0,0 +1,131 @@
+#!/bin/sh
+
+test_description='git archive --format=zip test'
+
+. ./test-lib.sh
+GIT_UNZIP=${GIT_UNZIP:-unzip}
+
+SUBSTFORMAT=%H%n
+
+test_lazy_prereq UNZIP '
+ "$GIT_UNZIP" -v
+ test $? -ne 127
+'
+
+test_lazy_prereq UNZIP_SYMLINKS '
+ (
+ mkdir unzip-symlinks &&
+ cd unzip-symlinks &&
+ "$GIT_UNZIP" "$TEST_DIRECTORY"/t5003/infozip-symlinks.zip &&
+ test -h symlink
+ )
+'
+
+check_zip() {
+ zipfile=$1.zip
+ listfile=$1.lst
+ dir=$1
+ dir_with_prefix=$dir/$2
+
+ test_expect_success UNZIP " extract ZIP archive" '
+ (mkdir $dir && cd $dir && "$GIT_UNZIP" ../$zipfile)
+ '
+
+ test_expect_success UNZIP " validate filenames" "
+ (cd ${dir_with_prefix}a && find .) | sort >$listfile &&
+ test_cmp a.lst $listfile
+ "
+
+ test_expect_success UNZIP " validate file contents" "
+ diff -r a ${dir_with_prefix}a
+ "
+}
+
+test_expect_success \
+ 'populate workdir' \
+ 'mkdir a b c &&
+ echo simple textfile >a/a &&
+ mkdir a/bin &&
+ cp /bin/sh a/bin &&
+ printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 &&
+ printf "A not substituted O" >a/substfile2 &&
+ (p=long_path_to_a_file && cd a &&
+ for depth in 1 2 3 4 5; do mkdir $p && cd $p; done &&
+ echo text >file_with_long_path)
+'
+
+test_expect_success SYMLINKS,UNZIP_SYMLINKS 'add symlink' '
+ ln -s a a/symlink_to_a
+'
+
+test_expect_success 'prepare file list' '
+ (cd a && find .) | sort >a.lst
+'
+
+test_expect_success \
+ 'add ignored file' \
+ 'echo ignore me >a/ignored &&
+ echo ignored export-ignore >.git/info/attributes'
+
+test_expect_success \
+ 'add files to repository' \
+ 'find a -type f | xargs git update-index --add &&
+ find a -type l | xargs git update-index --add &&
+ treeid=`git write-tree` &&
+ echo $treeid >treeid &&
+ git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE="2005-05-27 22:00:00" \
+ git commit-tree $treeid </dev/null)'
+
+test_expect_success \
+ 'create bare clone' \
+ 'git clone --bare . bare.git &&
+ cp .git/info/attributes bare.git/info/attributes'
+
+test_expect_success \
+ 'remove ignored file' \
+ 'rm a/ignored'
+
+test_expect_success \
+ 'git archive --format=zip' \
+ 'git archive --format=zip HEAD >d.zip'
+
+check_zip d
+
+test_expect_success \
+ 'git archive --format=zip in a bare repo' \
+ '(cd bare.git && git archive --format=zip HEAD) >d1.zip'
+
+test_expect_success \
+ 'git archive --format=zip vs. the same in a bare repo' \
+ 'test_cmp d.zip d1.zip'
+
+test_expect_success 'git archive --format=zip with --output' \
+ 'git archive --format=zip --output=d2.zip HEAD &&
+ test_cmp d.zip d2.zip'
+
+test_expect_success 'git archive with --output, inferring format' '
+ git archive --output=d3.zip HEAD &&
+ test_cmp d.zip d3.zip
+'
+
+test_expect_success \
+ 'git archive --format=zip with prefix' \
+ 'git archive --format=zip --prefix=prefix/ HEAD >e.zip'
+
+check_zip e prefix/
+
+test_expect_success 'git archive -0 --format=zip on large files' '
+ test_config core.bigfilethreshold 1 &&
+ git archive -0 --format=zip HEAD >large.zip
+'
+
+check_zip large
+
+test_expect_success 'git archive --format=zip on large files' '
+ test_config core.bigfilethreshold 1 &&
+ git archive --format=zip HEAD >large-compressed.zip
+'
+
+check_zip large-compressed
+
+test_done
diff --git a/t/t5003/infozip-symlinks.zip b/t/t5003/infozip-symlinks.zip
new file mode 100644
index 0000000000..065728c631
--- /dev/null
+++ b/t/t5003/infozip-symlinks.zip
Binary files differ
diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh
index 81904d9ec8..3e64a7a65d 100755
--- a/t/t5100-mailinfo.sh
+++ b/t/t5100-mailinfo.sh
@@ -11,7 +11,7 @@ test_expect_success 'split sample box' \
'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last &&
last=`cat last` &&
echo total is $last &&
- test `cat last` = 16'
+ test `cat last` = 17'
check_mailinfo () {
mail=$1 opt=$2
diff --git a/t/t5100/info0017 b/t/t5100/info0017
new file mode 100644
index 0000000000..d2bc89ffe9
--- /dev/null
+++ b/t/t5100/info0017
@@ -0,0 +1,5 @@
+Author: A U Thor
+Email: a.u.thor@example.com
+Subject: A E I O U
+Date: Mon, 17 Sep 2012 14:23:44 -0700
+
diff --git a/t/t5100/msg0017 b/t/t5100/msg0017
new file mode 100644
index 0000000000..2ee0900850
--- /dev/null
+++ b/t/t5100/msg0017
@@ -0,0 +1,2 @@
+New content here
+
diff --git a/t/t5100/patch0001 b/t/t5100/patch0001
index 8ce155167d..02c97746d6 100644
--- a/t/t5100/patch0001
+++ b/t/t5100/patch0001
@@ -1,5 +1,5 @@
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
diff --git a/t/t5100/patch0002 b/t/t5100/patch0002
index 8ce155167d..02c97746d6 100644
--- a/t/t5100/patch0002
+++ b/t/t5100/patch0002
@@ -1,5 +1,5 @@
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
diff --git a/t/t5100/patch0003 b/t/t5100/patch0003
index 8ce155167d..02c97746d6 100644
--- a/t/t5100/patch0003
+++ b/t/t5100/patch0003
@@ -1,5 +1,5 @@
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
diff --git a/t/t5100/patch0005 b/t/t5100/patch0005
index 7d24b24af8..ab7a38373b 100644
--- a/t/t5100/patch0005
+++ b/t/t5100/patch0005
@@ -1,7 +1,7 @@
---
- Documentation/git-cvsimport-script.txt | 9 ++++++++-
- git-cvsimport-script | 4 ++--
+ Documentation/git-cvsimport-script.txt | 9 ++++++++-
+ git-cvsimport-script | 4 ++--
2 files changed, 10 insertions(+), 3 deletions(-)
50452f9c0c2df1f04d83a26266ba704b13861632
diff --git a/t/t5100/patch0006 b/t/t5100/patch0006
index 8ce155167d..02c97746d6 100644
--- a/t/t5100/patch0006
+++ b/t/t5100/patch0006
@@ -1,5 +1,5 @@
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
diff --git a/t/t5100/patch0010 b/t/t5100/patch0010
index f055481d56..436821c97a 100644
--- a/t/t5100/patch0010
+++ b/t/t5100/patch0010
@@ -1,5 +1,5 @@
---
- builtin-mailinfo.c | 2 +-
+ builtin-mailinfo.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/patch0011 b/t/t5100/patch0011
index 8841d3c139..0988713761 100644
--- a/t/t5100/patch0011
+++ b/t/t5100/patch0011
@@ -1,5 +1,5 @@
---
- builtin-mailinfo.c | 4 ++--
+ builtin-mailinfo.c | 4 ++--
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 3e5fe51..aabfe5c 100644
diff --git a/t/t5100/patch0014 b/t/t5100/patch0014
index 124efd234f..3f3825f9f2 100644
--- a/t/t5100/patch0014
+++ b/t/t5100/patch0014
@@ -1,5 +1,5 @@
---
- builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
1 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/patch0014--scissors b/t/t5100/patch0014--scissors
index 124efd234f..3f3825f9f2 100644
--- a/t/t5100/patch0014--scissors
+++ b/t/t5100/patch0014--scissors
@@ -1,5 +1,5 @@
---
- builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
1 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/patch0017 b/t/t5100/patch0017
new file mode 100644
index 0000000000..35cf84c9a1
--- /dev/null
+++ b/t/t5100/patch0017
@@ -0,0 +1,6 @@
+diff --git a/foo b/foo
+index e69de29..d95f3ad 100644
+--- a/foo
++++ b/foo
+@@ -0,0 +1 @@
++New content
diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox
index de1031241d..8b2ae064c3 100644
--- a/t/t5100/sample.mbox
+++ b/t/t5100/sample.mbox
@@ -12,7 +12,7 @@ Subject: [PATCH] a commit.
Here is a patch from A U Thor.
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
@@ -52,7 +52,7 @@ two truly blank and another full of spaces in between.
Hope this helps.
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
@@ -83,7 +83,7 @@ Message-Id: <nitpicker.12121212@example.net>
Hopefully this would fix the problem stated there.
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
@@ -249,8 +249,8 @@ actual flags.
Signed-off-by: David K=E5gedal <davidk@lysator.liu.se>
---
- Documentation/git-cvsimport-script.txt | 9 ++++++++-
- git-cvsimport-script | 4 ++--
+ Documentation/git-cvsimport-script.txt | 9 ++++++++-
+ git-cvsimport-script | 4 ++--
2 files changed, 10 insertions(+), 3 deletions(-)
50452f9c0c2df1f04d83a26266ba704b13861632
@@ -379,7 +379,7 @@ Subject: [PATCH] a commit.
Here is a patch from A U Thor.
---
- foo | 2 +-
+ foo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/foo b/foo
@@ -449,7 +449,7 @@ memcmp("Subject: ", header[i], 7) will never match.
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
- builtin-mailinfo.c | 2 +-
+ builtin-mailinfo.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
@@ -482,7 +482,7 @@ Content-Transfer-Encoding: quoted-printable
Here comes a commit log message, and
its second line is here.
---
- builtin-mailinfo.c | 4 ++--
+ builtin-mailinfo.c | 4 ++--
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 3e5fe51..aabfe5c 100644
@@ -587,7 +587,7 @@ everything before it in the message body.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
- builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
1 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
@@ -683,3 +683,19 @@ index e69de29..d95f3ad 100644
@@ -0,0 +1 @@
+content
+From nobody Mon Sep 17 00:00:00 2001
+From: A U Thor <a.u.thor@example.com>
+Subject: A E I O U
+Date: Mon, 17 Sep 2012 14:23:44 -0700
+MIME-Version: 1.0
+Content-Type: text/plain; charset="iso-2022-jp"
+Content-type: text/plain; charset="UTF-8"
+
+New content here
+
+diff --git a/foo b/foo
+index e69de29..d95f3ad 100644
+--- a/foo
++++ b/foo
+@@ -0,0 +1 @@
++New content
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index d9d856b87b..a07c871797 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -13,9 +13,9 @@ TRASH=`pwd`
test_expect_success \
'setup' \
'rm -f .git/index* &&
- perl -e "print \"a\" x 4096;" > a &&
- perl -e "print \"b\" x 4096;" > b &&
- perl -e "print \"c\" x 4096;" > c &&
+ "$PERL_PATH" -e "print \"a\" x 4096;" > a &&
+ "$PERL_PATH" -e "print \"b\" x 4096;" > b &&
+ "$PERL_PATH" -e "print \"c\" x 4096;" > c &&
test-genrandom "seed a" 2097152 > a_big &&
test-genrandom "seed b" 2097152 > b_big &&
git update-index --add a a_big b b_big c &&
@@ -129,7 +129,7 @@ test_expect_success \
cd "$TRASH"
test_expect_success 'compare delta flavors' '
- perl -e '\''
+ "$PERL_PATH" -e '\''
defined($_ = -s $_) or die for @ARGV;
exit 1 if $ARGV[0] <= $ARGV[1];
'\'' test-2-$packname_2.pack test-3-$packname_3.pack
@@ -416,6 +416,11 @@ test_expect_success \
test_expect_success \
'make sure index-pack detects the SHA1 collision' \
'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg &&
- grep "SHA1 COLLISION FOUND" msg'
+ test_i18ngrep "SHA1 COLLISION FOUND" msg'
+
+test_expect_success \
+ 'make sure index-pack detects the SHA1 collision (large blobs)' \
+ 'test_must_fail git -c core.bigfilethreshold=1 index-pack -o bad.idx test-3.pack 2>msg &&
+ test_i18ngrep "SHA1 COLLISION FOUND" msg'
test_done
diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh
index 5f6cd4f333..5b1250f0d2 100755
--- a/t/t5303-pack-corruption-resilience.sh
+++ b/t/t5303-pack-corruption-resilience.sh
@@ -98,7 +98,7 @@ test_expect_success \
'create_new_pack &&
git prune-packed &&
chmod +w ${pack}.pack &&
- perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
+ "$PERL_PATH" -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
test_must_fail git cat-file blob $blob_1 > /dev/null &&
test_must_fail git cat-file blob $blob_2 > /dev/null &&
test_must_fail git cat-file blob $blob_3 > /dev/null'
@@ -155,7 +155,7 @@ test_expect_success \
'create_new_pack &&
git prune-packed &&
chmod +w ${pack}.pack &&
- perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
+ "$PERL_PATH" -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
git cat-file blob $blob_1 > /dev/null &&
test_must_fail git cat-file blob $blob_2 > /dev/null &&
test_must_fail git cat-file blob $blob_3 > /dev/null'
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 0eace37a03..129fc88bd2 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -145,6 +145,40 @@ test_expect_success 'push --all excludes remote-tracking hierarchy' '
)
'
+test_expect_success 'receive-pack runs auto-gc in remote repo' '
+ rm -rf parent child &&
+ git init parent &&
+ (
+ # Setup a repo with 2 packs
+ cd parent &&
+ echo "Some text" >file.txt &&
+ git add . &&
+ git commit -m "Initial commit" &&
+ git repack -adl &&
+ echo "Some more text" >>file.txt &&
+ git commit -a -m "Second commit" &&
+ git repack
+ ) &&
+ cp -R parent child &&
+ (
+ # Set the child to auto-pack if more than one pack exists
+ cd child &&
+ git config gc.autopacklimit 1 &&
+ git branch test_auto_gc &&
+ # And create a file that follows the temporary object naming
+ # convention for the auto-gc to remove
+ : >.git/objects/tmp_test_object &&
+ test-chmtime =-1209601 .git/objects/tmp_test_object
+ ) &&
+ (
+ cd parent &&
+ echo "Even more text" >>file.txt &&
+ git commit -a -m "Third commit" &&
+ git send-pack ../child HEAD:refs/heads/test_auto_gc
+ ) &&
+ test ! -e child/.git/objects/tmp_test_object
+'
+
rewound_push_setup() {
rm -rf parent child &&
mkdir parent &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 1d1ca98588..6322e8ade8 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -125,6 +125,11 @@ test_expect_success 'single branch object count' '
test_cmp expected count.singlebranch
'
+test_expect_success 'single given branch clone' '
+ git clone --single-branch --branch A "file://$(pwd)/." branch-a &&
+ test_must_fail git --git-dir=branch-a/.git rev-parse origin/B
+'
+
test_expect_success 'clone shallow' '
git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
'
@@ -276,7 +281,7 @@ test_expect_success 'clone shallow with --branch' '
'
test_expect_success 'clone shallow object count' '
- echo "in-pack: 12" > count3.expected &&
+ echo "in-pack: 6" > count3.expected &&
GIT_DIR=shallow3/.git git count-objects -v |
grep "^in-pack" > count3.actual &&
test_cmp count3.expected count3.actual
@@ -386,10 +391,55 @@ test_expect_success 'fetch mixed refs from cmdline and stdin' '
test_expect_success 'test duplicate refs from stdin' '
(
cd client &&
- test_must_fail git fetch-pack --stdin --no-progress .. <../input.dup
+ git fetch-pack --stdin --no-progress .. <../input.dup
) >output &&
cut -d " " -f 2 <output | sort >actual &&
test_cmp expect actual
'
+test_expect_success 'set up tests of missing reference' '
+ cat >expect-error <<-\EOF
+ error: no such remote ref refs/heads/xyzzy
+ EOF
+'
+
+test_expect_success 'test lonely missing ref' '
+ (
+ cd client &&
+ test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy
+ ) >/dev/null 2>error-m &&
+ test_cmp expect-error error-m
+'
+
+test_expect_success 'test missing ref after existing' '
+ (
+ cd client &&
+ test_must_fail git fetch-pack --no-progress .. refs/heads/A refs/heads/xyzzy
+ ) >/dev/null 2>error-em &&
+ test_cmp expect-error error-em
+'
+
+test_expect_success 'test missing ref before existing' '
+ (
+ cd client &&
+ test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy refs/heads/A
+ ) >/dev/null 2>error-me &&
+ test_cmp expect-error error-me
+'
+
+test_expect_success 'test --all, --depth, and explicit head' '
+ (
+ cd client &&
+ git fetch-pack --no-progress --all --depth=1 .. refs/heads/A
+ ) >out-adh 2>error-adh
+'
+
+test_expect_success 'test --all, --depth, and explicit tag' '
+ git tag OLDTAG refs/heads/B~5 &&
+ (
+ cd client &&
+ git fetch-pack --no-progress --all --depth=1 .. refs/tags/OLDTAG
+ ) >out-adt 2>error-adt
+'
+
test_done
diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh
index 35ec294d9a..69ee13c8be 100755
--- a/t/t5504-fetch-receive-strict.sh
+++ b/t/t5504-fetch-receive-strict.sh
@@ -89,7 +89,7 @@ test_expect_success 'push with !receive.fsckobjects' '
cat >exp <<EOF
To dst
-! refs/heads/master:refs/heads/test [remote rejected] (n/a (unpacker error))
+! refs/heads/master:refs/heads/test [remote rejected] (unpacker error)
EOF
test_expect_success 'push with receive.fsckobjects' '
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index e8af615e6d..ccc55ebf4b 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -52,7 +52,7 @@ test_expect_success setup '
'
-test_expect_success 'remote information for the origin' '
+test_expect_success C_LOCALE_OUTPUT 'remote information for the origin' '
(
cd test &&
tokens_match origin "$(git remote)" &&
@@ -66,8 +66,6 @@ test_expect_success 'add another remote' '
cd test &&
git remote add -f second ../two &&
tokens_match "origin second" "$(git remote)" &&
- check_remote_track origin master side &&
- check_remote_track second master side another &&
check_tracking_branch second master side another &&
git for-each-ref "--format=%(refname)" refs/remotes |
sed -e "/^refs\/remotes\/origin\//d" \
@@ -77,6 +75,14 @@ test_expect_success 'add another remote' '
)
'
+test_expect_success C_LOCALE_OUTPUT 'check remote tracking' '
+(
+ cd test &&
+ check_remote_track origin master side &&
+ check_remote_track second master side another
+)
+'
+
test_expect_success 'remote forces tracking branches' '
(
cd test &&
@@ -95,7 +101,7 @@ test_expect_success 'remove remote' '
)
'
-test_expect_success 'remove remote' '
+test_expect_success C_LOCALE_OUTPUT 'remove remote' '
(
cd test &&
tokens_match origin "$(git remote)" &&
@@ -125,14 +131,14 @@ EOF
} &&
git tag footag &&
git config --add remote.oops.fetch "+refs/*:refs/*" &&
- git remote rm oops 2>actual1 &&
+ git remote remove oops 2>actual1 &&
git branch foobranch &&
git config --add remote.oops.fetch "+refs/*:refs/*" &&
git remote rm oops 2>actual2 &&
git branch -d foobranch &&
git tag -d footag &&
- test_cmp expect1 actual1 &&
- test_cmp expect2 actual2
+ test_i18ncmp expect1 actual1 &&
+ test_i18ncmp expect2 actual2
)
'
@@ -192,7 +198,7 @@ test_expect_success 'show' '
git config --add remote.two.push refs/heads/master:refs/heads/another &&
git remote show origin two > output &&
git branch -d rebase octopus &&
- test_cmp expect output)
+ test_i18ncmp expect output)
'
cat > test/expect << EOF
@@ -217,7 +223,7 @@ test_expect_success 'show -n' '
cd test &&
git remote show -n origin > output &&
mv ../one.unreachable ../one &&
- test_cmp expect output)
+ test_i18ncmp expect output)
'
test_expect_success 'prune' '
@@ -255,7 +261,7 @@ EOF
test_expect_success 'set-head --auto fails w/multiple HEADs' '
(cd test &&
test_must_fail git remote set-head --auto two >output 2>&1 &&
- test_cmp expect output)
+ test_i18ncmp expect output)
'
cat >test/expect <<EOF
@@ -285,7 +291,7 @@ test_expect_success 'prune --dry-run' '
test_must_fail git rev-parse refs/remotes/origin/side &&
(cd ../one &&
git branch -m side side2) &&
- test_cmp expect output)
+ test_i18ncmp expect output)
'
test_expect_success 'add --mirror && prune' '
@@ -672,7 +678,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
git clone one five &&
origin_url=$(pwd)/one &&
(cd five &&
- git remote rm origin &&
+ git remote remove origin &&
mkdir -p .git/remotes &&
cat ../remotes_origin > .git/remotes/origin &&
git remote rename origin origin &&
@@ -705,7 +711,7 @@ test_expect_success 'remote prune to cause a dangling symref' '
cd seven &&
git remote prune origin
) >err 2>&1 &&
- grep "has become dangling" err &&
+ test_i18ngrep "has become dangling" err &&
: And the dangling symref will not cause other annoying errors &&
(
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 6764d511ce..d16e5d384a 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -87,17 +87,15 @@ test_expect_success 'use branch.<name>.remote if possible' '
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
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
EOF
#
- # Do not expect "git ls-remote <pattern>" to work; ls-remote, correctly,
- # confuses <pattern> for <remote>. Although ugly, this behaviour is akin
- # to the confusion of refspecs for remotes by git-fetch and git-push,
- # eg:
- #
- # $ git fetch branch
- #
-
+ # Do not expect "git ls-remote <pattern>" to work; ls-remote needs
+ # <remote> if you want to feed <pattern>, just like you cannot say
+ # fetch <branch>.
# We could just as easily have used "master"; the "*" emphasizes its
# role as a pattern.
test_must_fail git ls-remote refs*master >actual 2>&1 &&
diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh
index 227dd56137..0f8140957f 100755
--- a/t/t5514-fetch-multiple.sh
+++ b/t/t5514-fetch-multiple.sh
@@ -151,4 +151,34 @@ test_expect_success 'git fetch --multiple (ignoring skipFetchAll)' '
test_cmp ../expect output)
'
+test_expect_success 'git fetch --all --no-tags' '
+ >expect &&
+ git clone one test5 &&
+ git clone test5 test6 &&
+ (cd test5 && git tag test-tag) &&
+ (
+ cd test6 &&
+ git fetch --all --no-tags &&
+ git tag >output
+ ) &&
+ test_cmp expect test6/output
+'
+
+test_expect_success 'git fetch --all --tags' '
+ echo test-tag >expect &&
+ git clone one test7 &&
+ git clone test7 test8 &&
+ (
+ cd test7 &&
+ test_commit test-tag &&
+ git reset --hard HEAD^
+ ) &&
+ (
+ cd test8 &&
+ git fetch --all --tags &&
+ git tag >output
+ ) &&
+ test_cmp expect test8/output
+'
+
test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index b5417cc951..60093728fe 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -368,7 +368,7 @@ test_expect_success 'push with colon-less refspec (2)' '
git branch -D frotz
fi &&
git tag -f frotz &&
- git push testrepo frotz &&
+ git push -f testrepo frotz &&
check_push_result $the_commit tags/frotz &&
check_push_result $the_first_commit heads/frotz
@@ -929,6 +929,48 @@ test_expect_success 'push into aliased refs (inconsistent)' '
)
'
+test_expect_success 'push requires --force to update lightweight tag' '
+ mk_test heads/master &&
+ mk_child child1 &&
+ mk_child child2 &&
+ (
+ cd child1 &&
+ git tag Tag &&
+ git push ../child2 Tag &&
+ git push ../child2 Tag &&
+ >file1 &&
+ git add file1 &&
+ git commit -m "file1" &&
+ git tag -f Tag &&
+ test_must_fail git push ../child2 Tag &&
+ git push --force ../child2 Tag &&
+ git tag -f Tag &&
+ test_must_fail git push ../child2 Tag HEAD~ &&
+ git push --force ../child2 Tag
+ )
+'
+
+test_expect_success 'push requires --force to update annotated tag' '
+ mk_test heads/master &&
+ mk_child child1 &&
+ mk_child child2 &&
+ (
+ cd child1 &&
+ git tag -a -m "message 1" Tag &&
+ git push ../child2 Tag:refs/tmp/Tag &&
+ git push ../child2 Tag:refs/tmp/Tag &&
+ >file1 &&
+ git add file1 &&
+ git commit -m "file1" &&
+ git tag -f -a -m "message 2" Tag &&
+ test_must_fail git push ../child2 Tag:refs/tmp/Tag &&
+ git push --force ../child2 Tag:refs/tmp/Tag &&
+ git tag -f -a -m "message 3" Tag HEAD~ &&
+ test_must_fail git push ../child2 Tag:refs/tmp/Tag &&
+ git push --force ../child2 Tag:refs/tmp/Tag
+ )
+'
+
test_expect_success 'push --porcelain' '
mk_empty &&
echo >.git/foo "To testrepo" &&
diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh
index c334c51a07..4736da8f36 100755
--- a/t/t5528-push-default.sh
+++ b/t/t5528-push-default.sh
@@ -13,16 +13,36 @@ test_expect_success 'setup bare remotes' '
git push parent2 HEAD
'
+# $1 = local revision
+# $2 = remote revision (tested to be equal to the local one)
+check_pushed_commit () {
+ git log -1 --format='%h %s' "$1" >expect &&
+ git --git-dir=repo1 log -1 --format='%h %s' "$2" >actual &&
+ test_cmp expect actual
+}
+
+# $1 = push.default value
+# $2 = expected target branch for the push
+test_push_success () {
+ git -c push.default="$1" push &&
+ check_pushed_commit HEAD "$2"
+}
+
+# $1 = push.default value
+# check that push fails and does not modify any remote branch
+test_push_failure () {
+ git --git-dir=repo1 log --no-walk --format='%h %s' --all >expect &&
+ test_must_fail git -c push.default="$1" push &&
+ git --git-dir=repo1 log --no-walk --format='%h %s' --all >actual &&
+ test_cmp expect actual
+}
+
test_expect_success '"upstream" pushes to configured upstream' '
git checkout master &&
test_config branch.master.remote parent1 &&
test_config branch.master.merge refs/heads/foo &&
- test_config push.default upstream &&
test_commit two &&
- git push &&
- echo two >expect &&
- git --git-dir=repo1 log -1 --format=%s foo >actual &&
- test_cmp expect actual
+ test_push_success upstream foo
'
test_expect_success '"upstream" does not push on unconfigured remote' '
@@ -30,7 +50,7 @@ test_expect_success '"upstream" does not push on unconfigured remote' '
test_unconfig branch.master.remote &&
test_config push.default upstream &&
test_commit three &&
- test_must_fail git push
+ test_push_failure upstream
'
test_expect_success '"upstream" does not push on unconfigured branch' '
@@ -39,7 +59,7 @@ test_expect_success '"upstream" does not push on unconfigured branch' '
test_unconfig branch.master.merge &&
test_config push.default upstream
test_commit four &&
- test_must_fail git push
+ test_push_failure upstream
'
test_expect_success '"upstream" does not push when remotes do not match' '
@@ -51,4 +71,48 @@ test_expect_success '"upstream" does not push when remotes do not match' '
test_must_fail git push parent2
'
+test_expect_success 'push from/to new branch with upstream, matching and simple' '
+ git checkout -b new-branch &&
+ test_push_failure simple &&
+ test_push_failure matching &&
+ test_push_failure upstream
+'
+
+test_expect_success 'push from/to new branch with current creates remote branch' '
+ test_config branch.new-branch.remote repo1 &&
+ git checkout new-branch &&
+ test_push_success current new-branch
+'
+
+test_expect_success 'push to existing branch, with no upstream configured' '
+ test_config branch.master.remote repo1 &&
+ git checkout master &&
+ test_push_failure simple &&
+ test_push_failure upstream
+'
+
+test_expect_success 'push to existing branch, upstream configured with same name' '
+ test_config branch.master.remote repo1 &&
+ test_config branch.master.merge refs/heads/master &&
+ git checkout master &&
+ test_commit six &&
+ test_push_success upstream master &&
+ test_commit seven &&
+ test_push_success simple master
+'
+
+test_expect_success 'push to existing branch, upstream configured with different name' '
+ test_config branch.master.remote repo1 &&
+ test_config branch.master.merge refs/heads/other-name &&
+ git checkout master &&
+ test_commit eight &&
+ test_push_success upstream other-name &&
+ test_commit nine &&
+ test_push_failure simple &&
+ git --git-dir=repo1 log -1 --format="%h %s" "other-name" >expect-other-name &&
+ test_push_success current master &&
+ git --git-dir=repo1 log -1 --format="%h %s" "other-name" >actual-other-name &&
+ test_cmp expect-other-name actual-other-name
+'
+
test_done
diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh
index 6b2a5f4a65..c983d3694c 100755
--- a/t/t5530-upload-pack-error.sh
+++ b/t/t5530-upload-pack-error.sh
@@ -35,8 +35,8 @@ test_expect_success 'upload-pack fails due to error in pack-objects packing' '
printf "0032want %s\n00000009done\n0000" \
$(git rev-parse HEAD) >input &&
test_must_fail git upload-pack . <input >/dev/null 2>output.err &&
- grep "unable to read" output.err &&
- grep "pack-objects died" output.err
+ test_i18ngrep "unable to read" output.err &&
+ test_i18ngrep "pack-objects died" output.err
'
test_expect_success 'corrupt repo differently' '
diff --git a/t/t5532-fetch-proxy.sh b/t/t5532-fetch-proxy.sh
index 62f2460047..5531bd1af4 100755
--- a/t/t5532-fetch-proxy.sh
+++ b/t/t5532-fetch-proxy.sh
@@ -15,7 +15,7 @@ test_expect_success 'setup remote repo' '
cat >proxy <<'EOF'
#!/bin/sh
echo >&2 "proxying for $*"
-cmd=`perl -e '
+cmd=`"$PERL_PATH" -e '
read(STDIN, $buf, 4);
my $n = hex($buf) - 4;
read(STDIN, $buf, $n);
diff --git a/t/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh
new file mode 100755
index 0000000000..8ed58d27f2
--- /dev/null
+++ b/t/t5535-fetch-push-symref.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+test_description='avoiding conflicting update thru symref aliasing'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit one &&
+ git clone . src &&
+ git clone src dst1 &&
+ git clone src dst2 &&
+ test_commit two &&
+ ( cd src && git pull )
+'
+
+test_expect_success 'push' '
+ (
+ cd src &&
+ git push ../dst1 "refs/remotes/*:refs/remotes/*"
+ ) &&
+ git ls-remote src "refs/remotes/*" >expect &&
+ git ls-remote dst1 "refs/remotes/*" >actual &&
+ test_cmp expect actual &&
+ ( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect &&
+ ( cd dst1 && git symbolic-ref refs/remotes/origin/HEAD ) >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'fetch' '
+ (
+ cd dst2 &&
+ git fetch ../src "refs/remotes/*:refs/remotes/*"
+ ) &&
+ git ls-remote src "refs/remotes/*" >expect &&
+ git ls-remote dst2 "refs/remotes/*" >actual &&
+ test_cmp expect actual &&
+ ( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect &&
+ ( cd dst2 && git symbolic-ref refs/remotes/origin/HEAD ) >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh
index 1eea647656..01d0d95b4d 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push.sh
@@ -46,15 +46,7 @@ test_expect_success 'create password-protected repository' '
"$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git"
'
-test_expect_success 'setup askpass helper' '
- cat >askpass <<-\EOF &&
- #!/bin/sh
- echo user@host
- EOF
- chmod +x askpass &&
- GIT_ASKPASS="$PWD/askpass" &&
- export GIT_ASKPASS
-'
+setup_askpass_helper
test_expect_success 'clone remote repository' '
cd "$ROOT_PATH" &&
@@ -117,7 +109,7 @@ test_expect_success 'http-push fetches packed objects' '
# By reset, we force git to retrieve the packed object
(cd "$ROOT_PATH"/test_repo_clone_packed &&
git reset --hard HEAD^ &&
- git remote rm origin &&
+ git remote remove origin &&
git reflog expire --expire=0 --all &&
git prune &&
git push -f -v $HTTPD_URL/dumb/test_repo_packed.git master)
@@ -162,6 +154,7 @@ test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
test_expect_success 'push to password-protected repository (user in URL)' '
test_commit pw-user &&
+ set_askpass user@host &&
git push "$HTTPD_URL_USER/auth/dumb/test_repo.git" HEAD &&
git rev-parse --verify HEAD >expect &&
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \
@@ -169,9 +162,15 @@ test_expect_success 'push to password-protected repository (user in URL)' '
test_cmp expect actual
'
+test_expect_failure 'user was prompted only once for password' '
+ expect_askpass pass user@host
+'
+
test_expect_failure 'push to password-protected repository (no user in URL)' '
test_commit pw-nouser &&
+ set_askpass user@host &&
git push "$HTTPD_URL/auth/dumb/test_repo.git" HEAD &&
+ expect_askpass both user@host
git rev-parse --verify HEAD >expect &&
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \
rev-parse --verify HEAD >actual &&
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh
index 5b170be2c0..4b4b4a604f 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push.sh
@@ -36,6 +36,8 @@ test_expect_success 'setup remote repository' '
mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
'
+setup_askpass_helper
+
cat >exp <<EOF
GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200
@@ -64,7 +66,10 @@ test_expect_success 'no empty path components' '
test_expect_success 'clone remote repository' '
rm -rf test_repo_clone &&
- git clone $HTTPD_URL/smart/test_repo.git test_repo_clone
+ git clone $HTTPD_URL/smart/test_repo.git test_repo_clone &&
+ (
+ cd test_repo_clone && git config push.default matching
+ )
'
test_expect_success 'push to remote repository (standard)' '
@@ -216,13 +221,36 @@ test_expect_success 'push --mirror to repo with alternates' '
git push --mirror "$HTTPD_URL"/smart/alternates-mirror.git
'
-test_expect_success TTY 'quiet push' '
+test_expect_success TTY 'push shows progress when stderr is a tty' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit noisy &&
+ test_terminal git push >output 2>&1 &&
+ grep "^Writing objects" output
+'
+
+test_expect_success TTY 'push --quiet silences status and progress' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit quiet &&
- test_terminal git push --quiet --no-progress 2>&1 | tee output &&
+ test_terminal git push --quiet >output 2>&1 &&
test_cmp /dev/null output
'
+test_expect_success TTY 'push --no-progress silences progress but not status' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit no-progress &&
+ test_terminal git push --no-progress >output 2>&1 &&
+ grep "^To http" output &&
+ ! grep "^Writing objects"
+'
+
+test_expect_success 'push --progress shows progress to non-tty' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit progress &&
+ git push --progress >output 2>&1 &&
+ grep "^To http" output &&
+ grep "^Writing objects" output
+'
+
test_expect_success 'http push gives sane defaults to reflog' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit reflog-test &&
@@ -243,5 +271,29 @@ test_expect_success 'http push respects GIT_COMMITTER_* in reflog' '
test_cmp expect actual
'
+test_expect_success 'push over smart http with auth' '
+ cd "$ROOT_PATH/test_repo_clone" &&
+ echo push-auth-test >expect &&
+ test_commit push-auth-test &&
+ set_askpass user@host &&
+ git push "$HTTPD_URL"/auth/smart/test_repo.git &&
+ git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
+ log -1 --format=%s >actual &&
+ expect_askpass both user@host &&
+ test_cmp expect actual
+'
+
+test_expect_success 'push to auth-only-for-push repo' '
+ cd "$ROOT_PATH/test_repo_clone" &&
+ echo push-half-auth >expect &&
+ test_commit push-half-auth &&
+ set_askpass user@host &&
+ git push "$HTTPD_URL"/auth-push/smart/test_repo.git &&
+ git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
+ log -1 --format=%s >actual &&
+ expect_askpass both user@host &&
+ test_cmp expect actual
+'
+
stop_httpd
test_done
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
index b06f817af3..80d20c876b 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch.sh
@@ -22,7 +22,7 @@ test_expect_success 'setup repository' '
'
test_expect_success 'create http-accessible bare repository with loose objects' '
- cp -a .git "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+ cp -R .git "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git config core.bare true &&
mkdir -p hooks &&
@@ -41,68 +41,34 @@ test_expect_success 'clone http repository' '
'
test_expect_success 'create password-protected repository' '
- mkdir "$HTTPD_DOCUMENT_ROOT_PATH/auth/" &&
+ mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/" &&
cp -Rf "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
- "$HTTPD_DOCUMENT_ROOT_PATH/auth/repo.git"
-'
-
-test_expect_success 'setup askpass helpers' '
- cat >askpass <<-EOF &&
- #!/bin/sh
- echo >>"$PWD/askpass-query" "askpass: \$*" &&
- cat "$PWD/askpass-response"
- EOF
- chmod +x askpass &&
- GIT_ASKPASS="$PWD/askpass" &&
- export GIT_ASKPASS
-'
-
-expect_askpass() {
- dest=$HTTPD_DEST
- {
- case "$1" in
- none)
- ;;
- pass)
- echo "askpass: Password for 'http://$2@$dest': "
- ;;
- both)
- echo "askpass: Username for 'http://$dest': "
- echo "askpass: Password for 'http://$2@$dest': "
- ;;
- *)
- false
- ;;
- esac
- } >askpass-expect &&
- test_cmp askpass-expect askpass-query
-}
+ "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/repo.git"
+'
+
+setup_askpass_helper
test_expect_success 'cloning password-protected repository can fail' '
- >askpass-query &&
- echo wrong >askpass-response &&
- test_must_fail git clone "$HTTPD_URL/auth/repo.git" clone-auth-fail &&
+ set_askpass wrong &&
+ test_must_fail git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-fail &&
expect_askpass both wrong
'
test_expect_success 'http auth can use user/pass in URL' '
- >askpass-query &&
- echo wrong >askpass-response &&
- git clone "$HTTPD_URL_USER_PASS/auth/repo.git" clone-auth-none &&
+ set_askpass wrong &&
+ git clone "$HTTPD_URL_USER_PASS/auth/dumb/repo.git" clone-auth-none &&
expect_askpass none
'
test_expect_success 'http auth can use just user in URL' '
- >askpass-query &&
- echo user@host >askpass-response &&
- git clone "$HTTPD_URL_USER/auth/repo.git" clone-auth-pass &&
+ set_askpass user@host &&
+ git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-pass &&
expect_askpass pass user@host
'
test_expect_success 'http auth can request both user and pass' '
- >askpass-query &&
- echo user@host >askpass-response &&
- git clone "$HTTPD_URL/auth/repo.git" clone-auth-both &&
+ set_askpass user@host &&
+ git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-both &&
expect_askpass both user@host
'
@@ -112,25 +78,22 @@ test_expect_success 'http auth respects credential helper config' '
echo username=user@host
echo password=user@host
}; f" &&
- >askpass-query &&
- echo wrong >askpass-response &&
- git clone "$HTTPD_URL/auth/repo.git" clone-auth-helper &&
+ set_askpass wrong &&
+ git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-helper &&
expect_askpass none
'
test_expect_success 'http auth can get username from config' '
test_config_global "credential.$HTTPD_URL.username" user@host &&
- >askpass-query &&
- echo user@host >askpass-response &&
- git clone "$HTTPD_URL/auth/repo.git" clone-auth-user &&
+ set_askpass user@host &&
+ git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-user &&
expect_askpass pass user@host
'
test_expect_success 'configured username does not override URL' '
test_config_global "credential.$HTTPD_URL.username" wrong &&
- >askpass-query &&
- echo user@host >askpass-response &&
- git clone "$HTTPD_URL_USER/auth/repo.git" clone-auth-user2 &&
+ set_askpass user@host &&
+ git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-user2 &&
expect_askpass pass user@host
'
diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh
index be6094be77..c5cd2e348c 100755
--- a/t/t5551-http-fetch.sh
+++ b/t/t5551-http-fetch.sh
@@ -27,16 +27,19 @@ test_expect_success 'create http-accessible bare repository' '
git push public master:master
'
+setup_askpass_helper
+
cat >exp <<EOF
> GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1
> Accept: */*
+> Accept-Encoding: gzip
> Pragma: no-cache
< HTTP/1.1 200 OK
< Pragma: no-cache
< Cache-Control: no-cache, max-age=0, must-revalidate
< Content-Type: application/x-git-upload-pack-advertisement
> POST /smart/repo.git/git-upload-pack HTTP/1.1
-> Accept-Encoding: deflate, gzip
+> Accept-Encoding: gzip
> Content-Type: application/x-git-upload-pack-request
> Accept: application/x-git-upload-pack-result
> Content-Length: xxx
@@ -109,12 +112,57 @@ test_expect_success 'follow redirects (302)' '
git clone $HTTPD_URL/smart-redir-temp/repo.git --quiet repo-t
'
+test_expect_success 'clone from password-protected repository' '
+ echo two >expect &&
+ set_askpass user@host &&
+ git clone --bare "$HTTPD_URL/auth/smart/repo.git" smart-auth &&
+ expect_askpass both user@host &&
+ git --git-dir=smart-auth log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'clone from auth-only-for-push repository' '
+ echo two >expect &&
+ set_askpass wrong &&
+ git clone --bare "$HTTPD_URL/auth-push/smart/repo.git" smart-noauth &&
+ expect_askpass none &&
+ git --git-dir=smart-noauth log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'clone from auth-only-for-objects repository' '
+ echo two >expect &&
+ set_askpass user@host &&
+ git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth &&
+ expect_askpass both user@host &&
+ git --git-dir=half-auth log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-op half-auth fetch does not require a password' '
+ set_askpass wrong &&
+ git --git-dir=half-auth fetch &&
+ expect_askpass none
+'
+
+test_expect_success 'disable dumb http on server' '
+ git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
+ config http.getanyfile false
+'
+
+test_expect_success 'GIT_SMART_HTTP can disable smart http' '
+ (GIT_SMART_HTTP=0 &&
+ export GIT_SMART_HTTP &&
+ cd clone &&
+ test_must_fail git fetch)
+'
+
test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
- for i in `seq 50000`
+ for i in `test_seq 50000`
do
echo "commit refs/heads/too-many-refs"
echo "mark :$i"
@@ -130,7 +178,7 @@ test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '
done | git fast-import --export-marks=marks &&
# now assign tags to all the dangling commits we created above
- tag=$(perl -e "print \"bla\" x 30") &&
+ tag=$("$PERL_PATH" -e "print \"bla\" x 30") &&
sed -e "s/^:\(.\+\) \(.\+\)$/\2 refs\/tags\/$tag-\1/" <marks >>packed-refs
)
'
diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
index 7cbc9994a3..a3a4e47e1d 100755
--- a/t/t5570-git-daemon.sh
+++ b/t/t5570-git-daemon.sh
@@ -103,14 +103,12 @@ test_remote_error()
esac
done
- if test $# -ne 3
- then
- error "invalid number of arguments"
- fi
-
+ msg=$1
+ shift
cmd=$1
- repo=$2
- msg=$3
+ shift
+ repo=$1
+ shift || error "invalid number of arguments"
if test -x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/$repo"
then
@@ -122,7 +120,7 @@ test_remote_error()
fi
fi
- test_must_fail git "$cmd" "$GIT_DAEMON_URL/$repo" 2>output &&
+ test_must_fail git "$cmd" "$GIT_DAEMON_URL/$repo" "$@" 2>output &&
echo "fatal: remote error: $msg: /$repo" >expect &&
test_cmp expect output
ret=$?
@@ -131,18 +129,18 @@ test_remote_error()
}
msg="access denied or repository not exported"
-test_expect_success 'clone non-existent' "test_remote_error clone nowhere.git '$msg'"
-test_expect_success 'push disabled' "test_remote_error push repo.git '$msg'"
-test_expect_success 'read access denied' "test_remote_error -x fetch repo.git '$msg'"
-test_expect_success 'not exported' "test_remote_error -n fetch repo.git '$msg'"
+test_expect_success 'clone non-existent' "test_remote_error '$msg' clone nowhere.git "
+test_expect_success 'push disabled' "test_remote_error '$msg' push repo.git master"
+test_expect_success 'read access denied' "test_remote_error -x '$msg' fetch repo.git "
+test_expect_success 'not exported' "test_remote_error -n '$msg' fetch repo.git "
stop_git_daemon
start_git_daemon --informative-errors
-test_expect_success 'clone non-existent' "test_remote_error clone nowhere.git 'no such repository'"
-test_expect_success 'push disabled' "test_remote_error push repo.git 'service not enabled'"
-test_expect_success 'read access denied' "test_remote_error -x fetch repo.git 'no such repository'"
-test_expect_success 'not exported' "test_remote_error -n fetch repo.git 'repository not exported'"
+test_expect_success 'clone non-existent' "test_remote_error 'no such repository' clone nowhere.git "
+test_expect_success 'push disabled' "test_remote_error 'service not enabled' push repo.git master"
+test_expect_success 'read access denied' "test_remote_error -x 'no such repository' fetch repo.git "
+test_expect_success 'not exported' "test_remote_error -n 'repository not exported' fetch repo.git "
stop_git_daemon
test_done
diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh
index ee06d28649..4435693bb2 100755
--- a/t/t5600-clone-fail-cleanup.sh
+++ b/t/t5600-clone-fail-cleanup.sh
@@ -37,6 +37,16 @@ test_expect_success \
test_expect_success \
'successful clone must leave the directory' \
- 'cd bar'
+ 'test -d bar'
+
+test_expect_success 'failed clone --separate-git-dir should not leave any directories' '
+ mkdir foo/.git/objects.bak/ &&
+ mv foo/.git/objects/* foo/.git/objects.bak/ &&
+ test_must_fail git clone --separate-git-dir gitdir foo worktree &&
+ test_must_fail test -e gitdir &&
+ test_must_fail test -e worktree &&
+ mv foo/.git/objects.bak/* foo/.git/objects/ &&
+ rmdir foo/.git/objects.bak
+'
test_done
diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh
index 6972258b27..7ff6e0e16c 100755
--- a/t/t5701-clone-local.sh
+++ b/t/t5701-clone-local.sh
@@ -3,7 +3,10 @@
test_description='test local clone'
. ./test-lib.sh
-D=`pwd`
+repo_is_hardlinked() {
+ find "$1/objects" -type f -links 1 >output &&
+ test_line_count = 0 output
+}
test_expect_success 'preparing origin repository' '
: >file && git add . && git commit -m1 &&
@@ -19,105 +22,72 @@ test_expect_success 'preparing origin repository' '
'
test_expect_success 'local clone without .git suffix' '
- cd "$D" &&
git clone -l -s a b &&
- cd b &&
+ (cd b &&
test "$(GIT_CONFIG=.git/config git config --bool core.bare)" = false &&
- git fetch
+ git fetch)
'
test_expect_success 'local clone with .git suffix' '
- cd "$D" &&
git clone -l -s a.git c &&
- cd c &&
- git fetch
+ (cd c && git fetch)
'
test_expect_success 'local clone from x' '
- cd "$D" &&
git clone -l -s x y &&
- cd y &&
- git fetch
+ (cd y && git fetch)
'
test_expect_success 'local clone from x.git that does not exist' '
- cd "$D" &&
- if git clone -l -s x.git z
- then
- echo "Oops, should have failed"
- false
- else
- echo happy
- fi
+ test_must_fail git clone -l -s x.git z
'
test_expect_success 'With -no-hardlinks, local will make a copy' '
- cd "$D" &&
git clone --bare --no-hardlinks x w &&
- cd w &&
- linked=$(find objects -type f ! -links 1 | wc -l) &&
- test 0 = $linked
+ ! repo_is_hardlinked w
'
test_expect_success 'Even without -l, local will make a hardlink' '
- cd "$D" &&
rm -fr w &&
git clone -l --bare x w &&
- cd w &&
- copied=$(find objects -type f -links 1 | wc -l) &&
- test 0 = $copied
+ repo_is_hardlinked w
'
test_expect_success 'local clone of repo with nonexistent ref in HEAD' '
- cd "$D" &&
echo "ref: refs/heads/nonexistent" > a.git/HEAD &&
git clone a d &&
- cd d &&
+ (cd d &&
git fetch &&
- test ! -e .git/refs/remotes/origin/HEAD'
+ test ! -e .git/refs/remotes/origin/HEAD)
+'
test_expect_success 'bundle clone without .bundle suffix' '
- cd "$D" &&
git clone dir/b3 &&
- cd b3 &&
- git fetch
+ (cd b3 && git fetch)
'
test_expect_success 'bundle clone with .bundle suffix' '
- cd "$D" &&
git clone b1.bundle &&
- cd b1 &&
- git fetch
+ (cd b1 && git fetch)
'
test_expect_success 'bundle clone from b4' '
- cd "$D" &&
git clone b4 bdl &&
- cd bdl &&
- git fetch
+ (cd bdl && git fetch)
'
test_expect_success 'bundle clone from b4.bundle that does not exist' '
- cd "$D" &&
- if git clone b4.bundle bb
- then
- echo "Oops, should have failed"
- false
- else
- echo happy
- fi
+ test_must_fail git clone b4.bundle bb
'
test_expect_success 'bundle clone with nonexistent HEAD' '
- cd "$D" &&
git clone b2.bundle b2 &&
- cd b2 &&
+ (cd b2 &&
git fetch &&
- test ! -e .git/refs/heads/master
+ test_must_fail git rev-parse --verify refs/heads/master)
'
test_expect_success 'clone empty repository' '
- cd "$D" &&
mkdir empty &&
(cd empty &&
git init &&
@@ -135,7 +105,6 @@ test_expect_success 'clone empty repository' '
'
test_expect_success 'clone empty repository, and then push should not segfault.' '
- cd "$D" &&
rm -fr empty/ empty-clone/ &&
mkdir empty &&
(cd empty && git init) &&
@@ -145,16 +114,24 @@ test_expect_success 'clone empty repository, and then push should not segfault.'
'
test_expect_success 'cloning non-existent directory fails' '
- cd "$D" &&
rm -rf does-not-exist &&
test_must_fail git clone does-not-exist
'
test_expect_success 'cloning non-git directory fails' '
- cd "$D" &&
rm -rf not-a-git-repo not-a-git-repo-clone &&
mkdir not-a-git-repo &&
test_must_fail git clone not-a-git-repo not-a-git-repo-clone
'
+test_expect_success 'cloning file:// does not hardlink' '
+ git clone --bare file://"$(pwd)"/a non-local &&
+ ! repo_is_hardlinked non-local
+'
+
+test_expect_success 'cloning a local path with --no-local does not hardlink' '
+ git clone --bare --no-local a force-nonlocal &&
+ ! repo_is_hardlinked force-nonlocal
+'
+
test_done
diff --git a/t/t5709-clone-refspec.sh b/t/t5709-clone-refspec.sh
new file mode 100755
index 0000000000..6f1ea984d4
--- /dev/null
+++ b/t/t5709-clone-refspec.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+test_description='test refspec written by clone-command'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ # Make two branches, "master" and "side"
+ echo one >file &&
+ git add file &&
+ git commit -m one &&
+ echo two >file &&
+ git commit -a -m two &&
+ git tag two &&
+ echo three >file &&
+ git commit -a -m three &&
+ git checkout -b side &&
+ echo four >file &&
+ git commit -a -m four &&
+ git checkout master &&
+
+ # default clone
+ git clone . dir_all &&
+
+ # default --single that follows HEAD=master
+ git clone --single-branch . dir_master &&
+
+ # default --single that follows HEAD=side
+ git checkout side &&
+ git clone --single-branch . dir_side &&
+
+ # explicit --single that follows side
+ git checkout master &&
+ git clone --single-branch --branch side . dir_side2 &&
+
+ # default --single with --mirror
+ git clone --single-branch --mirror . dir_mirror &&
+
+ # default --single with --branch and --mirror
+ git clone --single-branch --mirror --branch side . dir_mirror_side &&
+
+ # --single that does not know what branch to follow
+ git checkout two^ &&
+ git clone --single-branch . dir_detached &&
+
+ # explicit --single with tag
+ git clone --single-branch --branch two . dir_tag &&
+
+ # advance both "master" and "side" branches
+ git checkout side &&
+ echo five >file &&
+ git commit -a -m five &&
+ git checkout master &&
+ echo six >file &&
+ git commit -a -m six &&
+
+ # update tag
+ git tag -d two && git tag two
+'
+
+test_expect_success 'by default all branches will be kept updated' '
+ (
+ cd dir_all && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # follow both master and side
+ git for-each-ref refs/heads >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'by default no tags will be kept updated' '
+ (
+ cd dir_all && git fetch &&
+ git for-each-ref refs/tags >../actual
+ ) &&
+ git for-each-ref refs/tags >expect &&
+ test_must_fail test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at master' '
+ (
+ cd dir_master && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow master
+ git for-each-ref refs/heads/master >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at side' '
+ (
+ cd dir_side && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow side
+ git for-each-ref refs/heads/side >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch side' '
+ (
+ cd dir_side2 && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow side
+ git for-each-ref refs/heads/side >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch with tag fetches updated tag' '
+ (
+ cd dir_tag && git fetch &&
+ git for-each-ref refs/tags >../actual
+ ) &&
+ git for-each-ref refs/tags >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with --mirror' '
+ (
+ cd dir_mirror && git fetch &&
+ git for-each-ref refs > ../actual
+ ) &&
+ git for-each-ref refs >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch and --mirror' '
+ (
+ cd dir_mirror_side && git fetch &&
+ git for-each-ref refs > ../actual
+ ) &&
+ git for-each-ref refs >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with detached' '
+ (
+ cd dir_detached && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ )
+ # nothing
+ >expect &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-testpy.sh
index 5702334510..1e683d4220 100755
--- a/t/t5800-remote-helpers.sh
+++ b/t/t5800-remote-testpy.sh
@@ -3,12 +3,12 @@
# Copyright (c) 2010 Sverre Rabbelier
#
-test_description='Test remote-helper import and export commands'
+test_description='Test python remote-helper framework'
. ./test-lib.sh
if ! test_have_prereq PYTHON ; then
- skip_all='skipping git-remote-hg tests, python not available'
+ skip_all='skipping python remote-helper tests, python not available'
test_done
fi
@@ -17,7 +17,7 @@ import sys
if sys.hexversion < 0x02040000:
sys.exit(1)
' || {
- skip_all='skipping git-remote-hg tests, python version < 2.4'
+ skip_all='skipping python remote-helper tests, python version < 2.4'
test_done
}
@@ -38,12 +38,12 @@ test_expect_success 'setup repository' '
'
test_expect_success 'cloning from local repo' '
- git clone "testgit::${PWD}/server" localclone &&
+ git clone "testpy::${PWD}/server" localclone &&
test_cmp public/file localclone/file
'
test_expect_success 'cloning from remote repo' '
- git clone "testgit::file://${PWD}/server" clone &&
+ git clone "testpy::file://${PWD}/server" clone &&
test_cmp public/file clone/file
'
@@ -73,11 +73,11 @@ test_expect_success 'pushing to local repo' '
'
# Generally, skip this test. It demonstrates a now-fixed race in
-# git-remote-testgit, but is too slow to leave in for general use.
+# git-remote-testpy, but is too slow to leave in for general use.
: test_expect_success 'racily pushing to local repo' '
test_when_finished "rm -rf server2 localclone2" &&
- cp -a server server2 &&
- git clone "testgit::${PWD}/server2" localclone2 &&
+ cp -R server server2 &&
+ git clone "testpy::${PWD}/server2" localclone2 &&
(cd localclone2 &&
echo content >>file &&
git commit -a -m three &&
@@ -145,4 +145,25 @@ test_expect_failure 'push new branch with old:new refspec' '
compare_refs clone HEAD server refs/heads/new-refspec
'
+test_expect_success 'proper failure checks for fetching' '
+ (GIT_REMOTE_TESTGIT_FAILURE=1 &&
+ export GIT_REMOTE_TESTGIT_FAILURE &&
+ cd localclone &&
+ test_must_fail git fetch 2>&1 | \
+ grep "Error while running fast-import"
+ )
+'
+
+# We sleep to give fast-export a chance to catch the SIGPIPE
+test_expect_failure 'proper failure checks for pushing' '
+ (GIT_REMOTE_TESTGIT_FAILURE=1 &&
+ export GIT_REMOTE_TESTGIT_FAILURE &&
+ GIT_REMOTE_TESTGIT_SLEEPY=1 &&
+ export GIT_REMOTE_TESTGIT_SLEEPY &&
+ cd localclone &&
+ test_must_fail git push --all 2>&1 | \
+ grep "Error while running fast-export"
+ )
+'
+
test_done
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
new file mode 100755
index 0000000000..f387027c05
--- /dev/null
+++ b/t/t5801-remote-helpers.sh
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Sverre Rabbelier
+#
+
+test_description='Test remote-helper import and export commands'
+
+. ./test-lib.sh
+
+if ! type "${BASH-bash}" >/dev/null 2>&1; then
+ skip_all='skipping remote-testgit tests, bash not available'
+ test_done
+fi
+
+compare_refs() {
+ git --git-dir="$1/.git" rev-parse --verify $2 >expect &&
+ git --git-dir="$3/.git" rev-parse --verify $4 >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'setup repository' '
+ git init server &&
+ (cd server &&
+ echo content >file &&
+ git add file &&
+ git commit -m one)
+'
+
+test_expect_success 'cloning from local repo' '
+ git clone "testgit::${PWD}/server" local &&
+ test_cmp server/file local/file
+'
+
+test_expect_success 'create new commit on remote' '
+ (cd server &&
+ echo content >>file &&
+ git commit -a -m two)
+'
+
+test_expect_success 'pulling from local repo' '
+ (cd local && git pull) &&
+ test_cmp server/file local/file
+'
+
+test_expect_success 'pushing to local repo' '
+ (cd local &&
+ echo content >>file &&
+ git commit -a -m three &&
+ git push) &&
+ compare_refs local HEAD server HEAD
+'
+
+test_expect_success 'fetch new branch' '
+ (cd server &&
+ git reset --hard &&
+ git checkout -b new &&
+ echo content >>file &&
+ git commit -a -m five
+ ) &&
+ (cd local &&
+ git fetch origin new
+ ) &&
+ compare_refs server HEAD local FETCH_HEAD
+'
+
+test_expect_success 'fetch multiple branches' '
+ (cd local &&
+ git fetch
+ ) &&
+ compare_refs server master local refs/remotes/origin/master &&
+ compare_refs server new local refs/remotes/origin/new
+'
+
+test_expect_success 'push when remote has extra refs' '
+ (cd local &&
+ git reset --hard origin/master &&
+ echo content >>file &&
+ git commit -a -m six &&
+ git push
+ ) &&
+ compare_refs local master server master
+'
+
+test_expect_success 'push new branch by name' '
+ (cd local &&
+ git checkout -b new-name &&
+ echo content >>file &&
+ git commit -a -m seven &&
+ git push origin new-name
+ ) &&
+ compare_refs local HEAD server refs/heads/new-name
+'
+
+test_expect_failure 'push new branch with old:new refspec' '
+ (cd local &&
+ git push origin new-name:new-refspec
+ ) &&
+ compare_refs local HEAD server refs/heads/new-refspec
+'
+
+test_expect_success 'cloning without refspec' '
+ GIT_REMOTE_TESTGIT_REFSPEC="" \
+ git clone "testgit::${PWD}/server" local2 &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling without refspecs' '
+ (cd local2 &&
+ git reset --hard &&
+ GIT_REMOTE_TESTGIT_REFSPEC="" git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure 'pushing without refspecs' '
+ test_when_finished "(cd local2 && git reset --hard origin)" &&
+ (cd local2 &&
+ echo content >>file &&
+ git commit -a -m ten &&
+ GIT_REMOTE_TESTGIT_REFSPEC="" git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling with straight refspec' '
+ (cd local2 &&
+ GIT_REMOTE_TESTGIT_REFSPEC="*:*" git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure 'pushing with straight refspec' '
+ test_when_finished "(cd local2 && git reset --hard origin)" &&
+ (cd local2 &&
+ echo content >>file &&
+ git commit -a -m eleven &&
+ GIT_REMOTE_TESTGIT_REFSPEC="*:*" git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling without marks' '
+ (cd local2 &&
+ GIT_REMOTE_TESTGIT_NO_MARKS=1 git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure 'pushing without marks' '
+ test_when_finished "(cd local2 && git reset --hard origin)" &&
+ (cd local2 &&
+ echo content >>file &&
+ git commit -a -m twelve &&
+ GIT_REMOTE_TESTGIT_NO_MARKS=1 git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'push all with existing object' '
+ (cd local &&
+ git branch dup2 master &&
+ git push origin --all
+ ) &&
+ compare_refs local dup2 server dup2
+'
+
+test_expect_success 'push ref with existing object' '
+ (cd local &&
+ git branch dup master &&
+ git push origin dup
+ ) &&
+ compare_refs local dup server dup
+'
+
+test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index a01d244502..3fc3b74c8e 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -3,6 +3,7 @@
test_description='git rev-list --pretty=format test'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-terminal.sh
test_tick
test_expect_success 'setup' '
@@ -11,12 +12,24 @@ touch foo && git add foo && git commit -m "added foo" &&
'
# usage: test_format name format_string <expected_output
-test_format() {
+test_format () {
cat >expect.$1
test_expect_success "format $1" "
-git rev-list --pretty=format:'$2' master >output.$1 &&
-test_cmp expect.$1 output.$1
-"
+ git rev-list --pretty=format:'$2' master >output.$1 &&
+ test_cmp expect.$1 output.$1
+ "
+}
+
+# Feed to --format to provide predictable colored sequences.
+AUTO_COLOR='%C(auto,red)foo%C(auto,reset)'
+has_color () {
+ printf '\033[31mfoo\033[m\n' >expect &&
+ test_cmp expect "$1"
+}
+
+has_no_color () {
+ echo foo >expect &&
+ test_cmp expect "$1"
}
test_format percent %%h <<'EOF'
@@ -124,6 +137,48 @@ commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
foo
EOF
+test_expect_success '%C(auto) does not enable color by default' '
+ git log --format=$AUTO_COLOR -1 >actual &&
+ has_no_color actual
+'
+
+test_expect_success '%C(auto) enables colors for color.diff' '
+ git -c color.diff=always log --format=$AUTO_COLOR -1 >actual &&
+ has_color actual
+'
+
+test_expect_success '%C(auto) enables colors for color.ui' '
+ git -c color.ui=always log --format=$AUTO_COLOR -1 >actual &&
+ has_color actual
+'
+
+test_expect_success '%C(auto) respects --color' '
+ git log --format=$AUTO_COLOR -1 --color >actual &&
+ has_color actual
+'
+
+test_expect_success '%C(auto) respects --no-color' '
+ git -c color.ui=always log --format=$AUTO_COLOR -1 --no-color >actual &&
+ has_no_color actual
+'
+
+test_expect_success TTY '%C(auto) respects --color=auto (stdout is tty)' '
+ (
+ TERM=vt100 && export TERM &&
+ test_terminal \
+ git log --format=$AUTO_COLOR -1 --color=auto >actual &&
+ has_color actual
+ )
+'
+
+test_expect_success '%C(auto) respects --color=auto (stdout not tty)' '
+ (
+ TERM=vt100 && export TERM &&
+ git log --format=$AUTO_COLOR -1 --color=auto >actual &&
+ has_no_color actual
+ )
+'
+
cat >commit-msg <<'EOF'
Test printing of complex bodies
@@ -283,4 +338,11 @@ test_expect_success 'oneline with empty message' '
test_line_count = 5 testg.txt
'
+test_expect_success 'single-character name is parsed correctly' '
+ git commit --author="a <a@example.com>" --allow-empty -m foo &&
+ echo "a <a@example.com>" >expect &&
+ git log -1 --format="%an <%ae>" >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh
index e51eb41f4b..bbb0581f88 100755
--- a/t/t6011-rev-list-with-bad-commit.sh
+++ b/t/t6011-rev-list-with-bad-commit.sh
@@ -37,7 +37,7 @@ test_expect_success 'verify number of revisions' \
test_expect_success 'corrupt second commit object' \
'
- perl -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack &&
+ "$PERL_PATH" -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack &&
test_must_fail git fsck --full
'
diff --git a/t/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh
index 59fc2f06e0..892a537989 100755
--- a/t/t6013-rev-list-reverse-parents.sh
+++ b/t/t6013-rev-list-reverse-parents.sh
@@ -25,7 +25,7 @@ test_expect_success 'set up --reverse example' '
test_expect_success '--reverse --parents --full-history combines correctly' '
git rev-list --parents --full-history master -- foo |
- perl -e "print reverse <>" > expected &&
+ "$PERL_PATH" -e "print reverse <>" > expected &&
git rev-list --reverse --parents --full-history master -- foo \
> actual &&
test_cmp actual expected
@@ -33,7 +33,7 @@ test_expect_success '--reverse --parents --full-history combines correctly' '
test_expect_success '--boundary does too' '
git rev-list --boundary --parents --full-history master ^root -- foo |
- perl -e "print reverse <>" > expected &&
+ "$PERL_PATH" -e "print reverse <>" > expected &&
git rev-list --boundary --reverse --parents --full-history \
master ^root -- foo > actual &&
test_cmp actual expected
diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh
index 1104249182..c680f789a7 100755
--- a/t/t6022-merge-rename.sh
+++ b/t/t6022-merge-rename.sh
@@ -242,10 +242,10 @@ test_expect_success 'merge of identical changes in a renamed file' '
rm -f A M N &&
git reset --hard &&
git checkout change+rename &&
- GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" &&
+ GIT_MERGE_VERBOSITY=3 git merge change | test_i18ngrep "^Skipped B" &&
git reset --hard HEAD^ &&
git checkout change &&
- GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B"
+ GIT_MERGE_VERBOSITY=3 git merge change+rename | test_i18ngrep "^Skipped B"
'
test_expect_success 'setup for rename + d/f conflicts' '
@@ -303,9 +303,9 @@ test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '
git checkout -q renamed-file-has-no-conflicts^0 &&
test_must_fail git merge --strategy=recursive dir-in-way >output &&
- grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
- grep "Auto-merging dir" output &&
- grep "Adding as dir~HEAD instead" output &&
+ test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
+ test_i18ngrep "Auto-merging dir" output &&
+ test_i18ngrep "Adding as dir~HEAD instead" output &&
test 3 -eq "$(git ls-files -u | wc -l)" &&
test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
@@ -325,9 +325,9 @@ test_expect_success 'Same as previous, but merged other way' '
test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors &&
! grep "error: refusing to lose untracked file at" errors &&
- grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
- grep "Auto-merging dir" output &&
- grep "Adding as dir~renamed-file-has-no-conflicts instead" output &&
+ test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
+ test_i18ngrep "Auto-merging dir" output &&
+ test_i18ngrep "Adding as dir~renamed-file-has-no-conflicts instead" output &&
test 3 -eq "$(git ls-files -u | wc -l)" &&
test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 72e28ee535..3e0e15fb3e 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -676,9 +676,7 @@ test_expect_success 'bisect fails if tree is broken on trial commit' '
check_same()
{
echo "Checking $1 is the same as $2" &&
- git rev-parse "$1" > expected.same &&
- git rev-parse "$2" > expected.actual &&
- test_cmp expected.same expected.actual
+ test_cmp_rev "$1" "$2"
}
test_expect_success 'bisect: --no-checkout - start commit bad' '
diff --git a/t/t6037-merge-ours-theirs.sh b/t/t6037-merge-ours-theirs.sh
index 2cf42c73f1..3889eca4ae 100755
--- a/t/t6037-merge-ours-theirs.sh
+++ b/t/t6037-merge-ours-theirs.sh
@@ -53,7 +53,19 @@ test_expect_success 'recursive favouring ours' '
! grep 1 file
'
-test_expect_success 'pull with -X' '
+test_expect_success 'binary file with -Xours/-Xtheirs' '
+ echo file binary >.gitattributes &&
+
+ git reset --hard master &&
+ git merge -s recursive -X theirs side &&
+ git diff --exit-code side HEAD -- file &&
+
+ git reset --hard master &&
+ git merge -s recursive -X ours side &&
+ git diff --exit-code master HEAD -- file
+'
+
+test_expect_success 'pull passes -X to underlying merge' '
git reset --hard master && git pull -s recursive -Xours . side &&
git reset --hard master && git pull -s recursive -X ours . side &&
git reset --hard master && git pull -s recursive -Xtheirs . side &&
diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh
index 466fa3804b..411550d2b6 100755
--- a/t/t6042-merge-rename-corner-cases.sh
+++ b/t/t6042-merge-rename-corner-cases.sh
@@ -380,7 +380,7 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
- grep "CONFLICT (rename/rename)" out &&
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
test 2 -eq $(git ls-files -s | wc -l) &&
test 2 -eq $(git ls-files -u | wc -l) &&
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index 5c87f28e4e..decdc33c52 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -140,6 +140,17 @@ test_expect_success '"git replace" replacing' '
test "$HASH2" = "$(git replace)"
'
+test_expect_success '"git replace" resolves sha1' '
+ SHORTHASH2=$(git rev-parse --short=8 $HASH2) &&
+ git replace -d $SHORTHASH2 &&
+ git replace $SHORTHASH2 $R &&
+ git show $HASH2 | grep "O Thor" &&
+ test_must_fail git replace $HASH2 $R &&
+ git replace -f $HASH2 $R &&
+ test_must_fail git replace -f &&
+ test "$HASH2" = "$(git replace)"
+'
+
# This creates a side branch where the bug in H2
# does not appear because P2 is created by applying
# H2 and squashing H5 into it.
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
new file mode 100755
index 0000000000..39ef61994f
--- /dev/null
+++ b/t/t6130-pathspec-noglob.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+test_description='test globbing (and noglob) of pathspec limiting'
+. ./test-lib.sh
+
+test_expect_success 'create commits with glob characters' '
+ test_commit unrelated bar &&
+ test_commit vanilla foo &&
+ # insert file "f*" in the commit, but in a way that avoids
+ # the name "f*" in the worktree, because it is not allowed
+ # on Windows (the tests below do not depend on the presence
+ # of the file in the worktree)
+ git update-index --add --cacheinfo 100644 "$(git rev-parse HEAD:foo)" "f*" &&
+ test_tick &&
+ git commit -m star &&
+ test_commit bracket "f[o][o]"
+'
+
+test_expect_success 'vanilla pathspec matches literally' '
+ echo vanilla >expect &&
+ git log --format=%s -- foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'star pathspec globs' '
+ cat >expect <<-\EOF &&
+ bracket
+ star
+ vanilla
+ EOF
+ git log --format=%s -- "f*" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'bracket pathspec globs and matches literal brackets' '
+ cat >expect <<-\EOF &&
+ bracket
+ vanilla
+ EOF
+ git log --format=%s -- "f[o][o]" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob option matches literally (vanilla)' '
+ echo vanilla >expect &&
+ git --literal-pathspecs log --format=%s -- foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob option matches literally (star)' '
+ echo star >expect &&
+ git --literal-pathspecs log --format=%s -- "f*" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob option matches literally (bracket)' '
+ echo bracket >expect &&
+ git --literal-pathspecs log --format=%s -- "f[o][o]" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob environment variable works' '
+ echo star >expect &&
+ GIT_LITERAL_PATHSPECS=1 git log --format=%s -- "f*" >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index 9b50f54cc2..992c2a0467 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -102,8 +102,8 @@ test_expect_success '[merge] summary/log configuration' '
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
@@ -149,8 +149,8 @@ test_expect_success 'merge.log=3 limits shortlog length' '
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left: (5 commits)
Left #5
Left #4
@@ -166,8 +166,8 @@ test_expect_success 'merge.log=5 shows all 5 commits' '
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
@@ -190,8 +190,8 @@ test_expect_success '--log=3 limits shortlog length' '
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left: (5 commits)
Left #5
Left #4
@@ -207,8 +207,8 @@ test_expect_success '--log=5 shows all 5 commits' '
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
@@ -238,8 +238,8 @@ test_expect_success 'fmt-merge-msg -m' '
cat >expected.log <<-EOF &&
Sync with left
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* ${apos}left${apos} of $(pwd):
Left #5
Left #4
@@ -271,8 +271,8 @@ test_expect_success 'setup: expected shortlog for two branches' '
cat >expected <<-EOF
Merge branches ${apos}left${apos} and ${apos}right${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
@@ -396,8 +396,8 @@ test_expect_success 'merge-msg two tags' '
Common #2
Common #1
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* tag ${apos}tag-l5${apos}:
Left #5
Left #4
@@ -426,8 +426,8 @@ test_expect_success 'merge-msg tag and branch' '
Common #2
Common #1
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 172178490a..752f5cb7d0 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -456,4 +456,14 @@ test_atom refs/tags/signed-long contents "subject line
body contents
$sig"
+cat >expected <<\EOF
+408fe76d02a785a006c2e9c669b7be5589ede96d <committer@example.com> refs/tags/master
+90b5ebede4899eda64893bc2a4c8f1d6fb6dfc40 <committer@example.com> refs/tags/bogo
+EOF
+
+test_expect_success 'Verify sort with multiple keys' '
+ git for-each-ref --format="%(objectname) %(taggeremail) %(refname)" --sort=objectname --sort=taggeremail \
+ refs/tags/bogo refs/tags/master > actual &&
+ test_cmp expected actual
+'
test_done
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index 82f3639937..b1a63655f9 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -11,7 +11,7 @@ test_expect_success 'gc empty repository' '
test_expect_success 'gc --gobbledegook' '
test_expect_code 129 git gc --nonsense 2>err &&
- grep "[Uu]sage: git gc" err
+ test_i18ngrep "[Uu]sage: git gc" err
'
test_expect_success 'gc -h with invalid configuration' '
@@ -22,7 +22,7 @@ test_expect_success 'gc -h with invalid configuration' '
echo "[gc] pruneexpire = CORRUPT" >>.git/config &&
test_expect_code 129 git gc -h >usage 2>&1
) &&
- grep "[Uu]sage" broken/usage
+ test_i18ngrep "[Uu]sage" broken/usage
'
test_done
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index e0227730de..1e7a209efa 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -5,7 +5,8 @@ test_description='git filter-branch'
test_expect_success 'setup' '
test_commit A &&
- test_commit B &&
+ GIT_COMMITTER_DATE="@0 +0000" GIT_AUTHOR_DATE="@0 +0000" &&
+ test_commit --notick B &&
git checkout -b branch B &&
test_commit D &&
mkdir dir &&
@@ -166,10 +167,11 @@ test_expect_success 'author information is preserved' '
test_tick &&
GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips &&
git branch preserved-author &&
- git filter-branch -f --msg-filter "cat; \
+ (sane_unset GIT_AUTHOR_NAME &&
+ git filter-branch -f --msg-filter "cat; \
test \$GIT_COMMIT != $(git rev-parse master) || \
echo Hallo" \
- preserved-author &&
+ preserved-author) &&
test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l)
'
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index f8c247a750..f5a79b13ae 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -263,6 +263,50 @@ test_expect_success 'tag -l can accept multiple patterns' '
test_cmp expect actual
'
+test_expect_success 'listing tags in column' '
+ COLUMNS=40 git tag -l --column=row >actual &&
+ cat >expected <<\EOF &&
+a1 aa1 cba t210 t211
+v0.2.1 v1.0 v1.0.1 v1.1.3
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'listing tags in column with column.*' '
+ git config column.tag row &&
+ git config column.ui dense &&
+ COLUMNS=40 git tag -l >actual &&
+ git config --unset column.ui &&
+ git config --unset column.tag &&
+ cat >expected <<\EOF &&
+a1 aa1 cba t210 t211
+v0.2.1 v1.0 v1.0.1 v1.1.3
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'listing tag with -n --column should fail' '
+ test_must_fail git tag --column -n
+'
+
+test_expect_success 'listing tags -n in column with column.ui ignored' '
+ git config column.ui "row dense" &&
+ COLUMNS=40 git tag -l -n >actual &&
+ git config --unset column.ui &&
+ cat >expected <<\EOF &&
+a1 Foo
+aa1 Foo
+cba Foo
+t210 Foo
+t211 Foo
+v0.2.1 Foo
+v1.0 Foo
+v1.0.1 Foo
+v1.1.3 Foo
+EOF
+ test_cmp expected actual
+'
+
# creating and verifying lightweight tags:
test_expect_success \
@@ -1022,12 +1066,12 @@ test_expect_success GPG \
'
# usage with rfc1991 signatures
-echo "rfc1991" > gpghome/gpg.conf
get_tag_header rfc1991-signed-tag $commit commit $time >expect
echo "RFC1991 signed tag" >>expect
echo '-----BEGIN PGP MESSAGE-----' >>expect
test_expect_success GPG \
'creating a signed tag with rfc1991' '
+ echo "rfc1991" >gpghome/gpg.conf &&
git tag -s -m "RFC1991 signed tag" rfc1991-signed-tag $commit &&
get_tag_msg rfc1991-signed-tag >actual &&
test_cmp expect actual
@@ -1041,6 +1085,7 @@ chmod +x fakeeditor
test_expect_success GPG \
'reediting a signed tag body omits signature' '
+ echo "rfc1991" >gpghome/gpg.conf &&
echo "RFC1991 signed tag" >expect &&
GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit &&
test_cmp expect actual
@@ -1048,11 +1093,13 @@ test_expect_success GPG \
test_expect_success GPG \
'verifying rfc1991 signature' '
+ echo "rfc1991" >gpghome/gpg.conf &&
git tag -v rfc1991-signed-tag
'
test_expect_success GPG \
'list tag with rfc1991 signature' '
+ echo "rfc1991" >gpghome/gpg.conf &&
echo "rfc1991-signed-tag RFC1991 signed tag" >expect &&
git tag -l -n1 rfc1991-signed-tag >actual &&
test_cmp expect actual &&
diff --git a/t/t7007-show.sh b/t/t7007-show.sh
index cce222f052..e41fa00b80 100755
--- a/t/t7007-show.sh
+++ b/t/t7007-show.sh
@@ -17,4 +17,107 @@ test_expect_success 'showing a tag that point at a missing object' '
test_must_fail git --no-pager show foo-tag
'
+test_expect_success 'set up a bit of history' '
+ test_commit main1 &&
+ test_commit main2 &&
+ test_commit main3 &&
+ git tag -m "annotated tag" annotated &&
+ git checkout -b side HEAD^^ &&
+ test_commit side2 &&
+ test_commit side3
+'
+
+test_expect_success 'showing two commits' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main2)
+ commit $(git rev-parse main3)
+ EOF
+ git show main2 main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing a range walks (linear)' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show main1..main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing a range walks (Y shape, ^ first)' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show ^side3 main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing a range walks (Y shape, ^ last)' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show main3 ^side3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing with -N walks' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show -2 main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing annotated tag' '
+ cat >expect <<-EOF &&
+ tag annotated
+ commit $(git rev-parse annotated^{commit})
+ EOF
+ git show annotated >actual &&
+ grep -E "^(commit|tag)" actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing annotated tag plus commit' '
+ cat >expect <<-EOF &&
+ tag annotated
+ commit $(git rev-parse annotated^{commit})
+ commit $(git rev-parse side3)
+ EOF
+ git show annotated side3 >actual &&
+ grep -E "^(commit|tag)" actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing range' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show ^side3 annotated >actual &&
+ grep -E "^(commit|tag)" actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success '-s suppresses diff' '
+ echo main3 >expect &&
+ git show -s --format=%s main3 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '--quiet suppresses diff' '
+ echo main3 >expect &&
+ git show --quiet --format=%s main3 >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh
index fd6410fc71..26f831984d 100755
--- a/t/t7008-grep-binary.sh
+++ b/t/t7008-grep-binary.sh
@@ -111,6 +111,28 @@ test_expect_success 'grep respects binary diff attribute' '
test_cmp expect actual
'
+test_expect_success 'grep --cached respects binary diff attribute' '
+ git grep --cached text t >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep --cached respects binary diff attribute (2)' '
+ git add .gitattributes &&
+ rm .gitattributes &&
+ git grep --cached text t >actual &&
+ test_when_finished "git rm --cached .gitattributes" &&
+ test_when_finished "git checkout .gitattributes" &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep revision respects binary diff attribute' '
+ git commit -m new &&
+ echo "Binary file HEAD:t matches" >expect &&
+ git grep text HEAD -- t >actual &&
+ test_when_finished "git reset HEAD^" &&
+ test_cmp expect actual
+'
+
test_expect_success 'grep respects not-binary diff attribute' '
echo binQary | q_to_nul >b &&
git add b &&
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index b8cb4906aa..f4f38a5e73 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' '
cat >expect <<EOF
# On branch side
+# You have unmerged paths.
+# (fix conflicts and run "git commit")
+#
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
@@ -118,4 +121,97 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '
test_cmp expected actual
'
+
+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '
+ git reset --hard &&
+ git checkout master &&
+ test_commit init main.txt init &&
+ git checkout -b second_branch &&
+ git rm main.txt &&
+ git commit -m "main.txt deleted on second_branch" &&
+ test_commit second conflict.txt second &&
+ git checkout master &&
+ test_commit on_second main.txt on_second &&
+ test_commit master conflict.txt master &&
+ test_must_fail git merge second_branch &&
+ cat >expected <<-\EOF &&
+ # On branch master
+ # You have unmerged paths.
+ # (fix conflicts and run "git commit")
+ #
+ # Unmerged paths:
+ # (use "git add/rm <file>..." as appropriate to mark resolution)
+ #
+ # both added: conflict.txt
+ # deleted by them: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'prepare for conflicts' '
+ git reset --hard &&
+ git checkout -b conflict &&
+ test_commit one main.txt one &&
+ git branch conflict_second &&
+ git mv main.txt sub_master.txt &&
+ git commit -m "main.txt renamed in sub_master.txt" &&
+ git checkout conflict_second &&
+ git mv main.txt sub_second.txt &&
+ git commit -m "main.txt renamed in sub_second.txt"
+'
+
+
+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '
+ test_must_fail git merge conflict &&
+ cat >expected <<-\EOF &&
+ # On branch conflict_second
+ # You have unmerged paths.
+ # (fix conflicts and run "git commit")
+ #
+ # Unmerged paths:
+ # (use "git add/rm <file>..." as appropriate to mark resolution)
+ #
+ # both deleted: main.txt
+ # added by them: sub_master.txt
+ # added by us: sub_second.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when conflicts with only rm advice (both deleted)' '
+ git reset --hard conflict_second &&
+ test_must_fail git merge conflict &&
+ git add sub_master.txt &&
+ git add sub_second.txt &&
+ cat >expected <<-\EOF &&
+ # On branch conflict_second
+ # You have unmerged paths.
+ # (fix conflicts and run "git commit")
+ #
+ # Changes to be committed:
+ #
+ # new file: sub_master.txt
+ #
+ # Unmerged paths:
+ # (use "git rm <file>..." to mark resolution)
+ #
+ # both deleted: main.txt
+ #
+ # Untracked files not listed (use -u option to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual &&
+ git reset --hard &&
+ git checkout master
+'
+
+
test_done
diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh
new file mode 100755
index 0000000000..0da1214bcc
--- /dev/null
+++ b/t/t7061-wtstatus-ignore.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+test_description='git-status ignored files'
+
+. ./test-lib.sh
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+?? untracked/
+EOF
+
+test_expect_success 'status untracked directory with --ignored' '
+ echo "ignored" >.gitignore &&
+ mkdir untracked &&
+ : >untracked/ignored &&
+ : >untracked/uncommitted &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+?? untracked/uncommitted
+!! untracked/ignored
+EOF
+
+test_expect_success 'status untracked directory with --ignored -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! ignored/
+EOF
+
+test_expect_success 'status ignored directory with --ignore' '
+ rm -rf untracked &&
+ mkdir ignored &&
+ : >ignored/uncommitted &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! ignored/uncommitted
+EOF
+
+test_expect_success 'status ignored directory with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! untracked-ignored/
+EOF
+
+test_expect_success 'status untracked directory with ignored files with --ignore' '
+ rm -rf ignored &&
+ mkdir untracked-ignored &&
+ mkdir untracked-ignored/test &&
+ : >untracked-ignored/ignored &&
+ : >untracked-ignored/test/ignored &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! untracked-ignored/ignored
+!! untracked-ignored/test/ignored
+EOF
+
+test_expect_success 'status untracked directory with ignored files with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+EOF
+
+test_expect_success 'status ignored tracked directory with --ignore' '
+ rm -rf untracked-ignored &&
+ mkdir tracked &&
+ : >tracked/committed &&
+ git add tracked/committed &&
+ git commit -m. &&
+ echo "tracked" >.gitignore &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+EOF
+
+test_expect_success 'status ignored tracked directory with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! tracked/
+EOF
+
+test_expect_success 'status ignored tracked directory and uncommitted file with --ignore' '
+ : >tracked/uncommitted &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! tracked/uncommitted
+EOF
+
+test_expect_success 'status ignored tracked directory and uncommitted file with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+test_done
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 81827e696f..2683cba7e3 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -133,6 +133,7 @@ test_expect_success 'submodule add --branch' '
(
cd addtest &&
git submodule add -b initial "$submodurl" submod-branch &&
+ test "initial" = "$(git config -f .gitmodules submodule.submod-branch.branch)" &&
git submodule init
) &&
@@ -258,6 +259,27 @@ test_expect_success 'init should register submodule url in .git/config' '
test_cmp expect url
'
+test_failure_with_unknown_submodule () {
+ test_must_fail git submodule $1 no-such-submodule 2>output.err &&
+ grep "^error: .*no-such-submodule" output.err
+}
+
+test_expect_success 'init should fail with unknown submodule' '
+ test_failure_with_unknown_submodule init
+'
+
+test_expect_success 'update should fail with unknown submodule' '
+ test_failure_with_unknown_submodule update
+'
+
+test_expect_success 'status should fail with unknown submodule' '
+ test_failure_with_unknown_submodule status
+'
+
+test_expect_success 'sync should fail with unknown submodule' '
+ test_failure_with_unknown_submodule sync
+'
+
test_expect_success 'update should fail when path is used by a file' '
echo hello >expect &&
@@ -417,11 +439,8 @@ test_expect_success 'moving to a commit without submodule does not leave empty d
git checkout second
'
-test_expect_success 'submodule <invalid-path> warns' '
-
- git submodule no-such-submodule 2> output.err &&
- grep "^error: .*no-such-submodule" output.err
-
+test_expect_success 'submodule <invalid-subcommand> fails' '
+ test_must_fail git submodule no-such-subcommand
'
test_expect_success 'add submodules without specifying an explicit path' '
@@ -483,21 +502,72 @@ test_expect_success 'set up for relative path tests' '
git add sub &&
git config -f .gitmodules submodule.sub.path sub &&
git config -f .gitmodules submodule.sub.url ../subrepo &&
- cp .git/config pristine-.git-config
+ cp .git/config pristine-.git-config &&
+ cp .gitmodules pristine-.gitmodules
)
'
-test_expect_success 'relative path works with URL' '
+test_expect_success '../subrepo works with URL - ssh://hostname/repo' '
(
cd reltest &&
cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
git config remote.origin.url ssh://hostname/repo &&
git submodule init &&
test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
)
'
-test_expect_success 'relative path works with user@host:path' '
+test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ssh://hostname:22/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = ssh://hostname:22/subrepo
+ )
+'
+
+# About the choice of the path in the next test:
+# - double-slash side-steps path mangling issues on Windows
+# - it is still an absolute local path
+# - there cannot be a server with a blank in its name just in case the
+# path is used erroneously to access a //server/share style path
+test_expect_success '../subrepo path works with local path - //somewhere else/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url "//somewhere else/repo" &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = "//somewhere else/subrepo"
+ )
+'
+
+test_expect_success '../subrepo works with file URL - file:///tmp/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url file:///tmp/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = file:///tmp/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url helper:://hostname/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = helper:://hostname/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with scp-style URL - user@host:repo' '
(
cd reltest &&
cp pristine-.git-config .git/config &&
@@ -507,6 +577,98 @@ test_expect_success 'relative path works with user@host:path' '
)
'
+test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url user@host:path/to/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = user@host:path/to/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - foo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url foo &&
+ # actual: fails with an error
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - foo/bar' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url foo/bar &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = foo/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ./foo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ./foo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ./foo/bar' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ./foo/bar &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = foo/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ../foo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ../foo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = ../subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ../foo/bar' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ../foo/bar &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = ../foo/subrepo
+ )
+'
+
+test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ mkdir -p a/b/c &&
+ (cd a/b/c; git init) &&
+ git config remote.origin.url ../foo/bar.git &&
+ git submodule add ../bar/a/b/c ./a/b/c &&
+ git submodule init &&
+ test "$(git config submodule.a/b/c.url)" = ../foo/bar/a/b/c
+ )
+'
+
test_expect_success 'moving the superproject does not break submodules' '
(
cd addtest &&
@@ -520,4 +682,79 @@ test_expect_success 'moving the superproject does not break submodules' '
)
'
+test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
+ (
+ cd addtest2 &&
+ (
+ cd repo &&
+ echo "$submodurl/repo" >expect &&
+ git config remote.origin.url >actual &&
+ test_cmp expect actual &&
+ echo "gitdir: ../.git/modules/repo" >expect &&
+ test_cmp expect .git
+ ) &&
+ rm -rf repo &&
+ git rm repo &&
+ git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual &&
+ test ! -s actual &&
+ echo "gitdir: ../.git/modules/submod" >expect &&
+ test_cmp expect submod/.git &&
+ (
+ cd repo &&
+ echo "$submodurl/bare.git" >expect &&
+ git config remote.origin.url >actual &&
+ test_cmp expect actual &&
+ echo "gitdir: ../.git/modules/repo_new" >expect &&
+ test_cmp expect .git
+ ) &&
+ echo "repo" >expect &&
+ git config -f .gitmodules submodule.repo.path >actual &&
+ test_cmp expect actual &&
+ git config -f .gitmodules submodule.repo_new.path >actual &&
+ test_cmp expect actual&&
+ echo "$submodurl/repo" >expect &&
+ git config -f .gitmodules submodule.repo.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/bare.git" >expect &&
+ git config -f .gitmodules submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/repo" >expect &&
+ git config submodule.repo.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/bare.git" >expect &&
+ git config submodule.repo_new.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'submodule add with an existing name fails unless forced' '
+ (
+ cd addtest2 &&
+ rm -rf repo &&
+ git rm repo &&
+ test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
+ test ! -d repo &&
+ echo "repo" >expect &&
+ git config -f .gitmodules submodule.repo_new.path >actual &&
+ test_cmp expect actual&&
+ echo "$submodurl/bare.git" >expect &&
+ git config -f .gitmodules submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/bare.git" >expect &&
+ git config submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ git submodule add -f -q --name repo_new "$submodurl/repo.git" repo &&
+ test -d repo &&
+ echo "repo" >expect &&
+ git config -f .gitmodules submodule.repo_new.path >actual &&
+ test_cmp expect actual&&
+ echo "$submodurl/repo.git" >expect &&
+ git config -f .gitmodules submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/repo.git" >expect &&
+ git config submodule.repo_new.url >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh
index 3620215c1f..94e26c47ea 100755
--- a/t/t7403-submodule-sync.sh
+++ b/t/t7403-submodule-sync.sh
@@ -17,16 +17,25 @@ test_expect_success setup '
git commit -m upstream &&
git clone . super &&
git clone super submodule &&
+ (cd submodule &&
+ git submodule add ../submodule sub-submodule &&
+ test_tick &&
+ git commit -m "sub-submodule"
+ ) &&
(cd super &&
git submodule add ../submodule submodule &&
test_tick &&
git commit -m "submodule"
) &&
git clone super super-clone &&
- (cd super-clone && git submodule update --init) &&
+ (cd super-clone && git submodule update --init --recursive) &&
git clone super empty-clone &&
(cd empty-clone && git submodule init) &&
- git clone super top-only-clone
+ git clone super top-only-clone &&
+ git clone super relative-clone &&
+ (cd relative-clone && git submodule update --init --recursive) &&
+ git clone super recursive-clone &&
+ (cd recursive-clone && git submodule update --init --recursive)
'
test_expect_success 'change submodule' '
@@ -44,6 +53,11 @@ test_expect_success 'change submodule url' '
git pull
) &&
mv submodule moved-submodule &&
+ (cd moved-submodule &&
+ git config -f .gitmodules submodule.sub-submodule.url ../moved-submodule &&
+ test_tick &&
+ git commit -a -m moved-sub-submodule
+ ) &&
(cd super &&
git config -f .gitmodules submodule.submodule.url ../moved-submodule &&
test_tick &&
@@ -59,6 +73,9 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
test -d "$(cd super-clone/submodule &&
git config remote.origin.url
)" &&
+ test ! -d "$(cd super-clone/submodule/sub-submodule &&
+ git config remote.origin.url
+ )" &&
(cd super-clone/submodule &&
git checkout master &&
git pull
@@ -68,6 +85,25 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
)
'
+test_expect_success '"git submodule sync --recursive" should update all submodule URLs' '
+ (cd super-clone &&
+ (cd submodule &&
+ git pull --no-recurse-submodules
+ ) &&
+ git submodule sync --recursive
+ ) &&
+ test -d "$(cd super-clone/submodule &&
+ git config remote.origin.url
+ )" &&
+ test -d "$(cd super-clone/submodule/sub-submodule &&
+ git config remote.origin.url
+ )" &&
+ (cd super-clone/submodule/sub-submodule &&
+ git checkout master &&
+ git pull
+ )
+'
+
test_expect_success '"git submodule sync" should update known submodule URLs' '
(cd empty-clone &&
git pull &&
@@ -86,4 +122,107 @@ test_expect_success '"git submodule sync" should not vivify uninteresting submod
)
'
+test_expect_success '"git submodule sync" handles origin URL of the form foo' '
+ (cd relative-clone &&
+ git remote set-url origin foo &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual fails with: "cannot strip off url foo
+ test "$(git config remote.origin.url)" = "../submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form foo/bar' '
+ (cd relative-clone &&
+ git remote set-url origin foo/bar &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual foo/submodule
+ test "$(git config remote.origin.url)" = "../foo/submodule"
+ )
+ (cd submodule/sub-submodule &&
+ test "$(git config remote.origin.url)" != "../../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync --recursive" propagates changes in origin' '
+ (cd recursive-clone &&
+ git remote set-url origin foo/bar &&
+ git submodule sync --recursive &&
+ (cd submodule &&
+ #actual foo/submodule
+ test "$(git config remote.origin.url)" = "../foo/submodule"
+ )
+ (cd submodule/sub-submodule &&
+ test "$(git config remote.origin.url)" = "../../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ./foo' '
+ (cd relative-clone &&
+ git remote set-url origin ./foo &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ./submodule
+ test "$(git config remote.origin.url)" = "../submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ./foo/bar' '
+ (cd relative-clone &&
+ git remote set-url origin ./foo/bar &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ./foo/submodule
+ test "$(git config remote.origin.url)" = "../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo' '
+ (cd relative-clone &&
+ git remote set-url origin ../foo &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ../submodule
+ test "$(git config remote.origin.url)" = "../../submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar' '
+ (cd relative-clone &&
+ git remote set-url origin ../foo/bar &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ../foo/submodule
+ test "$(git config remote.origin.url)" = "../../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar with deeply nested submodule' '
+ (cd relative-clone &&
+ git remote set-url origin ../foo/bar &&
+ mkdir -p a/b/c &&
+ ( cd a/b/c &&
+ git init &&
+ :> .gitignore &&
+ git add .gitignore &&
+ test_tick &&
+ git commit -m "initial commit" ) &&
+ git submodule add ../bar/a/b/c ./a/b/c &&
+ git submodule sync &&
+ (cd a/b/c &&
+ #actual ../foo/bar/a/b/c
+ test "$(git config remote.origin.url)" = "../../../../foo/bar/a/b/c"
+ )
+ )
+'
+
+
test_done
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index dcb195b4cf..4975ec07ce 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -123,6 +123,49 @@ test_expect_success 'submodule update should throw away changes with --force ' '
)
'
+test_expect_success 'submodule update --force forcibly checks out submodules' '
+ (cd super &&
+ (cd submodule &&
+ rm -f file
+ ) &&
+ git submodule update --force submodule &&
+ (cd submodule &&
+ test "$(git status -s file)" = ""
+ )
+ )
+'
+
+test_expect_success 'submodule update --remote should fetch upstream changes' '
+ (cd submodule &&
+ echo line4 >> file &&
+ git add file &&
+ test_tick &&
+ git commit -m "upstream line4"
+ ) &&
+ (cd super &&
+ git submodule update --remote --force submodule &&
+ cd submodule &&
+ test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline)"
+ )
+'
+
+test_expect_success 'local config should override .gitmodules branch' '
+ (cd submodule &&
+ git checkout -b test-branch &&
+ echo line5 >> file &&
+ git add file &&
+ test_tick &&
+ git commit -m "upstream line5" &&
+ git checkout master
+ ) &&
+ (cd super &&
+ git config submodule.submodule.branch test-branch &&
+ git submodule update --remote --force submodule &&
+ cd submodule &&
+ test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline test-branch)"
+ )
+'
+
test_expect_success 'submodule update --rebase staying on master' '
(cd super/submodule &&
git checkout master
@@ -367,7 +410,7 @@ test_expect_success 'submodule update continues after checkout error' '
git submodule init &&
git commit -am "new_submodule" &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../expect
+ git rev-parse --verify HEAD >../expect
) &&
(cd submodule &&
test_commit "update_submodule" file
@@ -384,7 +427,7 @@ test_expect_success 'submodule update continues after checkout error' '
git checkout HEAD^ &&
test_must_fail git submodule update &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../actual
+ git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)
@@ -413,7 +456,7 @@ test_expect_success 'submodule update continues after recursive checkout error'
test_commit "update_submodule_again_again" file
) &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../expect &&
+ git rev-parse --verify HEAD >../expect &&
test_commit "update_submodule2_again" file
) &&
git add submodule &&
@@ -428,7 +471,7 @@ test_expect_success 'submodule update continues after recursive checkout error'
) &&
test_must_fail git submodule update --recursive &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../actual
+ git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)
@@ -460,12 +503,12 @@ test_expect_success 'submodule update exit immediately in case of merge conflict
) &&
git checkout HEAD^ &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../expect
+ git rev-parse --verify HEAD >../expect
) &&
git config submodule.submodule.update merge &&
test_must_fail git submodule update &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../actual
+ git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)
@@ -495,12 +538,12 @@ test_expect_success 'submodule update exit immediately after recursive rebase er
) &&
git checkout HEAD^ &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../expect
+ git rev-parse --verify HEAD >../expect
) &&
git config submodule.submodule.update rebase &&
test_must_fail git submodule update &&
(cd submodule2 &&
- git rev-parse --max-count=1 HEAD > ../actual
+ git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)
@@ -615,7 +658,7 @@ test_expect_success 'submodule add properly re-creates deeper level submodules'
(cd super &&
git reset --hard master &&
rm -rf deeper/ &&
- git submodule add ../submodule deeper/submodule
+ git submodule add --force ../submodule deeper/submodule
)
'
@@ -636,4 +679,17 @@ test_expect_success 'submodule update properly revives a moved submodule' '
)
'
+test_expect_success SYMLINKS 'submodule update can handle symbolic links in pwd' '
+ mkdir -p linked/dir &&
+ ln -s linked/dir linkto &&
+ (
+ cd linkto &&
+ git clone "$TRASH_DIRECTORY"/super_update_r2 super &&
+ (
+ cd super &&
+ git submodule update --init --recursive
+ )
+ )
+'
+
test_done
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 9b69fe2e14..107b4b7c45 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -226,14 +226,14 @@ test_expect_success 'test "status --recursive"' '
test_cmp expect actual
'
-sed -e "/nested1 /s/.*/+$nested1sha1 nested1 (file2~1)/;/sub[1-3]/d" < expect > expect2
+sed -e "/nested2 /s/.*/+$nested2sha1 nested1\/nested2 (file2~1)/;/sub[1-3]/d" < expect > expect2
mv -f expect2 expect
test_expect_success 'ensure "status --cached --recursive" preserves the --cached flag' '
(
cd clone3 &&
(
- cd nested1 &&
+ cd nested1/nested2 &&
test_commit file2
) &&
git submodule status --cached --recursive -- nested1 > ../actual
diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh
index a45fadc58e..b770b2f04d 100755
--- a/t/t7408-submodule-reference.sh
+++ b/t/t7408-submodule-reference.sh
@@ -28,7 +28,7 @@ git prune'
cd "$base_dir"
-test_expect_success 'preparing supermodule' \
+test_expect_success 'preparing superproject' \
'test_create_repo super && cd super &&
echo file > file &&
git add file &&
@@ -55,7 +55,7 @@ diff expected current'
cd "$base_dir"
-test_expect_success 'cloning supermodule' \
+test_expect_success 'cloning superproject' \
'git clone super super-clone'
cd "$base_dir"
diff --git a/t/t7409-submodule-detached-worktree.sh b/t/t7409-submodule-detached-worktree.sh
new file mode 100755
index 0000000000..2fec13dcd3
--- /dev/null
+++ b/t/t7409-submodule-detached-worktree.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Daniel Graña
+#
+
+test_description='Test submodules on detached working tree
+
+This test verifies that "git submodule" initialization, update and addition works
+on detahced working trees
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+
+test_expect_success 'submodule on detached working tree' '
+ git init --bare remote &&
+ test_create_repo bundle1 &&
+ (
+ cd bundle1 &&
+ test_commit "shoot" &&
+ git rev-parse --verify HEAD >../expect
+ ) &&
+ mkdir home &&
+ (
+ cd home &&
+ export GIT_WORK_TREE="$(pwd)" GIT_DIR="$(pwd)/.dotfiles" &&
+ git clone --bare ../remote .dotfiles &&
+ git submodule add ../bundle1 .vim/bundle/sogood &&
+ test_commit "sogood" &&
+ (
+ unset GIT_WORK_TREE GIT_DIR &&
+ cd .vim/bundle/sogood &&
+ git rev-parse --verify HEAD >actual &&
+ test_cmp ../../../../expect actual
+ ) &&
+ git push origin master
+ ) &&
+ mkdir home2 &&
+ (
+ cd home2 &&
+ git clone --bare ../remote .dotfiles &&
+ export GIT_WORK_TREE="$(pwd)" GIT_DIR="$(pwd)/.dotfiles" &&
+ git checkout master &&
+ git submodule update --init &&
+ (
+ unset GIT_WORK_TREE GIT_DIR &&
+ cd .vim/bundle/sogood &&
+ git rev-parse --verify HEAD >actual &&
+ test_cmp ../../../../expect actual
+ )
+ )
+'
+
+test_expect_success 'submodule on detached working pointed by core.worktree' '
+ mkdir home3 &&
+ (
+ cd home3 &&
+ export GIT_DIR="$(pwd)/.dotfiles" &&
+ git clone --bare ../remote "$GIT_DIR" &&
+ git config core.bare false &&
+ git config core.worktree .. &&
+ git checkout master &&
+ git submodule add ../bundle1 .vim/bundle/dupe &&
+ test_commit "dupe" &&
+ git push origin master
+ ) &&
+ (
+ cd home &&
+ export GIT_DIR="$(pwd)/.dotfiles" &&
+ git config core.bare false &&
+ git config core.worktree .. &&
+ git pull &&
+ git submodule update --init &&
+ test -f .vim/bundle/dupe/shoot.t
+ )
+'
+
+test_done
diff --git a/t/t7500/add-content-and-comment b/t/t7500/add-content-and-comment
new file mode 100755
index 0000000000..c4dccff13a
--- /dev/null
+++ b/t/t7500/add-content-and-comment
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo "commit message" >> "$1"
+echo "# comment" >> "$1"
+exit 0
+
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index b20ca0eace..195e7477d8 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -108,6 +108,16 @@ test_expect_success 'amend commit' '
EDITOR=./editor git commit --amend
'
+test_expect_success 'amend --only ignores staged contents' '
+ cp file file.expect &&
+ echo changed >file &&
+ git add file &&
+ git commit --no-edit --amend --only &&
+ git cat-file blob HEAD:file >file.actual &&
+ test_cmp file.expect file.actual &&
+ git diff --exit-code
+'
+
test_expect_success 'set up editor' '
cat >editor <<-\EOF &&
#!/bin/sh
@@ -138,6 +148,21 @@ test_expect_success '--amend --edit' '
test_cmp expect msg
'
+test_expect_success '--amend --edit of empty message' '
+ cat >replace <<-\EOF &&
+ #!/bin/sh
+ echo "amended" >"$1"
+ EOF
+ chmod 755 replace &&
+ git commit --allow-empty --allow-empty-message -m "" &&
+ echo more bongo >file &&
+ git add file &&
+ EDITOR=./replace git commit --edit --amend &&
+ git diff-tree -s --format=%s HEAD >msg &&
+ ./replace expect &&
+ test_cmp expect msg
+'
+
test_expect_success '-m --edit' '
echo amended >expect &&
git commit --allow-empty -m buffer &&
@@ -487,4 +512,16 @@ test_expect_success 'amend can copy notes' '
'
+test_expect_success 'commit a file whose name is a dash' '
+ git reset --hard &&
+ for i in 1 2 3 4 5
+ do
+ echo $i
+ done >./- &&
+ git add ./- &&
+ test_tick &&
+ git commit -m "add dash" >output </dev/null &&
+ test_i18ngrep " changed, 5 insertions" output
+'
+
test_done
diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh
index 181456aa9a..b1c7648386 100755
--- a/t/t7502-commit.sh
+++ b/t/t7502-commit.sh
@@ -4,6 +4,15 @@ test_description='git commit porcelain-ish'
. ./test-lib.sh
+commit_msg_is () {
+ expect=commit_msg_is.expect
+ actual=commit_msg_is.actual
+
+ printf "%s" "$(git log --pretty=format:%s%b -1)" >$actual &&
+ printf "%s" "$1" >$expect &&
+ test_i18ncmp $expect $actual
+}
+
# Arguments: [<prefix] [<commit message>] [<commit options>]
check_summary_oneline() {
test_tick &&
@@ -168,7 +177,7 @@ test_expect_success 'verbose respects diff config' '
git config --unset color.diff
'
-test_expect_success 'cleanup commit messages (verbatim,-t)' '
+test_expect_success 'cleanup commit messages (verbatim option,-t)' '
echo >>negative &&
{ echo;echo "# text";echo; } >expect &&
@@ -178,7 +187,7 @@ test_expect_success 'cleanup commit messages (verbatim,-t)' '
'
-test_expect_success 'cleanup commit messages (verbatim,-F)' '
+test_expect_success 'cleanup commit messages (verbatim option,-F)' '
echo >>negative &&
git commit --cleanup=verbatim -F expect -a &&
@@ -187,7 +196,7 @@ test_expect_success 'cleanup commit messages (verbatim,-F)' '
'
-test_expect_success 'cleanup commit messages (verbatim,-m)' '
+test_expect_success 'cleanup commit messages (verbatim option,-m)' '
echo >>negative &&
git commit --cleanup=verbatim -m "$(cat expect)" -a &&
@@ -196,7 +205,7 @@ test_expect_success 'cleanup commit messages (verbatim,-m)' '
'
-test_expect_success 'cleanup commit messages (whitespace,-F)' '
+test_expect_success 'cleanup commit messages (whitespace option,-F)' '
echo >>negative &&
{ echo;echo "# text";echo; } >text &&
@@ -207,7 +216,7 @@ test_expect_success 'cleanup commit messages (whitespace,-F)' '
'
-test_expect_success 'cleanup commit messages (strip,-F)' '
+test_expect_success 'cleanup commit messages (strip option,-F)' '
echo >>negative &&
{ echo;echo "# text";echo sample;echo; } >text &&
@@ -218,7 +227,7 @@ test_expect_success 'cleanup commit messages (strip,-F)' '
'
-test_expect_success 'cleanup commit messages (strip,-F,-e)' '
+test_expect_success 'cleanup commit messages (strip option,-F,-e)' '
echo >>negative &&
{ echo;echo sample;echo; } >text &&
@@ -231,48 +240,111 @@ echo "sample
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit." >expect
-test_expect_success 'cleanup commit messages (strip,-F,-e): output' '
+test_expect_success 'cleanup commit messages (strip option,-F,-e): output' '
test_i18ncmp expect actual
'
-echo "#
-# Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
-#" >> expect
+test_expect_success 'cleanup commit message (fail on invalid cleanup mode option)' '
+ test_must_fail git commit --cleanup=non-existent
+'
+
+test_expect_success 'cleanup commit message (fail on invalid cleanup mode configuration)' '
+ test_must_fail git -c commit.cleanup=non-existent commit
+'
-test_expect_success 'author different from committer' '
- echo >>negative &&
- test_might_fail git commit -e -m "sample" &&
- head -n 7 .git/COMMIT_EDITMSG >actual &&
- test_i18ncmp expect actual
+test_expect_success 'cleanup commit message (no config and no option uses default)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git commit --no-status &&
+ commit_msg_is "commit message"
+'
+
+test_expect_success 'cleanup commit message (option overrides default)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git commit --cleanup=whitespace --no-status &&
+ commit_msg_is "commit message # comment"
+'
+
+test_expect_success 'cleanup commit message (config overrides default)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git -c commit.cleanup=whitespace commit --no-status &&
+ commit_msg_is "commit message # comment"
+'
+
+test_expect_success 'cleanup commit message (option overrides config)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git -c commit.cleanup=whitespace commit --cleanup=default &&
+ commit_msg_is "commit message"
+'
+
+test_expect_success 'cleanup commit message (default, -m)' '
+ echo content >>file &&
+ git add file &&
+ git commit -m "message #comment " &&
+ commit_msg_is "message #comment"
'
-mv expect expect.tmp
-sed '$d' < expect.tmp > expect
-rm -f expect.tmp
-echo "# Committer:
-#" >> expect
+test_expect_success 'cleanup commit message (whitespace option, -m)' '
+ echo content >>file &&
+ git add file &&
+ git commit --cleanup=whitespace --no-status -m "message #comment " &&
+ commit_msg_is "message #comment"
+'
+
+test_expect_success 'cleanup commit message (whitespace config, -m)' '
+ echo content >>file &&
+ git add file &&
+ git -c commit.cleanup=whitespace commit --no-status -m "message #comment " &&
+ commit_msg_is "message #comment"
+'
+
+test_expect_success 'message shows author when it is not equal to committer' '
+ echo >>negative &&
+ git commit -e -m "sample" -a &&
+ test_i18ngrep \
+ "^# Author: *A U Thor <author@example.com>\$" \
+ .git/COMMIT_EDITMSG
+'
-test_expect_success 'committer is automatic' '
+test_expect_success AUTOIDENT 'message shows committer when it is automatic' '
echo >>negative &&
(
sane_unset GIT_COMMITTER_EMAIL &&
sane_unset GIT_COMMITTER_NAME &&
- # must fail because there is no change
- test_must_fail git commit -e -m "sample"
+ git commit -e -m "sample" -a
) &&
- head -n 8 .git/COMMIT_EDITMSG | \
- sed "s/^# Committer: .*/# Committer:/" >actual
- test_i18ncmp expect actual
+ # the ident is calculated from the system, so we cannot
+ # check the actual value, only that it is there
+ test_i18ngrep "^# Committer: " .git/COMMIT_EDITMSG
'
-pwd=`pwd`
-cat >> .git/FAKE_EDITOR << EOF
-#! /bin/sh
-echo editor started > "$pwd/.git/result"
+write_script .git/FAKE_EDITOR <<EOF
+echo editor started > "$(pwd)/.git/result"
exit 0
EOF
-chmod +x .git/FAKE_EDITOR
+
+test_expect_success !AUTOIDENT 'do not fire editor when committer is bogus' '
+ >.git/result
+ >expect &&
+
+ echo >>negative &&
+ (
+ sane_unset GIT_COMMITTER_EMAIL &&
+ sane_unset GIT_COMMITTER_NAME &&
+ GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" &&
+ export GIT_EDITOR &&
+ test_must_fail git commit -e -m sample -a
+ ) &&
+ test_cmp expect .git/result
+'
test_expect_success 'do not fire editor in the presence of conflicts' '
@@ -293,16 +365,14 @@ test_expect_success 'do not fire editor in the presence of conflicts' '
test_must_fail git cherry-pick -n master &&
echo "editor not started" >.git/result &&
(
- GIT_EDITOR="$(pwd)/.git/FAKE_EDITOR" &&
+ GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" &&
export GIT_EDITOR &&
test_must_fail git commit
) &&
test "$(cat .git/result)" = "editor not started"
'
-pwd=`pwd`
-cat >.git/FAKE_EDITOR <<EOF
-#! $SHELL_PATH
+write_script .git/FAKE_EDITOR <<EOF
# kill -TERM command added below.
EOF
@@ -339,13 +409,12 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo
'
-cat >.git/FAKE_EDITOR <<EOF
-#!$SHELL_PATH
-mv "\$1" "\$1.orig"
+write_script .git/FAKE_EDITOR <<\EOF
+mv "$1" "$1.orig"
(
echo message
- cat "\$1.orig"
-) >"\$1"
+ cat "$1.orig"
+) >"$1"
EOF
echo '## Custom template' >template
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 5b4b694f18..357375151d 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -167,5 +167,19 @@ test_expect_success 'with failing hook (--no-verify)' '
'
+test_expect_success 'with failing hook (merge)' '
+
+ git checkout -B other HEAD@{1} &&
+ echo "more" >> file &&
+ git add file &&
+ rm -f "$HOOK" &&
+ git commit -m other &&
+ write_script "$HOOK" <<-EOF
+ exit 1
+ EOF
+ git checkout - &&
+ test_must_fail git merge other
+
+'
test_done
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index fc57b135c5..e313ef196e 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -59,6 +59,30 @@ test_expect_success 'status (1)' '
test_i18ngrep "use \"git rm --cached <file>\.\.\.\" to unstage" output
'
+test_expect_success 'status --column' '
+ COLUMNS=50 git status --column="column dense" >output &&
+ cat >expect <<\EOF &&
+# On branch master
+# Changes to be committed:
+# (use "git reset HEAD <file>..." to unstage)
+#
+# new file: dir2/added
+#
+# Changes not staged for commit:
+# (use "git add <file>..." to update what will be committed)
+# (use "git checkout -- <file>..." to discard changes in working directory)
+#
+# modified: dir1/modified
+#
+# Untracked files:
+# (use "git add <file>..." to include in what will be committed)
+#
+# dir1/untracked dir2/untracked untracked
+# dir2/modified output
+EOF
+ test_i18ncmp expect output
+'
+
cat >expect <<\EOF
# On branch master
# Changes to be committed:
@@ -271,6 +295,15 @@ test_expect_success 'status -s -b' '
'
+test_expect_success 'status -s -z -b' '
+ tr "\\n" Q <expect >expect.q &&
+ mv expect.q expect &&
+ git status -s -z -b >output &&
+ nul_to_q <output >output.q &&
+ mv output.q output &&
+ test_cmp expect output
+'
+
test_expect_success 'setup dir3' '
mkdir dir3 &&
: >dir3/untracked1 &&
@@ -647,9 +680,14 @@ test_expect_success 'status --porcelain ignores color.status' '
git config --unset color.status
git config --unset color.ui
-test_expect_success 'status --porcelain ignores -b' '
+test_expect_success 'status --porcelain respects -b' '
git status --porcelain -b >output &&
+ {
+ echo "## master" &&
+ cat expect
+ } >tmp &&
+ mv tmp expect &&
test_cmp expect output
'
@@ -903,7 +941,7 @@ test_expect_success 'status -s submodule summary (clean submodule)' '
test_expect_success 'status -z implies porcelain' '
git status --porcelain |
- perl -pe "s/\012/\000/g" >expect &&
+ "$PERL_PATH" -pe "s/\012/\000/g" >expect &&
git status -z >output &&
test_cmp expect output
'
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
new file mode 100755
index 0000000000..b3f6eb9c68
--- /dev/null
+++ b/t/t7512-status-help.sh
@@ -0,0 +1,649 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,
+# Thomas Nguy, Khoi Nguyen
+# Grenoble INP Ensimag
+#
+
+test_description='git status advices'
+
+. ./test-lib.sh
+
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+set_fake_editor
+
+test_expect_success 'prepare for conflicts' '
+ test_commit init main.txt init &&
+ git branch conflicts &&
+ test_commit on_master main.txt on_master &&
+ git checkout conflicts &&
+ test_commit on_conflicts main.txt on_conflicts
+'
+
+
+test_expect_success 'status when conflicts unresolved' '
+ test_must_fail git merge master &&
+ cat >expected <<-\EOF &&
+ # On branch conflicts
+ # You have unmerged paths.
+ # (fix conflicts and run "git commit")
+ #
+ # Unmerged paths:
+ # (use "git add <file>..." to mark resolution)
+ #
+ # both modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when conflicts resolved before commit' '
+ git reset --hard conflicts &&
+ test_must_fail git merge master &&
+ echo one >main.txt &&
+ git add main.txt &&
+ cat >expected <<-\EOF &&
+ # On branch conflicts
+ # All conflicts fixed but you are still merging.
+ # (use "git commit" to conclude merge)
+ #
+ # Changes to be committed:
+ #
+ # modified: main.txt
+ #
+ # Untracked files not listed (use -u option to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'prepare for rebase conflicts' '
+ git reset --hard master &&
+ git checkout -b rebase_conflicts &&
+ test_commit one_rebase main.txt one &&
+ test_commit two_rebase main.txt two &&
+ test_commit three_rebase main.txt three
+'
+
+
+test_expect_success 'status when rebase in progress before resolving conflicts' '
+ test_when_finished "git rebase --abort" &&
+ test_must_fail git rebase HEAD^ --onto HEAD^^ &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently rebasing.
+ # (fix conflicts and then run "git rebase --continue")
+ # (use "git rebase --skip" to skip this patch)
+ # (use "git rebase --abort" to check out the original branch)
+ #
+ # Unmerged paths:
+ # (use "git reset HEAD <file>..." to unstage)
+ # (use "git add <file>..." to mark resolution)
+ #
+ # both modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when rebase in progress before rebase --continue' '
+ git reset --hard rebase_conflicts &&
+ test_when_finished "git rebase --abort" &&
+ test_must_fail git rebase HEAD^ --onto HEAD^^ &&
+ echo three >main.txt &&
+ git add main.txt &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently rebasing.
+ # (all conflicts fixed: run "git rebase --continue")
+ #
+ # Changes to be committed:
+ # (use "git reset HEAD <file>..." to unstage)
+ #
+ # modified: main.txt
+ #
+ # Untracked files not listed (use -u option to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'prepare for rebase_i_conflicts' '
+ git reset --hard master &&
+ git checkout -b rebase_i_conflicts &&
+ test_commit one_unmerge main.txt one_unmerge &&
+ git branch rebase_i_conflicts_second &&
+ test_commit one_master main.txt one_master &&
+ git checkout rebase_i_conflicts_second &&
+ test_commit one_second main.txt one_second
+'
+
+
+test_expect_success 'status during rebase -i when conflicts unresolved' '
+ test_when_finished "git rebase --abort" &&
+ test_must_fail git rebase -i rebase_i_conflicts &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently rebasing.
+ # (fix conflicts and then run "git rebase --continue")
+ # (use "git rebase --skip" to skip this patch)
+ # (use "git rebase --abort" to check out the original branch)
+ #
+ # Unmerged paths:
+ # (use "git reset HEAD <file>..." to unstage)
+ # (use "git add <file>..." to mark resolution)
+ #
+ # both modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status during rebase -i after resolving conflicts' '
+ git reset --hard rebase_i_conflicts_second &&
+ test_when_finished "git rebase --abort" &&
+ test_must_fail git rebase -i rebase_i_conflicts &&
+ git add main.txt &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently rebasing.
+ # (all conflicts fixed: run "git rebase --continue")
+ #
+ # Changes to be committed:
+ # (use "git reset HEAD <file>..." to unstage)
+ #
+ # modified: main.txt
+ #
+ # Untracked files not listed (use -u option to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when rebasing -i in edit mode' '
+ git reset --hard master &&
+ git checkout -b rebase_i_edit &&
+ test_commit one_rebase_i main.txt one &&
+ test_commit two_rebase_i main.txt two &&
+ test_commit three_rebase_i main.txt three &&
+ FAKE_LINES="1 edit 2" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~2 &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when splitting a commit' '
+ git reset --hard master &&
+ git checkout -b split_commit &&
+ test_commit one_split main.txt one &&
+ test_commit two_split main.txt two &&
+ test_commit three_split main.txt three &&
+ test_commit four_split main.txt four &&
+ FAKE_LINES="1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git reset HEAD^ &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently splitting a commit during a rebase.
+ # (Once your working directory is clean, run "git rebase --continue")
+ #
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status after editing the last commit with --amend during a rebase -i' '
+ git reset --hard master &&
+ git checkout -b amend_last &&
+ test_commit one_amend main.txt one &&
+ test_commit two_amend main.txt two &&
+ test_commit three_amend main.txt three &&
+ test_commit four_amend main.txt four &&
+ FAKE_LINES="1 2 edit 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git commit --amend -m "foo" &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'prepare for several edits' '
+ git reset --hard master &&
+ git checkout -b several_edits &&
+ test_commit one_edits main.txt one &&
+ test_commit two_edits main.txt two &&
+ test_commit three_edits main.txt three &&
+ test_commit four_edits main.txt four
+'
+
+
+test_expect_success 'status: (continue first edit) second edit' '
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git rebase --continue &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (continue first edit) second edit and split' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git rebase --continue &&
+ git reset HEAD^ &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently splitting a commit during a rebase.
+ # (Once your working directory is clean, run "git rebase --continue")
+ #
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (continue first edit) second edit and amend' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git rebase --continue &&
+ git commit --amend -m "foo" &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (amend first edit) second edit' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git commit --amend -m "a" &&
+ git rebase --continue &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (amend first edit) second edit and split' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git commit --amend -m "b" &&
+ git rebase --continue &&
+ git reset HEAD^ &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently splitting a commit during a rebase.
+ # (Once your working directory is clean, run "git rebase --continue")
+ #
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (amend first edit) second edit and amend' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git commit --amend -m "c" &&
+ git rebase --continue &&
+ git commit --amend -m "d" &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (split first edit) second edit' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git reset HEAD^ &&
+ git add main.txt &&
+ git commit -m "e" &&
+ git rebase --continue &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (split first edit) second edit and split' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git reset HEAD^ &&
+ git add main.txt &&
+ git commit --amend -m "f" &&
+ git rebase --continue &&
+ git reset HEAD^ &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently splitting a commit during a rebase.
+ # (Once your working directory is clean, run "git rebase --continue")
+ #
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status: (split first edit) second edit and amend' '
+ git reset --hard several_edits &&
+ FAKE_LINES="edit 1 edit 2 3" &&
+ export FAKE_LINES &&
+ test_when_finished "git rebase --abort" &&
+ git rebase -i HEAD~3 &&
+ git reset HEAD^ &&
+ git add main.txt &&
+ git commit --amend -m "g" &&
+ git rebase --continue &&
+ git commit --amend -m "h" &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently editing a commit during a rebase.
+ # (use "git commit --amend" to amend the current commit)
+ # (use "git rebase --continue" once you are satisfied with your changes)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'prepare am_session' '
+ git reset --hard master &&
+ git checkout -b am_session &&
+ test_commit one_am one.txt "one" &&
+ test_commit two_am two.txt "two" &&
+ test_commit three_am three.txt "three"
+'
+
+
+test_expect_success 'status in an am session: file already exists' '
+ git checkout -b am_already_exists &&
+ test_when_finished "rm Maildir/* && git am --abort" &&
+ git format-patch -1 -oMaildir &&
+ test_must_fail git am Maildir/*.patch &&
+ cat >expected <<-\EOF &&
+ # On branch am_already_exists
+ # You are in the middle of an am session.
+ # (fix conflicts and then run "git am --resolved")
+ # (use "git am --skip" to skip this patch)
+ # (use "git am --abort" to restore the original branch)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status in an am session: file does not exist' '
+ git reset --hard am_session &&
+ git checkout -b am_not_exists &&
+ git rm three.txt &&
+ git commit -m "delete three.txt" &&
+ test_when_finished "rm Maildir/* && git am --abort" &&
+ git format-patch -1 -oMaildir &&
+ test_must_fail git am Maildir/*.patch &&
+ cat >expected <<-\EOF &&
+ # On branch am_not_exists
+ # You are in the middle of an am session.
+ # (fix conflicts and then run "git am --resolved")
+ # (use "git am --skip" to skip this patch)
+ # (use "git am --abort" to restore the original branch)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status in an am session: empty patch' '
+ git reset --hard am_session &&
+ git checkout -b am_empty &&
+ test_when_finished "rm Maildir/* && git am --abort" &&
+ git format-patch -3 -oMaildir &&
+ git rm one.txt two.txt three.txt &&
+ git commit -m "delete all am_empty" &&
+ echo error >Maildir/0002-two_am.patch &&
+ test_must_fail git am Maildir/*.patch &&
+ cat >expected <<-\EOF &&
+ # On branch am_empty
+ # You are in the middle of an am session.
+ # The current patch is empty.
+ # (use "git am --skip" to skip this patch)
+ # (use "git am --abort" to restore the original branch)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when bisecting' '
+ git reset --hard master &&
+ git checkout -b bisect &&
+ test_commit one_bisect main.txt one &&
+ test_commit two_bisect main.txt two &&
+ test_commit three_bisect main.txt three &&
+ test_when_finished "git bisect reset" &&
+ git bisect start &&
+ git bisect bad &&
+ git bisect good one_bisect &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently bisecting.
+ # (use "git bisect reset" to get back to the original branch)
+ #
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when rebase conflicts with statushints disabled' '
+ git reset --hard master &&
+ git checkout -b statushints_disabled &&
+ test_when_finished "git config --local advice.statushints true" &&
+ git config --local advice.statushints false &&
+ test_commit one_statushints main.txt one &&
+ test_commit two_statushints main.txt two &&
+ test_commit three_statushints main.txt three &&
+ test_when_finished "git rebase --abort" &&
+ test_must_fail git rebase HEAD^ --onto HEAD^^ &&
+ cat >expected <<-\EOF &&
+ # Not currently on any branch.
+ # You are currently rebasing.
+ #
+ # Unmerged paths:
+ # both modified: main.txt
+ #
+ no changes added to commit
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'prepare for cherry-pick conflicts' '
+ git reset --hard master &&
+ git checkout -b cherry_branch &&
+ test_commit one_cherry main.txt one &&
+ test_commit two_cherries main.txt two &&
+ git checkout -b cherry_branch_second &&
+ test_commit second_cherry main.txt second &&
+ git checkout cherry_branch &&
+ test_commit three_cherries main.txt three
+'
+
+
+test_expect_success 'status when cherry-picking before resolving conflicts' '
+ test_when_finished "git cherry-pick --abort" &&
+ test_must_fail git cherry-pick cherry_branch_second &&
+ cat >expected <<-\EOF &&
+ # On branch cherry_branch
+ # You are currently cherry-picking.
+ # (fix conflicts and run "git commit")
+ #
+ # Unmerged paths:
+ # (use "git add <file>..." to mark resolution)
+ #
+ # both modified: main.txt
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'status when cherry-picking after resolving conflicts' '
+ git reset --hard cherry_branch &&
+ test_when_finished "git cherry-pick --abort" &&
+ test_must_fail git cherry-pick cherry_branch_second &&
+ echo end >main.txt &&
+ git add main.txt &&
+ cat >expected <<-\EOF &&
+ # On branch cherry_branch
+ # You are currently cherry-picking.
+ # (all conflicts fixed: run "git commit")
+ #
+ # Changes to be committed:
+ #
+ # modified: main.txt
+ #
+ # Untracked files not listed (use -u option to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
+
+
+test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 9e27bbf902..5e19598fe7 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -157,7 +157,7 @@ test_expect_success 'merge -h with invalid index' '
>.git/index &&
test_expect_code 129 git merge -h 2>usage
) &&
- grep "[Uu]sage: git merge" broken/usage
+ test_i18ngrep "[Uu]sage: git merge" broken/usage
'
test_expect_success 'reject non-strategy with a git-merge-foo name' '
diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh
index 3b72c097ee..955f09f8e8 100755
--- a/t/t7602-merge-octopus-many.sh
+++ b/t/t7602-merge-octopus-many.sh
@@ -54,9 +54,9 @@ Trying simple merge with c2
Trying simple merge with c3
Trying simple merge with c4
Merge made by the 'octopus' strategy.
- c2.c | 1 +
- c3.c | 1 +
- c4.c | 1 +
+ c2.c | 1 +
+ c3.c | 1 +
+ c4.c | 1 +
3 files changed, 3 insertions(+)
create mode 100644 c2.c
create mode 100644 c3.c
@@ -71,7 +71,7 @@ test_expect_success 'merge output uses pretty names' '
cat >expected <<\EOF
Merge made by the 'recursive' strategy.
- c5.c | 1 +
+ c5.c | 1 +
1 file changed, 1 insertion(+)
create mode 100644 c5.c
EOF
@@ -85,8 +85,8 @@ cat >expected <<\EOF
Fast-forwarding to: c1
Trying simple merge with c2
Merge made by the 'octopus' strategy.
- c1.c | 1 +
- c2.c | 1 +
+ c1.c | 1 +
+ c2.c | 1 +
2 files changed, 2 insertions(+)
create mode 100644 c1.c
create mode 100644 c2.c
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index f5e16fc7db..bc38737b2a 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -55,6 +55,16 @@ test_expect_success 'setup' '
git rm file12 &&
git commit -m "branch1 changes" &&
+ git checkout -b stash1 master &&
+ echo stash1 change file11 >file11 &&
+ git add file11 &&
+ git commit -m "stash1 changes" &&
+
+ git checkout -b stash2 master &&
+ echo stash2 change file11 >file11 &&
+ git add file11 &&
+ git commit -m "stash2 changes" &&
+
git checkout master &&
git submodule update -N &&
echo master updated >file1 &&
@@ -193,7 +203,35 @@ test_expect_success 'mergetool skips resolved paths when rerere is active' '
git reset --hard
'
+test_expect_success 'conflicted stash sets up rerere' '
+ git config rerere.enabled true &&
+ git checkout stash1 &&
+ echo "Conflicting stash content" >file11 &&
+ git stash &&
+
+ git checkout --detach stash2 &&
+ test_must_fail git stash apply &&
+
+ test -n "$(git ls-files -u)" &&
+ conflicts="$(git rerere remaining)" &&
+ test "$conflicts" = "file11" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" != "No files need merging" &&
+
+ git commit -am "save the stash resolution" &&
+
+ git reset --hard stash2 &&
+ test_must_fail git stash apply &&
+
+ test -n "$(git ls-files -u)" &&
+ conflicts="$(git rerere remaining)" &&
+ test -z "$conflicts" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging"
+'
+
test_expect_success 'mergetool takes partial path' '
+ git reset --hard
git config rerere.enabled false &&
git checkout -b test12 branch1 &&
git submodule update -N &&
@@ -471,4 +509,17 @@ test_expect_success 'file with no base' '
git reset --hard master >/dev/null 2>&1
'
+test_expect_success 'custom commands override built-ins' '
+ git checkout -b test14 branch1 &&
+ git config mergetool.defaults.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
+ git config mergetool.defaults.trustExitCode true &&
+ test_must_fail git merge master &&
+ git mergetool --no-prompt --tool defaults -- both &&
+ echo master both added >expected &&
+ test_cmp both expected &&
+ git config --unset mergetool.defaults.cmd &&
+ git config --unset mergetool.defaults.trustExitCode &&
+ git reset --hard master >/dev/null 2>&1
+'
+
test_done
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 2763d795f0..eb1d3f85b5 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -76,6 +76,17 @@ test_expect_success PERL 'custom commands' '
test "$diff" = "branch"
'
+# Ensures that a custom difftool.<tool>.cmd overrides built-ins
+test_expect_success PERL 'custom commands override built-ins' '
+ restore_test_defaults &&
+ git config difftool.defaults.cmd "cat \$REMOTE" &&
+
+ diff=$(git difftool --tool defaults --no-prompt branch) &&
+ test "$diff" = "master" &&
+
+ git config --unset difftool.defaults.cmd
+'
+
# Ensures that git-difftool ignores bogus --tool values
test_expect_success PERL 'difftool ignores bad --tool values' '
diff=$(git difftool --no-prompt --tool=bad-tool branch)
@@ -105,6 +116,19 @@ test_expect_success PERL 'difftool honors --gui' '
restore_test_defaults
'
+test_expect_success PERL 'difftool --gui last setting wins' '
+ git config diff.guitool bogus-tool &&
+ git difftool --no-prompt --gui --no-gui &&
+
+ git config merge.tool bogus-tool &&
+ git config diff.tool bogus-tool &&
+ git config diff.guitool test-tool &&
+ diff=$(git difftool --no-prompt --no-gui --gui branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
test_expect_success PERL 'difftool --gui works without configured diff.guitool' '
git config diff.tool test-tool &&
@@ -317,4 +341,48 @@ test_expect_success PERL 'say no to the second file' '
echo "$diff" | stdin_doesnot_contain br2
'
+test_expect_success PERL 'difftool --tool-help' '
+ tool_help=$(git difftool --tool-help) &&
+ echo "$tool_help" | stdin_contains tool
+'
+
+test_expect_success PERL 'setup change in subdirectory' '
+ git checkout master &&
+ mkdir sub &&
+ echo master >sub/sub &&
+ git add sub/sub &&
+ git commit -m "added sub/sub" &&
+ echo test >>file &&
+ echo test >>sub/sub &&
+ git add . &&
+ git commit -m "modified both"
+'
+
+test_expect_success PERL 'difftool -d' '
+ diff=$(git difftool -d --extcmd ls branch) &&
+ echo "$diff" | stdin_contains sub &&
+ echo "$diff" | stdin_contains file
+'
+
+test_expect_success PERL 'difftool --dir-diff' '
+ diff=$(git difftool --dir-diff --extcmd ls branch) &&
+ echo "$diff" | stdin_contains sub &&
+ echo "$diff" | stdin_contains file
+'
+
+test_expect_success PERL 'difftool --dir-diff ignores --prompt' '
+ diff=$(git difftool --dir-diff --prompt --extcmd ls branch) &&
+ echo "$diff" | stdin_contains sub &&
+ echo "$diff" | stdin_contains file
+'
+
+test_expect_success PERL 'difftool --dir-diff from subdirectory' '
+ (
+ cd sub &&
+ diff=$(git difftool --dir-diff --extcmd ls branch) &&
+ echo "$diff" | stdin_contains sub &&
+ echo "$diff" | stdin_contains file
+ )
+'
+
test_done
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index d9ad633310..f698001c99 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -250,6 +250,84 @@ do
git -c grep.extendedRegexp=true grep "a+b*c" ab >actual &&
test_cmp expected actual
'
+
+ test_expect_success "grep $L with grep.patterntype=basic" '
+ echo "ab:a+bc" >expected &&
+ git -c grep.patterntype=basic grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep $L with grep.patterntype=extended" '
+ echo "ab:abc" >expected &&
+ git -c grep.patterntype=extended grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep $L with grep.patterntype=fixed" '
+ echo "ab:a+b*c" >expected &&
+ git -c grep.patterntype=fixed grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success LIBPCRE "grep $L with grep.patterntype=perl" '
+ echo "ab:a+b*c" >expected &&
+ git -c grep.patterntype=perl grep "a\x{2b}b\x{2a}c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep $L with grep.patternType=default and grep.extendedRegexp=true" '
+ echo "ab:abc" >expected &&
+ git \
+ -c grep.patternType=default \
+ -c grep.extendedRegexp=true \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=default" '
+ echo "ab:abc" >expected &&
+ git \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=default \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success 'grep $L with grep.patternType=extended and grep.extendedRegexp=false' '
+ echo "ab:abc" >expected &&
+ git \
+ -c grep.patternType=extended \
+ -c grep.extendedRegexp=false \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success 'grep $L with grep.patternType=basic and grep.extendedRegexp=true' '
+ echo "ab:a+bc" >expected &&
+ git \
+ -c grep.patternType=basic \
+ -c grep.extendedRegexp=true \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success 'grep $L with grep.extendedRegexp=false and grep.patternType=extended' '
+ echo "ab:abc" >expected &&
+ git \
+ -c grep.extendedRegexp=false \
+ -c grep.patternType=extended \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success 'grep $L with grep.extendedRegexp=true and grep.patternType=basic' '
+ echo "ab:a+bc" >expected &&
+ git \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=basic \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+ '
done
cat >expected <<EOF
@@ -351,6 +429,11 @@ test_expect_success 'grep -f, multiple patterns' '
test_cmp expected actual
'
+test_expect_success 'grep, multiple patterns' '
+ git grep "$(cat patterns)" >actual &&
+ test_cmp expected actual
+'
+
cat >expected <<EOF
file:foo mmap bar
file:foo_mmap bar
@@ -394,17 +477,6 @@ test_expect_success 'grep -q, silently report matches' '
test_cmp empty actual
'
-# Create 1024 file names that sort between "y" and "z" to make sure
-# the two files are handled by different calls to an external grep.
-# This depends on MAXARGS in builtin-grep.c being 1024 or less.
-c32="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v"
-test_expect_success 'grep -C1, hunk mark between files' '
- for a in $c32; do for b in $c32; do : >y-$a$b; done; done &&
- git add y-?? &&
- git grep -C1 "^[yz]" >actual &&
- test_cmp expected actual
-'
-
test_expect_success 'grep -C1 hunk mark between files' '
git grep -C1 "^[yz]" >actual &&
test_cmp expected actual
@@ -430,31 +502,41 @@ test_expect_success 'log grep setup' '
test_expect_success 'log grep (1)' '
git log --author=author --pretty=tformat:%s >actual &&
- ( echo third ; echo initial ) >expect &&
+ {
+ echo third && echo initial
+ } >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (2)' '
git log --author=" * " -F --pretty=tformat:%s >actual &&
- ( echo second ) >expect &&
+ {
+ echo second
+ } >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (3)' '
git log --author="^A U" --pretty=tformat:%s >actual &&
- ( echo third ; echo initial ) >expect &&
+ {
+ echo third && echo initial
+ } >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (4)' '
git log --author="frotz\.com>$" --pretty=tformat:%s >actual &&
- ( echo second ) >expect &&
+ {
+ echo second
+ } >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (5)' '
git log --author=Thor -F --pretty=tformat:%s >actual &&
- ( echo third ; echo initial ) >expect &&
+ {
+ echo third && echo initial
+ } >expect &&
test_cmp expect actual
'
@@ -464,11 +546,49 @@ test_expect_success 'log grep (6)' '
test_cmp expect actual
'
-test_expect_success 'log --grep --author implicitly uses all-match' '
- # grep matches initial and second but not third
- # author matches only initial and third
- git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
- echo initial >expect &&
+test_expect_success 'log grep (7)' '
+ git log -g --grep-reflog="commit: third" --pretty=tformat:%s >actual &&
+ echo third >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log grep (8)' '
+ git log -g --grep-reflog="commit: third" --grep-reflog="commit: second" --pretty=tformat:%s >actual &&
+ {
+ echo third && echo second
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log grep (9)' '
+ git log -g --grep-reflog="commit: third" --author="Thor" --pretty=tformat:%s >actual &&
+ echo third >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log grep (9)' '
+ git log -g --grep-reflog="commit: third" --author="non-existant" --pretty=tformat:%s >actual &&
+ : >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep-reflog can only be used under -g' '
+ test_must_fail git log --grep-reflog="commit: third"
+'
+
+test_expect_success 'log with multiple --grep uses union' '
+ git log --grep=i --grep=r --format=%s >actual &&
+ {
+ echo fourth && echo third && echo initial
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --all-match with multiple --grep uses intersection' '
+ git log --all-match --grep=i --grep=r --format=%s >actual &&
+ {
+ echo third
+ } >expect &&
test_cmp expect actual
'
@@ -480,7 +600,47 @@ test_expect_success 'log with multiple --author uses union' '
test_cmp expect actual
'
-test_expect_success 'log with --grep and multiple --author uses all-match' '
+test_expect_success 'log --all-match with multiple --author still uses union' '
+ git log --all-match --author="Thor" --author="Aster" --format=%s >actual &&
+ {
+ echo third && echo second && echo initial
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep --author uses intersection' '
+ # grep matches only third and fourth
+ # author matches only initial and third
+ git log --author="A U Thor" --grep=r --format=%s >actual &&
+ {
+ echo third
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep --grep --author takes union of greps and intersects with author' '
+ # grep matches initial and second but not third
+ # author matches only initial and third
+ git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
+ {
+ echo initial
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log ---all-match -grep --author --author still takes union of authors and intersects with grep' '
+ # grep matches only initial and third
+ # author matches all but second
+ git log --all-match --author="Thor" --author="Night" --grep=i --format=%s >actual &&
+ {
+ echo third && echo initial
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep --author --author takes union of authors and intersects with grep' '
+ # grep matches only initial and third
+ # author matches all but second
git log --author="Thor" --author="Night" --grep=i --format=%s >actual &&
{
echo third && echo initial
@@ -488,9 +648,25 @@ test_expect_success 'log with --grep and multiple --author uses all-match' '
test_cmp expect actual
'
-test_expect_success 'log with --grep and multiple --author uses all-match' '
- git log --author="Thor" --author="Night" --grep=q --format=%s >actual &&
- >expect &&
+test_expect_success 'log --all-match --grep --grep --author takes intersection' '
+ # grep matches only third
+ # author matches only initial and third
+ git log --all-match --author="A U Thor" --grep=i --grep=r --format=%s >actual &&
+ {
+ echo third
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --author does not search in timestamp' '
+ : >expect &&
+ git log --author="$GIT_AUTHOR_DATE" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --committer does not search in timestamp' '
+ : >expect &&
+ git log --committer="$GIT_COMMITTER_DATE" >actual &&
test_cmp expect actual
'
@@ -767,44 +943,147 @@ test_expect_success 'grep -G invalidpattern properly dies ' '
test_must_fail git grep -G "a["
'
+test_expect_success 'grep invalidpattern properly dies with grep.patternType=basic' '
+ test_must_fail git -c grep.patterntype=basic grep "a["
+'
+
test_expect_success 'grep -E invalidpattern properly dies ' '
test_must_fail git grep -E "a["
'
+test_expect_success 'grep invalidpattern properly dies with grep.patternType=extended' '
+ test_must_fail git -c grep.patterntype=extended grep "a["
+'
+
test_expect_success LIBPCRE 'grep -P invalidpattern properly dies ' '
test_must_fail git grep -P "a["
'
+test_expect_success LIBPCRE 'grep invalidpattern properly dies with grep.patternType=perl' '
+ test_must_fail git -c grep.patterntype=perl grep "a["
+'
+
test_expect_success 'grep -G -E -F pattern' '
echo "ab:a+b*c" >expected &&
git grep -G -E -F "a+b*c" ab >actual &&
test_cmp expected actual
'
+test_expect_success 'grep pattern with grep.patternType=basic, =extended, =fixed' '
+ echo "ab:a+b*c" >expected &&
+ git \
+ -c grep.patterntype=basic \
+ -c grep.patterntype=extended \
+ -c grep.patterntype=fixed \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'grep -E -F -G pattern' '
echo "ab:a+bc" >expected &&
git grep -E -F -G "a+b*c" ab >actual &&
test_cmp expected actual
'
+test_expect_success 'grep pattern with grep.patternType=extended, =fixed, =basic' '
+ echo "ab:a+bc" >expected &&
+ git \
+ -c grep.patterntype=extended \
+ -c grep.patterntype=fixed \
+ -c grep.patterntype=basic \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'grep -F -G -E pattern' '
echo "ab:abc" >expected &&
git grep -F -G -E "a+b*c" ab >actual &&
test_cmp expected actual
'
+test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =extended' '
+ echo "ab:abc" >expected &&
+ git \
+ -c grep.patterntype=fixed \
+ -c grep.patterntype=basic \
+ -c grep.patterntype=extended \
+ grep "a+b*c" ab >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'grep -G -F -P -E pattern' '
>empty &&
test_must_fail git grep -G -F -P -E "a\x{2b}b\x{2a}c" ab >actual &&
test_cmp empty actual
'
+test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =perl, =extended' '
+ >empty &&
+ test_must_fail git \
+ -c grep.patterntype=fixed \
+ -c grep.patterntype=basic \
+ -c grep.patterntype=perl \
+ -c grep.patterntype=extended \
+ grep "a\x{2b}b\x{2a}c" ab >actual &&
+ test_cmp empty actual
+'
+
test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '
echo "ab:a+b*c" >expected &&
git grep -G -F -E -P "a\x{2b}b\x{2a}c" ab >actual &&
test_cmp expected actual
'
+test_expect_success LIBPCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' '
+ echo "ab:a+b*c" >expected &&
+ git \
+ -c grep.patterntype=fixed \
+ -c grep.patterntype=basic \
+ -c grep.patterntype=extended \
+ -c grep.patterntype=perl \
+ grep "a\x{2b}b\x{2a}c" ab >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success LIBPCRE 'grep -P pattern with grep.patternType=fixed' '
+ echo "ab:a+b*c" >expected &&
+ git \
+ -c grep.patterntype=fixed \
+ grep -P "a\x{2b}b\x{2a}c" ab >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'grep -F pattern with grep.patternType=basic' '
+ echo "ab:a+b*c" >expected &&
+ git \
+ -c grep.patterntype=basic \
+ grep -F "*c" ab >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'grep -G pattern with grep.patternType=fixed' '
+ {
+ echo "ab:a+b*c"
+ echo "ab:a+bc"
+ } >expected &&
+ git \
+ -c grep.patterntype=fixed \
+ grep -G "a+b" ab >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'grep -E pattern with grep.patternType=fixed' '
+ {
+ echo "ab:a+b*c"
+ echo "ab:a+bc"
+ echo "ab:abc"
+ } >expected &&
+ git \
+ -c grep.patterntype=fixed \
+ grep -E "a+" ab >actual &&
+ test_cmp expected actual
+'
+
test_config() {
git config "$1" "$2" &&
test_when_finished "git config --unset $1"
diff --git a/t/t8004-blame-with-conflicts.sh b/t/t8004-blame-with-conflicts.sh
index ba19ac127e..9c353ab222 100755
--- a/t/t8004-blame-with-conflicts.sh
+++ b/t/t8004-blame-with-conflicts.sh
@@ -66,7 +66,7 @@ test_expect_success \
git blame file2
'
-test_expect_success 'blame runs on conflicted file in stages 1,3' '
+test_expect_success 'blame does not crash with conflicted file in stages 1,3' '
git blame file1
'
diff --git a/t/t8006-blame-textconv.sh b/t/t8006-blame-textconv.sh
index c3c22f7764..bf6caa4dc3 100755
--- a/t/t8006-blame-textconv.sh
+++ b/t/t8006-blame-textconv.sh
@@ -10,7 +10,7 @@ find_blame() {
cat >helper <<'EOF'
#!/bin/sh
grep -q '^bin: ' "$1" || { echo "E: $1 is not \"binary\" file" 1>&2; exit 1; }
-perl -p -e 's/^bin: /converted: /' "$1"
+"$PERL_PATH" -p -e 's/^bin: /converted: /' "$1"
EOF
chmod +x helper
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 8c12c65c72..97d6f4c7de 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -191,17 +191,44 @@ test_expect_success $PREREQ 'Show all headers' '
test_expect_success $PREREQ 'Prompting works' '
clean_fake_sendmail &&
- (echo "Example <from@example.com>"
- echo "to@example.com"
+ (echo "to@example.com"
echo ""
) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
--smtp-server="$(pwd)/fake.sendmail" \
$patches \
2>errors &&
- grep "^From: Example <from@example.com>\$" msgtxt1 &&
+ grep "^From: A U Thor <author@example.com>\$" msgtxt1 &&
grep "^To: to@example.com\$" msgtxt1
'
+test_expect_success $PREREQ,AUTOIDENT 'implicit ident is allowed' '
+ clean_fake_sendmail &&
+ (sane_unset GIT_AUTHOR_NAME &&
+ sane_unset GIT_AUTHOR_EMAIL &&
+ sane_unset GIT_COMMITTER_NAME &&
+ sane_unset GIT_COMMITTER_EMAIL &&
+ GIT_SEND_EMAIL_NOTTY=1 git send-email \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --to=to@example.com \
+ $patches </dev/null 2>errors
+ )
+'
+
+test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email' '
+ clean_fake_sendmail &&
+ (sane_unset GIT_AUTHOR_NAME &&
+ sane_unset GIT_AUTHOR_EMAIL &&
+ sane_unset GIT_COMMITTER_NAME &&
+ sane_unset GIT_COMMITTER_EMAIL &&
+ GIT_SEND_EMAIL_NOTTY=1 && export GIT_SEND_EMAIL_NOTTY &&
+ test_must_fail git send-email \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --to=to@example.com \
+ $patches </dev/null 2>errors &&
+ test_i18ngrep "tell me who you are" errors
+ )
+'
+
test_expect_success $PREREQ 'tocmd works' '
clean_fake_sendmail &&
cp $patches tocmd.patch &&
@@ -841,6 +868,88 @@ test_expect_success $PREREQ '--compose adds MIME for utf8 subject' '
grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
'
+test_expect_success $PREREQ 'utf8 author is correctly passed on' '
+ clean_fake_sendmail &&
+ test_commit weird_author &&
+ test_when_finished "git reset --hard HEAD^" &&
+ git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" &&
+ git format-patch --stdout -1 >funny_name.patch &&
+ git send-email --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ funny_name.patch &&
+ grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1
+'
+
+test_expect_success $PREREQ 'sendemail.composeencoding works' '
+ clean_fake_sendmail &&
+ git config sendemail.composeencoding iso-8859-1 &&
+ (echo "#!$SHELL_PATH" &&
+ echo "echo utf8 body: àéìöú >>\"\$1\""
+ ) >fake-editor-utf8 &&
+ chmod +x fake-editor-utf8 &&
+ GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
+ git send-email \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^utf8 body" msgtxt1 &&
+ grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
+'
+
+test_expect_success $PREREQ '--compose-encoding works' '
+ clean_fake_sendmail &&
+ (echo "#!$SHELL_PATH" &&
+ echo "echo utf8 body: àéìöú >>\"\$1\""
+ ) >fake-editor-utf8 &&
+ chmod +x fake-editor-utf8 &&
+ GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
+ git send-email \
+ --compose-encoding iso-8859-1 \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^utf8 body" msgtxt1 &&
+ grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
+'
+
+test_expect_success $PREREQ '--compose-encoding overrides sendemail.composeencoding' '
+ clean_fake_sendmail &&
+ git config sendemail.composeencoding iso-8859-1 &&
+ (echo "#!$SHELL_PATH" &&
+ echo "echo utf8 body: àéìöú >>\"\$1\""
+ ) >fake-editor-utf8 &&
+ chmod +x fake-editor-utf8 &&
+ GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
+ git send-email \
+ --compose-encoding iso-8859-2 \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^utf8 body" msgtxt1 &&
+ grep "^Content-Type: text/plain; charset=iso-8859-2" msgtxt1
+'
+
+test_expect_success $PREREQ '--compose-encoding adds correct MIME for subject' '
+ clean_fake_sendmail &&
+ GIT_EDITOR="\"$(pwd)/fake-editor\"" \
+ git send-email \
+ --compose-encoding iso-8859-2 \
+ --compose --subject utf8-sübjëct \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^fake edit" msgtxt1 &&
+ grep "^Subject: =?iso-8859-2?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
+'
+
test_expect_success $PREREQ 'detects ambiguous reference/file conflict' '
echo master > master &&
git add master &&
@@ -1061,6 +1170,23 @@ EOF
'
test_expect_success $PREREQ 'setup expect' '
+cat >expected <<EOF
+Subject: subject goes here
+EOF
+'
+
+test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' '
+ clean_fake_sendmail &&
+ echo bogus |
+ git send-email --from=author@example.com --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --8bit-encoding=UTF-8 \
+ email-using-8bit >stdout &&
+ grep "Subject" msgtxt1 >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success $PREREQ 'setup expect' '
cat >content-type-decl <<EOF
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
new file mode 100755
index 0000000000..89983527b6
--- /dev/null
+++ b/t/t9002-column.sh
@@ -0,0 +1,180 @@
+#!/bin/sh
+
+test_description='git column'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ cat >lista <<\EOF
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+EOF
+'
+
+test_expect_success 'never' '
+ git column --indent=Z --mode=never <lista >actual &&
+ test_cmp lista actual
+'
+
+test_expect_success 'always' '
+ cat >expected <<\EOF &&
+Zone
+Ztwo
+Zthree
+Zfour
+Zfive
+Zsix
+Zseven
+Zeight
+Znine
+Zten
+Zeleven
+EOF
+ git column --indent=Z --mode=plain <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '80 columns' '
+ cat >expected <<\EOF &&
+one two three four five six seven eight nine ten eleven
+EOF
+ COLUMNS=80 git column --mode=column <lista >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+EOF
+
+test_expect_success COLUMNS_CAN_BE_1 'COLUMNS = 1' '
+ COLUMNS=1 git column --mode=column <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'width = 1' '
+ git column --mode=column --width=1 <lista >actual &&
+ test_cmp expected actual
+'
+
+COLUMNS=20
+export COLUMNS
+
+test_expect_success '20 columns' '
+ cat >expected <<\EOF &&
+one seven
+two eight
+three nine
+four ten
+five eleven
+six
+EOF
+ git column --mode=column <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, nodense' '
+ cat >expected <<\EOF &&
+one seven
+two eight
+three nine
+four ten
+five eleven
+six
+EOF
+ git column --mode=column,nodense < lista > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, dense' '
+ cat >expected <<\EOF &&
+one five nine
+two six ten
+three seven eleven
+four eight
+EOF
+ git column --mode=column,dense < lista > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, padding 2' '
+ cat >expected <<\EOF &&
+one seven
+two eight
+three nine
+four ten
+five eleven
+six
+EOF
+ git column --mode=column --padding 2 <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, indented' '
+ cat >expected <<\EOF &&
+ one seven
+ two eight
+ three nine
+ four ten
+ five eleven
+ six
+EOF
+ git column --mode=column --indent=" " <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, row first' '
+ cat >expected <<\EOF &&
+one two
+three four
+five six
+seven eight
+nine ten
+eleven
+EOF
+ git column --mode=row <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, row first, nodense' '
+ cat >expected <<\EOF &&
+one two
+three four
+five six
+seven eight
+nine ten
+eleven
+EOF
+ git column --mode=row,nodense <lista >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '20 columns, row first, dense' '
+ cat >expected <<\EOF &&
+one two three
+four five six
+seven eight nine
+ten eleven
+EOF
+ git column --mode=row,dense <lista >actual &&
+ test_cmp expected actual
+'
+
+test_done
diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh
new file mode 100755
index 0000000000..2d2f016f6f
--- /dev/null
+++ b/t/t9020-remote-svn.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+test_description='tests remote-svn'
+
+. ./test-lib.sh
+
+MARKSPATH=.git/info/fast-import/remote-svn
+
+if ! test_have_prereq PYTHON
+then
+ skip_all='skipping remote-svn tests, python not available'
+ test_done
+fi
+
+# Override svnrdump with our simulator
+PATH="$HOME:$PATH"
+export PATH PYTHON_PATH GIT_BUILD_DIR
+
+write_script "$HOME/svnrdump" <<\EOF
+exec "$PYTHON_PATH" "$GIT_BUILD_DIR/contrib/svn-fe/svnrdump_sim.py" "$@"
+EOF
+
+init_git () {
+ rm -fr .git &&
+ git init &&
+ #git remote add svnsim testsvn::sim:///$TEST_DIRECTORY/t9020/example.svnrdump
+ # let's reuse an exisiting dump file!?
+ git remote add svnsim testsvn::sim://$TEST_DIRECTORY/t9154/svn.dump
+ git remote add svnfile testsvn::file://$TEST_DIRECTORY/t9154/svn.dump
+}
+
+if test -e "$GIT_BUILD_DIR/git-remote-testsvn"
+then
+ test_set_prereq REMOTE_SVN
+fi
+
+test_debug '
+ git --version
+ type git
+ type svnrdump
+'
+
+test_expect_success REMOTE_SVN 'simple fetch' '
+ init_git &&
+ git fetch svnsim &&
+ test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master &&
+ cp .git/refs/remotes/svnsim/master master.good
+'
+
+test_debug '
+ cat .git/refs/svn/svnsim/master
+ cat .git/refs/remotes/svnsim/master
+'
+
+test_expect_success REMOTE_SVN 'repeated fetch, nothing shall change' '
+ git fetch svnsim &&
+ test_cmp master.good .git/refs/remotes/svnsim/master
+'
+
+test_expect_success REMOTE_SVN 'fetch from a file:// url gives the same result' '
+ git fetch svnfile
+'
+
+test_expect_failure REMOTE_SVN 'the sha1 differ because the git-svn-id line in the commit msg contains the url' '
+ test_cmp .git/refs/remotes/svnfile/master .git/refs/remotes/svnsim/master
+'
+
+test_expect_success REMOTE_SVN 'mark-file regeneration' '
+ # filter out any other marks, that can not be regenerated. Only up to 3 digit revisions are allowed here
+ grep ":[0-9]\{1,3\} " $MARKSPATH/svnsim.marks > $MARKSPATH/svnsim.marks.old &&
+ rm $MARKSPATH/svnsim.marks &&
+ git fetch svnsim &&
+ test_cmp $MARKSPATH/svnsim.marks.old $MARKSPATH/svnsim.marks
+'
+
+test_expect_success REMOTE_SVN 'incremental imports must lead to the same head' '
+ export SVNRMAX=3 &&
+ init_git &&
+ git fetch svnsim &&
+ test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master &&
+ unset SVNRMAX &&
+ git fetch svnsim &&
+ test_cmp master.good .git/refs/remotes/svnsim/master
+'
+
+test_debug 'git branch -a'
+
+test_done
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 289fc313fb..ee73013eed 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -27,15 +27,17 @@ test_expect_success 'setup old-looking metadata' '
head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
+svnrepo_escaped=`echo $svnrepo | sed 's/ /%20/'`
+
test_expect_success 'initialize old-style (v0) git svn layout' '
mkdir -p "$GIT_DIR"/git-svn/info "$GIT_DIR"/svn/info &&
echo "$svnrepo" > "$GIT_DIR"/git-svn/info/url &&
echo "$svnrepo" > "$GIT_DIR"/svn/info/url &&
git svn migrate &&
- ! test -d "$GIT_DIR"/git svn &&
+ ! test -d "$GIT_DIR"/git-svn &&
git rev-parse --verify refs/${remotes_git_svn}^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test "$(git config --get svn-remote.svn.url)" = "$svnrepo" &&
+ test "$(git config --get svn-remote.svn.url)" = "$svnrepo_escaped" &&
test `git config --get svn-remote.svn.fetch` = \
":refs/${remotes_git_svn}"
'
diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh
index 63fc982c8c..15f93b4c28 100755
--- a/t/t9118-git-svn-funky-branch-names.sh
+++ b/t/t9118-git-svn-funky-branch-names.sh
@@ -28,10 +28,15 @@ test_expect_success 'setup svnrepo' '
svn_cmd cp -m "trailing .lock" "$svnrepo/pr ject/trunk" \
"$svnrepo/pr ject/branches/trailing_dotlock.lock" &&
svn_cmd cp -m "reflog" "$svnrepo/pr ject/trunk" \
- "$svnrepo/pr ject/branches/not-a%40{0}reflog" &&
+ "$svnrepo/pr ject/branches/not-a@{0}reflog@" &&
start_httpd
'
+# SVN 1.7 will truncate "not-a%40{0]" to just "not-a".
+# Look at what SVN wound up naming the branch and use that.
+# Be sure to escape the @ if it shows up.
+non_reflog=`svn_cmd ls "$svnrepo/pr ject/branches" | grep not-a | sed 's/\///' | sed 's/@/%40/'`
+
test_expect_success 'test clone with funky branch names' '
git svn clone -s "$svnrepo/pr ject" project &&
(
@@ -42,7 +47,7 @@ test_expect_success 'test clone with funky branch names' '
git rev-parse "refs/remotes/%2Eleading_dot" &&
git rev-parse "refs/remotes/trailing_dot%2E" &&
git rev-parse "refs/remotes/trailing_dotlock%2Elock" &&
- git rev-parse "refs/remotes/not-a%40{0}reflog"
+ git rev-parse "refs/remotes/$non_reflog"
)
'
diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh
index 8cfdfe790f..9a40f1e199 100755
--- a/t/t9129-git-svn-i18n-commitencoding.sh
+++ b/t/t9129-git-svn-i18n-commitencoding.sh
@@ -29,7 +29,7 @@ fi
compare_svn_head_with () {
# extract just the log message and strip out committer info.
# don't use --limit here since svn 1.1.x doesn't have it,
- LC_ALL="$a_utf8_locale" svn log `git svn info --url` | perl -w -e '
+ LC_ALL="$a_utf8_locale" svn log `git svn info --url` | "$PERL_PATH" -w -e '
use bytes;
$/ = ("-"x72) . "\n";
my @x = <STDIN>;
diff --git a/t/t9137-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh
index d60da63f7a..c17aa3186f 100755
--- a/t/t9137-git-svn-dcommit-clobber-series.sh
+++ b/t/t9137-git-svn-dcommit-clobber-series.sh
@@ -20,8 +20,8 @@ test_expect_success '(supposedly) non-conflicting change from SVN' '
test x"`sed -n -e 61p < file`" = x61 &&
svn_cmd co "$svnrepo" tmp &&
(cd tmp &&
- perl -i.bak -p -e "s/^58$/5588/" file &&
- perl -i.bak -p -e "s/^61$/6611/" file &&
+ "$PERL_PATH" -i.bak -p -e "s/^58$/5588/" file &&
+ "$PERL_PATH" -i.bak -p -e "s/^61$/6611/" file &&
poke file &&
test x"`sed -n -e 58p < file`" = x5588 &&
test x"`sed -n -e 61p < file`" = x6611 &&
@@ -40,8 +40,8 @@ test_expect_success 'some unrelated changes to git' "
test_expect_success 'change file but in unrelated area' "
test x\"\`sed -n -e 4p < file\`\" = x4 &&
test x\"\`sed -n -e 7p < file\`\" = x7 &&
- perl -i.bak -p -e 's/^4\$/4444/' file &&
- perl -i.bak -p -e 's/^7\$/7777/' file &&
+ "$PERL_PATH" -i.bak -p -e 's/^4\$/4444/' file &&
+ "$PERL_PATH" -i.bak -p -e 's/^7\$/7777/' file &&
test x\"\`sed -n -e 4p < file\`\" = x4444 &&
test x\"\`sed -n -e 7p < file\`\" = x7777 &&
git commit -m '4 => 4444, 7 => 7777' file &&
diff --git a/t/t9154-git-svn-fancy-glob.sh b/t/t9154-git-svn-fancy-glob.sh
index a6a56a6cb9..b780e0efe3 100755
--- a/t/t9154-git-svn-fancy-glob.sh
+++ b/t/t9154-git-svn-fancy-glob.sh
@@ -21,6 +21,15 @@ test_expect_success 'add red branch' "
test_must_fail git rev-parse refs/remotes/blue
"
+test_expect_success 'add gre branch' "
+ GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
+ git config svn-remote.svn.branches 'branches/{red,gre}:refs/remotes/*' &&
+ git svn fetch &&
+ git rev-parse refs/remotes/red &&
+ test_must_fail git rev-parse refs/remotes/green &&
+ test_must_fail git rev-parse refs/remotes/blue
+ "
+
test_expect_success 'add green branch' "
GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
git config svn-remote.svn.branches 'branches/{red,green}:refs/remotes/*' &&
diff --git a/t/t9163-git-svn-reset-clears-caches.sh b/t/t9163-git-svn-reset-clears-caches.sh
new file mode 100755
index 0000000000..cd4c662ba2
--- /dev/null
+++ b/t/t9163-git-svn-reset-clears-caches.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Peter Baumann
+#
+
+test_description='git svn reset clears memoized caches'
+. ./lib-git-svn.sh
+
+svn_ver="$(svn --version --quiet)"
+case $svn_ver in
+0.* | 1.[0-4].*)
+ skip_all="skipping git-svn test - SVN too old ($svn_ver)"
+ test_done
+ ;;
+esac
+
+# ... a - b - m <- trunk
+# \ /
+# ... c <- branch1
+#
+# SVN Commits not interesting for this test are abbreviated with "..."
+#
+test_expect_success 'initialize source svn repo' '
+ svn_cmd mkdir -m "create trunk" "$svnrepo"/trunk &&
+ svn_cmd mkdir -m "create branches" "$svnrepo/branches" &&
+ svn_cmd co "$svnrepo"/trunk "$SVN_TREE" &&
+ (
+ cd "$SVN_TREE" &&
+ touch foo &&
+ svn_cmd add foo &&
+ svn_cmd commit -m "a" &&
+ svn_cmd cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 &&
+ svn_cmd switch "$svnrepo"/branches/branch1 &&
+ touch bar &&
+ svn_cmd add bar &&
+ svn_cmd commit -m b &&
+ svn_cmd switch "$svnrepo"/trunk &&
+ touch baz &&
+ svn_cmd add baz &&
+ svn_cmd commit -m c &&
+ svn_cmd up &&
+ svn_cmd merge "$svnrepo"/branches/branch1 &&
+ svn_cmd commit -m "m"
+ ) &&
+ rm -rf "$SVN_TREE"
+'
+
+test_expect_success 'fetch to merge-base (a)' '
+ git svn init -s "$svnrepo" &&
+ git svn fetch --revision BASE:3
+'
+
+# git svn rebase looses the merge commit
+#
+# ... a - b - m <- trunk
+# \
+# ... c
+#
+test_expect_success 'rebase looses SVN merge (m)' '
+ git svn rebase &&
+ git svn fetch &&
+ test 1 = $(git cat-file -p master|grep parent|wc -l)
+'
+
+# git svn fetch creates correct history with merge commit
+#
+# ... a - b - m <- trunk
+# \ /
+# ... c <- branch1
+#
+test_expect_success 'reset and fetch gets the SVN merge (m) correctly' '
+ git svn reset -r 3 &&
+ git reset --hard trunk &&
+ git svn fetch &&
+ test 2 = $(git cat-file -p trunk|grep parent|wc -l)
+'
+
+test_done
diff --git a/t/t9164-git-svn-dcommit-concurrent.sh b/t/t9164-git-svn-dcommit-concurrent.sh
new file mode 100755
index 0000000000..d8464d4218
--- /dev/null
+++ b/t/t9164-git-svn-dcommit-concurrent.sh
@@ -0,0 +1,216 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Robert Luberda
+#
+
+test_description='concurrent git svn dcommit'
+. ./lib-git-svn.sh
+
+
+
+test_expect_success 'setup svn repository' '
+ svn_cmd checkout "$svnrepo" work.svn &&
+ (
+ cd work.svn &&
+ echo >file && echo > auto_updated_file
+ svn_cmd add file auto_updated_file &&
+ svn_cmd commit -m "initial commit"
+ ) &&
+ svn_cmd checkout "$svnrepo" work-auto-commits.svn
+'
+N=0
+next_N()
+{
+ N=$(( $N + 1 ))
+}
+
+# Setup SVN repository hooks to emulate SVN failures or concurrent commits
+# The function adds
+# either pre-commit hook, which causes SVN commit given in second argument
+# to fail
+# or post-commit hook, which creates a new commit (a new line added to
+# auto_updated_file) after given SVN commit
+# The first argument contains a type of the hook
+# The second argument contains a number (not SVN revision) of commit
+# the hook should be applied for (each time the hook is run, the given
+# number is decreased by one until it gets 0, in which case the hook
+# will execute its real action)
+setup_hook()
+{
+ hook_type="$1" # "pre-commit" or "post-commit"
+ skip_revs="$2"
+ [ "$hook_type" = "pre-commit" ] ||
+ [ "$hook_type" = "post-commit" ] ||
+ { echo "ERROR: invalid argument ($hook_type)" \
+ "passed to setup_hook" >&2 ; return 1; }
+ echo "cnt=$skip_revs" > "$hook_type-counter"
+ rm -f "$rawsvnrepo/hooks/"*-commit # drop previous hooks
+ hook="$rawsvnrepo/hooks/$hook_type"
+ cat > "$hook" <<- 'EOF1'
+ #!/bin/sh
+ set -e
+ cd "$1/.." # "$1" is repository location
+ exec >> svn-hook.log 2>&1
+ hook="$(basename "$0")"
+ echo "*** Executing $hook $@"
+ set -x
+ . ./$hook-counter
+ cnt="$(($cnt - 1))"
+ echo "cnt=$cnt" > ./$hook-counter
+ [ "$cnt" = "0" ] || exit 0
+EOF1
+ if [ "$hook_type" = "pre-commit" ]; then
+ echo "echo 'commit disallowed' >&2; exit 1" >>"$hook"
+ else
+ echo "PATH=\"$PATH\"; export PATH" >>"$hook"
+ echo "svnconf=\"$svnconf\"" >>"$hook"
+ cat >>"$hook" <<- 'EOF2'
+ cd work-auto-commits.svn
+ svn up --config-dir "$svnconf"
+ echo "$$" >> auto_updated_file
+ svn commit --config-dir "$svnconf" \
+ -m "auto-committing concurrent change"
+ exit 0
+EOF2
+ fi
+ chmod 755 "$hook"
+}
+
+check_contents()
+{
+ gitdir="$1"
+ (cd ../work.svn && svn_cmd up) &&
+ test_cmp file ../work.svn/file &&
+ test_cmp auto_updated_file ../work.svn/auto_updated_file
+}
+
+test_expect_success 'check if post-commit hook creates a concurrent commit' '
+ setup_hook post-commit 1 &&
+ (
+ cd work.svn &&
+ cp auto_updated_file au_file_saved &&
+ echo 1 >> file &&
+ svn_cmd commit -m "changing file" &&
+ svn_cmd up &&
+ test_must_fail test_cmp auto_updated_file au_file_saved
+ )
+'
+
+test_expect_success 'check if pre-commit hook fails' '
+ setup_hook pre-commit 2 &&
+ (
+ cd work.svn &&
+ echo 2 >> file &&
+ svn_cmd commit -m "changing file once again" &&
+ echo 3 >> file &&
+ test_must_fail svn_cmd commit -m "this commit should fail" &&
+ svn_cmd revert file
+ )
+'
+
+test_expect_success 'dcommit error handling' '
+ setup_hook pre-commit 2 &&
+ next_N && git svn clone "$svnrepo" work$N.git &&
+ (
+ cd work$N.git &&
+ echo 1 >> file && git commit -am "commit change $N.1" &&
+ echo 2 >> file && git commit -am "commit change $N.2" &&
+ echo 3 >> file && git commit -am "commit change $N.3" &&
+ # should fail to dcommit 2nd and 3rd change
+ # but still should leave the repository in reasonable state
+ test_must_fail git svn dcommit &&
+ git update-index --refresh &&
+ git show HEAD~2 | grep -q git-svn-id &&
+ ! git show HEAD~1 | grep -q git-svn-id &&
+ ! git show HEAD | grep -q git-svn-id
+ )
+'
+
+test_expect_success 'dcommit concurrent change in non-changed file' '
+ setup_hook post-commit 2 &&
+ next_N && git svn clone "$svnrepo" work$N.git &&
+ (
+ cd work$N.git &&
+ echo 1 >> file && git commit -am "commit change $N.1" &&
+ echo 2 >> file && git commit -am "commit change $N.2" &&
+ echo 3 >> file && git commit -am "commit change $N.3" &&
+ # should rebase and leave the repository in reasonable state
+ git svn dcommit &&
+ git update-index --refresh &&
+ check_contents &&
+ git show HEAD~3 | grep -q git-svn-id &&
+ git show HEAD~2 | grep -q git-svn-id &&
+ git show HEAD~1 | grep -q auto-committing &&
+ git show HEAD | grep -q git-svn-id
+ )
+'
+
+# An utility function used in the following test
+delete_first_line()
+{
+ file="$1" &&
+ sed 1d < "$file" > "${file}.tmp" &&
+ rm "$file" &&
+ mv "${file}.tmp" "$file"
+}
+
+test_expect_success 'dcommit concurrent non-conflicting change' '
+ setup_hook post-commit 2 &&
+ next_N && git svn clone "$svnrepo" work$N.git &&
+ (
+ cd work$N.git &&
+ cat file >> auto_updated_file &&
+ git commit -am "commit change $N.1" &&
+ delete_first_line auto_updated_file &&
+ git commit -am "commit change $N.2" &&
+ delete_first_line auto_updated_file &&
+ git commit -am "commit change $N.3" &&
+ # should rebase and leave the repository in reasonable state
+ git svn dcommit &&
+ git update-index --refresh &&
+ check_contents &&
+ git show HEAD~3 | grep -q git-svn-id &&
+ git show HEAD~2 | grep -q git-svn-id &&
+ git show HEAD~1 | grep -q auto-committing &&
+ git show HEAD | grep -q git-svn-id
+ )
+'
+
+test_expect_success 'dcommit --no-rebase concurrent non-conflicting change' '
+ setup_hook post-commit 2 &&
+ next_N && git svn clone "$svnrepo" work$N.git &&
+ (
+ cd work$N.git &&
+ cat file >> auto_updated_file &&
+ git commit -am "commit change $N.1" &&
+ delete_first_line auto_updated_file &&
+ git commit -am "commit change $N.2" &&
+ delete_first_line auto_updated_file &&
+ git commit -am "commit change $N.3" &&
+ # should fail as rebase is needed
+ test_must_fail git svn dcommit --no-rebase &&
+ # but should leave HEAD unchanged
+ git update-index --refresh &&
+ ! git show HEAD~2 | grep -q git-svn-id &&
+ ! git show HEAD~1 | grep -q git-svn-id &&
+ ! git show HEAD | grep -q git-svn-id
+ )
+'
+
+test_expect_success 'dcommit fails on concurrent conflicting change' '
+ setup_hook post-commit 1 &&
+ next_N && git svn clone "$svnrepo" work$N.git &&
+ (
+ cd work$N.git &&
+ echo a >> file &&
+ git commit -am "commit change $N.1" &&
+ echo b >> auto_updated_file &&
+ git commit -am "commit change $N.2" &&
+ echo c >> auto_updated_file &&
+ git commit -am "commit change $N.3" &&
+ test_must_fail git svn dcommit && # rebase should fail
+ test_must_fail git update-index --refresh
+ )
+'
+
+test_done
diff --git a/t/t9165-git-svn-fetch-merge-branch-of-branch.sh b/t/t9165-git-svn-fetch-merge-branch-of-branch.sh
new file mode 100755
index 0000000000..13ae7e33f9
--- /dev/null
+++ b/t/t9165-git-svn-fetch-merge-branch-of-branch.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Steven Walter
+#
+
+test_description='git svn merge detection'
+. ./lib-git-svn.sh
+
+svn_ver="$(svn --version --quiet)"
+case $svn_ver in
+0.* | 1.[0-4].*)
+ skip_all="skipping git-svn test - SVN too old ($svn_ver)"
+ test_done
+ ;;
+esac
+
+test_expect_success 'initialize source svn repo' '
+ svn_cmd mkdir -m x "$svnrepo"/trunk &&
+ svn_cmd mkdir -m x "$svnrepo"/branches &&
+ svn_cmd co "$svnrepo"/trunk "$SVN_TREE" &&
+ (
+ cd "$SVN_TREE" &&
+ touch foo &&
+ svn_cmd add foo &&
+ svn_cmd commit -m "initial commit" &&
+ svn_cmd cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 &&
+ svn_cmd switch "$svnrepo"/branches/branch1 &&
+ touch bar &&
+ svn_cmd add bar &&
+ svn_cmd commit -m branch1 &&
+ svn_cmd cp -m branch "$svnrepo"/branches/branch1 "$svnrepo"/branches/branch2 &&
+ svn_cmd switch "$svnrepo"/branches/branch2 &&
+ touch baz &&
+ svn_cmd add baz &&
+ svn_cmd commit -m branch2 &&
+ svn_cmd switch "$svnrepo"/trunk &&
+ touch bar2 &&
+ svn_cmd add bar2 &&
+ svn_cmd commit -m trunk &&
+ svn_cmd switch "$svnrepo"/branches/branch2 &&
+ svn_cmd merge "$svnrepo"/trunk &&
+ svn_cmd commit -m "merge trunk"
+ svn_cmd switch "$svnrepo"/trunk &&
+ svn_cmd merge --reintegrate "$svnrepo"/branches/branch2 &&
+ svn_cmd commit -m "merge branch2"
+ ) &&
+ rm -rf "$SVN_TREE"
+'
+
+test_expect_success 'clone svn repo' '
+ git svn init -s "$svnrepo" &&
+ git svn fetch
+'
+
+test_expect_success 'verify merge commit' 'x=$(git rev-parse HEAD^2) &&
+ y=$(git rev-parse branch2) &&
+ test "x$x" = "x$y"
+'
+
+test_done
diff --git a/t/t9166-git-svn-fetch-merge-branch-of-branch2.sh b/t/t9166-git-svn-fetch-merge-branch-of-branch2.sh
new file mode 100755
index 0000000000..af0ec0e2e3
--- /dev/null
+++ b/t/t9166-git-svn-fetch-merge-branch-of-branch2.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Steven Walter
+#
+
+test_description='git svn merge detection'
+. ./lib-git-svn.sh
+
+svn_ver="$(svn --version --quiet)"
+case $svn_ver in
+0.* | 1.[0-4].*)
+ skip_all="skipping git-svn test - SVN too old ($svn_ver)"
+ test_done
+ ;;
+esac
+
+test_expect_success 'initialize source svn repo' '
+ svn_cmd mkdir -m x "$svnrepo"/trunk &&
+ svn_cmd mkdir -m x "$svnrepo"/branches &&
+ svn_cmd co "$svnrepo"/trunk "$SVN_TREE" &&
+ (
+ cd "$SVN_TREE" &&
+ touch foo &&
+ svn_cmd add foo &&
+ svn_cmd commit -m "initial commit" &&
+ svn_cmd cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 &&
+ svn_cmd switch "$svnrepo"/branches/branch1 &&
+ touch bar &&
+ svn_cmd add bar &&
+ svn_cmd commit -m branch1 &&
+ svn_cmd cp -m branch "$svnrepo"/branches/branch1 "$svnrepo"/branches/branch2 &&
+ svn_cmd switch "$svnrepo"/branches/branch2 &&
+ touch baz &&
+ svn_cmd add baz &&
+ svn_cmd commit -m branch2 &&
+ svn_cmd switch "$svnrepo"/trunk &&
+ svn_cmd merge --reintegrate "$svnrepo"/branches/branch2 &&
+ svn_cmd commit -m "merge branch2"
+ ) &&
+ rm -rf "$SVN_TREE"
+'
+
+test_expect_success 'clone svn repo' '
+ git svn init -s "$svnrepo" &&
+ git svn fetch
+'
+
+test_expect_success 'verify merge commit' 'x=$(git rev-parse HEAD^2) &&
+ y=$(git rev-parse branch2) &&
+ test "x$x" = "x$y"
+'
+
+test_done
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index b59be9a894..3fb3368903 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -19,14 +19,15 @@ then
test_done
fi
-CVSROOT=$PWD/cvsroot
+CVSROOT=$PWD/tmpcvsroot
CVSWORK=$PWD/cvswork
GIT_DIR=$PWD/.git
export CVSROOT CVSWORK GIT_DIR
rm -rf "$CVSROOT" "$CVSWORK"
-mkdir "$CVSROOT" &&
+
cvs init &&
+test -d "$CVSROOT" &&
cvs -Q co -d "$CVSWORK" . &&
echo >empty &&
git add empty &&
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 7da0e8da7b..2fcf269469 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -12,7 +12,7 @@ test_description='test git fast-import utility'
# This could be written as "head -c $1", but IRIX "head" does not
# support the -c option.
head_c () {
- perl -e '
+ "$PERL_PATH" -e '
my $len = $ARGV[1];
while ($len > 0) {
my $s;
@@ -1657,7 +1657,7 @@ M 160000 :6 sub
INPUT_END
test_expect_success \
- 'P: supermodule & submodule mix' \
+ 'P: superproject & submodule mix' \
'git fast-import <input &&
git checkout subuse1 &&
rm -rf sub && mkdir sub && (cd sub &&
@@ -2117,7 +2117,7 @@ test_expect_success \
grep :1 git.marks'
test_expect_success \
- 'R: export-marks options can be overriden by commandline options' \
+ 'R: export-marks options can be overridden by commandline options' \
'cat input | git fast-import --export-marks=other.marks &&
grep :1 other.marks'
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index b00196bd23..9320b4f94c 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -303,7 +303,7 @@ test_expect_success 'dropping tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -320,7 +320,7 @@ test_expect_success 'rewriting tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -351,7 +351,7 @@ test_expect_failure 'no exact-ref revisions included' '
(
cd limit-by-paths &&
git fast-export master~2..master~1 > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -424,13 +424,13 @@ test_expect_success 'fast-export quotes pathnames' '
--cacheinfo 100644 $blob "path with \\backslash" \
--cacheinfo 100644 $blob "path with space" &&
git commit -m addition &&
- git ls-files -z -s | perl -0pe "s{\\t}{$&subdir/}" >index &&
+ git ls-files -z -s | "$PERL_PATH" -0pe "s{\\t}{$&subdir/}" >index &&
git read-tree --empty &&
git update-index -z --index-info <index &&
git commit -m rename &&
git read-tree --empty &&
git commit -m deletion &&
- git fast-export HEAD >export.out &&
+ git fast-export -M HEAD >export.out &&
git rev-list HEAD >expect &&
git init result &&
cd result &&
@@ -440,4 +440,63 @@ test_expect_success 'fast-export quotes pathnames' '
)
'
+test_expect_success 'test bidirectionality' '
+ >marks-cur &&
+ >marks-new &&
+ git init marks-test &&
+ git fast-export --export-marks=marks-cur --import-marks=marks-cur --branches | \
+ git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks=marks-new &&
+ (cd marks-test &&
+ git reset --hard &&
+ echo Wohlauf > file &&
+ git commit -a -m "back in time") &&
+ git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks=marks-new --branches | \
+ git fast-import --export-marks=marks-cur --import-marks=marks-cur
+'
+
+cat > expected << EOF
+blob
+mark :13
+data 5
+bump
+
+commit refs/heads/master
+mark :14
+author A U Thor <author@example.com> 1112912773 -0700
+committer C O Mitter <committer@example.com> 1112912773 -0700
+data 5
+bump
+from :12
+M 100644 :13 file
+
+EOF
+
+test_expect_success 'avoid uninteresting refs' '
+ > tmp-marks &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > /dev/null &&
+ git tag v1.0 &&
+ git branch uninteresting &&
+ echo bump > file &&
+ git commit -a -m bump &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks ^uninteresting ^v1.0 master > actual &&
+ test_cmp expected actual
+'
+
+cat > expected << EOF
+reset refs/heads/master
+from :14
+
+EOF
+
+test_expect_success 'refs are updated even if no commits need to be exported' '
+ > tmp-marks &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > /dev/null &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > actual &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 806623e885..9502f2438a 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -400,7 +400,7 @@ cat >expected.C <<EOF
Line 0
=======
LINE 0
->>>>>>> merge.3
+>>>>>>> merge.1.3
EOF
for i in 1 2 3 4 5 6 7 8
@@ -505,6 +505,76 @@ test_expect_success 'cvs co -c (shows module database)' '
'
#------------
+# CVS LOG
+#------------
+
+# Known issues with git-cvsserver current log output:
+# - Hard coded "lines: +2 -3" placeholder, instead of real numbers.
+# - CVS normally does not internally add a blank first line
+# nor a last line with nothing but a space to log messages.
+# - The latest cvs 1.12.x server sends +0000 timezone (with some hidden "MT"
+# tagging in the protocol), and if cvs 1.12.x client sees the MT tags,
+# it converts to local time zone. git-cvsserver doesn't do the +0000
+# or the MT tags...
+# - The latest 1.12.x releases add a "commitid:" field on to the end of the
+# "date:" line (after "lines:"). Maybe we could stick git's commit id
+# in it? Or does CVS expect a certain number of bits (too few for
+# a full sha1)?
+#
+# Given the above, expect the following test to break if git-cvsserver's
+# log output is improved. The test is just to ensure it doesn't
+# accidentally get worse.
+
+sed -e 's/^x//' -e 's/SP$/ /' > "$WORKDIR/expect" <<EOF
+x
+xRCS file: $WORKDIR/gitcvs.git/master/merge,v
+xWorking file: merge
+xhead: 1.4
+xbranch:
+xlocks: strict
+xaccess list:
+xsymbolic names:
+xkeyword substitution: kv
+xtotal revisions: 4; selected revisions: 4
+xdescription:
+x----------------------------
+xrevision 1.4
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (no-op)
+xSP
+x----------------------------
+xrevision 1.3
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (conflict)
+xSP
+x----------------------------
+xrevision 1.2
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (merge)
+xSP
+x----------------------------
+xrevision 1.1
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (pre-merge)
+xSP
+x=============================================================================
+EOF
+expectStat="$?"
+
+cd "$WORKDIR"
+test_expect_success 'cvs log' '
+ cd cvswork &&
+ test x"$expectStat" = x"0" &&
+ GIT_CONFIG="$git_config" cvs log merge >../out &&
+ sed -e "s%2[0-9][0-9][0-9]/[01][0-9]/[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]%__DATE__%" ../out > ../actual &&
+ test_cmp ../expect ../actual
+'
+
+#------------
# CVS ANNOTATE
#------------
diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh
index ff6d6fb473..1c5bc84fa7 100755
--- a/t/t9401-git-cvsserver-crlf.sh
+++ b/t/t9401-git-cvsserver-crlf.sh
@@ -38,6 +38,25 @@ not_present() {
fi
}
+check_status_options() {
+ (cd "$1" &&
+ GIT_CONFIG="$git_config" cvs -Q status "$2" > "${WORKDIR}/status.out" 2>&1
+ )
+ if [ x"$?" != x"0" ] ; then
+ echo "Error from cvs status: $1 $2" >> "${WORKDIR}/marked.log"
+ return 1;
+ fi
+ got="$(sed -n -e 's/^[ ]*Sticky Options:[ ]*//p' "${WORKDIR}/status.out")"
+ expect="$3"
+ if [ x"$expect" = x"" ] ; then
+ expect="(none)"
+ fi
+ test x"$got" = x"$expect"
+ stat=$?
+ echo "cvs status: $1 $2 $stat '$3' '$got'" >> "${WORKDIR}/marked.log"
+ return $stat
+}
+
cvs >/dev/null 2>&1
if test $? -ne 1
then
@@ -233,6 +252,22 @@ test_expect_success 'cvs co another copy (guess)' '
marked_as cvswork2/subdir newfile.c ""
'
+test_expect_success 'cvs status - sticky options' '
+ check_status_options cvswork2 textfile.c "" &&
+ check_status_options cvswork2 binfile.bin -kb &&
+ check_status_options cvswork2 .gitattributes "" &&
+ check_status_options cvswork2 mixedUp.c -kb &&
+ check_status_options cvswork2 multiline.c -kb &&
+ check_status_options cvswork2 multilineTxt.c "" &&
+ check_status_options cvswork2/subdir withCr.bin -kb &&
+ check_status_options cvswork2 subdir/withCr.bin -kb &&
+ check_status_options cvswork2/subdir file.h "" &&
+ check_status_options cvswork2 subdir/file.h "" &&
+ check_status_options cvswork2/subdir unspecified.other "" &&
+ check_status_options cvswork2/subdir newfile.bin "" &&
+ check_status_options cvswork2/subdir newfile.c ""
+'
+
test_expect_success 'add text (guess)' '
(cd cvswork &&
echo "simpleText" > simpleText.c &&
diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh
index fa2f65f6be..ef86948d21 100755
--- a/t/t9501-gitweb-standalone-http-status.sh
+++ b/t/t9501-gitweb-standalone-http-status.sh
@@ -12,6 +12,13 @@ code and message.'
. ./gitweb-lib.sh
+#
+# Gitweb only provides the functionality tested by the 'modification times'
+# tests if it can access a date parser from one of these modules:
+#
+perl -MHTTP::Date -e 0 >/dev/null 2>&1 && test_set_prereq DATE_PARSER
+perl -MTime::ParseDate -e 0 >/dev/null 2>&1 && test_set_prereq DATE_PARSER
+
# ----------------------------------------------------------------------
# snapshot settings
@@ -115,14 +122,14 @@ test_debug 'cat gitweb.output'
# ----------------------------------------------------------------------
# modification times (Last-Modified and If-Modified-Since)
-test_expect_success 'modification: feed last-modified' '
+test_expect_success DATE_PARSER 'modification: feed last-modified' '
gitweb_run "p=.git;a=atom;h=master" &&
grep "Status: 200 OK" gitweb.headers &&
grep "Last-modified: Thu, 7 Apr 2005 22:14:13 +0000" gitweb.headers
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: feed if-modified-since (modified)' '
+test_expect_success DATE_PARSER 'modification: feed if-modified-since (modified)' '
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=atom;h=master" &&
@@ -130,7 +137,7 @@ test_expect_success 'modification: feed if-modified-since (modified)' '
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: feed if-modified-since (unmodified)' '
+test_expect_success DATE_PARSER 'modification: feed if-modified-since (unmodified)' '
export HTTP_IF_MODIFIED_SINCE="Thu, 7 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=atom;h=master" &&
@@ -138,14 +145,14 @@ test_expect_success 'modification: feed if-modified-since (unmodified)' '
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: snapshot last-modified' '
+test_expect_success DATE_PARSER 'modification: snapshot last-modified' '
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
grep "Status: 200 OK" gitweb.headers &&
grep "Last-modified: Thu, 7 Apr 2005 22:14:13 +0000" gitweb.headers
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: snapshot if-modified-since (modified)' '
+test_expect_success DATE_PARSER 'modification: snapshot if-modified-since (modified)' '
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
@@ -153,7 +160,7 @@ test_expect_success 'modification: snapshot if-modified-since (modified)' '
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: snapshot if-modified-since (unmodified)' '
+test_expect_success DATE_PARSER 'modification: snapshot if-modified-since (unmodified)' '
export HTTP_IF_MODIFIED_SINCE="Thu, 7 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
@@ -161,7 +168,7 @@ test_expect_success 'modification: snapshot if-modified-since (unmodified)' '
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: tree snapshot' '
+test_expect_success DATE_PARSER 'modification: tree snapshot' '
ID=`git rev-parse --verify HEAD^{tree}` &&
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh
index 731e64c3ad..86dfee2e4f 100755
--- a/t/t9502-gitweb-standalone-parse-output.sh
+++ b/t/t9502-gitweb-standalone-parse-output.sh
@@ -40,7 +40,7 @@ check_snapshot () {
echo "basename=$basename"
grep "filename=.*$basename.tar" gitweb.headers >/dev/null 2>&1 &&
"$TAR" tf gitweb.body >file_list &&
- ! grep -v "^$prefix/" file_list
+ ! grep -v -e "^$prefix$" -e "^$prefix/" -e "^pax_global_header$" file_list
}
test_expect_success setup '
@@ -185,5 +185,20 @@ test_expect_success 'forks: project_index lists all projects (incl. forks)' '
test_cmp expected actual
'
+xss() {
+ echo >&2 "Checking $1..." &&
+ gitweb_run "$1" &&
+ if grep "$TAG" gitweb.body; then
+ echo >&2 "xss: $TAG should have been quoted in output"
+ return 1
+ fi
+ return 0
+}
+
+test_expect_success 'xss checks' '
+ TAG="<magic-xss-tag>" &&
+ xss "a=rss&p=$TAG" &&
+ xss "a=rss&p=foo.git&f=$TAG"
+'
test_done
diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh
new file mode 100755
index 0000000000..1fd51423ee
--- /dev/null
+++ b/t/t9604-cvsimport-timestamps.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='git cvsimport timestamps'
+. ./lib-cvs.sh
+
+setup_cvs_test_repository t9604
+
+test_expect_success 'check timestamps are UTC (TZ=CST6CDT)' '
+
+ TZ=CST6CDT git cvsimport -p"-x" -C module-1 module &&
+ git cvsimport -p"-x" -C module-1 module &&
+ (
+ cd module-1 &&
+ git log --format="%s %ai"
+ ) >actual-1 &&
+ cat >expect-1 <<-EOF &&
+ Rev 16 2006-10-29 07:00:01 +0000
+ Rev 15 2006-10-29 06:59:59 +0000
+ Rev 14 2006-04-02 08:00:01 +0000
+ Rev 13 2006-04-02 07:59:59 +0000
+ Rev 12 2005-12-01 00:00:00 +0000
+ Rev 11 2005-11-01 00:00:00 +0000
+ Rev 10 2005-10-01 00:00:00 +0000
+ Rev 9 2005-09-01 00:00:00 +0000
+ Rev 8 2005-08-01 00:00:00 +0000
+ Rev 7 2005-07-01 00:00:00 +0000
+ Rev 6 2005-06-01 00:00:00 +0000
+ Rev 5 2005-05-01 00:00:00 +0000
+ Rev 4 2005-04-01 00:00:00 +0000
+ Rev 3 2005-03-01 00:00:00 +0000
+ Rev 2 2005-02-01 00:00:00 +0000
+ Rev 1 2005-01-01 00:00:00 +0000
+ EOF
+ test_cmp actual-1 expect-1
+'
+
+test_expect_success 'check timestamps with author-specific timezones' '
+
+ cat >cvs-authors <<-EOF &&
+ user1=User One <user1@domain.org>
+ user2=User Two <user2@domain.org> CST6CDT
+ user3=User Three <user3@domain.org> EST5EDT
+ user4=User Four <user4@domain.org> MST7MDT
+ EOF
+ git cvsimport -p"-x" -A cvs-authors -C module-2 module &&
+ (
+ cd module-2 &&
+ git log --format="%s %ai %an"
+ ) >actual-2 &&
+ cat >expect-2 <<-EOF &&
+ Rev 16 2006-10-29 01:00:01 -0600 User Two
+ Rev 15 2006-10-29 01:59:59 -0500 User Two
+ Rev 14 2006-04-02 03:00:01 -0500 User Two
+ Rev 13 2006-04-02 01:59:59 -0600 User Two
+ Rev 12 2005-11-30 17:00:00 -0700 User Four
+ Rev 11 2005-10-31 19:00:00 -0500 User Three
+ Rev 10 2005-09-30 19:00:00 -0500 User Two
+ Rev 9 2005-09-01 00:00:00 +0000 User One
+ Rev 8 2005-07-31 18:00:00 -0600 User Four
+ Rev 7 2005-06-30 20:00:00 -0400 User Three
+ Rev 6 2005-05-31 19:00:00 -0500 User Two
+ Rev 5 2005-05-01 00:00:00 +0000 User One
+ Rev 4 2005-03-31 17:00:00 -0700 User Four
+ Rev 3 2005-02-28 19:00:00 -0500 User Three
+ Rev 2 2005-01-31 18:00:00 -0600 User Two
+ Rev 1 2005-01-01 00:00:00 +0000 User One
+ EOF
+ test_cmp actual-2 expect-2
+'
+
+test_done
diff --git a/t/t9604/cvsroot/.gitattributes b/t/t9604/cvsroot/.gitattributes
new file mode 100644
index 0000000000..562b12e16e
--- /dev/null
+++ b/t/t9604/cvsroot/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/t/t9604/cvsroot/CVSROOT/.gitignore b/t/t9604/cvsroot/CVSROOT/.gitignore
new file mode 100644
index 0000000000..3bb9b34173
--- /dev/null
+++ b/t/t9604/cvsroot/CVSROOT/.gitignore
@@ -0,0 +1,2 @@
+history
+val-tags
diff --git a/t/t9604/cvsroot/module/a,v b/t/t9604/cvsroot/module/a,v
new file mode 100644
index 0000000000..80658c3c8d
--- /dev/null
+++ b/t/t9604/cvsroot/module/a,v
@@ -0,0 +1,264 @@
+head 1.16;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.16
+date 2006.10.29.07.00.01; author user2; state Exp;
+branches;
+next 1.15;
+
+1.15
+date 2006.10.29.06.59.59; author user2; state Exp;
+branches;
+next 1.14;
+
+1.14
+date 2006.04.02.08.00.01; author user2; state Exp;
+branches;
+next 1.13;
+
+1.13
+date 2006.04.02.07.59.59; author user2; state Exp;
+branches;
+next 1.12;
+
+1.12
+date 2005.12.01.00.00.00; author user4; state Exp;
+branches;
+next 1.11;
+
+1.11
+date 2005.11.01.00.00.00; author user3; state Exp;
+branches;
+next 1.10;
+
+1.10
+date 2005.10.01.00.00.00; author user2; state Exp;
+branches;
+next 1.9;
+
+1.9
+date 2005.09.01.00.00.00; author user1; state Exp;
+branches;
+next 1.8;
+
+1.8
+date 2005.08.01.00.00.00; author user4; state Exp;
+branches;
+next 1.7;
+
+1.7
+date 2005.07.01.00.00.00; author user3; state Exp;
+branches;
+next 1.6;
+
+1.6
+date 2005.06.01.00.00.00; author user2; state Exp;
+branches;
+next 1.5;
+
+1.5
+date 2005.05.01.00.00.00; author user1; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 2005.04.01.00.00.00; author user4; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 2005.03.01.00.00.00; author user3; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 2005.02.01.00.00.00; author user2; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2005.01.01.00.00.00; author user1; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.16
+log
+@Rev 16
+@
+text
+@Rev 16
+@
+
+
+1.15
+log
+@Rev 15
+@
+text
+@d1 1
+a1 1
+Rev 15
+@
+
+
+1.14
+log
+@Rev 14
+@
+text
+@d1 1
+a1 1
+Rev 14
+@
+
+
+1.13
+log
+@Rev 13
+@
+text
+@d1 1
+a1 1
+Rev 13
+@
+
+
+1.12
+log
+@Rev 12
+@
+text
+@d1 1
+a1 1
+Rev 12
+@
+
+
+1.11
+log
+@Rev 11
+@
+text
+@d1 1
+a1 1
+Rev 11
+@
+
+
+1.10
+log
+@Rev 10
+@
+text
+@d1 1
+a1 1
+Rev 10
+@
+
+
+1.9
+log
+@Rev 9
+@
+text
+@d1 1
+a1 1
+Rev 9
+@
+
+
+1.8
+log
+@Rev 8
+@
+text
+@d1 1
+a1 1
+Rev 8
+@
+
+
+1.7
+log
+@Rev 7
+@
+text
+@d1 1
+a1 1
+Rev 7
+@
+
+
+1.6
+log
+@Rev 6
+@
+text
+@d1 1
+a1 1
+Rev 6
+@
+
+
+1.5
+log
+@Rev 5
+@
+text
+@d1 1
+a1 1
+Rev 5
+@
+
+
+1.4
+log
+@Rev 4
+@
+text
+@d1 1
+a1 1
+Rev 4
+@
+
+
+1.3
+log
+@Rev 3
+@
+text
+@d1 1
+a1 1
+Rev 3
+@
+
+
+1.2
+log
+@Rev 2
+@
+text
+@d1 1
+a1 1
+Rev 2
+@
+
+
+1.1
+log
+@Rev 1
+@
+text
+@d1 1
+a1 1
+Rev 1
+@
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index 3b9b48408a..0d4e366232 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -46,8 +46,7 @@ is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color");
# Save and restore STDERR; we will probably extract this into a
# "dies_ok" method and possibly move the STDERR handling to Git.pm.
open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; close STDERR;
-eval { $r->config("test.dupstring") };
-ok($@, "config: duplicate entry in scalar context fails");
+is($r->config("test.dupstring"), "value2", "config: multivar");
eval { $r->config_bool("test.boolother") };
ok($@, "config_bool: non-boolean values fail");
open STDERR, ">&", $tmpstderr or die "cannot restore STDERR";
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 13be144459..8c5979647f 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -45,7 +45,8 @@ test_expect_success 'git p4 sync uninitialized repo' '
test_when_finished cleanup_git &&
(
cd "$git" &&
- test_must_fail git p4 sync
+ test_must_fail git p4 sync 2>errs &&
+ test_i18ngrep "Perhaps you never did" errs
)
'
@@ -126,44 +127,35 @@ test_expect_success 'clone two dirs, @all, conflicting files' '
'
test_expect_success 'exit when p4 fails to produce marshaled output' '
- badp4dir="$TRASH_DIRECTORY/badp4dir" &&
- mkdir "$badp4dir" &&
- test_when_finished "rm \"$badp4dir/p4\" && rmdir \"$badp4dir\"" &&
- cat >"$badp4dir"/p4 <<-EOF &&
+ mkdir badp4dir &&
+ test_when_finished "rm badp4dir/p4 && rmdir badp4dir" &&
+ cat >badp4dir/p4 <<-EOF &&
#!$SHELL_PATH
exit 1
EOF
- chmod 755 "$badp4dir"/p4 &&
- PATH="$badp4dir:$PATH" git p4 clone --dest="$git" //depot >errs 2>&1 ; retval=$? &&
- test $retval -eq 1 &&
- test_must_fail grep -q Traceback errs
-'
-
-test_expect_success 'add p4 files with wildcards in the names' '
+ chmod 755 badp4dir/p4 &&
(
- cd "$cli" &&
- echo file-wild-hash >file-wild#hash &&
- echo file-wild-star >file-wild\*star &&
- echo file-wild-at >file-wild@at &&
- echo file-wild-percent >file-wild%percent &&
- p4 add -f file-wild* &&
- p4 submit -d "file wildcards"
- )
+ PATH="$TRASH_DIRECTORY/badp4dir:$PATH" &&
+ export PATH &&
+ test_expect_code 1 git p4 clone --dest="$git" //depot >errs 2>&1
+ ) &&
+ cat errs &&
+ ! test_i18ngrep Traceback errs
'
-test_expect_success 'wildcard files git p4 clone' '
- git p4 clone --dest="$git" //depot &&
+# Hide a file from p4d, make sure we catch its complaint. This won't fail in
+# p4 changes, files, or describe; just in p4 print. If P4CLIENT is unset, the
+# message will include "Librarian checkout".
+test_expect_success 'exit gracefully for p4 server errors' '
+ test_when_finished "mv \"$db\"/depot/file1,v,hidden \"$db\"/depot/file1,v" &&
+ mv "$db"/depot/file1,v "$db"/depot/file1,v,hidden &&
test_when_finished cleanup_git &&
- (
- cd "$git" &&
- test -f file-wild#hash &&
- test -f file-wild\*star &&
- test -f file-wild@at &&
- test -f file-wild%percent
- )
+ test_expect_code 1 git p4 clone --dest="$git" //depot@1 >out 2>err &&
+ test_i18ngrep "Error from p4 print" err
'
-test_expect_success 'clone bare' '
+test_expect_success 'clone --bare should make a bare repository' '
+ rm -rf "$git" &&
git p4 clone --dest="$git" --bare //depot &&
test_when_finished cleanup_git &&
(
@@ -174,138 +166,6 @@ test_expect_success 'clone bare' '
)
'
-p4_add_user() {
- name=$1 fullname=$2 &&
- p4 user -f -i <<-EOF &&
- User: $name
- Email: $name@localhost
- FullName: $fullname
- EOF
- p4 passwd -P secret $name
-}
-
-p4_grant_admin() {
- name=$1 &&
- {
- p4 protect -o &&
- echo " admin user $name * //depot/..."
- } | p4 protect -i
-}
-
-p4_check_commit_author() {
- file=$1 user=$2 &&
- p4 changes -m 1 //depot/$file | grep -q $user
-}
-
-make_change_by_user() {
- file=$1 name=$2 email=$3 &&
- echo "username: a change by $name" >>"$file" &&
- git add "$file" &&
- git commit --author "$name <$email>" -m "a change by $name"
-}
-
-# Test username support, submitting as user 'alice'
-test_expect_success 'preserve users' '
- p4_add_user alice Alice &&
- p4_add_user bob Bob &&
- p4_grant_admin alice &&
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- echo "username: a change by alice" >>file1 &&
- echo "username: a change by bob" >>file2 &&
- git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 &&
- git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 &&
- git config git-p4.skipSubmitEditCheck true &&
- P4EDITOR=touch P4USER=alice P4PASSWD=secret git p4 commit --preserve-user &&
- p4_check_commit_author file1 alice &&
- p4_check_commit_author file2 bob
- )
-'
-
-# Test username support, submitting as bob, who lacks admin rights. Should
-# not submit change to p4 (git diff should show deltas).
-test_expect_success 'refuse to preserve users without perms' '
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- 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 &&
- export P4EDITOR P4USER P4PASSWD &&
- test_must_fail git p4 commit --preserve-user &&
- ! git diff --exit-code HEAD..p4/master
- )
-'
-
-# What happens with unknown author? Without allowMissingP4Users it should fail.
-test_expect_success 'preserve user where author is unknown to p4' '
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEditCheck true &&
- echo "username-bob: a change by bob" >>file1 &&
- 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 &&
- export P4EDITOR P4USER P4PASSWD &&
- test_must_fail git p4 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 &&
- git p4 commit &&
- git diff --exit-code HEAD..p4/master &&
- p4_check_commit_author file1 alice
- )
-'
-
-# If we're *not* using --preserve-user, git p4 should warn if we're submitting
-# changes that are not all ours.
-# Test: user in p4 and user unknown to p4.
-# Test: warning disabled and user is the same.
-test_expect_success 'not preserving user with mixed authorship' '
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEditCheck true &&
- p4_add_user derek Derek &&
-
- make_change_by_user usernamefile3 Derek derek@localhost &&
- P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
- export P4EDITOR P4USER P4PASSWD &&
- git p4 commit |\
- grep "git author derek@localhost does not match" &&
-
- make_change_by_user usernamefile3 Charlie charlie@localhost &&
- git p4 commit |\
- grep "git author charlie@localhost does not match" &&
-
- make_change_by_user usernamefile3 alice alice@localhost &&
- git p4 commit |\
- test_must_fail grep "git author.*does not match" &&
-
- git config git-p4.skipUserNameCheck true &&
- make_change_by_user usernamefile3 Charlie charlie@localhost &&
- git p4 commit |\
- test_must_fail grep "git author.*does not match" &&
-
- p4_check_commit_author usernamefile3 alice
- )
-'
-
-marshal_dump() {
- what=$1
- "$PYTHON_PATH" -c 'import marshal, sys; d = marshal.load(sys.stdin); print d["'$what'"]'
-}
-
# Sleep a bit so that the top-most p4 change did not happen "now". Then
# import the repo and make sure that the initial import has the same time
# as the top-most change.
@@ -323,143 +183,15 @@ test_expect_success 'initial import time from top change time' '
)
'
-# Rename a file and confirm that rename is not detected in P4.
-# Rename the new file again with detectRenames option enabled and confirm that
-# this is detected in P4.
-# Rename the new file again adding an extra line, configure a big threshold in
-# detectRenames and confirm that rename is not detected in P4.
-# Repeat, this time with a smaller threshold and confirm that the rename is
-# detected in P4.
-test_expect_success 'detect renames' '
- git p4 clone --dest="$git" //depot@all &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEditCheck true &&
-
- git mv file1 file4 &&
- git commit -a -m "Rename file1 to file4" &&
- git diff-tree -r -M HEAD &&
- git p4 submit &&
- p4 filelog //depot/file4 &&
- p4 filelog //depot/file4 | test_must_fail grep -q "branch from" &&
-
- git mv file4 file5 &&
- git commit -a -m "Rename file4 to file5" &&
- git diff-tree -r -M HEAD &&
- git config git-p4.detectRenames true &&
- git p4 submit &&
- p4 filelog //depot/file5 &&
- p4 filelog //depot/file5 | grep -q "branch from //depot/file4" &&
-
- git mv file5 file6 &&
- echo update >>file6 &&
- git add file6 &&
- git commit -a -m "Rename file5 to file6 with changes" &&
- git diff-tree -r -M HEAD &&
- level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
- test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
- git config git-p4.detectRenames $(($level + 2)) &&
- git p4 submit &&
- p4 filelog //depot/file6 &&
- p4 filelog //depot/file6 | test_must_fail grep -q "branch from" &&
-
- git mv file6 file7 &&
- echo update >>file7 &&
- git add file7 &&
- git commit -a -m "Rename file6 to file7 with changes" &&
- git diff-tree -r -M HEAD &&
- level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
- test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
- git config git-p4.detectRenames $(($level - 2)) &&
- git p4 submit &&
- p4 filelog //depot/file7 &&
- p4 filelog //depot/file7 | grep -q "branch from //depot/file6"
- )
-'
-
-# Copy a file and confirm that copy is not detected in P4.
-# Copy a file with detectCopies option enabled and confirm that copy is not
-# detected in P4.
-# Modify and copy a file with detectCopies option enabled and confirm that copy
-# is detected in P4.
-# Copy a file with detectCopies and detectCopiesHarder options enabled and
-# confirm that copy is detected in P4.
-# Modify and copy a file, configure a bigger threshold in detectCopies and
-# confirm that copy is not detected in P4.
-# Modify and copy a file, configure a smaller threshold in detectCopies and
-# confirm that copy is detected in P4.
-test_expect_success 'detect copies' '
- git p4 clone --dest="$git" //depot@all &&
+test_expect_success 'unresolvable host in P4PORT should display error' '
test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
(
cd "$git" &&
- git config git-p4.skipSubmitEditCheck true &&
-
- cp file2 file8 &&
- git add file8 &&
- git commit -a -m "Copy file2 to file8" &&
- git diff-tree -r -C HEAD &&
- git p4 submit &&
- p4 filelog //depot/file8 &&
- p4 filelog //depot/file8 | test_must_fail grep -q "branch from" &&
-
- cp file2 file9 &&
- git add file9 &&
- git commit -a -m "Copy file2 to file9" &&
- git diff-tree -r -C HEAD &&
- git config git-p4.detectCopies true &&
- git p4 submit &&
- p4 filelog //depot/file9 &&
- p4 filelog //depot/file9 | test_must_fail grep -q "branch from" &&
-
- echo "file2" >>file2 &&
- cp file2 file10 &&
- git add file2 file10 &&
- git commit -a -m "Modify and copy file2 to file10" &&
- git diff-tree -r -C HEAD &&
- git p4 submit &&
- p4 filelog //depot/file10 &&
- p4 filelog //depot/file10 | grep -q "branch from //depot/file" &&
-
- cp file2 file11 &&
- git add file11 &&
- git commit -a -m "Copy file2 to file11" &&
- git diff-tree -r -C --find-copies-harder HEAD &&
- src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
- test "$src" = file10 &&
- git config git-p4.detectCopiesHarder true &&
- git p4 submit &&
- p4 filelog //depot/file11 &&
- p4 filelog //depot/file11 | grep -q "branch from //depot/file" &&
-
- cp file2 file12 &&
- echo "some text" >>file12 &&
- git add file12 &&
- git commit -a -m "Copy file2 to file12 with changes" &&
- git diff-tree -r -C --find-copies-harder HEAD &&
- level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
- test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
- src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
- test "$src" = file10 &&
- git config git-p4.detectCopies $(($level + 2)) &&
- git p4 submit &&
- p4 filelog //depot/file12 &&
- p4 filelog //depot/file12 | test_must_fail grep -q "branch from" &&
-
- cp file2 file13 &&
- echo "different text" >>file13 &&
- git add file13 &&
- git commit -a -m "Copy file2 to file13 with changes" &&
- git diff-tree -r -C --find-copies-harder HEAD &&
- level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
- test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
- src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
- test "$src" = file10 &&
- git config git-p4.detectCopies $(($level - 2)) &&
- git p4 submit &&
- p4 filelog //depot/file13 &&
- p4 filelog //depot/file13 | grep -q "branch from //depot/file"
+ P4PORT=nosuchhost:65537 &&
+ export P4PORT &&
+ test_expect_code 1 git p4 sync >out 2>err &&
+ grep "connect to nosuchhost" err
)
'
diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh
index 2859256de3..9730821c30 100755
--- a/t/t9801-git-p4-branch.sh
+++ b/t/t9801-git-p4-branch.sh
@@ -218,7 +218,7 @@ test_expect_success 'git p4 clone simple branches' '
cd branch1 &&
p4 edit file2 &&
echo file2_ >>file2 &&
- p4 submit -d "update file2 in branch3" &&
+ p4 submit -d "update file2 in branch1" &&
cd "$git" &&
git reset --hard p4/depot/branch1 &&
git p4 rebase &&
@@ -249,8 +249,6 @@ test_expect_success 'git p4 clone simple branches' '
# `- file2
# `- file3
test_expect_success 'git p4 add complex branches' '
- test_when_finished cleanup_git &&
- test_create_repo "$git" &&
(
cd "$cli" &&
changelist=$(p4 changes -m1 //depot/... | cut -d" " -f2) &&
@@ -306,6 +304,189 @@ test_expect_success 'git p4 clone complex branches' '
)
'
+# Move branch3/file3 to branch4/file3 in a single changelist
+test_expect_success 'git p4 submit to two branches in a single changelist' '
+ (
+ cd "$cli" &&
+ p4 integrate //depot/branch3/file3 //depot/branch4/file3 &&
+ p4 delete //depot/branch3/file3 &&
+ p4 submit -d "Move branch3/file3 to branch4/file3"
+ )
+'
+
+# Confirm that changes to two branches done in a single changelist
+# are correctly imported by git p4
+test_expect_success 'git p4 sync changes to two branches in the same changelist' '
+ test_when_finished cleanup_git &&
+ test_create_repo "$git" &&
+ (
+ cd "$git" &&
+ git config git-p4.branchList branch1:branch2 &&
+ git config --add git-p4.branchList branch1:branch3 &&
+ git config --add git-p4.branchList branch1:branch4 &&
+ git config --add git-p4.branchList branch1:branch5 &&
+ git p4 clone --dest=. --detect-branches //depot@all &&
+ git log --all --graph --decorate --stat &&
+ git reset --hard p4/depot/branch1 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ grep update file2 &&
+ git reset --hard p4/depot/branch2 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_missing file3 &&
+ ! grep update file2 &&
+ git reset --hard p4/depot/branch3 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_missing file3 &&
+ grep update file2 &&
+ git reset --hard p4/depot/branch4 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ ! grep update file2 &&
+ git reset --hard p4/depot/branch5 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ ! grep update file2 &&
+ test_path_is_missing .git/git-p4-tmp
+ )
+'
+
+# Create a branch by integrating a single file
+test_expect_success 'git p4 file subset branch' '
+ (
+ cd "$cli" &&
+ p4 integrate //depot/branch1/file1 //depot/branch6/file1 &&
+ p4 submit -d "Integrate file1 alone from branch1 to branch6"
+ )
+'
+
+# Check if git p4 creates a new branch containing a single file,
+# instead of keeping the old files from the original branch
+test_expect_failure 'git p4 clone file subset branch' '
+ test_when_finished cleanup_git &&
+ test_create_repo "$git" &&
+ (
+ cd "$git" &&
+ git config git-p4.branchList branch1:branch2 &&
+ git config --add git-p4.branchList branch1:branch3 &&
+ git config --add git-p4.branchList branch1:branch4 &&
+ git config --add git-p4.branchList branch1:branch5 &&
+ git config --add git-p4.branchList branch1:branch6 &&
+ git p4 clone --dest=. --detect-branches //depot@all &&
+ git log --all --graph --decorate --stat &&
+ git reset --hard p4/depot/branch1 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ grep update file2 &&
+ git reset --hard p4/depot/branch2 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_missing file3 &&
+ ! grep update file2 &&
+ git reset --hard p4/depot/branch3 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_missing file3 &&
+ grep update file2 &&
+ git reset --hard p4/depot/branch4 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ ! grep update file2 &&
+ git reset --hard p4/depot/branch5 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ ! grep update file2 &&
+ git reset --hard p4/depot/branch6 &&
+ test_path_is_file file1 &&
+ test_path_is_missing file2 &&
+ test_path_is_missing file3
+ )
+'
+
+# From a report in http://stackoverflow.com/questions/11893688
+# where --use-client-spec caused branch prefixes not to be removed;
+# every file in git appeared into a subdirectory of the branch name.
+test_expect_success 'use-client-spec detect-branches setup' '
+ rm -rf "$cli" &&
+ mkdir "$cli" &&
+ (
+ cd "$cli" &&
+ client_view "//depot/usecs/... //client/..." &&
+ mkdir b1 &&
+ echo b1/b1-file1 >b1/b1-file1 &&
+ p4 add b1/b1-file1 &&
+ p4 submit -d "b1/b1-file1" &&
+
+ p4 integrate //depot/usecs/b1/... //depot/usecs/b2/... &&
+ p4 submit -d "b1 -> b2" &&
+ p4 branch -i <<-EOF &&
+ Branch: b2
+ View: //depot/usecs/b1/... //depot/usecs/b2/...
+ EOF
+
+ echo b2/b2-file2 >b2/b2-file2 &&
+ p4 add b2/b2-file2 &&
+ p4 submit -d "b2/b2-file2"
+ )
+'
+
+test_expect_success 'use-client-spec detect-branches files in top-level' '
+ test_when_finished cleanup_git &&
+ test_create_repo "$git" &&
+ (
+ cd "$git" &&
+ git p4 sync --detect-branches --use-client-spec //depot/usecs@all &&
+ git checkout -b master p4/usecs/b1 &&
+ test_path_is_file b1-file1 &&
+ test_path_is_missing b2-file2 &&
+ test_path_is_missing b1 &&
+ test_path_is_missing b2 &&
+
+ git checkout -b b2 p4/usecs/b2 &&
+ test_path_is_file b1-file1 &&
+ test_path_is_file b2-file2 &&
+ test_path_is_missing b1 &&
+ test_path_is_missing b2
+ )
+'
+
+test_expect_success 'use-client-spec detect-branches skips branches setup' '
+ (
+ cd "$cli" &&
+
+ p4 integrate //depot/usecs/b1/... //depot/usecs/b3/... &&
+ p4 submit -d "b1 -> b3" &&
+ p4 branch -i <<-EOF &&
+ Branch: b3
+ View: //depot/usecs/b1/... //depot/usecs/b3/...
+ EOF
+
+ echo b3/b3-file3 >b3/b3-file3 &&
+ p4 add b3/b3-file3 &&
+ p4 submit -d "b3/b3-file3"
+ )
+'
+
+test_expect_success 'use-client-spec detect-branches skips branches' '
+ client_view "//depot/usecs/... //client/..." \
+ "-//depot/usecs/b3/... //client/b3/..." &&
+ test_when_finished cleanup_git &&
+ test_create_repo "$git" &&
+ (
+ cd "$git" &&
+ git p4 sync --detect-branches --use-client-spec //depot/usecs@all &&
+ test_must_fail git rev-parse refs/remotes/p4/usecs/b3
+ )
+'
+
test_expect_success 'kill p4d' '
kill_p4d
'
diff --git a/t/t9805-git-p4-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh
index 4a72f79522..ff2cc79701 100755
--- a/t/t9805-git-p4-skip-submit-edit.sh
+++ b/t/t9805-git-p4-skip-submit-edit.sh
@@ -38,7 +38,7 @@ test_expect_success 'no config, unedited, say no' '
cd "$git" &&
echo line >>file1 &&
git commit -a -m "change 3 (not really)" &&
- printf "bad response\nn\n" | git p4 submit &&
+ printf "bad response\nn\n" | test_expect_code 1 git p4 submit &&
p4 changes //depot/... >wc &&
test_line_count = 2 wc
)
@@ -78,20 +78,19 @@ test_expect_success 'skipSubmitEditCheck' '
test_expect_success 'no config, edited' '
git p4 clone --dest="$git" //depot &&
test_when_finished cleanup_git &&
- ed="$TRASH_DIRECTORY/ed.sh" &&
- test_when_finished "rm \"$ed\"" &&
- cat >"$ed" <<-EOF &&
+ test_when_finished "rm ed.sh" &&
+ cat >ed.sh <<-EOF &&
#!$SHELL_PATH
sleep 1
touch "\$1"
exit 0
EOF
- chmod 755 "$ed" &&
+ chmod 755 ed.sh &&
(
cd "$git" &&
echo line >>file1 &&
git commit -a -m "change 5" &&
- EDITOR="\"$ed\"" git p4 submit &&
+ P4EDITOR="" EDITOR="\"$TRASH_DIRECTORY/ed.sh\"" git p4 submit &&
p4 changes //depot/... >wc &&
test_line_count = 5 wc
)
diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh
index 2892367830..fa40cc8bb5 100755
--- a/t/t9806-git-p4-options.sh
+++ b/t/t9806-git-p4-options.sh
@@ -39,10 +39,9 @@ test_expect_success 'clone --branch' '
'
test_expect_success 'clone --changesfile' '
- cf="$TRASH_DIRECTORY/cf" &&
- test_when_finished "rm \"$cf\"" &&
- printf "1\n3\n" >"$cf" &&
- git p4 clone --changesfile="$cf" --dest="$git" //depot &&
+ test_when_finished "rm cf" &&
+ printf "1\n3\n" >cf &&
+ git p4 clone --changesfile="$TRASH_DIRECTORY/cf" --dest="$git" //depot &&
test_when_finished cleanup_git &&
(
cd "$git" &&
@@ -55,10 +54,9 @@ test_expect_success 'clone --changesfile' '
'
test_expect_success 'clone --changesfile, @all' '
- cf="$TRASH_DIRECTORY/cf" &&
- test_when_finished "rm \"$cf\"" &&
- printf "1\n3\n" >"$cf" &&
- test_must_fail git p4 clone --changesfile="$cf" --dest="$git" //depot@all
+ test_when_finished "rm cf" &&
+ printf "1\n3\n" >cf &&
+ test_must_fail git p4 clone --changesfile="$TRASH_DIRECTORY/cf" --dest="$git" //depot@all
'
# imports both master and p4/master in refs/heads
@@ -128,7 +126,7 @@ test_expect_success 'clone --use-client-spec' '
exec >/dev/null &&
test_must_fail git p4 clone --dest="$git" --use-client-spec
) &&
- cli2="$TRASH_DIRECTORY/cli2" &&
+ cli2=$(test-path-utils real_path "$TRASH_DIRECTORY/cli2") &&
mkdir -p "$cli2" &&
test_when_finished "rmdir \"$cli2\"" &&
(
@@ -151,7 +149,6 @@ test_expect_success 'clone --use-client-spec' '
cleanup_git &&
# same thing again, this time with variable instead of option
- mkdir "$git" &&
(
cd "$git" &&
git init &&
diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh
index 15417165e8..0ae048f29f 100755
--- a/t/t9807-git-p4-submit.sh
+++ b/t/t9807-git-p4-submit.sh
@@ -28,6 +28,11 @@ test_expect_success 'submit with no client dir' '
rm -rf "$cli" &&
git config git-p4.skipSubmitEdit true &&
git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file file1 &&
+ test_path_is_file file2
)
'
@@ -44,12 +49,52 @@ test_expect_success 'submit --origin' '
) &&
(
cd "$cli" &&
- p4 sync &&
test_path_is_missing "file3.t" &&
test_path_is_file "file4.t"
)
'
+test_expect_success 'submit --dry-run' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ test_commit "dry-run1" &&
+ test_commit "dry-run2" &&
+ git p4 submit --dry-run >out &&
+ test_i18ngrep "Would apply" out
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing "dry-run1.t" &&
+ test_path_is_missing "dry-run2.t"
+ )
+'
+
+test_expect_success 'submit --dry-run --export-labels' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo dry-run1 >dry-run1 &&
+ git add dry-run1 &&
+ git commit -m "dry-run1" dry-run1 &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit &&
+ echo dry-run2 >dry-run2 &&
+ git add dry-run2 &&
+ git commit -m "dry-run2" dry-run2 &&
+ git tag -m "dry-run-tag1" dry-run-tag1 HEAD^ &&
+ git p4 submit --dry-run --export-labels >out &&
+ test_i18ngrep "Would create p4 label" out
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file "dry-run1" &&
+ test_path_is_missing "dry-run2"
+ )
+'
+
test_expect_success 'submit with allowSubmit' '
test_when_finished cleanup_git &&
git p4 clone --dest="$git" //depot &&
@@ -79,12 +124,284 @@ test_expect_success 'submit with master branch name from argv' '
) &&
(
cd "$cli" &&
- p4 sync &&
test_path_is_file "file6.t" &&
test_path_is_missing "file7.t"
)
'
+#
+# Basic submit tests, the five handled cases
+#
+
+test_expect_success 'submit modify' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ echo line >>file1 &&
+ git add file1 &&
+ git commit -m file1 &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file file1 &&
+ test_line_count = 2 file1
+ )
+'
+
+test_expect_success 'submit add' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ echo file13 >file13 &&
+ git add file13 &&
+ git commit -m file13 &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file file13
+ )
+'
+
+test_expect_success 'submit delete' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git rm file4.t &&
+ git commit -m "delete file4.t" &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing file4.t
+ )
+'
+
+test_expect_success 'submit copy' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.detectCopies true &&
+ git config git-p4.detectCopiesHarder true &&
+ cp file5.t file5.ta &&
+ git add file5.ta &&
+ git commit -m "copy to file5.ta" &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file file5.ta &&
+ test ! -w file5.ta
+ )
+'
+
+test_expect_success 'submit rename' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.detectRenames true &&
+ git mv file6.t file6.ta &&
+ git commit -m "rename file6.t to file6.ta" &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing file6.t &&
+ test_path_is_file file6.ta &&
+ test ! -w file6.ta
+ )
+'
+
+#
+# Converting git commit message to p4 change description, including
+# parsing out the optional Jobs: line.
+#
+test_expect_success 'simple one-line description' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc2 >desc2 &&
+ git add desc2 &&
+ cat >msg <<-EOF &&
+ One-line description line for desc2.
+ EOF
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ test_cmp msg pmsg
+ )
+'
+
+test_expect_success 'description with odd formatting' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc3 >desc3 &&
+ git add desc3 &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Description:\n\tBogus description marker\n\n" &&
+ # git commit eats trailing newlines; only use one
+ printf "Files:\n\tBogus descs marker\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ test_cmp msg pmsg
+ )
+'
+
+make_job() {
+ name="$1" &&
+ tab="$(printf \\t)" &&
+ p4 job -o | \
+ sed -e "/^Job:/s/.*/Job: $name/" \
+ -e "/^Description/{ n; s/.*/$tab job text/; }" | \
+ p4 job -i
+}
+
+test_expect_success 'description with Jobs section at end' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc4 >desc4 &&
+ git add desc4 &&
+ echo 6060842 >jobname &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Files:\n\tBogus files marker\n" &&
+ printf "Junk: 3164175\n" &&
+ printf "Jobs: $(cat jobname)\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ # build a job
+ make_job $(cat jobname) &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ # make sure Jobs line and all following is gone
+ sed "/^Jobs:/,\$d" msg >jmsg &&
+ test_cmp jmsg pmsg &&
+ # make sure p4 knows about job
+ p4 -G describe $change | marshal_dump job0 >job0 &&
+ test_cmp jobname job0
+ )
+'
+
+test_expect_success 'description with Jobs and values on separate lines' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc5 >desc5 &&
+ git add desc5 &&
+ echo PROJ-6060842 >jobname1 &&
+ echo PROJ-6060847 >jobname2 &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Files:\n\tBogus files marker\n" &&
+ printf "Junk: 3164175\n" &&
+ printf "Jobs:\n" &&
+ printf "\t$(cat jobname1)\n" &&
+ printf "\t$(cat jobname2)\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ # build two jobs
+ make_job $(cat jobname1) &&
+ make_job $(cat jobname2) &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ # make sure Jobs line and all following is gone
+ sed "/^Jobs:/,\$d" msg >jmsg &&
+ test_cmp jmsg pmsg &&
+ # make sure p4 knows about the two jobs
+ p4 -G describe $change >change &&
+ (
+ marshal_dump job0 <change &&
+ marshal_dump job1 <change
+ ) | sort >jobs &&
+ cat jobname1 jobname2 | sort >expected &&
+ test_cmp expected jobs
+ )
+'
+
+test_expect_success 'description with Jobs section and bogus following text' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc6 >desc6 &&
+ git add desc6 &&
+ echo 6060843 >jobname &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Files:\n\tBogus files marker\n" &&
+ printf "Junk: 3164175\n" &&
+ printf "Jobs: $(cat jobname)\n" &&
+ printf "MoreJunk: 3711\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ # build a job
+ make_job $(cat jobname) &&
+ test_must_fail git p4 submit 2>err &&
+ test_i18ngrep "Unknown field name" err
+ ) &&
+ (
+ cd "$cli" &&
+ p4 revert desc6 &&
+ rm desc6
+ )
+'
+
+test_expect_success 'submit --prepare-p4-only' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo prep-only-add >prep-only-add &&
+ git add prep-only-add &&
+ git commit -m "prep only add" &&
+ git p4 submit --prepare-p4-only >out &&
+ test_i18ngrep "prepared for submission" out &&
+ test_i18ngrep "must be deleted" out
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file prep-only-add &&
+ p4 fstat -T action prep-only-add | grep -w add
+ )
+'
+
test_expect_success 'kill p4d' '
kill_p4d
'
diff --git a/t/t9808-git-p4-chdir.sh b/t/t9808-git-p4-chdir.sh
index 2f8014a60e..dc92e60cd6 100755
--- a/t/t9808-git-p4-chdir.sh
+++ b/t/t9808-git-p4-chdir.sh
@@ -21,7 +21,7 @@ test_expect_success 'init depot' '
# environment variable is set
test_expect_success 'P4CONFIG and absolute dir clone' '
printf "P4PORT=$P4PORT\nP4CLIENT=$P4CLIENT\n" >p4config &&
- test_when_finished "rm \"$TRASH_DIRECTORY/p4config\"" &&
+ test_when_finished "rm p4config" &&
test_when_finished cleanup_git &&
(
P4CONFIG=p4config && export P4CONFIG &&
@@ -33,7 +33,7 @@ test_expect_success 'P4CONFIG and absolute dir clone' '
# same thing, but with relative directory name, note missing $ on --dest
test_expect_success 'P4CONFIG and relative dir clone' '
printf "P4PORT=$P4PORT\nP4CLIENT=$P4CLIENT\n" >p4config &&
- test_when_finished "rm \"$TRASH_DIRECTORY/p4config\"" &&
+ test_when_finished "rm p4config" &&
test_when_finished cleanup_git &&
(
P4CONFIG=p4config && export P4CONFIG &&
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 796b02c7f3..281be29174 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -9,23 +9,6 @@ test_expect_success 'start p4d' '
'
#
-# Construct a client with this list of View lines
-#
-client_view() {
- (
- cat <<-EOF &&
- Client: client
- Description: client
- Root: $cli
- View:
- EOF
- for arg ; do
- printf "\t$arg\n"
- done
- ) | p4 client -i
-}
-
-#
# Verify these files exist, exactly. Caller creates
# a list of files in file "files".
#
@@ -349,7 +332,8 @@ test_expect_success 'subdir clone, submit copy' '
) &&
(
cd "$cli" &&
- test_path_is_file dir1/file11a
+ test_path_is_file dir1/file11a &&
+ test ! -w dir1/file11a
)
'
@@ -368,14 +352,47 @@ test_expect_success 'subdir clone, submit rename' '
(
cd "$cli" &&
test_path_is_missing dir1/file13 &&
- test_path_is_file dir1/file13a
+ test_path_is_file dir1/file13a &&
+ test ! -w dir1/file13a
+ )
+'
+
+# see t9800 for the non-client-spec case, and the rest of the wildcard tests
+test_expect_success 'wildcard files submit back to p4, client-spec case' '
+ client_view "//depot/... //client/..." &&
+ test_when_finished cleanup_git &&
+ git p4 clone --use-client-spec --dest="$git" //depot/dir1 &&
+ (
+ cd "$git" &&
+ echo git-wild-hash >dir1/git-wild#hash &&
+ echo git-wild-star >dir1/git-wild\*star &&
+ echo git-wild-at >dir1/git-wild@at &&
+ echo git-wild-percent >dir1/git-wild%percent &&
+ git add dir1/git-wild* &&
+ git commit -m "add some wildcard filenames" &&
+ git config git-p4.skipSubmitEditCheck true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file dir1/git-wild#hash &&
+ test_path_is_file dir1/git-wild\*star &&
+ test_path_is_file dir1/git-wild@at &&
+ test_path_is_file dir1/git-wild%percent
+ ) &&
+ (
+ # delete these carefully, cannot just do "p4 delete"
+ # on files with wildcards; but git-p4 knows how
+ cd "$git" &&
+ git rm dir1/git-wild* &&
+ git commit -m "clean up the wildcards" &&
+ git p4 submit
)
'
test_expect_success 'reinit depot' '
(
cd "$cli" &&
- p4 sync -f &&
rm files &&
p4 delete */* &&
p4 submit -d "delete all files" &&
diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh
index d8d9ca4679..34fbc90005 100755
--- a/t/t9810-git-p4-rcs.sh
+++ b/t/t9810-git-p4-rcs.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='git-p4 rcs keywords'
+test_description='git p4 rcs keywords'
. ./lib-git-p4.sh
@@ -26,10 +26,8 @@ test_expect_success 'init depot' '
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
+ sed "s/Revision/Revision: do not scrub me/" <filek >fileko &&
+ sed "s/Id/Id: do not scrub me/" <fileko >file_text &&
p4 add -t text+k filek &&
p4 submit -d "filek" &&
p4 add -t text+ko fileko &&
@@ -88,7 +86,8 @@ test_expect_success 'edit far away from RCS lines' '
(
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
- sed -i "s/^line7/line7 edit/" filek &&
+ sed "s/^line7/line7 edit/" <filek >filek.tmp &&
+ mv -f filek.tmp filek &&
git commit -m "filek line7 edit" filek &&
git p4 submit &&
scrub_k_check filek
@@ -105,7 +104,8 @@ test_expect_success 'edit near RCS lines' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "s/^line4/line4 edit/" filek &&
+ sed "s/^line4/line4 edit/" <filek >filek.tmp &&
+ mv -f filek.tmp filek &&
git commit -m "filek line4 edit" filek &&
git p4 submit &&
scrub_k_check filek
@@ -122,7 +122,8 @@ test_expect_success 'edit keyword lines' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "/Revision/d" filek &&
+ sed "/Revision/d" <filek >filek.tmp &&
+ mv -f filek.tmp filek &&
git commit -m "filek remove Revision line" filek &&
git p4 submit &&
scrub_k_check filek
@@ -139,7 +140,8 @@ test_expect_success 'scrub ko files differently' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "s/^line4/line4 edit/" fileko &&
+ sed "s/^line4/line4 edit/" <fileko >fileko.tmp &&
+ mv -f fileko.tmp fileko &&
git commit -m "fileko line4 edit" fileko &&
git p4 submit &&
scrub_ko_check fileko &&
@@ -147,7 +149,7 @@ test_expect_success 'scrub ko files differently' '
)
'
-# hack; git-p4 submit should do it on its own
+# hack; git p4 submit should do it on its own
test_expect_success 'cleanup after failure' '
(
cd "$cli" &&
@@ -155,14 +157,30 @@ test_expect_success 'cleanup after failure' '
)
'
+# perl $File:: bug check
+test_expect_success 'ktext expansion should not expand multi-line $File::' '
+ (
+ cd "$cli" &&
+ cat >lv.pm <<-\EOF
+ my $wanted = sub { my $f = $File::Find::name;
+ if ( -f && $f =~ /foo/ ) {
+ EOF
+ p4 add -t ktext lv.pm &&
+ p4 submit -d "lv.pm"
+ ) &&
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ test_cmp "$cli/lv.pm" lv.pm
+ )
+'
+
#
# 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.
#
@@ -173,27 +191,26 @@ test_expect_success 'do not scrub plain text' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "s/^line4/line4 edit/" file_text &&
+ sed "s/^line4/line4 edit/" <file_text >file_text.tmp &&
+ mv -f file_text.tmp 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 &&
+ sed "s/^line5/line5 p4 edit/" <file_text >file_text.tmp &&
+ mv -f file_text.tmp file_text &&
p4 submit -d "file5 p4 edit"
) &&
- ! git p4 submit &&
+ echo s | test_expect_code 1 git p4 submit &&
(
- # exepct something like:
- # file_text - file(s) not opened on this client
- # but not copious diff output
+ # make sure the file is not left open
cd "$cli" &&
- p4 diff file_text >wc &&
- test_line_count = 1 wc
+ ! p4 fstat -T action file_text
)
)
'
-# hack; git-p4 submit should do it on its own
+# hack; git p4 submit should do it on its own
test_expect_success 'cleanup after failure 2' '
(
cd "$cli" &&
@@ -244,9 +261,9 @@ test_expect_success 'cope with rcs keyword expansion damage' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- (cd ../cli && p4_append_to_file kwfile1.c) &&
+ (cd "$cli" && p4_append_to_file kwfile1.c) &&
old_lines=$(wc -l <kwfile1.c) &&
- perl -n -i -e "print unless m/Revision:/" kwfile1.c &&
+ "$PERL_PATH" -n -i -e "print unless m/Revision:/" kwfile1.c &&
new_lines=$(wc -l <kwfile1.c) &&
test $new_lines = $(($old_lines - 1)) &&
@@ -343,44 +360,6 @@ test_expect_failure 'Add keywords in git which do not match the default p4 value
)
'
-# 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"
- ) &&
- git p4 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" | git p4 submit) &&
- git rebase --skip &&
- ! test -f merge2.c
- )
-'
-
-
test_expect_success 'kill p4d' '
kill_p4d
'
diff --git a/t/t9811-git-p4-label-import.sh b/t/t9811-git-p4-label-import.sh
new file mode 100755
index 0000000000..095238fffe
--- /dev/null
+++ b/t/t9811-git-p4-label-import.sh
@@ -0,0 +1,222 @@
+#!/bin/sh
+
+test_description='git p4 label tests'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+# Basic p4 label import tests.
+#
+test_expect_success 'basic p4 labels' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$cli" &&
+ mkdir -p main &&
+
+ echo f1 >main/f1 &&
+ p4 add main/f1 &&
+ p4 submit -d "main/f1" &&
+
+ echo f2 >main/f2 &&
+ p4 add main/f2 &&
+ p4 submit -d "main/f2" &&
+
+ echo f3 >main/file_with_\$metachar &&
+ p4 add main/file_with_\$metachar &&
+ p4 submit -d "file with metachar" &&
+
+ p4 tag -l TAG_F1_ONLY main/f1 &&
+ p4 tag -l TAG_WITH\$_SHELL_CHAR main/... &&
+ p4 tag -l this_tag_will_be\ skipped main/... &&
+
+ echo f4 >main/f4 &&
+ p4 add main/f4 &&
+ p4 submit -d "main/f4" &&
+
+ p4 label -i <<-EOF &&
+ Label: TAG_LONG_LABEL
+ Description:
+ A Label first line
+ A Label second line
+ View: //depot/...
+ EOF
+
+ p4 tag -l TAG_LONG_LABEL ... &&
+
+ p4 labels ... &&
+
+ git p4 clone --dest="$git" //depot@all &&
+ cd "$git" &&
+ git config git-p4.labelImportRegexp ".*TAG.*" &&
+ git p4 sync --import-labels --verbose &&
+
+ git tag &&
+ git tag >taglist &&
+ test_line_count = 3 taglist &&
+
+ cd main &&
+ git checkout TAG_F1_ONLY &&
+ ! test -f f2 &&
+ git checkout TAG_WITH\$_SHELL_CHAR &&
+ test -f f1 && test -f f2 && test -f file_with_\$metachar &&
+
+ git show TAG_LONG_LABEL | grep -q "A Label second line"
+ )
+'
+# Test some label corner cases:
+#
+# - two tags on the same file; both should be available
+# - a tag that is only on one file; this kind of tag
+# cannot be imported (at least not easily).
+
+test_expect_success 'two labels on the same changelist' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$cli" &&
+ mkdir -p main &&
+
+ p4 edit main/f1 main/f2 &&
+ echo "hello world" >main/f1 &&
+ echo "not in the tag" >main/f2 &&
+ p4 submit -d "main/f[12]: testing two labels" &&
+
+ p4 tag -l TAG_F1_1 main/... &&
+ p4 tag -l TAG_F1_2 main/... &&
+
+ p4 labels ... &&
+
+ git p4 clone --dest="$git" //depot@all &&
+ cd "$git" &&
+ git p4 sync --import-labels &&
+
+ git tag | grep TAG_F1 &&
+ git tag | grep -q TAG_F1_1 &&
+ git tag | grep -q TAG_F1_2 &&
+
+ cd main &&
+
+ git checkout TAG_F1_1 &&
+ ls &&
+ test -f f1 &&
+
+ git checkout TAG_F1_2 &&
+ ls &&
+ test -f f1
+ )
+'
+
+# Export some git tags to p4
+test_expect_success 'export git tags to p4' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git tag -m "A tag created in git:xyzzy" GIT_TAG_1 &&
+ echo "hello world" >main/f10 &&
+ git add main/f10 &&
+ git commit -m "Adding file for export test" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit &&
+ git tag -m "Another git tag" GIT_TAG_2 &&
+ git tag LIGHTWEIGHT_TAG &&
+ git p4 rebase --import-labels --verbose &&
+ git p4 submit --export-labels --verbose
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync ... &&
+ p4 labels ... | grep GIT_TAG_1 &&
+ p4 labels ... | grep GIT_TAG_2 &&
+ p4 labels ... | grep LIGHTWEIGHT_TAG &&
+ p4 label -o GIT_TAG_1 | grep "tag created in git:xyzzy" &&
+ p4 sync ...@GIT_TAG_1 &&
+ ! test -f main/f10
+ p4 sync ...@GIT_TAG_2 &&
+ test -f main/f10
+ )
+'
+
+# Export a tag from git where an affected file is deleted later on
+# Need to create git tags after rebase, since only then can the
+# git commits be mapped to p4 changelists.
+test_expect_success 'export git tags to p4 with deletion' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git p4 sync --import-labels &&
+ echo "deleted file" >main/deleted_file &&
+ git add main/deleted_file &&
+ git commit -m "create deleted file" &&
+ git rm main/deleted_file &&
+ echo "new file" >main/f11 &&
+ git add main/f11 &&
+ git commit -m "delete the deleted file" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit &&
+ git p4 rebase --import-labels --verbose &&
+ git tag -m "tag on deleted file" GIT_TAG_ON_DELETED HEAD~1 &&
+ git tag -m "tag after deletion" GIT_TAG_AFTER_DELETION HEAD &&
+ git p4 submit --export-labels --verbose
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync ... &&
+ p4 sync ...@GIT_TAG_ON_DELETED &&
+ test -f main/deleted_file &&
+ p4 sync ...@GIT_TAG_AFTER_DELETION &&
+ ! test -f main/deleted_file &&
+ echo "checking label contents" &&
+ p4 label -o GIT_TAG_ON_DELETED | grep "tag on deleted file"
+ )
+'
+
+# Create a tag in git that cannot be exported to p4
+test_expect_success 'tag that cannot be exported' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git checkout -b a_branch &&
+ echo "hello" >main/f12 &&
+ git add main/f12 &&
+ git commit -m "adding f12" &&
+ git tag -m "tag on a_branch" GIT_TAG_ON_A_BRANCH &&
+ git checkout master &&
+ git p4 submit --export-labels
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync ... &&
+ !(p4 labels | grep GIT_TAG_ON_A_BRANCH)
+ )
+'
+
+test_expect_success 'use git config to enable import/export of tags' '
+ git p4 clone --verbose --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git config git-p4.exportLabels true &&
+ git config git-p4.importLabels true &&
+ git tag CFG_A_GIT_TAG &&
+ git p4 rebase --verbose &&
+ git p4 submit --verbose &&
+ git tag &&
+ git tag | grep TAG_F1_1
+ ) &&
+ (
+ cd "$cli" &&
+ p4 labels &&
+ p4 labels | grep CFG_A_GIT_TAG
+ )
+'
+
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9812-git-p4-wildcards.sh b/t/t9812-git-p4-wildcards.sh
new file mode 100755
index 0000000000..143d413057
--- /dev/null
+++ b/t/t9812-git-p4-wildcards.sh
@@ -0,0 +1,147 @@
+#!/bin/sh
+
+test_description='git p4 wildcards'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'add p4 files with wildcards in the names' '
+ (
+ cd "$cli" &&
+ printf "file2\nhas\nsome\nrandom\ntext\n" >file2 &&
+ p4 add file2 &&
+ echo file-wild-hash >file-wild#hash &&
+ echo file-wild-star >file-wild\*star &&
+ echo file-wild-at >file-wild@at &&
+ echo file-wild-percent >file-wild%percent &&
+ p4 add -f file-wild* &&
+ p4 submit -d "file wildcards"
+ )
+'
+
+test_expect_success 'wildcard files git p4 clone' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test -f file-wild#hash &&
+ test -f file-wild\*star &&
+ test -f file-wild@at &&
+ test -f file-wild%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, add' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo git-wild-hash >git-wild#hash &&
+ echo git-wild-star >git-wild\*star &&
+ echo git-wild-at >git-wild@at &&
+ echo git-wild-percent >git-wild%percent &&
+ git add git-wild* &&
+ git commit -m "add some wildcard filenames" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file git-wild#hash &&
+ test_path_is_file git-wild\*star &&
+ test_path_is_file git-wild@at &&
+ test_path_is_file git-wild%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, modify' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo new-line >>git-wild#hash &&
+ echo new-line >>git-wild\*star &&
+ echo new-line >>git-wild@at &&
+ echo new-line >>git-wild%percent &&
+ git add git-wild* &&
+ git commit -m "modify the wildcard files" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_line_count = 2 git-wild#hash &&
+ test_line_count = 2 git-wild\*star &&
+ test_line_count = 2 git-wild@at &&
+ test_line_count = 2 git-wild%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, copy' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ cp file2 git-wild-cp#hash &&
+ git add git-wild-cp#hash &&
+ cp git-wild\*star file-wild-3 &&
+ git add file-wild-3 &&
+ git commit -m "wildcard copies" &&
+ git config git-p4.detectCopies true &&
+ git config git-p4.detectCopiesHarder true &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file git-wild-cp#hash &&
+ test_path_is_file file-wild-3
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, rename' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git mv git-wild@at file-wild-4 &&
+ git mv file-wild-3 git-wild-cp%percent &&
+ git commit -m "wildcard renames" &&
+ git config git-p4.detectRenames true &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing git-wild@at &&
+ test_path_is_file git-wild-cp%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, delete' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git rm git-wild* &&
+ git commit -m "delete the wildcard files" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing git-wild#hash &&
+ test_path_is_missing git-wild\*star &&
+ test_path_is_missing git-wild@at &&
+ test_path_is_missing git-wild%percent
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9813-git-p4-preserve-users.sh b/t/t9813-git-p4-preserve-users.sh
new file mode 100755
index 0000000000..f2e85e518b
--- /dev/null
+++ b/t/t9813-git-p4-preserve-users.sh
@@ -0,0 +1,153 @@
+#!/bin/sh
+
+test_description='git p4 preserve users'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'create files' '
+ (
+ cd "$cli" &&
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ echo file1 >file1 &&
+ echo file2 >file2 &&
+ p4 add file1 file2 &&
+ p4 submit -d "add files"
+ )
+'
+
+p4_add_user() {
+ name=$1 fullname=$2 &&
+ p4 user -f -i <<-EOF &&
+ User: $name
+ Email: $name@localhost
+ FullName: $fullname
+ EOF
+ p4 passwd -P secret $name
+}
+
+p4_grant_admin() {
+ name=$1 &&
+ {
+ p4 protect -o &&
+ echo " admin user $name * //depot/..."
+ } | p4 protect -i
+}
+
+p4_check_commit_author() {
+ file=$1 user=$2 &&
+ p4 changes -m 1 //depot/$file | grep -q $user
+}
+
+make_change_by_user() {
+ file=$1 name=$2 email=$3 &&
+ echo "username: a change by $name" >>"$file" &&
+ git add "$file" &&
+ git commit --author "$name <$email>" -m "a change by $name"
+}
+
+# Test username support, submitting as user 'alice'
+test_expect_success 'preserve users' '
+ p4_add_user alice Alice &&
+ p4_add_user bob Bob &&
+ p4_grant_admin alice &&
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ echo "username: a change by alice" >>file1 &&
+ echo "username: a change by bob" >>file2 &&
+ git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 &&
+ git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 &&
+ git config git-p4.skipSubmitEditCheck true &&
+ P4EDITOR=touch P4USER=alice P4PASSWD=secret git p4 commit --preserve-user &&
+ p4_check_commit_author file1 alice &&
+ p4_check_commit_author file2 bob
+ )
+'
+
+# Test username support, submitting as bob, who lacks admin rights. Should
+# not submit change to p4 (git diff should show deltas).
+test_expect_success 'refuse to preserve users without perms' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ 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 &&
+ export P4EDITOR P4USER P4PASSWD &&
+ test_must_fail git p4 commit --preserve-user &&
+ ! git diff --exit-code HEAD..p4/master
+ )
+'
+
+# What happens with unknown author? Without allowMissingP4Users it should fail.
+test_expect_success 'preserve user where author is unknown to p4' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEditCheck true &&
+ echo "username-bob: a change by bob" >>file1 &&
+ 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 &&
+ export P4EDITOR P4USER P4PASSWD &&
+ test_must_fail git p4 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 &&
+ git p4 commit &&
+ git diff --exit-code HEAD..p4/master &&
+ p4_check_commit_author file1 alice
+ )
+'
+
+# If we're *not* using --preserve-user, git-p4 should warn if we're submitting
+# changes that are not all ours.
+# Test: user in p4 and user unknown to p4.
+# Test: warning disabled and user is the same.
+test_expect_success 'not preserving user with mixed authorship' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEditCheck true &&
+ p4_add_user derek Derek &&
+
+ make_change_by_user usernamefile3 Derek derek@localhost &&
+ P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
+ export P4EDITOR P4USER P4PASSWD &&
+ git p4 commit |\
+ grep "git author derek@localhost does not match" &&
+
+ make_change_by_user usernamefile3 Charlie charlie@localhost &&
+ git p4 commit |\
+ grep "git author charlie@localhost does not match" &&
+
+ make_change_by_user usernamefile3 alice alice@localhost &&
+ git p4 commit |\
+ test_must_fail grep "git author.*does not match" &&
+
+ git config git-p4.skipUserNameCheck true &&
+ make_change_by_user usernamefile3 Charlie charlie@localhost &&
+ git p4 commit |\
+ test_must_fail grep "git author.*does not match" &&
+
+ p4_check_commit_author usernamefile3 alice
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh
new file mode 100755
index 0000000000..be802e0e16
--- /dev/null
+++ b/t/t9814-git-p4-rename.sh
@@ -0,0 +1,241 @@
+#!/bin/sh
+
+test_description='git p4 rename'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+# We rely on this behavior to detect for p4 move availability.
+test_expect_success 'p4 help unknown returns 1' '
+ (
+ cd "$cli" &&
+ (
+ p4 help client >errs 2>&1
+ echo $? >retval
+ )
+ echo 0 >expected &&
+ test_cmp expected retval &&
+ rm retval &&
+ (
+ p4 help nosuchcommand >errs 2>&1
+ echo $? >retval
+ )
+ echo 1 >expected &&
+ test_cmp expected retval &&
+ rm retval
+ )
+'
+
+test_expect_success 'create files' '
+ (
+ cd "$cli" &&
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ cat >file1 <<-EOF &&
+ A large block of text
+ in file1 that will generate
+ enough context so that rename
+ and copy detection will find
+ something interesting to do.
+ EOF
+ cat >file2 <<-EOF &&
+ /*
+ * This blob looks a bit
+ * different.
+ */
+ int main(int argc, char **argv)
+ {
+ char text[200];
+
+ strcpy(text, "copy/rename this");
+ printf("text is %s\n", text);
+ return 0;
+ }
+ EOF
+ p4 add file1 file2 &&
+ p4 submit -d "add files"
+ )
+'
+
+# Rename a file and confirm that rename is not detected in P4.
+# Rename the new file again with detectRenames option enabled and confirm that
+# this is detected in P4.
+# Rename the new file again adding an extra line, configure a big threshold in
+# detectRenames and confirm that rename is not detected in P4.
+# Repeat, this time with a smaller threshold and confirm that the rename is
+# detected in P4.
+test_expect_success 'detect renames' '
+ git p4 clone --dest="$git" //depot@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+
+ git mv file1 file4 &&
+ git commit -a -m "Rename file1 to file4" &&
+ git diff-tree -r -M HEAD &&
+ git p4 submit &&
+ p4 filelog //depot/file4 >filelog &&
+ ! grep " from //depot" filelog &&
+
+ git mv file4 file5 &&
+ git commit -a -m "Rename file4 to file5" &&
+ git diff-tree -r -M HEAD &&
+ git config git-p4.detectRenames true &&
+ git p4 submit &&
+ p4 filelog //depot/file5 >filelog &&
+ grep " from //depot/file4" filelog &&
+
+ git mv file5 file6 &&
+ echo update >>file6 &&
+ git add file6 &&
+ git commit -a -m "Rename file5 to file6 with changes" &&
+ git diff-tree -r -M HEAD &&
+ level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
+ test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
+ git config git-p4.detectRenames $(($level + 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file6 >filelog &&
+ ! grep " from //depot" filelog &&
+
+ git mv file6 file7 &&
+ echo update >>file7 &&
+ git add file7 &&
+ git commit -a -m "Rename file6 to file7 with changes" &&
+ git diff-tree -r -M HEAD &&
+ level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
+ test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
+ git config git-p4.detectRenames $(($level - 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file7 >filelog &&
+ grep " from //depot/file6" filelog
+ )
+'
+
+# Copy a file and confirm that copy is not detected in P4.
+# Copy a file with detectCopies option enabled and confirm that copy is not
+# detected in P4.
+# Modify and copy a file with detectCopies option enabled and confirm that copy
+# is detected in P4.
+# Copy a file with detectCopies and detectCopiesHarder options enabled and
+# confirm that copy is detected in P4.
+# Modify and copy a file, configure a bigger threshold in detectCopies and
+# confirm that copy is not detected in P4.
+# Modify and copy a file, configure a smaller threshold in detectCopies and
+# confirm that copy is detected in P4.
+test_expect_success 'detect copies' '
+ git p4 clone --dest="$git" //depot@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+
+ cp file2 file8 &&
+ git add file8 &&
+ git commit -a -m "Copy file2 to file8" &&
+ git diff-tree -r -C HEAD &&
+ git p4 submit &&
+ p4 filelog //depot/file8 &&
+ p4 filelog //depot/file8 | test_must_fail grep -q "branch from" &&
+
+ cp file2 file9 &&
+ git add file9 &&
+ git commit -a -m "Copy file2 to file9" &&
+ git diff-tree -r -C HEAD &&
+ git config git-p4.detectCopies true &&
+ git p4 submit &&
+ p4 filelog //depot/file9 &&
+ p4 filelog //depot/file9 | test_must_fail grep -q "branch from" &&
+
+ echo "file2" >>file2 &&
+ cp file2 file10 &&
+ git add file2 file10 &&
+ git commit -a -m "Modify and copy file2 to file10" &&
+ git diff-tree -r -C HEAD &&
+ git p4 submit &&
+ p4 filelog //depot/file10 &&
+ p4 filelog //depot/file10 | grep -q "branch from //depot/file" &&
+
+ cp file2 file11 &&
+ git add file11 &&
+ git commit -a -m "Copy file2 to file11" &&
+ git diff-tree -r -C --find-copies-harder HEAD &&
+ src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
+ test "$src" = file10 &&
+ git config git-p4.detectCopiesHarder true &&
+ git p4 submit &&
+ p4 filelog //depot/file11 &&
+ p4 filelog //depot/file11 | grep -q "branch from //depot/file" &&
+
+ cp file2 file12 &&
+ echo "some text" >>file12 &&
+ git add file12 &&
+ git commit -a -m "Copy file2 to file12 with changes" &&
+ git diff-tree -r -C --find-copies-harder HEAD &&
+ level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
+ test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
+ src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
+ test "$src" = file10 -o "$src" = file11 &&
+ git config git-p4.detectCopies $(($level + 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file12 &&
+ p4 filelog //depot/file12 | test_must_fail grep -q "branch from" &&
+
+ cp file2 file13 &&
+ echo "different text" >>file13 &&
+ git add file13 &&
+ git commit -a -m "Copy file2 to file13 with changes" &&
+ git diff-tree -r -C --find-copies-harder HEAD &&
+ level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
+ test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
+ src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
+ test "$src" = file10 -o "$src" = file11 -o "$src" = file12 &&
+ git config git-p4.detectCopies $(($level - 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file13 &&
+ p4 filelog //depot/file13 | grep -q "branch from //depot/file"
+ )
+'
+
+# See if configurables can be set, and in particular if the run.move.allow
+# variable exists, which allows admins to disable the "p4 move" command.
+test_expect_success 'p4 configure command and run.move.allow are available' '
+ p4 configure show run.move.allow >out ; retval=$? &&
+ test $retval = 0 &&
+ {
+ egrep ^run.move.allow: out &&
+ test_set_prereq P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW ||
+ true
+ } || true
+'
+
+# If move can be disabled, turn it off and test p4 move handling
+test_expect_success P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW \
+ 'do not use p4 move when administratively disabled' '
+ test_when_finished "p4 configure set run.move.allow=1" &&
+ p4 configure set run.move.allow=0 &&
+ (
+ cd "$cli" &&
+ echo move-disallow-file >move-disallow-file &&
+ p4 add move-disallow-file &&
+ p4 submit -d "add move-disallow-file"
+ ) &&
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.detectRenames true &&
+ git mv move-disallow-file move-disallow-file-moved &&
+ git commit -m "move move-disallow-file" &&
+ git p4 submit
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh
new file mode 100755
index 0000000000..d2b7b3d98d
--- /dev/null
+++ b/t/t9815-git-p4-submit-fail.sh
@@ -0,0 +1,429 @@
+#!/bin/sh
+
+test_description='git p4 submit failure handling'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ echo line1 >file1 &&
+ p4 add file1 &&
+ p4 submit -d "line1 in file1"
+ )
+'
+
+test_expect_success 'conflict on one commit' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$cli" &&
+ p4 open file1 &&
+ echo line2 >>file1 &&
+ p4 submit -d "line2 in file1"
+ ) &&
+ (
+ # now this commit should cause a conflict
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ echo line3 >>file1 &&
+ git add file1 &&
+ git commit -m "line3 in file1 will conflict" &&
+ test_expect_code 1 git p4 submit >out &&
+ test_i18ngrep "No commits applied" out
+ )
+'
+
+test_expect_success 'conflict on second of two commits' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$cli" &&
+ p4 open file1 &&
+ echo line3 >>file1 &&
+ p4 submit -d "line3 in file1"
+ ) &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ # this commit is okay
+ test_commit "first_commit_okay" &&
+ # now this submit should cause a conflict
+ echo line4 >>file1 &&
+ git add file1 &&
+ git commit -m "line4 in file1 will conflict" &&
+ test_expect_code 1 git p4 submit >out &&
+ test_i18ngrep "Applied only the commits" out
+ )
+'
+
+test_expect_success 'conflict on first of two commits, skip' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$cli" &&
+ p4 open file1 &&
+ echo line4 >>file1 &&
+ p4 submit -d "line4 in file1"
+ ) &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ # this submit should cause a conflict
+ echo line5 >>file1 &&
+ git add file1 &&
+ git commit -m "line5 in file1 will conflict" &&
+ # but this commit is okay
+ test_commit "okay_commit_after_skip" &&
+ echo s | test_expect_code 1 git p4 submit >out &&
+ test_i18ngrep "Applied only the commits" out
+ )
+'
+
+test_expect_success 'conflict on first of two commits, quit' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$cli" &&
+ p4 open file1 &&
+ echo line7 >>file1 &&
+ p4 submit -d "line7 in file1"
+ ) &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ # this submit should cause a conflict
+ echo line8 >>file1 &&
+ git add file1 &&
+ git commit -m "line8 in file1 will conflict" &&
+ # but this commit is okay
+ test_commit "okay_commit_after_quit" &&
+ echo q | test_expect_code 1 git p4 submit >out &&
+ test_i18ngrep "No commits applied" out
+ )
+'
+
+test_expect_success 'conflict cli and config options' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git p4 submit --conflict=ask &&
+ git p4 submit --conflict=skip &&
+ git p4 submit --conflict=quit &&
+ test_expect_code 2 git p4 submit --conflict=foo &&
+ test_expect_code 2 git p4 submit --conflict &&
+ git config git-p4.conflict foo &&
+ test_expect_code 1 git p4 submit &&
+ git config --unset git-p4.conflict &&
+ git p4 submit
+ )
+'
+
+test_expect_success 'conflict on first of two commits, --conflict=skip' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$cli" &&
+ p4 open file1 &&
+ echo line9 >>file1 &&
+ p4 submit -d "line9 in file1"
+ ) &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ # this submit should cause a conflict
+ echo line10 >>file1 &&
+ git add file1 &&
+ git commit -m "line10 in file1 will conflict" &&
+ # but this commit is okay
+ test_commit "okay_commit_after_auto_skip" &&
+ test_expect_code 1 git p4 submit --conflict=skip >out &&
+ test_i18ngrep "Applied only the commits" out
+ )
+'
+
+test_expect_success 'conflict on first of two commits, --conflict=quit' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$cli" &&
+ p4 open file1 &&
+ echo line11 >>file1 &&
+ p4 submit -d "line11 in file1"
+ ) &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ # this submit should cause a conflict
+ echo line12 >>file1 &&
+ git add file1 &&
+ git commit -m "line12 in file1 will conflict" &&
+ # but this commit is okay
+ test_commit "okay_commit_after_auto_quit" &&
+ test_expect_code 1 git p4 submit --conflict=quit >out &&
+ test_i18ngrep "No commits applied" out
+ )
+'
+
+#
+# Cleanup after submit fail, all cases. Some modifications happen
+# before trying to apply the patch. Make sure these are unwound
+# properly. Put each one in a diff along with something that will
+# obviously conflict. Make sure it is back to normal after.
+#
+
+test_expect_success 'cleanup edit p4 populate' '
+ (
+ cd "$cli" &&
+ echo text file >text &&
+ p4 add text &&
+ echo text+x file >text+x &&
+ chmod 755 text+x &&
+ p4 add text+x &&
+ p4 submit -d "populate p4"
+ )
+'
+
+setup_conflict() {
+ # clone before modifying file1 to force it to conflict
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ # ticks outside subshells
+ test_tick &&
+ (
+ cd "$cli" &&
+ p4 open file1 &&
+ echo $test_tick >>file1 &&
+ p4 submit -d "$test_tick in file1"
+ ) &&
+ test_tick &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ # easy conflict
+ echo $test_tick >>file1 &&
+ git add file1
+ # caller will add more and submit
+ )
+}
+
+test_expect_success 'cleanup edit after submit fail' '
+ setup_conflict &&
+ (
+ cd "$git" &&
+ echo another line >>text &&
+ git add text &&
+ git commit -m "conflict" &&
+ test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ # make sure it is not open
+ ! p4 fstat -T action text
+ )
+'
+
+test_expect_success 'cleanup add after submit fail' '
+ setup_conflict &&
+ (
+ cd "$git" &&
+ echo new file >textnew &&
+ git add textnew &&
+ git commit -m "conflict" &&
+ test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ # make sure it is not there
+ # and that p4 thinks it is not added
+ # P4 returns 0 both for "not there but added" and
+ # "not there", so grep.
+ test_path_is_missing textnew &&
+ p4 fstat -T action textnew 2>&1 | grep "no such file"
+ )
+'
+
+test_expect_success 'cleanup delete after submit fail' '
+ setup_conflict &&
+ (
+ cd "$git" &&
+ git rm text+x &&
+ git commit -m "conflict" &&
+ test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ # make sure it is there
+ test_path_is_file text+x &&
+ ! p4 fstat -T action text+x
+ )
+'
+
+test_expect_success 'cleanup copy after submit fail' '
+ setup_conflict &&
+ (
+ cd "$git" &&
+ cp text text2 &&
+ git add text2 &&
+ git commit -m "conflict" &&
+ git config git-p4.detectCopies true &&
+ git config git-p4.detectCopiesHarder true &&
+ # make sure setup is okay
+ git diff-tree -r -C --find-copies-harder HEAD | grep text2 | grep C100 &&
+ test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing text2 &&
+ p4 fstat -T action text2 2>&1 | grep "no such file"
+ )
+'
+
+test_expect_success 'cleanup rename after submit fail' '
+ setup_conflict &&
+ (
+ cd "$git" &&
+ git mv text text2 &&
+ git commit -m "conflict" &&
+ git config git-p4.detectRenames true &&
+ # make sure setup is okay
+ git diff-tree -r -M HEAD | grep text2 | grep R100 &&
+ test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing text2 &&
+ p4 fstat -T action text2 2>&1 | grep "no such file"
+ )
+'
+
+#
+# Cleanup after deciding not to submit during editTemplate. This
+# involves unwinding more work, because files have been added, deleted
+# and chmod-ed now. Same approach as above.
+#
+
+test_expect_success 'cleanup edit after submit cancel' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo line >>text &&
+ git add text &&
+ git commit -m text &&
+ echo n | test_expect_code 1 git p4 submit &&
+ git reset --hard HEAD^
+ ) &&
+ (
+ cd "$cli" &&
+ ! p4 fstat -T action text &&
+ test_cmp "$git"/text text
+ )
+'
+
+test_expect_success 'cleanup add after submit cancel' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo line >textnew &&
+ git add textnew &&
+ git commit -m textnew &&
+ echo n | test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing textnew &&
+ p4 fstat -T action textnew 2>&1 | grep "no such file"
+ )
+'
+
+test_expect_success 'cleanup delete after submit cancel' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git rm text &&
+ git commit -m "rm text" &&
+ echo n | test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file text &&
+ ! p4 fstat -T action text
+ )
+'
+
+test_expect_success 'cleanup copy after submit cancel' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ cp text text2 &&
+ git add text2 &&
+ git commit -m text2 &&
+ git config git-p4.detectCopies true &&
+ git config git-p4.detectCopiesHarder true &&
+ git diff-tree -r -C --find-copies-harder HEAD | grep text2 | grep C100 &&
+ echo n | test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing text2 &&
+ p4 fstat -T action text2 2>&1 | grep "no such file"
+ )
+'
+
+test_expect_success 'cleanup rename after submit cancel' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git mv text text2 &&
+ git commit -m text2 &&
+ git config git-p4.detectRenames true &&
+ git diff-tree -r -M HEAD | grep text2 | grep R100 &&
+ echo n | test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing text2 &&
+ p4 fstat -T action text2 2>&1 | grep "no such file"
+ test_path_is_file text &&
+ ! p4 fstat -T action text
+ )
+'
+
+test_expect_success 'cleanup chmod after submit cancel' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ chmod u+x text &&
+ chmod u-x text+x &&
+ git add text text+x &&
+ git commit -m "chmod texts" &&
+ echo n | test_expect_code 1 git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file text &&
+ ! p4 fstat -T action text &&
+ stat --format=%A text | egrep ^-r-- &&
+ test_path_is_file text+x &&
+ ! p4 fstat -T action text+x &&
+ stat --format=%A text+x | egrep ^-r-x
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 5bda6b6e18..3cd53f87fb 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -3,21 +3,9 @@
# Copyright (c) 2012 Felipe Contreras
#
-if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then
- # we are in full-on bash mode
- true
-elif type bash >/dev/null 2>&1; then
- # execute in full-on bash mode
- unset POSIXLY_CORRECT
- exec bash "$0" "$@"
-else
- echo '1..0 #SKIP skipping bash completion tests; bash not available'
- exit 0
-fi
-
test_description='test bash completion'
-. ./test-lib.sh
+. ./lib-bash.sh
complete ()
{
@@ -63,99 +51,81 @@ run_completion ()
local _cword
_words=( $1 )
(( _cword = ${#_words[@]} - 1 ))
- _git && print_comp
+ __git_wrap__git_main && print_comp
}
+# Test high-level completion
+# Arguments are:
+# 1: typed text so far (cur)
+# 2: expected completion
test_completion ()
{
- test $# -gt 1 && echo "$2" > expected
- run_completion "$@" &&
+ if test $# -gt 1
+ then
+ printf '%s\n' "$2" >expected
+ else
+ sed -e 's/Z$//' >expected
+ fi &&
+ run_completion "$1" &&
test_cmp expected out
}
-newline=$'\n'
+# Test __gitcomp.
+# The first argument is the typed text so far (cur); the rest are
+# passed to __gitcomp. Expected output comes is read from the
+# standard input, like test_completion().
+test_gitcomp ()
+{
+ local -a COMPREPLY &&
+ sed -e 's/Z$//' >expected &&
+ cur="$1" &&
+ shift &&
+ __gitcomp "$@" &&
+ print_comp &&
+ test_cmp expected out
+}
test_expect_success '__gitcomp - trailing space - options' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
+ --reset-author" <<-EOF
--reuse-message=Z
--reedit-message=Z
--reset-author Z
EOF
- (
- local -a COMPREPLY &&
- cur="--re" &&
- __gitcomp "--dry-run --reuse-message= --reedit-message=
- --reset-author" &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - trailing space - config keys' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "br" "branch. branch.autosetupmerge
+ branch.autosetuprebase browser." <<-\EOF
branch.Z
branch.autosetupmerge Z
branch.autosetuprebase Z
browser.Z
EOF
- (
- local -a COMPREPLY &&
- cur="br" &&
- __gitcomp "branch. branch.autosetupmerge
- branch.autosetuprebase browser." &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - option parameter' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
+ "" "re" <<-\EOF
recursive Z
resolve Z
EOF
- (
- local -a COMPREPLY &&
- cur="--strategy=re" &&
- __gitcomp "octopus ours recursive resolve subtree
- " "" "re" &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - prefix' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
+ "branch.maint." "me" <<-\EOF
branch.maint.merge Z
branch.maint.mergeoptions Z
EOF
- (
- local -a COMPREPLY &&
- cur="branch.me" &&
- __gitcomp "remote merge mergeoptions rebase
- " "branch.maint." "me" &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - suffix' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "branch.me" "master maint next pu" "branch." \
+ "ma" "." <<-\EOF
branch.master.Z
branch.maint.Z
EOF
- (
- local -a COMPREPLY &&
- cur="branch.me" &&
- __gitcomp "master maint next pu
- " "branch." "ma" "." &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success 'basic' '
@@ -172,7 +142,7 @@ test_expect_success 'basic' '
'
test_expect_success 'double dash "git" itself' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_completion "git --" <<-\EOF
--paginate Z
--no-pager Z
--git-dir=
@@ -187,11 +157,10 @@ test_expect_success 'double dash "git" itself' '
--no-replace-objects Z
--help Z
EOF
- test_completion "git --"
'
test_expect_success 'double dash "git checkout"' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_completion "git checkout --" <<-\EOF
--quiet Z
--ours Z
--theirs Z
@@ -202,17 +171,15 @@ test_expect_success 'double dash "git checkout"' '
--orphan Z
--patch Z
EOF
- test_completion "git checkout --"
'
test_expect_success 'general options' '
test_completion "git --ver" "--version " &&
test_completion "git --hel" "--help " &&
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_completion "git --exe" <<-\EOF &&
--exec-path Z
--exec-path=
EOF
- test_completion "git --exe" &&
test_completion "git --htm" "--html-path " &&
test_completion "git --pag" "--paginate " &&
test_completion "git --no-p" "--no-pager " &&
@@ -240,4 +207,60 @@ test_expect_success 'general options plus command' '
test_completion "git --no-replace-objects check" "checkout "
'
+test_expect_success 'setup for ref completion' '
+ echo content >file1 &&
+ echo more >file2 &&
+ git add . &&
+ git commit -m one &&
+ git branch mybranch &&
+ git tag mytag
+'
+
+test_expect_success 'checkout completes ref names' '
+ test_completion "git checkout m" <<-\EOF
+ master Z
+ mybranch Z
+ mytag Z
+ EOF
+'
+
+test_expect_success 'show completes all refs' '
+ test_completion "git show m" <<-\EOF
+ master Z
+ mybranch Z
+ mytag Z
+ EOF
+'
+
+test_expect_success '<ref>: completes paths' '
+ test_completion "git show mytag:f" <<-\EOF
+ file1 Z
+ file2 Z
+ EOF
+'
+
+test_expect_success 'complete tree filename with spaces' '
+ echo content >"name with spaces" &&
+ git add . &&
+ git commit -m spaces &&
+ test_completion "git show HEAD:nam" <<-\EOF
+ name with spaces Z
+ EOF
+'
+
+test_expect_failure 'complete tree filename with metacharacters' '
+ echo content >"name with \${meta}" &&
+ git add . &&
+ git commit -m meta &&
+ test_completion "git show HEAD:nam" <<-\EOF
+ name with ${meta} Z
+ name with spaces Z
+ EOF
+'
+
+test_expect_success 'send-email' '
+ test_completion "git send-email --cov" "--cover-letter " &&
+ test_completion "git send-email ma" "master "
+'
+
test_done
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
new file mode 100755
index 0000000000..f17c1f8b85
--- /dev/null
+++ b/t/t9903-bash-prompt.sh
@@ -0,0 +1,456 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 SZEDER Gábor
+#
+
+test_description='test git-specific bash prompt functions'
+
+. ./lib-bash.sh
+
+. "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
+
+actual="$TRASH_DIRECTORY/actual"
+
+test_expect_success 'setup for prompt tests' '
+ mkdir -p subdir/subsubdir &&
+ git init otherrepo &&
+ echo 1 > file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+ git tag -a -m msg1 t1 &&
+ git checkout -b b1 &&
+ echo 2 > file &&
+ git commit -m "second b1" file &&
+ echo 3 > file &&
+ git commit -m "third b1" file &&
+ git tag -a -m msg2 t2 &&
+ git checkout -b b2 master &&
+ echo 0 > file &&
+ git commit -m "second b2" file &&
+ git checkout master
+'
+
+test_expect_success 'gitdir - from command line (through $__git_dir)' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ (
+ __git_dir="$TRASH_DIRECTORY/otherrepo/.git" &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - repo as argument' '
+ echo "otherrepo/.git" > expected &&
+ __gitdir "otherrepo" > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - remote as argument' '
+ echo "remote" > expected &&
+ __gitdir "remote" > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - .git directory in cwd' '
+ echo ".git" > expected &&
+ __gitdir > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - .git directory in parent' '
+ echo "$TRASH_DIRECTORY/.git" > expected &&
+ (
+ cd subdir/subsubdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - cwd is a .git directory' '
+ echo "." > expected &&
+ (
+ cd .git &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - parent is a .git directory' '
+ echo "$TRASH_DIRECTORY/.git" > expected &&
+ (
+ cd .git/refs/heads &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - $GIT_DIR set while .git directory in cwd' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ (
+ GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" &&
+ export GIT_DIR &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - $GIT_DIR set while .git directory in parent' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ (
+ GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" &&
+ export GIT_DIR &&
+ cd subdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - non-existing $GIT_DIR' '
+ (
+ GIT_DIR="$TRASH_DIRECTORY/non-existing" &&
+ export GIT_DIR &&
+ test_must_fail __gitdir
+ )
+'
+
+test_expect_success 'gitdir - gitfile in cwd' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
+ test_when_finished "rm -f subdir/.git" &&
+ (
+ cd subdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - gitfile in parent' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
+ test_when_finished "rm -f subdir/.git" &&
+ (
+ cd subdir/subsubdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success SYMLINKS 'gitdir - resulting path avoids symlinks' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ mkdir otherrepo/dir &&
+ test_when_finished "rm -rf otherrepo/dir" &&
+ ln -s otherrepo/dir link &&
+ test_when_finished "rm -f link" &&
+ (
+ cd link &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - not a git repository' '
+ (
+ cd subdir/subsubdir &&
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY" &&
+ export GIT_CEILING_DIRECTORIES &&
+ test_must_fail __gitdir
+ )
+'
+
+test_expect_success 'prompt - branch name' '
+ printf " (master)" > expected &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - detached head' '
+ printf " ((%s...))" $(git log -1 --format="%h" b1^) > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - contains' '
+ printf " ((t2~1))" > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ (
+ GIT_PS1_DESCRIBE_STYLE=contains &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - branch' '
+ printf " ((b1~1))" > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ (
+ GIT_PS1_DESCRIBE_STYLE=branch &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - describe' '
+ printf " ((t1-1-g%s))" $(git log -1 --format="%h" b1^) > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ (
+ GIT_PS1_DESCRIBE_STYLE=describe &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - default' '
+ printf " ((t2))" > expected &&
+ git checkout --detach b1 &&
+ test_when_finished "git checkout master" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ (
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - deep inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ (
+ cd .git/refs/heads &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - inside bare repository' '
+ printf " (BARE:master)" > expected &&
+ git init --bare bare.git &&
+ test_when_finished "rm -rf bare.git" &&
+ (
+ cd bare.git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - interactive rebase' '
+ printf " (b1|REBASE-i)" > expected
+ echo "#!$SHELL_PATH" >fake_editor.sh &&
+ cat >>fake_editor.sh <<\EOF &&
+echo "edit $(git log -1 --format="%h")" > "$1"
+EOF
+ test_when_finished "rm -f fake_editor.sh" &&
+ chmod a+x fake_editor.sh &&
+ test_set_editor "$TRASH_DIRECTORY/fake_editor.sh" &&
+ git checkout b1 &&
+ test_when_finished "git checkout master" &&
+ git rebase -i HEAD^ &&
+ test_when_finished "git rebase --abort"
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - rebase merge' '
+ printf " (b2|REBASE-m)" > expected &&
+ git checkout b2 &&
+ test_when_finished "git checkout master" &&
+ test_must_fail git rebase --merge b1 b2 &&
+ test_when_finished "git rebase --abort" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - rebase' '
+ printf " ((t2)|REBASE)" > expected &&
+ git checkout b2 &&
+ test_when_finished "git checkout master" &&
+ test_must_fail git rebase b1 b2 &&
+ test_when_finished "git rebase --abort" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - merge' '
+ printf " (b1|MERGING)" > expected &&
+ git checkout b1 &&
+ test_when_finished "git checkout master" &&
+ test_must_fail git merge b2 &&
+ test_when_finished "git reset --hard" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - cherry-pick' '
+ printf " (master|CHERRY-PICKING)" > expected &&
+ test_must_fail git cherry-pick b1 &&
+ test_when_finished "git reset --hard" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - bisect' '
+ printf " (master|BISECTING)" > expected &&
+ git bisect start &&
+ test_when_finished "git bisect reset" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - clean' '
+ printf " (master)" > expected &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - dirty worktree' '
+ printf " (master *)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - dirty index' '
+ printf " (master +)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ git add -u &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - dirty index and worktree' '
+ printf " (master *+)" > expected &&
+ echo "dirty index" > file &&
+ test_when_finished "git reset --hard" &&
+ git add -u &&
+ echo "dirty worktree" > file &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - before root commit' '
+ printf " (master #)" > expected &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ cd otherrepo &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - disabled by config' '
+ printf " (master)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ test_config bash.showDirtyState false &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - stash status indicator - no stash' '
+ printf " (master)" > expected &&
+ (
+ GIT_PS1_SHOWSTASHSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - stash status indicator - stash' '
+ printf " (master $)" > expected &&
+ echo 2 >file &&
+ git stash &&
+ test_when_finished "git stash drop" &&
+ (
+ GIT_PS1_SHOWSTASHSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - stash status indicator - not shown inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ echo 2 >file &&
+ git stash &&
+ test_when_finished "git stash drop" &&
+ (
+ GIT_PS1_SHOWSTASHSTATE=y &&
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - no untracked files' '
+ printf " (master)" > expected &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ cd otherrepo &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - untracked files' '
+ printf " (master %%)" > expected &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - format string starting with dash' '
+ printf -- "-master" > expected &&
+ __git_ps1 "-%s" > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_done
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 7b3b4bef30..fa62d010f6 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -76,11 +76,11 @@ test_decode_color () {
}
nul_to_q () {
- perl -pe 'y/\000/Q/'
+ "$PERL_PATH" -pe 'y/\000/Q/'
}
q_to_nul () {
- perl -pe 'y/Q/\000/'
+ "$PERL_PATH" -pe 'y/Q/\000/'
}
q_to_cr () {
@@ -143,11 +143,31 @@ test_pause () {
# Both <file> and <contents> default to <message>.
test_commit () {
- file=${2:-"$1.t"}
+ notick= &&
+ signoff= &&
+ while test $# != 0
+ do
+ case "$1" in
+ --notick)
+ notick=yes
+ ;;
+ --signoff)
+ signoff="$1"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done &&
+ file=${2:-"$1.t"} &&
echo "${3-$1}" > "$file" &&
git add "$file" &&
- test_tick &&
- git commit -m "$1" &&
+ if test -z "$notick"
+ then
+ test_tick
+ fi &&
+ git commit $signoff -m "$1" &&
git tag "$1"
}
@@ -212,9 +232,35 @@ write_script () {
# capital letters by convention).
test_set_prereq () {
- satisfied="$satisfied$1 "
+ satisfied_prereq="$satisfied_prereq$1 "
+}
+satisfied_prereq=" "
+lazily_testable_prereq= lazily_tested_prereq=
+
+# Usage: test_lazy_prereq PREREQ 'script'
+test_lazy_prereq () {
+ lazily_testable_prereq="$lazily_testable_prereq$1 "
+ eval test_prereq_lazily_$1=\$2
+}
+
+test_run_lazy_prereq_ () {
+ script='
+mkdir -p "$TRASH_DIRECTORY/prereq-test-dir" &&
+(
+ cd "$TRASH_DIRECTORY/prereq-test-dir" &&'"$2"'
+)'
+ say >&3 "checking prerequisite: $1"
+ say >&3 "$script"
+ test_eval_ "$script"
+ eval_ret=$?
+ rm -rf "$TRASH_DIRECTORY/prereq-test-dir"
+ if test "$eval_ret" = 0; then
+ say >&3 "prerequisite $1 ok"
+ else
+ say >&3 "prerequisite $1 not satisfied"
+ fi
+ return $eval_ret
}
-satisfied=" "
test_have_prereq () {
# prerequisites can be concatenated with ','
@@ -229,13 +275,48 @@ test_have_prereq () {
for prerequisite
do
+ case "$prerequisite" in
+ !*)
+ negative_prereq=t
+ prerequisite=${prerequisite#!}
+ ;;
+ *)
+ negative_prereq=
+ esac
+
+ case " $lazily_tested_prereq " in
+ *" $prerequisite "*)
+ ;;
+ *)
+ case " $lazily_testable_prereq " in
+ *" $prerequisite "*)
+ eval "script=\$test_prereq_lazily_$prerequisite" &&
+ if test_run_lazy_prereq_ "$prerequisite" "$script"
+ then
+ test_set_prereq $prerequisite
+ fi
+ lazily_tested_prereq="$lazily_tested_prereq$prerequisite "
+ esac
+ ;;
+ esac
+
total_prereq=$(($total_prereq + 1))
- case $satisfied in
+ case "$satisfied_prereq" in
*" $prerequisite "*)
+ satisfied_this_prereq=t
+ ;;
+ *)
+ satisfied_this_prereq=
+ esac
+
+ case "$satisfied_this_prereq,$negative_prereq" in
+ t,|,t)
ok_prereq=$(($ok_prereq + 1))
;;
*)
- # Keep a list of missing prerequisites
+ # Keep a list of missing prerequisites; restore
+ # the negative marker if necessary.
+ prerequisite=${negative_prereq:+!}$prerequisite
if test -z "$missing_prereq"
then
missing_prereq=$prerequisite
@@ -521,6 +602,34 @@ test_cmp() {
$GIT_TEST_CMP "$@"
}
+# Tests that its two parameters refer to the same revision
+test_cmp_rev () {
+ git rev-parse --verify "$1" >expect.rev &&
+ git rev-parse --verify "$2" >actual.rev &&
+ test_cmp expect.rev actual.rev
+}
+
+# Print a sequence of numbers or letters in increasing order. This is
+# similar to GNU seq(1), but the latter might not be available
+# everywhere (and does not do letters). It may be used like:
+#
+# for i in `test_seq 100`; do
+# for j in `test_seq 10 20`; do
+# for k in `test_seq a z`; do
+# echo $i-$j-$k
+# done
+# done
+# done
+
+test_seq () {
+ case $# in
+ 1) set 1 "$@" ;;
+ 2) ;;
+ *) error "bug in the test script: not 1 or 2 parameters to test_seq" ;;
+ esac
+ "$PERL_PATH" -le 'print for $ARGV[0]..$ARGV[1]' -- "$@"
+}
+
# This function can be used to schedule some commands to be run
# unconditionally at the end of the test to restore sanity:
#
diff --git a/t/test-lib.sh b/t/test-lib.sh
index b7d7100c4e..1a6c4ab08c 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -15,6 +15,38 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/ .
+# Keep the original TERM for say_color
+ORIGINAL_TERM=$TERM
+
+# Test the binaries we have just built. The tests are kept in
+# t/ subdirectory and are run in 'trash directory' subdirectory.
+if test -z "$TEST_DIRECTORY"
+then
+ # We allow tests to override this, in case they want to run tests
+ # outside of t/, e.g. for running tests on the test library
+ # itself.
+ TEST_DIRECTORY=$(pwd)
+fi
+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"/..
+
+################################################################
+# It appears that people try to run tests without building...
+"$GIT_BUILD_DIR/git" >/dev/null
+if test $? != 1
+then
+ echo >&2 'error: you do not seem to have built git yet.'
+ exit 1
+fi
+
+. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+export PERL_PATH SHELL_PATH
+
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
case "$GIT_TEST_TEE_STARTED, $* " in
@@ -24,16 +56,13 @@ done,*)
*' --tee '*|*' --va'*)
mkdir -p test-results
BASE=test-results/$(basename "$0" .sh)
- (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
+ (GIT_TEST_TEE_STARTED=done ${SHELL_PATH} "$0" "$@" 2>&1;
echo $? > $BASE.exit) | tee $BASE.out
test "$(cat $BASE.exit)" = 0
exit
;;
esac
-# Keep the original TERM for say_color
-ORIGINAL_TERM=$TERM
-
# For repeatability, reset the environment to known value.
LANG=C
LC_ALL=C
@@ -46,7 +75,7 @@ EDITOR=:
# /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 COLUMNS $(perl -e '
+unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
my @env = keys %ENV;
my $ok = join("|", qw(
TRACE
@@ -56,11 +85,13 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $(perl -e '
.*_TEST
PROVE
VALGRIND
- PERF_AGGREGATING_LATER
+ UNZIP
+ PERF_
));
my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
print join("\n", @vars);
')
+unset XDG_CONFIG_HOME
GIT_AUTHOR_EMAIL=author@example.com
GIT_AUTHOR_NAME='A U Thor'
GIT_COMMITTER_EMAIL=committer@example.com
@@ -72,19 +103,41 @@ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
export EDITOR
+# Add libc MALLOC and MALLOC_PERTURB test
+# only if we are not executing the test with valgrind
+if expr " $GIT_TEST_OPTS " : ".* --valgrind " >/dev/null ||
+ test -n "$TEST_NO_MALLOC_CHECK"
+then
+ setup_malloc_check () {
+ : nothing
+ }
+ teardown_malloc_check () {
+ : nothing
+ }
+else
+ setup_malloc_check () {
+ MALLOC_CHECK_=3 MALLOC_PERTURB_=165
+ export MALLOC_CHECK_ MALLOC_PERTURB_
+ }
+ teardown_malloc_check () {
+ unset MALLOC_CHECK_ MALLOC_PERTURB_
+ }
+fi
+
# Protect ourselves from common misconfiguration to export
# CDPATH into the environment
unset CDPATH
unset GREP_OPTIONS
+unset UNZIP
case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
- 1|2|true)
- echo "* warning: Some tests will not work if GIT_TRACE" \
- "is set as to trace on STDERR ! *"
- echo "* warning: Please set GIT_TRACE to something" \
- "other than 1, 2 or true ! *"
- ;;
+1|2|true)
+ echo "* warning: Some tests will not work if GIT_TRACE" \
+ "is set as to trace on STDERR ! *"
+ echo "* warning: Please set GIT_TRACE to something" \
+ "other than 1, 2 or true ! *"
+ ;;
esac
# Convenience
@@ -151,17 +204,25 @@ do
esac
done
-if test -n "$color"; then
+if test -n "$color"
+then
say_color () {
(
TERM=$ORIGINAL_TERM
export TERM
case "$1" in
- error) tput bold; tput setaf 1;; # bold red
- skip) tput bold; tput setaf 2;; # bold green
- pass) tput setaf 2;; # green
- info) tput setaf 3;; # brown
- *) test -n "$quiet" && return;;
+ error)
+ tput bold; tput setaf 1;; # bold red
+ skip)
+ tput setaf 4;; # blue
+ warn)
+ tput setaf 3;; # brown/yellow
+ pass)
+ tput setaf 2;; # green
+ info)
+ tput setaf 6;; # cyan
+ *)
+ test -n "$quiet" && return;;
esac
shift
printf "%s" "$*"
@@ -173,7 +234,7 @@ else
say_color() {
test -z "$1" && test -n "$quiet" && return
shift
- echo "$*"
+ printf "%s\n" "$*"
}
fi
@@ -229,7 +290,7 @@ trap 'die' EXIT
# 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
+. "$TEST_DIRECTORY/test-lib-functions.sh"
# You are not expected to call test_ok_ and test_failure_ directly, use
# the text_expect_* functions instead.
@@ -241,7 +302,7 @@ test_ok_ () {
test_failure_ () {
test_failure=$(($test_failure + 1))
- say_color error "not ok - $test_count $1"
+ say_color error "not ok $test_count - $1"
shift
echo "$@" | sed -e 's/^/# /'
test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
@@ -249,12 +310,12 @@ test_failure_ () {
test_known_broken_ok_ () {
test_fixed=$(($test_fixed+1))
- say_color "" "ok $test_count - $@ # TODO known breakage"
+ say_color error "ok $test_count - $@ # TODO known breakage vanished"
}
test_known_broken_failure_ () {
test_broken=$(($test_broken+1))
- say_color skip "not ok $test_count - $@ # TODO known breakage"
+ say_color warn "not ok $test_count - $@ # TODO known breakage"
}
test_debug () {
@@ -275,9 +336,12 @@ test_run_ () {
if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
then
+ setup_malloc_check
test_eval_ "$test_cleanup"
+ teardown_malloc_check
fi
- if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
+ if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"
+ then
echo ""
fi
return "$eval_ret"
@@ -325,10 +389,12 @@ test_at_end_hook_ () {
test_done () {
GIT_EXIT_OK=t
- if test -z "$HARNESS_ACTIVE"; then
+ if test -z "$HARNESS_ACTIVE"
+ then
test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
- test_results_path="$test_results_dir/${0%.sh}-$$.counts"
+ base=${0##*/}
+ test_results_path="$test_results_dir/${base%.sh}-$$.counts"
cat >>"$test_results_path" <<-EOF
total $test_count
@@ -342,22 +408,35 @@ test_done () {
if test "$test_fixed" != 0
then
- say_color pass "# fixed $test_fixed known breakage(s)"
+ say_color error "# $test_fixed known breakage(s) vanished; please update test(s)"
fi
if test "$test_broken" != 0
then
- say_color error "# still have $test_broken known breakage(s)"
- msg="remaining $(($test_count-$test_broken)) test(s)"
+ say_color warn "# still have $test_broken known breakage(s)"
+ fi
+ if test "$test_broken" != 0 || test "$test_fixed" != 0
+ then
+ test_remaining=$(( $test_count - $test_broken - $test_fixed ))
+ msg="remaining $test_remaining test(s)"
else
+ test_remaining=$test_count
msg="$test_count test(s)"
fi
case "$test_failure" in
0)
# Maybe print SKIP message
+ if test -n "$skip_all" && test $test_count -gt 0
+ then
+ error "Can't use skip_all after running some tests"
+ fi
[ -z "$skip_all" ] || skip_all=" # SKIP $skip_all"
- if test $test_external_has_tap -eq 0; then
- say_color pass "# passed all $msg"
+ if test $test_external_has_tap -eq 0
+ then
+ if test $test_remaining -gt 0
+ then
+ say_color pass "# passed all $msg"
+ fi
say "1..$test_count$skip_all"
fi
@@ -370,7 +449,8 @@ test_done () {
exit 0 ;;
*)
- if test $test_external_has_tap -eq 0; then
+ if test $test_external_has_tap -eq 0
+ then
say_color error "# failed $test_failure among $msg"
say "1..$test_count"
fi
@@ -380,23 +460,6 @@ test_done () {
esac
}
-# Test the binaries we have just built. The tests are kept in
-# t/ subdirectory and are run in 'trash directory' subdirectory.
-if test -z "$TEST_DIRECTORY"
-then
- # We allow tests to override this, in case they want to run tests
- # outside of t/, e.g. for running tests on the test library
- # itself.
- TEST_DIRECTORY=$(pwd)
-fi
-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"
then
make_symlink () {
@@ -467,22 +530,26 @@ then
PATH=$GIT_VALGRIND/bin:$PATH
GIT_EXEC_PATH=$GIT_VALGRIND/bin
export GIT_VALGRIND
-elif test -n "$GIT_TEST_INSTALLED" ; then
+elif test -n "$GIT_TEST_INSTALLED"
+then
GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) ||
error "Cannot run git from $GIT_TEST_INSTALLED."
PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH
GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
else # normal case, use ../bin-wrappers only unless $with_dashes:
git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
- if ! test -x "$git_bin_dir/git" ; then
- if test -z "$with_dashes" ; then
+ if ! test -x "$git_bin_dir/git"
+ then
+ if test -z "$with_dashes"
+ then
say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
fi
with_dashes=t
fi
PATH="$git_bin_dir:$PATH"
GIT_EXEC_PATH=$GIT_BUILD_DIR
- if test -n "$with_dashes" ; then
+ if test -n "$with_dashes"
+ then
PATH="$GIT_BUILD_DIR:$PATH"
fi
fi
@@ -492,8 +559,6 @@ GIT_CONFIG_NOSYSTEM=1
GIT_ATTR_NOSYSTEM=1
export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM
-. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
-
if test -z "$GIT_TEST_CMP"
then
if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT"
@@ -519,7 +584,8 @@ then
}
fi
-if ! test -x "$GIT_BUILD_DIR"/test-chmtime; then
+if ! test -x "$GIT_BUILD_DIR"/test-chmtime
+then
echo >&2 'You need to build test-chmtime:'
echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'
exit 1
@@ -542,7 +608,8 @@ rm -fr "$test" || {
HOME="$TRASH_DIRECTORY"
export HOME
-if test -z "$TEST_NO_CREATE_REPO"; then
+if test -z "$TEST_NO_CREATE_REPO"
+then
test_create_repo "$test"
else
mkdir -p "$test"
@@ -557,7 +624,7 @@ for skp in $GIT_SKIP_TESTS
do
case "$this_test" in
$skp)
- say_color skip >&3 "skipping test $this_test altogether"
+ say_color info >&3 "skipping test $this_test altogether"
skip_all="skip all tests in $this_test"
test_done
esac
@@ -615,6 +682,7 @@ case $(uname -s) in
;;
esac
+( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1
test -z "$NO_PERL" && test_set_prereq PERL
test -z "$NO_PYTHON" && test_set_prereq PYTHON
test -n "$USE_LIBPCRE" && test_set_prereq LIBPCRE
@@ -656,9 +724,35 @@ test_i18ngrep () {
fi
}
-# test whether the filesystem supports symbolic links
-ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS
-rm -f y
+test_lazy_prereq SYMLINKS '
+ # test whether the filesystem supports symbolic links
+ ln -s x y && test -h y
+'
+
+test_lazy_prereq CASE_INSENSITIVE_FS '
+ echo good >CamelCase &&
+ echo bad >camelcase &&
+ test "$(cat CamelCase)" != good
+'
+
+test_lazy_prereq UTF8_NFD_TO_NFC '
+ # check whether FS converts nfd unicode to nfc
+ auml=$(printf "\303\244")
+ aumlcdiar=$(printf "\141\314\210")
+ >"$auml" &&
+ case "$(echo *)" in
+ "$aumlcdiar")
+ true ;;
+ *)
+ false ;;
+ esac
+'
+
+test_lazy_prereq AUTOIDENT '
+ sane_unset GIT_AUTHOR_NAME &&
+ sane_unset GIT_AUTHOR_EMAIL &&
+ git var GIT_AUTHOR_IDENT
+'
# When the tests are run as root, permission tests will report that
# things are writable when they shouldn't be.
diff --git a/t/test-terminal.perl b/t/test-terminal.perl
index 10172aee18..1fb373f25b 100755
--- a/t/test-terminal.perl
+++ b/t/test-terminal.perl
@@ -31,7 +31,7 @@ sub finish_child {
} elsif ($? & 127) {
my $code = $? & 127;
warn "died of signal $code";
- return $code - 128;
+ return $code + 128;
} else {
return $? >> 8;
}