summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/Makefile7
-rw-r--r--t/README36
-rw-r--r--t/annotate-tests.sh5
-rw-r--r--t/lib-cvs.sh75
-rw-r--r--t/lib-git-svn.sh29
-rw-r--r--t/lib-httpd.sh44
-rw-r--r--t/lib-httpd/apache.conf4
-rw-r--r--t/lib-rebase.sh48
-rwxr-xr-xt/t0000-basic.sh66
-rwxr-xr-xt/t0001-init.sh83
-rwxr-xr-xt/t0004-unwritable.sh8
-rwxr-xr-xt/t0005-signals.sh22
-rwxr-xr-xt/t0020-crlf.sh31
-rwxr-xr-xt/t0024-crlf-archive.sh8
-rwxr-xr-xt/t0040-parse-options.sh75
-rwxr-xr-xt/t0050-filesystem.sh37
-rwxr-xr-xt/t0055-beyond-symlinks.sh6
-rwxr-xr-xt/t0060-path-utils.sh120
-rwxr-xr-xt/t0070-fundamental.sh15
-rwxr-xr-xt/t0100-previous.sh49
-rwxr-xr-xt/t1004-read-tree-m-u-wf.sh6
-rwxr-xr-xt/t1008-read-tree-overlay.sh31
-rwxr-xr-xt/t1010-mktree.sh71
-rwxr-xr-xt/t1020-subdirectory.sh2
-rwxr-xr-xt/t1100-commit-tree-options.sh2
-rwxr-xr-xt/t1300-repo-config.sh48
-rwxr-xr-xt/t1301-shared-repo.sh51
-rwxr-xr-xt/t1400-update-ref.sh6
-rwxr-xr-xt/t1401-symbolic-ref.sh36
-rwxr-xr-xt/t1410-reflog.sh4
-rwxr-xr-xt/t1411-reflog-show.sh67
-rwxr-xr-xt/t1450-fsck.sh98
-rwxr-xr-xt/t1500-rev-parse.sh17
-rwxr-xr-xt/t1501-worktree.sh7
-rwxr-xr-xt/t1502-rev-parse-parseopt.sh43
-rwxr-xr-xt/t1504-ceiling-dirs.sh2
-rwxr-xr-xt/t1505-rev-parse-last.sh69
-rwxr-xr-xt/t2001-checkout-cache-clash.sh6
-rwxr-xr-xt/t2003-checkout-cache-mkdir.sh8
-rwxr-xr-xt/t2004-checkout-cache-temp.sh2
-rwxr-xr-xt/t2007-checkout-symlink.sh6
-rwxr-xr-xt/t2012-checkout-last.sh94
-rwxr-xr-xt/t2013-checkout-submodule.sh42
-rwxr-xr-xt/t2014-switch.sh28
-rwxr-xr-xt/t2100-update-cache-badpath.sh14
-rwxr-xr-xt/t2200-add-update.sh4
-rwxr-xr-xt/t2201-add-update-typechange.sh16
-rwxr-xr-xt/t2300-cd-to-toplevel.sh18
-rwxr-xr-xt/t3000-ls-files-others.sh25
-rwxr-xr-xt/t3010-ls-files-killed-modified.sh21
-rwxr-xr-xt/t3030-merge-recursive.sh3
-rwxr-xr-xt/t3031-merge-criscross.sh95
-rwxr-xr-xt/t3100-ls-tree-restrict.sh40
-rwxr-xr-xt/t3200-branch.sh2
-rwxr-xr-xt/t3203-branch-output.sh81
-rwxr-xr-xt/t3400-rebase.sh55
-rwxr-xr-xt/t3404-rebase-interactive.sh52
-rwxr-xr-xt/t3406-rebase-message.sh23
-rwxr-xr-xt/t3410-rebase-preserve-dropped-merges.sh124
-rwxr-xr-xt/t3411-rebase-preserve-around-merges.sh103
-rwxr-xr-xt/t3412-rebase-root.sh280
-rwxr-xr-xt/t3413-rebase-hook.sh (renamed from t/t3409-rebase-hook.sh)6
-rwxr-xr-xt/t3414-rebase-preserve-onto.sh80
-rwxr-xr-xt/t3505-cherry-pick-empty.sh10
-rwxr-xr-xt/t3600-rm.sh57
-rwxr-xr-xt/t3700-add.sh41
-rwxr-xr-xt/t3701-add-interactive.sh52
-rwxr-xr-xt/t3702-add-edit.sh121
-rwxr-xr-xt/t3900-i18n-commit.sh46
-rw-r--r--t/t3900/ISO8859-1.txt (renamed from t/t3900/ISO-8859-1.txt)0
-rw-r--r--t/t3900/eucJP.txt (renamed from t/t3900/EUCJP.txt)0
-rwxr-xr-xt/t3901-i18n-patch.sh40
-rwxr-xr-xt/t3903-stash.sh23
-rwxr-xr-xt/t4002-diff-basic.sh8
-rwxr-xr-xt/t4004-diff-rename-symlink.sh6
-rwxr-xr-xt/t4006-diff-mode.sh19
-rwxr-xr-xt/t4007-rename-3.sh74
-rwxr-xr-xt/t4008-diff-break-rewrite.sh8
-rwxr-xr-xt/t4011-diff-symlink.sh13
-rwxr-xr-xt/t4012-diff-binary.sh2
-rwxr-xr-xt/t4013-diff-various.sh11
-rw-r--r--t/t4013/diff.diff_--dirstat_master~1_master~23
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side61
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..master12
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..master^8
-rw-r--r--t/t4013/diff.format-patch_--attach_--stdout_initial..side4
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master170
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master12
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master12
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master^8
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master^^4
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..side4
-rw-r--r--t/t4013/diff.log_--decorate_--all34
-rw-r--r--t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_2
-rw-r--r--t/t4013/diff.log_--patch-with-stat_master2
-rw-r--r--t/t4013/diff.log_--patch-with-stat_master_--_dir_2
-rw-r--r--t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master2
-rw-r--r--t/t4013/diff.log_--root_--patch-with-stat_--summary_master2
-rw-r--r--t/t4013/diff.log_--root_--patch-with-stat_master2
-rw-r--r--t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master2
-rw-r--r--t/t4013/diff.log_--root_-p_master2
-rw-r--r--t/t4013/diff.log_--root_master2
-rw-r--r--t/t4013/diff.log_-p_master2
-rw-r--r--t/t4013/diff.log_master2
-rw-r--r--t/t4013/diff.rev-list_--children_HEAD7
-rw-r--r--t/t4013/diff.rev-list_--parents_HEAD7
-rw-r--r--t/t4013/diff.show_master2
-rw-r--r--t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master2
-rw-r--r--t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master2
-rwxr-xr-xt/t4014-format-patch.sh296
-rwxr-xr-xt/t4018-diff-funcname.sh2
-rwxr-xr-xt/t4020-diff-external.sh35
-rwxr-xr-xt/t4021-format-patch-numbered.sh13
-rwxr-xr-xt/t4023-diff-rename-typechange.sh6
-rwxr-xr-xt/t4029-diff-trailing-space.sh2
-rwxr-xr-xt/t4032-diff-inter-hunk-context.sh92
-rwxr-xr-xt/t4033-diff-patience.sh168
-rwxr-xr-xt/t4034-diff-words.sh200
-rwxr-xr-xt/t4035-diff-quiet.sh (renamed from t/t4017-quiet.sh)0
-rwxr-xr-xt/t4036-format-patch-signer-mime.sh (renamed from t/t4021-format-patch-signer-mime.sh)0
-rwxr-xr-xt/t4037-diff-r-t-dirs.sh53
-rwxr-xr-xt/t4038-diff-combined.sh84
-rwxr-xr-xt/t4102-apply-rename.sh8
-rwxr-xr-xt/t4106-apply-stdin.sh26
-rwxr-xr-xt/t4114-apply-typechange.sh6
-rwxr-xr-xt/t4115-apply-symlink.sh6
-rwxr-xr-xt/t4118-apply-empty-context.sh4
-rwxr-xr-xt/t4122-apply-symlink-inside.sh6
-rwxr-xr-xt/t4124-apply-ws-rule.sh22
-rwxr-xr-xt/t4129-apply-samemode.sh19
-rwxr-xr-xt/t4130-apply-criss-cross-rename.sh66
-rwxr-xr-xt/t4131-apply-fake-ancestor.sh42
-rwxr-xr-xt/t4132-apply-removal.sh95
-rwxr-xr-xt/t4150-am.sh89
-rwxr-xr-xt/t4200-rerere.sh4
-rwxr-xr-xt/t4202-log.sh291
-rwxr-xr-xt/t4203-mailmap.sh215
-rwxr-xr-xt/t4204-patch-id.sh38
-rwxr-xr-xt/t4252-am-options.sh27
-rw-r--r--t/t4252/am-test-5-120
-rw-r--r--t/t4252/am-test-5-215
-rw-r--r--t/t4252/am-test-6-121
-rwxr-xr-xt/t5000-tar-tree.sh67
-rwxr-xr-xt/t5001-archive-attr.sh91
-rw-r--r--t/t5100/info00012
-rw-r--r--t/t5100/rfc2047-info-00042
-rw-r--r--t/t5100/rfc2047-samples.mbox32
-rw-r--r--t/t5100/sample.mbox12
-rwxr-xr-xt/t5300-pack-object.sh17
-rwxr-xr-xt/t5302-pack-index.sh18
-rwxr-xr-xt/t5303-pack-corruption-resilience.sh12
-rwxr-xr-xt/t5304-prune.sh38
-rwxr-xr-xt/t5400-send-pack.sh193
-rwxr-xr-xt/t5403-post-checkout-hook.sh14
-rwxr-xr-xt/t5500-fetch-pack.sh276
-rwxr-xr-xt/t5502-quickfetch.sh20
-rwxr-xr-xt/t5503-tagfollow.sh6
-rwxr-xr-xt/t5505-remote.sh159
-rwxr-xr-xt/t5506-remote-groups.sh81
-rwxr-xr-xt/t5510-fetch.sh50
-rwxr-xr-xt/t5511-refspec.sh12
-rwxr-xr-xt/t5515-fetch-merge-logic.sh3
-rwxr-xr-xt/t5516-fetch-push.sh19
-rwxr-xr-xt/t5520-pull.sh27
-rwxr-xr-xt/t5522-pull-symlink.sh (renamed from t/t5521-pull-symlink.sh)6
-rwxr-xr-xt/t5530-upload-pack-error.sh17
-rwxr-xr-xt/t5540-http-push.sh58
-rwxr-xr-xt/t5550-http-fetch.sh65
-rwxr-xr-xt/t5601-clone.sh49
-rwxr-xr-xt/t5602-clone-remote-exec.sh4
-rwxr-xr-xt/t5701-clone-local.sh26
-rwxr-xr-xt/t5704-bundle.sh33
-rwxr-xr-xt/t5705-clone-2gb.sh45
-rwxr-xr-xt/t6006-rev-list-format.sh9
-rwxr-xr-xt/t6010-merge-base.sh18
-rwxr-xr-xt/t6020-merge-df.sh23
-rwxr-xr-xt/t6023-merge-file.sh6
-rwxr-xr-xt/t6024-recursive-merge.sh9
-rwxr-xr-xt/t6030-bisect-porcelain.sh85
-rwxr-xr-xt/t6031-merge-recursive.sh20
-rwxr-xr-xt/t6034-merge-rename-nocruft.sh (renamed from t/t6023-merge-rename-nocruft.sh)0
-rwxr-xr-xt/t6035-merge-dir-to-symlink.sh93
-rwxr-xr-xt/t6040-tracking-info.sh24
-rwxr-xr-xt/t6200-fmt-merge-msg.sh36
-rwxr-xr-xt/t6300-for-each-ref.sh40
-rwxr-xr-xt/t7001-mv.sh4
-rwxr-xr-xt/t7002-grep.sh157
-rwxr-xr-xt/t7003-filter-branch.sh24
-rwxr-xr-xt/t7004-tag.sh219
-rwxr-xr-xt/t7005-editor.sh29
-rwxr-xr-xt/t7201-co.sh10
-rwxr-xr-xt/t7300-clean.sh6
-rwxr-xr-xt/t7400-submodule-basic.sh72
-rwxr-xr-xt/t7405-submodule-merge.sh74
-rwxr-xr-xt/t7406-submodule-reference.sh81
-rwxr-xr-xt/t7406-submodule-update.sh198
-rwxr-xr-xt/t7500-commit.sh15
-rwxr-xr-xt/t7501-commit.sh24
-rwxr-xr-xt/t7502-commit.sh2
-rwxr-xr-xt/t7503-pre-commit-hook.sh4
-rwxr-xr-xt/t7504-commit-msg-hook.sh8
-rwxr-xr-xt/t7508-status.sh (renamed from t/t7502-status.sh)0
-rwxr-xr-xt/t7610-mergetool.sh75
-rwxr-xr-xt/t7700-repack.sh31
-rwxr-xr-xt/t7701-repack-unpack-unreachable.sh14
-rwxr-xr-xt/t7800-difftool.sh216
-rwxr-xr-xt/t8003-blame.sh15
-rwxr-xr-xt/t8005-blame-i18n.sh40
-rw-r--r--t/t8005/cp1251.txt2
-rw-r--r--t/t8005/euc-japan.txt2
-rw-r--r--t/t8005/iso8859-5.txt2
-rw-r--r--t/t8005/sjis.txt4
-rw-r--r--t/t8005/utf8.txt4
-rwxr-xr-xt/t9001-send-email.sh490
-rwxr-xr-xt/t9100-git-svn-basic.sh70
-rwxr-xr-xt/t9101-git-svn-props.sh41
-rwxr-xr-xt/t9102-git-svn-deep-rmdir.sh4
-rwxr-xr-xt/t9103-git-svn-tracked-directory-removed.sh8
-rwxr-xr-xt/t9104-git-svn-follow-parent.sh40
-rwxr-xr-xt/t9105-git-svn-commit-diff.sh8
-rwxr-xr-xt/t9106-git-svn-commit-diff-clobber.sh14
-rwxr-xr-xt/t9107-git-svn-migrate.sh16
-rwxr-xr-xt/t9108-git-svn-glob.sh26
-rwxr-xr-xt/t9109-git-svn-multi-glob.sh (renamed from t/t9108-git-svn-multi-glob.sh)44
-rwxr-xr-xt/t9113-git-svn-dcommit-new-file.sh2
-rwxr-xr-xt/t9114-git-svn-dcommit-merge.sh6
-rwxr-xr-xt/t9116-git-svn-log.sh2
-rwxr-xr-xt/t9117-git-svn-init-clone.sh2
-rwxr-xr-xt/t9118-git-svn-funky-branch-names.sh8
-rwxr-xr-xt/t9119-git-svn-info.sh30
-rwxr-xr-xt/t9120-git-svn-clone-with-percent-escapes.sh19
-rwxr-xr-xt/t9122-git-svn-author.sh12
-rwxr-xr-xt/t9123-git-svn-rebuild-with-rewriteroot.sh2
-rwxr-xr-xt/t9124-git-svn-dcommit-auto-props.sh30
-rwxr-xr-xt/t9125-git-svn-multi-glob-branch-names.sh6
-rwxr-xr-xt/t9127-git-svn-partial-rebuild.sh14
-rwxr-xr-xt/t9128-git-svn-cmd-branch.sh18
-rwxr-xr-xt/t9129-git-svn-i18n-commitencoding.sh45
-rwxr-xr-xt/t9130-git-svn-authors-file.sh94
-rwxr-xr-xt/t9131-git-svn-empty-symlink.sh110
-rwxr-xr-xt/t9132-git-svn-broken-symlink.sh102
-rwxr-xr-xt/t9133-git-svn-nested-git-repo.sh101
-rwxr-xr-xt/t9134-git-svn-ignore-paths.sh147
-rwxr-xr-xt/t9135-git-svn-moved-branch-empty-file.sh16
-rw-r--r--t/t9135/svn.dump192
-rwxr-xr-xt/t9136-git-svn-recreated-branch-empty-file.sh12
-rw-r--r--t/t9136/svn.dump192
-rwxr-xr-xt/t9137-git-svn-dcommit-clobber-series.sh (renamed from t/t9106-git-svn-dcommit-clobber-series.sh)8
-rwxr-xr-xt/t9138-git-svn-authors-prog.sh69
-rwxr-xr-xt/t9139-git-svn-non-utf8-commitencoding.sh47
-rwxr-xr-xt/t9140-git-svn-reset.sh66
-rwxr-xr-xt/t9141-git-svn-multiple-branches.sh122
-rwxr-xr-xt/t9142-git-svn-shallow-clone.sh32
-rwxr-xr-xt/t9143-git-svn-gc.sh53
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh44
-rwxr-xr-xt/t9301-fast-export.sh118
-rwxr-xr-xt/t9400-git-cvsserver-server.sh14
-rwxr-xr-xt/t9401-git-cvsserver-crlf.sh13
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh65
-rwxr-xr-xt/t9600-cvsimport.sh50
-rwxr-xr-xt/t9601-cvsimport-vendor-branch.sh86
-rw-r--r--t/t9601/cvsroot/.gitattributes1
-rw-r--r--t/t9601/cvsroot/CVSROOT/.gitignore2
-rw-r--r--t/t9601/cvsroot/module/added-imported.txt,v44
-rw-r--r--t/t9601/cvsroot/module/imported-anonymously.txt,v42
-rw-r--r--t/t9601/cvsroot/module/imported-modified-imported.txt,v76
-rw-r--r--t/t9601/cvsroot/module/imported-modified.txt,v59
-rw-r--r--t/t9601/cvsroot/module/imported-once.txt,v43
-rw-r--r--t/t9601/cvsroot/module/imported-twice.txt,v60
-rwxr-xr-xt/t9602-cvsimport-branches-tags.sh79
-rw-r--r--t/t9602/README62
-rw-r--r--t/t9602/cvsroot/.gitattributes1
-rw-r--r--t/t9602/cvsroot/CVSROOT/.gitignore2
-rw-r--r--t/t9602/cvsroot/module/default,v102
-rw-r--r--t/t9602/cvsroot/module/sub1/default,v102
-rw-r--r--t/t9602/cvsroot/module/sub1/subsubA/default,v101
-rw-r--r--t/t9602/cvsroot/module/sub1/subsubB/default,v107
-rw-r--r--t/t9602/cvsroot/module/sub2/Attic/branch_B_MIXED_only,v59
-rw-r--r--t/t9602/cvsroot/module/sub2/default,v102
-rw-r--r--t/t9602/cvsroot/module/sub2/subsubA/default,v102
-rw-r--r--t/t9602/cvsroot/module/sub3/default,v102
-rwxr-xr-xt/t9603-cvsimport-patchsets.sh40
-rw-r--r--t/t9603/cvsroot/.gitattributes1
-rw-r--r--t/t9603/cvsroot/CVSROOT/.gitignore2
-rw-r--r--t/t9603/cvsroot/module/a,v74
-rw-r--r--t/t9603/cvsroot/module/b,v90
-rwxr-xr-xt/t9700-perl-git.sh11
-rwxr-xr-xt/t9700/test.pl23
-rw-r--r--t/test-lib.sh267
-rw-r--r--t/valgrind/.gitignore2
-rwxr-xr-xt/valgrind/analyze.sh123
-rw-r--r--t/valgrind/default.supp45
-rwxr-xr-xt/valgrind/valgrind.sh22
293 files changed, 11687 insertions, 1552 deletions
diff --git a/t/Makefile b/t/Makefile
index 9149373032..bd09390d32 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -3,6 +3,8 @@
# Copyright (c) 2005 Junio C Hamano
#
+-include ../config.mak
+
#GIT_TEST_OPTS=--verbose --debug
SHELL_PATH ?= $(SHELL)
TAR ?= $(TAR)
@@ -38,4 +40,7 @@ full-svn-test:
$(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
$(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=0 LC_ALL=en_US.UTF-8
-.PHONY: pre-clean $(T) aggregate-results clean
+valgrind:
+ GIT_TEST_OPTS=--valgrind $(MAKE)
+
+.PHONY: pre-clean $(T) aggregate-results clean valgrind
diff --git a/t/README b/t/README
index 8f12d48fe8..d8f6c7de6d 100644
--- a/t/README
+++ b/t/README
@@ -39,7 +39,8 @@ this:
* passed all 3 test(s)
You can pass --verbose (or -v), --debug (or -d), and --immediate
-(or -i) command line argument to the test.
+(or -i) command line argument to the test, or by setting GIT_TEST_OPTS
+appropriately before running "make".
--verbose::
This makes the test more verbose. Specifically, the
@@ -58,6 +59,21 @@ You can pass --verbose (or -v), --debug (or -d), and --immediate
This causes additional long-running tests to be run (where
available), for more exhaustive testing.
+--valgrind::
+ Execute all Git binaries with valgrind and exit with status
+ 126 on errors (just like regular tests, this will only stop
+ the test script when running under -i). Valgrind errors
+ go to stderr, so you might want to pass the -v option, too.
+
+ Since it makes no sense to run the tests with --valgrind and
+ not see any output, this option implies --verbose. For
+ convenience, it also implies --tee.
+
+--tee::
+ In addition to printing the test output to the terminal,
+ write it to files named 't/test-results/$TEST_NAME.out'.
+ As the names depend on the tests' file names, it is safe to
+ run the tests with this option in parallel.
Skipping Tests
--------------
@@ -212,6 +228,24 @@ library for your script to use.
is to summarize successes and failures in the test script and
exit with an appropriate error code.
+ - test_tick
+
+ Make commit and tag names consistent by setting the author and
+ committer times to defined stated. Subsequent calls will
+ advance the times by a fixed amount.
+
+ - test_commit <message> [<filename> [<contents>]]
+
+ Creates a commit with the given message, committing the given
+ file with the given contents (default for both is to reuse the
+ message string), and adds a tag (again reusing the message
+ string as name). Calls test_tick to make the SHA-1s
+ reproducible.
+
+ - test_merge <message> <commit-or-tag>
+
+ Merges the given rev using the given message. Like test_commit,
+ creates a tag and calls test_tick before committing.
Tips for Writing Tests
----------------------
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
index cacb273aff..396b9653a3 100644
--- a/t/annotate-tests.sh
+++ b/t/annotate-tests.sh
@@ -114,7 +114,10 @@ test_expect_success \
test_expect_success \
'some edit' \
'mv file file.orig &&
- sed -e "s/^3A/99/" -e "/^1A/d" -e "/^incomplete/d" < file.orig > file &&
+ {
+ cat file.orig &&
+ echo
+ } | sed -e "s/^3A/99/" -e "/^1A/d" -e "/^incomplete/d" > file &&
echo "incomplete" | tr -d "\\012" >>file &&
GIT_AUTHOR_NAME="D" git commit -a -m "edit"'
diff --git a/t/lib-cvs.sh b/t/lib-cvs.sh
new file mode 100644
index 0000000000..4b3b793730
--- /dev/null
+++ b/t/lib-cvs.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+. ./test-lib.sh
+
+unset CVS_SERVER
+# for clean cvsps cache
+HOME=$(pwd)
+export HOME
+
+if ! type cvs >/dev/null 2>&1
+then
+ say 'skipping cvsimport tests, cvs not found'
+ test_done
+fi
+
+CVS="cvs -f"
+export CVS
+
+cvsps_version=`cvsps -h 2>&1 | sed -ne 's/cvsps version //p'`
+case "$cvsps_version" in
+2.1 | 2.2*)
+ ;;
+'')
+ say 'skipping cvsimport tests, cvsps not found'
+ test_done
+ ;;
+*)
+ say 'skipping cvsimport tests, unsupported cvsps version'
+ test_done
+ ;;
+esac
+
+test_cvs_co () {
+ # Usage: test_cvs_co BRANCH_NAME
+ rm -rf module-cvs-"$1"
+ if [ "$1" = "master" ]
+ then
+ $CVS co -P -d module-cvs-"$1" -A module
+ else
+ $CVS co -P -d module-cvs-"$1" -r "$1" module
+ fi
+}
+
+test_git_co () {
+ # Usage: test_git_co BRANCH_NAME
+ (cd module-git && git checkout "$1")
+}
+
+test_cmp_branch_file () {
+ # Usage: test_cmp_branch_file BRANCH_NAME PATH
+ # The branch must already be checked out of CVS and git.
+ test_cmp module-cvs-"$1"/"$2" module-git/"$2"
+}
+
+test_cmp_branch_tree () {
+ # Usage: test_cmp_branch_tree BRANCH_NAME
+ # Check BRANCH_NAME out of CVS and git and make sure that all
+ # of the files and directories are identical.
+
+ test_cvs_co "$1" &&
+ test_git_co "$1" &&
+ (
+ cd module-cvs-"$1"
+ find . -type d -name CVS -prune -o -type f -print
+ ) | sort >module-cvs-"$1".list &&
+ (
+ cd module-git
+ find . -type d -name .git -prune -o -type f -print
+ ) | sort >module-git-"$1".list &&
+ test_cmp module-cvs-"$1".list module-git-"$1".list &&
+ cat module-cvs-"$1".list | while read f
+ do
+ test_cmp_branch_file "$1" "$f" || return 1
+ done
+}
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 67c431d4eb..5654962343 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -5,9 +5,12 @@ git_svn_id=git""-svn-id
if test -n "$NO_SVN_TESTS"
then
- test_expect_success 'skipping git svn tests, NO_SVN_TESTS defined' :
+ say 'skipping git svn tests, NO_SVN_TESTS defined'
+ test_done
+fi
+if ! test_have_prereq PERL; then
+ say 'skipping git svn tests, perl not available'
test_done
- exit
fi
GIT_DIR=$PWD/.git
@@ -17,13 +20,14 @@ SVN_TREE=$GIT_SVN_DIR/svn-tree
svn >/dev/null 2>&1
if test $? -ne 1
then
- test_expect_success 'skipping git svn tests, svn not found' :
+ say 'skipping git svn tests, svn not found'
test_done
- exit
fi
svnrepo=$PWD/svnrepo
export svnrepo
+svnconf=$PWD/svnconf
+export svnconf
perl -w -e "
use SVN::Core;
@@ -41,9 +45,8 @@ then
else
err='Perl SVN libraries not found or unusable, skipping test'
fi
- test_expect_success "$err" :
+ say "$err"
test_done
- exit
fi
rawsvnrepo="$svnrepo"
@@ -53,6 +56,19 @@ poke() {
test-chmtime +1 "$1"
}
+# We need this, because we should pass empty configuration directory to
+# the 'svn commit' to avoid automated property changes and other stuff
+# that could be set from user's configuration files in ~/.subversion.
+svn_cmd () {
+ [ -d "$svnconf" ] || mkdir "$svnconf"
+ orig_svncmd="$1"; shift
+ if [ -z "$orig_svncmd" ]; then
+ svn
+ return
+ fi
+ svn "$orig_svncmd" --config-dir "$svnconf" "$@"
+}
+
for d in \
"$SVN_HTTPD_PATH" \
/usr/sbin/apache2 \
@@ -144,7 +160,6 @@ require_svnserve () {
then
say 'skipping svnserve test. (set $SVNSERVE_PORT to enable)'
test_done
- exit
fi
}
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 6ac312b905..6765b08065 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -8,10 +8,23 @@ then
say "skipping test, network testing disabled by default"
say "(define GIT_TEST_HTTPD to enable)"
test_done
- exit
fi
-LIB_HTTPD_PATH=${LIB_HTTPD_PATH-'/usr/sbin/apache2'}
+HTTPD_PARA=""
+
+case $(uname) in
+ Darwin)
+ DEFAULT_HTTPD_PATH='/usr/sbin/httpd'
+ DEFAULT_HTTPD_MODULE_PATH='/usr/libexec/apache2'
+ HTTPD_PARA="$HTTPD_PARA -DDarwin"
+ ;;
+ *)
+ DEFAULT_HTTPD_PATH='/usr/sbin/apache2'
+ DEFAULT_HTTPD_MODULE_PATH='/usr/lib/apache2/modules'
+ ;;
+esac
+
+LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"}
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'8111'}
TEST_PATH="$TEST_DIRECTORY"/lib-httpd
@@ -20,9 +33,8 @@ HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www
if ! test -x "$LIB_HTTPD_PATH"
then
- say "skipping test, no web server found at '$LIB_HTTPD_PATH'"
- test_done
- exit
+ say "skipping test, no web server found at '$LIB_HTTPD_PATH'"
+ test_done
fi
HTTPD_VERSION=`$LIB_HTTPD_PATH -v | \
@@ -36,17 +48,14 @@ then
then
say "skipping test, at least Apache version 2 is required"
test_done
- exit
fi
- LIB_HTTPD_MODULE_PATH='/usr/lib/apache2/modules'
+ LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH"
fi
else
error "Could not identify web server at '$LIB_HTTPD_PATH'"
fi
-HTTPD_PARA=""
-
prepare_httpd() {
mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH"
@@ -82,18 +91,25 @@ prepare_httpd() {
}
start_httpd() {
- prepare_httpd
+ prepare_httpd >&3 2>&4
- trap 'stop_httpd; die' exit
+ trap 'code=$?; stop_httpd; (exit $code); die' EXIT
"$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
-f "$TEST_PATH/apache.conf" $HTTPD_PARA \
- -c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start
+ -c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start \
+ >&3 2>&4
+ if test $? -ne 0
+ then
+ say "skipping test, web server setup failed"
+ trap 'die' EXIT
+ test_done
+ fi
}
stop_httpd() {
- trap 'die' exit
+ trap 'die' EXIT
"$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
- -f "$TEST_PATH/apache.conf" -k stop
+ -f "$TEST_PATH/apache.conf" $HTTPD_PARA -k stop
}
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index fdb19a50f1..21aa42f1c6 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -1,9 +1,13 @@
ServerName dummy
+LockFile accept.lock
PidFile httpd.pid
DocumentRoot www
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog access.log common
ErrorLog error.log
+<IfModule !mod_log_config.c>
+ LoadModule log_config_module modules/mod_log_config.so
+</IfModule>
<IfDefine SSL>
LoadModule ssl_module modules/mod_ssl.so
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
new file mode 100644
index 0000000000..260a231933
--- /dev/null
+++ b/t/lib-rebase.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# After setting the fake editor with this function, you can
+#
+# - override the commit message with $FAKE_COMMIT_MESSAGE,
+# - amend the commit message with $FAKE_COMMIT_AMEND
+# - check that non-commit messages have a certain line count with $EXPECT_COUNT
+# - rewrite a rebase -i script with $FAKE_LINES in the form
+#
+# "[<lineno1>] [<lineno2>]..."
+#
+# If a line number is prefixed with "squash" or "edit", the respective line's
+# command will be replaced with the specified one.
+
+set_fake_editor () {
+ echo "#!$SHELL_PATH" >fake-editor.sh
+ cat >> fake-editor.sh <<\EOF
+case "$1" in
+*/COMMIT_EDITMSG)
+ test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1"
+ test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1"
+ exit
+ ;;
+esac
+test -z "$EXPECT_COUNT" ||
+ test "$EXPECT_COUNT" = $(sed -e '/^#/d' -e '/^$/d' < "$1" | wc -l) ||
+ exit
+test -z "$FAKE_LINES" && exit
+grep -v '^#' < "$1" > "$1".tmp
+rm -f "$1"
+cat "$1".tmp
+action=pick
+for line in $FAKE_LINES; do
+ case $line in
+ squash|edit)
+ action="$line";;
+ *)
+ echo sed -n "${line}s/^pick/$action/p"
+ sed -n "${line}p" < "$1".tmp
+ sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
+ action=pick;;
+ esac
+done
+EOF
+
+ test_set_editor "$(pwd)/fake-editor.sh"
+ chmod a+x fake-editor.sh
+}
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 70df15cbd8..f4ca4fc85c 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -57,6 +57,21 @@ test_expect_failure 'pretend we have a known breakage' '
test_expect_failure 'pretend we have fixed a known breakage' '
:
'
+test_set_prereq HAVEIT
+haveit=no
+test_expect_success HAVEIT 'test runs if prerequisite is satisfied' '
+ test_have_prereq HAVEIT &&
+ haveit=yes
+'
+donthaveit=yes
+test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' '
+ donthaveit=no
+'
+if test $haveit$donthaveit != yesyes
+then
+ say "bug in test framework: prerequisite tags do not work reliably"
+ exit 1
+fi
################################################################
# Basics of the basics
@@ -100,12 +115,31 @@ test_expect_success \
'test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904'
# Various types of objects
+# Some filesystems do not support symblic links; on such systems
+# some expected values are different
mkdir path2 path3 path3/subp3
-for p in path0 path2/file2 path3/file3 path3/subp3/file3
+paths='path0 path2/file2 path3/file3 path3/subp3/file3'
+for p in $paths
do
echo "hello $p" >$p
- ln -s "hello $p" ${p}sym
done
+if test_have_prereq SYMLINKS
+then
+ for p in $paths
+ do
+ ln -s "hello $p" ${p}sym
+ done
+ expectfilter=cat
+ expectedtree=087704a96baf1c2d1c869a8b084481e121c88b5b
+ expectedptree1=21ae8269cacbe57ae09138dcc3a2887f904d02b3
+ expectedptree2=3c5e5399f3a333eddecce7a9b9465b63f65f51e2
+else
+ expectfilter='grep -v sym'
+ expectedtree=8e18edf7d7edcf4371a3ac6ae5f07c2641db7c46
+ expectedptree1=cfb8591b2f65de8b8cc1020cd7d9e67e7793b325
+ expectedptree2=ce580448f0148b985a513b693fdf7d802cacb44f
+fi
+
test_expect_success \
'adding various types of objects with git update-index --add.' \
'find path* ! -type d -print | xargs git update-index --add'
@@ -115,7 +149,7 @@ test_expect_success \
'showing stage with git ls-files --stage' \
'git ls-files --stage >current'
-cat >expected <<\EOF
+$expectfilter >expected <<\EOF
100644 f87290f8eb2cbbea7857214459a0739927eab154 0 path0
120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0 path0sym
100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0 path2/file2
@@ -127,14 +161,14 @@ cat >expected <<\EOF
EOF
test_expect_success \
'validate git ls-files output for a known tree.' \
- 'diff current expected'
+ 'test_cmp expected current'
test_expect_success \
'writing tree out with git write-tree.' \
'tree=$(git write-tree)'
test_expect_success \
'validate object ID for a known tree.' \
- 'test "$tree" = 087704a96baf1c2d1c869a8b084481e121c88b5b'
+ 'test "$tree" = "$expectedtree"'
test_expect_success \
'showing tree with git ls-tree' \
@@ -145,16 +179,16 @@ cat >expected <<\EOF
040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2
040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3
EOF
-test_expect_success \
+test_expect_success SYMLINKS \
'git ls-tree output for a known tree.' \
- 'diff current expected'
+ 'test_cmp expected current'
# This changed in ls-tree pathspec change -- recursive does
# not show tree nodes anymore.
test_expect_success \
'showing tree with git ls-tree -r' \
'git ls-tree -r $tree >current'
-cat >expected <<\EOF
+$expectfilter >expected <<\EOF
100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2
@@ -166,7 +200,7 @@ cat >expected <<\EOF
EOF
test_expect_success \
'git ls-tree -r output for a known tree.' \
- 'diff current expected'
+ 'test_cmp expected current'
# But with -r -t we can have both.
test_expect_success \
@@ -185,23 +219,23 @@ cat >expected <<\EOF
100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3
120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym
EOF
-test_expect_success \
+test_expect_success SYMLINKS \
'git ls-tree -r output for a known tree.' \
- 'diff current expected'
+ 'test_cmp expected current'
test_expect_success \
'writing partial tree out with git write-tree --prefix.' \
'ptree=$(git write-tree --prefix=path3)'
test_expect_success \
'validate object ID for a known tree.' \
- 'test "$ptree" = 21ae8269cacbe57ae09138dcc3a2887f904d02b3'
+ 'test "$ptree" = "$expectedptree1"'
test_expect_success \
'writing partial tree out with git write-tree --prefix.' \
'ptree=$(git write-tree --prefix=path3/subp3)'
test_expect_success \
'validate object ID for a known tree.' \
- 'test "$ptree" = 3c5e5399f3a333eddecce7a9b9465b63f65f51e2'
+ 'test "$ptree" = "$expectedptree2"'
cat >badobjects <<EOF
100644 blob 1000000000000000000000000000000000000000 dir/file1
@@ -234,7 +268,7 @@ test_expect_success \
newtree=$(git write-tree) &&
test "$newtree" = "$tree"'
-cat >expected <<\EOF
+$expectfilter >expected <<\EOF
:100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M path0
:120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M path0sym
:100644 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0000000000000000000000000000000000000000 M path2/file2
@@ -257,7 +291,7 @@ test_expect_success \
'git diff-files >current && cmp -s current /dev/null'
################################################################
-P=087704a96baf1c2d1c869a8b084481e121c88b5b
+P=$expectedtree
test_expect_success \
'git commit-tree records the correct tree in a commit.' \
'commit0=$(echo NO | git commit-tree $P) &&
@@ -293,7 +327,7 @@ test_expect_success 'update-index D/F conflict' '
test $numpath0 = 1
'
-test_expect_success 'absolute path works as expected' '
+test_expect_success SYMLINKS 'absolute path works as expected' '
mkdir first &&
ln -s ../.git first/.git &&
mkdir second &&
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index e3d846420d..5386504790 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -208,4 +208,87 @@ test_expect_success 'init rejects insanely long --template' '
)
'
+test_expect_success 'init creates a new directory' '
+ rm -fr newdir &&
+ (
+ git init newdir &&
+ test -d newdir/.git/refs
+ )
+'
+
+test_expect_success 'init creates a new bare directory' '
+ rm -fr newdir &&
+ (
+ git init --bare newdir &&
+ test -d newdir/refs
+ )
+'
+
+test_expect_success 'init recreates a directory' '
+ rm -fr newdir &&
+ (
+ mkdir newdir &&
+ git init newdir &&
+ test -d newdir/.git/refs
+ )
+'
+
+test_expect_success 'init recreates a new bare directory' '
+ rm -fr newdir &&
+ (
+ mkdir newdir &&
+ git init --bare newdir &&
+ test -d newdir/refs
+ )
+'
+
+test_expect_success 'init creates a new deep directory' '
+ rm -fr newdir &&
+ git init newdir/a/b/c &&
+ test -d newdir/a/b/c/.git/refs
+'
+
+test_expect_success POSIXPERM 'init creates a new deep directory (umask vs. shared)' '
+ rm -fr newdir &&
+ (
+ # Leading directories should honor umask while
+ # the repository itself should follow "shared"
+ umask 002 &&
+ git init --bare --shared=0660 newdir/a/b/c &&
+ test -d newdir/a/b/c/refs &&
+ ls -ld newdir/a newdir/a/b > lsab.out &&
+ ! grep -v "^drwxrw[sx]r-x" lsab.out &&
+ ls -ld newdir/a/b/c > lsc.out &&
+ ! grep -v "^drwxrw[sx]---" lsc.out
+ )
+'
+
+test_expect_success 'init notices EEXIST (1)' '
+ rm -fr newdir &&
+ (
+ >newdir &&
+ test_must_fail git init newdir &&
+ test -f newdir
+ )
+'
+
+test_expect_success 'init notices EEXIST (2)' '
+ rm -fr newdir &&
+ (
+ mkdir newdir &&
+ >newdir/a
+ test_must_fail git init newdir/a/b &&
+ test -f newdir/a
+ )
+'
+
+test_expect_success POSIXPERM 'init notices EPERM' '
+ rm -fr newdir &&
+ (
+ mkdir newdir &&
+ chmod -w newdir &&
+ test_must_fail git init newdir/a/b
+ )
+'
+
test_done
diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh
index 63e1217e71..2342ac5788 100755
--- a/t/t0004-unwritable.sh
+++ b/t/t0004-unwritable.sh
@@ -15,7 +15,7 @@ test_expect_success setup '
'
-test_expect_success 'write-tree should notice unwritable repository' '
+test_expect_success POSIXPERM 'write-tree should notice unwritable repository' '
(
chmod a-w .git/objects .git/objects/?? &&
@@ -27,7 +27,7 @@ test_expect_success 'write-tree should notice unwritable repository' '
'
-test_expect_success 'commit should notice unwritable repository' '
+test_expect_success POSIXPERM 'commit should notice unwritable repository' '
(
chmod a-w .git/objects .git/objects/?? &&
@@ -39,7 +39,7 @@ test_expect_success 'commit should notice unwritable repository' '
'
-test_expect_success 'update-index should notice unwritable repository' '
+test_expect_success POSIXPERM 'update-index should notice unwritable repository' '
(
echo 6O >file &&
@@ -52,7 +52,7 @@ test_expect_success 'update-index should notice unwritable repository' '
'
-test_expect_success 'add should notice unwritable repository' '
+test_expect_success POSIXPERM 'add should notice unwritable repository' '
(
echo b >file &&
diff --git a/t/t0005-signals.sh b/t/t0005-signals.sh
new file mode 100755
index 0000000000..09f855af3e
--- /dev/null
+++ b/t/t0005-signals.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+test_description='signals work as we expect'
+. ./test-lib.sh
+
+cat >expect <<EOF
+three
+two
+one
+EOF
+
+test_expect_success 'sigchain works' '
+ test-sigchain >actual
+ case "$?" in
+ 143) true ;; # POSIX w/ SIGTERM=15
+ 3) true ;; # Windows
+ *) false ;;
+ esac &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh
index 1be7446d8d..4e72b53140 100755
--- a/t/t0020-crlf.sh
+++ b/t/t0020-crlf.sh
@@ -429,6 +429,37 @@ test_expect_success 'in-tree .gitattributes (4)' '
}
'
+test_expect_success 'checkout with existing .gitattributes' '
+
+ git config core.autocrlf true &&
+ git config --unset core.safecrlf &&
+ echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
+ git add .gitattributes &&
+ git commit -m initial &&
+ echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
+ echo "contents" > .file &&
+ git add .gitattributes .file &&
+ git commit -m second &&
+
+ git checkout master~1 &&
+ git checkout master &&
+ test "$(git diff-files --raw)" = ""
+
+'
+
+test_expect_success 'checkout when deleting .gitattributes' '
+
+ git rm .gitattributes &&
+ echo "contentsQ" | q_to_cr > .file2 &&
+ git add .file2 &&
+ git commit -m third
+
+ git checkout master~1 &&
+ git checkout master &&
+ remove_cr .file2 >/dev/null
+
+'
+
test_expect_success 'invalid .gitattributes (must not crash)' '
echo "three +crlf" >>.gitattributes &&
diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh
index e5330395fc..c7d0324374 100755
--- a/t/t0024-crlf-archive.sh
+++ b/t/t0024-crlf-archive.sh
@@ -28,12 +28,12 @@ test_expect_success 'tar archive' '
"$UNZIP" -v >/dev/null 2>&1
if [ $? -eq 127 ]; then
- echo "Skipping ZIP test, because unzip was not found"
- test_done
- exit
+ say "Skipping ZIP test, because unzip was not found"
+else
+ test_set_prereq UNZIP
fi
-test_expect_success 'zip archive' '
+test_expect_success UNZIP 'zip archive' '
git archive --format=zip HEAD >test.zip &&
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index e38241c80a..bbc821ef97 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -12,12 +12,14 @@ usage: test-parse-options <options>
-b, --boolean get a boolean
-4, --or4 bitwise-or boolean with ...0100
+ --neg-or4 same as --no-or4
-i, --integer <n> get a integer
-j <n> get a integer, too
--set23 set integer to 23
-t <time> get timestamp of <time>
-L, --length <str> get length of <str>
+ -F, --file <FILE> set file to <FILE>
String options
-s, --string <string>
@@ -29,6 +31,8 @@ String options
Magic arguments
--quux means --quux
+ -NUM set integer to NUM
+ + same as -b
Standard options
--abbrev[=<n>] use <n> digits to display SHA-1s
@@ -53,10 +57,12 @@ abbrev: 7
verbose: 2
quiet: no
dry run: yes
+file: prefix/my.file
EOF
test_expect_success 'short options' '
- test-parse-options -s123 -b -i 1729 -b -vv -n > output 2> output.err &&
+ test-parse-options -s123 -b -i 1729 -b -vv -n -F my.file \
+ > output 2> output.err &&
test_cmp expect output &&
test ! -s output.err
'
@@ -70,11 +76,12 @@ abbrev: 10
verbose: 2
quiet: no
dry run: no
+file: prefix/fi.le
EOF
test_expect_success 'long options' '
test-parse-options --boolean --integer 1729 --boolean --string2=321 \
- --verbose --verbose --no-dry-run --abbrev=10 \
+ --verbose --verbose --no-dry-run --abbrev=10 --file fi.le\
> output 2> output.err &&
test ! -s output.err &&
test_cmp expect output
@@ -84,6 +91,8 @@ test_expect_success 'missing required value' '
test-parse-options -s;
test $? = 129 &&
test-parse-options --string;
+ test $? = 129 &&
+ test-parse-options --file;
test $? = 129
'
@@ -96,6 +105,7 @@ abbrev: 7
verbose: 0
quiet: no
dry run: no
+file: (not set)
arg 00: a1
arg 01: b1
arg 02: --boolean
@@ -117,6 +127,7 @@ abbrev: 7
verbose: 0
quiet: no
dry run: no
+file: (not set)
EOF
test_expect_success 'unambiguously abbreviated option' '
@@ -145,6 +156,7 @@ abbrev: 7
verbose: 0
quiet: no
dry run: no
+file: (not set)
EOF
test_expect_success 'non ambiguous option (after two options it abbreviates)' '
@@ -172,6 +184,7 @@ abbrev: 7
verbose: 0
quiet: no
dry run: no
+file: (not set)
arg 00: --quux
EOF
@@ -190,6 +203,7 @@ abbrev: 7
verbose: 0
quiet: yes
dry run: no
+file: (not set)
arg 00: foo
EOF
@@ -210,6 +224,7 @@ abbrev: 7
verbose: 0
quiet: no
dry run: no
+file: (not set)
EOF
test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' '
@@ -237,6 +252,7 @@ abbrev: 7
verbose: 0
quiet: no
dry run: no
+file: (not set)
EOF
test_expect_success 'OPT_BIT() and OPT_SET_INT() work' '
@@ -245,7 +261,58 @@ test_expect_success 'OPT_BIT() and OPT_SET_INT() work' '
test_cmp expect output
'
-# --or4
-# --no-or4
+test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' '
+ test-parse-options --set23 -bbbbb --neg-or4 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+boolean: 6
+integer: 0
+timestamp: 0
+string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+file: (not set)
+EOF
+
+test_expect_success 'OPT_BIT() works' '
+ test-parse-options -bb --or4 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+test_expect_success 'OPT_NEGBIT() works' '
+ test-parse-options -bb --no-neg-or4 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+test_expect_success 'OPT_BOOLEAN() with PARSE_OPT_NODASH works' '
+ test-parse-options + + + + + + > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+boolean: 0
+integer: 12345
+timestamp: 0
+string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+file: (not set)
+EOF
+
+test_expect_success 'OPT_NUMBER_CALLBACK() works' '
+ test-parse-options -12345 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
test_done
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 7edf49db3c..89282ccf7a 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -8,7 +8,9 @@ auml=`printf '\xc3\xa4'`
aumlcdiar=`printf '\x61\xcc\x88'`
case_insensitive=
-test_expect_success 'see if we expect ' '
+unibad=
+no_symlinks=
+test_expect_success 'see what we expect' '
test_case=test_expect_success
test_unicode=test_expect_success
@@ -19,7 +21,6 @@ test_expect_success 'see if we expect ' '
then
test_case=test_expect_failure
case_insensitive=t
- say "will test on a case insensitive filesystem"
fi &&
rm -fr junk &&
mkdir junk &&
@@ -27,13 +28,26 @@ test_expect_success 'see if we expect ' '
case "$(cd junk && echo *)" in
"$aumlcdiar")
test_unicode=test_expect_failure
- say "will test on a unicode corrupting filesystem"
+ unibad=t
;;
*) ;;
esac &&
- rm -fr junk
+ 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" &&
+ say "will test on a case insensitive filesystem"
+test "$unibad" &&
+ say "will test on a unicode corrupting filesystem"
+test "$no_symlinks" &&
+ say "will test on a filesystem lacking symbolic links"
+
if test "$case_insensitive"
then
test_expect_success "detection of case insensitive filesystem during repo init" '
@@ -48,6 +62,21 @@ test_expect_success "detection of case insensitive filesystem during repo init"
'
fi
+if test "$no_symlinks"
+then
+test_expect_success "detection of filesystem w/o symlink support during repo init" '
+
+ v=$(git config --bool core.symlinks) &&
+ test "$v" = false
+'
+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
+'
+fi
+
test_expect_success "setup case tests" '
git config core.ignorecase true &&
diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
index b29c37a5a4..0c6ff567a1 100755
--- a/t/t0055-beyond-symlinks.sh
+++ b/t/t0055-beyond-symlinks.sh
@@ -4,7 +4,7 @@ test_description='update-index and add refuse to add beyond symlinks'
. ./test-lib.sh
-test_expect_success setup '
+test_expect_success SYMLINKS setup '
>a &&
mkdir b &&
ln -s b c &&
@@ -12,12 +12,12 @@ test_expect_success setup '
git update-index --add a b/d
'
-test_expect_success 'update-index --add beyond symlinks' '
+test_expect_success SYMLINKS 'update-index --add beyond symlinks' '
test_must_fail git update-index --add c/d &&
! ( git ls-files | grep c/d )
'
-test_expect_success 'add beyond symlinks' '
+test_expect_success SYMLINKS 'add beyond symlinks' '
test_must_fail git add c/d &&
! ( git ls-files | grep c/d )
'
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 4ed1f0b4dd..53cf1f8dc4 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -7,41 +7,91 @@ test_description='Test various path utilities'
. ./test-lib.sh
-norm_abs() {
- test_expect_success "normalize absolute: $1 => $2" \
+norm_path() {
+ test_expect_success $3 "normalize path: $1 => $2" \
"test \"\$(test-path-utils normalize_path_copy '$1')\" = '$2'"
}
+# On Windows, we are using MSYS's bash, which mangles the paths.
+# Absolute paths are anchored at the MSYS installation directory,
+# which means that the path / accounts for this many characters:
+rootoff=$(test-path-utils normalize_path_copy / | wc -c)
+# Account for the trailing LF:
+if test $rootoff = 2; then
+ rootoff= # we are on Unix
+else
+ rootoff=$(($rootoff-1))
+fi
+
ancestor() {
- test_expect_success "longest ancestor: $1 $2 => $3" \
- "test \"\$(test-path-utils longest_ancestor_length '$1' '$2')\" = '$3'"
+ # We do some math with the expected ancestor length.
+ expected=$3
+ if test -n "$rootoff" && test "x$expected" != x-1; then
+ expected=$(($expected+$rootoff))
+ fi
+ test_expect_success "longest ancestor: $1 $2 => $expected" \
+ "actual=\$(test-path-utils longest_ancestor_length '$1' '$2') &&
+ test \"\$actual\" = '$expected'"
}
-norm_abs "" ""
-norm_abs / /
-norm_abs // /
-norm_abs /// /
-norm_abs /. /
-norm_abs /./ /
-norm_abs /./.. ++failed++
-norm_abs /../. ++failed++
-norm_abs /./../.// ++failed++
-norm_abs /dir/.. /
-norm_abs /dir/sub/../.. /
-norm_abs /dir/sub/../../.. ++failed++
-norm_abs /dir /dir
-norm_abs /dir// /dir/
-norm_abs /./dir /dir
-norm_abs /dir/. /dir/
-norm_abs /dir///./ /dir/
-norm_abs /dir//sub/.. /dir/
-norm_abs /dir/sub/../ /dir/
-norm_abs //dir/sub/../. /dir/
-norm_abs /dir/s1/../s2/ /dir/s2/
-norm_abs /d1/s1///s2/..//../s3/ /d1/s3/
-norm_abs /d1/s1//../s2/../../d2 /d2
-norm_abs /d1/.../d2 /d1/.../d2
-norm_abs /d1/..././../d2 /d1/d2
+# Absolute path tests must be skipped on Windows because due to path mangling
+# the test program never sees a POSIX-style absolute path
+case $(uname -s) in
+*MINGW*)
+ ;;
+*)
+ test_set_prereq POSIX
+ ;;
+esac
+
+norm_path "" ""
+norm_path . ""
+norm_path ./ ""
+norm_path ./. ""
+norm_path ./.. ++failed++
+norm_path ../. ++failed++
+norm_path ./../.// ++failed++
+norm_path dir/.. ""
+norm_path dir/sub/../.. ""
+norm_path dir/sub/../../.. ++failed++
+norm_path dir dir
+norm_path dir// dir/
+norm_path ./dir dir
+norm_path dir/. dir/
+norm_path dir///./ dir/
+norm_path dir//sub/.. dir/
+norm_path dir/sub/../ dir/
+norm_path dir/sub/../. dir/
+norm_path dir/s1/../s2/ dir/s2/
+norm_path d1/s1///s2/..//../s3/ d1/s3/
+norm_path d1/s1//../s2/../../d2 d2
+norm_path d1/.../d2 d1/.../d2
+norm_path d1/..././../d2 d1/d2
+
+norm_path / / POSIX
+norm_path // / POSIX
+norm_path /// / POSIX
+norm_path /. / POSIX
+norm_path /./ / POSIX
+norm_path /./.. ++failed++ POSIX
+norm_path /../. ++failed++ POSIX
+norm_path /./../.// ++failed++ POSIX
+norm_path /dir/.. / POSIX
+norm_path /dir/sub/../.. / POSIX
+norm_path /dir/sub/../../.. ++failed++ POSIX
+norm_path /dir /dir POSIX
+norm_path /dir// /dir/ POSIX
+norm_path /./dir /dir POSIX
+norm_path /dir/. /dir/ POSIX
+norm_path /dir///./ /dir/ POSIX
+norm_path /dir//sub/.. /dir/ POSIX
+norm_path /dir/sub/../ /dir/ POSIX
+norm_path //dir/sub/../. /dir/ POSIX
+norm_path /dir/s1/../s2/ /dir/s2/ POSIX
+norm_path /d1/s1///s2/..//../s3/ /d1/s3/ POSIX
+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
@@ -80,9 +130,13 @@ 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 .:/foo/. 4
+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_done
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
new file mode 100755
index 0000000000..680d7d6861
--- /dev/null
+++ b/t/t0070-fundamental.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+test_description='check that the most basic functions work
+
+
+Verify wrappers and compatibility functions.
+'
+
+. ./test-lib.sh
+
+test_expect_success 'character classes (isspace, isalpha etc.)' '
+ test-ctype
+'
+
+test_done
diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh
new file mode 100755
index 0000000000..315b9b3f10
--- /dev/null
+++ b/t/t0100-previous.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='previous branch syntax @{-n}'
+
+. ./test-lib.sh
+
+test_expect_success 'branch -d @{-1}' '
+ test_commit A &&
+ git checkout -b junk &&
+ git checkout - &&
+ test "$(git symbolic-ref HEAD)" = refs/heads/master &&
+ git branch -d @{-1} &&
+ test_must_fail git rev-parse --verify refs/heads/junk
+'
+
+test_expect_success 'branch -d @{-12} when there is not enough switches yet' '
+ git reflog expire --expire=now &&
+ git checkout -b junk2 &&
+ git checkout - &&
+ test "$(git symbolic-ref HEAD)" = refs/heads/master &&
+ test_must_fail git branch -d @{-12} &&
+ git rev-parse --verify refs/heads/master
+'
+
+test_expect_success 'merge @{-1}' '
+ git checkout A &&
+ test_commit B &&
+ git checkout A &&
+ test_commit C &&
+ git branch -f master B &&
+ git branch -f other &&
+ git checkout other &&
+ git checkout master &&
+ git merge @{-1} &&
+ git cat-file commit HEAD | grep "Merge branch '\''other'\''"
+'
+
+test_expect_success 'merge @{-1} when there is not enough switches yet' '
+ git reflog expire --expire=now &&
+ git checkout -f master &&
+ git reset --hard B &&
+ git branch -f other C &&
+ git checkout other &&
+ git checkout master &&
+ test_must_fail git merge @{-12}
+'
+
+test_done
+
diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh
index 570d3729bd..f19b4a2a4a 100755
--- a/t/t1004-read-tree-m-u-wf.sh
+++ b/t/t1004-read-tree-m-u-wf.sh
@@ -157,7 +157,7 @@ test_expect_success '3-way not overwriting local changes (their side)' '
'
-test_expect_success 'funny symlink in work tree' '
+test_expect_success SYMLINKS 'funny symlink in work tree' '
git reset --hard &&
git checkout -b sym-b side-b &&
@@ -177,7 +177,7 @@ test_expect_success 'funny symlink in work tree' '
'
-test_expect_success 'funny symlink in work tree, un-unlink-able' '
+test_expect_success SYMLINKS 'funny symlink in work tree, un-unlink-able' '
rm -fr a b &&
git reset --hard &&
@@ -189,7 +189,7 @@ test_expect_success 'funny symlink in work tree, un-unlink-able' '
'
# clean-up from the above test
-chmod a+w a
+chmod a+w a 2>/dev/null
rm -fr a b
test_expect_success 'D/F setup' '
diff --git a/t/t1008-read-tree-overlay.sh b/t/t1008-read-tree-overlay.sh
new file mode 100755
index 0000000000..f9e00285db
--- /dev/null
+++ b/t/t1008-read-tree-overlay.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='test multi-tree read-tree without merging'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo one >a &&
+ git add a &&
+ git commit -m initial &&
+ git tag initial &&
+ echo two >b &&
+ git add b &&
+ git commit -m second &&
+ git checkout -b side initial &&
+ echo three >a &&
+ mkdir b &&
+ echo four >b/c &&
+ git add b/c &&
+ git commit -m third
+'
+
+test_expect_success 'multi-read' '
+ git read-tree initial master side &&
+ (echo a; echo b/c) >expect &&
+ git ls-files >actual &&
+ test_cmp expect actual
+'
+
+test_done
+
diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh
new file mode 100755
index 0000000000..9956e3ad62
--- /dev/null
+++ b/t/t1010-mktree.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='git mktree'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ for d in a a. a0
+ do
+ mkdir "$d" && echo "$d/one" >"$d/one" &&
+ git add "$d"
+ done &&
+ echo zero >one &&
+ git update-index --add --info-only one &&
+ git write-tree --missing-ok >tree.missing &&
+ git ls-tree $(cat tree.missing) >top.missing &&
+ git ls-tree -r $(cat tree.missing) >all.missing &&
+ echo one >one &&
+ git add one &&
+ git write-tree >tree &&
+ git ls-tree $(cat tree) >top &&
+ git ls-tree -r $(cat tree) >all &&
+ test_tick &&
+ git commit -q -m one &&
+ H=$(git rev-parse HEAD) &&
+ git update-index --add --cacheinfo 160000 $H sub &&
+ test_tick &&
+ git commit -q -m two &&
+ git rev-parse HEAD^{tree} >tree.withsub &&
+ git ls-tree HEAD >top.withsub &&
+ git ls-tree -r HEAD >all.withsub
+'
+
+test_expect_success 'ls-tree piped to mktree (1)' '
+ git mktree <top >actual &&
+ test_cmp tree actual
+'
+
+test_expect_success 'ls-tree piped to mktree (2)' '
+ git mktree <top.withsub >actual &&
+ test_cmp tree.withsub actual
+'
+
+test_expect_success 'ls-tree output in wrong order given to mktree (1)' '
+ perl -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 |
+ git mktree >actual &&
+ test_cmp tree.withsub actual
+'
+
+test_expect_success 'allow missing object with --missing' '
+ git mktree --missing <top.missing >actual &&
+ test_cmp tree.missing actual
+'
+
+test_expect_failure 'mktree reads ls-tree -r output (1)' '
+ git mktree <all >actual &&
+ test_cmp tree actual
+'
+
+test_expect_failure 'mktree reads ls-tree -r output (2)' '
+ git mktree <all.withsub >actual &&
+ test_cmp tree.withsub actual
+'
+
+test_done
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index fc386ba033..210e594f6f 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -126,7 +126,7 @@ test_expect_success 'no file/rev ambiguity check inside a bare repo' '
cd foo.git && git show -s HEAD
'
-test_expect_success 'detection should not be fooled by a symlink' '
+test_expect_success SYMLINKS 'detection should not be fooled by a symlink' '
cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
diff --git a/t/t1100-commit-tree-options.sh b/t/t1100-commit-tree-options.sh
index 7f7fc36734..c4414ff576 100755
--- a/t/t1100-commit-tree-options.sh
+++ b/t/t1100-commit-tree-options.sh
@@ -40,6 +40,6 @@ test_expect_success \
test_expect_success \
'compare commit' \
- 'diff expected commit'
+ 'test_cmp expected commit'
test_done
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 11b82f43dd..83b7294010 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -118,7 +118,14 @@ EOF
test_expect_success 'multiple unset is correct' 'cmp .git/config expect'
-mv .git/config2 .git/config
+cp .git/config2 .git/config
+
+test_expect_success '--replace-all missing value' '
+ test_must_fail git config --replace-all beta.haha &&
+ test_cmp .git/config2 .git/config
+'
+
+rm .git/config2
test_expect_success '--replace-all' \
'git config --replace-all beta.haha gamma'
@@ -336,10 +343,10 @@ test_expect_success 'get bool variable with empty value' \
'git config --bool emptyvalue.variable > output &&
cmp output expect'
-git config > output 2>&1
-
-test_expect_success 'no arguments, but no crash' \
- "test $? = 129 && grep usage output"
+test_expect_success 'no arguments, but no crash' '
+ test_must_fail git config >output 2>&1 &&
+ grep usage output
+'
cat > .git/config << EOF
[a.b]
@@ -373,7 +380,7 @@ EOF
test_expect_success 'new variable inserts into proper section' 'cmp .git/config expect'
test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \
- 'git config --file non-existing-config -l; test $? != 0'
+ 'test_must_fail git config --file non-existing-config -l'
cat > other-config << EOF
[ein]
@@ -453,6 +460,28 @@ EOF
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'
+
+cat > expect << EOF
+# Hallo
+ #Bello
+[branch "zwei"]
+ x = 1
+[branch "zwei"]
+ y = 1
+[branch "drei"]
+weird
+[branch "zwei"]
+ z = 1
+EOF
+
+test_expect_success "rename succeeded" "test_cmp expect .git/config"
+
+cat >> .git/config << EOF
[branch "zwei"] a = 1 [branch "vier"]
EOF
@@ -726,7 +755,12 @@ echo >>result
test_expect_success '--null --get-regexp' 'cmp result expect'
-test_expect_success 'symlinked configuration' '
+test_expect_success 'inner whitespace kept verbatim' '
+ git config section.val "foo bar" &&
+ test "z$(git config section.val)" = "zfoo bar"
+'
+
+test_expect_success SYMLINKS 'symlinked configuration' '
ln -s notyet myconfig &&
GIT_CONFIG=myconfig git config test.frotz nitfol &&
diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh
index 653362ba22..de42d21c92 100755
--- a/t/t1301-shared-repo.sh
+++ b/t/t1301-shared-repo.sh
@@ -26,7 +26,7 @@ modebits () {
for u in 002 022
do
- test_expect_success "shared=1 does not clear bits preset by umask $u" '
+ test_expect_success POSIXPERM "shared=1 does not clear bits preset by umask $u" '
mkdir sub && (
cd sub &&
umask $u &&
@@ -54,7 +54,7 @@ test_expect_success 'shared=all' '
test 2 = $(git config core.sharedrepository)
'
-test_expect_success 'update-server-info honors core.sharedRepository' '
+test_expect_success POSIXPERM 'update-server-info honors core.sharedRepository' '
: > a1 &&
git add a1 &&
test_tick &&
@@ -85,7 +85,7 @@ do
git config core.sharedrepository "$u" &&
umask 0277 &&
- test_expect_success "shared = $u ($y) ro" '
+ test_expect_success POSIXPERM "shared = $u ($y) ro" '
rm -f .git/info/refs &&
git update-server-info &&
@@ -97,7 +97,7 @@ do
'
umask 077 &&
- test_expect_success "shared = $u ($x) rw" '
+ test_expect_success POSIXPERM "shared = $u ($x) rw" '
rm -f .git/info/refs &&
git update-server-info &&
@@ -111,7 +111,7 @@ do
done
-test_expect_success 'git reflog expire honors core.sharedRepository' '
+test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' '
git config core.sharedRepository group &&
git reflog expire --all &&
actual="$(ls -l .git/logs/refs/heads/master)" &&
@@ -126,4 +126,45 @@ test_expect_success 'git reflog expire honors core.sharedRepository' '
esac
'
+test_expect_success POSIXPERM 'forced modes' '
+ mkdir -p templates/hooks &&
+ echo update-server-info >templates/hooks/post-update &&
+ chmod +x templates/hooks/post-update &&
+ echo : >random-file &&
+ mkdir new &&
+ (
+ cd new &&
+ umask 002 &&
+ git init --shared=0660 --template=../templates &&
+ >frotz &&
+ git add frotz &&
+ git commit -a -m initial &&
+ git repack
+ ) &&
+ # List repository files meant to be protected; note that
+ # COMMIT_EDITMSG does not matter---0mode is not about a
+ # repository with a work tree.
+ find new/.git -type f -name COMMIT_EDITMSG -prune -o -print |
+ xargs ls -ld >actual &&
+
+ # Everything must be unaccessible to others
+ test -z "$(sed -e "/^.......---/d" actual)" &&
+
+ # All directories must have either 2770 or 770
+ test -z "$(sed -n -e "/^drwxrw[sx]---/d" -e "/^d/p" actual)" &&
+
+ # post-update hook must be 0770
+ test -z "$(sed -n -e "/post-update/{
+ /^-rwxrwx---/d
+ p
+ }" actual)" &&
+
+ # All files inside objects must be accessible by us
+ test -z "$(sed -n -e "/objects\//{
+ /^d/d
+ /^-r.-r.----/d
+ p
+ }" actual)"
+'
+
test_done
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index bd589268fc..54ba3df95f 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -137,7 +137,7 @@ $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000
EOF
test_expect_success \
"verifying $m's log" \
- "diff expect .git/logs/$m"
+ "test_cmp expect .git/logs/$m"
rm -rf .git/$m .git/logs expect
test_expect_success \
@@ -168,7 +168,7 @@ $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000
EOF
test_expect_success \
"verifying $m's log" \
- 'diff expect .git/logs/$m'
+ 'test_cmp expect .git/logs/$m'
rm -f .git/$m .git/logs/$m expect
git update-ref $m $D
@@ -272,7 +272,7 @@ $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 c
EOF
test_expect_success \
'git commit logged updates' \
- "diff expect .git/logs/$m"
+ "test_cmp expect .git/logs/$m"
unset h_TEST h_OTHER h_FIXED h_MERGED
test_expect_success \
diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
new file mode 100755
index 0000000000..7fa5f5b22a
--- /dev/null
+++ b/t/t1401-symbolic-ref.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+test_description='basic symbolic-ref tests'
+. ./test-lib.sh
+
+# If the tests munging HEAD fail, they can break detection of
+# the git repo, meaning that further tests will operate on
+# the surrounding git repo instead of the trash directory.
+reset_to_sane() {
+ echo ref: refs/heads/foo >.git/HEAD
+}
+
+test_expect_success 'symbolic-ref writes HEAD' '
+ git symbolic-ref HEAD refs/heads/foo &&
+ echo ref: refs/heads/foo >expect &&
+ test_cmp expect .git/HEAD
+'
+
+test_expect_success 'symbolic-ref reads HEAD' '
+ echo refs/heads/foo >expect &&
+ git symbolic-ref HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'symbolic-ref refuses non-ref for HEAD' '
+ test_must_fail git symbolic-ref HEAD foo
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref refuses bare sha1' '
+ echo content >file && git add file && git commit -m one
+ test_must_fail git symbolic-ref HEAD `git rev-parse HEAD`
+'
+reset_to_sane
+
+test_done
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 5b24f05573..80af6b9b7e 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -70,9 +70,7 @@ test_expect_success setup '
E=`git rev-parse --verify HEAD:A/B/E` &&
check_fsck &&
- chmod +x C &&
- ( test "`git config --bool core.filemode`" != false ||
- echo executable >>C ) &&
+ test_chmod +x C &&
git add C &&
test_tick && git commit -m dragon &&
L=`git rev-parse --verify HEAD` &&
diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh
new file mode 100755
index 0000000000..c18ed8edf9
--- /dev/null
+++ b/t/t1411-reflog-show.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+test_description='Test reflog display routines'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ echo content >file &&
+ git add file &&
+ test_tick &&
+ git commit -m one
+'
+
+cat >expect <<'EOF'
+Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
+Reflog message: commit (initial): one
+EOF
+test_expect_success 'log -g shows reflog headers' '
+ 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 'oneline reflog format' '
+ git log -g -1 --oneline >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 @{now} syntax shows reflog date (multiline)' '
+ git log -g -1 HEAD@{now} >tmp &&
+ grep ^Reflog <tmp >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
+EOF
+test_expect_success 'using @{now} syntax shows reflog date (oneline)' '
+ git log -g -1 --oneline HEAD@{now} >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Reflog: HEAD@{1112911993 -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 &&
+ grep ^Reflog <tmp >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+e46513e HEAD@{1112911993 -0700}: commit (initial): one
+EOF
+test_expect_success 'using --date= shows reflog date (oneline)' '
+ git log -g -1 --oneline --date=raw >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
new file mode 100755
index 0000000000..a22632f483
--- /dev/null
+++ b/t/t1450-fsck.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+test_description='git fsck random collection of tests'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ test_commit A fileA one &&
+ git checkout HEAD^0 &&
+ test_commit B fileB two &&
+ git tag -d A B &&
+ git reflog expire --expire=now --all
+'
+
+test_expect_success 'HEAD is part of refs' '
+ test 0 = $(git fsck | wc -l)
+'
+
+test_expect_success 'loose objects borrowed from alternate are not missing' '
+ mkdir another &&
+ (
+ cd another &&
+ git init &&
+ echo ../../../.git/objects >.git/objects/info/alternates &&
+ test_commit C fileC one &&
+ git fsck >out &&
+ ! grep "missing blob" out
+ )
+'
+
+# Corruption tests follow. Make sure to remove all traces of the
+# specific corruption you test afterwards, lest a later test trip over
+# it.
+
+test_expect_success 'object with bad sha1' '
+ sha=$(echo blob | git hash-object -w --stdin) &&
+ echo $sha &&
+ old=$(echo $sha | sed "s+^..+&/+") &&
+ new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff &&
+ sha="$(dirname $new)$(basename $new)"
+ mv .git/objects/$old .git/objects/$new &&
+ git update-index --add --cacheinfo 100644 $sha foo &&
+ tree=$(git write-tree) &&
+ cmt=$(echo bogus | git commit-tree $tree) &&
+ git update-ref refs/heads/bogus $cmt &&
+ (git fsck 2>out; true) &&
+ grep "$sha.*corrupt" out &&
+ rm -f .git/objects/$new &&
+ git update-ref -d refs/heads/bogus &&
+ git read-tree -u --reset HEAD
+'
+
+test_expect_success 'branch pointing to non-commit' '
+ git rev-parse HEAD^{tree} > .git/refs/heads/invalid &&
+ git fsck 2>out &&
+ grep "not a commit" out &&
+ git update-ref -d refs/heads/invalid
+'
+
+cat > invalid-tag <<EOF
+object ffffffffffffffffffffffffffffffffffffffff
+type commit
+tag invalid
+tagger T A Gger <tagger@example.com> 1234567890 -0000
+
+This is an invalid tag.
+EOF
+
+test_expect_failure 'tag pointing to nonexistent' '
+ tag=$(git hash-object -w --stdin < invalid-tag) &&
+ echo $tag > .git/refs/tags/invalid &&
+ git fsck --tags 2>out &&
+ cat out &&
+ grep "could not load tagged object" out &&
+ rm .git/refs/tags/invalid
+'
+
+cat > wrong-tag <<EOF
+object $(echo blob | git hash-object -w --stdin)
+type commit
+tag wrong
+tagger T A Gger <tagger@example.com> 1234567890 -0000
+
+This is an invalid tag.
+EOF
+
+test_expect_failure 'tag pointing to something else than its type' '
+ tag=$(git hash-object -w --stdin < wrong-tag) &&
+ echo $tag > .git/refs/tags/wrong &&
+ git fsck --tags 2>out &&
+ cat out &&
+ grep "some sane error message" out &&
+ rm .git/refs/tags/wrong
+'
+
+
+
+test_done
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
index 85da4caa7e..48ee07779d 100755
--- a/t/t1500-rev-parse.sh
+++ b/t/t1500-rev-parse.sh
@@ -26,21 +26,28 @@ test_rev_parse() {
"test '$1' = \"\$(git rev-parse --show-prefix)\""
shift
[ $# -eq 0 ] && return
+
+ test_expect_success "$name: git-dir" \
+ "test '$1' = \"\$(git rev-parse --git-dir)\""
+ shift
+ [ $# -eq 0 ] && return
}
-# label is-bare is-inside-git is-inside-work prefix
+# label is-bare is-inside-git is-inside-work prefix git-dir
+
+ROOT=$(pwd)
-test_rev_parse toplevel false false true ''
+test_rev_parse toplevel false false true '' .git
cd .git || exit 1
-test_rev_parse .git/ false true false ''
+test_rev_parse .git/ false true false '' .
cd objects || exit 1
-test_rev_parse .git/objects/ false true false ''
+test_rev_parse .git/objects/ false true false '' "$ROOT/.git"
cd ../.. || exit 1
mkdir -p sub/dir || exit 1
cd sub/dir || exit 1
-test_rev_parse subdirectory false false true sub/dir/
+test_rev_parse subdirectory false false true sub/dir/ "$ROOT/.git"
cd ../.. || exit 1
git config core.bare true
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index 27dc6c55d5..f6a6f839a1 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -92,13 +92,6 @@ cd sub/dir || exit 1
test_rev_parse 'in repo.git/sub/dir' false true true sub/dir/
cd ../../../.. || exit 1
-test_expect_success 'detecting gitdir when cwd is in a subdir of gitdir' '
- (expected=$(pwd)/repo.git &&
- cd repo.git/refs &&
- unset GIT_DIR &&
- test "$expected" = "$(git rev-parse --git-dir)")
-'
-
test_expect_success 'repo finds its work tree' '
(cd repo.git &&
: > work/sub/dir/untracked &&
diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh
index 997002d4c4..e504058062 100755
--- a/t/t1502-rev-parse-parseopt.sh
+++ b/t/t1502-rev-parse-parseopt.sh
@@ -20,8 +20,7 @@ Extras
EOF
-test_expect_success 'test --parseopt help output' '
- git rev-parse --parseopt -- -h 2> output.err <<EOF
+cat > optionspec << EOF
some-command [options] <args>...
some-command does foo and bar!
@@ -37,7 +36,47 @@ C? option C with an optional argument
Extras
extra1 line above used to cause a segfault but no longer does
EOF
+
+test_expect_success 'test --parseopt help output' '
+ git rev-parse --parseopt -- -h 2> output.err < optionspec
test_cmp expect.err output.err
'
+cat > expect <<EOF
+set -- --foo --bar 'ham' -- 'arg'
+EOF
+
+test_expect_success 'test --parseopt' '
+ git rev-parse --parseopt -- --foo --bar=ham arg < optionspec > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'test --parseopt with mixed options and arguments' '
+ git rev-parse --parseopt -- --foo arg --bar=ham < optionspec > output &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+set -- --foo -- 'arg' '--bar=ham'
+EOF
+
+test_expect_success 'test --parseopt with --' '
+ git rev-parse --parseopt -- --foo -- arg --bar=ham < optionspec > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'test --parseopt --stop-at-non-option' '
+ git rev-parse --parseopt --stop-at-non-option -- --foo arg --bar=ham < optionspec > output &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+set -- --foo -- '--' 'arg' '--bar=ham'
+EOF
+
+test_expect_success 'test --parseopt --keep-dashdash' '
+ git rev-parse --parseopt --keep-dashdash -- --foo -- arg --bar=ham < optionspec > output &&
+ test_cmp expect output
+'
+
test_done
diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh
index e377d48902..df5ad8c686 100755
--- a/t/t1504-ceiling-dirs.sh
+++ b/t/t1504-ceiling-dirs.sh
@@ -13,7 +13,7 @@ test_fail() {
"git rev-parse --show-prefix"
}
-TRASH_ROOT="$(pwd)"
+TRASH_ROOT="$PWD"
ROOT_PARENT=$(dirname "$TRASH_ROOT")
diff --git a/t/t1505-rev-parse-last.sh b/t/t1505-rev-parse-last.sh
new file mode 100755
index 0000000000..d709ecf8df
--- /dev/null
+++ b/t/t1505-rev-parse-last.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+test_description='test @{-N} syntax'
+
+. ./test-lib.sh
+
+
+make_commit () {
+ echo "$1" > "$1" &&
+ git add "$1" &&
+ git commit -m "$1"
+}
+
+
+test_expect_success 'setup' '
+
+ make_commit 1 &&
+ git branch side &&
+ make_commit 2 &&
+ make_commit 3 &&
+ git checkout side &&
+ make_commit 4 &&
+ git merge master &&
+ git checkout master
+
+'
+
+# 1 -- 2 -- 3 master
+# \ \
+# \ \
+# --- 4 --- 5 side
+#
+# 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_expect_success '@{-1}~2 works' '
+ test_rev_equivalent side~2 @{-1}~2
+'
+
+test_expect_success '@{-1}^2 works' '
+ test_rev_equivalent side^2 @{-1}^2
+'
+
+test_expect_success '@{-1}@{1} works' '
+ test_rev_equivalent side@{1} @{-1}@{1}
+'
+
+test_expect_success '@{-2} works' '
+ test_rev_equivalent master @{-2}
+'
+
+test_expect_success '@{-3} fails' '
+ test_must_fail git rev-parse @{-3}
+'
+
+test_done
+
+
diff --git a/t/t2001-checkout-cache-clash.sh b/t/t2001-checkout-cache-clash.sh
index ef007532b1..98aa73e823 100755
--- a/t/t2001-checkout-cache-clash.sh
+++ b/t/t2001-checkout-cache-clash.sh
@@ -59,10 +59,10 @@ test_expect_success \
'git read-tree -m $tree1 && git checkout-index -f -a'
test_debug 'show_files $tree1'
-ln -s path0 path1
-test_expect_success \
+test_expect_success SYMLINKS \
'git update-index --add a symlink.' \
- 'git update-index --add path1'
+ 'ln -s path0 path1 &&
+ git update-index --add path1'
test_expect_success \
'writing tree out with git write-tree' \
'tree3=$(git write-tree)'
diff --git a/t/t2003-checkout-cache-mkdir.sh b/t/t2003-checkout-cache-mkdir.sh
index 71894b3743..02a4fc5d36 100755
--- a/t/t2003-checkout-cache-mkdir.sh
+++ b/t/t2003-checkout-cache-mkdir.sh
@@ -19,7 +19,7 @@ test_expect_success \
echo rezrov >path1/file1 &&
git update-index --add path0 path1/file1'
-test_expect_success \
+test_expect_success SYMLINKS \
'have symlink in place where dir is expected.' \
'rm -fr path0 path1 &&
mkdir path2 &&
@@ -59,7 +59,7 @@ test_expect_success \
test ! -f path1/file1'
# Linus fix #1
-test_expect_success \
+test_expect_success SYMLINKS \
'use --prefix=tmp/orary/ where tmp is a symlink' \
'rm -fr path0 path1 path2 tmp* &&
mkdir tmp1 tmp1/orary &&
@@ -71,7 +71,7 @@ test_expect_success \
test -h tmp'
# Linus fix #2
-test_expect_success \
+test_expect_success SYMLINKS \
'use --prefix=tmp/orary- where tmp is a symlink' \
'rm -fr path0 path1 path2 tmp* &&
mkdir tmp1 &&
@@ -82,7 +82,7 @@ test_expect_success \
test -h tmp'
# Linus fix #3
-test_expect_success \
+test_expect_success SYMLINKS \
'use --prefix=tmp- where tmp-path1 is a symlink' \
'rm -fr path0 path1 path2 tmp* &&
mkdir tmp1 &&
diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh
index 39133b8c7a..36cca14d95 100755
--- a/t/t2004-checkout-cache-temp.sh
+++ b/t/t2004-checkout-cache-temp.sh
@@ -194,7 +194,7 @@ test_expect_success \
test $(cat ../$s1) = tree1asubdir/path5)
)'
-test_expect_success \
+test_expect_success SYMLINKS \
'checkout --temp symlink' '
rm -f path* .merge_* out .git/index &&
ln -s b a &&
diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh
index 0526fce163..20f33436d0 100755
--- a/t/t2007-checkout-symlink.sh
+++ b/t/t2007-checkout-symlink.sh
@@ -6,6 +6,12 @@ test_description='git checkout to switch between branches with symlink<->dir'
. ./test-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say "symbolic links not supported - skipping tests"
+ test_done
+fi
+
test_expect_success setup '
mkdir frotz &&
diff --git a/t/t2012-checkout-last.sh b/t/t2012-checkout-last.sh
new file mode 100755
index 0000000000..87b30a268c
--- /dev/null
+++ b/t/t2012-checkout-last.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+test_description='checkout can switch to last branch'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ echo hello >world &&
+ git add world &&
+ git commit -m initial &&
+ git branch other &&
+ echo "hello again" >>world &&
+ git add world &&
+ git commit -m second
+'
+
+test_expect_success '"checkout -" does not work initially' '
+ test_must_fail git checkout -
+'
+
+test_expect_success 'first branch switch' '
+ git checkout other
+'
+
+test_expect_success '"checkout -" switches back' '
+ git checkout - &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/master"
+'
+
+test_expect_success '"checkout -" switches forth' '
+ git checkout - &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/other"
+'
+
+test_expect_success 'detach HEAD' '
+ git checkout $(git rev-parse HEAD)
+'
+
+test_expect_success '"checkout -" attaches again' '
+ git checkout - &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/other"
+'
+
+test_expect_success '"checkout -" detaches again' '
+ git checkout - &&
+ test "z$(git rev-parse HEAD)" = "z$(git rev-parse other)" &&
+ test_must_fail git symbolic-ref HEAD
+'
+
+test_expect_success 'more switches' '
+ for i in 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
+ do
+ git checkout -b branch$i
+ done
+'
+
+more_switches () {
+ for i in 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
+ do
+ git checkout branch$i
+ done
+}
+
+test_expect_success 'switch to the last' '
+ more_switches &&
+ git checkout @{-1} &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/branch2"
+'
+
+test_expect_success 'switch to second from the last' '
+ more_switches &&
+ git checkout @{-2} &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/branch3"
+'
+
+test_expect_success 'switch to third from the last' '
+ more_switches &&
+ git checkout @{-3} &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/branch4"
+'
+
+test_expect_success 'switch to fourth from the last' '
+ more_switches &&
+ git checkout @{-4} &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/branch5"
+'
+
+test_expect_success 'switch to twelfth from the last' '
+ more_switches &&
+ git checkout @{-12} &&
+ test "z$(git symbolic-ref HEAD)" = "zrefs/heads/branch13"
+'
+
+test_done
diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
new file mode 100755
index 0000000000..fda3f0af7e
--- /dev/null
+++ b/t/t2013-checkout-submodule.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+test_description='checkout can handle submodules'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir submodule &&
+ (cd submodule &&
+ git init &&
+ test_commit first) &&
+ git add submodule &&
+ test_tick &&
+ git commit -m superproject &&
+ (cd submodule &&
+ test_commit second) &&
+ git add submodule &&
+ test_tick &&
+ git commit -m updated.superproject
+'
+
+test_expect_success '"reset <submodule>" updates the index' '
+ git update-index --refresh &&
+ git diff-files --quiet &&
+ git diff-index --quiet --cached HEAD &&
+ test_must_fail git reset HEAD^ submodule &&
+ test_must_fail git diff-files --quiet &&
+ git reset submodule &&
+ git diff-files --quiet
+'
+
+test_expect_success '"checkout <submodule>" updates the index only' '
+ git update-index --refresh &&
+ git diff-files --quiet &&
+ git diff-index --quiet --cached HEAD &&
+ git checkout HEAD^ submodule &&
+ test_must_fail git diff-files --quiet &&
+ git checkout HEAD submodule &&
+ git diff-files --quiet
+'
+
+test_done
diff --git a/t/t2014-switch.sh b/t/t2014-switch.sh
new file mode 100755
index 0000000000..ccfb147113
--- /dev/null
+++ b/t/t2014-switch.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+test_description='Peter MacMillan'
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo Hello >file &&
+ git add file &&
+ test_tick &&
+ git commit -m V1 &&
+ echo Hello world >file &&
+ git add file &&
+ git checkout -b other
+'
+
+test_expect_success 'check all changes are staged' '
+ git diff --exit-code
+'
+
+test_expect_success 'second commit' '
+ git commit -m V2
+'
+
+test_expect_success 'check' '
+ git diff --cached --exit-code
+'
+
+test_done
diff --git a/t/t2100-update-cache-badpath.sh b/t/t2100-update-cache-badpath.sh
index 6ef2dcfd8a..2df3fdde8b 100755
--- a/t/t2100-update-cache-badpath.sh
+++ b/t/t2100-update-cache-badpath.sh
@@ -26,7 +26,12 @@ All of the attempts should fail.
mkdir path2 path3
date >path0
-ln -s xyzzy path1
+if test_have_prereq SYMLINKS
+then
+ ln -s xyzzy path1
+else
+ date > path1
+fi
date >path2/file2
date >path3/file3
@@ -38,7 +43,12 @@ rm -fr path?
mkdir path0 path1
date >path2
-ln -s frotz path3
+if test_have_prereq SYMLINKS
+then
+ ln -s frotz path3
+else
+ date > path3
+fi
date >path0/file0
date >path1/file1
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index b2ddf5ace3..912075063b 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -80,7 +80,7 @@ test_expect_success 'change gets noticed' '
'
-test_expect_success 'replace a file with a symlink' '
+test_expect_success SYMLINKS 'replace a file with a symlink' '
rm foo &&
ln -s top foo &&
@@ -150,7 +150,7 @@ test_expect_success 'add -u resolves unmerged paths' '
echo 2 >path3 &&
echo 2 >path5 &&
git add -u &&
- git ls-files -s "path?" >actual &&
+ git ls-files -s path1 path2 path3 path4 path5 path6 >actual &&
{
echo "100644 $three 0 path1"
echo "100644 $one 1 path3"
diff --git a/t/t2201-add-update-typechange.sh b/t/t2201-add-update-typechange.sh
index d24c7d9e5f..2e8f702452 100755
--- a/t/t2201-add-update-typechange.sh
+++ b/t/t2201-add-update-typechange.sh
@@ -11,7 +11,13 @@ test_expect_success setup '
_empty=$(git hash-object --stdin <xyzzy) &&
>yomin &&
>caskly &&
- ln -s frotz nitfol &&
+ if test_have_prereq SYMLINKS; then
+ ln -s frotz nitfol &&
+ T_letter=T
+ else
+ printf %s frotz > nitfol &&
+ T_letter=M
+ fi &&
mkdir rezrov &&
>rezrov/bozbar &&
git add caskly xyzzy yomin nitfol rezrov/bozbar &&
@@ -29,7 +35,11 @@ test_expect_success modify '
>nitfol &&
# rezrov/bozbar disappears
rm -fr rezrov &&
- ln -s xyzzy rezrov &&
+ if test_have_prereq SYMLINKS; then
+ ln -s xyzzy rezrov
+ else
+ printf %s xyzzy > rezrov
+ fi &&
# xyzzy disappears (not a submodule)
mkdir xyzzy &&
echo gnusto >xyzzy/bozbar &&
@@ -71,7 +81,7 @@ test_expect_success modify '
s/blob/000000/
}
/ nitfol/{
- s/ nitfol/ $_z40 T&/
+ s/ nitfol/ $_z40 $T_letter&/
s/blob/100644/
}
/ rezrov.bozbar/{
diff --git a/t/t2300-cd-to-toplevel.sh b/t/t2300-cd-to-toplevel.sh
index e42cbfe6c6..3b01ad2e4d 100755
--- a/t/t2300-cd-to-toplevel.sh
+++ b/t/t2300-cd-to-toplevel.sh
@@ -5,17 +5,17 @@ test_description='cd_to_toplevel'
. ./test-lib.sh
test_cd_to_toplevel () {
- test_expect_success "$2" '
+ test_expect_success $3 "$2" '
(
cd '"'$1'"' &&
. git-sh-setup &&
cd_to_toplevel &&
- [ "$(unset PWD; /bin/pwd)" = "$TOPLEVEL" ]
+ [ "$(pwd -P)" = "$TOPLEVEL" ]
)
'
}
-TOPLEVEL="$(unset PWD; /bin/pwd)/repo"
+TOPLEVEL="$(pwd -P)/repo"
mkdir -p repo/sub/dir
mv .git repo/
SUBDIRECTORY_OK=1
@@ -24,14 +24,14 @@ test_cd_to_toplevel repo 'at physical root'
test_cd_to_toplevel repo/sub/dir 'at physical subdir'
-ln -s repo symrepo
-test_cd_to_toplevel symrepo 'at symbolic root'
+ln -s repo symrepo 2>/dev/null
+test_cd_to_toplevel symrepo 'at symbolic root' SYMLINKS
-ln -s repo/sub/dir subdir-link
-test_cd_to_toplevel subdir-link 'at symbolic subdir'
+ln -s repo/sub/dir subdir-link 2>/dev/null
+test_cd_to_toplevel subdir-link 'at symbolic subdir' SYMLINKS
cd repo
-ln -s sub/dir internal-link
-test_cd_to_toplevel internal-link 'at internal symbolic subdir'
+ln -s sub/dir internal-link 2>/dev/null
+test_cd_to_toplevel internal-link 'at internal symbolic subdir' SYMLINKS
test_done
diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh
index bc0a351392..86291e8399 100755
--- a/t/t3000-ls-files-others.sh
+++ b/t/t3000-ls-files-others.sh
@@ -13,12 +13,18 @@ filesystem.
path2/file2 - a file in a directory
path3-junk - a file to confuse things
path3/file3 - a file in a directory
+ path4 - an empty directory
'
. ./test-lib.sh
date >path0
-ln -s xyzzy path1
-mkdir path2 path3
+if test_have_prereq SYMLINKS
+then
+ ln -s xyzzy path1
+else
+ date > path1
+fi
+mkdir path2 path3 path4
date >path2/file2
date >path2-junk
date >path3/file3
@@ -28,6 +34,7 @@ git update-index --add path3-junk path3/file3
cat >expected1 <<EOF
expected1
expected2
+expected3
output
path0
path1
@@ -35,6 +42,8 @@ path2-junk
path2/file2
EOF
sed -e 's|path2/file2|path2/|' <expected1 >expected2
+cat <expected2 >expected3
+echo path4/ >>expected2
test_expect_success \
'git ls-files --others to show output.' \
@@ -42,7 +51,7 @@ test_expect_success \
test_expect_success \
'git ls-files --others should pick up symlinks.' \
- 'diff output expected1'
+ 'test_cmp expected1 output'
test_expect_success \
'git ls-files --others --directory to show output.' \
@@ -51,6 +60,14 @@ test_expect_success \
test_expect_success \
'git ls-files --others --directory should not get confused.' \
- 'diff output expected2'
+ 'test_cmp expected2 output'
+
+test_expect_success \
+ 'git ls-files --others --directory --no-empty-directory to show output.' \
+ 'git ls-files --others --directory --no-empty-directory >output'
+
+test_expect_success \
+ '--no-empty-directory hides empty directory' \
+ 'test_cmp expected3 output'
test_done
diff --git a/t/t3010-ls-files-killed-modified.sh b/t/t3010-ls-files-killed-modified.sh
index ec14040637..95671c2053 100755
--- a/t/t3010-ls-files-killed-modified.sh
+++ b/t/t3010-ls-files-killed-modified.sh
@@ -38,7 +38,12 @@ modified without reporting path9 and path10.
. ./test-lib.sh
date >path0
-ln -s xyzzy path1
+if test_have_prereq SYMLINKS
+then
+ ln -s xyzzy path1
+else
+ date > path1
+fi
mkdir path2 path3
date >path2/file2
date >path3/file3
@@ -52,8 +57,14 @@ test_expect_success \
rm -fr path? ;# leave path10 alone
date >path2
-ln -s frotz path3
-ln -s nitfol path5
+if test_have_prereq SYMLINKS
+then
+ ln -s frotz path3
+ ln -s nitfol path5
+else
+ date > path3
+ date > path5
+fi
mkdir path0 path1 path6
date >path0/file0
date >path1/file1
@@ -75,7 +86,7 @@ EOF
test_expect_success \
'validate git ls-files -k output.' \
- 'diff .output .expected'
+ 'test_cmp .expected .output'
test_expect_success \
'git ls-files -m to show modified files.' \
@@ -91,6 +102,6 @@ EOF
test_expect_success \
'validate git ls-files -m output.' \
- 'diff .output .expected'
+ 'test_cmp .expected .output'
test_done
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 0de613dc53..9b3fa2bdcd 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -276,6 +276,9 @@ test_expect_success 'fail if the index has unresolved entries' '
test_must_fail git merge "$c5" &&
test_must_fail git merge "$c5" 2> out &&
+ grep "You have not concluded your merge" out &&
+ rm -f .git/MERGE_HEAD &&
+ test_must_fail git merge "$c5" 2> out &&
grep "You are in the middle of a conflicted merge" out
'
diff --git a/t/t3031-merge-criscross.sh b/t/t3031-merge-criscross.sh
new file mode 100755
index 0000000000..7f41607c56
--- /dev/null
+++ b/t/t3031-merge-criscross.sh
@@ -0,0 +1,95 @@
+#!/bin/sh
+
+test_description='merge-recursive backend test'
+
+. ./test-lib.sh
+
+# A <- create some files
+# / \
+# B C <- cause rename/delete conflicts between B and C
+# / \
+# |\ /|
+# | D E |
+# | \ / |
+# | X |
+# | / \ |
+# | / \ |
+# |/ \|
+# F G <- merge E into B, D into C
+# \ /
+# \ /
+# \ /
+# H <- recursive merge crashes
+#
+
+# initialize
+test_expect_success 'setup repo with criss-cross history' '
+ mkdir data &&
+
+ # create a bunch of files
+ n=1 &&
+ while test $n -le 10
+ do
+ echo $n > data/$n &&
+ n=$(($n+1)) ||
+ break
+ done &&
+
+ # check them in
+ git add data &&
+ git commit -m A &&
+ git branch A &&
+
+ # a file in one branch
+ git checkout -b B A &&
+ git rm data/9 &&
+ git add data &&
+ git commit -m B &&
+
+ # with a branch off of it
+ git branch D &&
+
+ # put some commits on D
+ git checkout D &&
+ echo testD > data/testD &&
+ git add data &&
+ git commit -m D &&
+
+ # back up to the top, create another branch and cause
+ # a rename conflict with the file we deleted earlier
+ git checkout -b C A &&
+ git mv data/9 data/new-9 &&
+ git add data &&
+ git commit -m C &&
+
+ # with a branch off of it
+ git branch E &&
+
+ # put a commit on E
+ git checkout E &&
+ echo testE > data/testE &&
+ git add data &&
+ git commit -m E &&
+
+ # now, merge E into B
+ git checkout B &&
+ test_must_fail git merge E &&
+ # force-resolve
+ git add data &&
+ git commit -m F &&
+ git branch F &&
+
+ # and merge D into C
+ git checkout C &&
+ test_must_fail git merge D &&
+ # force-resolve
+ git add data &&
+ git commit -m G &&
+ git branch G
+'
+
+test_expect_success 'recursive merge between F and G, causes segfault' '
+ git merge F
+'
+
+test_done
diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh
index 6e6a2542a2..ee60d03fe8 100755
--- a/t/t3100-ls-tree-restrict.sh
+++ b/t/t3100-ls-tree-restrict.sh
@@ -22,9 +22,21 @@ test_expect_success \
'setup' \
'mkdir path2 path2/baz &&
echo Hi >path0 &&
- ln -s path0 path1 &&
+ if test_have_prereq SYMLINKS
+ then
+ ln -s path0 path1 &&
+ ln -s ../path1 path2/bazbo
+ make_expected () {
+ cat >expected
+ }
+ else
+ printf path0 > path1 &&
+ printf ../path1 > path2/bazbo
+ make_expected () {
+ sed -e "s/120000 /100644 /" >expected
+ }
+ fi &&
echo Lo >path2/foo &&
- ln -s ../path1 path2/bazbo &&
echo Mi >path2/baz/b &&
find path? \( -type f -o -type l \) -print |
xargs git update-index --add &&
@@ -41,7 +53,7 @@ test_output () {
test_expect_success \
'ls-tree plain' \
'git ls-tree $tree >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
100644 blob X path0
120000 blob X path1
040000 tree X path2
@@ -51,7 +63,7 @@ EOF
test_expect_success \
'ls-tree recursive' \
'git ls-tree -r $tree >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
100644 blob X path0
120000 blob X path1
100644 blob X path2/baz/b
@@ -63,7 +75,7 @@ EOF
test_expect_success \
'ls-tree recursive with -t' \
'git ls-tree -r -t $tree >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
100644 blob X path0
120000 blob X path1
040000 tree X path2
@@ -77,7 +89,7 @@ EOF
test_expect_success \
'ls-tree recursive with -d' \
'git ls-tree -r -d $tree >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
040000 tree X path2
040000 tree X path2/baz
EOF
@@ -86,7 +98,7 @@ EOF
test_expect_success \
'ls-tree filtered with path' \
'git ls-tree $tree path >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
EOF
test_output'
@@ -96,7 +108,7 @@ EOF
test_expect_success \
'ls-tree filtered with path1 path0' \
'git ls-tree $tree path1 path0 >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
100644 blob X path0
120000 blob X path1
EOF
@@ -105,7 +117,7 @@ EOF
test_expect_success \
'ls-tree filtered with path0/' \
'git ls-tree $tree path0/ >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
EOF
test_output'
@@ -114,7 +126,7 @@ EOF
test_expect_success \
'ls-tree filtered with path2' \
'git ls-tree $tree path2 >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
040000 tree X path2
EOF
test_output'
@@ -123,7 +135,7 @@ EOF
test_expect_success \
'ls-tree filtered with path2/' \
'git ls-tree $tree path2/ >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
040000 tree X path2/baz
120000 blob X path2/bazbo
100644 blob X path2/foo
@@ -135,7 +147,7 @@ EOF
test_expect_success \
'ls-tree filtered with path2/baz' \
'git ls-tree $tree path2/baz >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
040000 tree X path2/baz
EOF
test_output'
@@ -143,14 +155,14 @@ EOF
test_expect_success \
'ls-tree filtered with path2/bak' \
'git ls-tree $tree path2/bak >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
EOF
test_output'
test_expect_success \
'ls-tree -t filtered with path2/bak' \
'git ls-tree -t $tree path2/bak >current &&
- cat >expected <<\EOF &&
+ make_expected <<\EOF &&
040000 tree X path2
EOF
test_output'
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 1b1e9ece57..d59a9b4aef 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -121,7 +121,7 @@ test_expect_success 'renaming a symref is not allowed' \
! test -f .git/refs/heads/master3
'
-test_expect_success \
+test_expect_success SYMLINKS \
'git branch -m u v should fail when the reflog for u is a symlink' '
git branch -l u &&
mv .git/logs/refs/heads/u real-u &&
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
new file mode 100755
index 0000000000..809d1c4ed4
--- /dev/null
+++ b/t/t3203-branch-output.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+test_description='git branch display tests'
+. ./test-lib.sh
+
+test_expect_success 'make commits' '
+ echo content >file &&
+ git add file &&
+ git commit -m one &&
+ echo content >>file &&
+ git commit -a -m two
+'
+
+test_expect_success 'make branches' '
+ git branch branch-one
+ git branch branch-two HEAD^
+'
+
+test_expect_success 'make remote branches' '
+ git update-ref refs/remotes/origin/branch-one branch-one
+ git update-ref refs/remotes/origin/branch-two branch-two
+ git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/branch-one
+'
+
+cat >expect <<'EOF'
+ branch-one
+ branch-two
+* master
+EOF
+test_expect_success 'git branch shows local branches' '
+ git branch >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ origin/HEAD -> origin/branch-one
+ origin/branch-one
+ origin/branch-two
+EOF
+test_expect_success 'git branch -r shows remote branches' '
+ git branch -r >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ branch-one
+ branch-two
+* master
+ remotes/origin/HEAD -> origin/branch-one
+ remotes/origin/branch-one
+ remotes/origin/branch-two
+EOF
+test_expect_success 'git branch -a shows local and remote branches' '
+ git branch -a >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+two
+one
+two
+EOF
+test_expect_success 'git branch -v shows branch summaries' '
+ git branch -v >tmp &&
+ awk "{print \$NF}" <tmp >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+* (no branch)
+ branch-one
+ branch-two
+ master
+EOF
+test_expect_success 'git branch shows detached HEAD properly' '
+ git checkout HEAD^0 &&
+ git branch >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b7a670ef40..c5c29ccc4f 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -14,7 +14,8 @@ export GIT_AUTHOR_EMAIL
test_expect_success \
'prepare repository with topic branches' \
- 'echo First > A &&
+ 'git config core.logAllRefUpdates true &&
+ echo First > A &&
git update-index --add A &&
git commit -m "Add A." &&
git checkout -b my-topic-branch &&
@@ -40,13 +41,48 @@ test_expect_success \
git tag topic
'
+test_expect_success 'rebase on dirty worktree' '
+ echo dirty >> A &&
+ test_must_fail git rebase master'
+
+test_expect_success 'rebase on dirty cache' '
+ git add A &&
+ test_must_fail git rebase master'
+
test_expect_success 'rebase against master' '
+ git reset --hard HEAD &&
git rebase master'
+test_expect_success 'rebase against master twice' '
+ git rebase master >out &&
+ grep "Current branch my-topic-branch is up to date" out
+'
+
+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_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_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_expect_success \
'the rebase operation should not have destroyed author information' \
'! (git log | grep "Author:" | grep "<>")'
+test_expect_success 'HEAD was detached during rebase' '
+ test $(git rev-parse HEAD@{1}) != $(git rev-parse my-topic-branch@{1})
+'
+
test_expect_success 'rebase after merge master' '
git reset --hard topic &&
git merge master &&
@@ -78,10 +114,23 @@ test_expect_success 'rebase a single mode change' '
git checkout -b modechange HEAD^ &&
echo 1 > X &&
git add X &&
- chmod a+x A &&
+ test_chmod +x A &&
test_tick &&
- git commit -m modechange A X &&
+ git commit -m modechange &&
GIT_TRACE=1 git rebase master
'
+test_expect_success 'Show verbose error when HEAD could not be detached' '
+ : > B &&
+ test_must_fail git rebase topic 2> output.err > output.out &&
+ grep "Untracked working tree file .B. would be overwritten" output.err
+'
+
+test_expect_success 'rebase -q is quiet' '
+ rm B &&
+ git checkout -b quiet topic &&
+ git rebase -q master > output.out 2>&1 &&
+ test ! -s output.out
+'
+
test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 4becc5513d..4cae019521 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -10,6 +10,10 @@ that the result still makes sense.
'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+set_fake_editor
+
# set up two branches like this:
#
# A - B - C - D - E
@@ -61,39 +65,6 @@ test_expect_success 'setup' '
git tag I
'
-echo "#!$SHELL_PATH" >fake-editor.sh
-cat >> fake-editor.sh <<\EOF
-case "$1" in
-*/COMMIT_EDITMSG)
- test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1"
- test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1"
- exit
- ;;
-esac
-test -z "$EXPECT_COUNT" ||
- test "$EXPECT_COUNT" = $(sed -e '/^#/d' -e '/^$/d' < "$1" | wc -l) ||
- exit
-test -z "$FAKE_LINES" && exit
-grep -v '^#' < "$1" > "$1".tmp
-rm -f "$1"
-cat "$1".tmp
-action=pick
-for line in $FAKE_LINES; do
- case $line in
- squash|edit)
- action="$line";;
- *)
- echo sed -n "${line}s/^pick/$action/p"
- sed -n "${line}p" < "$1".tmp
- sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
- action=pick;;
- esac
-done
-EOF
-
-test_set_editor "$(pwd)/fake-editor.sh"
-chmod a+x fake-editor.sh
-
test_expect_success 'no changes are a nop' '
git rebase -i F &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&
@@ -148,11 +119,11 @@ index e69de29..00750ed 100644
EOF
cat > expect2 << EOF
-<<<<<<< HEAD:file1
+<<<<<<< HEAD
2
=======
3
->>>>>>> b7ca976... G:file1
+>>>>>>> b7ca976... G
EOF
test_expect_success 'stop on conflicting pick' '
@@ -488,4 +459,15 @@ test_expect_success 'submodule rebase -i' '
FAKE_LINES="1 squash 2 3" git rebase -i A
'
+test_expect_success 'avoid unnecessary reset' '
+ git checkout master &&
+ test-chmtime =123456789 file3 &&
+ git update-index --refresh &&
+ HEAD=$(git rev-parse HEAD) &&
+ git rebase -i HEAD~4 &&
+ test $HEAD = $(git rev-parse HEAD) &&
+ MTIME=$(test-chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&
+ test 123456789 = $MTIME
+'
+
test_done
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 5391080943..85fc7c4af8 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -22,7 +22,8 @@ test_expect_success setup '
git checkout topic &&
quick_one A &&
quick_one B &&
- quick_one Z
+ quick_one Z &&
+ git tag start
'
@@ -41,4 +42,24 @@ test_expect_success 'rebase -m' '
'
+test_expect_success 'rebase --stat' '
+ git reset --hard start
+ git rebase --stat master >diffstat.txt &&
+ grep "^ fileX | *1 +$" diffstat.txt
+'
+
+test_expect_success 'rebase w/config rebase.stat' '
+ git reset --hard start
+ git config rebase.stat true &&
+ git rebase master >diffstat.txt &&
+ grep "^ fileX | *1 +$" diffstat.txt
+'
+
+test_expect_success 'rebase -n overrides config rebase.stat config' '
+ git reset --hard start
+ git config rebase.stat true &&
+ git rebase -n master >diffstat.txt &&
+ ! grep "^ fileX | *1 +$" diffstat.txt
+'
+
test_done
diff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh
index 5816415aaf..c49143a1a4 100755
--- a/t/t3410-rebase-preserve-dropped-merges.sh
+++ b/t/t3410-rebase-preserve-dropped-merges.sh
@@ -22,47 +22,17 @@ rewritten.
# where B, D and G touch the same file.
test_expect_success 'setup' '
- : > file1 &&
- git add file1 &&
- test_tick &&
- git commit -m A &&
- git tag A &&
- echo 1 > file1 &&
- test_tick &&
- git commit -m B file1 &&
- : > file2 &&
- git add file2 &&
- test_tick &&
- git commit -m C &&
- echo 2 > file1 &&
- test_tick &&
- git commit -m D file1 &&
- : > file3 &&
- git add file3 &&
- test_tick &&
- git commit -m E &&
- git tag E &&
- git checkout -b branch1 A &&
- : > file4 &&
- git add file4 &&
- test_tick &&
- git commit -m F &&
- git tag F &&
- echo 3 > file1 &&
- test_tick &&
- git commit -m G file1 &&
- git tag G &&
- : > file5 &&
- git add file5 &&
- test_tick &&
- git commit -m H &&
- git tag H &&
- git checkout -b branch2 F &&
- : > file6 &&
- git add file6 &&
- test_tick &&
- git commit -m I &&
- git tag I
+ test_commit A file1 &&
+ test_commit B file1 1 &&
+ test_commit C file2 &&
+ test_commit D file1 2 &&
+ test_commit E file3 &&
+ git checkout A &&
+ test_commit F file4 &&
+ test_commit G file1 3 &&
+ test_commit H file5 &&
+ git checkout F &&
+ test_commit I file6
'
# A - B - C - D - E
@@ -72,68 +42,44 @@ test_expect_success 'setup' '
# I -- G2 -- J -- K I -- K
# G2 = same changes as G
test_expect_success 'skip same-resolution merges with -p' '
- git checkout branch1 &&
+ git checkout H &&
! git merge E &&
- echo 23 > file1 &&
- git add file1 &&
- git commit -m L &&
- git checkout branch2 &&
- echo 3 > file1 &&
- git commit -a -m G2 &&
+ test_commit L file1 23 &&
+ git checkout I &&
+ test_commit G2 file1 3 &&
! git merge E &&
- echo 23 > file1 &&
- git add file1 &&
- git commit -m J &&
- echo file7 > file7 &&
- git add file7 &&
- git commit -m K &&
- GIT_EDITOR=: git rebase -i -p branch1 &&
- test $(git rev-parse branch2^^) = $(git rev-parse branch1) &&
+ test_commit J file1 23 &&
+ test_commit K file7 file7 &&
+ git rebase -i -p L &&
+ test $(git rev-parse HEAD^^) = $(git rev-parse L) &&
test "23" = "$(cat file1)" &&
- test "" = "$(cat file6)" &&
- test "file7" = "$(cat file7)" &&
-
- git checkout branch1 &&
- git reset --hard H &&
- git checkout branch2 &&
- git reset --hard I
+ test "I" = "$(cat file6)" &&
+ test "file7" = "$(cat file7)"
'
# A - B - C - D - E
# \ \ \
-# F - G - H -- L \ --> L
-# \ | \
-# I -- G2 -- J -- K I -- G2 -- K
+# F - G - H -- L2 \ --> L2
+# \ | \
+# I -- G3 --- J2 -- K2 I -- G3 -- K2
# G2 = different changes as G
test_expect_success 'keep different-resolution merges with -p' '
- git checkout branch1 &&
+ git checkout H &&
! git merge E &&
- echo 23 > file1 &&
- git add file1 &&
- git commit -m L &&
- git checkout branch2 &&
- echo 4 > file1 &&
- git commit -a -m G2 &&
+ test_commit L2 file1 23 &&
+ git checkout I &&
+ test_commit G3 file1 4 &&
! git merge E &&
- echo 24 > file1 &&
- git add file1 &&
- git commit -m J &&
- echo file7 > file7 &&
- git add file7 &&
- git commit -m K &&
- ! GIT_EDITOR=: git rebase -i -p branch1 &&
+ test_commit J2 file1 24 &&
+ test_commit K2 file7 file7 &&
+ test_must_fail git rebase -i -p L2 &&
echo 234 > file1 &&
git add file1 &&
- GIT_EDITOR=: git rebase --continue &&
- test $(git rev-parse branch2^^^) = $(git rev-parse branch1) &&
+ git rebase --continue &&
+ test $(git rev-parse HEAD^^^) = $(git rev-parse L2) &&
test "234" = "$(cat file1)" &&
- test "" = "$(cat file6)" &&
- test "file7" = "$(cat file7)" &&
-
- git checkout branch1 &&
- git reset --hard H &&
- git checkout branch2 &&
- git reset --hard I
+ test "I" = "$(cat file6)" &&
+ test "file7" = "$(cat file7)"
'
test_done
diff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh
index aacfaae843..14a23cd872 100755
--- a/t/t3411-rebase-preserve-around-merges.sh
+++ b/t/t3411-rebase-preserve-around-merges.sh
@@ -5,44 +5,14 @@
test_description='git rebase preserve merges
-This test runs git rebase with and tries to squash a commit from after a merge
-to before the merge.
+This test runs git rebase with -p and tries to squash a commit from after
+a merge to before the merge.
'
. ./test-lib.sh
-# Copy/paste from t3404-rebase-interactive.sh
-echo "#!$SHELL_PATH" >fake-editor.sh
-cat >> fake-editor.sh <<\EOF
-case "$1" in
-*/COMMIT_EDITMSG)
- test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1"
- test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1"
- exit
- ;;
-esac
-test -z "$EXPECT_COUNT" ||
- test "$EXPECT_COUNT" = $(sed -e '/^#/d' -e '/^$/d' < "$1" | wc -l) ||
- exit
-test -z "$FAKE_LINES" && exit
-grep -v '^#' < "$1" > "$1".tmp
-rm -f "$1"
-cat "$1".tmp
-action=pick
-for line in $FAKE_LINES; do
- case $line in
- squash|edit)
- action="$line";;
- *)
- echo sed -n "${line}s/^pick/$action/p"
- sed -n "${line}p" < "$1".tmp
- sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
- action=pick;;
- esac
-done
-EOF
+. "$TEST_DIRECTORY"/lib-rebase.sh
-test_set_editor "$(pwd)/fake-editor.sh"
-chmod a+x fake-editor.sh
+set_fake_editor
# set up two branches like this:
#
@@ -51,27 +21,13 @@ chmod a+x fake-editor.sh
# -- C1 --
test_expect_success 'setup' '
- touch a &&
- touch b &&
- git add a &&
- git commit -m A1 &&
- git tag A1
- git add b &&
- git commit -m B1 &&
- git tag B1 &&
- git checkout -b branch &&
- touch c &&
- git add c &&
- git commit -m C1 &&
- git checkout master &&
- touch d &&
- git add d &&
- git commit -m D1 &&
- git merge branch &&
- touch f &&
- git add f &&
- git commit -m F1 &&
- git tag F1
+ test_commit A1 &&
+ test_commit B1 &&
+ test_commit C1 &&
+ git reset --hard B1 &&
+ test_commit D1 &&
+ test_merge E1 C1 &&
+ test_commit F1
'
# Should result in:
@@ -82,7 +38,7 @@ test_expect_success 'setup' '
#
test_expect_success 'squash F1 into D1' '
FAKE_LINES="1 squash 3 2" git rebase -i -p B1 &&
- test "$(git rev-parse HEAD^2)" = "$(git rev-parse branch)" &&
+ test "$(git rev-parse HEAD^2)" = "$(git rev-parse C1)" &&
test "$(git rev-parse HEAD~2)" = "$(git rev-parse B1)" &&
git tag E2
'
@@ -100,32 +56,15 @@ test_expect_success 'squash F1 into D1' '
# And rebase G1..M1 onto E2
test_expect_success 'rebase two levels of merge' '
- git checkout -b branch2 A1 &&
- touch g &&
- git add g &&
- git commit -m G1 &&
- git checkout -b branch3 &&
- touch h
- git add h &&
- git commit -m H1 &&
- git checkout -b branch4 &&
- touch i &&
- git add i &&
- git commit -m I1 &&
- git tag I1 &&
- git checkout branch3 &&
- touch j &&
- git add j &&
- git commit -m J1 &&
- git merge I1 --no-commit &&
- git commit -m K1 &&
- git tag K1 &&
- git checkout branch2 &&
- touch l &&
- git add l &&
- git commit -m L1 &&
- git merge K1 --no-commit &&
- git commit -m M1 &&
+ test_commit G1 &&
+ test_commit H1 &&
+ test_commit I1 &&
+ git checkout -b branch3 H1 &&
+ test_commit J1 &&
+ test_merge K1 I1 &&
+ git checkout -b branch2 G1 &&
+ test_commit L1 &&
+ test_merge M1 K1 &&
GIT_EDITOR=: git rebase -i -p E2 &&
test "$(git rev-parse HEAD~3)" = "$(git rev-parse E2)" &&
test "$(git rev-parse HEAD~2)" = "$(git rev-parse HEAD^2^2~2)" &&
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
new file mode 100755
index 0000000000..5869061c5b
--- /dev/null
+++ b/t/t3412-rebase-root.sh
@@ -0,0 +1,280 @@
+#!/bin/sh
+
+test_description='git rebase --root
+
+Tests if git rebase --root --onto <newparent> can rebase the root commit.
+'
+. ./test-lib.sh
+
+log_with_names () {
+ git rev-list --topo-order --parents --pretty="tformat:%s" HEAD |
+ git name-rev --stdin --name-only --refs=refs/heads/$1
+}
+
+
+test_expect_success 'prepare repository' '
+ test_commit 1 A &&
+ test_commit 2 A &&
+ git symbolic-ref HEAD refs/heads/other &&
+ rm .git/index &&
+ test_commit 3 B &&
+ test_commit 1b A 1 &&
+ test_commit 4 B
+'
+
+test_expect_success 'rebase --root expects --onto' '
+ test_must_fail git rebase --root
+'
+
+test_expect_success 'setup pre-rebase hook' '
+ mkdir -p .git/hooks &&
+ cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+EOF
+ chmod +x .git/hooks/pre-rebase
+'
+cat > expect <<EOF
+4
+3
+2
+1
+EOF
+
+test_expect_success 'rebase --root --onto <newbase>' '
+ git checkout -b work &&
+ git rebase --root --onto master &&
+ git log --pretty=tformat:"%s" > rebased &&
+ test_cmp expect rebased
+'
+
+test_expect_success 'pre-rebase got correct input (1)' '
+ test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
+test_expect_success 'rebase --root --onto <newbase> <branch>' '
+ git branch work2 other &&
+ git rebase --root --onto master work2 &&
+ git log --pretty=tformat:"%s" > rebased2 &&
+ test_cmp expect rebased2
+'
+
+test_expect_success 'pre-rebase got correct input (2)' '
+ test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2
+'
+
+test_expect_success 'rebase -i --root --onto <newbase>' '
+ git checkout -b work3 other &&
+ git rebase -i --root --onto master &&
+ git log --pretty=tformat:"%s" > rebased3 &&
+ test_cmp expect rebased3
+'
+
+test_expect_success 'pre-rebase got correct input (3)' '
+ test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
+test_expect_success 'rebase -i --root --onto <newbase> <branch>' '
+ git branch work4 other &&
+ git rebase -i --root --onto master work4 &&
+ git log --pretty=tformat:"%s" > rebased4 &&
+ test_cmp expect rebased4
+'
+
+test_expect_success 'pre-rebase got correct input (4)' '
+ test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work4
+'
+
+test_expect_success 'rebase -i -p with linear history' '
+ git checkout -b work5 other &&
+ git rebase -i -p --root --onto master &&
+ git log --pretty=tformat:"%s" > rebased5 &&
+ test_cmp expect rebased5
+'
+
+test_expect_success 'pre-rebase got correct input (5)' '
+ test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
+test_expect_success 'set up merge history' '
+ git checkout other^ &&
+ git checkout -b side &&
+ test_commit 5 C &&
+ git checkout other &&
+ git merge side
+'
+
+cat > expect-side <<'EOF'
+commit work6 work6~1 work6^2
+Merge branch 'side' into other
+commit work6^2 work6~2
+5
+commit work6~1 work6~2
+4
+commit work6~2 work6~3
+3
+commit work6~3 work6~4
+2
+commit work6~4
+1
+EOF
+
+test_expect_success 'rebase -i -p with merge' '
+ git checkout -b work6 other &&
+ git rebase -i -p --root --onto master &&
+ log_with_names work6 > rebased6 &&
+ test_cmp expect-side rebased6
+'
+
+test_expect_success 'set up second root and merge' '
+ git symbolic-ref HEAD refs/heads/third &&
+ rm .git/index &&
+ rm A B C &&
+ test_commit 6 D &&
+ git checkout other &&
+ git merge third
+'
+
+cat > expect-third <<'EOF'
+commit work7 work7~1 work7^2
+Merge branch 'third' into other
+commit work7^2 work7~4
+6
+commit work7~1 work7~2 work7~1^2
+Merge branch 'side' into other
+commit work7~1^2 work7~3
+5
+commit work7~2 work7~3
+4
+commit work7~3 work7~4
+3
+commit work7~4 work7~5
+2
+commit work7~5
+1
+EOF
+
+test_expect_success 'rebase -i -p with two roots' '
+ git checkout -b work7 other &&
+ git rebase -i -p --root --onto master &&
+ log_with_names work7 > rebased7 &&
+ test_cmp expect-third rebased7
+'
+
+test_expect_success 'setup pre-rebase hook that fails' '
+ mkdir -p .git/hooks &&
+ cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+false
+EOF
+ chmod +x .git/hooks/pre-rebase
+'
+
+test_expect_success 'pre-rebase hook stops rebase' '
+ git checkout -b stops1 other &&
+ test_must_fail git rebase --root --onto master &&
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1
+ test 0 = $(git rev-list other...stops1 | wc -l)
+'
+
+test_expect_success 'pre-rebase hook stops rebase -i' '
+ git checkout -b stops2 other &&
+ test_must_fail git rebase --root --onto master &&
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops2
+ test 0 = $(git rev-list other...stops2 | wc -l)
+'
+
+test_expect_success 'remove pre-rebase hook' '
+ rm -f .git/hooks/pre-rebase
+'
+
+test_expect_success 'set up a conflict' '
+ git checkout master &&
+ echo conflict > B &&
+ git add B &&
+ git commit -m conflict
+'
+
+test_expect_success 'rebase --root with conflict (first part)' '
+ git checkout -b conflict1 other &&
+ test_must_fail git rebase --root --onto master &&
+ git ls-files -u | grep "B$"
+'
+
+test_expect_success 'fix the conflict' '
+ echo 3 > B &&
+ git add B
+'
+
+cat > expect-conflict <<EOF
+6
+5
+4
+3
+conflict
+2
+1
+EOF
+
+test_expect_success 'rebase --root with conflict (second part)' '
+ git rebase --continue &&
+ git log --pretty=tformat:"%s" > conflict1 &&
+ test_cmp expect-conflict conflict1
+'
+
+test_expect_success 'rebase -i --root with conflict (first part)' '
+ git checkout -b conflict2 other &&
+ test_must_fail git rebase -i --root --onto master &&
+ git ls-files -u | grep "B$"
+'
+
+test_expect_success 'fix the conflict' '
+ echo 3 > B &&
+ git add B
+'
+
+test_expect_success 'rebase -i --root with conflict (second part)' '
+ git rebase --continue &&
+ git log --pretty=tformat:"%s" > conflict2 &&
+ test_cmp expect-conflict conflict2
+'
+
+cat >expect-conflict-p <<\EOF
+commit conflict3 conflict3~1 conflict3^2
+Merge branch 'third' into other
+commit conflict3^2 conflict3~4
+6
+commit conflict3~1 conflict3~2 conflict3~1^2
+Merge branch 'side' into other
+commit conflict3~1^2 conflict3~3
+5
+commit conflict3~2 conflict3~3
+4
+commit conflict3~3 conflict3~4
+3
+commit conflict3~4 conflict3~5
+conflict
+commit conflict3~5 conflict3~6
+2
+commit conflict3~6
+1
+EOF
+
+test_expect_success 'rebase -i -p --root with conflict (first part)' '
+ git checkout -b conflict3 other &&
+ test_must_fail git rebase -i -p --root --onto master &&
+ git ls-files -u | grep "B$"
+'
+
+test_expect_success 'fix the conflict' '
+ echo 3 > B &&
+ git add B
+'
+
+test_expect_success 'rebase -i -p --root with conflict (second part)' '
+ git rebase --continue &&
+ log_with_names conflict3 >out &&
+ test_cmp expect-conflict-p out
+'
+
+test_done
diff --git a/t/t3409-rebase-hook.sh b/t/t3413-rebase-hook.sh
index 1f1b850677..098b75507b 100755
--- a/t/t3409-rebase-hook.sh
+++ b/t/t3413-rebase-hook.sh
@@ -118,7 +118,11 @@ test_expect_success 'pre-rebase hook stops rebase (1)' '
test_expect_success 'pre-rebase hook stops rebase (2)' '
git checkout test &&
git reset --hard side &&
- EDITOR=true test_must_fail git rebase -i master &&
+ (
+ EDITOR=:
+ export EDITOR
+ test_must_fail git rebase -i master
+ ) &&
test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
test 0 = $(git rev-list HEAD...side | wc -l)
'
diff --git a/t/t3414-rebase-preserve-onto.sh b/t/t3414-rebase-preserve-onto.sh
new file mode 100755
index 0000000000..ee0a6cccfd
--- /dev/null
+++ b/t/t3414-rebase-preserve-onto.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Greg Price
+#
+
+test_description='git rebase -p should respect --onto
+
+In a rebase with --onto, we should rewrite all the commits that
+aren'"'"'t on top of $ONTO, even if they are on top of $UPSTREAM.
+'
+. ./test-lib.sh
+
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+# Set up branches like this:
+# A1---B1---E1---F1---G1
+# \ \ /
+# \ \--C1---D1--/
+# H1
+
+test_expect_success 'setup' '
+ test_commit A1 &&
+ test_commit B1 &&
+ test_commit C1 &&
+ test_commit D1 &&
+ git reset --hard B1 &&
+ test_commit E1 &&
+ test_commit F1 &&
+ test_merge G1 D1 &&
+ git reset --hard A1 &&
+ test_commit H1
+'
+
+# Now rebase merge G1 from both branches' base B1, both should move:
+# A1---B1---E1---F1---G1
+# \ \ /
+# \ \--C1---D1--/
+# \
+# H1---E2---F2---G2
+# \ /
+# \--C2---D2--/
+
+test_expect_success 'rebase from B1 onto H1' '
+ git checkout G1 &&
+ git rebase -p --onto H1 B1 &&
+ test "$(git rev-parse HEAD^1^1^1)" = "$(git rev-parse H1)" &&
+ test "$(git rev-parse HEAD^2^1^1)" = "$(git rev-parse H1)"
+'
+
+# On the other hand if rebase from E1 which is within one branch,
+# then the other branch stays:
+# A1---B1---E1---F1---G1
+# \ \ /
+# \ \--C1---D1--/
+# \ \
+# H1-----F3-----G3
+
+test_expect_success 'rebase from E1 onto H1' '
+ git checkout G1 &&
+ git rebase -p --onto H1 E1 &&
+ test "$(git rev-parse HEAD^1^1)" = "$(git rev-parse H1)" &&
+ test "$(git rev-parse HEAD^2)" = "$(git rev-parse D1)"
+'
+
+# And the same if we rebase from a commit in the second-parent branch.
+# A1---B1---E1---F1----G1
+# \ \ \ /
+# \ \--C1---D1-\-/
+# \ \
+# H1------D3------G4
+
+test_expect_success 'rebase from C1 onto H1' '
+ git checkout G1 &&
+ git rev-list --first-parent --pretty=oneline C1..G1 &&
+ git rebase -p --onto H1 C1 &&
+ test "$(git rev-parse HEAD^2^1)" = "$(git rev-parse H1)" &&
+ test "$(git rev-parse HEAD^1)" = "$(git rev-parse F1)"
+'
+
+test_done
diff --git a/t/t3505-cherry-pick-empty.sh b/t/t3505-cherry-pick-empty.sh
index 9aaeabd972..e51e505a9f 100755
--- a/t/t3505-cherry-pick-empty.sh
+++ b/t/t3505-cherry-pick-empty.sh
@@ -17,11 +17,11 @@ test_expect_success setup '
'
-test_expect_code 1 'cherry-pick an empty commit' '
-
- git checkout master &&
- git cherry-pick empty-branch
-
+test_expect_success 'cherry-pick an empty commit' '
+ git checkout master && {
+ git cherry-pick empty-branch
+ test "$?" = 1
+ }
'
test_expect_success 'index lockfile was removed' '
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 95542e9cfe..76b1bb4545 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -12,30 +12,37 @@ test_expect_success \
'Initialize test directory' \
"touch -- foo bar baz 'space embedded' -q &&
git add -- foo bar baz 'space embedded' -q &&
- git commit -m 'add normal files' &&
- test_tabs=y &&
- if touch -- 'tab embedded' 'newline
-embedded'
- then
+ git commit -m 'add normal files'"
+
+if touch -- 'tab embedded' 'newline
+embedded' 2>/dev/null
+then
+ test_set_prereq FUNNYNAMES
+else
+ say 'Your filesystem does not allow tabs in filenames.'
+fi
+
+test_expect_success FUNNYNAMES 'add files with funny names' "
git add -- 'tab embedded' 'newline
embedded' &&
git commit -m 'add files with tabs and newlines'
- else
- say 'Your filesystem does not allow tabs in filenames.'
- test_tabs=n
- fi"
+"
+# Determine rm behavior
# Later we will try removing an unremovable path to make sure
# git rm barfs, but if the test is run as root that cannot be
# arranged.
-test_expect_success \
- 'Determine rm behavior' \
- ': >test-file
- chmod a-w .
- rm -f test-file
- test -f test-file && test_failed_remove=y
- chmod 775 .
- rm -f test-file'
+: >test-file
+chmod a-w .
+rm -f test-file 2>/dev/null
+if test -f test-file
+then
+ test_set_prereq RO_DIR
+else
+ say 'skipping removal failure test (perhaps running as root?)'
+fi
+chmod 775 .
+rm -f test-file
test_expect_success \
'Pre-check that foo exists and is in index before git rm foo' \
@@ -100,20 +107,16 @@ test_expect_success \
'Test that "git rm -- -q" succeeds (remove a file that looks like an option)' \
'git rm -- -q'
-test "$test_tabs" = y && test_expect_success \
+test_expect_success FUNNYNAMES \
"Test that \"git rm -f\" succeeds with embedded space, tab, or newline characters." \
"git rm -f 'space embedded' 'tab embedded' 'newline
embedded'"
-if test "$test_failed_remove" = y; then
-chmod a-w .
-test_expect_success \
- 'Test that "git rm -f" fails if its rm fails' \
- 'test_must_fail git rm -f baz'
-chmod 775 .
-else
- test_expect_success 'skipping removal failure (perhaps running as root?)' :
-fi
+test_expect_success RO_DIR 'Test that "git rm -f" fails if its rm fails' '
+ chmod a-w . &&
+ test_must_fail git rm -f baz &&
+ chmod 775 .
+'
test_expect_success \
'When the rm in "git rm -f" fails, it should not remove the file from the index' \
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 9f6454d2ff..85eb0fbf96 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -30,7 +30,7 @@ test_expect_success \
*) echo fail; git ls-files --stage xfoo1; (exit 1);;
esac'
-test_expect_success 'git add: filemode=0 should not get confused by symlink' '
+test_expect_success SYMLINKS 'git add: filemode=0 should not get confused by symlink' '
rm -f xfoo1 &&
ln -s foo xfoo1 &&
git add xfoo1 &&
@@ -51,7 +51,7 @@ test_expect_success \
*) echo fail; git ls-files --stage xfoo2; (exit 1);;
esac'
-test_expect_success 'git add: filemode=0 should not get confused by symlink' '
+test_expect_success SYMLINKS 'git add: filemode=0 should not get confused by symlink' '
rm -f xfoo2 &&
ln -s foo xfoo2 &&
git update-index --add xfoo2 &&
@@ -61,7 +61,7 @@ test_expect_success 'git add: filemode=0 should not get confused by symlink' '
esac
'
-test_expect_success \
+test_expect_success SYMLINKS \
'git update-index --add: Test that executable bit is not used...' \
'git config core.filemode 0 &&
ln -s xfoo2 xfoo3 &&
@@ -179,7 +179,7 @@ test_expect_success 'git add --refresh' '
test -z "`git diff-index HEAD -- foo`"
'
-test_expect_success 'git add should fail atomically upon an unreadable file' '
+test_expect_success POSIXPERM 'git add should fail atomically upon an unreadable file' '
git reset --hard &&
date >foo1 &&
date >foo2 &&
@@ -190,7 +190,7 @@ test_expect_success 'git add should fail atomically upon an unreadable file' '
rm -f foo2
-test_expect_success 'git add --ignore-errors' '
+test_expect_success POSIXPERM 'git add --ignore-errors' '
git reset --hard &&
date >foo1 &&
date >foo2 &&
@@ -201,7 +201,7 @@ test_expect_success 'git add --ignore-errors' '
rm -f foo2
-test_expect_success 'git add (add.ignore-errors)' '
+test_expect_success POSIXPERM 'git add (add.ignore-errors)' '
git config add.ignore-errors 1 &&
git reset --hard &&
date >foo1 &&
@@ -212,7 +212,7 @@ test_expect_success 'git add (add.ignore-errors)' '
'
rm -f foo2
-test_expect_success 'git add (add.ignore-errors = false)' '
+test_expect_success POSIXPERM 'git add (add.ignore-errors = false)' '
git config add.ignore-errors 0 &&
git reset --hard &&
date >foo1 &&
@@ -221,8 +221,21 @@ test_expect_success 'git add (add.ignore-errors = false)' '
test_must_fail git add --verbose . &&
! ( git ls-files foo1 | grep foo1 )
'
+rm -f foo2
+
+test_expect_success POSIXPERM '--no-ignore-errors overrides config' '
+ git config add.ignore-errors 1 &&
+ git reset --hard &&
+ date >foo1 &&
+ date >foo2 &&
+ chmod 0 foo2 &&
+ test_must_fail git add --verbose --no-ignore-errors . &&
+ ! ( git ls-files foo1 | grep foo1 ) &&
+ git config add.ignore-errors 0
+'
+rm -f foo2
-test_expect_success 'git add '\''fo\[ou\]bar'\'' ignores foobar' '
+test_expect_success BSLASHPSPEC "git add 'fo\\[ou\\]bar' ignores foobar" '
git reset --hard &&
touch fo\[ou\]bar foobar &&
git add '\''fo\[ou\]bar'\'' &&
@@ -230,4 +243,16 @@ test_expect_success 'git add '\''fo\[ou\]bar'\'' ignores foobar' '
! ( git ls-files foobar | grep foobar )
'
+test_expect_success 'git add to resolve conflicts on otherwise ignored path' '
+ git reset --hard &&
+ H=$(git rev-parse :1/2/a) &&
+ (
+ echo "100644 $H 1 track-this"
+ echo "100644 $H 3 track-this"
+ ) | git update-index --index-info &&
+ echo track-this >>.gitignore &&
+ echo resolved >track-this &&
+ git add track-this
+'
+
test_done
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index e95663d8e6..fd2a55a5c2 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -3,6 +3,11 @@
test_description='add -i basic tests'
. ./test-lib.sh
+if ! test_have_prereq PERL; then
+ say 'skipping git add -i tests, perl not available'
+ test_done
+fi
+
test_expect_success 'setup (initial)' '
echo content >file &&
git add file &&
@@ -135,10 +140,12 @@ test_expect_success 'real edit works' '
if test "$(git config --bool core.filemode)" = false
then
- say 'skipping filemode tests (filesystem does not properly support modes)'
+ say 'skipping filemode tests (filesystem does not properly support modes)'
else
+ test_set_prereq FILEMODE
+fi
-test_expect_success 'patch does not affect mode' '
+test_expect_success FILEMODE 'patch does not affect mode' '
git reset --hard &&
echo content >>file &&
chmod +x file &&
@@ -147,7 +154,7 @@ test_expect_success 'patch does not affect mode' '
git diff file | grep "new mode"
'
-test_expect_success 'stage mode but not hunk' '
+test_expect_success FILEMODE 'stage mode but not hunk' '
git reset --hard &&
echo content >>file &&
chmod +x file &&
@@ -156,7 +163,44 @@ test_expect_success 'stage mode but not hunk' '
git diff file | grep "+content"
'
-fi
# end of tests disabled when filemode is not usable
+test_expect_success 'setup again' '
+ git reset --hard &&
+ test_chmod +x file &&
+ echo content >>file
+'
+
+# Write the patch file with a new line at the top and bottom
+cat >patch <<EOF
+index 180b47c..b6f2c08 100644
+--- a/file
++++ b/file
+@@ -1,2 +1,4 @@
++firstline
+ baseline
+ content
++lastline
+EOF
+# Expected output, similar to the patch but w/ diff at the top
+cat >expected <<EOF
+diff --git a/file b/file
+index b6f2c08..61b9053 100755
+--- a/file
++++ b/file
+@@ -1,2 +1,4 @@
++firstline
+ baseline
+ content
++lastline
+EOF
+# Test splitting the first patch, then adding both
+test_expect_success 'add first line works' '
+ git commit -am "clear local changes" &&
+ git apply patch &&
+ (echo s; echo y; echo y) | git add -p file &&
+ git diff --cached > diff &&
+ test_cmp expected diff
+'
+
test_done
diff --git a/t/t3702-add-edit.sh b/t/t3702-add-edit.sh
new file mode 100755
index 0000000000..4ee47cc9a8
--- /dev/null
+++ b/t/t3702-add-edit.sh
@@ -0,0 +1,121 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johannes E. Schindelin
+#
+
+test_description='add -e basic tests'
+. ./test-lib.sh
+
+
+cat > file << EOF
+LO, praise of the prowess of people-kings
+of spear-armed Danes, in days long sped,
+we have heard, and what honor the athelings won!
+Oft Scyld the Scefing from squadroned foes,
+from many a tribe, the mead-bench tore,
+awing the earls. Since erst he lay
+friendless, a foundling, fate repaid him:
+for he waxed under welkin, in wealth he throve,
+till before him the folk, both far and near,
+who house by the whale-path, heard his mandate,
+gave him gifts: a good king he!
+EOF
+
+cat > second-part << EOF
+To him an heir was afterward born,
+a son in his halls, whom heaven sent
+to favor the folk, feeling their woe
+that erst they had lacked an earl for leader
+so long a while; the Lord endowed him,
+the Wielder of Wonder, with world's renown.
+EOF
+
+test_expect_success 'setup' '
+
+ git add file &&
+ test_tick &&
+ git commit -m initial file
+
+'
+
+cat > expected-patch << EOF
+diff --git a/file b/file
+index b9834b5..9020acb 100644
+--- a/file
++++ b/file
+@@ -1,11 +1,6 @@
+-LO, praise of the prowess of people-kings
+-of spear-armed Danes, in days long sped,
+-we have heard, and what honor the athelings won!
+-Oft Scyld the Scefing from squadroned foes,
+-from many a tribe, the mead-bench tore,
+-awing the earls. Since erst he lay
+-friendless, a foundling, fate repaid him:
+-for he waxed under welkin, in wealth he throve,
+-till before him the folk, both far and near,
+-who house by the whale-path, heard his mandate,
+-gave him gifts: a good king he!
++To him an heir was afterward born,
++a son in his halls, whom heaven sent
++to favor the folk, feeling their woe
++that erst they had lacked an earl for leader
++so long a while; the Lord endowed him,
++the Wielder of Wonder, with world's renown.
+EOF
+
+cat > patch << EOF
+diff --git a/file b/file
+index b9834b5..ef6e94c 100644
+--- a/file
++++ b/file
+@@ -3,1 +3,333 @@ of spear-armed Danes, in days long sped,
+ we have heard, and what honor the athelings won!
++
+ Oft Scyld the Scefing from squadroned foes,
+@@ -2,7 +1,5 @@ awing the earls. Since erst he lay
+ friendless, a foundling, fate repaid him:
++
+ for he waxed under welkin, in wealth he throve,
+EOF
+
+cat > expected << EOF
+diff --git a/file b/file
+index b9834b5..ef6e94c 100644
+--- a/file
++++ b/file
+@@ -1,10 +1,12 @@
+ LO, praise of the prowess of people-kings
+ of spear-armed Danes, in days long sped,
+ we have heard, and what honor the athelings won!
++
+ Oft Scyld the Scefing from squadroned foes,
+ from many a tribe, the mead-bench tore,
+ awing the earls. Since erst he lay
+ friendless, a foundling, fate repaid him:
++
+ for he waxed under welkin, in wealth he throve,
+ till before him the folk, both far and near,
+ who house by the whale-path, heard his mandate,
+EOF
+
+echo "#!$SHELL_PATH" >fake-editor.sh
+cat >> fake-editor.sh <<\EOF
+mv -f "$1" orig-patch &&
+mv -f patch "$1"
+EOF
+
+test_set_editor "$(pwd)/fake-editor.sh"
+chmod a+x fake-editor.sh
+
+test_expect_success 'add -e' '
+
+ cp second-part file &&
+ git add -e &&
+ test_cmp second-part file &&
+ test_cmp orig-patch expected-patch &&
+ git diff --cached > out &&
+ test_cmp out expected
+
+'
+
+test_done
diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh
index 784c31aec9..256c4c9701 100755
--- a/t/t3900-i18n-commit.sh
+++ b/t/t3900-i18n-commit.sh
@@ -9,7 +9,15 @@ test_description='commit and log output encodings'
compare_with () {
git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' >current &&
- test_cmp current "$2"
+ case "$3" in
+ '')
+ test_cmp "$2" current ;;
+ ?*)
+ iconv -f "$3" -t UTF-8 >current.utf8 <current &&
+ iconv -f "$3" -t UTF-8 >expect.utf8 <"$2" &&
+ test_cmp expect.utf8 current.utf8
+ ;;
+ esac
}
test_expect_success setup '
@@ -26,7 +34,7 @@ test_expect_success 'no encoding header for base case' '
test z = "z$E"
'
-for H in ISO-8859-1 EUCJP ISO-2022-JP
+for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "$H setup" '
git config i18n.commitencoding $H &&
@@ -36,7 +44,7 @@ do
'
done
-for H in ISO-8859-1 EUCJP ISO-2022-JP
+for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "check encoding header for $H" '
E=$(git cat-file commit '$H' | sed -ne "s/^encoding //p") &&
@@ -53,14 +61,14 @@ test_expect_success 'config to remove customization' '
else
test z = "z$Z"
fi &&
- git config i18n.commitencoding utf-8
+ git config i18n.commitencoding UTF-8
'
-test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' '
- compare_with ISO-8859-1 "$TEST_DIRECTORY"/t3900/1-UTF-8.txt
+test_expect_success 'ISO8859-1 should be shown in UTF-8 now' '
+ compare_with ISO8859-1 "$TEST_DIRECTORY"/t3900/1-UTF-8.txt
'
-for H in EUCJP ISO-2022-JP
+for H in eucJP ISO-2022-JP
do
test_expect_success "$H should be shown in UTF-8 now" '
compare_with '$H' "$TEST_DIRECTORY"/t3900/2-UTF-8.txt
@@ -78,7 +86,7 @@ test_expect_success 'config to add customization' '
fi
'
-for H in ISO-8859-1 EUCJP ISO-2022-JP
+for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "$H should be shown in itself now" '
git config i18n.commitencoding '$H' &&
@@ -87,32 +95,38 @@ do
done
test_expect_success 'config to tweak customization' '
- git config i18n.logoutputencoding utf-8
+ git config i18n.logoutputencoding UTF-8
'
-test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' '
- compare_with ISO-8859-1 "$TEST_DIRECTORY"/t3900/1-UTF-8.txt
+test_expect_success 'ISO8859-1 should be shown in UTF-8 now' '
+ compare_with ISO8859-1 "$TEST_DIRECTORY"/t3900/1-UTF-8.txt
'
-for H in EUCJP ISO-2022-JP
+for H in eucJP ISO-2022-JP
do
test_expect_success "$H should be shown in UTF-8 now" '
compare_with '$H' "$TEST_DIRECTORY"/t3900/2-UTF-8.txt
'
done
-for J in EUCJP ISO-2022-JP
+for J in eucJP ISO-2022-JP
do
+ if test "$J" = ISO-2022-JP
+ then
+ ICONV=$J
+ else
+ ICONV=
+ fi
git config i18n.logoutputencoding $J
- for H in EUCJP ISO-2022-JP
+ for H in eucJP ISO-2022-JP
do
test_expect_success "$H should be shown in $J now" '
- compare_with '$H' "$TEST_DIRECTORY"/t3900/'$J'.txt
+ compare_with '$H' "$TEST_DIRECTORY"/t3900/'$J'.txt $ICONV
'
done
done
-for H in ISO-8859-1 EUCJP ISO-2022-JP
+for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "No conversion with $H" '
compare_with "--encoding=none '$H'" "$TEST_DIRECTORY"/t3900/'$H'.txt
diff --git a/t/t3900/ISO-8859-1.txt b/t/t3900/ISO8859-1.txt
index 7cbef0ee6f..7cbef0ee6f 100644
--- a/t/t3900/ISO-8859-1.txt
+++ b/t/t3900/ISO8859-1.txt
diff --git a/t/t3900/EUCJP.txt b/t/t3900/eucJP.txt
index 546f2aac01..546f2aac01 100644
--- a/t/t3900/EUCJP.txt
+++ b/t/t3900/eucJP.txt
diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh
index 7655da3f8d..31a5770b34 100755
--- a/t/t3901-i18n-patch.sh
+++ b/t/t3901-i18n-patch.sh
@@ -17,9 +17,9 @@ check_encoding () {
git cat-file commit HEAD~$j |
case "$header" in
8859)
- grep "^encoding ISO-8859-1" ;;
+ grep "^encoding ISO8859-1" ;;
*)
- ! grep "^encoding ISO-8859-1" ;;
+ grep "^encoding ISO8859-1"; test "$?" != 0 ;;
esac || {
bad=1
break
@@ -55,7 +55,7 @@ test_expect_success setup '
git commit -s -m "Second on side" &&
# the second one on the side branch is ISO-8859-1
- git config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
# use author and committer name in ISO-8859-1 to match it.
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
test_tick &&
@@ -68,14 +68,14 @@ test_expect_success setup '
'
test_expect_success 'format-patch output (ISO-8859-1)' '
- git config i18n.logoutputencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding ISO8859-1 &&
git format-patch --stdout master..HEAD^ >out-l1 &&
git format-patch --stdout HEAD^ >out-l2 &&
- grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l1 &&
- grep "^From: =?ISO-8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l1 &&
- grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l2 &&
- grep "^From: =?ISO-8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l2
+ grep "^Content-Type: text/plain; charset=ISO8859-1" out-l1 &&
+ grep "^From: =?ISO8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l1 &&
+ grep "^Content-Type: text/plain; charset=ISO8859-1" out-l2 &&
+ grep "^From: =?ISO8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l2
'
test_expect_success 'format-patch output (UTF-8)' '
@@ -110,7 +110,7 @@ test_expect_success 'rebase (U/U)' '
test_expect_success 'rebase (U/L)' '
git config i18n.commitencoding UTF-8 &&
- git config i18n.logoutputencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding ISO8859-1 &&
. "$TEST_DIRECTORY"/t3901-utf8.txt &&
git reset --hard side &&
@@ -121,8 +121,8 @@ test_expect_success 'rebase (U/L)' '
test_expect_success 'rebase (L/L)' '
# In this test we want ISO-8859-1 encoded commits as the result
- git config i18n.commitencoding ISO-8859-1 &&
- git config i18n.logoutputencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
+ git config i18n.logoutputencoding ISO8859-1 &&
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
git reset --hard side &&
@@ -134,7 +134,7 @@ test_expect_success 'rebase (L/L)' '
test_expect_success 'rebase (L/U)' '
# This is pathological -- use UTF-8 as intermediate form
# to get ISO-8859-1 results.
- git config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
git config i18n.logoutputencoding UTF-8 &&
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
@@ -162,8 +162,8 @@ test_expect_success 'cherry-pick(U/U)' '
test_expect_success 'cherry-pick(L/L)' '
# Both the commitencoding and logoutputencoding is set to ISO-8859-1
- git config i18n.commitencoding ISO-8859-1 &&
- git config i18n.logoutputencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
+ git config i18n.logoutputencoding ISO8859-1 &&
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
git reset --hard master &&
@@ -178,7 +178,7 @@ test_expect_success 'cherry-pick(U/L)' '
# Commitencoding is set to UTF-8 but logoutputencoding is ISO-8859-1
git config i18n.commitencoding UTF-8 &&
- git config i18n.logoutputencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding ISO8859-1 &&
. "$TEST_DIRECTORY"/t3901-utf8.txt &&
git reset --hard master &&
@@ -193,7 +193,7 @@ test_expect_success 'cherry-pick(L/U)' '
# Again, the commitencoding is set to ISO-8859-1 but
# logoutputencoding is set to UTF-8.
- git config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
git config i18n.logoutputencoding UTF-8 &&
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
@@ -218,7 +218,7 @@ test_expect_success 'rebase --merge (U/U)' '
test_expect_success 'rebase --merge (U/L)' '
git config i18n.commitencoding UTF-8 &&
- git config i18n.logoutputencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding ISO8859-1 &&
. "$TEST_DIRECTORY"/t3901-utf8.txt &&
git reset --hard side &&
@@ -229,8 +229,8 @@ test_expect_success 'rebase --merge (U/L)' '
test_expect_success 'rebase --merge (L/L)' '
# In this test we want ISO-8859-1 encoded commits as the result
- git config i18n.commitencoding ISO-8859-1 &&
- git config i18n.logoutputencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
+ git config i18n.logoutputencoding ISO8859-1 &&
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
git reset --hard side &&
@@ -242,7 +242,7 @@ test_expect_success 'rebase --merge (L/L)' '
test_expect_success 'rebase --merge (L/U)' '
# This is pathological -- use UTF-8 as intermediate form
# to get ISO-8859-1 results.
- git config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
git config i18n.logoutputencoding UTF-8 &&
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 7484cbede6..7a3fb67957 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -177,4 +177,27 @@ test_expect_success 'stash branch' '
test 0 = $(git stash list | wc -l)
'
+test_expect_success 'apply -q is quiet' '
+ echo foo > file &&
+ git stash &&
+ git stash apply -q > output.out 2>&1 &&
+ test ! -s output.out
+'
+
+test_expect_success 'save -q is quiet' '
+ git stash save --quiet > output.out 2>&1 &&
+ test ! -s output.out
+'
+
+test_expect_success 'pop -q is quiet' '
+ git stash pop -q > output.out 2>&1 &&
+ test ! -s output.out
+'
+
+test_expect_success 'drop -q is quiet' '
+ git stash &&
+ git stash drop -q > output.out 2>&1 &&
+ test ! -s output.out
+'
+
test_done
diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh
index cc3681f161..18695ce821 100755
--- a/t/t4002-diff-basic.sh
+++ b/t/t4002-diff-basic.sh
@@ -258,4 +258,12 @@ test_expect_success \
git diff-tree -r -R $tree_A $tree_B >.test-b &&
cmp -s .test-a .test-b'
+test_expect_success \
+ 'diff can read from stdin' \
+ 'test_must_fail git diff --no-index -- MN - < NN |
+ grep -v "^index" | sed "s#/-#/NN#" >.test-a &&
+ test_must_fail git diff --no-index -- MN NN |
+ grep -v "^index" >.test-b &&
+ test_cmp .test-a .test-b'
+
test_done
diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh
index b35af9b42d..a4da1196a9 100755
--- a/t/t4004-diff-rename-symlink.sh
+++ b/t/t4004-diff-rename-symlink.sh
@@ -12,6 +12,12 @@ by an edit for them.
. ./test-lib.sh
. "$TEST_DIRECTORY"/diff-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
test_expect_success \
'prepare reference tree' \
'echo xyzzy | tr -d '\\\\'012 >yomin &&
diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh
index 4e92fce1d0..8c1b81e248 100755
--- a/t/t4006-diff-mode.sh
+++ b/t/t4006-diff-mode.sh
@@ -15,21 +15,10 @@ test_expect_success \
tree=`git write-tree` &&
echo $tree'
-if [ "$(git config --get core.filemode)" = false ]
-then
- say 'filemode disabled on the filesystem, using update-index --chmod=+x'
- test_expect_success \
- 'git update-index --chmod=+x' \
- 'git update-index rezrov &&
- git update-index --chmod=+x rezrov &&
- git diff-index $tree >current'
-else
- test_expect_success \
- 'chmod' \
- 'chmod +x rezrov &&
- git update-index rezrov &&
- git diff-index $tree >current'
-fi
+test_expect_success \
+ 'chmod' \
+ 'test_chmod +x rezrov &&
+ git diff-index $tree >current'
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh
index 42072d724e..11502b7509 100755
--- a/t/t4007-rename-3.sh
+++ b/t/t4007-rename-3.sh
@@ -9,32 +9,36 @@ test_description='Rename interaction with pathspec.
. ./test-lib.sh
. "$TEST_DIRECTORY"/diff-lib.sh ;# test-lib chdir's into trash
-test_expect_success \
- 'prepare reference tree' \
- 'mkdir path0 path1 &&
- cp "$TEST_DIRECTORY"/../COPYING path0/COPYING &&
- git update-index --add path0/COPYING &&
- tree=$(git write-tree) &&
- echo $tree'
-
-test_expect_success \
- 'prepare work tree' \
- 'cp path0/COPYING path1/COPYING &&
- git update-index --add --remove path0/COPYING path1/COPYING'
+test_expect_success 'prepare reference tree' '
+ mkdir path0 path1 &&
+ cp "$TEST_DIRECTORY"/../COPYING path0/COPYING &&
+ git update-index --add path0/COPYING &&
+ tree=$(git write-tree) &&
+ echo $tree
+'
+
+test_expect_success 'prepare work tree' '
+ cp path0/COPYING path1/COPYING &&
+ git update-index --add --remove path0/COPYING path1/COPYING
+'
# In the tree, there is only path0/COPYING. In the cache, path0 and
# path1 both have COPYING and the latter is a copy of path0/COPYING.
# Comparing the full tree with cache should tell us so.
-git diff-index -C --find-copies-harder $tree >current
-
cat >expected <<\EOF
:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100 path0/COPYING path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#1)' \
- 'compare_diff_raw current expected'
+test_expect_success 'copy detection' '
+ git diff-index -C --find-copies-harder $tree >current &&
+ compare_diff_raw current expected
+'
+
+test_expect_success 'copy detection, cached' '
+ git diff-index -C --find-copies-harder --cached $tree >current &&
+ compare_diff_raw current expected
+'
# In the tree, there is only path0/COPYING. In the cache, path0 and
# path1 both have COPYING and the latter is a copy of path0/COPYING.
@@ -42,49 +46,45 @@ test_expect_success \
# path1/COPYING suddenly appearing from nowhere, not detected as
# a copy from path0/COPYING.
-git diff-index -C $tree path1 >current
-
cat >expected <<\EOF
:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#2)' \
- 'compare_diff_raw current expected'
-
-test_expect_success \
- 'tweak work tree' \
- 'rm -f path0/COPYING &&
- git update-index --remove path0/COPYING'
+test_expect_success 'copy, limited to a subtree' '
+ git diff-index -C --find-copies-harder $tree path1 >current &&
+ compare_diff_raw current expected
+'
+test_expect_success 'tweak work tree' '
+ rm -f path0/COPYING &&
+ git update-index --remove path0/COPYING
+'
# In the tree, there is only path0/COPYING. In the cache, path0 does
# not have COPYING anymore and path1 has COPYING which is a copy of
# path0/COPYING. Showing the full tree with cache should tell us about
# the rename.
-git diff-index -C $tree >current
-
cat >expected <<\EOF
:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100 path0/COPYING path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#3)' \
- 'compare_diff_raw current expected'
+test_expect_success 'rename detection' '
+ git diff-index -C --find-copies-harder $tree >current &&
+ compare_diff_raw current expected
+'
# In the tree, there is only path0/COPYING. In the cache, path0 does
# not have COPYING anymore and path1 has COPYING which is a copy of
# path0/COPYING. When we say we care only about path1, we should just
# see path1/COPYING appearing from nowhere.
-git diff-index -C $tree path1 >current
-
cat >expected <<\EOF
:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#4)' \
- 'compare_diff_raw current expected'
+test_expect_success 'rename, limited to a subtree' '
+ git diff-index -C --find-copies-harder $tree path1 >current &&
+ compare_diff_raw current expected
+'
test_done
diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh
index 7e343a9cd1..e19ca65885 100755
--- a/t/t4008-diff-break-rewrite.sh
+++ b/t/t4008-diff-break-rewrite.sh
@@ -99,7 +99,7 @@ test_expect_success \
'validate result of -B -M (#4)' \
'compare_diff_raw expected current'
-test_expect_success \
+test_expect_success SYMLINKS \
'make file0 into something completely different' \
'rm -f file0 &&
ln -s frotz file0 &&
@@ -114,7 +114,7 @@ cat >expected <<\EOF
:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 M100 file1
EOF
-test_expect_success \
+test_expect_success SYMLINKS \
'validate result of -B (#5)' \
'compare_diff_raw expected current'
@@ -129,7 +129,7 @@ cat >expected <<\EOF
:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 R file0 file1
EOF
-test_expect_success \
+test_expect_success SYMLINKS \
'validate result of -B -M (#6)' \
'compare_diff_raw expected current'
@@ -144,7 +144,7 @@ cat >expected <<\EOF
:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 M file1
EOF
-test_expect_success \
+test_expect_success SYMLINKS \
'validate result of -M (#7)' \
'compare_diff_raw expected current'
diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh
index 02efecae3a..d7e327cc5b 100755
--- a/t/t4011-diff-symlink.sh
+++ b/t/t4011-diff-symlink.sh
@@ -9,6 +9,12 @@ test_description='Test diff of symlinks.
. ./test-lib.sh
. "$TEST_DIRECTORY"/diff-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
cat > expected << EOF
diff --git a/frotz b/frotz
new file mode 120000
@@ -82,4 +88,11 @@ test_expect_success \
git diff-index -M -p $tree > current &&
compare_diff_patch current expected'
+test_expect_success \
+ 'diff symlinks with non-existing targets' \
+ 'ln -s narf pinky &&
+ ln -s take\ over brain &&
+ test_must_fail git diff --no-index pinky brain > output 2> output.err &&
+ grep narf output &&
+ ! grep error output.err'
test_done
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 3cf5b5c4ea..f64aa48d24 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -87,7 +87,7 @@ nul_to_q() {
test_expect_success 'diff --no-index with binary creation' '
echo Q | q_to_nul >binary &&
- (:# hide error code from diff, which just indicates differences
+ (: hide error code from diff, which just indicates differences
git diff --binary --no-index /dev/null binary >current ||
true
) &&
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 9c709022ef..8b33321f8c 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -101,8 +101,7 @@ do
'' | '#'*) continue ;;
esac
test=`echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g'`
- cnt=`expr $test_count + 1`
- pfx=`printf "%04d" $cnt`
+ pfx=`printf "%04d" $test_count`
expect="$TEST_DIRECTORY/t4013/diff.$test"
actual="$pfx-diff.$test"
@@ -207,6 +206,10 @@ log --root -c --patch-with-stat --summary master
log --root --cc --patch-with-stat --summary master
log -SF master
log -SF -p master
+log --decorate --all
+
+rev-list --parents HEAD
+rev-list --children HEAD
whatchanged master
whatchanged -p master
@@ -243,11 +246,12 @@ format-patch --stdout initial..master
format-patch --stdout --no-numbered initial..master
format-patch --stdout --numbered initial..master
format-patch --attach --stdout initial..side
+format-patch --attach --stdout --suffix=.diff initial..side
format-patch --attach --stdout initial..master^
format-patch --attach --stdout initial..master
format-patch --inline --stdout initial..side
format-patch --inline --stdout initial..master^
-format-patch --inline --stdout initial..master
+format-patch --inline --stdout --numbered-files initial..master
format-patch --inline --stdout initial..master
format-patch --inline --stdout --subject-prefix=TESTCASE initial..master
config format.subjectprefix DIFFERENT_PREFIX
@@ -268,6 +272,7 @@ diff --no-index --name-status dir2 dir
diff --no-index --name-status -- dir2 dir
diff --no-index dir dir3
diff master master^ side
+diff --dirstat master~1 master~2
EOF
test_done
diff --git a/t/t4013/diff.diff_--dirstat_master~1_master~2 b/t/t4013/diff.diff_--dirstat_master~1_master~2
new file mode 100644
index 0000000000..b672e1ca63
--- /dev/null
+++ b/t/t4013/diff.diff_--dirstat_master~1_master~2
@@ -0,0 +1,3 @@
+$ git diff --dirstat master~1 master~2
+ 40.0% dir/
+$
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
new file mode 100644
index 0000000000..52116d3ead
--- /dev/null
+++ b/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
@@ -0,0 +1,61 @@
+$ git format-patch --attach --stdout --suffix=.diff initial..side
+From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001
+From: A U Thor <author@example.com>
+Date: Mon, 26 Jun 2006 00:03:00 +0000
+Subject: [PATCH] Side
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n"
+
+This is a multi-part message in MIME format.
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
+ 3 files changed, 9 insertions(+), 0 deletions(-)
+ create mode 100644 file3
+
+
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/x-patch; name="0001-Side.diff"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0001-Side.diff"
+
+diff --git a/dir/sub b/dir/sub
+index 35d242b..7289e35 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,2 +1,4 @@
+ A
+ B
++1
++2
+diff --git a/file0 b/file0
+index 01e79c3..f4615da 100644
+--- a/file0
++++ b/file0
+@@ -1,3 +1,6 @@
+ 1
+ 2
+ 3
++A
++B
++C
+diff --git a/file3 b/file3
+new file mode 100644
+index 0000000..7289e35
+--- /dev/null
++++ b/file3
+@@ -0,0 +1,4 @@
++A
++B
++1
++2
+
+--------------g-i-t--v-e-r-s-i-o-n--
+
+
+$
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
index e5ab74437e..ce49bd676e 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
@@ -22,9 +22,9 @@ This is the second commit.
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Type: text/x-patch; name="0001-Second.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: attachment; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Disposition: attachment; filename="0001-Second.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
@@ -80,9 +80,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Type: text/x-patch; name="0002-Third.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: attachment; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Disposition: attachment; filename="0002-Third.patch"
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -129,9 +129,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Type: text/x-patch; name="0003-Side.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: attachment; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Disposition: attachment; filename="0003-Side.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
index 2c71d20d37..5f1b23863b 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
@@ -22,9 +22,9 @@ This is the second commit.
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Type: text/x-patch; name="0001-Second.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: attachment; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Disposition: attachment; filename="0001-Second.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
@@ -80,9 +80,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Type: text/x-patch; name="0002-Third.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: attachment; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Disposition: attachment; filename="0002-Third.patch"
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
index 38f790290a..4a2364abc2 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
@@ -20,9 +20,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Type: text/x-patch; name="0001-Side.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: attachment; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Disposition: attachment; filename="0001-Side.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
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
new file mode 100644
index 0000000000..43b81eba54
--- /dev/null
+++ b/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
@@ -0,0 +1,170 @@
+$ git format-patch --inline --stdout --numbered-files initial..master
+From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001
+From: A U Thor <author@example.com>
+Date: Mon, 26 Jun 2006 00:01:00 +0000
+Subject: [PATCH 1/3] Second
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n"
+
+This is a multi-part message in MIME format.
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+This is the second commit.
+---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file2 | 3 ---
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+ delete mode 100644 file2
+
+
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/x-patch; name="1"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline; filename="1"
+
+diff --git a/dir/sub b/dir/sub
+index 35d242b..8422d40 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,2 +1,4 @@
+ A
+ B
++C
++D
+diff --git a/file0 b/file0
+index 01e79c3..b414108 100644
+--- a/file0
++++ b/file0
+@@ -1,3 +1,6 @@
+ 1
+ 2
+ 3
++4
++5
++6
+diff --git a/file2 b/file2
+deleted file mode 100644
+index 01e79c3..0000000
+--- a/file2
++++ /dev/null
+@@ -1,3 +0,0 @@
+-1
+-2
+-3
+
+--------------g-i-t--v-e-r-s-i-o-n--
+
+
+
+From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001
+From: A U Thor <author@example.com>
+Date: Mon, 26 Jun 2006 00:02:00 +0000
+Subject: [PATCH 2/3] Third
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n"
+
+This is a multi-part message in MIME format.
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+---
+ dir/sub | 2 ++
+ file1 | 3 +++
+ 2 files changed, 5 insertions(+), 0 deletions(-)
+ create mode 100644 file1
+
+
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/x-patch; name="2"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline; filename="2"
+
+diff --git a/dir/sub b/dir/sub
+index 8422d40..cead32e 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -2,3 +2,5 @@ A
+ B
+ C
+ D
++E
++F
+diff --git a/file1 b/file1
+new file mode 100644
+index 0000000..b1e6722
+--- /dev/null
++++ b/file1
+@@ -0,0 +1,3 @@
++A
++B
++C
+
+--------------g-i-t--v-e-r-s-i-o-n--
+
+
+
+From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001
+From: A U Thor <author@example.com>
+Date: Mon, 26 Jun 2006 00:03:00 +0000
+Subject: [PATCH 3/3] Side
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n"
+
+This is a multi-part message in MIME format.
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+---
+ dir/sub | 2 ++
+ file0 | 3 +++
+ file3 | 4 ++++
+ 3 files changed, 9 insertions(+), 0 deletions(-)
+ create mode 100644 file3
+
+
+--------------g-i-t--v-e-r-s-i-o-n
+Content-Type: text/x-patch; name="3"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline; filename="3"
+
+diff --git a/dir/sub b/dir/sub
+index 35d242b..7289e35 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,2 +1,4 @@
+ A
+ B
++1
++2
+diff --git a/file0 b/file0
+index 01e79c3..f4615da 100644
+--- a/file0
++++ b/file0
+@@ -1,3 +1,6 @@
+ 1
+ 2
+ 3
++A
++B
++C
+diff --git a/file3 b/file3
+new file mode 100644
+index 0000000..7289e35
+--- /dev/null
++++ b/file3
+@@ -0,0 +1,4 @@
++A
++B
++1
++2
+
+--------------g-i-t--v-e-r-s-i-o-n--
+
+
+$
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 58f8a7b7d6..ca3f60bf0e 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
@@ -22,9 +22,9 @@ This is the second commit.
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Type: text/x-patch; name="0001-Second.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Disposition: inline; filename="0001-Second.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
@@ -80,9 +80,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Type: text/x-patch; name="0002-Third.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Disposition: inline; filename="0002-Third.patch"
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -129,9 +129,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Type: text/x-patch; name="0003-Side.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Disposition: inline; filename="0003-Side.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
index 9e7bbdffa2..08f23014bc 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
@@ -22,9 +22,9 @@ This is the second commit.
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Type: text/x-patch; name="0001-Second.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Disposition: inline; filename="0001-Second.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
@@ -80,9 +80,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Type: text/x-patch; name="0002-Third.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Disposition: inline; filename="0002-Third.patch"
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
@@ -129,9 +129,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Type: text/x-patch; name="0003-Side.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Disposition: inline; filename="0003-Side.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
index f881f644cc..07f1230d31 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
@@ -22,9 +22,9 @@ This is the second commit.
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Type: text/x-patch; name="0001-Second.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Disposition: inline; filename="0001-Second.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
@@ -80,9 +80,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Type: text/x-patch; name="0002-Third.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff"
+Content-Disposition: inline; filename="0002-Third.patch"
diff --git a/dir/sub b/dir/sub
index 8422d40..cead32e 100644
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
index 4f258b8858..29e00ab8af 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
@@ -22,9 +22,9 @@ This is the second commit.
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Type: text/x-patch; name="0001-Second.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff"
+Content-Disposition: inline; filename="0001-Second.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..8422d40 100644
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..side b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
index e86dce69a3..67633d424a 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
@@ -20,9 +20,9 @@ Content-Transfer-Encoding: 8bit
--------------g-i-t--v-e-r-s-i-o-n
-Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Type: text/x-patch; name="0001-Side.patch"
Content-Transfer-Encoding: 8bit
-Content-Disposition: inline; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff"
+Content-Disposition: inline; filename="0001-Side.patch"
diff --git a/dir/sub b/dir/sub
index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all
new file mode 100644
index 0000000000..954210ea90
--- /dev/null
+++ b/t/t4013/diff.log_--decorate_--all
@@ -0,0 +1,34 @@
+$ git log --decorate --all
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (master)
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (side)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:03:00 2006 +0000
+
+ Side
+
+commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:02:00 2006 +0000
+
+ Third
+
+commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:01:00 2006 +0000
+
+ Second
+
+ This is the second commit.
+
+commit 444ac553ac7612cc88969031b02b3767fb8a353a (initial)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:00:00 2006 +0000
+
+ Initial
+$
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 3ceb8e73c5..bd7f5c0f70 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -1,6 +1,6 @@
$ git log --patch-with-stat --summary master -- dir/
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index 43d77761f9..14595a614c 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -1,6 +1,6 @@
$ git log --patch-with-stat master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index 5187a26816..5a4e72765d 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -1,6 +1,6 @@
$ git log --patch-with-stat master -- dir/
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
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 c9640976a8..df0aaa9f2c 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
@@ -1,6 +1,6 @@
$ git log --root --cc --patch-with-stat --summary master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
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 ad050af55f..c11b5f2c7f 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -1,6 +1,6 @@
$ git log --root --patch-with-stat --summary master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 628c6c03bc..5f0c98f9ce 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -1,6 +1,6 @@
$ git log --root --patch-with-stat master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
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 5d4e0f13b5..e62c368dc6 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
@@ -1,6 +1,6 @@
$ git log --root -c --patch-with-stat --summary master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_--root_-p_master b/t/t4013/diff.log_--root_-p_master
index 217a2eb203..b42c334439 100644
--- a/t/t4013/diff.log_--root_-p_master
+++ b/t/t4013/diff.log_--root_-p_master
@@ -1,6 +1,6 @@
$ git log --root -p master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_--root_master b/t/t4013/diff.log_--root_master
index e17ccfc234..e8f46159da 100644
--- a/t/t4013/diff.log_--root_master
+++ b/t/t4013/diff.log_--root_master
@@ -1,6 +1,6 @@
$ git log --root master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_-p_master b/t/t4013/diff.log_-p_master
index f8fefef2c3..bf1326dc36 100644
--- a/t/t4013/diff.log_-p_master
+++ b/t/t4013/diff.log_-p_master
@@ -1,6 +1,6 @@
$ git log -p master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_master b/t/t4013/diff.log_master
index e9d9e7b40a..a8f6ce5abd 100644
--- a/t/t4013/diff.log_master
+++ b/t/t4013/diff.log_master
@@ -1,6 +1,6 @@
$ git log master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.rev-list_--children_HEAD b/t/t4013/diff.rev-list_--children_HEAD
new file mode 100644
index 0000000000..e7f17d5aa0
--- /dev/null
+++ b/t/t4013/diff.rev-list_--children_HEAD
@@ -0,0 +1,7 @@
+$ git rev-list --children HEAD
+59d314ad6f356dd08601a4cd5e530381da3e3c64
+c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a 59d314ad6f356dd08601a4cd5e530381da3e3c64
+9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 59d314ad6f356dd08601a4cd5e530381da3e3c64
+1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+444ac553ac7612cc88969031b02b3767fb8a353a 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
+$
diff --git a/t/t4013/diff.rev-list_--parents_HEAD b/t/t4013/diff.rev-list_--parents_HEAD
new file mode 100644
index 0000000000..65d2a80208
--- /dev/null
+++ b/t/t4013/diff.rev-list_--parents_HEAD
@@ -0,0 +1,7 @@
+$ git rev-list --parents HEAD
+59d314ad6f356dd08601a4cd5e530381da3e3c64 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
+c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a 444ac553ac7612cc88969031b02b3767fb8a353a
+9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
+1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 444ac553ac7612cc88969031b02b3767fb8a353a
+444ac553ac7612cc88969031b02b3767fb8a353a
+$
diff --git a/t/t4013/diff.show_master b/t/t4013/diff.show_master
index 9e6e1f2710..fb08ce0e46 100644
--- a/t/t4013/diff.show_master
+++ b/t/t4013/diff.show_master
@@ -1,6 +1,6 @@
$ git show master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
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 5facf2543d..e96ff1fb8c 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
@@ -1,6 +1,6 @@
$ git whatchanged --root --cc --patch-with-stat --summary master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
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 10f6767e49..c0aff68ef6 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
@@ -1,6 +1,6 @@
$ git whatchanged --root -c --patch-with-stat --summary master
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
-Merge: 9a6d494... c7a2ab9...
+Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index f045898fe3..531f5b795c 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -16,9 +16,7 @@ test_expect_success setup '
git checkout -b side &&
for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
- chmod +x elif &&
- git update-index file elif &&
- git update-index --chmod=+x elif &&
+ test_chmod +x elif &&
git commit -m "Side changes #1" &&
for i in D E F; do echo "$i"; done >>file &&
@@ -130,6 +128,21 @@ test_expect_success 'additional command line cc' '
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
+'
+
+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
+'
+
test_expect_success 'multiple files' '
rm -rf patches/ &&
@@ -138,56 +151,243 @@ 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 'thread' '
+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 '
+ if (/^(message-id|references|in-reply-to)/i) {
+ $printing = 1;
+ } elsif (/^\S/) {
+ $printing = 0;
+ }
+ if ($printing) {
+ $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
+ for $k (keys %h) {s/$k/$h{$k}/};
+ print;
+ }
+ print "---\n" if /^From /i;
+ ' > actual &&
+ test 0 = "$(cat status.out)" &&
+ test_cmp "$expect" actual
+}
+
+cat >> expect.no-threading <<EOF
+---
+---
+---
+EOF
- rm -rf patches/ &&
+test_expect_success 'no threading' '
git checkout side &&
- git format-patch --thread -o patches/ master &&
- FIRST_MID=$(grep "Message-Id:" patches/0001-* | sed "s/^[^<]*\(<[^>]*>\).*$/\1/") &&
- for i in patches/0002-* patches/0003-*
- do
- grep "References: $FIRST_MID" $i &&
- grep "In-Reply-To: $FIRST_MID" $i || break
- done
+ check_threading expect.no-threading master
'
-test_expect_success 'thread in-reply-to' '
+cat > expect.thread <<EOF
+---
+Message-Id: <0>
+---
+Message-Id: <1>
+In-Reply-To: <0>
+References: <0>
+---
+Message-Id: <2>
+In-Reply-To: <0>
+References: <0>
+EOF
- rm -rf patches/ &&
- git checkout side &&
- git format-patch --in-reply-to="<test.message>" --thread -o patches/ master &&
- FIRST_MID="<test.message>" &&
- for i in patches/*
- do
- grep "References: $FIRST_MID" $i &&
- grep "In-Reply-To: $FIRST_MID" $i || break
- done
+test_expect_success 'thread' '
+ check_threading expect.thread --thread master
'
-test_expect_success 'thread cover-letter' '
+cat > expect.in-reply-to <<EOF
+---
+Message-Id: <0>
+In-Reply-To: <1>
+References: <1>
+---
+Message-Id: <2>
+In-Reply-To: <1>
+References: <1>
+---
+Message-Id: <3>
+In-Reply-To: <1>
+References: <1>
+EOF
- rm -rf patches/ &&
- git checkout side &&
- git format-patch --cover-letter --thread -o patches/ master &&
- FIRST_MID=$(grep "Message-Id:" patches/0000-* | sed "s/^[^<]*\(<[^>]*>\).*$/\1/") &&
- for i in patches/0001-* patches/0002-* patches/0003-*
- do
- grep "References: $FIRST_MID" $i &&
- grep "In-Reply-To: $FIRST_MID" $i || break
- done
+test_expect_success 'thread in-reply-to' '
+ check_threading expect.in-reply-to --in-reply-to="<test.message>" \
+ --thread master
+'
+
+cat > expect.cover-letter <<EOF
+---
+Message-Id: <0>
+---
+Message-Id: <1>
+In-Reply-To: <0>
+References: <0>
+---
+Message-Id: <2>
+In-Reply-To: <0>
+References: <0>
+---
+Message-Id: <3>
+In-Reply-To: <0>
+References: <0>
+EOF
+
+test_expect_success 'thread cover-letter' '
+ check_threading expect.cover-letter --cover-letter --thread master
'
+cat > expect.cl-irt <<EOF
+---
+Message-Id: <0>
+In-Reply-To: <1>
+References: <1>
+---
+Message-Id: <2>
+In-Reply-To: <0>
+References: <1>
+ <0>
+---
+Message-Id: <3>
+In-Reply-To: <0>
+References: <1>
+ <0>
+---
+Message-Id: <4>
+In-Reply-To: <0>
+References: <1>
+ <0>
+EOF
+
test_expect_success 'thread cover-letter in-reply-to' '
+ check_threading expect.cl-irt --cover-letter \
+ --in-reply-to="<test.message>" --thread master
+'
- rm -rf patches/ &&
- git checkout side &&
- git format-patch --cover-letter --in-reply-to="<test.message>" --thread -o patches/ master &&
- FIRST_MID="<test.message>" &&
- for i in patches/*
- do
- grep "References: $FIRST_MID" $i &&
- grep "In-Reply-To: $FIRST_MID" $i || break
- done
+test_expect_success 'thread explicit shallow' '
+ check_threading expect.cl-irt --cover-letter \
+ --in-reply-to="<test.message>" --thread=shallow master
+'
+
+cat > expect.deep <<EOF
+---
+Message-Id: <0>
+---
+Message-Id: <1>
+In-Reply-To: <0>
+References: <0>
+---
+Message-Id: <2>
+In-Reply-To: <1>
+References: <0>
+ <1>
+EOF
+
+test_expect_success 'thread deep' '
+ check_threading expect.deep --thread=deep master
+'
+
+cat > expect.deep-irt <<EOF
+---
+Message-Id: <0>
+In-Reply-To: <1>
+References: <1>
+---
+Message-Id: <2>
+In-Reply-To: <0>
+References: <1>
+ <0>
+---
+Message-Id: <3>
+In-Reply-To: <2>
+References: <1>
+ <0>
+ <2>
+EOF
+
+test_expect_success 'thread deep in-reply-to' '
+ check_threading expect.deep-irt --thread=deep \
+ --in-reply-to="<test.message>" master
+'
+
+cat > expect.deep-cl <<EOF
+---
+Message-Id: <0>
+---
+Message-Id: <1>
+In-Reply-To: <0>
+References: <0>
+---
+Message-Id: <2>
+In-Reply-To: <1>
+References: <0>
+ <1>
+---
+Message-Id: <3>
+In-Reply-To: <2>
+References: <0>
+ <1>
+ <2>
+EOF
+
+test_expect_success 'thread deep cover-letter' '
+ check_threading expect.deep-cl --cover-letter --thread=deep master
+'
+
+cat > expect.deep-cl-irt <<EOF
+---
+Message-Id: <0>
+In-Reply-To: <1>
+References: <1>
+---
+Message-Id: <2>
+In-Reply-To: <0>
+References: <1>
+ <0>
+---
+Message-Id: <3>
+In-Reply-To: <2>
+References: <1>
+ <0>
+ <2>
+---
+Message-Id: <4>
+In-Reply-To: <3>
+References: <1>
+ <0>
+ <2>
+ <3>
+EOF
+
+test_expect_success 'thread deep cover-letter in-reply-to' '
+ check_threading expect.deep-cl-irt --cover-letter \
+ --in-reply-to="<test.message>" --thread=deep master
+'
+
+test_expect_success 'thread via config' '
+ git config format.thread true &&
+ check_threading expect.thread master
+'
+
+test_expect_success 'thread deep via config' '
+ git config format.thread deep &&
+ check_threading expect.deep master
+'
+
+test_expect_success 'thread config + override' '
+ git config format.thread deep &&
+ check_threading expect.thread --thread master
+'
+
+test_expect_success 'thread config + --no-thread' '
+ git config format.thread deep &&
+ check_threading expect.no-threading --no-thread master
'
test_expect_success 'excessive subject' '
@@ -293,16 +493,26 @@ test_expect_success 'format-patch from a subdirectory (2)' '
'
test_expect_success 'format-patch from a subdirectory (3)' '
- here="$TEST_DIRECTORY/$test" &&
rm -f 0* &&
filename=$(
rm -rf sub &&
mkdir -p sub/dir &&
cd sub/dir &&
- git format-patch -1 -o "$here"
+ git format-patch -1 -o "$TRASH_DIRECTORY"
) &&
basename=$(expr "$filename" : ".*/\(.*\)") &&
test -f "$basename"
'
+test_expect_success 'format-patch --in-reply-to' '
+ git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
+ grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
+ grep "^References: <baz@foo.bar>" patch8
+'
+
+test_expect_success 'format-patch --signoff' '
+ git format-patch -1 --signoff --stdout |
+ grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+'
+
test_done
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index be541348c6..5b10e976a3 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -32,7 +32,7 @@ EOF
sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java
-builtin_patterns="bibtex html java objc pascal php python ruby tex"
+builtin_patterns="bibtex cpp html java objc pascal php python ruby tex"
for p in $builtin_patterns
do
test_expect_success "builtin $p pattern compiles" '
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index 2a72e751e2..a7602cf923 100755
--- a/t/t4020-diff-external.sh
+++ b/t/t4020-diff-external.sh
@@ -128,12 +128,45 @@ test_expect_success 'force diff with "diff"' '
test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual
'
+test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
+ echo anotherfile > file2 &&
+ git add file2 &&
+ git commit -m "added 2nd file" &&
+ echo modified >file2 &&
+ GIT_EXTERNAL_DIFF=echo git diff
+'
+
+test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' '
+ touch file.ext &&
+ git add file.ext &&
+ echo with extension > file.ext &&
+ GIT_EXTERNAL_DIFF=echo git diff file.ext | grep ......_file\.ext &&
+ git update-index --force-remove file.ext &&
+ rm file.ext
+'
+
+echo "#!$SHELL_PATH" >fake-diff.sh
+cat >> fake-diff.sh <<\EOF
+cat $2 >> crlfed.txt
+EOF
+chmod a+x fake-diff.sh
+
+keep_only_cr () {
+ tr -dc '\015'
+}
+
+test_expect_success 'external diff with autocrlf = true' '
+ git config core.autocrlf true &&
+ GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
+ test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
+'
+
test_expect_success 'diff --cached' '
git add file &&
git update-index --assume-unchanged file &&
echo second >file &&
git diff --cached >actual &&
- test_cmp ../t4020/diff.NUL actual
+ test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual
'
test_done
diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh
index 390af2389f..709b3231ca 100755
--- a/t/t4021-format-patch-numbered.sh
+++ b/t/t4021-format-patch-numbered.sh
@@ -86,6 +86,13 @@ test_expect_success 'format.numbered && --no-numbered' '
'
+test_expect_success 'format.numbered && --keep-subject' '
+
+ git format-patch --keep-subject --stdout HEAD^ >patch4a &&
+ grep "^Subject: Third" patch4a
+
+'
+
test_expect_success 'format.numbered = auto' '
git config format.numbered auto
@@ -108,4 +115,10 @@ test_expect_success 'format.numbered = auto && --no-numbered' '
'
+test_expect_success '--start-number && --numbered' '
+
+ git format-patch --start-number 3 --numbered --stdout HEAD~1 > patch8 &&
+ grep "^Subject: \[PATCH 3/3\]" patch8
+'
+
test_done
diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
index 297ddb5a25..9bdf6596d8 100755
--- a/t/t4023-diff-rename-typechange.sh
+++ b/t/t4023-diff-rename-typechange.sh
@@ -4,6 +4,12 @@ test_description='typechange rename detection'
. ./test-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
test_expect_success setup '
rm -f foo bar &&
diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh
index 9ddbbcde57..3ccc237a8d 100755
--- a/t/t4029-diff-trailing-space.sh
+++ b/t/t4029-diff-trailing-space.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Copyright (c) Jim Meyering
#
diff --git a/t/t4032-diff-inter-hunk-context.sh b/t/t4032-diff-inter-hunk-context.sh
new file mode 100755
index 0000000000..e4e3e28fc7
--- /dev/null
+++ b/t/t4032-diff-inter-hunk-context.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+test_description='diff hunk fusing'
+
+. ./test-lib.sh
+
+f() {
+ echo $1
+ i=1
+ while test $i -le $2
+ do
+ echo $i
+ i=$(expr $i + 1)
+ done
+ echo $3
+}
+
+t() {
+ case $# in
+ 4) hunks=$4; cmd="diff -U$3";;
+ 5) hunks=$5; cmd="diff -U$3 --inter-hunk-context=$4";;
+ esac
+ label="$cmd, $1 common $2"
+ file=f$1
+ expected=expected.$file.$3.$hunks
+
+ if ! test -f $file
+ then
+ f A $1 B >$file
+ git add $file
+ git commit -q -m. $file
+ f X $1 Y >$file
+ fi
+
+ test_expect_success "$label: count hunks ($hunks)" "
+ test $(git $cmd $file | grep '^@@ ' | wc -l) = $hunks
+ "
+
+ test -f $expected &&
+ test_expect_success "$label: check output" "
+ git $cmd $file | grep -v '^index ' >actual &&
+ test_cmp $expected actual
+ "
+}
+
+cat <<EOF >expected.f1.0.1 || exit 1
+diff --git a/f1 b/f1
+--- a/f1
++++ b/f1
+@@ -1,3 +1,3 @@
+-A
++X
+ 1
+-B
++Y
+EOF
+
+cat <<EOF >expected.f1.0.2 || exit 1
+diff --git a/f1 b/f1
+--- a/f1
++++ b/f1
+@@ -1 +1 @@
+-A
++X
+@@ -3 +3 @@ A
+-B
++Y
+EOF
+
+# common lines ctx intrctx hunks
+t 1 line 0 2
+t 1 line 0 0 2
+t 1 line 0 1 1
+t 1 line 0 2 1
+t 1 line 1 1
+
+t 2 lines 0 2
+t 2 lines 0 0 2
+t 2 lines 0 1 2
+t 2 lines 0 2 1
+t 2 lines 1 1
+
+t 3 lines 1 2
+t 3 lines 1 0 2
+t 3 lines 1 1 1
+t 3 lines 1 2 1
+
+t 9 lines 3 2
+t 9 lines 3 2 2
+t 9 lines 3 3 1
+
+test_done
diff --git a/t/t4033-diff-patience.sh b/t/t4033-diff-patience.sh
new file mode 100755
index 0000000000..1eb14989df
--- /dev/null
+++ b/t/t4033-diff-patience.sh
@@ -0,0 +1,168 @@
+#!/bin/sh
+
+test_description='patience diff algorithm'
+
+. ./test-lib.sh
+
+cat >file1 <<\EOF
+#include <stdio.h>
+
+// Frobs foo heartily
+int frobnitz(int foo)
+{
+ int i;
+ for(i = 0; i < 10; i++)
+ {
+ printf("Your answer is: ");
+ printf("%d\n", foo);
+ }
+}
+
+int fact(int n)
+{
+ if(n > 1)
+ {
+ return fact(n-1) * n;
+ }
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ frobnitz(fact(10));
+}
+EOF
+
+cat >file2 <<\EOF
+#include <stdio.h>
+
+int fib(int n)
+{
+ if(n > 2)
+ {
+ return fib(n-1) + fib(n-2);
+ }
+ return 1;
+}
+
+// Frobs foo heartily
+int frobnitz(int foo)
+{
+ int i;
+ for(i = 0; i < 10; i++)
+ {
+ printf("%d\n", foo);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ frobnitz(fib(10));
+}
+EOF
+
+cat >expect <<\EOF
+diff --git a/file1 b/file2
+index 6faa5a3..e3af329 100644
+--- a/file1
++++ b/file2
+@@ -1,26 +1,25 @@
+ #include <stdio.h>
+
++int fib(int n)
++{
++ if(n > 2)
++ {
++ return fib(n-1) + fib(n-2);
++ }
++ return 1;
++}
++
+ // Frobs foo heartily
+ int frobnitz(int foo)
+ {
+ int i;
+ for(i = 0; i < 10; i++)
+ {
+- printf("Your answer is: ");
+ printf("%d\n", foo);
+ }
+ }
+
+-int fact(int n)
+-{
+- if(n > 1)
+- {
+- return fact(n-1) * n;
+- }
+- return 1;
+-}
+-
+ int main(int argc, char **argv)
+ {
+- frobnitz(fact(10));
++ frobnitz(fib(10));
+ }
+EOF
+
+test_expect_success 'patience diff' '
+
+ test_must_fail git diff --no-index --patience file1 file2 > output &&
+ test_cmp expect output
+
+'
+
+test_expect_success 'patience diff output is valid' '
+
+ mv file2 expect &&
+ git apply < output &&
+ test_cmp expect file2
+
+'
+
+cat >uniq1 <<\EOF
+1
+2
+3
+4
+5
+6
+EOF
+
+cat >uniq2 <<\EOF
+a
+b
+c
+d
+e
+f
+EOF
+
+cat >expect <<\EOF
+diff --git a/uniq1 b/uniq2
+index b414108..0fdf397 100644
+--- a/uniq1
++++ b/uniq2
+@@ -1,6 +1,6 @@
+-1
+-2
+-3
+-4
+-5
+-6
++a
++b
++c
++d
++e
++f
+EOF
+
+test_expect_success 'completely different files' '
+
+ test_must_fail git diff --no-index --patience uniq1 uniq2 > output &&
+ test_cmp expect output
+
+'
+
+test_done
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
new file mode 100755
index 0000000000..4508effcaa
--- /dev/null
+++ b/t/t4034-diff-words.sh
@@ -0,0 +1,200 @@
+#!/bin/sh
+
+test_description='word diff colors'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ git config diff.color.old red
+ git config diff.color.new green
+
+'
+
+decrypt_color () {
+ sed \
+ -e 's/.\[1m/<WHITE>/g' \
+ -e 's/.\[31m/<RED>/g' \
+ -e 's/.\[32m/<GREEN>/g' \
+ -e 's/.\[36m/<BROWN>/g' \
+ -e 's/.\[m/<RESET>/g'
+}
+
+word_diff () {
+ test_must_fail git diff --no-index "$@" pre post > output &&
+ decrypt_color < output > output.decrypted &&
+ test_cmp expect output.decrypted
+}
+
+cat > pre <<\EOF
+h(4)
+
+a = b + c
+EOF
+
+cat > post <<\EOF
+h(4),hh[44]
+
+a = b + c
+
+aa = a
+
+aeff = aeff * ( aaa )
+EOF
+
+cat > expect <<\EOF
+<WHITE>diff --git a/pre b/post<RESET>
+<WHITE>index 330b04f..5ed8eff 100644<RESET>
+<WHITE>--- a/pre<RESET>
+<WHITE>+++ b/post<RESET>
+<BROWN>@@ -1,3 +1,7 @@<RESET>
+<RED>h(4)<RESET><GREEN>h(4),hh[44]<RESET>
+<RESET>
+a = b + c<RESET>
+
+<GREEN>aa = a<RESET>
+
+<GREEN>aeff = aeff * ( aaa )<RESET>
+EOF
+
+test_expect_success 'word diff with runs of whitespace' '
+
+ word_diff --color-words
+
+'
+
+cat > expect <<\EOF
+<WHITE>diff --git a/pre b/post<RESET>
+<WHITE>index 330b04f..5ed8eff 100644<RESET>
+<WHITE>--- a/pre<RESET>
+<WHITE>+++ b/post<RESET>
+<BROWN>@@ -1,3 +1,7 @@<RESET>
+h(4),<GREEN>hh<RESET>[44]
+<RESET>
+a = b + c<RESET>
+
+<GREEN>aa = a<RESET>
+
+<GREEN>aeff = aeff * ( aaa<RESET> )
+EOF
+cp expect expect.letter-runs-are-words
+
+test_expect_success 'word diff with a regular expression' '
+
+ word_diff --color-words="[a-z]+"
+
+'
+
+test_expect_success 'set a diff driver' '
+ git config diff.testdriver.wordRegex "[^[:space:]]" &&
+ cat <<EOF > .gitattributes
+pre diff=testdriver
+post diff=testdriver
+EOF
+'
+
+test_expect_success 'option overrides .gitattributes' '
+
+ word_diff --color-words="[a-z]+"
+
+'
+
+cat > expect <<\EOF
+<WHITE>diff --git a/pre b/post<RESET>
+<WHITE>index 330b04f..5ed8eff 100644<RESET>
+<WHITE>--- a/pre<RESET>
+<WHITE>+++ b/post<RESET>
+<BROWN>@@ -1,3 +1,7 @@<RESET>
+h(4)<GREEN>,hh[44]<RESET>
+<RESET>
+a = b + c<RESET>
+
+<GREEN>aa = a<RESET>
+
+<GREEN>aeff = aeff * ( aaa )<RESET>
+EOF
+cp expect expect.non-whitespace-is-word
+
+test_expect_success 'use regex supplied by driver' '
+
+ word_diff --color-words
+
+'
+
+test_expect_success 'set diff.wordRegex option' '
+ git config diff.wordRegex "[[:alnum:]]+"
+'
+
+cp expect.letter-runs-are-words expect
+
+test_expect_success 'command-line overrides config' '
+ word_diff --color-words="[a-z]+"
+'
+
+cp expect.non-whitespace-is-word expect
+
+test_expect_success '.gitattributes override config' '
+ word_diff --color-words
+'
+
+test_expect_success 'remove diff driver regex' '
+ git config --unset diff.testdriver.wordRegex
+'
+
+cat > expect <<\EOF
+<WHITE>diff --git a/pre b/post<RESET>
+<WHITE>index 330b04f..5ed8eff 100644<RESET>
+<WHITE>--- a/pre<RESET>
+<WHITE>+++ b/post<RESET>
+<BROWN>@@ -1,3 +1,7 @@<RESET>
+h(4),<GREEN>hh[44<RESET>]
+<RESET>
+a = b + c<RESET>
+
+<GREEN>aa = a<RESET>
+
+<GREEN>aeff = aeff * ( aaa<RESET> )
+EOF
+
+test_expect_success 'use configured regex' '
+ word_diff --color-words
+'
+
+echo 'aaa (aaa)' > pre
+echo 'aaa (aaa) aaa' > post
+
+cat > expect <<\EOF
+<WHITE>diff --git a/pre b/post<RESET>
+<WHITE>index c29453b..be22f37 100644<RESET>
+<WHITE>--- a/pre<RESET>
+<WHITE>+++ b/post<RESET>
+<BROWN>@@ -1 +1 @@<RESET>
+aaa (aaa) <GREEN>aaa<RESET>
+EOF
+
+test_expect_success 'test parsing words for newline' '
+
+ word_diff --color-words="a+"
+
+
+'
+
+echo '(:' > pre
+echo '(' > post
+
+cat > expect <<\EOF
+<WHITE>diff --git a/pre b/post<RESET>
+<WHITE>index 289cb9d..2d06f37 100644<RESET>
+<WHITE>--- a/pre<RESET>
+<WHITE>+++ b/post<RESET>
+<BROWN>@@ -1 +1 @@<RESET>
+(<RED>:<RESET>
+EOF
+
+test_expect_success 'test when words are only removed at the end' '
+
+ word_diff --color-words=.
+
+'
+
+test_done
diff --git a/t/t4017-quiet.sh b/t/t4035-diff-quiet.sh
index e747e84227..e747e84227 100755
--- a/t/t4017-quiet.sh
+++ b/t/t4035-diff-quiet.sh
diff --git a/t/t4021-format-patch-signer-mime.sh b/t/t4036-format-patch-signer-mime.sh
index ba43f18549..ba43f18549 100755
--- a/t/t4021-format-patch-signer-mime.sh
+++ b/t/t4036-format-patch-signer-mime.sh
diff --git a/t/t4037-diff-r-t-dirs.sh b/t/t4037-diff-r-t-dirs.sh
new file mode 100755
index 0000000000..f5ce3b29a2
--- /dev/null
+++ b/t/t4037-diff-r-t-dirs.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+test_description='diff -r -t shows directory additions and deletions'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ mkdir dc dr dt &&
+ >dc/1 &&
+ >dr/2 &&
+ >dt/3 &&
+ >fc &&
+ >fr &&
+ >ft &&
+ git add . &&
+ test_tick &&
+ git commit -m initial &&
+
+ rm -fr dt dr ft fr &&
+ mkdir da ft &&
+ for p in dc/1 da/4 dt ft/5 fc
+ do
+ echo hello >$p || exit
+ done &&
+ git add -u &&
+ git add . &&
+ test_tick &&
+ git commit -m second
+'
+
+cat >expect <<\EOF
+A da
+A da/4
+M dc
+M dc/1
+D dr
+D dr/2
+A dt
+D dt
+D dt/3
+M fc
+D fr
+D ft
+A ft
+A ft/5
+EOF
+
+test_expect_success verify '
+ git diff-tree -r -t --name-status HEAD^ HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
new file mode 100755
index 0000000000..2cf7e01ac2
--- /dev/null
+++ b/t/t4038-diff-combined.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+test_description='combined diff'
+
+. ./test-lib.sh
+
+setup_helper () {
+ one=$1 branch=$2 side=$3 &&
+
+ git branch $side $branch &&
+ for l in $one two three fyra
+ do
+ echo $l
+ done >file &&
+ git add file &&
+ test_tick &&
+ git commit -m $branch &&
+ git checkout $side &&
+ for l in $one two three quatro
+ do
+ echo $l
+ done >file &&
+ git add file &&
+ test_tick &&
+ git commit -m $side &&
+ test_must_fail git merge $branch &&
+ for l in $one three four
+ do
+ echo $l
+ done >file &&
+ git add file &&
+ test_tick &&
+ git commit -m "merge $branch into $side"
+}
+
+verify_helper () {
+ it=$1 &&
+
+ # Ignore lines that were removed only from the other parent
+ sed -e '
+ 1,/^@@@/d
+ /^ -/d
+ s/^\(.\)./\1/
+ ' "$it" >"$it.actual.1" &&
+ sed -e '
+ 1,/^@@@/d
+ /^- /d
+ s/^.\(.\)/\1/
+ ' "$it" >"$it.actual.2" &&
+
+ git diff "$it^" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.1" &&
+ test_cmp "$it.expect.1" "$it.actual.1" &&
+
+ git diff "$it^2" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.2" &&
+ test_cmp "$it.expect.2" "$it.actual.2"
+}
+
+test_expect_success setup '
+ >file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+
+ git branch withone &&
+ git branch sansone &&
+
+ git checkout withone &&
+ setup_helper one withone sidewithone &&
+
+ git checkout sansone &&
+ setup_helper "" sansone sidesansone
+'
+
+test_expect_success 'check combined output (1)' '
+ git show sidewithone -- >sidewithone &&
+ verify_helper sidewithone
+'
+
+test_expect_failure 'check combined output (2)' '
+ git show sidesansone -- >sidesansone &&
+ verify_helper sidesansone
+'
+
+test_done
diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh
index d42abff1ad..1597965241 100755
--- a/t/t4102-apply-rename.sh
+++ b/t/t4102-apply-rename.sh
@@ -31,14 +31,16 @@ test_expect_success setup \
test_expect_success apply \
'git apply --index --stat --summary --apply test-patch'
-if [ "$(git config --get core.filemode)" = false ]
+if test "$(git config --bool core.filemode)" = false
then
say 'filemode disabled on the filesystem'
else
- test_expect_success validate \
- 'test -f bar && ls -l bar | grep "^-..x......"'
+ test_set_prereq FILEMODE
fi
+test_expect_success FILEMODE validate \
+ 'test -f bar && ls -l bar | grep "^-..x......"'
+
test_expect_success 'apply reverse' \
'git apply -R --index --stat --summary --apply test-patch &&
test "$(cat foo)" = "This is foo"'
diff --git a/t/t4106-apply-stdin.sh b/t/t4106-apply-stdin.sh
new file mode 100755
index 0000000000..72467a1e8e
--- /dev/null
+++ b/t/t4106-apply-stdin.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+test_description='git apply --numstat - <patch'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo hello >text &&
+ git add text &&
+ echo goodbye >text &&
+ git diff >patch
+'
+
+test_expect_success 'git apply --numstat - < patch' '
+ echo "1 1 text" >expect &&
+ git apply --numstat - <patch >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git apply --numstat - < patch patch' '
+ for i in 1 2; do echo "1 1 text"; done >expect &&
+ git apply --numstat - < patch patch >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t4114-apply-typechange.sh b/t/t4114-apply-typechange.sh
index 0f185caa44..99ec13dd53 100755
--- a/t/t4114-apply-typechange.sh
+++ b/t/t4114-apply-typechange.sh
@@ -9,6 +9,12 @@ test_description='git apply should not get confused with type changes.
. ./test-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
test_expect_success 'setup repository and commits' '
echo "hello world" > foo &&
echo "hi planet" > bar &&
diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh
index 9ace578f17..b852e58980 100755
--- a/t/t4115-apply-symlink.sh
+++ b/t/t4115-apply-symlink.sh
@@ -9,6 +9,12 @@ test_description='git apply symlinks and partial files
. ./test-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
test_expect_success setup '
ln -s path1/path2/path3/path4/path5 link1 &&
diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh
index f92e259cc6..65f2e4c3ef 100755
--- a/t/t4118-apply-empty-context.sh
+++ b/t/t4118-apply-empty-context.sh
@@ -20,10 +20,10 @@ test_expect_success setup '
cat file1 &&
echo Q | tr -d "\\012"
} >file2 &&
- cat file2 >file2.orig
+ cat file2 >file2.orig &&
git add file1 file2 &&
sed -e "/^B/d" <file1.orig >file1 &&
- sed -e "/^[BQ]/d" <file2.orig >file2 &&
+ cat file1 > file2 &&
echo Q | tr -d "\\012" >>file2 &&
cat file1 >file1.mods &&
cat file2 >file2.mods &&
diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh
index 841773f75f..0d3c1d5dd5 100755
--- a/t/t4122-apply-symlink-inside.sh
+++ b/t/t4122-apply-symlink-inside.sh
@@ -3,6 +3,12 @@
test_description='apply to deeper directory without getting fooled with symlink'
. ./test-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
lecho () {
for l_
do
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index f83322e513..fac2093d7f 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -148,4 +148,26 @@ do
done
done
+create_patch () {
+ sed -e "s/_/ /" <<-\EOF
+ diff --git a/target b/target
+ index e69de29..8bd6648 100644
+ --- a/target
+ +++ b/target
+ @@ -0,0 +1,3 @@
+ +An empty line follows
+ +
+ +A line with trailing whitespace and no newline_
+ \ No newline at end of file
+ EOF
+}
+
+test_expect_success 'trailing whitespace & no newline at the end of file' '
+ >target &&
+ create_patch >patch-file &&
+ git apply --whitespace=fix patch-file &&
+ grep "newline$" target &&
+ grep "^$" target
+'
+
test_done
diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh
index adfcbb5a3b..fc7af04931 100755
--- a/t/t4129-apply-samemode.sh
+++ b/t/t4129-apply-samemode.sh
@@ -4,6 +4,13 @@ test_description='applying patch with mode bits'
. ./test-lib.sh
+if test "$(git config --bool core.filemode)" = false
+then
+ say 'filemode disabled on the filesystem'
+else
+ test_set_prereq FILEMODE
+fi
+
test_expect_success setup '
echo original >file &&
git add file &&
@@ -16,14 +23,14 @@ test_expect_success setup '
git diff --stat -p >patch-1.txt
'
-test_expect_success 'same mode (no index)' '
+test_expect_success FILEMODE 'same mode (no index)' '
git reset --hard &&
chmod +x file &&
git apply patch-0.txt &&
test -x file
'
-test_expect_success 'same mode (with index)' '
+test_expect_success FILEMODE 'same mode (with index)' '
git reset --hard &&
chmod +x file &&
git add file &&
@@ -32,7 +39,7 @@ test_expect_success 'same mode (with index)' '
git diff --exit-code
'
-test_expect_success 'same mode (index only)' '
+test_expect_success FILEMODE 'same mode (index only)' '
git reset --hard &&
chmod +x file &&
git add file &&
@@ -40,20 +47,20 @@ test_expect_success 'same mode (index only)' '
git ls-files -s file | grep "^100755"
'
-test_expect_success 'mode update (no index)' '
+test_expect_success FILEMODE 'mode update (no index)' '
git reset --hard &&
git apply patch-1.txt &&
test -x file
'
-test_expect_success 'mode update (with index)' '
+test_expect_success FILEMODE 'mode update (with index)' '
git reset --hard &&
git apply --index patch-1.txt &&
test -x file &&
git diff --exit-code
'
-test_expect_success 'mode update (index only)' '
+test_expect_success FILEMODE 'mode update (index only)' '
git reset --hard &&
git apply --cached patch-1.txt &&
git ls-files -s file | grep "^100755"
diff --git a/t/t4130-apply-criss-cross-rename.sh b/t/t4130-apply-criss-cross-rename.sh
new file mode 100755
index 0000000000..7cfa2d6287
--- /dev/null
+++ b/t/t4130-apply-criss-cross-rename.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+test_description='git apply handling criss-cross rename patch.'
+. ./test-lib.sh
+
+create_file() {
+ cnt=0
+ while test $cnt -le 100
+ do
+ cnt=$(($cnt + 1))
+ echo "$2" >> "$1"
+ done
+}
+
+test_expect_success 'setup' '
+ create_file file1 "File1 contents" &&
+ create_file file2 "File2 contents" &&
+ create_file file3 "File3 contents" &&
+ git add file1 file2 file3 &&
+ git commit -m 1
+'
+
+test_expect_success 'criss-cross rename' '
+ mv file1 tmp &&
+ mv file2 file1 &&
+ mv tmp file2 &&
+ cp file1 file1-swapped &&
+ cp file2 file2-swapped
+'
+
+test_expect_success 'diff -M -B' '
+ git diff -M -B > diff &&
+ git reset --hard
+
+'
+
+test_expect_success 'apply' '
+ git apply diff &&
+ test_cmp file1 file1-swapped &&
+ test_cmp file2 file2-swapped
+'
+
+test_expect_success 'criss-cross rename' '
+ git reset --hard &&
+ mv file1 tmp &&
+ mv file2 file1 &&
+ mv file3 file2
+ mv tmp file3 &&
+ cp file1 file1-swapped &&
+ cp file2 file2-swapped &&
+ cp file3 file3-swapped
+'
+
+test_expect_success 'diff -M -B' '
+ git diff -M -B > diff &&
+ git reset --hard
+'
+
+test_expect_success 'apply' '
+ git apply diff &&
+ test_cmp file1 file1-swapped &&
+ test_cmp file2 file2-swapped &&
+ test_cmp file3 file3-swapped
+'
+
+test_done
diff --git a/t/t4131-apply-fake-ancestor.sh b/t/t4131-apply-fake-ancestor.sh
new file mode 100755
index 0000000000..94373ca9a0
--- /dev/null
+++ b/t/t4131-apply-fake-ancestor.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Stephen Boyd
+#
+
+test_description='git apply --build-fake-ancestor handling.'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit 1 &&
+ test_commit 2 &&
+ mkdir sub &&
+ test_commit 3 sub/3 &&
+ test_commit 4
+'
+
+test_expect_success 'apply --build-fake-ancestor' '
+ git checkout 2 &&
+ echo "A" > 1.t &&
+ git diff > 1.patch &&
+ git reset --hard &&
+ git checkout 1 &&
+ git apply --build-fake-ancestor 1.ancestor 1.patch
+'
+
+test_expect_success 'apply --build-fake-ancestor in a subdirectory' '
+ git checkout 3 &&
+ echo "C" > sub/3.t &&
+ git diff > 3.patch &&
+ git reset --hard &&
+ git checkout 4 &&
+ (
+ cd sub &&
+ git apply --build-fake-ancestor 3.ancestor ../3.patch &&
+ test -f 3.ancestor
+ ) &&
+ git apply --build-fake-ancestor 3.ancestor 3.patch &&
+ test_cmp sub/3.ancestor 3.ancestor
+'
+
+test_done
diff --git a/t/t4132-apply-removal.sh b/t/t4132-apply-removal.sh
new file mode 100755
index 0000000000..bb1ffe3b6c
--- /dev/null
+++ b/t/t4132-apply-removal.sh
@@ -0,0 +1,95 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Junio C Hamano
+
+test_description='git-apply notices removal patches generated by GNU diff'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ cat <<-EOF >c &&
+ diff -ruN a/file b/file
+ --- a/file TS0
+ +++ b/file TS1
+ @@ -0,0 +1 @@
+ +something
+ EOF
+
+ cat <<-EOF >d &&
+ diff -ruN a/file b/file
+ --- a/file TS0
+ +++ b/file TS1
+ @@ -1 +0,0 @@
+ -something
+ EOF
+
+ timeWest="1982-09-16 07:00:00.000000000 -0800" &&
+ timeGMT="1982-09-16 15:00:00.000000000 +0000" &&
+ timeEast="1982-09-17 00:00:00.000000000 +0900" &&
+
+ epocWest="1969-12-31 16:00:00.000000000 -0800" &&
+ epocGMT="1970-01-01 00:00:00.000000000 +0000" &&
+ epocEast="1970-01-01 09:00:00.000000000 +0900" &&
+
+ sed -e "s/TS0/$epocWest/" -e "s/TS1/$timeWest/" <c >createWest.patch &&
+ sed -e "s/TS0/$epocEast/" -e "s/TS1/$timeEast/" <c >createEast.patch &&
+ sed -e "s/TS0/$epocGMT/" -e "s/TS1/$timeGMT/" <c >createGMT.patch &&
+
+ sed -e "s/TS0/$timeWest/" -e "s/TS1/$timeWest/" <c >addWest.patch &&
+ sed -e "s/TS0/$timeEast/" -e "s/TS1/$timeEast/" <c >addEast.patch &&
+ sed -e "s/TS0/$timeGMT/" -e "s/TS1/$timeGMT/" <c >addGMT.patch &&
+
+ sed -e "s/TS0/$timeWest/" -e "s/TS1/$timeWest/" <d >emptyWest.patch &&
+ sed -e "s/TS0/$timeEast/" -e "s/TS1/$timeEast/" <d >emptyEast.patch &&
+ sed -e "s/TS0/$timeGMT/" -e "s/TS1/$timeGMT/" <d >emptyGMT.patch &&
+
+ sed -e "s/TS0/$timeWest/" -e "s/TS1/$epocWest/" <d >removeWest.patch &&
+ sed -e "s/TS0/$timeEast/" -e "s/TS1/$epocEast/" <d >removeEast.patch &&
+ sed -e "s/TS0/$timeGMT/" -e "s/TS1/$epocGMT/" <d >removeGMT.patch &&
+
+ echo something >something &&
+ >empty
+'
+
+for patch in *.patch
+do
+ test_expect_success "test $patch" '
+ rm -f file .git/index &&
+ case "$patch" in
+ create*)
+ # must be able to create
+ git apply --index $patch &&
+ test_cmp file something &&
+ # must notice the file is already there
+ >file &&
+ git add file &&
+ test_must_fail git apply $patch
+ ;;
+ add*)
+ # must be able to create or patch
+ git apply $patch &&
+ test_cmp file something &&
+ >file &&
+ git apply $patch &&
+ test_cmp file something
+ ;;
+ empty*)
+ # must leave an empty file
+ cat something >file &&
+ git add file &&
+ git apply --index $patch &&
+ test -f file &&
+ test_cmp empty file
+ ;;
+ remove*)
+ # must remove the file
+ cat something >file &&
+ git add file &&
+ git apply --index $patch &&
+ ! test -f file
+ ;;
+ esac
+ '
+done
+
+test_done
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 796f795267..8296605234 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -77,6 +77,12 @@ test_expect_success setup '
git commit -s -F msg &&
git tag second &&
git format-patch --stdout first >patch1 &&
+ {
+ echo "X-Fake-Field: Line One" &&
+ echo "X-Fake-Field: Line Two" &&
+ echo "X-Fake-Field: Line Three" &&
+ git format-patch --stdout first | sed -e "1d"
+ } > patch1.eml &&
sed -n -e "3,\$p" msg >file &&
git add file &&
test_tick &&
@@ -108,6 +114,15 @@ test_expect_success 'am applies patch correctly' '
test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
'
+test_expect_success 'am applies patch e-mail not in a mbox' '
+ git checkout first &&
+ git am patch1.eml &&
+ ! test -d .git/rebase-apply &&
+ test -z "$(git diff second)" &&
+ test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
+ test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
+'
+
GIT_AUTHOR_NAME="Another Thor"
GIT_AUTHOR_EMAIL="a.thor@example.com"
GIT_COMMITTER_NAME="Co M Miter"
@@ -180,6 +195,17 @@ test_expect_success 'am -3 falls back to 3-way merge' '
test -z "$(git diff lorem)"
'
+test_expect_success 'am -3 -q is quiet' '
+ git reset master2 --hard &&
+ sed -n -e "3,\$p" msg >file &&
+ head -n 9 msg >>file &&
+ git add file &&
+ test_tick &&
+ git commit -m "copied stuff" &&
+ git am -3 -q lorem-move.patch > output.out 2>&1 &&
+ ! test -s output.out
+'
+
test_expect_success 'am pauses on conflict' '
git checkout lorem2^^ &&
test_must_fail git am lorem-move.patch &&
@@ -257,4 +283,67 @@ test_expect_success 'am works from file (absolute path given) in subdirectory' '
test -z "$(git diff second)"
'
+test_expect_success 'am --committer-date-is-author-date' '
+ git checkout first &&
+ test_tick &&
+ git am --committer-date-is-author-date patch1 &&
+ git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
+ at=$(sed -ne "/^author /s/.*> //p" head1) &&
+ ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
+ test "$at" = "$ct"
+'
+
+test_expect_success 'am without --committer-date-is-author-date' '
+ git checkout first &&
+ test_tick &&
+ git am patch1 &&
+ git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
+ at=$(sed -ne "/^author /s/.*> //p" head1) &&
+ ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
+ test "$at" != "$ct"
+'
+
+# This checks for +0000 because TZ is set to UTC and that should
+# show up when the current time is used. The date in message is set
+# by test_tick that uses -0700 timezone; if this feature does not
+# work, we will see that instead of +0000.
+test_expect_success 'am --ignore-date' '
+ git checkout first &&
+ test_tick &&
+ git am --ignore-date patch1 &&
+ git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
+ at=$(sed -ne "/^author /s/.*> //p" head1) &&
+ echo "$at" | grep "+0000"
+'
+
+test_expect_success 'am into an unborn branch' '
+ rm -fr subdir &&
+ mkdir -p subdir &&
+ git format-patch --numbered-files -o subdir -1 first &&
+ (
+ cd subdir &&
+ git init &&
+ git am 1
+ ) &&
+ result=$(
+ cd subdir && git rev-parse HEAD^{tree}
+ ) &&
+ test "z$result" = "z$(git rev-parse first^{tree})"
+'
+
+test_expect_success 'am newline in subject' '
+ git checkout first &&
+ test_tick &&
+ sed -e "s/second/second \\\n foo/" patch1 > patchnl &&
+ git am < patchnl > output.out 2>&1 &&
+ grep "^Applying: second \\\n foo$" output.out
+'
+
+test_expect_success 'am -q is quiet' '
+ git checkout first &&
+ test_tick &&
+ git am -q < patch1 > output.out 2>&1 &&
+ ! test -s output.out
+'
+
test_done
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index b68ab11f29..a6bc028a57 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -57,7 +57,7 @@ test_expect_success 'conflicting merge' '
test_must_fail git merge first
'
-sha1=$(sed -e 's/ .*//' .git/MERGE_RR)
+sha1=$(perl -pe 's/ .*//' .git/MERGE_RR)
rr=.git/rr-cache/$sha1
test_expect_success 'recorded preimage' "grep ^=======$ $rr/preimage"
@@ -190,8 +190,6 @@ test_expect_success 'file2 added differently in two branches' '
git add file2 &&
git commit -m version2 &&
test_must_fail git merge fourth &&
- sha1=$(sed -e "s/ .*//" .git/MERGE_RR) &&
- rr=.git/rr-cache/$sha1 &&
echo Cello > file2 &&
git add file2 &&
git commit -m resolution
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 0ab925c4e4..48e0088b47 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -16,27 +16,71 @@ test_expect_success setup '
test_tick &&
git commit -m second &&
- mkdir a &&
- echo ni >a/two &&
- git add a/two &&
+ git mv one ichi &&
test_tick &&
git commit -m third &&
- echo san >a/three &&
- git add a/three &&
+ cp ichi ein &&
+ git add ein &&
test_tick &&
git commit -m fourth &&
- git rm a/three &&
+ mkdir a &&
+ echo ni >a/two &&
+ git add a/two &&
test_tick &&
- git commit -m fifth
+ git commit -m fifth &&
+
+ git rm a/two &&
+ test_tick &&
+ git commit -m sixth
'
+printf "sixth\nfifth\nfourth\nthird\nsecond\ninitial" > expect
+test_expect_success 'pretty' '
+
+ git log --pretty="format:%s" > actual &&
+ test_cmp expect actual
+'
+
+printf "sixth\nfifth\nfourth\nthird\nsecond\ninitial\n" > expect
+test_expect_success 'pretty (tformat)' '
+
+ git log --pretty="tformat:%s" > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'pretty (shortcut)' '
+
+ git log --pretty="%s" > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'format' '
+
+ git log --format="%s" > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+804a787 sixth
+394ef78 fifth
+5d31159 fourth
+2fbe8c0 third
+f7dab8e second
+3a2fdcb initial
+EOF
+test_expect_success 'oneline' '
+
+ git log --oneline > actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'diff-filter=A' '
actual=$(git log --pretty="format:%s" --diff-filter=A HEAD) &&
- expect=$(echo fourth ; echo third ; echo initial) &&
+ expect=$(echo fifth ; echo fourth ; echo third ; echo initial) &&
test "$actual" = "$expect" || {
echo Oops
echo "Actual: $actual"
@@ -60,7 +104,31 @@ test_expect_success 'diff-filter=M' '
test_expect_success 'diff-filter=D' '
actual=$(git log --pretty="format:%s" --diff-filter=D HEAD) &&
- expect=$(echo fifth) &&
+ expect=$(echo sixth ; echo third) &&
+ test "$actual" = "$expect" || {
+ echo Oops
+ echo "Actual: $actual"
+ false
+ }
+
+'
+
+test_expect_success 'diff-filter=R' '
+
+ actual=$(git log -M --pretty="format:%s" --diff-filter=R HEAD) &&
+ expect=$(echo third) &&
+ test "$actual" = "$expect" || {
+ echo Oops
+ echo "Actual: $actual"
+ false
+ }
+
+'
+
+test_expect_success 'diff-filter=C' '
+
+ actual=$(git log -C -C --pretty="format:%s" --diff-filter=C HEAD) &&
+ expect=$(echo fourth) &&
test "$actual" = "$expect" || {
echo Oops
echo "Actual: $actual"
@@ -69,9 +137,42 @@ test_expect_success 'diff-filter=D' '
'
+test_expect_success 'git log --follow' '
+
+ actual=$(git log --follow --pretty="format:%s" ichi) &&
+ expect=$(echo third ; echo second ; echo initial) &&
+ test "$actual" = "$expect" || {
+ echo Oops
+ echo "Actual: $actual"
+ false
+ }
+
+'
+
+cat > expect << EOF
+804a787 sixth
+394ef78 fifth
+5d31159 fourth
+EOF
+test_expect_success 'git log --no-walk <commits> sorts by commit time' '
+ git log --no-walk --oneline 5d31159 804a787 394ef78 > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+5d31159 fourth
+804a787 sixth
+394ef78 fifth
+EOF
+test_expect_success 'git show <commits> leaves list of commits as given' '
+ git show --oneline -s 5d31159 804a787 394ef78 > actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup case sensitivity tests' '
echo case >one &&
test_tick &&
+ git add one
git commit -a -m Second
'
@@ -93,5 +194,177 @@ test_expect_success 'log --grep -i' '
test_cmp expect actual
'
+cat > expect <<EOF
+* Second
+* sixth
+* fifth
+* fourth
+* third
+* second
+* initial
+EOF
+
+test_expect_success 'simple log --graph' '
+ git log --graph --pretty=tformat:%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'set up merge history' '
+ git checkout -b side HEAD~4 &&
+ test_commit side-1 1 1 &&
+ test_commit side-2 2 2 &&
+ git checkout master &&
+ git merge side
+'
+
+cat > expect <<\EOF
+* Merge branch 'side'
+|\
+| * side-2
+| * side-1
+* | Second
+* | sixth
+* | fifth
+* | fourth
+|/
+* third
+* second
+* initial
+EOF
+
+test_expect_success 'log --graph with merge' '
+ git log --graph --date-order --pretty=tformat:%s |
+ sed "s/ *$//" >actual &&
+ test_cmp expect actual
+'
+
+cat > expect <<\EOF
+* commit master
+|\ Merge: A B
+| | Author: A U Thor <author@example.com>
+| |
+| | Merge branch 'side'
+| |
+| * commit side
+| | Author: A U Thor <author@example.com>
+| |
+| | side-2
+| |
+| * commit tags/side-1
+| | Author: A U Thor <author@example.com>
+| |
+| | side-1
+| |
+* | commit master~1
+| | Author: A U Thor <author@example.com>
+| |
+| | Second
+| |
+* | commit master~2
+| | Author: A U Thor <author@example.com>
+| |
+| | sixth
+| |
+* | commit master~3
+| | Author: A U Thor <author@example.com>
+| |
+| | fifth
+| |
+* | commit master~4
+|/ Author: A U Thor <author@example.com>
+|
+| fourth
+|
+* commit tags/side-1~1
+| Author: A U Thor <author@example.com>
+|
+| third
+|
+* commit tags/side-1~2
+| Author: A U Thor <author@example.com>
+|
+| second
+|
+* commit tags/side-1~3
+ Author: A U Thor <author@example.com>
+
+ initial
+EOF
+
+test_expect_success 'log --graph with full output' '
+ git log --graph --date-order --pretty=short |
+ git name-rev --name-only --stdin |
+ sed "s/Merge:.*/Merge: A B/;s/ *$//" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'set up more tangled history' '
+ git checkout -b tangle HEAD~6 &&
+ test_commit tangle-a tangle-a a &&
+ git merge master~3 &&
+ git merge side~1 &&
+ git checkout master &&
+ git merge tangle &&
+ git checkout -b reach &&
+ test_commit reach &&
+ git checkout master &&
+ git checkout -b octopus-a &&
+ test_commit octopus-a &&
+ git checkout master &&
+ git checkout -b octopus-b &&
+ test_commit octopus-b &&
+ git checkout master &&
+ test_commit seventh &&
+ git merge octopus-a octopus-b
+ git merge reach
+'
+
+cat > expect <<\EOF
+* Merge branch 'reach'
+|\
+| \
+| \
+*-. \ Merge branches 'octopus-a' and 'octopus-b'
+|\ \ \
+* | | | seventh
+| | * | octopus-b
+| |/ /
+|/| |
+| * | octopus-a
+|/ /
+| * reach
+|/
+* Merge branch 'tangle'
+|\
+| * Merge branch 'side' (early part) into tangle
+| |\
+| * \ Merge branch 'master' (early part) into tangle
+| |\ \
+| * | | tangle-a
+* | | | Merge branch 'side'
+|\ \ \ \
+| * | | | side-2
+| | |_|/
+| |/| |
+| * | | side-1
+* | | | Second
+* | | | sixth
+| |_|/
+|/| |
+* | | fifth
+* | | fourth
+|/ /
+* | third
+|/
+* second
+* initial
+EOF
+
+test_expect_success 'log --graph with merge' '
+ git log --graph --date-order --pretty=tformat:%s |
+ sed "s/ *$//" >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
new file mode 100755
index 0000000000..9a7d1b4466
--- /dev/null
+++ b/t/t4203-mailmap.sh
@@ -0,0 +1,215 @@
+#!/bin/sh
+
+test_description='.mailmap configurations'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo one >one &&
+ git add one &&
+ test_tick &&
+ git commit -m initial &&
+ echo two >>one &&
+ git add one &&
+ git commit --author "nick1 <bugs@company.xx>" -m second
+'
+
+cat >expect <<\EOF
+A U Thor (1):
+ initial
+
+nick1 (1):
+ second
+
+EOF
+
+test_expect_success 'No mailmap' '
+ git shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+Repo Guy (1):
+ initial
+
+nick1 (1):
+ second
+
+EOF
+
+test_expect_success 'default .mailmap' '
+ echo "Repo Guy <author@example.com>" > .mailmap &&
+ git shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+# Using a mailmap file in a subdirectory of the repo here, but
+# could just as well have been a file outside of the repository
+cat >expect <<\EOF
+Internal Guy (1):
+ second
+
+Repo Guy (1):
+ initial
+
+EOF
+test_expect_success 'mailmap.file set' '
+ mkdir internal_mailmap &&
+ echo "Internal Guy <bugs@company.xx>" > internal_mailmap/.mailmap &&
+ git config mailmap.file internal_mailmap/.mailmap &&
+ git shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+External Guy (1):
+ initial
+
+Internal Guy (1):
+ second
+
+EOF
+test_expect_success 'mailmap.file override' '
+ echo "External Guy <author@example.com>" >> internal_mailmap/.mailmap &&
+ git config mailmap.file internal_mailmap/.mailmap &&
+ git shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+Repo Guy (1):
+ initial
+
+nick1 (1):
+ second
+
+EOF
+
+test_expect_success 'mailmap.file non-existant' '
+ rm internal_mailmap/.mailmap &&
+ rmdir internal_mailmap &&
+ git shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+A U Thor (1):
+ initial
+
+nick1 (1):
+ second
+
+EOF
+test_expect_success 'No mailmap files, but configured' '
+ rm .mailmap &&
+ git shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+# Extended mailmap configurations should give us the following output for shortlog
+cat >expect <<\EOF
+A U Thor <author@example.com> (1):
+ initial
+
+CTO <cto@company.xx> (1):
+ seventh
+
+Other Author <other@author.xx> (2):
+ third
+ fourth
+
+Santa Claus <santa.claus@northpole.xx> (2):
+ fifth
+ sixth
+
+Some Dude <some@dude.xx> (1):
+ second
+
+EOF
+
+test_expect_success 'Shortlog output (complex mapping)' '
+ echo three >>one &&
+ git add one &&
+ test_tick &&
+ git commit --author "nick2 <bugs@company.xx>" -m third &&
+
+ echo four >>one &&
+ git add one &&
+ test_tick &&
+ git commit --author "nick2 <nick2@company.xx>" -m fourth &&
+
+ echo five >>one &&
+ git add one &&
+ test_tick &&
+ git commit --author "santa <me@company.xx>" -m fifth &&
+
+ echo six >>one &&
+ git add one &&
+ test_tick &&
+ git commit --author "claus <me@company.xx>" -m sixth &&
+
+ echo seven >>one &&
+ git add one &&
+ test_tick &&
+ git commit --author "CTO <cto@coompany.xx>" -m seventh &&
+
+ mkdir internal_mailmap &&
+ echo "Committed <committer@example.com>" > internal_mailmap/.mailmap &&
+ echo "<cto@company.xx> <cto@coompany.xx>" >> internal_mailmap/.mailmap &&
+ echo "Some Dude <some@dude.xx> nick1 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
+ echo "Other Author <other@author.xx> nick2 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
+ echo "Other Author <other@author.xx> <nick2@company.xx>" >> internal_mailmap/.mailmap &&
+ echo "Santa Claus <santa.claus@northpole.xx> <me@company.xx>" >> internal_mailmap/.mailmap &&
+ echo "Santa Claus <santa.claus@northpole.xx> <me@company.xx>" >> internal_mailmap/.mailmap &&
+
+ git shortlog -e HEAD >actual &&
+ test_cmp expect actual
+
+'
+
+# git log with --pretty format which uses the name and email mailmap placemarkers
+cat >expect <<\EOF
+Author CTO <cto@coompany.xx> maps to CTO <cto@company.xx>
+Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+
+Author claus <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
+Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+
+Author santa <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
+Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+
+Author nick2 <nick2@company.xx> maps to Other Author <other@author.xx>
+Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+
+Author nick2 <bugs@company.xx> maps to Other Author <other@author.xx>
+Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+
+Author nick1 <bugs@company.xx> maps to Some Dude <some@dude.xx>
+Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+
+Author A U Thor <author@example.com> maps to A U Thor <author@example.com>
+Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+EOF
+
+test_expect_success 'Log output (complex mapping)' '
+ git log --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
+ test_cmp expect actual
+'
+
+# git blame
+cat >expect <<\EOF
+^3a2fdcb (A U Thor 2005-04-07 15:13:13 -0700 1) one
+7de6f99b (Some Dude 2005-04-07 15:13:13 -0700 2) two
+5815879d (Other Author 2005-04-07 15:14:13 -0700 3) three
+ff859d96 (Other Author 2005-04-07 15:15:13 -0700 4) four
+5ab6d4fa (Santa Claus 2005-04-07 15:16:13 -0700 5) five
+38a42d8b (Santa Claus 2005-04-07 15:17:13 -0700 6) six
+8ddc0386 (CTO 2005-04-07 15:18:13 -0700 7) seven
+EOF
+
+test_expect_success 'Blame output (complex mapping)' '
+ git blame one >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh
new file mode 100755
index 0000000000..04f7bae850
--- /dev/null
+++ b/t/t4204-patch-id.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+test_description='git patch-id'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit initial foo a &&
+ test_commit first foo b &&
+ git checkout -b same HEAD^ &&
+ test_commit same-msg foo b &&
+ git checkout -b notsame HEAD^ &&
+ test_commit notsame-msg foo c
+'
+
+test_expect_success 'patch-id output is well-formed' '
+ git log -p -1 | git patch-id > output &&
+ grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output
+'
+
+get_patch_id () {
+ git log -p -1 "$1" | git patch-id |
+ sed "s# .*##" > patch-id_"$1"
+}
+
+test_expect_success 'patch-id detects equality' '
+ get_patch_id master &&
+ get_patch_id same &&
+ test_cmp patch-id_master patch-id_same
+'
+
+test_expect_success 'patch-id detects inequality' '
+ get_patch_id master &&
+ get_patch_id notsame &&
+ ! test_cmp patch-id_master patch-id_notsame
+'
+
+test_done
diff --git a/t/t4252-am-options.sh b/t/t4252-am-options.sh
index 3ab9e8e6e3..f603c1b133 100755
--- a/t/t4252-am-options.sh
+++ b/t/t4252-am-options.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='git am not losing options'
+test_description='git am with options and not losing them'
. ./test-lib.sh
tm="$TEST_DIRECTORY/t4252"
@@ -50,4 +50,29 @@ test_expect_success 'interrupted am -C1 -p2' '
grep "^Three$" file-2
'
+test_expect_success 'interrupted am --directory="frotz nitfol"' '
+ rm -rf .git/rebase-apply &&
+ git reset --hard initial &&
+ test_must_fail git am --directory="frotz nitfol" "$tm"/am-test-5-? &&
+ git am --skip &&
+ grep One "frotz nitfol/file-5"
+'
+
+test_expect_success 'apply to a funny path' '
+ with_sq="with'\''sq"
+ rm -fr .git/rebase-apply &&
+ git reset --hard initial &&
+ git am --directory="$with_sq" "$tm"/am-test-5-2 &&
+ test -f "$with_sq/file-5"
+'
+
+test_expect_success 'am --reject' '
+ rm -rf .git/rebase-apply &&
+ git reset --hard initial &&
+ test_must_fail git am --reject "$tm"/am-test-6-1 &&
+ grep "@@ -1,3 +1,3 @@" file-2.rej &&
+ test_must_fail git diff-files --exit-code --quiet file-2 &&
+ grep "[-]-reject" .git/rebase-apply/apply-opt
+'
+
test_done
diff --git a/t/t4252/am-test-5-1 b/t/t4252/am-test-5-1
new file mode 100644
index 0000000000..da7bf29cbe
--- /dev/null
+++ b/t/t4252/am-test-5-1
@@ -0,0 +1,20 @@
+From: A U Thor <au.thor@example.com>
+Date: Thu Dec 4 16:00:00 2008 -0800
+Subject: Six
+
+Applying this patch with --directory='frotz nitfol' should fail
+
+diff --git i/junk/file-2 w/junk/file-2
+index 06e567b..b6f3a16 100644
+--- i/junk/file-2
++++ w/junk/file-2
+@@ -1,7 +1,7 @@
+ One
+ 2
+-3
++Three
+ 4
+ 5
+-6
++Six
+ 7
diff --git a/t/t4252/am-test-5-2 b/t/t4252/am-test-5-2
new file mode 100644
index 0000000000..373025bcf6
--- /dev/null
+++ b/t/t4252/am-test-5-2
@@ -0,0 +1,15 @@
+From: A U Thor <au.thor@example.com>
+Date: Thu Dec 4 16:00:00 2008 -0800
+Subject: Six
+
+Applying this patch with --directory='frotz nitfol' should succeed
+
+diff --git i/file-5 w/file-5
+new file mode 100644
+index 000000..1d6ed9f
+--- /dev/null
++++ w/file-5
+@@ -0,0 +1,3 @@
++One
++two
++three
diff --git a/t/t4252/am-test-6-1 b/t/t4252/am-test-6-1
new file mode 100644
index 0000000000..a8859e9b8f
--- /dev/null
+++ b/t/t4252/am-test-6-1
@@ -0,0 +1,21 @@
+From: A U Thor <au.thor@example.com>
+Date: Thu Dec 4 16:00:00 2008 -0800
+Subject: Huh
+
+Should fail and leave rejects
+
+diff --git i/file-2 w/file-2
+index 06e567b..b6f3a16 100644
+--- i/file-2
++++ w/file-2
+@@ -1,3 +1,3 @@
+-0
++One
+ 2
+ 3
+@@ -4,4 +4,4 @@
+ 4
+ 5
+-6
++Six
+ 7
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index c942c8be85..5f84b18fa5 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -37,7 +37,11 @@ test_expect_success \
cp /bin/sh a/bin &&
printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 &&
printf "A not substituted O" >a/substfile2 &&
- ln -s a a/l1 &&
+ if test_have_prereq SYMLINKS; then
+ ln -s a a/l1
+ else
+ printf %s a > a/l1
+ fi &&
(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) &&
@@ -46,7 +50,7 @@ test_expect_success \
test_expect_success \
'add ignored file' \
'echo ignore me >a/ignored &&
- echo ignored export-ignore >.gitattributes'
+ echo ignored export-ignore >.git/info/attributes'
test_expect_success \
'add files to repository' \
@@ -60,7 +64,7 @@ test_expect_success \
test_expect_success \
'create bare clone' \
'git clone --bare . bare.git &&
- cp .gitattributes bare.git/info/attributes'
+ cp .git/info/attributes bare.git/info/attributes'
test_expect_success \
'remove ignored file' \
@@ -76,7 +80,7 @@ test_expect_success \
test_expect_success \
'git archive vs. git tar-tree' \
- 'diff b.tar b2.tar'
+ 'test_cmp b.tar b2.tar'
test_expect_success \
'git archive in a bare repo' \
@@ -86,18 +90,26 @@ test_expect_success \
'git archive vs. the same in a bare repo' \
'test_cmp b.tar b3.tar'
+test_expect_success 'git archive with --output' \
+ 'git archive --output=b4.tar HEAD &&
+ test_cmp b.tar b4.tar'
+
+test_expect_success 'git archive --remote' \
+ 'git archive --remote=. HEAD >b5.tar &&
+ test_cmp b.tar b5.tar'
+
test_expect_success \
'validate file modification time' \
'mkdir extract &&
"$TAR" xf b.tar -C extract a/a &&
test-chmtime -v +0 extract/a/a |cut -f 1 >b.mtime &&
echo "1117231200" >expected.mtime &&
- diff expected.mtime b.mtime'
+ test_cmp expected.mtime b.mtime'
test_expect_success \
'git get-tar-commit-id' \
'git get-tar-commit-id <b.tar >b.commitid &&
- diff .git/$(git symbolic-ref HEAD) b.commitid'
+ test_cmp .git/$(git symbolic-ref HEAD) b.commitid'
test_expect_success \
'extract tar archive' \
@@ -106,7 +118,7 @@ test_expect_success \
test_expect_success \
'validate filenames' \
'(cd b/a && find .) | sort >b.lst &&
- diff a.lst b.lst'
+ test_cmp a.lst b.lst'
test_expect_success \
'validate file contents' \
@@ -123,7 +135,7 @@ test_expect_success \
test_expect_success \
'validate filenames with prefix' \
'(cd c/prefix/a && find .) | sort >c.lst &&
- diff a.lst c.lst'
+ test_cmp a.lst c.lst'
test_expect_success \
'validate file contents with prefix' \
@@ -131,10 +143,11 @@ test_expect_success \
test_expect_success \
'create archives with substfiles' \
- 'echo "substfile?" export-subst >a/.gitattributes &&
+ 'cp .git/info/attributes .git/info/attributes.before &&
+ echo "substfile?" export-subst >>.git/info/attributes &&
git archive HEAD >f.tar &&
git archive --prefix=prefix/ HEAD >g.tar &&
- rm a/.gitattributes'
+ mv .git/info/attributes.before .git/info/attributes'
test_expect_success \
'extract substfiles' \
@@ -144,8 +157,8 @@ test_expect_success \
'validate substfile contents' \
'git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \
>f/a/substfile1.expected &&
- diff f/a/substfile1.expected f/a/substfile1 &&
- diff a/substfile2 f/a/substfile2
+ test_cmp f/a/substfile1.expected f/a/substfile1 &&
+ test_cmp a/substfile2 f/a/substfile2
'
test_expect_success \
@@ -156,8 +169,8 @@ test_expect_success \
'validate substfile contents from archive with prefix' \
'git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \
>g/prefix/a/substfile1.expected &&
- diff g/prefix/a/substfile1.expected g/prefix/a/substfile1 &&
- diff a/substfile2 g/prefix/a/substfile2
+ test_cmp g/prefix/a/substfile1.expected g/prefix/a/substfile1 &&
+ test_cmp a/substfile2 g/prefix/a/substfile2
'
test_expect_success \
@@ -172,23 +185,27 @@ 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'
+
$UNZIP -v >/dev/null 2>&1
if [ $? -eq 127 ]; then
- echo "Skipping ZIP tests, because unzip was not found"
- test_done
- exit
+ say "Skipping ZIP tests, because unzip was not found"
+else
+ test_set_prereq UNZIP
fi
-test_expect_success \
+test_expect_success UNZIP \
'extract ZIP archive' \
'(mkdir d && cd d && $UNZIP ../d.zip)'
-test_expect_success \
+test_expect_success UNZIP \
'validate filenames' \
'(cd d/a && find .) | sort >d.lst &&
- diff a.lst d.lst'
+ test_cmp a.lst d.lst'
-test_expect_success \
+test_expect_success UNZIP \
'validate file contents' \
'diff -r a d/a'
@@ -196,16 +213,16 @@ test_expect_success \
'git archive --format=zip with prefix' \
'git archive --format=zip --prefix=prefix/ HEAD >e.zip'
-test_expect_success \
+test_expect_success UNZIP \
'extract ZIP archive with prefix' \
'(mkdir e && cd e && $UNZIP ../e.zip)'
-test_expect_success \
+test_expect_success UNZIP \
'validate filenames with prefix' \
'(cd e/prefix/a && find .) | sort >e.lst &&
- diff a.lst e.lst'
+ test_cmp a.lst e.lst'
-test_expect_success \
+test_expect_success UNZIP \
'validate file contents with prefix' \
'diff -r a e/prefix/a'
diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh
new file mode 100755
index 0000000000..426b319bd3
--- /dev/null
+++ b/t/t5001-archive-attr.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+test_description='git archive attribute tests'
+
+. ./test-lib.sh
+
+SUBSTFORMAT=%H%n
+
+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 &&
+
+ echo ignored by tree >ignored-by-tree &&
+ echo ignored-by-tree export-ignore >.gitattributes &&
+ git add ignored-by-tree .gitattributes &&
+
+ echo ignored by worktree >ignored-by-worktree &&
+ echo ignored-by-worktree export-ignore >.gitattributes &&
+ git add ignored-by-worktree &&
+
+ printf "A\$Format:%s\$O" "$SUBSTFORMAT" >nosubstfile &&
+ printf "A\$Format:%s\$O" "$SUBSTFORMAT" >substfile1 &&
+ printf "A not substituted O" >substfile2 &&
+ echo "substfile?" export-subst >>.git/info/attributes &&
+ git add nosubstfile substfile1 substfile2 &&
+
+ 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/ignored-by-tree
+test_expect_exists archive/ignored-by-worktree
+
+test_expect_success 'git archive with worktree attributes' '
+ git archive --worktree-attributes HEAD >worktree.tar &&
+ (mkdir worktree && cd worktree && "$TAR" xf -) <worktree.tar
+'
+
+test_expect_missing worktree/ignored
+test_expect_exists worktree/ignored-by-tree
+test_expect_missing worktree/ignored-by-worktree
+
+test_expect_success 'git archive vs. bare' '
+ (cd bare && git archive HEAD) >bare-archive.tar &&
+ test_cmp archive.tar bare-archive.tar
+'
+
+test_expect_success 'git archive with worktree attributes, bare' '
+ (cd bare && git archive --worktree-attributes HEAD) >bare-worktree.tar &&
+ (mkdir bare-worktree && cd bare-worktree && "$TAR" xf -) <bare-worktree.tar
+'
+
+test_expect_missing bare-worktree/ignored
+test_expect_exists bare-worktree/ignored-by-tree
+test_expect_exists bare-worktree/ignored-by-worktree
+
+test_expect_success 'export-subst' '
+ git log "--pretty=format:A${SUBSTFORMAT}O" HEAD >substfile1.expected &&
+ test_cmp nosubstfile archive/nosubstfile &&
+ test_cmp substfile1.expected archive/substfile1 &&
+ test_cmp substfile2 archive/substfile2
+'
+
+test_expect_success 'git tar-tree vs. git archive with worktree attributes' '
+ git tar-tree HEAD >tar-tree.tar &&
+ test_cmp worktree.tar tar-tree.tar
+'
+
+test_expect_success 'git tar-tree vs. git archive with worktree attrs, bare' '
+ (cd bare && git tar-tree HEAD) >bare-tar-tree.tar &&
+ test_cmp bare-worktree.tar bare-tar-tree.tar
+'
+
+test_done
diff --git a/t/t5100/info0001 b/t/t5100/info0001
index 8c052777e0..f951538acc 100644
--- a/t/t5100/info0001
+++ b/t/t5100/info0001
@@ -1,4 +1,4 @@
-Author: A U Thor
+Author: A (zzz) U Thor (Comment)
Email: a.u.thor@example.com
Subject: a commit.
Date: Fri, 9 Jun 2006 00:44:16 -0700
diff --git a/t/t5100/rfc2047-info-0004 b/t/t5100/rfc2047-info-0004
index 0ca7ff0529..f67a90a974 100644
--- a/t/t5100/rfc2047-info-0004
+++ b/t/t5100/rfc2047-info-0004
@@ -1,4 +1,4 @@
-Author: Nathaniel Borenstein (×ולש ןב ילטפנ)
+Author: Nathaniel Borenstein (×ולש ןב ילטפנ)
Email: nsb@thumper.bellcore.com
Subject: Test of new header generator
diff --git a/t/t5100/rfc2047-samples.mbox b/t/t5100/rfc2047-samples.mbox
index 3ca2470da2..1fc224810d 100644
--- a/t/t5100/rfc2047-samples.mbox
+++ b/t/t5100/rfc2047-samples.mbox
@@ -1,48 +1,48 @@
From nobody Mon Sep 17 00:00:00 2001
From: =?US-ASCII?Q?Keith_Moore?= <moore@cs.utk.edu>
-To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk>
-CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>
-Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
- =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=
+To: =?ISO8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk>
+CC: =?ISO8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>
+Subject: =?ISO8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
+ =?ISO8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=
From nobody Mon Sep 17 00:00:00 2001
-From: =?ISO-8859-1?Q?Olle_J=E4rnefors?= <ojarnef@admin.kth.se>
+From: =?ISO8859-1?Q?Olle_J=E4rnefors?= <ojarnef@admin.kth.se>
To: ietf-822@dimacs.rutgers.edu, ojarnef@admin.kth.se
Subject: Time for ISO 10646?
From nobody Mon Sep 17 00:00:00 2001
To: Dave Crocker <dcrocker@mordor.stanford.edu>
Cc: ietf-822@dimacs.rutgers.edu, paf@comsol.se
-From: =?ISO-8859-1?Q?Patrik_F=E4ltstr=F6m?= <paf@nada.kth.se>
+From: =?ISO8859-1?Q?Patrik_F=E4ltstr=F6m?= <paf@nada.kth.se>
Subject: Re: RFC-HDR care and feeding
From nobody Mon Sep 17 00:00:00 2001
From: Nathaniel Borenstein <nsb@thumper.bellcore.com>
- (=?iso-8859-8?b?7eXs+SDv4SDp7Oj08A==?=)
+ (=?ISO8859-8?b?7eXs+SDv4SDp7Oj08A==?=)
To: Greg Vaudreuil <gvaudre@NRI.Reston.VA.US>, Ned Freed
<ned@innosoft.com>, Keith Moore <moore@cs.utk.edu>
Subject: Test of new header generator
MIME-Version: 1.0
-Content-type: text/plain; charset=ISO-8859-1
+Content-type: text/plain; charset=ISO8859-1
From nobody Mon Sep 17 00:00:00 2001
-Subject: (=?ISO-8859-1?Q?a?=)
+Subject: (=?ISO8859-1?Q?a?=)
From nobody Mon Sep 17 00:00:00 2001
-Subject: (=?ISO-8859-1?Q?a?= b)
+Subject: (=?ISO8859-1?Q?a?= b)
From nobody Mon Sep 17 00:00:00 2001
-Subject: (=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)
+Subject: (=?ISO8859-1?Q?a?= =?ISO8859-1?Q?b?=)
From nobody Mon Sep 17 00:00:00 2001
-Subject: (=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)
+Subject: (=?ISO8859-1?Q?a?= =?ISO8859-1?Q?b?=)
From nobody Mon Sep 17 00:00:00 2001
-Subject: (=?ISO-8859-1?Q?a?=
- =?ISO-8859-1?Q?b?=)
+Subject: (=?ISO8859-1?Q?a?=
+ =?ISO8859-1?Q?b?=)
From nobody Mon Sep 17 00:00:00 2001
-Subject: (=?ISO-8859-1?Q?a_b?=)
+Subject: (=?ISO8859-1?Q?a_b?=)
From nobody Mon Sep 17 00:00:00 2001
-Subject: (=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=)
+Subject: (=?ISO8859-1?Q?a?= =?ISO8859-2?Q?_b?=)
diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox
index 85df55f2c4..c3074ac573 100644
--- a/t/t5100/sample.mbox
+++ b/t/t5100/sample.mbox
@@ -2,10 +2,10 @@
From nobody Mon Sep 17 00:00:00 2001
-From: A
+From: A (zzz)
U
Thor
- <a.u.thor@example.com>
+ <a.u.thor@example.com> (Comment)
Date: Fri, 9 Jun 2006 00:44:16 -0700
Subject: [PATCH] a commit.
@@ -99,7 +99,7 @@ index 9123cdc..918dcf8 100644
From nobody Sat Aug 27 23:07:49 2005
Path: news.gmane.org!not-for-mail
Message-ID: <20050721.091036.01119516.yoshfuji@linux-ipv6.org>
-From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?=
+From: YOSHIFUJI Hideaki / =?ISO-2022-JP?B?GyRCNUhGIzFRTEAbKEI=?=
<yoshfuji@linux-ipv6.org>
Newsgroups: gmane.comp.version-control.git
Subject: [PATCH 1/2] GIT: Try all addresses for given remote name
@@ -218,7 +218,7 @@ GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
From nobody Sat Aug 27 23:07:49 2005
Path: news.gmane.org!not-for-mail
Message-ID: <u5tacjjdpxq.fsf@lysator.liu.se>
-From: =?iso-8859-1?Q?David_K=E5gedal?= <davidk@lysator.liu.se>
+From: =?ISO8859-1?Q?David_K=E5gedal?= <davidk@lysator.liu.se>
Newsgroups: gmane.comp.version-control.git
Subject: [PATCH] Fixed two bugs in git-cvsimport-script.
Date: Mon, 15 Aug 2005 20:18:25 +0200
@@ -226,7 +226,7 @@ Lines: 83
Approved: news@gmane.org
NNTP-Posting-Host: main.gmane.org
Mime-Version: 1.0
-Content-Type: text/plain; charset=iso-8859-1
+Content-Type: text/plain; charset=ISO8859-1
Content-Transfer-Encoding: QUOTED-PRINTABLE
X-Trace: sea.gmane.org 1124130247 31839 80.91.229.2 (15 Aug 2005 18:24:07 GMT)
X-Complaints-To: usenet@sea.gmane.org
@@ -476,7 +476,7 @@ MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
--=-=-=
-Content-Type: text/plain; charset=iso-8859-15
+Content-Type: text/plain; charset=ISO8859-15
Content-Transfer-Encoding: quoted-printable
Here comes a commit log message, and
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index ccfc64c6ee..e2aa254eae 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -13,11 +13,10 @@ TRASH=`pwd`
test_expect_success \
'setup' \
'rm -f .git/index*
- for i in a b c
- do
- dd if=/dev/zero bs=4k count=1 | perl -pe "y/\\000/$i/" >$i &&
- git update-index --add $i || return 1
- done &&
+ perl -e "print \"a\" x 4096;" > a &&
+ perl -e "print \"b\" x 4096;" > b &&
+ perl -e "print \"c\" x 4096;" > c &&
+ git update-index --add a b c &&
cat c >d && echo foo >>d && git update-index --add d &&
tree=`git write-tree` &&
commit=`git commit-tree $tree </dev/null` && {
@@ -221,7 +220,7 @@ test_expect_success \
test_expect_success \
'verify-pack catches a corrupted pack signature' \
'cat test-1-${packname_1}.pack >test-3.pack &&
- dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=2 &&
+ echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=2 &&
if git verify-pack test-3.idx
then false
else :;
@@ -230,7 +229,7 @@ test_expect_success \
test_expect_success \
'verify-pack catches a corrupted pack version' \
'cat test-1-${packname_1}.pack >test-3.pack &&
- dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=7 &&
+ echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=7 &&
if git verify-pack test-3.idx
then false
else :;
@@ -239,7 +238,7 @@ test_expect_success \
test_expect_success \
'verify-pack catches a corrupted type/size of the 1st packed object data' \
'cat test-1-${packname_1}.pack >test-3.pack &&
- dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=12 &&
+ echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=12 &&
if git verify-pack test-3.idx
then false
else :;
@@ -250,7 +249,7 @@ test_expect_success \
'l=`wc -c <test-3.idx` &&
l=`expr $l - 20` &&
cat test-1-${packname_1}.pack >test-3.pack &&
- dd if=/dev/zero of=test-3.idx count=20 bs=1 conv=notrunc seek=$l &&
+ printf "%20s" "" | dd of=test-3.idx count=20 bs=1 conv=notrunc seek=$l &&
if git verify-pack test-3.pack
then false
else :;
diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh
index 884e24253a..4360e77d31 100755
--- a/t/t5302-pack-index.sh
+++ b/t/t5302-pack-index.sh
@@ -10,6 +10,7 @@ test_expect_success \
'setup' \
'rm -rf .git
git init &&
+ git config pack.threads 1 &&
i=1 &&
while test $i -le 100
do
@@ -68,32 +69,27 @@ test_expect_success \
'index v2: force some 64-bit offsets with pack-objects' \
'pack3=$(git pack-objects --index-version=2,0x40000 test-3 <obj-list)'
-have_64bits=
if msg=$(git verify-pack -v "test-3-${pack3}.pack" 2>&1) ||
! (echo "$msg" | grep "pack too large .* off_t")
then
- have_64bits=t
+ test_set_prereq OFF64_T
else
say "skipping tests concerning 64-bit offsets"
fi
-test "$have_64bits" &&
-test_expect_success \
+test_expect_success OFF64_T \
'index v2: verify a pack with some 64-bit offsets' \
'git verify-pack -v "test-3-${pack3}.pack"'
-test "$have_64bits" &&
-test_expect_success \
+test_expect_success OFF64_T \
'64-bit offsets: should be different from previous index v2 results' \
'! cmp "test-2-${pack2}.idx" "test-3-${pack3}.idx"'
-test "$have_64bits" &&
-test_expect_success \
+test_expect_success OFF64_T \
'index v2: force some 64-bit offsets with index-pack' \
'git index-pack --index-version=2,0x40000 -o 3.idx "test-1-${pack1}.pack"'
-test "$have_64bits" &&
-test_expect_success \
+test_expect_success OFF64_T \
'64-bit offsets: index-pack result should match pack-objects one' \
'cmp "test-3-${pack3}.idx" "3.idx"'
@@ -207,7 +203,7 @@ test_expect_success \
obj=`git hash-object file_001` &&
nr=`index_obj_nr ".git/objects/pack/pack-${pack1}.idx" $obj` &&
chmod +w ".git/objects/pack/pack-${pack1}.idx" &&
- dd if=/dev/zero of=".git/objects/pack/pack-${pack1}.idx" conv=notrunc \
+ printf xxxx | dd of=".git/objects/pack/pack-${pack1}.idx" conv=notrunc \
bs=1 count=4 seek=$((8 + 256 * 4 + `wc -l <obj-list` * 20 + $nr * 4)) &&
( while read obj
do git cat-file -p $obj >/dev/null || exit 1
diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh
index d4e30fc43c..5132d41309 100755
--- a/t/t5303-pack-corruption-resilience.sh
+++ b/t/t5303-pack-corruption-resilience.sh
@@ -55,6 +55,8 @@ do_corrupt_object() {
test_must_fail git verify-pack ${pack}.pack
}
+printf '\0' > zero
+
test_expect_success \
'initial setup validation' \
'create_test_files &&
@@ -66,7 +68,7 @@ test_expect_success \
test_expect_success \
'create corruption in header of first object' \
- 'do_corrupt_object $blob_1 0 < /dev/zero &&
+ 'do_corrupt_object $blob_1 0 < zero &&
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'
@@ -125,7 +127,7 @@ test_expect_success \
'create corruption in header of first delta' \
'create_new_pack &&
git prune-packed &&
- do_corrupt_object $blob_2 0 < /dev/zero &&
+ do_corrupt_object $blob_2 0 < zero &&
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'
@@ -180,7 +182,7 @@ test_expect_success \
'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \
'create_new_pack &&
git prune-packed &&
- do_corrupt_object $blob_2 2 < /dev/zero &&
+ do_corrupt_object $blob_2 2 < zero &&
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'
@@ -207,7 +209,7 @@ test_expect_success \
'corruption #0 in delta base reference of first delta (OBJ_OFS_DELTA)' \
'create_new_pack --delta-base-offset &&
git prune-packed &&
- do_corrupt_object $blob_2 2 < /dev/zero &&
+ do_corrupt_object $blob_2 2 < zero &&
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'
@@ -259,7 +261,7 @@ test_expect_success \
test_expect_success \
'... and a redundant pack allows for full recovery too' \
- 'do_corrupt_object $blob_2 2 < /dev/zero &&
+ 'do_corrupt_object $blob_2 2 < zero &&
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/t5304-prune.sh b/t/t5304-prune.sh
index 771c0a06a4..55ed7c7935 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -112,4 +112,42 @@ test_expect_success 'prune: do not prune heads listed as an argument' '
'
+test_expect_success 'gc --no-prune' '
+
+ before=$(git count-objects | sed "s/ .*//") &&
+ BLOB=$(echo aleph_0 | git hash-object -w --stdin) &&
+ BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
+ test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
+ test -f $BLOB_FILE &&
+ test-chmtime =-$((86400*5001)) $BLOB_FILE &&
+ git config gc.pruneExpire 2.days.ago &&
+ git gc --no-prune &&
+ test 1 = $(git count-objects | sed "s/ .*//") &&
+ test -f $BLOB_FILE
+
+'
+
+test_expect_success 'gc respects gc.pruneExpire' '
+
+ git config gc.pruneExpire 5002.days.ago &&
+ git gc &&
+ test -f $BLOB_FILE &&
+ git config gc.pruneExpire 5000.days.ago &&
+ git gc &&
+ test ! -f $BLOB_FILE
+
+'
+
+test_expect_success 'gc --prune=<date>' '
+
+ BLOB=$(echo aleph_0 | git hash-object -w --stdin) &&
+ BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
+ test-chmtime =-$((86400*5001)) $BLOB_FILE &&
+ git gc --prune=5002.days.ago &&
+ test -f $BLOB_FILE &&
+ git gc --prune=5000.days.ago &&
+ test ! -f $BLOB_FILE
+
+'
+
test_done
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index b21317d685..f2d5581b12 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -32,9 +32,7 @@ test_expect_success setup '
done &&
git update-ref HEAD "$commit" &&
git clone ./. victim &&
- cd victim &&
- git log &&
- cd .. &&
+ ( cd victim && git log ) &&
git update-ref HEAD "$zero" &&
parent=$zero &&
i=0 &&
@@ -59,88 +57,84 @@ test_expect_success 'pack the source repository' '
'
test_expect_success 'pack the destination repository' '
+ (
cd victim &&
git repack -a -d &&
- git prune &&
- cd ..
+ git prune
+ )
'
-test_expect_success \
- 'pushing rewound head should not barf but require --force' '
- # should not fail but refuse to update.
- if git send-pack ./victim/.git/ master
- then
- # now it should fail with Pasky patch
- echo >&2 Gaah, it should have failed.
- false
- else
- echo >&2 Thanks, it correctly failed.
- true
- fi &&
- if cmp victim/.git/refs/heads/master .git/refs/heads/master
- then
- # should have been left as it was!
- false
- else
- true
- fi &&
+test_expect_success 'refuse pushing rewound head without --force' '
+ pushed_head=$(git rev-parse --verify master) &&
+ victim_orig=$(cd victim && git rev-parse --verify master) &&
+ test_must_fail git send-pack ./victim master &&
+ victim_head=$(cd victim && git rev-parse --verify master) &&
+ test "$victim_head" = "$victim_orig" &&
# this should update
- git send-pack --force ./victim/.git/ master &&
- cmp victim/.git/refs/heads/master .git/refs/heads/master
+ git send-pack --force ./victim master &&
+ victim_head=$(cd victim && git rev-parse --verify master) &&
+ test "$victim_head" = "$pushed_head"
'
test_expect_success \
'push can be used to delete a ref' '
- cd victim &&
- git branch extra master &&
- cd .. &&
- test -f victim/.git/refs/heads/extra &&
- git send-pack ./victim/.git/ :extra master &&
- ! test -f victim/.git/refs/heads/extra
+ ( cd victim && git branch extra master ) &&
+ git send-pack ./victim :extra master &&
+ ( cd victim &&
+ test_must_fail git rev-parse --verify extra )
'
-unset GIT_CONFIG
-HOME=`pwd`/no-such-directory
-export HOME ;# this way we force the victim/.git/config to be used.
-
-test_expect_success \
- 'pushing a delete should be denied with denyDeletes' '
- cd victim &&
- git config receive.denyDeletes true &&
- git branch extra master &&
- cd .. &&
- test -f victim/.git/refs/heads/extra &&
- test_must_fail git send-pack ./victim/.git/ :extra master
+test_expect_success 'refuse deleting push with denyDeletes' '
+ (
+ cd victim &&
+ ( git branch -D extra || : ) &&
+ git config receive.denyDeletes true &&
+ git branch extra master
+ ) &&
+ test_must_fail git send-pack ./victim :extra master
'
-rm -f victim/.git/refs/heads/extra
-test_expect_success \
- 'pushing with --force should be denied with denyNonFastforwards' '
- cd victim &&
- git config receive.denyNonFastforwards true &&
- cd .. &&
- git update-ref refs/heads/master master^ || return 1
- git send-pack --force ./victim/.git/ master && return 1
- ! test_cmp .git/refs/heads/master victim/.git/refs/heads/master
+test_expect_success 'denyNonFastforwards trumps --force' '
+ (
+ cd victim &&
+ ( git branch -D extra || : ) &&
+ git config receive.denyNonFastforwards true
+ ) &&
+ victim_orig=$(cd victim && git rev-parse --verify master) &&
+ test_must_fail git send-pack --force ./victim master^:master &&
+ victim_head=$(cd victim && git rev-parse --verify master) &&
+ test "$victim_orig" = "$victim_head"
'
-test_expect_success \
- 'pushing does not include non-head refs' '
- mkdir parent && cd parent &&
- git init && touch file && git add file && git commit -m add &&
- cd .. &&
- git clone parent child && cd child && git push --all &&
- cd ../parent &&
- git branch -a >branches && ! grep origin/master branches
+test_expect_success 'push --all excludes remote tracking hierarchy' '
+ mkdir parent &&
+ (
+ cd parent &&
+ git init && : >file && git add file && git commit -m add
+ ) &&
+ git clone parent child &&
+ (
+ cd child && git push --all
+ ) &&
+ (
+ cd parent &&
+ test -z "$(git for-each-ref refs/remotes/origin)"
+ )
'
rewound_push_setup() {
rm -rf parent child &&
- mkdir parent && cd parent &&
- git init && echo one >file && git add file && git commit -m one &&
- echo two >file && git commit -a -m two &&
- cd .. &&
- git clone parent child && cd child && git reset --hard HEAD^
+ mkdir parent &&
+ (
+ cd parent &&
+ git init &&
+ echo one >file && git add file && git commit -m one &&
+ echo two >file && git commit -a -m two
+ ) &&
+ git clone parent child &&
+ (
+ cd child && git reset --hard HEAD^
+ )
}
rewound_push_succeeded() {
@@ -156,30 +150,57 @@ rewound_push_failed() {
fi
}
-test_expect_success \
- 'pushing explicit refspecs respects forcing' '
+test_expect_success 'pushing explicit refspecs respects forcing' '
rewound_push_setup &&
- if git send-pack ../parent/.git refs/heads/master:refs/heads/master
- then
- false
- else
- true
- fi && rewound_push_failed &&
- git send-pack ../parent/.git +refs/heads/master:refs/heads/master &&
- rewound_push_succeeded
+ parent_orig=$(cd parent && git rev-parse --verify master) &&
+ (
+ cd child &&
+ test_must_fail git send-pack ../parent \
+ refs/heads/master:refs/heads/master
+ ) &&
+ parent_head=$(cd parent && git rev-parse --verify master) &&
+ test "$parent_orig" = "$parent_head" &&
+ (
+ cd child &&
+ git send-pack ../parent \
+ +refs/heads/master:refs/heads/master
+ ) &&
+ parent_head=$(cd parent && git rev-parse --verify master) &&
+ child_head=$(cd parent && git rev-parse --verify master) &&
+ test "$parent_head" = "$child_head"
'
-test_expect_success \
- 'pushing wildcard refspecs respects forcing' '
+test_expect_success 'pushing wildcard refspecs respects forcing' '
rewound_push_setup &&
- if git send-pack ../parent/.git refs/heads/*:refs/heads/*
- then
- false
- else
- true
- fi && rewound_push_failed &&
- git send-pack ../parent/.git +refs/heads/*:refs/heads/* &&
- rewound_push_succeeded
+ parent_orig=$(cd parent && git rev-parse --verify master) &&
+ (
+ cd child &&
+ test_must_fail git send-pack ../parent \
+ "refs/heads/*:refs/heads/*"
+ ) &&
+ parent_head=$(cd parent && git rev-parse --verify master) &&
+ test "$parent_orig" = "$parent_head" &&
+ (
+ cd child &&
+ git send-pack ../parent \
+ "+refs/heads/*:refs/heads/*"
+ ) &&
+ parent_head=$(cd parent && git rev-parse --verify master) &&
+ child_head=$(cd parent && git rev-parse --verify master) &&
+ test "$parent_head" = "$child_head"
+'
+
+test_expect_success 'warn pushing to delete current branch' '
+ rewound_push_setup &&
+ (
+ cd child &&
+ git send-pack ../parent :refs/heads/master 2>errs
+ ) &&
+ grep "warning: to refuse deleting" child/errs &&
+ (
+ cd parent &&
+ test_must_fail git rev-parse --verify master
+ )
'
test_done
diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh
index 9b2e1a94c5..5858b868ed 100755
--- a/t/t5403-post-checkout-hook.sh
+++ b/t/t5403-post-checkout-hook.sh
@@ -71,4 +71,18 @@ test_expect_success 'post-checkout receives the right args when not switching br
test $old = $new -a $flag = 0
'
+if test "$(git config --bool core.filemode)" = true; then
+mkdir -p templates/hooks
+cat >templates/hooks/post-checkout <<'EOF'
+#!/bin/sh
+echo $@ > $GIT_DIR/post-checkout.args
+EOF
+chmod +x templates/hooks/post-checkout
+
+test_expect_success 'post-checkout hook is triggered by clone' '
+ git clone --template=templates . clone3 &&
+ test -f clone3/.git/post-checkout.args
+'
+fi
+
test_done
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index c450f33f33..a8c2ca2a78 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -3,9 +3,8 @@
# Copyright (c) 2005 Johannes Schindelin
#
-test_description='Testing multi_ack pack fetching
+test_description='Testing multi_ack pack fetching'
-'
. ./test-lib.sh
# Test fetch-pack/upload-pack pair.
@@ -13,77 +12,60 @@ test_description='Testing multi_ack pack fetching
# Some convenience functions
add () {
- name=$1
- text="$@"
- branch=`echo $name | sed -e 's/^\(.\).*$/\1/'`
- parents=""
+ name=$1 &&
+ text="$@" &&
+ branch=`echo $name | sed -e 's/^\(.\).*$/\1/'` &&
+ parents="" &&
- shift
+ shift &&
while test $1; do
- parents="$parents -p $1"
+ parents="$parents -p $1" &&
shift
- done
+ done &&
- echo "$text" > test.txt
- git update-index --add test.txt
- tree=$(git write-tree)
+ echo "$text" > test.txt &&
+ git update-index --add test.txt &&
+ tree=$(git write-tree) &&
# make sure timestamps are in correct order
- sec=$(($sec+1))
- commit=$(echo "$text" | GIT_AUTHOR_DATE=$sec \
- git commit-tree $tree $parents 2>>log2.txt)
- eval "$name=$commit; export $name"
- echo $commit > .git/refs/heads/$branch
+ test_tick &&
+ commit=$(echo "$text" | git commit-tree $tree $parents) &&
+ eval "$name=$commit; export $name" &&
+ echo $commit > .git/refs/heads/$branch &&
eval ${branch}TIP=$commit
}
-count_objects () {
- ls .git/objects/??/* 2>>log2.txt | wc -l | tr -d " "
-}
-
-test_expect_object_count () {
- message=$1
- count=$2
-
- output="$(count_objects)"
- test_expect_success \
- "new object count $message" \
- "test $count = $output"
-}
-
pull_to_client () {
- number=$1
- heads=$2
- count=$3
- no_strict_count_check=$4
-
- cd client
- test_expect_success "$number pull" \
- "git fetch-pack -k -v .. $heads"
- case "$heads" in *A*) echo $ATIP > .git/refs/heads/A;; esac
- case "$heads" in *B*) echo $BTIP > .git/refs/heads/B;; esac
- git symbolic-ref HEAD refs/heads/`echo $heads | sed -e 's/^\(.\).*$/\1/'`
-
- test_expect_success "fsck" 'git fsck --full > fsck.txt 2>&1'
-
- test_expect_success 'check downloaded results' \
- 'mv .git/objects/pack/pack-* . &&
- p=`ls -1 pack-*.pack` &&
- git unpack-objects <$p &&
- git fsck --full'
-
- test_expect_success "new object count after $number pull" \
- 'idx=`echo pack-*.idx` &&
- pack_count=`git show-index <$idx | wc -l` &&
- test $pack_count = $count'
- test -z "$pack_count" && pack_count=0
- if [ -z "$no_strict_count_check" ]; then
- test_expect_success "minimal count" "test $count = $pack_count"
- else
- test $count != $pack_count && \
- echo "WARNING: $pack_count objects transmitted, only $count of which were needed"
- fi
- rm -f pack-*
- cd ..
+ number=$1 &&
+ heads=$2 &&
+ count=$3 &&
+ test_expect_success "$number pull" '
+ (
+ cd client &&
+ git fetch-pack -k -v .. $heads &&
+
+ case "$heads" in
+ *A*)
+ echo $ATIP > .git/refs/heads/A;;
+ esac &&
+ case "$heads" in *B*)
+ echo $BTIP > .git/refs/heads/B;;
+ esac &&
+ git symbolic-ref HEAD refs/heads/`echo $heads \
+ | sed -e "s/^\(.\).*$/\1/"` &&
+
+ git fsck --full &&
+
+ mv .git/objects/pack/pack-* . &&
+ p=`ls -1 pack-*.pack` &&
+ git unpack-objects <$p &&
+ git fsck --full &&
+
+ idx=`echo pack-*.idx` &&
+ pack_count=`git show-index <$idx | wc -l` &&
+ test $pack_count = $count &&
+ rm -f pack-*
+ )
+ '
}
# Here begins the actual testing
@@ -94,89 +76,129 @@ pull_to_client () {
# client pulls A20, B1. Then tracks only B. Then pulls A.
-(
+test_expect_success 'setup' '
mkdir client &&
- cd client &&
- git init 2>> log2.txt &&
- git config transfer.unpacklimit 0
-)
-
-add A1
-
-prev=1; cur=2; while [ $cur -le 10 ]; do
- add A$cur $(eval echo \$A$prev)
- prev=$cur
- cur=$(($cur+1))
-done
-
-add B1 $A1
-
-echo $ATIP > .git/refs/heads/A
-echo $BTIP > .git/refs/heads/B
-git symbolic-ref HEAD refs/heads/B
+ (
+ cd client &&
+ git init &&
+ git config transfer.unpacklimit 0
+ ) &&
+ add A1 &&
+ prev=1 &&
+ cur=2 &&
+ while [ $cur -le 10 ]; do
+ add A$cur $(eval echo \$A$prev) &&
+ prev=$cur &&
+ cur=$(($cur+1))
+ done &&
+ add B1 $A1
+ echo $ATIP > .git/refs/heads/A &&
+ echo $BTIP > .git/refs/heads/B &&
+ git symbolic-ref HEAD refs/heads/B
+'
pull_to_client 1st "B A" $((11*3))
-add A11 $A10
-
-prev=1; cur=2; while [ $cur -le 65 ]; do
- add B$cur $(eval echo \$B$prev)
- prev=$cur
- cur=$(($cur+1))
-done
+test_expect_success 'post 1st pull setup' '
+ add A11 $A10 &&
+ prev=1 &&
+ cur=2 &&
+ while [ $cur -le 65 ]; do
+ add B$cur $(eval echo \$B$prev) &&
+ prev=$cur &&
+ cur=$(($cur+1))
+ done
+'
pull_to_client 2nd "B" $((64*3))
-pull_to_client 3rd "A" $((1*3)) # old fails
-
-test_expect_success "clone shallow" 'git clone --depth 2 "file://$(pwd)/." shallow'
+pull_to_client 3rd "A" $((1*3))
-(cd shallow; git count-objects -v) > count.shallow
-
-test_expect_success "clone shallow object count" \
- "test \"in-pack: 18\" = \"$(grep in-pack count.shallow)\""
-
-count_output () {
- sed -e '/^in-pack:/d' -e '/^packs:/d' -e '/^size-pack:/d' -e '/: 0$/d' "$1"
-}
+test_expect_success 'clone shallow' '
+ git clone --depth 2 "file://$(pwd)/." shallow
+'
-test_expect_success "clone shallow object count (part 2)" '
- test -z "$(count_output count.shallow)"
+test_expect_success 'clone shallow object count' '
+ (
+ cd shallow &&
+ git count-objects -v
+ ) > count.shallow &&
+ grep "^in-pack: 18" count.shallow
'
-test_expect_success "fsck in shallow repo" \
- "(cd shallow; git fsck --full)"
+test_expect_success 'clone shallow object count (part 2)' '
+ sed -e "/^in-pack:/d" -e "/^packs:/d" -e "/^size-pack:/d" \
+ -e "/: 0$/d" count.shallow > count_output &&
+ ! test -s count_output
+'
-#test_done; exit
+test_expect_success 'fsck in shallow repo' '
+ (
+ cd shallow &&
+ git fsck --full
+ )
+'
-add B66 $B65
-add B67 $B66
+test_expect_success 'add two more' '
+ add B66 $B65 &&
+ add B67 $B66
+'
-test_expect_success "pull in shallow repo" \
- "(cd shallow; git pull .. B)"
+test_expect_success 'pull in shallow repo' '
+ (
+ cd shallow &&
+ git pull .. B
+ )
+'
-(cd shallow; git count-objects -v) > count.shallow
-test_expect_success "clone shallow object count" \
- "test \"count: 6\" = \"$(grep count count.shallow)\""
+test_expect_success 'clone shallow object count' '
+ (
+ cd shallow &&
+ git count-objects -v
+ ) > count.shallow &&
+ grep "^count: 6" count.shallow
+'
-add B68 $B67
-add B69 $B68
+test_expect_success 'add two more (part 2)' '
+ add B68 $B67 &&
+ add B69 $B68
+'
-test_expect_success "deepening pull in shallow repo" \
- "(cd shallow; git pull --depth 4 .. B)"
+test_expect_success 'deepening pull in shallow repo' '
+ (
+ cd shallow &&
+ git pull --depth 4 .. B
+ )
+'
-(cd shallow; git count-objects -v) > count.shallow
-test_expect_success "clone shallow object count" \
- "test \"count: 12\" = \"$(grep count count.shallow)\""
+test_expect_success 'clone shallow object count' '
+ (
+ cd shallow &&
+ git count-objects -v
+ ) > count.shallow &&
+ grep "^count: 12" count.shallow
+'
-test_expect_success "deepening fetch in shallow repo" \
- "(cd shallow; git fetch --depth 4 .. A:A)"
+test_expect_success 'deepening fetch in shallow repo' '
+ (
+ cd shallow &&
+ git fetch --depth 4 .. A:A
+ )
+'
-(cd shallow; git count-objects -v) > count.shallow
-test_expect_success "clone shallow object count" \
- "test \"count: 18\" = \"$(grep count count.shallow)\""
+test_expect_success 'clone shallow object count' '
+ (
+ cd shallow &&
+ git count-objects -v
+ ) > count.shallow &&
+ grep "^count: 18" count.shallow
+'
-test_expect_success "pull in shallow repo with missing merge base" \
- "(cd shallow && test_must_fail git pull --depth 4 .. A)"
+test_expect_success 'pull in shallow repo with missing merge base' '
+ (
+ cd shallow &&
+ test_must_fail git pull --depth 4 .. A
+ )
+'
test_done
diff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh
index 16eadd6b68..1037a723fe 100755
--- a/t/t5502-quickfetch.sh
+++ b/t/t5502-quickfetch.sh
@@ -119,4 +119,24 @@ test_expect_success 'quickfetch should not copy from alternate' '
'
+test_expect_success 'quickfetch should handle ~1000 refs (on Windows)' '
+
+ git gc &&
+ head=$(git rev-parse HEAD) &&
+ branchprefix="$head refs/heads/branch" &&
+ for i in 0 1 2 3 4 5 6 7 8 9; do
+ for j in 0 1 2 3 4 5 6 7 8 9; do
+ for k in 0 1 2 3 4 5 6 7 8 9; do
+ echo "$branchprefix$i$j$k" >> .git/packed-refs
+ done
+ done
+ done &&
+ (
+ cd cloned &&
+ git fetch &&
+ git fetch
+ )
+
+'
+
test_done
diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh
index 4074e23ffa..d5db75d826 100755
--- a/t/t5503-tagfollow.sh
+++ b/t/t5503-tagfollow.sh
@@ -4,6 +4,12 @@ test_description='test automatic tag following'
. ./test-lib.sh
+case $(uname -s) in
+*MINGW*)
+ say "GIT_DEBUG_SEND_PACK not supported - skipping tests"
+ test_done
+esac
+
# End state of the repository:
#
# T - tag1 S - tag2
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index bc5b7ce4a6..852ccb5d7d 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -28,7 +28,7 @@ tokens_match () {
}
check_remote_track () {
- actual=$(git remote show "$1" | sed -e '1,/Tracked/d') &&
+ actual=$(git remote show "$1" | sed -ne 's|^ \(.*\) tracked$|\1|p')
shift &&
tokens_match "$*" "$actual"
}
@@ -135,48 +135,78 @@ EOF
cat > test/expect << EOF
* remote origin
- URL: $(pwd)/one
- Remote branch merged with 'git pull' while on branch master
+ Fetch URL: $(pwd)/one
+ Push URL: $(pwd)/one
+ HEAD branch: master
+ Remote branches:
+ master new (next fetch will store in remotes/origin)
+ side tracked
+ Local branches configured for 'git pull':
+ ahead merges with remote master
+ master merges with remote master
+ octopus merges with remote topic-a
+ and with remote topic-b
+ and with remote topic-c
+ rebase rebases onto remote master
+ Local refs configured for 'git push':
+ master pushes to master (local out of date)
+ master pushes to upstream (create)
+* remote two
+ Fetch URL: ../two
+ Push URL: ../three
+ HEAD branch (remote HEAD is ambiguous, may be one of the following):
+ another
master
- New remote branch (next fetch will store in remotes/origin)
- master
- Tracked remote branches
- side
- master
- Local branches pushed with 'git push'
- master:upstream
- +refs/tags/lastbackup
+ Local refs configured for 'git push':
+ ahead forces to master (fast forwardable)
+ master pushes to another (up to date)
EOF
test_expect_success 'show' '
(cd test &&
- git config --add remote.origin.fetch \
- refs/heads/master:refs/heads/upstream &&
+ git config --add remote.origin.fetch refs/heads/master:refs/heads/upstream &&
git fetch &&
+ git checkout -b ahead origin/master &&
+ echo 1 >> file &&
+ test_tick &&
+ git commit -m update file &&
+ git checkout master &&
+ git branch --track octopus origin/master &&
+ git branch --track rebase origin/master &&
git branch -d -r origin/master &&
+ git config --add remote.two.url ../two &&
+ git config --add remote.two.pushurl ../three &&
+ git config branch.rebase.rebase true &&
+ git config branch.octopus.merge "topic-a topic-b topic-c" &&
(cd ../one &&
echo 1 > file &&
test_tick &&
git commit -m update file) &&
- git config remote.origin.push \
- refs/heads/master:refs/heads/upstream &&
- git config --add remote.origin.push \
- +refs/tags/lastbackup &&
- git remote show origin > output &&
+ git config --add remote.origin.push : &&
+ git config --add remote.origin.push refs/heads/master:refs/heads/upstream &&
+ git config --add remote.origin.push +refs/tags/lastbackup &&
+ git config --add remote.two.push +refs/heads/ahead:refs/heads/master &&
+ 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)
'
cat > test/expect << EOF
* remote origin
- URL: $(pwd)/one
- Remote branch merged with 'git pull' while on branch master
- master
- Tracked remote branches
+ Fetch URL: $(pwd)/one
+ Push URL: $(pwd)/one
+ HEAD branch: (not queried)
+ Remote branches: (status not queried)
master
side
- Local branches pushed with 'git push'
- master:upstream
- +refs/tags/lastbackup
+ Local branches configured for 'git pull':
+ ahead merges with remote master
+ master merges with remote master
+ Local refs configured for 'git push' (status not queried):
+ (matching) pushes to (matching)
+ refs/heads/master pushes to refs/heads/upstream
+ refs/tags/lastbackup forces to refs/tags/lastbackup
EOF
test_expect_success 'show -n' '
@@ -197,6 +227,46 @@ test_expect_success 'prune' '
test_must_fail git rev-parse refs/remotes/origin/side)
'
+test_expect_success 'set-head --delete' '
+ (cd test &&
+ git symbolic-ref refs/remotes/origin/HEAD &&
+ git remote set-head --delete origin &&
+ test_must_fail git symbolic-ref refs/remotes/origin/HEAD)
+'
+
+test_expect_success 'set-head --auto' '
+ (cd test &&
+ git remote set-head --auto origin &&
+ echo refs/remotes/origin/master >expect &&
+ git symbolic-ref refs/remotes/origin/HEAD >output &&
+ test_cmp expect output
+ )
+'
+
+cat >test/expect <<EOF
+error: Multiple remote HEAD branches. Please choose one explicitly with:
+ git remote set-head two another
+ git remote set-head two master
+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)
+'
+
+cat >test/expect <<EOF
+refs/remotes/origin/side2
+EOF
+
+test_expect_success 'set-head explicit' '
+ (cd test &&
+ git remote set-head origin side2 &&
+ git symbolic-ref refs/remotes/origin/HEAD >output &&
+ git remote set-head origin master &&
+ test_cmp expect output)
+'
+
cat > test/expect << EOF
Pruning origin
URL: $(pwd)/one
@@ -343,7 +413,7 @@ test_expect_success '"remote show" does not show symbolic refs' '
git clone one three &&
(cd three &&
git remote show origin > output &&
- ! grep HEAD < output &&
+ ! grep "^ *HEAD$" < output &&
! grep -i stale < output)
'
@@ -402,4 +472,41 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
'
+test_expect_success 'remote prune to cause a dangling symref' '
+ git clone one seven &&
+ (
+ cd one &&
+ git checkout side2 &&
+ git branch -D master
+ ) &&
+ (
+ cd seven &&
+ git remote prune origin
+ ) 2>err &&
+ grep "has become dangling" err &&
+
+ : And the dangling symref will not cause other annoying errors
+ (
+ cd seven &&
+ git branch -a
+ ) 2>err &&
+ ! grep "points nowhere" err
+ (
+ cd seven &&
+ test_must_fail git branch nomore origin
+ ) 2>err &&
+ grep "dangling symref" err
+'
+
+test_expect_success 'show empty remote' '
+
+ test_create_repo empty &&
+ git clone empty empty-clone &&
+ (
+ cd empty-clone &&
+ git remote show origin
+ )
+'
+
test_done
+
diff --git a/t/t5506-remote-groups.sh b/t/t5506-remote-groups.sh
new file mode 100755
index 0000000000..2a1806b0b4
--- /dev/null
+++ b/t/t5506-remote-groups.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+test_description='git remote group handling'
+. ./test-lib.sh
+
+mark() {
+ echo "$1" >mark
+}
+
+update_repo() {
+ (cd $1 &&
+ echo content >>file &&
+ git add file &&
+ git commit -F ../mark)
+}
+
+update_repos() {
+ update_repo one $1 &&
+ update_repo two $1
+}
+
+repo_fetched() {
+ if test "`git log -1 --pretty=format:%s $1 --`" = "`cat mark`"; then
+ echo >&2 "repo was fetched: $1"
+ return 0
+ fi
+ echo >&2 "repo was not fetched: $1"
+ return 1
+}
+
+test_expect_success 'setup' '
+ mkdir one && (cd one && git init) &&
+ mkdir two && (cd two && git init) &&
+ git remote add -m master one one &&
+ git remote add -m master two two
+'
+
+test_expect_success 'no group updates all' '
+ mark update-all &&
+ update_repos &&
+ git remote update &&
+ repo_fetched one &&
+ repo_fetched two
+'
+
+test_expect_success 'nonexistant group produces error' '
+ mark nonexistant &&
+ update_repos &&
+ test_must_fail git remote update nonexistant &&
+ ! repo_fetched one &&
+ ! repo_fetched two
+'
+
+test_expect_success 'updating group updates all members' '
+ mark group-all &&
+ update_repos &&
+ git config --add remotes.all one &&
+ git config --add remotes.all two &&
+ git remote update all &&
+ repo_fetched one &&
+ repo_fetched two
+'
+
+test_expect_success 'updating group does not update non-members' '
+ mark group-some &&
+ update_repos &&
+ git config --add remotes.some one &&
+ git remote update some &&
+ repo_fetched one &&
+ ! repo_fetched two
+'
+
+test_expect_success 'updating remote name updates that remote' '
+ mark remote-name &&
+ update_repos &&
+ git remote update one &&
+ repo_fetched one &&
+ ! repo_fetched two
+'
+
+test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 9e679b402d..d13c806624 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -9,6 +9,11 @@ test_description='Per branch config variables affects "git fetch".
D=`pwd`
+test_bundle_object_count () {
+ git verify-pack -v "$1" >verify.out &&
+ test "$2" = $(grep '^[0-9a-f]\{40\} ' verify.out | wc -l)
+}
+
test_expect_success setup '
echo >file original &&
git add file &&
@@ -146,6 +151,7 @@ test_expect_success 'unbundle 1' '
test_must_fail git fetch "$D/bundle1" master:master
'
+
test_expect_success 'bundle 1 has only 3 files ' '
cd "$D" &&
(
@@ -156,8 +162,7 @@ test_expect_success 'bundle 1 has only 3 files ' '
cat
) <bundle1 >bundle.pack &&
git index-pack bundle.pack &&
- verify=$(git verify-pack -v bundle.pack) &&
- test 4 = $(echo "$verify" | wc -l)
+ test_bundle_object_count bundle.pack 3
'
test_expect_success 'unbundle 2' '
@@ -180,7 +185,7 @@ test_expect_success 'bundle does not prerequisite objects' '
cat
) <bundle3 >bundle.pack &&
git index-pack bundle.pack &&
- test 4 = $(git verify-pack -v bundle.pack | wc -l)
+ test_bundle_object_count bundle.pack 3
'
test_expect_success 'bundle should be able to create a full history' '
@@ -191,38 +196,39 @@ test_expect_success 'bundle should be able to create a full history' '
'
-test "$TEST_RSYNC" && {
+! rsync --help > /dev/null 2> /dev/null &&
+say 'Skipping rsync tests because rsync was not found' || {
test_expect_success 'fetch via rsync' '
git pack-refs &&
mkdir rsynced &&
- cd rsynced &&
- git init &&
- git fetch rsync://127.0.0.1$(pwd)/../.git master:refs/heads/master &&
- git gc --prune &&
- test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
- git fsck --full
+ (cd rsynced &&
+ git init --bare &&
+ git fetch "rsync:$(pwd)/../.git" master:refs/heads/master &&
+ git gc --prune &&
+ test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
+ git fsck --full)
'
test_expect_success 'push via rsync' '
- mkdir ../rsynced2 &&
- (cd ../rsynced2 &&
+ mkdir rsynced2 &&
+ (cd rsynced2 &&
git init) &&
- git push rsync://127.0.0.1$(pwd)/../rsynced2/.git master &&
- cd ../rsynced2 &&
- git gc --prune &&
- test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
- git fsck --full
+ (cd rsynced &&
+ git push "rsync:$(pwd)/../rsynced2/.git" master) &&
+ (cd rsynced2 &&
+ git gc --prune &&
+ test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
+ git fsck --full)
'
test_expect_success 'push via rsync' '
- cd .. &&
mkdir rsynced3 &&
(cd rsynced3 &&
git init) &&
- git push --all rsync://127.0.0.1$(pwd)/rsynced3/.git &&
- cd rsynced3 &&
- test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
- git fsck --full
+ git push --all "rsync:$(pwd)/rsynced3/.git" &&
+ (cd rsynced3 &&
+ test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
+ git fsck --full)
'
}
diff --git a/t/t5511-refspec.sh b/t/t5511-refspec.sh
index 22ba380034..c28932216b 100755
--- a/t/t5511-refspec.sh
+++ b/t/t5511-refspec.sh
@@ -72,4 +72,16 @@ test_refspec fetch ':refs/remotes/frotz/HEAD-to-me'
test_refspec push ':refs/remotes/frotz/delete me' invalid
test_refspec fetch ':refs/remotes/frotz/HEAD to me' invalid
+test_refspec fetch 'refs/heads/*/for-linus:refs/remotes/mine/*-blah' invalid
+test_refspec push 'refs/heads/*/for-linus:refs/remotes/mine/*-blah' invalid
+
+test_refspec fetch 'refs/heads*/for-linus:refs/remotes/mine/*' invalid
+test_refspec push 'refs/heads*/for-linus:refs/remotes/mine/*' invalid
+
+test_refspec fetch 'refs/heads/*/*/for-linus:refs/remotes/mine/*' invalid
+test_refspec push 'refs/heads/*/*/for-linus:refs/remotes/mine/*' invalid
+
+test_refspec fetch 'refs/heads/*/for-linus:refs/remotes/mine/*'
+test_refspec push 'refs/heads/*/for-linus:refs/remotes/mine/*'
+
test_done
diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh
index 1f4608d8ba..dbb927dec8 100755
--- a/t/t5515-fetch-merge-logic.sh
+++ b/t/t5515-fetch-merge-logic.sh
@@ -129,8 +129,7 @@ do
'' | '#'*) continue ;;
esac
test=`echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g'`
- cnt=`expr $test_count + 1`
- pfx=`printf "%04d" $cnt`
+ pfx=`printf "%04d" $test_count`
expect_f="$TEST_DIRECTORY/t5515/fetch.$test"
actual_f="$pfx-fetch.$test"
expect_r="$TEST_DIRECTORY/t5515/refs.$test"
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 4426df9226..2d2633f3f8 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -419,6 +419,19 @@ test_expect_success 'push with config remote.*.push = HEAD' '
git config --remove-section remote.there
git config --remove-section branch.master
+test_expect_success 'push with config remote.*.pushurl' '
+
+ mk_test heads/master &&
+ git checkout master &&
+ git config remote.there.url test2repo &&
+ git config remote.there.pushurl testrepo &&
+ git push there &&
+ check_push_result $the_commit heads/master
+'
+
+# clean up the cruft left with the previous one
+git config --remove-section remote.there
+
test_expect_success 'push with dry-run' '
mk_test heads/master &&
@@ -492,7 +505,7 @@ test_expect_success 'warn on push to HEAD of non-bare repository' '
git checkout master &&
git config receive.denyCurrentBranch warn) &&
git push testrepo master 2>stderr &&
- grep "warning.*this may cause confusion" stderr
+ grep "warning: updating the current branch" stderr
'
test_expect_success 'deny push to HEAD of non-bare repository' '
@@ -510,7 +523,7 @@ test_expect_success 'allow push to HEAD of bare repository (bare)' '
git config receive.denyCurrentBranch true &&
git config core.bare true) &&
git push testrepo master 2>stderr &&
- ! grep "warning.*this may cause confusion" stderr
+ ! grep "warning: updating the current branch" stderr
'
test_expect_success 'allow push to HEAD of non-bare repository (config)' '
@@ -520,7 +533,7 @@ test_expect_success 'allow push to HEAD of non-bare repository (config)' '
git config receive.denyCurrentBranch false
) &&
git push testrepo master 2>stderr &&
- ! grep "warning.*this may cause confusion" stderr
+ ! grep "warning: updating the current branch" stderr
'
test_expect_success 'fetch with branches' '
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 725771fac1..e78d40242a 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -92,20 +92,47 @@ test_expect_success '--rebase with rebased upstream' '
git remote add -f me . &&
git checkout copy &&
+ git tag copy-orig &&
git reset --hard HEAD^ &&
echo conflicting modification > file &&
git commit -m conflict file &&
git checkout to-rebase &&
echo file > file2 &&
git commit -m to-rebase file2 &&
+ git tag to-rebase-orig &&
git pull --rebase me copy &&
test "conflicting modification" = "$(cat file)" &&
test file = $(cat file2)
'
+test_expect_success '--rebase with rebased default upstream' '
+
+ git update-ref refs/remotes/me/copy copy-orig &&
+ git checkout --track -b to-rebase2 me/copy &&
+ git reset --hard to-rebase-orig &&
+ git pull --rebase &&
+ test "conflicting modification" = "$(cat file)" &&
+ test file = $(cat file2)
+
+'
+
+test_expect_success 'rebased upstream + fetch + pull --rebase' '
+
+ git update-ref refs/remotes/me/copy copy-orig &&
+ git reset --hard to-rebase-orig &&
+ git checkout --track -b to-rebase3 me/copy &&
+ git reset --hard to-rebase-orig &&
+ git fetch &&
+ git pull --rebase &&
+ test "conflicting modification" = "$(cat file)" &&
+ test file = "$(cat file2)"
+
+'
+
test_expect_success 'pull --rebase dies early with dirty working directory' '
+ git checkout to-rebase &&
git update-ref refs/remotes/me/copy copy^ &&
COPY=$(git rev-parse --verify me/copy) &&
git rebase --onto $COPY copy &&
diff --git a/t/t5521-pull-symlink.sh b/t/t5522-pull-symlink.sh
index 5672b51e2e..86bbd7d024 100755
--- a/t/t5521-pull-symlink.sh
+++ b/t/t5522-pull-symlink.sh
@@ -4,6 +4,12 @@ test_description='pulling from symlinked subdir'
. ./test-lib.sh
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
# The scenario we are building:
#
# trash\ directory/
diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh
index f5102b902a..a696b8791b 100755
--- a/t/t5530-upload-pack-error.sh
+++ b/t/t5530-upload-pack-error.sh
@@ -30,11 +30,12 @@ test_expect_success 'fsck fails' '
test_must_fail git fsck
'
-test_expect_success 'upload-pack fails due to error in pack-objects' '
+test_expect_success 'upload-pack fails due to error in pack-objects packing' '
! echo "0032want $(git rev-parse HEAD)
00000009done
0000" | git upload-pack . > /dev/null 2> output.err &&
+ grep "unable to read" output.err &&
grep "pack-objects died" output.err
'
@@ -51,9 +52,21 @@ test_expect_success 'fsck fails' '
test_expect_success 'upload-pack fails due to error in rev-list' '
! echo "0032want $(git rev-parse HEAD)
+0034shallow $(git rev-parse HEAD^)00000009done
+0000" | git upload-pack . > /dev/null 2> output.err &&
+ # pack-objects survived
+ grep "Total.*, reused" output.err &&
+ # but there was an error, which must have been in rev-list
+ grep "bad tree object" output.err
+'
+
+test_expect_success 'upload-pack fails due to error in pack-objects enumeration' '
+
+ ! echo "0032want $(git rev-parse HEAD)
00000009done
0000" | git upload-pack . > /dev/null 2> output.err &&
- grep "waitpid (async) failed" output.err
+ grep "bad tree object" output.err &&
+ grep "pack-objects died" output.err
'
test_expect_success 'create empty repository' '
diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh
index c236b5e83b..f4a2cf6c17 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push.sh
@@ -11,22 +11,16 @@ This test runs various sanity checks on http-push.'
ROOT_PATH="$PWD"
LIB_HTTPD_DAV=t
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5540'}
if git http-push > /dev/null 2>&1 || [ $? -eq 128 ]
then
say "skipping test, USE_CURL_MULTI is not defined"
test_done
- exit
fi
. "$TEST_DIRECTORY"/lib-httpd.sh
-
-if ! start_httpd >&3 2>&4
-then
- say "skipping test, web server setup failed"
- test_done
- exit
-fi
+start_httpd
test_expect_success 'setup remote repository' '
cd "$ROOT_PATH" &&
@@ -73,6 +67,42 @@ test_expect_success ' push to remote repository with unpacked refs' '
test $HEAD = $(git rev-parse --verify HEAD))
'
+test_expect_success 'http-push fetches unpacked objects' '
+ cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
+ "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo_unpacked.git &&
+
+ git clone $HTTPD_URL/test_repo_unpacked.git \
+ "$ROOT_PATH"/fetch_unpacked &&
+
+ # By reset, we force git to retrieve the object
+ (cd "$ROOT_PATH"/fetch_unpacked &&
+ git reset --hard HEAD^ &&
+ git remote rm origin &&
+ git reflog expire --expire=0 --all &&
+ git prune &&
+ git push -f -v $HTTPD_URL/test_repo_unpacked.git master)
+'
+
+test_expect_success 'http-push fetches packed objects' '
+ cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
+ "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo_packed.git &&
+
+ git clone $HTTPD_URL/test_repo_packed.git \
+ "$ROOT_PATH"/test_repo_clone_packed &&
+
+ (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo_packed.git &&
+ git --bare repack &&
+ git --bare prune-packed) &&
+
+ # 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 reflog expire --expire=0 --all &&
+ git prune &&
+ git push -f -v $HTTPD_URL/test_repo_packed.git master)
+'
+
test_expect_success 'create and delete remote branch' '
cd "$ROOT_PATH"/test_repo_clone &&
git checkout -b dev &&
@@ -94,6 +124,18 @@ test_expect_success 'MKCOL sends directory names with trailing slashes' '
'
+x1="[0-9a-f]"
+x2="$x1$x1"
+x5="$x1$x1$x1$x1$x1"
+x38="$x5$x5$x5$x5$x5$x5$x5$x1$x1$x1"
+x40="$x38$x2"
+
+test_expect_success 'PUT and MOVE sends object to URLs with SHA-1 hash suffix' '
+ sed -e "s/PUT /OP /" -e "s/MOVE /OP /" "$HTTPD_ROOT_PATH"/access.log |
+ grep -e "\"OP .*/objects/$x2/${x38}_$x40 HTTP/[.0-9]*\" 20[0-9] "
+
+'
+
stop_httpd
test_done
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
new file mode 100755
index 0000000000..0e69324652
--- /dev/null
+++ b/t/t5550-http-fetch.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+test_description='test fetching over http'
+. ./test-lib.sh
+
+if test -n "$NO_CURL"; then
+ say 'skipping test, git built without http support'
+ test_done
+fi
+
+. "$TEST_DIRECTORY"/lib-httpd.sh
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5550'}
+start_httpd
+
+test_expect_success 'setup repository' '
+ echo content >file &&
+ git add file &&
+ git commit -m one
+'
+
+test_expect_success 'create http-accessible bare repository' '
+ mkdir "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+ (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+ git --bare init &&
+ echo "exec git update-server-info" >hooks/post-update &&
+ chmod +x hooks/post-update
+ ) &&
+ git remote add public "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+ git push public master:master
+'
+
+test_expect_success 'clone http repository' '
+ git clone $HTTPD_URL/repo.git clone &&
+ test_cmp file clone/file
+'
+
+test_expect_success 'fetch changes via http' '
+ echo content >>file &&
+ git commit -a -m two &&
+ git push public
+ (cd clone && git pull) &&
+ test_cmp file clone/file
+'
+
+test_expect_success 'http remote detects correct HEAD' '
+ git push public master:other &&
+ (cd clone &&
+ git remote set-head origin -d &&
+ git remote set-head origin -a &&
+ git symbolic-ref refs/remotes/origin/HEAD > output &&
+ echo refs/remotes/origin/master > expect &&
+ test_cmp expect output
+ )
+'
+
+test_expect_success 'fetch packed objects' '
+ cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git &&
+ cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git &&
+ git --bare repack &&
+ git --bare prune-packed &&
+ git clone $HTTPD_URL/repo_pack.git
+'
+
+stop_httpd
+test_done
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 78a3fa639c..2335d8bc85 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -125,4 +125,53 @@ test_expect_success 'clone to destination with extra trailing /' '
'
+test_expect_success 'clone to an existing empty directory' '
+ mkdir target-3 &&
+ git clone src target-3 &&
+ T=$( cd target-3 && git rev-parse HEAD ) &&
+ S=$( cd src && git rev-parse HEAD ) &&
+ test "$T" = "$S"
+'
+
+test_expect_success 'clone to an existing non-empty directory' '
+ mkdir target-4 &&
+ >target-4/Fakefile &&
+ test_must_fail git clone src target-4
+'
+
+test_expect_success 'clone to an existing path' '
+ >target-5 &&
+ test_must_fail git clone src target-5
+'
+
+test_expect_success 'clone a void' '
+ mkdir src-0 &&
+ (
+ cd src-0 && git init
+ ) &&
+ git clone src-0 target-6 &&
+ (
+ cd src-0 && test_commit A
+ ) &&
+ git clone src-0 target-7 &&
+ # There is no reason to insist they are bit-for-bit
+ # identical, but this test should suffice for now.
+ test_cmp target-6/.git/config target-7/.git/config
+'
+
+test_expect_success 'clone respects global branch.autosetuprebase' '
+ (
+ HOME=$(pwd) &&
+ export HOME &&
+ test_config="$HOME/.gitconfig" &&
+ unset GIT_CONFIG_NOGLOBAL &&
+ git config -f "$test_config" branch.autosetuprebase remote &&
+ rm -fr dst &&
+ git clone src dst &&
+ cd dst &&
+ actual="z$(git config branch.master.rebase)" &&
+ test ztrue = $actual
+ )
+'
+
test_done
diff --git a/t/t5602-clone-remote-exec.sh b/t/t5602-clone-remote-exec.sh
index 82b1d1e2b3..deffdaee49 100755
--- a/t/t5602-clone-remote-exec.sh
+++ b/t/t5602-clone-remote-exec.sh
@@ -18,8 +18,8 @@ test_expect_success 'clone calls git upload-pack unqualified with no -u option'
'
test_expect_success 'clone calls specified git upload-pack with -u option' '
- GIT_SSH=./not_ssh git clone -u /something/bin/git-upload-pack localhost:/path/to/repo junk
- echo "localhost /something/bin/git-upload-pack '\''/path/to/repo'\''" >expected
+ GIT_SSH=./not_ssh git clone -u ./something/bin/git-upload-pack localhost:/path/to/repo junk
+ echo "localhost ./something/bin/git-upload-pack '\''/path/to/repo'\''" >expected
test_cmp expected not_ssh_output
'
diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh
index fe0fda282c..19b5c0d552 100755
--- a/t/t5701-clone-local.sh
+++ b/t/t5701-clone-local.sh
@@ -116,4 +116,30 @@ test_expect_success 'bundle clone with nonexistent HEAD' '
test ! -e .git/refs/heads/master
'
+test_expect_success 'clone empty repository' '
+ cd "$D" &&
+ mkdir empty &&
+ (cd empty && git init) &&
+ git clone empty empty-clone &&
+ test_tick &&
+ (cd empty-clone
+ echo "content" >> foo &&
+ git add foo &&
+ git commit -m "Initial commit" &&
+ git push origin master &&
+ expected=$(git rev-parse master) &&
+ actual=$(git --git-dir=../empty/.git rev-parse master) &&
+ test $actual = $expected)
+'
+
+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) &&
+ git clone empty empty-clone &&
+ (cd empty-clone &&
+ test_must_fail git push)
+'
+
test_done
diff --git a/t/t5704-bundle.sh b/t/t5704-bundle.sh
new file mode 100755
index 0000000000..a8f4419e61
--- /dev/null
+++ b/t/t5704-bundle.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+test_description='some bundle related tests'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+
+ : > file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+ test_tick &&
+ git tag -m tag tag &&
+ : > file2 &&
+ git add file2 &&
+ : > file3 &&
+ test_tick &&
+ git commit -m second &&
+ git add file3 &&
+ test_tick &&
+ git commit -m third
+
+'
+
+test_expect_success 'tags can be excluded by rev-list options' '
+
+ git bundle create bundle --all --since=7.Apr.2005.15:16:00.-0700 &&
+ git ls-remote bundle > output &&
+ ! grep tag output
+
+'
+
+test_done
diff --git a/t/t5705-clone-2gb.sh b/t/t5705-clone-2gb.sh
new file mode 100755
index 0000000000..9f52154cac
--- /dev/null
+++ b/t/t5705-clone-2gb.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+test_description='Test cloning a repository larger than 2 gigabyte'
+. ./test-lib.sh
+
+test -z "$GIT_TEST_CLONE_2GB" &&
+say "Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t" &&
+test_done &&
+exit
+
+test_expect_success 'setup' '
+
+ git config pack.compression 0 &&
+ git config pack.depth 0 &&
+ blobsize=$((20*1024*1024)) &&
+ blobcount=$((2*1024*1024*1024/$blobsize+1)) &&
+ i=1 &&
+ (while test $i -le $blobcount
+ do
+ printf "Generating blob $i/$blobcount\r" >&2 &&
+ printf "blob\nmark :$i\ndata $blobsize\n" &&
+ #test-genrandom $i $blobsize &&
+ printf "%-${blobsize}s" $i &&
+ echo "M 100644 :$i $i" >> commit
+ i=$(($i+1)) ||
+ echo $? > exit-status
+ done &&
+ echo "commit refs/heads/master" &&
+ echo "author A U Thor <author@email.com> 123456789 +0000" &&
+ echo "committer C O Mitter <committer@email.com> 123456789 +0000" &&
+ echo "data 5" &&
+ echo ">2gb" &&
+ cat commit) |
+ git fast-import &&
+ test ! -f exit-status
+
+'
+
+test_expect_success 'clone' '
+
+ git clone --bare --no-hardlinks . clone
+
+'
+
+test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 86bf7e14ba..59d1f6283b 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -14,7 +14,7 @@ touch foo && git add foo && git commit -m "added foo" &&
test_format() {
cat >expect.$1
test_expect_success "format $1" "
-git rev-list --pretty=format:$2 master >output.$1 &&
+git rev-list --pretty=format:'$2' master >output.$1 &&
test_cmp expect.$1 output.$1
"
}
@@ -101,6 +101,13 @@ commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
foobarbazxyzzy
EOF
+test_format advanced-colors '%C(red yellow bold)foo%C(reset)' <<'EOF'
+commit 131a310eb913d107dd3c09a65d1651175898735d
+foo
+commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
+foo
+EOF
+
cat >commit-msg <<'EOF'
Test printing of complex bodies
diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh
index 04e4b7c5c2..0144d9e858 100755
--- a/t/t6010-merge-base.sh
+++ b/t/t6010-merge-base.sh
@@ -110,6 +110,18 @@ test_expect_success 'compute merge-base (all)' \
# Another set to demonstrate base between one commit and a merge
# in the documentation.
+#
+# * C (MMC) * B (MMB) * A (MMA)
+# * o * o * o
+# * o * o * o
+# * o * o * o
+# * o | _______/
+# | |/
+# | * 1 (MM1)
+# | _______/
+# |/
+# * root (MMR)
+
test_expect_success 'merge-base for octopus-step (setup)' '
test_tick && git commit --allow-empty -m root && git tag MMR &&
@@ -137,6 +149,12 @@ test_expect_success 'merge-base A B C' '
test "$MM1" = "$MB"
'
+test_expect_success 'merge-base A B C using show-branch' '
+ MB=$(git show-branch --merge-base MMA MMB MMC) &&
+ MMR=$(git rev-parse --verify MMR) &&
+ test "$MMR" = "$MB"
+'
+
test_expect_success 'criss-cross merge-base for octopus-step (setup)' '
git reset --hard MMR &&
test_tick && git commit --allow-empty -m 1 && git tag CC1 &&
diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh
index a19d49de28..e71c687f2b 100755
--- a/t/t6020-merge-df.sh
+++ b/t/t6020-merge-df.sh
@@ -22,4 +22,27 @@ git commit -m "File: dir"'
test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master'
+test_expect_failure 'F/D conflict' '
+ git reset --hard &&
+ git checkout master &&
+ rm .git/index &&
+
+ mkdir before &&
+ echo FILE >before/one &&
+ echo FILE >after &&
+ git add . &&
+ git commit -m first &&
+
+ rm -f after &&
+ git mv before after &&
+ git commit -m move &&
+
+ git checkout -b para HEAD^ &&
+ echo COMPLETELY ANOTHER FILE >another &&
+ git add . &&
+ git commit -m para &&
+
+ git merge master
+'
+
test_done
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index f8942bc890..7dcf391914 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -54,6 +54,12 @@ deduxit me super semitas jusitiae,
EOF
printf "propter nomen suum." >> new4.txt
+test_expect_success 'merge with no changes' '
+ cp orig.txt test.txt &&
+ git merge-file test.txt orig.txt orig.txt &&
+ test_cmp test.txt orig.txt
+'
+
cp new1.txt test.txt
test_expect_success "merge without conflict" \
"git merge-file test.txt orig.txt new2.txt"
diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh
index 129fa3000c..b3fbf659c0 100755
--- a/t/t6024-recursive-merge.sh
+++ b/t/t6024-recursive-merge.sh
@@ -65,18 +65,18 @@ test_expect_success "combined merge conflicts" "
"
cat > expect << EOF
-<<<<<<< HEAD:a1
+<<<<<<< HEAD
F
=======
G
->>>>>>> G:a1
+>>>>>>> G
EOF
test_expect_success "result contains a conflict" "test_cmp expect a1"
git ls-files --stage > out
cat > expect << EOF
-100644 da056ce14a2241509897fa68bb2b3b6e6194ef9e 1 a1
+100644 439cc46de773d8a83c77799b7cc9191c128bfcff 1 a1
100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1
100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1
EOF
@@ -93,8 +93,7 @@ test_expect_success 'refuse to merge binary files' '
git add binary-file &&
git commit -m binary2 &&
test_must_fail git merge F > merge.out 2> merge.err &&
- grep "Cannot merge binary files: HEAD:binary-file vs. F:binary-file" \
- merge.err
+ grep "Cannot merge binary files: binary-file (HEAD vs. F)" merge.err
'
test_expect_success 'mark rename/delete as unmerged' '
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 052a6c90f5..1315bab595 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -482,28 +482,89 @@ test_expect_success 'good merge bases when good and bad are siblings' '
git bisect reset
'
-check_trace() {
- grep "$1" "$GIT_TRACE" | grep "\^$2" | grep "$3" >/dev/null
-}
-
test_expect_success 'optimized merge base checks' '
- GIT_TRACE="$(pwd)/trace.log" &&
- export GIT_TRACE &&
git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt &&
grep "merge base must be tested" my_bisect_log.txt &&
grep "$HASH4" my_bisect_log.txt &&
- check_trace "rev-list" "$HASH7" "$SIDE_HASH7" &&
git bisect good > my_bisect_log2.txt &&
test -f ".git/BISECT_ANCESTORS_OK" &&
test "$HASH6" = $(git rev-parse --verify HEAD) &&
- : > "$GIT_TRACE" &&
git bisect bad > my_bisect_log3.txt &&
- test_must_fail check_trace "rev-list" "$HASH6" "$SIDE_HASH7" &&
git bisect good "$A_HASH" > my_bisect_log4.txt &&
grep "merge base must be tested" my_bisect_log4.txt &&
- test_must_fail test -f ".git/BISECT_ANCESTORS_OK" &&
- check_trace "rev-list" "$HASH6" "$A_HASH" &&
- unset GIT_TRACE
+ test_must_fail test -f ".git/BISECT_ANCESTORS_OK"
+'
+
+# This creates another side branch called "parallel" with some files
+# in some directories, to test bisecting with paths.
+#
+# We should have the following:
+#
+# P1-P2-P3-P4-P5-P6-P7
+# / / /
+# H1-H2-H3-H4-H5-H6-H7
+# \ \ \
+# S5-A \
+# \ \
+# S6-S7----B
+#
+test_expect_success '"parallel" side branch creation' '
+ git bisect reset &&
+ git checkout -b parallel $HASH1 &&
+ mkdir dir1 dir2 &&
+ add_line_into_file "1(para): line 1 on parallel branch" dir1/file1 &&
+ PARA_HASH1=$(git rev-parse --verify HEAD) &&
+ add_line_into_file "2(para): line 2 on parallel branch" dir2/file2 &&
+ PARA_HASH2=$(git rev-parse --verify HEAD) &&
+ add_line_into_file "3(para): line 3 on parallel branch" dir2/file3 &&
+ PARA_HASH3=$(git rev-parse --verify HEAD)
+ git merge -m "merge HASH4 and PARA_HASH3" "$HASH4" &&
+ PARA_HASH4=$(git rev-parse --verify HEAD)
+ add_line_into_file "5(para): add line on parallel branch" dir1/file1 &&
+ PARA_HASH5=$(git rev-parse --verify HEAD)
+ add_line_into_file "6(para): add line on parallel branch" dir2/file2 &&
+ PARA_HASH6=$(git rev-parse --verify HEAD)
+ git merge -m "merge HASH7 and PARA_HASH6" "$HASH7" &&
+ PARA_HASH7=$(git rev-parse --verify HEAD)
+'
+
+test_expect_success 'restricting bisection on one dir' '
+ git bisect reset &&
+ git bisect start HEAD $HASH1 -- dir1 &&
+ para1=$(git rev-parse --verify HEAD) &&
+ test "$para1" = "$PARA_HASH1" &&
+ git bisect bad > my_bisect_log.txt &&
+ grep "$PARA_HASH1 is first bad commit" my_bisect_log.txt
+'
+
+test_expect_success 'restricting bisection on one dir and a file' '
+ git bisect reset &&
+ git bisect start HEAD $HASH1 -- dir1 hello &&
+ para4=$(git rev-parse --verify HEAD) &&
+ test "$para4" = "$PARA_HASH4" &&
+ git bisect bad &&
+ hash3=$(git rev-parse --verify HEAD) &&
+ test "$hash3" = "$HASH3" &&
+ git bisect good &&
+ hash4=$(git rev-parse --verify HEAD) &&
+ test "$hash4" = "$HASH4" &&
+ git bisect good &&
+ para1=$(git rev-parse --verify HEAD) &&
+ test "$para1" = "$PARA_HASH1" &&
+ git bisect good > my_bisect_log.txt &&
+ grep "$PARA_HASH4 is first bad commit" my_bisect_log.txt
+'
+
+test_expect_success 'skipping away from skipped commit' '
+ git bisect start $PARA_HASH7 $HASH1 &&
+ para4=$(git rev-parse --verify HEAD) &&
+ test "$para4" = "$PARA_HASH4" &&
+ git bisect skip &&
+ hash7=$(git rev-parse --verify HEAD) &&
+ test "$hash7" = "$HASH7" &&
+ git bisect skip &&
+ para3=$(git rev-parse --verify HEAD) &&
+ test "$para3" = "$PARA_HASH3"
'
#
diff --git a/t/t6031-merge-recursive.sh b/t/t6031-merge-recursive.sh
index 8073e0c3ef..8a3304fb0b 100755
--- a/t/t6031-merge-recursive.sh
+++ b/t/t6031-merge-recursive.sh
@@ -3,8 +3,10 @@
test_description='merge-recursive: handle file mode'
. ./test-lib.sh
-# Note that we follow "chmod +x F" with "update-index --chmod=+x F" to
-# help filesystems that do not have the executable bit.
+if ! test "$(git config --bool core.filemode)" = false
+then
+ test_set_prereq FILEMODE
+fi
test_expect_success 'mode change in one branch: keep changed version' '
: >file1 &&
@@ -15,11 +17,14 @@ test_expect_success 'mode change in one branch: keep changed version' '
git add dummy &&
git commit -m a &&
git checkout -b b1 master &&
- chmod +x file1 &&
- git update-index --chmod=+x file1 &&
+ test_chmod +x file1 &&
git commit -m b1 &&
git checkout a1 &&
git merge-recursive master -- a1 b1 &&
+ git ls-files -s file1 | grep ^100755
+'
+
+test_expect_success FILEMODE 'verify executable bit on file' '
test -x file1
'
@@ -28,8 +33,7 @@ test_expect_success 'mode change in both branches: expect conflict' '
git checkout -b a2 master &&
: >file2 &&
H=$(git hash-object file2) &&
- chmod +x file2 &&
- git update-index --add --chmod=+x file2 &&
+ test_chmod +x file2 &&
git commit -m a2 &&
git checkout -b b2 master &&
: >file2 &&
@@ -46,6 +50,10 @@ test_expect_success 'mode change in both branches: expect conflict' '
echo "100644 $H 3 file2"
) >expect &&
test_cmp actual expect &&
+ git ls-files -s file2 | grep ^100755
+'
+
+test_expect_success FILEMODE 'verify executable bit on file' '
test -x file2
'
diff --git a/t/t6023-merge-rename-nocruft.sh b/t/t6034-merge-rename-nocruft.sh
index 65be95fbaa..65be95fbaa 100755
--- a/t/t6023-merge-rename-nocruft.sh
+++ b/t/t6034-merge-rename-nocruft.sh
diff --git a/t/t6035-merge-dir-to-symlink.sh b/t/t6035-merge-dir-to-symlink.sh
new file mode 100755
index 0000000000..5b96fb0b37
--- /dev/null
+++ b/t/t6035-merge-dir-to-symlink.sh
@@ -0,0 +1,93 @@
+#!/bin/sh
+
+test_description='merging when a directory was replaced with a symlink'
+. ./test-lib.sh
+
+if ! test_have_prereq SYMLINKS
+then
+ say 'Symbolic links not supported, skipping tests.'
+ test_done
+fi
+
+test_expect_success 'create a commit where dir a/b changed to symlink' '
+ mkdir -p a/b/c a/b-2/c &&
+ > a/b/c/d &&
+ > a/b-2/c/d &&
+ > a/x &&
+ git add -A &&
+ git commit -m base &&
+ git tag start &&
+ rm -rf a/b &&
+ ln -s b-2 a/b &&
+ git add -A &&
+ git commit -m "dir to symlink"
+'
+
+test_expect_success 'keep a/b-2/c/d across checkout' '
+ git checkout HEAD^0 &&
+ git reset --hard master &&
+ git rm --cached a/b &&
+ git commit -m "untracked symlink remains" &&
+ git checkout start^0 &&
+ test -f a/b-2/c/d
+'
+
+test_expect_success 'checkout should not have deleted a/b-2/c/d' '
+ git checkout HEAD^0 &&
+ git reset --hard master &&
+ git checkout start^0 &&
+ test -f a/b-2/c/d
+'
+
+test_expect_success 'setup for merge test' '
+ git reset --hard &&
+ test -f a/b-2/c/d &&
+ echo x > a/x &&
+ git add a/x &&
+ git commit -m x &&
+ git tag baseline
+'
+
+test_expect_success 'do not lose a/b-2/c/d in merge (resolve)' '
+ git reset --hard &&
+ git checkout baseline^0 &&
+ git merge -s resolve master &&
+ test -h a/b &&
+ test -f a/b-2/c/d
+'
+
+test_expect_failure 'do not lose a/b-2/c/d in merge (recursive)' '
+ git reset --hard &&
+ git checkout baseline^0 &&
+ git merge -s recursive master &&
+ test -h a/b &&
+ test -f a/b-2/c/d
+'
+
+test_expect_success 'setup a merge where dir a/b-2 changed to symlink' '
+ git reset --hard &&
+ git checkout start^0 &&
+ rm -rf a/b-2 &&
+ ln -s b a/b-2 &&
+ git add -A &&
+ git commit -m "dir a/b-2 to symlink" &&
+ git tag test2
+'
+
+test_expect_failure 'merge should not have conflicts (resolve)' '
+ git reset --hard &&
+ git checkout baseline^0 &&
+ git merge -s resolve test2 &&
+ test -h a/b-2 &&
+ test -f a/b/c/d
+'
+
+test_expect_failure 'merge should not have conflicts (recursive)' '
+ git reset --hard &&
+ git checkout baseline^0 &&
+ git merge -s recursive test2 &&
+ test -h a/b-2 &&
+ test -f a/b/c/d
+'
+
+test_done
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index ba9060190d..00e1de9627 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -29,7 +29,9 @@ test_expect_success setup '
git checkout -b b4 origin &&
advance e &&
advance f
- )
+ ) &&
+ git checkout -b follower --track master &&
+ advance g
'
script='s/^..\(b.\)[ 0-9a-f]*\[\([^]]*\)\].*/\1 \2/p'
@@ -56,6 +58,12 @@ test_expect_success 'checkout' '
grep "have 1 and 1 different" actual
'
+test_expect_success 'checkout with local tracked branch' '
+ git checkout master &&
+ git checkout follower >actual
+ grep "is ahead of" actual
+'
+
test_expect_success 'status' '
(
cd test &&
@@ -66,5 +74,19 @@ test_expect_success 'status' '
grep "have 1 and 1 different" actual
'
+test_expect_success 'status when tracking lightweight tags' '
+ git checkout master &&
+ git tag light &&
+ git branch --track lighttrack light >actual &&
+ grep "set up to track" actual &&
+ git checkout lighttrack
+'
+test_expect_success 'status when tracking annotated tags' '
+ git checkout master &&
+ git tag -m heavy heavy &&
+ git branch --track heavytrack heavy >actual &&
+ grep "set up to track" actual &&
+ git checkout heavytrack
+'
test_done
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index 8f5a06f7dd..42f6fff373 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -83,13 +83,13 @@ test_expect_success 'merge-msg test #1' '
'
cat >expected <<EOF
-Merge branch 'left' of $TEST_DIRECTORY/$test
+Merge branch 'left' of $(pwd)
EOF
test_expect_success 'merge-msg test #2' '
git checkout master &&
- git fetch "$TEST_DIRECTORY/$test" left &&
+ git fetch "$(pwd)" left &&
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
test_cmp expected actual
@@ -208,4 +208,36 @@ test_expect_success 'merge-msg test #5-2' '
test_cmp expected actual
'
+test_expect_success 'merge-msg -F' '
+
+ git config --unset-all merge.log
+ git config --unset-all merge.summary
+ git config merge.summary yes &&
+
+ git checkout master &&
+ setdate &&
+ git fetch . left right &&
+
+ git fmt-merge-msg -F .git/FETCH_HEAD >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'merge-msg -F in subdirectory' '
+
+ git config --unset-all merge.log
+ git config --unset-all merge.summary
+ git config merge.summary yes &&
+
+ git checkout master &&
+ setdate &&
+ git fetch . left right &&
+ mkdir sub &&
+ cp .git/FETCH_HEAD sub/FETCH_HEAD &&
+ (
+ cd sub &&
+ git fmt-merge-msg -F FETCH_HEAD >../actual
+ ) &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 8bfae44a83..8052c86ad3 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -26,6 +26,13 @@ test_expect_success 'Create sample commit with known timestamp' '
git tag -a -m "Tagging at $datestamp" testtag
'
+test_expect_success 'Create upstream config' '
+ git update-ref refs/remotes/origin/master master &&
+ git remote add origin nowhere &&
+ git config branch.master.remote origin &&
+ git config branch.master.merge refs/heads/master
+'
+
test_atom() {
case "$1" in
head) ref=refs/heads/master ;;
@@ -39,6 +46,7 @@ test_atom() {
}
test_atom head refname refs/heads/master
+test_atom head upstream refs/remotes/origin/master
test_atom head objecttype commit
test_atom head objectsize 171
test_atom head objectname 67a36f10722846e891fbada1ba48ed035de75581
@@ -68,6 +76,7 @@ test_atom head contents 'Initial
'
test_atom tag refname refs/tags/testtag
+test_atom tag upstream ''
test_atom tag objecttype tag
test_atom tag objectsize 154
test_atom tag objectname 98b46b1d36e5b07909de1b3886224e3e81e87322
@@ -203,6 +212,7 @@ test_expect_success 'Check format "rfc2822" date fields output' '
cat >expected <<\EOF
refs/heads/master
+refs/remotes/origin/master
refs/tags/testtag
EOF
@@ -214,6 +224,7 @@ test_expect_success 'Verify ascending sort' '
cat >expected <<\EOF
refs/tags/testtag
+refs/remotes/origin/master
refs/heads/master
EOF
@@ -224,6 +235,7 @@ test_expect_success 'Verify descending sort' '
cat >expected <<\EOF
'refs/heads/master'
+'refs/remotes/origin/master'
'refs/tags/testtag'
EOF
@@ -244,6 +256,7 @@ test_expect_success 'Quoting style: python' '
cat >expected <<\EOF
"refs/heads/master"
+"refs/remotes/origin/master"
"refs/tags/testtag"
EOF
@@ -273,16 +286,26 @@ test_expect_success 'Check short refname format' '
test_cmp expected actual
'
+cat >expected <<EOF
+origin/master
+EOF
+
+test_expect_success 'Check short upstream format' '
+ git for-each-ref --format="%(upstream:short)" refs/heads >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'Check for invalid refname format' '
test_must_fail git for-each-ref --format="%(refname:INVALID)"
'
cat >expected <<\EOF
heads/master
-master
+tags/master
EOF
-test_expect_success 'Check ambiguous head and tag refs' '
+test_expect_success 'Check ambiguous head and tag refs (strict)' '
+ git config --bool core.warnambiguousrefs true &&
git checkout -b newtag &&
echo "Using $datestamp" > one &&
git add one &&
@@ -294,11 +317,22 @@ test_expect_success 'Check ambiguous head and tag refs' '
'
cat >expected <<\EOF
+heads/master
+master
+EOF
+
+test_expect_success 'Check ambiguous head and tag refs (loose)' '
+ git config --bool core.warnambiguousrefs false &&
+ git for-each-ref --format "%(refname:short)" refs/heads/master refs/tags/master >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
heads/ambiguous
ambiguous
EOF
-test_expect_success 'Check ambiguous head and tag refs II' '
+test_expect_success 'Check ambiguous head and tag refs II (loose)' '
git checkout master &&
git tag ambiguous testtag^0 &&
git branch ambiguous testtag^0 &&
diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh
index 8fb3a56838..10b8f8c44b 100755
--- a/t/t7001-mv.sh
+++ b/t/t7001-mv.sh
@@ -206,7 +206,7 @@ test_expect_success 'git mv should not change sha1 of moved cache entry' '
rm -f dirty dirty2
-test_expect_success 'git mv should overwrite symlink to a file' '
+test_expect_success SYMLINKS 'git mv should overwrite symlink to a file' '
rm -fr .git &&
git init &&
@@ -225,7 +225,7 @@ test_expect_success 'git mv should overwrite symlink to a file' '
rm -f moved symlink
-test_expect_success 'git mv should overwrite file with a symlink' '
+test_expect_success SYMLINKS 'git mv should overwrite file with a symlink' '
rm -fr .git &&
git init &&
diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh
index b81593780a..b4709e28b5 100755
--- a/t/t7002-grep.sh
+++ b/t/t7002-grep.sh
@@ -8,6 +8,15 @@ test_description='git grep various.
. ./test-lib.sh
+cat >hello.c <<EOF
+#include <stdio.h>
+int main(int argc, const char **argv)
+{
+ printf("Hello world.\n");
+ return 0;
+}
+EOF
+
test_expect_success setup '
{
echo foo mmap bar
@@ -16,12 +25,17 @@ test_expect_success setup '
echo foo mmap bar_mmap
echo foo_mmap bar mmap baz
} >file &&
+ echo vvv >v &&
+ echo ww w >w &&
echo x x xx x >x &&
echo y yy >y &&
echo zzz > z &&
mkdir t &&
echo test >t/t &&
- git add file x y z t/t &&
+ echo vvv >t/v &&
+ mkdir t/a &&
+ echo vvv >t/a/v &&
+ git add . &&
test_tick &&
git commit -m initial
'
@@ -48,6 +62,12 @@ do
diff expected actual
'
+ test_expect_success "grep -w $L (w)" '
+ : >expected &&
+ ! git grep -n -w -e "^w" >actual &&
+ test_cmp expected actual
+ '
+
test_expect_success "grep -w $L (x)" '
{
echo ${HC}x:1:x x xx x
@@ -116,8 +136,105 @@ do
! git grep -c test $H | grep /dev/null
'
+ test_expect_success "grep --max-depth -1 $L" '
+ {
+ echo ${HC}t/a/v:1:vvv
+ echo ${HC}t/v:1:vvv
+ echo ${HC}v:1:vvv
+ } >expected &&
+ git grep --max-depth -1 -n -e vvv $H >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep --max-depth 0 $L" '
+ {
+ echo ${HC}v:1:vvv
+ } >expected &&
+ git grep --max-depth 0 -n -e vvv $H >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep --max-depth 0 -- '*' $L" '
+ {
+ echo ${HC}t/a/v:1:vvv
+ echo ${HC}t/v:1:vvv
+ echo ${HC}v:1:vvv
+ } >expected &&
+ git grep --max-depth 0 -n -e vvv $H -- "*" >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep --max-depth 1 $L" '
+ {
+ echo ${HC}t/v:1:vvv
+ echo ${HC}v:1:vvv
+ } >expected &&
+ git grep --max-depth 1 -n -e vvv $H >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "grep --max-depth 0 -- t $L" '
+ {
+ echo ${HC}t/v:1:vvv
+ } >expected &&
+ git grep --max-depth 0 -n -e vvv $H -- t >actual &&
+ test_cmp expected actual
+ '
+
done
+cat >expected <<EOF
+file:foo mmap bar_mmap
+EOF
+
+test_expect_success 'grep -e A --and -e B' '
+ git grep -e "foo mmap" --and -e bar_mmap >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+file:foo_mmap bar mmap
+file:foo_mmap bar mmap baz
+EOF
+
+
+test_expect_success 'grep ( -e A --or -e B ) --and -e B' '
+ git grep \( -e foo_ --or -e baz \) \
+ --and -e " mmap" >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+file:foo mmap bar
+EOF
+
+test_expect_success 'grep -e A --and --not -e B' '
+ git grep -e "foo mmap" --and --not -e bar_mmap >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+y:y yy
+--
+z:zzz
+EOF
+
+# 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 --no-ext-grep, hunk mark between files' '
+ git grep -C1 --no-ext-grep "^[yz]" >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'log grep setup' '
echo a >>file &&
test_tick &&
@@ -170,9 +287,45 @@ test_expect_success 'log grep (6)' '
test_expect_success 'grep with CE_VALID file' '
git update-index --assume-unchanged t/t &&
rm t/t &&
- test "$(git grep --no-ext-grep t)" = "t/t:test" &&
+ test "$(git grep --no-ext-grep test)" = "t/t:test" &&
git update-index --no-assume-unchanged t/t &&
git checkout t/t
'
+cat >expected <<EOF
+hello.c=#include <stdio.h>
+hello.c: return 0;
+EOF
+
+test_expect_success 'grep -p with userdiff' '
+ git config diff.custom.funcname "^#" &&
+ echo "hello.c diff=custom" >.gitattributes &&
+ git grep -p return >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+hello.c=int main(int argc, const char **argv)
+hello.c: return 0;
+EOF
+
+test_expect_success 'grep -p' '
+ rm -f .gitattributes &&
+ git grep -p return >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+hello.c-#include <stdio.h>
+hello.c=int main(int argc, const char **argv)
+hello.c-{
+hello.c- printf("Hello world.\n");
+hello.c: return 0;
+EOF
+
+test_expect_success 'grep -p -B5' '
+ git grep -p -B5 return >actual &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index 6a9936e5c4..329c851685 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -48,6 +48,22 @@ test_expect_success 'result is really identical' '
test $H = $(git rev-parse HEAD)
'
+TRASHDIR=$(pwd)
+test_expect_success 'correct GIT_DIR while using -d' '
+ mkdir drepo &&
+ ( cd drepo &&
+ git init &&
+ test_commit drepo &&
+ git filter-branch -d "$TRASHDIR/dfoo" \
+ --index-filter "cp \"$TRASHDIR\"/dfoo/backup-refs \"$TRASHDIR\"" \
+ ) &&
+ grep drepo "$TRASHDIR/backup-refs"
+'
+
+test_expect_success 'Fail if commit filter fails' '
+ test_must_fail git filter-branch -f --commit-filter "exit 1" HEAD
+'
+
test_expect_success 'rewrite, renaming a specific file' '
git filter-branch -f --tree-filter "mv d doh || :" HEAD
'
@@ -264,4 +280,12 @@ test_expect_success 'Tag name filtering allows slashes in tag names' '
test_cmp expect actual
'
+test_expect_success 'Prune empty commits' '
+ git rev-list HEAD > expect &&
+ make_commit to_remove &&
+ git filter-branch -f --index-filter "git update-index --remove to_remove" --prune-empty HEAD &&
+ git rev-list HEAD > actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index f377fea4bb..73dbc4360b 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -185,8 +185,9 @@ cba
EOF
test_expect_success \
'listing tags with substring as pattern must print those matching' '
- git tag -l "*a*" > actual &&
- test_cmp expect actual
+ rm *a* &&
+ git tag -l "*a*" > current &&
+ test_cmp expect current
'
cat >expect <<EOF
@@ -580,28 +581,38 @@ test_expect_success \
'
# subsequent tests require gpg; check if it is available
-gpg --version >/dev/null
+gpg --version >/dev/null 2>/dev/null
if [ $? -eq 127 ]; then
- echo "gpg not found - skipping tag signing and verification tests"
- test_done
- exit
+ say "gpg not found - skipping tag signing and verification tests"
+else
+ # As said here: http://www.gnupg.org/documentation/faqs.html#q6.19
+ # the gpg version 1.0.6 didn't parse trust packets correctly, so for
+ # that version, creation of signed tags using the generated key fails.
+ case "$(gpg --version)" in
+ 'gpg (GnuPG) 1.0.6'*)
+ say "Skipping signed tag tests, because a bug in 1.0.6 version"
+ ;;
+ *)
+ test_set_prereq GPG
+ ;;
+ esac
fi
# trying to verify annotated non-signed tags:
-test_expect_success \
+test_expect_success GPG \
'trying to verify an annotated non-signed tag should fail' '
tag_exists annotated-tag &&
test_must_fail git tag -v annotated-tag
'
-test_expect_success \
+test_expect_success GPG \
'trying to verify a file-annotated non-signed tag should fail' '
tag_exists file-annotated-tag &&
test_must_fail git tag -v file-annotated-tag
'
-test_expect_success \
+test_expect_success GPG \
'trying to verify two annotated non-signed tags should fail' '
tag_exists annotated-tag file-annotated-tag &&
test_must_fail git tag -v annotated-tag file-annotated-tag
@@ -609,17 +620,6 @@ test_expect_success \
# creating and verifying signed tags:
-# As said here: http://www.gnupg.org/documentation/faqs.html#q6.19
-# the gpg version 1.0.6 didn't parse trust packets correctly, so for
-# that version, creation of signed tags using the generated key fails.
-case "$(gpg --version)" in
-'gpg (GnuPG) 1.0.6'*)
- echo "Skipping signed tag tests, because a bug in 1.0.6 version"
- test_done
- exit
- ;;
-esac
-
# key generation info: gpg --homedir t/t7004 --gen-key
# Type DSA and Elgamal, size 2048 bits, no expiration date.
# Name and email: C O Mitter <committer@example.com>
@@ -633,7 +633,7 @@ export GNUPGHOME
get_tag_header signed-tag $commit commit $time >expect
echo 'A signed tag message' >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success 'creating a signed tag with -m message should succeed' '
+test_expect_success GPG 'creating a signed tag with -m message should succeed' '
git tag -s -m "A signed tag message" signed-tag &&
get_tag_msg signed-tag >actual &&
test_cmp expect actual
@@ -642,7 +642,7 @@ test_expect_success 'creating a signed tag with -m message should succeed' '
get_tag_header u-signed-tag $commit commit $time >expect
echo 'Another message' >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success 'sign with a given key id' '
+test_expect_success GPG 'sign with a given key id' '
git tag -u committer@example.com -m "Another message" u-signed-tag &&
get_tag_msg u-signed-tag >actual &&
@@ -650,14 +650,14 @@ test_expect_success 'sign with a given key id' '
'
-test_expect_success 'sign with an unknown id (1)' '
+test_expect_success GPG 'sign with an unknown id (1)' '
test_must_fail git tag -u author@example.com \
-m "Another message" o-signed-tag
'
-test_expect_success 'sign with an unknown id (2)' '
+test_expect_success GPG 'sign with an unknown id (2)' '
test_must_fail git tag -u DEADBEEF -m "Another message" o-signed-tag
@@ -674,7 +674,7 @@ chmod +x fakeeditor
get_tag_header implied-sign $commit commit $time >expect
./fakeeditor >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success '-u implies signed tag' '
+test_expect_success GPG '-u implies signed tag' '
GIT_EDITOR=./fakeeditor git tag -u CDDE430D implied-sign &&
get_tag_msg implied-sign >actual &&
test_cmp expect actual
@@ -687,7 +687,7 @@ EOF
get_tag_header file-signed-tag $commit commit $time >expect
cat sigmsgfile >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with -F messagefile should succeed' '
git tag -s -F sigmsgfile file-signed-tag &&
get_tag_msg file-signed-tag >actual &&
@@ -701,7 +701,7 @@ EOF
get_tag_header stdin-signed-tag $commit commit $time >expect
cat siginputmsg >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success 'creating a signed tag with -F - should succeed' '
+test_expect_success GPG 'creating a signed tag with -F - should succeed' '
git tag -s -F - stdin-signed-tag <siginputmsg &&
get_tag_msg stdin-signed-tag >actual &&
test_cmp expect actual
@@ -710,13 +710,13 @@ test_expect_success 'creating a signed tag with -F - should succeed' '
get_tag_header implied-annotate $commit commit $time >expect
./fakeeditor >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success '-s implies annotated tag' '
+test_expect_success GPG '-s implies annotated tag' '
GIT_EDITOR=./fakeeditor git tag -s implied-annotate &&
get_tag_msg implied-annotate >actual &&
test_cmp expect actual
'
-test_expect_success \
+test_expect_success GPG \
'trying to create a signed tag with non-existing -F file should fail' '
! test -f nonexistingfile &&
! tag_exists nosigtag &&
@@ -724,13 +724,13 @@ test_expect_success \
! tag_exists nosigtag
'
-test_expect_success 'verifying a signed tag should succeed' \
+test_expect_success GPG 'verifying a signed tag should succeed' \
'git tag -v signed-tag'
-test_expect_success 'verifying two signed tags in one command should succeed' \
+test_expect_success GPG 'verifying two signed tags in one command should succeed' \
'git tag -v signed-tag file-signed-tag'
-test_expect_success \
+test_expect_success GPG \
'verifying many signed and non-signed tags should fail' '
test_must_fail git tag -v signed-tag annotated-tag &&
test_must_fail git tag -v file-annotated-tag file-signed-tag &&
@@ -739,7 +739,7 @@ test_expect_success \
test_must_fail git tag -v signed-tag annotated-tag file-signed-tag
'
-test_expect_success 'verifying a forged tag should fail' '
+test_expect_success GPG 'verifying a forged tag should fail' '
forged=$(git cat-file tag signed-tag |
sed -e "s/signed-tag/forged-tag/" |
git mktag) &&
@@ -751,7 +751,7 @@ test_expect_success 'verifying a forged tag should fail' '
get_tag_header empty-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with an empty -m message should succeed' '
git tag -s -m "" empty-signed-tag &&
get_tag_msg empty-signed-tag >actual &&
@@ -762,7 +762,7 @@ test_expect_success \
>sigemptyfile
get_tag_header emptyfile-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with an empty -F messagefile should succeed' '
git tag -s -F sigemptyfile emptyfile-signed-tag &&
get_tag_msg emptyfile-signed-tag >actual &&
@@ -785,7 +785,7 @@ Trailing spaces
Trailing blank lines
EOF
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'extra blanks in the message for a signed tag should be removed' '
git tag -s -F sigblanksfile blanks-signed-tag &&
get_tag_msg blanks-signed-tag >actual &&
@@ -795,7 +795,7 @@ test_expect_success \
get_tag_header blank-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with a blank -m message should succeed' '
git tag -s -m " " blank-signed-tag &&
get_tag_msg blank-signed-tag >actual &&
@@ -808,7 +808,7 @@ echo '' >>sigblankfile
echo ' ' >>sigblankfile
get_tag_header blankfile-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with blank -F file with spaces should succeed' '
git tag -s -F sigblankfile blankfile-signed-tag &&
get_tag_msg blankfile-signed-tag >actual &&
@@ -819,7 +819,7 @@ test_expect_success \
printf ' ' >sigblanknonlfile
get_tag_header blanknonlfile-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with spaces and no newline should succeed' '
git tag -s -F sigblanknonlfile blanknonlfile-signed-tag &&
get_tag_msg blanknonlfile-signed-tag >actual &&
@@ -856,7 +856,7 @@ Another line.
Last line.
EOF
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with a -F file with #comments should succeed' '
git tag -s -F sigcommentsfile comments-signed-tag &&
get_tag_msg comments-signed-tag >actual &&
@@ -866,7 +866,7 @@ test_expect_success \
get_tag_header comment-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with #commented -m message should succeed' '
git tag -s -m "#comment" comment-signed-tag &&
get_tag_msg comment-signed-tag >actual &&
@@ -879,7 +879,7 @@ echo '' >>sigcommentfile
echo '####' >>sigcommentfile
get_tag_header commentfile-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with #commented -F messagefile should succeed' '
git tag -s -F sigcommentfile commentfile-signed-tag &&
get_tag_msg commentfile-signed-tag >actual &&
@@ -890,7 +890,7 @@ test_expect_success \
printf '#comment' >sigcommentnonlfile
get_tag_header commentnonlfile-signed-tag $commit commit $time >expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag with a #comment and no newline should succeed' '
git tag -s -F sigcommentnonlfile commentnonlfile-signed-tag &&
get_tag_msg commentnonlfile-signed-tag >actual &&
@@ -900,7 +900,7 @@ test_expect_success \
# listing messages for signed tags:
-test_expect_success \
+test_expect_success GPG \
'listing the one-line message of a signed tag should succeed' '
git tag -s -m "A message line signed" stag-one-line &&
@@ -925,7 +925,7 @@ test_expect_success \
test_cmp expect actual
'
-test_expect_success \
+test_expect_success GPG \
'listing the zero-lines message of a signed tag should succeed' '
git tag -s -m "" stag-zero-lines &&
@@ -953,7 +953,7 @@ test_expect_success \
echo 'stag line one' >sigtagmsg
echo 'stag line two' >>sigtagmsg
echo 'stag line three' >>sigtagmsg
-test_expect_success \
+test_expect_success GPG \
'listing many message lines of a signed tag should succeed' '
git tag -s -F sigtagmsg stag-lines &&
@@ -998,12 +998,12 @@ test_expect_success \
tree=$(git rev-parse HEAD^{tree})
blob=$(git rev-parse HEAD:foo)
-tag=$(git rev-parse signed-tag)
+tag=$(git rev-parse signed-tag 2>/dev/null)
get_tag_header tree-signed-tag $tree tree $time >expect
echo "A message for a tree" >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag pointing to a tree should succeed' '
git tag -s -m "A message for a tree" tree-signed-tag HEAD^{tree} &&
get_tag_msg tree-signed-tag >actual &&
@@ -1013,7 +1013,7 @@ test_expect_success \
get_tag_header blob-signed-tag $blob blob $time >expect
echo "A message for a blob" >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag pointing to a blob should succeed' '
git tag -s -m "A message for a blob" blob-signed-tag HEAD:foo &&
get_tag_msg blob-signed-tag >actual &&
@@ -1023,7 +1023,7 @@ test_expect_success \
get_tag_header tag-signed-tag $tag tag $time >expect
echo "A message for another tag" >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
-test_expect_success \
+test_expect_success GPG \
'creating a signed tag pointing to another tag should succeed' '
git tag -s -m "A message for another tag" tag-signed-tag signed-tag &&
get_tag_msg tag-signed-tag >actual &&
@@ -1032,7 +1032,7 @@ test_expect_success \
# try to sign with bad user.signingkey
git config user.signingkey BobTheMouse
-test_expect_success \
+test_expect_success GPG \
'git tag -s fails if gpg is misconfigured' \
'test_must_fail git tag -s -m tail tag-gpg-failure'
git config --unset user.signingkey
@@ -1040,7 +1040,7 @@ git config --unset user.signingkey
# try to verify without gpg:
rm -rf gpghome
-test_expect_success \
+test_expect_success GPG \
'verify signed tag fails when public key is not present' \
'test_must_fail git tag -v signed-tag'
@@ -1090,6 +1090,121 @@ test_expect_success 'filename for the message is relative to cwd' '
git cat-file tag tag-from-subdir-2 | grep "in sub directory"
'
+# create a few more commits to test --contains
+
+hash1=$(git rev-parse HEAD)
+
+test_expect_success 'creating second commit and tag' '
+ echo foo-2.0 >foo &&
+ git add foo &&
+ git commit -m second
+ git tag v2.0
+'
+
+hash2=$(git rev-parse HEAD)
+
+test_expect_success 'creating third commit without tag' '
+ echo foo-dev >foo &&
+ git add foo &&
+ git commit -m third
+'
+
+hash3=$(git rev-parse HEAD)
+
+# simple linear checks of --continue
+
+cat > expected <<EOF
+v0.2.1
+v1.0
+v1.0.1
+v1.1.3
+v2.0
+EOF
+
+test_expect_success 'checking that first commit is in all tags (hash)' "
+ git tag -l --contains $hash1 v* >actual
+ test_cmp expected actual
+"
+
+# other ways of specifying the commit
+test_expect_success 'checking that first commit is in all tags (tag)' "
+ git tag -l --contains v1.0 v* >actual
+ test_cmp expected actual
+"
+
+test_expect_success 'checking that first commit is in all tags (relative)' "
+ git tag -l --contains HEAD~2 v* >actual
+ test_cmp expected actual
+"
+
+cat > expected <<EOF
+v2.0
+EOF
+
+test_expect_success 'checking that second commit only has one tag' "
+ git tag -l --contains $hash2 v* >actual
+ test_cmp expected actual
+"
+
+
+cat > expected <<EOF
+EOF
+
+test_expect_success 'checking that third commit has no tags' "
+ git tag -l --contains $hash3 v* >actual
+ test_cmp expected actual
+"
+
+# how about a simple merge?
+
+test_expect_success 'creating simple branch' '
+ git branch stable v2.0 &&
+ git checkout stable &&
+ echo foo-3.0 > foo &&
+ git commit foo -m fourth
+ git tag v3.0
+'
+
+hash4=$(git rev-parse HEAD)
+
+cat > expected <<EOF
+v3.0
+EOF
+
+test_expect_success 'checking that branch head only has one tag' "
+ git tag -l --contains $hash4 v* >actual
+ test_cmp expected actual
+"
+
+test_expect_success 'merging original branch into this branch' '
+ git merge --strategy=ours master &&
+ git tag v4.0
+'
+
+cat > expected <<EOF
+v4.0
+EOF
+
+test_expect_success 'checking that original branch head has one tag now' "
+ git tag -l --contains $hash3 v* >actual
+ test_cmp expected actual
+"
+
+cat > expected <<EOF
+v0.2.1
+v1.0
+v1.0.1
+v1.1.3
+v2.0
+v3.0
+v4.0
+EOF
+
+test_expect_success 'checking that initial commit is in all tags' "
+ git tag -l --contains $hash1 v* >actual
+ test_cmp expected actual
+"
+
# mixing modes and options:
test_expect_success 'mixing incompatibles modes and options is forbidden' '
diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh
index 2d919d69ef..b647957d75 100755
--- a/t/t7005-editor.sh
+++ b/t/t7005-editor.sh
@@ -7,6 +7,7 @@ test_description='GIT_EDITOR, core.editor, and stuff'
for i in GIT_EDITOR core_editor EDITOR VISUAL vi
do
cat >e-$i.sh <<-EOF
+ #!$SHELL_PATH
echo "Edited by $i" >"\$1"
EOF
chmod +x e-$i.sh
@@ -87,30 +88,26 @@ do
'
done
+if ! echo 'echo space > "$1"' > "e space.sh"
+then
+ say "Skipping; FS does not support spaces in filenames"
+ test_done
+fi
+
test_expect_success 'editor with a space' '
- if echo "echo space > \"\$1\"" > "e space.sh"
- then
- chmod a+x "e space.sh" &&
- GIT_EDITOR="./e\ space.sh" git commit --amend &&
- test space = "$(git show -s --pretty=format:%s)"
- else
- say "Skipping; FS does not support spaces in filenames"
- fi
+ chmod a+x "e space.sh" &&
+ GIT_EDITOR="./e\ space.sh" git commit --amend &&
+ test space = "$(git show -s --pretty=format:%s)"
'
unset GIT_EDITOR
test_expect_success 'core.editor with a space' '
- if test -f "e space.sh"
- then
- git config core.editor \"./e\ space.sh\" &&
- git commit --amend &&
- test space = "$(git show -s --pretty=format:%s)"
- else
- say "Skipping; FS does not support spaces in filenames"
- fi
+ git config core.editor \"./e\ space.sh\" &&
+ git commit --amend &&
+ test space = "$(git show -s --pretty=format:%s)"
'
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 0e21632f19..ebfd34df36 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -171,7 +171,7 @@ test_expect_success 'checkout to detach HEAD' '
git checkout -f renamer && git clean -f &&
git checkout renamer^ 2>messages &&
(cat >messages.expect <<EOF
-Note: moving to "renamer^" which isn'"'"'t a local branch
+Note: moving to '\''renamer^'\'' which isn'\''t a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
git checkout -b <new_branch_name>
@@ -534,4 +534,12 @@ test_expect_success 'failing checkout -b should not break working tree' '
'
+test_expect_success 'switch out of non-branch' '
+ git reset --hard master &&
+ git checkout master^0 &&
+ echo modified >one &&
+ test_must_fail git checkout renamer 2>error.log &&
+ ! grep "^Previous HEAD" error.log
+'
+
test_done
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 1636fac2a4..929d5d4d3b 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -373,9 +373,9 @@ test_expect_success 'removal failure' '
mkdir foo &&
touch foo/bar &&
- exec <foo/bar &&
- chmod 0 foo &&
- test_must_fail git clean -f -d
+ (exec <foo/bar &&
+ chmod 0 foo &&
+ test_must_fail git clean -f -d)
'
chmod 755 foo
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 2ec7ac6a51..0f2ccc6cf0 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -47,6 +47,65 @@ test_expect_success 'Prepare submodule testing' '
GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/init.git
'
+test_expect_success 'Prepare submodule add testing' '
+ submodurl=$(pwd)
+ (
+ mkdir addtest &&
+ cd addtest &&
+ git init
+ )
+'
+
+test_expect_success 'submodule add' '
+ (
+ cd addtest &&
+ git submodule add "$submodurl" submod &&
+ git submodule init
+ )
+'
+
+test_expect_success 'submodule add --branch' '
+ (
+ cd addtest &&
+ git submodule add -b initial "$submodurl" submod-branch &&
+ git submodule init &&
+ cd submod-branch &&
+ git branch | grep initial
+ )
+'
+
+test_expect_success 'submodule add with ./ in path' '
+ (
+ cd addtest &&
+ git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
+ git submodule init
+ )
+'
+
+test_expect_success 'submodule add with // in path' '
+ (
+ cd addtest &&
+ git submodule add "$submodurl" slashslashsubmod///frotz// &&
+ git submodule init
+ )
+'
+
+test_expect_success 'submodule add with /.. in path' '
+ (
+ cd addtest &&
+ git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
+ git submodule init
+ )
+'
+
+test_expect_success 'submodule add with ./, /.. and // in path' '
+ (
+ cd addtest &&
+ git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
+ git submodule init
+ )
+'
+
test_expect_success 'status should fail for unmapped paths' '
if git submodule status
then
@@ -234,4 +293,17 @@ test_expect_success 'gracefully add submodule with a trailing slash' '
'
+test_expect_success 'ls-files gracefully handles trailing slash' '
+
+ test "init" = "$(git ls-files init/)"
+
+'
+
+test_expect_success 'submodule <invalid-path> warns' '
+
+ git submodule no-such-submodule 2> output.err &&
+ grep "^error: .*no-such-submodule" output.err
+
+'
+
test_done
diff --git a/t/t7405-submodule-merge.sh b/t/t7405-submodule-merge.sh
new file mode 100755
index 0000000000..9a21f783d3
--- /dev/null
+++ b/t/t7405-submodule-merge.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+test_description='merging with submodules'
+
+. ./test-lib.sh
+
+#
+# history
+#
+# a --- c
+# / \ /
+# root X
+# \ / \
+# b --- d
+#
+
+test_expect_success setup '
+
+ mkdir sub &&
+ (cd sub &&
+ git init &&
+ echo original > file &&
+ git add file &&
+ test_tick &&
+ git commit -m sub-root) &&
+ git add sub &&
+ test_tick &&
+ git commit -m root &&
+
+ git checkout -b a master &&
+ (cd sub &&
+ echo A > file &&
+ git add file &&
+ test_tick &&
+ git commit -m sub-a) &&
+ git add sub &&
+ test_tick &&
+ git commit -m a &&
+
+ git checkout -b b master &&
+ (cd sub &&
+ echo B > file &&
+ git add file &&
+ test_tick &&
+ git commit -m sub-b) &&
+ git add sub &&
+ test_tick &&
+ git commit -m b
+
+ git checkout -b c a &&
+ git merge -s ours b &&
+
+ git checkout -b d b &&
+ git merge -s ours a
+'
+
+test_expect_success 'merging with modify/modify conflict' '
+
+ git checkout -b test1 a &&
+ test_must_fail git merge b &&
+ test -f .git/MERGE_MSG &&
+ git diff &&
+ test -n "$(git ls-files -u)"
+'
+
+test_expect_success 'merging with a modify/modify conflict between merge bases' '
+
+ git reset --hard HEAD &&
+ git checkout -b test2 c &&
+ git merge d
+
+'
+
+test_done
diff --git a/t/t7406-submodule-reference.sh b/t/t7406-submodule-reference.sh
new file mode 100755
index 0000000000..cc16d3f05d
--- /dev/null
+++ b/t/t7406-submodule-reference.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+#
+# Copyright (c) 2009, Red Hat Inc, Author: Michael S. Tsirkin (mst@redhat.com)
+#
+
+test_description='test clone --reference'
+. ./test-lib.sh
+
+base_dir=`pwd`
+
+U=$base_dir/UPLOAD_LOG
+
+test_expect_success 'preparing first repository' \
+'test_create_repo A && cd A &&
+echo first > file1 &&
+git add file1 &&
+git commit -m A-initial'
+
+cd "$base_dir"
+
+test_expect_success 'preparing second repository' \
+'git clone A B && cd B &&
+echo second > file2 &&
+git add file2 &&
+git commit -m B-addition &&
+git repack -a -d &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'preparing supermodule' \
+'test_create_repo super && cd super &&
+echo file > file &&
+git add file &&
+git commit -m B-super-initial'
+
+cd "$base_dir"
+
+test_expect_success 'submodule add --reference' \
+'cd super && git submodule add --reference ../B "file://$base_dir/A" sub &&
+git commit -m B-super-added'
+
+cd "$base_dir"
+
+test_expect_success 'after add: existence of info/alternates' \
+'test `wc -l <super/sub/.git/objects/info/alternates` = 1'
+
+cd "$base_dir"
+
+test_expect_success 'that reference gets used with add' \
+'cd super/sub &&
+echo "0 objects, 0 kilobytes" > expected &&
+git count-objects > current &&
+diff expected current'
+
+cd "$base_dir"
+
+test_expect_success 'cloning supermodule' \
+'git clone super super-clone'
+
+cd "$base_dir"
+
+test_expect_success 'update with reference' \
+'cd super-clone && git submodule update --init --reference ../B'
+
+cd "$base_dir"
+
+test_expect_success 'after update: existence of info/alternates' \
+'test `wc -l <super-clone/sub/.git/objects/info/alternates` = 1'
+
+cd "$base_dir"
+
+test_expect_success 'that reference gets used with update' \
+'cd super-clone/sub &&
+echo "0 objects, 0 kilobytes" > expected &&
+git count-objects > current &&
+diff expected current'
+
+cd "$base_dir"
+
+test_done
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
new file mode 100755
index 0000000000..2d33d9efec
--- /dev/null
+++ b/t/t7406-submodule-update.sh
@@ -0,0 +1,198 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Red Hat, Inc.
+#
+
+test_description='Test updating submodules
+
+This test verifies that "git submodule update" detaches the HEAD of the
+submodule and "git submodule update --rebase/--merge" does not detach the HEAD.
+'
+
+. ./test-lib.sh
+
+
+compare_head()
+{
+ sha_master=`git-rev-list --max-count=1 master`
+ sha_head=`git-rev-list --max-count=1 HEAD`
+
+ test "$sha_master" = "$sha_head"
+}
+
+
+test_expect_success 'setup a submodule tree' '
+ echo file > file &&
+ git add file &&
+ test_tick &&
+ git commit -m upstream
+ git clone . super &&
+ git clone super submodule &&
+ (cd super &&
+ git submodule add ../submodule submodule &&
+ test_tick &&
+ git commit -m "submodule" &&
+ git submodule init submodule
+ ) &&
+ (cd submodule &&
+ echo "line2" > file &&
+ git add file &&
+ git commit -m "Commit 2"
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ git pull --rebase origin
+ ) &&
+ git add submodule &&
+ git commit -m "submodule update"
+ )
+'
+
+test_expect_success 'submodule update detaching the HEAD ' '
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update submodule &&
+ cd submodule &&
+ ! compare_head
+ )
+'
+
+test_expect_success 'submodule update --rebase staying on master' '
+ (cd super/submodule &&
+ git checkout master
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update --rebase submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
+test_expect_success 'submodule update --merge staying on master' '
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update --merge submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
+test_expect_success 'submodule update - rebase in .git/config' '
+ (cd super &&
+ git config submodule.submodule.update rebase
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
+test_expect_success 'submodule update - checkout in .git/config but --rebase given' '
+ (cd super &&
+ git config submodule.submodule.update checkout
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update --rebase submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
+test_expect_success 'submodule update - merge in .git/config' '
+ (cd super &&
+ git config submodule.submodule.update merge
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
+test_expect_success 'submodule update - checkout in .git/config but --merge given' '
+ (cd super &&
+ git config submodule.submodule.update checkout
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update --merge submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
+test_expect_success 'submodule update - checkout in .git/config' '
+ (cd super &&
+ git config submodule.submodule.update checkout
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD^
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update submodule &&
+ cd submodule &&
+ ! compare_head
+ )
+'
+
+test_expect_success 'submodule init picks up rebase' '
+ (cd super &&
+ git config submodule.rebasing.url git://non-existing/git &&
+ git config submodule.rebasing.path does-not-matter &&
+ git config submodule.rebasing.update rebase &&
+ git submodule init rebasing &&
+ test "rebase" = $(git config submodule.rebasing.update)
+ )
+'
+
+test_expect_success 'submodule init picks up merge' '
+ (cd super &&
+ git config submodule.merging.url git://non-existing/git &&
+ git config submodule.merging.path does-not-matter &&
+ git config submodule.merging.update merge &&
+ git submodule init merging &&
+ test "merge" = $(git config submodule.merging.update)
+ )
+'
+
+test_done
diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh
index 6e18a96319..8eec0fa9bc 100755
--- a/t/t7500-commit.sh
+++ b/t/t7500-commit.sh
@@ -149,10 +149,7 @@ EOF
test_expect_success '--signoff' '
echo "yet another content *narf*" >> foo &&
- echo "zort" | (
- test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
- git commit -s -F - foo
- ) &&
+ echo "zort" | git commit -s -F - foo &&
git cat-file commit HEAD | sed "1,/^$/d" > output &&
test_cmp expect output
'
@@ -186,4 +183,14 @@ test_expect_success 'commit message from stdin' '
commit_msg_is "Log with foo word"
'
+test_expect_success 'commit -F overrides -t' '
+ (
+ cd subdir &&
+ echo "-F log" > f.log &&
+ echo "-t template" > t.template &&
+ git commit --allow-empty -F f.log -t t.template
+ ) &&
+ commit_msg_is "-F log"
+'
+
test_done
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index 63bfc6d8b3..e2ef53228e 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -38,7 +38,7 @@ test_expect_success \
"echo King of the bongo >file &&
test_must_fail git commit -m foo -a file"
-test_expect_success \
+test_expect_success PERL \
"using paths with --interactive" \
"echo bong-o-bong >file &&
! (echo 7 | git commit -m foo --interactive file)"
@@ -119,7 +119,7 @@ test_expect_success \
"echo 'gak' >file && \
git commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a"
-test_expect_success \
+test_expect_success PERL \
"interactive add" \
"echo 7 | git commit --interactive | grep 'What now'"
@@ -127,6 +127,26 @@ test_expect_success \
"showing committed revisions" \
"git rev-list HEAD >current"
+cat >editor <<\EOF
+#!/bin/sh
+sed -e "s/good/bad/g" < "$1" > "$1-"
+mv "$1-" "$1"
+EOF
+chmod 755 editor
+
+cat >msg <<EOF
+A good commit message.
+EOF
+
+test_expect_success \
+ 'editor not invoked if -F is given' '
+ echo "moo" >file &&
+ VISUAL=./editor git commit -a -F msg &&
+ git show -s --pretty=format:"%s" | grep -q good &&
+ echo "quack" >file &&
+ echo "Another good message." | VISUAL=./editor git commit -a -F - &&
+ git show -s --pretty=format:"%s" | grep -q good
+ '
# We could just check the head sha1, but checking each commit makes it
# easier to isolate bugs.
diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh
index ad42c78d7c..56cd866019 100755
--- a/t/t7502-commit.sh
+++ b/t/t7502-commit.sh
@@ -234,7 +234,7 @@ cat >.git/FAKE_EDITOR <<EOF
# kill -TERM command added below.
EOF
-test_expect_success 'a SIGTERM should break locks' '
+test_expect_success EXECKEEPSPID 'a SIGTERM should break locks' '
echo >>negative &&
! "$SHELL_PATH" -c '\''
echo kill -TERM $$ >> .git/FAKE_EDITOR
diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-hook.sh
index b069095995..8528f64c8d 100755
--- a/t/t7503-pre-commit-hook.sh
+++ b/t/t7503-pre-commit-hook.sh
@@ -69,7 +69,7 @@ test_expect_success '--no-verify with failing hook' '
'
chmod -x "$HOOK"
-test_expect_success 'with non-executable hook' '
+test_expect_success POSIXPERM 'with non-executable hook' '
echo "content" >> file &&
git add file &&
@@ -77,7 +77,7 @@ test_expect_success 'with non-executable hook' '
'
-test_expect_success '--no-verify with non-executable hook' '
+test_expect_success POSIXPERM '--no-verify with non-executable hook' '
echo "more content" >> file &&
git add file &&
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index 47680e6df4..1f53ea8090 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -136,7 +136,7 @@ test_expect_success '--no-verify with failing hook (editor)' '
'
chmod -x "$HOOK"
-test_expect_success 'with non-executable hook' '
+test_expect_success POSIXPERM 'with non-executable hook' '
echo "content" >> file &&
git add file &&
@@ -144,7 +144,7 @@ test_expect_success 'with non-executable hook' '
'
-test_expect_success 'with non-executable hook (editor)' '
+test_expect_success POSIXPERM 'with non-executable hook (editor)' '
echo "content again" >> file &&
git add file &&
@@ -153,7 +153,7 @@ test_expect_success 'with non-executable hook (editor)' '
'
-test_expect_success '--no-verify with non-executable hook' '
+test_expect_success POSIXPERM '--no-verify with non-executable hook' '
echo "more content" >> file &&
git add file &&
@@ -161,7 +161,7 @@ test_expect_success '--no-verify with non-executable hook' '
'
-test_expect_success '--no-verify with non-executable hook (editor)' '
+test_expect_success POSIXPERM '--no-verify with non-executable hook (editor)' '
echo "even more content" >> file &&
git add file &&
diff --git a/t/t7502-status.sh b/t/t7508-status.sh
index 93f875f500..93f875f500 100755
--- a/t/t7502-status.sh
+++ b/t/t7508-status.sh
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index 09fa5f115c..e768c3eb2d 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -9,38 +9,81 @@ Testing basic merge tool invocation'
. ./test-lib.sh
+# All the mergetool test work by checking out a temporary branch based
+# off 'branch1' and then merging in master and checking the results of
+# running mergetool
+
test_expect_success 'setup' '
echo master >file1 &&
- git add file1 &&
+ mkdir subdir &&
+ echo master sub >subdir/file3 &&
+ git add file1 subdir/file3 &&
git commit -m "added file1" &&
+
git checkout -b branch1 master &&
echo branch1 change >file1 &&
echo branch1 newfile >file2 &&
- git add file1 file2 &&
+ echo branch1 sub >subdir/file3 &&
+ git add file1 file2 subdir/file3 &&
git commit -m "branch1 changes" &&
- git checkout -b branch2 master &&
- echo branch2 change >file1 &&
- echo branch2 newfile >file2 &&
- git add file1 file2 &&
- git commit -m "branch2 changes" &&
+
git checkout master &&
echo master updated >file1 &&
echo master new >file2 &&
- git add file1 file2 &&
- git commit -m "master updates"
-'
+ echo master new sub >subdir/file3 &&
+ git add file1 file2 subdir/file3 &&
+ git commit -m "master updates" &&
-test_expect_success 'custom mergetool' '
git config merge.tool mytool &&
git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
- git config mergetool.mytool.trustExitCode true &&
- git checkout branch1 &&
+ git config mergetool.mytool.trustExitCode true
+'
+
+test_expect_success 'custom mergetool' '
+ git checkout -b test1 branch1 &&
test_must_fail git merge master >/dev/null 2>&1 &&
- ( yes "" | git mergetool file1>/dev/null 2>&1 ) &&
- ( yes "" | git mergetool file2>/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
test "$(cat file1)" = "master updated" &&
test "$(cat file2)" = "master new" &&
- git commit -m "branch1 resolved with mergetool"
+ test "$(cat subdir/file3)" = "master new sub" &&
+ git commit -m "branch1 resolved with mergetool"
'
+test_expect_success 'mergetool crlf' '
+ git config core.autocrlf true &&
+ git checkout -b test2 branch1
+ test_must_fail git merge master >/dev/null 2>&1 &&
+ ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
+ test "$(printf x | cat file1 -)" = "$(printf "master updated\r\nx")" &&
+ test "$(printf x | cat file2 -)" = "$(printf "master new\r\nx")" &&
+ test "$(printf x | cat subdir/file3 -)" = "$(printf "master new sub\r\nx")" &&
+ git commit -m "branch1 resolved with mergetool - autocrlf" &&
+ git config core.autocrlf false &&
+ git reset --hard
+'
+
+test_expect_success 'mergetool in subdir' '
+ git checkout -b test3 branch1
+ cd subdir && (
+ test_must_fail git merge master >/dev/null 2>&1 &&
+ ( yes "" | git mergetool file3 >/dev/null 2>&1 ) &&
+ test "$(cat file3)" = "master new sub" )
+'
+
+# We can't merge files from parent directories when running mergetool
+# from a subdir. Is this a bug?
+#
+#test_expect_failure 'mergetool in subdir' '
+# cd subdir && (
+# ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
+# ( yes "" | git mergetool ../file2 >/dev/null 2>&1 ) &&
+# test "$(cat ../file1)" = "master updated" &&
+# test "$(cat ../file2)" = "master new" &&
+# git commit -m "branch1 resolved with mergetool - subdir" )
+#'
+
test_done
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 9ce546e3b2..f4aa054750 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -69,6 +69,25 @@ test_expect_success 'packed obs in alt ODB are repacked even when local repo is
done
'
+test_expect_success 'packed obs in alt ODB are repacked when local repo has packs' '
+ rm -f .git/objects/pack/* &&
+ echo new_content >> file1 &&
+ git add file1 &&
+ git commit -m more_content &&
+ git repack &&
+ git repack -a -d &&
+ myidx=$(ls -1 .git/objects/pack/*.idx) &&
+ test -f "$myidx" &&
+ for p in alt_objects/pack/*.idx; do
+ git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
+ done | while read sha1 rest; do
+ if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
+ echo "Missing object in local pack: $sha1"
+ return 1
+ fi
+ done
+'
+
test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
# swap the .keep so the commit object is in the pack with .keep
for p in alt_objects/pack/*.pack
@@ -130,5 +149,17 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar
test_must_fail git show $csha1
'
+test_expect_success 'objects made unreachable by grafts only are kept' '
+ test_tick &&
+ git commit --allow-empty -m "commit 4" &&
+ H0=$(git rev-parse HEAD) &&
+ H1=$(git rev-parse HEAD^) &&
+ H2=$(git rev-parse HEAD^^) &&
+ echo "$H0 $H2" > .git/info/grafts &&
+ git reflog expire --expire=now --expire-unreachable=now --all &&
+ git repack -a -d &&
+ git cat-file -t $H1
+ '
+
test_done
diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh
index 63a8225ae5..5babdf26e6 100755
--- a/t/t7701-repack-unpack-unreachable.sh
+++ b/t/t7701-repack-unpack-unreachable.sh
@@ -50,12 +50,10 @@ test_expect_success '-A with -d option leaves unreachable objects unpacked' '
compare_mtimes ()
{
- perl -e 'my $reference = shift;
- foreach my $file (@ARGV) {
- exit(1) unless(-f $file && -M $file == -M $reference);
- }
- exit(0);
- ' -- "$@"
+ read tref rest &&
+ while read t rest; do
+ test "$tref" = "$t" || break
+ done
}
test_expect_success '-A without -d option leaves unreachable objects packed' '
@@ -87,7 +85,9 @@ test_expect_success 'unpacked objects receive timestamp of pack file' '
tmppack=".git/objects/pack/tmp_pack" &&
ln "$packfile" "$tmppack" &&
git repack -A -l -d &&
- compare_mtimes "$tmppack" "$fsha1path" "$csha1path" "$tsha1path"
+ test-chmtime -v +0 "$tmppack" "$fsha1path" "$csha1path" "$tsha1path" \
+ > mtimes &&
+ compare_mtimes < mtimes
'
test_done
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
new file mode 100755
index 0000000000..ebdccf9a1e
--- /dev/null
+++ b/t/t7800-difftool.sh
@@ -0,0 +1,216 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 David Aguilar
+#
+
+test_description='git-difftool
+
+Testing basic diff tool invocation
+'
+
+. ./test-lib.sh
+
+if ! test_have_prereq PERL; then
+ say 'skipping difftool tests, perl not available'
+ test_done
+fi
+
+remove_config_vars()
+{
+ # Unset all config variables used by git-difftool
+ git config --unset diff.tool
+ git config --unset difftool.test-tool.cmd
+ git config --unset difftool.prompt
+ git config --unset merge.tool
+ git config --unset mergetool.test-tool.cmd
+ return 0
+}
+
+restore_test_defaults()
+{
+ # Restores the test defaults used by several tests
+ remove_config_vars
+ unset GIT_DIFF_TOOL
+ unset GIT_MERGE_TOOL
+ unset GIT_DIFFTOOL_PROMPT
+ unset GIT_DIFFTOOL_NO_PROMPT
+ git config diff.tool test-tool &&
+ git config difftool.test-tool.cmd 'cat $LOCAL'
+}
+
+prompt_given()
+{
+ prompt="$1"
+ test "$prompt" = "Hit return to launch 'test-tool': branch"
+}
+
+# Create a file on master and change it on branch
+test_expect_success 'setup' '
+ echo master >file &&
+ git add file &&
+ git commit -m "added file" &&
+
+ git checkout -b branch master &&
+ echo branch >file &&
+ git commit -a -m "branch changed file" &&
+ git checkout master
+'
+
+# Configure a custom difftool.<tool>.cmd and use it
+test_expect_success 'custom commands' '
+ restore_test_defaults &&
+ git config difftool.test-tool.cmd "cat \$REMOTE" &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "master" &&
+
+ restore_test_defaults &&
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch"
+'
+
+# Ensures that git-difftool ignores bogus --tool values
+test_expect_success 'difftool ignores bad --tool values' '
+ diff=$(git difftool --no-prompt --tool=bogus-tool branch)
+ test "$?" = 1 &&
+ test "$diff" = ""
+'
+
+# Specify the diff tool using $GIT_DIFF_TOOL
+test_expect_success 'GIT_DIFF_TOOL variable' '
+ git config --unset diff.tool
+ GIT_DIFF_TOOL=test-tool &&
+ export GIT_DIFF_TOOL &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test the $GIT_*_TOOL variables and ensure
+# that $GIT_DIFF_TOOL always wins unless --tool is specified
+test_expect_success 'GIT_DIFF_TOOL overrides' '
+ git config diff.tool bogus-tool &&
+ git config merge.tool bogus-tool &&
+
+ GIT_MERGE_TOOL=test-tool &&
+ export GIT_MERGE_TOOL &&
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+ unset GIT_MERGE_TOOL &&
+
+ GIT_MERGE_TOOL=bogus-tool &&
+ GIT_DIFF_TOOL=test-tool &&
+ export GIT_MERGE_TOOL &&
+ export GIT_DIFF_TOOL &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ GIT_DIFF_TOOL=bogus-tool &&
+ export GIT_DIFF_TOOL &&
+
+ diff=$(git difftool --no-prompt --tool=test-tool branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test that we don't have to pass --no-prompt to difftool
+# when $GIT_DIFFTOOL_NO_PROMPT is true
+test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '
+ GIT_DIFFTOOL_NO_PROMPT=true &&
+ export GIT_DIFFTOOL_NO_PROMPT &&
+
+ diff=$(git difftool branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# git-difftool supports the difftool.prompt variable.
+# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
+test_expect_success 'GIT_DIFFTOOL_PROMPT variable' '
+ git config difftool.prompt false &&
+ GIT_DIFFTOOL_PROMPT=true &&
+ export GIT_DIFFTOOL_PROMPT &&
+
+ prompt=$(echo | git difftool --prompt branch | tail -1) &&
+ prompt_given "$prompt" &&
+
+ restore_test_defaults
+'
+
+# Test that we don't have to pass --no-prompt when difftool.prompt is false
+test_expect_success 'difftool.prompt config variable is false' '
+ git config difftool.prompt false &&
+
+ diff=$(git difftool branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test that the -y flag can override difftool.prompt = true
+test_expect_success 'difftool.prompt can overridden with -y' '
+ git config difftool.prompt true &&
+
+ diff=$(git difftool -y branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+# Test that the --prompt flag can override difftool.prompt = false
+test_expect_success 'difftool.prompt can overridden with --prompt' '
+ git config difftool.prompt false &&
+
+ prompt=$(echo | git difftool --prompt branch | tail -1) &&
+ prompt_given "$prompt" &&
+
+ restore_test_defaults
+'
+
+# Test that the last flag passed on the command-line wins
+test_expect_success 'difftool last flag wins' '
+ diff=$(git difftool --prompt --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults &&
+
+ prompt=$(echo | git difftool --no-prompt --prompt branch | tail -1) &&
+ prompt_given "$prompt" &&
+
+ restore_test_defaults
+'
+
+# git-difftool falls back to git-mergetool config variables
+# so test that behavior here
+test_expect_success 'difftool + mergetool config variables' '
+ remove_config_vars
+ git config merge.tool test-tool &&
+ git config mergetool.test-tool.cmd "cat \$LOCAL" &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ # set merge.tool to something bogus, diff.tool to test-tool
+ git config merge.tool bogus-tool &&
+ git config diff.tool test-tool &&
+
+ diff=$(git difftool --no-prompt branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
+test_expect_success 'difftool.<tool>.path' '
+ git config difftool.tkdiff.path echo &&
+ diff=$(git difftool --tool=tkdiff --no-prompt branch) &&
+ git config --unset difftool.tkdiff.path &&
+ lines=$(echo "$diff" | grep file | wc -l) &&
+ test "$lines" -eq 1
+'
+
+test_done
diff --git a/t/t8003-blame.sh b/t/t8003-blame.sh
index 966bb0a61a..13c25f1d52 100755
--- a/t/t8003-blame.sh
+++ b/t/t8003-blame.sh
@@ -129,4 +129,19 @@ test_expect_success 'blame wholesale copy and more' '
'
+test_expect_success 'blame path that used to be a directory' '
+ mkdir path &&
+ echo A A A A A >path/file &&
+ echo B B B B B >path/elif &&
+ git add path &&
+ test_tick &&
+ git commit -m "path was a directory" &&
+ rm -fr path &&
+ echo A A A A A >path &&
+ git add path &&
+ test_tick &&
+ git commit -m "path is a regular file" &&
+ git blame HEAD^.. -- path
+'
+
test_done
diff --git a/t/t8005-blame-i18n.sh b/t/t8005-blame-i18n.sh
index 4470a92bb2..cb390559f9 100755
--- a/t/t8005-blame-i18n.sh
+++ b/t/t8005-blame-i18n.sh
@@ -4,7 +4,7 @@ test_description='git blame encoding conversion'
. ./test-lib.sh
. "$TEST_DIRECTORY"/t8005/utf8.txt
-. "$TEST_DIRECTORY"/t8005/cp1251.txt
+. "$TEST_DIRECTORY"/t8005/euc-japan.txt
. "$TEST_DIRECTORY"/t8005/sjis.txt
test_expect_success 'setup the repository' '
@@ -13,14 +13,14 @@ test_expect_success 'setup the repository' '
git add file &&
git commit --author "$UTF8_NAME <utf8@localhost>" -m "$UTF8_MSG" &&
- echo "CP1251 LINE" >> file &&
+ echo "EUC-JAPAN LINE" >> file &&
git add file &&
- git config i18n.commitencoding cp1251 &&
- git commit --author "$CP1251_NAME <cp1251@localhost>" -m "$CP1251_MSG" &&
+ git config i18n.commitencoding eucJP &&
+ git commit --author "$EUC_JAPAN_NAME <euc-japan@localhost>" -m "$EUC_JAPAN_MSG" &&
echo "SJIS LINE" >> file &&
git add file &&
- git config i18n.commitencoding shift-jis &&
+ git config i18n.commitencoding SJIS &&
git commit --author "$SJIS_NAME <sjis@localhost>" -m "$SJIS_MSG"
'
@@ -36,24 +36,24 @@ EOF
test_expect_success \
'blame respects i18n.commitencoding' '
git blame --incremental file | \
- grep "^\(author\|summary\) " > actual &&
+ egrep "^(author|summary) " > actual &&
test_cmp actual expected
'
cat >expected <<EOF
-author $CP1251_NAME
-summary $CP1251_MSG
-author $CP1251_NAME
-summary $CP1251_MSG
-author $CP1251_NAME
-summary $CP1251_MSG
+author $EUC_JAPAN_NAME
+summary $EUC_JAPAN_MSG
+author $EUC_JAPAN_NAME
+summary $EUC_JAPAN_MSG
+author $EUC_JAPAN_NAME
+summary $EUC_JAPAN_MSG
EOF
test_expect_success \
'blame respects i18n.logoutputencoding' '
- git config i18n.logoutputencoding cp1251 &&
+ git config i18n.logoutputencoding eucJP &&
git blame --incremental file | \
- grep "^\(author\|summary\) " > actual &&
+ egrep "^(author|summary) " > actual &&
test_cmp actual expected
'
@@ -67,17 +67,17 @@ summary $UTF8_MSG
EOF
test_expect_success \
- 'blame respects --encoding=utf-8' '
- git blame --incremental --encoding=utf-8 file | \
- grep "^\(author\|summary\) " > actual &&
+ 'blame respects --encoding=UTF-8' '
+ git blame --incremental --encoding=UTF-8 file | \
+ egrep "^(author|summary) " > actual &&
test_cmp actual expected
'
cat >expected <<EOF
author $SJIS_NAME
summary $SJIS_MSG
-author $CP1251_NAME
-summary $CP1251_MSG
+author $EUC_JAPAN_NAME
+summary $EUC_JAPAN_MSG
author $UTF8_NAME
summary $UTF8_MSG
EOF
@@ -85,7 +85,7 @@ EOF
test_expect_success \
'blame respects --encoding=none' '
git blame --incremental --encoding=none file | \
- grep "^\(author\|summary\) " > actual &&
+ egrep "^(author|summary) " > actual &&
test_cmp actual expected
'
diff --git a/t/t8005/cp1251.txt b/t/t8005/cp1251.txt
deleted file mode 100644
index ce41e98b81..0000000000
--- a/t/t8005/cp1251.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-CP1251_NAME="Èâàí Ïåòðîâè÷ Ñèäîðîâ"
-CP1251_MSG="Òåñòîâîå ñîîáùåíèå"
diff --git a/t/t8005/euc-japan.txt b/t/t8005/euc-japan.txt
new file mode 100644
index 0000000000..288f040c99
--- /dev/null
+++ b/t/t8005/euc-japan.txt
@@ -0,0 +1,2 @@
+EUC_JAPAN_NAME="»³ÅÄ ÂÀϺ"
+EUC_JAPAN_MSG="¥Ö¥ì¡¼¥à¤Î¥Æ¥¹¥È¤Ç¤¹¡£"
diff --git a/t/t8005/iso8859-5.txt b/t/t8005/iso8859-5.txt
new file mode 100644
index 0000000000..2e4b80c8df
--- /dev/null
+++ b/t/t8005/iso8859-5.txt
@@ -0,0 +1,2 @@
+ISO8859_5_NAME="¸ÒÐÝ ¿ÕâàÞÒØç ÁØÔÞàÞÒ"
+ISO8859_5_MSG="ÂÕáâÞÒÞÕ áÞÞÑéÕÝØÕ"
diff --git a/t/t8005/sjis.txt b/t/t8005/sjis.txt
index 2ccfbad207..bbdefeaced 100644
--- a/t/t8005/sjis.txt
+++ b/t/t8005/sjis.txt
@@ -1,2 +1,2 @@
-SJIS_NAME="„I„r„p„~ „P„u„„„‚„€„r„y„‰ „R„y„t„€„‚„€„r"
-SJIS_MSG="„S„u„ƒ„„„€„r„€„u „ƒ„€„€„q„‹„u„~„y„u"
+SJIS_NAME="ŽR“c ‘¾˜Y"
+SJIS_MSG="ƒuƒŒ[ƒ€‚̃eƒXƒg‚Å‚·B"
diff --git a/t/t8005/utf8.txt b/t/t8005/utf8.txt
index f46cfc56d8..4d00dbea76 100644
--- a/t/t8005/utf8.txt
+++ b/t/t8005/utf8.txt
@@ -1,2 +1,2 @@
-UTF8_NAME="Иван Петрович Сидоров"
-UTF8_MSG="ТеÑтовое Ñообщение"
+UTF8_NAME="山田 太郎"
+UTF8_MSG="ブレームã®ãƒ†ã‚¹ãƒˆã§ã™ã€‚"
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index cb3d183770..fb606a9f05 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -3,6 +3,11 @@
test_description='git send-email'
. ./test-lib.sh
+if ! test_have_prereq PERL; then
+ say 'skipping git send-email tests, perl not available'
+ test_done
+fi
+
PROG='git send-email'
test_expect_success \
'prepare reference tree' \
@@ -32,31 +37,76 @@ clean_fake_sendmail() {
}
test_expect_success 'Extract patches' '
- patches=`git format-patch -n HEAD^1`
+ patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
+'
+
+# Test no confirm early to ensure remaining tests will not hang
+test_no_confirm () {
+ rm -f no_confirm_okay
+ echo n | \
+ GIT_SEND_EMAIL_NOTTY=1 \
+ git send-email \
+ --from="Example <from@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $@ \
+ $patches > stdout &&
+ test_must_fail grep "Send this email" stdout &&
+ > no_confirm_okay
+}
+
+# Exit immediately to prevent hang if a no-confirm test fails
+check_no_confirm () {
+ test -f no_confirm_okay || {
+ say 'No confirm test failed; skipping remaining tests to prevent hanging'
+ test_done
+ }
+}
+
+test_expect_success 'No confirm with --suppress-cc' '
+ test_no_confirm --suppress-cc=sob
+'
+check_no_confirm
+
+test_expect_success 'No confirm with --confirm=never' '
+ test_no_confirm --confirm=never
+'
+check_no_confirm
+
+# leave sendemail.confirm set to never after this so that none of the
+# remaining tests prompt unintentionally.
+test_expect_success 'No confirm with sendemail.confirm=never' '
+ git config sendemail.confirm never &&
+ test_no_confirm --compose --subject=foo
'
+check_no_confirm
test_expect_success 'Send patches' '
- git send-email --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
+ git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
'
cat >expected <<\EOF
!nobody@example.com!
!author@example.com!
+!one@example.com!
+!two@example.com!
EOF
test_expect_success \
'Verify commandline' \
- 'diff commandline1 expected'
+ 'test_cmp expected commandline1'
cat >expected-show-all-headers <<\EOF
0001-Second.patch
(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
Dry-OK. Log says:
Server: relay.example.com
MAIL FROM:<from@example.com>
-RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<bcc@example.com>
+RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<bcc@example.com>
From: Example <from@example.com>
To: to@example.com
-Cc: cc@example.com, A <author@example.com>
+Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
Subject: [PATCH 1/1] Second.
Date: DATE-STRING
Message-Id: MESSAGE-ID-STRING
@@ -70,6 +120,7 @@ EOF
test_expect_success 'Show all headers' '
git send-email \
--dry-run \
+ --suppress-cc=sob \
--from="Example <from@example.com>" \
--to=to@example.com \
--cc=cc@example.com \
@@ -84,6 +135,38 @@ test_expect_success 'Show all headers' '
test_cmp expected-show-all-headers actual-show-all-headers
'
+test_expect_success 'Prompting works' '
+ clean_fake_sendmail &&
+ (echo "Example <from@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 "^To: to@example.com$" msgtxt1
+'
+
+test_expect_success 'cccmd works' '
+ clean_fake_sendmail &&
+ cp $patches cccmd.patch &&
+ echo cccmd--cccmd@example.com >>cccmd.patch &&
+ {
+ echo "#!$SHELL_PATH"
+ echo sed -n -e s/^cccmd--//p \"\$1\"
+ } > cccmd-sed &&
+ chmod +x cccmd-sed &&
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --cc-cmd=./cccmd-sed \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ cccmd.patch \
+ &&
+ grep ^Cc:.*cccmd@example.com msgtxt1
+'
+
z8=zzzzzzzz
z64=$z8$z8$z8$z8$z8$z8$z8$z8
z512=$z64$z64$z64$z64$z64$z64$z64$z64
@@ -104,6 +187,28 @@ test_expect_success 'no patch was sent' '
! test -e commandline1
'
+test_expect_success 'Author From: in message body' '
+ clean_fake_sendmail &&
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ sed "1,/^$/d" < msgtxt1 > msgbody1
+ grep "From: A <author@example.com>" msgbody1
+'
+
+test_expect_success 'Author From: not in message body' '
+ clean_fake_sendmail &&
+ git send-email \
+ --from="A <author@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ sed "1,/^$/d" < msgtxt1 > msgbody1
+ ! grep "From: A <author@example.com>" msgbody1
+'
+
test_expect_success 'allow long lines with --no-validate' '
git send-email \
--from="Example <nobody@example.com>" \
@@ -148,15 +253,13 @@ test_set_editor "$(pwd)/fake-editor"
test_expect_success '--compose works' '
clean_fake_sendmail &&
- echo y | \
- GIT_SEND_EMAIL_NOTTY=1 \
- git send-email \
- --compose --subject foo \
- --from="Example <nobody@example.com>" \
- --to=nobody@example.com \
- --smtp-server="$(pwd)/fake.sendmail" \
- $patches \
- 2>errors
+ git send-email \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches \
+ 2>errors
'
test_expect_success 'first message is compose text' '
@@ -167,16 +270,18 @@ test_expect_success 'second message is patch' '
grep "Subject:.*Second" msgtxt2
'
-cat >expected-show-all-headers <<\EOF
+cat >expected-suppress-sob <<\EOF
0001-Second.patch
(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
Dry-OK. Log says:
Server: relay.example.com
MAIL FROM:<from@example.com>
-RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>
+RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
From: Example <from@example.com>
To: to@example.com
-Cc: cc@example.com, A <author@example.com>
+Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
Subject: [PATCH 1/1] Second.
Date: DATE-STRING
Message-Id: MESSAGE-ID-STRING
@@ -185,10 +290,10 @@ X-Mailer: X-MAILER-STRING
Result: OK
EOF
-test_expect_success 'sendemail.cc set' '
- git config sendemail.cc cc@example.com &&
+test_suppression () {
git send-email \
--dry-run \
+ --suppress-cc=$1 ${2+"--suppress-cc=$2"} \
--from="Example <from@example.com>" \
--to=to@example.com \
--smtp-server relay.example.com \
@@ -196,20 +301,27 @@ test_expect_success 'sendemail.cc set' '
sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
-e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
-e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
- >actual-show-all-headers &&
- test_cmp expected-show-all-headers actual-show-all-headers
+ >actual-suppress-$1${2+"-$2"} &&
+ test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"}
+}
+
+test_expect_success 'sendemail.cc set' '
+ git config sendemail.cc cc@example.com &&
+ test_suppression sob
'
-cat >expected-show-all-headers <<\EOF
+cat >expected-suppress-sob <<\EOF
0001-Second.patch
(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
Dry-OK. Log says:
Server: relay.example.com
MAIL FROM:<from@example.com>
-RCPT TO:<to@example.com>,<author@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
From: Example <from@example.com>
To: to@example.com
-Cc: A <author@example.com>
+Cc: A <author@example.com>, One <one@example.com>, two@example.com
Subject: [PATCH 1/1] Second.
Date: DATE-STRING
Message-Id: MESSAGE-ID-STRING
@@ -220,17 +332,281 @@ EOF
test_expect_success 'sendemail.cc unset' '
git config --unset sendemail.cc &&
+ test_suppression sob
+'
+
+cat >expected-suppress-cccmd <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+(body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success 'sendemail.cccmd' '
+ echo echo cc-cmd@example.com > cccmd &&
+ chmod +x cccmd &&
+ git config sendemail.cccmd ./cccmd &&
+ test_suppression cccmd
+'
+
+cat >expected-suppress-all <<\EOF
+0001-Second.patch
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=all' '
+ test_suppression all
+'
+
+cat >expected-suppress-body <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+(cc-cmd) Adding cc: cc-cmd@example.com from: './cccmd'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<cc-cmd@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com, cc-cmd@example.com
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=body' '
+ test_suppression body
+'
+
+cat >expected-suppress-body-cccmd <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=body --suppress-cc=cccmd' '
+ test_suppression body cccmd
+'
+
+cat >expected-suppress-sob <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=sob' '
+ git config --unset sendemail.cccmd
+ test_suppression sob
+'
+
+cat >expected-suppress-bodycc <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+(body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=bodycc' '
+ test_suppression bodycc
+'
+
+cat >expected-suppress-cc <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<committer@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, C O Mitter <committer@example.com>
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=cc' '
+ test_suppression cc
+'
+
+test_confirm () {
+ echo y | \
+ GIT_SEND_EMAIL_NOTTY=1 \
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $@ $patches > stdout &&
+ grep "Send this email" stdout
+}
+
+test_expect_success '--confirm=always' '
+ test_confirm --confirm=always --suppress-cc=all
+'
+
+test_expect_success '--confirm=auto' '
+ test_confirm --confirm=auto
+'
+
+test_expect_success '--confirm=cc' '
+ test_confirm --confirm=cc
+'
+
+test_expect_success '--confirm=compose' '
+ test_confirm --confirm=compose --compose
+'
+
+test_expect_success 'confirm by default (due to cc)' '
+ CONFIRM=$(git config --get sendemail.confirm) &&
+ git config --unset sendemail.confirm &&
+ test_confirm
+ ret="$?"
+ git config sendemail.confirm ${CONFIRM:-never}
+ test $ret = "0"
+'
+
+test_expect_success 'confirm by default (due to --compose)' '
+ CONFIRM=$(git config --get sendemail.confirm) &&
+ git config --unset sendemail.confirm &&
+ test_confirm --suppress-cc=all --compose
+ ret="$?"
+ git config sendemail.confirm ${CONFIRM:-never}
+ test $ret = "0"
+'
+
+test_expect_success 'confirm detects EOF (inform assumes y)' '
+ CONFIRM=$(git config --get sendemail.confirm) &&
+ git config --unset sendemail.confirm &&
+ rm -fr outdir &&
+ git format-patch -2 -o outdir &&
+ GIT_SEND_EMAIL_NOTTY=1 \
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ outdir/*.patch < /dev/null
+ ret="$?"
+ git config sendemail.confirm ${CONFIRM:-never}
+ test $ret = "0"
+'
+
+test_expect_success 'confirm detects EOF (auto causes failure)' '
+ CONFIRM=$(git config --get sendemail.confirm) &&
+ git config sendemail.confirm auto &&
+ GIT_SEND_EMAIL_NOTTY=1 &&
+ export GIT_SEND_EMAIL_NOTTY &&
+ test_must_fail git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches < /dev/null
+ ret="$?"
+ git config sendemail.confirm ${CONFIRM:-never}
+ test $ret = "0"
+'
+
+test_expect_success 'confirm doesnt loop forever' '
+ CONFIRM=$(git config --get sendemail.confirm) &&
+ git config sendemail.confirm auto &&
+ GIT_SEND_EMAIL_NOTTY=1 &&
+ export GIT_SEND_EMAIL_NOTTY &&
+ yes "bogus" | test_must_fail git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches
+ ret="$?"
+ git config sendemail.confirm ${CONFIRM:-never}
+ test $ret = "0"
+'
+
+test_expect_success 'utf8 Cc is rfc2047 encoded' '
+ clean_fake_sendmail &&
+ rm -fr outdir &&
+ git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
git send-email \
- --dry-run \
- --from="Example <from@example.com>" \
- --to=to@example.com \
- --smtp-server relay.example.com \
- $patches |
- sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
- -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
- -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
- >actual-show-all-headers &&
- test_cmp expected-show-all-headers actual-show-all-headers
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ outdir/*.patch &&
+ grep "^Cc:" msgtxt1 |
+ grep "=?UTF-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
'
test_expect_success '--compose adds MIME for utf8 body' '
@@ -239,9 +615,7 @@ test_expect_success '--compose adds MIME for utf8 body' '
echo "echo utf8 body: àéìöú >>\"\$1\""
) >fake-editor-utf8 &&
chmod +x fake-editor-utf8 &&
- echo y | \
GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
- GIT_SEND_EMAIL_NOTTY=1 \
git send-email \
--compose --subject foo \
--from="Example <nobody@example.com>" \
@@ -249,7 +623,7 @@ test_expect_success '--compose adds MIME for utf8 body' '
--smtp-server="$(pwd)/fake.sendmail" \
$patches &&
grep "^utf8 body" msgtxt1 &&
- grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
+ grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
'
test_expect_success '--compose respects user mime type' '
@@ -263,9 +637,7 @@ test_expect_success '--compose respects user mime type' '
echo " echo utf8 body: àéìöú) >\"\$1\""
) >fake-editor-utf8-mime &&
chmod +x fake-editor-utf8-mime &&
- echo y | \
GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
- GIT_SEND_EMAIL_NOTTY=1 \
git send-email \
--compose --subject foo \
--from="Example <nobody@example.com>" \
@@ -274,14 +646,12 @@ test_expect_success '--compose respects user mime type' '
$patches &&
grep "^utf8 body" msgtxt1 &&
grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
- ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
+ ! grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
'
test_expect_success '--compose adds MIME for utf8 subject' '
clean_fake_sendmail &&
- echo y | \
GIT_EDITOR="\"$(pwd)/fake-editor\"" \
- GIT_SEND_EMAIL_NOTTY=1 \
git send-email \
--compose --subject utf8-sübjëct \
--from="Example <nobody@example.com>" \
@@ -289,7 +659,7 @@ test_expect_success '--compose adds MIME for utf8 subject' '
--smtp-server="$(pwd)/fake.sendmail" \
$patches &&
grep "^fake edit" msgtxt1 &&
- grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
+ grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
'
test_expect_success 'detects ambiguous reference/file conflict' '
@@ -303,7 +673,7 @@ test_expect_success 'detects ambiguous reference/file conflict' '
test_expect_success 'feed two files' '
rm -fr outdir &&
git format-patch -2 -o outdir &&
- GIT_SEND_EMAIL_NOTTY=1 git send-email \
+ git send-email \
--dry-run \
--from="Example <nobody@example.com>" \
--to=nobody@example.com \
@@ -313,4 +683,36 @@ test_expect_success 'feed two files' '
test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
'
+test_expect_success 'in-reply-to but no threading' '
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --in-reply-to="<in-reply-id@example.com>" \
+ --nothread \
+ $patches |
+ grep "In-Reply-To: <in-reply-id@example.com>"
+'
+
+test_expect_success 'no in-reply-to and no threading' '
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --nothread \
+ $patches $patches >stdout &&
+ ! grep "In-Reply-To: " stdout
+'
+
+test_expect_success 'threading but no chain-reply-to' '
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --thread \
+ --nochain-reply-to \
+ $patches $patches >stdout &&
+ grep "In-Reply-To: " stdout
+'
+
test_done
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index bb921af56a..570e0359e4 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -6,19 +6,19 @@
test_description='git svn basic tests'
GIT_SVN_LC_ALL=${LC_ALL:-$LANG}
+. ./lib-git-svn.sh
+
+say 'define NO_SVN_TESTS to skip git svn tests'
+
case "$GIT_SVN_LC_ALL" in
*.UTF-8)
- have_utf8=t
+ test_set_prereq UTF8
;;
*)
- have_utf8=
+ say "UTF-8 locale not set, some tests skipped ($GIT_SVN_LC_ALL)"
;;
esac
-. ./lib-git-svn.sh
-
-say 'define NO_SVN_TESTS to skip git svn tests'
-
test_expect_success \
'initialize git svn' '
mkdir import &&
@@ -31,7 +31,7 @@ test_expect_success \
echo "zzz" > bar/zzz &&
echo "#!/bin/sh" > exec.sh &&
chmod +x exec.sh &&
- svn import -m "import for git svn" . "$svnrepo" >/dev/null &&
+ svn_cmd import -m "import for git svn" . "$svnrepo" >/dev/null &&
cd .. &&
rm -rf import &&
git svn init "$svnrepo"'
@@ -51,7 +51,7 @@ test_expect_success "$name" '
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
${remotes_git_svn}..mybranch &&
- svn up "$SVN_TREE" &&
+ svn_cmd up "$SVN_TREE" &&
test -d "$SVN_TREE"/dir && test ! -d "$SVN_TREE"/dir/a'
@@ -118,7 +118,7 @@ test_expect_success "$name" '
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
${remotes_git_svn}..mybranch5 &&
- svn up "$SVN_TREE" &&
+ svn_cmd up "$SVN_TREE" &&
test ! -x "$SVN_TREE"/exec.sh'
@@ -129,7 +129,7 @@ test_expect_success "$name" '
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
${remotes_git_svn}..mybranch5 &&
- svn up "$SVN_TREE" &&
+ svn_cmd up "$SVN_TREE" &&
test -x "$SVN_TREE"/exec.sh'
@@ -141,7 +141,7 @@ test_expect_success "$name" '
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
${remotes_git_svn}..mybranch5 &&
- svn up "$SVN_TREE" &&
+ svn_cmd up "$SVN_TREE" &&
test -L "$SVN_TREE"/exec.sh'
name='new symlink is added to a file that was also just made executable'
@@ -153,7 +153,7 @@ test_expect_success "$name" '
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
${remotes_git_svn}..mybranch5 &&
- svn up "$SVN_TREE" &&
+ svn_cmd up "$SVN_TREE" &&
test -x "$SVN_TREE"/bar/zzz &&
test -L "$SVN_TREE"/exec-2.sh'
@@ -166,25 +166,20 @@ test_expect_success "$name" '
git commit -m "$name" &&
git svn set-tree --find-copies-harder --rmdir \
${remotes_git_svn}..mybranch5 &&
- svn up "$SVN_TREE" &&
+ svn_cmd up "$SVN_TREE" &&
test -f "$SVN_TREE"/exec-2.sh &&
test ! -L "$SVN_TREE"/exec-2.sh &&
test_cmp help "$SVN_TREE"/exec-2.sh'
-if test "$have_utf8" = t
-then
- name="commit with UTF-8 message: locale: $GIT_SVN_LC_ALL"
- LC_ALL="$GIT_SVN_LC_ALL"
- export LC_ALL
- test_expect_success "$name" "
- echo '# hello' >> exec-2.sh &&
- git update-index exec-2.sh &&
- git commit -m 'éïâˆ' &&
- git svn set-tree HEAD"
- unset LC_ALL
-else
- say "UTF-8 locale not set, test skipped ($GIT_SVN_LC_ALL)"
-fi
+name="commit with UTF-8 message: locale: $GIT_SVN_LC_ALL"
+LC_ALL="$GIT_SVN_LC_ALL"
+export LC_ALL
+test_expect_success UTF8 "$name" "
+ echo '# hello' >> exec-2.sh &&
+ git update-index exec-2.sh &&
+ git commit -m 'éïâˆ' &&
+ git svn set-tree HEAD"
+unset LC_ALL
name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
@@ -197,7 +192,7 @@ test_expect_success "$name" \
name='check imported tree checksums expected tree checksums'
rm -f expected
-if test "$have_utf8" = t
+if test_have_prereq UTF8
then
echo tree bf522353586b1b883488f2bc73dab0d9f774b9a9 > expected
fi
@@ -236,6 +231,25 @@ test_expect_success \
"^:refs/${remotes_git_svn}$"
'
+test_expect_success 'dcommit $rev does not clobber current branch' '
+ git svn fetch -i bar &&
+ git checkout -b my-bar refs/remotes/bar &&
+ echo 1 > foo &&
+ git add foo &&
+ git commit -m "change 1" &&
+ echo 2 > foo &&
+ git add foo &&
+ git commit -m "change 2" &&
+ old_head=$(git rev-parse HEAD) &&
+ git svn dcommit -i bar HEAD^ &&
+ test $old_head = $(git rev-parse HEAD) &&
+ test refs/heads/my-bar = $(git symbolic-ref HEAD) &&
+ git log refs/remotes/bar | grep "change 1" &&
+ ! git log refs/remotes/bar | grep "change 2" &&
+ git checkout master &&
+ git branch -D my-bar
+ '
+
test_expect_success 'able to dcommit to a subdirectory' "
git svn fetch -i bar &&
git checkout -b my-bar refs/remotes/bar &&
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 1e31d6ea72..929499e996 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -48,7 +48,7 @@ EOF
printf "\r\n" > empty_crlf
a_empty_crlf=`git hash-object -w empty_crlf`
- svn import --no-auto-props -m 'import for git svn' . "$svnrepo" >/dev/null
+ svn_cmd import --no-auto-props -m 'import for git svn' . "$svnrepo" >/dev/null
cd ..
rm -rf import
@@ -57,13 +57,13 @@ test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
poke kw.c &&
- svn commit -m "Not yet an Id" &&
+ svn_cmd commit -m "Not yet an Id" &&
echo Hello world >> kw.c &&
poke kw.c &&
- svn commit -m "Modified file, but still not yet an Id" &&
- svn propset svn:keywords Id kw.c &&
+ svn_cmd commit -m "Modified file, but still not yet an Id" &&
+ svn_cmd propset svn:keywords Id kw.c &&
poke kw.c &&
- svn commit -m "Propset Id" &&
+ svn_cmd commit -m "Propset Id" &&
cd ..'
test_expect_success 'initialize git svn' 'git svn init "$svnrepo"'
@@ -83,16 +83,16 @@ test_expect_success 'raw $Id$ found in kw.c' "test '$expect' = '$got'"
test_expect_success "propset CR on crlf files" \
'cd test_wc &&
- svn propset svn:eol-style CR empty &&
- svn propset svn:eol-style CR crlf &&
- svn propset svn:eol-style CR ne_crlf &&
- svn commit -m "propset CR on crlf files" &&
+ svn_cmd propset svn:eol-style CR empty &&
+ svn_cmd propset svn:eol-style CR crlf &&
+ svn_cmd propset svn:eol-style CR ne_crlf &&
+ svn_cmd commit -m "propset CR on crlf files" &&
cd ..'
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
'git svn fetch &&
git pull . ${remotes_git_svn} &&
- svn co "$svnrepo" new_wc'
+ svn_cmd co "$svnrepo" new_wc'
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
@@ -106,11 +106,11 @@ cd test_wc
a_cr=`printf '$Id$\r\nHello\r\nWorld\r\n' | git hash-object --stdin`
a_ne_cr=`printf '$Id$\r\nHello\r\nWorld' | git hash-object --stdin`
test_expect_success 'Set CRLF on cr files' \
- 'svn propset svn:eol-style CRLF cr &&
- svn propset svn:eol-style CRLF ne_cr &&
- svn propset svn:keywords Id cr &&
- svn propset svn:keywords Id ne_cr &&
- svn commit -m "propset CRLF on cr files"'
+ 'svn_cmd propset svn:eol-style CRLF cr &&
+ svn_cmd propset svn:eol-style CRLF ne_cr &&
+ svn_cmd propset svn:keywords Id cr &&
+ svn_cmd propset svn:keywords Id ne_cr &&
+ svn_cmd commit -m "propset CRLF on cr files"'
cd ..
test_expect_success 'fetch and pull latest from svn' \
'git svn fetch && git pull . ${remotes_git_svn}'
@@ -140,10 +140,12 @@ test_expect_success 'test show-ignore' "
cd test_wc &&
mkdir -p deeply/nested/directory &&
touch deeply/nested/directory/.keep &&
- svn add deeply &&
- svn up &&
- svn propset -R svn:ignore 'no-such-file*' .
- svn commit -m 'propset svn:ignore'
+ svn_cmd add deeply &&
+ svn_cmd up &&
+ svn_cmd propset -R svn:ignore '
+no-such-file*
+' .
+ svn_cmd commit -m 'propset svn:ignore'
cd .. &&
git svn show-ignore > show-ignore.got &&
cmp show-ignore.expect show-ignore.got
@@ -171,6 +173,7 @@ test_expect_success 'test create-ignore' "
"
cat >prop.expect <<\EOF
+
no-such-file*
EOF
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index e223218015..028fb19e09 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,7 +9,7 @@ test_expect_success 'initialize repo' '
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m "import for git svn" . "$svnrepo" &&
+ svn_cmd import -m "import for git svn" . "$svnrepo" &&
cd ..
'
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' '
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m "remove another" &&
git svn set-tree --rmdir HEAD &&
- svn ls -R "$svnrepo" | grep ^deeply/nested/directory/number/1
+ svn_cmd ls -R "$svnrepo" | grep ^deeply/nested/directory/number/1
'
diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh
index 963dd95e4a..3413164cb1 100755
--- a/t/t9103-git-svn-tracked-directory-removed.sh
+++ b/t/t9103-git-svn-tracked-directory-removed.sh
@@ -10,15 +10,15 @@ test_expect_success 'make history for tracking' '
mkdir import &&
mkdir import/trunk &&
echo hello >> import/trunk/README &&
- svn import -m initial import "$svnrepo" &&
+ svn_cmd import -m initial import "$svnrepo" &&
rm -rf import &&
- svn co "$svnrepo"/trunk trunk &&
+ svn_cmd co "$svnrepo"/trunk trunk &&
echo bye bye >> trunk/README &&
- svn rm -m "gone" "$svnrepo"/trunk &&
+ svn_cmd rm -m "gone" "$svnrepo"/trunk &&
rm -rf trunk &&
mkdir trunk &&
echo "new" > trunk/FOLLOWME &&
- svn import -m "new trunk" trunk "$svnrepo"/trunk
+ svn_cmd import -m "new trunk" trunk "$svnrepo"/trunk
'
test_expect_success 'clone repo with git' '
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index ab9fa32220..78610b61e6 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,18 +11,18 @@ test_expect_success 'initialize repo' '
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m "initial" . "$svnrepo" &&
+ svn_cmd import -m "initial" . "$svnrepo" &&
cd .. &&
- svn co "$svnrepo" wc &&
+ svn_cmd co "$svnrepo" wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
- svn commit -m "another commit" &&
- svn up &&
- svn mv trunk thunk &&
+ svn_cmd commit -m "another commit" &&
+ svn_cmd up &&
+ svn_cmd mv trunk thunk &&
echo goodbye >> thunk/readme &&
poke thunk/readme &&
- svn commit -m "bye now" &&
+ svn_cmd commit -m "bye now" &&
cd ..
'
@@ -51,7 +51,7 @@ test_expect_success 'init and fetch from one svn-remote' '
'
test_expect_success 'follow deleted parent' '
- (svn cp -m "resurrecting trunk as junk" \
+ (svn_cmd cp -m "resurrecting trunk as junk" \
"$svnrepo"/trunk@2 "$svnrepo"/junk ||
svn cp -m "resurrecting trunk as junk" \
-r2 "$svnrepo"/trunk "$svnrepo"/junk) &&
@@ -97,8 +97,8 @@ test_expect_success 'follow higher-level parent' '
'
test_expect_success 'follow deleted directory' '
- svn mv -m "bye!" "$svnrepo"/glob/blob/hi "$svnrepo"/glob/blob/bye &&
- svn rm -m "remove glob" "$svnrepo"/glob &&
+ svn_cmd mv -m "bye!" "$svnrepo"/glob/blob/hi "$svnrepo"/glob/blob/bye &&
+ svn_cmd rm -m "remove glob" "$svnrepo"/glob &&
git svn init --minimize-url -i glob "$svnrepo"/glob &&
git svn fetch -i glob &&
test "`git cat-file blob refs/remotes/glob:blob/bye`" = hi &&
@@ -120,7 +120,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' '
cd import &&
svn import -m "r9270 test" . "$svnrepo"/r9270 &&
cd .. &&
- svn co "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn_cmd co "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -138,7 +138,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' '
'
test_expect_success "track initial change if it was only made to parent" '
- svn cp -m "wheee!" "$svnrepo"/r9270/trunk "$svnrepo"/r9270/drunk &&
+ svn_cmd cp -m "wheee!" "$svnrepo"/r9270/trunk "$svnrepo"/r9270/drunk &&
git svn init --minimize-url -i r9270-d \
"$svnrepo"/r9270/drunk/subversion/bindings/swig/perl/native/t &&
git svn fetch -i r9270-d &&
@@ -152,20 +152,20 @@ test_expect_success "track initial change if it was only made to parent" '
test_expect_success "follow-parent is atomic" '
(
cd wc &&
- svn up &&
- svn mkdir stunk &&
+ svn_cmd up &&
+ svn_cmd mkdir stunk &&
echo "trunk stunk" > stunk/readme &&
- svn add stunk/readme &&
- svn ci -m "trunk stunk" &&
+ svn_cmd add stunk/readme &&
+ svn_cmd ci -m "trunk stunk" &&
echo "stunk like junk" >> stunk/readme &&
- svn ci -m "really stunk" &&
+ svn_cmd ci -m "really stunk" &&
echo "stink stank stunk" >> stunk/readme &&
- svn ci -m "even the grinch agrees"
+ svn_cmd ci -m "even the grinch agrees"
) &&
- svn copy -m "stunk flunked" "$svnrepo"/stunk "$svnrepo"/flunk &&
+ svn_cmd copy -m "stunk flunked" "$svnrepo"/stunk "$svnrepo"/flunk &&
{ svn cp -m "early stunk flunked too" \
"$svnrepo"/stunk@17 "$svnrepo"/flunked ||
- svn cp -m "early stunk flunked too" \
+ svn_cmd cp -m "early stunk flunked too" \
-r17 "$svnrepo"/stunk "$svnrepo"/flunked; } &&
git svn init --minimize-url -i stunk "$svnrepo"/stunk &&
git svn fetch -i stunk &&
@@ -192,7 +192,7 @@ test_expect_success "follow-parent is atomic" '
'
test_expect_success "track multi-parent paths" '
- svn cp -m "resurrect /glob" "$svnrepo"/r9270 "$svnrepo"/glob &&
+ svn_cmd cp -m "resurrect /glob" "$svnrepo"/r9270 "$svnrepo"/glob &&
git svn multi-fetch &&
test `git cat-file commit refs/remotes/glob | \
grep "^parent " | wc -l` -eq 2
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index ba99abb6d9..dd48e9cba8 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m "initial" . "$svnrepo" &&
+ svn_cmd import -m "initial" . "$svnrepo" &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -27,16 +27,16 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' '
test -n "$prev" && test -n "$head" &&
git svn commit-diff -r1 "$prev" "$head" "$svnrepo" &&
- svn co "$svnrepo" wc &&
+ svn_cmd co "$svnrepo" wc &&
cmp readme wc/readme
'
test_expect_success 'commit-diff to a sub-directory (with git svn config)' '
- svn import -m "sub-directory" import "$svnrepo"/subdir &&
+ svn_cmd import -m "sub-directory" import "$svnrepo"/subdir &&
git svn init --minimize-url "$svnrepo"/subdir &&
git svn fetch &&
git svn commit-diff -r3 "$prev" "$head" &&
- svn cat "$svnrepo"/subdir/readme > readme.2 &&
+ svn_cmd cat "$svnrepo"/subdir/readme > readme.2 &&
cmp readme readme.2
'
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index 6eb0fd85c8..12f21b700e 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,18 +8,18 @@ test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m "initial" . "$svnrepo" &&
+ svn_cmd import -m "initial" . "$svnrepo" &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m "initial"
'
test_expect_success 'commit change from svn side' '
- svn co "$svnrepo" t.svn &&
+ svn_cmd co "$svnrepo" t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
- svn commit -m "second line from svn" &&
+ svn_cmd commit -m "second line from svn" &&
cd .. &&
rm -rf t.svn
'
@@ -43,11 +43,11 @@ test_expect_success 'dcommit fails to commit because of conflict' '
git svn init "$svnrepo" &&
git svn fetch &&
git reset --hard refs/${remotes_git_svn} &&
- svn co "$svnrepo" t.svn &&
+ svn_cmd co "$svnrepo" t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
- svn commit -m "fourth line from svn" &&
+ svn_cmd commit -m "fourth line from svn" &&
cd .. &&
rm -rf t.svn &&
echo "fourth line from git" >> file &&
@@ -67,11 +67,11 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' '
- svn co "$svnrepo" t.svn &&
+ svn_cmd co "$svnrepo" t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
- svn commit -m "third line from svn" &&
+ svn_cmd commit -m "third line from svn" &&
cd .. &&
rm -rf t.svn
'
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index acad16a6f0..c0098d9808 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -12,7 +12,7 @@ test_expect_success 'setup old-looking metadata' '
mkdir -p $i && \
echo hello >> $i/README || exit 1
done && \
- svn import -m test . "$svnrepo"
+ svn_cmd import -m test . "$svnrepo"
cd .. &&
git svn init "$svnrepo" &&
git svn fetch &&
@@ -56,7 +56,15 @@ test_expect_success 'initialize a multi-repository repo' '
git config --add svn-remote.svn.fetch "branches/b:refs/remotes/b" &&
for i in tags/0.1 tags/0.2 tags/0.3; do
git config --add svn-remote.svn.fetch \
- $i:refs/remotes/$i || exit 1; done
+ $i:refs/remotes/$i || exit 1; done &&
+ git config --get-all svn-remote.svn.fetch > fetch.out &&
+ grep "^trunk:refs/remotes/trunk$" fetch.out &&
+ grep "^branches/a:refs/remotes/a$" fetch.out &&
+ grep "^branches/b:refs/remotes/b$" fetch.out &&
+ grep "^tags/0\.1:refs/remotes/tags/0\.1$" fetch.out &&
+ grep "^tags/0\.2:refs/remotes/tags/0\.2$" fetch.out &&
+ grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out &&
+ grep "^:refs/${remotes_git_svn}" fetch.out
'
# refs should all be different, but the trees should all be the same:
@@ -86,14 +94,14 @@ test_expect_success 'migrate --minimize on old inited layout' '
echo "$svnrepo"$path > "$GIT_DIR"/svn/$ref/info/url ) || exit 1;
done &&
git svn migrate --minimize &&
- test -z "`git config -l |grep -v "^svn-remote\.git-svn\."`" &&
+ test -z "`git config -l | grep "^svn-remote\.git-svn\."`" &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep "^trunk:refs/remotes/trunk$" fetch.out &&
grep "^branches/a:refs/remotes/a$" fetch.out &&
grep "^branches/b:refs/remotes/b$" fetch.out &&
grep "^tags/0\.1:refs/remotes/tags/0\.1$" fetch.out &&
grep "^tags/0\.2:refs/remotes/tags/0\.2$" fetch.out &&
- grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out
+ grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out &&
grep "^:refs/${remotes_git_svn}" fetch.out
'
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index d8582b1aa5..d732d31302 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,30 +14,30 @@ test_expect_success 'test refspec globbing' '
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo "hello world" > trunk/src/a/readme &&
echo "goodbye world" > trunk/src/b/readme &&
- svn import -m "initial" trunk "$svnrepo"/trunk &&
- svn co "$svnrepo" tmp &&
+ svn_cmd import -m "initial" trunk "$svnrepo"/trunk &&
+ svn_cmd co "$svnrepo" tmp &&
(
cd tmp &&
mkdir branches tags &&
- svn add branches tags &&
- svn cp trunk branches/start &&
- svn commit -m "start a new branch" &&
- svn up &&
+ svn_cmd add branches tags &&
+ svn_cmd cp trunk branches/start &&
+ svn_cmd commit -m "start a new branch" &&
+ svn_cmd up &&
echo "hi" >> branches/start/src/b/readme &&
poke branches/start/src/b/readme &&
echo "hey" >> branches/start/src/a/readme &&
poke branches/start/src/a/readme &&
- svn commit -m "hi" &&
- svn up &&
- svn cp branches/start tags/end &&
+ svn_cmd commit -m "hi" &&
+ svn_cmd up &&
+ svn_cmd cp branches/start tags/end &&
echo "bye" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
echo "aye" >> tags/end/src/a/readme &&
poke tags/end/src/a/readme &&
- svn commit -m "the end" &&
+ svn_cmd commit -m "the end" &&
echo "byebye" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m "nothing to see here"
+ svn_cmd commit -m "nothing to see here"
) &&
git config --add svn-remote.svn.url "$svnrepo" &&
git config --add svn-remote.svn.fetch \
@@ -72,7 +72,7 @@ test_expect_success 'test left-hand-side only globbing' '
cd tmp &&
echo "try try" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m "try to try"
+ svn_cmd commit -m "try to try"
) &&
git svn fetch two &&
test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 &&
@@ -102,7 +102,7 @@ test_expect_success 'test disallow multi-globs' '
cd tmp &&
echo "try try" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m "try to try"
+ svn_cmd commit -m "try to try"
) &&
test_must_fail git svn fetch three 2> stderr.three &&
test_cmp expect.three stderr.three
diff --git a/t/t9108-git-svn-multi-glob.sh b/t/t9109-git-svn-multi-glob.sh
index 8f79c3f251..c318f9f946 100755
--- a/t/t9108-git-svn-multi-glob.sh
+++ b/t/t9109-git-svn-multi-glob.sh
@@ -14,30 +14,30 @@ test_expect_success 'test refspec globbing' '
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo "hello world" > trunk/src/a/readme &&
echo "goodbye world" > trunk/src/b/readme &&
- svn import -m "initial" trunk "$svnrepo"/trunk &&
- svn co "$svnrepo" tmp &&
+ svn_cmd import -m "initial" trunk "$svnrepo"/trunk &&
+ svn_cmd co "$svnrepo" tmp &&
(
cd tmp &&
mkdir branches branches/v1 tags &&
- svn add branches tags &&
- svn cp trunk branches/v1/start &&
- svn commit -m "start a new branch" &&
- svn up &&
+ svn_cmd add branches tags &&
+ svn_cmd cp trunk branches/v1/start &&
+ svn_cmd commit -m "start a new branch" &&
+ svn_cmd up &&
echo "hi" >> branches/v1/start/src/b/readme &&
poke branches/v1/start/src/b/readme &&
echo "hey" >> branches/v1/start/src/a/readme &&
poke branches/v1/start/src/a/readme &&
- svn commit -m "hi" &&
- svn up &&
- svn cp branches/v1/start tags/end &&
+ svn_cmd commit -m "hi" &&
+ svn_cmd up &&
+ svn_cmd cp branches/v1/start tags/end &&
echo "bye" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
echo "aye" >> tags/end/src/a/readme &&
poke tags/end/src/a/readme &&
- svn commit -m "the end" &&
+ svn_cmd commit -m "the end" &&
echo "byebye" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m "nothing to see here"
+ svn_cmd commit -m "nothing to see here"
) &&
git config --add svn-remote.svn.url "$svnrepo" &&
git config --add svn-remote.svn.fetch \
@@ -72,7 +72,7 @@ test_expect_success 'test left-hand-side only globbing' '
cd tmp &&
echo "try try" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m "try to try"
+ svn_cmd commit -m "try to try"
) &&
git svn fetch two &&
test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 &&
@@ -97,25 +97,25 @@ test_expect_success 'test another branch' '
(
cd tmp &&
mkdir branches/v2 &&
- svn add branches/v2 &&
- svn cp trunk branches/v2/start &&
- svn commit -m "Another versioned branch" &&
- svn up &&
+ svn_cmd add branches/v2 &&
+ svn_cmd cp trunk branches/v2/start &&
+ svn_cmd commit -m "Another versioned branch" &&
+ svn_cmd up &&
echo "hello" >> branches/v2/start/src/b/readme &&
poke branches/v2/start/src/b/readme &&
echo "howdy" >> branches/v2/start/src/a/readme &&
poke branches/v2/start/src/a/readme &&
- svn commit -m "Changed 2 in v2/start" &&
- svn up &&
- svn cp branches/v2/start tags/next &&
+ svn_cmd commit -m "Changed 2 in v2/start" &&
+ svn_cmd up &&
+ svn_cmd cp branches/v2/start tags/next &&
echo "bye" >> tags/next/src/b/readme &&
poke tags/next/src/b/readme &&
echo "aye" >> tags/next/src/a/readme &&
poke tags/next/src/a/readme &&
- svn commit -m "adding more" &&
+ svn_cmd commit -m "adding more" &&
echo "byebye" >> tags/next/src/b/readme &&
poke tags/next/src/b/readme &&
- svn commit -m "adios"
+ svn_cmd commit -m "adios"
) &&
git config --add svn-remote.four.url "$svnrepo" &&
git config --add svn-remote.four.fetch trunk:refs/remotes/four/trunk &&
@@ -151,7 +151,7 @@ test_expect_success 'test disallow multiple globs' '
cd tmp &&
echo "try try" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m "try to try"
+ svn_cmd commit -m "try to try"
) &&
test_must_fail git svn fetch three 2> stderr.three &&
test_cmp expect.three stderr.three
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index e9b6128b3f..e8479cec7a 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,7 +15,7 @@ test_description='git svn dcommit new files over svn:// test'
require_svnserve
test_expect_success 'start tracking an empty repo' '
- svn mkdir -m "empty dir" "$svnrepo"/empty-dir &&
+ svn_cmd mkdir -m "empty dir" "$svnrepo"/empty-dir &&
echo "[general]" > "$rawsvnrepo"/conf/svnserve.conf &&
echo anon-access = write >> "$rawsvnrepo"/conf/svnserve.conf &&
start_svnserve &&
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index 17b2855c4f..84f7c9b4bb 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,12 +35,12 @@ EOF
}
test_expect_success 'setup svn repository' '
- svn co "$svnrepo" mysvnwork &&
+ svn_cmd co "$svnrepo" mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
- svn add trunk &&
- svn ci -m "first commit" trunk &&
+ svn_cmd add trunk &&
+ svn_cmd ci -m "first commit" trunk &&
cd ..
'
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index fd6d1d2046..0374a7476b 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,7 +14,7 @@ test_expect_success 'setup repository and import' '
mkdir -p $i && \
echo hello >> $i/README || exit 1
done && \
- svn import -m test . "$svnrepo"
+ svn_cmd import -m test . "$svnrepo"
cd .. &&
git svn init "$svnrepo" -T trunk -b branches -t tags &&
git svn fetch &&
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
index dde46cd92f..b7ef9e2589 100755
--- a/t/t9117-git-svn-init-clone.sh
+++ b/t/t9117-git-svn-init-clone.sh
@@ -16,7 +16,7 @@ cd tmp
test_expect_success 'setup svnrepo' '
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m "$test_description" project "$svnrepo"/project &&
+ svn_cmd import -m "$test_description" project "$svnrepo"/project &&
rm -rf project
'
diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh
index 7a7c128687..ac52bff0ef 100755
--- a/t/t9118-git-svn-funky-branch-names.sh
+++ b/t/t9118-git-svn-funky-branch-names.sh
@@ -13,13 +13,13 @@ scary_ref='Abo-Uebernahme%20(Bug%20#994)'
test_expect_success 'setup svnrepo' '
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m "$test_description" project "$svnrepo/pr ject" &&
+ svn_cmd import -m "$test_description" project "$svnrepo/pr ject" &&
rm -rf project &&
- svn cp -m "fun" "$svnrepo/pr ject/trunk" \
+ svn_cmd cp -m "fun" "$svnrepo/pr ject/trunk" \
"$svnrepo/pr ject/branches/fun plugin" &&
- svn cp -m "more fun!" "$svnrepo/pr ject/branches/fun plugin" \
+ svn_cmd cp -m "more fun!" "$svnrepo/pr ject/branches/fun plugin" \
"$svnrepo/pr ject/branches/more fun plugin!" &&
- svn cp -m "scary" "$svnrepo/pr ject/branches/fun plugin" \
+ svn_cmd cp -m "scary" "$svnrepo/pr ject/branches/fun plugin" \
"$svnrepo/pr ject/branches/$scary_uri" &&
start_httpd
'
diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh
index 27dd7c273a..95741cbbac 100755
--- a/t/t9119-git-svn-info.sh
+++ b/t/t9119-git-svn-info.sh
@@ -7,7 +7,7 @@ test_description='git svn info'
. ./lib-git-svn.sh
# Tested with: svn, version 1.4.4 (r25188)
-v=`svn --version | sed -n -e 's/^svn, version \(1\.[0-9]*\.[0-9]*\).*$/\1/p'`
+v=`svn_cmd --version | sed -n -e 's/^svn, version \(1\.[0-9]*\.[0-9]*\).*$/\1/p'`
case $v in
1.[45].*)
;;
@@ -31,7 +31,7 @@ ptouch() {
my $atime = $mtime;
utime $atime, $mtime, $git_file;
}
- ' "`svn info $2 | grep '^Text Last Updated:'`" "$1"
+ ' "`svn_cmd info $2 | grep '^Text Last Updated:'`" "$1"
}
quoted_svnrepo="$(echo $svnrepo | sed 's/ /%20/')"
@@ -45,14 +45,14 @@ test_expect_success 'setup repository and import' '
mkdir directory &&
touch directory/.placeholder &&
ln -s directory symlink-directory &&
- svn import -m "initial" . "$svnrepo" &&
+ svn_cmd import -m "initial" . "$svnrepo" &&
cd .. &&
- svn co "$svnrepo" svnwc &&
+ svn_cmd co "$svnrepo" svnwc &&
cd svnwc &&
echo foo > foo &&
- svn add foo &&
- svn commit -m "change outside directory" &&
- svn update &&
+ svn_cmd add foo &&
+ svn_cmd commit -m "change outside directory" &&
+ svn_cmd update &&
cd .. &&
mkdir gitwc &&
cd gitwc &&
@@ -143,7 +143,7 @@ test_expect_success 'info added-file' "
cp gitwc/added-file svnwc/added-file &&
ptouch gitwc/added-file svnwc/added-file &&
cd svnwc &&
- svn add added-file > /dev/null &&
+ svn_cmd add added-file > /dev/null &&
cd .. &&
(cd svnwc; svn info added-file) > expected.info-added-file &&
(cd gitwc; git svn info added-file) > actual.info-added-file &&
@@ -160,7 +160,7 @@ test_expect_success 'info added-directory' "
ptouch gitwc/added-directory svnwc/added-directory &&
touch gitwc/added-directory/.placeholder &&
cd svnwc &&
- svn add added-directory > /dev/null &&
+ svn_cmd add added-directory > /dev/null &&
cd .. &&
cd gitwc &&
git add added-directory &&
@@ -184,7 +184,7 @@ test_expect_success 'info added-symlink-file' "
cd .. &&
cd svnwc &&
ln -s added-file added-symlink-file &&
- svn add added-symlink-file > /dev/null &&
+ svn_cmd add added-symlink-file > /dev/null &&
cd .. &&
ptouch gitwc/added-symlink-file svnwc/added-symlink-file &&
(cd svnwc; svn info added-symlink-file) \
@@ -207,7 +207,7 @@ test_expect_success 'info added-symlink-directory' "
cd .. &&
cd svnwc &&
ln -s added-directory added-symlink-directory &&
- svn add added-symlink-directory > /dev/null &&
+ svn_cmd add added-symlink-directory > /dev/null &&
cd .. &&
ptouch gitwc/added-symlink-directory svnwc/added-symlink-directory &&
(cd svnwc; svn info added-symlink-directory) \
@@ -233,7 +233,7 @@ test_expect_success 'info deleted-file' "
git rm -f file > /dev/null &&
cd .. &&
cd svnwc &&
- svn rm --force file > /dev/null &&
+ svn_cmd rm --force file > /dev/null &&
cd .. &&
(cd svnwc; svn info file) |
sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
@@ -254,7 +254,7 @@ test_expect_success 'info deleted-directory' "
git rm -r -f directory > /dev/null &&
cd .. &&
cd svnwc &&
- svn rm --force directory > /dev/null &&
+ svn_cmd rm --force directory > /dev/null &&
cd .. &&
(cd svnwc; svn info directory) |
sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
@@ -275,7 +275,7 @@ test_expect_success 'info deleted-symlink-file' "
git rm -f symlink-file > /dev/null &&
cd .. &&
cd svnwc &&
- svn rm --force symlink-file > /dev/null &&
+ svn_cmd rm --force symlink-file > /dev/null &&
cd .. &&
(cd svnwc; svn info symlink-file) |
sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
@@ -297,7 +297,7 @@ test_expect_success 'info deleted-symlink-directory' "
git rm -f symlink-directory > /dev/null &&
cd .. &&
cd svnwc &&
- svn rm --force symlink-directory > /dev/null &&
+ svn_cmd rm --force symlink-directory > /dev/null &&
cd .. &&
(cd svnwc; svn info symlink-directory) |
sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh
index ef2c0523cd..f159ab689b 100755
--- a/t/t9120-git-svn-clone-with-percent-escapes.sh
+++ b/t/t9120-git-svn-clone-with-percent-escapes.sh
@@ -9,22 +9,17 @@ test_description='git svn clone with percent escapes'
test_expect_success 'setup svnrepo' '
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m "$test_description" project "$svnrepo/pr ject" &&
+ svn_cmd import -m "$test_description" project "$svnrepo/pr ject" &&
rm -rf project &&
start_httpd
'
-if test "$SVN_HTTPD_PORT" = ""
-then
- test_expect_failure 'test clone with percent escapes - needs SVN_HTTPD_PORT set' 'false'
-else
- test_expect_success 'test clone with percent escapes' '
- git svn clone "$svnrepo/pr%20ject" clone &&
- cd clone &&
- git rev-parse refs/${remotes_git_svn} &&
- cd ..
- '
-fi
+test_expect_success 'test clone with percent escapes' '
+ git svn clone "$svnrepo/pr%20ject" clone &&
+ cd clone &&
+ git rev-parse refs/${remotes_git_svn} &&
+ cd ..
+'
stop_httpd
diff --git a/t/t9122-git-svn-author.sh b/t/t9122-git-svn-author.sh
index 1b1cf47281..30013b7bb9 100755
--- a/t/t9122-git-svn-author.sh
+++ b/t/t9122-git-svn-author.sh
@@ -4,12 +4,12 @@ test_description='git svn authorship'
. ./lib-git-svn.sh
test_expect_success 'setup svn repository' '
- svn checkout "$svnrepo" work.svn &&
+ svn_cmd checkout "$svnrepo" work.svn &&
(
cd work.svn &&
echo >file
- svn add file
- svn commit -m "first commit" file
+ svn_cmd add file
+ svn_cmd commit -m "first commit" file
)
'
@@ -74,10 +74,10 @@ test_expect_success 'interact with it via git svn' '
# Make sure there are no svn commit messages with excess blank lines
(
cd work.svn &&
- svn up &&
+ svn_cmd up &&
- test $(svn log -r2:2 | wc -l) = 5 &&
- test $(svn log -r4:4 | wc -l) = 7
+ test $(svn_cmd log -r2:2 | wc -l) = 5 &&
+ test $(svn_cmd log -r4:4 | wc -l) = 7
)
'
diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh
index cf0415274c..045521615c 100755
--- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh
+++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh
@@ -10,7 +10,7 @@ test_description='git svn respects rewriteRoot during rebuild'
mkdir import
cd import
touch foo
- svn import -m 'import for git svn' . "$svnrepo" >/dev/null
+ svn_cmd import -m 'import for git svn' . "$svnrepo" >/dev/null
cd ..
rm -rf import
diff --git a/t/t9124-git-svn-dcommit-auto-props.sh b/t/t9124-git-svn-dcommit-auto-props.sh
index 263dbf5fc2..d6b076f6b7 100755
--- a/t/t9124-git-svn-dcommit-auto-props.sh
+++ b/t/t9124-git-svn-dcommit-auto-props.sh
@@ -21,7 +21,7 @@ test_expect_success 'initialize git svn' '
(
cd import &&
echo foo >foo &&
- svn import -m "import for git svn" . "$svnrepo"
+ svn_cmd import -m "import for git svn" . "$svnrepo"
) &&
rm -rf import &&
git svn init "$svnrepo"
@@ -61,23 +61,23 @@ test_expect_success 'check resulting svn repository' '
(
mkdir work &&
cd work &&
- svn co "$svnrepo" &&
+ svn_cmd co "$svnrepo" &&
cd svnrepo &&
# Check properties from first commit.
- test "x$(svn propget svn:executable exec1.sh)" = "x*" &&
- test "x$(svn propget svn:mime-type exec1.sh)" = \
+ test "x$(svn_cmd propget svn:executable exec1.sh)" = "x*" &&
+ test "x$(svn_cmd propget svn:mime-type exec1.sh)" = \
"xapplication/x-shellscript" &&
- test "x$(svn propget svn:mime-type hello.txt)" = "xtext/plain" &&
- test "x$(svn propget svn:eol-style hello.txt)" = "xnative" &&
- test "x$(svn propget svn:mime-type bar)" = "x" &&
+ test "x$(svn_cmd propget svn:mime-type hello.txt)" = "xtext/plain" &&
+ test "x$(svn_cmd propget svn:eol-style hello.txt)" = "xnative" &&
+ test "x$(svn_cmd propget svn:mime-type bar)" = "x" &&
# Check properties from second commit.
- test "x$(svn propget svn:executable exec2.sh)" = "x*" &&
- test "x$(svn propget svn:mime-type exec2.sh)" = "x" &&
- test "x$(svn propget svn:mime-type world.txt)" = "x" &&
- test "x$(svn propget svn:eol-style world.txt)" = "x" &&
- test "x$(svn propget svn:mime-type zot)" = "x"
+ test "x$(svn_cmd propget svn:executable exec2.sh)" = "x*" &&
+ test "x$(svn_cmd propget svn:mime-type exec2.sh)" = "x" &&
+ test "x$(svn_cmd propget svn:mime-type world.txt)" = "x" &&
+ test "x$(svn_cmd propget svn:eol-style world.txt)" = "x" &&
+ test "x$(svn_cmd propget svn:mime-type zot)" = "x"
)
'
@@ -89,12 +89,12 @@ test_expect_success 'check renamed file' '
git svn dcommit --config-dir=user &&
(
cd work/svnrepo &&
- svn up &&
+ svn_cmd up &&
test ! -e foo &&
test -e foo.sh &&
- test "x$(svn propget svn:mime-type foo.sh)" = \
+ test "x$(svn_cmd propget svn:mime-type foo.sh)" = \
"xapplication/x-shellscript" &&
- test "x$(svn propget svn:eol-style foo.sh)" = "xLF"
+ test "x$(svn_cmd propget svn:eol-style foo.sh)" = "xLF"
)
'
diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh
index 475c751c1c..c19418614f 100755
--- a/t/t9125-git-svn-multi-glob-branch-names.sh
+++ b/t/t9125-git-svn-multi-glob-branch-names.sh
@@ -8,11 +8,11 @@ test_expect_success 'setup svnrepo' '
mkdir project project/trunk project/branches \
project/branches/v14.1 project/tags &&
echo foo > project/trunk/foo &&
- svn import -m "$test_description" project "$svnrepo/project" &&
+ svn_cmd import -m "$test_description" project "$svnrepo/project" &&
rm -rf project &&
- svn cp -m "fun" "$svnrepo/project/trunk" \
+ svn_cmd cp -m "fun" "$svnrepo/project/trunk" \
"$svnrepo/project/branches/v14.1/beta" &&
- svn cp -m "more fun!" "$svnrepo/project/branches/v14.1/beta" \
+ svn_cmd cp -m "more fun!" "$svnrepo/project/branches/v14.1/beta" \
"$svnrepo/project/branches/v14.1/gold"
'
diff --git a/t/t9127-git-svn-partial-rebuild.sh b/t/t9127-git-svn-partial-rebuild.sh
index 87696a92dc..4aab8ecc14 100755
--- a/t/t9127-git-svn-partial-rebuild.sh
+++ b/t/t9127-git-svn-partial-rebuild.sh
@@ -14,21 +14,21 @@ test_expect_success 'initialize svnrepo' '
cd trunk &&
echo foo > foo &&
cd .. &&
- svn import -m "import for git-svn" . "$svnrepo" >/dev/null &&
- svn copy "$svnrepo"/trunk "$svnrepo"/branches/a \
+ svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null &&
+ svn_cmd copy "$svnrepo"/trunk "$svnrepo"/branches/a \
-m "created branch a" &&
cd .. &&
rm -rf import &&
- svn co "$svnrepo"/trunk trunk &&
+ svn_cmd co "$svnrepo"/trunk trunk &&
cd trunk &&
echo bar >> foo &&
- svn ci -m "updated trunk" &&
+ svn_cmd ci -m "updated trunk" &&
cd .. &&
- svn co "$svnrepo"/branches/a a &&
+ svn_cmd co "$svnrepo"/branches/a a &&
cd a &&
echo baz >> a &&
- svn add a &&
- svn ci -m "updated a" &&
+ svn_cmd add a &&
+ svn_cmd ci -m "updated a" &&
cd .. &&
git svn init --stdlayout "$svnrepo"
)
diff --git a/t/t9128-git-svn-cmd-branch.sh b/t/t9128-git-svn-cmd-branch.sh
index 252daa7e1a..807e494a3a 100755
--- a/t/t9128-git-svn-cmd-branch.sh
+++ b/t/t9128-git-svn-cmd-branch.sh
@@ -14,13 +14,13 @@ test_expect_success 'initialize svnrepo' '
cd trunk &&
echo foo > foo &&
cd .. &&
- svn import -m "import for git-svn" . "$svnrepo" >/dev/null &&
+ svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null &&
cd .. &&
rm -rf import &&
- svn co "$svnrepo"/trunk trunk &&
+ svn_cmd co "$svnrepo"/trunk trunk &&
cd trunk &&
echo bar >> foo &&
- svn ci -m "updated trunk" &&
+ svn_cmd ci -m "updated trunk" &&
cd .. &&
rm -rf trunk
)
@@ -57,14 +57,14 @@ test_expect_success 'git svn branch tests' '
'
test_expect_success 'branch uses correct svn-remote' '
- (svn co "$svnrepo" svn &&
+ (svn_cmd co "$svnrepo" svn &&
cd svn &&
mkdir mirror &&
- svn add mirror &&
- svn copy trunk mirror/ &&
- svn copy tags mirror/ &&
- svn copy branches mirror/ &&
- svn ci -m "made mirror" ) &&
+ svn_cmd add mirror &&
+ svn_cmd copy trunk mirror/ &&
+ svn_cmd copy tags mirror/ &&
+ svn_cmd copy branches mirror/ &&
+ svn_cmd ci -m "made mirror" ) &&
rm -rf svn &&
git svn init -s -R mirror --prefix=mirror/ "$svnrepo"/mirror &&
git svn fetch -R mirror &&
diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh
index 8a9dde44d5..b9224bdb20 100755
--- a/t/t9129-git-svn-i18n-commitencoding.sh
+++ b/t/t9129-git-svn-i18n-commitencoding.sh
@@ -15,21 +15,30 @@ compare_git_head_with () {
}
compare_svn_head_with () {
- LC_ALL=en_US.UTF-8 svn log --limit 1 `git svn info --url` | \
- sed -e 1,3d -e "/^-\{1,\}\$/d" >current &&
+ # 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=en_US.UTF-8 svn log `git svn info --url` | perl -w -e '
+ use bytes;
+ $/ = ("-"x72) . "\n";
+ my @x = <STDIN>;
+ @x = split(/\n/, $x[1]);
+ splice(@x, 0, 2);
+ $x[-1] = "";
+ print join("\n", @x);
+ ' > current &&
test_cmp current "$1"
}
-for H in ISO-8859-1 EUCJP ISO-2022-JP
+for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "$H setup" '
mkdir $H &&
- svn import -m "$H test" $H "$svnrepo"/$H &&
+ svn_cmd import -m "$H test" $H "$svnrepo"/$H &&
git svn clone "$svnrepo"/$H $H
'
done
-for H in ISO-8859-1 EUCJP ISO-2022-JP
+for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "$H commit on git side" '
(
@@ -46,7 +55,7 @@ do
'
done
-for H in ISO-8859-1 EUCJP ISO-2022-JP
+for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "$H dcommit to svn" '
(
@@ -61,24 +70,26 @@ do
done
if locale -a |grep -q en_US.utf8; then
- test_expect_success 'ISO-8859-1 should match UTF-8 in svn' '
+ test_set_prereq UTF8
+else
+ say "UTF-8 locale not available, test skipped"
+fi
+
+test_expect_success UTF8 'ISO-8859-1 should match UTF-8 in svn' '
(
- cd ISO-8859-1 &&
+ cd ISO8859-1 &&
compare_svn_head_with "$TEST_DIRECTORY"/t3900/1-UTF-8.txt
)
- '
+'
- for H in EUCJP ISO-2022-JP
- do
- test_expect_success '$H should match UTF-8 in svn' '
+for H in eucJP ISO-2022-JP
+do
+ test_expect_success UTF8 "$H should match UTF-8 in svn" '
(
cd $H &&
compare_svn_head_with "$TEST_DIRECTORY"/t3900/2-UTF-8.txt
)
- '
- done
-else
- say "UTF-8 locale not available, test skipped"
-fi
+ '
+done
test_done
diff --git a/t/t9130-git-svn-authors-file.sh b/t/t9130-git-svn-authors-file.sh
new file mode 100755
index 0000000000..f5abdb3c7f
--- /dev/null
+++ b/t/t9130-git-svn-authors-file.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Eric Wong
+#
+
+test_description='git svn authors file tests'
+
+. ./lib-git-svn.sh
+
+cat > svn-authors <<EOF
+aa = AAAAAAA AAAAAAA <aa@example.com>
+bb = BBBBBBB BBBBBBB <bb@example.com>
+EOF
+
+test_expect_success 'setup svnrepo' '
+ for i in aa bb cc dd
+ do
+ svn_cmd mkdir -m $i --username $i "$svnrepo"/$i
+ done
+ '
+
+test_expect_success 'start import with incomplete authors file' '
+ ! git svn clone --authors-file=svn-authors "$svnrepo" x
+ '
+
+test_expect_success 'imported 2 revisions successfully' '
+ (
+ cd x
+ test "`git rev-list refs/remotes/git-svn | wc -l`" -eq 2 &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn | \
+ grep "^author BBBBBBB BBBBBBB <bb@example\.com> " &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
+ grep "^author AAAAAAA AAAAAAA <aa@example\.com> "
+ )
+ '
+
+cat >> svn-authors <<EOF
+cc = CCCCCCC CCCCCCC <cc@example.com>
+dd = DDDDDDD DDDDDDD <dd@example.com>
+EOF
+
+test_expect_success 'continues to import once authors have been added' '
+ (
+ cd x
+ git svn fetch --authors-file=../svn-authors &&
+ test "`git rev-list refs/remotes/git-svn | wc -l`" -eq 4 &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn | \
+ grep "^author DDDDDDD DDDDDDD <dd@example\.com> " &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
+ grep "^author CCCCCCC CCCCCCC <cc@example\.com> "
+ )
+ '
+
+test_expect_success 'authors-file against globs' '
+ svn_cmd mkdir -m globs --username aa \
+ "$svnrepo"/aa/trunk "$svnrepo"/aa/branches "$svnrepo"/aa/tags &&
+ git svn clone --authors-file=svn-authors -s "$svnrepo"/aa aa-work &&
+ for i in bb ee cc
+ do
+ branch="aa/branches/$i"
+ svn_cmd mkdir -m "$branch" --username $i "$svnrepo/$branch"
+ done
+ '
+
+test_expect_success 'fetch fails on ee' '
+ ( cd aa-work && ! git svn fetch --authors-file=../svn-authors )
+ '
+
+tmp_config_get () {
+ GIT_CONFIG=.git/svn/.metadata git config --get "$1"
+}
+
+test_expect_success 'failure happened without negative side effects' '
+ (
+ cd aa-work &&
+ test 6 -eq "`tmp_config_get svn-remote.svn.branches-maxRev`" &&
+ test 6 -eq "`tmp_config_get svn-remote.svn.tags-maxRev`"
+ )
+ '
+
+cat >> svn-authors <<EOF
+ee = EEEEEEE EEEEEEE <ee@example.com>
+EOF
+
+test_expect_success 'fetch continues after authors-file is fixed' '
+ (
+ cd aa-work &&
+ git svn fetch --authors-file=../svn-authors &&
+ test 8 -eq "`tmp_config_get svn-remote.svn.branches-maxRev`" &&
+ test 8 -eq "`tmp_config_get svn-remote.svn.tags-maxRev`"
+ )
+ '
+
+test_done
diff --git a/t/t9131-git-svn-empty-symlink.sh b/t/t9131-git-svn-empty-symlink.sh
new file mode 100755
index 0000000000..9a24a65b64
--- /dev/null
+++ b/t/t9131-git-svn-empty-symlink.sh
@@ -0,0 +1,110 @@
+#!/bin/sh
+
+test_description='test that git handles an svn repository with empty symlinks'
+
+. ./lib-git-svn.sh
+test_expect_success 'load svn dumpfile' '
+ svnadmin load "$rawsvnrepo" <<EOF
+SVN-fs-dump-format-version: 2
+
+UUID: 60780f9a-7df5-43b4-83ab-60e2c0673ef7
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2008-11-26T07:17:27.590577Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 111
+Content-length: 111
+
+K 7
+svn:log
+V 4
+test
+K 10
+svn:author
+V 12
+normalperson
+K 8
+svn:date
+V 27
+2008-11-26T07:18:03.511836Z
+PROPS-END
+
+Node-path: bar
+Node-kind: file
+Node-action: add
+Prop-content-length: 33
+Text-content-length: 0
+Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
+Content-length: 33
+
+K 11
+svn:special
+V 1
+*
+PROPS-END
+
+Revision-number: 2
+Prop-content-length: 121
+Content-length: 121
+
+K 7
+svn:log
+V 13
+bar => doink
+
+K 10
+svn:author
+V 12
+normalperson
+K 8
+svn:date
+V 27
+2008-11-27T03:55:31.601672Z
+PROPS-END
+
+Node-path: bar
+Node-kind: file
+Node-action: change
+Text-content-length: 10
+Text-content-md5: 92ca4fe7a9721f877f765c252dcd66c9
+Content-length: 10
+
+link doink
+
+EOF
+'
+
+test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" x'
+test_expect_success 'enable broken symlink workaround' \
+ '(cd x && git config svn.brokenSymlinkWorkaround true)'
+test_expect_success '"bar" is an empty file' 'test -f x/bar && ! test -s x/bar'
+test_expect_success 'get "bar" => symlink fix from svn' \
+ '(cd x && git svn rebase)'
+test_expect_success SYMLINKS '"bar" becomes a symlink' 'test -L x/bar'
+
+
+test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" y'
+test_expect_success 'disable broken symlink workaround' \
+ '(cd y && git config svn.brokenSymlinkWorkaround false)'
+test_expect_success '"bar" is an empty file' 'test -f y/bar && ! test -s y/bar'
+test_expect_success 'get "bar" => symlink fix from svn' \
+ '(cd y && git svn rebase)'
+test_expect_success '"bar" does not become a symlink' '! test -L y/bar'
+
+# svn.brokenSymlinkWorkaround is unset
+test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" z'
+test_expect_success '"bar" is an empty file' 'test -f z/bar && ! test -s z/bar'
+test_expect_success 'get "bar" => symlink fix from svn' \
+ '(cd z && git svn rebase)'
+test_expect_success '"bar" does not become a symlink' '! test -L z/bar'
+
+
+test_done
diff --git a/t/t9132-git-svn-broken-symlink.sh b/t/t9132-git-svn-broken-symlink.sh
new file mode 100755
index 0000000000..6c4c90b036
--- /dev/null
+++ b/t/t9132-git-svn-broken-symlink.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+test_description='test that git handles an svn repository with empty symlinks'
+
+. ./lib-git-svn.sh
+test_expect_success 'load svn dumpfile' '
+ svnadmin load "$rawsvnrepo" <<EOF
+SVN-fs-dump-format-version: 2
+
+UUID: 60780f9a-7df5-43b4-83ab-60e2c0673ef7
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2008-11-26T07:17:27.590577Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 111
+Content-length: 111
+
+K 7
+svn:log
+V 4
+test
+K 10
+svn:author
+V 12
+normalperson
+K 8
+svn:date
+V 27
+2008-11-26T07:18:03.511836Z
+PROPS-END
+
+Node-path: bar
+Node-kind: file
+Node-action: add
+Prop-content-length: 33
+Text-content-length: 4
+Text-content-md5: 912ec803b2ce49e4a541068d495ab570
+Content-length: 37
+
+K 11
+svn:special
+V 1
+*
+PROPS-END
+asdf
+
+Revision-number: 2
+Prop-content-length: 121
+Content-length: 121
+
+K 7
+svn:log
+V 13
+bar => doink
+
+K 10
+svn:author
+V 12
+normalperson
+K 8
+svn:date
+V 27
+2008-11-27T03:55:31.601672Z
+PROPS-END
+
+Node-path: bar
+Node-kind: file
+Node-action: change
+Text-content-length: 10
+Text-content-md5: 92ca4fe7a9721f877f765c252dcd66c9
+Content-length: 10
+
+link doink
+
+EOF
+'
+
+test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" x'
+
+test_expect_success SYMLINKS '"bar" is a symlink that points to "asdf"' '
+ test -L x/bar &&
+ (cd x && test xasdf = x"`git cat-file blob HEAD:bar`")
+'
+
+test_expect_success 'get "bar" => symlink fix from svn' '
+ (cd x && git svn rebase)
+'
+
+test_expect_success SYMLINKS '"bar" remains a proper symlink' '
+ test -L x/bar &&
+ (cd x && test xdoink = x"`git cat-file blob HEAD:bar`")
+'
+
+test_done
diff --git a/t/t9133-git-svn-nested-git-repo.sh b/t/t9133-git-svn-nested-git-repo.sh
new file mode 100755
index 0000000000..f3c30e63b7
--- /dev/null
+++ b/t/t9133-git-svn-nested-git-repo.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Eric Wong
+#
+
+test_description='git svn property tests'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup repo with a git repo inside it' '
+ svn_cmd co "$svnrepo" s &&
+ (
+ cd s &&
+ git init &&
+ test -f .git/HEAD &&
+ > .git/a &&
+ echo a > a &&
+ svn_cmd add .git a &&
+ svn_cmd commit -m "create a nested git repo" &&
+ svn_cmd up &&
+ echo hi >> .git/a &&
+ svn_cmd commit -m "modify .git/a" &&
+ svn_cmd up
+ )
+'
+
+test_expect_success 'clone an SVN repo containing a git repo' '
+ git svn clone "$svnrepo" g &&
+ echo a > expect &&
+ test_cmp expect g/a
+'
+
+test_expect_success 'SVN-side change outside of .git' '
+ (
+ cd s &&
+ echo b >> a &&
+ svn_cmd commit -m "SVN-side change outside of .git" &&
+ svn_cmd up &&
+ svn_cmd log -v | fgrep "SVN-side change outside of .git"
+ )
+'
+
+test_expect_success 'update git svn-cloned repo' '
+ (
+ cd g &&
+ git svn rebase &&
+ echo a > expect &&
+ echo b >> expect &&
+ test_cmp a expect &&
+ rm expect
+ )
+'
+
+test_expect_success 'SVN-side change inside of .git' '
+ (
+ cd s &&
+ git add a &&
+ git commit -m "add a inside an SVN repo" &&
+ git log &&
+ svn_cmd add --force .git &&
+ svn_cmd commit -m "SVN-side change inside of .git" &&
+ svn_cmd up &&
+ svn_cmd log -v | fgrep "SVN-side change inside of .git"
+ )
+'
+
+test_expect_success 'update git svn-cloned repo' '
+ (
+ cd g &&
+ git svn rebase &&
+ echo a > expect &&
+ echo b >> expect &&
+ test_cmp a expect &&
+ rm expect
+ )
+'
+
+test_expect_success 'SVN-side change in and out of .git' '
+ (
+ cd s &&
+ echo c >> a &&
+ git add a &&
+ git commit -m "add a inside an SVN repo" &&
+ svn_cmd commit -m "SVN-side change in and out of .git" &&
+ svn_cmd up &&
+ svn_cmd log -v | fgrep "SVN-side change in and out of .git"
+ )
+'
+
+test_expect_success 'update git svn-cloned repo again' '
+ (
+ cd g &&
+ git svn rebase &&
+ echo a > expect &&
+ echo b >> expect &&
+ echo c >> expect &&
+ test_cmp a expect &&
+ rm expect
+ )
+'
+
+test_done
diff --git a/t/t9134-git-svn-ignore-paths.sh b/t/t9134-git-svn-ignore-paths.sh
new file mode 100755
index 0000000000..09ff10cd9b
--- /dev/null
+++ b/t/t9134-git-svn-ignore-paths.sh
@@ -0,0 +1,147 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Vitaly Shukela
+# Copyright (c) 2009 Eric Wong
+#
+
+test_description='git svn property tests'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup test repository' '
+ svn_cmd co "$svnrepo" s &&
+ (
+ cd s &&
+ mkdir qqq www &&
+ echo test_qqq > qqq/test_qqq.txt &&
+ echo test_www > www/test_www.txt &&
+ svn_cmd add qqq &&
+ svn_cmd add www &&
+ svn_cmd commit -m "create some files" &&
+ svn_cmd up &&
+ echo hi >> www/test_www.txt &&
+ svn_cmd commit -m "modify www/test_www.txt" &&
+ svn_cmd up
+ )
+'
+
+test_expect_success 'clone an SVN repository with ignored www directory' '
+ git svn clone --ignore-paths="^www" "$svnrepo" g &&
+ echo test_qqq > expect &&
+ for i in g/*/*.txt; do cat $i >> expect2; done &&
+ test_cmp expect expect2
+'
+
+test_expect_success 'init+fetch an SVN repository with ignored www directory' '
+ git svn init "$svnrepo" c &&
+ ( cd c && git svn fetch --ignore-paths="^www" ) &&
+ rm expect2 &&
+ echo test_qqq > expect &&
+ for i in c/*/*.txt; do cat $i >> expect2; done &&
+ test_cmp expect expect2
+'
+
+test_expect_success 'verify ignore-paths config saved by clone' '
+ (
+ cd g &&
+ git config --get svn-remote.svn.ignore-paths | fgrep "www"
+ )
+'
+
+test_expect_success 'SVN-side change outside of www' '
+ (
+ cd s &&
+ echo b >> qqq/test_qqq.txt &&
+ svn_cmd commit -m "SVN-side change outside of www" &&
+ svn_cmd up &&
+ svn_cmd log -v | fgrep "SVN-side change outside of www"
+ )
+'
+
+test_expect_success 'update git svn-cloned repo (config ignore)' '
+ (
+ cd g &&
+ git svn rebase &&
+ printf "test_qqq\nb\n" > expect &&
+ for i in */*.txt; do cat $i >> expect2; done &&
+ test_cmp expect2 expect &&
+ rm expect expect2
+ )
+'
+
+test_expect_success 'update git svn-cloned repo (option ignore)' '
+ (
+ cd c &&
+ git svn rebase --ignore-paths="^www" &&
+ printf "test_qqq\nb\n" > expect &&
+ for i in */*.txt; do cat $i >> expect2; done &&
+ test_cmp expect2 expect &&
+ rm expect expect2
+ )
+'
+
+test_expect_success 'SVN-side change inside of ignored www' '
+ (
+ cd s &&
+ echo zaq >> www/test_www.txt
+ svn_cmd commit -m "SVN-side change inside of www/test_www.txt" &&
+ svn_cmd up &&
+ svn_cmd log -v | fgrep "SVN-side change inside of www/test_www.txt"
+ )
+'
+
+test_expect_success 'update git svn-cloned repo (config ignore)' '
+ (
+ cd g &&
+ git svn rebase &&
+ printf "test_qqq\nb\n" > expect &&
+ for i in */*.txt; do cat $i >> expect2; done &&
+ test_cmp expect2 expect &&
+ rm expect expect2
+ )
+'
+
+test_expect_success 'update git svn-cloned repo (option ignore)' '
+ (
+ cd c &&
+ git svn rebase --ignore-paths="^www" &&
+ printf "test_qqq\nb\n" > expect &&
+ for i in */*.txt; do cat $i >> expect2; done &&
+ test_cmp expect2 expect &&
+ rm expect expect2
+ )
+'
+
+test_expect_success 'SVN-side change in and out of ignored www' '
+ (
+ cd s &&
+ echo cvf >> www/test_www.txt
+ echo ygg >> qqq/test_qqq.txt
+ svn_cmd commit -m "SVN-side change in and out of ignored www" &&
+ svn_cmd up &&
+ svn_cmd log -v | fgrep "SVN-side change in and out of ignored www"
+ )
+'
+
+test_expect_success 'update git svn-cloned repo again (config ignore)' '
+ (
+ cd g &&
+ git svn rebase &&
+ printf "test_qqq\nb\nygg\n" > expect &&
+ for i in */*.txt; do cat $i >> expect2; done &&
+ test_cmp expect2 expect &&
+ rm expect expect2
+ )
+'
+
+test_expect_success 'update git svn-cloned repo again (option ignore)' '
+ (
+ cd c &&
+ git svn rebase --ignore-paths="^www" &&
+ printf "test_qqq\nb\nygg\n" > expect &&
+ for i in */*.txt; do cat $i >> expect2; done &&
+ test_cmp expect2 expect &&
+ rm expect expect2
+ )
+'
+
+test_done
diff --git a/t/t9135-git-svn-moved-branch-empty-file.sh b/t/t9135-git-svn-moved-branch-empty-file.sh
new file mode 100755
index 0000000000..03705fa4ce
--- /dev/null
+++ b/t/t9135-git-svn-moved-branch-empty-file.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+test_description='test moved svn branch with missing empty files'
+
+. ./lib-git-svn.sh
+test_expect_success 'load svn dumpfile' '
+ svnadmin load "$rawsvnrepo" < "${TEST_DIRECTORY}/t9135/svn.dump"
+ '
+
+test_expect_success 'clone using git svn' 'git svn clone -s "$svnrepo" x'
+
+test_expect_success 'test that b1 exists and is empty' '
+ (cd x && test -f b1 && ! test -s b1)
+ '
+
+test_done
diff --git a/t/t9135/svn.dump b/t/t9135/svn.dump
new file mode 100644
index 0000000000..b51c0ccceb
--- /dev/null
+++ b/t/t9135/svn.dump
@@ -0,0 +1,192 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 1f80e919-e9e3-4d80-a3ae-d9f21095e27b
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2009-02-10T19:23:16.424027Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 123
+Content-length: 123
+
+K 7
+svn:log
+V 20
+init standard layout
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-10T19:23:17.195072Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 121
+Content-length: 121
+
+K 7
+svn:log
+V 18
+branch-b off trunk
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-10T19:23:19.160095Z
+PROPS-END
+
+Node-path: branches/branch-b
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+Prop-content-length: 34
+Content-length: 34
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+
+
+Revision-number: 3
+Prop-content-length: 120
+Content-length: 120
+
+K 7
+svn:log
+V 17
+add empty file b1
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-10T19:23:20.194568Z
+PROPS-END
+
+Node-path: branches/branch-b/b1
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 0
+Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 4
+Prop-content-length: 110
+Content-length: 110
+
+K 7
+svn:log
+V 8
+branch-c
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-10T19:23:21.169100Z
+PROPS-END
+
+Node-path: branches/branch-c
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 3
+Node-copyfrom-path: trunk
+
+
+Revision-number: 5
+Prop-content-length: 126
+Content-length: 126
+
+K 7
+svn:log
+V 23
+oops, wrong branchpoint
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-10T19:23:21.253557Z
+PROPS-END
+
+Node-path: branches/branch-c
+Node-action: delete
+
+
+Revision-number: 6
+Prop-content-length: 127
+Content-length: 127
+
+K 7
+svn:log
+V 24
+branch-c off of branch-b
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-10T19:23:21.314659Z
+PROPS-END
+
+Node-path: branches/branch-c
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 5
+Node-copyfrom-path: branches/branch-b
+Prop-content-length: 34
+Content-length: 34
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+
+
diff --git a/t/t9136-git-svn-recreated-branch-empty-file.sh b/t/t9136-git-svn-recreated-branch-empty-file.sh
new file mode 100755
index 0000000000..733d16e0b2
--- /dev/null
+++ b/t/t9136-git-svn-recreated-branch-empty-file.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+test_description='test recreated svn branch with empty files'
+
+. ./lib-git-svn.sh
+test_expect_success 'load svn dumpfile' '
+ svnadmin load "$rawsvnrepo" < "${TEST_DIRECTORY}/t9136/svn.dump"
+ '
+
+test_expect_success 'clone using git svn' 'git svn clone -s "$svnrepo" x'
+
+test_done
diff --git a/t/t9136/svn.dump b/t/t9136/svn.dump
new file mode 100644
index 0000000000..6b1ce0b2e8
--- /dev/null
+++ b/t/t9136/svn.dump
@@ -0,0 +1,192 @@
+SVN-fs-dump-format-version: 2
+
+UUID: eecae021-8f16-48da-969d-79beb8ae6ea5
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2009-02-22T00:50:56.292890Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 106
+Content-length: 106
+
+K 7
+svn:log
+V 4
+init
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-22T00:50:57.192384Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: tags
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk/file
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 0
+Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 105
+Content-length: 105
+
+K 7
+svn:log
+V 3
+1.0
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-22T00:50:58.124724Z
+PROPS-END
+
+Node-path: tags/1.0
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+
+
+Revision-number: 3
+Prop-content-length: 111
+Content-length: 111
+
+K 7
+svn:log
+V 9
+1.0.1-bad
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-22T00:50:58.151727Z
+PROPS-END
+
+Node-path: tags/1.0.1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 2
+Node-copyfrom-path: tags/1.0
+
+
+Revision-number: 4
+Prop-content-length: 111
+Content-length: 111
+
+K 7
+svn:log
+V 9
+Wrong tag
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-22T00:50:58.167427Z
+PROPS-END
+
+Node-path: tags/1.0.1
+Node-action: delete
+
+
+Revision-number: 5
+Prop-content-length: 113
+Content-length: 113
+
+K 7
+svn:log
+V 10
+1.0-branch
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-22T00:50:58.184498Z
+PROPS-END
+
+Node-path: branches/1.0
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 4
+Node-copyfrom-path: tags/1.0
+
+
+Revision-number: 6
+Prop-content-length: 113
+Content-length: 113
+
+K 7
+svn:log
+V 10
+1.0.1-good
+K 10
+svn:author
+V 8
+john.doe
+K 8
+svn:date
+V 27
+2009-02-22T00:50:58.200695Z
+PROPS-END
+
+Node-path: tags/1.0.1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 5
+Node-copyfrom-path: branches/1.0
+
+
diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh
index fd185011b7..636ca0abb9 100755
--- a/t/t9106-git-svn-dcommit-clobber-series.sh
+++ b/t/t9137-git-svn-dcommit-clobber-series.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
awk "BEGIN { for (i = 1; i < 64; i++) { print i } }" > file
- svn import -m "initial" . "$svnrepo" &&
+ svn_cmd import -m "initial" . "$svnrepo" &&
cd .. &&
git svn init "$svnrepo" &&
git svn fetch &&
@@ -18,14 +18,14 @@ test_expect_success 'initialize repo' '
test_expect_success '(supposedly) non-conflicting change from SVN' '
test x"`sed -n -e 58p < file`" = x58 &&
test x"`sed -n -e 61p < file`" = x61 &&
- svn co "$svnrepo" tmp &&
+ 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 &&
poke file &&
test x"`sed -n -e 58p < file`" = x5588 &&
test x"`sed -n -e 61p < file`" = x6611 &&
- svn commit -m "58 => 5588, 61 => 6611" &&
+ svn_cmd commit -m "58 => 5588, 61 => 6611" &&
cd ..
'
@@ -46,7 +46,7 @@ test_expect_success 'change file but in unrelated area' "
test x\"\`sed -n -e 7p < file\`\" = x7777 &&
git commit -m '4 => 4444, 7 => 7777' file &&
git svn dcommit &&
- svn up tmp &&
+ svn_cmd up tmp &&
cd tmp &&
test x\"\`sed -n -e 4p < file\`\" = x4444 &&
test x\"\`sed -n -e 7p < file\`\" = x7777 &&
diff --git a/t/t9138-git-svn-authors-prog.sh b/t/t9138-git-svn-authors-prog.sh
new file mode 100755
index 0000000000..a4b00f2a3f
--- /dev/null
+++ b/t/t9138-git-svn-authors-prog.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Eric Wong, Mark Lodato
+#
+
+test_description='git svn authors prog tests'
+
+. ./lib-git-svn.sh
+
+cat > svn-authors-prog <<'EOF'
+#!/usr/bin/perl
+$_ = shift;
+if (s/-sub$//) {
+ print "$_ <$_\@sub.example.com>\n";
+}
+else {
+ print "$_ <$_\@example.com>\n";
+}
+EOF
+chmod +x svn-authors-prog
+
+cat > svn-authors <<'EOF'
+ff = FFFFFFF FFFFFFF <fFf@other.example.com>
+EOF
+
+test_expect_success 'setup svnrepo' '
+ for i in aa bb cc-sub dd-sub ee-foo ff
+ do
+ svn mkdir -m $i --username $i "$svnrepo"/$i
+ done
+ '
+
+test_expect_success 'import authors with prog and file' '
+ git svn clone --authors-prog=./svn-authors-prog \
+ --authors-file=svn-authors "$svnrepo" x
+ '
+
+test_expect_success 'imported 6 revisions successfully' '
+ (
+ cd x
+ test "`git rev-list refs/remotes/git-svn | wc -l`" -eq 6
+ )
+ '
+
+test_expect_success 'authors-prog ran correctly' '
+ (
+ cd x
+ git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
+ grep "^author ee-foo <ee-foo@example\.com> " &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn~2 | \
+ grep "^author dd <dd@sub\.example\.com> " &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn~3 | \
+ grep "^author cc <cc@sub\.example\.com> " &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn~4 | \
+ grep "^author bb <bb@example\.com> " &&
+ git rev-list -1 --pretty=raw refs/remotes/git-svn~5 | \
+ grep "^author aa <aa@example\.com> "
+ )
+ '
+
+test_expect_success 'authors-file overrode authors-prog' '
+ (
+ cd x
+ git rev-list -1 --pretty=raw refs/remotes/git-svn | \
+ grep "^author FFFFFFF FFFFFFF <fFf@other\.example\.com> "
+ )
+ '
+
+test_done
diff --git a/t/t9139-git-svn-non-utf8-commitencoding.sh b/t/t9139-git-svn-non-utf8-commitencoding.sh
new file mode 100755
index 0000000000..f337959ccc
--- /dev/null
+++ b/t/t9139-git-svn-non-utf8-commitencoding.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Eric Wong
+
+test_description='git svn refuses to dcommit non-UTF8 messages'
+
+. ./lib-git-svn.sh
+
+# ISO-2022-JP can pass for valid UTF-8, so skipping that in this test
+
+for H in ISO8859-1 eucJP
+do
+ test_expect_success "$H setup" '
+ mkdir $H &&
+ svn_cmd import -m "$H test" $H "$svnrepo"/$H &&
+ git svn clone "$svnrepo"/$H $H
+ '
+done
+
+for H in ISO8859-1 eucJP
+do
+ test_expect_success "$H commit on git side" '
+ (
+ cd $H &&
+ git config i18n.commitencoding $H &&
+ git checkout -b t refs/remotes/git-svn &&
+ echo $H >F &&
+ git add F &&
+ git commit -a -F "$TEST_DIRECTORY"/t3900/$H.txt &&
+ E=$(git cat-file commit HEAD | sed -ne "s/^encoding //p") &&
+ test "z$E" = "z$H"
+ )
+ '
+done
+
+for H in ISO8859-1 eucJP
+do
+ test_expect_success "$H dcommit to svn" '
+ (
+ cd $H &&
+ git config --unset i18n.commitencoding &&
+ ! git svn dcommit
+ )
+ '
+done
+
+test_done
diff --git a/t/t9140-git-svn-reset.sh b/t/t9140-git-svn-reset.sh
new file mode 100755
index 0000000000..0735526d4b
--- /dev/null
+++ b/t/t9140-git-svn-reset.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Ben Jackson
+#
+
+test_description='git svn reset'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup test repository' '
+ svn_cmd co "$svnrepo" s &&
+ (
+ cd s &&
+ mkdir vis &&
+ echo always visible > vis/vis.txt &&
+ svn_cmd add vis &&
+ svn_cmd commit -m "create visible files" &&
+ mkdir hid &&
+ echo initially hidden > hid/hid.txt &&
+ svn_cmd add hid &&
+ svn_cmd commit -m "create initially hidden files" &&
+ svn_cmd up &&
+ echo mod >> vis/vis.txt &&
+ svn_cmd commit -m "modify vis" &&
+ svn_cmd up
+ )
+'
+
+test_expect_success 'clone SVN repository with hidden directory' '
+ git svn init "$svnrepo" g &&
+ ( cd g && git svn fetch --ignore-paths="^hid" )
+'
+
+test_expect_success 'modify hidden file in SVN repo' '
+ ( cd s &&
+ echo mod hidden >> hid/hid.txt &&
+ svn_cmd commit -m "modify hid" &&
+ svn_cmd up
+ )
+'
+
+test_expect_success 'fetch fails on modified hidden file' '
+ ( cd g &&
+ git svn find-rev refs/remotes/git-svn > ../expect &&
+ ! git svn fetch 2> ../errors &&
+ git svn find-rev refs/remotes/git-svn > ../expect2 ) &&
+ fgrep "not found in commit" errors &&
+ test_cmp expect expect2
+'
+
+test_expect_success 'reset unwinds back to r1' '
+ ( cd g &&
+ git svn reset -r1 &&
+ git svn find-rev refs/remotes/git-svn > ../expect2 ) &&
+ echo 1 >expect &&
+ test_cmp expect expect2
+'
+
+test_expect_success 'refetch succeeds not ignoring any files' '
+ ( cd g &&
+ git svn fetch &&
+ git svn rebase &&
+ fgrep "mod hidden" hid/hid.txt
+ )
+'
+
+test_done
diff --git a/t/t9141-git-svn-multiple-branches.sh b/t/t9141-git-svn-multiple-branches.sh
new file mode 100755
index 0000000000..3cd06718eb
--- /dev/null
+++ b/t/t9141-git-svn-multiple-branches.sh
@@ -0,0 +1,122 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Marc Branchaud
+#
+
+test_description='git svn multiple branch and tag paths in the svn repo'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup svnrepo' '
+ mkdir project \
+ project/trunk \
+ project/b_one \
+ project/b_two \
+ project/tags_A \
+ project/tags_B &&
+ echo 1 > project/trunk/a.file &&
+ svn_cmd import -m "$test_description" project "$svnrepo/project" &&
+ rm -rf project &&
+ svn_cmd cp -m "Branch 1" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_one/first" &&
+ svn_cmd cp -m "Tag 1" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/1.0" &&
+ svn_cmd co "$svnrepo/project" svn_project &&
+ ( cd svn_project &&
+ echo 2 > trunk/a.file &&
+ svn_cmd ci -m "Change 1" trunk/a.file &&
+ svn_cmd cp -m "Branch 2" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_one/second" &&
+ svn_cmd cp -m "Tag 2" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/2.0" &&
+ echo 3 > trunk/a.file &&
+ svn_cmd ci -m "Change 2" trunk/a.file &&
+ svn_cmd cp -m "Branch 3" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_two/1" &&
+ svn_cmd cp -m "Tag 3" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/3.0" &&
+ echo 4 > trunk/a.file &&
+ svn_cmd ci -m "Change 3" trunk/a.file &&
+ svn_cmd cp -m "Branch 4" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_two/2" &&
+ svn_cmd cp -m "Tag 4" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/4.0" &&
+ svn_cmd up &&
+ echo 5 > b_one/first/a.file &&
+ svn_cmd ci -m "Change 4" b_one/first/a.file &&
+ svn_cmd cp -m "Tag 5" "$svnrepo/project/b_one/first" \
+ "$svnrepo/project/tags_B/v5" &&
+ echo 6 > b_one/second/a.file &&
+ svn_cmd ci -m "Change 5" b_one/second/a.file &&
+ svn_cmd cp -m "Tag 6" "$svnrepo/project/b_one/second" \
+ "$svnrepo/project/tags_B/v6" &&
+ echo 7 > b_two/1/a.file &&
+ svn_cmd ci -m "Change 6" b_two/1/a.file &&
+ svn_cmd cp -m "Tag 7" "$svnrepo/project/b_two/1" \
+ "$svnrepo/project/tags_B/v7" &&
+ echo 8 > b_two/2/a.file &&
+ svn_cmd ci -m "Change 7" b_two/2/a.file &&
+ svn_cmd cp -m "Tag 8" "$svnrepo/project/b_two/2" \
+ "$svnrepo/project/tags_B/v8"
+ )
+'
+
+test_expect_success 'clone multiple branch and tag paths' '
+ git svn clone -T trunk \
+ -b b_one/* --branches b_two/* \
+ -t tags_A/* --tags tags_B \
+ "$svnrepo/project" git_project &&
+ ( cd git_project &&
+ git rev-parse refs/remotes/first &&
+ git rev-parse refs/remotes/second &&
+ git rev-parse refs/remotes/1 &&
+ git rev-parse refs/remotes/2 &&
+ git rev-parse refs/remotes/tags/1.0 &&
+ git rev-parse refs/remotes/tags/2.0 &&
+ git rev-parse refs/remotes/tags/3.0 &&
+ git rev-parse refs/remotes/tags/4.0 &&
+ git rev-parse refs/remotes/tags/v5 &&
+ git rev-parse refs/remotes/tags/v6 &&
+ git rev-parse refs/remotes/tags/v7 &&
+ git rev-parse refs/remotes/tags/v8
+ )
+'
+
+test_expect_success 'Multiple branch or tag paths require -d' '
+ ( cd git_project &&
+ test_must_fail git svn branch -m "No new branch" Nope &&
+ test_must_fail git svn tag -m "No new tag" Tagless &&
+ test_must_fail git rev-parse refs/remotes/Nope &&
+ test_must_fail git rev-parse refs/remotes/tags/Tagless
+ ) &&
+ ( cd svn_project &&
+ svn_cmd up &&
+ test_must_fail test -d b_one/Nope &&
+ test_must_fail test -d b_two/Nope &&
+ test_must_fail test -d tags_A/Tagless &&
+ test_must_fail test -d tags_B/Tagless
+ )
+'
+
+test_expect_success 'create new branches and tags' '
+ ( cd git_project &&
+ git svn branch -m "New branch 1" -d b_one New1 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e b_one/New1/a.file ) &&
+
+ ( cd git_project &&
+ git svn branch -m "New branch 2" -d b_two New2 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e b_two/New2/a.file ) &&
+
+ ( cd git_project &&
+ git svn branch -t -m "New tag 1" -d tags_A Tag1 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e tags_A/Tag1/a.file ) &&
+
+ ( cd git_project &&
+ git svn tag -m "New tag 2" -d tags_B Tag2 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e tags_B/Tag2/a.file )
+'
+
+test_done
diff --git a/t/t9142-git-svn-shallow-clone.sh b/t/t9142-git-svn-shallow-clone.sh
new file mode 100755
index 0000000000..1236accd99
--- /dev/null
+++ b/t/t9142-git-svn-shallow-clone.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Eric Wong
+#
+
+test_description='git svn shallow clone'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup test repository' '
+ svn_cmd mkdir -m "create standard layout" \
+ "$svnrepo"/trunk "$svnrepo"/branches "$svnrepo"/tags &&
+ svn_cmd cp -m "branch off trunk" \
+ "$svnrepo"/trunk "$svnrepo"/branches/a &&
+ svn_cmd co "$svnrepo"/branches/a &&
+ (
+ cd a &&
+ > foo &&
+ svn_cmd add foo &&
+ svn_cmd commit -m "add foo"
+ )
+'
+
+start_httpd
+
+test_expect_success 'clone trunk with "-r HEAD"' '
+ git svn clone -r HEAD "$svnrepo/trunk" g &&
+ ( cd g && git rev-parse --symbolic --verify HEAD )
+'
+
+stop_httpd
+
+test_done
diff --git a/t/t9143-git-svn-gc.sh b/t/t9143-git-svn-gc.sh
new file mode 100755
index 0000000000..f2ba2d1da3
--- /dev/null
+++ b/t/t9143-git-svn-gc.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Robert Allan Zeh
+
+test_description='git svn gc basic tests'
+
+. ./lib-git-svn.sh
+
+test_expect_success 'setup directories and test repo' '
+ mkdir import &&
+ mkdir tmp &&
+ echo "Sample text for Subversion repository." > import/test.txt &&
+ svn_cmd import -m "import for git svn" import "$svnrepo" > /dev/null
+ '
+
+test_expect_success 'checkout working copy from svn' \
+ 'svn_cmd co "$svnrepo" test_wc'
+
+test_expect_success 'set some properties to create an unhandled.log file' '
+ (
+ cd test_wc &&
+ svn_cmd propset foo bar test.txt &&
+ svn_cmd commit -m "property set"
+ )'
+
+test_expect_success 'Setup repo' 'git svn init "$svnrepo"'
+
+test_expect_success 'Fetch repo' 'git svn fetch'
+
+test_expect_success 'make backup copy of unhandled.log' '
+ cp .git/svn/git-svn/unhandled.log tmp
+ '
+
+test_expect_success 'create leftover index' '> .git/svn/git-svn/index'
+
+test_expect_success 'git svn gc runs' 'git svn gc'
+
+test_expect_success 'git svn index removed' '! test -f .git/svn/git-svn/index'
+
+if perl -MCompress::Zlib -e 0 2>/dev/null
+then
+ test_expect_success 'git svn gc produces a valid gzip file' '
+ gunzip .git/svn/git-svn/unhandled.log.gz
+ '
+else
+ say "Perl Compress::Zlib unavailable, skipping gunzip test"
+fi
+
+test_expect_success 'git svn gc does not change unhandled.log files' '
+ test_cmp .git/svn/git-svn/unhandled.log tmp/unhandled.log
+ '
+
+test_done
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 245a7c3662..fc3795dc98 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -6,12 +6,16 @@ test_description='Test export of commits to CVS'
. ./test-lib.sh
+if ! test_have_prereq PERL; then
+ say 'skipping git cvsexportcommit tests, perl not available'
+ test_done
+fi
+
cvs >/dev/null 2>&1
if test $? -ne 1
then
- test_expect_success 'skipping git cvsexportcommit tests, cvs not found' :
+ say 'skipping git cvsexportcommit tests, cvs not found'
test_done
- exit
fi
CVSROOT=$(pwd)/cvsroot
@@ -225,11 +229,12 @@ test_expect_success \
test_must_fail git cvsexportcommit -c $id
)'
-case "$(git config --bool core.filemode)" in
-false)
- ;;
-*)
-test_expect_success \
+if ! test "$(git config --bool core.filemode)" = false
+then
+ test_set_prereq FILEMODE
+fi
+
+test_expect_success FILEMODE \
'Retain execute bit' \
'mkdir G &&
echo executeon >G/on &&
@@ -243,8 +248,6 @@ test_expect_success \
test -x G/on &&
! test -x G/off
)'
- ;;
-esac
test_expect_success '-w option should work with relative GIT_DIR' '
mkdir W &&
@@ -285,6 +288,27 @@ test_expect_success 'check files before directories' '
'
+test_expect_success 're-commit a removed filename which remains in CVS attic' '
+
+ (cd "$CVSWORK" &&
+ echo >attic_gremlin &&
+ cvs -Q add attic_gremlin &&
+ cvs -Q ci -m "added attic_gremlin" &&
+ rm attic_gremlin &&
+ cvs -Q rm attic_gremlin &&
+ cvs -Q ci -m "removed attic_gremlin") &&
+
+ echo > attic_gremlin &&
+ git add attic_gremlin &&
+ git commit -m "Added attic_gremlin" &&
+ git cvsexportcommit -w "$CVSWORK" -c HEAD &&
+ (cd "$CVSWORK"; cvs -Q update -d) &&
+ test -f "$CVSWORK/attic_gremlin"
+'
+
+# the state of the CVS sandbox may be indeterminate for ' space'
+# after this test on some platforms / with some versions of CVS
+# consider adding new tests above this point
test_expect_success 'commit a file with leading spaces in the name' '
echo space > " space" &&
@@ -292,7 +316,7 @@ test_expect_success 'commit a file with leading spaces in the name' '
git commit -m "Add a file with a leading space" &&
id=$(git rev-parse HEAD) &&
git cvsexportcommit -w "$CVSWORK" -c $id &&
- check_entries "$CVSWORK" " space/1.1/|DS/1.1/|release-notes/1.2/" &&
+ check_entries "$CVSWORK" " space/1.1/|DS/1.1/|attic_gremlin/1.3/|release-notes/1.2/" &&
test_cmp "$CVSWORK/ space" " space"
'
diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh
index 86c376088c..356964e53a 100755
--- a/t/t9301-fast-export.sh
+++ b/t/t9301-fast-export.sh
@@ -8,6 +8,9 @@ test_description='git fast-export'
test_expect_success 'setup' '
+ echo break it > file0 &&
+ git add file0 &&
+ test_tick &&
echo Wohlauf > file &&
git add file &&
test_tick &&
@@ -57,15 +60,15 @@ test_expect_success 'fast-export master~2..master' '
(cd new &&
git fast-import &&
test $MASTER != $(git rev-parse --verify refs/heads/partial) &&
- git diff master..partial &&
- git diff master^..partial^ &&
+ git diff --exit-code master partial &&
+ git diff --exit-code master^ partial^ &&
test_must_fail git rev-parse partial~2)
'
test_expect_success 'iso-8859-1' '
- git config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.commitencoding ISO8859-1 &&
# use author and committer name in ISO-8859-1 to match it.
. "$TEST_DIRECTORY"/t3901-8859-1.txt &&
test_tick &&
@@ -259,4 +262,113 @@ test_expect_success 'cope with tagger-less tags' '
'
+test_expect_success 'setup for limiting exports by PATH' '
+ mkdir limit-by-paths &&
+ cd limit-by-paths &&
+ git init &&
+ echo hi > there &&
+ git add there &&
+ git commit -m "First file" &&
+ echo foo > bar &&
+ git add bar &&
+ git commit -m "Second file" &&
+ git tag -a -m msg mytag &&
+ echo morefoo >> bar &&
+ git add bar &&
+ git commit -m "Change to second file" &&
+ cd ..
+'
+
+cat > limit-by-paths/expected << EOF
+blob
+mark :1
+data 3
+hi
+
+reset refs/tags/mytag
+commit refs/tags/mytag
+mark :2
+author A U Thor <author@example.com> 1112912713 -0700
+committer C O Mitter <committer@example.com> 1112912713 -0700
+data 11
+First file
+M 100644 :1 there
+
+EOF
+
+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 &&
+ cd ..
+'
+
+cat >> limit-by-paths/expected << EOF
+tag mytag
+from :2
+tagger C O Mitter <committer@example.com> 1112912713 -0700
+data 4
+msg
+
+EOF
+
+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 &&
+ cd ..
+'
+
+cat > limit-by-paths/expected << EOF
+blob
+mark :1
+data 4
+foo
+
+blob
+mark :2
+data 3
+hi
+
+reset refs/heads/master
+commit refs/heads/master
+mark :3
+author A U Thor <author@example.com> 1112912713 -0700
+committer C O Mitter <committer@example.com> 1112912713 -0700
+data 12
+Second file
+M 100644 :1 bar
+M 100644 :2 there
+
+EOF
+
+test_expect_failure 'no exact-ref revisions included' '
+ cd limit-by-paths &&
+ git fast-export master~2..master~1 > output &&
+ test_cmp output expected &&
+ cd ..
+'
+
+
+test_expect_success 'set-up a few more tags for tag export tests' '
+ git checkout -f master &&
+ HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` &&
+ git tag tree_tag -m "tagging a tree" $HEAD_TREE &&
+ git tag -a tree_tag-obj -m "tagging a tree" $HEAD_TREE &&
+ git tag tag-obj_tag -m "tagging a tag" tree_tag-obj &&
+ git tag -a tag-obj_tag-obj -m "tagging a tag" tree_tag-obj
+'
+
+test_expect_success 'tree_tag' '
+ mkdir result &&
+ (cd result && git init) &&
+ git fast-export tree_tag > fe-stream &&
+ (cd result && git fast-import < ../fe-stream)
+'
+
+# NEEDSWORK: not just check return status, but validate the output
+test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj'
+test_expect_success 'tag-obj_tag' 'git fast-export tag-obj_tag'
+test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj'
+
test_done
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 6a37f71d11..64f947d75b 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -10,17 +10,19 @@ cvs CLI client via git-cvsserver server'
. ./test-lib.sh
+if ! test_have_prereq PERL; then
+ say 'skipping git cvsserver tests, perl not available'
+ test_done
+fi
cvs >/dev/null 2>&1
if test $? -ne 1
then
- test_expect_success 'skipping git-cvsserver tests, cvs not found' :
+ say 'skipping git-cvsserver tests, cvs not found'
test_done
- exit
fi
perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
- test_expect_success 'skipping git-cvsserver tests, Perl SQLite interface unavailable' :
+ say 'skipping git-cvsserver tests, Perl SQLite interface unavailable'
test_done
- exit
}
unset GIT_DIR GIT_CONFIG
@@ -44,7 +46,7 @@ test_expect_success 'setup' '
git add secondrootfile &&
git commit -m "second root") &&
git pull secondroot master &&
- git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
+ git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log"
'
@@ -267,7 +269,7 @@ test_expect_success 'gitcvs.ext.dbname' \
rm -fr "$SERVERDIR"
cd "$WORKDIR" &&
-git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
+git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" ||
exit 1
diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh
index e27a1c5f85..aca40c1b1f 100755
--- a/t/t9401-git-cvsserver-crlf.sh
+++ b/t/t9401-git-cvsserver-crlf.sh
@@ -49,14 +49,17 @@ not_present() {
cvs >/dev/null 2>&1
if test $? -ne 1
then
- test_expect_success 'skipping git-cvsserver tests, cvs not found' :
+ say 'skipping git-cvsserver tests, cvs not found'
+ test_done
+fi
+if ! test_have_prereq PERL
+then
+ say 'skipping git-cvsserver tests, perl not available'
test_done
- exit
fi
perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
- test_expect_success 'skipping git-cvsserver tests, Perl SQLite interface unavailable' :
+ say 'skipping git-cvsserver tests, Perl SQLite interface unavailable'
test_done
- exit
}
unset GIT_DIR GIT_CONFIG
@@ -84,7 +87,7 @@ test_expect_success 'setup' '
echo "subdir/file.h crlf" >> .gitattributes &&
git add .gitattributes textfile.c binfile.bin mixedUp.c subdir/* &&
git commit -q -m "First Commit" &&
- git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
+ git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log"
'
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 43cd6eecba..627518108a 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -43,9 +43,11 @@ gitweb_run () {
GATEWAY_INTERFACE="CGI/1.1"
HTTP_ACCEPT="*/*"
REQUEST_METHOD="GET"
+ SCRIPT_NAME="$TEST_DIRECTORY/../gitweb/gitweb.perl"
QUERY_STRING=""$1""
PATH_INFO=""$2""
- export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD QUERY_STRING PATH_INFO
+ export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD \
+ SCRIPT_NAME QUERY_STRING PATH_INFO
GITWEB_CONFIG=$(pwd)/gitweb_config.perl
export GITWEB_CONFIG
@@ -54,27 +56,23 @@ 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 -- "$TEST_DIRECTORY/../gitweb/gitweb.perl" \
+ perl -- "$SCRIPT_NAME" \
>/dev/null 2>gitweb.log &&
if grep "^[[]" gitweb.log >/dev/null 2>&1; then false; else true; fi
# gitweb.log is left for debugging
}
-safe_chmod () {
- chmod "$1" "$2" &&
- if [ "$(git config --get core.filemode)" = false ]
- then
- git update-index --chmod="$1" "$2"
- fi
-}
-
. ./test-lib.sh
+if ! test_have_prereq PERL; then
+ say 'skipping gitweb tests, perl not available'
+ test_done
+fi
+
perl -MEncode -e 'decode_utf8("", Encode::FB_CROAK)' >/dev/null 2>&1 || {
- test_expect_success 'skipping gitweb tests, perl version is too old' :
+ say 'skipping gitweb tests, perl version is too old'
test_done
- exit
}
gitweb_init
@@ -240,7 +238,7 @@ test_debug 'cat gitweb.log'
test_expect_success \
'commitdiff(0): mode change' \
- 'safe_chmod +x new_file &&
+ 'test_chmod +x new_file &&
git commit -a -m "Mode changed." &&
gitweb_run "p=.git;a=commitdiff"'
test_debug 'cat gitweb.log'
@@ -252,7 +250,7 @@ test_expect_success \
gitweb_run "p=.git;a=commitdiff"'
test_debug 'cat gitweb.log'
-test_expect_success \
+test_expect_success SYMLINKS \
'commitdiff(0): file to symlink' \
'rm renamed_file &&
ln -s file renamed_file &&
@@ -279,7 +277,7 @@ test_debug 'cat gitweb.log'
test_expect_success \
'commitdiff(0): mode change and modified' \
'echo "New line" >> file2 &&
- safe_chmod +x file2 &&
+ test_chmod +x file2 &&
git commit -a -m "Mode change and modification." &&
gitweb_run "p=.git;a=commitdiff"'
test_debug 'cat gitweb.log'
@@ -306,7 +304,7 @@ test_expect_success \
'commitdiff(0): renamed, mode change and modified' \
'git mv file3 file2 &&
echo "Propter nomen suum." >> file2 &&
- safe_chmod +x file2 &&
+ test_chmod +x file2 &&
git commit -a -m "File rename, mode change and modification." &&
gitweb_run "p=.git;a=commitdiff"'
test_debug 'cat gitweb.log'
@@ -314,7 +312,7 @@ test_debug 'cat gitweb.log'
# ----------------------------------------------------------------------
# commitdiff testing (taken from t4114-apply-typechange.sh)
-test_expect_success 'setup typechange commits' '
+test_expect_success SYMLINKS 'setup typechange commits' '
echo "hello world" > foo &&
echo "hi planet" > bar &&
git update-index --add foo bar &&
@@ -423,10 +421,15 @@ test_expect_success \
git add 03-new &&
git mv 04-rename-from 04-rename-to &&
echo "Changed" >> 04-rename-to &&
- safe_chmod +x 05-mode-change &&
- rm -f 06-file-or-symlink && ln -s 01-change 06-file-or-symlink &&
+ test_chmod +x 05-mode-change &&
+ rm -f 06-file-or-symlink &&
+ if test_have_prereq SYMLINKS; then
+ ln -s 01-change 06-file-or-symlink
+ else
+ printf %s 01-change > 06-file-or-symlink
+ fi &&
echo "Changed and have mode changed" > 07-change-mode-change &&
- safe_chmod +x 07-change-mode-change &&
+ test_chmod +x 07-change-mode-change &&
git commit -a -m "Large commit" &&
git checkout master'
@@ -587,7 +590,7 @@ test_expect_success \
echo "ISO-8859-1" >> file &&
git add file &&
git config i18n.commitencoding ISO-8859-1 &&
- git commit -F "$TEST_DIRECTORY"/t3900/ISO-8859-1.txt &&
+ git commit -F "$TEST_DIRECTORY"/t3900/ISO8859-1.txt &&
git config --unset i18n.commitencoding &&
gitweb_run "p=.git;a=commit"'
test_debug 'cat gitweb.log'
@@ -657,22 +660,40 @@ cat >>gitweb_config.perl <<EOF
\$feature{'blame'}{'override'} = 1;
\$feature{'snapshot'}{'override'} = 1;
+\$feature{'avatar'}{'override'} = 1;
EOF
test_expect_success \
+ 'config override: tree view, features not overridden in repo config' \
+ 'gitweb_run "p=.git;a=tree"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
'config override: tree view, features disabled in repo config' \
'git config gitweb.blame no &&
git config gitweb.snapshot none &&
+ git config gitweb.avatar gravatar &&
gitweb_run "p=.git;a=tree"'
test_debug 'cat gitweb.log'
test_expect_success \
- 'config override: tree view, features enabled in repo config' \
+ 'config override: tree view, features enabled in repo config (1)' \
'git config gitweb.blame yes &&
git config gitweb.snapshot "zip,tgz, tbz2" &&
gitweb_run "p=.git;a=tree"'
test_debug 'cat gitweb.log'
+cat >.git/config <<\EOF
+# testing noval and alternate separator
+[gitweb]
+ blame
+ snapshot = zip tgz
+EOF
+test_expect_success \
+ 'config override: tree view, features enabled in repo config (2)' \
+ 'gitweb_run "p=.git;a=tree"'
+test_debug 'cat gitweb.log'
+
# ----------------------------------------------------------------------
# non-ASCII in README.html
diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
index d2379e7f62..363345faef 100755
--- a/t/t9600-cvsimport.sh
+++ b/t/t9600-cvsimport.sh
@@ -1,44 +1,22 @@
#!/bin/sh
test_description='git cvsimport basic tests'
-. ./test-lib.sh
+. ./lib-cvs.sh
-CVSROOT=$(pwd)/cvsroot
-export CVSROOT
-unset CVS_SERVER
-# for clean cvsps cache
-HOME=$(pwd)
-export HOME
-
-if ! type cvs >/dev/null 2>&1
-then
- say 'skipping cvsimport tests, cvs not found'
+if ! test_have_prereq PERL; then
+ say 'skipping git cvsimport tests, perl not available'
test_done
- exit
fi
-cvsps_version=`cvsps -h 2>&1 | sed -ne 's/cvsps version //p'`
-case "$cvsps_version" in
-2.1 | 2.2*)
- ;;
-'')
- say 'skipping cvsimport tests, cvsps not found'
- test_done
- exit
- ;;
-*)
- say 'skipping cvsimport tests, unsupported cvsps version'
- test_done
- exit
- ;;
-esac
+CVSROOT=$(pwd)/cvsroot
+export CVSROOT
-test_expect_success 'setup cvsroot' 'cvs init'
+test_expect_success 'setup cvsroot' '$CVS init'
test_expect_success 'setup a cvs module' '
mkdir "$CVSROOT/module" &&
- cvs co -d module-cvs module &&
+ $CVS co -d module-cvs module &&
cd module-cvs &&
cat <<EOF >o_fortuna &&
O Fortuna
@@ -57,13 +35,13 @@ egestatem,
potestatem
dissolvit ut glaciem.
EOF
- cvs add o_fortuna &&
+ $CVS add o_fortuna &&
cat <<EOF >message &&
add "O Fortuna" lyrics
These public domain lyrics make an excellent sample text.
EOF
- cvs commit -F message &&
+ $CVS commit -F message &&
cd ..
'
@@ -101,7 +79,7 @@ translate to English
My Latin is terrible.
EOF
- cvs commit -F message &&
+ $CVS commit -F message &&
cd ..
'
@@ -119,8 +97,8 @@ test_expect_success 'update cvs module' '
cd module-cvs &&
echo 1 >tick &&
- cvs add tick &&
- cvs commit -m 1
+ $CVS add tick &&
+ $CVS commit -m 1
cd ..
'
@@ -138,7 +116,7 @@ test_expect_success 'cvsimport.module config works' '
test_expect_success 'import from a CVS working tree' '
- cvs co -d import-from-wt module &&
+ $CVS co -d import-from-wt module &&
cd import-from-wt &&
git cvsimport -a -z0 &&
echo 1 >expect &&
@@ -148,4 +126,6 @@ test_expect_success 'import from a CVS working tree' '
'
+test_expect_success 'test entire HEAD' 'test_cmp_branch_tree master'
+
test_done
diff --git a/t/t9601-cvsimport-vendor-branch.sh b/t/t9601-cvsimport-vendor-branch.sh
new file mode 100755
index 0000000000..3afaf56526
--- /dev/null
+++ b/t/t9601-cvsimport-vendor-branch.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+# Description of the files in the repository:
+#
+# imported-once.txt:
+#
+# Imported once. 1.1 and 1.1.1.1 should be identical.
+#
+# imported-twice.txt:
+#
+# Imported twice. HEAD should reflect the contents of the
+# second import (i.e., have the same contents as 1.1.1.2).
+#
+# imported-modified.txt:
+#
+# Imported, then modified on HEAD. HEAD should reflect the
+# modification.
+#
+# imported-modified-imported.txt:
+#
+# Imported, then modified on HEAD, then imported again.
+#
+# added-imported.txt,v:
+#
+# Added with 'cvs add' to create 1.1, then imported with
+# completely different contents to create 1.1.1.1, therefore the
+# vendor branch was never the default branch.
+#
+# imported-anonymously.txt:
+#
+# Like imported-twice.txt, but with a vendor branch whose branch
+# tag has been removed.
+
+test_description='git cvsimport handling of vendor branches'
+. ./lib-cvs.sh
+
+CVSROOT="$TEST_DIRECTORY"/t9601/cvsroot
+export CVSROOT
+
+test_expect_success 'import a module with a vendor branch' '
+
+ git cvsimport -C module-git module
+
+'
+
+test_expect_success 'check HEAD out of cvs repository' 'test_cvs_co master'
+
+test_expect_success 'check master out of git repository' 'test_git_co master'
+
+test_expect_success 'check a file that was imported once' '
+
+ test_cmp_branch_file master imported-once.txt
+
+'
+
+test_expect_failure 'check a file that was imported twice' '
+
+ test_cmp_branch_file master imported-twice.txt
+
+'
+
+test_expect_success 'check a file that was imported then modified on HEAD' '
+
+ test_cmp_branch_file master imported-modified.txt
+
+'
+
+test_expect_success 'check a file that was imported, modified, then imported again' '
+
+ test_cmp_branch_file master imported-modified-imported.txt
+
+'
+
+test_expect_success 'check a file that was added to HEAD then imported' '
+
+ test_cmp_branch_file master added-imported.txt
+
+'
+
+test_expect_success 'a vendor branch whose tag has been removed' '
+
+ test_cmp_branch_file master imported-anonymously.txt
+
+'
+
+test_done
diff --git a/t/t9601/cvsroot/.gitattributes b/t/t9601/cvsroot/.gitattributes
new file mode 100644
index 0000000000..562b12e16e
--- /dev/null
+++ b/t/t9601/cvsroot/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/t/t9601/cvsroot/CVSROOT/.gitignore b/t/t9601/cvsroot/CVSROOT/.gitignore
new file mode 100644
index 0000000000..3bb9b34173
--- /dev/null
+++ b/t/t9601/cvsroot/CVSROOT/.gitignore
@@ -0,0 +1,2 @@
+history
+val-tags
diff --git a/t/t9601/cvsroot/module/added-imported.txt,v b/t/t9601/cvsroot/module/added-imported.txt,v
new file mode 100644
index 0000000000..5f83072ea4
--- /dev/null
+++ b/t/t9601/cvsroot/module/added-imported.txt,v
@@ -0,0 +1,44 @@
+head 1.1;
+access;
+symbols
+ vtag-4:1.1.1.1
+ vbranchA:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 2004.02.09.15.43.15; author kfogel; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2004.02.09.15.43.16; author kfogel; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.1
+log
+@Add a file to the working copy.
+@
+text
+@Adding this file, before importing it with different contents.
+@
+
+
+1.1.1.1
+log
+@Import (vbranchA, vtag-4).
+@
+text
+@d1 1
+a1 1
+This is vtag-4 (on vbranchA) of added-then-imported.txt.
+@
+
diff --git a/t/t9601/cvsroot/module/imported-anonymously.txt,v b/t/t9601/cvsroot/module/imported-anonymously.txt,v
new file mode 100644
index 0000000000..55e1b0ca5d
--- /dev/null
+++ b/t/t9601/cvsroot/module/imported-anonymously.txt,v
@@ -0,0 +1,42 @@
+head 1.1;
+branch 1.1.1;
+access;
+symbols
+ vtag-1:1.1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@This is vtag-1 (on vbranchA) of imported-anonymously.txt.
+@
+
+
+1.1.1.1
+log
+@Import (vbranchA, vtag-1).
+@
+text
+@@
+
+
diff --git a/t/t9601/cvsroot/module/imported-modified-imported.txt,v b/t/t9601/cvsroot/module/imported-modified-imported.txt,v
new file mode 100644
index 0000000000..e5830aeb37
--- /dev/null
+++ b/t/t9601/cvsroot/module/imported-modified-imported.txt,v
@@ -0,0 +1,76 @@
+head 1.2;
+access;
+symbols
+ vtag-2:1.1.1.2
+ vtag-1:1.1.1.1
+ vbranchA:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 2004.02.09.15.43.14; author kfogel; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches;
+next 1.1.1.2;
+
+1.1.1.2
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.2
+log
+@First regular commit, to imported-modified-imported.txt, on HEAD.
+@
+text
+@This is a modification of imported-modified-imported.txt on HEAD.
+It should supersede the version from the vendor branch.
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d1 2
+a2 1
+This is vtag-1 (on vbranchA) of imported-modified-imported.txt.
+@
+
+
+1.1.1.1
+log
+@Import (vbranchA, vtag-1).
+@
+text
+@@
+
+
+1.1.1.2
+log
+@Import (vbranchA, vtag-2).
+@
+text
+@d1 1
+a1 1
+This is vtag-2 (on vbranchA) of imported-modified-imported.txt.
+@
+
+
diff --git a/t/t9601/cvsroot/module/imported-modified.txt,v b/t/t9601/cvsroot/module/imported-modified.txt,v
new file mode 100644
index 0000000000..bbcfe447b9
--- /dev/null
+++ b/t/t9601/cvsroot/module/imported-modified.txt,v
@@ -0,0 +1,59 @@
+head 1.2;
+access;
+symbols
+ vtag-1:1.1.1.1
+ vbranchA:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 2004.02.09.15.43.14; author kfogel; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.2
+log
+@Commit on HEAD.
+@
+text
+@This is a modification of imported-modified.txt on HEAD.
+It should supersede the version from the vendor branch.
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d1 2
+a2 1
+This is vtag-1 (on vbranchA) of imported-modified.txt.
+@
+
+
+1.1.1.1
+log
+@Import (vbranchA, vtag-1).
+@
+text
+@@
+
+
diff --git a/t/t9601/cvsroot/module/imported-once.txt,v b/t/t9601/cvsroot/module/imported-once.txt,v
new file mode 100644
index 0000000000..c5dd82b12d
--- /dev/null
+++ b/t/t9601/cvsroot/module/imported-once.txt,v
@@ -0,0 +1,43 @@
+head 1.1;
+branch 1.1.1;
+access;
+symbols
+ vtag-1:1.1.1.1
+ vbranchA:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@This is vtag-1 (on vbranchA) of imported-once.txt.
+@
+
+
+1.1.1.1
+log
+@Import (vbranchA, vtag-1).
+@
+text
+@@
+
+
diff --git a/t/t9601/cvsroot/module/imported-twice.txt,v b/t/t9601/cvsroot/module/imported-twice.txt,v
new file mode 100644
index 0000000000..d1f3f1b344
--- /dev/null
+++ b/t/t9601/cvsroot/module/imported-twice.txt,v
@@ -0,0 +1,60 @@
+head 1.1;
+branch 1.1.1;
+access;
+symbols
+ vtag-2:1.1.1.2
+ vtag-1:1.1.1.1
+ vbranchA:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches;
+next 1.1.1.2;
+
+1.1.1.2
+date 2004.02.09.15.43.13; author kfogel; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@This is vtag-1 (on vbranchA) of imported-twice.txt.
+@
+
+
+1.1.1.1
+log
+@Import (vbranchA, vtag-1).
+@
+text
+@@
+
+
+1.1.1.2
+log
+@Import (vbranchA, vtag-2).
+@
+text
+@d1 1
+a1 1
+This is vtag-2 (on vbranchA) of imported-twice.txt.
+@
+
+
diff --git a/t/t9602-cvsimport-branches-tags.sh b/t/t9602-cvsimport-branches-tags.sh
new file mode 100755
index 0000000000..67878b2d0c
--- /dev/null
+++ b/t/t9602-cvsimport-branches-tags.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# A description of the repository used for this test can be found in
+# t9602/README.
+
+test_description='git cvsimport handling of branches and tags'
+. ./lib-cvs.sh
+
+CVSROOT="$TEST_DIRECTORY"/t9602/cvsroot
+export CVSROOT
+
+test_expect_success 'import module' '
+
+ git cvsimport -C module-git module
+
+'
+
+test_expect_success 'test branch master' '
+
+ test_cmp_branch_tree master
+
+'
+
+test_expect_success 'test branch vendorbranch' '
+
+ test_cmp_branch_tree vendorbranch
+
+'
+
+test_expect_failure 'test branch B_FROM_INITIALS' '
+
+ test_cmp_branch_tree B_FROM_INITIALS
+
+'
+
+test_expect_failure 'test branch B_FROM_INITIALS_BUT_ONE' '
+
+ test_cmp_branch_tree B_FROM_INITIALS_BUT_ONE
+
+'
+
+test_expect_failure 'test branch B_MIXED' '
+
+ test_cmp_branch_tree B_MIXED
+
+'
+
+test_expect_success 'test branch B_SPLIT' '
+
+ test_cmp_branch_tree B_SPLIT
+
+'
+
+test_expect_failure 'test tag vendortag' '
+
+ test_cmp_branch_tree vendortag
+
+'
+
+test_expect_success 'test tag T_ALL_INITIAL_FILES' '
+
+ test_cmp_branch_tree T_ALL_INITIAL_FILES
+
+'
+
+test_expect_failure 'test tag T_ALL_INITIAL_FILES_BUT_ONE' '
+
+ test_cmp_branch_tree T_ALL_INITIAL_FILES_BUT_ONE
+
+'
+
+test_expect_failure 'test tag T_MIXED' '
+
+ test_cmp_branch_tree T_MIXED
+
+'
+
+
+test_done
diff --git a/t/t9602/README b/t/t9602/README
new file mode 100644
index 0000000000..c231e0f26f
--- /dev/null
+++ b/t/t9602/README
@@ -0,0 +1,62 @@
+This repository is for testing the ability to group revisions
+correctly along tags and branches. Here is its history:
+
+ 1. The initial import (revision 1.1 of everybody) created a
+ directory structure with a file named `default' in each dir:
+
+ ./
+ default
+ sub1/default
+ subsubA/default
+ subsubB/default
+ sub2/default
+ subsubA/default
+ sub3/default
+
+ 2. Then tagged everyone with T_ALL_INITIAL_FILES.
+
+ 3. Then tagged everyone except sub1/subsubB/default with
+ T_ALL_INITIAL_FILES_BUT_ONE.
+
+ 4. Then created branch B_FROM_INITIALS on everyone.
+
+ 5. Then created branch B_FROM_INITIALS_BUT_ONE on everyone except
+ /sub1/subsubB/default.
+
+ 6. Then committed modifications to two files: sub3/default, and
+ sub1/subsubA/default.
+
+ 7. Then committed a modification to all 7 files.
+
+ 8. Then backdated sub3/default to revision 1.2, and
+ sub2/subsubA/default to revision 1.1, and tagged with T_MIXED.
+
+ 9. Same as 8, but tagged with -b to create branch B_MIXED.
+
+ 10. Switched the working copy to B_MIXED, and added
+ sub2/branch_B_MIXED_only. (That's why the RCS file is in
+ sub2/Attic/ -- it never existed on trunk.)
+
+ 11. In one commit, modified default, sub1/default, and
+ sub2/subsubA/default, on branch B_MIXED.
+
+ 12. Did "cvs up -A" on sub2/default, then in one commit, made a
+ change to sub2/default and sub2/branch_B_MIXED_only. So this
+ commit should be spread between the branch and the trunk.
+
+ 13. Do "cvs up -A" to get everyone back to trunk, then make a new
+ branch B_SPLIT on everyone except sub1/subsubB/default,v.
+
+ 14. Switch to branch B_SPLIT (see sub1/subsubB/default disappear)
+ and commit a change that affects everyone except sub3/default.
+
+ 15. An hour or so later, "cvs up -A" to get sub1/subsubB/default
+ back, then commit a change on that file, on trunk. (It's
+ important that this change happened after the previous commits
+ on B_SPLIT.)
+
+ 16. Branch sub1/subsubB/default to B_SPLIT, then "cvs up -r B_SPLIT"
+ to switch the whole working copy to the branch.
+
+ 17. Commit a change on B_SPLIT, to sub1/subsubB/default and
+ sub3/default.
diff --git a/t/t9602/cvsroot/.gitattributes b/t/t9602/cvsroot/.gitattributes
new file mode 100644
index 0000000000..562b12e16e
--- /dev/null
+++ b/t/t9602/cvsroot/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/t/t9602/cvsroot/CVSROOT/.gitignore b/t/t9602/cvsroot/CVSROOT/.gitignore
new file mode 100644
index 0000000000..3bb9b34173
--- /dev/null
+++ b/t/t9602/cvsroot/CVSROOT/.gitignore
@@ -0,0 +1,2 @@
+history
+val-tags
diff --git a/t/t9602/cvsroot/module/default,v b/t/t9602/cvsroot/module/default,v
new file mode 100644
index 0000000000..3b68382a3b
--- /dev/null
+++ b/t/t9602/cvsroot/module/default,v
@@ -0,0 +1,102 @@
+head 1.2;
+access;
+symbols
+ B_SPLIT:1.2.0.4
+ B_MIXED:1.2.0.2
+ T_MIXED:1.2
+ B_FROM_INITIALS_BUT_ONE:1.1.1.1.0.4
+ B_FROM_INITIALS:1.1.1.1.0.2
+ T_ALL_INITIAL_FILES_BUT_ONE:1.1.1.1
+ T_ALL_INITIAL_FILES:1.1.1.1
+ vendortag:1.1.1.1
+ vendorbranch:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 2003.05.23.00.17.53; author jrandom; state Exp;
+branches
+ 1.2.2.1
+ 1.2.4.1;
+next 1.1;
+
+1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches;
+next ;
+
+1.2.2.1
+date 2003.05.23.00.31.36; author jrandom; state Exp;
+branches;
+next ;
+
+1.2.4.1
+date 2003.06.03.03.20.31; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.2
+log
+@Second commit to proj, affecting all 7 files.
+@
+text
+@This is the file `default' in the top level of the project.
+
+Every directory in the `proj' project has a file named `default'.
+
+This line was added in the second commit (affecting all 7 files).
+@
+
+
+1.2.4.1
+log
+@First change on branch B_SPLIT.
+
+This change excludes sub3/default, because it was not part of this
+commit, and sub1/subsubB/default, which is not even on the branch yet.
+@
+text
+@a5 2
+
+First change on branch B_SPLIT.
+@
+
+
+1.2.2.1
+log
+@Modify three files, on branch B_MIXED.
+@
+text
+@a5 2
+
+This line was added on branch B_MIXED only (affecting 3 files).
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d4 2
+@
+
+
+1.1.1.1
+log
+@Initial import.
+@
+text
+@@
diff --git a/t/t9602/cvsroot/module/sub1/default,v b/t/t9602/cvsroot/module/sub1/default,v
new file mode 100644
index 0000000000..b7fdccdfdf
--- /dev/null
+++ b/t/t9602/cvsroot/module/sub1/default,v
@@ -0,0 +1,102 @@
+head 1.2;
+access;
+symbols
+ B_SPLIT:1.2.0.4
+ B_MIXED:1.2.0.2
+ T_MIXED:1.2
+ B_FROM_INITIALS_BUT_ONE:1.1.1.1.0.4
+ B_FROM_INITIALS:1.1.1.1.0.2
+ T_ALL_INITIAL_FILES_BUT_ONE:1.1.1.1
+ T_ALL_INITIAL_FILES:1.1.1.1
+ vendortag:1.1.1.1
+ vendorbranch:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 2003.05.23.00.17.53; author jrandom; state Exp;
+branches
+ 1.2.2.1
+ 1.2.4.1;
+next 1.1;
+
+1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches;
+next ;
+
+1.2.2.1
+date 2003.05.23.00.31.36; author jrandom; state Exp;
+branches;
+next ;
+
+1.2.4.1
+date 2003.06.03.03.20.31; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.2
+log
+@Second commit to proj, affecting all 7 files.
+@
+text
+@This is sub1/default.
+
+Every directory in the `proj' project has a file named `default'.
+
+This line was added in the second commit (affecting all 7 files).
+@
+
+
+1.2.4.1
+log
+@First change on branch B_SPLIT.
+
+This change excludes sub3/default, because it was not part of this
+commit, and sub1/subsubB/default, which is not even on the branch yet.
+@
+text
+@a5 2
+
+First change on branch B_SPLIT.
+@
+
+
+1.2.2.1
+log
+@Modify three files, on branch B_MIXED.
+@
+text
+@a5 2
+
+This line was added on branch B_MIXED only (affecting 3 files).
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d4 2
+@
+
+
+1.1.1.1
+log
+@Initial import.
+@
+text
+@@
diff --git a/t/t9602/cvsroot/module/sub1/subsubA/default,v b/t/t9602/cvsroot/module/sub1/subsubA/default,v
new file mode 100644
index 0000000000..472b7b2bd9
--- /dev/null
+++ b/t/t9602/cvsroot/module/sub1/subsubA/default,v
@@ -0,0 +1,101 @@
+head 1.3;
+access;
+symbols
+ B_SPLIT:1.3.0.4
+ B_MIXED:1.3.0.2
+ T_MIXED:1.3
+ B_FROM_INITIALS_BUT_ONE:1.1.1.1.0.4
+ B_FROM_INITIALS:1.1.1.1.0.2
+ T_ALL_INITIAL_FILES_BUT_ONE:1.1.1.1
+ T_ALL_INITIAL_FILES:1.1.1.1
+ vendortag:1.1.1.1
+ vendorbranch:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 2003.05.23.00.17.53; author jrandom; state Exp;
+branches
+ 1.3.4.1;
+next 1.2;
+
+1.2
+date 2003.05.23.00.15.26; author jrandom; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches;
+next ;
+
+1.3.4.1
+date 2003.06.03.03.20.31; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.3
+log
+@Second commit to proj, affecting all 7 files.
+@
+text
+@This is sub1/subsubA/default.
+
+Every directory in the `proj' project has a file named `default'.
+
+This line was added by the first commit (affecting two files).
+
+This line was added in the second commit (affecting all 7 files).
+@
+
+
+1.3.4.1
+log
+@First change on branch B_SPLIT.
+
+This change excludes sub3/default, because it was not part of this
+commit, and sub1/subsubB/default, which is not even on the branch yet.
+@
+text
+@a7 2
+
+First change on branch B_SPLIT.
+@
+
+
+1.2
+log
+@First commit to proj, affecting two files.
+@
+text
+@d6 2
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d4 2
+@
+
+
+1.1.1.1
+log
+@Initial import.
+@
+text
+@@
diff --git a/t/t9602/cvsroot/module/sub1/subsubB/default,v b/t/t9602/cvsroot/module/sub1/subsubB/default,v
new file mode 100644
index 0000000000..fe6efa4554
--- /dev/null
+++ b/t/t9602/cvsroot/module/sub1/subsubB/default,v
@@ -0,0 +1,107 @@
+head 1.3;
+access;
+symbols
+ B_SPLIT:1.3.0.2
+ B_MIXED:1.2.0.2
+ T_MIXED:1.2
+ B_FROM_INITIALS:1.1.1.1.0.2
+ T_ALL_INITIAL_FILES:1.1.1.1
+ vendortag:1.1.1.1
+ vendorbranch:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 2003.06.03.04.29.14; author jrandom; state Exp;
+branches
+ 1.3.2.1;
+next 1.2;
+
+1.2
+date 2003.05.23.00.17.53; author jrandom; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches;
+next ;
+
+1.3.2.1
+date 2003.06.03.04.33.13; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.3
+log
+@A trunk change to sub1/subsubB/default. This was committed about an
+hour after an earlier change that affected most files on branch
+B_SPLIT. This file is not on that branch yet, but after this commit,
+we'll branch to B_SPLIT, albeit rooted in a revision that didn't exist
+at the time the rest of B_SPLIT was created.
+@
+text
+@This is sub1/subsubB/default.
+
+Every directory in the `proj' project has a file named `default'.
+
+This line was added in the second commit (affecting all 7 files).
+
+This bit was committed on trunk about an hour after an earlier change
+to everyone else on branch B_SPLIT. Afterwards, we'll finally branch
+this file to B_SPLIT, but rooted in a revision that didn't exist at
+the time the rest of B_SPLIT was created.
+@
+
+
+1.3.2.1
+log
+@This change affects sub3/default and sub1/subsubB/default, on branch
+B_SPLIT. Note that the latter file did not even exist on this branch
+until after some other files had had revisions committed on B_SPLIT.
+@
+text
+@a10 4
+
+This change affects sub3/default and sub1/subsubB/default, on branch
+B_SPLIT. Note that the latter file did not even exist on this branch
+until after some other files had had revisions committed on B_SPLIT.
+@
+
+
+1.2
+log
+@Second commit to proj, affecting all 7 files.
+@
+text
+@d6 5
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d4 2
+@
+
+
+1.1.1.1
+log
+@Initial import.
+@
+text
+@@
diff --git a/t/t9602/cvsroot/module/sub2/Attic/branch_B_MIXED_only,v b/t/t9602/cvsroot/module/sub2/Attic/branch_B_MIXED_only,v
new file mode 100644
index 0000000000..34c9789f2f
--- /dev/null
+++ b/t/t9602/cvsroot/module/sub2/Attic/branch_B_MIXED_only,v
@@ -0,0 +1,59 @@
+head 1.1;
+access;
+symbols
+ B_MIXED:1.1.0.2;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 2003.05.23.00.25.26; author jrandom; state dead;
+branches
+ 1.1.2.1;
+next ;
+
+1.1.2.1
+date 2003.05.23.00.25.26; author jrandom; state Exp;
+branches;
+next 1.1.2.2;
+
+1.1.2.2
+date 2003.05.23.00.48.51; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.1
+log
+@file branch_B_MIXED_only was initially added on branch B_MIXED.
+@
+text
+@@
+
+
+1.1.2.1
+log
+@Add a file on branch B_MIXED.
+@
+text
+@a0 1
+This file was added on branch B_MIXED. It never existed on trunk.
+@
+
+
+1.1.2.2
+log
+@A single commit affecting one file on branch B_MIXED and one on trunk.
+@
+text
+@a1 3
+
+The same commit added these two lines here on branch B_MIXED, and two
+similar lines to ./default on trunk.
+@
+
+
diff --git a/t/t9602/cvsroot/module/sub2/default,v b/t/t9602/cvsroot/module/sub2/default,v
new file mode 100644
index 0000000000..018f7f8ece
--- /dev/null
+++ b/t/t9602/cvsroot/module/sub2/default,v
@@ -0,0 +1,102 @@
+head 1.3;
+access;
+symbols
+ B_SPLIT:1.3.0.2
+ B_MIXED:1.2.0.2
+ T_MIXED:1.2
+ B_FROM_INITIALS_BUT_ONE:1.1.1.1.0.4
+ B_FROM_INITIALS:1.1.1.1.0.2
+ T_ALL_INITIAL_FILES_BUT_ONE:1.1.1.1
+ T_ALL_INITIAL_FILES:1.1.1.1
+ vendortag:1.1.1.1
+ vendorbranch:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 2003.05.23.00.48.51; author jrandom; state Exp;
+branches
+ 1.3.2.1;
+next 1.2;
+
+1.2
+date 2003.05.23.00.17.53; author jrandom; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches;
+next ;
+
+1.3.2.1
+date 2003.06.03.03.20.31; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.3
+log
+@A single commit affecting one file on branch B_MIXED and one on trunk.
+@
+text
+@This is sub2/default.
+
+Every directory in the `proj' project has a file named `default'.
+
+This line was added in the second commit (affecting all 7 files).
+
+The same commit added these two lines here on trunk, and two similar
+lines to ./branch_B_MIXED_only on branch B_MIXED.
+@
+
+
+1.3.2.1
+log
+@First change on branch B_SPLIT.
+
+This change excludes sub3/default, because it was not part of this
+commit, and sub1/subsubB/default, which is not even on the branch yet.
+@
+text
+@a8 2
+
+First change on branch B_SPLIT.
+@
+
+
+1.2
+log
+@Second commit to proj, affecting all 7 files.
+@
+text
+@d6 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d4 2
+@
+
+
+1.1.1.1
+log
+@Initial import.
+@
+text
+@@
diff --git a/t/t9602/cvsroot/module/sub2/subsubA/default,v b/t/t9602/cvsroot/module/sub2/subsubA/default,v
new file mode 100644
index 0000000000..d13242cb09
--- /dev/null
+++ b/t/t9602/cvsroot/module/sub2/subsubA/default,v
@@ -0,0 +1,102 @@
+head 1.2;
+access;
+symbols
+ B_SPLIT:1.2.0.2
+ B_MIXED:1.1.0.2
+ T_MIXED:1.1
+ B_FROM_INITIALS_BUT_ONE:1.1.1.1.0.4
+ B_FROM_INITIALS:1.1.1.1.0.2
+ T_ALL_INITIAL_FILES_BUT_ONE:1.1.1.1
+ T_ALL_INITIAL_FILES:1.1.1.1
+ vendortag:1.1.1.1
+ vendorbranch:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 2003.05.23.00.17.53; author jrandom; state Exp;
+branches
+ 1.2.2.1;
+next 1.1;
+
+1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches
+ 1.1.1.1
+ 1.1.2.1;
+next ;
+
+1.1.1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches;
+next ;
+
+1.1.2.1
+date 2003.05.23.00.31.36; author jrandom; state Exp;
+branches;
+next ;
+
+1.2.2.1
+date 2003.06.03.03.20.31; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.2
+log
+@Second commit to proj, affecting all 7 files.
+@
+text
+@This is sub2/subsub2/default.
+
+Every directory in the `proj' project has a file named `default'.
+
+This line was added in the second commit (affecting all 7 files).
+@
+
+
+1.2.2.1
+log
+@First change on branch B_SPLIT.
+
+This change excludes sub3/default, because it was not part of this
+commit, and sub1/subsubB/default, which is not even on the branch yet.
+@
+text
+@a5 2
+
+First change on branch B_SPLIT.
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d4 2
+@
+
+
+1.1.2.1
+log
+@Modify three files, on branch B_MIXED.
+@
+text
+@a3 2
+
+This line was added on branch B_MIXED only (affecting 3 files).
+@
+
+
+1.1.1.1
+log
+@Initial import.
+@
+text
+@@
diff --git a/t/t9602/cvsroot/module/sub3/default,v b/t/t9602/cvsroot/module/sub3/default,v
new file mode 100644
index 0000000000..88e4567434
--- /dev/null
+++ b/t/t9602/cvsroot/module/sub3/default,v
@@ -0,0 +1,102 @@
+head 1.3;
+access;
+symbols
+ B_SPLIT:1.3.0.2
+ B_MIXED:1.2.0.2
+ T_MIXED:1.2
+ B_FROM_INITIALS_BUT_ONE:1.1.1.1.0.4
+ B_FROM_INITIALS:1.1.1.1.0.2
+ T_ALL_INITIAL_FILES_BUT_ONE:1.1.1.1
+ T_ALL_INITIAL_FILES:1.1.1.1
+ vendortag:1.1.1.1
+ vendorbranch:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 2003.05.23.00.17.53; author jrandom; state Exp;
+branches
+ 1.3.2.1;
+next 1.2;
+
+1.2
+date 2003.05.23.00.15.26; author jrandom; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 2003.05.22.23.20.19; author jrandom; state Exp;
+branches;
+next ;
+
+1.3.2.1
+date 2003.06.03.04.33.13; author jrandom; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.3
+log
+@Second commit to proj, affecting all 7 files.
+@
+text
+@This is sub3/default.
+
+Every directory in the `proj' project has a file named `default'.
+
+This line was added by the first commit (affecting two files).
+
+This line was added in the second commit (affecting all 7 files).
+@
+
+
+1.3.2.1
+log
+@This change affects sub3/default and sub1/subsubB/default, on branch
+B_SPLIT. Note that the latter file did not even exist on this branch
+until after some other files had had revisions committed on B_SPLIT.
+@
+text
+@a7 4
+
+This change affects sub3/default and sub1/subsubB/default, on branch
+B_SPLIT. Note that the latter file did not even exist on this branch
+until after some other files had had revisions committed on B_SPLIT.
+@
+
+
+1.2
+log
+@First commit to proj, affecting two files.
+@
+text
+@d6 2
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d4 2
+@
+
+
+1.1.1.1
+log
+@Initial import.
+@
+text
+@@
diff --git a/t/t9603-cvsimport-patchsets.sh b/t/t9603-cvsimport-patchsets.sh
new file mode 100755
index 0000000000..958bdce4dd
--- /dev/null
+++ b/t/t9603-cvsimport-patchsets.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# Structure of the test cvs repository
+#
+# Message File:Content Commit Time
+# Rev 1 a: 1.1 2009-02-21 19:11:43 +0100
+# Rev 2 a: 1.2 b: 1.1 2009-02-21 19:11:14 +0100
+# Rev 3 b: 1.2 2009-02-21 19:11:43 +0100
+#
+# As you can see the commit of Rev 3 has the same time as
+# Rev 1 this leads to a broken import because of a cvsps
+# bug.
+
+test_description='git cvsimport testing for correct patchset estimation'
+. ./lib-cvs.sh
+
+CVSROOT="$TEST_DIRECTORY"/t9603/cvsroot
+export CVSROOT
+
+test_expect_failure 'import with criss cross times on revisions' '
+
+ git cvsimport -p"-x" -C module-git module &&
+ cd module-git &&
+ git log --pretty=format:%s > ../actual-master &&
+ git log A~2..A --pretty="format:%s %ad" -- > ../actual-A &&
+ echo "" >> ../actual-master &&
+ echo "" >> ../actual-A &&
+ cd .. &&
+ echo "Rev 4
+Rev 3
+Rev 2
+Rev 1" > expect-master &&
+ test_cmp actual-master expect-master &&
+
+ echo "Rev 5 Branch A Wed Mar 11 19:09:10 2009 +0000
+Rev 4 Branch A Wed Mar 11 19:03:52 2009 +0000" > expect-A &&
+ test_cmp actual-A expect-A
+'
+
+test_done
diff --git a/t/t9603/cvsroot/.gitattributes b/t/t9603/cvsroot/.gitattributes
new file mode 100644
index 0000000000..562b12e16e
--- /dev/null
+++ b/t/t9603/cvsroot/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/t/t9603/cvsroot/CVSROOT/.gitignore b/t/t9603/cvsroot/CVSROOT/.gitignore
new file mode 100644
index 0000000000..3bb9b34173
--- /dev/null
+++ b/t/t9603/cvsroot/CVSROOT/.gitignore
@@ -0,0 +1,2 @@
+history
+val-tags
diff --git a/t/t9603/cvsroot/module/a,v b/t/t9603/cvsroot/module/a,v
new file mode 100644
index 0000000000..ba8fd5af23
--- /dev/null
+++ b/t/t9603/cvsroot/module/a,v
@@ -0,0 +1,74 @@
+head 1.2;
+access;
+symbols
+ A:1.2.0.2;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 2009.02.21.18.11.14; author tester; state Exp;
+branches
+ 1.2.2.1;
+next 1.1;
+
+1.1
+date 2009.02.21.18.11.43; author tester; state Exp;
+branches;
+next ;
+
+1.2.2.1
+date 2009.03.11.19.03.52; author tester; state Exp;
+branches;
+next 1.2.2.2;
+
+1.2.2.2
+date 2009.03.11.19.09.10; author tester; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.2
+log
+@Rev 2
+@
+text
+@1.2
+@
+
+
+1.2.2.1
+log
+@Rev 4 Branch A
+@
+text
+@d1 1
+a1 1
+1.2.2.1
+@
+
+
+1.2.2.2
+log
+@Rev 5 Branch A
+@
+text
+@d1 1
+a1 1
+1.2.2.2
+@
+
+
+1.1
+log
+@Rev 1
+@
+text
+@d1 1
+a1 1
+1.1
+@
diff --git a/t/t9603/cvsroot/module/b,v b/t/t9603/cvsroot/module/b,v
new file mode 100644
index 0000000000..d26885518a
--- /dev/null
+++ b/t/t9603/cvsroot/module/b,v
@@ -0,0 +1,90 @@
+head 1.3;
+access;
+symbols
+ A:1.2.0.2;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 2009.03.11.19.05.08; author tester; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 2009.02.21.18.11.43; author tester; state Exp;
+branches
+ 1.2.2.1;
+next 1.1;
+
+1.1
+date 2009.02.21.18.11.14; author tester; state Exp;
+branches;
+next ;
+
+1.2.2.1
+date 2009.03.11.19.03.52; author tester; state Exp;
+branches;
+next 1.2.2.2;
+
+1.2.2.2
+date 2009.03.11.19.09.10; author tester; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.3
+log
+@Rev 4
+@
+text
+@1.3
+@
+
+
+1.2
+log
+@Rev 3
+@
+text
+@d1 1
+a1 1
+1.2
+@
+
+
+1.2.2.1
+log
+@Rev 4 Branch A
+@
+text
+@d1 1
+a1 1
+1.2.2.1
+@
+
+
+1.2.2.2
+log
+@Rev 5 Branch A
+@
+text
+@d1 1
+a1 1
+1.2
+@
+
+
+1.1
+log
+@Rev 2
+@
+text
+@d1 1
+a1 1
+1.1
+@
diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh
index b81d5dfc34..4eb7d3f7f0 100755
--- a/t/t9700-perl-git.sh
+++ b/t/t9700-perl-git.sh
@@ -6,8 +6,13 @@
test_description='perl interface (Git.pm)'
. ./test-lib.sh
+if ! test_have_prereq PERL; then
+ say 'skipping perl interface tests, perl not available'
+ test_done
+fi
+
perl -MTest::More -e 0 2>/dev/null || {
- say_color skip "Perl Test::More unavailable, skipping test"
+ say "Perl Test::More unavailable, skipping test"
test_done
}
@@ -24,6 +29,10 @@ test_expect_success \
git add . &&
git commit -m "first commit" &&
+ echo "new file in subdir 2" > directory2/file2 &&
+ git add . &&
+ git commit -m "commit in directory2" &&
+
echo "changed file 1" > file1 &&
git commit -a -m "second commit" &&
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index 697daf3ffd..6c70aec020 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -86,15 +86,22 @@ close TEMPFILE;
unlink $tmpfile;
# paths
-is($r->repo_path, "./.git", "repo_path");
+is($r->repo_path, $abs_repo_dir . "/.git", "repo_path");
is($r->wc_path, $abs_repo_dir . "/", "wc_path");
is($r->wc_subdir, "", "wc_subdir initial");
$r->wc_chdir("directory1");
is($r->wc_subdir, "directory1", "wc_subdir after wc_chdir");
-TODO: {
- local $TODO = "commands do not work after wc_chdir";
- # Failure output is active even in non-verbose mode and thus
- # annoying. Hence we skip these tests as long as they fail.
- todo_skip 'config after wc_chdir', 1;
- is($r->config("color.string"), "value", "config after wc_chdir");
-}
+is($r->config("test.string"), "value", "config after wc_chdir");
+
+# Object generation in sub directory
+chdir("directory2");
+my $r2 = Git->repository();
+is($r2->repo_path, $abs_repo_dir . "/.git", "repo_path (2)");
+is($r2->wc_path, $abs_repo_dir . "/", "wc_path (2)");
+is($r2->wc_subdir, "directory2/", "wc_subdir initial (2)");
+
+# commands in sub directory
+my $last_commit = $r2->command_oneline(qw(rev-parse --verify HEAD));
+like($last_commit, qr/^[0-9a-fA-F]{40}$/, 'rev-parse returned hash');
+my $dir_commit = $r2->command_oneline('log', '-n1', '--pretty=format:%H', '.');
+isnt($last_commit, $dir_commit, 'log . does not show last commit');
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 1b4f216385..a5b8d03db0 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -3,6 +3,22 @@
# Copyright (c) 2005 Junio C Hamano
#
+# 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
+done,*)
+ # do not redirect again
+ ;;
+*' --tee '*|*' --va'*)
+ mkdir -p test-results
+ BASE=test-results/$(basename "$0" .sh)
+ (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
+ echo $? > $BASE.exit) | tee $BASE.out
+ test "$(cat $BASE.exit)" = 0
+ exit
+ ;;
+esac
+
# Keep the original TERM for say_color
ORIGINAL_TERM=$TERM
@@ -94,8 +110,15 @@ do
--no-python)
# noop now...
shift ;;
+ --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
+ valgrind=t; verbose=t; shift ;;
+ --tee)
+ shift ;; # was handled already
+ --root=*)
+ root=$(expr "z$1" : 'z[^=]*=\(.*\)')
+ shift ;;
*)
- break ;;
+ echo "error: unknown test option '$1'" >&2; exit 1 ;;
esac
done
@@ -127,7 +150,7 @@ fi
error () {
say_color error "error: $*"
- trap - exit
+ GIT_EXIT_OK=t
exit 1
}
@@ -159,11 +182,18 @@ test_broken=0
test_success=0
die () {
- echo >&5 "FATAL: Unexpected exit with code $?"
- exit 1
+ code=$?
+ if test -n "$GIT_EXIT_OK"
+ then
+ exit $code
+ else
+ echo >&5 "FATAL: Unexpected exit with code $code"
+ exit 1
+ fi
}
-trap 'die' exit
+GIT_EXIT_OK=
+trap 'die' EXIT
# The semantics of the editor variables are that of invoking
# sh -c "$EDITOR \"$@\"" files ...
@@ -193,32 +223,87 @@ test_tick () {
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
}
+# Call test_commit with the arguments "<message> [<file> [<contents>]]"
+#
+# This will commit a file with the given contents and the given commit
+# message. It will also add a tag with <message> as name.
+#
+# Both <file> and <contents> default to <message>.
+
+test_commit () {
+ file=${2:-"$1.t"}
+ echo "${3-$1}" > "$file" &&
+ git add "$file" &&
+ test_tick &&
+ git commit -m "$1" &&
+ git tag "$1"
+}
+
+# Call test_merge with the arguments "<message> <commit>", where <commit>
+# can be a tag pointing to the commit-to-merge.
+
+test_merge () {
+ test_tick &&
+ git merge -m "$1" "$2" &&
+ git tag "$1"
+}
+
+# This function helps systems where core.filemode=false is set.
+# Use it instead of plain 'chmod +x' to set or unset the executable bit
+# of a file in the working directory and add it to the index.
+
+test_chmod () {
+ chmod "$@" &&
+ git update-index --add "--chmod=$@"
+}
+
+# Use test_set_prereq to tell that a particular prerequisite is available.
+# The prerequisite can later be checked for in two ways:
+#
+# - Explicitly using test_have_prereq.
+#
+# - Implicitly by specifying the prerequisite tag in the calls to
+# test_expect_{success,failure,code}.
+#
+# The single parameter is the prerequisite tag (a simple word, in all
+# capital letters by convention).
+
+test_set_prereq () {
+ satisfied="$satisfied$1 "
+}
+satisfied=" "
+
+test_have_prereq () {
+ case $satisfied in
+ *" $1 "*)
+ : yes, have it ;;
+ *)
+ ! : nope ;;
+ esac
+}
+
# You are not expected to call test_ok_ and test_failure_ directly, use
# the text_expect_* functions instead.
test_ok_ () {
- test_count=$(expr "$test_count" + 1)
- test_success=$(expr "$test_success" + 1)
+ test_success=$(($test_success + 1))
say_color "" " ok $test_count: $@"
}
test_failure_ () {
- test_count=$(expr "$test_count" + 1)
- test_failure=$(expr "$test_failure" + 1);
+ test_failure=$(($test_failure + 1))
say_color error "FAIL $test_count: $1"
shift
echo "$@" | sed -e 's/^/ /'
- test "$immediate" = "" || { trap - exit; exit 1; }
+ test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
}
test_known_broken_ok_ () {
- test_count=$(expr "$test_count" + 1)
test_fixed=$(($test_fixed+1))
say_color "" " FIXED $test_count: $@"
}
test_known_broken_failure_ () {
- test_count=$(expr "$test_count" + 1)
test_broken=$(($test_broken+1))
say_color skip " still broken $test_count: $@"
}
@@ -234,20 +319,23 @@ test_run_ () {
}
test_skip () {
- this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$')
- this_test="$this_test.$(expr "$test_count" + 1)"
+ test_count=$(($test_count+1))
to_skip=
for skp in $GIT_SKIP_TESTS
do
- case "$this_test" in
+ case $this_test.$test_count in
$skp)
to_skip=t
esac
done
+ if test -z "$to_skip" && test -n "$prereq" &&
+ ! test_have_prereq "$prereq"
+ then
+ to_skip=t
+ fi
case "$to_skip" in
t)
say_color skip >&3 "skipping test: $@"
- test_count=$(expr "$test_count" + 1)
say_color skip "skip $test_count: $1"
: true
;;
@@ -258,8 +346,9 @@ test_skip () {
}
test_expect_failure () {
+ test "$#" = 3 && { prereq=$1; shift; } || prereq=
test "$#" = 2 ||
- error "bug in the test script: not 2 parameters to test-expect-failure"
+ error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
if ! test_skip "$@"
then
say >&3 "checking known breakage: $2"
@@ -268,15 +357,16 @@ test_expect_failure () {
then
test_known_broken_ok_ "$1"
else
- test_known_broken_failure_ "$1"
+ test_known_broken_failure_ "$1"
fi
fi
echo >&3 ""
}
test_expect_success () {
+ test "$#" = 3 && { prereq=$1; shift; } || prereq=
test "$#" = 2 ||
- error "bug in the test script: not 2 parameters to test-expect-success"
+ error "bug in the test script: not 2 or 3 parameters to test-expect-success"
if ! test_skip "$@"
then
say >&3 "expecting success: $2"
@@ -292,8 +382,9 @@ test_expect_success () {
}
test_expect_code () {
+ test "$#" = 4 && { prereq=$1; shift; } || prereq=
test "$#" = 3 ||
- error "bug in the test script: not 3 parameters to test-expect-code"
+ error "bug in the test script: not 3 or 4 parameters to test-expect-code"
if ! test_skip "$@"
then
say >&3 "expecting exit code $1: $3"
@@ -317,15 +408,16 @@ test_expect_code () {
# Usage: test_external description command arguments...
# Example: test_external 'Perl API' perl ../path/to/test.pl
test_external () {
- test "$#" -eq 3 ||
- error >&5 "bug in the test script: not 3 parameters to test_external"
+ test "$#" = 4 && { prereq=$1; shift; } || prereq=
+ test "$#" = 3 ||
+ error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
descr="$1"
shift
if ! test_skip "$descr" "$@"
then
# Announce the script to reduce confusion about the
# test output that follows.
- say_color "" " run $(expr "$test_count" + 1): $descr ($*)"
+ say_color "" " run $test_count: $descr ($*)"
# Run command; redirect its stderr to &4 as in
# test_run_, but keep its stdout on our stdout even in
# non-verbose mode.
@@ -409,17 +501,17 @@ test_create_repo () {
repo="$1"
mkdir -p "$repo"
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git" init "--template=$GIT_EXEC_PATH/templates/blt/" >&3 2>&4 ||
+ "$GIT_EXEC_PATH/git-init" "--template=$TEST_DIRECTORY/../templates/blt/" >&3 2>&4 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
cd "$owd"
}
test_done () {
- trap - exit
+ GIT_EXIT_OK=t
test_results_dir="$TEST_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
- test_results_path="$test_results_dir/${0%-*}-$$"
+ test_results_path="$test_results_dir/${0%.sh}-$$"
echo "total $test_count" >> $test_results_path
echo "success $test_success" >> $test_results_path
@@ -459,8 +551,81 @@ test_done () {
# Test the binaries we have just built. The tests are kept in
# t/ subdirectory and are run in 'trash directory' subdirectory.
TEST_DIRECTORY=$(pwd)
-PATH=$TEST_DIRECTORY/..:$PATH
-GIT_EXEC_PATH=$(pwd)/..
+if test -z "$valgrind"
+then
+ if test -z "$GIT_TEST_INSTALLED"
+ then
+ PATH=$TEST_DIRECTORY/..:$PATH
+ GIT_EXEC_PATH=$TEST_DIRECTORY/..
+ else
+ GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) ||
+ error "Cannot run git from $GIT_TEST_INSTALLED."
+ PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH
+ GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
+ fi
+else
+ make_symlink () {
+ test -h "$2" &&
+ test "$1" = "$(readlink "$2")" || {
+ # be super paranoid
+ if mkdir "$2".lock
+ then
+ rm -f "$2" &&
+ ln -s "$1" "$2" &&
+ rm -r "$2".lock
+ else
+ while test -d "$2".lock
+ do
+ say "Waiting for lock on $2."
+ sleep 1
+ done
+ fi
+ }
+ }
+
+ make_valgrind_symlink () {
+ # handle only executables
+ test -x "$1" || return
+
+ base=$(basename "$1")
+ symlink_target=$TEST_DIRECTORY/../$base
+ # do not override scripts
+ if test -x "$symlink_target" &&
+ test ! -d "$symlink_target" &&
+ test "#!" != "$(head -c 2 < "$symlink_target")"
+ then
+ symlink_target=../valgrind.sh
+ fi
+ case "$base" in
+ *.sh|*.perl)
+ symlink_target=../unprocessed-script
+ esac
+ # create the link, or replace it if it is out of date
+ make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
+ }
+
+ # override all git executables in TEST_DIRECTORY/..
+ GIT_VALGRIND=$TEST_DIRECTORY/valgrind
+ mkdir -p "$GIT_VALGRIND"/bin
+ for file in $TEST_DIRECTORY/../git* $TEST_DIRECTORY/../test-*
+ do
+ make_valgrind_symlink $file
+ done
+ OLDIFS=$IFS
+ IFS=:
+ for path in $PATH
+ do
+ ls "$path"/git-* 2> /dev/null |
+ while read file
+ do
+ make_valgrind_symlink "$file"
+ done
+ done
+ IFS=$OLDIFS
+ PATH=$GIT_VALGRIND/bin:$PATH
+ GIT_EXEC_PATH=$GIT_VALGRIND/bin
+ export GIT_VALGRIND
+fi
GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
unset GIT_CONFIG
GIT_CONFIG_NOSYSTEM=1
@@ -483,9 +648,14 @@ fi
# Test repository
test="trash directory.$(basename "$0" .sh)"
-test ! -z "$debug" || remove_trash="$TEST_DIRECTORY/$test"
+test -n "$root" && test="$root/$test"
+case "$test" in
+/*) TRASH_DIRECTORY="$test" ;;
+ *) TRASH_DIRECTORY="$TEST_DIRECTORY/$test" ;;
+esac
+test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY
rm -fr "$test" || {
- trap - exit
+ GIT_EXIT_OK=t
echo >&5 "FATAL: Cannot prepare test area"
exit 1
}
@@ -495,7 +665,8 @@ test_create_repo "$test"
# in subprocesses like git equals our $PWD (for pathname comparisons).
cd -P "$test" || exit 1
-this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$')
+this_test=${0##*/}
+this_test=${this_test%%-*}
for skp in $GIT_SKIP_TESTS
do
to_skip=
@@ -513,3 +684,37 @@ do
test_done
esac
done
+
+# Fix some commands on Windows
+case $(uname -s) in
+*MINGW*)
+ # Windows has its own (incompatible) sort and find
+ sort () {
+ /usr/bin/sort "$@"
+ }
+ find () {
+ /usr/bin/find "$@"
+ }
+ sum () {
+ md5sum "$@"
+ }
+ # git sees Windows-style pwd
+ pwd () {
+ builtin pwd -W
+ }
+ # no POSIX permissions
+ # backslashes in pathspec are converted to '/'
+ # exec does not inherit the PID
+ ;;
+*)
+ test_set_prereq POSIXPERM
+ test_set_prereq BSLASHPSPEC
+ test_set_prereq EXECKEEPSPID
+ ;;
+esac
+
+test -z "$NO_PERL" && test_set_prereq PERL
+
+# 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
diff --git a/t/valgrind/.gitignore b/t/valgrind/.gitignore
new file mode 100644
index 0000000000..d4ae6676d1
--- /dev/null
+++ b/t/valgrind/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+/templates
diff --git a/t/valgrind/analyze.sh b/t/valgrind/analyze.sh
new file mode 100755
index 0000000000..d8105d9fab
--- /dev/null
+++ b/t/valgrind/analyze.sh
@@ -0,0 +1,123 @@
+#!/bin/sh
+
+out_prefix=$(dirname "$0")/../test-results/valgrind.out
+output=
+count=0
+total_count=0
+missing_message=
+new_line='
+'
+
+# start outputting the current valgrind error in $out_prefix.++$count,
+# and the test case which failed in the corresponding .message file
+start_output () {
+ test -z "$output" || return
+
+ # progress
+ total_count=$(($total_count+1))
+ test -t 2 && printf "\rFound %d errors" $total_count >&2
+
+ count=$(($count+1))
+ output=$out_prefix.$count
+ : > $output
+
+ echo "*** $1 ***" > $output.message
+}
+
+finish_output () {
+ test ! -z "$output" || return
+ output=
+
+ # if a test case has more than one valgrind error, we need to
+ # copy the last .message file to the previous errors
+ test -z "$missing_message" || {
+ while test $missing_message -lt $count
+ do
+ cp $out_prefix.$count.message \
+ $out_prefix.$missing_message.message
+ missing_message=$(($missing_message+1))
+ done
+ missing_message=
+ }
+}
+
+# group the valgrind errors by backtrace
+output_all () {
+ last_line=
+ j=0
+ i=1
+ while test $i -le $count
+ do
+ # output <number> <backtrace-in-one-line>
+ echo "$i $(tr '\n' ' ' < $out_prefix.$i)"
+ i=$(($i+1))
+ done |
+ sort -t ' ' -k 2 | # order by <backtrace-in-one-line>
+ while read number line
+ do
+ # find duplicates, do not output backtrace twice
+ if test "$line" != "$last_line"
+ then
+ last_line=$line
+ j=$(($j+1))
+ printf "\nValgrind error $j:\n\n"
+ cat $out_prefix.$number
+ printf "\nfound in:\n"
+ fi
+ # print the test case where this came from
+ printf "\n"
+ cat $out_prefix.$number.message
+ done
+}
+
+handle_one () {
+ OLDIFS=$IFS
+ IFS="$new_line"
+ while read line
+ do
+ case "$line" in
+ # backtrace, possibly a new one
+ ==[0-9]*)
+
+ # Does the current valgrind error have a message yet?
+ case "$output" in
+ *.message)
+ test -z "$missing_message" &&
+ missing_message=$count
+ output=
+ esac
+
+ start_output $(basename $1)
+ echo "$line" |
+ sed 's/==[0-9]*==/==valgrind==/' >> $output
+ ;;
+ # end of backtrace
+ '}')
+ test -z "$output" || {
+ echo "$line" >> $output
+ test $output = ${output%.message} &&
+ output=$output.message
+ }
+ ;;
+ # end of test case
+ '')
+ finish_output
+ ;;
+ # normal line; if $output is set, print the line
+ *)
+ test -z "$output" || echo "$line" >> $output
+ ;;
+ esac
+ done < $1
+ IFS=$OLDIFS
+
+ # just to be safe
+ finish_output
+}
+
+for test_script in "$(dirname "$0")"/../test-results/*.out
+do
+ handle_one $test_script
+done
+
+output_all
diff --git a/t/valgrind/default.supp b/t/valgrind/default.supp
new file mode 100644
index 0000000000..9e013fa3b2
--- /dev/null
+++ b/t/valgrind/default.supp
@@ -0,0 +1,45 @@
+{
+ ignore-zlib-errors-cond
+ Memcheck:Cond
+ obj:*libz.so*
+}
+
+{
+ ignore-zlib-errors-value8
+ Memcheck:Value8
+ obj:*libz.so*
+}
+
+{
+ ignore-zlib-errors-value4
+ Memcheck:Value4
+ obj:*libz.so*
+}
+
+{
+ ignore-ldso-cond
+ Memcheck:Cond
+ obj:*ld-*.so
+}
+
+{
+ ignore-ldso-addr8
+ Memcheck:Addr8
+ obj:*ld-*.so
+}
+
+{
+ ignore-ldso-addr4
+ Memcheck:Addr4
+ obj:*ld-*.so
+}
+
+{
+ writing-data-from-zlib-triggers-even-more-errors
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-*.so
+ fun:write_in_full
+ fun:write_buffer
+ fun:write_loose_object
+}
diff --git a/t/valgrind/valgrind.sh b/t/valgrind/valgrind.sh
new file mode 100755
index 0000000000..582b4dca94
--- /dev/null
+++ b/t/valgrind/valgrind.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+base=$(basename "$0")
+
+TRACK_ORIGINS=
+
+VALGRIND_VERSION=$(valgrind --version)
+VALGRIND_MAJOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*\([0-9]*\)')
+VALGRIND_MINOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*[0-9]*\.\([0-9]*\)')
+test 3 -gt "$VALGRIND_MAJOR" ||
+test 3 -eq "$VALGRIND_MAJOR" -a 4 -gt "$VALGRIND_MINOR" ||
+TRACK_ORIGINS=--track-origins=yes
+
+exec valgrind -q --error-exitcode=126 \
+ --leak-check=no \
+ --suppressions="$GIT_VALGRIND/default.supp" \
+ --gen-suppressions=all \
+ $TRACK_ORIGINS \
+ --log-fd=4 \
+ --input-fd=4 \
+ $GIT_VALGRIND_OPTIONS \
+ "$GIT_VALGRIND"/../../"$base" "$@"