summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README17
-rwxr-xr-xt/check-non-portable-shell.pl2
-rw-r--r--t/gitweb-lib.sh7
-rw-r--r--t/helper/.gitignore9
-rw-r--r--t/helper/test-date.c27
-rw-r--r--t/helper/test-dump-fsmonitor.c2
-rw-r--r--t/helper/test-hashmap.c50
-rw-r--r--t/helper/test-lazy-init-name-hash.c12
-rw-r--r--t/helper/test-parse-pathspec-file.c33
-rw-r--r--t/helper/test-progress.c81
-rw-r--r--t/helper/test-read-cache.c5
-rw-r--r--t/helper/test-read-graph.c53
-rw-r--r--t/helper/test-run-command.c197
-rw-r--r--t/helper/test-tool.c3
-rw-r--r--t/helper/test-tool.h3
-rw-r--r--t/lib-bash.sh6
-rw-r--r--t/lib-git-daemon.sh2
-rw-r--r--t/lib-git-p4.sh2
-rw-r--r--t/lib-git-svn.sh4
-rw-r--r--t/lib-httpd.sh2
-rw-r--r--t/lib-httpd/apply-one-time-sed.sh8
-rw-r--r--t/lib-rebase.sh37
-rw-r--r--t/oid-info/hash-info9
-rwxr-xr-xt/perf/aggregate.perl21
-rwxr-xr-xt/perf/bisect_regression2
-rwxr-xr-xt/perf/p5303-many-packs.sh19
-rwxr-xr-xt/perf/p5601-clone-reference.sh (renamed from t/perf/p5600-clone-reference.sh)0
-rw-r--r--t/perf/perf-lib.sh4
-rwxr-xr-xt/t0000-basic.sh123
-rwxr-xr-xt/t0003-attributes.sh47
-rwxr-xr-xt/t0014-alias.sh7
-rwxr-xr-xt/t0020-crlf.sh18
-rwxr-xr-xt/t0021-conversion.sh7
-rwxr-xr-xt/t0027-auto-crlf.sh2
-rwxr-xr-xt/t0028-working-tree-encoding.sh45
-rwxr-xr-xt/t0040-parse-options.sh11
-rwxr-xr-xt/t0050-filesystem.sh20
-rwxr-xr-xt/t0060-path-utils.sh17
-rwxr-xr-xt/t0061-run-command.sh25
-rwxr-xr-xt/t0067-parse_pathspec_file.sh108
-rwxr-xr-xt/t0090-cache-tree.sh5
-rwxr-xr-xt/t0211-trace2-perf.sh4
-rwxr-xr-xt/t0212-trace2-event.sh19
-rwxr-xr-xt/t0410-partial-clone.sh93
-rwxr-xr-xt/t0500-progress-display.sh286
-rwxr-xr-xt/t1011-read-tree-sparse-checkout.sh3
-rwxr-xr-xt/t1050-large.sh6
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh371
-rwxr-xr-xt/t1300-config.sh9
-rwxr-xr-xt/t1305-config-include.sh2
-rwxr-xr-xt/t1306-xdg-files.sh8
-rwxr-xr-xt/t1307-config-blob.sh2
-rwxr-xr-xt/t1308-config-set.sh8
-rwxr-xr-xt/t1309-early-config.sh9
-rwxr-xr-xt/t1400-update-ref.sh26
-rwxr-xr-xt/t1404-update-ref-errors.sh64
-rwxr-xr-xt/t1409-avoid-packing-refs.sh16
-rwxr-xr-xt/t1410-reflog.sh4
-rwxr-xr-xt/t1414-reflog-walk.sh3
-rwxr-xr-xt/t1450-fsck.sh18
-rwxr-xr-xt/t1500-rev-parse.sh25
-rwxr-xr-xt/t1501-work-tree.sh2
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh35
-rwxr-xr-xt/t1507-rev-parse-upstream.sh116
-rwxr-xr-xt/t1512-rev-parse-disambiguation.sh4
-rwxr-xr-xt/t1600-index.sh35
-rwxr-xr-xt/t2022-checkout-paths.sh11
-rwxr-xr-xt/t2024-checkout-dwim.sh28
-rwxr-xr-xt/t2026-checkout-pathspec-file.sh163
-rwxr-xr-xt/t2070-restore.sh28
-rwxr-xr-xt/t2072-restore-pathspec-file.sh164
-rwxr-xr-xt/t2400-worktree-add.sh28
-rwxr-xr-xt/t2405-worktree-submodule.sh90
-rwxr-xr-xt/t3005-ls-files-relative.sh12
-rwxr-xr-xt/t3008-ls-files-lazy-init-name-hash.sh2
-rwxr-xr-xt/t3011-common-prefixes-and-directory-traversal.sh209
-rwxr-xr-xt/t3030-merge-recursive.sh37
-rwxr-xr-xt/t3060-ls-files-with-tree.sh4
-rwxr-xr-xt/t3201-branch-contains.sh8
-rwxr-xr-xt/t3206-range-diff.sh529
-rw-r--r--t/t3206/history.export31
-rwxr-xr-xt/t3210-pack-refs.sh2
-rwxr-xr-xt/t3301-notes.sh400
-rwxr-xr-xt/t3305-notes-fanout.sh22
-rwxr-xr-xt/t3306-notes-prune.sh45
-rwxr-xr-xt/t3400-rebase.sh46
-rwxr-xr-xt/t3403-rebase-skip.sh32
-rwxr-xr-xt/t3404-rebase-interactive.sh656
-rwxr-xr-xt/t3416-rebase-onto-threedots.sh57
-rwxr-xr-xt/t3418-rebase-continue.sh14
-rwxr-xr-xt/t3420-rebase-autostash.sh12
-rwxr-xr-xt/t3421-rebase-topology-linear.sh33
-rwxr-xr-xt/t3422-rebase-incompatible-options.sh10
-rwxr-xr-xt/t3427-rebase-subtree.sh160
-rwxr-xr-xt/t3429-rebase-edit-todo.sh53
-rwxr-xr-xt/t3430-rebase-merges.sh76
-rwxr-xr-xt/t3431-rebase-fork-point.sh57
-rwxr-xr-xt/t3432-rebase-fast-forward.sh125
-rwxr-xr-xt/t3434-rebase-i18n.sh84
-rw-r--r--t/t3434/ISO8859-1.txt3
-rw-r--r--t/t3434/eucJP.txt4
-rwxr-xr-xt/t3501-revert-cherry-pick.sh4
-rwxr-xr-xt/t3506-cherry-pick-ff.sh8
-rwxr-xr-xt/t3508-cherry-pick-many-commits.sh2
-rwxr-xr-xt/t3600-rm.sh25
-rwxr-xr-xt/t3700-add.sh4
-rwxr-xr-xt/t3701-add-interactive.sh168
-rwxr-xr-xt/t3704-add-pathspec-file.sh159
-rwxr-xr-xt/t3800-mktag.sh49
-rwxr-xr-xt/t3900-i18n-commit.sh37
-rwxr-xr-xt/t3903-stash.sh66
-rwxr-xr-xt/t3905-stash-include-untracked.sh4
-rwxr-xr-xt/t3906-stash-submodule.sh42
-rwxr-xr-xt/t3908-stash-in-worktree.sh27
-rwxr-xr-xt/t4000-diff-format.sh2
-rwxr-xr-xt/t4002-diff-basic.sh367
-rwxr-xr-xt/t4009-diff-rename-4.sh19
-rwxr-xr-xt/t4010-diff-pathspec.sh20
-rwxr-xr-xt/t4011-diff-symlink.sh40
-rwxr-xr-xt/t4013-diff-various.sh3
-rwxr-xr-xt/t4014-format-patch.sh1059
-rwxr-xr-xt/t4015-diff-whitespace.sh213
-rwxr-xr-xt/t4018-diff-funcname.sh3
-rw-r--r--t/t4018/dts-labels9
-rw-r--r--t/t4018/dts-node-unitless8
-rw-r--r--t/t4018/dts-nodes8
-rw-r--r--t/t4018/dts-nodes-boolean-prop9
-rw-r--r--t/t4018/dts-nodes-comment18
-rw-r--r--t/t4018/dts-nodes-comment28
-rw-r--r--t/t4018/dts-nodes-multiline-prop13
-rw-r--r--t/t4018/dts-reference9
-rw-r--r--t/t4018/dts-root5
-rw-r--r--t/t4018/dts-root-comment8
-rw-r--r--t/t4018/elixir-do-not-pick-end5
-rw-r--r--t/t4018/elixir-ex-unit-test6
-rw-r--r--t/t4018/elixir-function5
-rw-r--r--t/t4018/elixir-macro5
-rw-r--r--t/t4018/elixir-module9
-rw-r--r--t/t4018/elixir-module-func8
-rw-r--r--t/t4018/elixir-nested-module9
-rw-r--r--t/t4018/elixir-private-function5
-rw-r--r--t/t4018/elixir-protocol6
-rw-r--r--t/t4018/elixir-protocol-implementation5
-rw-r--r--t/t4018/python-async-def4
-rw-r--r--t/t4018/python-class4
-rw-r--r--t/t4018/python-def4
-rw-r--r--t/t4018/python-indented-async-def7
-rw-r--r--t/t4018/python-indented-class5
-rw-r--r--t/t4018/python-indented-def7
-rwxr-xr-xt/t4027-diff-submodule.sh16
-rwxr-xr-xt/t4034-diff-words.sh94
-rw-r--r--t/t4034/dts/expect37
-rw-r--r--t/t4034/dts/post32
-rw-r--r--t/t4034/dts/pre32
-rwxr-xr-xt/t4038-diff-combined.sh23
-rwxr-xr-xt/t4039-diff-assume-unchanged.sh3
-rwxr-xr-xt/t4041-diff-submodule-option.sh20
-rwxr-xr-xt/t4044-diff-index-unique-abbrev.sh46
-rwxr-xr-xt/t4045-diff-relative.sh2
-rwxr-xr-xt/t4048-diff-combined-binary.sh58
-rwxr-xr-xt/t4054-diff-bogus-tree.sh3
-rwxr-xr-xt/t4057-diff-combined-paths.sh2
-rwxr-xr-xt/t4066-diff-emit-delay.sh10
-rwxr-xr-xt/t4067-diff-partial-clone.sh31
-rw-r--r--t/t4100/t-apply-1.patch4
-rw-r--r--t/t4100/t-apply-3.patch2
-rw-r--r--t/t4100/t-apply-5.patch4
-rw-r--r--t/t4100/t-apply-7.patch2
-rwxr-xr-xt/t4108-apply-threeway.sh55
-rwxr-xr-xt/t4134-apply-submodule.sh5
-rwxr-xr-xt/t4138-apply-ws-expansion.sh16
-rwxr-xr-xt/t4150-am.sh52
-rwxr-xr-xt/t4200-rerere.sh3
-rwxr-xr-xt/t4202-log.sh171
-rwxr-xr-xt/t4203-mailmap.sh122
-rwxr-xr-xt/t4204-patch-id.sh2
-rwxr-xr-xt/t4205-log-pretty-formats.sh81
-rwxr-xr-xt/t4210-log-i18n.sh41
-rwxr-xr-xt/t4211-line-log.sh82
-rwxr-xr-xt/t4213-log-tabexpand.sh2
-rwxr-xr-xt/t4214-log-graph-octopus.sh353
-rwxr-xr-xt/t4215-log-skewed-merges.sh376
-rwxr-xr-xt/t4256-am-format-flowed.sh2
-rwxr-xr-xt/t4300-merge-tree.sh188
-rwxr-xr-xt/t5004-archive-corner-cases.sh19
-rwxr-xr-xt/t5150-request-pull.sh6
-rwxr-xr-xt/t5307-pack-missing-commit.sh4
-rwxr-xr-xt/t5314-pack-cycle-detection.sh2
-rwxr-xr-xt/t5317-pack-objects-filter-objects.sh34
-rwxr-xr-xt/t5318-commit-graph.sh97
-rwxr-xr-xt/t5319-multi-pack-index.sh95
-rwxr-xr-xt/t5324-split-commit-graph.sh19
-rwxr-xr-xt/t5400-send-pack.sh2
-rwxr-xr-xt/t5500-fetch-pack.sh77
-rwxr-xr-xt/t5504-fetch-receive-strict.sh17
-rwxr-xr-xt/t5510-fetch.sh109
-rwxr-xr-xt/t5512-ls-remote.sh29
-rwxr-xr-xt/t5514-fetch-multiple.sh11
-rwxr-xr-xt/t5515-fetch-merge-logic.sh6
-rwxr-xr-xt/t5516-fetch-push.sh12
-rwxr-xr-xt/t5517-push-mirror.sh10
-rwxr-xr-xt/t5520-pull.sh343
-rwxr-xr-xt/t5528-push-default.sh2
-rwxr-xr-xt/t5530-upload-pack-error.sh26
-rwxr-xr-xt/t5535-fetch-push-symref.sh2
-rwxr-xr-xt/t5537-fetch-shallow.sh11
-rwxr-xr-xt/t5539-fetch-http-shallow.sh2
-rwxr-xr-xt/t5540-http-push-webdav.sh6
-rwxr-xr-xt/t5541-http-push-smart.sh50
-rwxr-xr-xt/t5545-push-options.sh5
-rwxr-xr-xt/t5551-http-fetch-smart.sh12
-rwxr-xr-xt/t5552-skipping-fetch-negotiator.sh41
-rwxr-xr-xt/t5553-set-upstream.sh178
-rwxr-xr-xt/t5562-http-backend-content-length.sh2
-rwxr-xr-xt/t5573-pull-verify-signatures.sh64
-rwxr-xr-xt/t5580-clone-push-unc.sh2
-rwxr-xr-xt/t5601-clone.sh11
-rwxr-xr-xt/t5604-clone-reference.sh5
-rwxr-xr-xt/t5607-clone-bundle.sh11
-rwxr-xr-xt/t5608-clone-2gb.sh2
-rwxr-xr-xt/t5616-partial-clone.sh150
-rwxr-xr-xt/t5700-protocol-v1.sh6
-rwxr-xr-xt/t5702-protocol-v2.sh38
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh249
-rwxr-xr-xt/t5801-remote-helpers.sh1
-rwxr-xr-xt/t6000-rev-list-misc.sh8
-rwxr-xr-xt/t6006-rev-list-format.sh33
-rwxr-xr-xt/t6011-rev-list-with-bad-commit.sh2
-rwxr-xr-xt/t6016-rev-list-graph-simplify-history.sh30
-rwxr-xr-xt/t6019-rev-list-ancestry-path.sh4
-rwxr-xr-xt/t6021-merge-criss-cross.sh2
-rwxr-xr-xt/t6024-recursive-merge.sh130
-rwxr-xr-xt/t6025-merge-symlinks.sh95
-rwxr-xr-xt/t6030-bisect-porcelain.sh2
-rwxr-xr-xt/t6036-recursive-corner-cases.sh12
-rwxr-xr-xt/t6042-merge-rename-corner-cases.sh111
-rwxr-xr-xt/t6043-merge-rename-directories.sh574
-rwxr-xr-xt/t6046-merge-skip-unneeded-updates.sh135
-rwxr-xr-xt/t6047-diff3-conflict-markers.sh202
-rwxr-xr-xt/t6102-rev-list-unexpected-objects.sh2
-rwxr-xr-xt/t6112-rev-list-filters-objects.sh194
-rwxr-xr-xt/t6120-describe.sh87
-rwxr-xr-xt/t6300-for-each-ref.sh19
-rwxr-xr-xt/t6500-gc.sh6
-rwxr-xr-xt/t6501-freshen-objects.sh6
-rwxr-xr-xt/t7004-tag.sh9
-rwxr-xr-xt/t7008-filter-branch-null-sha1.sh (renamed from t/t7009-filter-branch-null-sha1.sh)0
-rwxr-xr-xt/t7012-skip-worktree-writing.sh15
-rwxr-xr-xt/t7030-verify-tag.sh38
-rwxr-xr-xt/t7061-wtstatus-ignore.sh9
-rwxr-xr-xt/t7105-reset-patch.sh21
-rwxr-xr-xt/t7107-reset-pathspec-file.sh173
-rwxr-xr-xt/t7300-clean.sh73
-rwxr-xr-xt/t7400-submodule-basic.sh41
-rwxr-xr-xt/t7406-submodule-update.sh5
-rwxr-xr-xt/t7410-submodule-checkout-to.sh77
-rwxr-xr-xt/t7415-submodule-names.sh7
-rwxr-xr-xt/t7419-submodule-set-branch.sh6
-rwxr-xr-xt/t7420-submodule-set-url.sh55
-rwxr-xr-xt/t7500-commit-template-squash-signoff.sh9
-rwxr-xr-xt/t7501-commit-basic-functionality.sh83
-rwxr-xr-xt/t7503-pre-commit-and-pre-merge-commit-hooks.sh281
-rwxr-xr-xt/t7503-pre-commit-hook.sh139
-rwxr-xr-xt/t7505-prepare-commit-msg-hook.sh8
-rw-r--r--t/t7505/expected-rebase-i3
-rwxr-xr-xt/t7508-status.sh2
-rwxr-xr-xt/t7510-signed-commit.sh39
-rwxr-xr-xt/t7512-status-help.sh6
-rwxr-xr-xt/t7513-interpret-trailers.sh2
-rwxr-xr-xt/t7519-status-fsmonitor.sh37
-rwxr-xr-xt/t7519/fsmonitor-all1
-rwxr-xr-xt/t7519/fsmonitor-all-v221
-rwxr-xr-xt/t7519/fsmonitor-env24
-rwxr-xr-xt/t7519/fsmonitor-watchman16
-rwxr-xr-xt/t7519/fsmonitor-watchman-v2173
-rwxr-xr-xt/t7526-commit-pathspec-file.sh164
-rwxr-xr-xt/t7612-merge-verify-signatures.sh22
-rwxr-xr-xt/t7700-repack.sh172
-rwxr-xr-xt/t7800-difftool.sh5
-rwxr-xr-xt/t7811-grep-open.sh1
-rwxr-xr-xt/t7812-grep-icase-non-ascii.sh31
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh32
-rwxr-xr-xt/t7815-grep-binary.sh (renamed from t/t7008-grep-binary.sh)101
-rwxr-xr-xt/t7816-grep-binary-pattern.sh127
-rwxr-xr-xt/t9001-send-email.sh4
-rwxr-xr-xt/t9010-svn-fe.sh4
-rwxr-xr-xt/t9300-fast-import.sh73
-rwxr-xr-xt/t9301-fast-import-notes.sh2
-rwxr-xr-xt/t9350-fast-export.sh68
-rwxr-xr-xt/t9502-gitweb-standalone-parse-output.sh7
-rwxr-xr-xt/t9809-git-p4-client-view.sh2
-rwxr-xr-xt/t9902-completion.sh145
-rw-r--r--t/test-lib-functions.sh61
-rw-r--r--t/test-lib.sh81
294 files changed, 12209 insertions, 3615 deletions
diff --git a/t/README b/t/README
index 60d5b77bcc..9afd61e3ca 100644
--- a/t/README
+++ b/t/README
@@ -352,8 +352,8 @@ details.
GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
test suite. Accept any boolean values that are accepted by git-config.
-GIT_TEST_PROTOCOL_VERSION=<n>, when set, overrides the
-'protocol.version' setting to n if it is less than n.
+GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version'
+default to n.
GIT_TEST_FULL_IN_PACK_ARRAY=<boolean> exercises the uncommon
pack-objects code path where there are more than 1024 packs even if
@@ -397,6 +397,10 @@ GIT_TEST_STASH_USE_BUILTIN=<boolean>, when false, disables the
built-in version of git-stash. See 'stash.useBuiltin' in
git-config(1).
+GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when true, enables the
+built-in version of git add -i. See 'add.interactive.useBuiltin' in
+git-config(1).
+
GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading
of the index for the whole test suite by bypassing the default number of
cache entries and thread minimums. Setting this to 1 will make the
@@ -978,6 +982,15 @@ library for your script to use.
output to the downstream---unlike the real version, it generates
only up to 99 lines.
+ - test_bool_env <env-variable-name> <default-value>
+
+ Given the name of an environment variable with a bool value,
+ normalize its value to a 0 (true) or 1 (false or empty string)
+ return code. Return with code corresponding to the given default
+ value if the variable is unset.
+ Abort the test script if either the value of the variable or the
+ default are not valid bool values.
+
Prerequisites
-------------
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index 38bfeebd88..fd3303552b 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -46,7 +46,7 @@ while (<>) {
/(?:\$\(seq|^\s*seq\b)/ and err 'seq is not portable (use test_seq)';
/\bgrep\b.*--file\b/ and err 'grep --file FILE is not portable (use grep -f FILE)';
/\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)';
- /^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
+ /^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
err '"FOO=bar shell_func" assignment extends beyond "shell_func"';
$line = '';
# this resets our $. for each file
diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh
index 006d2a8152..1f32ca66ea 100644
--- a/t/gitweb-lib.sh
+++ b/t/gitweb-lib.sh
@@ -58,10 +58,11 @@ gitweb_run () {
GATEWAY_INTERFACE='CGI/1.1'
HTTP_ACCEPT='*/*'
REQUEST_METHOD='GET'
- QUERY_STRING=""$1""
- PATH_INFO=""$2""
+ QUERY_STRING=$1
+ PATH_INFO=$2
+ REQUEST_URI=/gitweb.cgi$PATH_INFO
export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD \
- QUERY_STRING PATH_INFO
+ QUERY_STRING PATH_INFO REQUEST_URI
GITWEB_CONFIG=$(pwd)/gitweb_config.perl
export GITWEB_CONFIG
diff --git a/t/helper/.gitignore b/t/helper/.gitignore
index 2bad28af92..48c7bb0bbb 100644
--- a/t/helper/.gitignore
+++ b/t/helper/.gitignore
@@ -1,5 +1,4 @@
-*
-!*.sh
-!*.[ch]
-!*.gitignore
-
+/test-tool
+/test-fake-ssh
+/test-line-buffer
+/test-svn-fe
diff --git a/t/helper/test-date.c b/t/helper/test-date.c
index 585347ea48..099eff4f0f 100644
--- a/t/helper/test-date.c
+++ b/t/helper/test-date.c
@@ -12,13 +12,13 @@ static const char *usage_msg = "\n"
" test-tool date is64bit\n"
" test-tool date time_t-is64bit\n";
-static void show_relative_dates(const char **argv, struct timeval *now)
+static void show_relative_dates(const char **argv)
{
struct strbuf buf = STRBUF_INIT;
for (; *argv; argv++) {
time_t t = atoi(*argv);
- show_date_relative(t, now, &buf);
+ show_date_relative(t, &buf);
printf("%s -> %s\n", *argv, buf.buf);
}
strbuf_release(&buf);
@@ -74,20 +74,20 @@ static void parse_dates(const char **argv)
strbuf_release(&result);
}
-static void parse_approxidate(const char **argv, struct timeval *now)
+static void parse_approxidate(const char **argv)
{
for (; *argv; argv++) {
timestamp_t t;
- t = approxidate_relative(*argv, now);
+ t = approxidate_relative(*argv);
printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(ISO8601)));
}
}
-static void parse_approx_timestamp(const char **argv, struct timeval *now)
+static void parse_approx_timestamp(const char **argv)
{
for (; *argv; argv++) {
timestamp_t t;
- t = approxidate_relative(*argv, now);
+ t = approxidate_relative(*argv);
printf("%s -> %"PRItime"\n", *argv, t);
}
}
@@ -103,22 +103,13 @@ static void getnanos(const char **argv)
int cmd__date(int argc, const char **argv)
{
- struct timeval now;
const char *x;
- x = getenv("GIT_TEST_DATE_NOW");
- if (x) {
- now.tv_sec = atoi(x);
- now.tv_usec = 0;
- }
- else
- gettimeofday(&now, NULL);
-
argv++;
if (!*argv)
usage(usage_msg);
if (!strcmp(*argv, "relative"))
- show_relative_dates(argv+1, &now);
+ show_relative_dates(argv+1);
else if (!strcmp(*argv, "human"))
show_human_dates(argv+1);
else if (skip_prefix(*argv, "show:", &x))
@@ -126,9 +117,9 @@ int cmd__date(int argc, const char **argv)
else if (!strcmp(*argv, "parse"))
parse_dates(argv+1);
else if (!strcmp(*argv, "approxidate"))
- parse_approxidate(argv+1, &now);
+ parse_approxidate(argv+1);
else if (!strcmp(*argv, "timestamp"))
- parse_approx_timestamp(argv+1, &now);
+ parse_approx_timestamp(argv+1);
else if (!strcmp(*argv, "getnanos"))
getnanos(argv+1);
else if (!strcmp(*argv, "is64bit"))
diff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c
index 2786f47088..975f0ac890 100644
--- a/t/helper/test-dump-fsmonitor.c
+++ b/t/helper/test-dump-fsmonitor.c
@@ -13,7 +13,7 @@ int cmd__dump_fsmonitor(int ac, const char **av)
printf("no fsmonitor\n");
return 0;
}
- printf("fsmonitor last update %"PRIuMAX"\n", (uintmax_t)istate->fsmonitor_last_update);
+ printf("fsmonitor last update %s\n", istate->fsmonitor_last_update);
for (i = 0; i < istate->cache_nr; i++)
printf((istate->cache[i]->ce_flags & CE_FSMONITOR_VALID) ? "+" : "-");
diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c
index aaf17b0ddf..f38706216f 100644
--- a/t/helper/test-hashmap.c
+++ b/t/helper/test-hashmap.c
@@ -5,6 +5,7 @@
struct test_entry
{
+ int padding; /* hashmap entry no longer needs to be the first member */
struct hashmap_entry ent;
/* key and value as two \0-terminated strings */
char key[FLEX_ARRAY];
@@ -16,15 +17,17 @@ static const char *get_value(const struct test_entry *e)
}
static int test_entry_cmp(const void *cmp_data,
- const void *entry,
- const void *entry_or_key,
+ const struct hashmap_entry *eptr,
+ const struct hashmap_entry *entry_or_key,
const void *keydata)
{
const int ignore_case = cmp_data ? *((int *)cmp_data) : 0;
- const struct test_entry *e1 = entry;
- const struct test_entry *e2 = entry_or_key;
+ const struct test_entry *e1, *e2;
const char *key = keydata;
+ e1 = container_of(eptr, const struct test_entry, ent);
+ e2 = container_of(entry_or_key, const struct test_entry, ent);
+
if (ignore_case)
return strcasecmp(e1->key, key ? key : e2->key);
else
@@ -37,7 +40,7 @@ static struct test_entry *alloc_test_entry(unsigned int hash,
size_t klen = strlen(key);
size_t vlen = strlen(value);
struct test_entry *entry = xmalloc(st_add4(sizeof(*entry), klen, vlen, 2));
- hashmap_entry_init(entry, hash);
+ hashmap_entry_init(&entry->ent, hash);
memcpy(entry->key, key, klen + 1);
memcpy(entry->key + klen + 1, value, vlen + 1);
return entry;
@@ -103,11 +106,11 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
/* add entries */
for (i = 0; i < TEST_SIZE; i++) {
- hashmap_entry_init(entries[i], hashes[i]);
- hashmap_add(&map, entries[i]);
+ hashmap_entry_init(&entries[i]->ent, hashes[i]);
+ hashmap_add(&map, &entries[i]->ent);
}
- hashmap_free(&map, 0);
+ hashmap_free(&map);
}
} else {
/* test map lookups */
@@ -116,8 +119,8 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
/* fill the map (sparsely if specified) */
j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
for (i = 0; i < j; i++) {
- hashmap_entry_init(entries[i], hashes[i]);
- hashmap_add(&map, entries[i]);
+ hashmap_entry_init(&entries[i]->ent, hashes[i]);
+ hashmap_add(&map, &entries[i]->ent);
}
for (j = 0; j < rounds; j++) {
@@ -127,7 +130,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
}
}
- hashmap_free(&map, 0);
+ hashmap_free(&map);
}
}
@@ -179,7 +182,7 @@ int cmd__hashmap(int argc, const char **argv)
entry = alloc_test_entry(hash, p1, p2);
/* add to hashmap */
- hashmap_add(&map, entry);
+ hashmap_add(&map, &entry->ent);
} else if (!strcmp("put", cmd) && p1 && p2) {
@@ -187,43 +190,44 @@ int cmd__hashmap(int argc, const char **argv)
entry = alloc_test_entry(hash, p1, p2);
/* add / replace entry */
- entry = hashmap_put(&map, entry);
+ entry = hashmap_put_entry(&map, entry, ent);
/* print and free replaced entry, if any */
puts(entry ? get_value(entry) : "NULL");
free(entry);
} else if (!strcmp("get", cmd) && p1) {
-
/* lookup entry in hashmap */
- entry = hashmap_get_from_hash(&map, hash, p1);
+ entry = hashmap_get_entry_from_hash(&map, hash, p1,
+ struct test_entry, ent);
/* print result */
if (!entry)
puts("NULL");
- while (entry) {
+ hashmap_for_each_entry_from(&map, entry, ent)
puts(get_value(entry));
- entry = hashmap_get_next(&map, entry);
- }
} else if (!strcmp("remove", cmd) && p1) {
/* setup static key */
struct hashmap_entry key;
+ struct hashmap_entry *rm;
hashmap_entry_init(&key, hash);
/* remove entry from hashmap */
- entry = hashmap_remove(&map, &key, p1);
+ rm = hashmap_remove(&map, &key, p1);
+ entry = rm ? container_of(rm, struct test_entry, ent)
+ : NULL;
/* print result and free entry*/
puts(entry ? get_value(entry) : "NULL");
free(entry);
} else if (!strcmp("iterate", cmd)) {
-
struct hashmap_iter iter;
- hashmap_iter_init(&map, &iter);
- while ((entry = hashmap_iter_next(&iter)))
+
+ hashmap_for_each_entry(&map, &iter, entry,
+ ent /* member name */)
printf("%s %s\n", entry->key, get_value(entry));
} else if (!strcmp("size", cmd)) {
@@ -258,6 +262,6 @@ int cmd__hashmap(int argc, const char **argv)
}
strbuf_release(&line);
- hashmap_free(&map, 1);
+ hashmap_free_entries(&map, struct test_entry, ent);
return 0;
}
diff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c
index b99a37080d..cd1b4c9736 100644
--- a/t/helper/test-lazy-init-name-hash.c
+++ b/t/helper/test-lazy-init-name-hash.c
@@ -41,17 +41,13 @@ static void dump_run(void)
die("non-threaded code path used");
}
- dir = hashmap_iter_first(&the_index.dir_hash, &iter_dir);
- while (dir) {
+ hashmap_for_each_entry(&the_index.dir_hash, &iter_dir, dir,
+ ent /* member name */)
printf("dir %08x %7d %s\n", dir->ent.hash, dir->nr, dir->name);
- dir = hashmap_iter_next(&iter_dir);
- }
- ce = hashmap_iter_first(&the_index.name_hash, &iter_cache);
- while (ce) {
+ hashmap_for_each_entry(&the_index.name_hash, &iter_cache, ce,
+ ent /* member name */)
printf("name %08x %s\n", ce->ent.hash, ce->name);
- ce = hashmap_iter_next(&iter_cache);
- }
discard_cache();
}
diff --git a/t/helper/test-parse-pathspec-file.c b/t/helper/test-parse-pathspec-file.c
new file mode 100644
index 0000000000..02f4ccfd2a
--- /dev/null
+++ b/t/helper/test-parse-pathspec-file.c
@@ -0,0 +1,33 @@
+#include "test-tool.h"
+#include "parse-options.h"
+#include "pathspec.h"
+#include "gettext.h"
+
+int cmd__parse_pathspec_file(int argc, const char **argv)
+{
+ struct pathspec pathspec;
+ const char *pathspec_from_file = 0;
+ int pathspec_file_nul = 0, i;
+
+ static const char *const usage[] = {
+ "test-tool parse-pathspec-file --pathspec-from-file [--pathspec-file-nul]",
+ NULL
+ };
+
+ struct option options[] = {
+ OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
+ OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
+ OPT_END()
+ };
+
+ parse_options(argc, argv, 0, options, usage, 0);
+
+ parse_pathspec_file(&pathspec, 0, 0, 0, pathspec_from_file,
+ pathspec_file_nul);
+
+ for (i = 0; i < pathspec.nr; i++)
+ printf("%s\n", pathspec.items[i].original);
+
+ clear_pathspec(&pathspec);
+ return 0;
+}
diff --git a/t/helper/test-progress.c b/t/helper/test-progress.c
new file mode 100644
index 0000000000..42b96cb103
--- /dev/null
+++ b/t/helper/test-progress.c
@@ -0,0 +1,81 @@
+/*
+ * A test helper to exercise the progress display.
+ *
+ * Reads instructions from standard input, one instruction per line:
+ *
+ * "progress <items>" - Call display_progress() with the given item count
+ * as parameter.
+ * "throughput <bytes> <millis> - Call display_throughput() with the given
+ * byte count as parameter. The 'millis'
+ * specify the time elapsed since the
+ * start_progress() call.
+ * "update" - Set the 'progress_update' flag.
+ *
+ * See 't0500-progress-display.sh' for examples.
+ */
+#include "test-tool.h"
+#include "gettext.h"
+#include "parse-options.h"
+#include "progress.h"
+#include "strbuf.h"
+
+/*
+ * These are defined in 'progress.c', but are not exposed in 'progress.h',
+ * because they are exclusively for testing.
+ */
+extern int progress_testing;
+extern uint64_t progress_test_ns;
+void progress_test_force_update(void);
+
+int cmd__progress(int argc, const char **argv)
+{
+ int total = 0;
+ const char *title;
+ struct strbuf line = STRBUF_INIT;
+ struct progress *progress;
+
+ const char *usage[] = {
+ "test-tool progress [--total=<n>] <progress-title>",
+ NULL
+ };
+ struct option options[] = {
+ OPT_INTEGER(0, "total", &total, "total number of items"),
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, NULL, options, usage, 0);
+ if (argc != 1)
+ die("need a title for the progress output");
+ title = argv[0];
+
+ progress_testing = 1;
+ progress = start_progress(title, total);
+ while (strbuf_getline(&line, stdin) != EOF) {
+ char *end;
+
+ if (skip_prefix(line.buf, "progress ", (const char **) &end)) {
+ uint64_t item_count = strtoull(end, &end, 10);
+ if (*end != '\0')
+ die("invalid input: '%s'\n", line.buf);
+ display_progress(progress, item_count);
+ } else if (skip_prefix(line.buf, "throughput ",
+ (const char **) &end)) {
+ uint64_t byte_count, test_ms;
+
+ byte_count = strtoull(end, &end, 10);
+ if (*end != ' ')
+ die("invalid input: '%s'\n", line.buf);
+ test_ms = strtoull(end + 1, &end, 10);
+ if (*end != '\0')
+ die("invalid input: '%s'\n", line.buf);
+ progress_test_ns = test_ms * 1000 * 1000;
+ display_throughput(progress, byte_count);
+ } else if (!strcmp(line.buf, "update"))
+ progress_test_force_update();
+ else
+ die("invalid input: '%s'\n", line.buf);
+ }
+ stop_progress(&progress);
+
+ return 0;
+}
diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c
index 7e79b555de..244977a29b 100644
--- a/t/helper/test-read-cache.c
+++ b/t/helper/test-read-cache.c
@@ -4,11 +4,10 @@
int cmd__read_cache(int argc, const char **argv)
{
- int i, cnt = 1, namelen;
+ int i, cnt = 1;
const char *name = NULL;
if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) {
- namelen = strlen(name);
argc--;
argv++;
}
@@ -24,7 +23,7 @@ int cmd__read_cache(int argc, const char **argv)
refresh_index(&the_index, REFRESH_QUIET,
NULL, NULL, NULL);
- pos = index_name_pos(&the_index, name, namelen);
+ pos = index_name_pos(&the_index, name, strlen(name));
if (pos < 0)
die("%s not in index", name);
printf("%s is%s up to date\n", name,
diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c
new file mode 100644
index 0000000000..d2884efe0a
--- /dev/null
+++ b/t/helper/test-read-graph.c
@@ -0,0 +1,53 @@
+#include "test-tool.h"
+#include "cache.h"
+#include "commit-graph.h"
+#include "repository.h"
+#include "object-store.h"
+
+int cmd__read_graph(int argc, const char **argv)
+{
+ struct commit_graph *graph = NULL;
+ char *graph_name;
+ int open_ok;
+ int fd;
+ struct stat st;
+ const char *object_dir;
+
+ setup_git_directory();
+ object_dir = get_object_directory();
+
+ graph_name = get_commit_graph_filename(object_dir);
+
+ open_ok = open_commit_graph(graph_name, &fd, &st);
+ if (!open_ok)
+ die_errno(_("Could not open commit-graph '%s'"), graph_name);
+
+ graph = load_commit_graph_one_fd_st(fd, &st);
+ if (!graph)
+ return 1;
+
+ FREE_AND_NULL(graph_name);
+
+ printf("header: %08x %d %d %d %d\n",
+ ntohl(*(uint32_t*)graph->data),
+ *(unsigned char*)(graph->data + 4),
+ *(unsigned char*)(graph->data + 5),
+ *(unsigned char*)(graph->data + 6),
+ *(unsigned char*)(graph->data + 7));
+ printf("num_commits: %u\n", graph->num_commits);
+ printf("chunks:");
+
+ if (graph->chunk_oid_fanout)
+ printf(" oid_fanout");
+ if (graph->chunk_oid_lookup)
+ printf(" oid_lookup");
+ if (graph->chunk_commit_data)
+ printf(" commit_metadata");
+ if (graph->chunk_extra_edges)
+ printf(" extra_edges");
+ printf("\n");
+
+ UNLEAK(graph);
+
+ return 0;
+}
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index 8579b1f7d1..1646aa25d8 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -10,9 +10,14 @@
#include "test-tool.h"
#include "git-compat-util.h"
+#include "cache.h"
#include "run-command.h"
#include "argv-array.h"
#include "strbuf.h"
+#include "parse-options.h"
+#include "string-list.h"
+#include "thread-utils.h"
+#include "wildmatch.h"
#include "gettext.h"
#include "parse-options.h"
@@ -50,6 +55,151 @@ static int task_finished(int result,
return 1;
}
+struct testsuite {
+ struct string_list tests, failed;
+ int next;
+ int quiet, immediate, verbose, verbose_log, trace, write_junit_xml;
+};
+#define TESTSUITE_INIT \
+ { STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, -1, 0, 0, 0, 0, 0, 0 }
+
+static int next_test(struct child_process *cp, struct strbuf *err, void *cb,
+ void **task_cb)
+{
+ struct testsuite *suite = cb;
+ const char *test;
+ if (suite->next >= suite->tests.nr)
+ return 0;
+
+ test = suite->tests.items[suite->next++].string;
+ argv_array_pushl(&cp->args, "sh", test, NULL);
+ if (suite->quiet)
+ argv_array_push(&cp->args, "--quiet");
+ if (suite->immediate)
+ argv_array_push(&cp->args, "-i");
+ if (suite->verbose)
+ argv_array_push(&cp->args, "-v");
+ if (suite->verbose_log)
+ argv_array_push(&cp->args, "-V");
+ if (suite->trace)
+ argv_array_push(&cp->args, "-x");
+ if (suite->write_junit_xml)
+ argv_array_push(&cp->args, "--write-junit-xml");
+
+ strbuf_addf(err, "Output of '%s':\n", test);
+ *task_cb = (void *)test;
+
+ return 1;
+}
+
+static int test_finished(int result, struct strbuf *err, void *cb,
+ void *task_cb)
+{
+ struct testsuite *suite = cb;
+ const char *name = (const char *)task_cb;
+
+ if (result)
+ string_list_append(&suite->failed, name);
+
+ strbuf_addf(err, "%s: '%s'\n", result ? "FAIL" : "SUCCESS", name);
+
+ return 0;
+}
+
+static int test_failed(struct strbuf *out, void *cb, void *task_cb)
+{
+ struct testsuite *suite = cb;
+ const char *name = (const char *)task_cb;
+
+ string_list_append(&suite->failed, name);
+ strbuf_addf(out, "FAILED TO START: '%s'\n", name);
+
+ return 0;
+}
+
+static const char * const testsuite_usage[] = {
+ "test-run-command testsuite [<options>] [<pattern>...]",
+ NULL
+};
+
+static int testsuite(int argc, const char **argv)
+{
+ struct testsuite suite = TESTSUITE_INIT;
+ int max_jobs = 1, i, ret;
+ DIR *dir;
+ struct dirent *d;
+ struct option options[] = {
+ OPT_BOOL('i', "immediate", &suite.immediate,
+ "stop at first failed test case(s)"),
+ OPT_INTEGER('j', "jobs", &max_jobs, "run <N> jobs in parallel"),
+ OPT_BOOL('q', "quiet", &suite.quiet, "be terse"),
+ OPT_BOOL('v', "verbose", &suite.verbose, "be verbose"),
+ OPT_BOOL('V', "verbose-log", &suite.verbose_log,
+ "be verbose, redirected to a file"),
+ OPT_BOOL('x', "trace", &suite.trace, "trace shell commands"),
+ OPT_BOOL(0, "write-junit-xml", &suite.write_junit_xml,
+ "write JUnit-style XML files"),
+ OPT_END()
+ };
+
+ memset(&suite, 0, sizeof(suite));
+ suite.tests.strdup_strings = suite.failed.strdup_strings = 1;
+
+ argc = parse_options(argc, argv, NULL, options,
+ testsuite_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+
+ if (max_jobs <= 0)
+ max_jobs = online_cpus();
+
+ dir = opendir(".");
+ if (!dir)
+ die("Could not open the current directory");
+ while ((d = readdir(dir))) {
+ const char *p = d->d_name;
+
+ if (*p != 't' || !isdigit(p[1]) || !isdigit(p[2]) ||
+ !isdigit(p[3]) || !isdigit(p[4]) || p[5] != '-' ||
+ !ends_with(p, ".sh"))
+ continue;
+
+ /* No pattern: match all */
+ if (!argc) {
+ string_list_append(&suite.tests, p);
+ continue;
+ }
+
+ for (i = 0; i < argc; i++)
+ if (!wildmatch(argv[i], p, 0)) {
+ string_list_append(&suite.tests, p);
+ break;
+ }
+ }
+ closedir(dir);
+
+ if (!suite.tests.nr)
+ die("No tests match!");
+ if (max_jobs > suite.tests.nr)
+ max_jobs = suite.tests.nr;
+
+ fprintf(stderr, "Running %d tests (%d at a time)\n",
+ suite.tests.nr, max_jobs);
+
+ ret = run_processes_parallel(max_jobs, next_test, test_failed,
+ test_finished, &suite);
+
+ if (suite.failed.nr > 0) {
+ ret = 1;
+ fprintf(stderr, "%d tests failed:\n\n", suite.failed.nr);
+ for (i = 0; i < suite.failed.nr; i++)
+ fprintf(stderr, "\t%s\n", suite.failed.items[i].string);
+ }
+
+ string_list_clear(&suite.tests, 0);
+ string_list_clear(&suite.failed, 0);
+
+ return !!ret;
+}
+
static uint64_t my_random_next = 1234;
static uint64_t my_random(void)
@@ -178,11 +328,58 @@ static int quote_echo(int argc, const char **argv)
return 0;
}
+static int inherit_handle(const char *argv0)
+{
+ struct child_process cp = CHILD_PROCESS_INIT;
+ char path[PATH_MAX];
+ int tmp;
+
+ /* First, open an inheritable handle */
+ xsnprintf(path, sizeof(path), "out-XXXXXX");
+ tmp = xmkstemp(path);
+
+ argv_array_pushl(&cp.args,
+ "test-tool", argv0, "inherited-handle-child", NULL);
+ cp.in = -1;
+ cp.no_stdout = cp.no_stderr = 1;
+ if (start_command(&cp) < 0)
+ die("Could not start child process");
+
+ /* Then close it, and try to delete it. */
+ close(tmp);
+ if (unlink(path))
+ die("Could not delete '%s'", path);
+
+ if (close(cp.in) < 0 || finish_command(&cp) < 0)
+ die("Child did not finish");
+
+ return 0;
+}
+
+static int inherit_handle_child(void)
+{
+ struct strbuf buf = STRBUF_INIT;
+
+ if (strbuf_read(&buf, 0, 0) < 0)
+ die("Could not read stdin");
+ printf("Received %s\n", buf.buf);
+ strbuf_release(&buf);
+
+ return 0;
+}
+
int cmd__run_command(int argc, const char **argv)
{
struct child_process proc = CHILD_PROCESS_INIT;
int jobs;
+ if (argc > 1 && !strcmp(argv[1], "testsuite"))
+ exit(testsuite(argc - 1, argv + 1));
+ if (!strcmp(argv[1], "inherited-handle"))
+ exit(inherit_handle(argv[0]));
+ if (!strcmp(argv[1], "inherited-handle-child"))
+ exit(inherit_handle_child());
+
if (argc >= 2 && !strcmp(argv[1], "quote-stress-test"))
return !!quote_stress_test(argc - 1, argv + 1);
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index ce7e89028c..c9a232d238 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -39,11 +39,14 @@ static struct test_cmd cmds[] = {
{ "oidmap", cmd__oidmap },
{ "online-cpus", cmd__online_cpus },
{ "parse-options", cmd__parse_options },
+ { "parse-pathspec-file", cmd__parse_pathspec_file },
{ "path-utils", cmd__path_utils },
{ "pkt-line", cmd__pkt_line },
{ "prio-queue", cmd__prio_queue },
+ { "progress", cmd__progress },
{ "reach", cmd__reach },
{ "read-cache", cmd__read_cache },
+ { "read-graph", cmd__read_graph },
{ "read-midx", cmd__read_midx },
{ "ref-store", cmd__ref_store },
{ "regex", cmd__regex },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index f805bb39ae..c8549fd87f 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -29,11 +29,14 @@ int cmd__mktemp(int argc, const char **argv);
int cmd__oidmap(int argc, const char **argv);
int cmd__online_cpus(int argc, const char **argv);
int cmd__parse_options(int argc, const char **argv);
+int cmd__parse_pathspec_file(int argc, const char** argv);
int cmd__path_utils(int argc, const char **argv);
int cmd__pkt_line(int argc, const char **argv);
int cmd__prio_queue(int argc, const char **argv);
+int cmd__progress(int argc, const char **argv);
int cmd__reach(int argc, const char **argv);
int cmd__read_cache(int argc, const char **argv);
+int cmd__read_graph(int argc, const char **argv);
int cmd__read_midx(int argc, const char **argv);
int cmd__ref_store(int argc, const char **argv);
int cmd__regex(int argc, const char **argv);
diff --git a/t/lib-bash.sh b/t/lib-bash.sh
index 2be955fafb..b0b6060929 100644
--- a/t/lib-bash.sh
+++ b/t/lib-bash.sh
@@ -2,10 +2,12 @@
# to run under Bash; primarily intended for tests of the completion
# script.
-if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then
+if test -n "$BASH" && test -z "$POSIXLY_CORRECT"
+then
# we are in full-on bash mode
true
-elif type bash >/dev/null 2>&1; then
+elif type bash >/dev/null 2>&1
+then
# execute in full-on bash mode
unset POSIXLY_CORRECT
exec bash "$0" "$@"
diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
index fb8f887080..e62569222b 100644
--- a/t/lib-git-daemon.sh
+++ b/t/lib-git-daemon.sh
@@ -15,7 +15,7 @@
#
# test_done
-if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON
+if ! test_bool_env GIT_TEST_GIT_DAEMON true
then
skip_all="git-daemon testing disabled (unset GIT_TEST_GIT_DAEMON to enable)"
test_done
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index 547b9f88e1..5aff2abe8b 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -175,7 +175,7 @@ stop_and_cleanup_p4d () {
cleanup_git () {
retry_until_success rm -r "$git"
- test_must_fail test -d "$git" &&
+ test_path_is_missing "$git" &&
retry_until_success mkdir "$git"
}
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 5d4ae629e1..7d248e6588 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -69,7 +69,7 @@ svn_cmd () {
maybe_start_httpd () {
loc=${1-svn}
- if git env--helper --type=bool --default=false --exit-code GIT_TEST_HTTPD
+ if test_bool_env GIT_TEST_SVN_HTTPD false
then
. "$TEST_DIRECTORY"/lib-httpd.sh
LIB_HTTPD_SVN="$loc"
@@ -104,7 +104,7 @@ EOF
}
require_svnserve () {
- if ! git env--helper --type=bool --default=false --exit-code GIT_TEST_SVNSERVE
+ if ! test_bool_env GIT_TEST_SVNSERVE false
then
skip_all='skipping svnserve test. (set $GIT_TEST_SVNSERVE to enable)'
test_done
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 0d985758c6..656997b4d6 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -41,7 +41,7 @@ then
test_done
fi
-if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_HTTPD
+if ! test_bool_env GIT_TEST_HTTPD true
then
skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)"
test_done
diff --git a/t/lib-httpd/apply-one-time-sed.sh b/t/lib-httpd/apply-one-time-sed.sh
index fcef728925..bf7689d020 100644
--- a/t/lib-httpd/apply-one-time-sed.sh
+++ b/t/lib-httpd/apply-one-time-sed.sh
@@ -7,11 +7,13 @@
#
# This can be used to simulate the effects of the repository changing in
# between HTTP request-response pairs.
-if [ -e one-time-sed ]; then
+if test -f one-time-sed
+then
"$GIT_EXEC_PATH/git-http-backend" >out
- sed "$(cat one-time-sed)" <out >out_modified
+ sed "$(cat one-time-sed)" out >out_modified
- if diff out out_modified >/dev/null; then
+ if cmp -s out out_modified
+ then
cat out
else
cat out_modified
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 7ea30e5006..b72c051f47 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -44,10 +44,10 @@ set_fake_editor () {
rm -f "$1"
echo 'rebase -i script before editing:'
cat "$1".tmp
- action=pick
+ action=\&
for line in $FAKE_LINES; do
case $line in
- pick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)
+ pick|p|squash|s|fixup|f|edit|e|reword|r|drop|d|label|l|reset|r|merge|m)
action="$line";;
exec_*|x_*|break|b)
echo "$line" | sed 's/_/ /g' >> "$1";;
@@ -58,11 +58,12 @@ set_fake_editor () {
bad)
action="badcmd";;
fakesha)
+ test \& != "$action" || action=pick
echo "$action XXXXXXX False commit" >> "$1"
action=pick;;
*)
- sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
- action=pick;;
+ sed -n "${line}s/^[a-z][a-z]*/$action/p" < "$1".tmp >> "$1"
+ action=\&;;
esac
done
echo 'rebase -i script after editing:'
@@ -118,3 +119,31 @@ make_empty () {
git commit --allow-empty -m "$1" &&
git tag "$1"
}
+
+# Call this (inside test_expect_success) at the end of a test file to
+# check that no tests have changed editor related environment
+# variables or config settings
+test_editor_unchanged () {
+ # We're only interested in exported variables hence 'sh -c'
+ sh -c 'cat >actual <<-EOF
+ EDITOR=$EDITOR
+ FAKE_COMMIT_AMEND=$FAKE_COMMIT_AMEND
+ FAKE_COMMIT_MESSAGE=$FAKE_COMMIT_MESSAGE
+ FAKE_LINES=$FAKE_LINES
+ GIT_EDITOR=$GIT_EDITOR
+ GIT_SEQUENCE_EDITOR=$GIT_SEQUENCE_EDITOR
+ core.editor=$(git config core.editor)
+ sequence.editor=$(git config sequence.editor)
+ EOF'
+ cat >expect <<-\EOF
+ EDITOR=:
+ FAKE_COMMIT_AMEND=
+ FAKE_COMMIT_MESSAGE=
+ FAKE_LINES=
+ GIT_EDITOR=
+ GIT_SEQUENCE_EDITOR=
+ core.editor=
+ sequence.editor=
+ EOF
+ test_cmp expect actual
+}
diff --git a/t/oid-info/hash-info b/t/oid-info/hash-info
index ccdbfdf974..d0736dd1a0 100644
--- a/t/oid-info/hash-info
+++ b/t/oid-info/hash-info
@@ -6,3 +6,12 @@ hexsz sha256:64
zero sha1:0000000000000000000000000000000000000000
zero sha256:0000000000000000000000000000000000000000000000000000000000000000
+
+algo sha1:sha1
+algo sha256:sha256
+
+empty_blob sha1:e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+empty_blob sha256:473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813
+
+empty_tree sha1:4b825dc642cb6eb9a060e54bf8d69288fbee4904
+empty_tree sha256:6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321
diff --git a/t/perf/aggregate.perl b/t/perf/aggregate.perl
index 66554d2161..14e4cda287 100755
--- a/t/perf/aggregate.perl
+++ b/t/perf/aggregate.perl
@@ -4,7 +4,6 @@ use lib '../../perl/build/lib';
use strict;
use warnings;
use Getopt::Long;
-use Git;
use Cwd qw(realpath);
sub get_times {
@@ -85,6 +84,11 @@ sub format_size {
return $out;
}
+sub sane_backticks {
+ open(my $fh, '-|', @_);
+ return <$fh>;
+}
+
my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests,
$codespeed, $sortby, $subsection, $reponame);
@@ -102,7 +106,8 @@ while (scalar @ARGV) {
my $prefix = '';
last if -f $arg or $arg eq "--";
if (! -d $arg) {
- my $rev = Git::command_oneline(qw(rev-parse --verify), $arg);
+ my $rev = sane_backticks(qw(git rev-parse --verify), $arg);
+ chomp $rev;
$dir = "build/".$rev;
} elsif ($arg eq '.') {
$dir = '.';
@@ -219,13 +224,7 @@ sub print_default_results {
for my $i (0..$#dirs) {
my $d = $dirs[$i];
my $base = "$resultsdir/$prefixes{$d}$t";
- $times{$prefixes{$d}.$t} = [];
- foreach my $type (qw(times size)) {
- if (-e "$base.$type") {
- $times{$prefixes{$d}.$t} = [get_times("$base.$type")];
- last;
- }
- }
+ $times{$prefixes{$d}.$t} = [get_times("$base.result")];
my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
my $w = length format_times($r,$u,$s,$firstr);
$colwidth[$i] = $w if $w > $colwidth[$i];
@@ -267,7 +266,7 @@ sub print_sorted_results {
my ($prevr, $prevu, $prevs, $prevrev);
for my $i (0..$#dirs) {
my $d = $dirs[$i];
- my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times");
+ my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.result");
if ($i > 0 and defined $r and defined $prevr and $prevr > 0) {
my $percent = 100.0 * ($r - $prevr) / $prevr;
push @evolutions, { "percent" => $percent,
@@ -327,7 +326,7 @@ sub print_codespeed_results {
my $commitid = $prefixes{$d};
$commitid =~ s/^build_//;
$commitid =~ s/\.$//;
- my ($result_value, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times");
+ my ($result_value, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.result");
my %vals = (
"commitid" => $commitid,
diff --git a/t/perf/bisect_regression b/t/perf/bisect_regression
index a94d9955d0..ce47e1662a 100755
--- a/t/perf/bisect_regression
+++ b/t/perf/bisect_regression
@@ -51,7 +51,7 @@ oldtime=$(echo "$oldtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/')
newtime=$(echo "$newtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/')
test $(echo "$newtime" "$oldtime" | awk '{ print ($1 > $2) }') = 1 ||
- die "New time '$newtime' shoud be greater than old time '$oldtime'"
+ die "New time '$newtime' should be greater than old time '$oldtime'"
tmpdir=$(mktemp -d -t bisect_regression_XXXXXX) || die "Failed to create temp directory"
echo "$oldtime" >"$tmpdir/oldtime" || die "Failed to write to '$tmpdir/oldtime'"
diff --git a/t/perf/p5303-many-packs.sh b/t/perf/p5303-many-packs.sh
index 3779851941..7ee791669a 100755
--- a/t/perf/p5303-many-packs.sh
+++ b/t/perf/p5303-many-packs.sh
@@ -77,6 +77,7 @@ do
# actual pack generation, without smudging the on-disk setup
# between trials.
test_perf "repack ($nr_packs)" '
+ GIT_TEST_FULL_IN_PACK_ARRAY=1 \
git pack-objects --keep-true-parents \
--honor-pack-keep --non-empty --all \
--reflog --indexed-objects --delta-base-offset \
@@ -84,4 +85,22 @@ do
'
done
+# Measure pack loading with 10,000 packs.
+test_expect_success 'generate lots of packs' '
+ for i in $(test_seq 10000); do
+ echo "blob"
+ echo "data <<EOF"
+ echo "blob $i"
+ echo "EOF"
+ echo "checkpoint"
+ done |
+ git -c fastimport.unpackLimit=0 fast-import
+'
+
+# The purpose of this test is to evaluate load time for a large number
+# of packs while doing as little other work as possible.
+test_perf "load 10,000 packs" '
+ git rev-parse --verify "HEAD^{commit}"
+'
+
test_done
diff --git a/t/perf/p5600-clone-reference.sh b/t/perf/p5601-clone-reference.sh
index 68fed66347..68fed66347 100755
--- a/t/perf/p5600-clone-reference.sh
+++ b/t/perf/p5601-clone-reference.sh
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index b58a43ea43..13e389367a 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -214,7 +214,7 @@ test_perf_ () {
else
test_ok_ "$1"
fi
- "$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".times
+ "$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".result
}
test_perf () {
@@ -223,7 +223,7 @@ test_perf () {
test_size_ () {
say >&3 "running: $2"
- if test_eval_ "$2" 3>"$base".size; then
+ if test_eval_ "$2" 3>"$base".result; then
test_ok_ "$1"
else
test_failure_ "$@"
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 9ca0818cbe..3e440c078d 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -20,9 +20,9 @@ modification *should* take notice and update the test vectors here.
. ./test-lib.sh
-try_local_x () {
- local x="local" &&
- echo "$x"
+try_local_xy () {
+ local x="local" y="alsolocal" &&
+ echo "$x $y"
}
# Check whether the shell supports the "local" keyword. "local" is not
@@ -35,11 +35,12 @@ try_local_x () {
# relying on "local".
test_expect_success 'verify that the running shell supports "local"' '
x="notlocal" &&
- echo "local" >expected1 &&
- try_local_x >actual1 &&
+ y="alsonotlocal" &&
+ echo "local alsolocal" >expected1 &&
+ try_local_xy >actual1 &&
test_cmp expected1 actual1 &&
- echo "notlocal" >expected2 &&
- echo "$x" >actual2 &&
+ echo "notlocal alsonotlocal" >expected2 &&
+ echo "$x $y" >actual2 &&
test_cmp expected2 actual2
'
@@ -126,7 +127,7 @@ check_sub_test_lib_test () {
check_sub_test_lib_test_err () {
name="$1" # stdin is the expected output from the test
- # expected error output is in descriptior 3
+ # expected error output is in descriptor 3
(
cd "$name" &&
sed -e 's/^> //' -e 's/Z$//' >expect.out &&
@@ -154,7 +155,7 @@ test_expect_success 'pretend we have a fully passing test suite' "
"
test_expect_success 'pretend we have a partially passing test suite' "
- test_must_fail run_sub_test_lib_test \
+ run_sub_test_lib_test_err \
partial-pass '2/3 tests passing' <<-\\EOF &&
test_expect_success 'passing test #1' 'true'
test_expect_success 'failing test #2' 'false'
@@ -218,7 +219,7 @@ test_expect_success 'pretend we have fixed one of two known breakages (run in su
"
test_expect_success 'pretend we have a pass, fail, and known breakage' "
- test_must_fail run_sub_test_lib_test \
+ run_sub_test_lib_test_err \
mixed-results1 'mixed results #1' <<-\\EOF &&
test_expect_success 'passing test' 'true'
test_expect_success 'failing test' 'false'
@@ -237,7 +238,7 @@ test_expect_success 'pretend we have a pass, fail, and known breakage' "
"
test_expect_success 'pretend we have a mix of all possible results' "
- test_must_fail run_sub_test_lib_test \
+ run_sub_test_lib_test_err \
mixed-results2 'mixed results #2' <<-\\EOF &&
test_expect_success 'passing test' 'true'
test_expect_success 'passing test' 'true'
@@ -273,24 +274,24 @@ test_expect_success 'pretend we have a mix of all possible results' "
"
test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
- test_must_fail run_sub_test_lib_test \
- test-verbose "test verbose" --verbose <<-\EOF &&
+ run_sub_test_lib_test_err \
+ t1234-verbose "test verbose" --verbose <<-\EOF &&
test_expect_success "passing test" true
test_expect_success "test with output" "echo foo"
test_expect_success "failing test" false
test_done
EOF
- mv test-verbose/out test-verbose/out+ &&
- grep -v "^Initialized empty" test-verbose/out+ >test-verbose/out &&
- check_sub_test_lib_test test-verbose <<-\EOF
- > expecting success: true
+ mv t1234-verbose/out t1234-verbose/out+ &&
+ grep -v "^Initialized empty" t1234-verbose/out+ >t1234-verbose/out &&
+ check_sub_test_lib_test t1234-verbose <<-\EOF
+ > expecting success of 1234.1 '\''passing test'\'': true
> ok 1 - passing test
> Z
- > expecting success: echo foo
+ > expecting success of 1234.2 '\''test with output'\'': echo foo
> foo
> ok 2 - test with output
> Z
- > expecting success: false
+ > expecting success of 1234.3 '\''failing test'\'': false
> not ok 3 - failing test
> # false
> Z
@@ -300,18 +301,18 @@ test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
'
test_expect_success 'test --verbose-only' '
- test_must_fail run_sub_test_lib_test \
- test-verbose-only-2 "test verbose-only=2" \
+ run_sub_test_lib_test_err \
+ t2345-verbose-only-2 "test verbose-only=2" \
--verbose-only=2 <<-\EOF &&
test_expect_success "passing test" true
test_expect_success "test with output" "echo foo"
test_expect_success "failing test" false
test_done
EOF
- check_sub_test_lib_test test-verbose-only-2 <<-\EOF
+ check_sub_test_lib_test t2345-verbose-only-2 <<-\EOF
> ok 1 - passing test
> Z
- > expecting success: echo foo
+ > expecting success of 2345.2 '\''test with output'\'': echo foo
> foo
> ok 2 - test with output
> Z
@@ -391,6 +392,44 @@ test_expect_success 'GIT_SKIP_TESTS sh pattern' "
)
"
+test_expect_success 'GIT_SKIP_TESTS entire suite' "
+ (
+ GIT_SKIP_TESTS='git' && export GIT_SKIP_TESTS &&
+ run_sub_test_lib_test git-skip-tests-entire-suite \
+ 'GIT_SKIP_TESTS entire suite' <<-\\EOF &&
+ for i in 1 2 3
+ do
+ test_expect_success \"passing test #\$i\" 'true'
+ done
+ test_done
+ EOF
+ check_sub_test_lib_test git-skip-tests-entire-suite <<-\\EOF
+ > 1..0 # SKIP skip all tests in git
+ EOF
+ )
+"
+
+test_expect_success 'GIT_SKIP_TESTS does not skip unmatched suite' "
+ (
+ GIT_SKIP_TESTS='notgit' && export GIT_SKIP_TESTS &&
+ run_sub_test_lib_test git-skip-tests-unmatched-suite \
+ 'GIT_SKIP_TESTS does not skip unmatched suite' <<-\\EOF &&
+ for i in 1 2 3
+ do
+ test_expect_success \"passing test #\$i\" 'true'
+ done
+ test_done
+ EOF
+ check_sub_test_lib_test git-skip-tests-unmatched-suite <<-\\EOF
+ > ok 1 - passing test #1
+ > ok 2 - passing test #2
+ > ok 3 - passing test #3
+ > # passed all 3 test(s)
+ > 1..3
+ EOF
+ )
+"
+
test_expect_success '--run basic' "
run_sub_test_lib_test run-basic \
'--run basic' --run='1 3 5' <<-\\EOF &&
@@ -795,7 +834,7 @@ then
fi
test_expect_success 'tests clean up even on failures' "
- test_must_fail run_sub_test_lib_test \
+ run_sub_test_lib_test_err \
failing-cleanup 'Failing tests with cleanup commands' <<-\\EOF &&
test_expect_success 'tests clean up even after a failure' '
touch clean-after-failure &&
@@ -824,7 +863,7 @@ test_expect_success 'tests clean up even on failures' "
"
test_expect_success 'test_atexit is run' "
- test_must_fail run_sub_test_lib_test \
+ run_sub_test_lib_test_err \
atexit-cleanup 'Run atexit commands' -i <<-\\EOF &&
test_expect_success 'tests clean up even after a failure' '
> ../../clean-atexit &&
@@ -878,6 +917,40 @@ test_expect_success 'test_oid can look up data for SHA-256' '
test "$hexsz" -eq 64
'
+test_expect_success 'test_bool_env' '
+ (
+ sane_unset envvar &&
+
+ test_bool_env envvar true &&
+ ! test_bool_env envvar false &&
+
+ envvar= &&
+ export envvar &&
+ ! test_bool_env envvar true &&
+ ! test_bool_env envvar false &&
+
+ envvar=true &&
+ test_bool_env envvar true &&
+ test_bool_env envvar false &&
+
+ envvar=false &&
+ ! test_bool_env envvar true &&
+ ! test_bool_env envvar false &&
+
+ envvar=invalid &&
+ # When encountering an invalid bool value, test_bool_env
+ # prints its error message to the original stderr of the
+ # test script, hence the redirection of fd 7, and aborts
+ # with "exit 1", hence the subshell.
+ ! ( test_bool_env envvar true ) 7>err &&
+ grep "error: test_bool_env requires bool values" err &&
+
+ envvar=true &&
+ ! ( test_bool_env envvar invalid ) 7>err &&
+ grep "error: test_bool_env requires bool values" err
+ )
+'
+
################################################################
# Basics of the basics
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 71e63d8b50..b660593c20 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -5,19 +5,16 @@ test_description=gitattributes
. ./test-lib.sh
attr_check () {
- path="$1" expect="$2"
+ path="$1" expect="$2" git_opts="$3" &&
- git $3 check-attr test -- "$path" >actual 2>err &&
- echo "$path: test: $2" >expect &&
+ git $git_opts check-attr test -- "$path" >actual 2>err &&
+ echo "$path: test: $expect" >expect &&
test_cmp expect actual &&
- test_line_count = 0 err
+ test_must_be_empty err
}
attr_check_quote () {
-
- path="$1"
- quoted_path="$2"
- expect="$3"
+ path="$1" quoted_path="$2" expect="$3" &&
git check-attr test -- "$path" >actual &&
echo "\"$quoted_path\": test: $expect" >expect &&
@@ -27,7 +24,7 @@ attr_check_quote () {
test_expect_success 'open-quoted pathname' '
echo "\"a test=a" >.gitattributes &&
- test_must_fail attr_check a a
+ attr_check a unspecified
'
@@ -112,20 +109,20 @@ test_expect_success 'attribute test' '
test_expect_success 'attribute matching is case sensitive when core.ignorecase=0' '
- test_must_fail attr_check F f "-c core.ignorecase=0" &&
- test_must_fail attr_check a/F f "-c core.ignorecase=0" &&
- test_must_fail attr_check a/c/F f "-c core.ignorecase=0" &&
- test_must_fail attr_check a/G a/g "-c core.ignorecase=0" &&
- test_must_fail attr_check a/B/g a/b/g "-c core.ignorecase=0" &&
- test_must_fail attr_check a/b/G a/b/g "-c core.ignorecase=0" &&
- test_must_fail attr_check a/b/H a/b/h "-c core.ignorecase=0" &&
- test_must_fail attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=0" &&
- test_must_fail attr_check oNoFf unset "-c core.ignorecase=0" &&
- test_must_fail attr_check oFfOn set "-c core.ignorecase=0" &&
+ attr_check F unspecified "-c core.ignorecase=0" &&
+ attr_check a/F unspecified "-c core.ignorecase=0" &&
+ attr_check a/c/F unspecified "-c core.ignorecase=0" &&
+ attr_check a/G unspecified "-c core.ignorecase=0" &&
+ attr_check a/B/g a/g "-c core.ignorecase=0" &&
+ attr_check a/b/G unspecified "-c core.ignorecase=0" &&
+ attr_check a/b/H unspecified "-c core.ignorecase=0" &&
+ attr_check a/b/D/g a/g "-c core.ignorecase=0" &&
+ attr_check oNoFf unspecified "-c core.ignorecase=0" &&
+ attr_check oFfOn unspecified "-c core.ignorecase=0" &&
attr_check NO unspecified "-c core.ignorecase=0" &&
- test_must_fail attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
+ attr_check a/b/D/NO unspecified "-c core.ignorecase=0" &&
attr_check a/b/d/YES a/b/d/* "-c core.ignorecase=0" &&
- test_must_fail attr_check a/E/f "A/e/F" "-c core.ignorecase=0"
+ attr_check a/E/f f "-c core.ignorecase=0"
'
@@ -149,8 +146,8 @@ test_expect_success 'attribute matching is case insensitive when core.ignorecase
'
test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
- test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
- test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
+ attr_check a/B/D/g a/g "-c core.ignorecase=0" &&
+ attr_check A/B/D/NO unspecified "-c core.ignorecase=0" &&
attr_check A/b/h a/b/h "-c core.ignorecase=1" &&
attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" &&
attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1"
@@ -244,7 +241,7 @@ EOF
git check-attr foo -- "a/b/f" >>actual 2>>err &&
git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
test_cmp expect actual &&
- test_line_count = 0 err
+ test_must_be_empty err
'
test_expect_success '"**" with no slashes test' '
@@ -265,7 +262,7 @@ EOF
git check-attr foo -- "a/b/f" >>actual 2>>err &&
git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
test_cmp expect actual &&
- test_line_count = 0 err
+ test_must_be_empty err
'
test_expect_success 'using --git-dir and --work-tree' '
diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh
index a070e645d7..8d3d9144c0 100755
--- a/t/t0014-alias.sh
+++ b/t/t0014-alias.sh
@@ -37,4 +37,11 @@ test_expect_success 'looping aliases - internal execution' '
# test_i18ngrep "^fatal: alias loop detected: expansion of" output
#'
+test_expect_success 'run-command formats empty args properly' '
+ test_must_fail env GIT_TRACE=1 git frotz a "" b " " c 2>actual.raw &&
+ sed -ne "/run_command:/s/.*trace: run_command: //p" actual.raw >actual &&
+ echo "git-frotz a '\'''\'' b '\'' '\'' c" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh
index 854da0ae16..b63ba62e5d 100755
--- a/t/t0020-crlf.sh
+++ b/t/t0020-crlf.sh
@@ -159,8 +159,8 @@ test_expect_success 'checkout with autocrlf=input' '
rm -f tmp one dir/two three &&
git config core.autocrlf input &&
git read-tree --reset -u HEAD &&
- test_must_fail has_cr one &&
- test_must_fail has_cr dir/two &&
+ ! has_cr one &&
+ ! has_cr dir/two &&
git update-index -- one dir/two &&
test "$one" = $(git hash-object --stdin <one) &&
test "$two" = $(git hash-object --stdin <dir/two) &&
@@ -237,9 +237,9 @@ test_expect_success '.gitattributes says two is binary' '
git config core.autocrlf true &&
git read-tree --reset -u HEAD &&
- test_must_fail has_cr dir/two &&
+ ! has_cr dir/two &&
verbose has_cr one &&
- test_must_fail has_cr three
+ ! has_cr three
'
test_expect_success '.gitattributes says two is input' '
@@ -248,7 +248,7 @@ test_expect_success '.gitattributes says two is input' '
echo "two crlf=input" >.gitattributes &&
git read-tree --reset -u HEAD &&
- test_must_fail has_cr dir/two
+ ! has_cr dir/two
'
test_expect_success '.gitattributes says two and three are text' '
@@ -270,7 +270,7 @@ test_expect_success 'in-tree .gitattributes (1)' '
rm -rf tmp one dir .gitattributes patch.file three &&
git read-tree --reset -u HEAD &&
- test_must_fail has_cr one &&
+ ! has_cr one &&
verbose has_cr three
'
@@ -280,7 +280,7 @@ test_expect_success 'in-tree .gitattributes (2)' '
git read-tree --reset HEAD &&
git checkout-index -f -q -u -a &&
- test_must_fail has_cr one &&
+ ! has_cr one &&
verbose has_cr three
'
@@ -291,7 +291,7 @@ test_expect_success 'in-tree .gitattributes (3)' '
git checkout-index -u .gitattributes &&
git checkout-index -u one dir/two three &&
- test_must_fail has_cr one &&
+ ! has_cr one &&
verbose has_cr three
'
@@ -302,7 +302,7 @@ test_expect_success 'in-tree .gitattributes (4)' '
git checkout-index -u one dir/two three &&
git checkout-index -u .gitattributes &&
- test_must_fail has_cr one &&
+ ! has_cr one &&
verbose has_cr three
'
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index e10f5f787f..6c6d77b51a 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -35,7 +35,7 @@ filter_git () {
# Compare two files and ensure that `clean` and `smudge` respectively are
# called at least once if specified in the `expect` file. The actual
# invocation count is not relevant because their number can vary.
-# c.f. http://public-inbox.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
+# c.f. http://lore.kernel.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
test_cmp_count () {
expect=$1
actual=$2
@@ -50,7 +50,7 @@ test_cmp_count () {
# Compare two files but exclude all `clean` invocations because Git can
# call `clean` zero or more times.
-# c.f. http://public-inbox.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
+# c.f. http://lore.kernel.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
test_cmp_exclude_clean () {
expect=$1
actual=$2
@@ -390,6 +390,9 @@ test_expect_success PERL 'required process filter should filter data' '
EOF
test_cmp_exclude_clean expected.log debug.log &&
+ # Make sure that the file appears dirty, so checkout below has to
+ # run the configured filter.
+ touch test.r &&
filter_git checkout --quiet --no-progress empty-branch &&
cat >expected.log <<-EOF &&
START
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index 959b6da449..9fcd56fab3 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -215,7 +215,7 @@ stats_ascii () {
}
-# contruct the attr/ returned by git ls-files --eol
+# construct the attr/ returned by git ls-files --eol
# Take none (=empty), one or two args
# convert.c: eol=XX overrides text=auto
attr_ascii () {
diff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh
index 1090e650ed..bfc4fb9af5 100755
--- a/t/t0028-working-tree-encoding.sh
+++ b/t/t0028-working-tree-encoding.sh
@@ -17,7 +17,7 @@ test_lazy_prereq NO_UTF32_BOM '
write_utf16 () {
if test_have_prereq NO_UTF16_BOM
then
- printf '\xfe\xff'
+ printf '\376\377'
fi &&
iconv -f UTF-8 -t UTF-16
}
@@ -25,7 +25,7 @@ write_utf16 () {
write_utf32 () {
if test_have_prereq NO_UTF32_BOM
then
- printf '\x00\x00\xfe\xff'
+ printf '\0\0\376\377'
fi &&
iconv -f UTF-8 -t UTF-32
}
@@ -40,7 +40,7 @@ test_expect_success 'setup test files' '
printf "$text" | write_utf16 >test.utf16.raw &&
printf "$text" | write_utf32 >test.utf32.raw &&
printf "\377\376" >test.utf16lebom.raw &&
- printf "$text" | iconv -f UTF-8 -t UTF-32LE >>test.utf16lebom.raw &&
+ printf "$text" | iconv -f UTF-8 -t UTF-16LE >>test.utf16lebom.raw &&
# Line ending tests
printf "one\ntwo\nthree\n" >lf.utf8.raw &&
@@ -280,4 +280,43 @@ test_expect_success ICONV_SHIFT_JIS 'check roundtrip encoding' '
git reset
'
+# $1: checkout encoding
+# $2: test string
+# $3: binary test string in checkout encoding
+test_commit_utf8_checkout_other () {
+ encoding="$1"
+ orig_string="$2"
+ expect_bytes="$3"
+
+ test_expect_success "Commit UTF-8, checkout $encoding" '
+ test_when_finished "git checkout HEAD -- .gitattributes" &&
+
+ test_ext="commit_utf8_checkout_$encoding" &&
+ test_file="test.$test_ext" &&
+
+ # Commit as UTF-8
+ echo "*.$test_ext text working-tree-encoding=UTF-8" >.gitattributes &&
+ printf "$orig_string" >$test_file &&
+ git add $test_file &&
+ git commit -m "Test data" &&
+
+ # Checkout in tested encoding
+ rm $test_file &&
+ echo "*.$test_ext text working-tree-encoding=$encoding" >.gitattributes &&
+ git checkout HEAD -- $test_file &&
+
+ # Test
+ printf $expect_bytes >$test_file.raw &&
+ test_cmp_bin $test_file.raw $test_file
+ '
+}
+
+test_commit_utf8_checkout_other "UTF-8" "Test Тест" "\124\145\163\164\040\320\242\320\265\321\201\321\202"
+test_commit_utf8_checkout_other "UTF-16LE" "Test Тест" "\124\000\145\000\163\000\164\000\040\000\042\004\065\004\101\004\102\004"
+test_commit_utf8_checkout_other "UTF-16BE" "Test Тест" "\000\124\000\145\000\163\000\164\000\040\004\042\004\065\004\101\004\102"
+test_commit_utf8_checkout_other "UTF-16LE-BOM" "Test Тест" "\377\376\124\000\145\000\163\000\164\000\040\000\042\004\065\004\101\004\102\004"
+test_commit_utf8_checkout_other "UTF-16BE-BOM" "Test Тест" "\376\377\000\124\000\145\000\163\000\164\000\040\004\042\004\065\004\101\004\102"
+test_commit_utf8_checkout_other "UTF-32LE" "Test Тест" "\124\000\000\000\145\000\000\000\163\000\000\000\164\000\000\000\040\000\000\000\042\004\000\000\065\004\000\000\101\004\000\000\102\004\000\000"
+test_commit_utf8_checkout_other "UTF-32BE" "Test Тест" "\000\000\000\124\000\000\000\145\000\000\000\163\000\000\000\164\000\000\000\040\000\000\004\042\000\000\004\065\000\000\004\101\000\000\004\102"
+
test_done
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index cebc77fab0..9d7c7fdaa2 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -242,7 +242,7 @@ test_expect_success 'Alias options do not contribute to abbreviation' '
'
cat >typo.err <<\EOF
-error: did you mean `--boolean` (with two dashes ?)
+error: did you mean `--boolean` (with two dashes)?
EOF
test_expect_success 'detect possible typos' '
@@ -252,7 +252,7 @@ test_expect_success 'detect possible typos' '
'
cat >typo.err <<\EOF
-error: did you mean `--ambiguous` (with two dashes ?)
+error: did you mean `--ambiguous` (with two dashes)?
EOF
test_expect_success 'detect possible typos' '
@@ -399,4 +399,11 @@ test_expect_success 'GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS works' '
test-tool parse-options --ye
'
+test_expect_success '--end-of-options treats remainder as args' '
+ test-tool parse-options \
+ --expect="verbose: -1" \
+ --expect="arg 00: --verbose" \
+ --end-of-options --verbose
+'
+
test_done
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 192c94eccd..608673fb77 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -131,4 +131,24 @@ $test_unicode 'merge (silent unicode normalization)' '
git merge topic
'
+test_expect_success CASE_INSENSITIVE_FS 'checkout with no pathspec and a case insensitive fs' '
+ git init repo &&
+ (
+ cd repo &&
+
+ >Gitweb &&
+ git add Gitweb &&
+ git commit -m "add Gitweb" &&
+
+ git checkout --orphan todo &&
+ git reset --hard &&
+ mkdir -p gitweb/subdir &&
+ >gitweb/subdir/file &&
+ git add gitweb &&
+ git commit -m "add gitweb/subdir/file" &&
+
+ git checkout master
+ )
+'
+
test_done
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index b193ed4205..2ea2d00c39 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -294,9 +294,13 @@ test_git_path GIT_OBJECT_DIRECTORY=foo objects/foo foo/foo
test_git_path GIT_OBJECT_DIRECTORY=foo objects2 .git/objects2
test_expect_success 'setup common repository' 'git --git-dir=bar init'
test_git_path GIT_COMMON_DIR=bar index .git/index
+test_git_path GIT_COMMON_DIR=bar index.lock .git/index.lock
test_git_path GIT_COMMON_DIR=bar HEAD .git/HEAD
test_git_path GIT_COMMON_DIR=bar logs/HEAD .git/logs/HEAD
+test_git_path GIT_COMMON_DIR=bar logs/HEAD.lock .git/logs/HEAD.lock
test_git_path GIT_COMMON_DIR=bar logs/refs/bisect/foo .git/logs/refs/bisect/foo
+test_git_path GIT_COMMON_DIR=bar logs/refs bar/logs/refs
+test_git_path GIT_COMMON_DIR=bar logs/refs/ bar/logs/refs/
test_git_path GIT_COMMON_DIR=bar logs/refs/bisec/foo bar/logs/refs/bisec/foo
test_git_path GIT_COMMON_DIR=bar logs/refs/bisec bar/logs/refs/bisec
test_git_path GIT_COMMON_DIR=bar logs/refs/bisectfoo bar/logs/refs/bisectfoo
@@ -465,11 +469,14 @@ test_expect_success 'match .gitmodules' '
'
test_expect_success MINGW 'is_valid_path() on Windows' '
- test-tool path-utils is_valid_path \
+ test-tool path-utils is_valid_path \
win32 \
"win32 x" \
../hello.txt \
C:\\git \
+ comm \
+ conout.c \
+ lptN \
\
--not \
"win32 " \
@@ -477,7 +484,13 @@ test_expect_success MINGW 'is_valid_path() on Windows' '
"win32." \
"win32 . ." \
.../hello.txt \
- colon:test
+ colon:test \
+ "AUX.c" \
+ "abc/conOut\$ .xyz/test" \
+ lpt8 \
+ "lpt*" \
+ Nul \
+ "PRN./abc"
'
test_done
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index 015fac8b5d..7d599675e3 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -12,6 +12,10 @@ cat >hello-script <<-EOF
cat hello-script
EOF
+test_expect_success MINGW 'subprocess inherits only std handles' '
+ test-tool run-command inherited-handle
+'
+
test_expect_success 'start_command reports ENOENT (slash)' '
test-tool run-command start-command-ENOENT ./does-not-exist 2>err &&
test_i18ngrep "\./does-not-exist" err
@@ -210,10 +214,23 @@ test_expect_success MINGW 'verify curlies are quoted properly' '
test_cmp expect actual
'
-test_expect_success MINGW 'can spawn with argv[0] containing spaces' '
- cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" ./ &&
- test_must_fail "$PWD/test-fake-ssh$X" 2>err &&
- grep TRASH_DIRECTORY err
+test_expect_success MINGW 'can spawn .bat with argv[0] containing spaces' '
+ bat="$TRASH_DIRECTORY/bat with spaces in name.bat" &&
+
+ # Every .bat invocation will log its arguments to file "out"
+ rm -f out &&
+ echo "echo %* >>out" >"$bat" &&
+
+ # Ask git to invoke .bat; clone will fail due to fake SSH helper
+ test_must_fail env GIT_SSH="$bat" git clone myhost:src ssh-clone &&
+
+ # Spawning .bat can fail if there are two quoted cmd.exe arguments.
+ # .bat itself is first (due to spaces in name), so just one more is
+ # needed to verify. GIT_SSH will invoke .bat multiple times:
+ # 1) -G myhost
+ # 2) myhost "git-upload-pack src"
+ # First invocation will always succeed. Test the second one.
+ grep "git-upload-pack" out
'
test_done
diff --git a/t/t0067-parse_pathspec_file.sh b/t/t0067-parse_pathspec_file.sh
new file mode 100755
index 0000000000..7bab49f361
--- /dev/null
+++ b/t/t0067-parse_pathspec_file.sh
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+test_description='Test parse_pathspec_file()'
+
+. ./test-lib.sh
+
+test_expect_success 'one item from stdin' '
+ cat >expect <<-\EOF &&
+ fileA.t
+ EOF
+
+ echo fileA.t |
+ test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'one item from file' '
+ cat >expect <<-\EOF &&
+ fileA.t
+ EOF
+
+ echo fileA.t >list &&
+ test-tool parse-pathspec-file --pathspec-from-file=list >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'NUL delimiters' '
+ cat >expect <<-\EOF &&
+ fileA.t
+ fileB.t
+ EOF
+
+ printf "fileA.t\0fileB.t\0" |
+ test-tool parse-pathspec-file --pathspec-from-file=- --pathspec-file-nul >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'LF delimiters' '
+ cat >expect <<-\EOF &&
+ fileA.t
+ fileB.t
+ EOF
+
+ printf "fileA.t\nfileB.t\n" |
+ test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'no trailing delimiter' '
+ cat >expect <<-\EOF &&
+ fileA.t
+ fileB.t
+ EOF
+
+ printf "fileA.t\nfileB.t" |
+ test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'CRLF delimiters' '
+ cat >expect <<-\EOF &&
+ fileA.t
+ fileB.t
+ EOF
+
+ printf "fileA.t\r\nfileB.t\r\n" |
+ test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'quotes' '
+ cat >expect <<-\EOF &&
+ fileA.t
+ EOF
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ test-tool parse-pathspec-file --pathspec-from-file=list >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success '--pathspec-file-nul takes quotes literally' '
+ # Note: there is an extra newline because --pathspec-file-nul takes
+ # input \n literally, too
+ cat >expect <<-\EOF &&
+ "file\101.t"
+
+ EOF
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ test-tool parse-pathspec-file --pathspec-from-file=list --pathspec-file-nul >actual &&
+
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh
index ce9a4a5f32..5a633690bf 100755
--- a/t/t0090-cache-tree.sh
+++ b/t/t0090-cache-tree.sh
@@ -21,9 +21,10 @@ generate_expected_cache_tree_rec () {
parent="$2" &&
# ls-files might have foo/bar, foo/bar/baz, and foo/bar/quux
# We want to count only foo because it's the only direct child
- subtrees=$(git ls-files|grep /|cut -d / -f 1|uniq) &&
+ git ls-files >files &&
+ subtrees=$(grep / files|cut -d / -f 1|uniq) &&
subtree_count=$(echo "$subtrees"|awk -v c=0 '$1 != "" {++c} END {print c}') &&
- entries=$(git ls-files|wc -l) &&
+ entries=$(wc -l <files) &&
printf "SHA $dir (%d entries, %d subtrees)\n" "$entries" "$subtree_count" &&
for subtree in $subtrees
do
diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh
index 2c3ad6e8c1..6ee8ee3b67 100755
--- a/t/t0211-trace2-perf.sh
+++ b/t/t0211-trace2-perf.sh
@@ -130,11 +130,11 @@ test_expect_success 'perf stream, child processes' '
d0|main|version|||||$V
d0|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 004child test-tool trace2 001return 0
d0|main|cmd_name|||||trace2 (trace2)
- d0|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 004child test-tool trace2 001return 0
+ d0|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 004child test-tool trace2 001return 0]
d1|main|version|||||$V
d1|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 001return 0
d1|main|cmd_name|||||trace2 (trace2/trace2)
- d1|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 001return 0
+ d1|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 001return 0]
d2|main|version|||||$V
d2|main|start||_T_ABS_|||_EXE_ trace2 001return 0
d2|main|cmd_name|||||trace2 (trace2/trace2/trace2)
diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh
index ff5b9cc729..7065a1b937 100755
--- a/t/t0212-trace2-event.sh
+++ b/t/t0212-trace2-event.sh
@@ -265,4 +265,23 @@ test_expect_success JSON_PP 'using global config, event stream, error event' '
test_cmp expect actual
'
+test_expect_success 'discard traces when there are too many files' '
+ mkdir trace_target_dir &&
+ test_when_finished "rm -r trace_target_dir" &&
+ (
+ GIT_TRACE2_MAX_FILES=5 &&
+ export GIT_TRACE2_MAX_FILES &&
+ cd trace_target_dir &&
+ test_seq $GIT_TRACE2_MAX_FILES >../expected_filenames.txt &&
+ xargs touch <../expected_filenames.txt &&
+ cd .. &&
+ GIT_TRACE2_EVENT="$(pwd)/trace_target_dir" test-tool trace2 001return 0
+ ) &&
+ echo git-trace2-discard >>expected_filenames.txt &&
+ ls trace_target_dir >ls_output.txt &&
+ test_cmp expected_filenames.txt ls_output.txt &&
+ head -n1 trace_target_dir/git-trace2-discard | grep \"event\":\"version\" &&
+ head -n2 trace_target_dir/git-trace2-discard | tail -n1 | grep \"event\":\"too_many_files\"
+'
+
test_done
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh
index 5bd892f2f7..a3988bd4b8 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -26,7 +26,7 @@ promise_and_delete () {
test_expect_success 'extensions.partialclone without filter' '
test_create_repo server &&
git clone --filter="blob:none" "file://$(pwd)/server" client &&
- git -C client config --unset core.partialclonefilter &&
+ git -C client config --unset remote.origin.partialclonefilter &&
git -C client fetch origin
'
@@ -166,8 +166,9 @@ test_expect_success 'fetching of missing objects' '
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
- IDX=$(cat promisorlist | sed "s/promisor$/idx/") &&
- git verify-pack --verbose "$IDX" | grep "$HASH"
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH" out
'
test_expect_success 'fetching of missing objects works with ref-in-want enabled' '
@@ -182,8 +183,55 @@ test_expect_success 'fetching of missing objects works with ref-in-want enabled'
grep "git< fetch=.*ref-in-want" trace
'
+test_expect_success 'fetching of missing objects from another promisor remote' '
+ git clone "file://$(pwd)/server" server2 &&
+ test_commit -C server2 bar &&
+ git -C server2 repack -a -d --write-bitmap-index &&
+ HASH2=$(git -C server2 rev-parse bar) &&
+
+ git -C repo remote add server2 "file://$(pwd)/server2" &&
+ git -C repo config remote.server2.promisor true &&
+ git -C repo cat-file -p "$HASH2" &&
+
+ git -C repo fetch server2 &&
+ rm -rf repo/.git/objects/* &&
+ git -C repo cat-file -p "$HASH2" &&
+
+ # Ensure that the .promisor file is written, and check that its
+ # associated packfile contains the object
+ ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 1 promisorlist &&
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH2" out
+'
+
+test_expect_success 'fetching of missing objects configures a promisor remote' '
+ git clone "file://$(pwd)/server" server3 &&
+ test_commit -C server3 baz &&
+ git -C server3 repack -a -d --write-bitmap-index &&
+ HASH3=$(git -C server3 rev-parse baz) &&
+ git -C server3 config uploadpack.allowfilter 1 &&
+
+ rm repo/.git/objects/pack/pack-*.promisor &&
+
+ git -C repo remote add server3 "file://$(pwd)/server3" &&
+ git -C repo fetch --filter="blob:none" server3 $HASH3 &&
+
+ test_cmp_config -C repo true remote.server3.promisor &&
+
+ # Ensure that the .promisor file is written, and check that its
+ # associated packfile contains the object
+ ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 1 promisorlist &&
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH3" out
+'
+
test_expect_success 'fetching of missing blobs works' '
- rm -rf server repo &&
+ rm -rf server server2 repo &&
+ rm -rf server server3 repo &&
test_create_repo server &&
test_commit -C server foo &&
git -C server repack -a -d --write-bitmap-index &&
@@ -234,7 +282,7 @@ test_expect_success 'rev-list stops traversal at missing and promised commit' '
git -C repo config core.repositoryformatversion 1 &&
git -C repo config extensions.partialclone "arbitrary string" &&
- GIT_TEST_COMMIT_GRAPH=0 git -C repo rev-list --exclude-promisor-objects --objects bar >out &&
+ GIT_TEST_COMMIT_GRAPH=0 git -C repo -c core.commitGraph=false rev-list --exclude-promisor-objects --objects bar >out &&
grep $(git -C repo rev-parse bar) out &&
! grep $FOO out
'
@@ -381,6 +429,19 @@ test_expect_success 'rev-list dies for missing objects on cmd line' '
done
'
+test_expect_success 'single promisor remote can be re-initialized gracefully' '
+ # ensure one promisor is in the promisors list
+ rm -rf repo &&
+ test_create_repo repo &&
+ test_create_repo other &&
+ git -C repo remote add foo "file://$(pwd)/other" &&
+ git -C repo config remote.foo.promisor true &&
+ git -C repo config extensions.partialclone foo &&
+
+ # reinitialize the promisors list
+ git -C repo fetch --filter=blob:none foo
+'
+
test_expect_success 'gc repacks promisor objects separately from non-promisor objects' '
rm -rf repo &&
test_create_repo repo &&
@@ -492,6 +553,20 @@ test_expect_success 'gc stops traversal when a missing but promised object is re
! grep "$TREE_HASH" out
'
+test_expect_success 'do not fetch when checking existence of tree we construct ourselves' '
+ rm -rf repo &&
+ test_create_repo repo &&
+ test_commit -C repo base &&
+ test_commit -C repo side1 &&
+ git -C repo checkout base &&
+ test_commit -C repo side2 &&
+
+ git -C repo config core.repositoryformatversion 1 &&
+ git -C repo config extensions.partialclone "arbitrary string" &&
+
+ git -C repo cherry-pick side1
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@@ -514,8 +589,12 @@ test_expect_success 'fetching of missing objects from an HTTP server' '
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
- IDX=$(cat promisorlist | sed "s/promisor$/idx/") &&
- git verify-pack --verbose "$IDX" | grep "$HASH"
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH" out
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh
new file mode 100755
index 0000000000..d2d088d9a0
--- /dev/null
+++ b/t/t0500-progress-display.sh
@@ -0,0 +1,286 @@
+#!/bin/sh
+
+test_description='progress display'
+
+. ./test-lib.sh
+
+show_cr () {
+ tr '\015' Q | sed -e "s/Q/<CR>\\$LF/g"
+}
+
+test_expect_success 'simple progress display' '
+ cat >expect <<-\EOF &&
+ Working hard: 1<CR>
+ Working hard: 2<CR>
+ Working hard: 5<CR>
+ Working hard: 5, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ update
+ progress 1
+ update
+ progress 2
+ progress 3
+ progress 4
+ update
+ progress 5
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display with total' '
+ cat >expect <<-\EOF &&
+ Working hard: 33% (1/3)<CR>
+ Working hard: 66% (2/3)<CR>
+ Working hard: 100% (3/3)<CR>
+ Working hard: 100% (3/3), done.
+ EOF
+
+ cat >in <<-\EOF &&
+ progress 1
+ progress 2
+ progress 3
+ EOF
+ test-tool progress --total=3 "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #1' '
+ sed -e "s/Z$//" >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6: 0% (100/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: 1% (1000/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: Z
+ 10% (10000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ progress 100
+ progress 1000
+ progress 10000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6" \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #2' '
+ # Note: we do not need that many spaces after the title to cover up
+ # the last line before breaking the progress line.
+ sed -e "s/Z$//" >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6: 0% (1/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: 0% (2/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: Z
+ 10% (10000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ update
+ progress 1
+ update
+ progress 2
+ progress 10000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6" \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #3 - even the first is too long' '
+ # Note: we do not actually need any spaces at the end of the title
+ # line, because there is no previous progress line to cover up.
+ sed -e "s/Z$//" >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6: Z
+ 25% (25000/100000)<CR>
+ 50% (50000/100000)<CR>
+ 75% (75000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ progress 25000
+ progress 50000
+ progress 75000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6" \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #4 - title line matches terminal width' '
+ cat >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6.........7.........:
+ 25% (25000/100000)<CR>
+ 50% (50000/100000)<CR>
+ 75% (75000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ progress 25000
+ progress 50000
+ progress 75000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6.........7........." \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+# Progress counter goes backwards, this should not happen in practice.
+test_expect_success 'progress shortens - crazy caller' '
+ cat >expect <<-\EOF &&
+ Working hard: 10% (100/1000)<CR>
+ Working hard: 20% (200/1000)<CR>
+ Working hard: 0% (1/1000) <CR>
+ Working hard: 100% (1000/1000)<CR>
+ Working hard: 100% (1000/1000), done.
+ EOF
+
+ cat >in <<-\EOF &&
+ progress 100
+ progress 200
+ progress 1
+ progress 1000
+ EOF
+ test-tool progress --total=1000 "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display with throughput' '
+ cat >expect <<-\EOF &&
+ Working hard: 10<CR>
+ Working hard: 20, 200.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 30, 300.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 40, 400.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 40, 400.00 KiB | 100.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 102400 1000
+ update
+ progress 10
+ throughput 204800 2000
+ update
+ progress 20
+ throughput 307200 3000
+ update
+ progress 30
+ throughput 409600 4000
+ update
+ progress 40
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display with throughput and total' '
+ cat >expect <<-\EOF &&
+ Working hard: 25% (10/40)<CR>
+ Working hard: 50% (20/40), 200.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 75% (30/40), 300.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 102400 1000
+ progress 10
+ throughput 204800 2000
+ progress 20
+ throughput 307200 3000
+ progress 30
+ throughput 409600 4000
+ progress 40
+ EOF
+ test-tool progress --total=40 "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'cover up after throughput shortens' '
+ cat >expect <<-\EOF &&
+ Working hard: 1<CR>
+ Working hard: 2, 800.00 KiB | 400.00 KiB/s<CR>
+ Working hard: 3, 1.17 MiB | 400.00 KiB/s <CR>
+ Working hard: 4, 1.56 MiB | 400.00 KiB/s<CR>
+ Working hard: 4, 1.56 MiB | 400.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 409600 1000
+ update
+ progress 1
+ throughput 819200 2000
+ update
+ progress 2
+ throughput 1228800 3000
+ update
+ progress 3
+ throughput 1638400 4000
+ update
+ progress 4
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'cover up after throughput shortens a lot' '
+ cat >expect <<-\EOF &&
+ Working hard: 1<CR>
+ Working hard: 2, 1000.00 KiB | 1000.00 KiB/s<CR>
+ Working hard: 3, 3.00 MiB | 1.50 MiB/s <CR>
+ Working hard: 3, 3.00 MiB | 1024.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 1 1000
+ update
+ progress 1
+ throughput 1024000 2000
+ update
+ progress 2
+ throughput 3145728 3000
+ update
+ progress 3
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_done
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index ba71b159ba..eb44bafb59 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -215,7 +215,6 @@ test_expect_success 'read-tree adds to worktree, dirty case' '
'
test_expect_success 'index removal and worktree narrowing at the same time' '
- >empty &&
echo init.t >.git/info/sparse-checkout &&
echo sub/added >>.git/info/sparse-checkout &&
git checkout -f top &&
@@ -223,7 +222,7 @@ test_expect_success 'index removal and worktree narrowing at the same time' '
git checkout removed &&
git ls-files sub/added >result &&
test ! -f sub/added &&
- test_cmp empty result
+ test_must_be_empty result
'
test_expect_success 'read-tree --reset removes outside worktree' '
diff --git a/t/t1050-large.sh b/t/t1050-large.sh
index dcb4dbba67..d3b2adb28b 100755
--- a/t/t1050-large.sh
+++ b/t/t1050-large.sh
@@ -194,15 +194,15 @@ test_expect_success 'pack-objects with large loose object' '
test_cmp huge actual
'
-test_expect_success 'tar achiving' '
+test_expect_success 'tar archiving' '
git archive --format=tar HEAD >/dev/null
'
-test_expect_success 'zip achiving, store only' '
+test_expect_success 'zip archiving, store only' '
git archive --format=zip -0 HEAD >/dev/null
'
-test_expect_success 'zip achiving, deflate' '
+test_expect_success 'zip archiving, deflate' '
git archive --format=zip HEAD >/dev/null
'
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
new file mode 100755
index 0000000000..ff7f8f7a1f
--- /dev/null
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -0,0 +1,371 @@
+#!/bin/sh
+
+test_description='sparse checkout builtin tests'
+
+. ./test-lib.sh
+
+list_files() {
+ # Do not replace this with 'ls "$1"', as "ls" with BSD-lineage
+ # enables "-A" by default for root and ends up including ".git" and
+ # such in its output. (Note, though, that running the test suite as
+ # root is generally not recommended.)
+ (cd "$1" && printf '%s\n' *)
+}
+
+test_expect_success 'setup' '
+ git init repo &&
+ (
+ cd repo &&
+ echo "initial" >a &&
+ mkdir folder1 folder2 deep &&
+ mkdir deep/deeper1 deep/deeper2 &&
+ mkdir deep/deeper1/deepest &&
+ cp a folder1 &&
+ cp a folder2 &&
+ cp a deep &&
+ cp a deep/deeper1 &&
+ cp a deep/deeper2 &&
+ cp a deep/deeper1/deepest &&
+ git add . &&
+ git commit -m "initial commit"
+ )
+'
+
+test_expect_success 'git sparse-checkout list (empty)' '
+ git -C repo sparse-checkout list >list 2>err &&
+ test_must_be_empty list &&
+ test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
+'
+
+test_expect_success 'git sparse-checkout list (populated)' '
+ test_when_finished rm -f repo/.git/info/sparse-checkout &&
+ cat >repo/.git/info/sparse-checkout <<-EOF &&
+ /folder1/*
+ /deep/
+ **/a
+ !*bin*
+ EOF
+ cp repo/.git/info/sparse-checkout expect &&
+ git -C repo sparse-checkout list >list &&
+ test_cmp expect list
+'
+
+test_expect_success 'git sparse-checkout init' '
+ git -C repo sparse-checkout init &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ test_cmp_config -C repo true core.sparsecheckout &&
+ list_files repo >dir &&
+ echo a >expect &&
+ test_cmp expect dir
+'
+
+test_expect_success 'git sparse-checkout list after init' '
+ git -C repo sparse-checkout list >actual &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'init with existing sparse-checkout' '
+ echo "*folder*" >> repo/.git/info/sparse-checkout &&
+ git -C repo sparse-checkout init &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ *folder*
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ list_files repo >dir &&
+ cat >expect <<-EOF &&
+ a
+ folder1
+ folder2
+ EOF
+ test_cmp expect dir
+'
+
+test_expect_success 'clone --sparse' '
+ git clone --sparse repo clone &&
+ git -C clone sparse-checkout list >actual &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ EOF
+ test_cmp expect actual &&
+ list_files clone >dir &&
+ echo a >expect &&
+ test_cmp expect dir
+'
+
+test_expect_success 'set enables config' '
+ git init empty-config &&
+ (
+ cd empty-config &&
+ test_commit test file &&
+ test_path_is_missing .git/config.worktree &&
+ test_must_fail git sparse-checkout set nothing &&
+ test_path_is_file .git/config.worktree &&
+ test_must_fail git config core.sparseCheckout &&
+ git sparse-checkout set "/*" &&
+ test_cmp_config true core.sparseCheckout
+ )
+'
+
+test_expect_success 'set sparse-checkout using builtin' '
+ git -C repo sparse-checkout set "/*" "!/*/" "*folder*" &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ *folder*
+ EOF
+ git -C repo sparse-checkout list >actual &&
+ test_cmp expect actual &&
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ list_files repo >dir &&
+ cat >expect <<-EOF &&
+ a
+ folder1
+ folder2
+ EOF
+ test_cmp expect dir
+'
+
+test_expect_success 'set sparse-checkout using --stdin' '
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ /folder1/
+ /folder2/
+ EOF
+ git -C repo sparse-checkout set --stdin <expect &&
+ git -C repo sparse-checkout list >actual &&
+ test_cmp expect actual &&
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ list_files repo >dir &&
+ cat >expect <<-EOF &&
+ a
+ folder1
+ folder2
+ EOF
+ test_cmp expect dir
+'
+
+test_expect_success 'cone mode: match patterns' '
+ git -C repo config --worktree core.sparseCheckoutCone true &&
+ rm -rf repo/a repo/folder1 repo/folder2 &&
+ git -C repo read-tree -mu HEAD 2>err &&
+ test_i18ngrep ! "disabling cone patterns" err &&
+ git -C repo reset --hard &&
+ list_files repo >dir &&
+ cat >expect <<-EOF &&
+ a
+ folder1
+ folder2
+ EOF
+ test_cmp expect dir
+'
+
+test_expect_success 'cone mode: warn on bad pattern' '
+ test_when_finished mv sparse-checkout repo/.git/info/ &&
+ cp repo/.git/info/sparse-checkout . &&
+ echo "!/deep/deeper/*" >>repo/.git/info/sparse-checkout &&
+ git -C repo read-tree -mu HEAD 2>err &&
+ test_i18ngrep "unrecognized negative pattern" err
+'
+
+test_expect_success 'sparse-checkout disable' '
+ test_when_finished rm -rf repo/.git/info/sparse-checkout &&
+ git -C repo sparse-checkout disable &&
+ test_path_is_file repo/.git/info/sparse-checkout &&
+ git -C repo config --list >config &&
+ test_must_fail git config core.sparseCheckout &&
+ list_files repo >dir &&
+ cat >expect <<-EOF &&
+ a
+ deep
+ folder1
+ folder2
+ EOF
+ test_cmp expect dir
+'
+
+test_expect_success 'cone mode: init and set' '
+ git -C repo sparse-checkout init --cone &&
+ git -C repo config --list >config &&
+ test_i18ngrep "core.sparsecheckoutcone=true" config &&
+ list_files repo >dir &&
+ echo a >expect &&
+ test_cmp expect dir &&
+ git -C repo sparse-checkout set deep/deeper1/deepest/ 2>err &&
+ test_must_be_empty err &&
+ list_files repo >dir &&
+ cat >expect <<-EOF &&
+ a
+ deep
+ EOF
+ test_cmp expect dir &&
+ list_files repo/deep >dir &&
+ cat >expect <<-EOF &&
+ a
+ deeper1
+ EOF
+ test_cmp expect dir &&
+ list_files repo/deep/deeper1 >dir &&
+ cat >expect <<-EOF &&
+ a
+ deepest
+ EOF
+ test_cmp expect dir &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ /deep/
+ !/deep/*/
+ /deep/deeper1/
+ !/deep/deeper1/*/
+ /deep/deeper1/deepest/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ git -C repo sparse-checkout set --stdin 2>err <<-EOF &&
+ folder1
+ folder2
+ EOF
+ test_must_be_empty err &&
+ cat >expect <<-EOF &&
+ a
+ folder1
+ folder2
+ EOF
+ list_files repo >dir &&
+ test_cmp expect dir
+'
+
+test_expect_success 'cone mode: list' '
+ cat >expect <<-EOF &&
+ folder1
+ folder2
+ EOF
+ git -C repo sparse-checkout set --stdin <expect &&
+ git -C repo sparse-checkout list >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cone mode: set with nested folders' '
+ git -C repo sparse-checkout set deep deep/deeper1/deepest 2>err &&
+ test_line_count = 0 err &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ /deep/
+ EOF
+ test_cmp repo/.git/info/sparse-checkout expect
+'
+
+test_expect_success 'revert to old sparse-checkout on bad update' '
+ test_when_finished git -C repo reset --hard &&
+ echo update >repo/deep/deeper2/a &&
+ cp repo/.git/info/sparse-checkout expect &&
+ test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err &&
+ test_i18ngrep "cannot set sparse-checkout patterns" err &&
+ test_cmp repo/.git/info/sparse-checkout expect &&
+ list_files repo/deep >dir &&
+ cat >expect <<-EOF &&
+ a
+ deeper1
+ deeper2
+ EOF
+ test_cmp dir expect
+'
+
+test_expect_success 'revert to old sparse-checkout on empty update' '
+ git init empty-test &&
+ (
+ echo >file &&
+ git add file &&
+ git commit -m "test" &&
+ test_must_fail git sparse-checkout set nothing 2>err &&
+ test_i18ngrep "Sparse checkout leaves no entry on working directory" err &&
+ test_i18ngrep ! ".git/index.lock" err &&
+ git sparse-checkout set file
+ )
+'
+
+test_expect_success 'fail when lock is taken' '
+ test_when_finished rm -rf repo/.git/info/sparse-checkout.lock &&
+ touch repo/.git/info/sparse-checkout.lock &&
+ test_must_fail git -C repo sparse-checkout set deep 2>err &&
+ test_i18ngrep "File exists" err
+'
+
+test_expect_success '.gitignore should not warn about cone mode' '
+ git -C repo config --worktree core.sparseCheckoutCone true &&
+ echo "**/bin/*" >repo/.gitignore &&
+ git -C repo reset --hard 2>err &&
+ test_i18ngrep ! "disabling cone patterns" err
+'
+
+test_expect_success 'sparse-checkout (init|set|disable) fails with dirty status' '
+ git clone repo dirty &&
+ echo dirty >dirty/folder1/a &&
+ test_must_fail git -C dirty sparse-checkout init &&
+ test_must_fail git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
+ test_must_fail git -C dirty sparse-checkout disable &&
+ git -C dirty reset --hard &&
+ git -C dirty sparse-checkout init &&
+ git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
+ git -C dirty sparse-checkout disable
+'
+
+test_expect_success 'cone mode: set with core.ignoreCase=true' '
+ git -C repo sparse-checkout init --cone &&
+ git -C repo -c core.ignoreCase=true sparse-checkout set folder1 &&
+ cat >expect <<-EOF &&
+ /*
+ !/*/
+ /folder1/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ list_files repo >dir &&
+ cat >expect <<-EOF &&
+ a
+ folder1
+ EOF
+ test_cmp expect dir
+'
+
+test_expect_success 'interaction with submodules' '
+ git clone repo super &&
+ (
+ cd super &&
+ mkdir modules &&
+ git submodule add ../repo modules/child &&
+ git add . &&
+ git commit -m "add submodule" &&
+ git sparse-checkout init --cone &&
+ git sparse-checkout set folder1
+ ) &&
+ list_files super >dir &&
+ cat >expect <<-\EOF &&
+ a
+ folder1
+ modules
+ EOF
+ test_cmp expect dir &&
+ list_files super/modules/child >dir &&
+ cat >expect <<-\EOF &&
+ a
+ deep
+ folder1
+ folder2
+ EOF
+ test_cmp expect dir
+'
+
+test_done
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 428177c390..983a0a1583 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -1294,26 +1294,25 @@ test_expect_success 'git -c is not confused by empty environment' '
GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list
'
-sq="'"
test_expect_success 'detect bogus GIT_CONFIG_PARAMETERS' '
cat >expect <<-\EOF &&
env.one one
env.two two
EOF
- GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq} ${sq}env.two=two${sq}" \
+ GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ} ${SQ}env.two=two${SQ}" \
git config --get-regexp "env.*" >actual &&
test_cmp expect actual &&
cat >expect <<-EOF &&
- env.one one${sq}
+ env.one one${SQ}
env.two two
EOF
- GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq}\\$sq$sq$sq ${sq}env.two=two${sq}" \
+ GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ$SQ$SQ ${SQ}env.two=two${SQ}" \
git config --get-regexp "env.*" >actual &&
test_cmp expect actual &&
test_must_fail env \
- GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq}\\$sq ${sq}env.two=two${sq}" \
+ GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ ${SQ}env.two=two${SQ}" \
git config --get-regexp "env.*"
'
diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index d20b4d150d..f1e1b289f9 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -63,7 +63,7 @@ test_expect_success 'listing includes option and expansion' '
test.one=1
EOF
git config --list >actual.full &&
- grep -v ^core actual.full >actual &&
+ grep -v -e ^core -e ^extensions actual.full >actual &&
test_cmp expect actual
'
diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh
index 21e139a313..dd87b43be1 100755
--- a/t/t1306-xdg-files.sh
+++ b/t/t1306-xdg-files.sh
@@ -153,7 +153,7 @@ test_expect_success 'Checking attributes in both XDG and local attributes files'
test_expect_success 'Checking attributes in a non-XDG global attributes file' '
- test_might_fail rm .gitattributes &&
+ rm -f .gitattributes &&
echo "f attr_f=test" >"$HOME"/my_gitattributes &&
git config core.attributesfile "$HOME"/my_gitattributes &&
echo "f: attr_f: test" >expected &&
@@ -165,7 +165,7 @@ test_expect_success 'Checking attributes in a non-XDG global attributes file' '
test_expect_success 'write: xdg file exists and ~/.gitconfig doesn'\''t' '
mkdir -p "$HOME"/.config/git &&
>"$HOME"/.config/git/config &&
- test_might_fail rm "$HOME"/.gitconfig &&
+ rm -f "$HOME"/.gitconfig &&
git config --global user.name "write_config" &&
echo "[user]" >expected &&
echo " name = write_config" >>expected &&
@@ -183,8 +183,8 @@ test_expect_success 'write: xdg file exists and ~/.gitconfig exists' '
test_expect_success 'write: ~/.config/git/ exists and config file doesn'\''t' '
- test_might_fail rm "$HOME"/.gitconfig &&
- test_might_fail rm "$HOME"/.config/git/config &&
+ rm -f "$HOME"/.gitconfig &&
+ rm -f "$HOME"/.config/git/config &&
git config --global user.name "write_gitconfig" &&
echo "[user]" >expected &&
echo " name = write_gitconfig" >>expected &&
diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh
index 37dc689d8c..002e6d3388 100755
--- a/t/t1307-config-blob.sh
+++ b/t/t1307-config-blob.sh
@@ -74,7 +74,7 @@ test_expect_success 'can parse blob ending with CR' '
'
test_expect_success 'config --blob outside of a repository is an error' '
- test_must_fail nongit git config --blob=foo --list
+ nongit test_must_fail git config --blob=foo --list
'
test_done
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index d0a2727b85..7b4e1a63eb 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -166,14 +166,14 @@ test_expect_success 'find value with highest priority from a configset' '
'
test_expect_success 'find value_list for a key from a configset' '
- cat >except <<-\EOF &&
+ cat >expect <<-\EOF &&
+ lama
+ ball
sam
bat
hask
- lama
- ball
EOF
- test-tool config configset_get_value case.baz config2 .git/config >actual &&
+ test-tool config configset_get_value_multi case.baz config2 .git/config >actual &&
test_cmp expect actual
'
diff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh
index 0c37e7180d..ebb8e1aecb 100755
--- a/t/t1309-early-config.sh
+++ b/t/t1309-early-config.sh
@@ -29,7 +29,7 @@ test_expect_success 'ceiling' '
cd sub &&
test-tool config read_early_config early.config
) >output &&
- test -z "$(cat output)"
+ test_must_be_empty output
'
test_expect_success 'ceiling #2' '
@@ -91,7 +91,12 @@ test_expect_failure 'ignore .git/ with invalid config' '
test_expect_success 'early config and onbranch' '
echo "[broken" >broken &&
- test_with_config "[includeif \"onbranch:refs/heads/master\"]path=../broken"
+ test_with_config "[includeif \"onbranch:master\"]path=../broken"
+'
+
+test_expect_success 'onbranch config outside of git repo' '
+ test_config_global includeIf.onbranch:master.path non-existent &&
+ nongit git help
'
test_done
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 1fbd940408..b815cdd1b8 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -344,14 +344,16 @@ test_expect_success "verifying $m's log (logged by config)" '
test_cmp expect .git/logs/$m
'
-git update-ref $m $D
-cat >.git/logs/$m <<EOF
-$Z $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500
-$C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500
-$A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500
-$F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500
-$Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500
-EOF
+test_expect_success 'set up for querying the reflog' '
+ git update-ref $m $D &&
+ cat >.git/logs/$m <<-EOF
+ $Z $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500
+ $C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500
+ $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500
+ $F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500
+ $Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500
+ EOF
+'
ed="Thu, 26 May 2005 18:32:00 -0500"
gd="Thu, 26 May 2005 18:33:00 -0500"
@@ -378,13 +380,13 @@ test_expect_success 'Query "master@{May 26 2005 23:32:00}" (exactly history star
test_when_finished "rm -f o e" &&
git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e &&
test $C = $(cat o) &&
- test "" = "$(cat e)"
+ test_must_be_empty e
'
test_expect_success 'Query "master@{May 26 2005 23:32:30}" (first non-creation change)' '
test_when_finished "rm -f o e" &&
git rev-parse --verify "master@{May 26 2005 23:32:30}" >o 2>e &&
test $A = $(cat o) &&
- test "" = "$(cat e)"
+ test_must_be_empty e
'
test_expect_success 'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' '
test_when_finished "rm -f o e" &&
@@ -396,13 +398,13 @@ test_expect_success 'Query "master@{2005-05-26 23:38:00}" (middle of history)' '
test_when_finished "rm -f o e" &&
git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e &&
test $Z = $(cat o) &&
- test "" = "$(cat e)"
+ test_must_be_empty e
'
test_expect_success 'Query "master@{2005-05-26 23:43:00}" (exact end of history)' '
test_when_finished "rm -f o e" &&
git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e &&
test $E = $(cat o) &&
- test "" = "$(cat e)"
+ test_must_be_empty e
'
test_expect_success 'Query "master@{2005-05-28}" (past end of history)' '
test_when_finished "rm -f o e" &&
diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh
index 970c5c36b9..2d142e5535 100755
--- a/t/t1404-update-ref-errors.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -32,8 +32,6 @@ test_update_rejected () {
test_cmp unchanged actual
}
-Q="'"
-
# Test adding and deleting D/F-conflicting references in a single
# transaction.
df_test() {
@@ -93,7 +91,7 @@ df_test() {
delname="$delref"
fi &&
cat >expected-err <<-EOF &&
- fatal: cannot lock ref $Q$addname$Q: $Q$delref$Q exists; cannot create $Q$addref$Q
+ fatal: cannot lock ref $SQ$addname$SQ: $SQ$delref$SQ exists; cannot create $SQ$addref$SQ
EOF
$pack &&
if $add_del
@@ -123,7 +121,7 @@ test_expect_success 'existing loose ref is a simple prefix of new' '
prefix=refs/1l &&
test_update_rejected "a c e" false "b c/x d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
'
@@ -131,7 +129,7 @@ test_expect_success 'existing packed ref is a simple prefix of new' '
prefix=refs/1p &&
test_update_rejected "a c e" true "b c/x d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
'
@@ -139,7 +137,7 @@ test_expect_success 'existing loose ref is a deeper prefix of new' '
prefix=refs/2l &&
test_update_rejected "a c e" false "b c/x/y d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
'
@@ -147,7 +145,7 @@ test_expect_success 'existing packed ref is a deeper prefix of new' '
prefix=refs/2p &&
test_update_rejected "a c e" true "b c/x/y d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
'
@@ -155,7 +153,7 @@ test_expect_success 'new ref is a simple prefix of existing loose' '
prefix=refs/3l &&
test_update_rejected "a c/x e" false "b c d" \
- "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -163,7 +161,7 @@ test_expect_success 'new ref is a simple prefix of existing packed' '
prefix=refs/3p &&
test_update_rejected "a c/x e" true "b c d" \
- "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -171,7 +169,7 @@ test_expect_success 'new ref is a deeper prefix of existing loose' '
prefix=refs/4l &&
test_update_rejected "a c/x/y e" false "b c d" \
- "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -179,7 +177,7 @@ test_expect_success 'new ref is a deeper prefix of existing packed' '
prefix=refs/4p &&
test_update_rejected "a c/x/y e" true "b c d" \
- "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -187,7 +185,7 @@ test_expect_success 'one new ref is a simple prefix of another' '
prefix=refs/5 &&
test_update_rejected "a e" false "b c c/x d" \
- "cannot process $Q$prefix/c$Q and $Q$prefix/c/x$Q at the same time"
+ "cannot process $SQ$prefix/c$SQ and $SQ$prefix/c/x$SQ at the same time"
'
@@ -334,7 +332,7 @@ test_expect_success 'D/F conflict prevents indirect delete long packed + indirec
test_expect_success 'missing old value blocks update' '
prefix=refs/missing-update &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/foo $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -345,7 +343,7 @@ test_expect_success 'incorrect old value blocks update' '
prefix=refs/incorrect-update &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
EOF
printf "%s\n" "update $prefix/foo $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -356,7 +354,7 @@ test_expect_success 'existing old value blocks create' '
prefix=refs/existing-create &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: reference already exists
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: reference already exists
EOF
printf "%s\n" "create $prefix/foo $E" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -367,7 +365,7 @@ test_expect_success 'incorrect old value blocks delete' '
prefix=refs/incorrect-delete &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
EOF
printf "%s\n" "delete $prefix/foo $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -378,7 +376,7 @@ test_expect_success 'missing old value blocks indirect update' '
prefix=refs/missing-indirect-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -390,7 +388,7 @@ test_expect_success 'incorrect old value blocks indirect update' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -402,7 +400,7 @@ test_expect_success 'existing old value blocks indirect create' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
EOF
printf "%s\n" "create $prefix/symref $E" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -414,7 +412,7 @@ test_expect_success 'incorrect old value blocks indirect delete' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "delete $prefix/symref $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -425,7 +423,7 @@ test_expect_success 'missing old value blocks indirect no-deref update' '
prefix=refs/missing-noderef-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: reference is missing but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: reference is missing but expected $D
EOF
printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -437,7 +435,7 @@ test_expect_success 'incorrect old value blocks indirect no-deref update' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -449,7 +447,7 @@ test_expect_success 'existing old value blocks indirect no-deref create' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
EOF
printf "%s\n" "option no-deref" "create $prefix/symref $E" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -461,7 +459,7 @@ test_expect_success 'incorrect old value blocks indirect no-deref delete' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "option no-deref" "delete $prefix/symref $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -474,13 +472,13 @@ test_expect_success 'non-empty directory blocks create' '
: >.git/$prefix/foo/bar/baz.lock &&
test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/foo $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/foo $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -493,13 +491,13 @@ test_expect_success 'broken reference blocks create' '
echo "gobbledigook" >.git/$prefix/foo &&
test_when_finished "rm -f .git/$prefix/foo" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/foo $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/foo $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -513,13 +511,13 @@ test_expect_success 'non-empty directory blocks indirect create' '
: >.git/$prefix/foo/bar/baz.lock &&
test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/symref $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/symref $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -532,13 +530,13 @@ test_expect_success 'broken reference blocks indirect create' '
echo "gobbledigook" >.git/$prefix/foo &&
test_when_finished "rm -f .git/$prefix/foo" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/symref $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/symref $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -614,7 +612,7 @@ test_expect_success 'delete fails cleanly if packed-refs file is locked' '
test_when_finished "rm -f .git/packed-refs.lock" &&
test_must_fail git update-ref -d $prefix/foo >out 2>err &&
git for-each-ref $prefix >actual &&
- test_i18ngrep "Unable to create $Q.*packed-refs.lock$Q: " err &&
+ test_i18ngrep "Unable to create $SQ.*packed-refs.lock$SQ: " err &&
test_cmp unchanged actual
'
diff --git a/t/t1409-avoid-packing-refs.sh b/t/t1409-avoid-packing-refs.sh
index e5cb8a252d..be12fb6350 100755
--- a/t/t1409-avoid-packing-refs.sh
+++ b/t/t1409-avoid-packing-refs.sh
@@ -8,7 +8,7 @@ test_description='avoid rewriting packed-refs unnecessarily'
# shouldn't upset readers, and it should be omitted if the file is
# ever rewritten.
mark_packed_refs () {
- sed -e "s/^\(#.*\)/\1 t1409 /" <.git/packed-refs >.git/packed-refs.new &&
+ sed -e "s/^\(#.*\)/\1 t1409 /" .git/packed-refs >.git/packed-refs.new &&
mv .git/packed-refs.new .git/packed-refs
}
@@ -27,15 +27,15 @@ test_expect_success 'setup' '
'
test_expect_success 'do not create packed-refs file gratuitously' '
- test_must_fail test -f .git/packed-refs &&
+ test_path_is_missing .git/packed-refs &&
git update-ref refs/heads/foo $A &&
- test_must_fail test -f .git/packed-refs &&
+ test_path_is_missing .git/packed-refs &&
git update-ref refs/heads/foo $B &&
- test_must_fail test -f .git/packed-refs &&
+ test_path_is_missing .git/packed-refs &&
git update-ref refs/heads/foo $C $B &&
- test_must_fail test -f .git/packed-refs &&
+ test_path_is_missing .git/packed-refs &&
git update-ref -d refs/heads/foo &&
- test_must_fail test -f .git/packed-refs
+ test_path_is_missing .git/packed-refs
'
test_expect_success 'check that marking the packed-refs file works' '
@@ -46,7 +46,7 @@ test_expect_success 'check that marking the packed-refs file works' '
git for-each-ref >actual &&
test_cmp expected actual &&
git pack-refs --all &&
- test_must_fail check_packed_refs_marked &&
+ ! check_packed_refs_marked &&
git for-each-ref >actual2 &&
test_cmp expected actual2
'
@@ -80,7 +80,7 @@ test_expect_success 'touch packed-refs on delete of packed' '
git pack-refs --all &&
mark_packed_refs &&
git update-ref -d refs/heads/packed-delete &&
- test_must_fail check_packed_refs_marked
+ ! check_packed_refs_marked
'
test_expect_success 'leave packed-refs untouched on update of loose' '
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 82950c0282..76d9b744a6 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -195,7 +195,7 @@ test_expect_success 'delete' '
git reflog delete master@{1} &&
git reflog show master > output &&
- test $(($master_entry_count - 1)) = $(wc -l < output) &&
+ test_line_count = $(($master_entry_count - 1)) output &&
test $HEAD_entry_count = $(git reflog | wc -l) &&
! grep ox < output &&
@@ -209,7 +209,7 @@ test_expect_success 'delete' '
git reflog delete master@{07.04.2005.15:15:00.-0700} &&
git reflog show master > output &&
- test $(($master_entry_count - 1)) = $(wc -l < output) &&
+ test_line_count = $(($master_entry_count - 1)) output &&
! grep dragon < output
'
diff --git a/t/t1414-reflog-walk.sh b/t/t1414-reflog-walk.sh
index feb1efd8ff..1181a9fb28 100755
--- a/t/t1414-reflog-walk.sh
+++ b/t/t1414-reflog-walk.sh
@@ -18,10 +18,9 @@ do_walk () {
git log -g --format="%gd %gs" "$@"
}
-sq="'"
test_expect_success 'set up expected reflog' '
cat >expect.all <<-EOF
- HEAD@{0} commit (merge): Merge branch ${sq}master${sq} into side
+ HEAD@{0} commit (merge): Merge branch ${SQ}master${SQ} into side
HEAD@{1} commit: three
HEAD@{2} checkout: moving from master to side
HEAD@{3} commit: two
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index a2405b0d32..02478bc4ec 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -70,7 +70,6 @@ test_expect_success 'object with bad sha1' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "$sha.*corrupt" out
'
@@ -78,7 +77,6 @@ test_expect_success 'branch pointing to non-commit' '
git rev-parse HEAD^{tree} >.git/refs/heads/invalid &&
test_when_finished "git update-ref -d refs/heads/invalid" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "not a commit" out
'
@@ -88,7 +86,6 @@ test_expect_success 'HEAD link pointing at a funny object' '
echo $ZERO_OID >.git/HEAD &&
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
- cat out &&
test_i18ngrep "detached HEAD points" out
'
@@ -98,7 +95,6 @@ test_expect_success 'HEAD link pointing at a funny place' '
echo "ref: refs/funny/place" >.git/HEAD &&
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
- cat out &&
test_i18ngrep "HEAD points to something strange" out
'
@@ -157,7 +153,6 @@ test_expect_success 'email with embedded > is not okay' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new" out
'
@@ -169,7 +164,6 @@ test_expect_success 'missing < email delimiter is reported nicely' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.* - bad name" out
'
@@ -181,7 +175,6 @@ test_expect_success 'missing email is reported nicely' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.* - missing email" out
'
@@ -193,7 +186,6 @@ test_expect_success '> in name is reported' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new" out
'
@@ -207,7 +199,6 @@ test_expect_success 'integer overflow in timestamps is reported' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.*integer overflow" out
'
@@ -219,7 +210,6 @@ test_expect_success 'commit with NUL in header' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.*unterminated header: NUL at offset" out
'
@@ -297,7 +287,6 @@ test_expect_success 'tag pointing to nonexistent' '
echo $tag >.git/refs/tags/invalid &&
test_when_finished "git update-ref -d refs/tags/invalid" &&
test_must_fail git fsck --tags >out &&
- cat out &&
test_i18ngrep "broken link" out
'
@@ -378,7 +367,6 @@ test_expect_success 'tag with NUL in header' '
echo $tag >.git/refs/tags/wrong &&
test_when_finished "git update-ref -d refs/tags/wrong" &&
test_must_fail git fsck --tags 2>out &&
- cat out &&
test_i18ngrep "error in tag $tag.*unterminated header: NUL at offset" out
'
@@ -409,7 +397,6 @@ test_expect_success 'rev-list --verify-objects with bad sha1' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out &&
- cat out &&
test_i18ngrep -q "error: hash mismatch $(dirname $new)$(test_oid ff_2)" out
'
@@ -433,7 +420,6 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' '
sha=$(printf "100644 file$_bz$_bzoid" |
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*null sha1" out
)
'
@@ -444,7 +430,6 @@ test_expect_success 'fsck notices submodule entry pointing to null sha1' '
sha=$(printf "160000 submodule$_bz$_bzoid" |
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*null sha1" out
)
'
@@ -466,7 +451,6 @@ while read name path pretty; do
printf "$mode $type %s\t%s" "$value" "$path" >bad &&
bad_tree=$(git mktree <bad) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*tree $bad_tree" out
)'
done <<-\EOF
@@ -633,7 +617,7 @@ test_expect_success 'fsck --name-objects' '
remove_object $(git rev-parse julius:caesar.t) &&
test_must_fail git fsck --name-objects >out &&
tree=$(git rev-parse --verify julius:) &&
- test_i18ngrep -E "$tree \((refs/heads/master|HEAD)@\{[0-9]*\}:" out
+ test_i18ngrep "$tree (refs/tags/julius:" out
)
'
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
index 01abee533d..603019b541 100755
--- a/t/t1500-rev-parse.sh
+++ b/t/t1500-rev-parse.sh
@@ -59,6 +59,7 @@ test_rev_parse () {
ROOT=$(pwd)
test_expect_success 'setup' '
+ test_oid_init &&
mkdir -p sub/dir work &&
cp -R .git repo.git
'
@@ -131,6 +132,30 @@ test_expect_success 'rev-parse --is-shallow-repository in non-shallow repo' '
test_cmp expect actual
'
+test_expect_success 'rev-parse --show-object-format in repo' '
+ echo "$(test_oid algo)" >expect &&
+ git rev-parse --show-object-format >actual &&
+ test_cmp expect actual &&
+ git rev-parse --show-object-format=storage >actual &&
+ test_cmp expect actual &&
+ git rev-parse --show-object-format=input >actual &&
+ test_cmp expect actual &&
+ git rev-parse --show-object-format=output >actual &&
+ test_cmp expect actual &&
+ test_must_fail git rev-parse --show-object-format=squeamish-ossifrage 2>err &&
+ grep "unknown mode for --show-object-format: squeamish-ossifrage" err
+'
+
+test_expect_success '--show-toplevel from subdir of working tree' '
+ pwd >expect &&
+ git -C sub/dir rev-parse --show-toplevel >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '--show-toplevel from inside .git' '
+ test_must_fail git -C .git rev-parse --show-toplevel
+'
+
test_expect_success 'showing the superproject correctly' '
git rev-parse --show-superproject-working-tree >out &&
test_must_be_empty out &&
diff --git a/t/t1501-work-tree.sh b/t/t1501-work-tree.sh
index 3498d3d55e..b75558040f 100755
--- a/t/t1501-work-tree.sh
+++ b/t/t1501-work-tree.sh
@@ -350,7 +350,7 @@ test_expect_success 'Multi-worktree setup' '
mkdir work &&
mkdir -p repo.git/repos/foo &&
cp repo.git/HEAD repo.git/index repo.git/repos/foo &&
- test_might_fail cp repo.git/sharedindex.* repo.git/repos/foo &&
+ { cp repo.git/sharedindex.* repo.git/repos/foo || :; } &&
sane_unset GIT_DIR GIT_CONFIG GIT_WORK_TREE
'
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index 4ee009da66..8a75f37a11 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -8,10 +8,9 @@ exec </dev/null
test_did_you_mean ()
{
- sq="'" &&
cat >expected <<-EOF &&
- fatal: Path '$2$3' $4, but not ${5:-$sq$3$sq}.
- Did you mean '$1:$2$3'${2:+ aka $sq$1:./$3$sq}?
+ fatal: Path '$2$3' $4, but not ${5:-$SQ$3$SQ}.
+ Did you mean '$1:$2$3'${2:+ aka $SQ$1:./$3$SQ}?
EOF
test_cmp expected error
}
@@ -139,10 +138,10 @@ test_expect_success 'incorrect file in :path and :N:path' '
test_expect_success 'invalid @{n} reference' '
test_must_fail git rev-parse master@{99999} >output 2>error &&
- test -z "$(cat output)" &&
+ test_must_be_empty output &&
grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error &&
test_must_fail git rev-parse --verify master@{99999} >output 2>error &&
- test -z "$(cat output)" &&
+ test_must_be_empty output &&
grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error
'
@@ -156,13 +155,13 @@ test_expect_success 'relative path not found' '
test_expect_success 'relative path outside worktree' '
test_must_fail git rev-parse HEAD:../file.txt >output 2>error &&
- test -z "$(cat output)" &&
+ test_must_be_empty output &&
test_i18ngrep "outside repository" error
'
test_expect_success 'relative path when cwd is outside worktree' '
test_must_fail git --git-dir=.git --work-tree=subdir rev-parse HEAD:./file.txt >output 2>error &&
- test -z "$(cat output)" &&
+ test_must_be_empty output &&
grep "relative path syntax can.t be used outside working tree." error
'
@@ -215,4 +214,26 @@ test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
test_cmp expect actual
'
+test_expect_success 'reject Nth parent if N is too high' '
+ test_must_fail git rev-parse HEAD^100000000000000000000000000000000
+'
+
+test_expect_success 'reject Nth ancestor if N is too high' '
+ test_must_fail git rev-parse HEAD~100000000000000000000000000000000
+'
+
+test_expect_success 'pathspecs with wildcards are not ambiguous' '
+ echo "*.c" >expect &&
+ git rev-parse "*.c" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'backslash does not trigger wildcard rule' '
+ test_must_fail git rev-parse "foo\\bar"
+'
+
+test_expect_success 'escaped char does not trigger wildcard rule' '
+ test_must_fail git rev-parse "foo\\*bar"
+'
+
test_done
diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh
index fa3e499641..dfc0d96d8a 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -28,16 +28,9 @@ test_expect_success 'setup' '
)
'
-sq="'"
-
-full_name () {
- (cd clone &&
- git rev-parse --symbolic-full-name "$@")
-}
-
commit_subject () {
(cd clone &&
- git show -s --pretty=format:%s "$@")
+ git show -s --pretty=tformat:%s "$@")
}
error_message () {
@@ -46,63 +39,78 @@ error_message () {
}
test_expect_success '@{upstream} resolves to correct full name' '
- test refs/remotes/origin/master = "$(full_name @{upstream})" &&
- test refs/remotes/origin/master = "$(full_name @{UPSTREAM})" &&
- test refs/remotes/origin/master = "$(full_name @{UpSTReam})"
+ echo refs/remotes/origin/master >expect &&
+ git -C clone rev-parse --symbolic-full-name @{upstream} >actual &&
+ test_cmp expect actual &&
+ git -C clone rev-parse --symbolic-full-name @{UPSTREAM} >actual &&
+ test_cmp expect actual &&
+ git -C clone rev-parse --symbolic-full-name @{UpSTReam} >actual &&
+ test_cmp expect actual
'
test_expect_success '@{u} resolves to correct full name' '
- test refs/remotes/origin/master = "$(full_name @{u})" &&
- test refs/remotes/origin/master = "$(full_name @{U})"
+ echo refs/remotes/origin/master >expect &&
+ git -C clone rev-parse --symbolic-full-name @{u} >actual &&
+ test_cmp expect actual &&
+ git -C clone rev-parse --symbolic-full-name @{U} >actual &&
+ test_cmp expect actual
'
test_expect_success 'my-side@{upstream} resolves to correct full name' '
- test refs/remotes/origin/side = "$(full_name my-side@{u})"
+ echo refs/remotes/origin/side >expect &&
+ git -C clone rev-parse --symbolic-full-name my-side@{u} >actual &&
+ test_cmp expect actual
'
test_expect_success 'upstream of branch with @ in middle' '
- full_name fun@ny@{u} >actual &&
+ git -C clone rev-parse --symbolic-full-name fun@ny@{u} >actual &&
echo refs/remotes/origin/side >expect &&
test_cmp expect actual &&
- full_name fun@ny@{U} >actual &&
+ git -C clone rev-parse --symbolic-full-name fun@ny@{U} >actual &&
test_cmp expect actual
'
test_expect_success 'upstream of branch with @ at start' '
- full_name @funny@{u} >actual &&
+ git -C clone rev-parse --symbolic-full-name @funny@{u} >actual &&
echo refs/remotes/origin/side >expect &&
test_cmp expect actual
'
test_expect_success 'upstream of branch with @ at end' '
- full_name funny@@{u} >actual &&
+ git -C clone rev-parse --symbolic-full-name funny@@{u} >actual &&
echo refs/remotes/origin/side >expect &&
test_cmp expect actual
'
test_expect_success 'refs/heads/my-side@{upstream} does not resolve to my-side{upstream}' '
- test_must_fail full_name refs/heads/my-side@{upstream}
+ test_must_fail git -C clone rev-parse --symbolic-full-name refs/heads/my-side@{upstream}
'
test_expect_success 'my-side@{u} resolves to correct commit' '
git checkout side &&
test_commit 5 &&
(cd clone && git fetch) &&
- test 2 = "$(commit_subject my-side)" &&
- test 5 = "$(commit_subject my-side@{u})"
+ echo 2 >expect &&
+ commit_subject my-side >actual &&
+ test_cmp expect actual &&
+ echo 5 >expect &&
+ commit_subject my-side@{u} >actual
'
test_expect_success 'not-tracking@{u} fails' '
- test_must_fail full_name non-tracking@{u} &&
+ test_must_fail git -C clone rev-parse --symbolic-full-name non-tracking@{u} &&
(cd clone && git checkout --no-track -b non-tracking) &&
- test_must_fail full_name non-tracking@{u}
+ test_must_fail git -C clone rev-parse --symbolic-full-name non-tracking@{u}
'
test_expect_success '<branch>@{u}@{1} resolves correctly' '
test_commit 6 &&
(cd clone && git fetch) &&
- test 5 = $(commit_subject my-side@{u}@{1}) &&
- test 5 = $(commit_subject my-side@{U}@{1})
+ echo 5 >expect &&
+ commit_subject my-side@{u}@{1} >actual &&
+ test_cmp expect actual &&
+ commit_subject my-side@{U}@{1} >actual &&
+ test_cmp expect actual
'
test_expect_success '@{u} without specifying branch fails on a detached HEAD' '
@@ -129,7 +137,7 @@ test_expect_success 'merge my-side@{u} records the correct name' '
git branch -t new my-side@{u} &&
git merge -s ours new@{u} &&
git show -s --pretty=tformat:%s >actual &&
- echo "Merge remote-tracking branch ${sq}origin/side${sq}" >expect &&
+ echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect &&
test_cmp expect actual
)
'
@@ -151,12 +159,14 @@ test_expect_success 'checkout other@{u}' '
'
test_expect_success 'branch@{u} works when tracking a local branch' '
- test refs/heads/master = "$(full_name local-master@{u})"
+ echo refs/heads/master >expect &&
+ git -C clone rev-parse --symbolic-full-name local-master@{u} >actual &&
+ test_cmp expect actual
'
test_expect_success 'branch@{u} error message when no upstream' '
cat >expect <<-EOF &&
- fatal: no upstream configured for branch ${sq}non-tracking${sq}
+ fatal: no upstream configured for branch ${SQ}non-tracking${SQ}
EOF
error_message non-tracking@{u} &&
test_i18ncmp expect error
@@ -164,7 +174,7 @@ test_expect_success 'branch@{u} error message when no upstream' '
test_expect_success '@{u} error message when no upstream' '
cat >expect <<-EOF &&
- fatal: no upstream configured for branch ${sq}master${sq}
+ fatal: no upstream configured for branch ${SQ}master${SQ}
EOF
test_must_fail git rev-parse --verify @{u} 2>actual &&
test_i18ncmp expect actual
@@ -172,7 +182,7 @@ test_expect_success '@{u} error message when no upstream' '
test_expect_success 'branch@{u} error message with misspelt branch' '
cat >expect <<-EOF &&
- fatal: no such branch: ${sq}no-such-branch${sq}
+ fatal: no such branch: ${SQ}no-such-branch${SQ}
EOF
error_message no-such-branch@{u} &&
test_i18ncmp expect error
@@ -189,7 +199,7 @@ test_expect_success '@{u} error message when not on a branch' '
test_expect_success 'branch@{u} error message if upstream branch not fetched' '
cat >expect <<-EOF &&
- fatal: upstream branch ${sq}refs/heads/side${sq} not stored as a remote-tracking branch
+ fatal: upstream branch ${SQ}refs/heads/side${SQ} not stored as a remote-tracking branch
EOF
error_message bad-upstream@{u} &&
test_i18ncmp expect error
@@ -205,35 +215,37 @@ test_expect_success 'pull works when tracking a local branch' '
# makes sense if the previous one succeeded
test_expect_success '@{u} works when tracking a local branch' '
- test refs/heads/master = "$(full_name @{u})"
+ echo refs/heads/master >expect &&
+ git -C clone rev-parse --symbolic-full-name @{u} >actual &&
+ test_cmp expect actual
'
-commit=$(git rev-parse HEAD)
-cat >expect <<EOF
-commit $commit
-Reflog: master@{0} (C O Mitter <committer@example.com>)
-Reflog message: branch: Created from HEAD
-Author: A U Thor <author@example.com>
-Date: Thu Apr 7 15:15:13 2005 -0700
-
- 3
-EOF
test_expect_success 'log -g other@{u}' '
+ commit=$(git rev-parse HEAD) &&
+ cat >expect <<-EOF &&
+ commit $commit
+ Reflog: master@{0} (C O Mitter <committer@example.com>)
+ Reflog message: branch: Created from HEAD
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:15:13 2005 -0700
+
+ 3
+ EOF
git log -1 -g other@{u} >actual &&
test_cmp expect actual
'
-cat >expect <<EOF
-commit $commit
-Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>)
-Reflog message: branch: Created from HEAD
-Author: A U Thor <author@example.com>
-Date: Thu Apr 7 15:15:13 2005 -0700
-
- 3
-EOF
-
test_expect_success 'log -g other@{u}@{now}' '
+ commit=$(git rev-parse HEAD) &&
+ cat >expect <<-EOF &&
+ commit $commit
+ Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>)
+ Reflog message: branch: Created from HEAD
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:15:13 2005 -0700
+
+ 3
+ EOF
git log -1 -g other@{u}@{now} >actual &&
test_cmp expect actual
'
diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh
index c19fb500cb..18fa6cf40d 100755
--- a/t/t1512-rev-parse-disambiguation.sh
+++ b/t/t1512-rev-parse-disambiguation.sh
@@ -282,7 +282,7 @@ test_expect_success 'rev-parse --disambiguate' '
# commits created by commit-tree in earlier tests share a
# different prefix.
git rev-parse --disambiguate=000000000 >actual &&
- test $(wc -l <actual) = 16 &&
+ test_line_count = 16 actual &&
test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000
'
@@ -339,7 +339,7 @@ test_expect_success C_LOCALE_OUTPUT 'ambiguity hints' '
test_expect_success C_LOCALE_OUTPUT 'ambiguity hints respect type' '
test_must_fail git rev-parse 000000000^{commit} 2>stderr &&
grep ^hint: stderr >hints &&
- # 5 commits, 1 tag (which is a commitish), plus intro line
+ # 5 commits, 1 tag (which is a committish), plus intro line
test_line_count = 7 hints
'
diff --git a/t/t1600-index.sh b/t/t1600-index.sh
index 42962ed7d4..b7c31aa86a 100755
--- a/t/t1600-index.sh
+++ b/t/t1600-index.sh
@@ -59,17 +59,42 @@ test_expect_success 'out of bounds index.version issues warning' '
)
'
-test_expect_success 'GIT_INDEX_VERSION takes precedence over config' '
+test_index_version () {
+ INDEX_VERSION_CONFIG=$1 &&
+ FEATURE_MANY_FILES=$2 &&
+ ENV_VAR_VERSION=$3
+ EXPECTED_OUTPUT_VERSION=$4 &&
(
rm -f .git/index &&
- GIT_INDEX_VERSION=4 &&
- export GIT_INDEX_VERSION &&
- git config --add index.version 2 &&
+ rm -f .git/config &&
+ if test "$INDEX_VERSION_CONFIG" -ne 0
+ then
+ git config --add index.version $INDEX_VERSION_CONFIG
+ fi &&
+ git config --add feature.manyFiles $FEATURE_MANY_FILES
+ if test "$ENV_VAR_VERSION" -ne 0
+ then
+ GIT_INDEX_VERSION=$ENV_VAR_VERSION &&
+ export GIT_INDEX_VERSION
+ else
+ unset GIT_INDEX_VERSION
+ fi &&
git add a 2>&1 &&
- echo 4 >expect &&
+ echo $EXPECTED_OUTPUT_VERSION >expect &&
test-tool index-version <.git/index >actual &&
test_cmp expect actual
)
+}
+
+test_expect_success 'index version config precedence' '
+ test_index_version 0 false 0 2 &&
+ test_index_version 2 false 0 2 &&
+ test_index_version 3 false 0 2 &&
+ test_index_version 4 false 0 4 &&
+ test_index_version 2 false 4 4 &&
+ test_index_version 2 true 0 2 &&
+ test_index_version 0 true 0 4 &&
+ test_index_version 0 true 2 2
'
test_done
diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh
index fc3eb43b89..6844afafc0 100755
--- a/t/t2022-checkout-paths.sh
+++ b/t/t2022-checkout-paths.sh
@@ -78,4 +78,15 @@ test_expect_success 'do not touch files that are already up-to-date' '
test_cmp expect actual
'
+test_expect_success 'checkout HEAD adds deleted intent-to-add file back to index' '
+ echo "nonempty" >nonempty &&
+ >empty &&
+ git add nonempty empty &&
+ git commit -m "create files to be deleted" &&
+ git rm --cached nonempty empty &&
+ git add -N nonempty empty &&
+ git checkout HEAD nonempty empty &&
+ git diff --cached --exit-code
+'
+
test_done
diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh
index fa0718c730..accfa9aa4b 100755
--- a/t/t2024-checkout-dwim.sh
+++ b/t/t2024-checkout-dwim.sh
@@ -37,7 +37,9 @@ test_expect_success 'setup' '
git checkout -b foo &&
test_commit a_foo &&
git checkout -b bar &&
- test_commit a_bar
+ test_commit a_bar &&
+ git checkout -b ambiguous_branch_and_file &&
+ test_commit a_ambiguous_branch_and_file
) &&
git init repo_b &&
(
@@ -46,7 +48,9 @@ test_expect_success 'setup' '
git checkout -b foo &&
test_commit b_foo &&
git checkout -b baz &&
- test_commit b_baz
+ test_commit b_baz &&
+ git checkout -b ambiguous_branch_and_file &&
+ test_commit b_ambiguous_branch_and_file
) &&
git remote add repo_a repo_a &&
git remote add repo_b repo_b &&
@@ -75,6 +79,26 @@ test_expect_success 'checkout of branch from multiple remotes fails #1' '
test_branch master
'
+test_expect_success 'when arg matches multiple remotes, do not fallback to interpreting as pathspec' '
+ # create a file with name matching remote branch name
+ git checkout -b t_ambiguous_branch_and_file &&
+ >ambiguous_branch_and_file &&
+ git add ambiguous_branch_and_file &&
+ git commit -m "ambiguous_branch_and_file" &&
+
+ # modify file to verify that it will not be touched by checkout
+ test_when_finished "git checkout -- ambiguous_branch_and_file" &&
+ echo "file contents" >ambiguous_branch_and_file &&
+ cp ambiguous_branch_and_file expect &&
+
+ test_must_fail git checkout ambiguous_branch_and_file 2>err &&
+
+ test_i18ngrep "matched multiple (2) remote tracking branches" err &&
+
+ # file must not be altered
+ test_cmp expect ambiguous_branch_and_file
+'
+
test_expect_success 'checkout of branch from multiple remotes fails with advice' '
git checkout -B master &&
test_might_fail git branch -D foo &&
diff --git a/t/t2026-checkout-pathspec-file.sh b/t/t2026-checkout-pathspec-file.sh
new file mode 100755
index 0000000000..43d31d7948
--- /dev/null
+++ b/t/t2026-checkout-pathspec-file.sh
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+test_description='checkout --pathspec-from-file'
+
+. ./test-lib.sh
+
+test_tick
+
+test_expect_success setup '
+ test_commit file0 &&
+
+ echo 1 >fileA.t &&
+ echo 1 >fileB.t &&
+ echo 1 >fileC.t &&
+ echo 1 >fileD.t &&
+ git add fileA.t fileB.t fileC.t fileD.t &&
+ git commit -m "files 1" &&
+
+ echo 2 >fileA.t &&
+ echo 2 >fileB.t &&
+ echo 2 >fileC.t &&
+ echo 2 >fileD.t &&
+ git add fileA.t fileB.t fileC.t fileD.t &&
+ git commit -m "files 2" &&
+
+ git tag checkpoint
+'
+
+restore_checkpoint () {
+ git reset --hard checkpoint
+}
+
+verify_expect () {
+ git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success '--pathspec-from-file from stdin' '
+ restore_checkpoint &&
+
+ echo fileA.t | git checkout --pathspec-from-file=- HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success '--pathspec-from-file from file' '
+ restore_checkpoint &&
+
+ echo fileA.t >list &&
+ git checkout --pathspec-from-file=list HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'NUL delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\0fileB.t\0" | git checkout --pathspec-from-file=- --pathspec-file-nul HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'LF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t\n" | git checkout --pathspec-from-file=- HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'no trailing delimiter' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t" | git checkout --pathspec-from-file=- HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'CRLF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\r\nfileB.t\r\n" | git checkout --pathspec-from-file=- HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ git checkout --pathspec-from-file=list HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes not compatible with --pathspec-file-nul' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ test_must_fail git checkout --pathspec-from-file=list --pathspec-file-nul HEAD^1
+'
+
+test_expect_success 'only touches what was listed' '
+ restore_checkpoint &&
+
+ printf "fileB.t\nfileC.t\n" | git checkout --pathspec-from-file=- HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileB.t
+ M fileC.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'error conditions' '
+ restore_checkpoint &&
+ echo fileA.t >list &&
+
+ test_must_fail git checkout --pathspec-from-file=list --detach 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --detach" err &&
+
+ test_must_fail git checkout --pathspec-from-file=list --patch 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err &&
+
+ test_must_fail git checkout --pathspec-from-file=list -- fileA.t 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err &&
+
+ test_must_fail git checkout --pathspec-file-nul 2>err &&
+ test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err
+'
+
+test_done
diff --git a/t/t2070-restore.sh b/t/t2070-restore.sh
index 2650df1966..076d0df7fc 100755
--- a/t/t2070-restore.sh
+++ b/t/t2070-restore.sh
@@ -95,4 +95,32 @@ test_expect_success 'restore --ignore-unmerged ignores unmerged entries' '
)
'
+test_expect_success 'restore --staged adds deleted intent-to-add file back to index' '
+ echo "nonempty" >nonempty &&
+ >empty &&
+ git add nonempty empty &&
+ git commit -m "create files to be deleted" &&
+ git rm --cached nonempty empty &&
+ git add -N nonempty empty &&
+ git restore --staged nonempty empty &&
+ git diff --cached --exit-code
+'
+
+test_expect_success 'restore --staged invalidates cache tree for deletions' '
+ test_when_finished git reset --hard &&
+ >new1 &&
+ >new2 &&
+ git add new1 new2 &&
+
+ # It is important to commit and then reset here, so that the index
+ # contains a valid cache-tree for the "both" tree.
+ git commit -m both &&
+ git reset --soft HEAD^ &&
+
+ git restore --staged new1 &&
+ git commit -m "just new2" &&
+ git rev-parse HEAD:new2 &&
+ test_must_fail git rev-parse HEAD:new1
+'
+
test_done
diff --git a/t/t2072-restore-pathspec-file.sh b/t/t2072-restore-pathspec-file.sh
new file mode 100755
index 0000000000..0d47946e8a
--- /dev/null
+++ b/t/t2072-restore-pathspec-file.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+
+test_description='restore --pathspec-from-file'
+
+. ./test-lib.sh
+
+test_tick
+
+test_expect_success setup '
+ test_commit file0 &&
+
+ echo 1 >fileA.t &&
+ echo 1 >fileB.t &&
+ echo 1 >fileC.t &&
+ echo 1 >fileD.t &&
+ git add fileA.t fileB.t fileC.t fileD.t &&
+ git commit -m "files 1" &&
+
+ echo 2 >fileA.t &&
+ echo 2 >fileB.t &&
+ echo 2 >fileC.t &&
+ echo 2 >fileD.t &&
+ git add fileA.t fileB.t fileC.t fileD.t &&
+ git commit -m "files 2" &&
+
+ git tag checkpoint
+'
+
+restore_checkpoint () {
+ git reset --hard checkpoint
+}
+
+verify_expect () {
+ git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success '--pathspec-from-file from stdin' '
+ restore_checkpoint &&
+
+ echo fileA.t | git restore --pathspec-from-file=- --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success '--pathspec-from-file from file' '
+ restore_checkpoint &&
+
+ echo fileA.t >list &&
+ git restore --pathspec-from-file=list --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'NUL delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\0fileB.t\0" | git restore --pathspec-from-file=- --pathspec-file-nul --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'LF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t\n" | git restore --pathspec-from-file=- --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'no trailing delimiter' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t" | git restore --pathspec-from-file=- --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'CRLF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\r\nfileB.t\r\n" | git restore --pathspec-from-file=- --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ git restore --pathspec-from-file=list --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes not compatible with --pathspec-file-nul' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ test_must_fail git restore --pathspec-from-file=list --pathspec-file-nul --source=HEAD^1
+'
+
+test_expect_success 'only touches what was listed' '
+ restore_checkpoint &&
+
+ printf "fileB.t\nfileC.t\n" | git restore --pathspec-from-file=- --source=HEAD^1 &&
+
+ cat >expect <<-\EOF &&
+ M fileB.t
+ M fileC.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'error conditions' '
+ restore_checkpoint &&
+ echo fileA.t >list &&
+ >empty_list &&
+
+ test_must_fail git restore --pathspec-from-file=list --patch --source=HEAD^1 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err &&
+
+ test_must_fail git restore --pathspec-from-file=list --source=HEAD^1 -- fileA.t 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err &&
+
+ test_must_fail git restore --pathspec-file-nul --source=HEAD^1 2>err &&
+ test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err &&
+
+ test_must_fail git restore --pathspec-from-file=empty_list --source=HEAD^1 2>err &&
+ test_i18ngrep -e "you must specify path(s) to restore" err
+'
+
+test_done
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index e819ba741e..b5ece19460 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -438,7 +438,7 @@ test_expect_success 'git worktree add does not match remote' '
cd foo &&
test_must_fail git config "branch.foo.remote" &&
test_must_fail git config "branch.foo.merge" &&
- ! test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
+ test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo
)
'
@@ -483,7 +483,7 @@ test_expect_success 'git worktree --no-guess-remote option overrides config' '
cd foo &&
test_must_fail git config "branch.foo.remote" &&
test_must_fail git config "branch.foo.merge" &&
- ! test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
+ test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo
)
'
@@ -587,4 +587,28 @@ test_expect_success '"add" should not fail because of another bad worktree' '
)
'
+test_expect_success '"add" with uninitialized submodule, with submodule.recurse unset' '
+ test_create_repo submodule &&
+ test_commit -C submodule first &&
+ test_create_repo project &&
+ git -C project submodule add ../submodule &&
+ git -C project add submodule &&
+ test_tick &&
+ git -C project commit -m add_sub &&
+ git clone project project-clone &&
+ git -C project-clone worktree add ../project-2
+'
+test_expect_success '"add" with uninitialized submodule, with submodule.recurse set' '
+ git -C project-clone -c submodule.recurse worktree add ../project-3
+'
+
+test_expect_success '"add" with initialized submodule, with submodule.recurse unset' '
+ git -C project-clone submodule update --init &&
+ git -C project-clone worktree add ../project-4
+'
+
+test_expect_success '"add" with initialized submodule, with submodule.recurse set' '
+ git -C project-clone -c submodule.recurse worktree add ../project-5
+'
+
test_done
diff --git a/t/t2405-worktree-submodule.sh b/t/t2405-worktree-submodule.sh
new file mode 100755
index 0000000000..e1b2bfd87e
--- /dev/null
+++ b/t/t2405-worktree-submodule.sh
@@ -0,0 +1,90 @@
+#!/bin/sh
+
+test_description='Combination of submodules and multiple worktrees'
+
+. ./test-lib.sh
+
+base_path=$(pwd -P)
+
+test_expect_success 'setup: create origin repos' '
+ git init origin/sub &&
+ test_commit -C origin/sub file1 &&
+ git init origin/main &&
+ test_commit -C origin/main first &&
+ git -C origin/main submodule add ../sub &&
+ git -C origin/main commit -m "add sub" &&
+ test_commit -C origin/sub "file1 updated" file1 file1updated file1updated &&
+ git -C origin/main/sub pull &&
+ git -C origin/main add sub &&
+ git -C origin/main commit -m "sub updated"
+'
+
+test_expect_success 'setup: clone superproject to create main worktree' '
+ git clone --recursive "$base_path/origin/main" main
+'
+
+rev1_hash_main=$(git --git-dir=origin/main/.git show --pretty=format:%h -q "HEAD~1")
+rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1")
+
+test_expect_success 'add superproject worktree' '
+ git -C main worktree add "$base_path/worktree" "$rev1_hash_main"
+'
+
+test_expect_failure 'submodule is checked out just after worktree add' '
+ git -C worktree diff --submodule master"^!" >out &&
+ grep "file1 updated" out
+'
+
+test_expect_success 'add superproject worktree and initialize submodules' '
+ git -C main worktree add "$base_path/worktree-submodule-update" "$rev1_hash_main" &&
+ git -C worktree-submodule-update submodule update
+'
+
+test_expect_success 'submodule is checked out just after submodule update in linked worktree' '
+ git -C worktree-submodule-update diff --submodule master"^!" >out &&
+ grep "file1 updated" out
+'
+
+test_expect_success 'add superproject worktree and manually add submodule worktree' '
+ git -C main worktree add "$base_path/linked_submodule" "$rev1_hash_main" &&
+ git -C main/sub worktree add "$base_path/linked_submodule/sub" "$rev1_hash_sub"
+'
+
+test_expect_success 'submodule is checked out after manually adding submodule worktree' '
+ git -C linked_submodule diff --submodule master"^!" >out &&
+ grep "file1 updated" out
+'
+
+test_expect_success 'checkout --recurse-submodules uses $GIT_DIR for submodules in a linked worktree' '
+ git -C main worktree add "$base_path/checkout-recurse" --detach &&
+ git -C checkout-recurse submodule update --init &&
+ echo "gitdir: ../../main/.git/worktrees/checkout-recurse/modules/sub" >expect-gitfile &&
+ cat checkout-recurse/sub/.git >actual-gitfile &&
+ test_cmp expect-gitfile actual-gitfile &&
+ git -C main/sub rev-parse HEAD >expect-head-main &&
+ git -C checkout-recurse checkout --recurse-submodules HEAD~1 &&
+ cat checkout-recurse/sub/.git >actual-gitfile &&
+ git -C main/sub rev-parse HEAD >actual-head-main &&
+ test_cmp expect-gitfile actual-gitfile &&
+ test_cmp expect-head-main actual-head-main
+'
+
+test_expect_success 'core.worktree is removed in $GIT_DIR/modules/<name>/config, not in $GIT_COMMON_DIR/modules/<name>/config' '
+ echo "../../../sub" >expect-main &&
+ git -C main/sub config --get core.worktree >actual-main &&
+ test_cmp expect-main actual-main &&
+ echo "../../../../../../checkout-recurse/sub" >expect-linked &&
+ git -C checkout-recurse/sub config --get core.worktree >actual-linked &&
+ test_cmp expect-linked actual-linked &&
+ git -C checkout-recurse checkout --recurse-submodules first &&
+ test_expect_code 1 git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree >linked-config &&
+ test_must_be_empty linked-config &&
+ git -C main/sub config --get core.worktree >actual-main &&
+ test_cmp expect-main actual-main
+'
+
+test_expect_success 'unsetting core.worktree does not prevent running commands directly against the submodule repository' '
+ git -C main/.git/worktrees/checkout-recurse/modules/sub log
+'
+
+test_done
diff --git a/t/t3005-ls-files-relative.sh b/t/t3005-ls-files-relative.sh
index 209b4c7cd8..2ec69a8a26 100755
--- a/t/t3005-ls-files-relative.sh
+++ b/t/t3005-ls-files-relative.sh
@@ -7,10 +7,6 @@ This test runs git ls-files with various relative path arguments.
. ./test-lib.sh
-new_line='
-'
-sq=\'
-
test_expect_success 'prepare' '
: >never-mind-me &&
git add never-mind-me &&
@@ -44,9 +40,9 @@ test_expect_success 'ls-files -c' '
cd top/sub &&
for f in ../y*
do
- echo "error: pathspec $sq$f$sq did not match any file(s) known to git"
+ echo "error: pathspec $SQ$f$SQ did not match any file(s) known to git"
done >expect.err &&
- echo "Did you forget to ${sq}git add${sq}?" >>expect.err &&
+ echo "Did you forget to ${SQ}git add${SQ}?" >>expect.err &&
ls ../x* >expect.out &&
test_must_fail git ls-files -c --error-unmatch ../[xy]* >actual.out 2>actual.err &&
test_cmp expect.out actual.out &&
@@ -59,9 +55,9 @@ test_expect_success 'ls-files -o' '
cd top/sub &&
for f in ../x*
do
- echo "error: pathspec $sq$f$sq did not match any file(s) known to git"
+ echo "error: pathspec $SQ$f$SQ did not match any file(s) known to git"
done >expect.err &&
- echo "Did you forget to ${sq}git add${sq}?" >>expect.err &&
+ echo "Did you forget to ${SQ}git add${SQ}?" >>expect.err &&
ls ../y* >expect.out &&
test_must_fail git ls-files -o --error-unmatch ../[xy]* >actual.out 2>actual.err &&
test_cmp expect.out actual.out &&
diff --git a/t/t3008-ls-files-lazy-init-name-hash.sh b/t/t3008-ls-files-lazy-init-name-hash.sh
index 64f047332b..85f3704958 100755
--- a/t/t3008-ls-files-lazy-init-name-hash.sh
+++ b/t/t3008-ls-files-lazy-init-name-hash.sh
@@ -4,7 +4,7 @@ test_description='Test the lazy init name hash with various folder structures'
. ./test-lib.sh
-if test 1 -eq $($GIT_BUILD_DIR/t/helper/test-tool online-cpus)
+if test 1 -eq $(test-tool online-cpus)
then
skip_all='skipping lazy-init tests, single cpu'
test_done
diff --git a/t/t3011-common-prefixes-and-directory-traversal.sh b/t/t3011-common-prefixes-and-directory-traversal.sh
new file mode 100755
index 0000000000..3da5b2b6e7
--- /dev/null
+++ b/t/t3011-common-prefixes-and-directory-traversal.sh
@@ -0,0 +1,209 @@
+#!/bin/sh
+
+test_description='directory traversal handling, especially with common prefixes'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit hello &&
+
+ >empty &&
+ mkdir untracked_dir &&
+ >untracked_dir/empty &&
+ git init untracked_repo &&
+ >untracked_repo/empty &&
+
+ cat <<-EOF >.gitignore &&
+ ignored
+ an_ignored_dir/
+ EOF
+ mkdir an_ignored_dir &&
+ mkdir an_untracked_dir &&
+ >an_ignored_dir/ignored &&
+ >an_ignored_dir/untracked &&
+ >an_untracked_dir/ignored &&
+ >an_untracked_dir/untracked
+'
+
+test_expect_success 'git ls-files -o shows the right entries' '
+ cat <<-EOF >expect &&
+ .gitignore
+ actual
+ an_ignored_dir/ignored
+ an_ignored_dir/untracked
+ an_untracked_dir/ignored
+ an_untracked_dir/untracked
+ empty
+ expect
+ untracked_dir/empty
+ untracked_repo/
+ EOF
+ git ls-files -o >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o --exclude-standard shows the right entries' '
+ cat <<-EOF >expect &&
+ .gitignore
+ actual
+ an_untracked_dir/untracked
+ empty
+ expect
+ untracked_dir/empty
+ untracked_repo/
+ EOF
+ git ls-files -o --exclude-standard >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o untracked_dir recurses' '
+ echo untracked_dir/empty >expect &&
+ git ls-files -o untracked_dir >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o untracked_dir/ recurses' '
+ echo untracked_dir/empty >expect &&
+ git ls-files -o untracked_dir/ >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o --directory untracked_dir does not recurse' '
+ echo untracked_dir/ >expect &&
+ git ls-files -o --directory untracked_dir >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o --directory untracked_dir/ does not recurse' '
+ echo untracked_dir/ >expect &&
+ git ls-files -o --directory untracked_dir/ >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o untracked_repo does not recurse' '
+ echo untracked_repo/ >expect &&
+ git ls-files -o untracked_repo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o untracked_repo/ does not recurse' '
+ echo untracked_repo/ >expect &&
+ git ls-files -o untracked_repo/ >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o untracked_dir untracked_repo recurses into untracked_dir only' '
+ cat <<-EOF >expect &&
+ untracked_dir/empty
+ untracked_repo/
+ EOF
+ git ls-files -o untracked_dir untracked_repo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o untracked_dir/ untracked_repo/ recurses into untracked_dir only' '
+ cat <<-EOF >expect &&
+ untracked_dir/empty
+ untracked_repo/
+ EOF
+ git ls-files -o untracked_dir/ untracked_repo/ >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o --directory untracked_dir untracked_repo does not recurse' '
+ cat <<-EOF >expect &&
+ untracked_dir/
+ untracked_repo/
+ EOF
+ git ls-files -o --directory untracked_dir untracked_repo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o --directory untracked_dir/ untracked_repo/ does not recurse' '
+ cat <<-EOF >expect &&
+ untracked_dir/
+ untracked_repo/
+ EOF
+ git ls-files -o --directory untracked_dir/ untracked_repo/ >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o .git shows nothing' '
+ git ls-files -o .git >actual &&
+ test_must_be_empty actual
+'
+
+test_expect_success 'git ls-files -o .git/ shows nothing' '
+ git ls-files -o .git/ >actual &&
+ test_must_be_empty actual
+'
+
+test_expect_success FUNNYNAMES 'git ls-files -o untracked_* recurses appropriately' '
+ mkdir "untracked_*" &&
+ >"untracked_*/empty" &&
+
+ cat <<-EOF >expect &&
+ untracked_*/empty
+ untracked_dir/empty
+ untracked_repo/
+ EOF
+ git ls-files -o "untracked_*" >actual &&
+ test_cmp expect actual
+'
+
+# It turns out fill_directory returns the right paths, but ls-files' post-call
+# filtering in show_dir_entry() via calling dir_path_match() which ends up
+# in git_fnmatch() has logic for PATHSPEC_ONESTAR that assumes the pathspec
+# must match the full path; it doesn't check it for matching a leading
+# directory.
+test_expect_failure FUNNYNAMES 'git ls-files -o untracked_*/ recurses appropriately' '
+ cat <<-EOF >expect &&
+ untracked_*/empty
+ untracked_dir/empty
+ untracked_repo/
+ EOF
+ git ls-files -o "untracked_*/" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success FUNNYNAMES 'git ls-files -o --directory untracked_* does not recurse' '
+ cat <<-EOF >expect &&
+ untracked_*/
+ untracked_dir/
+ untracked_repo/
+ EOF
+ git ls-files -o --directory "untracked_*" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success FUNNYNAMES 'git ls-files -o --directory untracked_*/ does not recurse' '
+ cat <<-EOF >expect &&
+ untracked_*/
+ untracked_dir/
+ untracked_repo/
+ EOF
+ git ls-files -o --directory "untracked_*/" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git ls-files -o consistent between one or two dirs' '
+ git ls-files -o --exclude-standard an_ignored_dir/ an_untracked_dir/ >tmp &&
+ ! grep ^an_ignored_dir/ tmp >expect &&
+ git ls-files -o --exclude-standard an_ignored_dir/ >actual &&
+ test_cmp expect actual
+'
+
+# ls-files doesn't have a way to request showing both untracked and ignored
+# files at the same time, so use `git status --ignored`
+test_expect_success 'git status --ignored shows same files under dir with or without pathspec' '
+ cat <<-EOF >expect &&
+ ?? an_untracked_dir/
+ !! an_untracked_dir/ignored
+ EOF
+ git status --porcelain --ignored >output &&
+ grep an_untracked_dir output >expect &&
+ git status --porcelain --ignored an_untracked_dir/ >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index ff641b348a..2170758e38 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -452,6 +452,34 @@ test_expect_success 'merge-recursive d/f conflict result' '
'
+test_expect_success SYMLINKS 'dir in working tree with symlink ancestor does not produce d/f conflict' '
+ git init sym &&
+ (
+ cd sym &&
+ ln -s . foo &&
+ mkdir bar &&
+ >bar/file &&
+ git add foo bar/file &&
+ git commit -m "foo symlink" &&
+
+ git checkout -b branch1 &&
+ git commit --allow-empty -m "empty commit" &&
+
+ git checkout master &&
+ git rm foo &&
+ mkdir foo &&
+ >foo/bar &&
+ git add foo/bar &&
+ git commit -m "replace foo symlink with real foo dir and foo/bar file" &&
+
+ git checkout branch1 &&
+
+ git cherry-pick master &&
+ test_path_is_dir foo &&
+ test_path_is_file foo/bar
+ )
+'
+
test_expect_success 'reset and 3-way merge' '
git reset --hard "$c2" &&
@@ -667,15 +695,22 @@ test_expect_success 'merging with triple rename across D/F conflict' '
test_expect_success 'merge-recursive remembers the names of all base trees' '
git reset --hard HEAD &&
+ # make the index match $c1 so that merge-recursive below does not
+ # fail early
+ git diff --binary HEAD $c1 -- | git apply --cached &&
+
# more trees than static slots used by oid_to_hex()
for commit in $c0 $c2 $c4 $c5 $c6 $c7
do
git rev-parse "$commit^{tree}"
done >trees &&
- # ignore the return code -- it only fails because the input is weird
+ # ignore the return code; it only fails because the input is weird...
test_must_fail git -c merge.verbosity=5 merge-recursive $(cat trees) -- $c1 $c3 >out &&
+ # ...but make sure it fails in the expected way
+ test_i18ngrep CONFLICT.*rename/rename out &&
+
# merge-recursive prints in reverse order, but we do not care
sort <trees >expect &&
sed -n "s/^virtual //p" out | sort >actual &&
diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh
index 44f378ce41..52ed665fcd 100755
--- a/t/t3060-ls-files-with-tree.sh
+++ b/t/t3060-ls-files-with-tree.sh
@@ -47,7 +47,7 @@ test_expect_success setup '
git add .
'
-test_expect_success 'git -ls-files --with-tree should succeed from subdir' '
+test_expect_success 'git ls-files --with-tree should succeed from subdir' '
# We have to run from a sub-directory to trigger prune_path
# Then we finally get to run our --with-tree test
(
@@ -57,7 +57,7 @@ test_expect_success 'git -ls-files --with-tree should succeed from subdir' '
'
test_expect_success \
- 'git -ls-files --with-tree should add entries from named tree.' \
+ 'git ls-files --with-tree should add entries from named tree.' \
'test_cmp expected output'
test_done
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 0ea4fc4694..40251c9f8f 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -192,10 +192,10 @@ test_expect_success 'branch --merged with --verbose' '
EOF
test_cmp expect actual &&
git branch --verbose --merged topic >actual &&
- cat >expect <<-\EOF &&
- master c77a0a9 second on master
- * topic 2c939f4 [ahead 1] foo
- zzz c77a0a9 second on master
+ cat >expect <<-EOF &&
+ master $(git rev-parse --short master) second on master
+ * topic $(git rev-parse --short topic ) [ahead 1] foo
+ zzz $(git rev-parse --short zzz ) second on master
EOF
test_i18ncmp expect actual
'
diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index ec548654ce..0575dd72b1 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -8,97 +8,204 @@ test_description='range-diff tests'
# harm than good. We need some real history.
test_expect_success 'setup' '
- git fast-import < "$TEST_DIRECTORY"/t3206/history.export
+ git fast-import <"$TEST_DIRECTORY"/t3206/history.export &&
+ test_oid_cache <<-\EOF
+ # topic
+ t1 sha1:4de457d
+ t2 sha1:fccce22
+ t3 sha1:147e64e
+ t4 sha1:a63e992
+ t1 sha256:b89f8b9
+ t2 sha256:5f12aad
+ t3 sha256:ea8b273
+ t4 sha256:14b7336
+
+ # unmodified
+ u1 sha1:35b9b25
+ u2 sha1:de345ab
+ u3 sha1:9af6654
+ u4 sha1:2901f77
+ u1 sha256:e3731be
+ u2 sha256:14fadf8
+ u3 sha256:736c4bc
+ u4 sha256:673e77d
+
+ # reordered
+ r1 sha1:aca177a
+ r2 sha1:14ad629
+ r3 sha1:ee58208
+ r4 sha1:307b27a
+ r1 sha256:f59d3aa
+ r2 sha256:fb261a8
+ r3 sha256:cb2649b
+ r4 sha256:958577e
+
+ # removed (deleted)
+ d1 sha1:7657159
+ d2 sha1:43d84d3
+ d3 sha1:a740396
+ d1 sha256:e312513
+ d2 sha256:eb19258
+ d3 sha256:1ccb3c1
+
+ # added
+ a1 sha1:2716022
+ a2 sha1:b62accd
+ a3 sha1:df46cfa
+ a4 sha1:3e64548
+ a5 sha1:12b4063
+ a1 sha256:d724f4d
+ a2 sha256:1de7762
+ a3 sha256:e159431
+ a4 sha256:b3e483c
+ a5 sha256:90866a7
+
+ # rebased
+ b1 sha1:cc9c443
+ b2 sha1:c5d9641
+ b3 sha1:28cc2b6
+ b4 sha1:5628ab7
+ b5 sha1:a31b12e
+ b1 sha256:a1a8717
+ b2 sha256:20a5862
+ b3 sha256:587172a
+ b4 sha256:2721c5d
+ b5 sha256:7b57864
+
+ # changed
+ c1 sha1:a4b3333
+ c2 sha1:f51d370
+ c3 sha1:0559556
+ c4 sha1:d966c5c
+ c1 sha256:f8c2b9d
+ c2 sha256:3fb6318
+ c3 sha256:168ab68
+ c4 sha256:3526539
+
+ # changed-message
+ m1 sha1:f686024
+ m2 sha1:4ab067d
+ m3 sha1:b9cb956
+ m4 sha1:8add5f1
+ m1 sha256:31e6281
+ m2 sha256:a06bf1b
+ m3 sha256:82dc654
+ m4 sha256:48470c5
+
+ # renamed
+ n1 sha1:f258d75
+ n2 sha1:017b62d
+ n3 sha1:3ce7af6
+ n4 sha1:1e6226b
+ n1 sha256:ad52114
+ n2 sha256:3b54c8f
+ n3 sha256:3b0a644
+ n4 sha256:e461653
+
+ # added and removed
+ s1 sha1:096b1ba
+ s2 sha1:d92e698
+ s3 sha1:9a1db4d
+ s4 sha1:fea3b5c
+ s1 sha256:a7f9134
+ s2 sha256:b4c2580
+ s3 sha256:1d62aa2
+ s4 sha256:48160e8
+
+ # Empty delimiter (included so lines match neatly)
+ __ sha1:-------
+ __ sha256:-------
+ EOF
'
test_expect_success 'simple A..B A..C (unmodified)' '
git range-diff --no-color master..topic master..unmodified \
>actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: 35b9b25 s/5/A/
- 2: fccce22 = 2: de345ab s/4/A/
- 3: 147e64e = 3: 9af6654 s/11/B/
- 4: a63e992 = 4: 2901f77 s/12/B/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
+ 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
+ 4: $(test_oid t4) = 4: $(test_oid u4) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'simple B...C (unmodified)' '
git range-diff --no-color topic...unmodified >actual &&
- # same "expected" as above
- test_cmp expected actual
+ # same "expect" as above
+ test_cmp expect actual
'
test_expect_success 'simple A B C (unmodified)' '
git range-diff --no-color master topic unmodified >actual &&
- # same "expected" as above
- test_cmp expected actual
+ # same "expect" as above
+ test_cmp expect actual
'
test_expect_success 'trivial reordering' '
git range-diff --no-color master topic reordered >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: aca177a s/5/A/
- 3: 147e64e = 2: 14ad629 s/11/B/
- 4: a63e992 = 3: ee58208 s/12/B/
- 2: fccce22 = 4: 307b27a s/4/A/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid r1) s/5/A/
+ 3: $(test_oid t3) = 2: $(test_oid r2) s/11/B/
+ 4: $(test_oid t4) = 3: $(test_oid r3) s/12/B/
+ 2: $(test_oid t2) = 4: $(test_oid r4) s/4/A/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'removed a commit' '
git range-diff --no-color master topic removed >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: 7657159 s/5/A/
- 2: fccce22 < -: ------- s/4/A/
- 3: 147e64e = 2: 43d84d3 s/11/B/
- 4: a63e992 = 3: a740396 s/12/B/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid d1) s/5/A/
+ 2: $(test_oid t2) < -: $(test_oid __) s/4/A/
+ 3: $(test_oid t3) = 2: $(test_oid d2) s/11/B/
+ 4: $(test_oid t4) = 3: $(test_oid d3) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'added a commit' '
git range-diff --no-color master topic added >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: 2716022 s/5/A/
- 2: fccce22 = 2: b62accd s/4/A/
- -: ------- > 3: df46cfa s/6/A/
- 3: 147e64e = 4: 3e64548 s/11/B/
- 4: a63e992 = 5: 12b4063 s/12/B/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid a1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid a2) s/4/A/
+ -: $(test_oid __) > 3: $(test_oid a3) s/6/A/
+ 3: $(test_oid t3) = 4: $(test_oid a4) s/11/B/
+ 4: $(test_oid t4) = 5: $(test_oid a5) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'new base, A B C' '
git range-diff --no-color master topic rebased >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: cc9c443 s/5/A/
- 2: fccce22 = 2: c5d9641 s/4/A/
- 3: 147e64e = 3: 28cc2b6 s/11/B/
- 4: a63e992 = 4: 5628ab7 s/12/B/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid b1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid b2) s/4/A/
+ 3: $(test_oid t3) = 3: $(test_oid b3) s/11/B/
+ 4: $(test_oid t4) = 4: $(test_oid b4) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'new base, B...C' '
# this syntax includes the commits from master!
git range-diff --no-color topic...rebased >actual &&
- cat >expected <<-EOF &&
- -: ------- > 1: a31b12e unrelated
- 1: 4de457d = 2: cc9c443 s/5/A/
- 2: fccce22 = 3: c5d9641 s/4/A/
- 3: 147e64e = 4: 28cc2b6 s/11/B/
- 4: a63e992 = 5: 5628ab7 s/12/B/
+ cat >expect <<-EOF &&
+ -: $(test_oid __) > 1: $(test_oid b5) unrelated
+ 1: $(test_oid t1) = 2: $(test_oid b1) s/5/A/
+ 2: $(test_oid t2) = 3: $(test_oid b2) s/4/A/
+ 3: $(test_oid t3) = 4: $(test_oid b3) s/11/B/
+ 4: $(test_oid t4) = 5: $(test_oid b4) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'changed commit' '
git range-diff --no-color topic...changed >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
- 2: fccce22 = 2: f51d370 s/4/A/
- 3: 147e64e ! 3: 0559556 s/11/B/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
+ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
@@ file: A
9
10
@@ -108,7 +215,7 @@ test_expect_success 'changed commit' '
12
13
14
- 4: a63e992 ! 4: d966c5c s/12/B/
+ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
@@ file
@@ file: A
9
@@ -119,45 +226,45 @@ test_expect_success 'changed commit' '
+B
13
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'changed commit with --no-patch diff option' '
git range-diff --no-color --no-patch topic...changed >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
- 2: fccce22 = 2: f51d370 s/4/A/
- 3: 147e64e ! 3: 0559556 s/11/B/
- 4: a63e992 ! 4: d966c5c s/12/B/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
+ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
+ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'changed commit with --stat diff option' '
git range-diff --no-color --stat topic...changed >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
- 2: fccce22 = 2: f51d370 s/4/A/
+ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
- 3: 147e64e ! 3: 0559556 s/11/B/
+ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
- 4: a63e992 ! 4: d966c5c s/12/B/
+ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'changed commit with sm config' '
git range-diff --no-color --submodule=log topic...changed >actual &&
- cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
- 2: fccce22 = 2: f51d370 s/4/A/
- 3: 147e64e ! 3: 0559556 s/11/B/
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
+ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
@@ file: A
9
10
@@ -167,7 +274,7 @@ test_expect_success 'changed commit with sm config' '
12
13
14
- 4: a63e992 ! 4: d966c5c s/12/B/
+ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
@@ file
@@ file: A
9
@@ -178,14 +285,14 @@ test_expect_success 'changed commit with sm config' '
+B
13
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'renamed file' '
git range-diff --no-color --submodule=log topic...renamed-file >actual &&
- sed s/Z/\ /g >expected <<-EOF &&
- 1: 4de457d = 1: f258d75 s/5/A/
- 2: fccce22 ! 2: 017b62d s/4/A/
+ sed s/Z/\ /g >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid n1) s/5/A/
+ 2: $(test_oid t2) ! 2: $(test_oid n2) s/4/A/
@@ Metadata
ZAuthor: Thomas Rast <trast@inf.ethz.ch>
Z
@@ -198,7 +305,7 @@ test_expect_success 'renamed file' '
Z@@
Z 1
Z 2
- 3: 147e64e ! 3: 3ce7af6 s/11/B/
+ 3: $(test_oid t3) ! 3: $(test_oid n3) s/11/B/
@@ Metadata
Z ## Commit message ##
Z s/11/B/
@@ -210,7 +317,7 @@ test_expect_success 'renamed file' '
Z 8
Z 9
Z 10
- 4: a63e992 ! 4: 1e6226b s/12/B/
+ 4: $(test_oid t4) ! 4: $(test_oid n4) s/12/B/
@@ Metadata
Z ## Commit message ##
Z s/12/B/
@@ -223,14 +330,54 @@ test_expect_success 'renamed file' '
Z 10
Z B
EOF
- test_cmp expected actual
+ test_cmp expect actual
+'
+
+test_expect_success 'file with mode only change' '
+ git range-diff --no-color --submodule=log topic...mode-only-change >actual &&
+ sed s/Z/\ /g >expect <<-EOF &&
+ 1: fccce22 ! 1: 4d39cb3 s/4/A/
+ @@ Metadata
+ ZAuthor: Thomas Rast <trast@inf.ethz.ch>
+ Z
+ Z ## Commit message ##
+ - s/4/A/
+ + s/4/A/ + add other-file
+ Z
+ Z ## file ##
+ Z@@
+ @@ file
+ Z A
+ Z 6
+ Z 7
+ +
+ + ## other-file (new) ##
+ 2: 147e64e ! 2: 26c107f s/11/B/
+ @@ Metadata
+ ZAuthor: Thomas Rast <trast@inf.ethz.ch>
+ Z
+ Z ## Commit message ##
+ - s/11/B/
+ + s/11/B/ + mode change other-file
+ Z
+ Z ## file ##
+ Z@@ file: A
+ @@ file: A
+ Z 12
+ Z 13
+ Z 14
+ +
+ + ## other-file (mode change 100644 => 100755) ##
+ 3: a63e992 = 3: 4c1e0f5 s/12/B/
+ EOF
+ test_cmp expect actual
'
test_expect_success 'file added and later removed' '
git range-diff --no-color --submodule=log topic...added-removed >actual &&
- sed s/Z/\ /g >expected <<-EOF &&
- 1: 4de457d = 1: 096b1ba s/5/A/
- 2: fccce22 ! 2: d92e698 s/4/A/
+ sed s/Z/\ /g >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid s1) s/5/A/
+ 2: $(test_oid t2) ! 2: $(test_oid s2) s/4/A/
@@ Metadata
ZAuthor: Thomas Rast <trast@inf.ethz.ch>
Z
@@ -246,7 +393,7 @@ test_expect_success 'file added and later removed' '
Z 7
+
+ ## new-file (new) ##
- 3: 147e64e ! 3: 9a1db4d s/11/B/
+ 3: $(test_oid t3) ! 3: $(test_oid s3) s/11/B/
@@ Metadata
ZAuthor: Thomas Rast <trast@inf.ethz.ch>
Z
@@ -262,9 +409,9 @@ test_expect_success 'file added and later removed' '
Z 14
+
+ ## new-file (deleted) ##
- 4: a63e992 = 4: fea3b5c s/12/B/
+ 4: $(test_oid t4) = 4: $(test_oid s4) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'no commits on one side' '
@@ -274,9 +421,9 @@ test_expect_success 'no commits on one side' '
test_expect_success 'changed message' '
git range-diff --no-color topic...changed-message >actual &&
- sed s/Z/\ /g >expected <<-EOF &&
- 1: 4de457d = 1: f686024 s/5/A/
- 2: fccce22 ! 2: 4ab067d s/4/A/
+ sed s/Z/\ /g >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid m1) s/5/A/
+ 2: $(test_oid t2) ! 2: $(test_oid m2) s/4/A/
@@ Metadata
Z ## Commit message ##
Z s/4/A/
@@ -286,16 +433,16 @@ test_expect_success 'changed message' '
Z ## file ##
Z@@
Z 1
- 3: 147e64e = 3: b9cb956 s/11/B/
- 4: a63e992 = 4: 8add5f1 s/12/B/
+ 3: $(test_oid t3) = 3: $(test_oid m3) s/11/B/
+ 4: $(test_oid t4) = 4: $(test_oid m4) s/12/B/
EOF
- test_cmp expected actual
+ test_cmp expect actual
'
test_expect_success 'dual-coloring' '
- sed -e "s|^:||" >expect <<-\EOF &&
- :<YELLOW>1: a4b3333 = 1: f686024 s/5/A/<RESET>
- :<RED>2: f51d370 <RESET><YELLOW>!<RESET><GREEN> 2: 4ab067d<RESET><YELLOW> s/4/A/<RESET>
+ sed -e "s|^:||" >expect <<-EOF &&
+ :<YELLOW>1: $(test_oid c1) = 1: $(test_oid m1) s/5/A/<RESET>
+ :<RED>2: $(test_oid c2) <RESET><YELLOW>!<RESET><GREEN> 2: $(test_oid m2)<RESET><YELLOW> s/4/A/<RESET>
: <REVERSE><CYAN>@@<RESET> <RESET>Metadata<RESET>
: ## Commit message ##<RESET>
: s/4/A/<RESET>
@@ -305,7 +452,7 @@ test_expect_success 'dual-coloring' '
: ## file ##<RESET>
: <CYAN> @@<RESET>
: 1<RESET>
- :<RED>3: 0559556 <RESET><YELLOW>!<RESET><GREEN> 3: b9cb956<RESET><YELLOW> s/11/B/<RESET>
+ :<RED>3: $(test_oid c3) <RESET><YELLOW>!<RESET><GREEN> 3: $(test_oid m3)<RESET><YELLOW> s/11/B/<RESET>
: <REVERSE><CYAN>@@<RESET> <RESET>file: A<RESET>
: 9<RESET>
: 10<RESET>
@@ -315,7 +462,7 @@ test_expect_success 'dual-coloring' '
: 12<RESET>
: 13<RESET>
: 14<RESET>
- :<RED>4: d966c5c <RESET><YELLOW>!<RESET><GREEN> 4: 8add5f1<RESET><YELLOW> s/12/B/<RESET>
+ :<RED>4: $(test_oid c4) <RESET><YELLOW>!<RESET><GREEN> 4: $(test_oid m4)<RESET><YELLOW> s/12/B/<RESET>
: <REVERSE><CYAN>@@<RESET> <RESET>file<RESET>
: <CYAN> @@ file: A<RESET>
: 9<RESET>
@@ -354,4 +501,206 @@ test_expect_success 'format-patch --range-diff as commentary' '
grep "> 1: .* new message" 0001-*
'
+test_expect_success 'range-diff overrides diff.noprefix internally' '
+ git -c diff.noprefix=true range-diff HEAD^...
+'
+
+test_expect_success 'range-diff compares notes by default' '
+ git notes add -m "topic note" topic &&
+ git notes add -m "unmodified note" unmodified &&
+ test_when_finished git notes remove topic unmodified &&
+ git range-diff --no-color master..topic master..unmodified \
+ >actual &&
+ sed s/Z/\ /g >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
+ 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
+ 4: $(test_oid t4) ! 4: $(test_oid u4) s/12/B/
+ @@ Commit message
+ Z
+ Z
+ Z ## Notes ##
+ - topic note
+ + unmodified note
+ Z
+ Z ## file ##
+ Z@@ file: A
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'range-diff with --no-notes' '
+ git notes add -m "topic note" topic &&
+ git notes add -m "unmodified note" unmodified &&
+ test_when_finished git notes remove topic unmodified &&
+ git range-diff --no-color --no-notes master..topic master..unmodified \
+ >actual &&
+ cat >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
+ 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
+ 4: $(test_oid t4) = 4: $(test_oid u4) s/12/B/
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'range-diff with multiple --notes' '
+ git notes --ref=note1 add -m "topic note1" topic &&
+ git notes --ref=note1 add -m "unmodified note1" unmodified &&
+ test_when_finished git notes --ref=note1 remove topic unmodified &&
+ git notes --ref=note2 add -m "topic note2" topic &&
+ git notes --ref=note2 add -m "unmodified note2" unmodified &&
+ test_when_finished git notes --ref=note2 remove topic unmodified &&
+ git range-diff --no-color --notes=note1 --notes=note2 master..topic master..unmodified \
+ >actual &&
+ sed s/Z/\ /g >expect <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
+ 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
+ 4: $(test_oid t4) ! 4: $(test_oid u4) s/12/B/
+ @@ Commit message
+ Z
+ Z
+ Z ## Notes (note1) ##
+ - topic note1
+ + unmodified note1
+ Z
+ Z
+ Z ## Notes (note2) ##
+ - topic note2
+ + unmodified note2
+ Z
+ Z ## file ##
+ Z@@ file: A
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'format-patch --range-diff does not compare notes by default' '
+ git notes add -m "topic note" topic &&
+ git notes add -m "unmodified note" unmodified &&
+ test_when_finished git notes remove topic unmodified &&
+ git format-patch --cover-letter --range-diff=$prev \
+ master..unmodified >actual &&
+ test_when_finished "rm 000?-*" &&
+ test_line_count = 5 actual &&
+ test_i18ngrep "^Range-diff:$" 0000-* &&
+ grep "= 1: .* s/5/A" 0000-* &&
+ grep "= 2: .* s/4/A" 0000-* &&
+ grep "= 3: .* s/11/B" 0000-* &&
+ grep "= 4: .* s/12/B" 0000-* &&
+ ! grep "Notes" 0000-* &&
+ ! grep "note" 0000-*
+'
+
+test_expect_success 'format-patch --range-diff with --no-notes' '
+ git notes add -m "topic note" topic &&
+ git notes add -m "unmodified note" unmodified &&
+ test_when_finished git notes remove topic unmodified &&
+ git format-patch --no-notes --cover-letter --range-diff=$prev \
+ master..unmodified >actual &&
+ test_when_finished "rm 000?-*" &&
+ test_line_count = 5 actual &&
+ test_i18ngrep "^Range-diff:$" 0000-* &&
+ grep "= 1: .* s/5/A" 0000-* &&
+ grep "= 2: .* s/4/A" 0000-* &&
+ grep "= 3: .* s/11/B" 0000-* &&
+ grep "= 4: .* s/12/B" 0000-* &&
+ ! grep "Notes" 0000-* &&
+ ! grep "note" 0000-*
+'
+
+test_expect_success 'format-patch --range-diff with --notes' '
+ git notes add -m "topic note" topic &&
+ git notes add -m "unmodified note" unmodified &&
+ test_when_finished git notes remove topic unmodified &&
+ git format-patch --notes --cover-letter --range-diff=$prev \
+ master..unmodified >actual &&
+ test_when_finished "rm 000?-*" &&
+ test_line_count = 5 actual &&
+ test_i18ngrep "^Range-diff:$" 0000-* &&
+ grep "= 1: .* s/5/A" 0000-* &&
+ grep "= 2: .* s/4/A" 0000-* &&
+ grep "= 3: .* s/11/B" 0000-* &&
+ grep "! 4: .* s/12/B" 0000-* &&
+ sed s/Z/\ /g >expect <<-EOF &&
+ @@ Commit message
+ Z
+ Z
+ Z ## Notes ##
+ - topic note
+ + unmodified note
+ Z
+ Z ## file ##
+ Z@@ file: A
+ EOF
+ sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'format-patch --range-diff with format.notes config' '
+ git notes add -m "topic note" topic &&
+ git notes add -m "unmodified note" unmodified &&
+ test_when_finished git notes remove topic unmodified &&
+ test_config format.notes true &&
+ git format-patch --cover-letter --range-diff=$prev \
+ master..unmodified >actual &&
+ test_when_finished "rm 000?-*" &&
+ test_line_count = 5 actual &&
+ test_i18ngrep "^Range-diff:$" 0000-* &&
+ grep "= 1: .* s/5/A" 0000-* &&
+ grep "= 2: .* s/4/A" 0000-* &&
+ grep "= 3: .* s/11/B" 0000-* &&
+ grep "! 4: .* s/12/B" 0000-* &&
+ sed s/Z/\ /g >expect <<-EOF &&
+ @@ Commit message
+ Z
+ Z
+ Z ## Notes ##
+ - topic note
+ + unmodified note
+ Z
+ Z ## file ##
+ Z@@ file: A
+ EOF
+ sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'format-patch --range-diff with multiple notes' '
+ git notes --ref=note1 add -m "topic note1" topic &&
+ git notes --ref=note1 add -m "unmodified note1" unmodified &&
+ test_when_finished git notes --ref=note1 remove topic unmodified &&
+ git notes --ref=note2 add -m "topic note2" topic &&
+ git notes --ref=note2 add -m "unmodified note2" unmodified &&
+ test_when_finished git notes --ref=note2 remove topic unmodified &&
+ git format-patch --notes=note1 --notes=note2 --cover-letter --range-diff=$prev \
+ master..unmodified >actual &&
+ test_when_finished "rm 000?-*" &&
+ test_line_count = 5 actual &&
+ test_i18ngrep "^Range-diff:$" 0000-* &&
+ grep "= 1: .* s/5/A" 0000-* &&
+ grep "= 2: .* s/4/A" 0000-* &&
+ grep "= 3: .* s/11/B" 0000-* &&
+ grep "! 4: .* s/12/B" 0000-* &&
+ sed s/Z/\ /g >expect <<-EOF &&
+ @@ Commit message
+ Z
+ Z
+ Z ## Notes (note1) ##
+ - topic note1
+ + unmodified note1
+ Z
+ Z
+ Z ## Notes (note2) ##
+ - topic note2
+ + unmodified note2
+ Z
+ Z ## file ##
+ Z@@ file: A
+ EOF
+ sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3206/history.export b/t/t3206/history.export
index 7bb3814962..4c808e5b3b 100644
--- a/t/t3206/history.export
+++ b/t/t3206/history.export
@@ -55,7 +55,7 @@ A
19
20
-commit refs/heads/topic
+commit refs/heads/mode-only-change
mark :4
author Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
committer Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
@@ -678,3 +678,32 @@ s/12/B/
from :55
M 100644 :9 renamed-file
+commit refs/heads/mode-only-change
+mark :57
+author Thomas Rast <trast@inf.ethz.ch> 1374485024 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473767 +0100
+data 24
+s/4/A/ + add other-file
+from :4
+M 100644 :5 file
+M 100644 :49 other-file
+
+commit refs/heads/mode-only-change
+mark :58
+author Thomas Rast <trast@inf.ethz.ch> 1374485036 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473768 +0100
+data 33
+s/11/B/ + mode change other-file
+from :57
+M 100644 :7 file
+M 100755 :49 other-file
+
+commit refs/heads/mode-only-change
+mark :59
+author Thomas Rast <trast@inf.ethz.ch> 1374485044 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473768 +0100
+data 8
+s/12/B/
+from :58
+M 100644 :9 file
+
diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh
index 9ea5fa4fd2..f41b2afb99 100755
--- a/t/t3210-pack-refs.sh
+++ b/t/t3210-pack-refs.sh
@@ -240,7 +240,7 @@ test_expect_success 'retry acquiring packed-refs.lock' '
test_expect_success SYMLINKS 'pack symlinked packed-refs' '
# First make sure that symlinking works when reading:
- git update-ref refs/heads/loosy refs/heads/master &&
+ git update-ref refs/heads/lossy refs/heads/master &&
git for-each-ref >all-refs-before &&
mv .git/packed-refs .git/my-deviant-packed-refs &&
ln -s my-deviant-packed-refs .git/packed-refs &&
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index 704bbc6541..8f43303007 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -54,7 +54,9 @@ test_expect_success 'create notes' '
test_path_is_missing .git/NOTES_EDITMSG &&
git ls-tree -r refs/notes/commits >actual &&
test_line_count = 1 actual &&
- test "b4" = "$(git notes show)" &&
+ echo b4 >expect &&
+ git notes show >actual &&
+ test_cmp expect actual &&
git show HEAD^ &&
test_must_fail git notes show HEAD^
'
@@ -66,8 +68,9 @@ test_expect_success 'show notes entry with %N' '
'
test_expect_success 'create reflog entry' '
+ ref=$(git rev-parse --short refs/notes/commits) &&
cat <<-EOF >expect &&
- a1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
+ $ref refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
EOF
git reflog show refs/notes/commits >actual &&
test_cmp expect actual
@@ -78,14 +81,21 @@ test_expect_success 'edit existing notes' '
test_path_is_missing .git/NOTES_EDITMSG &&
git ls-tree -r refs/notes/commits >actual &&
test_line_count = 1 actual &&
- test "b3" = "$(git notes show)" &&
+ echo b3 >expect &&
+ git notes show >actual &&
+ test_cmp expect actual &&
git show HEAD^ &&
test_must_fail git notes show HEAD^
'
test_expect_success 'show notes from treeish' '
- test "b3" = "$(git notes --ref commits^{tree} show)" &&
- test "b4" = "$(git notes --ref commits@{1} show)"
+ echo b3 >expect &&
+ git notes --ref commits^{tree} show >actual &&
+ test_cmp expect actual &&
+
+ echo b4 >expect &&
+ git notes --ref commits@{1} show >actual &&
+ test_cmp expect actual
'
test_expect_success 'cannot edit notes from non-ref' '
@@ -98,7 +108,9 @@ test_expect_success 'cannot "git notes add -m" where notes already exists' '
test_path_is_missing .git/NOTES_EDITMSG &&
git ls-tree -r refs/notes/commits >actual &&
test_line_count = 1 actual &&
- test "b3" = "$(git notes show)" &&
+ echo b3 >expect &&
+ git notes show >actual &&
+ test_cmp expect actual &&
git show HEAD^ &&
test_must_fail git notes show HEAD^
'
@@ -108,7 +120,9 @@ test_expect_success 'can overwrite existing note with "git notes add -f -m"' '
test_path_is_missing .git/NOTES_EDITMSG &&
git ls-tree -r refs/notes/commits >actual &&
test_line_count = 1 actual &&
- test "b1" = "$(git notes show)" &&
+ echo b1 >expect &&
+ git notes show >actual &&
+ test_cmp expect actual &&
git show HEAD^ &&
test_must_fail git notes show HEAD^
'
@@ -118,7 +132,9 @@ test_expect_success 'add w/no options on existing note morphs into edit' '
test_path_is_missing .git/NOTES_EDITMSG &&
git ls-tree -r refs/notes/commits >actual &&
test_line_count = 1 actual &&
- test "b2" = "$(git notes show)" &&
+ echo b2 >expect &&
+ git notes show >actual &&
+ test_cmp expect actual &&
git show HEAD^ &&
test_must_fail git notes show HEAD^
'
@@ -128,14 +144,17 @@ test_expect_success 'can overwrite existing note with "git notes add -f"' '
test_path_is_missing .git/NOTES_EDITMSG &&
git ls-tree -r refs/notes/commits >actual &&
test_line_count = 1 actual &&
- test "b1" = "$(git notes show)" &&
+ echo b1 >expect &&
+ git notes show >actual &&
+ test_cmp expect actual &&
git show HEAD^ &&
test_must_fail git notes show HEAD^
'
test_expect_success 'show notes' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 7a4ca6ee52a974a66cbaa78e33214535dff1d691
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:14:13 2005 -0700
@@ -144,7 +163,8 @@ test_expect_success 'show notes' '
Notes:
${indent}b1
EOF
- ! (git cat-file commit HEAD | grep b1) &&
+ git cat-file commit HEAD >commits &&
+ ! grep b1 commits &&
git log -1 >actual &&
test_cmp expect actual
'
@@ -152,8 +172,9 @@ test_expect_success 'show notes' '
test_expect_success 'show multi-line notes' '
test_commit 3rd &&
MSG="b3${LF}c3c3c3c3${LF}d3d3d3" git notes add &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-multiline <<-EOF &&
- commit d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:15:13 2005 -0700
@@ -174,8 +195,9 @@ test_expect_success 'show -F notes' '
test_commit 4th &&
echo "xyzzy" >note5 &&
git notes add -F note5 &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-F <<-EOF &&
- commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:16:13 2005 -0700
@@ -198,10 +220,13 @@ test_expect_success 'Re-adding -F notes without -f fails' '
'
test_expect_success 'git log --pretty=raw does not show notes' '
+ commit=$(git rev-parse HEAD) &&
+ tree=$(git rev-parse HEAD^{tree}) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
- tree 05ac65288c4c4b3b709a020ae94b2ece2f2201ae
- parent d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit $commit
+ tree $tree
+ parent $parent
author A U Thor <author@example.com> 1112912173 -0700
committer C O Mitter <committer@example.com> 1112912173 -0700
@@ -291,8 +316,9 @@ test_expect_success 'git log --no-notes resets ref list' '
test_expect_success 'show -m notes' '
test_commit 5th &&
git notes add -m spam -m "foo${LF}bar${LF}baz" &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-m <<-EOF &&
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -313,8 +339,9 @@ test_expect_success 'show -m notes' '
test_expect_success 'remove note with add -f -F /dev/null' '
git notes add -f -F /dev/null &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-rm-F <<-EOF &&
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -356,14 +383,16 @@ test_expect_success 'create note with combination of -m and -F' '
test_expect_success 'remove note with "git notes remove"' '
git notes remove HEAD^ &&
git notes remove &&
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect-rm-remove <<-EOF &&
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
${indent}5th
- commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:16:13 2005 -0700
@@ -459,9 +488,13 @@ test_expect_success 'removing with --stdin --ignore-missing' '
'
test_expect_success 'list notes with "git notes list"' '
- cat >expect <<-EOF &&
- c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
- c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit_2=$(git rev-parse 2nd) &&
+ commit_3=$(git rev-parse 3rd) &&
+ note_2=$(git rev-parse refs/notes/commits:$commit_2) &&
+ note_3=$(git rev-parse refs/notes/commits:$commit_3) &&
+ sort -t" " -k2 >expect <<-EOF &&
+ $note_2 $commit_2
+ $note_3 $commit_3
EOF
git notes list >actual &&
test_cmp expect actual
@@ -473,9 +506,7 @@ test_expect_success 'list notes with "git notes"' '
'
test_expect_success 'list specific note with "git notes list <object>"' '
- cat >expect <<-EOF &&
- c18dc024e14f08d18d14eea0d747ff692d66d6a3
- EOF
+ git rev-parse refs/notes/commits:$commit_3 >expect &&
git notes list HEAD^^ >actual &&
test_cmp expect actual
'
@@ -498,10 +529,12 @@ test_expect_success 'append to existing note with "git notes append"' '
'
test_expect_success '"git notes list" does not expand to "git notes list HEAD"' '
- cat >expect_list <<-EOF &&
- c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
- 4b6ad22357cc8a1296720574b8d2fbc22fab0671 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
- c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit_5=$(git rev-parse 5th) &&
+ note_5=$(git rev-parse refs/notes/commits:$commit_5) &&
+ sort -t" " -k2 >expect_list <<-EOF &&
+ $note_2 $commit_2
+ $note_3 $commit_3
+ $note_5 $commit_5
EOF
git notes list >actual &&
test_cmp expect_list actual
@@ -531,8 +564,9 @@ test_expect_success 'appending empty string to non-existing note does not create
test_expect_success 'create other note on a different notes ref (setup)' '
test_commit 6th &&
GIT_NOTES_REF="refs/notes/other" git notes add -m "other note" &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-not-other <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -569,8 +603,10 @@ test_expect_success 'Do not show note when core.notesRef is overridden' '
'
test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect-both <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -582,7 +618,7 @@ test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
Notes (other):
${indent}other note
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -616,8 +652,9 @@ test_expect_success 'notes.displayRef can be given more than once' '
'
test_expect_success 'notes.displayRef respects order' '
+ commit=$(git rev-parse HEAD) &&
cat >expect-both-reversed <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -642,14 +679,16 @@ test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
'
test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect-none <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
${indent}6th
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -666,8 +705,9 @@ test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
'
test_expect_success '--no-standard-notes' '
+ commit=$(git rev-parse HEAD) &&
cat >expect-commits <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -700,7 +740,8 @@ test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
git notes show HEAD: >actual &&
test_cmp expect actual &&
echo "Note on a blob" >expect &&
- filename=$(git ls-tree --name-only HEAD | head -n1) &&
+ git ls-tree --name-only HEAD >files &&
+ filename=$(head -n1 files) &&
git notes add -m "Note on a blob" HEAD:$filename &&
git notes show HEAD:$filename >actual &&
test_cmp expect actual &&
@@ -712,8 +753,10 @@ test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
'
test_expect_success 'create note from other note with "git notes add -C"' '
+ test_commit 7th &&
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit fb01e0ca8c33b6cc0c6451dde747f97df567cb5c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:19:13 2005 -0700
@@ -722,11 +765,13 @@ test_expect_success 'create note from other note with "git notes add -C"' '
Notes:
${indent}order test
EOF
- test_commit 7th &&
- git notes add -C $(git notes list HEAD^) &&
+ note=$(git notes list HEAD^) &&
+ git notes add -C $note &&
git log -1 >actual &&
test_cmp expect actual &&
- test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
+ git notes list HEAD^ >expect &&
+ git notes list HEAD >actual &&
+ test_cmp expect actual
'
test_expect_success 'create note from non-existing note with "git notes add -C" fails' '
@@ -744,8 +789,9 @@ test_expect_success 'create note from non-blob with "git notes add -C" fails' '
'
test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 9a4c31c7f722b5d517e92c64e932dd751e1413bf
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:20:13 2005 -0700
@@ -754,16 +800,19 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i
Notes:
${indent}This is a blob object
EOF
- blob=$(echo "This is a blob object" | git hash-object -w --stdin) &&
- git notes add -C $blob &&
+ echo "This is a blob object" | git hash-object -w --stdin >blob &&
+ git notes add -C $(cat blob) &&
git log -1 >actual &&
test_cmp expect actual &&
- test "$(git notes list HEAD)" = "$blob"
+ git notes list HEAD >actual &&
+ test_cmp blob actual
'
test_expect_success 'create note from other note with "git notes add -c"' '
+ test_commit 9th &&
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:21:13 2005 -0700
@@ -772,8 +821,8 @@ test_expect_success 'create note from other note with "git notes add -c"' '
Notes:
${indent}yet another note
EOF
- test_commit 9th &&
- MSG="yet another note" git notes add -c $(git notes list HEAD^^) &&
+ note=$(git notes list HEAD^^) &&
+ MSG="yet another note" git notes add -c $note &&
git log -1 >actual &&
test_cmp expect actual
'
@@ -785,8 +834,9 @@ test_expect_success 'create note from non-existing note with "git notes add -c"
'
test_expect_success 'append to note from other note with "git notes append -C"' '
+ commit=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:21:13 2005 -0700
@@ -797,14 +847,16 @@ test_expect_success 'append to note from other note with "git notes append -C"'
${indent}
${indent}yet another note
EOF
- git notes append -C $(git notes list HEAD^) HEAD^ &&
+ note=$(git notes list HEAD^) &&
+ git notes append -C $note HEAD^ &&
git log -1 HEAD^ >actual &&
test_cmp expect actual
'
test_expect_success 'create note from other note with "git notes append -c"' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:22:13 2005 -0700
@@ -813,14 +865,16 @@ test_expect_success 'create note from other note with "git notes append -c"' '
Notes:
${indent}other note
EOF
- MSG="other note" git notes append -c $(git notes list HEAD^) &&
+ note=$(git notes list HEAD^) &&
+ MSG="other note" git notes append -c $note &&
git log -1 >actual &&
test_cmp expect actual
'
test_expect_success 'append to note from other note with "git notes append -c"' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:22:13 2005 -0700
@@ -831,14 +885,37 @@ test_expect_success 'append to note from other note with "git notes append -c"'
${indent}
${indent}yet another note
EOF
- MSG="yet another note" git notes append -c $(git notes list HEAD) &&
+ note=$(git notes list HEAD) &&
+ MSG="yet another note" git notes append -c $note &&
git log -1 >actual &&
test_cmp expect actual
'
test_expect_success 'copy note with "git notes copy"' '
+ commit=$(git rev-parse 4th) &&
cat >expect <<-EOF &&
- commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+ commit $commit
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:16:13 2005 -0700
+
+ ${indent}4th
+
+ Notes:
+ ${indent}This is a blob object
+ EOF
+ git notes copy 8th 4th &&
+ git log 3rd..4th >actual &&
+ test_cmp expect actual &&
+ git notes list 4th >expect &&
+ git notes list 8th >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'copy note with "git notes copy" with default' '
+ test_commit 11th &&
+ commit=$(git rev-parse HEAD) &&
+ cat >expect <<-EOF &&
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:23:13 2005 -0700
@@ -849,23 +926,59 @@ test_expect_success 'copy note with "git notes copy"' '
${indent}
${indent}yet another note
EOF
- test_commit 11th &&
- git notes copy HEAD^ HEAD &&
+ git notes copy HEAD^ &&
git log -1 >actual &&
test_cmp expect actual &&
- test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
+ git notes list HEAD^ >expect &&
+ git notes list HEAD >actual &&
+ test_cmp expect actual
'
test_expect_success 'prevent overwrite with "git notes copy"' '
test_must_fail git notes copy HEAD~2 HEAD &&
+ cat >expect <<-EOF &&
+ commit $commit
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:23:13 2005 -0700
+
+ ${indent}11th
+
+ Notes:
+ ${indent}other note
+ ${indent}
+ ${indent}yet another note
+ EOF
git log -1 >actual &&
test_cmp expect actual &&
- test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
+ git notes list HEAD^ >expect &&
+ git notes list HEAD >actual &&
+ test_cmp expect actual
'
test_expect_success 'allow overwrite with "git notes copy -f"' '
+ commit=$(git rev-parse HEAD) &&
+ cat >expect <<-EOF &&
+ commit $commit
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:23:13 2005 -0700
+
+ ${indent}11th
+
+ Notes:
+ ${indent}This is a blob object
+ EOF
+ git notes copy -f HEAD~3 HEAD &&
+ git log -1 >actual &&
+ test_cmp expect actual &&
+ git notes list HEAD~3 >expect &&
+ git notes list HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'allow overwrite with "git notes copy -f" with default' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:23:13 2005 -0700
@@ -876,10 +989,12 @@ test_expect_success 'allow overwrite with "git notes copy -f"' '
${indent}
${indent}yet another note
EOF
- git notes copy -f HEAD~2 HEAD &&
+ git notes copy -f HEAD~2 &&
git log -1 >actual &&
test_cmp expect actual &&
- test "$(git notes list HEAD)" = "$(git notes list HEAD~2)"
+ git notes list HEAD~2 >expect &&
+ git notes list HEAD >actual &&
+ test_cmp expect actual
'
test_expect_success 'cannot copy note from object without notes' '
@@ -889,8 +1004,10 @@ test_expect_success 'cannot copy note from object without notes' '
'
test_expect_success 'git notes copy --stdin' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit e871aa61182b1d95d0a6fb75445d891722863b6b
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:25:13 2005 -0700
@@ -901,7 +1018,7 @@ test_expect_success 'git notes copy --stdin' '
${indent}
${indent}yet another note
- commit 65e263ded02ae4e8839bc151095113737579dc12
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:24:13 2005 -0700
@@ -912,41 +1029,57 @@ test_expect_success 'git notes copy --stdin' '
${indent}
${indent}yet another note
EOF
- (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
- echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
- git notes copy --stdin &&
+ from=$(git rev-parse HEAD~3) &&
+ to=$(git rev-parse HEAD^) &&
+ echo "$from" "$to" >copy &&
+ from=$(git rev-parse HEAD~2) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >>copy &&
+ git notes copy --stdin <copy &&
git log -2 >actual &&
test_cmp expect actual &&
- test "$(git notes list HEAD)" = "$(git notes list HEAD~2)" &&
- test "$(git notes list HEAD^)" = "$(git notes list HEAD~3)"
+ git notes list HEAD~2 >expect &&
+ git notes list HEAD >actual &&
+ test_cmp expect actual &&
+ git notes list HEAD~3 >expect &&
+ git notes list HEAD^ >actual &&
+ test_cmp expect actual
'
test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
+ test_commit 14th &&
+ test_commit 15th &&
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
${indent}15th
- commit 07c85d77059393ed0154b8c96906547a59dfcddd
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:26:13 2005 -0700
${indent}14th
EOF
- test_commit 14th &&
- test_commit 15th &&
- (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
- echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
- git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD~3) &&
+ to=$(git rev-parse HEAD^) &&
+ echo "$from" "$to" >copy &&
+ from=$(git rev-parse HEAD~2) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >>copy &&
+ git notes copy --for-rewrite=foo <copy &&
git log -2 >actual &&
test_cmp expect actual
'
test_expect_success 'git notes copy --for-rewrite (enabled)' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -957,7 +1090,7 @@ test_expect_success 'git notes copy --for-rewrite (enabled)' '
${indent}
${indent}yet another note
- commit 07c85d77059393ed0154b8c96906547a59dfcddd
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:26:13 2005 -0700
@@ -970,24 +1103,31 @@ test_expect_success 'git notes copy --for-rewrite (enabled)' '
EOF
test_config notes.rewriteMode overwrite &&
test_config notes.rewriteRef "refs/notes/*" &&
- (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
- echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
- git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD~3) &&
+ to=$(git rev-parse HEAD^) &&
+ echo "$from" "$to" >copy &&
+ from=$(git rev-parse HEAD~2) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >>copy &&
+ git notes copy --for-rewrite=foo <copy &&
git log -2 >actual &&
test_cmp expect actual
'
test_expect_success 'git notes copy --for-rewrite (disabled)' '
test_config notes.rewrite.bar false &&
- echo $(git rev-parse HEAD~3) $(git rev-parse HEAD) |
- git notes copy --for-rewrite=bar &&
+ from=$(git rev-parse HEAD~3) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
+ git notes copy --for-rewrite=bar <copy &&
git log -2 >actual &&
test_cmp expect actual
'
test_expect_success 'git notes copy --for-rewrite (overwrite)' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -999,8 +1139,10 @@ test_expect_success 'git notes copy --for-rewrite (overwrite)' '
git notes add -f -m"a fresh note" HEAD^ &&
test_config notes.rewriteMode overwrite &&
test_config notes.rewriteRef "refs/notes/*" &&
- echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
- git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
+ git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
test_cmp expect actual
'
@@ -1008,15 +1150,18 @@ test_expect_success 'git notes copy --for-rewrite (overwrite)' '
test_expect_success 'git notes copy --for-rewrite (ignore)' '
test_config notes.rewriteMode ignore &&
test_config notes.rewriteRef "refs/notes/*" &&
- echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
- git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
+ git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
test_cmp expect actual
'
test_expect_success 'git notes copy --for-rewrite (append)' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1030,15 +1175,18 @@ test_expect_success 'git notes copy --for-rewrite (append)' '
git notes add -f -m"another fresh note" HEAD^ &&
test_config notes.rewriteMode concatenate &&
test_config notes.rewriteRef "refs/notes/*" &&
- echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
- git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
+ git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
test_cmp expect actual
'
test_expect_success 'git notes copy --for-rewrite (append two to one)' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1057,9 +1205,13 @@ test_expect_success 'git notes copy --for-rewrite (append two to one)' '
git notes add -f -m"append 2" HEAD^^ &&
test_config notes.rewriteMode concatenate &&
test_config notes.rewriteRef "refs/notes/*" &&
- (echo $(git rev-parse HEAD^) $(git rev-parse HEAD) &&
- echo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) |
- git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
+ from=$(git rev-parse HEAD^^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >>copy &&
+ git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
test_cmp expect actual
'
@@ -1068,15 +1220,18 @@ test_expect_success 'git notes copy --for-rewrite (append empty)' '
git notes remove HEAD^ &&
test_config notes.rewriteMode concatenate &&
test_config notes.rewriteRef "refs/notes/*" &&
- echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
- git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
+ git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
test_cmp expect actual
'
test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1088,15 +1243,18 @@ test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
test_config notes.rewriteMode concatenate &&
test_config notes.rewriteRef "refs/notes/*" &&
git notes add -f -m"replacement note 1" HEAD^ &&
- echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
- GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo &&
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
+ GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
test_cmp expect actual
'
test_expect_success 'GIT_NOTES_REWRITE_REF works' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1108,9 +1266,11 @@ test_expect_success 'GIT_NOTES_REWRITE_REF works' '
git notes add -f -m"replacement note 2" HEAD^ &&
test_config notes.rewriteMode overwrite &&
test_unconfig notes.rewriteRef &&
- echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
GIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \
- git notes copy --for-rewrite=foo &&
+ git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
test_cmp expect actual
'
@@ -1119,41 +1279,55 @@ test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '
git notes add -f -m"replacement note 3" HEAD^ &&
test_config notes.rewriteMode overwrite &&
test_config notes.rewriteRef refs/notes/other &&
- echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ from=$(git rev-parse HEAD^) &&
+ to=$(git rev-parse HEAD) &&
+ echo "$from" "$to" >copy &&
GIT_NOTES_REWRITE_REF=refs/notes/commits \
- git notes copy --for-rewrite=foo &&
+ git notes copy --for-rewrite=foo <copy &&
git log -1 >actual &&
grep "replacement note 3" actual
'
test_expect_success 'git notes copy diagnoses too many or too few parameters' '
- test_must_fail git notes copy &&
- test_must_fail git notes copy one two three
+ test_must_fail git notes copy 2>error &&
+ test_i18ngrep "too few parameters" error &&
+ test_must_fail git notes copy one two three 2>error &&
+ test_i18ngrep "too many parameters" error
'
test_expect_success 'git notes get-ref expands refs/heads/master to refs/notes/refs/heads/master' '
test_unconfig core.notesRef &&
sane_unset GIT_NOTES_REF &&
- test "$(git notes --ref=refs/heads/master get-ref)" = "refs/notes/refs/heads/master"
+ echo refs/notes/refs/heads/master >expect &&
+ git notes --ref=refs/heads/master get-ref >actual &&
+ test_cmp expect actual
'
test_expect_success 'git notes get-ref (no overrides)' '
test_unconfig core.notesRef &&
sane_unset GIT_NOTES_REF &&
- test "$(git notes get-ref)" = "refs/notes/commits"
+ echo refs/notes/commits >expect &&
+ git notes get-ref >actual &&
+ test_cmp expect actual
'
test_expect_success 'git notes get-ref (core.notesRef)' '
test_config core.notesRef refs/notes/foo &&
- test "$(git notes get-ref)" = "refs/notes/foo"
+ echo refs/notes/foo >expect &&
+ git notes get-ref >actual &&
+ test_cmp expect actual
'
test_expect_success 'git notes get-ref (GIT_NOTES_REF)' '
- test "$(GIT_NOTES_REF=refs/notes/bar git notes get-ref)" = "refs/notes/bar"
+ echo refs/notes/bar >expect &&
+ GIT_NOTES_REF=refs/notes/bar git notes get-ref >actual &&
+ test_cmp expect actual
'
test_expect_success 'git notes get-ref (--ref)' '
- test "$(GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref)" = "refs/notes/baz"
+ echo refs/notes/baz >expect &&
+ GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref >actual &&
+ test_cmp expect actual
'
test_expect_success 'setup testing of empty notes' '
diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh
index 54460beec4..831f83d211 100755
--- a/t/t3305-notes-fanout.sh
+++ b/t/t3305-notes-fanout.sh
@@ -35,15 +35,10 @@ test_expect_success 'many notes created with git-notes triggers fanout' '
git ls-tree -r --name-only refs/notes/commits |
while read path
do
- case "$path" in
- ??/??????????????????????????????????????)
- : true
- ;;
- *)
+ echo $path | grep "^../[0-9a-f]*$" || {
echo "Invalid path \"$path\"" &&
- return 1
- ;;
- esac
+ return 1;
+ }
done
'
@@ -77,15 +72,10 @@ test_expect_success 'deleting most notes triggers fanout consolidation' '
git ls-tree -r --name-only refs/notes/commits |
while read path
do
- case "$path" in
- ????????????????????????????????????????)
- : true
- ;;
- *)
+ echo $path | grep -v "^../.*" || {
echo "Invalid path \"$path\"" &&
- return 1
- ;;
- esac
+ return 1;
+ }
done
'
diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh
index 61748088eb..8f4102ff9e 100755
--- a/t/t3306-notes-prune.sh
+++ b/t/t3306-notes-prune.sh
@@ -11,23 +11,26 @@ test_expect_success 'setup: create a few commits with notes' '
test_tick &&
git commit -m 1st &&
git notes add -m "Note #1" &&
+ first=$(git rev-parse HEAD) &&
: > file2 &&
git add file2 &&
test_tick &&
git commit -m 2nd &&
git notes add -m "Note #2" &&
+ second=$(git rev-parse HEAD) &&
: > file3 &&
git add file3 &&
test_tick &&
git commit -m 3rd &&
- COMMIT_FILE=.git/objects/5e/e1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+ third=$(git rev-parse HEAD) &&
+ COMMIT_FILE=$(echo $third | sed "s!^..!.git/objects/&/!") &&
test -f $COMMIT_FILE &&
test-tool chmtime =+0 $COMMIT_FILE &&
git notes add -m "Note #3"
'
cat > expect <<END_OF_LOG
-commit 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
+commit $third
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:15:13 2005 -0700
@@ -36,7 +39,7 @@ Date: Thu Apr 7 15:15:13 2005 -0700
Notes:
Note #3
-commit 08341ad9e94faa089d60fd3f523affb25c6da189
+commit $second
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:14:13 2005 -0700
@@ -45,7 +48,7 @@ Date: Thu Apr 7 15:14:13 2005 -0700
Notes:
Note #2
-commit ab5f302035f2e7aaf04265f08b42034c23256e1f
+commit $first
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:13:13 2005 -0700
@@ -70,16 +73,16 @@ test_expect_success 'remove some commits' '
test_expect_success 'verify that commits are gone' '
- test_must_fail git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f
+ test_must_fail git cat-file -p $third &&
+ git cat-file -p $second &&
+ git cat-file -p $first
'
test_expect_success 'verify that notes are still present' '
- git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+ git notes show $third &&
+ git notes show $second &&
+ git notes show $first
'
test_expect_success 'prune -n does not remove notes' '
@@ -90,13 +93,10 @@ test_expect_success 'prune -n does not remove notes' '
test_cmp expect actual
'
-cat > expect <<EOF
-5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
-EOF
test_expect_success 'prune -n lists prunable notes' '
-
+ echo $third >expect &&
git notes prune -n > actual &&
test_cmp expect actual
'
@@ -109,9 +109,9 @@ test_expect_success 'prune notes' '
test_expect_success 'verify that notes are gone' '
- test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+ test_must_fail git notes show $third &&
+ git notes show $second &&
+ git notes show $first
'
test_expect_success 'remove some commits' '
@@ -121,21 +121,18 @@ test_expect_success 'remove some commits' '
git gc --prune=now
'
-cat > expect <<EOF
-08341ad9e94faa089d60fd3f523affb25c6da189
-EOF
-
test_expect_success 'prune -v notes' '
+ echo $second >expect &&
git notes prune -v > actual &&
test_cmp expect actual
'
test_expect_success 'verify that notes are gone' '
- test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- test_must_fail git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+ test_must_fail git notes show $third &&
+ test_must_fail git notes show $second &&
+ git notes show $first
'
test_done
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 80b23fd326..221b35f2df 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -64,7 +64,7 @@ test_expect_success 'rebase sets ORIG_HEAD to pre-rebase state' '
pre="$(git rev-parse --verify HEAD)" &&
git rebase master &&
test_cmp_rev "$pre" ORIG_HEAD &&
- ! test_cmp_rev "$pre" HEAD
+ test_cmp_rev ! "$pre" HEAD
'
test_expect_success 'rebase, with <onto> and <upstream> specified as :/quuxery' '
@@ -159,6 +159,12 @@ test_expect_success 'fail when upstream arg is missing and not configured' '
test_must_fail git rebase
'
+test_expect_success 'rebase works with format.useAutoBase' '
+ test_config format.useAutoBase true &&
+ git checkout topic &&
+ git rebase master
+'
+
test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' '
git checkout -b default-base master &&
git checkout -b default topic &&
@@ -295,12 +301,48 @@ test_expect_success 'rebase --am and --show-current-patch' '
echo two >>init.t &&
git commit -a -m two &&
git tag two &&
- test_must_fail git rebase --onto init HEAD^ &&
+ test_must_fail git rebase -f --onto init HEAD^ &&
GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&
grep "show.*$(git rev-parse two)" stderr
)
'
+test_expect_success 'rebase --am and .gitattributes' '
+ test_create_repo attributes &&
+ (
+ cd attributes &&
+ test_commit init &&
+ git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
+ git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
+
+ test_commit second &&
+ git checkout -b test HEAD^ &&
+
+ echo "*.txt filter=test" >.gitattributes &&
+ git add .gitattributes &&
+ test_commit third &&
+
+ echo "This text is smudged." >a.txt &&
+ git add a.txt &&
+ test_commit fourth &&
+
+ git checkout -b removal HEAD^ &&
+ git rm .gitattributes &&
+ git add -u &&
+ test_commit fifth &&
+ git cherry-pick test &&
+
+ git checkout test &&
+ git rebase master &&
+ grep "smudged" a.txt &&
+
+ git checkout removal &&
+ git reset --hard &&
+ git rebase master &&
+ grep "clean" a.txt
+ )
+'
+
test_expect_success 'rebase--merge.sh and --show-current-patch' '
test_create_repo conflict-merge &&
(
diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh
index 1f5122b632..ee8a8dba52 100755
--- a/t/t3403-rebase-skip.sh
+++ b/t/t3403-rebase-skip.sh
@@ -7,6 +7,8 @@ test_description='git rebase --merge --skip tests'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
# we assume the default git am -3 --skip strategy is tested independently
# and always works :)
@@ -20,6 +22,13 @@ test_expect_success setup '
git commit -a -m "hello world" &&
echo goodbye >> hello &&
git commit -a -m "goodbye" &&
+ git tag goodbye &&
+
+ git checkout --detach &&
+ git checkout HEAD^ . &&
+ test_tick &&
+ git commit -m reverted-goodbye &&
+ git tag reverted-goodbye &&
git checkout -f skip-reference &&
echo moo > hello &&
@@ -76,4 +85,27 @@ test_expect_success 'moved back to branch correctly' '
test_debug 'gitk --all & sleep 1'
+test_expect_success 'fixup that empties commit fails' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 fixup 2" git rebase -i \
+ goodbye^ reverted-goodbye
+ )
+'
+
+test_expect_success 'squash that empties commit fails' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 squash 2" git rebase -i \
+ goodbye^ reverted-goodbye
+ )
+'
+
+# Must be the last test in this file
+test_expect_success '$EDITOR and friends are unchanged' '
+ test_editor_unchanged
+'
+
test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 461dd539ff..b90ea0fe44 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -29,9 +29,6 @@ Initial setup:
. "$TEST_DIRECTORY"/lib-rebase.sh
-# WARNING: Modifications to the initial repository can change the SHA ID used
-# in the expect2 file for the 'stop on conflicting pick' test.
-
test_expect_success 'setup' '
test_commit A file1 &&
test_commit B file1 &&
@@ -79,8 +76,11 @@ test_expect_success 'rebase -i with empty HEAD' '
cat >expect <<-\EOF &&
error: nothing to do
EOF
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 exec_true" git rebase -i HEAD^ >actual 2>&1 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 exec_true" \
+ git rebase -i HEAD^ >actual 2>&1
+ ) &&
test_i18ncmp expect actual
'
@@ -139,8 +139,11 @@ test_expect_success 'rebase -i sets work tree properly' '
test_expect_success 'rebase -i with the exec command checks tree cleanness' '
git checkout master &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="exec_echo_foo_>file1 1" git rebase -i HEAD^ &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="exec_echo_foo_>file1 1" \
+ git rebase -i HEAD^
+ ) &&
test_cmp_rev master^ HEAD &&
git reset --hard &&
git rebase --continue
@@ -155,8 +158,6 @@ test_expect_success 'rebase -x with empty command fails' '
test_i18ncmp expected actual
'
-LF='
-'
test_expect_success 'rebase -x with newline in command fails' '
test_when_finished "git rebase --abort ||:" &&
test_must_fail env git rebase -x "a${LF}b" @ 2>actual &&
@@ -168,9 +169,11 @@ test_expect_success 'rebase -x with newline in command fails' '
test_expect_success 'rebase -i with exec of inexistent command' '
git checkout master &&
test_when_finished "git rebase --abort" &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="exec_this-command-does-not-exist 1" \
- git rebase -i HEAD^ >actual 2>&1 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="exec_this-command-does-not-exist 1" \
+ git rebase -i HEAD^ >actual 2>&1
+ ) &&
! grep "Maybe git-rebase is broken" actual
'
@@ -181,7 +184,6 @@ test_expect_success 'implicit interactive rebase does not invoke sequence editor
test_expect_success 'no changes are a nop' '
git checkout branch2 &&
- set_fake_editor &&
git rebase -i F &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&
test $(git rev-parse I) = $(git rev-parse HEAD)
@@ -191,7 +193,6 @@ test_expect_success 'test the [branch] option' '
git checkout -b dead-end &&
git rm file6 &&
git commit -m "stop here" &&
- set_fake_editor &&
git rebase -i F branch2 &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&
test $(git rev-parse I) = $(git rev-parse branch2) &&
@@ -200,7 +201,6 @@ test_expect_success 'test the [branch] option' '
test_expect_success 'test --onto <branch>' '
git checkout -b test-onto branch2 &&
- set_fake_editor &&
git rebase -i --onto branch1 F &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/test-onto" &&
test $(git rev-parse HEAD^) = $(git rev-parse branch1) &&
@@ -210,7 +210,6 @@ test_expect_success 'test --onto <branch>' '
test_expect_success 'rebase on top of a non-conflicting commit' '
git checkout branch1 &&
git tag original-branch1 &&
- set_fake_editor &&
git rebase -i branch2 &&
test file6 = $(git diff --name-only original-branch1) &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" &&
@@ -230,31 +229,35 @@ test_expect_success 'reflog for the branch shows correct finish message' '
'
test_expect_success 'exchange two commits' '
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2
+ ) &&
test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
- test G = $(git cat-file commit HEAD | sed -ne \$p)
+ test G = $(git cat-file commit HEAD | sed -ne \$p) &&
+ blob1=$(git rev-parse --short HEAD^:file1) &&
+ blob2=$(git rev-parse --short HEAD:file1) &&
+ commit=$(git rev-parse --short HEAD)
'
test_expect_success 'stop on conflicting pick' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
diff --git a/file1 b/file1
- index f70f10e..fd79235 100644
+ index $blob1..$blob2 100644
--- a/file1
+++ b/file1
@@ -1 +1 @@
-A
+G
EOF
- cat >expect2 <<-\EOF &&
+ cat >expect2 <<-EOF &&
<<<<<<< HEAD
D
=======
G
- >>>>>>> 5d18e54... G
+ >>>>>>> $commit... G
EOF
git tag new-branch1 &&
- set_fake_editor &&
test_must_fail git rebase -i master &&
test "$(git rev-parse HEAD~3)" = "$(git rev-parse master)" &&
test_cmp expect .git/rebase-merge/patch &&
@@ -283,7 +286,6 @@ test_expect_success 'abort' '
test_expect_success 'abort with error when new base cannot be checked out' '
git rm --cached file1 &&
git commit -m "remove file in base" &&
- set_fake_editor &&
test_must_fail git rebase -i master > output 2>&1 &&
test_i18ngrep "The following untracked working tree files would be overwritten by checkout:" \
output &&
@@ -298,7 +300,6 @@ test_expect_success 'retain authorship' '
test_tick &&
GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
git tag twerp &&
- set_fake_editor &&
git rebase -i --onto master HEAD^ &&
git show HEAD | grep "^Author: Twerp Snog"
'
@@ -316,7 +317,6 @@ test_expect_success 'retain authorship w/ conflicts' '
test_commit b conflict b conflict-b &&
GIT_AUTHOR_NAME=$oGIT_AUTHOR_NAME &&
- set_fake_editor &&
test_must_fail git rebase -i conflict-a &&
echo resolved >conflict &&
git add conflict &&
@@ -332,9 +332,11 @@ test_expect_success 'squash' '
test_tick &&
GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 &&
echo "******************************" &&
- set_fake_editor &&
- FAKE_LINES="1 squash 2" EXPECT_HEADER_COUNT=2 \
- git rebase -i --onto master HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 squash 2" EXPECT_HEADER_COUNT=2 \
+ git rebase -i --onto master HEAD~2
+ ) &&
test B = $(cat file7) &&
test $(git rev-parse HEAD^) = $(git rev-parse master)
'
@@ -345,7 +347,6 @@ test_expect_success 'retain authorship when squashing' '
test_expect_success REBASE_P '-p handles "no changes" gracefully' '
HEAD=$(git rev-parse HEAD) &&
- set_fake_editor &&
git rebase -i -p HEAD^ &&
git update-index --refresh &&
git diff-files --quiet &&
@@ -355,8 +356,10 @@ test_expect_success REBASE_P '-p handles "no changes" gracefully' '
test_expect_failure REBASE_P 'exchange two commits with -p' '
git checkout H &&
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i -p HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i -p HEAD~2
+ ) &&
test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test G = $(git cat-file commit HEAD | sed -ne \$p)
'
@@ -390,7 +393,6 @@ test_expect_success REBASE_P 'preserve merges with -p' '
git commit -m M file1 &&
git checkout -b to-be-rebased &&
test_tick &&
- set_fake_editor &&
git rebase -i -p --onto branch1 master &&
git update-index --refresh &&
git diff-files --quiet &&
@@ -405,8 +407,10 @@ test_expect_success REBASE_P 'preserve merges with -p' '
'
test_expect_success REBASE_P 'edit ancestor with -p' '
- set_fake_editor &&
- FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3
+ ) &&
echo 2 > unrelated-file &&
test_tick &&
git commit -m L2-modified --amend unrelated-file &&
@@ -420,11 +424,13 @@ test_expect_success REBASE_P 'edit ancestor with -p' '
test_expect_success '--continue tries to commit' '
git reset --hard D &&
test_tick &&
- set_fake_editor &&
- test_must_fail git rebase -i --onto new-branch1 HEAD^ &&
- echo resolved > file1 &&
- git add file1 &&
- FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail git rebase -i --onto new-branch1 HEAD^ &&
+ echo resolved > file1 &&
+ git add file1 &&
+ FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue
+ ) &&
test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&
git show HEAD | grep chouette
'
@@ -432,7 +438,6 @@ test_expect_success '--continue tries to commit' '
test_expect_success 'verbose flag is heeded, even after --continue' '
git reset --hard master@{1} &&
test_tick &&
- set_fake_editor &&
test_must_fail git rebase -v -i --onto new-branch1 HEAD^ &&
echo resolved > file1 &&
git add file1 &&
@@ -442,10 +447,13 @@ test_expect_success 'verbose flag is heeded, even after --continue' '
test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 squash 2 squash 3 squash 4" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="1 squash 2 squash 3 squash 4" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l)
'
@@ -453,9 +461,12 @@ test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '
git checkout -b multi-fixup E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="NEVER" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="NEVER" \
+ FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 0 = $(git show | grep NEVER | wc -l) &&
git checkout @{-1} &&
@@ -465,12 +476,15 @@ test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '
test_expect_success 'commit message used after conflict' '
git checkout -b conflict-fixup conflict-branch &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 fixup 3 fixup 4" git rebase -i $base &&
- echo three > conflict &&
- git add conflict &&
- FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \
- git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 fixup 3 fixup 4" \
+ git rebase -i $base &&
+ echo three > conflict &&
+ git add conflict &&
+ FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \
+ git rebase --continue
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
git checkout @{-1} &&
@@ -480,12 +494,15 @@ test_expect_success 'commit message used after conflict' '
test_expect_success 'commit message retained after conflict' '
git checkout -b conflict-squash conflict-branch &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 fixup 3 squash 4" git rebase -i $base &&
- echo three > conflict &&
- git add conflict &&
- FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \
- git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 fixup 3 squash 4" \
+ git rebase -i $base &&
+ echo three > conflict &&
+ git add conflict &&
+ FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \
+ git rebase --continue
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 2 = $(git show | grep TWICE | wc -l) &&
git checkout @{-1} &&
@@ -502,10 +519,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa
EOF
git checkout -b squash-fixup E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 squash 3 fixup 4" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="1 fixup 2 squash 3 fixup 4" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup &&
test_cmp expect-squash-fixup actual-squash-fixup &&
git cat-file commit HEAD@{2} |
@@ -519,10 +539,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa
test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
git checkout -b skip-comments E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
git checkout @{-1} &&
@@ -532,10 +555,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '
git checkout -b skip-blank-lines E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
git checkout @{-1} &&
@@ -545,17 +571,21 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '
test_expect_success 'squash works as expected' '
git checkout -b squash-works no-conflict-branch &&
one=$(git rev-parse HEAD~3) &&
- set_fake_editor &&
- FAKE_LINES="1 s 3 2" EXPECT_HEADER_COUNT=2 \
- git rebase -i HEAD~3 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 s 3 2" EXPECT_HEADER_COUNT=2 git rebase -i HEAD~3
+ ) &&
test $one = $(git rev-parse HEAD~2)
'
test_expect_success 'interrupted squash works as expected' '
git checkout -b interrupted-squash conflict-branch &&
one=$(git rev-parse HEAD~3) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 squash 3 2" git rebase -i HEAD~3 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 squash 3 2" \
+ git rebase -i HEAD~3
+ ) &&
test_write_lines one two four > conflict &&
git add conflict &&
test_must_fail git rebase --continue &&
@@ -568,8 +598,11 @@ test_expect_success 'interrupted squash works as expected' '
test_expect_success 'interrupted squash works as expected (case 2)' '
git checkout -b interrupted-squash2 conflict-branch &&
one=$(git rev-parse HEAD~3) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="3 squash 1 2" git rebase -i HEAD~3 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="3 squash 1 2" \
+ git rebase -i HEAD~3
+ ) &&
test_write_lines one four > conflict &&
git add conflict &&
test_must_fail git rebase --continue &&
@@ -589,11 +622,13 @@ test_expect_success '--continue tries to commit, even for "edit"' '
git commit -m "unrelated change" &&
parent=$(git rev-parse HEAD^) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i HEAD^ &&
- echo edited > file7 &&
- git add file7 &&
- FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+ echo edited > file7 &&
+ git add file7 &&
+ FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue
+ ) &&
test edited = $(git show HEAD:file7) &&
git show HEAD | grep chouette &&
test $parent = $(git rev-parse HEAD^)
@@ -602,34 +637,41 @@ test_expect_success '--continue tries to commit, even for "edit"' '
test_expect_success 'aborted --continue does not squash commits after "edit"' '
old=$(git rev-parse HEAD) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i HEAD^ &&
- echo "edited again" > file7 &&
- git add file7 &&
- test_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+ echo "edited again" > file7 &&
+ git add file7 &&
+ test_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue
+ ) &&
test $old = $(git rev-parse HEAD) &&
git rebase --abort
'
test_expect_success 'auto-amend only edited commits after "edit"' '
test_tick &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i HEAD^ &&
- echo "edited again" > file7 &&
- git add file7 &&
- FAKE_COMMIT_MESSAGE="edited file7 again" git commit &&
- echo "and again" > file7 &&
- git add file7 &&
- test_tick &&
- test_must_fail env FAKE_COMMIT_MESSAGE="and again" git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+ echo "edited again" > file7 &&
+ git add file7 &&
+ FAKE_COMMIT_MESSAGE="edited file7 again" git commit &&
+ echo "and again" > file7 &&
+ git add file7 &&
+ test_tick &&
+ test_must_fail env FAKE_COMMIT_MESSAGE="and again" \
+ git rebase --continue
+ ) &&
git rebase --abort
'
test_expect_success 'clean error after failed "exec"' '
test_tick &&
test_when_finished "git rebase --abort || :" &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 exec_false" git rebase -i HEAD^ &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 exec_false" git rebase -i HEAD^
+ ) &&
echo "edited again" > file7 &&
git add file7 &&
test_must_fail git rebase --continue 2>error &&
@@ -640,8 +682,10 @@ test_expect_success 'rebase a detached HEAD' '
grandparent=$(git rev-parse HEAD~2) &&
git checkout $(git rev-parse HEAD) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2
+ ) &&
test $grandparent = $(git rev-parse HEAD~2)
'
@@ -656,9 +700,10 @@ test_expect_success 'rebase a commit violating pre-commit' '
test_must_fail git commit -m doesnt-verify file1 &&
git commit -m doesnt-verify --no-verify file1 &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES=2 git rebase -i HEAD~2
-
+ (
+ set_fake_editor &&
+ FAKE_LINES=2 git rebase -i HEAD~2
+ )
'
test_expect_success 'rebase with a file named HEAD in worktree' '
@@ -678,8 +723,10 @@ test_expect_success 'rebase with a file named HEAD in worktree' '
git commit -m "Add body"
) &&
- set_fake_editor &&
- FAKE_LINES="1 squash 2" git rebase -i @{-1} &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 squash 2" git rebase -i @{-1}
+ ) &&
test "$(git show -s --pretty=format:%an)" = "Squashed Away"
'
@@ -690,7 +737,6 @@ test_expect_success 'do "noop" when there is nothing to cherry-pick' '
GIT_EDITOR=: git commit --amend \
--author="Somebody else <somebody@else.com>" &&
test $(git rev-parse branch3) != $(git rev-parse branch4) &&
- set_fake_editor &&
git rebase -i branch3 &&
test $(git rev-parse branch3) = $(git rev-parse branch4)
@@ -715,13 +761,14 @@ test_expect_success 'submodule rebase setup' '
git commit -a -m "submodule second"
) &&
test_tick &&
- set_fake_editor &&
git commit -a -m "Three changes submodule"
'
test_expect_success 'submodule rebase -i' '
- set_fake_editor &&
- FAKE_LINES="1 squash 2 3" git rebase -i A
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 squash 2 3" git rebase -i A
+ )
'
test_expect_success 'submodule conflict setup' '
@@ -738,7 +785,6 @@ test_expect_success 'submodule conflict setup' '
'
test_expect_success 'rebase -i continue with only submodule staged' '
- set_fake_editor &&
test_must_fail git rebase -i submodule-base &&
git add sub &&
git rebase --continue &&
@@ -748,7 +794,6 @@ test_expect_success 'rebase -i continue with only submodule staged' '
test_expect_success 'rebase -i continue with unstaged submodule' '
git checkout submodule-topic &&
git reset --hard &&
- set_fake_editor &&
test_must_fail git rebase -i submodule-base &&
git reset &&
git rebase --continue &&
@@ -761,7 +806,6 @@ test_expect_success 'avoid unnecessary reset' '
test-tool chmtime =123456789 file3 &&
git update-index --refresh &&
HEAD=$(git rev-parse HEAD) &&
- set_fake_editor &&
git rebase -i HEAD~4 &&
test $HEAD = $(git rev-parse HEAD) &&
MTIME=$(test-tool chmtime --get file3) &&
@@ -770,16 +814,22 @@ test_expect_success 'avoid unnecessary reset' '
test_expect_success 'reword' '
git checkout -b reword-branch master &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" git rebase -i A &&
- git show HEAD | grep "E changed" &&
- test $(git rev-parse master) != $(git rev-parse HEAD) &&
- test $(git rev-parse master^) = $(git rev-parse HEAD^) &&
- FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" git rebase -i A &&
- git show HEAD^ | grep "D changed" &&
- FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" git rebase -i A &&
- git show HEAD~3 | grep "B changed" &&
- FAKE_LINES="1 r 2 pick 3 p 4" FAKE_COMMIT_MESSAGE="C changed" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" \
+ git rebase -i A &&
+ git show HEAD | grep "E changed" &&
+ test $(git rev-parse master) != $(git rev-parse HEAD) &&
+ test $(git rev-parse master^) = $(git rev-parse HEAD^) &&
+ FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" \
+ git rebase -i A &&
+ git show HEAD^ | grep "D changed" &&
+ FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" \
+ git rebase -i A &&
+ git show HEAD~3 | grep "B changed" &&
+ FAKE_LINES="1 r 2 pick 3 p 4" FAKE_COMMIT_MESSAGE="C changed" \
+ git rebase -i A
+ ) &&
git show HEAD~2 | grep "C changed"
'
@@ -790,7 +840,6 @@ test_expect_success 'rebase -i can copy notes' '
test_commit n2 &&
test_commit n3 &&
git notes add -m"a note" n3 &&
- set_fake_editor &&
git rebase -i --onto n1 n2 &&
test "a note" = "$(git notes show HEAD)"
'
@@ -803,8 +852,11 @@ test_expect_success 'rebase -i can copy notes over a fixup' '
EOF
git reset --hard n3 &&
git notes add -m"an earlier note" n2 &&
- set_fake_editor &&
- GIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES="1 f 2" git rebase -i n1 &&
+ (
+ set_fake_editor &&
+ GIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES="1 f 2" \
+ git rebase -i n1
+ ) &&
git notes show > output &&
test_cmp expect output
'
@@ -813,8 +865,10 @@ test_expect_success 'rebase while detaching HEAD' '
git symbolic-ref HEAD &&
grandparent=$(git rev-parse HEAD~2) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0
+ ) &&
test $grandparent = $(git rev-parse HEAD~2) &&
test_must_fail git symbolic-ref HEAD
'
@@ -823,7 +877,6 @@ test_tick # Ensure that the rebased commits get a different timestamp.
test_expect_success 'always cherry-pick with --no-ff' '
git checkout no-ff-branch &&
git tag original-no-ff-branch &&
- set_fake_editor &&
git rebase -i --no-ff A &&
for p in 0 1 2
do
@@ -855,8 +908,10 @@ test_expect_success 'set up commits with funny messages' '
test_expect_success 'rebase-i history with funny messages' '
git rev-list A..funny >expect &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 4" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 4" git rebase -i A
+ ) &&
git rev-list A.. >actual &&
test_cmp expect actual
'
@@ -870,9 +925,9 @@ test_expect_success 'prepare for rebase -i --exec' '
'
test_expect_success 'running "git rebase -i --exec git show HEAD"' '
- set_fake_editor &&
- git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -883,9 +938,9 @@ test_expect_success 'running "git rebase -i --exec git show HEAD"' '
test_expect_success 'running "git rebase --exec git show HEAD -i"' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -896,9 +951,9 @@ test_expect_success 'running "git rebase --exec git show HEAD -i"' '
test_expect_success 'running "git rebase -ix git show HEAD"' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase -ix "git show HEAD" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -ix "git show HEAD" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -910,9 +965,9 @@ test_expect_success 'running "git rebase -ix git show HEAD"' '
test_expect_success 'rebase -ix with several <CMD>' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -923,9 +978,9 @@ test_expect_success 'rebase -ix with several <CMD>' '
test_expect_success 'rebase -ix with several instances of --exec' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
exec_git_show_HEAD exec_pwd" &&
export FAKE_LINES &&
@@ -944,13 +999,11 @@ test_expect_success C_LOCALE_OUTPUT 'rebase -ix with --autosquash' '
echo bis >bis.txt &&
git add bis.txt &&
git commit -m "fixup! two_exec" &&
- set_fake_editor &&
- (
- git checkout -b autosquash_actual &&
- git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
- ) &&
+ git checkout -b autosquash_actual &&
+ git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual &&
git checkout autosquash &&
(
+ set_fake_editor &&
git checkout -b autosquash_expected &&
FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
@@ -971,7 +1024,6 @@ test_expect_success 'rebase --exec works without -i ' '
test_expect_success 'rebase -i --exec without <CMD>' '
git reset --hard execute &&
- set_fake_editor &&
test_must_fail git rebase -i --exec 2>actual &&
test_i18ngrep "requires a value" actual &&
git checkout master
@@ -979,8 +1031,10 @@ test_expect_success 'rebase -i --exec without <CMD>' '
test_expect_success 'rebase -i --root re-order and drop commits' '
git checkout E &&
- set_fake_editor &&
- FAKE_LINES="3 1 2 5" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="3 1 2 5" git rebase -i --root
+ ) &&
test E = $(git cat-file commit HEAD | sed -ne \$p) &&
test B = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test A = $(git cat-file commit HEAD^^ | sed -ne \$p) &&
@@ -993,39 +1047,59 @@ test_expect_success 'rebase -i --root retain root commit author and message' '
echo B >file7 &&
git add file7 &&
GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
- set_fake_editor &&
- FAKE_LINES="2" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2" git rebase -i --root
+ ) &&
git cat-file commit HEAD | grep -q "^author Twerp Snog" &&
git cat-file commit HEAD | grep -q "^different author$"
'
test_expect_success 'rebase -i --root temporary sentinel commit' '
git checkout B &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="2" git rebase -i --root &&
- git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="2" git rebase -i --root
+ ) &&
+ git cat-file commit HEAD | grep "^tree $EMPTY_TREE" &&
git rebase --abort
'
test_expect_success 'rebase -i --root fixup root commit' '
git checkout B &&
- set_fake_editor &&
- FAKE_LINES="1 fixup 2" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 fixup 2" git rebase -i --root
+ ) &&
test A = $(git cat-file commit HEAD | sed -ne \$p) &&
test B = $(git show HEAD:file1) &&
test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
'
-test_expect_success 'rebase -i --root reword root commit' '
+test_expect_success 'rebase -i --root reword original root commit' '
test_when_finished "test_might_fail git rebase --abort" &&
- git checkout -b reword-root-branch master &&
- set_fake_editor &&
- FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
- git rebase -i --root &&
+ git checkout -b reword-original-root-branch master &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
+ git rebase -i --root
+ ) &&
git show HEAD^ | grep "A changed" &&
test -z "$(git show -s --format=%p HEAD^)"
'
+test_expect_success 'rebase -i --root reword new root commit' '
+ test_when_finished "test_might_fail git rebase --abort" &&
+ git checkout -b reword-now-root-branch master &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="reword 3 1" FAKE_COMMIT_MESSAGE="C changed" \
+ git rebase -i --root
+ ) &&
+ git show HEAD^ | grep "C changed" &&
+ test -z "$(git show -s --format=%p HEAD^)"
+'
+
test_expect_success 'rebase -i --root when root has untracked file conflict' '
test_when_finished "reset_rebase" &&
git checkout -b failing-root-pick A &&
@@ -1033,8 +1107,10 @@ test_expect_success 'rebase -i --root when root has untracked file conflict' '
git rm file1 &&
git commit -m "remove file 1 add file 2" &&
echo z >file1 &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2" git rebase -i --root
+ ) &&
rm file1 &&
git rebase --continue &&
test "$(git log -1 --format=%B)" = "remove file 1 add file 2" &&
@@ -1044,32 +1120,38 @@ test_expect_success 'rebase -i --root when root has untracked file conflict' '
test_expect_success 'rebase -i --root reword root when root has untracked file conflict' '
test_when_finished "reset_rebase" &&
echo z>file1 &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="reword 1 2" \
- FAKE_COMMIT_MESSAGE="Modified A" git rebase -i --root &&
- rm file1 &&
- FAKE_COMMIT_MESSAGE="Reworded A" git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="reword 1 2" \
+ FAKE_COMMIT_MESSAGE="Modified A" git rebase -i --root &&
+ rm file1 &&
+ FAKE_COMMIT_MESSAGE="Reworded A" git rebase --continue
+ ) &&
test "$(git log -1 --format=%B HEAD^)" = "Reworded A" &&
test "$(git rev-list --count HEAD)" = 2
'
test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' '
- git checkout reword-root-branch &&
+ git checkout reword-original-root-branch &&
git reset --hard &&
git checkout conflict-branch &&
- set_fake_editor &&
- test_must_fail git rebase --onto HEAD~2 HEAD~ &&
- test_must_fail git rebase --edit-todo &&
+ (
+ set_fake_editor &&
+ test_must_fail git rebase -f --onto HEAD~2 HEAD~ &&
+ test_must_fail git rebase --edit-todo
+ ) &&
git rebase --abort
'
test_expect_success 'rebase --edit-todo can be used to modify todo' '
git reset --hard &&
git checkout no-conflict-branch^0 &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2 3" git rebase -i HEAD~3 &&
- FAKE_LINES="2 1" git rebase --edit-todo &&
- git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2 3" git rebase -i HEAD~3 &&
+ FAKE_LINES="2 1" git rebase --edit-todo &&
+ git rebase --continue
+ ) &&
test M = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test L = $(git cat-file commit HEAD | sed -ne \$p)
'
@@ -1077,7 +1159,6 @@ test_expect_success 'rebase --edit-todo can be used to modify todo' '
test_expect_success 'rebase -i produces readable reflog' '
git reset --hard &&
git branch -f branch-reflog-test H &&
- set_fake_editor &&
git rebase -i --onto I F branch-reflog-test &&
cat >expect <<-\EOF &&
rebase -i (finish): returning to refs/heads/branch-reflog-test
@@ -1098,8 +1179,10 @@ test_expect_success 'rebase -i respects core.commentchar' '
sed -e "2,\$s/^/\\\\/" "$1" >"$1.tmp" &&
mv "$1.tmp" "$1"
EOF
- test_set_editor "$(pwd)/remove-all-but-first.sh" &&
- git rebase -i B &&
+ (
+ test_set_editor "$(pwd)/remove-all-but-first.sh" &&
+ git rebase -i B
+ ) &&
test B = $(git cat-file commit HEAD^ | sed -ne \$p)
'
@@ -1108,9 +1191,11 @@ test_expect_success 'rebase -i respects core.commentchar=auto' '
write_script copy-edit-script.sh <<-\EOF &&
cp "$1" edit-script
EOF
- test_set_editor "$(pwd)/copy-edit-script.sh" &&
test_when_finished "git rebase --abort || :" &&
- git rebase -i HEAD^ &&
+ (
+ test_set_editor "$(pwd)/copy-edit-script.sh" &&
+ git rebase -i HEAD^
+ ) &&
test -z "$(grep -ve "^#" -e "^\$" -e "^pick" edit-script)"
'
@@ -1145,8 +1230,11 @@ test_expect_success 'interrupted rebase -i with --strategy and -X' '
echo five >conflict &&
echo Z >file1 &&
git commit -a -m "one file conflict" &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2" git rebase -i --strategy=recursive -Xours conflict-branch &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2" git rebase -i --strategy=recursive \
+ -Xours conflict-branch
+ ) &&
git rebase --continue &&
test $(git show conflict-branch:conflict) = $(cat conflict) &&
test $(cat file1) = Z
@@ -1161,7 +1249,7 @@ test_expect_success 'rebase -i error on commits with \ in message' '
test_expect_code 1 grep " emp" error
'
-test_expect_success 'short SHA-1 setup' '
+test_expect_success SHA1 'short SHA-1 setup' '
test_when_finished "git checkout master" &&
git checkout --orphan collide &&
git rm -rf . &&
@@ -1173,22 +1261,37 @@ test_expect_success 'short SHA-1 setup' '
)
'
-test_expect_success 'short SHA-1 collide' '
+test_expect_success SHA1 'short SHA-1 collide' '
test_when_finished "reset_rebase && git checkout master" &&
git checkout collide &&
+ colliding_sha1=6bcda37 &&
+ test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" &&
(
- unset test_tick &&
- test_tick &&
- set_fake_editor &&
- FAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \
- FAKE_LINES="reword 1 2" git rebase -i HEAD~2
- )
+ unset test_tick &&
+ test_tick &&
+ set_fake_editor &&
+ FAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \
+ FAKE_LINES="reword 1 break 2" git rebase -i HEAD~2 &&
+ test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" &&
+ grep "^pick $colliding_sha1 " \
+ .git/rebase-merge/git-rebase-todo.tmp &&
+ grep "^pick [0-9a-f]\{40\}" \
+ .git/rebase-merge/git-rebase-todo &&
+ grep "^pick [0-9a-f]\{40\}" \
+ .git/rebase-merge/git-rebase-todo.backup &&
+ git rebase --continue
+ ) &&
+ collide2="$(git rev-parse HEAD~1 | cut -c 1-4)" &&
+ collide3="$(git rev-parse collide3 | cut -c 1-4)" &&
+ test "$collide2" = "$collide3"
'
test_expect_success 'respect core.abbrev' '
git config core.abbrev 12 &&
- set_cat_todo_editor &&
- test_must_fail git rebase -i HEAD~4 >todo-list &&
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase -i HEAD~4 >todo-list
+ ) &&
test 4 = $(grep -c "pick [0-9a-f]\{12,\}" todo-list)
'
@@ -1196,16 +1299,20 @@ test_expect_success 'todo count' '
write_script dump-raw.sh <<-\EOF &&
cat "$1"
EOF
- test_set_editor "$(pwd)/dump-raw.sh" &&
- git rebase -i HEAD~4 >actual &&
+ (
+ test_set_editor "$(pwd)/dump-raw.sh" &&
+ git rebase -i HEAD~4 >actual
+ ) &&
test_i18ngrep "^# Rebase ..* onto ..* ([0-9]" actual
'
test_expect_success 'rebase -i commits that overwrite untracked files (pick)' '
git checkout --force branch2 &&
git clean -f &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2" git rebase -i A
+ ) &&
test_cmp_rev HEAD F &&
test_path_is_missing file6 &&
>file6 &&
@@ -1220,8 +1327,10 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)'
git checkout --force branch2 &&
git clean -f &&
git tag original-branch2 &&
- set_fake_editor &&
- FAKE_LINES="edit 1 squash 2" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 squash 2" git rebase -i A
+ ) &&
test_cmp_rev HEAD F &&
test_path_is_missing file6 &&
>file6 &&
@@ -1236,8 +1345,10 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)'
test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' '
git checkout --force branch2 &&
git clean -f &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2" git rebase -i --no-ff A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2" git rebase -i --no-ff A
+ ) &&
test $(git cat-file commit HEAD | sed -ne \$p) = F &&
test_path_is_missing file6 &&
>file6 &&
@@ -1260,8 +1371,10 @@ test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' '
git tag seq-onto &&
git reset --hard HEAD~2 &&
git cherry-pick seq-onto &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES= git rebase -i seq-onto &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES= git rebase -i seq-onto
+ ) &&
test -d .git/rebase-merge &&
git rebase --continue &&
git diff --exit-code seq-onto &&
@@ -1280,8 +1393,10 @@ rebase_setup_and_clean () {
test_expect_success 'drop' '
rebase_setup_and_clean drop-test &&
- set_fake_editor &&
- FAKE_LINES="1 drop 2 3 d 4 5" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 drop 2 3 d 4 5" git rebase -i --root
+ ) &&
test E = $(git cat-file commit HEAD | sed -ne \$p) &&
test C = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test A = $(git cat-file commit HEAD^^ | sed -ne \$p)
@@ -1290,9 +1405,10 @@ test_expect_success 'drop' '
test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '
test_config rebase.missingCommitsCheck ignore &&
rebase_setup_and_clean missing-commit &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 4" \
- git rebase -i --root 2>actual &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 4" git rebase -i --root 2>actual
+ ) &&
test D = $(git cat-file commit HEAD | sed -ne \$p) &&
test_i18ngrep \
"Successfully rebased and updated refs/heads/missing-commit" \
@@ -1308,9 +1424,10 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' '
EOF
test_config rebase.missingCommitsCheck warn &&
rebase_setup_and_clean missing-commit &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 4" \
- git rebase -i --root 2>actual.2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 4" git rebase -i --root 2>actual.2
+ ) &&
head -n4 actual.2 >actual &&
test_i18ncmp expect actual &&
test D = $(git cat-file commit HEAD | sed -ne \$p)
@@ -1332,14 +1449,15 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '
EOF
test_config rebase.missingCommitsCheck error &&
rebase_setup_and_clean missing-commit &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2 4" \
- git rebase -i --root 2>actual &&
- test_i18ncmp expect actual &&
- cp .git/rebase-merge/git-rebase-todo.backup \
- .git/rebase-merge/git-rebase-todo &&
- FAKE_LINES="1 2 drop 3 4 drop 5" \
- git rebase --edit-todo &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 4" \
+ git rebase -i --root 2>actual &&
+ test_i18ncmp expect actual &&
+ cp .git/rebase-merge/git-rebase-todo.backup \
+ .git/rebase-merge/git-rebase-todo &&
+ FAKE_LINES="1 2 drop 3 4 drop 5" git rebase --edit-todo
+ ) &&
git rebase --continue &&
test D = $(git cat-file commit HEAD | sed -ne \$p) &&
test B = $(git cat-file commit HEAD^ | sed -ne \$p)
@@ -1360,21 +1478,27 @@ test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and e
x git show HEAD
EOF
git checkout abbrevcmd &&
- set_cat_todo_editor &&
test_config rebase.abbreviateCommands true &&
- test_must_fail git rebase -i --exec "git show HEAD" \
- --autosquash master >actual &&
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase -i --exec "git show HEAD" \
+ --autosquash master >actual
+ ) &&
test_cmp expected actual
'
test_expect_success 'static check of bad command' '
rebase_setup_and_clean bad-cmd &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \
git rebase -i --root 2>actual &&
- test_i18ngrep "badcmd $(git rev-list --oneline -1 master~1)" actual &&
- test_i18ngrep "You can fix this with .git rebase --edit-todo.." actual &&
- FAKE_LINES="1 2 3 drop 4 5" git rebase --edit-todo &&
+ test_i18ngrep "badcmd $(git rev-list --oneline -1 master~1)" \
+ actual &&
+ test_i18ngrep "You can fix this with .git rebase --edit-todo.." \
+ actual &&
+ FAKE_LINES="1 2 3 drop 4 5" git rebase --edit-todo
+ ) &&
git rebase --continue &&
test E = $(git cat-file commit HEAD | sed -ne \$p) &&
test C = $(git cat-file commit HEAD^ | sed -ne \$p)
@@ -1390,19 +1514,24 @@ test_expect_success 'tabs and spaces are accepted in the todolist' '
) >"$1.new"
mv "$1.new" "$1"
EOF
- test_set_editor "$(pwd)/add-indent.sh" &&
- git rebase -i HEAD^^^ &&
+ (
+ test_set_editor "$(pwd)/add-indent.sh" &&
+ git rebase -i HEAD^^^
+ ) &&
test E = $(git cat-file commit HEAD | sed -ne \$p)
'
test_expect_success 'static check of bad SHA-1' '
rebase_setup_and_clean bad-sha &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2 edit fakesha 3 4 5 #" \
- git rebase -i --root 2>actual &&
- test_i18ngrep "edit XXXXXXX False commit" actual &&
- test_i18ngrep "You can fix this with .git rebase --edit-todo.." actual &&
- FAKE_LINES="1 2 4 5 6" git rebase --edit-todo &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 edit fakesha 3 4 5 #" \
+ git rebase -i --root 2>actual &&
+ test_i18ngrep "edit XXXXXXX False commit" actual &&
+ test_i18ngrep "You can fix this with .git rebase --edit-todo.." \
+ actual &&
+ FAKE_LINES="1 2 4 5 6" git rebase --edit-todo
+ ) &&
git rebase --continue &&
test E = $(git cat-file commit HEAD | sed -ne \$p)
'
@@ -1419,42 +1548,73 @@ test_expect_success 'editor saves as CR/LF' '
)
'
-SQ="'"
test_expect_success 'rebase -i --gpg-sign=<key-id>' '
test_when_finished "test_might_fail git rebase --abort" &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" HEAD^ \
- >out 2>err &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" \
+ HEAD^ >out 2>err
+ ) &&
test_i18ngrep "$SQ-S\"S I Gner\"$SQ" err
'
test_expect_success 'rebase -i --gpg-sign=<key-id> overrides commit.gpgSign' '
test_when_finished "test_might_fail git rebase --abort" &&
test_config commit.gpgsign true &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" HEAD^ \
- >out 2>err &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" \
+ HEAD^ >out 2>err
+ ) &&
test_i18ngrep "$SQ-S\"S I Gner\"$SQ" err
'
test_expect_success 'valid author header after --root swap' '
rebase_setup_and_clean author-header no-conflict-branch &&
- set_fake_editor &&
git commit --amend --author="Au ${SQ}thor <author@example.com>" --no-edit &&
git cat-file commit HEAD | grep ^author >expected &&
- FAKE_LINES="5 1" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="5 1" git rebase -i --root
+ ) &&
git cat-file commit HEAD^ | grep ^author >actual &&
test_cmp expected actual
'
test_expect_success 'valid author header when author contains single quote' '
rebase_setup_and_clean author-header no-conflict-branch &&
- set_fake_editor &&
git commit --amend --author="Au ${SQ}thor <author@example.com>" --no-edit &&
git cat-file commit HEAD | grep ^author >expected &&
- FAKE_LINES="2" git rebase -i HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2" git rebase -i HEAD~2
+ ) &&
git cat-file commit HEAD | grep ^author >actual &&
test_cmp expected actual
'
+test_expect_success 'post-commit hook is called' '
+ test_when_finished "rm -f .git/hooks/post-commit" &&
+ >actual &&
+ mkdir -p .git/hooks &&
+ write_script .git/hooks/post-commit <<-\EOS &&
+ git rev-parse HEAD >>actual
+ EOS
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 4 1 reword 2 fixup 3" git rebase -i A E &&
+ echo x>file3 &&
+ git add file3 &&
+ FAKE_COMMIT_MESSAGE=edited git rebase --continue
+ ) &&
+ git rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \
+ >expect &&
+ test_cmp expect actual
+'
+
+# This must be the last test in this file
+test_expect_success '$EDITOR and friends are unchanged' '
+ test_editor_unchanged
+'
+
test_done
diff --git a/t/t3416-rebase-onto-threedots.sh b/t/t3416-rebase-onto-threedots.sh
index ddf2f64853..9c2548423b 100755
--- a/t/t3416-rebase-onto-threedots.sh
+++ b/t/t3416-rebase-onto-threedots.sh
@@ -99,7 +99,64 @@ test_expect_success 'rebase -i --onto master...side' '
git checkout side &&
git reset --hard K &&
+ set_fake_editor &&
test_must_fail git rebase -i --onto master...side J
'
+test_expect_success 'rebase --keep-base --onto incompatible' '
+ test_must_fail git rebase --keep-base --onto master...
+'
+
+test_expect_success 'rebase --keep-base --root incompatible' '
+ test_must_fail git rebase --keep-base --root
+'
+
+test_expect_success 'rebase --keep-base master from topic' '
+ git reset --hard &&
+ git checkout topic &&
+ git reset --hard G &&
+
+ git rebase --keep-base master &&
+ git rev-parse C >base.expect &&
+ git merge-base master HEAD >base.actual &&
+ test_cmp base.expect base.actual &&
+
+ git rev-parse HEAD~2 >actual &&
+ git rev-parse C^0 >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --keep-base master from side' '
+ git reset --hard &&
+ git checkout side &&
+ git reset --hard K &&
+
+ test_must_fail git rebase --keep-base master
+'
+
+test_expect_success 'rebase -i --keep-base master from topic' '
+ git reset --hard &&
+ git checkout topic &&
+ git reset --hard G &&
+
+ set_fake_editor &&
+ EXPECT_COUNT=2 git rebase -i --keep-base master &&
+ git rev-parse C >base.expect &&
+ git merge-base master HEAD >base.actual &&
+ test_cmp base.expect base.actual &&
+
+ git rev-parse HEAD~2 >actual &&
+ git rev-parse C^0 >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase -i --keep-base master from side' '
+ git reset --hard &&
+ git checkout side &&
+ git reset --hard K &&
+
+ set_fake_editor &&
+ test_must_fail git rebase -i --keep-base master
+'
+
test_done
diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
index 4eff14dae5..7a2da972fd 100755
--- a/t/t3418-rebase-continue.sh
+++ b/t/t3418-rebase-continue.sh
@@ -120,6 +120,20 @@ test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '
git rebase --continue
'
+test_expect_success 'rebase -r passes merge strategy options correctly' '
+ rm -fr .git/rebase-* &&
+ git reset --hard commit-new-file-F3-on-topic-branch &&
+ test_commit merge-theirs &&
+ git reset --hard HEAD^ &&
+ test_commit some-other-commit &&
+ test_tick &&
+ git merge --no-ff merge-theirs &&
+ FAKE_LINES="1 3 edit 4 5 7 8 9" git rebase -i -f -r -m \
+ -s recursive --strategy-option=theirs HEAD~2 &&
+ test_commit force-change-ours &&
+ git rebase --continue
+'
+
test_expect_success '--skip after failed fixup cleans commit message' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout -b with-conflicting-fixup &&
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index b8f4d03467..5f7e73cf83 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -37,7 +37,6 @@ test_expect_success setup '
create_expected_success_am () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
First, rewinding head to replay your work on top of it...
Applying: second commit
Applying: third commit
@@ -48,7 +47,6 @@ create_expected_success_am () {
create_expected_success_interactive () {
q_to_cr >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
Applied autostash.
Successfully rebased and updated refs/heads/rebased-feature-branch.
EOF
@@ -57,7 +55,6 @@ create_expected_success_interactive () {
create_expected_failure_am () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
First, rewinding head to replay your work on top of it...
Applying: second commit
Applying: third commit
@@ -70,7 +67,6 @@ create_expected_failure_am () {
create_expected_failure_interactive () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
Applying autostash resulted in conflicts.
Your changes are safe in the stash.
You can run "git stash pop" or "git stash drop" at any time.
@@ -306,4 +302,12 @@ test_expect_success 'branch is left alone when possible' '
test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
'
+test_expect_success 'never change active branch' '
+ git checkout -b not-the-feature-branch unrelated-onto-branch &&
+ test_when_finished "git reset --hard && git checkout master" &&
+ echo changed >file0 &&
+ git rebase --autostash not-the-feature-branch feature-branch &&
+ test_cmp_rev not-the-feature-branch unrelated-onto-branch
+'
+
test_done
diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh
index 7274dca40b..325072b0a3 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -31,6 +31,16 @@ test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
+test_expect_success 'setup branches and remote tracking' '
+ git tag -l >tags &&
+ for tag in $(cat tags)
+ do
+ git branch branch-$tag $tag || return 1
+ done &&
+ git remote add origin "file://$PWD" &&
+ git fetch origin
+'
+
test_run_rebase () {
result=$1
shift
@@ -51,12 +61,13 @@ test_run_rebase () {
test_expect_$result "rebase $* -f rewrites even if upstream is an ancestor" "
reset_rebase &&
git rebase $* -f b e &&
- ! test_cmp_rev e HEAD &&
+ test_cmp_rev ! e HEAD &&
test_cmp_rev b HEAD~2 &&
test_linear_range 'd e' b..
"
}
test_run_rebase success ''
+test_run_rebase success --fork-point
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase failure -p
@@ -64,6 +75,23 @@ test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
shift
+ test_expect_$result "rebase $* -f rewrites even if remote upstream is an ancestor" "
+ reset_rebase &&
+ git rebase $* -f branch-b branch-e &&
+ test_cmp_rev ! branch-e origin/branch-e &&
+ test_cmp_rev branch-b HEAD~2 &&
+ test_linear_range 'd e' branch-b..
+ "
+}
+test_run_rebase success ''
+test_run_rebase success --fork-point
+test_run_rebase success -m
+test_run_rebase success -i
+test_have_prereq !REBASE_P || test_run_rebase success -p
+
+test_run_rebase () {
+ result=$1
+ shift
test_expect_$result "rebase $* fast-forwards from ancestor of upstream" "
reset_rebase &&
git rebase $* e b &&
@@ -71,6 +99,7 @@ test_run_rebase () {
"
}
test_run_rebase success ''
+test_run_rebase success --fork-point
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -339,7 +368,7 @@ test_run_rebase () {
test_expect_$result "rebase $* -f --root on linear history causes re-write" "
reset_rebase &&
git rebase $* -f --root c &&
- ! test_cmp_rev a HEAD~2 &&
+ test_cmp_rev ! a HEAD~2 &&
test_linear_range 'a b c' HEAD
"
}
diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh
index a5868ea152..50e7960702 100755
--- a/t/t3422-rebase-incompatible-options.sh
+++ b/t/t3422-rebase-incompatible-options.sh
@@ -76,14 +76,4 @@ test_expect_success REBASE_P \
test_must_fail git rebase --preserve-merges --rebase-merges A
'
-test_expect_success '--rebase-merges incompatible with --strategy' '
- git checkout B^0 &&
- test_must_fail git rebase --rebase-merges -s resolve A
-'
-
-test_expect_success '--rebase-merges incompatible with --strategy-option' '
- git checkout B^0 &&
- test_must_fail git rebase --rebase-merges -Xignore-space-change A
-'
-
test_done
diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh
index d8640522a0..bec48e6a1f 100755
--- a/t/t3427-rebase-subtree.sh
+++ b/t/t3427-rebase-subtree.sh
@@ -11,113 +11,99 @@ commit_message() {
git log --pretty=format:%s -1 "$1"
}
+# There are a few bugs in the rebase with regards to the subtree strategy, and
+# this test script tries to document them. First, the following commit history
+# is generated (the onelines are shown, time flows from left to right):
+#
+# master1 - master2 - master3
+# \
+# README ---------------------- Add subproject master - master4 - files_subtree/master5
+#
+# Where the merge moves the files master[123].t into the subdirectory
+# files_subtree/ and master4 as well as files_subtree/master5 add files to that
+# directory directly.
+#
+# Then, in subsequent test cases, `git filter-branch` is used to distill just
+# the commits that touch files_subtree/. To give it a final pre-rebase touch,
+# an empty commit is added on top. The pre-rebase commit history looks like
+# this:
+#
+# Add subproject master - master4 - files_subtree/master5 - Empty commit
+#
+# where the root commit adds three files: master1.t, master2.t and master3.t.
+#
+# This commit history is then rebased onto `master3` with the
+# `-Xsubtree=files_subtree` option in three different ways:
+#
+# 1. using `--preserve-merges`
+# 2. using `--preserve-merges` and --keep-empty
+# 3. without specifying a rebase backend
+
test_expect_success 'setup' '
test_commit README &&
- mkdir files &&
- (
- cd files &&
- git init &&
- test_commit master1 &&
- test_commit master2 &&
- test_commit master3
- ) &&
- git fetch files master &&
- git branch files-master FETCH_HEAD &&
- git read-tree --prefix=files_subtree files-master &&
- git checkout -- files_subtree &&
- tree=$(git write-tree) &&
- head=$(git rev-parse HEAD) &&
- rev=$(git rev-parse --verify files-master^0) &&
- commit=$(git commit-tree -p $head -p $rev -m "Add subproject master" $tree) &&
- git update-ref HEAD $commit &&
- (
- cd files_subtree &&
- test_commit master4
- ) &&
- test_commit files_subtree/master5
-'
-# FAILURE: Does not preserve master4.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --preserve-merges --onto commit 4' '
- reset_rebase &&
- git checkout -b rebase-preserve-merges-4 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&
- verbose test "$(commit_message HEAD~)" = "files_subtree/master4"
+ git init files &&
+ test_commit -C files master1 &&
+ test_commit -C files master2 &&
+ test_commit -C files master3 &&
+
+ : perform subtree merge into files_subtree/ &&
+ git fetch files refs/heads/master:refs/heads/files-master &&
+ git merge -s ours --no-commit --allow-unrelated-histories \
+ files-master &&
+ git read-tree --prefix=files_subtree -u files-master &&
+ git commit -m "Add subproject master" &&
+
+ : add two extra commits to rebase &&
+ test_commit -C files_subtree master4 &&
+ test_commit files_subtree/master5 &&
+
+ git checkout -b to-rebase &&
+ git fast-export --no-data HEAD -- files_subtree/ |
+ sed -e "s%\([0-9a-f]\{40\} \)files_subtree/%\1%" |
+ git fast-import --force --quiet &&
+ git reset --hard &&
+ git commit -m "Empty commit" --allow-empty
'
-# FAILURE: Does not preserve master5.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --preserve-merges --onto commit 5' '
+# FAILURE: Does not preserve master4.
+test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '
reset_rebase &&
- git checkout -b rebase-preserve-merges-5 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
+ git checkout -b rebase-preserve-merges to-rebase &&
git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&
+ verbose test "$(commit_message HEAD~)" = "master4" &&
verbose test "$(commit_message HEAD)" = "files_subtree/master5"
'
# FAILURE: Does not preserve master4.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '
- reset_rebase &&
- git checkout -b rebase-keep-empty-4 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
- verbose test "$(commit_message HEAD~2)" = "files_subtree/master4"
-'
-
-# FAILURE: Does not preserve master5.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '
- reset_rebase &&
- git checkout -b rebase-keep-empty-5 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
- verbose test "$(commit_message HEAD~)" = "files_subtree/master5"
-'
-
-# FAILURE: Does not preserve Empty.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '
+test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '
reset_rebase &&
- git checkout -b rebase-keep-empty-empty master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
+ git checkout -b rebase-keep-empty to-rebase &&
git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
verbose test "$(commit_message HEAD)" = "Empty commit"
'
-# FAILURE: fatal: Could not parse object
-test_expect_failure 'Rebase -Xsubtree --onto commit 4' '
+test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '
reset_rebase &&
- git checkout -b rebase-onto-4 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --onto files-master master &&
- verbose test "$(commit_message HEAD~2)" = "files_subtree/master4"
+ git checkout -b rebase-onto to-rebase &&
+ test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&
+ : first pick results in no changes &&
+ git rebase --continue &&
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
+ verbose test "$(commit_message HEAD)" = "Empty commit"
'
-# FAILURE: fatal: Could not parse object
-test_expect_failure 'Rebase -Xsubtree --onto commit 5' '
- reset_rebase &&
- git checkout -b rebase-onto-5 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --onto files-master master &&
- verbose test "$(commit_message HEAD~)" = "files_subtree/master5"
-'
-# FAILURE: fatal: Could not parse object
-test_expect_failure 'Rebase -Xsubtree --onto empty commit' '
+test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' '
reset_rebase &&
- git checkout -b rebase-onto-empty master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --onto files-master master &&
+ git checkout -b rebase-merges-onto to-rebase &&
+ test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root &&
+ : first pick results in no changes &&
+ git rebase --continue &&
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
verbose test "$(commit_message HEAD)" = "Empty commit"
'
diff --git a/t/t3429-rebase-edit-todo.sh b/t/t3429-rebase-edit-todo.sh
index 76f6d306ea..7024d49ae7 100755
--- a/t/t3429-rebase-edit-todo.sh
+++ b/t/t3429-rebase-edit-todo.sh
@@ -3,15 +3,21 @@
test_description='rebase should reread the todo file if an exec modifies it'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+test_expect_success 'setup' '
+ test_commit first file &&
+ test_commit second file &&
+ test_commit third file
+'
test_expect_success 'rebase exec modifies rebase-todo' '
- test_commit initial &&
todo=.git/rebase-merge/git-rebase-todo &&
git rebase HEAD -x "echo exec touch F >>$todo" &&
test -e F
'
-test_expect_success SHA1 'loose object cache vs re-reading todo list' '
+test_expect_success 'loose object cache vs re-reading todo list' '
GIT_REBASE_TODO=.git/rebase-merge/git-rebase-todo &&
export GIT_REBASE_TODO &&
write_script append-todo.sh <<-\EOS &&
@@ -33,4 +39,47 @@ test_expect_success SHA1 'loose object cache vs re-reading todo list' '
git rebase HEAD -x "./append-todo.sh 5 6"
'
+test_expect_success 'todo is re-read after reword and squash' '
+ write_script reword-editor.sh <<-\EOS &&
+ GIT_SEQUENCE_EDITOR="echo \"exec echo $(cat file) >>actual\" >>" \
+ git rebase --edit-todo
+ EOS
+
+ test_write_lines first third >expected &&
+ set_fake_editor &&
+ GIT_SEQUENCE_EDITOR="$EDITOR" FAKE_LINES="reword 1 squash 2 fixup 3" \
+ GIT_EDITOR=./reword-editor.sh git rebase -i --root third &&
+ test_cmp expected actual
+'
+
+test_expect_success 're-reading todo doesnt interfere with revert --edit' '
+ git reset --hard third &&
+
+ git revert --edit third second &&
+
+ cat >expect <<-\EOF &&
+ Revert "second"
+ Revert "third"
+ third
+ second
+ first
+ EOF
+ git log --format="%s" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 're-reading todo doesnt interfere with cherry-pick --edit' '
+ git reset --hard first &&
+
+ git cherry-pick --edit second third &&
+
+ cat >expect <<-\EOF &&
+ third
+ second
+ first
+ EOF
+ git log --format="%s" >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 7b6c4847ad..e72ca348ea 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -37,20 +37,27 @@ test_expect_success 'setup' '
test_commit A &&
git checkout -b first &&
test_commit B &&
+ b=$(git rev-parse --short HEAD) &&
git checkout master &&
test_commit C &&
+ c=$(git rev-parse --short HEAD) &&
test_commit D &&
+ d=$(git rev-parse --short HEAD) &&
git merge --no-commit B &&
test_tick &&
git commit -m E &&
git tag -m E E &&
+ e=$(git rev-parse --short HEAD) &&
git checkout -b second C &&
test_commit F &&
+ f=$(git rev-parse --short HEAD) &&
test_commit G &&
+ g=$(git rev-parse --short HEAD) &&
git checkout master &&
git merge --no-commit G &&
test_tick &&
git commit -m H &&
+ h=$(git rev-parse --short HEAD) &&
git tag -m H H &&
git checkout A &&
test_commit conflicting-G G.t
@@ -93,24 +100,24 @@ test_expect_success 'create completely different structure' '
'
test_expect_success 'generate correct todo list' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
label onto
reset onto
- pick d9df450 B
+ pick $b B
label E
reset onto
- pick 5dee784 C
+ pick $c C
label branch-point
- pick ca2c861 F
- pick 088b00a G
+ pick $f F
+ pick $g G
label H
reset branch-point # C
- pick 12bd07b D
- merge -C 2051b56 E # E
- merge -C 233d48a H # H
+ pick $d D
+ merge -C $e E # E
+ merge -C $h H # H
EOF
@@ -151,7 +158,6 @@ test_expect_success 'failed `merge -C` writes patch (may be rescheduled, too)' '
test_path_is_file .git/rebase-merge/patch
'
-SQ="'"
test_expect_success 'failed `merge <branch>` does not crash' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout conflicting-G &&
@@ -340,7 +346,7 @@ test_expect_success 'A root commit can be a cousin, treat it that way' '
git merge --allow-unrelated-histories khnum &&
test_tick &&
git rebase -f -r HEAD^ &&
- ! test_cmp_rev HEAD^2 khnum &&
+ test_cmp_rev ! HEAD^2 khnum &&
test_cmp_graph HEAD^.. <<-\EOF &&
* Merge branch '\''khnum'\'' into asherah
|\
@@ -402,7 +408,7 @@ test_expect_success 'octopus merges' '
| | * three
| * | two
| |/
- * | one
+ * / one
|/
o before-octopus
EOF
@@ -441,4 +447,52 @@ test_expect_success '--continue after resolving conflicts after a merge' '
test_path_is_missing .git/MERGE_HEAD
'
+test_expect_success '--rebase-merges with strategies' '
+ git checkout -b with-a-strategy F &&
+ test_tick &&
+ git merge -m "Merge conflicting-G" conflicting-G &&
+
+ : first, test with a merge strategy option &&
+ git rebase -ir -Xtheirs G &&
+ echo conflicting-G >expect &&
+ test_cmp expect G.t &&
+
+ : now, try with a merge strategy other than recursive &&
+ git reset --hard @{1} &&
+ write_script git-merge-override <<-\EOF &&
+ echo overridden$1 >>G.t
+ git add G.t
+ EOF
+ PATH="$PWD:$PATH" git rebase -ir -s override -Xxopt G &&
+ test_write_lines G overridden--xopt >expect &&
+ test_cmp expect G.t
+'
+
+test_expect_success '--rebase-merges with commit that can generate bad characters for filename' '
+ git checkout -b colon-in-label E &&
+ git merge -m "colon: this should work" G &&
+ git rebase --rebase-merges --force-rebase E
+'
+
+test_expect_success '--rebase-merges with message matched with onto label' '
+ git checkout -b onto-label E &&
+ git merge -m onto G &&
+ git rebase --rebase-merges --force-rebase E &&
+ test_cmp_graph <<-\EOF
+ * onto
+ |\
+ | * G
+ | * F
+ * | E
+ |\ \
+ | * | B
+ * | | D
+ | |/
+ |/|
+ * | C
+ |/
+ * A
+ EOF
+'
+
test_done
diff --git a/t/t3431-rebase-fork-point.sh b/t/t3431-rebase-fork-point.sh
new file mode 100755
index 0000000000..78851b9a2a
--- /dev/null
+++ b/t/t3431-rebase-fork-point.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='git rebase --fork-point test'
+
+. ./test-lib.sh
+
+# A---B---D---E (master)
+# \
+# C*---F---G (side)
+#
+# C was formerly part of master but master was rewound to remove C
+#
+test_expect_success setup '
+ test_commit A &&
+ test_commit B &&
+ test_commit C &&
+ git branch -t side &&
+ git reset --hard HEAD^ &&
+ test_commit D &&
+ test_commit E &&
+ git checkout side &&
+ test_commit F &&
+ test_commit G
+'
+
+test_rebase () {
+ expected="$1" &&
+ shift &&
+ test_expect_success "git rebase $*" "
+ git checkout master &&
+ git reset --hard E &&
+ git checkout side &&
+ git reset --hard G &&
+ git rebase $* &&
+ test_write_lines $expected >expect &&
+ git log --pretty=%s >actual &&
+ test_cmp expect actual
+ "
+}
+
+test_rebase 'G F E D B A'
+test_rebase 'G F D B A' --onto D
+test_rebase 'G F B A' --keep-base
+test_rebase 'G F C E D B A' --no-fork-point
+test_rebase 'G F C D B A' --no-fork-point --onto D
+test_rebase 'G F C B A' --no-fork-point --keep-base
+test_rebase 'G F E D B A' --fork-point refs/heads/master
+test_rebase 'G F D B A' --fork-point --onto D refs/heads/master
+test_rebase 'G F B A' --fork-point --keep-base refs/heads/master
+test_rebase 'G F C E D B A' refs/heads/master
+test_rebase 'G F C D B A' --onto D refs/heads/master
+test_rebase 'G F C B A' --keep-base refs/heads/master
+
+test_done
diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh
new file mode 100755
index 0000000000..92f95b57da
--- /dev/null
+++ b/t/t3432-rebase-fast-forward.sh
@@ -0,0 +1,125 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='ensure rebase fast-forwards commits when possible'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ test_commit A &&
+ test_commit B &&
+ test_commit C &&
+ test_commit D &&
+ git checkout -t -b side
+'
+
+test_rebase_same_head () {
+ status_n="$1" &&
+ shift &&
+ what_n="$1" &&
+ shift &&
+ cmp_n="$1" &&
+ shift &&
+ status_f="$1" &&
+ shift &&
+ what_f="$1" &&
+ shift &&
+ cmp_f="$1" &&
+ shift &&
+ test_rebase_same_head_ $status_n $what_n $cmp_n "" "$*" &&
+ test_rebase_same_head_ $status_f $what_f $cmp_f " --no-ff" "$*"
+}
+
+test_rebase_same_head_ () {
+ status="$1" &&
+ shift &&
+ what="$1" &&
+ shift &&
+ cmp="$1" &&
+ shift &&
+ flag="$1"
+ shift &&
+ test_expect_$status "git rebase$flag $* with $changes is $what with $cmp HEAD" "
+ oldhead=\$(git rev-parse HEAD) &&
+ test_when_finished 'git reset --hard \$oldhead' &&
+ git rebase$flag $* >stdout &&
+ if test $what = work
+ then
+ # Must check this case first, for 'is up to
+ # date, rebase forced[...]rewinding head' cases
+ test_i18ngrep 'rewinding head' stdout
+ elif test $what = noop
+ then
+ test_i18ngrep 'is up to date' stdout &&
+ test_i18ngrep ! 'rebase forced' stdout
+ elif test $what = noop-force
+ then
+ test_i18ngrep 'is up to date, rebase forced' stdout
+ fi &&
+ newhead=\$(git rev-parse HEAD) &&
+ if test $cmp = same
+ then
+ test_cmp_rev \$oldhead \$newhead
+ elif test $cmp = diff
+ then
+ test_cmp_rev ! \$oldhead \$newhead
+ fi
+ "
+}
+
+changes='no changes'
+test_rebase_same_head success noop same success work same
+test_rebase_same_head success noop same success noop-force same master
+test_rebase_same_head success noop same success noop-force diff --onto B B
+test_rebase_same_head success noop same success noop-force diff --onto B... B
+test_rebase_same_head success noop same success noop-force same --onto master... master
+test_rebase_same_head success noop same success noop-force same --keep-base master
+test_rebase_same_head success noop same success noop-force same --keep-base
+test_rebase_same_head success noop same success noop-force same --no-fork-point
+test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point
+test_rebase_same_head success noop same success work same --fork-point master
+test_rebase_same_head success noop same success work diff --fork-point --onto B B
+test_rebase_same_head success noop same success work diff --fork-point --onto B... B
+test_rebase_same_head success noop same success work same --fork-point --onto master... master
+test_rebase_same_head success noop same success work same --keep-base --keep-base master
+
+test_expect_success 'add work same to side' '
+ test_commit E
+'
+
+changes='our changes'
+test_rebase_same_head success noop same success work same
+test_rebase_same_head success noop same success noop-force same master
+test_rebase_same_head success noop same success noop-force diff --onto B B
+test_rebase_same_head success noop same success noop-force diff --onto B... B
+test_rebase_same_head success noop same success noop-force same --onto master... master
+test_rebase_same_head success noop same success noop-force same --keep-base master
+test_rebase_same_head success noop same success noop-force same --keep-base
+test_rebase_same_head success noop same success noop-force same --no-fork-point
+test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point
+test_rebase_same_head success noop same success work same --fork-point master
+test_rebase_same_head success noop same success work diff --fork-point --onto B B
+test_rebase_same_head success noop same success work diff --fork-point --onto B... B
+test_rebase_same_head success noop same success work same --fork-point --onto master... master
+test_rebase_same_head success noop same success work same --fork-point --keep-base master
+
+test_expect_success 'add work same to upstream' '
+ git checkout master &&
+ test_commit F &&
+ git checkout side
+'
+
+changes='our and their changes'
+test_rebase_same_head success noop same success noop-force diff --onto B B
+test_rebase_same_head success noop same success noop-force diff --onto B... B
+test_rebase_same_head success noop same success work diff --onto master... master
+test_rebase_same_head success noop same success work diff --keep-base master
+test_rebase_same_head success noop same success work diff --keep-base
+test_rebase_same_head failure work same success work diff --fork-point --onto B B
+test_rebase_same_head failure work same success work diff --fork-point --onto B... B
+test_rebase_same_head success noop same success work diff --fork-point --onto master... master
+test_rebase_same_head success noop same success work diff --fork-point --keep-base master
+
+test_done
diff --git a/t/t3434-rebase-i18n.sh b/t/t3434-rebase-i18n.sh
new file mode 100755
index 0000000000..c7c835cde9
--- /dev/null
+++ b/t/t3434-rebase-i18n.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Doan Tran Cong Danh
+#
+
+test_description='rebase with changing encoding
+
+Initial setup:
+
+1 - 2 master
+ \
+ 3 - 4 first
+ \
+ 5 - 6 second
+'
+
+. ./test-lib.sh
+
+compare_msg () {
+ iconv -f "$2" -t "$3" "$TEST_DIRECTORY/t3434/$1" >expect &&
+ git cat-file commit HEAD >raw &&
+ sed "1,/^$/d" raw >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success setup '
+ test_commit one &&
+ git branch first &&
+ test_commit two &&
+ git switch first &&
+ test_commit three &&
+ git branch second &&
+ test_commit four &&
+ git switch second &&
+ test_commit five &&
+ test_commit six
+'
+
+test_expect_success 'rebase --rebase-merges update encoding eucJP to UTF-8' '
+ git switch -c merge-eucJP-UTF-8 first &&
+ git config i18n.commitencoding eucJP &&
+ git merge -F "$TEST_DIRECTORY/t3434/eucJP.txt" second &&
+ git config i18n.commitencoding UTF-8 &&
+ git rebase --rebase-merges master &&
+ compare_msg eucJP.txt eucJP UTF-8
+'
+
+test_expect_success 'rebase --rebase-merges update encoding eucJP to ISO-2022-JP' '
+ git switch -c merge-eucJP-ISO-2022-JP first &&
+ git config i18n.commitencoding eucJP &&
+ git merge -F "$TEST_DIRECTORY/t3434/eucJP.txt" second &&
+ git config i18n.commitencoding ISO-2022-JP &&
+ git rebase --rebase-merges master &&
+ compare_msg eucJP.txt eucJP ISO-2022-JP
+'
+
+test_rebase_continue_update_encode () {
+ old=$1
+ new=$2
+ msgfile=$3
+ test_expect_success "rebase --continue update from $old to $new" '
+ (git rebase --abort || : abort current git-rebase failure) &&
+ git switch -c conflict-$old-$new one &&
+ echo for-conflict >two.t &&
+ git add two.t &&
+ git config i18n.commitencoding $old &&
+ git commit -F "$TEST_DIRECTORY/t3434/$msgfile" &&
+ git config i18n.commitencoding $new &&
+ test_must_fail git rebase -m master &&
+ test -f .git/rebase-merge/message &&
+ git stripspace <.git/rebase-merge/message >two.t &&
+ git add two.t &&
+ git rebase --continue &&
+ compare_msg $msgfile $old $new &&
+ : git-commit assume invalid utf-8 is latin1 &&
+ test_cmp expect two.t
+ '
+}
+
+test_rebase_continue_update_encode ISO-8859-1 UTF-8 ISO8859-1.txt
+test_rebase_continue_update_encode eucJP UTF-8 eucJP.txt
+test_rebase_continue_update_encode eucJP ISO-2022-JP eucJP.txt
+
+test_done
diff --git a/t/t3434/ISO8859-1.txt b/t/t3434/ISO8859-1.txt
new file mode 100644
index 0000000000..7cbef0ee6f
--- /dev/null
+++ b/t/t3434/ISO8859-1.txt
@@ -0,0 +1,3 @@
+
+
+bdfg
diff --git a/t/t3434/eucJP.txt b/t/t3434/eucJP.txt
new file mode 100644
index 0000000000..546f2aac01
--- /dev/null
+++ b/t/t3434/eucJP.txt
@@ -0,0 +1,4 @@
+ϤҤۤ
+
+ƤΤΤǡ
+ͤۤפݤޤӤء
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index d1c68af8c5..7c1da21df1 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -106,7 +106,7 @@ test_expect_success 'cherry-pick on unborn branch' '
rm -rf * &&
git cherry-pick initial &&
git diff --quiet initial &&
- ! test_cmp_rev initial HEAD
+ test_cmp_rev ! initial HEAD
'
test_expect_success 'cherry-pick "-" to pick from previous branch' '
@@ -150,7 +150,7 @@ test_expect_success 'cherry-pick works with dirty renamed file' '
test_tick &&
git commit -m renamed &&
echo modified >renamed &&
- git cherry-pick refs/heads/unrelated >out &&
+ git cherry-pick refs/heads/unrelated &&
test $(git rev-parse :0:renamed) = $(git rev-parse HEAD~2:to-rename.t) &&
grep -q "^modified$" renamed
'
diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index 127dd0082f..9d5adbc130 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -16,7 +16,11 @@ test_expect_success setup '
git add file1 &&
test_tick &&
git commit -m "second" &&
- git tag second
+ git tag second &&
+ test_oid_cache <<-EOF
+ cp_ff sha1:1df192cd8bc58a2b275d842cede4d221ad9000d1
+ cp_ff sha256:e70d6b7fc064bddb516b8d512c9057094b96ce6ff08e12080acc4fe7f1d60a1d
+ EOF
'
test_expect_success 'cherry-pick using --ff fast forwards' '
@@ -102,7 +106,7 @@ test_expect_success 'cherry pick a root commit with --ff' '
git add file2 &&
git commit --amend -m "file2" &&
git cherry-pick --ff first &&
- test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
+ test "$(git rev-parse --verify HEAD)" = "$(test_oid cp_ff)"
'
test_expect_success 'cherry-pick --ff on unborn branch' '
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index b457333e18..23070a7b73 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -5,7 +5,7 @@ test_description='test cherry-picking many commits'
. ./test-lib.sh
check_head_differs_from() {
- ! test_cmp_rev HEAD "$1"
+ test_cmp_rev ! HEAD "$1"
}
check_head_equals() {
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 66282a720e..f2c0168941 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -113,9 +113,10 @@ test_expect_success '"rm" command printed' '
echo frotz >test-file &&
git add test-file &&
git commit -m "add file for rm test" &&
- git rm test-file >rm-output &&
- test $(grep "^rm " rm-output | wc -l) = 1 &&
- rm -f test-file rm-output &&
+ git rm test-file >rm-output.raw &&
+ grep "^rm " rm-output.raw >rm-output &&
+ test_line_count = 1 rm-output &&
+ rm -f test-file rm-output.raw rm-output &&
git commit -m "remove file from rm test"
'
@@ -240,14 +241,17 @@ test_expect_success 'refresh index before checking if it is up-to-date' '
'
test_expect_success 'choking "git rm" should not let it die with cruft' '
+ test_oid_init &&
git reset -q --hard &&
test_when_finished "rm -f .git/index.lock && git reset -q --hard" &&
i=0 &&
+ hash=$(test_oid deadbeef) &&
while test $i -lt 12000
do
- echo "100644 1234567890123456789012345678901234567890 0 some-file-$i"
+ echo "100644 $hash 0 some-file-$i"
i=$(( $i + 1 ))
done | git update-index --index-info &&
+ # git command is intentionally placed upstream of pipe to induce SIGPIPE
git rm -n "some-file-*" | : &&
test_path_is_missing .git/index.lock
'
@@ -301,7 +305,8 @@ EOF
test_expect_success 'rm removes empty submodules from work tree' '
mkdir submod &&
- git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) submod &&
+ hash=$(git rev-parse HEAD) &&
+ git update-index --add --cacheinfo 160000 "$hash" submod &&
git config -f .gitmodules submodule.sub.url ./. &&
git config -f .gitmodules submodule.sub.path submod &&
git submodule init &&
@@ -420,6 +425,13 @@ test_expect_success 'rm will error out on a modified .gitmodules file unless sta
git status -s -uno >actual &&
test_cmp expect actual
'
+test_expect_success 'rm will not error out on .gitmodules file with zero stat data' '
+ git reset --hard &&
+ git submodule update &&
+ git read-tree HEAD &&
+ git rm submod &&
+ test_path_is_missing submod
+'
test_expect_success 'rm issues a warning when section is not found in .gitmodules' '
git reset --hard &&
@@ -620,7 +632,8 @@ test_expect_success 'setup subsubmodule' '
git submodule update &&
(
cd submod &&
- git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) subsubmod &&
+ hash=$(git rev-parse HEAD) &&
+ git update-index --add --cacheinfo 160000 "$hash" subsubmod &&
git config -f .gitmodules submodule.sub.url ../. &&
git config -f .gitmodules submodule.sub.path subsubmod &&
git submodule init &&
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index c325167b90..88bc799807 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -326,7 +326,9 @@ test_expect_success 'git add --dry-run of an existing file output' "
cat >expect.err <<\EOF
The following paths are ignored by one of your .gitignore files:
ignored-file
-Use -f if you really want to add them.
+hint: Use -f if you really want to add them.
+hint: Turn this message off by running
+hint: "git config advice.addIgnoredFile false"
EOF
cat >expect.out <<\EOF
add 'track-this'
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 69991a3168..e36fd0a5d3 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -23,6 +23,17 @@ diff_cmp () {
test_cmp "$1.filtered" "$2.filtered"
}
+# This function uses a trick to manipulate the interactive add to use color:
+# the `want_color()` function special-cases the situation where a pager was
+# spawned and Git now wants to output colored text: to detect that situation,
+# the environment variable `GIT_PAGER_IN_USE` is set. However, color is
+# suppressed despite that environment variable if the `TERM` variable
+# indicates a dumb terminal, so we set that variable, too.
+
+force_color () {
+ env GIT_PAGER_IN_USE=true TERM=vt100 "$@"
+}
+
test_expect_success 'setup (initial)' '
echo content >file &&
git add file &&
@@ -57,6 +68,15 @@ test_expect_success 'revert works (initial)' '
! grep . output
'
+test_expect_success 'add untracked (multiple)' '
+ test_when_finished "git reset && rm [1-9]" &&
+ touch $(test_seq 9) &&
+ test_write_lines a "2-5 8-" | git add -i -- [1-9] &&
+ test_write_lines 2 3 4 5 8 9 >expected &&
+ git ls-files [1-9] >output &&
+ test_cmp expected output
+'
+
test_expect_success 'setup (commit)' '
echo baseline >file &&
git add file &&
@@ -94,7 +114,6 @@ test_expect_success 'revert works (commit)' '
grep "unchanged *+3/-0 file" output
'
-
test_expect_success 'setup expected' '
cat >expected <<-\EOF
EOF
@@ -263,6 +282,35 @@ test_expect_success FILEMODE 'stage mode and hunk' '
# end of tests disabled when filemode is not usable
+test_expect_success 'different prompts for mode change/deleted' '
+ git reset --hard &&
+ >file &&
+ >deleted &&
+ git add --chmod=+x file deleted &&
+ echo changed >file &&
+ rm deleted &&
+ test_write_lines n n n |
+ git -c core.filemode=true add -p >actual &&
+ sed -n "s/^\(([0-9/]*) Stage .*?\).*/\1/p" actual >actual.filtered &&
+ cat >expect <<-\EOF &&
+ (1/1) Stage deletion [y,n,q,a,d,?]?
+ (1/2) Stage mode change [y,n,q,a,d,j,J,g,/,?]?
+ (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]?
+ EOF
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'correct message when there is nothing to do' '
+ git reset --hard &&
+ git add -p 2>err &&
+ test_i18ngrep "No changes" err &&
+ printf "\\0123" >binary &&
+ git add binary &&
+ printf "\\0abc" >binary &&
+ git add -p 2>err &&
+ test_i18ngrep "Only binary files changed" err
+'
+
test_expect_success 'setup again' '
git reset --hard &&
test_chmod +x file &&
@@ -314,7 +362,7 @@ test_expect_success C_LOCALE_OUTPUT 'add first line works' '
git commit -am "clear local changes" &&
git apply patch &&
printf "%s\n" s y y | git add -p file 2>error |
- sed -n -e "s/^Stage this hunk[^@]*\(@@ .*\)/\1/" \
+ sed -n -e "s/^([1-2]\/[1-2]) Stage this hunk[^@]*\(@@ .*\)/\1/" \
-e "/^[-+@ \\\\]"/p >output &&
test_must_be_empty error &&
git diff --cached >diff &&
@@ -374,6 +422,36 @@ test_expect_success 'split hunk setup' '
test_write_lines 10 15 20 21 22 23 24 30 40 50 60 >test
'
+test_expect_success 'goto hunk' '
+ test_when_finished "git reset" &&
+ tr _ " " >expect <<-EOF &&
+ (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? + 1: -1,2 +1,3 +15
+ _ 2: -2,4 +3,8 +21
+ go to which hunk? @@ -1,2 +1,3 @@
+ _10
+ +15
+ _20
+ (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_
+ EOF
+ test_write_lines s y g 1 | git add -p >actual &&
+ tail -n 7 <actual >actual.trimmed &&
+ test_cmp expect actual.trimmed
+'
+
+test_expect_success 'navigate to hunk via regex' '
+ test_when_finished "git reset" &&
+ tr _ " " >expect <<-EOF &&
+ (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? @@ -1,2 +1,3 @@
+ _10
+ +15
+ _20
+ (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_
+ EOF
+ test_write_lines s y /1,2 | git add -p >actual &&
+ tail -n 5 <actual >actual.trimmed &&
+ test_cmp expect actual.trimmed
+'
+
test_expect_success 'split hunk "add -p (edit)"' '
# Split, say Edit and do nothing. Then:
#
@@ -403,6 +481,40 @@ test_expect_failure 'split hunk "add -p (no, yes, edit)"' '
! grep "^+31" actual
'
+test_expect_success 'split hunk with incomplete line at end' '
+ git reset --hard &&
+ printf "missing LF" >>test &&
+ git add test &&
+ test_write_lines before 10 20 30 40 50 60 70 >test &&
+ git grep --cached missing &&
+ test_write_lines s n y q | git add -p &&
+ test_must_fail git grep --cached missing &&
+ git grep before &&
+ test_must_fail git grep --cached before
+'
+
+test_expect_failure 'edit, adding lines to the first hunk' '
+ test_write_lines 10 11 20 30 40 50 51 60 >test &&
+ git reset &&
+ tr _ " " >patch <<-EOF &&
+ @@ -1,5 +1,6 @@
+ _10
+ +11
+ +12
+ _20
+ +21
+ +22
+ _30
+ EOF
+ # test sequence is s(plit), e(dit), n(o)
+ # q n q q is there to make sure we exit at the end.
+ printf "%s\n" s e n q n q q |
+ EDITOR=./fake_editor.sh git add -p 2>error &&
+ test_must_be_empty error &&
+ git diff --cached >actual &&
+ grep "^+22" actual
+'
+
test_expect_success 'patch mode ignores unmerged entries' '
git reset --hard &&
test_commit conflict &&
@@ -429,35 +541,48 @@ test_expect_success 'patch mode ignores unmerged entries' '
diff_cmp expected diff
'
-test_expect_success TTY 'diffs can be colorized' '
+test_expect_success 'diffs can be colorized' '
git reset --hard &&
echo content >test &&
- printf y | test_terminal git add -p >output 2>&1 &&
+ printf y >y &&
+ force_color git add -p >output 2>&1 <y &&
# We do not want to depend on the exact coloring scheme
# git uses for diffs, so just check that we saw some kind of color.
grep "$(printf "\\033")" output
'
-test_expect_success TTY 'diffFilter filters diff' '
+test_expect_success 'diffFilter filters diff' '
git reset --hard &&
echo content >test &&
test_config interactive.diffFilter "sed s/^/foo:/" &&
- printf y | test_terminal git add -p >output 2>&1 &&
+ printf y >y &&
+ force_color git add -p >output 2>&1 <y &&
# avoid depending on the exact coloring or content of the prompts,
# and just make sure we saw our diff prefixed
grep foo:.*content output
'
-test_expect_success TTY 'detect bogus diffFilter output' '
+test_expect_success 'detect bogus diffFilter output' '
git reset --hard &&
echo content >test &&
- test_config interactive.diffFilter "echo too-short" &&
- printf y | test_must_fail test_terminal git add -p
+ test_config interactive.diffFilter "sed 1d" &&
+ printf y >y &&
+ test_must_fail force_color git add -p <y
+'
+
+test_expect_success 'diff.algorithm is passed to `git diff-files`' '
+ git reset --hard &&
+
+ >file &&
+ git add file &&
+ echo changed >file &&
+ test_must_fail git -c diff.algorithm=bogus add -p 2>err &&
+ test_i18ngrep "error: option diff-algorithm accepts " err
'
test_expect_success 'patch-mode via -i prompts for files' '
@@ -647,4 +772,29 @@ test_expect_success 'checkout -p works with pathological context lines' '
test_write_lines a b a b a a b a b a >expect &&
test_cmp expect a
'
+
+test_expect_success 'show help from add--helper' '
+ git reset --hard &&
+ cat >expect <<-EOF &&
+
+ <BOLD>*** Commands ***<RESET>
+ 1: <BOLD;BLUE>s<RESET>tatus 2: <BOLD;BLUE>u<RESET>pdate 3: <BOLD;BLUE>r<RESET>evert 4: <BOLD;BLUE>a<RESET>dd untracked
+ 5: <BOLD;BLUE>p<RESET>atch 6: <BOLD;BLUE>d<RESET>iff 7: <BOLD;BLUE>q<RESET>uit 8: <BOLD;BLUE>h<RESET>elp
+ <BOLD;BLUE>What now<RESET>> <BOLD;RED>status - show paths with changes<RESET>
+ <BOLD;RED>update - add working tree state to the staged set of changes<RESET>
+ <BOLD;RED>revert - revert staged set of changes back to the HEAD version<RESET>
+ <BOLD;RED>patch - pick hunks and update selectively<RESET>
+ <BOLD;RED>diff - view diff between HEAD and index<RESET>
+ <BOLD;RED>add untracked - add contents of untracked files to the staged set of changes<RESET>
+ <BOLD>*** Commands ***<RESET>
+ 1: <BOLD;BLUE>s<RESET>tatus 2: <BOLD;BLUE>u<RESET>pdate 3: <BOLD;BLUE>r<RESET>evert 4: <BOLD;BLUE>a<RESET>dd untracked
+ 5: <BOLD;BLUE>p<RESET>atch 6: <BOLD;BLUE>d<RESET>iff 7: <BOLD;BLUE>q<RESET>uit 8: <BOLD;BLUE>h<RESET>elp
+ <BOLD;BLUE>What now<RESET>>$SP
+ Bye.
+ EOF
+ test_write_lines h | force_color git add -i >actual.colored &&
+ test_decode_color <actual.colored >actual &&
+ test_i18ncmp expect actual
+'
+
test_done
diff --git a/t/t3704-add-pathspec-file.sh b/t/t3704-add-pathspec-file.sh
new file mode 100755
index 0000000000..9e35c1fbca
--- /dev/null
+++ b/t/t3704-add-pathspec-file.sh
@@ -0,0 +1,159 @@
+#!/bin/sh
+
+test_description='add --pathspec-from-file'
+
+. ./test-lib.sh
+
+test_tick
+
+test_expect_success setup '
+ test_commit file0 &&
+ echo A >fileA.t &&
+ echo B >fileB.t &&
+ echo C >fileC.t &&
+ echo D >fileD.t
+'
+
+restore_checkpoint () {
+ git reset
+}
+
+verify_expect () {
+ git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success '--pathspec-from-file from stdin' '
+ restore_checkpoint &&
+
+ echo fileA.t | git add --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success '--pathspec-from-file from file' '
+ restore_checkpoint &&
+
+ echo fileA.t >list &&
+ git add --pathspec-from-file=list &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'NUL delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\0fileB.t\0" | git add --pathspec-from-file=- --pathspec-file-nul &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'LF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t\n" | git add --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'no trailing delimiter' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t" | git add --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'CRLF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\r\nfileB.t\r\n" | git add --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ git add --pathspec-from-file=list &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes not compatible with --pathspec-file-nul' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ test_must_fail git add --pathspec-from-file=list --pathspec-file-nul
+'
+
+test_expect_success 'only touches what was listed' '
+ restore_checkpoint &&
+
+ printf "fileB.t\nfileC.t\n" | git add --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ A fileB.t
+ A fileC.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'error conditions' '
+ restore_checkpoint &&
+ echo fileA.t >list &&
+ >empty_list &&
+
+ test_must_fail git add --pathspec-from-file=list --interactive 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err &&
+
+ test_must_fail git add --pathspec-from-file=list --patch 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err &&
+
+ test_must_fail git add --pathspec-from-file=list --edit 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --edit" err &&
+
+ test_must_fail git add --pathspec-from-file=list -- fileA.t 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err &&
+
+ test_must_fail git add --pathspec-file-nul 2>err &&
+ test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err &&
+
+ # This case succeeds, but still prints to stderr
+ git add --pathspec-from-file=empty_list 2>err &&
+ test_i18ngrep -e "Nothing specified, nothing added." err
+'
+
+test_done
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 8eb47942e2..64dcc5ec28 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -23,6 +23,7 @@ check_verify_failure () {
# first create a commit, so we have a valid object/type
# for the tag.
test_expect_success 'setup' '
+ test_oid_init &&
echo Hello >A &&
git update-index --add A &&
git commit -m "Initial commit" &&
@@ -69,28 +70,28 @@ check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
# 4. type line label check
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
xxxx tag
tag mytag
tagger . <> 0 +0000
EOF
-check_verify_failure '"type" line label check' '^error: char47: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
############################################################
# 5. type line eol check
-echo "object 779e9b33986b1c2670fff52c5067603117b3e895" >tag.sig
+echo "object $head" >tag.sig
printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
-check_verify_failure '"type" line eol check' '^error: char48: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
############################################################
# 6. tag line label check #1
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
type tag
xxx mytag
tagger . <> 0 +0000
@@ -98,37 +99,37 @@ tagger . <> 0 +0000
EOF
check_verify_failure '"tag" line label check #1' \
- '^error: char57: no "tag " found$'
+ '^error: char.*: no "tag " found$'
############################################################
# 7. tag line label check #2
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
type taggggggggggggggggggggggggggggggg
tag
EOF
check_verify_failure '"tag" line label check #2' \
- '^error: char87: no "tag " found$'
+ '^error: char.*: no "tag " found$'
############################################################
# 8. type line type-name length check
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
type taggggggggggggggggggggggggggggggg
tag mytag
EOF
check_verify_failure '"type" line type-name length check' \
- '^error: char53: type too long$'
+ '^error: char.*: type too long$'
############################################################
# 9. verify object (SHA1/type) check
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $(test_oid deadbeef)
type tagggg
tag mytag
tagger . <> 0 +0000
@@ -150,7 +151,7 @@ tagger . <> 0 +0000
EOF
check_verify_failure 'verify tag-name check' \
- '^error: char67: could not verify tag name$'
+ '^error: char.*: could not verify tag name$'
############################################################
# 11. tagger line label check #1
@@ -164,7 +165,7 @@ This is filler
EOF
check_verify_failure '"tagger" line label check #1' \
- '^error: char70: could not find "tagger "$'
+ '^error: char.*: could not find "tagger "$'
############################################################
# 12. tagger line label check #2
@@ -179,7 +180,7 @@ This is filler
EOF
check_verify_failure '"tagger" line label check #2' \
- '^error: char70: could not find "tagger "$'
+ '^error: char.*: could not find "tagger "$'
############################################################
# 13. disallow missing tag author name
@@ -194,7 +195,7 @@ This is filler
EOF
check_verify_failure 'disallow missing tag author name' \
- '^error: char77: missing tagger name$'
+ '^error: char.*: missing tagger name$'
############################################################
# 14. disallow missing tag author name
@@ -209,7 +210,7 @@ tagger T A Gger <
EOF
check_verify_failure 'disallow malformed tagger' \
- '^error: char77: malformed tagger field$'
+ '^error: char.*: malformed tagger field$'
############################################################
# 15. allow empty tag email
@@ -238,7 +239,7 @@ tagger T A Gger <tag ger@example.com> 0 +0000
EOF
check_verify_failure 'disallow spaces in tag email' \
- '^error: char77: malformed tagger field$'
+ '^error: char.*: malformed tagger field$'
############################################################
# 17. disallow missing tag timestamp
@@ -252,7 +253,7 @@ tagger T A Gger <tagger@example.com>__
EOF
check_verify_failure 'disallow missing tag timestamp' \
- '^error: char107: missing tag timestamp$'
+ '^error: char.*: missing tag timestamp$'
############################################################
# 18. detect invalid tag timestamp1
@@ -266,7 +267,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
EOF
check_verify_failure 'detect invalid tag timestamp1' \
- '^error: char107: missing tag timestamp$'
+ '^error: char.*: missing tag timestamp$'
############################################################
# 19. detect invalid tag timestamp2
@@ -280,7 +281,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
EOF
check_verify_failure 'detect invalid tag timestamp2' \
- '^error: char111: malformed tag timestamp$'
+ '^error: char.*: malformed tag timestamp$'
############################################################
# 20. detect invalid tag timezone1
@@ -294,7 +295,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
EOF
check_verify_failure 'detect invalid tag timezone1' \
- '^error: char118: malformed tag timezone$'
+ '^error: char.*: malformed tag timezone$'
############################################################
# 21. detect invalid tag timezone2
@@ -308,7 +309,7 @@ tagger T A Gger <tagger@example.com> 1206478233 + 30
EOF
check_verify_failure 'detect invalid tag timezone2' \
- '^error: char118: malformed tag timezone$'
+ '^error: char.*: malformed tag timezone$'
############################################################
# 22. detect invalid tag timezone3
@@ -322,7 +323,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
EOF
check_verify_failure 'detect invalid tag timezone3' \
- '^error: char118: malformed tag timezone$'
+ '^error: char.*: malformed tag timezone$'
############################################################
# 23. detect invalid header entry
@@ -337,7 +338,7 @@ this line should not be here
EOF
check_verify_failure 'detect invalid header entry' \
- '^error: char124: trailing garbage in tag header$'
+ '^error: char.*: trailing garbage in tag header$'
############################################################
# 24. create valid tag
diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh
index b92ff95977..d277a9f4b7 100755
--- a/t/t3900-i18n-commit.sh
+++ b/t/t3900-i18n-commit.sh
@@ -204,4 +204,41 @@ test_commit_autosquash_flags eucJP fixup
test_commit_autosquash_flags ISO-2022-JP squash
+test_commit_autosquash_multi_encoding () {
+ flag=$1
+ old=$2
+ new=$3
+ msg=$4
+ test_expect_success "commit --$flag into $old from $new" '
+ git checkout -b $flag-$old-$new C0 &&
+ git config i18n.commitencoding $old &&
+ echo $old >>F &&
+ git commit -a -F "$TEST_DIRECTORY"/t3900/$msg &&
+ test_tick &&
+ echo intermediate stuff >>G &&
+ git add G &&
+ git commit -a -m "intermediate commit" &&
+ test_tick &&
+ git config i18n.commitencoding $new &&
+ echo $new-$flag >>F &&
+ git commit -a --$flag HEAD^ &&
+ git rebase --autosquash -i HEAD^^^ &&
+ git rev-list HEAD >actual &&
+ test_line_count = 3 actual &&
+ iconv -f $old -t UTF-8 "$TEST_DIRECTORY"/t3900/$msg >expect &&
+ if test $flag = squash; then
+ subject="$(head -1 expect)" &&
+ printf "\nsquash! %s\n" "$subject" >>expect
+ fi &&
+ git cat-file commit HEAD^ >raw &&
+ (sed "1,/^$/d" raw | iconv -f $new -t utf-8) >actual &&
+ test_cmp expect actual
+ '
+}
+
+test_commit_autosquash_multi_encoding fixup UTF-8 ISO-8859-1 1-UTF-8.txt
+test_commit_autosquash_multi_encoding squash ISO-8859-1 UTF-8 ISO8859-1.txt
+test_commit_autosquash_multi_encoding squash eucJP ISO-2022-JP eucJP.txt
+test_commit_autosquash_multi_encoding fixup ISO-2022-JP UTF-8 ISO-2022-JP.txt
+
test_done
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index b8e337893f..ea56e85e70 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -7,6 +7,18 @@ test_description='Test git stash'
. ./test-lib.sh
+diff_cmp () {
+ for i in "$1" "$2"
+ do
+ sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \
+ -e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \
+ -e 's/^index [0-9a-f]*,[0-9a-f]*\.\.[0-9a-f]*/index 1234567,7654321..89abcde/' \
+ "$i" >"$i.compare" || return 1
+ done &&
+ test_cmp "$1.compare" "$2.compare" &&
+ rm -f "$1.compare" "$2.compare"
+}
+
test_expect_success 'stash some dirty working directory' '
echo 1 >file &&
git add file &&
@@ -36,7 +48,7 @@ EOF
test_expect_success 'parents of stash' '
test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
git diff stash^2..stash >output &&
- test_cmp expect output
+ diff_cmp expect output
'
test_expect_success 'applying bogus stash does nothing' '
@@ -210,13 +222,13 @@ test_expect_success 'stash branch' '
test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
test $(git rev-parse HEAD) = $(git rev-parse master^) &&
git diff --cached >output &&
- test_cmp expect output &&
+ diff_cmp expect output &&
git diff >output &&
- test_cmp expect1 output &&
+ diff_cmp expect1 output &&
git add file &&
git commit -m alternate\ second &&
git diff master..stashbranch >output &&
- test_cmp output expect2 &&
+ diff_cmp output expect2 &&
test 0 = $(git stash list | wc -l)
'
@@ -232,8 +244,11 @@ test_expect_success 'save -q is quiet' '
test_must_be_empty output.out
'
-test_expect_success 'pop -q is quiet' '
+test_expect_success 'pop -q works and is quiet' '
git stash pop -q >output.out 2>&1 &&
+ echo bar >expect &&
+ git show :file >actual &&
+ test_cmp expect actual &&
test_must_be_empty output.out
'
@@ -242,6 +257,8 @@ test_expect_success 'pop -q --index works and is quiet' '
git add file &&
git stash save --quiet &&
git stash pop -q --index >output.out 2>&1 &&
+ git diff-files file2 >file2.diff &&
+ test_must_be_empty file2.diff &&
test foo = "$(git show :file)" &&
test_must_be_empty output.out
'
@@ -577,7 +594,7 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
+bar
EOF
git stash show -p ${STASH_ID} >actual &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'stash show - no stashes on stack, stash-like argument' '
@@ -609,7 +626,7 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
+foo
EOF
git stash show -p ${STASH_ID} >actual &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'stash show --patience shows diff' '
@@ -627,7 +644,7 @@ test_expect_success 'stash show --patience shows diff' '
+foo
EOF
git stash show --patience ${STASH_ID} >actual &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'drop: fail early if specified stash is not a stash ref' '
@@ -791,7 +808,7 @@ test_expect_success 'stash where working directory contains "HEAD" file' '
git diff-index --cached --quiet HEAD &&
test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
git diff stash^..stash >output &&
- test_cmp expect output
+ diff_cmp expect output
'
test_expect_success 'store called with invalid commit' '
@@ -847,7 +864,7 @@ test_expect_success 'stash list implies --first-parent -m' '
+working
EOF
git stash list --format=%gd -p >actual &&
- test_cmp expect actual
+ diff_cmp expect actual
'
test_expect_success 'stash list --cc shows combined diff' '
@@ -864,7 +881,7 @@ test_expect_success 'stash list --cc shows combined diff' '
++working
EOF
git stash list --format=%gd -p --cc >actual &&
- test_cmp expect actual
+ diff_cmp expect actual
'
test_expect_success 'stash is not confused by partial renames' '
@@ -1241,4 +1258,31 @@ test_expect_success 'stash --keep-index with file deleted in index does not resu
test_path_is_missing to-remove
'
+test_expect_success 'stash apply should succeed with unmodified file' '
+ echo base >file &&
+ git add file &&
+ git commit -m base &&
+
+ # now stash a modification
+ echo modified >file &&
+ git stash &&
+
+ # make the file stat dirty
+ cp file other &&
+ mv other file &&
+
+ git stash apply
+'
+
+test_expect_success 'stash handles skip-worktree entries nicely' '
+ test_commit A &&
+ echo changed >A.t &&
+ git add A.t &&
+ git update-index --skip-worktree A.t &&
+ rm A.t &&
+ git stash &&
+
+ git rev-parse --verify refs/stash:A.t
+'
+
test_done
diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh
index 29ca76f2fb..f075c7f1f3 100755
--- a/t/t3905-stash-include-untracked.sh
+++ b/t/t3905-stash-include-untracked.sh
@@ -277,8 +277,8 @@ test_expect_success 'stash -u -- <ignored> leaves ignored file alone' '
test_path_is_file ignored.d/bar
'
-test_expect_success 'stash -u -- <non-existant> shows no changes when there are none' '
- git stash push -u -- non-existant >actual &&
+test_expect_success 'stash -u -- <non-existent> shows no changes when there are none' '
+ git stash push -u -- non-existent >actual &&
echo "No local changes to save" >expect &&
test_i18ncmp expect actual
'
diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh
index d7219d6f8f..b93d1d74da 100755
--- a/t/t3906-stash-submodule.sh
+++ b/t/t3906-stash-submodule.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='stash apply can handle submodules'
+test_description='stash can handle submodules'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-submodule-update.sh
@@ -21,4 +21,44 @@ KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1
KNOWN_FAILURE_NOFF_MERGE_DOESNT_CREATE_EMPTY_SUBMODULE_DIR=1
test_submodule_switch "git_stash"
+setup_basic () {
+ test_when_finished "rm -rf main sub" &&
+ git init sub &&
+ (
+ cd sub &&
+ test_commit sub_file
+ ) &&
+ git init main &&
+ (
+ cd main &&
+ git submodule add ../sub &&
+ test_commit main_file
+ )
+}
+
+test_expect_success 'stash push with submodule.recurse=true preserves dirty submodule worktree' '
+ setup_basic &&
+ (
+ cd main &&
+ git config submodule.recurse true &&
+ echo "x" >main_file.t &&
+ echo "y" >sub/sub_file.t &&
+ git stash push &&
+ test_must_fail git -C sub diff --quiet
+ )
+'
+
+test_expect_success 'stash push and pop with submodule.recurse=true preserves dirty submodule worktree' '
+ setup_basic &&
+ (
+ cd main &&
+ git config submodule.recurse true &&
+ echo "x" >main_file.t &&
+ echo "y" >sub/sub_file.t &&
+ git stash push &&
+ git stash pop &&
+ test_must_fail git -C sub diff --quiet
+ )
+'
+
test_done
diff --git a/t/t3908-stash-in-worktree.sh b/t/t3908-stash-in-worktree.sh
new file mode 100755
index 0000000000..2b2b366ef9
--- /dev/null
+++ b/t/t3908-stash-in-worktree.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Johannes E Schindelin
+#
+
+test_description='Test git stash in a worktree'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit initial &&
+ git worktree add wt &&
+ test_commit -C wt in-worktree
+'
+
+test_expect_success 'apply in subdirectory' '
+ mkdir wt/subdir &&
+ (
+ cd wt/subdir &&
+ echo modified >../initial.t &&
+ git stash &&
+ git stash apply >out
+ ) &&
+ grep "\.\.\/initial\.t" wt/subdir/out
+'
+
+test_done
diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh
index 8de36b7d12..e5116a76a1 100755
--- a/t/t4000-diff-format.sh
+++ b/t/t4000-diff-format.sh
@@ -78,7 +78,7 @@ test_expect_success 'git diff-files --no-patch --patch shows the patch' '
test_expect_success 'git diff-files --no-patch --patch-with-raw shows the patch and raw data' '
git diff-files --no-patch --patch-with-raw >actual &&
- grep -q "^:100644 100755 .* 0000000000000000000000000000000000000000 M path0\$" actual &&
+ grep -q "^:100644 100755 .* $ZERO_OID M path0\$" actual &&
tail -n +4 actual >actual-patch &&
compare_diff_patch expected actual-patch
'
diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh
index 3a6c21e825..cbcdd10464 100755
--- a/t/t4002-diff-basic.sh
+++ b/t/t4002-diff-basic.sh
@@ -7,123 +7,272 @@ test_description='Test diff raw-output.
'
. ./test-lib.sh
+
. "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh
-cat >.test-plain-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 040000 0000000000000000000000000000000000000000 6d50f65d3bdab91c63444294d38f08aeff328e42 A DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 5e5f22072bb39f6e12cf663a57cb634c76eefb49 M Z
+test_oid_init
+
+test_oid_cache <<\EOF
+aa_1 sha1:ccba72ad3888a3520b39efcf780b9ee64167535d
+aa_1 sha256:9febfbf18197819b2735c45291f138525d2476d59470f98239647544586ba403
+
+aa_2 sha1:6aa2b5335b16431a0ef71e5c0a28be69183cf6a2
+aa_2 sha256:6eaa3437de83f145a4aaa6ba355303075ade547b128ec6a2cd00a81ff7ce7a56
+
+an_1 sha1:7e426fb079479fd67f6d81f984e4ec649a44bc25
+an_1 sha256:8f92a0bec99e399a38e3bd0e1bf19fbf121e0160efb29b857df79d439f1c4536
+
+dd_1 sha1:bcc68ef997017466d5c9094bcf7692295f588c9a
+dd_1 sha256:07e17428b00639b85485d2b01083d219e2f3e3ba8579e9ca44e9cc8dd554d952
+
+df_1 sha1:6d50f65d3bdab91c63444294d38f08aeff328e42
+df_1 sha256:e367cecc27e9bf5451b1c65828cb21938d36a5f8e39c1b03ad6509cc36bb8e9d
+
+df_2 sha1:71420ab81e254145d26d6fc0cddee64c1acd4787
+df_2 sha256:0f0a86d10347ff6921d03a3c954679f3f1d14fa3d5cd82f57b32c09755f3a47d
+
+dfd1 sha1:68a6d8b91da11045cf4aa3a5ab9f2a781c701249
+dfd1 sha256:f3bd3265b02b6978ce86490d8ad026c573639c974b3de1d9faf30d8d5a77d3d5
+
+dm_1 sha1:141c1f1642328e4bc46a7d801a71da392e66791e
+dm_1 sha256:c89f8656e7b94e21ee5fbaf0e2149bbf783c51edbe2ce110349cac13059ee7ed
+
+dm_2 sha1:3c4d8de5fbad08572bab8e10eef8dbb264cf0231
+dm_2 sha256:83a572e37e0c94086294dae2cecc43d9131afd6f6c906e495c78972230b54988
+
+dn_1 sha1:35abde1506ddf806572ff4d407bd06885d0f8ee9
+dn_1 sha256:775d5852582070e620be63327bfa515fab8f71c7ac3e4f0c3cd6267b4377ba28
+
+ll_2 sha1:1d41122ebdd7a640f29d3c9cc4f9d70094374762
+ll_2 sha256:7917b4948a883cfed0a77d3d5a625dc8577d6ddcc3c6c3bbc56c4d4226a2246d
+
+md_1 sha1:03f24c8c4700babccfd28b654e7e8eac402ad6cd
+md_1 sha256:fc9f30369b978595ad685ba11ca9a17de0af16d79cd4b629975f4f1590033902
+
+md_2 sha1:103d9f89b50b9aad03054b579be5e7aa665f2d57
+md_2 sha256:fc78ec75275628762fe520479a6b2398dec295ce7aabcb1d15e5963c7b4e9317
+
+mm_1 sha1:b258508afb7ceb449981bd9d63d2d3e971bf8d34
+mm_1 sha256:a4b7847d228e900e3000285e240c20fd96f9dd41ce1445305f6eada126d4a04a
+
+mm_2 sha1:b431b272d829ff3aa4d1a5085f4394ab4d3305b6
+mm_2 sha256:3f8b83ea36aacf689bcf1a1290a9a8ed341564d32682ea6f76fea9a979186782
+
+mm_3 sha1:19989d4559aae417fedee240ccf2ba315ea4dc2b
+mm_3 sha256:71b3bfc5747ac033fff9ea0ab39ee453a3af2969890e75d6ef547b87544e2681
+
+mn_1 sha1:bd084b0c27c7b6cc34f11d6d0509a29be3caf970
+mn_1 sha256:47a67450583d7a329eb01a7c4ba644945af72c0ed2c7c95eb5a00d6e46d4d483
+
+mn_2 sha1:a716d58de4a570e0038f5c307bd8db34daea021f
+mn_2 sha256:f95104c1ebe27acb84bac25a7be98c71f6b8d3054b21f357a5be0c524ad97e08
+
+nm_1 sha1:c8f25781e8f1792e3e40b74225e20553041b5226
+nm_1 sha256:09baddc7afaa62e62e152c23c9c3ab94bf15a3894031e227e9be7fe68e1f4e49
+
+nm_2 sha1:cdb9a8c3da571502ac30225e9c17beccb8387983
+nm_2 sha256:58b5227956ac2d2a08d0efa513c0ae37430948b16791ea3869a1308dbf05536d
+
+na_1 sha1:15885881ea69115351c09b38371f0348a3fb8c67
+na_1 sha256:18e4fdd1670cd7968ee23d35bfd29e5418d56fb190c840094c1c57ceee0aad8f
+
+nd_1 sha1:a4e179e4291e5536a5e1c82e091052772d2c5a93
+nd_1 sha256:07dac9b01d00956ea0c65bd993d7de4864aeef2ed3cbb1255d9f1d949fcd6df6
+
+ss_1 sha1:40c959f984c8b89a2b02520d17f00d717f024397
+ss_1 sha256:50fc1b5df74d9910db2f9270993484235f15b69b75b01bcfb53e059289d14af9
+
+ss_2 sha1:2ac547ae9614a00d1b28275de608131f7a0e259f
+ss_2 sha256:a90f02e6044f1497d13db587d22ab12f90150a7d1e084afcf96065fab35ae2bc
+
+tt_1 sha1:4ac13458899ab908ef3b1128fa378daefc88d356
+tt_1 sha256:c53113c7dd5060e86b5b251428bd058f6726f66273c6a24bff1c61a04f498dd3
+
+tt_2 sha1:4c86f9a85fbc5e6804ee2e17a797538fbe785bca
+tt_2 sha256:0775f2a296129a7cf2862b46bc0e88c14d593f2773a3e3fb1c5193db6f5a7e77
+
+tt_3 sha1:c4e4a12231b9fa79a0053cb6077fcb21bb5b135a
+tt_3 sha256:47860f93cdd211f96443e0560f21c57ab6c2f4b0ac27ff03651a352e53fe8484
+
+z__1 sha1:7d670fdcdb9929f6c7dac196ff78689cd1c566a1
+z__1 sha256:44d0f37aff5e51cfcfdd1134c93a6419bcca7b9964f792ffcd5f9b4fcba1ee63
+
+z__2 sha1:5e5f22072bb39f6e12cf663a57cb634c76eefb49
+z__2 sha256:d29de162113190fed104eb5f010820cef4e315f89b9326e8497f7219fb737894
+
+z__3 sha1:1ba523955d5160681af65cb776411f574c1e8155
+z__3 sha256:07422d772b07794ab4369a5648e617719f89c2d2212cbeab05d97214b6471636
+
+zaa1 sha1:8acb8e9750e3f644bf323fcf3d338849db106c77
+zaa1 sha256:e79b029282c8abec2d9f3f7faceaf2a1405e02d1f368e66450ae66cf5b68d1f4
+
+zaa2 sha1:6c0b99286d0bce551ac4a7b3dff8b706edff3715
+zaa2 sha256:c82bd78c3e69ea1796e6b1a7a3ba45bb106c50e819296475b862123d3f5cc5a0
+
+zan1 sha1:087494262084cefee7ed484d20c8dc0580791272
+zan1 sha256:4b159eb3804d05599023dd074f771d06d02870f4ab24a7165add8ac3d703b8d3
+
+zdd1 sha1:879007efae624d2b1307214b24a956f0a8d686a8
+zdd1 sha256:eecfdd4d8092dd0363fb6d4548b54c6afc8982c3ed9b34e393f1d6a921d8eaa3
+
+zdm1 sha1:9b541b2275c06e3a7b13f28badf5294e2ae63df4
+zdm1 sha256:ab136e88e19a843c4bf7713d2090d5a2186ba16a6a80dacc12eeddd256a8e556
+
+zdm2 sha1:d77371d15817fcaa57eeec27f770c505ba974ec1
+zdm2 sha256:1c1a5f57363f46a15d95ce8527b3c2c158d88d16853b4acbf81bd20fd2c89a46
+
+zdn1 sha1:beb5d38c55283d280685ea21a0e50cfcc0ca064a
+zdn1 sha256:0f0eca66183617b0aa5ad74b256540329f841470922ca6760263c996d825eb18
+
+zmd1 sha1:d41fda41b7ec4de46b43cb7ea42a45001ae393d5
+zmd1 sha256:1ed32d481852eddf31a0ce12652a0ad14bf5b7a842667b5dbb0b50f35bf1c80a
+
+zmd2 sha1:a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9
+zmd2 sha256:b238da211b404f8917df2d9c6f7030535e904b2186131007a3c292ec6902f933
+
+zmm1 sha1:4ca22bae2527d3d9e1676498a0fba3b355bd1278
+zmm1 sha256:072b1d85b5f34fabc99dfa46008c5418df68302d3e317430006f49b32d244226
+
+zmm2 sha1:61422ba9c2c873416061a88cd40a59a35b576474
+zmm2 sha256:81dd5d2b3c5cda16fef552256aed4e2ea0802a8450a08f308a92142112ff6dda
+
+zmm3 sha1:697aad7715a1e7306ca76290a3dd4208fbaeddfa
+zmm3 sha256:8b10fab49e9be3414aa5e9a93d0e46f9569053440138a7c19a5eb5536d8e95bf
+
+zmn1 sha1:b16d7b25b869f2beb124efa53467d8a1550ad694
+zmn1 sha256:609e4f75d1295e844c826feeba213acb0b6cfc609adfe8ff705b19e3829ae3e9
+
+zmn2 sha1:a5c544c21cfcb07eb80a4d89a5b7d1570002edfd
+zmn2 sha256:d6d03edf2dc1a3b267a8205de5f41a2ff4b03def8c7ae02052b543fb09d589fc
+
+zna1 sha1:d12979c22fff69c59ca9409e7a8fe3ee25eaee80
+zna1 sha256:b37b80e789e8ea32aa323f004628f02013f632124b0282c7fe00a127d3c64c3c
+
+znd1 sha1:a18393c636b98e9bd7296b8b437ea4992b72440c
+znd1 sha256:af92a22eee8c38410a0c9d2b5135a10aeb052cbc7cf675541ed9a67bfcaf7cf9
+
+znm1 sha1:3fdbe17fd013303a2e981e1ca1c6cd6e72789087
+znm1 sha256:f75aeaa0c11e76918e381c105f0752932c6150e941fec565d24fa31098a13dc1
+
+znm2 sha1:7e09d6a3a14bd630913e8c75693cea32157b606d
+znm2 sha256:938d73cfbaa1c902a84fb5b3afd9736aa0590367fb9bd59c6c4d072ce70fcd6d
+EOF
+
+cat >.test-plain-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 040000 $(test_oid zero) $(test_oid df_1) A DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M TT
+:040000 040000 $(test_oid z__1) $(test_oid z__2) M Z
EOF
-cat >.test-recursive-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 100644 0000000000000000000000000000000000000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 A DF/DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M TT
-:000000 100644 0000000000000000000000000000000000000000 8acb8e9750e3f644bf323fcf3d338849db106c77 A Z/AA
-:000000 100644 0000000000000000000000000000000000000000 087494262084cefee7ed484d20c8dc0580791272 A Z/AN
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D Z/DD
-:100644 000000 9b541b2275c06e3a7b13f28badf5294e2ae63df4 0000000000000000000000000000000000000000 D Z/DM
-:100644 000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a 0000000000000000000000000000000000000000 D Z/DN
-:100644 100644 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 M Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 61422ba9c2c873416061a88cd40a59a35b576474 M Z/MM
-:100644 100644 b16d7b25b869f2beb124efa53467d8a1550ad694 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd M Z/MN
+cat >.test-recursive-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 100644 $(test_oid zero) $(test_oid dfd1) A DF/DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M TT
+:000000 100644 $(test_oid zero) $(test_oid zaa1) A Z/AA
+:000000 100644 $(test_oid zero) $(test_oid zan1) A Z/AN
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D Z/DD
+:100644 000000 $(test_oid zdm1) $(test_oid zero) D Z/DM
+:100644 000000 $(test_oid zdn1) $(test_oid zero) D Z/DN
+:100644 100644 $(test_oid zmd1) $(test_oid zmd2) M Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm2) M Z/MM
+:100644 100644 $(test_oid zmn1) $(test_oid zmn2) M Z/MN
EOF
-cat >.test-plain-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 1ba523955d5160681af65cb776411f574c1e8155 M Z
+cat >.test-plain-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M TT
+:040000 040000 $(test_oid z__1) $(test_oid z__3) M Z
EOF
-cat >.test-recursive-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:000000 100644 0000000000000000000000000000000000000000 6c0b99286d0bce551ac4a7b3dff8b706edff3715 A Z/AA
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D Z/DD
-:100644 100644 9b541b2275c06e3a7b13f28badf5294e2ae63df4 d77371d15817fcaa57eeec27f770c505ba974ec1 M Z/DM
-:100644 000000 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 0000000000000000000000000000000000000000 D Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 697aad7715a1e7306ca76290a3dd4208fbaeddfa M Z/MM
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M Z/NM
+cat >.test-recursive-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M TT
+:000000 100644 $(test_oid zero) $(test_oid zaa2) A Z/AA
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D Z/DD
+:100644 100644 $(test_oid zdm1) $(test_oid zdm2) M Z/DM
+:100644 000000 $(test_oid zmd1) $(test_oid zero) D Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm3) M Z/MM
+:000000 100644 $(test_oid zero) $(test_oid zna1) A Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M Z/NM
EOF
-cat >.test-plain-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:040000 000000 6d50f65d3bdab91c63444294d38f08aeff328e42 0000000000000000000000000000000000000000 D DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:040000 040000 5e5f22072bb39f6e12cf663a57cb634c76eefb49 1ba523955d5160681af65cb776411f574c1e8155 M Z
+cat >.test-plain-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:040000 000000 $(test_oid df_1) $(test_oid zero) D DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M TT
+:040000 040000 $(test_oid z__2) $(test_oid z__3) M Z
EOF
-cat >.test-recursive-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:100644 000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 0000000000000000000000000000000000000000 D DF/DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:100644 100644 8acb8e9750e3f644bf323fcf3d338849db106c77 6c0b99286d0bce551ac4a7b3dff8b706edff3715 M Z/AA
-:100644 000000 087494262084cefee7ed484d20c8dc0580791272 0000000000000000000000000000000000000000 D Z/AN
-:000000 100644 0000000000000000000000000000000000000000 d77371d15817fcaa57eeec27f770c505ba974ec1 A Z/DM
-:000000 100644 0000000000000000000000000000000000000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a A Z/DN
-:100644 000000 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 0000000000000000000000000000000000000000 D Z/MD
-:100644 100644 61422ba9c2c873416061a88cd40a59a35b576474 697aad7715a1e7306ca76290a3dd4208fbaeddfa M Z/MM
-:100644 100644 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd b16d7b25b869f2beb124efa53467d8a1550ad694 M Z/MN
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M Z/NM
+cat >.test-recursive-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:100644 000000 $(test_oid dfd1) $(test_oid zero) D DF/DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M TT
+:100644 100644 $(test_oid zaa1) $(test_oid zaa2) M Z/AA
+:100644 000000 $(test_oid zan1) $(test_oid zero) D Z/AN
+:000000 100644 $(test_oid zero) $(test_oid zdm2) A Z/DM
+:000000 100644 $(test_oid zero) $(test_oid zdn1) A Z/DN
+:100644 000000 $(test_oid zmd2) $(test_oid zero) D Z/MD
+:100644 100644 $(test_oid zmm2) $(test_oid zmm3) M Z/MM
+:100644 100644 $(test_oid zmn2) $(test_oid zmn1) M Z/MN
+:000000 100644 $(test_oid zero) $(test_oid zna1) A Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M Z/NM
EOF
cmp_diff_files_output () {
diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh
index 3641fd84d6..b63bdf031f 100755
--- a/t/t4009-diff-rename-4.sh
+++ b/t/t4009-diff-rename-4.sh
@@ -14,6 +14,7 @@ test_expect_success \
'cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
echo frotz >rezrov &&
git update-index --add COPYING rezrov &&
+ orig=$(git hash-object COPYING) &&
tree=$(git write-tree) &&
echo $tree'
@@ -22,6 +23,8 @@ test_expect_success \
'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 &&
sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 &&
rm -f COPYING &&
+ c1=$(git hash-object COPYING.1) &&
+ c2=$(git hash-object COPYING.2) &&
git update-index --add --remove COPYING COPYING.?'
# tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2,
@@ -31,11 +34,11 @@ test_expect_success \
git diff-index -z -C $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
COPYING
COPYING.1
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 R1234
+:100644 100644 $orig $c2 R1234
COPYING
COPYING.2
EOF
@@ -57,10 +60,10 @@ test_expect_success \
# about rezrov.
git diff-index -z -C $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M
+cat >expected <<EOF
+:100644 100644 $orig $c2 M
COPYING
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+:100644 100644 $orig $c1 C1234
COPYING
COPYING.1
EOF
@@ -82,8 +85,8 @@ test_expect_success \
git update-index --add --remove COPYING COPYING.1'
git diff-index -z -C --find-copies-harder $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
COPYING
COPYING.1
EOF
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index 281f8fad0c..e5ca359edf 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -17,11 +17,15 @@ test_expect_success \
'echo frotz >file0 &&
mkdir path1 &&
echo rezrov >path1/file1 &&
+ before0=$(git hash-object file0) &&
+ before1=$(git hash-object path1/file1) &&
git update-index --add file0 path1/file1 &&
tree=$(git write-tree) &&
echo "$tree" &&
echo nitfol >file0 &&
echo yomin >path1/file1 &&
+ after0=$(git hash-object file0) &&
+ after1=$(git hash-object path1/file1) &&
git update-index file0 path1/file1'
cat >expected <<\EOF
@@ -31,32 +35,32 @@ test_expect_success \
'git diff-index --cached $tree -- path >current &&
compare_diff_raw current expected'
-cat >expected <<\EOF
-:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+cat >expected <<EOF
+:100644 100644 $before1 $after1 M path1/file1
EOF
test_expect_success \
'limit to path1 should show path1/file1' \
'git diff-index --cached $tree -- path1 >current &&
compare_diff_raw current expected'
-cat >expected <<\EOF
-:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+cat >expected <<EOF
+:100644 100644 $before1 $after1 M path1/file1
EOF
test_expect_success \
'limit to path1/ should show path1/file1' \
'git diff-index --cached $tree -- path1/ >current &&
compare_diff_raw current expected'
-cat >expected <<\EOF
-:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+cat >expected <<EOF
+:100644 100644 $before1 $after1 M path1/file1
EOF
test_expect_success \
'"*file1" should show path1/file1' \
'git diff-index --cached $tree -- "*file1" >current &&
compare_diff_raw current expected'
-cat >expected <<\EOF
-:100644 100644 8e4020bb5a8d8c873b25de15933e75cc0fc275df dca6b92303befc93086aa025d90a5facd7eb2812 M file0
+cat >expected <<EOF
+:100644 100644 $before0 $after0 M file0
EOF
test_expect_success \
'limit to file0 should show file0' \
diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh
index 5ae19b987d..717034bb50 100755
--- a/t/t4011-diff-symlink.sh
+++ b/t/t4011-diff-symlink.sh
@@ -9,11 +9,24 @@ test_description='Test diff of symlinks.
. ./test-lib.sh
. "$TEST_DIRECTORY"/diff-lib.sh
+# Print the short OID of a symlink with the given name.
+symlink_oid () {
+ local oid=$(printf "%s" "$1" | git hash-object --stdin) &&
+ git rev-parse --short "$oid"
+}
+
+# Print the short OID of the given file.
+short_oid () {
+ local oid=$(git hash-object "$1") &&
+ git rev-parse --short "$oid"
+}
+
test_expect_success 'diff new symlink and file' '
- cat >expected <<-\EOF &&
+ symlink=$(symlink_oid xyzzy) &&
+ cat >expected <<-EOF &&
diff --git a/frotz b/frotz
new file mode 120000
- index 0000000..7c465af
+ index 0000000..$symlink
--- /dev/null
+++ b/frotz
@@ -0,0 +1 @@
@@ -21,7 +34,7 @@ test_expect_success 'diff new symlink and file' '
\ No newline at end of file
diff --git a/nitfol b/nitfol
new file mode 100644
- index 0000000..7c465af
+ index 0000000..$symlink
--- /dev/null
+++ b/nitfol
@@ -0,0 +1 @@
@@ -46,10 +59,10 @@ test_expect_success 'diff unchanged symlink and file' '
'
test_expect_success 'diff removed symlink and file' '
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
diff --git a/frotz b/frotz
deleted file mode 120000
- index 7c465af..0000000
+ index $symlink..0000000
--- a/frotz
+++ /dev/null
@@ -1 +0,0 @@
@@ -57,7 +70,7 @@ test_expect_success 'diff removed symlink and file' '
\ No newline at end of file
diff --git a/nitfol b/nitfol
deleted file mode 100644
- index 7c465af..0000000
+ index $symlink..0000000
--- a/nitfol
+++ /dev/null
@@ -1 +0,0 @@
@@ -90,9 +103,10 @@ test_expect_success 'diff identical, but newly created symlink and file' '
'
test_expect_success 'diff different symlink and file' '
- cat >expected <<-\EOF &&
+ new=$(symlink_oid yxyyz) &&
+ cat >expected <<-EOF &&
diff --git a/frotz b/frotz
- index 7c465af..df1db54 120000
+ index $symlink..$new 120000
--- a/frotz
+++ b/frotz
@@ -1 +1 @@
@@ -101,7 +115,7 @@ test_expect_success 'diff different symlink and file' '
+yxyyz
\ No newline at end of file
diff --git a/nitfol b/nitfol
- index 7c465af..df1db54 100644
+ index $symlink..$new 100644
--- a/nitfol
+++ b/nitfol
@@ -1 +1 @@
@@ -137,14 +151,16 @@ test_expect_success SYMLINKS 'setup symlinks with attributes' '
'
test_expect_success SYMLINKS 'symlinks do not respect userdiff config by path' '
- cat >expect <<-\EOF &&
+ file=$(short_oid file.bin) &&
+ link=$(symlink_oid file.bin) &&
+ cat >expect <<-EOF &&
diff --git a/file.bin b/file.bin
new file mode 100644
- index 0000000..d95f3ad
+ index 0000000..$file
Binary files /dev/null and b/file.bin differ
diff --git a/link.bin b/link.bin
new file mode 120000
- index 0000000..dce41ec
+ index 0000000..$link
--- /dev/null
+++ b/link.bin
@@ -0,0 +1 @@
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index a9054d2db1..5ac94b390d 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -7,9 +7,6 @@ test_description='Various diff formatting options'
. ./test-lib.sh
-LF='
-'
-
test_expect_success setup '
GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" &&
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index ca7debf1d4..b653dd7d44 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -9,7 +9,6 @@ test_description='various format-patch tests'
. "$TEST_DIRECTORY"/lib-terminal.sh
test_expect_success setup '
-
for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
cat file >elif &&
git add file elif &&
@@ -34,7 +33,8 @@ test_expect_success setup '
git commit -m "Side changes #3 with \\n backslash-n in it." &&
git checkout master &&
- git diff-tree -p C2 | git apply --index &&
+ git diff-tree -p C2 >patch &&
+ git apply --index <patch &&
test_tick &&
git commit -m "Master accepts moral equivalent of #2" &&
@@ -59,33 +59,28 @@ test_expect_success setup '
git checkout master
'
-test_expect_success "format-patch --ignore-if-in-upstream" '
-
+test_expect_success 'format-patch --ignore-if-in-upstream' '
git format-patch --stdout master..side >patch0 &&
- cnt=$(grep "^From " patch0 | wc -l) &&
- test $cnt = 3
-
+ grep "^From " patch0 >from0 &&
+ test_line_count = 3 from0
'
-test_expect_success "format-patch --ignore-if-in-upstream" '
-
+test_expect_success 'format-patch --ignore-if-in-upstream' '
git format-patch --stdout \
--ignore-if-in-upstream master..side >patch1 &&
- cnt=$(grep "^From " patch1 | wc -l) &&
- test $cnt = 2
-
+ grep "^From " patch1 >from1 &&
+ test_line_count = 2 from1
'
-test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
+test_expect_success 'format-patch --ignore-if-in-upstream handles tags' '
git tag -a v1 -m tag side &&
git tag -a v2 -m tag master &&
git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
- cnt=$(grep "^From " patch1 | wc -l) &&
- test $cnt = 2
+ grep "^From " patch1 >from1 &&
+ test_line_count = 2 from1
'
test_expect_success "format-patch doesn't consider merge commits" '
-
git checkout -b slave master &&
echo "Another line" >>file &&
test_tick &&
@@ -96,148 +91,138 @@ test_expect_success "format-patch doesn't consider merge commits" '
git checkout -b merger master &&
test_tick &&
git merge --no-ff slave &&
- cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
- test $cnt = 3
+ git format-patch -3 --stdout >patch &&
+ grep "^From " patch >from &&
+ test_line_count = 3 from
'
-test_expect_success "format-patch result applies" '
-
+test_expect_success 'format-patch result applies' '
git checkout -b rebuild-0 master &&
git am -3 patch0 &&
- cnt=$(git rev-list master.. | wc -l) &&
- test $cnt = 2
+ git rev-list master.. >list &&
+ test_line_count = 2 list
'
-test_expect_success "format-patch --ignore-if-in-upstream result applies" '
-
+test_expect_success 'format-patch --ignore-if-in-upstream result applies' '
git checkout -b rebuild-1 master &&
git am -3 patch1 &&
- cnt=$(git rev-list master.. | wc -l) &&
- test $cnt = 2
+ git rev-list master.. >list &&
+ test_line_count = 2 list
'
test_expect_success 'commit did not screw up the log message' '
-
- git cat-file commit side | grep "^Side .* with .* backslash-n"
-
+ git cat-file commit side >actual &&
+ grep "^Side .* with .* backslash-n" actual
'
test_expect_success 'format-patch did not screw up the log message' '
-
grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
-
'
test_expect_success 'replay did not screw up the log message' '
-
- git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
-
+ git cat-file commit rebuild-1 >actual &&
+ grep "^Side .* with .* backslash-n" actual
'
test_expect_success 'extra headers' '
-
git config format.headers "To: R E Cipient <rcipient@example.com>
" &&
git config --add format.headers "Cc: S E Cipient <scipient@example.com>
" &&
- git format-patch --stdout master..side > patch2 &&
- sed -e "/^\$/q" patch2 > hdrs2 &&
+ git format-patch --stdout master..side >patch2 &&
+ sed -e "/^\$/q" patch2 >hdrs2 &&
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
-
'
test_expect_success 'extra headers without newlines' '
-
git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
git format-patch --stdout master..side >patch3 &&
- sed -e "/^\$/q" patch3 > hdrs3 &&
+ sed -e "/^\$/q" patch3 >hdrs3 &&
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
-
'
test_expect_success 'extra headers with multiple To:s' '
-
git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
- git format-patch --stdout master..side > patch4 &&
- sed -e "/^\$/q" patch4 > hdrs4 &&
+ git format-patch --stdout master..side >patch4 &&
+ sed -e "/^\$/q" patch4 >hdrs4 &&
grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
'
test_expect_success 'additional command line cc (ascii)' '
-
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
- git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
- grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
- grep "^ *S E Cipient <scipient@example.com>\$" patch5
+ git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side >patch5 &&
+ sed -e "/^\$/q" patch5 >hdrs5 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
+ grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
'
test_expect_failure 'additional command line cc (rfc822)' '
-
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
- git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
- grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
- grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
+ git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side >patch5 &&
+ sed -e "/^\$/q" patch5 >hdrs5 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
+ grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
'
test_expect_success 'command line headers' '
-
git config --unset-all format.headers &&
- git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
- grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
+ git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side >patch6 &&
+ sed -e "/^\$/q" patch6 >hdrs6 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
'
test_expect_success 'configuration headers and command line headers' '
-
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
- git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
- grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
- grep "^ *S E Cipient <scipient@example.com>\$" patch7
+ git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side >patch7 &&
+ sed -e "/^\$/q" patch7 >hdrs7 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
+ grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
'
test_expect_success 'command line To: header (ascii)' '
-
git config --unset-all format.headers &&
- git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: R E Cipient <rcipient@example.com>\$" patch8
+ git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
+ sed -e "/^\$/q" patch8 >hdrs8 &&
+ grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
'
test_expect_failure 'command line To: header (rfc822)' '
-
- git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
+ git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
+ sed -e "/^\$/q" patch8 >hdrs8 &&
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
'
test_expect_failure 'command line To: header (rfc2047)' '
-
- git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
+ git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
+ sed -e "/^\$/q" patch8 >hdrs8 &&
+ grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
'
test_expect_success 'configuration To: header (ascii)' '
-
git config format.to "R E Cipient <rcipient@example.com>" &&
- git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: R E Cipient <rcipient@example.com>\$" patch9
+ git format-patch --stdout master..side >patch9 &&
+ sed -e "/^\$/q" patch9 >hdrs9 &&
+ grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
'
test_expect_failure 'configuration To: header (rfc822)' '
-
git config format.to "R. E. Cipient <rcipient@example.com>" &&
- git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
+ git format-patch --stdout master..side >patch9 &&
+ sed -e "/^\$/q" patch9 >hdrs9 &&
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
'
test_expect_failure 'configuration To: header (rfc2047)' '
-
git config format.to "R Ä Cipient <rcipient@example.com>" &&
- git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
+ git format-patch --stdout master..side >patch9 &&
+ sed -e "/^\$/q" patch9 >hdrs9 &&
+ grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
'
# check_patch <patch>: Verify that <patch> looks like a half-sane
@@ -249,89 +234,79 @@ check_patch () {
}
test_expect_success 'format.from=false' '
-
- git -c format.from=false format-patch --stdout master..side |
- sed -e "/^\$/q" >patch &&
+ git -c format.from=false format-patch --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
check_patch patch &&
- ! grep "^From: C O Mitter <committer@example.com>\$" patch
+ ! grep "^From: C O Mitter <committer@example.com>\$" hdrs
'
test_expect_success 'format.from=true' '
-
- git -c format.from=true format-patch --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- grep "^From: C O Mitter <committer@example.com>\$" patch
+ git -c format.from=true format-patch --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ grep "^From: C O Mitter <committer@example.com>\$" hdrs
'
test_expect_success 'format.from with address' '
-
- git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- grep "^From: F R Om <from@example.com>\$" patch
+ git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ grep "^From: F R Om <from@example.com>\$" hdrs
'
test_expect_success '--no-from overrides format.from' '
-
- git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- ! grep "^From: F R Om <from@example.com>\$" patch
+ git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ ! grep "^From: F R Om <from@example.com>\$" hdrs
'
test_expect_success '--from overrides format.from' '
-
- git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- ! grep "^From: F R Om <from@example.com>\$" patch
+ git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ ! grep "^From: F R Om <from@example.com>\$" hdrs
'
test_expect_success '--no-to overrides config.to' '
-
git config --replace-all format.to \
"R E Cipient <rcipient@example.com>" &&
- git format-patch --no-to --stdout master..side |
- sed -e "/^\$/q" >patch10 &&
- check_patch patch10 &&
- ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
+ git format-patch --no-to --stdout master..side >patch10 &&
+ sed -e "/^\$/q" patch10 >hdrs10 &&
+ check_patch hdrs10 &&
+ ! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
'
test_expect_success '--no-to and --to replaces config.to' '
-
git config --replace-all format.to \
"Someone <someone@out.there>" &&
git format-patch --no-to --to="Someone Else <else@out.there>" \
- --stdout master..side |
- sed -e "/^\$/q" >patch11 &&
- check_patch patch11 &&
- ! grep "^To: Someone <someone@out.there>\$" patch11 &&
- grep "^To: Someone Else <else@out.there>\$" patch11
+ --stdout master..side >patch11 &&
+ sed -e "/^\$/q" patch11 >hdrs11 &&
+ check_patch hdrs11 &&
+ ! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
+ grep "^To: Someone Else <else@out.there>\$" hdrs11
'
test_expect_success '--no-cc overrides config.cc' '
-
git config --replace-all format.cc \
"C E Cipient <rcipient@example.com>" &&
- git format-patch --no-cc --stdout master..side |
- sed -e "/^\$/q" >patch12 &&
- check_patch patch12 &&
- ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
+ git format-patch --no-cc --stdout master..side >patch12 &&
+ sed -e "/^\$/q" patch12 >hdrs12 &&
+ check_patch hdrs12 &&
+ ! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
'
test_expect_success '--no-add-header overrides config.headers' '
-
git config --replace-all format.headers \
"Header1: B E Cipient <rcipient@example.com>" &&
- git format-patch --no-add-header --stdout master..side |
- sed -e "/^\$/q" >patch13 &&
- check_patch patch13 &&
- ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
+ git format-patch --no-add-header --stdout master..side >patch13 &&
+ sed -e "/^\$/q" patch13 >hdrs13 &&
+ check_patch hdrs13 &&
+ ! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
'
test_expect_success 'multiple files' '
-
rm -rf patches/ &&
git checkout side &&
git format-patch -o patches/ master &&
@@ -357,7 +332,7 @@ test_expect_success 'reroll count (-v)' '
check_threading () {
expect="$1" &&
shift &&
- (git format-patch --stdout "$@"; echo $? > status.out) |
+ git format-patch --stdout "$@" >patch &&
# Prints everything between the Message-ID and In-Reply-To,
# and replaces all Message-ID-lookalikes by a sequence number
perl -ne '
@@ -372,12 +347,11 @@ check_threading () {
print;
}
print "---\n" if /^From /i;
- ' > actual &&
- test 0 = "$(cat status.out)" &&
+ ' <patch >actual &&
test_cmp "$expect" actual
}
-cat >> expect.no-threading <<EOF
+cat >>expect.no-threading <<EOF
---
---
---
@@ -388,7 +362,7 @@ test_expect_success 'no threading' '
check_threading expect.no-threading master
'
-cat > expect.thread <<EOF
+cat >expect.thread <<EOF
---
Message-Id: <0>
---
@@ -405,7 +379,7 @@ test_expect_success 'thread' '
check_threading expect.thread --thread master
'
-cat > expect.in-reply-to <<EOF
+cat >expect.in-reply-to <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -425,7 +399,7 @@ test_expect_success 'thread in-reply-to' '
--thread master
'
-cat > expect.cover-letter <<EOF
+cat >expect.cover-letter <<EOF
---
Message-Id: <0>
---
@@ -446,7 +420,7 @@ test_expect_success 'thread cover-letter' '
check_threading expect.cover-letter --cover-letter --thread master
'
-cat > expect.cl-irt <<EOF
+cat >expect.cl-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -478,7 +452,7 @@ test_expect_success 'thread explicit shallow' '
--in-reply-to="<test.message>" --thread=shallow master
'
-cat > expect.deep <<EOF
+cat >expect.deep <<EOF
---
Message-Id: <0>
---
@@ -496,7 +470,7 @@ test_expect_success 'thread deep' '
check_threading expect.deep --thread=deep master
'
-cat > expect.deep-irt <<EOF
+cat >expect.deep-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -519,7 +493,7 @@ test_expect_success 'thread deep in-reply-to' '
--in-reply-to="<test.message>" master
'
-cat > expect.deep-cl <<EOF
+cat >expect.deep-cl <<EOF
---
Message-Id: <0>
---
@@ -543,7 +517,7 @@ test_expect_success 'thread deep cover-letter' '
check_threading expect.deep-cl --cover-letter --thread=deep master
'
-cat > expect.deep-cl-irt <<EOF
+cat >expect.deep-cl-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -594,7 +568,6 @@ test_expect_success 'thread config + --no-thread' '
'
test_expect_success 'excessive subject' '
-
rm -rf patches/ &&
git checkout side &&
before=$(git hash-object file) &&
@@ -622,10 +595,9 @@ test_expect_success 'cover-letter inherits diff options' '
! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
git format-patch --cover-letter -1 -M &&
grep "file => foo .* 0 *\$" 0000-cover-letter.patch
-
'
-cat > expect << EOF
+cat >expect <<EOF
This is an excessively long subject line for a message due to the
habit some projects have of not having a short, one-line subject at
the start of the commit message, but rather sticking a whole
@@ -636,14 +608,12 @@ cat > expect << EOF
EOF
test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
-
git format-patch --cover-letter -2 &&
- sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
+ sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
test_cmp expect output
-
'
-cat > expect << EOF
+cat >expect <<EOF
index $before..$after 100644
--- a/file
+++ b/file
@@ -656,16 +626,14 @@ index $before..$after 100644
EOF
test_expect_success 'format-patch respects -U' '
-
git format-patch -U4 -2 &&
sed -e "1,/^diff/d" -e "/^+5/q" \
<0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
>output &&
test_cmp expect output
-
'
-cat > expect << EOF
+cat >expect <<EOF
diff --git a/file b/file
index $before..$after 100644
@@ -679,11 +647,9 @@ index $before..$after 100644
EOF
test_expect_success 'format-patch -p suppresses stat' '
-
git format-patch -p -2 &&
- sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
+ sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
test_cmp expect output
-
'
test_expect_success 'format-patch from a subdirectory (1)' '
@@ -736,7 +702,7 @@ test_expect_success 'format-patch from a subdirectory (3)' '
'
test_expect_success 'format-patch --in-reply-to' '
- git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
+ 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
'
@@ -827,21 +793,56 @@ test_expect_success 'format-patch with multiple notes refs' '
! grep "this is note 2" out
'
-echo "fatal: --name-only does not make sense" > expect.name-only
-echo "fatal: --name-status does not make sense" > expect.name-status
-echo "fatal: --check does not make sense" > expect.check
+test_expect_success 'format-patch with multiple notes refs in config' '
+ test_when_finished "test_unconfig format.notes" &&
+
+ git notes --ref note1 add -m "this is note 1" HEAD &&
+ test_when_finished git notes --ref note1 remove HEAD &&
+ git notes --ref note2 add -m "this is note 2" HEAD &&
+ test_when_finished git notes --ref note2 remove HEAD &&
+
+ git config format.notes note1 &&
+ git format-patch -1 --stdout >out &&
+ grep "this is note 1" out &&
+ ! grep "this is note 2" out &&
+ git config format.notes note2 &&
+ git format-patch -1 --stdout >out &&
+ ! grep "this is note 1" out &&
+ grep "this is note 2" out &&
+ git config --add format.notes note1 &&
+ git format-patch -1 --stdout >out &&
+ grep "this is note 1" out &&
+ grep "this is note 2" out &&
+
+ git config --replace-all format.notes note1 &&
+ git config --add format.notes false &&
+ git format-patch -1 --stdout >out &&
+ ! grep "this is note 1" out &&
+ ! grep "this is note 2" out &&
+ git config --add format.notes note2 &&
+ git format-patch -1 --stdout >out &&
+ ! grep "this is note 1" out &&
+ grep "this is note 2" out
+'
+
+echo "fatal: --name-only does not make sense" >expect.name-only
+echo "fatal: --name-status does not make sense" >expect.name-status
+echo "fatal: --check does not make sense" >expect.check
test_expect_success 'options no longer allowed for format-patch' '
- test_must_fail git format-patch --name-only 2> output &&
+ test_must_fail git format-patch --name-only 2>output &&
test_i18ncmp expect.name-only output &&
- test_must_fail git format-patch --name-status 2> output &&
+ test_must_fail git format-patch --name-status 2>output &&
test_i18ncmp expect.name-status output &&
- test_must_fail git format-patch --check 2> output &&
- test_i18ncmp expect.check output'
+ test_must_fail git format-patch --check 2>output &&
+ test_i18ncmp expect.check output
+'
test_expect_success 'format-patch --numstat should produce a patch' '
- git format-patch --numstat --stdout master..side > output &&
- test 5 = $(grep "^diff --git a/" output | wc -l)'
+ git format-patch --numstat --stdout master..side >output &&
+ grep "^diff --git a/" output >diff &&
+ test_line_count = 5 diff
+'
test_expect_success 'format-patch -- <path>' '
git format-patch master..side -- file 2>error &&
@@ -852,20 +853,25 @@ test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
git format-patch --ignore-if-in-upstream HEAD
'
-git_version="$(git --version | sed "s/.* //")"
+test_expect_success 'get git version' '
+ git_version=$(git --version) &&
+ git_version=${git_version##* }
+'
signature() {
printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
}
test_expect_success 'format-patch default signature' '
- git format-patch --stdout -1 | tail -n 3 >output &&
+ git format-patch --stdout -1 >patch &&
+ tail -n 3 patch >output &&
signature >expect &&
test_cmp expect output
'
test_expect_success 'format-patch --signature' '
- git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
+ git format-patch --stdout --signature="my sig" -1 >patch &&
+ tail -n 3 patch >output &&
signature "my sig" >expect &&
test_cmp expect output
'
@@ -897,8 +903,8 @@ test_expect_success 'format-patch --signature --cover-letter' '
git config --unset-all format.signature &&
git format-patch --stdout --signature="my sig" --cover-letter \
-1 >output &&
- grep "my sig" output &&
- test 2 = $(grep "my sig" output | wc -l)
+ grep "my sig" output >sig &&
+ test_line_count = 2 sig
'
test_expect_success 'format.signature="" suppresses signatures' '
@@ -935,7 +941,7 @@ test_expect_success 'prepare mail-signature input' '
test_expect_success '--signature-file=file works' '
git format-patch --stdout --signature-file=mail-signature -1 >output &&
check_patch output &&
- sed -e "1,/^-- \$/d" <output >actual &&
+ sed -e "1,/^-- \$/d" output >actual &&
{
cat mail-signature && echo
} >expect &&
@@ -946,7 +952,7 @@ test_expect_success 'format.signaturefile works' '
test_config format.signaturefile mail-signature &&
git format-patch --stdout -1 >output &&
check_patch output &&
- sed -e "1,/^-- \$/d" <output >actual &&
+ sed -e "1,/^-- \$/d" output >actual &&
{
cat mail-signature && echo
} >expect &&
@@ -968,7 +974,7 @@ test_expect_success '--signature-file overrides format.signaturefile' '
git format-patch --stdout \
--signature-file=other-mail-signature -1 >output &&
check_patch output &&
- sed -e "1,/^-- \$/d" <output >actual &&
+ sed -e "1,/^-- \$/d" output >actual &&
{
cat other-mail-signature && echo
} >expect &&
@@ -1037,7 +1043,7 @@ test_expect_success 'format-patch wraps extremely long subject (ascii)' '
git add file &&
git commit -m "$M512" &&
git format-patch --stdout -1 >patch &&
- sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
+ sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
test_cmp expect subject
'
@@ -1076,7 +1082,7 @@ test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
git add file &&
git commit -m "$M512" &&
git format-patch --stdout -1 >patch &&
- sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
+ sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
test_cmp expect subject
'
@@ -1085,7 +1091,7 @@ check_author() {
git add file &&
GIT_AUTHOR_NAME=$1 git commit -m author-check &&
git format-patch --stdout -1 >patch &&
- sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
+ sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
test_cmp expect actual
}
@@ -1205,7 +1211,7 @@ test_expect_success '--from=ident replaces author' '
From: A U Thor <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1217,7 +1223,7 @@ test_expect_success '--from uses committer ident' '
From: A U Thor <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1227,7 +1233,7 @@ test_expect_success '--from omits redundant in-body header' '
From: A U Thor <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1242,7 +1248,7 @@ test_expect_success 'in-body headers trigger content encoding' '
From: éxötìc <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1256,283 +1262,283 @@ append_signoff()
test_expect_success 'signoff: commit with no body' '
append_signoff </dev/null >actual &&
- cat <<\EOF | sed "s/EOL$//" >expected &&
-4:Subject: [PATCH] EOL
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat <<-\EOF | sed "s/EOL$//" >expect &&
+ 4:Subject: [PATCH] EOL
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: commit with only subject' '
echo subject | append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: commit with only subject that does not end with NL' '
printf subject | append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: no existing signoffs' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ body
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: no existing signoffs and no trailing NL' '
printf "subject\n\nbody" | append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: some random signoff' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: my@house
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: my@house
-12:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Signed-off-by: my@house
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: my@house
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: misc conforming footer elements' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: my@house
-(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
-Tested-by: Some One <someone@example.com>
-Bug: 1234
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: my@house
-15:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Signed-off-by: my@house
+ (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
+ Tested-by: Some One <someone@example.com>
+ Bug: 1234
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: my@house
+ 15:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: some random signoff-alike' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
-Fooled-by-me: my@house
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-11:
-12:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ body
+ Fooled-by-me: my@house
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 11:
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: not really a signoff' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-I want to mention about Signed-off-by: here.
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:I want to mention about Signed-off-by: here.
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ I want to mention about Signed-off-by: here.
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:I want to mention about Signed-off-by: here.
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: not really a signoff (2)' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-My unfortunate
-Signed-off-by: example happens to be wrapped here.
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:Signed-off-by: example happens to be wrapped here.
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ My unfortunate
+ Signed-off-by: example happens to be wrapped here.
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:Signed-off-by: example happens to be wrapped here.
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-Signed-off-by: my@house
-Signed-off-by: your@house
+ Signed-off-by: my@house
+ Signed-off-by: your@house
-A lot of houses.
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: my@house
-10:Signed-off-by: your@house
-11:
-13:
-14:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ A lot of houses.
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: my@house
+ 10:Signed-off-by: your@house
+ 11:
+ 13:
+ 14:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: the same signoff at the end' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: C O Mitter <committer@example.com>
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: the same signoff NOT at the end' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: C O Mitter <committer@example.com>
-Signed-off-by: my@house
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-12:Signed-off-by: my@house
-EOF
- test_cmp expected actual
+ Signed-off-by: C O Mitter <committer@example.com>
+ Signed-off-by: my@house
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ 12:Signed-off-by: my@house
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: tolerate garbage in conforming footer' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Tested-by: my@house
-Some Trash
-Signed-off-by: C O Mitter <committer@example.com>
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-13:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Tested-by: my@house
+ Some Trash
+ Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 13:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: respect trailer config' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-Myfooter: x
-Some Trash
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-11:
-12:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual &&
+ Myfooter: x
+ Some Trash
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 11:
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual &&
test_config trailer.Myfooter.ifexists add &&
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-Myfooter: x
-Some Trash
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Myfooter: x
+ Some Trash
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Reviewed-id: Noone
-Tested-by: my@house
-Change-id: Ideadbeef
-Signed-off-by: C O Mitter <committer@example.com>
-Bug: 1234
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-14:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Reviewed-id: Noone
+ Tested-by: my@house
+ Change-id: Ideadbeef
+ Signed-off-by: C O Mitter <committer@example.com>
+ Bug: 1234
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 14:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'format patch ignores color.ui' '
@@ -1543,46 +1549,218 @@ test_expect_success 'format patch ignores color.ui' '
test_cmp expect actual
'
+test_expect_success 'cover letter with invalid --cover-from-description and config' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_must_fail git format-patch --cover-letter --cover-from-description garbage master &&
+ test_config format.coverFromDescription garbage &&
+ test_must_fail git format-patch --cover-letter master
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = default' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription default &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description default' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description default master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = none' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription none &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ ! grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description none' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description none master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ ! grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = message' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription message &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description message' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description message master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = subject' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription subject &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description subject' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description subject master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = auto (short subject line)' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription auto &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description auto (short subject line)' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description auto master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = auto (long subject line)' '
+ test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
+
+body" &&
+ test_config format.coverFromDescription auto &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description auto (long subject line)' '
+ test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description auto master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with command-line --cover-from-description overrides config' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription none &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description subject master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
test_expect_success 'cover letter using branch description (1)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter master >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (2)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (3)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (4)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter master.. >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (5)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter -2 HEAD >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (6)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter -2 >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter with nothing' '
@@ -1632,11 +1810,39 @@ test_expect_success 'From line has expected format' '
test_cmp from filtered
'
+test_expect_success 'format-patch -o with no leading directories' '
+ rm -fr patches &&
+ git format-patch -o patches master..side &&
+ count=$(git rev-list --count master..side) &&
+ ls patches >list &&
+ test_line_count = $count list
+'
+
+test_expect_success 'format-patch -o with leading existing directories' '
+ rm -rf existing-dir &&
+ mkdir existing-dir &&
+ git format-patch -o existing-dir/patches master..side &&
+ count=$(git rev-list --count master..side) &&
+ ls existing-dir/patches >list &&
+ test_line_count = $count list
+'
+
+test_expect_success 'format-patch -o with leading non-existing directories' '
+ rm -rf non-existing-dir &&
+ git format-patch -o non-existing-dir/patches master..side &&
+ count=$(git rev-list --count master..side) &&
+ test_path_is_dir non-existing-dir &&
+ ls non-existing-dir/patches >list &&
+ test_line_count = $count list
+'
+
test_expect_success 'format-patch format.outputDirectory option' '
test_config format.outputDirectory patches &&
rm -fr patches &&
git format-patch master..side &&
- test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
+ count=$(git rev-list --count master..side) &&
+ ls patches >list &&
+ test_line_count = $count list
'
test_expect_success 'format-patch -o overrides format.outputDirectory' '
@@ -1649,20 +1855,41 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' '
test_expect_success 'format-patch --base' '
git checkout patchid &&
- git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 &&
- git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 &&
- echo >expected &&
- echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
- signature >> expected &&
- test_cmp expected actual1 &&
- test_cmp expected actual2 &&
+
+ git format-patch --stdout --base=HEAD~3 -1 >patch &&
+ tail -n 7 patch >actual1 &&
+
+ git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
+ tail -n 7 patch >actual2 &&
+
+ echo >expect &&
+ git rev-parse HEAD~3 >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >>expect &&
+
+ git show --patch HEAD~2 >patch &&
+ git patch-id --stable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
+
+ git show --patch HEAD~1 >patch &&
+ git patch-id --stable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
+
+ signature >>expect &&
+ test_cmp expect actual1 &&
+ test_cmp expect actual2 &&
+
echo >fail &&
- echo "base-commit: $(git rev-parse HEAD~3)" >>fail &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
- signature >> fail &&
+ echo "base-commit: $(cat commit-id-base)" >>fail &&
+
+ git show --patch HEAD~2 >patch &&
+ git patch-id --unstable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
+
+ git show --patch HEAD~1 >patch &&
+ git patch-id --unstable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
+
+ signature >>fail &&
! test_cmp fail actual1 &&
! test_cmp fail actual2
'
@@ -1672,8 +1899,9 @@ test_expect_success 'format-patch --base errors out when base commit is in revis
test_must_fail git format-patch --base=HEAD~1 -2 &&
git format-patch --stdout --base=HEAD~2 -2 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
- test_cmp expected actual
+ git rev-parse HEAD~2 >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
@@ -1699,8 +1927,8 @@ test_expect_success 'format-patch --base errors out when base commit is not ance
test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(cat commit-id-base)" >expected &&
- test_cmp expected actual
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch --base=auto' '
@@ -1711,8 +1939,9 @@ test_expect_success 'format-patch --base=auto' '
test_commit N2 &&
git format-patch --stdout --base=auto -2 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse upstream)" >expected &&
- test_cmp expected actual
+ git rev-parse upstream >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch errors out when history involves criss-cross' '
@@ -1742,23 +1971,29 @@ test_expect_success 'format-patch errors out when history involves criss-cross'
test_must_fail git format-patch --base=auto -1
'
-test_expect_success 'format-patch format.useAutoBaseoption' '
- test_when_finished "git config --unset format.useAutoBase" &&
+test_expect_success 'format-patch format.useAutoBase option' '
git checkout local &&
- git config format.useAutoBase true &&
+ test_config format.useAutoBase true &&
git format-patch --stdout -1 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse upstream)" >expected &&
- test_cmp expected actual
+ git rev-parse upstream >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch --base overrides format.useAutoBase' '
- test_when_finished "git config --unset format.useAutoBase" &&
- git config format.useAutoBase true &&
+ test_config format.useAutoBase true &&
git format-patch --stdout --base=HEAD~1 -1 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
- test_cmp expected actual
+ git rev-parse HEAD~1 >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'format-patch --no-base overrides format.useAutoBase' '
+ test_config format.useAutoBase true &&
+ git format-patch --stdout --no-base -1 >patch &&
+ ! grep "^base-commit:" patch
'
test_expect_success 'format-patch --base with --attach' '
@@ -1833,7 +2068,7 @@ test_expect_success 'interdiff: cover-letter' '
git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
- sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
+ sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
test_cmp expect actual
'
@@ -1849,7 +2084,7 @@ test_expect_success 'interdiff: solo-patch' '
EOF
git format-patch --interdiff=boop~2 -1 boop &&
test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
- sed "1,/^ @@ /d; /^$/q" <0001-fleep.patch >actual &&
+ sed "1,/^ @@ /d; /^$/q" 0001-fleep.patch >actual &&
test_cmp expect actual
'
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index 6b087df3dc..88d3026894 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -16,6 +16,8 @@ test_expect_success "Ray Lehtiniemi's example" '
} while (0);
EOF
git update-index --add x &&
+ old_hash_x=$(git hash-object x) &&
+ before=$(git rev-parse --short "$old_hash_x") &&
cat <<-\EOF >x &&
do
@@ -24,10 +26,12 @@ test_expect_success "Ray Lehtiniemi's example" '
}
while (0);
EOF
+ new_hash_x=$(git hash-object x) &&
+ after=$(git rev-parse --short "$new_hash_x") &&
- cat <<-\EOF >expect &&
+ cat <<-EOF >expect &&
diff --git a/x b/x
- index adf3937..6edc172 100644
+ index $before..$after 100644
--- a/x
+++ b/x
@@ -1,3 +1,5 @@
@@ -61,6 +65,8 @@ test_expect_success 'another test, without options' '
EOF
git update-index x &&
+ old_hash_x=$(git hash-object x) &&
+ before=$(git rev-parse --short "$old_hash_x") &&
tr "_" " " <<-\EOF >x &&
_ whitespace at beginning
@@ -70,10 +76,12 @@ test_expect_success 'another test, without options' '
unchanged line
CR at end
EOF
+ new_hash_x=$(git hash-object x) &&
+ after=$(git rev-parse --short "$new_hash_x") &&
- tr "Q_" "\015 " <<-\EOF >expect &&
+ tr "Q_" "\015 " <<-EOF >expect &&
diff --git a/x b/x
- index d99af23..22d9f73 100644
+ index $before..$after 100644
--- a/x
+++ b/x
@@ -1,6 +1,6 @@
@@ -108,9 +116,9 @@ test_expect_success 'another test, without options' '
git diff -w --ignore-cr-at-eol >out &&
test_must_be_empty out &&
- tr "Q_" "\015 " <<-\EOF >expect &&
+ tr "Q_" "\015 " <<-EOF >expect &&
diff --git a/x b/x
- index d99af23..22d9f73 100644
+ index $before..$after 100644
--- a/x
+++ b/x
@@ -1,6 +1,6 @@
@@ -132,9 +140,9 @@ test_expect_success 'another test, without options' '
git diff -b --ignore-cr-at-eol >out &&
test_cmp expect out &&
- tr "Q_" "\015 " <<-\EOF >expect &&
+ tr "Q_" "\015 " <<-EOF >expect &&
diff --git a/x b/x
- index d99af23..22d9f73 100644
+ index $before..$after 100644
--- a/x
+++ b/x
@@ -1,6 +1,6 @@
@@ -154,9 +162,9 @@ test_expect_success 'another test, without options' '
git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
test_cmp expect out &&
- tr "Q_" "\015 " <<-\EOF >expect &&
+ tr "Q_" "\015 " <<-EOF >expect &&
diff --git a/x b/x
- index_d99af23..22d9f73 100644
+ index_$before..$after 100644
--- a/x
+++ b/x
@@ -1,6 +1,6 @@
@@ -522,13 +530,15 @@ test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
test_expect_success 'check mixed spaces and tabs in indent' '
# This is indented with SP HT SP.
echo " foo();" >x &&
- git diff --check | grep "space before tab in indent"
+ test_must_fail git diff --check >check &&
+ grep "space before tab in indent" check
'
test_expect_success 'check mixed tabs and spaces in indent' '
# This is indented with HT SP HT.
echo " foo();" >x &&
- git diff --check | grep "space before tab in indent"
+ test_must_fail git diff --check >check &&
+ grep "space before tab in indent" check
'
test_expect_success 'check with no whitespace errors' '
@@ -749,20 +759,23 @@ test_expect_success 'check tab-in-indent excluded from wildcard whitespace attri
test_expect_success 'line numbers in --check output are correct' '
echo "" >x &&
echo "foo(); " >>x &&
- git diff --check | grep "x:2:"
+ test_must_fail git diff --check >check &&
+ grep "x:2:" check
'
test_expect_success 'checkdiff detects new trailing blank lines (1)' '
echo "foo();" >x &&
echo "" >>x &&
- git diff --check | grep "new blank line"
+ test_must_fail git diff --check >check &&
+ grep "new blank line" check
'
test_expect_success 'checkdiff detects new trailing blank lines (2)' '
- { echo a; echo b; echo; echo; } >x &&
+ test_write_lines a b "" "" >x &&
git add x &&
- { echo a; echo; echo; echo; echo; } >x &&
- git diff --check | grep "new blank line"
+ test_write_lines a "" "" "" "" >x &&
+ test_must_fail git diff --check >check &&
+ grep "new blank line" check
'
test_expect_success 'checkdiff allows new blank lines' '
@@ -786,23 +799,27 @@ test_expect_success 'whitespace-only changes not reported' '
test_must_be_empty actual
'
-cat <<EOF >expect
-diff --git a/x b/z
-similarity index NUM%
-rename from x
-rename to z
-index 380c32a..a97b785 100644
-EOF
test_expect_success 'whitespace-only changes reported across renames' '
git reset --hard &&
for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
git add x &&
+ hash_x=$(git hash-object x) &&
+ before=$(git rev-parse --short "$hash_x") &&
git commit -m "base" &&
sed -e "5s/^/ /" x >z &&
git rm x &&
git add z &&
- git diff -w -M --cached |
- sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
+ hash_z=$(git hash-object z) &&
+ after=$(git rev-parse --short "$hash_z") &&
+ git diff -w -M --cached >actual.raw &&
+ sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
+ cat <<-EOF >expect &&
+ diff --git a/x b/z
+ similarity index NUM%
+ rename from x
+ rename to z
+ index $before..$after 100644
+ EOF
test_cmp expect actual
'
@@ -834,7 +851,8 @@ test_expect_success 'combined diff with autocrlf conversion' '
git config core.autocrlf true &&
test_must_fail git merge master &&
- git diff | sed -e "1,/^@@@/d" >actual &&
+ git diff >actual.raw &&
+ sed -e "1,/^@@@/d" actual.raw >actual &&
! grep "^-" actual
'
@@ -858,13 +876,18 @@ test_expect_success 'diff that introduces a line with only tabs' '
git config core.whitespace blank-at-eol &&
git reset --hard &&
echo "test" >x &&
+ old_hash_x=$(git hash-object x) &&
+ before=$(git rev-parse --short "$old_hash_x") &&
git commit -m "initial" x &&
echo "{NTN}" | tr "NT" "\n\t" >>x &&
- git diff --color | test_decode_color >current &&
+ new_hash_x=$(git hash-object x) &&
+ after=$(git rev-parse --short "$new_hash_x") &&
+ git diff --color >current.raw &&
+ test_decode_color <current.raw >current &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
<BOLD>diff --git a/x b/x<RESET>
- <BOLD>index 9daeafb..2874b91 100644<RESET>
+ <BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
<CYAN>@@ -1 +1,4 @@<RESET>
@@ -883,19 +906,23 @@ test_expect_success 'diff that introduces and removes ws breakages' '
echo "0. blank-at-eol " &&
echo "1. blank-at-eol "
} >x &&
+ old_hash_x=$(git hash-object x) &&
+ before=$(git rev-parse --short "$old_hash_x") &&
git commit -a --allow-empty -m preimage &&
{
echo "0. blank-at-eol " &&
echo "1. still-blank-at-eol " &&
echo "2. and a new line "
} >x &&
+ new_hash_x=$(git hash-object x) &&
+ after=$(git rev-parse --short "$new_hash_x") &&
- git diff --color |
- test_decode_color >current &&
+ git diff --color >current.raw &&
+ test_decode_color <current.raw >current &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
<BOLD>diff --git a/x b/x<RESET>
- <BOLD>index d0233a2..700886e 100644<RESET>
+ <BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
<CYAN>@@ -1,2 +1,3 @@<RESET>
@@ -915,16 +942,20 @@ test_expect_success 'ws-error-highlight test setup' '
echo "0. blank-at-eol " &&
echo "1. blank-at-eol "
} >x &&
+ old_hash_x=$(git hash-object x) &&
+ before=$(git rev-parse --short "$old_hash_x") &&
git commit -a --allow-empty -m preimage &&
{
echo "0. blank-at-eol " &&
echo "1. still-blank-at-eol " &&
echo "2. and a new line "
} >x &&
+ new_hash_x=$(git hash-object x) &&
+ after=$(git rev-parse --short "$new_hash_x") &&
- cat >expect.default-old <<-\EOF &&
+ cat >expect.default-old <<-EOF &&
<BOLD>diff --git a/x b/x<RESET>
- <BOLD>index d0233a2..700886e 100644<RESET>
+ <BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
<CYAN>@@ -1,2 +1,3 @@<RESET>
@@ -934,9 +965,9 @@ test_expect_success 'ws-error-highlight test setup' '
<GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
EOF
- cat >expect.all <<-\EOF &&
+ cat >expect.all <<-EOF &&
<BOLD>diff --git a/x b/x<RESET>
- <BOLD>index d0233a2..700886e 100644<RESET>
+ <BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
<CYAN>@@ -1,2 +1,3 @@<RESET>
@@ -946,9 +977,9 @@ test_expect_success 'ws-error-highlight test setup' '
<GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
EOF
- cat >expect.none <<-\EOF
+ cat >expect.none <<-EOF
<BOLD>diff --git a/x b/x<RESET>
- <BOLD>index d0233a2..700886e 100644<RESET>
+ <BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
<CYAN>@@ -1,2 +1,3 @@<RESET>
@@ -962,32 +993,32 @@ test_expect_success 'ws-error-highlight test setup' '
test_expect_success 'test --ws-error-highlight option' '
- git diff --color --ws-error-highlight=default,old |
- test_decode_color >current &&
+ git diff --color --ws-error-highlight=default,old >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.default-old current &&
- git diff --color --ws-error-highlight=all |
- test_decode_color >current &&
+ git diff --color --ws-error-highlight=all >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.all current &&
- git diff --color --ws-error-highlight=none |
- test_decode_color >current &&
+ git diff --color --ws-error-highlight=none >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.none current
'
test_expect_success 'test diff.wsErrorHighlight config' '
- git -c diff.wsErrorHighlight=default,old diff --color |
- test_decode_color >current &&
+ git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.default-old current &&
- git -c diff.wsErrorHighlight=all diff --color |
- test_decode_color >current &&
+ git -c diff.wsErrorHighlight=all diff --color >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.all current &&
- git -c diff.wsErrorHighlight=none diff --color |
- test_decode_color >current &&
+ git -c diff.wsErrorHighlight=none diff --color >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.none current
'
@@ -995,18 +1026,18 @@ test_expect_success 'test diff.wsErrorHighlight config' '
test_expect_success 'option overrides diff.wsErrorHighlight' '
git -c diff.wsErrorHighlight=none \
- diff --color --ws-error-highlight=default,old |
- test_decode_color >current &&
+ diff --color --ws-error-highlight=default,old >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.default-old current &&
git -c diff.wsErrorHighlight=default \
- diff --color --ws-error-highlight=all |
- test_decode_color >current &&
+ diff --color --ws-error-highlight=all >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.all current &&
git -c diff.wsErrorHighlight=all \
- diff --color --ws-error-highlight=none |
- test_decode_color >current &&
+ diff --color --ws-error-highlight=none >current.raw &&
+ test_decode_color <current.raw >current &&
test_cmp expect.none current
'
@@ -1022,14 +1053,16 @@ test_expect_success 'detect moved code, complete file' '
EOF
git add test.c &&
git commit -m "add main function" &&
+ file=$(git rev-parse --short HEAD:test.c) &&
git mv test.c main.c &&
test_config color.diff.oldMoved "normal red" &&
test_config color.diff.newMoved "normal green" &&
- git diff HEAD --color-moved=zebra --color --no-renames | test_decode_color >actual &&
- cat >expected <<-\EOF &&
+ git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
+ test_decode_color <actual.raw >actual &&
+ cat >expected <<-EOF &&
<BOLD>diff --git a/main.c b/main.c<RESET>
<BOLD>new file mode 100644<RESET>
- <BOLD>index 0000000..a986c57<RESET>
+ <BOLD>index 0000000..$file<RESET>
<BOLD>--- /dev/null<RESET>
<BOLD>+++ b/main.c<RESET>
<CYAN>@@ -0,0 +1,5 @@<RESET>
@@ -1040,7 +1073,7 @@ test_expect_success 'detect moved code, complete file' '
<BGREEN>+<RESET><BGREEN>}<RESET>
<BOLD>diff --git a/test.c b/test.c<RESET>
<BOLD>deleted file mode 100644<RESET>
- <BOLD>index a986c57..0000000<RESET>
+ <BOLD>index $file..0000000<RESET>
<BOLD>--- a/test.c<RESET>
<BOLD>+++ /dev/null<RESET>
<CYAN>@@ -1,5 +0,0 @@<RESET>
@@ -1094,6 +1127,8 @@ test_expect_success 'detect malicious moved code, inside file' '
EOF
git add main.c test.c &&
git commit -m "add main and test file" &&
+ before_main=$(git rev-parse --short HEAD:main.c) &&
+ before_test=$(git rev-parse --short HEAD:test.c) &&
cat <<-\EOF >main.c &&
#include<stdio.h>
int stuff()
@@ -1126,10 +1161,15 @@ test_expect_success 'detect malicious moved code, inside file' '
bar();
}
EOF
- git diff HEAD --no-renames --color-moved=zebra --color | test_decode_color >actual &&
- cat <<-\EOF >expected &&
+ hash_main=$(git hash-object main.c) &&
+ after_main=$(git rev-parse --short "$hash_main") &&
+ hash_test=$(git hash-object test.c) &&
+ after_test=$(git rev-parse --short "$hash_test") &&
+ git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
+ test_decode_color <actual.raw >actual &&
+ cat <<-EOF >expected &&
<BOLD>diff --git a/main.c b/main.c<RESET>
- <BOLD>index 27a619c..7cf9336 100644<RESET>
+ <BOLD>index $before_main..$after_main 100644<RESET>
<BOLD>--- a/main.c<RESET>
<BOLD>+++ b/main.c<RESET>
<CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
@@ -1147,7 +1187,7 @@ test_expect_success 'detect malicious moved code, inside file' '
{<RESET>
foo();<RESET>
<BOLD>diff --git a/test.c b/test.c<RESET>
- <BOLD>index 1dc1d85..2bedec9 100644<RESET>
+ <BOLD>index $before_test..$after_test 100644<RESET>
<BOLD>--- a/test.c<RESET>
<BOLD>+++ b/test.c<RESET>
<CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
@@ -1175,10 +1215,11 @@ test_expect_success 'plain moved code, inside file' '
test_config color.diff.oldMovedAlternative "blue" &&
test_config color.diff.newMovedAlternative "yellow" &&
# needs previous test as setup
- git diff HEAD --no-renames --color-moved=plain --color | test_decode_color >actual &&
- cat <<-\EOF >expected &&
+ git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
+ test_decode_color <actual.raw >actual &&
+ cat <<-EOF >expected &&
<BOLD>diff --git a/main.c b/main.c<RESET>
- <BOLD>index 27a619c..7cf9336 100644<RESET>
+ <BOLD>index $before_main..$after_main 100644<RESET>
<BOLD>--- a/main.c<RESET>
<BOLD>+++ b/main.c<RESET>
<CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
@@ -1196,7 +1237,7 @@ test_expect_success 'plain moved code, inside file' '
{<RESET>
foo();<RESET>
<BOLD>diff --git a/test.c b/test.c<RESET>
- <BOLD>index 1dc1d85..2bedec9 100644<RESET>
+ <BOLD>index $before_test..$after_test 100644<RESET>
<BOLD>--- a/test.c<RESET>
<BOLD>+++ b/test.c<RESET>
<CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
@@ -1754,7 +1795,8 @@ test_expect_success 'move detection with submodules' '
! grep BRED decoded_actual &&
# nor did we mess with it another way
- git diff --submodule=diff --color | test_decode_color >expect &&
+ git diff --submodule=diff --color >expect.raw &&
+ test_decode_color <expect.raw >expect &&
test_cmp expect decoded_actual &&
rm -rf bananas &&
git submodule deinit bananas
@@ -2008,11 +2050,6 @@ test_expect_success 'compare mixed whitespace delta across moved blocks' '
test_cmp expected actual
'
-# Note that the "6" in the expected hunk header below is funny, since we only
-# show 5 lines (the missing one was blank and thus ignored). This is how
-# --ignore-blank-lines behaves even without --function-context, and this test
-# is just checking the interaction of the two features. Don't take it as an
-# endorsement of that output.
test_expect_success 'combine --ignore-blank-lines with --function-context' '
test_write_lines 1 "" 2 3 4 5 >a &&
test_write_lines 1 2 3 4 >b &&
@@ -2022,6 +2059,7 @@ test_expect_success 'combine --ignore-blank-lines with --function-context' '
cat <<-\EOF >expect &&
@@ -1,6 +1,4 @@
1
+ -
2
3
4
@@ -2030,4 +2068,27 @@ test_expect_success 'combine --ignore-blank-lines with --function-context' '
test_cmp expect actual
'
+test_expect_success 'combine --ignore-blank-lines with --function-context 2' '
+ test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
+ test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
+ test_must_fail git diff --no-index \
+ --ignore-blank-lines --function-context a b >actual.raw &&
+ sed -n "/@@/,\$p" <actual.raw >actual &&
+ cat <<-\EOF >expect &&
+ @@ -5,11 +6,9 @@ c
+ function
+ 1
+ 2
+ 3
+ 4
+ 5
+ -
+ 6
+ 7
+ 8
+ -9
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index 9261d6d3a0..02255a08bf 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -31,6 +31,8 @@ diffpatterns="
cpp
csharp
css
+ dts
+ elixir
fortran
fountain
golang
@@ -104,7 +106,6 @@ do
result=success
fi
test_expect_$result "hunk header: $i" "
- test_when_finished 'cat actual' && # for debugging only
git diff -U1 $i >actual &&
grep '@@ .* @@.*RIGHT' actual
"
diff --git a/t/t4018/dts-labels b/t/t4018/dts-labels
new file mode 100644
index 0000000000..b21ef8737b
--- /dev/null
+++ b/t/t4018/dts-labels
@@ -0,0 +1,9 @@
+/ {
+ label_1: node1@ff00 {
+ label2: RIGHT {
+ vendor,some-property;
+
+ ChangeMe = <0x45-30>;
+ };
+ };
+};
diff --git a/t/t4018/dts-node-unitless b/t/t4018/dts-node-unitless
new file mode 100644
index 0000000000..c5287d9141
--- /dev/null
+++ b/t/t4018/dts-node-unitless
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1 {
+ RIGHT {
+ prop-array = <1>, <4>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes b/t/t4018/dts-nodes
new file mode 100644
index 0000000000..5a4334bb16
--- /dev/null
+++ b/t/t4018/dts-nodes
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 {
+ #size-cells = <1>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-boolean-prop b/t/t4018/dts-nodes-boolean-prop
new file mode 100644
index 0000000000..afc6b5b404
--- /dev/null
+++ b/t/t4018/dts-nodes-boolean-prop
@@ -0,0 +1,9 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 {
+ boolean-prop1;
+
+ ChangeMe;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-comment1 b/t/t4018/dts-nodes-comment1
new file mode 100644
index 0000000000..559dfce9b3
--- /dev/null
+++ b/t/t4018/dts-nodes-comment1
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 /* &a comment */ {
+ #size-cells = <1>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-comment2 b/t/t4018/dts-nodes-comment2
new file mode 100644
index 0000000000..27e9718b31
--- /dev/null
+++ b/t/t4018/dts-nodes-comment2
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 { /* a trailing comment */
+ #size-cells = <1>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-multiline-prop b/t/t4018/dts-nodes-multiline-prop
new file mode 100644
index 0000000000..072d58b69d
--- /dev/null
+++ b/t/t4018/dts-nodes-multiline-prop
@@ -0,0 +1,13 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 {
+ multilineprop = <3>,
+ <4>,
+ <5>,
+ <6>,
+ <7>;
+
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-reference b/t/t4018/dts-reference
new file mode 100644
index 0000000000..8f0c87d863
--- /dev/null
+++ b/t/t4018/dts-reference
@@ -0,0 +1,9 @@
+&label_1 {
+ TEST = <455>;
+};
+
+&RIGHT {
+ vendor,some-property;
+
+ ChangeMe = <0x45-30>;
+};
diff --git a/t/t4018/dts-root b/t/t4018/dts-root
new file mode 100644
index 0000000000..4353b8220c
--- /dev/null
+++ b/t/t4018/dts-root
@@ -0,0 +1,5 @@
+/ { RIGHT /* Technically just supposed to be a slash and brace */
+ #size-cells = <1>;
+
+ ChangeMe = <0xffeedd00>;
+};
diff --git a/t/t4018/dts-root-comment b/t/t4018/dts-root-comment
new file mode 100644
index 0000000000..333a625c70
--- /dev/null
+++ b/t/t4018/dts-root-comment
@@ -0,0 +1,8 @@
+/ { RIGHT /* Technically just supposed to be a slash and brace */
+ #size-cells = <1>;
+
+ /* This comment should be ignored */
+
+ some-property = <40+2>;
+ ChangeMe = <0xffeedd00>;
+};
diff --git a/t/t4018/elixir-do-not-pick-end b/t/t4018/elixir-do-not-pick-end
new file mode 100644
index 0000000000..fae08ba7e8
--- /dev/null
+++ b/t/t4018/elixir-do-not-pick-end
@@ -0,0 +1,5 @@
+defmodule RIGHT do
+end
+#
+#
+# ChangeMe; do not pick up 'end' line
diff --git a/t/t4018/elixir-ex-unit-test b/t/t4018/elixir-ex-unit-test
new file mode 100644
index 0000000000..0560a2b697
--- /dev/null
+++ b/t/t4018/elixir-ex-unit-test
@@ -0,0 +1,6 @@
+defmodule Test do
+ test "RIGHT" do
+ assert true == true
+ assert ChangeMe
+ end
+end
diff --git a/t/t4018/elixir-function b/t/t4018/elixir-function
new file mode 100644
index 0000000000..d452f495a7
--- /dev/null
+++ b/t/t4018/elixir-function
@@ -0,0 +1,5 @@
+def function(RIGHT, arg) do
+ # comment
+ # comment
+ ChangeMe
+end
diff --git a/t/t4018/elixir-macro b/t/t4018/elixir-macro
new file mode 100644
index 0000000000..4f925e9ad4
--- /dev/null
+++ b/t/t4018/elixir-macro
@@ -0,0 +1,5 @@
+defmacro foo(RIGHT) do
+ # Code
+ # Code
+ ChangeMe
+end
diff --git a/t/t4018/elixir-module b/t/t4018/elixir-module
new file mode 100644
index 0000000000..91a4e7aa20
--- /dev/null
+++ b/t/t4018/elixir-module
@@ -0,0 +1,9 @@
+defmodule RIGHT do
+ @moduledoc """
+ Foo bar
+ """
+
+ def ChangeMe(a) where is_map(a) do
+ a
+ end
+end
diff --git a/t/t4018/elixir-module-func b/t/t4018/elixir-module-func
new file mode 100644
index 0000000000..c9910d0675
--- /dev/null
+++ b/t/t4018/elixir-module-func
@@ -0,0 +1,8 @@
+defmodule Foo do
+ def fun(RIGHT) do
+ # Code
+ # Code
+ # Code
+ ChangeMe
+ end
+end
diff --git a/t/t4018/elixir-nested-module b/t/t4018/elixir-nested-module
new file mode 100644
index 0000000000..771ebc5c42
--- /dev/null
+++ b/t/t4018/elixir-nested-module
@@ -0,0 +1,9 @@
+defmodule MyApp.RIGHT do
+ @moduledoc """
+ Foo bar
+ """
+
+ def ChangeMe(a) where is_map(a) do
+ a
+ end
+end
diff --git a/t/t4018/elixir-private-function b/t/t4018/elixir-private-function
new file mode 100644
index 0000000000..1aabe33b7a
--- /dev/null
+++ b/t/t4018/elixir-private-function
@@ -0,0 +1,5 @@
+defp function(RIGHT, arg) do
+ # comment
+ # comment
+ ChangeMe
+end
diff --git a/t/t4018/elixir-protocol b/t/t4018/elixir-protocol
new file mode 100644
index 0000000000..7d9173691e
--- /dev/null
+++ b/t/t4018/elixir-protocol
@@ -0,0 +1,6 @@
+defprotocol RIGHT do
+ @doc """
+ Calculates the size (and not the length!) of a data structure
+ """
+ def size(data, ChangeMe)
+end
diff --git a/t/t4018/elixir-protocol-implementation b/t/t4018/elixir-protocol-implementation
new file mode 100644
index 0000000000..f9234bbfc4
--- /dev/null
+++ b/t/t4018/elixir-protocol-implementation
@@ -0,0 +1,5 @@
+defimpl RIGHT do
+ # Docs
+ # Docs
+ def foo(ChangeMe), do: :ok
+end
diff --git a/t/t4018/python-async-def b/t/t4018/python-async-def
new file mode 100644
index 0000000000..87640e03d2
--- /dev/null
+++ b/t/t4018/python-async-def
@@ -0,0 +1,4 @@
+async def RIGHT(pi: int = 3.14):
+ while True:
+ break
+ return ChangeMe()
diff --git a/t/t4018/python-class b/t/t4018/python-class
new file mode 100644
index 0000000000..ba9e741430
--- /dev/null
+++ b/t/t4018/python-class
@@ -0,0 +1,4 @@
+class RIGHT(int, str):
+ # comment
+ # another comment
+ # ChangeMe
diff --git a/t/t4018/python-def b/t/t4018/python-def
new file mode 100644
index 0000000000..e50b31b0ad
--- /dev/null
+++ b/t/t4018/python-def
@@ -0,0 +1,4 @@
+def RIGHT(pi: int = 3.14):
+ while True:
+ break
+ return ChangeMe()
diff --git a/t/t4018/python-indented-async-def b/t/t4018/python-indented-async-def
new file mode 100644
index 0000000000..f5d03258af
--- /dev/null
+++ b/t/t4018/python-indented-async-def
@@ -0,0 +1,7 @@
+class Foo:
+ async def RIGHT(self, x: int):
+ return [
+ 1,
+ 2,
+ ChangeMe,
+ ]
diff --git a/t/t4018/python-indented-class b/t/t4018/python-indented-class
new file mode 100644
index 0000000000..19b4f35c4c
--- /dev/null
+++ b/t/t4018/python-indented-class
@@ -0,0 +1,5 @@
+if TYPE_CHECKING:
+ class RIGHT:
+ # comment
+ # another comment
+ # ChangeMe
diff --git a/t/t4018/python-indented-def b/t/t4018/python-indented-def
new file mode 100644
index 0000000000..208fbadd2b
--- /dev/null
+++ b/t/t4018/python-indented-def
@@ -0,0 +1,7 @@
+class Foo:
+ def RIGHT(self, x: int):
+ return [
+ 1,
+ 2,
+ ChangeMe,
+ ]
diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh
index 9aa8e2b39b..e29deaf4a5 100755
--- a/t/t4027-diff-submodule.sh
+++ b/t/t4027-diff-submodule.sh
@@ -6,6 +6,7 @@ test_description='difference in submodules'
. "$TEST_DIRECTORY"/diff-lib.sh
test_expect_success setup '
+ test_oid_init &&
test_tick &&
test_create_repo sub &&
(
@@ -36,7 +37,8 @@ test_expect_success setup '
'
test_expect_success 'git diff --raw HEAD' '
- git diff --raw --abbrev=40 HEAD >actual &&
+ hexsz=$(test_oid hexsz) &&
+ git diff --raw --abbrev=$hexsz HEAD >actual &&
test_cmp expect actual
'
@@ -245,23 +247,21 @@ test_expect_success 'git diff (empty submodule dir)' '
'
test_expect_success 'conflicted submodule setup' '
-
- # 39 efs
- c=fffffffffffffffffffffffffffffffffffffff &&
+ c=$(test_oid ff_1) &&
(
echo "000000 $ZERO_OID 0 sub" &&
echo "160000 1$c 1 sub" &&
echo "160000 2$c 2 sub" &&
echo "160000 3$c 3 sub"
) | git update-index --index-info &&
- echo >expect.nosub '\''diff --cc sub
+ echo >expect.nosub "diff --cc sub
index 2ffffff,3ffffff..0000000
--- a/sub
+++ b/sub
@@@ -1,1 -1,1 +1,1 @@@
-- Subproject commit 2fffffffffffffffffffffffffffffffffffffff
- -Subproject commit 3fffffffffffffffffffffffffffffffffffffff
-++Subproject commit 0000000000000000000000000000000000000000'\'' &&
+- Subproject commit 2$c
+ -Subproject commit 3$c
+++Subproject commit $ZERO_OID" &&
hh=$(git rev-parse HEAD) &&
sed -e "s/$ZERO_OID/$hh/" expect.nosub >expect.withsub
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
index 912df91226..fb145aa173 100755
--- a/t/t4034-diff-words.sh
+++ b/t/t4034-diff-words.sh
@@ -19,9 +19,11 @@ cat >post.simple <<-\EOF
aeff = aeff * ( aaa )
EOF
-cat >expect.letter-runs-are-words <<-\EOF
+pre=$(git rev-parse --short $(git hash-object pre.simple))
+post=$(git rev-parse --short $(git hash-object post.simple))
+cat >expect.letter-runs-are-words <<-EOF
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 330b04f..5ed8eff 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1,3 +1,7 @@<RESET>
@@ -33,9 +35,9 @@ cat >expect.letter-runs-are-words <<-\EOF
<GREEN>aeff = aeff * ( aaa<RESET> )
EOF
-cat >expect.non-whitespace-is-word <<-\EOF
+cat >expect.non-whitespace-is-word <<-EOF
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 330b04f..5ed8eff 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1,3 +1,7 @@<RESET>
@@ -49,9 +51,12 @@ cat >expect.non-whitespace-is-word <<-\EOF
EOF
word_diff () {
+ pre=$(git rev-parse --short $(git hash-object pre)) &&
+ post=$(git rev-parse --short $(git hash-object post)) &&
test_must_fail git diff --no-index "$@" pre post >output &&
test_decode_color <output >output.decrypted &&
- test_cmp expect output.decrypted
+ sed -e "2s/index [^ ]*/index $pre..$post/" expect >expected
+ test_cmp expected output.decrypted
}
test_language_driver () {
@@ -77,9 +82,9 @@ test_expect_success 'set up pre and post with runs of whitespace' '
'
test_expect_success 'word diff with runs of whitespace' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 330b04f..5ed8eff 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1,3 +1,7 @@<RESET>
@@ -97,9 +102,9 @@ test_expect_success 'word diff with runs of whitespace' '
'
test_expect_success '--word-diff=porcelain' '
- sed 's/#.*$//' >expect <<-\EOF &&
+ sed 's/#.*$//' >expect <<-EOF &&
diff --git a/pre b/post
- index 330b04f..5ed8eff 100644
+ index $pre..$post 100644
--- a/pre
+++ b/post
@@ -1,3 +1,7 @@
@@ -121,9 +126,9 @@ test_expect_success '--word-diff=porcelain' '
'
test_expect_success '--word-diff=plain' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
diff --git a/pre b/post
- index 330b04f..5ed8eff 100644
+ index $pre..$post 100644
--- a/pre
+++ b/post
@@ -1,3 +1,7 @@
@@ -140,9 +145,9 @@ test_expect_success '--word-diff=plain' '
'
test_expect_success '--word-diff=plain --color' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 330b04f..5ed8eff 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1,3 +1,7 @@<RESET>
@@ -158,9 +163,9 @@ test_expect_success '--word-diff=plain --color' '
'
test_expect_success 'word diff without context' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 330b04f..5ed8eff 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1 +1 @@<RESET>
@@ -207,9 +212,9 @@ test_expect_success 'command-line overrides config' '
'
test_expect_success 'command-line overrides config: --word-diff-regex' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 330b04f..5ed8eff 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1,3 +1,7 @@<RESET>
@@ -234,9 +239,9 @@ test_expect_success 'setup: remove diff driver regex' '
'
test_expect_success 'use configured regex' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 330b04f..5ed8eff 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1,3 +1,7 @@<RESET>
@@ -254,9 +259,11 @@ test_expect_success 'use configured regex' '
test_expect_success 'test parsing words for newline' '
echo "aaa (aaa)" >pre &&
echo "aaa (aaa) aaa" >post &&
- cat >expect <<-\EOF &&
+ pre=$(git rev-parse --short $(git hash-object pre)) &&
+ post=$(git rev-parse --short $(git hash-object post)) &&
+ cat >expect <<-EOF &&
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index c29453b..be22f37 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1 +1 @@<RESET>
@@ -268,9 +275,11 @@ test_expect_success 'test parsing words for newline' '
test_expect_success 'test when words are only removed at the end' '
echo "(:" >pre &&
echo "(" >post &&
- cat >expect <<-\EOF &&
+ pre=$(git rev-parse --short $(git hash-object pre)) &&
+ post=$(git rev-parse --short $(git hash-object post)) &&
+ cat >expect <<-EOF &&
<BOLD>diff --git a/pre b/post<RESET>
- <BOLD>index 289cb9d..2d06f37 100644<RESET>
+ <BOLD>index $pre..$post 100644<RESET>
<BOLD>--- a/pre<RESET>
<BOLD>+++ b/post<RESET>
<CYAN>@@ -1 +1 @@<RESET>
@@ -282,9 +291,11 @@ test_expect_success 'test when words are only removed at the end' '
test_expect_success '--word-diff=none' '
echo "(:" >pre &&
echo "(" >post &&
- cat >expect <<-\EOF &&
+ pre=$(git rev-parse --short $(git hash-object pre)) &&
+ post=$(git rev-parse --short $(git hash-object post)) &&
+ cat >expect <<-EOF &&
diff --git a/pre b/post
- index 289cb9d..2d06f37 100644
+ index $pre..$post 100644
--- a/pre
+++ b/post
@@ -1 +1 @@
@@ -303,6 +314,7 @@ test_language_driver bibtex
test_language_driver cpp
test_language_driver csharp
test_language_driver css
+test_language_driver dts
test_language_driver fortran
test_language_driver html
test_language_driver java
@@ -316,16 +328,6 @@ test_language_driver ruby
test_language_driver tex
test_expect_success 'word-diff with diff.sbe' '
- cat >expect <<-\EOF &&
- diff --git a/pre b/post
- index a1a53b5..bc8fe6d 100644
- --- a/pre
- +++ b/post
- @@ -1,3 +1,3 @@
- a
-
- [-b-]{+c+}
- EOF
cat >pre <<-\EOF &&
a
@@ -336,21 +338,35 @@ test_expect_success 'word-diff with diff.sbe' '
c
EOF
+ pre=$(git rev-parse --short $(git hash-object pre)) &&
+ post=$(git rev-parse --short $(git hash-object post)) &&
+ cat >expect <<-EOF &&
+ diff --git a/pre b/post
+ index $pre..$post 100644
+ --- a/pre
+ +++ b/post
+ @@ -1,3 +1,3 @@
+ a
+
+ [-b-]{+c+}
+ EOF
test_config diff.suppress-blank-empty true &&
word_diff --word-diff=plain
'
test_expect_success 'word-diff with no newline at EOF' '
- cat >expect <<-\EOF &&
+ printf "%s" "a a a a a" >pre &&
+ printf "%s" "a a ab a a" >post &&
+ pre=$(git rev-parse --short $(git hash-object pre)) &&
+ post=$(git rev-parse --short $(git hash-object post)) &&
+ cat >expect <<-EOF &&
diff --git a/pre b/post
- index 7bf316e..3dd0303 100644
+ index $pre..$post 100644
--- a/pre
+++ b/post
@@ -1 +1 @@
a a [-a-]{+ab+} a a
EOF
- printf "%s" "a a a a a" >pre &&
- printf "%s" "a a ab a a" >post &&
word_diff --word-diff=plain
'
diff --git a/t/t4034/dts/expect b/t/t4034/dts/expect
new file mode 100644
index 0000000000..560fc99184
--- /dev/null
+++ b/t/t4034/dts/expect
@@ -0,0 +1,37 @@
+<BOLD>diff --git a/pre b/post<RESET>
+<BOLD>index b6a9051..7803aee 100644<RESET>
+<BOLD>--- a/pre<RESET>
+<BOLD>+++ b/post<RESET>
+<CYAN>@@ -1,32 +1,32 @@<RESET>
+/ {<RESET>
+ <RED>this_handle<RESET><GREEN>HANDLE_2<RESET>: <RED>node<RESET><GREEN>new-node<RESET>@<RED>f00<RESET><GREEN>eeda<RESET> {
+ compatible = "<RED>mydev<RESET><GREEN>vendor,compat<RESET>";
+ string-prop = <RED>start<RESET><GREEN>end<RESET>: "hello <RED>world!<RESET><GREEN>world?<RESET>" <RED>end<RESET><GREEN>start<RESET>: ;
+ <RED>#size-cells<RESET><GREEN>#address-cells<RESET> = <<RED>0+0<RESET><GREEN>0+40<RESET>>;
+ reg = <<RED>0xf00<RESET><GREEN>0xeeda<RESET>>;
+ prop = <<GREEN>(<RESET>1<GREEN>)<RESET>>;
+ prop = <<GREEN>(<RESET>-1e10<GREEN>)<RESET>>;
+ prop = <(!<RED>3<RESET><GREEN>1<RESET>)>;
+ prop = <(~<RED>3<RESET><GREEN>1<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>*<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>&<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>*<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>/<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>%<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3+4<RESET><GREEN>1+2<RESET>)>;
+ prop = <(<RED>3-4<RESET><GREEN>1-2<RESET>)>;
+ prop = /bits/ <RED>64<RESET><GREEN>32<RESET> <(<RED>3<RESET><GREEN>1<RESET><<<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>>><RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>&<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>^<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>|<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>&&<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>||<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>4?5<RESET><GREEN>1?2<RESET>:3)>;
+ list = <&<RED>this_handle<RESET><GREEN>HANDLE_2<RESET>>, <0 0 0 <RED>0<RESET><GREEN>1<RESET>>;
+ };<RESET>
+
+ &<RED>phandle<RESET><GREEN>phandle2<RESET> {
+ <RED>pre-phandle<RESET><GREEN>prop_handle<RESET> = <&<RED>this_handle<RESET><GREEN>HANDLE_2<RESET>>;
+ };<RESET>
+};<RESET>
diff --git a/t/t4034/dts/post b/t/t4034/dts/post
new file mode 100644
index 0000000000..7803aee280
--- /dev/null
+++ b/t/t4034/dts/post
@@ -0,0 +1,32 @@
+/ {
+ HANDLE_2: new-node@eeda {
+ compatible = "vendor,compat";
+ string-prop = end: "hello world?" start: ;
+ #address-cells = <0+40>;
+ reg = <0xeeda>;
+ prop = <(1)>;
+ prop = <(-1e10)>;
+ prop = <(!1)>;
+ prop = <(~1)>;
+ prop = <(1*2)>;
+ prop = <(1&2)>;
+ prop = <(1*2)>;
+ prop = <(1/2)>;
+ prop = <(1%2)>;
+ prop = <(1+2)>;
+ prop = <(1-2)>;
+ prop = /bits/ 32 <(1<<2)>;
+ prop = <(1>>2)>;
+ prop = <(1&2)>;
+ prop = <(1^2)>;
+ prop = <(1|2)>;
+ prop = <(1&&2)>;
+ prop = <(1||2)>;
+ prop = <(1?2:3)>;
+ list = <&HANDLE_2>, <0 0 0 1>;
+ };
+
+ &phandle2 {
+ prop_handle = <&HANDLE_2>;
+ };
+};
diff --git a/t/t4034/dts/pre b/t/t4034/dts/pre
new file mode 100644
index 0000000000..b6a905113c
--- /dev/null
+++ b/t/t4034/dts/pre
@@ -0,0 +1,32 @@
+/ {
+ this_handle: node@f00 {
+ compatible = "mydev";
+ string-prop = start: "hello world!" end: ;
+ #size-cells = <0+0>;
+ reg = <0xf00>;
+ prop = <1>;
+ prop = <-1e10>;
+ prop = <(!3)>;
+ prop = <(~3)>;
+ prop = <(3*4)>;
+ prop = <(3&4)>;
+ prop = <(3*4)>;
+ prop = <(3/4)>;
+ prop = <(3%4)>;
+ prop = <(3+4)>;
+ prop = <(3-4)>;
+ prop = /bits/ 64 <(3<<4)>;
+ prop = <(3>>4)>;
+ prop = <(3&4)>;
+ prop = <(3^4)>;
+ prop = <(3|4)>;
+ prop = <(3&&4)>;
+ prop = <(3||4)>;
+ prop = <(4?5:3)>;
+ list = <&this_handle>, <0 0 0 0>;
+ };
+
+ &phandle {
+ pre-phandle = <&this_handle>;
+ };
+};
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index d4afe12554..94680836ce 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -354,7 +354,7 @@ test_expect_failure 'combine diff coalesce three parents' '
'
# Test for a bug reported at
-# https://public-inbox.org/git/20130515143508.GO25742@login.drsnuggles.stderr.nl/
+# https://lore.kernel.org/git/20130515143508.GO25742@login.drsnuggles.stderr.nl/
# where a delete lines were missing from combined diff output when they
# occurred exactly before the context lines of a later change.
test_expect_success 'combine diff missing delete bug' '
@@ -440,11 +440,13 @@ test_expect_success 'setup for --combined-all-paths' '
git branch side2c &&
git checkout side1c &&
test_seq 1 10 >filename-side1c &&
+ side1cf=$(git hash-object filename-side1c) &&
git add filename-side1c &&
git commit -m with &&
git checkout side2c &&
test_seq 1 9 >filename-side2c &&
echo ten >>filename-side2c &&
+ side2cf=$(git hash-object filename-side2c) &&
git add filename-side2c &&
git commit -m iam &&
git checkout -b mergery side1c &&
@@ -452,13 +454,14 @@ test_expect_success 'setup for --combined-all-paths' '
git rm filename-side1c &&
echo eleven >>filename-side2c &&
git mv filename-side2c filename-merged &&
+ mergedf=$(git hash-object filename-merged) &&
git add filename-merged &&
git commit
'
test_expect_success '--combined-all-paths and --raw' '
- cat <<-\EOF >expect &&
- ::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR filename-side1c filename-side2c filename-merged
+ cat <<-EOF >expect &&
+ ::100644 100644 100644 $side1cf $side2cf $mergedf RR filename-side1c filename-side2c filename-merged
EOF
git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp &&
sed 1d <actual.tmp >actual &&
@@ -482,11 +485,13 @@ test_expect_success FUNNYNAMES 'setup for --combined-all-paths with funny names'
git checkout side1d &&
test_seq 1 10 >"$(printf "file\twith\ttabs")" &&
git add file* &&
+ side1df=$(git hash-object *tabs) &&
git commit -m with &&
git checkout side2d &&
test_seq 1 9 >"$(printf "i\tam\ttabbed")" &&
echo ten >>"$(printf "i\tam\ttabbed")" &&
git add *tabbed &&
+ side2df=$(git hash-object *tabbed) &&
git commit -m iam &&
git checkout -b funny-names-mergery side1d &&
git merge --no-commit side2d &&
@@ -494,12 +499,14 @@ test_expect_success FUNNYNAMES 'setup for --combined-all-paths with funny names'
echo eleven >>"$(printf "i\tam\ttabbed")" &&
git mv "$(printf "i\tam\ttabbed")" "$(printf "fickle\tnaming")" &&
git add fickle* &&
- git commit
+ headf=$(git hash-object fickle*) &&
+ git commit &&
+ head=$(git rev-parse HEAD)
'
test_expect_success FUNNYNAMES '--combined-all-paths and --raw and funny names' '
- cat <<-\EOF >expect &&
- ::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR "file\twith\ttabs" "i\tam\ttabbed" "fickle\tnaming"
+ cat <<-EOF >expect &&
+ ::100644 100644 100644 $side1df $side2df $headf RR "file\twith\ttabs" "i\tam\ttabbed" "fickle\tnaming"
EOF
git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp &&
sed 1d <actual.tmp >actual &&
@@ -507,9 +514,9 @@ test_expect_success FUNNYNAMES '--combined-all-paths and --raw and funny names'
'
test_expect_success FUNNYNAMES '--combined-all-paths and --raw -and -z and funny names' '
- printf "aaf8087c3cbd4db8e185a2d074cf27c53cfb75d7\0::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR\0file\twith\ttabs\0i\tam\ttabbed\0fickle\tnaming\0" >expect &&
+ printf "$head\0::100644 100644 100644 $side1df $side2df $headf RR\0file\twith\ttabs\0i\tam\ttabbed\0fickle\tnaming\0" >expect &&
git diff-tree -c -M --raw --combined-all-paths -z HEAD >actual &&
- test_cmp -a expect actual
+ test_cmp expect actual
'
test_expect_success FUNNYNAMES '--combined-all-paths and --cc and funny names' '
diff --git a/t/t4039-diff-assume-unchanged.sh b/t/t4039-diff-assume-unchanged.sh
index 53ac44b0f0..0eb0314a8b 100755
--- a/t/t4039-diff-assume-unchanged.sh
+++ b/t/t4039-diff-assume-unchanged.sh
@@ -12,6 +12,7 @@ test_expect_success 'setup' '
git commit -m zero &&
echo one > one &&
echo two > two &&
+ blob=$(git hash-object one) &&
git add one two &&
git commit -m onetwo &&
git update-index --assume-unchanged one &&
@@ -20,7 +21,7 @@ test_expect_success 'setup' '
'
test_expect_success 'diff-index does not examine assume-unchanged entries' '
- git diff-index HEAD^ -- one | grep -q 5626abf0f72e58d7a153368ba57db4c673c0e171
+ git diff-index HEAD^ -- one | grep -q $blob
'
test_expect_success 'diff-files does not examine assume-unchanged entries' '
diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh
index 619bf97098..f852136585 100755
--- a/t/t4041-diff-submodule-option.sh
+++ b/t/t4041-diff-submodule-option.sh
@@ -284,7 +284,7 @@ test_expect_success 'submodule contains untracked content (all ignored)' '
test_must_be_empty actual
'
-test_expect_success 'submodule contains untracked and modifed content' '
+test_expect_success 'submodule contains untracked and modified content' '
echo new > sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
@@ -294,7 +294,7 @@ test_expect_success 'submodule contains untracked and modifed content' '
test_cmp expected actual
'
-test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' '
+test_expect_success 'submodule contains untracked and modified content (untracked ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
@@ -303,19 +303,19 @@ test_expect_success 'submodule contains untracked and modifed content (untracked
test_cmp expected actual
'
-test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' '
+test_expect_success 'submodule contains untracked and modified content (dirty ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
test_must_be_empty actual
'
-test_expect_success 'submodule contains untracked and modifed content (all ignored)' '
+test_expect_success 'submodule contains untracked and modified content (all ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
test_must_be_empty actual
'
-test_expect_success 'submodule contains modifed content' '
+test_expect_success 'submodule contains modified content' '
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
@@ -369,7 +369,7 @@ test_expect_success 'modified submodule contains untracked content (all ignored)
test_must_be_empty actual
'
-test_expect_success 'modified submodule contains untracked and modifed content' '
+test_expect_success 'modified submodule contains untracked and modified content' '
echo modification >> sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
@@ -381,7 +381,7 @@ test_expect_success 'modified submodule contains untracked and modifed content'
test_cmp expected actual
'
-test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' '
+test_expect_success 'modified submodule contains untracked and modified content (untracked ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
@@ -392,7 +392,7 @@ test_expect_success 'modified submodule contains untracked and modifed content (
test_cmp expected actual
'
-test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' '
+test_expect_success 'modified submodule contains untracked and modified content (dirty ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
@@ -402,13 +402,13 @@ test_expect_success 'modified submodule contains untracked and modifed content (
test_cmp expected actual
'
-test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' '
+test_expect_success 'modified submodule contains untracked and modified content (all ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
test_must_be_empty actual
'
-test_expect_success 'modified submodule contains modifed content' '
+test_expect_success 'modified submodule contains modified content' '
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
diff --git a/t/t4044-diff-index-unique-abbrev.sh b/t/t4044-diff-index-unique-abbrev.sh
index 647905e01f..4701796d10 100755
--- a/t/t4044-diff-index-unique-abbrev.sh
+++ b/t/t4044-diff-index-unique-abbrev.sh
@@ -3,34 +3,48 @@
test_description='test unique sha1 abbreviation on "index from..to" line'
. ./test-lib.sh
-if ! test_have_prereq SHA1
-then
- skip_all='not using SHA-1 for objects'
- test_done
-fi
-
-cat >expect_initial <<EOF
-100644 blob 51d2738463ea4ca66f8691c91e33ce64b7d41bb1 foo
-EOF
+test_expect_success 'setup' '
+ test_oid_cache <<-EOF &&
+ val1 sha1:4827
+ val1 sha256:5664
-cat >expect_update <<EOF
-100644 blob 51d2738efb4ad8a1e40bed839ab8e116f0a15e47 foo
-EOF
+ val2 sha1:11742
+ val2 sha256:10625
-test_expect_success 'setup' '
- echo 4827 > foo &&
+ hash1 sha1:51d2738463ea4ca66f8691c91e33ce64b7d41bb1
+ hash1 sha256:ae31dfff0af93b2c62b0098a039b38569c43b0a7e97b873000ca42d128f27350
+
+ hasht1 sha1:51d27384
+ hasht1 sha256:ae31dfff
+
+ hash2 sha1:51d2738efb4ad8a1e40bed839ab8e116f0a15e47
+ hash2 sha256:ae31dffada88a46fd5f53c7ed5aa25a7a8951f1d5e88456c317c8d5484d263e5
+
+ hasht2 sha1:51d2738e
+ hasht2 sha256:ae31dffa
+ EOF
+
+ cat >expect_initial <<-EOF &&
+ 100644 blob $(test_oid hash1) foo
+ EOF
+
+ cat >expect_update <<-EOF &&
+ 100644 blob $(test_oid hash2) foo
+ EOF
+
+ echo "$(test_oid val1)" > foo &&
git add foo &&
git commit -m "initial" &&
git cat-file -p HEAD: > actual &&
test_cmp expect_initial actual &&
- echo 11742 > foo &&
+ echo "$(test_oid val2)" > foo &&
git commit -a -m "update" &&
git cat-file -p HEAD: > actual &&
test_cmp expect_update actual
'
cat >expect <<EOF
-index 51d27384..51d2738e 100644
+index $(test_oid hasht1)..$(test_oid hasht2) 100644
EOF
test_expect_success 'diff does not produce ambiguous index line' '
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 36f8ed8a81..258808708e 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -70,7 +70,7 @@ check_raw () {
expect=$1
shift
cat >expected <<-EOF
- :000000 100644 0000000000000000000000000000000000000000 $blob A $expect
+ :000000 100644 $ZERO_OID $blob A $expect
EOF
test_expect_success "--raw $*" "
git -C '$dir' diff --no-abbrev --raw $* HEAD^ >actual &&
diff --git a/t/t4048-diff-combined-binary.sh b/t/t4048-diff-combined-binary.sh
index 87a8949500..7f9ad9fa3d 100755
--- a/t/t4048-diff-combined-binary.sh
+++ b/t/t4048-diff-combined-binary.sh
@@ -9,24 +9,27 @@ test_expect_success 'setup binary merge conflict' '
git commit -m one &&
echo twoQ2 | q_to_nul >binary &&
git commit -a -m two &&
+ two=$(git rev-parse --short HEAD:binary) &&
git checkout -b branch-binary HEAD^ &&
echo threeQ3 | q_to_nul >binary &&
git commit -a -m three &&
+ three=$(git rev-parse --short HEAD:binary) &&
test_must_fail git merge master &&
echo resolvedQhooray | q_to_nul >binary &&
- git commit -a -m resolved
+ git commit -a -m resolved &&
+ res=$(git rev-parse --short HEAD:binary)
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --git a/binary b/binary
-index 7ea6ded..9563691 100644
+index $three..$res 100644
Binary files a/binary and b/binary differ
resolved
diff --git a/binary b/binary
-index 6197570..9563691 100644
+index $two..$res 100644
Binary files a/binary and b/binary differ
EOF
test_expect_success 'diff -m indicates binary-ness' '
@@ -34,11 +37,11 @@ test_expect_success 'diff -m indicates binary-ness' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --combined binary
-index 7ea6ded,6197570..9563691
+index $three,$two..$res
Binary files differ
EOF
test_expect_success 'diff -c indicates binary-ness' '
@@ -46,11 +49,11 @@ test_expect_success 'diff -c indicates binary-ness' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --cc binary
-index 7ea6ded,6197570..9563691
+index $three,$two..$res
Binary files differ
EOF
test_expect_success 'diff --cc indicates binary-ness' '
@@ -62,23 +65,26 @@ test_expect_success 'setup non-binary with binary attribute' '
git checkout master &&
test_commit one text &&
test_commit two text &&
+ two=$(git rev-parse --short HEAD:text) &&
git checkout -b branch-text HEAD^ &&
test_commit three text &&
+ three=$(git rev-parse --short HEAD:text) &&
test_must_fail git merge master &&
test_commit resolved text &&
+ res=$(git rev-parse --short HEAD:text) &&
echo text -diff >.gitattributes
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --git a/text b/text
-index 2bdf67a..2ab19ae 100644
+index $three..$res 100644
Binary files a/text and b/text differ
resolved
diff --git a/text b/text
-index f719efd..2ab19ae 100644
+index $two..$res 100644
Binary files a/text and b/text differ
EOF
test_expect_success 'diff -m respects binary attribute' '
@@ -86,11 +92,11 @@ test_expect_success 'diff -m respects binary attribute' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --combined text
-index 2bdf67a,f719efd..2ab19ae
+index $three,$two..$res
Binary files differ
EOF
test_expect_success 'diff -c respects binary attribute' '
@@ -98,11 +104,11 @@ test_expect_success 'diff -c respects binary attribute' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --cc text
-index 2bdf67a,f719efd..2ab19ae
+index $three,$two..$res
Binary files differ
EOF
test_expect_success 'diff --cc respects binary attribute' '
@@ -115,11 +121,11 @@ test_expect_success 'setup textconv attribute' '
git config diff.upcase.textconv "tr a-z A-Z <"
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --git a/text b/text
-index 2bdf67a..2ab19ae 100644
+index $three..$res 100644
--- a/text
+++ b/text
@@ -1 +1 @@
@@ -128,7 +134,7 @@ index 2bdf67a..2ab19ae 100644
resolved
diff --git a/text b/text
-index f719efd..2ab19ae 100644
+index $two..$res 100644
--- a/text
+++ b/text
@@ -1 +1 @@
@@ -140,11 +146,11 @@ test_expect_success 'diff -m respects textconv attribute' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --combined text
-index 2bdf67a,f719efd..2ab19ae
+index $three,$two..$res
--- a/text
+++ b/text
@@@ -1,1 -1,1 +1,1 @@@
@@ -157,11 +163,11 @@ test_expect_success 'diff -c respects textconv attribute' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
resolved
diff --cc text
-index 2bdf67a,f719efd..2ab19ae
+index $three,$two..$res
--- a/text
+++ b/text
@@@ -1,1 -1,1 +1,1 @@@
@@ -174,9 +180,9 @@ test_expect_success 'diff --cc respects textconv attribute' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
diff --combined text
-index 2bdf67a,f719efd..2ab19ae
+index $three,$two..$res
--- a/text
+++ b/text
@@@ -1,1 -1,1 +1,1 @@@
@@ -190,9 +196,9 @@ test_expect_success 'diff-tree plumbing does not respect textconv' '
test_cmp expect actual
'
-cat >expect <<'EOF'
+cat >expect <<EOF
diff --cc text
-index 2bdf67a,f719efd..0000000
+index $three,$two..0000000
--- a/text
+++ b/text
@@@ -1,1 -1,1 +1,5 @@@
diff --git a/t/t4054-diff-bogus-tree.sh b/t/t4054-diff-bogus-tree.sh
index fcae82fffa..8c95f152b2 100755
--- a/t/t4054-diff-bogus-tree.sh
+++ b/t/t4054-diff-bogus-tree.sh
@@ -4,8 +4,9 @@ test_description='test diff with a bogus tree containing the null sha1'
. ./test-lib.sh
test_expect_success 'create bogus tree' '
+ name=$(echo $ZERO_OID | sed -e "s/00/Q/g") &&
bogus_tree=$(
- printf "100644 fooQQQQQQQQQQQQQQQQQQQQQ" |
+ printf "100644 fooQ$name" |
q_to_nul |
git hash-object -w --stdin -t tree
)
diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh
index dff36b77ec..4f4b541658 100755
--- a/t/t4057-diff-combined-paths.sh
+++ b/t/t4057-diff-combined-paths.sh
@@ -33,7 +33,7 @@ test_expect_success 'trivial merge - combine-diff empty' '
'
-test_expect_success 'only one trully conflicting path' '
+test_expect_success 'only one truly conflicting path' '
git checkout side &&
for i in $(test_seq 2 9)
do
diff --git a/t/t4066-diff-emit-delay.sh b/t/t4066-diff-emit-delay.sh
index 5df6b5e64e..6331f63b12 100755
--- a/t/t4066-diff-emit-delay.sh
+++ b/t/t4066-diff-emit-delay.sh
@@ -18,7 +18,7 @@ test_expect_success 'set up history with a merge' '
'
test_expect_success 'log --cc -p --stat --color-moved' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
commit D
---
D.t | 1 +
@@ -26,7 +26,7 @@ test_expect_success 'log --cc -p --stat --color-moved' '
diff --git a/D.t b/D.t
new file mode 100644
- index 0000000..1784810
+ index 0000000..$(git rev-parse --short D:D.t)
--- /dev/null
+++ b/D.t
@@ -0,0 +1 @@
@@ -42,7 +42,7 @@ test_expect_success 'log --cc -p --stat --color-moved' '
diff --git a/C.t b/C.t
new file mode 100644
- index 0000000..3cc58df
+ index 0000000..$(git rev-parse --short C:C.t)
--- /dev/null
+++ b/C.t
@@ -0,0 +1 @@
@@ -54,7 +54,7 @@ test_expect_success 'log --cc -p --stat --color-moved' '
diff --git a/B.t b/B.t
new file mode 100644
- index 0000000..223b783
+ index 0000000..$(git rev-parse --short B:B.t)
--- /dev/null
+++ b/B.t
@@ -0,0 +1 @@
@@ -66,7 +66,7 @@ test_expect_success 'log --cc -p --stat --color-moved' '
diff --git a/A.t b/A.t
new file mode 100644
- index 0000000..f70f10e
+ index 0000000..$(git rev-parse --short A:A.t)
--- /dev/null
+++ b/A.t
@@ -0,0 +1 @@
diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh
index 90c8fb2901..4831ad35e6 100755
--- a/t/t4067-diff-partial-clone.sh
+++ b/t/t4067-diff-partial-clone.sh
@@ -75,6 +75,37 @@ test_expect_success 'diff skips same-OID blobs' '
! grep "want $(cat hash-b)" trace
'
+test_expect_success 'when fetching missing objects, diff skips GITLINKs' '
+ test_when_finished "rm -rf sub server client trace" &&
+
+ test_create_repo sub &&
+ test_commit -C sub first &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ git -C server add a &&
+ git -C server submodule add "file://$(pwd)/sub" &&
+ git -C server commit -m x &&
+
+ test_commit -C server/sub second &&
+ echo another-a >server/a &&
+ git -C server add a sub &&
+ git -C server commit -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ echo a | git hash-object --stdin >hash-old-a &&
+ echo another-a | git hash-object --stdin >hash-new-a &&
+
+ # Ensure that a and another-a are fetched, and check (by successful
+ # execution of the diff) that no invalid OIDs are sent.
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD &&
+ grep "want $(cat hash-old-a)" trace &&
+ grep "want $(cat hash-new-a)" trace
+'
+
test_expect_success 'diff with rename detection batches blobs' '
test_when_finished "rm -rf server client trace" &&
diff --git a/t/t4100/t-apply-1.patch b/t/t4100/t-apply-1.patch
index 90ab54f0f5..43394f8285 100644
--- a/t/t4100/t-apply-1.patch
+++ b/t/t4100/t-apply-1.patch
@@ -75,8 +75,8 @@ diff --git a/Documentation/git.txt b/Documentation/git.txt
+link:git-ssh-pull.html[git-ssh-pull]::
Pulls from a remote repository over ssh connection
- Interogators:
-@@ -156,8 +156,8 @@ Interogators:
+ Interrogators:
+@@ -156,8 +156,8 @@ Interrogators:
link:git-diff-helper.html[git-diff-helper]::
Generates patch format output for git-diff-*
diff --git a/t/t4100/t-apply-3.patch b/t/t4100/t-apply-3.patch
index 90cdbaa5bb..cac172e779 100644
--- a/t/t4100/t-apply-3.patch
+++ b/t/t4100/t-apply-3.patch
@@ -211,7 +211,7 @@ dissimilarity index 82%
-
- /* If this is an exact directory match, we may have
- * directory files following this path. Match on them.
-- * Otherwise, we're at a pach subcomponent, and we need
+- * Otherwise, we're at a patch subcomponent, and we need
- * to try to match again.
- */
- if (mtype == 0)
diff --git a/t/t4100/t-apply-5.patch b/t/t4100/t-apply-5.patch
index 5f6ddc1059..57ec79d887 100644
--- a/t/t4100/t-apply-5.patch
+++ b/t/t4100/t-apply-5.patch
@@ -185,8 +185,8 @@ diff a/Documentation/git.txt b/Documentation/git.txt
+link:git-ssh-pull.html[git-ssh-pull]::
Pulls from a remote repository over ssh connection
- Interogators:
-@@ -156,8 +156,8 @@ Interogators:
+ Interrogators:
+@@ -156,8 +156,8 @@ Interrogators:
link:git-diff-helper.html[git-diff-helper]::
Generates patch format output for git-diff-*
diff --git a/t/t4100/t-apply-7.patch b/t/t4100/t-apply-7.patch
index 07c6589e74..fa24305108 100644
--- a/t/t4100/t-apply-7.patch
+++ b/t/t4100/t-apply-7.patch
@@ -335,7 +335,7 @@ diff a/ls-tree.c b/ls-tree.c
- /* If this is an exact directory match, we may have
- * directory files following this path. Match on them.
-- * Otherwise, we're at a pach subcomponent, and we need
+- * Otherwise, we're at a patch subcomponent, and we need
- * to try to match again.
+ if (e->directory) {
+ /* If this is a directory, we have the following cases:
diff --git a/t/t4108-apply-threeway.sh b/t/t4108-apply-threeway.sh
index fa5d4efb89..d7349ced6b 100755
--- a/t/t4108-apply-threeway.sh
+++ b/t/t4108-apply-threeway.sh
@@ -4,23 +4,17 @@ test_description='git apply --3way'
. ./test-lib.sh
-create_file () {
- for i
- do
- echo "$i"
- done
-}
-
-sanitize_conflicted_diff () {
+print_sanitized_conflicted_diff () {
+ git diff HEAD >diff.raw &&
sed -e '
/^index /d
- s/^\(+[<>][<>][<>][<>]*\) .*/\1/
- '
+ s/^\(+[<>|][<>|][<>|][<>|]*\) .*/\1/
+ ' diff.raw
}
test_expect_success setup '
test_tick &&
- create_file >one 1 2 3 4 5 6 7 &&
+ test_write_lines 1 2 3 4 5 6 7 >one &&
cat one >two &&
git add one two &&
git commit -m initial &&
@@ -28,13 +22,13 @@ test_expect_success setup '
git branch side &&
test_tick &&
- create_file >one 1 two 3 4 5 six 7 &&
- create_file >two 1 two 3 4 5 6 7 &&
+ test_write_lines 1 two 3 4 5 six 7 >one &&
+ test_write_lines 1 two 3 4 5 6 7 >two &&
git commit -a -m master &&
git checkout side &&
- create_file >one 1 2 3 4 five 6 7 &&
- create_file >two 1 2 3 4 five 6 7 &&
+ test_write_lines 1 2 3 4 five 6 7 >one &&
+ test_write_lines 1 2 3 4 five 6 7 >two &&
git commit -a -m side &&
git checkout master
@@ -52,7 +46,7 @@ test_expect_success 'apply without --3way' '
git diff-index --exit-code --cached HEAD
'
-test_expect_success 'apply with --3way' '
+test_apply_with_3way () {
# Merging side should be similar to applying this patch
git diff ...side >P.diff &&
@@ -61,22 +55,31 @@ test_expect_success 'apply with --3way' '
git checkout master^0 &&
test_must_fail git merge --no-commit side &&
git ls-files -s >expect.ls &&
- git diff HEAD | sanitize_conflicted_diff >expect.diff &&
+ print_sanitized_conflicted_diff >expect.diff &&
# should fail to apply
git reset --hard &&
git checkout master^0 &&
test_must_fail git apply --index --3way P.diff &&
git ls-files -s >actual.ls &&
- git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+ print_sanitized_conflicted_diff >actual.diff &&
# The result should resemble the corresponding merge
test_cmp expect.ls actual.ls &&
test_cmp expect.diff actual.diff
+}
+
+test_expect_success 'apply with --3way' '
+ test_apply_with_3way
+'
+
+test_expect_success 'apply with --3way with merge.conflictStyle = diff3' '
+ test_config merge.conflictStyle diff3 &&
+ test_apply_with_3way
'
test_expect_success 'apply with --3way with rerere enabled' '
- git config rerere.enabled true &&
+ test_config rerere.enabled true &&
# Merging side should be similar to applying this patch
git diff ...side >P.diff &&
@@ -87,7 +90,7 @@ test_expect_success 'apply with --3way with rerere enabled' '
test_must_fail git merge --no-commit side &&
# Manually resolve and record the resolution
- create_file 1 two 3 4 five six 7 >one &&
+ test_write_lines 1 two 3 4 five six 7 >one &&
git rerere &&
cat one >expect &&
@@ -104,14 +107,14 @@ test_expect_success 'apply -3 with add/add conflict setup' '
git reset --hard &&
git checkout -b adder &&
- create_file 1 2 3 4 5 6 7 >three &&
- create_file 1 2 3 4 5 6 7 >four &&
+ test_write_lines 1 2 3 4 5 6 7 >three &&
+ test_write_lines 1 2 3 4 5 6 7 >four &&
git add three four &&
git commit -m "add three and four" &&
git checkout -b another adder^ &&
- create_file 1 2 3 4 5 6 7 >three &&
- create_file 1 2 3 four 5 6 7 >four &&
+ test_write_lines 1 2 3 4 5 6 7 >three &&
+ test_write_lines 1 2 3 four 5 6 7 >four &&
git add three four &&
git commit -m "add three and four" &&
@@ -121,7 +124,7 @@ test_expect_success 'apply -3 with add/add conflict setup' '
git checkout adder^0 &&
test_must_fail git merge --no-commit another &&
git ls-files -s >expect.ls &&
- git diff HEAD | sanitize_conflicted_diff >expect.diff
+ print_sanitized_conflicted_diff >expect.diff
'
test_expect_success 'apply -3 with add/add conflict' '
@@ -131,7 +134,7 @@ test_expect_success 'apply -3 with add/add conflict' '
test_must_fail git apply --index --3way P.diff &&
# ... and leave conflicts in the index and in the working tree
git ls-files -s >actual.ls &&
- git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+ print_sanitized_conflicted_diff >actual.diff &&
# The result should resemble the corresponding merge
test_cmp expect.ls actual.ls &&
diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh
index 0043930ca6..99ed4cc546 100755
--- a/t/t4134-apply-submodule.sh
+++ b/t/t4134-apply-submodule.sh
@@ -8,6 +8,7 @@ test_description='git apply submodule tests'
. ./test-lib.sh
test_expect_success setup '
+ test_oid_init &&
cat > create-sm.patch <<EOF &&
diff --git a/dir/sm b/dir/sm
new file mode 160000
@@ -15,7 +16,7 @@ index 0000000..0123456
--- /dev/null
+++ b/dir/sm
@@ -0,0 +1 @@
-+Subproject commit 0123456789abcdef0123456789abcdef01234567
++Subproject commit $(test_oid numeric)
EOF
cat > remove-sm.patch <<EOF
diff --git a/dir/sm b/dir/sm
@@ -24,7 +25,7 @@ index 0123456..0000000
--- a/dir/sm
+++ /dev/null
@@ -1 +0,0 @@
--Subproject commit 0123456789abcdef0123456789abcdef01234567
+-Subproject commit $(test_oid numeric)
EOF
'
diff --git a/t/t4138-apply-ws-expansion.sh b/t/t4138-apply-ws-expansion.sh
index 3b636a63a3..b19faeb67a 100755
--- a/t/t4138-apply-ws-expansion.sh
+++ b/t/t4138-apply-ws-expansion.sh
@@ -17,8 +17,8 @@ test_expect_success setup '
printf "\t%s\n" 1 2 3 >after &&
printf "%64s\n" a b c >>after &&
printf "\t%s\n" 4 5 6 >>after &&
- git diff --no-index before after |
- sed -e "s/before/test-1/" -e "s/after/test-1/" >patch1.patch &&
+ test_expect_code 1 git diff --no-index before after >patch1.patch.raw &&
+ sed -e "s/before/test-1/" -e "s/after/test-1/" patch1.patch.raw >patch1.patch &&
printf "%64s\n" 1 2 3 4 5 6 >test-1 &&
printf "%64s\n" 1 2 3 a b c 4 5 6 >expect-1 &&
@@ -33,8 +33,8 @@ test_expect_success setup '
x=$(( $x + 1 ))
done &&
printf "\t%s\n" d e f >>after &&
- git diff --no-index before after |
- sed -e "s/before/test-2/" -e "s/after/test-2/" >patch2.patch &&
+ test_expect_code 1 git diff --no-index before after >patch2.patch.raw &&
+ sed -e "s/before/test-2/" -e "s/after/test-2/" patch2.patch.raw >patch2.patch &&
printf "%64s\n" a b c d e f >test-2 &&
printf "%64s\n" a b c >expect-2 &&
x=1 &&
@@ -56,8 +56,8 @@ test_expect_success setup '
x=$(( $x + 1 ))
done &&
printf "\t%s\n" d e f >>after &&
- git diff --no-index before after |
- sed -e "s/before/test-3/" -e "s/after/test-3/" >patch3.patch &&
+ test_expect_code 1 git diff --no-index before after >patch3.patch.raw &&
+ sed -e "s/before/test-3/" -e "s/after/test-3/" patch3.patch.raw >patch3.patch &&
printf "%64s\n" a b c d e f >test-3 &&
printf "%64s\n" a b c >expect-3 &&
x=0 &&
@@ -84,8 +84,8 @@ test_expect_success setup '
printf "\t%02d\n" $x >>after
x=$(( $x + 1 ))
done &&
- git diff --no-index before after |
- sed -e "s/before/test-4/" -e "s/after/test-4/" >patch4.patch &&
+ test_expect_code 1 git diff --no-index before after >patch4.patch.raw &&
+ sed -e "s/before/test-4/" -e "s/after/test-4/" patch4.patch.raw >patch4.patch &&
>test-4 &&
x=0 &&
while test $x -lt 50
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 3f7f750cc8..4f1e24ecbe 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -1061,4 +1061,56 @@ test_expect_success 'am --quit keeps HEAD where it is' '
test_cmp expected actual
'
+test_expect_success 'am and .gitattibutes' '
+ test_create_repo attributes &&
+ (
+ cd attributes &&
+ test_commit init &&
+ git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
+ git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
+
+ test_commit second &&
+ git checkout -b test HEAD^ &&
+
+ echo "*.txt filter=test conflict-marker-size=10" >.gitattributes &&
+ git add .gitattributes &&
+ test_commit third &&
+
+ echo "This text is smudged." >a.txt &&
+ git add a.txt &&
+ test_commit fourth &&
+
+ git checkout -b removal HEAD^ &&
+ git rm .gitattributes &&
+ git add -u &&
+ test_commit fifth &&
+ git cherry-pick test &&
+
+ git checkout -b conflict third &&
+ echo "This text is different." >a.txt &&
+ git add a.txt &&
+ test_commit sixth &&
+
+ git checkout test &&
+ git format-patch --stdout master..HEAD >patches &&
+ git reset --hard master &&
+ git am patches &&
+ grep "smudged" a.txt &&
+
+ git checkout removal &&
+ git reset --hard &&
+ git format-patch --stdout master..HEAD >patches &&
+ git reset --hard master &&
+ git am patches &&
+ grep "clean" a.txt &&
+
+ git checkout conflict &&
+ git reset --hard &&
+ git format-patch --stdout master..HEAD >patches &&
+ git reset --hard fourth &&
+ test_must_fail git am -3 patches &&
+ grep "<<<<<<<<<<" a.txt
+ )
+'
+
test_done
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index 55b7750ade..831d424c47 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -25,6 +25,7 @@ test_description='git rerere
. ./test-lib.sh
test_expect_success 'setup' '
+ test_oid_init &&
cat >a1 <<-\EOF &&
Some title
==========
@@ -210,7 +211,7 @@ test_expect_success 'set up for garbage collection tests' '
echo Hello >$rr/preimage &&
echo World >$rr/postimage &&
- sha2=4000000000000000000000000000000000000000 &&
+ sha2=$(test_oid deadbeef) &&
rr2=.git/rr-cache/$sha2 &&
mkdir $rr2 &&
echo Hello >$rr2/preimage &&
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index c20209324c..192347a3e1 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -87,12 +87,12 @@ test_expect_success 'format %w(,1,2)' '
'
cat > expect << EOF
-804a787 sixth
-394ef78 fifth
-5d31159 fourth
-2fbe8c0 third
-f7dab8e second
-3a2fdcb initial
+$(git rev-parse --short :/sixth ) sixth
+$(git rev-parse --short :/fifth ) fifth
+$(git rev-parse --short :/fourth ) fourth
+$(git rev-parse --short :/third ) third
+$(git rev-parse --short :/second ) second
+$(git rev-parse --short :/initial) initial
EOF
test_expect_success 'oneline' '
@@ -173,43 +173,45 @@ test_expect_success 'git config log.follow is overridden by --no-follow' '
verbose test "$actual" = "$expect"
'
+# Note that these commits are intentionally listed out of order.
+last_three="$(git rev-parse :/fourth :/sixth :/fifth)"
cat > expect << EOF
-804a787 sixth
-394ef78 fifth
-5d31159 fourth
+$(git rev-parse --short :/sixth ) sixth
+$(git rev-parse --short :/fifth ) fifth
+$(git rev-parse --short :/fourth) fourth
EOF
test_expect_success 'git log --no-walk <commits> sorts by commit time' '
- git log --no-walk --oneline 5d31159 804a787 394ef78 > actual &&
+ git log --no-walk --oneline $last_three > actual &&
test_cmp expect actual
'
test_expect_success 'git log --no-walk=sorted <commits> sorts by commit time' '
- git log --no-walk=sorted --oneline 5d31159 804a787 394ef78 > actual &&
+ git log --no-walk=sorted --oneline $last_three > actual &&
test_cmp expect actual
'
cat > expect << EOF
-=== 804a787 sixth
-=== 394ef78 fifth
-=== 5d31159 fourth
+=== $(git rev-parse --short :/sixth ) sixth
+=== $(git rev-parse --short :/fifth ) fifth
+=== $(git rev-parse --short :/fourth) fourth
EOF
test_expect_success 'git log --line-prefix="=== " --no-walk <commits> sorts by commit time' '
- git log --line-prefix="=== " --no-walk --oneline 5d31159 804a787 394ef78 > actual &&
+ git log --line-prefix="=== " --no-walk --oneline $last_three > actual &&
test_cmp expect actual
'
cat > expect << EOF
-5d31159 fourth
-804a787 sixth
-394ef78 fifth
+$(git rev-parse --short :/fourth) fourth
+$(git rev-parse --short :/sixth ) sixth
+$(git rev-parse --short :/fifth ) fifth
EOF
test_expect_success 'git log --no-walk=unsorted <commits> leaves list of commits as given' '
- git log --no-walk=unsorted --oneline 5d31159 804a787 394ef78 > actual &&
+ git log --no-walk=unsorted --oneline $last_three > actual &&
test_cmp expect actual
'
test_expect_success 'git show <commits> leaves list of commits as given' '
- git show --oneline -s 5d31159 804a787 394ef78 > actual &&
+ git show --oneline -s $last_three > actual &&
test_cmp expect actual
'
@@ -667,7 +669,7 @@ cat > expect <<\EOF
* | | fifth
* | | fourth
|/ /
-* | third
+* / third
|/
* second
* initial
@@ -837,6 +839,21 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' '
test_cmp expect.decorate actual
'
+test_expect_success 'decorate-refs-exclude and simplify-by-decoration' '
+ cat >expect.decorate <<-\EOF &&
+ Merge-tag-reach (HEAD -> master)
+ reach (tag: reach, reach)
+ seventh (tag: seventh)
+ Merge-branch-tangle
+ Merge-branch-side-early-part-into-tangle (tangle)
+ tangle-a (tag: tangle-a)
+ EOF
+ git log -n6 --decorate=short --pretty="tformat:%f%d" \
+ --decorate-refs-exclude="*octopus*" \
+ --simplify-by-decoration >actual &&
+ test_cmp expect.decorate actual
+'
+
test_expect_success 'log.decorate config parsing' '
git log --oneline --decorate=full >expect.full &&
git log --oneline --decorate=short >expect.short &&
@@ -942,7 +959,7 @@ cat >expect <<\EOF
| |
| | diff --git a/reach.t b/reach.t
| | new file mode 100644
-| | index 0000000..10c9591
+| | index BEFORE..AFTER
| | --- /dev/null
| | +++ b/reach.t
| | @@ -0,0 +1 @@
@@ -965,7 +982,7 @@ cat >expect <<\EOF
| | |
| | | diff --git a/octopus-b.t b/octopus-b.t
| | | new file mode 100644
-| | | index 0000000..d5fcad0
+| | | index BEFORE..AFTER
| | | --- /dev/null
| | | +++ b/octopus-b.t
| | | @@ -0,0 +1 @@
@@ -981,7 +998,7 @@ cat >expect <<\EOF
| |
| | diff --git a/octopus-a.t b/octopus-a.t
| | new file mode 100644
-| | index 0000000..11ee015
+| | index BEFORE..AFTER
| | --- /dev/null
| | +++ b/octopus-a.t
| | @@ -0,0 +1 @@
@@ -997,7 +1014,7 @@ cat >expect <<\EOF
|
| diff --git a/seventh.t b/seventh.t
| new file mode 100644
-| index 0000000..9744ffc
+| index BEFORE..AFTER
| --- /dev/null
| +++ b/seventh.t
| @@ -0,0 +1 @@
@@ -1031,7 +1048,7 @@ cat >expect <<\EOF
| | | |
| | | | diff --git a/tangle-a b/tangle-a
| | | | new file mode 100644
-| | | | index 0000000..7898192
+| | | | index BEFORE..AFTER
| | | | --- /dev/null
| | | | +++ b/tangle-a
| | | | @@ -0,0 +1 @@
@@ -1053,7 +1070,7 @@ cat >expect <<\EOF
| | | |
| | | | diff --git a/2 b/2
| | | | new file mode 100644
-| | | | index 0000000..0cfbf08
+| | | | index BEFORE..AFTER
| | | | --- /dev/null
| | | | +++ b/2
| | | | @@ -0,0 +1 @@
@@ -1069,7 +1086,7 @@ cat >expect <<\EOF
| | | |
| | | | diff --git a/1 b/1
| | | | new file mode 100644
-| | | | index 0000000..d00491f
+| | | | index BEFORE..AFTER
| | | | --- /dev/null
| | | | +++ b/1
| | | | @@ -0,0 +1 @@
@@ -1085,7 +1102,7 @@ cat >expect <<\EOF
| | | |
| | | | diff --git a/one b/one
| | | | new file mode 100644
-| | | | index 0000000..9a33383
+| | | | index BEFORE..AFTER
| | | | --- /dev/null
| | | | +++ b/one
| | | | @@ -0,0 +1 @@
@@ -1101,7 +1118,7 @@ cat >expect <<\EOF
| | |
| | | diff --git a/a/two b/a/two
| | | deleted file mode 100644
-| | | index 9245af5..0000000
+| | | index BEFORE..AFTER
| | | --- a/a/two
| | | +++ /dev/null
| | | @@ -1 +0,0 @@
@@ -1117,7 +1134,7 @@ cat >expect <<\EOF
| | |
| | | diff --git a/a/two b/a/two
| | | new file mode 100644
-| | | index 0000000..9245af5
+| | | index BEFORE..AFTER
| | | --- /dev/null
| | | +++ b/a/two
| | | @@ -0,0 +1 @@
@@ -1133,7 +1150,7 @@ cat >expect <<\EOF
| |
| | diff --git a/ein b/ein
| | new file mode 100644
-| | index 0000000..9d7e69f
+| | index BEFORE..AFTER
| | --- /dev/null
| | +++ b/ein
| | @@ -0,0 +1 @@
@@ -1150,14 +1167,14 @@ cat >expect <<\EOF
|
| diff --git a/ichi b/ichi
| new file mode 100644
-| index 0000000..9d7e69f
+| index BEFORE..AFTER
| --- /dev/null
| +++ b/ichi
| @@ -0,0 +1 @@
| +ichi
| diff --git a/one b/one
| deleted file mode 100644
-| index 9d7e69f..0000000
+| index BEFORE..AFTER
| --- a/one
| +++ /dev/null
| @@ -1 +0,0 @@
@@ -1172,7 +1189,7 @@ cat >expect <<\EOF
| 1 file changed, 1 insertion(+), 1 deletion(-)
|
| diff --git a/one b/one
-| index 5626abf..9d7e69f 100644
+| index BEFORE..AFTER 100644
| --- a/one
| +++ b/one
| @@ -1 +1 @@
@@ -1189,7 +1206,7 @@ cat >expect <<\EOF
diff --git a/one b/one
new file mode 100644
- index 0000000..5626abf
+ index BEFORE..AFTER
--- /dev/null
+++ b/one
@@ -0,0 +1 @@
@@ -1206,7 +1223,8 @@ sanitize_output () {
-e 's/, 0 insertions(+)//' \
-e 's/ 1 files changed, / 1 file changed, /' \
-e 's/, 1 deletions(-)/, 1 deletion(-)/' \
- -e 's/, 1 insertions(+)/, 1 insertion(+)/'
+ -e 's/, 1 insertions(+)/, 1 insertion(+)/' \
+ -e 's/index [0-9a-f]*\.\.[0-9a-f]*/index BEFORE..AFTER/'
}
test_expect_success 'log --graph with diff and stats' '
@@ -1232,7 +1250,7 @@ cat >expect <<\EOF
*** | |
*** | | diff --git a/reach.t b/reach.t
*** | | new file mode 100644
-*** | | index 0000000..10c9591
+*** | | index BEFORE..AFTER
*** | | --- /dev/null
*** | | +++ b/reach.t
*** | | @@ -0,0 +1 @@
@@ -1255,7 +1273,7 @@ cat >expect <<\EOF
*** | | |
*** | | | diff --git a/octopus-b.t b/octopus-b.t
*** | | | new file mode 100644
-*** | | | index 0000000..d5fcad0
+*** | | | index BEFORE..AFTER
*** | | | --- /dev/null
*** | | | +++ b/octopus-b.t
*** | | | @@ -0,0 +1 @@
@@ -1271,7 +1289,7 @@ cat >expect <<\EOF
*** | |
*** | | diff --git a/octopus-a.t b/octopus-a.t
*** | | new file mode 100644
-*** | | index 0000000..11ee015
+*** | | index BEFORE..AFTER
*** | | --- /dev/null
*** | | +++ b/octopus-a.t
*** | | @@ -0,0 +1 @@
@@ -1287,7 +1305,7 @@ cat >expect <<\EOF
*** |
*** | diff --git a/seventh.t b/seventh.t
*** | new file mode 100644
-*** | index 0000000..9744ffc
+*** | index BEFORE..AFTER
*** | --- /dev/null
*** | +++ b/seventh.t
*** | @@ -0,0 +1 @@
@@ -1321,7 +1339,7 @@ cat >expect <<\EOF
*** | | | |
*** | | | | diff --git a/tangle-a b/tangle-a
*** | | | | new file mode 100644
-*** | | | | index 0000000..7898192
+*** | | | | index BEFORE..AFTER
*** | | | | --- /dev/null
*** | | | | +++ b/tangle-a
*** | | | | @@ -0,0 +1 @@
@@ -1343,7 +1361,7 @@ cat >expect <<\EOF
*** | | | |
*** | | | | diff --git a/2 b/2
*** | | | | new file mode 100644
-*** | | | | index 0000000..0cfbf08
+*** | | | | index BEFORE..AFTER
*** | | | | --- /dev/null
*** | | | | +++ b/2
*** | | | | @@ -0,0 +1 @@
@@ -1359,7 +1377,7 @@ cat >expect <<\EOF
*** | | | |
*** | | | | diff --git a/1 b/1
*** | | | | new file mode 100644
-*** | | | | index 0000000..d00491f
+*** | | | | index BEFORE..AFTER
*** | | | | --- /dev/null
*** | | | | +++ b/1
*** | | | | @@ -0,0 +1 @@
@@ -1375,7 +1393,7 @@ cat >expect <<\EOF
*** | | | |
*** | | | | diff --git a/one b/one
*** | | | | new file mode 100644
-*** | | | | index 0000000..9a33383
+*** | | | | index BEFORE..AFTER
*** | | | | --- /dev/null
*** | | | | +++ b/one
*** | | | | @@ -0,0 +1 @@
@@ -1391,7 +1409,7 @@ cat >expect <<\EOF
*** | | |
*** | | | diff --git a/a/two b/a/two
*** | | | deleted file mode 100644
-*** | | | index 9245af5..0000000
+*** | | | index BEFORE..AFTER
*** | | | --- a/a/two
*** | | | +++ /dev/null
*** | | | @@ -1 +0,0 @@
@@ -1407,7 +1425,7 @@ cat >expect <<\EOF
*** | | |
*** | | | diff --git a/a/two b/a/two
*** | | | new file mode 100644
-*** | | | index 0000000..9245af5
+*** | | | index BEFORE..AFTER
*** | | | --- /dev/null
*** | | | +++ b/a/two
*** | | | @@ -0,0 +1 @@
@@ -1423,7 +1441,7 @@ cat >expect <<\EOF
*** | |
*** | | diff --git a/ein b/ein
*** | | new file mode 100644
-*** | | index 0000000..9d7e69f
+*** | | index BEFORE..AFTER
*** | | --- /dev/null
*** | | +++ b/ein
*** | | @@ -0,0 +1 @@
@@ -1440,14 +1458,14 @@ cat >expect <<\EOF
*** |
*** | diff --git a/ichi b/ichi
*** | new file mode 100644
-*** | index 0000000..9d7e69f
+*** | index BEFORE..AFTER
*** | --- /dev/null
*** | +++ b/ichi
*** | @@ -0,0 +1 @@
*** | +ichi
*** | diff --git a/one b/one
*** | deleted file mode 100644
-*** | index 9d7e69f..0000000
+*** | index BEFORE..AFTER
*** | --- a/one
*** | +++ /dev/null
*** | @@ -1 +0,0 @@
@@ -1462,7 +1480,7 @@ cat >expect <<\EOF
*** | 1 file changed, 1 insertion(+), 1 deletion(-)
*** |
*** | diff --git a/one b/one
-*** | index 5626abf..9d7e69f 100644
+*** | index BEFORE..AFTER 100644
*** | --- a/one
*** | +++ b/one
*** | @@ -1 +1 @@
@@ -1479,7 +1497,7 @@ cat >expect <<\EOF
***
*** diff --git a/one b/one
*** new file mode 100644
-*** index 0000000..5626abf
+*** index BEFORE..AFTER
*** --- /dev/null
*** +++ b/one
*** @@ -0,0 +1 @@
@@ -1555,6 +1573,14 @@ test_expect_success GPG 'setup signed branch' '
git commit -S -m signed_commit
'
+test_expect_success GPG 'setup signed branch with subkey' '
+ test_when_finished "git reset --hard && git checkout master" &&
+ git checkout -b signed-subkey master &&
+ echo foo >foo &&
+ git add foo &&
+ git commit -SB7227189 -m signed_commit
+'
+
test_expect_success GPGSM 'setup signed branch x509' '
test_when_finished "git reset --hard && git checkout master" &&
git checkout -b signed-x509 master &&
@@ -1565,6 +1591,18 @@ test_expect_success GPGSM 'setup signed branch x509' '
git commit -S -m signed_commit
'
+test_expect_success GPGSM 'log x509 fingerprint' '
+ echo "F8BF62E0693D0694816377099909C779FA23FD65 | " >expect &&
+ git log -n1 --format="%GF | %GP" signed-x509 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success GPGSM 'log OpenPGP fingerprint' '
+ echo "D4BE22311AD3131E5EDA29A461092E85B7227189" > expect &&
+ git log -n1 --format="%GP" signed-subkey >actual &&
+ test_cmp expect actual
+'
+
test_expect_success GPG 'log --graph --show-signature' '
git log --graph --show-signature -n1 signed >actual &&
grep "^| gpg: Signature made" actual &&
@@ -1674,10 +1712,10 @@ test_expect_success 'set up --source tests' '
'
test_expect_success 'log --source paints branch names' '
- cat >expect <<-\EOF &&
- 09e12a9 source-b three
- 8e393e1 source-a two
- 1ac6c77 source-b one
+ cat >expect <<-EOF &&
+ $(git rev-parse --short :/three) source-b three
+ $(git rev-parse --short :/two ) source-a two
+ $(git rev-parse --short :/one ) source-b one
EOF
git log --oneline --source source-a source-b >actual &&
test_cmp expect actual
@@ -1685,19 +1723,19 @@ test_expect_success 'log --source paints branch names' '
test_expect_success 'log --source paints tag names' '
git tag -m tagged source-tag &&
- cat >expect <<-\EOF &&
- 09e12a9 source-tag three
- 8e393e1 source-a two
- 1ac6c77 source-tag one
+ cat >expect <<-EOF &&
+ $(git rev-parse --short :/three) source-tag three
+ $(git rev-parse --short :/two ) source-a two
+ $(git rev-parse --short :/one ) source-tag one
EOF
git log --oneline --source source-tag source-a >actual &&
test_cmp expect actual
'
test_expect_success 'log --source paints symmetric ranges' '
- cat >expect <<-\EOF &&
- 09e12a9 source-b three
- 8e393e1 source-a two
+ cat >expect <<-EOF &&
+ $(git rev-parse --short :/three) source-b three
+ $(git rev-parse --short :/two ) source-a two
EOF
git log --oneline --source source-a...source-b >actual &&
test_cmp expect actual
@@ -1707,4 +1745,11 @@ test_expect_success '--exclude-promisor-objects does not BUG-crash' '
test_must_fail git log --exclude-promisor-objects source-a
'
+test_expect_success 'log --end-of-options' '
+ git update-ref refs/heads/--source HEAD &&
+ git log --end-of-options --source >actual &&
+ git log >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 918ada69eb..586c3a86b1 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -13,8 +13,8 @@ fuzz_blame () {
}
test_expect_success setup '
- cat >contacts <<-\EOF &&
- A U Thor <author@example.com>
+ cat >contacts <<- EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
@@ -33,19 +33,19 @@ test_expect_success 'check-mailmap no arguments' '
'
test_expect_success 'check-mailmap arguments' '
- cat >expect <<-\EOF &&
- A U Thor <author@example.com>
+ cat >expect <<- EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
git check-mailmap \
- "A U Thor <author@example.com>" \
+ "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" \
"nick1 <bugs@company.xx>" >actual &&
test_cmp expect actual
'
test_expect_success 'check-mailmap --stdin' '
- cat >expect <<-\EOF &&
- A U Thor <author@example.com>
+ cat >expect <<- EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
git check-mailmap --stdin <contacts >actual &&
@@ -66,8 +66,8 @@ test_expect_success 'check-mailmap bogus contact' '
test_must_fail git check-mailmap bogus
'
-cat >expect <<\EOF
-A U Thor (1):
+cat >expect << EOF
+$GIT_AUTHOR_NAME (1):
initial
nick1 (1):
@@ -90,7 +90,7 @@ nick1 (1):
EOF
test_expect_success 'default .mailmap' '
- echo "Repo Guy <author@example.com>" > .mailmap &&
+ echo "Repo Guy <$GIT_AUTHOR_EMAIL>" > .mailmap &&
git shortlog HEAD >actual &&
test_cmp expect actual
'
@@ -122,7 +122,7 @@ Internal Guy (1):
EOF
test_expect_success 'mailmap.file override' '
- echo "External Guy <author@example.com>" >> internal_mailmap/.mailmap &&
+ echo "External Guy <$GIT_AUTHOR_EMAIL>" >> internal_mailmap/.mailmap &&
git config mailmap.file internal_mailmap/.mailmap &&
git shortlog HEAD >actual &&
test_cmp expect actual
@@ -178,8 +178,8 @@ test_expect_success 'name entry after email entry, case-insensitive' '
test_cmp expect actual
'
-cat >expect <<\EOF
-A U Thor (1):
+cat >expect << EOF
+$GIT_AUTHOR_NAME (1):
initial
nick1 (1):
@@ -195,18 +195,18 @@ test_expect_success 'No mailmap files, but configured' '
test_expect_success 'setup mailmap blob tests' '
git checkout -b map &&
test_when_finished "git checkout master" &&
- cat >just-bugs <<-\EOF &&
+ cat >just-bugs <<- EOF &&
Blob Guy <bugs@company.xx>
EOF
- cat >both <<-\EOF &&
- Blob Guy <author@example.com>
+ cat >both <<- EOF &&
+ Blob Guy <$GIT_AUTHOR_EMAIL>
Blob Guy <bugs@company.xx>
EOF
- printf "Tricky Guy <author@example.com>" >no-newline &&
+ printf "Tricky Guy <$GIT_AUTHOR_EMAIL>" >no-newline &&
git add just-bugs both no-newline &&
git commit -m "my mailmaps" &&
- echo "Repo Guy <author@example.com>" >.mailmap &&
- echo "Internal Guy <author@example.com>" >internal.map
+ echo "Repo Guy <$GIT_AUTHOR_EMAIL>" >.mailmap &&
+ echo "Internal Guy <$GIT_AUTHOR_EMAIL>" >internal.map
'
test_expect_success 'mailmap.blob set' '
@@ -266,12 +266,12 @@ test_expect_success 'mailmap.blob defaults to off in non-bare repo' '
git init non-bare &&
(
cd non-bare &&
- test_commit one .mailmap "Fake Name <author@example.com>" &&
+ test_commit one .mailmap "Fake Name <$GIT_AUTHOR_EMAIL>" &&
echo " 1 Fake Name" >expect &&
git shortlog -ns HEAD >actual &&
test_cmp expect actual &&
rm .mailmap &&
- echo " 1 A U Thor" >expect &&
+ echo " 1 $GIT_AUTHOR_NAME" >expect &&
git shortlog -ns HEAD >actual &&
test_cmp expect actual
)
@@ -305,26 +305,26 @@ test_expect_success 'cleanup after mailmap.blob tests' '
'
test_expect_success 'single-character name' '
- echo " 1 A <author@example.com>" >expect &&
+ echo " 1 A <$GIT_AUTHOR_EMAIL>" >expect &&
echo " 1 nick1 <bugs@company.xx>" >>expect &&
- echo "A <author@example.com>" >.mailmap &&
+ echo "A <$GIT_AUTHOR_EMAIL>" >.mailmap &&
test_when_finished "rm .mailmap" &&
git shortlog -es HEAD >actual &&
test_cmp expect actual
'
test_expect_success 'preserve canonical email case' '
- echo " 1 A U Thor <AUTHOR@example.com>" >expect &&
+ echo " 1 $GIT_AUTHOR_NAME <AUTHOR@example.com>" >expect &&
echo " 1 nick1 <bugs@company.xx>" >>expect &&
- echo "<AUTHOR@example.com> <author@example.com>" >.mailmap &&
+ echo "<AUTHOR@example.com> <$GIT_AUTHOR_EMAIL>" >.mailmap &&
test_when_finished "rm .mailmap" &&
git shortlog -es 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):
+cat >expect << EOF
+$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> (1):
initial
CTO <cto@company.xx> (1):
@@ -370,7 +370,7 @@ test_expect_success 'Shortlog output (complex mapping)' '
git commit --author "CTO <cto@coompany.xx>" -m seventh &&
mkdir -p internal_mailmap &&
- echo "Committed <committer@example.com>" > internal_mailmap/.mailmap &&
+ echo "Committed <$GIT_COMMITTER_EMAIL>" > 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 &&
@@ -384,27 +384,27 @@ test_expect_success 'Shortlog output (complex mapping)' '
'
# git log with --pretty format which uses the name and email mailmap placemarkers
-cat >expect <<\EOF
+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>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
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>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
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>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
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>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
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>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
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>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-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>
+Author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> maps to $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
EOF
test_expect_success 'Log output (complex mapping)' '
@@ -412,14 +412,42 @@ test_expect_success 'Log output (complex mapping)' '
test_cmp expect actual
'
-cat >expect <<\EOF
+cat >expect << EOF
+Author email cto@coompany.xx has local-part cto
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email me@company.xx has local-part me
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email me@company.xx has local-part me
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email nick2@company.xx has local-part nick2
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email bugs@company.xx has local-part bugs
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email bugs@company.xx has local-part bugs
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email author@example.com has local-part author
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+EOF
+
+test_expect_success 'Log output (local-part email address)' '
+ git log --pretty=format:"Author email %ae has local-part %al%nCommitter email %ce has local-part %cl%n" >actual &&
+ test_cmp expect actual
+'
+
+cat >expect << EOF
Author: CTO <cto@company.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Other Author <other@author.xx>
Author: Other Author <other@author.xx>
Author: Some Dude <some@dude.xx>
-Author: A U Thor <author@example.com>
+Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
test_expect_success 'Log output with --use-mailmap' '
@@ -427,14 +455,14 @@ test_expect_success 'Log output with --use-mailmap' '
test_cmp expect actual
'
-cat >expect <<\EOF
+cat >expect << EOF
Author: CTO <cto@company.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Other Author <other@author.xx>
Author: Other Author <other@author.xx>
Author: Some Dude <some@dude.xx>
-Author: A U Thor <author@example.com>
+Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
test_expect_success 'Log output with log.mailmap' '
@@ -443,28 +471,28 @@ test_expect_success 'Log output with log.mailmap' '
'
test_expect_success 'log.mailmap=false disables mailmap' '
- cat >expect <<-\EOF &&
+ cat >expect <<- EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
Author: nick2 <nick2@company.xx>
Author: nick2 <bugs@company.xx>
Author: nick1 <bugs@company.xx>
- Author: A U Thor <author@example.com>
+ Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
git -c log.mailmap=False log | grep Author > actual &&
test_cmp expect actual
'
test_expect_success '--no-use-mailmap disables mailmap' '
- cat >expect <<-\EOF &&
+ cat >expect <<- EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
Author: nick2 <nick2@company.xx>
Author: nick2 <bugs@company.xx>
Author: nick1 <bugs@company.xx>
- Author: A U Thor <author@example.com>
+ Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
git log --no-use-mailmap | grep Author > actual &&
test_cmp expect actual
@@ -500,8 +528,8 @@ test_expect_success 'Only grep replaced author with --use-mailmap' '
'
# git blame
-cat >expect <<\EOF
-^OBJI (A U Thor DATE 1) one
+cat >expect <<EOF
+^OBJI ($GIT_AUTHOR_NAME DATE 1) one
OBJID (Some Dude DATE 2) two
OBJID (Other Author DATE 3) three
OBJID (Other Author DATE 4) four
diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh
index 0288c17ec6..8ff8bd84c7 100755
--- a/t/t4204-patch-id.sh
+++ b/t/t4204-patch-id.sh
@@ -25,7 +25,7 @@ test_expect_success 'setup' '
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
+ grep "^$OID_REGEX $(git rev-parse HEAD)$" output
'
#calculate patch id. Make sure output is not empty.
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index f42a69faa2..204c149d5a 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -134,6 +134,36 @@ test_expect_failure C_LOCALE_OUTPUT 'NUL termination with --stat' '
test_cmp expected actual
'
+for p in short medium full fuller email raw
+do
+ test_expect_success "NUL termination with --reflog --pretty=$p" '
+ revs="$(git rev-list --reflog)" &&
+ for r in $revs
+ do
+ git show -s "$r" --pretty="$p" &&
+ printf "\0" || return 1
+ done >expect &&
+ {
+ git log -z --reflog --pretty="$p" &&
+ printf "\0"
+ } >actual &&
+ test_cmp expect actual
+ '
+done
+
+test_expect_success 'NUL termination with --reflog --pretty=oneline' '
+ revs="$(git rev-list --reflog)" &&
+ for r in $revs
+ do
+ git show -s --pretty=oneline "$r" >raw &&
+ cat raw | lf_to_nul || exit 1
+ done >expect &&
+ # the trailing NUL is already produced so we do not need to
+ # output another one
+ git log -z --pretty=oneline --reflog >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup more commits' '
test_commit "message one" one one message-one &&
test_commit "message two" two two message-two &&
@@ -503,6 +533,12 @@ test_expect_success 'ISO and ISO-strict date formats display the same values' '
test_cmp expected actual
'
+test_expect_success 'short date' '
+ git log --format=%ad%n%cd --date=short >expected &&
+ git log --format=%as%n%cs >actual &&
+ test_cmp expected actual
+'
+
# get new digests (with no abbreviations)
test_expect_success 'set up log decoration tests' '
head1=$(git rev-parse --verify HEAD~0) &&
@@ -640,7 +676,7 @@ test_expect_success 'pretty format %(trailers:key=foo) multiple keys' '
test_cmp expect actual
'
-test_expect_success '%(trailers:key=nonexistant) becomes empty' '
+test_expect_success '%(trailers:key=nonexistent) becomes empty' '
git log --no-walk --pretty="x%(trailers:key=Nacked-by)x" >actual &&
echo "xx" >expect &&
test_cmp expect actual
@@ -788,4 +824,47 @@ test_expect_success '%S in git log --format works with other placeholders (part
test_cmp expect actual
'
+test_expect_success 'log --pretty=reference' '
+ git log --pretty="tformat:%h (%s, %as)" >expect &&
+ git log --pretty=reference >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --pretty=reference with log.date is overridden by short date' '
+ git log --pretty="tformat:%h (%s, %as)" >expect &&
+ test_config log.date rfc &&
+ git log --pretty=reference >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --pretty=reference with explicit date overrides short date' '
+ git log --date=rfc --pretty="tformat:%h (%s, %ad)" >expect &&
+ git log --date=rfc --pretty=reference >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --pretty=reference is never unabbreviated' '
+ git log --pretty="tformat:%h (%s, %as)" >expect &&
+ git log --no-abbrev-commit --pretty=reference >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --pretty=reference is never decorated' '
+ git log --pretty="tformat:%h (%s, %as)" >expect &&
+ git log --decorate=short --pretty=reference >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --pretty=reference does not output reflog info' '
+ git log --walk-reflogs --pretty="tformat:%h (%s, %as)" >expect &&
+ git log --walk-reflogs --pretty=reference >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --pretty=reference is colored appropriately' '
+ git log --color=always --pretty="tformat:%C(auto)%h (%s, %as)" >expect &&
+ git log --color=always --pretty=reference >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh
index 7c519436ef..c3792081e6 100755
--- a/t/t4210-log-i18n.sh
+++ b/t/t4210-log-i18n.sh
@@ -1,12 +1,15 @@
#!/bin/sh
test_description='test log with i18n features'
-. ./test-lib.sh
+. ./lib-gettext.sh
# two forms of é
utf8_e=$(printf '\303\251')
latin1_e=$(printf '\351')
+# invalid UTF-8
+invalid_e=$(printf '\303\50)') # ")" at end to close opening "("
+
test_expect_success 'create commits in different encodings' '
test_tick &&
cat >msg <<-EOF &&
@@ -48,9 +51,43 @@ test_expect_success !MINGW 'log --grep does not find non-reencoded values (utf8)
test_must_be_empty actual
'
-test_expect_success 'log --grep does not find non-reencoded values (latin1)' '
+test_expect_success !MINGW 'log --grep does not find non-reencoded values (latin1)' '
git log --encoding=ISO-8859-1 --format=%s --grep=$utf8_e >actual &&
test_must_be_empty actual
'
+for engine in fixed basic extended perl
+do
+ prereq=
+ if test $engine = "perl"
+ then
+ prereq="PCRE"
+ else
+ prereq=""
+ fi
+ force_regex=
+ if test $engine != "fixed"
+ then
+ force_regex=.*
+ fi
+ test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" "
+ cat >expect <<-\EOF &&
+ latin1
+ utf8
+ EOF
+ LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$latin1_e\" >actual &&
+ test_cmp expect actual
+ "
+
+ test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" "
+ LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$utf8_e\" >actual &&
+ test_must_be_empty actual
+ "
+
+ test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" "
+ LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$invalid_e\" >actual &&
+ test_must_be_empty actual
+ "
+done
+
test_done
diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh
index 1db7bd0f59..8319163744 100755
--- a/t/t4211-line-log.sh
+++ b/t/t4211-line-log.sh
@@ -132,4 +132,86 @@ test_expect_success '--raw is forbidden' '
test_must_fail git log -L1,24:b.c --raw
'
+test_expect_success 'setup for checking fancy rename following' '
+ git checkout --orphan moves-start &&
+ git reset --hard &&
+
+ printf "%s\n" 12 13 14 15 b c d e >file-1 &&
+ printf "%s\n" 22 23 24 25 B C D E >file-2 &&
+ git add file-1 file-2 &&
+ test_tick &&
+ git commit -m "Add file-1 and file-2" &&
+ oid_add_f1_f2=$(git rev-parse --short HEAD) &&
+
+ git checkout -b moves-main &&
+ printf "%s\n" 11 12 13 14 15 b c d e >file-1 &&
+ git commit -a -m "Modify file-1 on main" &&
+ oid_mod_f1_main=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 21 22 23 24 25 B C D E >file-2 &&
+ git commit -a -m "Modify file-2 on main #1" &&
+ oid_mod_f2_main_1=$(git rev-parse --short HEAD) &&
+
+ git mv file-1 renamed-1 &&
+ git commit -m "Rename file-1 to renamed-1 on main" &&
+
+ printf "%s\n" 11 12 13 14 15 b c d e f >renamed-1 &&
+ git commit -a -m "Modify renamed-1 on main" &&
+ oid_mod_r1_main=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 21 22 23 24 25 B C D E F >file-2 &&
+ git commit -a -m "Modify file-2 on main #2" &&
+ oid_mod_f2_main_2=$(git rev-parse --short HEAD) &&
+
+ git checkout -b moves-side moves-start &&
+ printf "%s\n" 12 13 14 15 16 b c d e >file-1 &&
+ git commit -a -m "Modify file-1 on side #1" &&
+ oid_mod_f1_side_1=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 22 23 24 25 26 B C D E >file-2 &&
+ git commit -a -m "Modify file-2 on side" &&
+ oid_mod_f2_side=$(git rev-parse --short HEAD) &&
+
+ git mv file-2 renamed-2 &&
+ git commit -m "Rename file-2 to renamed-2 on side" &&
+
+ printf "%s\n" 12 13 14 15 16 a b c d e >file-1 &&
+ git commit -a -m "Modify file-1 on side #2" &&
+ oid_mod_f1_side_2=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 22 23 24 25 26 A B C D E >renamed-2 &&
+ git commit -a -m "Modify renamed-2 on side" &&
+ oid_mod_r2_side=$(git rev-parse --short HEAD) &&
+
+ git checkout moves-main &&
+ git merge moves-side &&
+ oid_merge=$(git rev-parse --short HEAD)
+'
+
+test_expect_success 'fancy rename following #1' '
+ cat >expect <<-EOF &&
+ $oid_merge Merge branch '\''moves-side'\'' into moves-main
+ $oid_mod_f1_side_2 Modify file-1 on side #2
+ $oid_mod_f1_side_1 Modify file-1 on side #1
+ $oid_mod_r1_main Modify renamed-1 on main
+ $oid_mod_f1_main Modify file-1 on main
+ $oid_add_f1_f2 Add file-1 and file-2
+ EOF
+ git log -L1:renamed-1 --oneline --no-patch >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'fancy rename following #2' '
+ cat >expect <<-EOF &&
+ $oid_merge Merge branch '\''moves-side'\'' into moves-main
+ $oid_mod_r2_side Modify renamed-2 on side
+ $oid_mod_f2_side Modify file-2 on side
+ $oid_mod_f2_main_2 Modify file-2 on main #2
+ $oid_mod_f2_main_1 Modify file-2 on main #1
+ $oid_add_f1_f2 Add file-1 and file-2
+ EOF
+ git log -L1:renamed-2 --oneline --no-patch >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4213-log-tabexpand.sh b/t/t4213-log-tabexpand.sh
index 7f90f58c03..53a4af3244 100755
--- a/t/t4213-log-tabexpand.sh
+++ b/t/t4213-log-tabexpand.sh
@@ -36,7 +36,7 @@ count_expand ()
esac
# Prefix the output with the command line arguments, and
- # replace SP with a dot both in the expecte and actual output
+ # replace SP with a dot both in the expected and actual output
# so that test_cmp would show the difference together with the
# breakage in a way easier to consume by the debugging user.
{
diff --git a/t/t4214-log-graph-octopus.sh b/t/t4214-log-graph-octopus.sh
index dab96c89aa..40d27db674 100755
--- a/t/t4214-log-graph-octopus.sh
+++ b/t/t4214-log-graph-octopus.sh
@@ -5,61 +5,63 @@ test_description='git log --graph of skewed left octopus merge.'
. ./test-lib.sh
test_expect_success 'set up merge history' '
+ test_commit initial &&
+ for i in 1 2 3 4 ; do
+ git checkout master -b $i || return $?
+ # Make tag name different from branch name, to avoid
+ # ambiguity error when calling checkout.
+ test_commit $i $i $i tag$i || return $?
+ done &&
+ git checkout 1 -b merge &&
+ test_merge octopus-merge 1 2 3 4 &&
+ test_commit after-merge &&
+ git checkout 1 -b L &&
+ test_commit left &&
+ git checkout 4 -b crossover &&
+ test_commit after-4 &&
+ git checkout initial -b more-L &&
+ test_commit after-initial
+'
+
+test_expect_success 'log --graph with tricky octopus merge, no color' '
cat >expect.uncolored <<-\EOF &&
* left
- | *---. octopus-merge
- | |\ \ \
- |/ / / /
+ | *-. octopus-merge
+ |/|\ \
| | | * 4
| | * | 3
| | |/
- | * | 2
+ | * / 2
| |/
- * | 1
+ * / 1
|/
* initial
EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s left octopus-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with tricky octopus merge with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
cat >expect.colors <<-\EOF &&
* left
- <RED>|<RESET> *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge
- <RED>|<RESET> <RED>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <MAGENTA>\<RESET>
- <RED>|<RESET><RED>/<RESET> <YELLOW>/<RESET> <BLUE>/<RESET> <MAGENTA>/<RESET>
+ <RED>|<RESET> *<MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET>
<RED>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4
<RED>|<RESET> <YELLOW>|<RESET> * <MAGENTA>|<RESET> 3
<RED>|<RESET> <YELLOW>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET>
- <RED>|<RESET> * <MAGENTA>|<RESET> 2
+ <RED>|<RESET> * <MAGENTA>/<RESET> 2
<RED>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET>
- * <MAGENTA>|<RESET> 1
+ * <MAGENTA>/<RESET> 1
<MAGENTA>|<RESET><MAGENTA>/<RESET>
* initial
EOF
- test_commit initial &&
- for i in 1 2 3 4 ; do
- git checkout master -b $i || return $?
- # Make tag name different from branch name, to avoid
- # ambiguity error when calling checkout.
- test_commit $i $i $i tag$i || return $?
- done &&
- git checkout 1 -b merge &&
- test_tick &&
- git merge -m octopus-merge 1 2 3 4 &&
- git checkout 1 -b L &&
- test_commit left
-'
-
-test_expect_success 'log --graph with tricky octopus merge with colors' '
- test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
- git log --color=always --graph --date-order --pretty=tformat:%s --all >actual.colors.raw &&
+ git log --color=always --graph --date-order --pretty=tformat:%s left octopus-merge >actual.colors.raw &&
test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
test_cmp expect.colors actual.colors
'
-test_expect_success 'log --graph with tricky octopus merge, no color' '
- git log --color=never --graph --date-order --pretty=tformat:%s --all >actual.raw &&
- sed "s/ *\$//" actual.raw >actual &&
- test_cmp expect.uncolored actual
-'
-
# Repeat the previous two tests with "normal" octopus merge (i.e.,
# without the first parent skewing to the "left" branch column).
@@ -70,13 +72,13 @@ test_expect_success 'log --graph with normal octopus merge, no color' '
| | | * 4
| | * | 3
| | |/
- | * | 2
+ | * / 2
| |/
- * | 1
+ * / 1
|/
* initial
EOF
- git log --color=never --graph --date-order --pretty=tformat:%s merge >actual.raw &&
+ git log --color=never --graph --date-order --pretty=tformat:%s octopus-merge >actual.raw &&
sed "s/ *\$//" actual.raw >actual &&
test_cmp expect.uncolored actual
'
@@ -88,15 +90,288 @@ test_expect_success 'log --graph with normal octopus merge with colors' '
<RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 4
<RED>|<RESET> <GREEN>|<RESET> * <BLUE>|<RESET> 3
<RED>|<RESET> <GREEN>|<RESET> <BLUE>|<RESET><BLUE>/<RESET>
- <RED>|<RESET> * <BLUE>|<RESET> 2
+ <RED>|<RESET> * <BLUE>/<RESET> 2
<RED>|<RESET> <BLUE>|<RESET><BLUE>/<RESET>
- * <BLUE>|<RESET> 1
+ * <BLUE>/<RESET> 1
<BLUE>|<RESET><BLUE>/<RESET>
* initial
EOF
test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
- git log --color=always --graph --date-order --pretty=tformat:%s merge >actual.colors.raw &&
+ git log --color=always --graph --date-order --pretty=tformat:%s octopus-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with normal octopus merge and child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-merge
+ *---. octopus-merge
+ |\ \ \
+ | | | * 4
+ | | * | 3
+ | | |/
+ | * / 2
+ | |/
+ * / 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with normal octopus and child merge with colors' '
+ cat >expect.colors <<-\EOF &&
+ * after-merge
+ *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge
+ <GREEN>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <MAGENTA>\<RESET>
+ <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4
+ <GREEN>|<RESET> <YELLOW>|<RESET> * <MAGENTA>|<RESET> 3
+ <GREEN>|<RESET> <YELLOW>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ <GREEN>|<RESET> * <MAGENTA>/<RESET> 2
+ <GREEN>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ * <MAGENTA>/<RESET> 1
+ <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ * initial
+ EOF
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ git log --color=always --graph --date-order --pretty=tformat:%s after-merge >actual.colors.raw &&
test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
test_cmp expect.colors actual.colors
'
+
+test_expect_success 'log --graph with tricky octopus merge and its child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * left
+ | * after-merge
+ | *-. octopus-merge
+ |/|\ \
+ | | | * 4
+ | | * | 3
+ | | |/
+ | * / 2
+ | |/
+ * / 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s left after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with tricky octopus merge and its child with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * left
+ <RED>|<RESET> * after-merge
+ <RED>|<RESET> *<CYAN>-<RESET><CYAN>.<RESET> octopus-merge
+ <RED>|<RESET><RED>/<RESET><BLUE>|<RESET><MAGENTA>\<RESET> <CYAN>\<RESET>
+ <RED>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET> * 4
+ <RED>|<RESET> <BLUE>|<RESET> * <CYAN>|<RESET> 3
+ <RED>|<RESET> <BLUE>|<RESET> <CYAN>|<RESET><CYAN>/<RESET>
+ <RED>|<RESET> * <CYAN>/<RESET> 2
+ <RED>|<RESET> <CYAN>|<RESET><CYAN>/<RESET>
+ * <CYAN>/<RESET> 1
+ <CYAN>|<RESET><CYAN>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s left after-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with crossover in octopus merge, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-4
+ | *---. octopus-merge
+ | |\ \ \
+ | |_|_|/
+ |/| | |
+ * | | | 4
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-4 octopus-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with crossover in octopus merge with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-4
+ <RED>|<RESET> *<BLUE>-<RESET><BLUE>-<RESET><RED>-<RESET><RED>.<RESET> octopus-merge
+ <RED>|<RESET> <GREEN>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <RED>\<RESET>
+ <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET>
+ * <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> 4
+ <MAGENTA>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 3
+ <MAGENTA>|<RESET> <GREEN>|<RESET><MAGENTA>_<RESET><YELLOW>|<RESET><MAGENTA>/<RESET>
+ <MAGENTA>|<RESET><MAGENTA>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET>
+ <MAGENTA>|<RESET> <GREEN>|<RESET> * 2
+ <MAGENTA>|<RESET> <GREEN>|<RESET><MAGENTA>/<RESET>
+ <MAGENTA>|<RESET><MAGENTA>/<RESET><GREEN>|<RESET>
+ <MAGENTA>|<RESET> * 1
+ <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-4 octopus-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with crossover in octopus merge and its child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-4
+ | * after-merge
+ | *---. octopus-merge
+ | |\ \ \
+ | |_|_|/
+ |/| | |
+ * | | | 4
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-4 after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with crossover in octopus merge and its child with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-4
+ <RED>|<RESET> * after-merge
+ <RED>|<RESET> *<MAGENTA>-<RESET><MAGENTA>-<RESET><RED>-<RESET><RED>.<RESET> octopus-merge
+ <RED>|<RESET> <YELLOW>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET> <RED>\<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>_<RESET><MAGENTA>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET>
+ * <YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET> 4
+ <CYAN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 3
+ <CYAN>|<RESET> <YELLOW>|<RESET><CYAN>_<RESET><BLUE>|<RESET><CYAN>/<RESET>
+ <CYAN>|<RESET><CYAN>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET>
+ <CYAN>|<RESET> <YELLOW>|<RESET> * 2
+ <CYAN>|<RESET> <YELLOW>|<RESET><CYAN>/<RESET>
+ <CYAN>|<RESET><CYAN>/<RESET><YELLOW>|<RESET>
+ <CYAN>|<RESET> * 1
+ <CYAN>|<RESET><CYAN>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-4 after-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with unrelated commit and octopus tip, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-initial
+ | *---. octopus-merge
+ | |\ \ \
+ | | | | * 4
+ | |_|_|/
+ |/| | |
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-initial octopus-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with unrelated commit and octopus tip with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-initial
+ <RED>|<RESET> *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge
+ <RED>|<RESET> <GREEN>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <MAGENTA>\<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4
+ <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 3
+ <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> * 2
+ <RED>|<RESET> <GREEN>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET>
+ <RED>|<RESET> * 1
+ <RED>|<RESET><RED>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-initial octopus-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with unrelated commit and octopus child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-initial
+ | * after-merge
+ | *---. octopus-merge
+ | |\ \ \
+ | | | | * 4
+ | |_|_|/
+ |/| | |
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-initial after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with unrelated commit and octopus child with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-initial
+ <RED>|<RESET> * after-merge
+ <RED>|<RESET> *<MAGENTA>-<RESET><MAGENTA>-<RESET><CYAN>-<RESET><CYAN>.<RESET> octopus-merge
+ <RED>|<RESET> <YELLOW>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET> <CYAN>\<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET> * 4
+ <RED>|<RESET> <YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>_<RESET><MAGENTA>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 3
+ <RED>|<RESET> <YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET> * 2
+ <RED>|<RESET> <YELLOW>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET>
+ <RED>|<RESET> * 1
+ <RED>|<RESET><RED>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-initial after-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
test_done
diff --git a/t/t4215-log-skewed-merges.sh b/t/t4215-log-skewed-merges.sh
new file mode 100755
index 0000000000..1d0d3240ff
--- /dev/null
+++ b/t/t4215-log-skewed-merges.sh
@@ -0,0 +1,376 @@
+#!/bin/sh
+
+test_description='git log --graph of skewed merges'
+
+. ./test-lib.sh
+
+check_graph () {
+ cat >expect &&
+ git log --graph --pretty=tformat:%s "$@" >actual.raw &&
+ sed "s/ *$//" actual.raw >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'log --graph with merge fusing with its left and right neighbors' '
+ git checkout --orphan _p &&
+ test_commit A &&
+ test_commit B &&
+ git checkout -b _q @^ && test_commit C &&
+ git checkout -b _r @^ && test_commit D &&
+ git checkout _p && git merge --no-ff _q _r -m E &&
+ git checkout _r && test_commit F &&
+ git checkout _p && git merge --no-ff _r -m G &&
+ git checkout @^^ && git merge --no-ff _p -m H &&
+
+ check_graph <<-\EOF
+ * H
+ |\
+ | * G
+ | |\
+ | | * F
+ | * | E
+ |/|\|
+ | | * D
+ | * | C
+ | |/
+ * / B
+ |/
+ * A
+ EOF
+'
+
+test_expect_success 'log --graph with left-skewed merge' '
+ git checkout --orphan 0_p && test_commit 0_A &&
+ git checkout -b 0_q 0_p && test_commit 0_B &&
+ git checkout -b 0_r 0_p &&
+ test_commit 0_C &&
+ test_commit 0_D &&
+ git checkout -b 0_s 0_p && test_commit 0_E &&
+ git checkout -b 0_t 0_p && git merge --no-ff 0_r^ 0_s -m 0_F &&
+ git checkout 0_p && git merge --no-ff 0_s -m 0_G &&
+ git checkout @^ && git merge --no-ff 0_q 0_r 0_t 0_p -m 0_H &&
+
+ check_graph <<-\EOF
+ *-----. 0_H
+ |\ \ \ \
+ | | | | * 0_G
+ | |_|_|/|
+ |/| | | |
+ | | | * | 0_F
+ | |_|/|\|
+ |/| | | |
+ | | | | * 0_E
+ | |_|_|/
+ |/| | |
+ | | * | 0_D
+ | | |/
+ | | * 0_C
+ | |/
+ |/|
+ | * 0_B
+ |/
+ * 0_A
+ EOF
+'
+
+test_expect_success 'log --graph with nested left-skewed merge' '
+ git checkout --orphan 1_p &&
+ test_commit 1_A &&
+ test_commit 1_B &&
+ test_commit 1_C &&
+ git checkout -b 1_q @^ && test_commit 1_D &&
+ git checkout 1_p && git merge --no-ff 1_q -m 1_E &&
+ git checkout -b 1_r @~3 && test_commit 1_F &&
+ git checkout 1_p && git merge --no-ff 1_r -m 1_G &&
+ git checkout @^^ && git merge --no-ff 1_p -m 1_H &&
+
+ check_graph <<-\EOF
+ * 1_H
+ |\
+ | * 1_G
+ | |\
+ | | * 1_F
+ | * | 1_E
+ |/| |
+ | * | 1_D
+ * | | 1_C
+ |/ /
+ * / 1_B
+ |/
+ * 1_A
+ EOF
+'
+
+test_expect_success 'log --graph with nested left-skewed merge following normal merge' '
+ git checkout --orphan 2_p &&
+ test_commit 2_A &&
+ test_commit 2_B &&
+ test_commit 2_C &&
+ git checkout -b 2_q @^^ &&
+ test_commit 2_D &&
+ test_commit 2_E &&
+ git checkout -b 2_r @^ && test_commit 2_F &&
+ git checkout 2_q &&
+ git merge --no-ff 2_r -m 2_G &&
+ git merge --no-ff 2_p^ -m 2_H &&
+ git checkout -b 2_s @^^ && git merge --no-ff 2_q -m 2_J &&
+ git checkout 2_p && git merge --no-ff 2_s -m 2_K &&
+
+ check_graph <<-\EOF
+ * 2_K
+ |\
+ | * 2_J
+ | |\
+ | | * 2_H
+ | | |\
+ | | * | 2_G
+ | |/| |
+ | | * | 2_F
+ | * | | 2_E
+ | |/ /
+ | * | 2_D
+ * | | 2_C
+ | |/
+ |/|
+ * | 2_B
+ |/
+ * 2_A
+ EOF
+'
+
+test_expect_success 'log --graph with nested right-skewed merge following left-skewed merge' '
+ git checkout --orphan 3_p &&
+ test_commit 3_A &&
+ git checkout -b 3_q &&
+ test_commit 3_B &&
+ test_commit 3_C &&
+ git checkout -b 3_r @^ &&
+ test_commit 3_D &&
+ git checkout 3_q && git merge --no-ff 3_r -m 3_E &&
+ git checkout 3_p && git merge --no-ff 3_q -m 3_F &&
+ git checkout 3_r && test_commit 3_G &&
+ git checkout 3_p && git merge --no-ff 3_r -m 3_H &&
+ git checkout @^^ && git merge --no-ff 3_p -m 3_J &&
+
+ check_graph <<-\EOF
+ * 3_J
+ |\
+ | * 3_H
+ | |\
+ | | * 3_G
+ | * | 3_F
+ |/| |
+ | * | 3_E
+ | |\|
+ | | * 3_D
+ | * | 3_C
+ | |/
+ | * 3_B
+ |/
+ * 3_A
+ EOF
+'
+
+test_expect_success 'log --graph with right-skewed merge following a left-skewed one' '
+ git checkout --orphan 4_p &&
+ test_commit 4_A &&
+ test_commit 4_B &&
+ test_commit 4_C &&
+ git checkout -b 4_q @^^ && test_commit 4_D &&
+ git checkout -b 4_r 4_p^ && git merge --no-ff 4_q -m 4_E &&
+ git checkout -b 4_s 4_p^^ &&
+ git merge --no-ff 4_r -m 4_F &&
+ git merge --no-ff 4_p -m 4_G &&
+ git checkout @^^ && git merge --no-ff 4_s -m 4_H &&
+
+ check_graph --date-order <<-\EOF
+ * 4_H
+ |\
+ | * 4_G
+ | |\
+ | * | 4_F
+ |/| |
+ | * | 4_E
+ | |\ \
+ | | * | 4_D
+ | |/ /
+ |/| |
+ | | * 4_C
+ | |/
+ | * 4_B
+ |/
+ * 4_A
+ EOF
+'
+
+test_expect_success 'log --graph with octopus merge with column joining its penultimate parent' '
+ git checkout --orphan 5_p &&
+ test_commit 5_A &&
+ git branch 5_q &&
+ git branch 5_r &&
+ test_commit 5_B &&
+ git checkout 5_q && test_commit 5_C &&
+ git checkout 5_r && test_commit 5_D &&
+ git checkout 5_p &&
+ git merge --no-ff 5_q 5_r -m 5_E &&
+ git checkout 5_q && test_commit 5_F &&
+ git checkout -b 5_s 5_p^ &&
+ git merge --no-ff 5_p 5_q -m 5_G &&
+ git checkout 5_r &&
+ git merge --no-ff 5_s -m 5_H &&
+
+ check_graph <<-\EOF
+ * 5_H
+ |\
+ | *-. 5_G
+ | |\ \
+ | | | * 5_F
+ | | * | 5_E
+ | |/|\ \
+ | |_|/ /
+ |/| | /
+ | | |/
+ * | | 5_D
+ | | * 5_C
+ | |/
+ |/|
+ | * 5_B
+ |/
+ * 5_A
+ EOF
+'
+
+test_expect_success 'log --graph with multiple tips' '
+ git checkout --orphan 6_1 &&
+ test_commit 6_A &&
+ git branch 6_2 &&
+ git branch 6_4 &&
+ test_commit 6_B &&
+ git branch 6_3 &&
+ test_commit 6_C &&
+ git checkout 6_2 && test_commit 6_D &&
+ git checkout 6_3 && test_commit 6_E &&
+ git checkout -b 6_5 6_1 &&
+ git merge --no-ff 6_2 -m 6_F &&
+ git checkout 6_4 && test_commit 6_G &&
+ git checkout 6_3 &&
+ git merge --no-ff 6_4 -m 6_H &&
+ git checkout 6_1 &&
+ git merge --no-ff 6_2 -m 6_I &&
+
+ check_graph 6_1 6_3 6_5 <<-\EOF
+ * 6_I
+ |\
+ | | * 6_H
+ | | |\
+ | | | * 6_G
+ | | * | 6_E
+ | | | | * 6_F
+ | |_|_|/|
+ |/| | |/
+ | | |/|
+ | |/| |
+ | * | | 6_D
+ | | |/
+ | |/|
+ * | | 6_C
+ | |/
+ |/|
+ * | 6_B
+ |/
+ * 6_A
+ EOF
+'
+
+test_expect_success 'log --graph with multiple tips and colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * 6_I
+ <RED>|<RESET><GREEN>\<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> * 6_H
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET><BLUE>\<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 6_G
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 6_F
+ <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET><GREEN>|<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET><GREEN>/<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET><GREEN>/<RESET><BLUE>|<RESET>
+ <RED>|<RESET> <GREEN>|<RESET><GREEN>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> * <BLUE>|<RESET> 6_E
+ <RED>|<RESET> * <CYAN>|<RESET> <BLUE>|<RESET> 6_D
+ <RED>|<RESET> <BLUE>|<RESET> <CYAN>|<RESET><BLUE>/<RESET>
+ <RED>|<RESET> <BLUE>|<RESET><BLUE>/<RESET><CYAN>|<RESET>
+ * <BLUE>|<RESET> <CYAN>|<RESET> 6_C
+ <CYAN>|<RESET> <BLUE>|<RESET><CYAN>/<RESET>
+ <CYAN>|<RESET><CYAN>/<RESET><BLUE>|<RESET>
+ * <BLUE>|<RESET> 6_B
+ <BLUE>|<RESET><BLUE>/<RESET>
+ * 6_A
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s 6_1 6_3 6_5 >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with multiple tips' '
+ git checkout --orphan 7_1 &&
+ test_commit 7_A &&
+ test_commit 7_B &&
+ test_commit 7_C &&
+ git checkout -b 7_2 7_1~2 &&
+ test_commit 7_D &&
+ test_commit 7_E &&
+ git checkout -b 7_3 7_1~1 &&
+ test_commit 7_F &&
+ test_commit 7_G &&
+ git checkout -b 7_4 7_2~1 &&
+ test_commit 7_H &&
+ git checkout -b 7_5 7_1~2 &&
+ test_commit 7_I &&
+ git checkout -b 7_6 7_3~1 &&
+ test_commit 7_J &&
+ git checkout -b M_1 7_1 &&
+ git merge --no-ff 7_2 -m 7_M1 &&
+ git checkout -b M_3 7_3 &&
+ git merge --no-ff 7_4 -m 7_M2 &&
+ git checkout -b M_5 7_5 &&
+ git merge --no-ff 7_6 -m 7_M3 &&
+ git checkout -b M_7 7_1 &&
+ git merge --no-ff 7_2 7_3 -m 7_M4 &&
+
+ check_graph M_1 M_3 M_5 M_7 <<-\EOF
+ * 7_M1
+ |\
+ | | * 7_M2
+ | | |\
+ | | | * 7_H
+ | | | | * 7_M3
+ | | | | |\
+ | | | | | * 7_J
+ | | | | * | 7_I
+ | | | | | | * 7_M4
+ | |_|_|_|_|/|\
+ |/| | | | |/ /
+ | | |_|_|/| /
+ | |/| | | |/
+ | | | |_|/|
+ | | |/| | |
+ | | * | | | 7_G
+ | | | |_|/
+ | | |/| |
+ | | * | | 7_F
+ | * | | | 7_E
+ | | |/ /
+ | |/| |
+ | * | | 7_D
+ | | |/
+ | |/|
+ * | | 7_C
+ | |/
+ |/|
+ * | 7_B
+ |/
+ * 7_A
+ EOF
+'
+
+test_done
diff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh
index 6340310e9a..2369c4e17a 100755
--- a/t/t4256-am-format-flowed.sh
+++ b/t/t4256-am-format-flowed.sh
@@ -11,7 +11,7 @@ test_expect_success 'setup' '
'
test_expect_success 'am with format=flowed' '
- git am <"$TEST_DIRECTORY/t4256/1/patch" >stdout 2>stderr &&
+ git am <"$TEST_DIRECTORY/t4256/1/patch" 2>stderr &&
test_i18ngrep "warning: Patch sent with format=flowed" stderr &&
test_cmp "$TEST_DIRECTORY/t4256/1/mailinfo.c" mailinfo.c
'
diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh
index d87cc7d9ef..e59601e5fe 100755
--- a/t/t4300-merge-tree.sh
+++ b/t/t4300-merge-tree.sh
@@ -11,16 +11,16 @@ test_expect_success setup '
'
test_expect_success 'file add A, !B' '
- cat >expected <<\EXPECTED &&
+ git reset --hard initial &&
+ test_commit "add-a-not-b" "ONE" "AAA" &&
+ git merge-tree initial initial add-a-not-b >actual &&
+ cat >expected <<EXPECTED &&
added in remote
- their 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE
+ their 100644 $(git rev-parse HEAD:ONE) ONE
@@ -0,0 +1 @@
+AAA
EXPECTED
- git reset --hard initial &&
- test_commit "add-a-not-b" "ONE" "AAA" &&
- git merge-tree initial initial add-a-not-b >actual &&
test_cmp expected actual
'
@@ -41,10 +41,15 @@ test_expect_success 'file add A, B (same)' '
'
test_expect_success 'file add A, B (different)' '
- cat >expected <<\EXPECTED &&
+ git reset --hard initial &&
+ test_commit "add-a-b-diff-A" "ONE" "AAA" &&
+ git reset --hard initial &&
+ test_commit "add-a-b-diff-B" "ONE" "BBB" &&
+ git merge-tree initial add-a-b-diff-A add-a-b-diff-B >actual &&
+ cat >expected <<EXPECTED &&
added in both
- our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE
- their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE
+ our 100644 $(git rev-parse add-a-b-diff-A:ONE) ONE
+ their 100644 $(git rev-parse add-a-b-diff-B:ONE) ONE
@@ -1 +1,5 @@
+<<<<<<< .our
AAA
@@ -53,11 +58,6 @@ added in both
+>>>>>>> .their
EXPECTED
- git reset --hard initial &&
- test_commit "add-a-b-diff-A" "ONE" "AAA" &&
- git reset --hard initial &&
- test_commit "add-a-b-diff-B" "ONE" "BBB" &&
- git merge-tree initial add-a-b-diff-A add-a-b-diff-B >actual &&
test_cmp expected actual
'
@@ -69,18 +69,18 @@ test_expect_success 'file change A, !B' '
'
test_expect_success 'file change !A, B' '
- cat >expected <<\EXPECTED &&
+ git reset --hard initial &&
+ test_commit "change-not-a-b" "initial-file" "BBB" &&
+ git merge-tree initial initial change-not-a-b >actual &&
+ cat >expected <<EXPECTED &&
merged
- result 100644 ba629238ca89489f2b350e196ca445e09d8bb834 initial-file
- our 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
+ result 100644 $(git rev-parse change-a-not-b:initial-file) initial-file
+ our 100644 $(git rev-parse initial:initial-file ) initial-file
@@ -1 +1 @@
-initial
+BBB
EXPECTED
- git reset --hard initial &&
- test_commit "change-not-a-b" "initial-file" "BBB" &&
- git merge-tree initial initial change-not-a-b >actual &&
test_cmp expected actual
'
@@ -94,11 +94,16 @@ test_expect_success 'file change A, B (same)' '
'
test_expect_success 'file change A, B (different)' '
- cat >expected <<\EXPECTED &&
+ git reset --hard initial &&
+ test_commit "change-a-b-diff-A" "initial-file" "AAA" &&
+ git reset --hard initial &&
+ test_commit "change-a-b-diff-B" "initial-file" "BBB" &&
+ git merge-tree initial change-a-b-diff-A change-a-b-diff-B >actual &&
+ cat >expected <<EXPECTED &&
changed in both
- base 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
- our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d initial-file
- their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 initial-file
+ base 100644 $(git rev-parse initial:initial-file ) initial-file
+ our 100644 $(git rev-parse change-a-b-diff-A:initial-file) initial-file
+ their 100644 $(git rev-parse change-a-b-diff-B:initial-file) initial-file
@@ -1 +1,5 @@
+<<<<<<< .our
AAA
@@ -107,34 +112,10 @@ changed in both
+>>>>>>> .their
EXPECTED
- git reset --hard initial &&
- test_commit "change-a-b-diff-A" "initial-file" "AAA" &&
- git reset --hard initial &&
- test_commit "change-a-b-diff-B" "initial-file" "BBB" &&
- git merge-tree initial change-a-b-diff-A change-a-b-diff-B >actual &&
test_cmp expected actual
'
test_expect_success 'file change A, B (mixed)' '
- cat >expected <<\EXPECTED &&
-changed in both
- base 100644 f4f1f998c7776568c4ff38f516d77fef9399b5a7 ONE
- our 100644 af14c2c3475337c73759d561ef70b59e5c731176 ONE
- their 100644 372d761493f524d44d59bd24700c3bdf914c973c ONE
-@@ -7,7 +7,11 @@
- AAA
- AAA
- AAA
-+<<<<<<< .our
- BBB
-+=======
-+CCC
-+>>>>>>> .their
- AAA
- AAA
- AAA
-EXPECTED
-
git reset --hard initial &&
test_commit "change-a-b-mix-base" "ONE" "
AAA
@@ -159,6 +140,26 @@ AAA" &&
"$(sed -e "1{s/AAA/BBB/;}" -e "10{s/AAA/CCC/;}" <ONE)" &&
git merge-tree change-a-b-mix-base change-a-b-mix-A change-a-b-mix-B \
>actual &&
+
+ cat >expected <<EXPECTED &&
+changed in both
+ base 100644 $(git rev-parse change-a-b-mix-base:ONE) ONE
+ our 100644 $(git rev-parse change-a-b-mix-A:ONE ) ONE
+ their 100644 $(git rev-parse change-a-b-mix-B:ONE ) ONE
+@@ -7,7 +7,11 @@
+ AAA
+ AAA
+ AAA
++<<<<<<< .our
+ BBB
++=======
++CCC
++>>>>>>> .their
+ AAA
+ AAA
+ AAA
+EXPECTED
+
test_cmp expected actual
'
@@ -173,20 +174,20 @@ test_expect_success 'file remove A, !B' '
'
test_expect_success 'file remove !A, B' '
- cat >expected <<\EXPECTED &&
-removed in remote
- base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE
- our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE
-@@ -1 +0,0 @@
--AAA
-EXPECTED
-
git reset --hard initial &&
test_commit "rm-not-a-b-base" "ONE" "AAA" &&
git rm ONE &&
git commit -m "rm-not-a-b" &&
git tag "rm-not-a-b" &&
git merge-tree rm-a-not-b-base rm-a-not-b-base rm-a-not-b >actual &&
+ cat >expected <<EXPECTED &&
+removed in remote
+ base 100644 $(git rev-parse rm-a-not-b-base:ONE) ONE
+ our 100644 $(git rev-parse rm-a-not-b-base:ONE) ONE
+@@ -1 +0,0 @@
+-AAA
+EXPECTED
+
test_cmp expected actual
'
@@ -201,14 +202,6 @@ test_expect_success 'file remove A, B (same)' '
'
test_expect_success 'file change A, remove B' '
- cat >expected <<\EXPECTED &&
-removed in remote
- base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE
- our 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE
-@@ -1 +0,0 @@
--BBB
-EXPECTED
-
git reset --hard initial &&
test_commit "change-a-rm-b-base" "ONE" "AAA" &&
test_commit "change-a-rm-b-A" "ONE" "BBB" &&
@@ -218,16 +211,18 @@ EXPECTED
git tag "change-a-rm-b-B" &&
git merge-tree change-a-rm-b-base change-a-rm-b-A change-a-rm-b-B \
>actual &&
+ cat >expected <<EXPECTED &&
+removed in remote
+ base 100644 $(git rev-parse change-a-rm-b-base:ONE) ONE
+ our 100644 $(git rev-parse change-a-rm-b-A:ONE ) ONE
+@@ -1 +0,0 @@
+-BBB
+EXPECTED
+
test_cmp expected actual
'
test_expect_success 'file remove A, change B' '
- cat >expected <<\EXPECTED &&
-removed in local
- base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE
- their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE
-EXPECTED
-
git reset --hard initial &&
test_commit "rm-a-change-b-base" "ONE" "AAA" &&
@@ -238,6 +233,11 @@ EXPECTED
test_commit "rm-a-change-b-B" "ONE" "BBB" &&
git merge-tree rm-a-change-b-base rm-a-change-b-A rm-a-change-b-B \
>actual &&
+ cat >expected <<EXPECTED &&
+removed in local
+ base 100644 $(git rev-parse rm-a-change-b-base:ONE) ONE
+ their 100644 $(git rev-parse rm-a-change-b-B:ONE ) ONE
+EXPECTED
test_cmp expected actual
'
@@ -250,10 +250,17 @@ test_expect_success 'tree add A, B (same)' '
'
test_expect_success 'tree add A, B (different)' '
- cat >expect <<-\EOF &&
+ git reset --hard initial &&
+ mkdir sub &&
+ test_commit "add sub/file" "sub/file" "AAA" add-tree-a-b-A &&
+ git reset --hard initial &&
+ mkdir sub &&
+ test_commit "add sub/file" "sub/file" "BBB" add-tree-a-b-B &&
+ git merge-tree initial add-tree-a-b-A add-tree-a-b-B >actual &&
+ cat >expect <<-EOF &&
added in both
- our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file
- their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 sub/file
+ our 100644 $(git rev-parse add-tree-a-b-A:sub/file) sub/file
+ their 100644 $(git rev-parse add-tree-a-b-B:sub/file) sub/file
@@ -1 +1,5 @@
+<<<<<<< .our
AAA
@@ -261,24 +268,10 @@ test_expect_success 'tree add A, B (different)' '
+BBB
+>>>>>>> .their
EOF
- git reset --hard initial &&
- mkdir sub &&
- test_commit "add sub/file" "sub/file" "AAA" add-tree-a-b-A &&
- git reset --hard initial &&
- mkdir sub &&
- test_commit "add sub/file" "sub/file" "BBB" add-tree-a-b-B &&
- git merge-tree initial add-tree-a-b-A add-tree-a-b-B >actual &&
test_cmp expect actual
'
test_expect_success 'tree unchanged A, removed B' '
- cat >expect <<-\EOF &&
- removed in remote
- base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file
- our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file
- @@ -1 +0,0 @@
- -AAA
- EOF
git reset --hard initial &&
mkdir sub &&
test_commit "add sub/file" "sub/file" "AAA" tree-remove-b-initial &&
@@ -287,6 +280,13 @@ test_expect_success 'tree unchanged A, removed B' '
git commit -m "remove sub/file" &&
git tag tree-remove-b-B &&
git merge-tree tree-remove-b-initial tree-remove-b-initial tree-remove-b-B >actual &&
+ cat >expect <<-EOF &&
+ removed in remote
+ base 100644 $(git rev-parse tree-remove-b-initial:sub/file) sub/file
+ our 100644 $(git rev-parse tree-remove-b-initial:sub/file) sub/file
+ @@ -1 +0,0 @@
+ -AAA
+ EOF
test_cmp expect actual
'
@@ -296,14 +296,14 @@ test_expect_success 'turn file to tree' '
mkdir initial-file &&
test_commit "turn-file-to-tree" "initial-file/ONE" "CCC" &&
git merge-tree initial initial turn-file-to-tree >actual &&
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
added in remote
- their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 initial-file/ONE
+ their 100644 $(git rev-parse turn-file-to-tree:initial-file/ONE) initial-file/ONE
@@ -0,0 +1 @@
+CCC
removed in remote
- base 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
- our 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
+ base 100644 $(git rev-parse initial:initial-file) initial-file
+ our 100644 $(git rev-parse initial:initial-file) initial-file
@@ -1 +0,0 @@
-initial
EOF
@@ -318,14 +318,14 @@ test_expect_success 'turn tree to file' '
rm -fr dir &&
test_commit "make-file" "dir" "CCC" &&
git merge-tree add-tree add-another-tree make-file >actual &&
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
removed in remote
- base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path
- our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path
+ base 100644 $(git rev-parse add-tree:dir/path) dir/path
+ our 100644 $(git rev-parse add-tree:dir/path) dir/path
@@ -1 +0,0 @@
-AAA
added in remote
- their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 dir
+ their 100644 $(git rev-parse make-file:dir) dir
@@ -0,0 +1 @@
+CCC
EOF
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
index 271eb5a1fd..3e7b23cb32 100755
--- a/t/t5004-archive-corner-cases.sh
+++ b/t/t5004-archive-corner-cases.sh
@@ -204,4 +204,23 @@ test_expect_success EXPENSIVE,LONG_IS_64BIT,UNZIP,UNZIP_ZIP64_SUPPORT,ZIPINFO \
grep $size big.lst
'
+build_tree() {
+ perl -e '
+ my $hash = $ARGV[0];
+ foreach my $order (2..6) {
+ $first = 10 ** $order;
+ foreach my $i (-13..-9) {
+ my $name = "a" x ($first + $i);
+ print "100644 blob $hash\t$name\n"
+ }
+ }
+ ' "$1"
+}
+
+test_expect_success 'tar archive with long paths' '
+ blob=$(echo foo | git hash-object -w --stdin) &&
+ tree=$(build_tree $blob | git mktree) &&
+ git archive -o long_paths.tar $tree
+'
+
test_done
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index 852dcd913f..1ad4ecc29a 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -4,6 +4,12 @@ test_description='Test workflows involving pull request.'
. ./test-lib.sh
+if ! test_have_prereq PERL
+then
+ skip_all='skipping request-pull tests, perl not available'
+ test_done
+fi
+
test_expect_success 'setup' '
git init --bare upstream.git &&
diff --git a/t/t5307-pack-missing-commit.sh b/t/t5307-pack-missing-commit.sh
index dacb440b27..f4338abb78 100755
--- a/t/t5307-pack-missing-commit.sh
+++ b/t/t5307-pack-missing-commit.sh
@@ -24,11 +24,11 @@ test_expect_success 'check corruption' '
'
test_expect_success 'rev-list notices corruption (1)' '
- test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git rev-list HEAD
+ test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git -c core.commitGraph=false rev-list HEAD
'
test_expect_success 'rev-list notices corruption (2)' '
- test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git rev-list --objects HEAD
+ test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git -c core.commitGraph=false rev-list --objects HEAD
'
test_expect_success 'pack-objects notices corruption' '
diff --git a/t/t5314-pack-cycle-detection.sh b/t/t5314-pack-cycle-detection.sh
index e525466de0..0aec8619e2 100755
--- a/t/t5314-pack-cycle-detection.sh
+++ b/t/t5314-pack-cycle-detection.sh
@@ -53,7 +53,7 @@ immediately after the lookup for "dummy".
-# Create a pack containing the the tree $1 and blob $1:file, with
+# Create a pack containing the tree $1 and blob $1:file, with
# the latter stored as a delta against $2:file.
#
# We convince pack-objects to make the delta in the direction of our choosing
diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh
index 2d2f5d0229..dc0446574b 100755
--- a/t/t5317-pack-objects-filter-objects.sh
+++ b/t/t5317-pack-objects-filter-objects.sh
@@ -45,12 +45,7 @@ test_expect_success 'verify blob:none packfile has no blobs' '
git -C r1 index-pack ../filter.pack &&
git -C r1 verify-pack -v ../filter.pack >verify_result &&
- grep blob verify_result |
- awk -f print_1.awk |
- sort >observed &&
-
- nr=$(wc -l <observed) &&
- test 0 -eq $nr
+ ! grep blob verify_result
'
test_expect_success 'verify normal and blob:none packfiles have same commits/trees' '
@@ -72,7 +67,8 @@ test_expect_success 'get an error for missing tree object' '
echo foo >r5/foo &&
git -C r5 add foo &&
git -C r5 commit -m "foo" &&
- del=$(git -C r5 rev-parse HEAD^{tree} | sed "s|..|&/|") &&
+ git -C r5 rev-parse HEAD^{tree} >tree &&
+ del=$(sed "s|..|&/|" tree) &&
rm r5/.git/objects/$del &&
test_must_fail git -C r5 pack-objects --revs --stdout 2>bad_tree <<-EOF &&
HEAD
@@ -148,12 +144,7 @@ test_expect_success 'verify blob:limit=500 omits all blobs' '
git -C r2 index-pack ../filter.pack &&
git -C r2 verify-pack -v ../filter.pack >verify_result &&
- grep blob verify_result |
- awk -f print_1.awk |
- sort >observed &&
-
- nr=$(wc -l <observed) &&
- test 0 -eq $nr
+ ! grep blob verify_result
'
test_expect_success 'verify blob:limit=1000' '
@@ -163,12 +154,7 @@ test_expect_success 'verify blob:limit=1000' '
git -C r2 index-pack ../filter.pack &&
git -C r2 verify-pack -v ../filter.pack >verify_result &&
- grep blob verify_result |
- awk -f print_1.awk |
- sort >observed &&
-
- nr=$(wc -l <observed) &&
- test 0 -eq $nr
+ ! grep blob verify_result
'
test_expect_success 'verify blob:limit=1001' '
@@ -230,10 +216,9 @@ test_expect_success 'verify explicitly specifying oversized blob in input' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
- HEAD
- $(git -C r2 rev-parse HEAD:large.10000)
- EOF
+ echo HEAD >objects &&
+ git -C r2 rev-parse HEAD:large.10000 >>objects &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k <objects >filter.pack &&
git -C r2 index-pack ../filter.pack &&
git -C r2 verify-pack -v ../filter.pack >verify_result &&
@@ -377,7 +362,8 @@ test_expect_success 'verify sparse:oid=OID' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- oid=$(git -C r4 ls-files -s pattern | awk -f print_2.awk) &&
+ git -C r4 ls-files -s pattern >staged &&
+ oid=$(awk -f print_2.awk staged) &&
git -C r4 pack-objects --revs --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF &&
HEAD
EOF
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index 22cb9d6643..81cf118cb6 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -23,11 +23,10 @@ test_expect_success 'write graph with no packs' '
test_path_is_missing info/commit-graph
'
-test_expect_success 'close with correct error on bad input' '
+test_expect_success 'exit with correct error on bad input to --stdin-packs' '
cd "$TRASH_DIRECTORY/full" &&
echo doesnotexist >in &&
- { git commit-graph write --stdin-packs <in 2>stderr; ret=$?; } &&
- test "$ret" = 1 &&
+ test_expect_code 1 git commit-graph write --stdin-packs <in 2>stderr &&
test_i18ngrep "error adding pack" stderr
'
@@ -41,6 +40,15 @@ test_expect_success 'create commits and repack' '
git repack
'
+test_expect_success 'exit with correct error on bad input to --stdin-commits' '
+ cd "$TRASH_DIRECTORY/full" &&
+ echo HEAD | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
+ test_i18ngrep "invalid commit object id" stderr &&
+ # valid tree OID, but not a commit OID
+ git rev-parse HEAD^{tree} | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
+ test_i18ngrep "invalid commit object id" stderr
+'
+
graph_git_two_modes() {
git -c core.commitGraph=true $1 >output
git -c core.commitGraph=false $1 >expect
@@ -77,7 +85,7 @@ graph_read_expect() {
num_commits: $1
chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL
EOF
- git commit-graph read >output &&
+ test-tool read-graph >output &&
test_cmp expect output
}
@@ -116,6 +124,42 @@ test_expect_success 'Add more commits' '
git repack
'
+test_expect_success 'commit-graph write progress off for redirected stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph write 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'commit-graph write force progress on for stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ GIT_PROGRESS_DELAY=0 git commit-graph write --progress 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'commit-graph write with the --no-progress option' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph write --no-progress 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'commit-graph verify progress off for redirected stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph verify 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'commit-graph verify force progress on for stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ GIT_PROGRESS_DELAY=0 git commit-graph verify --progress 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'commit-graph verify with the --no-progress option' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph verify --no-progress 2>err &&
+ test_line_count = 0 err
+'
+
# Current graph structure:
#
# __M3___
@@ -437,7 +481,7 @@ test_expect_success 'detect bad version' '
'
test_expect_success 'detect bad hash version' '
- corrupt_graph_and_verify $GRAPH_BYTE_HASH "\02" \
+ corrupt_graph_and_verify $GRAPH_BYTE_HASH "\03" \
"hash version"
'
@@ -577,4 +621,47 @@ test_expect_success 'get_commit_tree_in_graph works for non-the_repository' '
test_cmp expect actual
'
+test_expect_success 'corrupt commit-graph write (broken parent)' '
+ rm -rf repo &&
+ git init repo &&
+ (
+ cd repo &&
+ empty="$(git mktree </dev/null)" &&
+ cat >broken <<-EOF &&
+ tree $empty
+ parent 0000000000000000000000000000000000000000
+ author whatever <whatever@example.com> 1234 -0000
+ committer whatever <whatever@example.com> 1234 -0000
+
+ broken commit
+ EOF
+ broken="$(git hash-object -w -t commit --literally broken)" &&
+ git commit-tree -p "$broken" -m "good commit" "$empty" >good &&
+ test_must_fail git commit-graph write --stdin-commits \
+ <good 2>test_err &&
+ test_i18ngrep "unable to parse commit" test_err
+ )
+'
+
+test_expect_success 'corrupt commit-graph write (missing tree)' '
+ rm -rf repo &&
+ git init repo &&
+ (
+ cd repo &&
+ tree="$(git mktree </dev/null)" &&
+ cat >broken <<-EOF &&
+ parent 0000000000000000000000000000000000000000
+ author whatever <whatever@example.com> 1234 -0000
+ committer whatever <whatever@example.com> 1234 -0000
+
+ broken commit
+ EOF
+ broken="$(git hash-object -w -t commit --literally broken)" &&
+ git commit-tree -p "$broken" -m "good" "$tree" >good &&
+ test_must_fail git commit-graph write --stdin-commits \
+ <good 2>test_err &&
+ test_i18ngrep "unable to parse commit" test_err
+ )
+'
+
test_done
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index c72ca04399..43a7a66c9d 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -28,6 +28,20 @@ midx_read_expect () {
test_cmp expect actual
}
+test_expect_success 'setup' '
+ test_oid_init &&
+ test_oid_cache <<-EOF
+ idxoff sha1:2999
+ idxoff sha256:3739
+
+ packnameoff sha1:652
+ packnameoff sha256:940
+
+ fanoutoff sha1:1
+ fanoutoff sha256:3
+ EOF
+'
+
test_expect_success 'write midx with no packs' '
test_when_finished rm -f pack/multi-pack-index &&
git multi-pack-index --object-dir=. write &&
@@ -147,6 +161,21 @@ test_expect_success 'write midx with two packs' '
compare_results_with_midx "two packs"
+test_expect_success 'write progress off for redirected stderr' '
+ git multi-pack-index --object-dir=$objdir write 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'write force progress on for stderr' '
+ git multi-pack-index --object-dir=$objdir --progress write 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'write with the --no-progress option' '
+ git multi-pack-index --object-dir=$objdir --no-progress write 2>err &&
+ test_line_count = 0 err
+'
+
test_expect_success 'add more packs' '
for j in $(test_seq 11 20)
do
@@ -169,6 +198,21 @@ test_expect_success 'verify multi-pack-index success' '
git multi-pack-index verify --object-dir=$objdir
'
+test_expect_success 'verify progress off for redirected stderr' '
+ git multi-pack-index verify --object-dir=$objdir 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'verify force progress on for stderr' '
+ git multi-pack-index verify --object-dir=$objdir --progress 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'verify with the --no-progress option' '
+ git multi-pack-index verify --object-dir=$objdir --no-progress 2>err &&
+ test_line_count = 0 err
+'
+
# usage: corrupt_midx_and_verify <pos> <data> <objdir> <string>
corrupt_midx_and_verify() {
POS=$1 &&
@@ -195,7 +239,7 @@ test_expect_success 'verify bad signature' '
"multi-pack-index signature"
'
-HASH_LEN=20
+HASH_LEN=$(test_oid rawsz)
NUM_OBJECTS=74
MIDX_BYTE_VERSION=4
MIDX_BYTE_OID_VERSION=5
@@ -208,9 +252,9 @@ MIDX_CHUNK_LOOKUP_WIDTH=12
MIDX_OFFSET_PACKNAMES=$(($MIDX_HEADER_SIZE + \
$MIDX_NUM_CHUNKS * $MIDX_CHUNK_LOOKUP_WIDTH))
MIDX_BYTE_PACKNAME_ORDER=$(($MIDX_OFFSET_PACKNAMES + 2))
-MIDX_OFFSET_OID_FANOUT=$(($MIDX_OFFSET_PACKNAMES + 652))
+MIDX_OFFSET_OID_FANOUT=$(($MIDX_OFFSET_PACKNAMES + $(test_oid packnameoff)))
MIDX_OID_FANOUT_WIDTH=4
-MIDX_BYTE_OID_FANOUT_ORDER=$((MIDX_OFFSET_OID_FANOUT + 250 * $MIDX_OID_FANOUT_WIDTH + 1))
+MIDX_BYTE_OID_FANOUT_ORDER=$((MIDX_OFFSET_OID_FANOUT + 250 * $MIDX_OID_FANOUT_WIDTH + $(test_oid fanoutoff)))
MIDX_OFFSET_OID_LOOKUP=$(($MIDX_OFFSET_OID_FANOUT + 256 * $MIDX_OID_FANOUT_WIDTH))
MIDX_BYTE_OID_LOOKUP=$(($MIDX_OFFSET_OID_LOOKUP + 16 * $HASH_LEN))
MIDX_OFFSET_OBJECT_OFFSETS=$(($MIDX_OFFSET_OID_LOOKUP + $NUM_OBJECTS * $HASH_LEN))
@@ -274,16 +318,31 @@ test_expect_success 'verify incorrect pack-int-id' '
'
test_expect_success 'verify incorrect offset' '
- corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\07" $objdir \
+ corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\377" $objdir \
"incorrect object offset"
'
test_expect_success 'git-fsck incorrect offset' '
- corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\07" $objdir \
+ corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\377" $objdir \
"incorrect object offset" \
"git -c core.multipackindex=true fsck"
'
+test_expect_success 'repack progress off for redirected stderr' '
+ git multi-pack-index --object-dir=$objdir repack 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'repack force progress on for stderr' '
+ git multi-pack-index --object-dir=$objdir --progress repack 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'repack with the --no-progress option' '
+ git multi-pack-index --object-dir=$objdir --no-progress repack 2>err &&
+ test_line_count = 0 err
+'
+
test_expect_success 'repack removes multi-pack-index' '
test_path_is_file $objdir/pack/multi-pack-index &&
GIT_TEST_MULTI_PACK_INDEX=0 git repack -adf &&
@@ -342,7 +401,7 @@ test_expect_success 'force some 64-bit offsets with pack-objects' '
pack64=$(git pack-objects --index-version=2,0x40 objects64/pack/test-64 <obj-list) &&
idx64=objects64/pack/test-64-$pack64.idx &&
chmod u+w $idx64 &&
- corrupt_data $idx64 2999 "\02" &&
+ corrupt_data $idx64 $(test_oid idxoff) "\02" &&
midx64=$(git multi-pack-index --object-dir=objects64 write) &&
midx_read_expect 1 63 5 objects64 " large-offsets"
'
@@ -413,6 +472,30 @@ test_expect_success 'expire does not remove any packs' '
)
'
+test_expect_success 'expire progress off for redirected stderr' '
+ (
+ cd dup &&
+ git multi-pack-index expire 2>err &&
+ test_line_count = 0 err
+ )
+'
+
+test_expect_success 'expire force progress on for stderr' '
+ (
+ cd dup &&
+ git multi-pack-index --progress expire 2>err &&
+ test_file_not_empty err
+ )
+'
+
+test_expect_success 'expire with the --no-progress option' '
+ (
+ cd dup &&
+ git multi-pack-index --no-progress expire 2>err &&
+ test_line_count = 0 err
+ )
+'
+
test_expect_success 'expire removes unreferenced packs' '
(
cd dup &&
diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh
index 99f4ef4c19..53b2e6b455 100755
--- a/t/t5324-split-commit-graph.sh
+++ b/t/t5324-split-commit-graph.sh
@@ -8,9 +8,17 @@ GIT_TEST_COMMIT_GRAPH=0
test_expect_success 'setup repo' '
git init &&
git config core.commitGraph true &&
+ git config gc.writeCommitGraph false &&
infodir=".git/objects/info" &&
graphdir="$infodir/commit-graphs" &&
- test_oid_init
+ test_oid_init &&
+ test_oid_cache <<-EOM
+ shallow sha1:1760
+ shallow sha256:2064
+
+ base sha1:1376
+ base sha256:1496
+ EOM
'
graph_read_expect() {
@@ -24,7 +32,7 @@ graph_read_expect() {
num_commits: $1
chunks: oid_fanout oid_lookup commit_metadata
EOF
- git commit-graph read >output &&
+ test-tool read-graph >output &&
test_cmp expect output
}
@@ -247,7 +255,7 @@ test_expect_success 'verify hashes along chain, even in shallow' '
cd verify &&
git commit-graph verify &&
base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
- corrupt_file "$base_file" 1760 "\01" &&
+ corrupt_file "$base_file" $(test_oid shallow) "\01" &&
test_must_fail git commit-graph verify --shallow 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "incorrect checksum" err
@@ -274,7 +282,7 @@ test_expect_success 'warn on base graph chunk incorrect' '
cd base-chunk &&
git commit-graph verify &&
base_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
- corrupt_file "$base_file" 1376 "\01" &&
+ corrupt_file "$base_file" $(test_oid base) "\01" &&
git commit-graph verify --shallow 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "commit-graph chain does not match" err
@@ -319,7 +327,7 @@ test_expect_success 'add octopus merge' '
git merge commits/3 commits/4 &&
git branch merge/octopus &&
git commit-graph write --reachable --split &&
- git commit-graph verify 2>err &&
+ git commit-graph verify --progress 2>err &&
test_line_count = 3 err &&
test_i18ngrep ! warning err &&
test_line_count = 3 $graphdir/commit-graph-chain
@@ -334,6 +342,7 @@ test_expect_success 'split across alternate where alternate is not split' '
git clone --no-hardlinks . alt-split &&
(
cd alt-split &&
+ rm -f .git/objects/info/commit-graph &&
echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
test_commit 18 &&
git commit-graph write --reachable --split &&
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 571d620aed..b84618c925 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -288,7 +288,7 @@ test_expect_success 'receive-pack de-dupes .have lines' '
$shared .have
EOF
- GIT_TRACE_PACKET=$(pwd)/trace GIT_TEST_PROTOCOL_VERSION= \
+ GIT_TRACE_PACKET=$(pwd)/trace GIT_TEST_PROTOCOL_VERSION=0 \
git push \
--receive-pack="unset GIT_TRACE_PACKET; git-receive-pack" \
fork HEAD:foo &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 1c71c0ec77..baa1a99f45 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -440,11 +440,12 @@ test_expect_success 'setup tests for the --stdin parameter' '
'
test_expect_success 'setup fetch refs from cmdline v[12]' '
+ cp -r client client0 &&
cp -r client client1 &&
cp -r client client2
'
-for version in '' 1 2
+for version in '' 0 1 2
do
test_expect_success "protocol.version=$version fetch refs from cmdline" "
(
@@ -638,7 +639,7 @@ test_expect_success 'fetch-pack cannot fetch a raw sha1 that is not advertised a
git init client &&
# Some protocol versions (e.g. 2) support fetching
# unadvertised objects, so restrict this test to v0.
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= git -C client fetch-pack ../server \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C client fetch-pack ../server \
$(git -C server rev-parse refs/heads/master^) 2>err &&
test_i18ngrep "Server does not allow request for unadvertised object" err
'
@@ -708,13 +709,22 @@ do
# file with scheme
for p in file
do
- test_expect_success "fetch-pack --diag-url $p://$h/$r" '
+ test_expect_success !MINGW "fetch-pack --diag-url $p://$h/$r" '
check_prot_path $p://$h/$r $p "/$r"
'
+ test_expect_success MINGW "fetch-pack --diag-url $p://$h/$r" '
+ check_prot_path $p://$h/$r $p "//$h/$r"
+ '
+ test_expect_success MINGW "fetch-pack --diag-url $p:///$r" '
+ check_prot_path $p:///$r $p "/$r"
+ '
# No "/~" -> "~" conversion for file
- test_expect_success "fetch-pack --diag-url $p://$h/~$r" '
+ test_expect_success !MINGW "fetch-pack --diag-url $p://$h/~$r" '
check_prot_path $p://$h/~$r $p "/~$r"
'
+ test_expect_success MINGW "fetch-pack --diag-url $p://$h/~$r" '
+ check_prot_path $p://$h/~$r $p "//$h/~$r"
+ '
done
# file without scheme
for h in nohost nohost:12 [::1] [::1]:23 [ [:aa
@@ -783,6 +793,44 @@ test_expect_success 'clone shallow since selects no commits' '
)
'
+# A few subtle things about the request in this test:
+#
+# - the server must have commit-graphs present and enabled
+#
+# - the history is such that our want/have share a common ancestor ("base"
+# here)
+#
+# - we send only a single have, which is fewer than a normal client would
+# send. This ensures that we don't parse "base" up front with
+# parse_object(), but rather traverse to it as a parent while deciding if we
+# can stop the "have" negotiation, and call parse_commit(). The former
+# sees the actual object data and so always loads the three oid, whereas the
+# latter will try to load it lazily.
+#
+# - we must use protocol v2, because it handles the "have" negotiation before
+# processing the shallow directives
+#
+test_expect_success 'shallow since with commit graph and already-seen commit' '
+ test_create_repo shallow-since-graph &&
+ (
+ cd shallow-since-graph &&
+ test_commit base &&
+ test_commit master &&
+ git checkout -b other HEAD^ &&
+ test_commit other &&
+ git commit-graph write --reachable &&
+ git config core.commitGraph true &&
+
+ GIT_PROTOCOL=version=2 git upload-pack . <<-EOF >/dev/null
+ 0012command=fetch
+ 00010013deepen-since 1
+ 0032want $(git rev-parse other)
+ 0032have $(git rev-parse master)
+ 0000
+ EOF
+ )
+'
+
test_expect_success 'shallow clone exclude tag two' '
test_create_repo shallow-exclude &&
(
@@ -870,7 +918,10 @@ test_expect_success 'filtering by size' '
git -C client fetch-pack --filter=blob:limit=0 ../server HEAD &&
# Ensure that object is not inadvertently fetched
- test_must_fail git -C client cat-file -e $(git hash-object server/one.t)
+ commit=$(git -C server rev-parse HEAD) &&
+ blob=$(git hash-object server/one.t) &&
+ git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
+ ! grep "$blob" oids
'
test_expect_success 'filtering by size has no effect if support for it is not advertised' '
@@ -882,7 +933,10 @@ test_expect_success 'filtering by size has no effect if support for it is not ad
git -C client fetch-pack --filter=blob:limit=0 ../server HEAD 2> err &&
# Ensure that object is fetched
- git -C client cat-file -e $(git hash-object server/one.t) &&
+ commit=$(git -C server rev-parse HEAD) &&
+ blob=$(git hash-object server/one.t) &&
+ git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
+ grep "$blob" oids &&
test_i18ngrep "filtering not recognized by server" err
'
@@ -904,9 +958,11 @@ fetch_filter_blob_limit_zero () {
git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere &&
# Ensure that commit is fetched, but blob is not
- test_config -C client extensions.partialclone "arbitrary string" &&
- git -C client cat-file -e $(git -C "$SERVER" rev-parse two) &&
- test_must_fail git -C client cat-file -e $(git hash-object "$SERVER/two.t")
+ commit=$(git -C "$SERVER" rev-parse two) &&
+ blob=$(git hash-object server/two.t) &&
+ git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
+ grep "$commit" oids &&
+ ! grep "$blob" oids
}
test_expect_success 'fetch with --filter=blob:limit=0' '
@@ -920,4 +976,7 @@ test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh
index fdfe179b11..645b4c78d3 100755
--- a/t/t5504-fetch-receive-strict.sh
+++ b/t/t5504-fetch-receive-strict.sh
@@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'
. ./test-lib.sh
test_expect_success 'setup and inject "corrupt or missing" object' '
+ test_oid_init &&
echo hello >greetings &&
git add greetings &&
git commit -m greetings &&
@@ -144,11 +145,11 @@ test_expect_success 'fsck with no skipList input' '
test_expect_success 'setup sorted and unsorted skipLists' '
cat >SKIP.unsorted <<-EOF &&
- 0000000000000000000000000000000000000004
- 0000000000000000000000000000000000000002
+ $(test_oid 004)
+ $(test_oid 002)
$commit
- 0000000000000000000000000000000000000001
- 0000000000000000000000000000000000000003
+ $(test_oid 001)
+ $(test_oid 003)
EOF
sort SKIP.unsorted >SKIP.sorted
'
@@ -172,14 +173,14 @@ test_expect_success 'fsck with invalid or bogus skipList input' '
test_expect_success 'fsck with other accepted skipList input (comments & empty lines)' '
cat >SKIP.with-comment <<-EOF &&
# Some bad commit
- 0000000000000000000000000000000000000001
+ $(test_oid 001)
EOF
test_must_fail git -c fsck.skipList=SKIP.with-comment fsck 2>err-with-comment &&
test_i18ngrep "missingEmail" err-with-comment &&
cat >SKIP.with-empty-line <<-EOF &&
- 0000000000000000000000000000000000000001
+ $(test_oid 001)
- 0000000000000000000000000000000000000002
+ $(test_oid 002)
EOF
test_must_fail git -c fsck.skipList=SKIP.with-empty-line fsck 2>err-with-empty-line &&
test_i18ngrep "missingEmail" err-with-empty-line
@@ -204,7 +205,7 @@ test_expect_success 'fsck with exhaustive accepted skipList input (various types
echo " # Comment after whitespace" >>SKIP.exhaustive &&
echo "$commit # Our bad commit (with leading whitespace and trailing comment)" >>SKIP.exhaustive &&
echo "# Some bad commit (leading whitespace)" >>SKIP.exhaustive &&
- echo " 0000000000000000000000000000000000000001" >>SKIP.exhaustive &&
+ echo " $(test_oid 001)" >>SKIP.exhaustive &&
git -c fsck.skipList=SKIP.exhaustive fsck 2>err &&
test_must_be_empty err
'
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 139f7106f7..566994cede 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -11,7 +11,7 @@ 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 "$2" = $(grep "^$OID_REGEX " verify.out | wc -l)
}
convert_bundle_to_pack () {
@@ -174,6 +174,30 @@ test_expect_success 'fetch --prune --tags with refspec prunes based on refspec'
git rev-parse sometag
'
+test_expect_success '--refmap="" ignores configured refspec' '
+ cd "$TRASH_DIRECTORY" &&
+ git clone "$D" remote-refs &&
+ git -C remote-refs rev-parse remotes/origin/master >old &&
+ git -C remote-refs update-ref refs/remotes/origin/master master~1 &&
+ git -C remote-refs rev-parse remotes/origin/master >new &&
+ git -C remote-refs fetch --refmap= origin "+refs/heads/*:refs/hidden/origin/*" &&
+ git -C remote-refs rev-parse remotes/origin/master >actual &&
+ test_cmp new actual &&
+ git -C remote-refs fetch origin &&
+ git -C remote-refs rev-parse remotes/origin/master >actual &&
+ test_cmp old actual
+'
+
+test_expect_success '--refmap="" and --prune' '
+ git -C remote-refs update-ref refs/remotes/origin/foo/otherbranch master &&
+ git -C remote-refs update-ref refs/hidden/foo/otherbranch master &&
+ git -C remote-refs fetch --prune --refmap="" origin +refs/heads/*:refs/hidden/* &&
+ git -C remote-refs rev-parse remotes/origin/foo/otherbranch &&
+ test_must_fail git -C remote-refs rev-parse refs/hidden/foo/otherbranch &&
+ git -C remote-refs fetch --prune origin &&
+ test_must_fail git -C remote-refs rev-parse remotes/origin/foo/otherbranch
+'
+
test_expect_success 'fetch tags when there is no tags' '
cd "$D" &&
@@ -261,9 +285,10 @@ test_expect_success 'create bundle 1' '
'
test_expect_success 'header of bundle looks right' '
+ head -n 4 "$D"/bundle1 &&
head -n 1 "$D"/bundle1 | grep "^#" &&
- head -n 2 "$D"/bundle1 | grep "^-[0-9a-f]\{40\} " &&
- head -n 3 "$D"/bundle1 | grep "^[0-9a-f]\{40\} " &&
+ head -n 2 "$D"/bundle1 | grep "^-$OID_REGEX " &&
+ head -n 3 "$D"/bundle1 | grep "^$OID_REGEX " &&
head -n 4 "$D"/bundle1 | grep "^$"
'
@@ -289,7 +314,7 @@ test_expect_success 'bundle 1 has only 3 files ' '
test_expect_success 'unbundle 2' '
cd "$D/bundle" &&
git fetch ../bundle2 master:master &&
- test "tip" = "$(git log -1 --pretty=oneline master | cut -b42-)"
+ test "tip" = "$(git log -1 --pretty=oneline master | cut -d" " -f2)"
'
test_expect_success 'bundle does not prerequisite objects' '
@@ -570,6 +595,35 @@ test_expect_success 'LHS of refspec follows ref disambiguation rules' '
)
'
+test_expect_success 'fetch.writeCommitGraph' '
+ git clone three write &&
+ (
+ cd three &&
+ test_commit new
+ ) &&
+ (
+ cd write &&
+ git -c fetch.writeCommitGraph fetch origin &&
+ test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain
+ )
+'
+
+test_expect_success 'fetch.writeCommitGraph with submodules' '
+ git clone dups super &&
+ (
+ cd super &&
+ git submodule add "file://$TRASH_DIRECTORY/three" &&
+ git commit -m "add submodule"
+ ) &&
+ git clone "super" super-clone &&
+ (
+ cd super-clone &&
+ rm -rf .git/objects/info &&
+ git -c fetch.writeCommitGraph=true fetch origin &&
+ test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain
+ )
+'
+
# configured prune tests
set_config_tristate () {
@@ -902,6 +956,29 @@ test_expect_success C_LOCALE_OUTPUT 'fetch compact output' '
test_cmp expect actual
'
+test_expect_success '--no-show-forced-updates' '
+ mkdir forced-updates &&
+ (
+ cd forced-updates &&
+ git init &&
+ test_commit 1 &&
+ test_commit 2
+ ) &&
+ git clone forced-updates forced-update-clone &&
+ git clone forced-updates no-forced-update-clone &&
+ git -C forced-updates reset --hard HEAD~1 &&
+ (
+ cd forced-update-clone &&
+ git fetch --show-forced-updates origin 2>output &&
+ test_i18ngrep "(forced update)" output
+ ) &&
+ (
+ cd no-forced-update-clone &&
+ git fetch --no-show-forced-updates origin 2>output &&
+ test_i18ngrep ! "(forced update)" output
+ )
+'
+
setup_negotiation_tip () {
SERVER="$1"
URL="$2"
@@ -978,27 +1055,7 @@ test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protoc
check_negotiation_tip
'
-test_expect_success '--no-show-forced-updates' '
- mkdir forced-updates &&
- (
- cd forced-updates &&
- git init &&
- test_commit 1 &&
- test_commit 2
- ) &&
- git clone forced-updates forced-update-clone &&
- git clone forced-updates no-forced-update-clone &&
- git -C forced-updates reset --hard HEAD~1 &&
- (
- cd forced-update-clone &&
- git fetch --show-forced-updates origin 2>output &&
- test_i18ngrep "(forced update)" output
- ) &&
- (
- cd no-forced-update-clone &&
- git fetch --no-show-forced-updates origin 2>output &&
- ! test_i18ngrep "(forced update)" output
- )
-'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
test_done
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 43e1d8d4d2..04b35402c7 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -225,49 +225,50 @@ test_expect_success 'ls-remote --symref' '
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref >actual &&
+ GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote with filtered symref (refname)' '
- cat >expect <<-\EOF &&
+ rev=$(git rev-parse HEAD) &&
+ cat >expect <<-EOF &&
ref: refs/heads/master HEAD
- 1bd44cb9d13204b0fe1958db0082f5028a16eb3a HEAD
+ $rev HEAD
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref . HEAD >actual &&
+ GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . HEAD >actual &&
test_cmp expect actual
'
test_expect_failure 'ls-remote with filtered symref (--heads)' '
git symbolic-ref refs/heads/foo refs/tags/mark &&
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
ref: refs/tags/mark refs/heads/foo
- 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/foo
- 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/master
+ $rev refs/heads/foo
+ $rev refs/heads/master
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref --heads . >actual &&
+ GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote --symref omits filtered-out matches' '
- cat >expect <<-\EOF &&
- 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/foo
- 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/master
+ cat >expect <<-EOF &&
+ $rev refs/heads/foo
+ $rev refs/heads/master
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref --heads . >actual &&
+ GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
test_cmp expect actual &&
- GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref . "refs/heads/*" >actual &&
+ GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . "refs/heads/*" >actual &&
test_cmp expect actual
'
test_lazy_prereq GIT_DAEMON '
- git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON
+ test_bool_env GIT_TEST_GIT_DAEMON true
'
# This test spawns a daemon, so run it only if the user would be OK with
diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh
index 5426d4b5ab..de8e2f1531 100755
--- a/t/t5514-fetch-multiple.sh
+++ b/t/t5514-fetch-multiple.sh
@@ -183,4 +183,15 @@ test_expect_success 'git fetch --all --tags' '
test_cmp expect test8/output
'
+test_expect_success 'parallel' '
+ git remote add one ./bogus1 &&
+ git remote add two ./bogus2 &&
+
+ test_must_fail env GIT_TRACE="$PWD/trace" \
+ git fetch --jobs=2 --multiple one two 2>err &&
+ grep "preparing to run up to 2 tasks" trace &&
+ test_i18ngrep "could not fetch .one.*128" err &&
+ test_i18ngrep "could not fetch .two.*128" err
+'
+
test_done
diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh
index e55d8474ef..a9a7d50d3e 100755
--- a/t/t5515-fetch-merge-logic.sh
+++ b/t/t5515-fetch-merge-logic.sh
@@ -8,13 +8,11 @@ test_description='Merge logic in fetch'
# NEEDSWORK: If the overspecification of the expected result is reduced, we
# might be able to run this test in all protocol versions.
-GIT_TEST_PROTOCOL_VERSION=
+GIT_TEST_PROTOCOL_VERSION=0
+export GIT_TEST_PROTOCOL_VERSION
. ./test-lib.sh
-LF='
-'
-
test_expect_success setup '
GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" &&
GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index c81ca360ac..f12cbef097 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1151,7 +1151,7 @@ test_expect_success 'fetch exact SHA1' '
# unadvertised objects, so restrict this test to v0.
# fetching the hidden object should fail by default
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err &&
test_i18ngrep "Server does not allow request for unadvertised object" err &&
test_must_fail git rev-parse --verify refs/heads/copy &&
@@ -1210,7 +1210,7 @@ do
cd shallow &&
# Some protocol versions (e.g. 2) support fetching
# unadvertised objects, so restrict this test to v0.
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git fetch --depth=1 ../testrepo/.git $SHA1 &&
git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
git fetch --depth=1 ../testrepo/.git $SHA1 &&
@@ -1241,9 +1241,9 @@ do
cd shallow &&
# Some protocol versions (e.g. 2) support fetching
# unadvertised objects, so restrict this test to v0.
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git fetch ../testrepo/.git $SHA1_3 &&
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git fetch ../testrepo/.git $SHA1_1 &&
git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
git fetch ../testrepo/.git $SHA1_1 &&
@@ -1251,7 +1251,7 @@ do
test_must_fail git cat-file commit $SHA1_2 &&
git fetch ../testrepo/.git $SHA1_2 &&
git cat-file commit $SHA1_2 &&
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git fetch ../testrepo/.git $SHA1_3 2>err &&
test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
)
@@ -1291,7 +1291,7 @@ test_expect_success 'peeled advertisements are not considered ref tips' '
git -C testrepo commit --allow-empty -m two &&
git -C testrepo tag -m foo mytag HEAD^ &&
oid=$(git -C testrepo rev-parse mytag^{commit}) &&
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git fetch testrepo $oid 2>err &&
test_i18ngrep "Server does not allow request for unadvertised object" err
'
diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh
index c05a661400..e4edd56404 100755
--- a/t/t5517-push-mirror.sh
+++ b/t/t5517-push-mirror.sh
@@ -265,4 +265,14 @@ test_expect_success 'remote.foo.mirror=no has no effect' '
'
+test_expect_success 'push to mirrored repository with refspec fails' '
+ mk_repo_pair &&
+ (
+ cd master &&
+ echo one >foo && git add foo && git commit -m one &&
+ git config --add remote.up.mirror true &&
+ test_must_fail git push up master
+ )
+'
+
test_done
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index cf4cc32fd0..602d996a33 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -5,7 +5,7 @@ test_description='pulling into void'
. ./test-lib.sh
modify () {
- sed -e "$1" <"$2" >"$2.x" &&
+ sed -e "$1" "$2" >"$2.x" &&
mv "$2.x" "$2"
}
@@ -15,8 +15,10 @@ test_pull_autostash () {
git add new_file &&
git pull "$@" . copy &&
test_cmp_rev HEAD^ copy &&
- test "$(cat new_file)" = dirty &&
- test "$(cat file)" = "modified again"
+ echo dirty >expect &&
+ test_cmp expect new_file &&
+ echo "modified again" >expect &&
+ test_cmp expect file
}
test_pull_autostash_fail () {
@@ -39,8 +41,8 @@ test_expect_success 'pulling into void' '
cd cloned &&
git pull ..
) &&
- test -f file &&
- test -f cloned/file &&
+ test_path_is_file file &&
+ test_path_is_file cloned/file &&
test_cmp file cloned/file
'
@@ -50,8 +52,8 @@ test_expect_success 'pulling into void using master:master' '
cd cloned-uho &&
git pull .. master:master
) &&
- test -f file &&
- test -f cloned-uho/file &&
+ test_path_is_file file &&
+ test_path_is_file cloned-uho/file &&
test_cmp file cloned-uho/file
'
@@ -99,7 +101,7 @@ test_expect_success 'pulling into void must not create an octopus' '
(
cd cloned-octopus &&
test_must_fail git pull .. master master &&
- ! test -f file
+ test_path_is_missing file
)
'
@@ -110,9 +112,11 @@ test_expect_success 'test . as a remote' '
echo updated >file &&
git commit -a -m updated &&
git checkout copy &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
git pull &&
- test "$(cat file)" = updated &&
+ echo updated >expect &&
+ test_cmp expect file &&
git reflog -1 >reflog.actual &&
sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
echo "OBJID HEAD@{0}: pull: Fast-forward" >reflog.expected &&
@@ -125,9 +129,11 @@ test_expect_success 'the default remote . should not break explicit pull' '
git commit -a -m modified &&
git checkout copy &&
git reset --hard HEAD^ &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
git pull . second &&
- test "$(cat file)" = modified &&
+ echo modified >expect &&
+ test_cmp expect file &&
git reflog -1 >reflog.actual &&
sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected &&
@@ -137,10 +143,11 @@ test_expect_success 'the default remote . should not break explicit pull' '
test_expect_success 'fail if wildcard spec does not match any refs' '
git checkout -b test copy^ &&
test_when_finished "git checkout -f copy && git branch -D test" &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
test_must_fail git pull . "refs/nonexisting1/*:refs/nonexisting2/*" 2>err &&
test_i18ngrep "no candidates for merging" err &&
- test "$(cat file)" = file
+ test_cmp expect file
'
test_expect_success 'fail if no branches specified with non-default remote' '
@@ -148,11 +155,12 @@ test_expect_success 'fail if no branches specified with non-default remote' '
test_when_finished "git remote remove test_remote" &&
git checkout -b test copy^ &&
test_when_finished "git checkout -f copy && git branch -D test" &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
test_config branch.test.remote origin &&
test_must_fail git pull test_remote 2>err &&
test_i18ngrep "specify a branch on the command line" err &&
- test "$(cat file)" = file
+ test_cmp expect file
'
test_expect_success 'fail if not on a branch' '
@@ -160,10 +168,11 @@ test_expect_success 'fail if not on a branch' '
test_when_finished "git remote remove origin" &&
git checkout HEAD^ &&
test_when_finished "git checkout -f copy" &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
test_must_fail git pull 2>err &&
test_i18ngrep "not currently on a branch" err &&
- test "$(cat file)" = file
+ test_cmp expect file
'
test_expect_success 'fail if no configuration for current branch' '
@@ -172,10 +181,11 @@ test_expect_success 'fail if no configuration for current branch' '
git checkout -b test copy^ &&
test_when_finished "git checkout -f copy && git branch -D test" &&
test_config branch.test.remote test_remote &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
test_must_fail git pull 2>err &&
test_i18ngrep "no tracking information" err &&
- test "$(cat file)" = file
+ test_cmp expect file
'
test_expect_success 'pull --all: fail if no configuration for current branch' '
@@ -184,10 +194,11 @@ test_expect_success 'pull --all: fail if no configuration for current branch' '
git checkout -b test copy^ &&
test_when_finished "git checkout -f copy && git branch -D test" &&
test_config branch.test.remote test_remote &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
test_must_fail git pull --all 2>err &&
test_i18ngrep "There is no tracking information" err &&
- test "$(cat file)" = file
+ test_cmp expect file
'
test_expect_success 'fail if upstream branch does not exist' '
@@ -195,26 +206,31 @@ test_expect_success 'fail if upstream branch does not exist' '
test_when_finished "git checkout -f copy && git branch -D test" &&
test_config branch.test.remote . &&
test_config branch.test.merge refs/heads/nonexisting &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
test_must_fail git pull 2>err &&
test_i18ngrep "no such ref was fetched" err &&
- test "$(cat file)" = file
+ test_cmp expect file
'
test_expect_success 'fail if the index has unresolved entries' '
git checkout -b third second^ &&
test_when_finished "git checkout -f copy && git branch -D third" &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
test_commit modified2 file &&
- test -z "$(git ls-files -u)" &&
+ git ls-files -u >unmerged &&
+ test_must_be_empty unmerged &&
test_must_fail git pull . second &&
- test -n "$(git ls-files -u)" &&
+ git ls-files -u >unmerged &&
+ test_file_not_empty unmerged &&
cp file expected &&
test_must_fail git pull . second 2>err &&
test_i18ngrep "Pulling is not possible because you have unmerged files." err &&
test_cmp expected file &&
git add file &&
- test -z "$(git ls-files -u)" &&
+ git ls-files -u >unmerged &&
+ test_must_be_empty unmerged &&
test_must_fail git pull . second 2>err &&
test_i18ngrep "You have not concluded your merge" err &&
test_cmp expected file
@@ -223,36 +239,42 @@ test_expect_success 'fail if the index has unresolved entries' '
test_expect_success 'fast-forwards working tree if branch head is updated' '
git checkout -b third second^ &&
test_when_finished "git checkout -f copy && git branch -D third" &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
git pull . second:third 2>err &&
test_i18ngrep "fetch updated the current branch head" err &&
- test "$(cat file)" = modified &&
- test "$(git rev-parse third)" = "$(git rev-parse second)"
+ echo modified >expect &&
+ test_cmp expect file &&
+ test_cmp_rev third second
'
test_expect_success 'fast-forward fails with conflicting work tree' '
git checkout -b third second^ &&
test_when_finished "git checkout -f copy && git branch -D third" &&
- test "$(cat file)" = file &&
+ echo file >expect &&
+ test_cmp expect file &&
echo conflict >file &&
test_must_fail git pull . second:third 2>err &&
test_i18ngrep "Cannot fast-forward your working tree" err &&
- test "$(cat file)" = conflict &&
- test "$(git rev-parse third)" = "$(git rev-parse second)"
+ echo conflict >expect &&
+ test_cmp expect file &&
+ test_cmp_rev third second
'
test_expect_success '--rebase' '
git branch to-rebase &&
- echo modified again > file &&
+ echo modified again >file &&
git commit -m file file &&
git checkout to-rebase &&
- echo new > file2 &&
+ echo new >file2 &&
git add file2 &&
git commit -m "new file" &&
git tag before-rebase &&
git pull --rebase . copy &&
- test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
- test new = "$(git show HEAD:file2)"
+ test_cmp_rev HEAD^ copy &&
+ echo new >expect &&
+ git show HEAD:file2 >actual &&
+ test_cmp expect actual
'
test_expect_success '--rebase fast forward' '
@@ -263,7 +285,7 @@ test_expect_success '--rebase fast forward' '
git checkout to-rebase &&
git pull --rebase . ff &&
- test "$(git rev-parse HEAD)" = "$(git rev-parse ff)" &&
+ test_cmp_rev HEAD ff &&
# The above only validates the result. Did we actually bypass rebase?
git reflog -1 >reflog.actual &&
@@ -287,7 +309,7 @@ test_expect_success '--rebase --autostash fast forward' '
git checkout behind &&
echo dirty >file &&
git pull --rebase --autostash . to-rebase-ff &&
- test "$(git rev-parse HEAD)" = "$(git rev-parse to-rebase-ff)"
+ test_cmp_rev HEAD to-rebase-ff
'
test_expect_success '--rebase with conflicts shows advice' '
@@ -325,9 +347,11 @@ test_expect_success 'failed --rebase shows advice' '
test_expect_success '--rebase fails with multiple branches' '
git reset --hard before-rebase &&
test_must_fail git pull --rebase . copy master 2>err &&
- test "$(git rev-parse HEAD)" = "$(git rev-parse before-rebase)" &&
+ test_cmp_rev HEAD before-rebase &&
test_i18ngrep "Cannot rebase onto multiple branches" err &&
- test modified = "$(git show HEAD:file)"
+ echo modified >expect &&
+ git show HEAD:file >actual &&
+ test_cmp expect actual
'
test_expect_success 'pull --rebase succeeds with dirty working directory and rebase.autostash set' '
@@ -377,8 +401,10 @@ test_expect_success 'pull.rebase' '
git reset --hard before-rebase &&
test_config pull.rebase true &&
git pull . copy &&
- test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
- test new = "$(git show HEAD:file2)"
+ test_cmp_rev HEAD^ copy &&
+ echo new >expect &&
+ git show HEAD:file2 >actual &&
+ test_cmp expect actual
'
test_expect_success 'pull --autostash & pull.rebase=true' '
@@ -395,8 +421,10 @@ test_expect_success 'branch.to-rebase.rebase' '
git reset --hard before-rebase &&
test_config branch.to-rebase.rebase true &&
git pull . copy &&
- test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
- test new = "$(git show HEAD:file2)"
+ test_cmp_rev HEAD^ copy &&
+ echo new >expect &&
+ git show HEAD:file2 >actual &&
+ test_cmp expect actual
'
test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '
@@ -404,23 +432,29 @@ test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '
test_config pull.rebase true &&
test_config branch.to-rebase.rebase false &&
git pull . copy &&
- test "$(git rev-parse HEAD^)" != "$(git rev-parse copy)" &&
- test new = "$(git show HEAD:file2)"
+ test_cmp_rev ! HEAD^ copy &&
+ echo new >expect &&
+ git show HEAD:file2 >actual &&
+ test_cmp expect actual
'
-test_expect_success "pull --rebase warns on --verify-signatures" '
+test_expect_success 'pull --rebase warns on --verify-signatures' '
git reset --hard before-rebase &&
git pull --rebase --verify-signatures . copy 2>err &&
- test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
- test new = "$(git show HEAD:file2)" &&
+ test_cmp_rev HEAD^ copy &&
+ echo new >expect &&
+ git show HEAD:file2 >actual &&
+ test_cmp expect actual &&
test_i18ngrep "ignoring --verify-signatures for rebase" err
'
-test_expect_success "pull --rebase does not warn on --no-verify-signatures" '
+test_expect_success 'pull --rebase does not warn on --no-verify-signatures' '
git reset --hard before-rebase &&
git pull --rebase --no-verify-signatures . copy 2>err &&
- test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
- test new = "$(git show HEAD:file2)" &&
+ test_cmp_rev HEAD^ copy &&
+ echo new >expect &&
+ git show HEAD:file2 >actual &&
+ test_cmp expect actual &&
test_i18ngrep ! "verify-signatures" err
'
@@ -440,25 +474,31 @@ test_expect_success 'pull.rebase=false create a new merge commit' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase false &&
git pull . copy &&
- test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
- test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
- test file3 = "$(git show HEAD:file3.t)"
+ test_cmp_rev HEAD^1 before-preserve-rebase &&
+ test_cmp_rev HEAD^2 copy &&
+ echo file3 >expect &&
+ git show HEAD:file3.t >actual &&
+ test_cmp expect actual
'
test_expect_success 'pull.rebase=true flattens keep-merge' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase true &&
git pull . copy &&
- test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
- test file3 = "$(git show HEAD:file3.t)"
+ test_cmp_rev HEAD^^ copy &&
+ echo file3 >expect &&
+ git show HEAD:file3.t >actual &&
+ test_cmp expect actual
'
test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase 1 &&
git pull . copy &&
- test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
- test file3 = "$(git show HEAD:file3.t)"
+ test_cmp_rev HEAD^^ copy &&
+ echo file3 >expect &&
+ git show HEAD:file3.t >actual &&
+ test_cmp expect actual
'
test_expect_success REBASE_P \
@@ -466,8 +506,8 @@ test_expect_success REBASE_P \
git reset --hard before-preserve-rebase &&
test_config pull.rebase preserve &&
git pull . copy &&
- test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
- test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
+ test_cmp_rev HEAD^^ copy &&
+ test_cmp_rev HEAD^2 keep-merge
'
test_expect_success 'pull.rebase=interactive' '
@@ -478,7 +518,8 @@ test_expect_success 'pull.rebase=interactive' '
test_set_editor "$TRASH_DIRECTORY/fake-editor" &&
test_when_finished "test_might_fail git rebase --abort" &&
test_must_fail git pull --rebase=interactive . copy &&
- test "I was here" = "$(cat fake.out)"
+ echo "I was here" >expect &&
+ test_cmp expect fake.out
'
test_expect_success 'pull --rebase=i' '
@@ -489,30 +530,35 @@ test_expect_success 'pull --rebase=i' '
test_set_editor "$TRASH_DIRECTORY/fake-editor" &&
test_when_finished "test_might_fail git rebase --abort" &&
test_must_fail git pull --rebase=i . copy &&
- test "I was here, too" = "$(cat fake.out)"
+ echo "I was here, too" >expect &&
+ test_cmp expect fake.out
'
test_expect_success 'pull.rebase=invalid fails' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase invalid &&
- ! git pull . copy
+ test_must_fail git pull . copy
'
test_expect_success '--rebase=false create a new merge commit' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase true &&
git pull --rebase=false . copy &&
- test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
- test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
- test file3 = "$(git show HEAD:file3.t)"
+ test_cmp_rev HEAD^1 before-preserve-rebase &&
+ test_cmp_rev HEAD^2 copy &&
+ echo file3 >expect &&
+ git show HEAD:file3.t >actual &&
+ test_cmp expect actual
'
test_expect_success '--rebase=true rebases and flattens keep-merge' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase preserve &&
git pull --rebase=true . copy &&
- test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
- test file3 = "$(git show HEAD:file3.t)"
+ test_cmp_rev HEAD^^ copy &&
+ echo file3 >expect &&
+ git show HEAD:file3.t >actual &&
+ test_cmp expect actual
'
test_expect_success REBASE_P \
@@ -520,58 +566,62 @@ test_expect_success REBASE_P \
git reset --hard before-preserve-rebase &&
test_config pull.rebase true &&
git pull --rebase=preserve . copy &&
- test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
- test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
+ test_cmp_rev HEAD^^ copy &&
+ test_cmp_rev HEAD^2 keep-merge
'
test_expect_success '--rebase=invalid fails' '
git reset --hard before-preserve-rebase &&
- ! git pull --rebase=invalid . copy
+ test_must_fail git pull --rebase=invalid . copy
'
test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase preserve &&
git pull --rebase . copy &&
- test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
- test file3 = "$(git show HEAD:file3.t)"
+ test_cmp_rev HEAD^^ copy &&
+ echo file3 >expect &&
+ git show HEAD:file3.t >actual &&
+ test_cmp expect actual
'
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 &&
+ echo conflicting modification >file &&
git commit -m conflict file &&
git checkout to-rebase &&
- echo file > file2 &&
+ 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)"
-
+ echo "conflicting modification" >expect &&
+ test_cmp expect file &&
+ echo file >expect &&
+ test_cmp expect file2
'
test_expect_success '--rebase -f with rebased upstream' '
test_when_finished "test_might_fail git rebase --abort" &&
git reset --hard to-rebase-orig &&
git pull --rebase -f me copy &&
- test "conflicting modification" = "$(cat file)" &&
- test file = "$(cat file2)"
+ echo "conflicting modification" >expect &&
+ test_cmp expect file &&
+ echo file >expect &&
+ test_cmp expect 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)"
-
+ echo "conflicting modification" >expect &&
+ test_cmp expect file &&
+ echo file >expect &&
+ test_cmp expect file2
'
test_expect_success 'rebased upstream + fetch + pull --rebase' '
@@ -582,13 +632,14 @@ test_expect_success 'rebased upstream + fetch + pull --rebase' '
git reset --hard to-rebase-orig &&
git fetch &&
git pull --rebase &&
- test "conflicting modification" = "$(cat file)" &&
- test file = "$(cat file2)"
+ echo "conflicting modification" >expect &&
+ test_cmp expect file &&
+ echo file >expect &&
+ test_cmp expect 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)" &&
@@ -596,23 +647,23 @@ test_expect_success 'pull --rebase dies early with dirty working directory' '
test_config branch.to-rebase.remote me &&
test_config branch.to-rebase.merge refs/heads/copy &&
test_config branch.to-rebase.rebase true &&
- echo dirty >> file &&
+ echo dirty >>file &&
git add file &&
test_must_fail git pull &&
- test "$COPY" = "$(git rev-parse --verify me/copy)" &&
+ test_cmp_rev "$COPY" me/copy &&
git checkout HEAD -- file &&
git pull &&
- test "$COPY" != "$(git rev-parse --verify me/copy)"
-
+ test_cmp_rev ! "$COPY" me/copy
'
test_expect_success 'pull --rebase works on branch yet to be born' '
git rev-parse master >expect &&
mkdir empty_repo &&
- (cd empty_repo &&
- git init &&
- git pull --rebase .. master &&
- git rev-parse HEAD >../actual
+ (
+ cd empty_repo &&
+ git init &&
+ git pull --rebase .. master &&
+ git rev-parse HEAD >../actual
) &&
test_cmp expect actual
'
@@ -624,10 +675,14 @@ test_expect_success 'pull --rebase fails on unborn branch with staged changes' '
cd empty_repo2 &&
echo staged-file >staged-file &&
git add staged-file &&
- test "$(git ls-files)" = staged-file &&
+ echo staged-file >expect &&
+ git ls-files >actual &&
+ test_cmp expect actual &&
test_must_fail git pull --rebase .. master 2>err &&
- test "$(git ls-files)" = staged-file &&
- test "$(git show :staged-file)" = staged-file &&
+ git ls-files >actual &&
+ test_cmp expect actual &&
+ git show :staged-file >actual &&
+ test_cmp expect actual &&
test_i18ngrep "unborn branch with changes added to the index" err
)
'
@@ -638,7 +693,8 @@ test_expect_success 'pull --rebase fails on corrupt HEAD' '
(
cd corrupt &&
test_commit one &&
- obj=$(git rev-parse --verify HEAD | sed "s#^..#&/#") &&
+ git rev-parse --verify HEAD >head &&
+ obj=$(sed "s#^..#&/#" head) &&
rm -f .git/objects/$obj &&
test_must_fail git pull --rebase
)
@@ -646,66 +702,77 @@ test_expect_success 'pull --rebase fails on corrupt HEAD' '
test_expect_success 'setup for detecting upstreamed changes' '
mkdir src &&
- (cd src &&
- git init &&
- printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff &&
- git add stuff &&
- git commit -m "Initial revision"
+ (
+ cd src &&
+ git init &&
+ printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff &&
+ git add stuff &&
+ git commit -m "Initial revision"
) &&
git clone src dst &&
- (cd src &&
- modify s/5/43/ stuff &&
- git commit -a -m "5->43" &&
- modify s/6/42/ stuff &&
- git commit -a -m "Make it bigger"
+ (
+ cd src &&
+ modify s/5/43/ stuff &&
+ git commit -a -m "5->43" &&
+ modify s/6/42/ stuff &&
+ git commit -a -m "Make it bigger"
) &&
- (cd dst &&
- modify s/5/43/ stuff &&
- git commit -a -m "Independent discovery of 5->43"
+ (
+ cd dst &&
+ modify s/5/43/ stuff &&
+ git commit -a -m "Independent discovery of 5->43"
)
'
test_expect_success 'git pull --rebase detects upstreamed changes' '
- (cd dst &&
- git pull --rebase &&
- test -z "$(git ls-files -u)"
+ (
+ cd dst &&
+ git pull --rebase &&
+ git ls-files -u >untracked &&
+ test_must_be_empty untracked
)
'
test_expect_success 'setup for avoiding reapplying old patches' '
- (cd dst &&
- test_might_fail git rebase --abort &&
- git reset --hard origin/master
+ (
+ cd dst &&
+ test_might_fail git rebase --abort &&
+ git reset --hard origin/master
) &&
git clone --bare src src-replace.git &&
rm -rf src &&
mv src-replace.git src &&
- (cd dst &&
- modify s/2/22/ stuff &&
- git commit -a -m "Change 2" &&
- modify s/3/33/ stuff &&
- git commit -a -m "Change 3" &&
- modify s/4/44/ stuff &&
- git commit -a -m "Change 4" &&
- git push &&
-
- modify s/44/55/ stuff &&
- git commit --amend -a -m "Modified Change 4"
+ (
+ cd dst &&
+ modify s/2/22/ stuff &&
+ git commit -a -m "Change 2" &&
+ modify s/3/33/ stuff &&
+ git commit -a -m "Change 3" &&
+ modify s/4/44/ stuff &&
+ git commit -a -m "Change 4" &&
+ git push &&
+
+ modify s/44/55/ stuff &&
+ git commit --amend -a -m "Modified Change 4"
)
'
test_expect_success 'git pull --rebase does not reapply old patches' '
- (cd dst &&
- test_must_fail git pull --rebase &&
- test 1 = $(find .git/rebase-apply -name "000*" | wc -l)
+ (
+ cd dst &&
+ test_must_fail git pull --rebase &&
+ find .git/rebase-apply -name "000*" >patches &&
+ test_line_count = 1 patches
)
'
test_expect_success 'git pull --rebase against local branch' '
git checkout -b copy2 to-rebase-orig &&
git pull --rebase . to-rebase &&
- test "conflicting modification" = "$(cat file)" &&
- test file = "$(cat file2)"
+ echo "conflicting modification" >expect &&
+ test_cmp expect file &&
+ echo file >expect &&
+ test_cmp expect file2
'
test_done
diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh
index 44309566f1..4d1e0c363e 100755
--- a/t/t5528-push-default.sh
+++ b/t/t5528-push-default.sh
@@ -163,7 +163,7 @@ test_pushdefault_workflow success current master
# update parent1's foo (which is our upstream)
test_pushdefault_workflow success upstream foo
-# upsream is foo which is not the name of the current branch
+# upstream is foo which is not the name of the current branch
test_pushdefault_workflow failure simple master
# master and foo are updated
diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh
index a1d3031d40..4ce9a9f704 100755
--- a/t/t5530-upload-pack-error.sh
+++ b/t/t5530-upload-pack-error.sh
@@ -14,7 +14,7 @@ corrupt_repo () {
}
test_expect_success 'setup and corrupt repository' '
-
+ test_oid_init &&
echo file >file &&
git add file &&
git rev-parse :file &&
@@ -31,9 +31,10 @@ test_expect_success 'fsck fails' '
'
test_expect_success 'upload-pack fails due to error in pack-objects packing' '
-
- printf "0032want %s\n00000009done\n0000" \
- $(git rev-parse HEAD) >input &&
+ head=$(git rev-parse HEAD) &&
+ hexsz=$(test_oid hexsz) &&
+ printf "%04xwant %s\n00000009done\n0000" \
+ $(($hexsz + 10)) $head >input &&
test_must_fail git upload-pack . <input >/dev/null 2>output.err &&
test_i18ngrep "unable to read" output.err &&
test_i18ngrep "pack-objects died" output.err
@@ -51,16 +52,17 @@ test_expect_success 'fsck fails' '
'
test_expect_success 'upload-pack fails due to error in rev-list' '
- printf "0032want %s\n0034shallow %s00000009done\n0000" \
- $(git rev-parse HEAD) $(git rev-parse HEAD^) >input &&
+ printf "%04xwant %s\n%04xshallow %s00000009done\n0000" \
+ $(($hexsz + 10)) $(git rev-parse HEAD) \
+ $(($hexsz + 12)) $(git rev-parse HEAD^) >input &&
test_must_fail git upload-pack . <input >/dev/null 2>output.err &&
grep "bad tree object" output.err
'
test_expect_success 'upload-pack fails due to bad want (no object)' '
- printf "0045want %s multi_ack_detailed\n00000009done\n0000" \
- "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" >input &&
+ printf "%04xwant %s multi_ack_detailed\n00000009done\n0000" \
+ $(($hexsz + 29)) $(test_oid deadbeef) >input &&
test_must_fail git upload-pack . <input >output 2>output.err &&
grep "not our ref" output.err &&
grep "ERR" output &&
@@ -70,8 +72,8 @@ test_expect_success 'upload-pack fails due to bad want (no object)' '
test_expect_success 'upload-pack fails due to bad want (not tip)' '
oid=$(echo an object we have | git hash-object -w --stdin) &&
- printf "0045want %s multi_ack_detailed\n00000009done\n0000" \
- "$oid" >input &&
+ printf "%04xwant %s multi_ack_detailed\n00000009done\n0000" \
+ $(($hexsz + 29)) "$oid" >input &&
test_must_fail git upload-pack . <input >output 2>output.err &&
grep "not our ref" output.err &&
grep "ERR" output &&
@@ -80,8 +82,8 @@ test_expect_success 'upload-pack fails due to bad want (not tip)' '
test_expect_success 'upload-pack fails due to error in pack-objects enumeration' '
- printf "0032want %s\n00000009done\n0000" \
- $(git rev-parse HEAD) >input &&
+ printf "%04xwant %s\n00000009done\n0000" \
+ $((hexsz + 10)) $(git rev-parse HEAD) >input &&
test_must_fail git upload-pack . <input >/dev/null 2>output.err &&
grep "bad tree object" output.err &&
grep "pack-objects died" output.err
diff --git a/t/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh
index 8ed58d27f2..e8f6d233ff 100755
--- a/t/t5535-fetch-push-symref.sh
+++ b/t/t5535-fetch-push-symref.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='avoiding conflicting update thru symref aliasing'
+test_description='avoiding conflicting update through symref aliasing'
. ./test-lib.sh
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 66f0b64d39..9e16512fe3 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -15,7 +15,11 @@ test_expect_success 'setup' '
commit 2 &&
commit 3 &&
commit 4 &&
- git config --global transfer.fsckObjects true
+ git config --global transfer.fsckObjects true &&
+ test_oid_cache <<-EOF
+ sed sha1:s/0034shallow %s/0036unshallow %s/
+ sed sha256:s/004cshallow %s/004eunshallow %s/
+ EOF
'
test_expect_success 'setup shallow clone' '
@@ -239,7 +243,7 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
# with an empty packfile. This is done by refetching with a shorter
# depth (to ensure that the packfile is empty), and overwriting the
# shallow line in the response with the unshallow line we want.
- printf "s/0034shallow %s/0036unshallow %s/" \
+ printf "$(test_oid sed)" \
"$(git -C "$REPO" rev-parse HEAD)" \
"$(git -C "$REPO" rev-parse HEAD^)" \
>"$HTTPD_ROOT_PATH/one-time-sed" &&
@@ -255,4 +259,7 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
git -C client fsck
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh
index b4ad81f006..c0d02dee89 100755
--- a/t/t5539-fetch-http-shallow.sh
+++ b/t/t5539-fetch-http-shallow.sh
@@ -69,7 +69,7 @@ test_expect_success 'no shallow lines after receiving ACK ready' '
test_commit new-too &&
# NEEDSWORK: If the overspecification of the expected result is reduced, we
# might be able to run this test in all protocol versions.
- GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" GIT_TEST_PROTOCOL_VERSION= \
+ GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" GIT_TEST_PROTOCOL_VERSION=0 \
git fetch --depth=2 &&
grep "fetch-pack< ACK .* ready" ../trace &&
! grep "fetch-pack> done" ../trace
diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index a094fd5e71..d476c33509 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -134,15 +134,13 @@ 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"
+xtrunc=$(echo $OID_REGEX | sed -e "s/\[0-9a-f\]\[0-9a-f\]//")
test_expect_success 'PUT and MOVE sends object to URLs with SHA-1 hash suffix' '
sed \
-e "s/PUT /OP /" \
-e "s/MOVE /OP /" \
- -e "s|/objects/$x2/${x38}_$x40|WANTED_PATH_REQUEST|" \
+ -e "s|/objects/$x2/${xtrunc}_$OID_REGEX|WANTED_PATH_REQUEST|" \
"$HTTPD_ROOT_PATH"/access.log |
grep -e "\"OP .*WANTED_PATH_REQUEST HTTP/[.0-9]*\" 20[0-9] "
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index b86ddb60f2..23be8ce92d 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -49,7 +49,7 @@ test_expect_success 'no empty path components' '
# NEEDSWORK: If the overspecification of the expected result is reduced, we
# might be able to run this test in all protocol versions.
- if test -z "$GIT_TEST_PROTOCOL_VERSION"
+ if test "$GIT_TEST_PROTOCOL_VERSION" = 0
then
check_access_log exp
fi
@@ -135,7 +135,7 @@ EOF
test_expect_success 'used receive-pack service' '
# NEEDSWORK: If the overspecification of the expected result is reduced, we
# might be able to run this test in all protocol versions.
- if test -z "$GIT_TEST_PROTOCOL_VERSION"
+ if test "$GIT_TEST_PROTOCOL_VERSION" = 0
then
check_access_log exp
fi
@@ -184,11 +184,12 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
test_config -C "$d" http.receivepack true &&
up="$HTTPD_URL"/smart/atomic-branches.git &&
- # Tell "$up" about two branches for now
+ # Tell "$up" about three branches for now
test_commit atomic1 &&
test_commit atomic2 &&
git branch collateral &&
- git push "$up" master collateral &&
+ git branch other &&
+ git push "$up" master collateral other &&
# collateral is a valid push, but should be failed by atomic push
git checkout collateral &&
@@ -226,6 +227,41 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output
'
+test_expect_success 'push --atomic fails on server-side errors' '
+ # Use previously set up repository
+ d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
+ test_config -C "$d" http.receivepack true &&
+ up="$HTTPD_URL"/smart/atomic-branches.git &&
+
+ # break ref updates for other on the remote site
+ mkdir "$d/refs/heads/other.lock" &&
+
+ # add the new commit to other
+ git branch -f other collateral &&
+
+ # --atomic should cause entire push to be rejected
+ test_must_fail git push --atomic "$up" atomic other 2>output &&
+
+ # the new branch should not have been created upstream
+ test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
+
+ # upstream should still reflect atomic2, the last thing we pushed
+ # successfully
+ git rev-parse atomic2 >expected &&
+ # ...to other.
+ git -C "$d" rev-parse refs/heads/other >actual &&
+ test_cmp expected actual &&
+
+ # the new branch should not have been created upstream
+ test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
+
+ # the failed refs should be indicated to the user
+ grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output &&
+
+ # the collateral failure refs should be indicated to the user
+ grep "^ ! .*rejected.* atomic -> atomic .*atomic transaction failed" output
+'
+
test_expect_success 'push --all can push to empty repo' '
d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
git init --bare "$d" &&
@@ -262,7 +298,7 @@ test_expect_success TTY 'push shows progress when stderr is a tty' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit noisy &&
test_terminal git push >output 2>&1 &&
- test_i18ngrep "Writing objects" output
+ test_i18ngrep "^Writing objects" output
'
test_expect_success TTY 'push --quiet silences status and progress' '
@@ -277,7 +313,7 @@ test_expect_success TTY 'push --no-progress silences progress but not status' '
test_commit no-progress &&
test_terminal git push --no-progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
- test_i18ngrep ! "Writing objects" output
+ test_i18ngrep ! "^Writing objects" output
'
test_expect_success 'push --progress shows progress to non-tty' '
@@ -285,7 +321,7 @@ test_expect_success 'push --progress shows progress to non-tty' '
test_commit progress &&
git push --progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
- test_i18ngrep "Writing objects" output
+ test_i18ngrep "^Writing objects" output
'
test_expect_success 'http push gives sane defaults to reflog' '
diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh
index 6d1d59c9b1..38e6f7340e 100755
--- a/t/t5545-push-options.sh
+++ b/t/t5545-push-options.sh
@@ -115,7 +115,7 @@ test_expect_success 'push options and submodules' '
git -C parent submodule add ../upstream workbench &&
git -C parent/workbench remote add up ../../upstream &&
- git -C parent commit -m "add submoule" &&
+ git -C parent commit -m "add submodule" &&
test_commit -C parent/workbench two &&
git -C parent add workbench &&
@@ -278,4 +278,7 @@ test_expect_success 'push options keep quoted characters intact (http)' '
test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git/hooks/pre-receive.push_options
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
index e38e543867..6788aeface 100755
--- a/t/t5551-http-fetch-smart.sh
+++ b/t/t5551-http-fetch-smart.sh
@@ -43,7 +43,7 @@ test_expect_success 'clone http repository' '
< Cache-Control: no-cache, max-age=0, must-revalidate
< Content-Type: application/x-git-upload-pack-result
EOF
- GIT_TRACE_CURL=true GIT_TEST_PROTOCOL_VERSION= \
+ GIT_TRACE_CURL=true GIT_TEST_PROTOCOL_VERSION=0 \
git clone --quiet $HTTPD_URL/smart/repo.git clone 2>err &&
test_cmp file clone/file &&
tr '\''\015'\'' Q <err |
@@ -84,7 +84,7 @@ test_expect_success 'clone http repository' '
# NEEDSWORK: If the overspecification of the expected result is reduced, we
# might be able to run this test in all protocol versions.
- if test -z "$GIT_TEST_PROTOCOL_VERSION"
+ if test "$GIT_TEST_PROTOCOL_VERSION" = 0
then
sed -e "s/^> Accept-Encoding: .*/> Accept-Encoding: ENCODINGS/" \
actual >actual.smudged &&
@@ -113,7 +113,7 @@ test_expect_success 'used upload-pack service' '
# NEEDSWORK: If the overspecification of the expected result is reduced, we
# might be able to run this test in all protocol versions.
- if test -z "$GIT_TEST_PROTOCOL_VERSION"
+ if test "$GIT_TEST_PROTOCOL_VERSION" = 0
then
check_access_log exp
fi
@@ -241,7 +241,7 @@ test_expect_success 'cookies stored in http.cookiefile when http.savecookies set
# NEEDSWORK: If the overspecification of the expected result is reduced, we
# might be able to run this test in all protocol versions.
- if test -z "$GIT_TEST_PROTOCOL_VERSION"
+ if test "$GIT_TEST_PROTOCOL_VERSION" = 0
then
tail -3 cookies.txt | sort >cookies_tail.txt &&
test_cmp expect_cookies.txt cookies_tail.txt
@@ -336,7 +336,7 @@ test_expect_success 'test allowreachablesha1inwant with unreachable' '
git -C test_reachable.git remote add origin "$HTTPD_URL/smart/repo.git" &&
# Some protocol versions (e.g. 2) support fetching
# unadvertised objects, so restrict this test to v0.
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git -C test_reachable.git fetch origin "$(git rev-parse HEAD)"
'
@@ -358,7 +358,7 @@ test_expect_success 'test allowanysha1inwant with unreachable' '
git -C test_reachable.git remote add origin "$HTTPD_URL/smart/repo.git" &&
# Some protocol versions (e.g. 2) support fetching
# unadvertised objects, so restrict this test to v0.
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git -C test_reachable.git fetch origin "$(git rev-parse HEAD)" &&
git -C "$server" config uploadpack.allowanysha1inwant 1 &&
diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh
index 8a14be51a1..156c704040 100755
--- a/t/t5552-skipping-fetch-negotiator.sh
+++ b/t/t5552-skipping-fetch-negotiator.sh
@@ -60,29 +60,6 @@ test_expect_success 'commits with no parents are sent regardless of skip distanc
have_not_sent c6 c4 c3
'
-test_expect_success 'unknown fetch.negotiationAlgorithm values error out' '
- rm -rf server client trace &&
- git init server &&
- test_commit -C server to_fetch &&
-
- git init client &&
- test_commit -C client on_client &&
- git -C client checkout on_client &&
-
- test_config -C client fetch.negotiationAlgorithm invalid &&
- test_must_fail git -C client fetch "$(pwd)/server" 2>err &&
- test_i18ngrep "unknown fetch negotiation algorithm" err &&
-
- # Explicit "default" value
- test_config -C client fetch.negotiationAlgorithm default &&
- git -C client -c fetch.negotiationAlgorithm=default fetch "$(pwd)/server" &&
-
- # Implementation detail: If there is nothing to fetch, we will not error out
- test_config -C client fetch.negotiationAlgorithm invalid &&
- git -C client fetch "$(pwd)/server" 2>err &&
- test_i18ngrep ! "unknown fetch negotiation algorithm" err
-'
-
test_expect_success 'when two skips collide, favor the larger one' '
rm -rf server client trace &&
git init server &&
@@ -130,7 +107,11 @@ test_expect_success 'use ref advertisement to filter out commits' '
# The ref advertisement itself is filtered when protocol v2 is used, so
# use v0.
- GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch &&
+ (
+ GIT_TEST_PROTOCOL_VERSION=0 &&
+ export GIT_TEST_PROTOCOL_VERSION &&
+ trace_fetch client origin to_fetch
+ ) &&
have_sent c5 c4^ c2side &&
have_not_sent c4 c4^^ c4^^^
'
@@ -192,7 +173,17 @@ test_expect_success 'do not send "have" with ancestors of commits that server AC
test_commit -C server commit-on-b1 &&
test_config -C client fetch.negotiationalgorithm skipping &&
- trace_fetch client "$(pwd)/server" to_fetch &&
+
+ # NEEDSWORK: The number of "have"s sent depends on whether the transport
+ # is stateful. If the overspecification of the result were reduced, this
+ # test could be used for both stateful and stateless transports.
+ (
+ # Force protocol v0, in which local transport is stateful (in
+ # protocol v2 it is stateless).
+ GIT_TEST_PROTOCOL_VERSION=0 &&
+ export GIT_TEST_PROTOCOL_VERSION &&
+ trace_fetch client "$(pwd)/server" to_fetch
+ ) &&
grep " fetch" trace &&
# fetch-pack sends 2 requests each containing 16 "have" lines before
diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh
new file mode 100755
index 0000000000..81975ad8f9
--- /dev/null
+++ b/t/t5553-set-upstream.sh
@@ -0,0 +1,178 @@
+#!/bin/sh
+
+test_description='"git fetch/pull --set-upstream" basic tests.'
+. ./test-lib.sh
+
+check_config () {
+ printf "%s\n" "$2" "$3" >"expect.$1" &&
+ {
+ git config "branch.$1.remote" && git config "branch.$1.merge"
+ } >"actual.$1" &&
+ test_cmp "expect.$1" "actual.$1"
+}
+
+check_config_missing () {
+ test_expect_code 1 git config "branch.$1.remote" &&
+ test_expect_code 1 git config "branch.$1.merge"
+}
+
+clear_config () {
+ for branch in "$@"; do
+ test_might_fail git config --unset-all "branch.$branch.remote"
+ test_might_fail git config --unset-all "branch.$branch.merge"
+ done
+}
+
+ensure_fresh_upstream () {
+ rm -rf parent && git init --bare parent
+}
+
+test_expect_success 'setup bare parent fetch' '
+ ensure_fresh_upstream &&
+ git remote add upstream parent
+'
+
+test_expect_success 'setup commit on master and other fetch' '
+ test_commit one &&
+ git push upstream master &&
+ git checkout -b other &&
+ test_commit two &&
+ git push upstream other
+'
+
+# tests for fetch --set-upstream
+
+test_expect_success 'fetch --set-upstream does not set upstream w/o branch' '
+ clear_config master other &&
+ git checkout master &&
+ git fetch --set-upstream upstream &&
+ check_config_missing master &&
+ check_config_missing other
+'
+
+test_expect_success 'fetch --set-upstream upstream master sets branch master but not other' '
+ clear_config master other &&
+ git fetch --set-upstream upstream master &&
+ check_config master upstream refs/heads/master &&
+ check_config_missing other
+'
+
+test_expect_success 'fetch --set-upstream upstream other sets branch other' '
+ clear_config master other &&
+ git fetch --set-upstream upstream other &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other
+'
+
+test_expect_success 'fetch --set-upstream master:other does not set the branch other2' '
+ clear_config other2 &&
+ git fetch --set-upstream upstream master:other2 &&
+ check_config_missing other2
+'
+
+test_expect_success 'fetch --set-upstream http://nosuchdomain.example.com fails with invalid url' '
+ # master explicitly not cleared, we check that it is not touched from previous value
+ clear_config other other2 &&
+ test_must_fail git fetch --set-upstream http://nosuchdomain.example.com &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+test_expect_success 'fetch --set-upstream with valid URL sets upstream to URL' '
+ clear_config other other2 &&
+ url="file://'"$PWD"'" &&
+ git fetch --set-upstream "$url" &&
+ check_config master "$url" HEAD &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+# tests for pull --set-upstream
+
+test_expect_success 'setup bare parent pull' '
+ git remote rm upstream &&
+ ensure_fresh_upstream &&
+ git remote add upstream parent
+'
+
+test_expect_success 'setup commit on master and other pull' '
+ test_commit three &&
+ git push --tags upstream master &&
+ test_commit four &&
+ git push upstream other
+'
+
+test_expect_success 'pull --set-upstream upstream master sets branch master but not other' '
+ clear_config master other &&
+ git pull --set-upstream upstream master &&
+ check_config master upstream refs/heads/master &&
+ check_config_missing other
+'
+
+test_expect_success 'pull --set-upstream master:other2 does not set the branch other2' '
+ clear_config other2 &&
+ git pull --set-upstream upstream master:other2 &&
+ check_config_missing other2
+'
+
+test_expect_success 'pull --set-upstream upstream other sets branch master' '
+ clear_config master other &&
+ git pull --set-upstream upstream other &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other
+'
+
+test_expect_success 'pull --set-upstream upstream tag does not set the tag' '
+ clear_config three &&
+ git pull --tags --set-upstream upstream three &&
+ check_config_missing three
+'
+
+test_expect_success 'pull --set-upstream http://nosuchdomain.example.com fails with invalid url' '
+ # master explicitly not cleared, we check that it is not touched from previous value
+ clear_config other other2 three &&
+ test_must_fail git pull --set-upstream http://nosuchdomain.example.com &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other &&
+ check_config_missing other2 &&
+ check_config_missing three
+'
+
+test_expect_success 'pull --set-upstream upstream HEAD sets branch HEAD' '
+ clear_config master other &&
+ git pull --set-upstream upstream HEAD &&
+ check_config master upstream HEAD &&
+ git checkout other &&
+ git pull --set-upstream upstream HEAD &&
+ check_config other upstream HEAD
+'
+
+test_expect_success 'pull --set-upstream upstream with more than one branch does nothing' '
+ clear_config master three &&
+ git pull --set-upstream upstream master three &&
+ check_config_missing master &&
+ check_config_missing three
+'
+
+test_expect_success 'pull --set-upstream with valid URL sets upstream to URL' '
+ clear_config master other other2 &&
+ git checkout master &&
+ url="file://'"$PWD"'" &&
+ git pull --set-upstream "$url" &&
+ check_config master "$url" HEAD &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+test_expect_success 'pull --set-upstream with valid URL and branch sets branch' '
+ clear_config master other other2 &&
+ git checkout master &&
+ url="file://'"$PWD"'" &&
+ git pull --set-upstream "$url" master &&
+ check_config master "$url" refs/heads/master &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+test_done
diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh
index f0f425b2cf..4a110b307e 100755
--- a/t/t5562-http-backend-content-length.sh
+++ b/t/t5562-http-backend-content-length.sh
@@ -59,7 +59,7 @@ test_expect_success 'setup' '
printf done | packetize >>fetch_body &&
test_copy_bytes 10 <fetch_body >fetch_body.trunc &&
hash_next=$(git commit-tree -p HEAD -m next HEAD^{tree}) &&
- printf "%s %s refs/heads/newbranch\\0report-status\\n" "$_z40" "$hash_next" | packetize >push_body &&
+ printf "%s %s refs/heads/newbranch\\0report-status\\n" "$ZERO_OID" "$hash_next" | packetize >push_body &&
printf 0000 >>push_body &&
echo "$hash_next" | git pack-objects --stdout >>push_body &&
test_copy_bytes 10 <push_body >push_body.trunc &&
diff --git a/t/t5573-pull-verify-signatures.sh b/t/t5573-pull-verify-signatures.sh
index 3e9876e197..a53dd8550d 100755
--- a/t/t5573-pull-verify-signatures.sh
+++ b/t/t5573-pull-verify-signatures.sh
@@ -60,6 +60,27 @@ test_expect_success GPG 'pull commit with untrusted signature with --verify-sign
test_i18ngrep "has an untrusted GPG signature" pullerror
'
+test_expect_success GPG 'pull commit with untrusted signature with --verify-signatures and minTrustLevel=ultimate' '
+ test_when_finished "git reset --hard && git checkout initial" &&
+ test_config gpg.minTrustLevel ultimate &&
+ test_must_fail git pull --ff-only --verify-signatures untrusted 2>pullerror &&
+ test_i18ngrep "has an untrusted GPG signature" pullerror
+'
+
+test_expect_success GPG 'pull commit with untrusted signature with --verify-signatures and minTrustLevel=marginal' '
+ test_when_finished "git reset --hard && git checkout initial" &&
+ test_config gpg.minTrustLevel marginal &&
+ test_must_fail git pull --ff-only --verify-signatures untrusted 2>pullerror &&
+ test_i18ngrep "has an untrusted GPG signature" pullerror
+'
+
+test_expect_success GPG 'pull commit with untrusted signature with --verify-signatures and minTrustLevel=undefined' '
+ test_when_finished "git reset --hard && git checkout initial" &&
+ test_config gpg.minTrustLevel undefined &&
+ git pull --ff-only --verify-signatures untrusted >pulloutput &&
+ test_i18ngrep "has a good GPG signature" pulloutput
+'
+
test_expect_success GPG 'pull signed commit with --verify-signatures' '
test_when_finished "git reset --hard && git checkout initial" &&
git pull --verify-signatures signed >pulloutput &&
@@ -79,10 +100,53 @@ test_expect_success GPG 'pull commit with bad signature with --no-verify-signatu
'
test_expect_success GPG 'pull unsigned commit into unborn branch' '
+ test_when_finished "rm -rf empty-repo" &&
git init empty-repo &&
test_must_fail \
git -C empty-repo pull --verify-signatures .. 2>pullerror &&
test_i18ngrep "does not have a GPG signature" pullerror
'
+test_expect_success GPG 'pull commit into unborn branch with bad signature and --verify-signatures' '
+ test_when_finished "rm -rf empty-repo" &&
+ git init empty-repo &&
+ test_must_fail \
+ git -C empty-repo pull --ff-only --verify-signatures ../bad 2>pullerror &&
+ test_i18ngrep "has a bad GPG signature" pullerror
+'
+
+test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures' '
+ test_when_finished "rm -rf empty-repo" &&
+ git init empty-repo &&
+ test_must_fail \
+ git -C empty-repo pull --ff-only --verify-signatures ../untrusted 2>pullerror &&
+ test_i18ngrep "has an untrusted GPG signature" pullerror
+'
+
+test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures and minTrustLevel=ultimate' '
+ test_when_finished "rm -rf empty-repo" &&
+ git init empty-repo &&
+ test_config_global gpg.minTrustLevel ultimate &&
+ test_must_fail \
+ git -C empty-repo pull --ff-only --verify-signatures ../untrusted 2>pullerror &&
+ test_i18ngrep "has an untrusted GPG signature" pullerror
+'
+
+test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures and minTrustLevel=marginal' '
+ test_when_finished "rm -rf empty-repo" &&
+ git init empty-repo &&
+ test_config_global gpg.minTrustLevel marginal &&
+ test_must_fail \
+ git -C empty-repo pull --ff-only --verify-signatures ../untrusted 2>pullerror &&
+ test_i18ngrep "has an untrusted GPG signature" pullerror
+'
+
+test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures and minTrustLevel=undefined' '
+ test_when_finished "rm -rf empty-repo" &&
+ git init empty-repo &&
+ test_config_global gpg.minTrustLevel undefined &&
+ git -C empty-repo pull --ff-only --verify-signatures ../untrusted >pulloutput &&
+ test_i18ngrep "has a good GPG signature" pulloutput
+'
+
test_done
diff --git a/t/t5580-clone-push-unc.sh b/t/t5580-clone-push-unc.sh
index b3c8a92450..01b52c195a 100755
--- a/t/t5580-clone-push-unc.sh
+++ b/t/t5580-clone-push-unc.sh
@@ -58,7 +58,7 @@ test_expect_success push '
test_expect_success MINGW 'remote nick cannot contain backslashes' '
BACKSLASHED="$(winpwd | tr / \\\\)" &&
- git ls-remote "$BACKSLASHED" >out 2>err &&
+ git ls-remote "$BACKSLASHED" 2>err &&
test_i18ngrep ! "unable to access" err
'
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 37d76808d4..84ea2a3eb7 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -434,7 +434,6 @@ test_expect_success 'double quoted plink.exe in GIT_SSH_COMMAND' '
expect_ssh "-v -P 123" myhost src
'
-SQ="'"
test_expect_success 'single quoted plink.exe in GIT_SSH_COMMAND' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
GIT_SSH_COMMAND="$SQ$TRASH_DIRECTORY/plink.exe$SQ -v" \
@@ -636,10 +635,10 @@ partial_clone_server () {
rm -rf "$SERVER" client &&
test_create_repo "$SERVER" &&
test_commit -C "$SERVER" one &&
- HASH1=$(git hash-object "$SERVER/one.t") &&
+ HASH1=$(git -C "$SERVER" hash-object one.t) &&
git -C "$SERVER" revert HEAD &&
test_commit -C "$SERVER" two &&
- HASH2=$(git hash-object "$SERVER/two.t") &&
+ HASH2=$(git -C "$SERVER" hash-object two.t) &&
test_config -C "$SERVER" uploadpack.allowfilter 1 &&
test_config -C "$SERVER" uploadpack.allowanysha1inwant 1
}
@@ -654,7 +653,8 @@ partial_clone () {
git -C client fsck &&
# Ensure that unneeded blobs are not inadvertently fetched.
- test_config -C client extensions.partialclone "not a remote" &&
+ test_config -C client remote.origin.promisor "false" &&
+ git -C client config --unset remote.origin.partialclonefilter &&
test_must_fail git -C client cat-file -e "$HASH1" &&
# But this blob was fetched, because clone performs an initial checkout
@@ -739,4 +739,7 @@ test_expect_success 'partial clone using HTTP' '
partial_clone "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh
index 4894237ab8..0c74b4e21a 100755
--- a/t/t5604-clone-reference.sh
+++ b/t/t5604-clone-reference.sh
@@ -326,15 +326,16 @@ test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at obje
for raw in $(ls T*.raw)
do
sed -e "s!/../!/Y/!; s![0-9a-f]\{38,\}!Z!" -e "/commit-graph/d" \
- -e "/multi-pack-index/d" <$raw >$raw.de-sha || return 1
+ -e "/multi-pack-index/d" <$raw >$raw.de-sha-1 &&
+ sort $raw.de-sha-1 >$raw.de-sha || return 1
done &&
cat >expected-files <<-EOF &&
./Y/Z
./Y/Z
+ ./Y/Z
./a-loose-dir/Z
./an-object
- ./Y/Z
./info/packs
./pack/pack-Z.idx
./pack/pack-Z.pack
diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh
index 2a0fb15cf1..b7a3fdf02d 100755
--- a/t/t5607-clone-bundle.sh
+++ b/t/t5607-clone-bundle.sh
@@ -83,4 +83,15 @@ test_expect_success 'failed bundle creation does not leave cruft' '
test_path_is_missing fail.bundle.lock
'
+test_expect_success 'fetch SHA-1 from bundle' '
+ test_create_repo foo &&
+ test_commit -C foo x &&
+ git -C foo bundle create tip.bundle -1 master &&
+ git -C foo rev-parse HEAD >hash &&
+
+ # Exercise to ensure that fetching a SHA-1 from a bundle works with no
+ # errors
+ git fetch --no-tags foo/tip.bundle "$(cat hash)"
+'
+
test_done
diff --git a/t/t5608-clone-2gb.sh b/t/t5608-clone-2gb.sh
index 2c6bc07344..eee0842888 100755
--- a/t/t5608-clone-2gb.sh
+++ b/t/t5608-clone-2gb.sh
@@ -3,7 +3,7 @@
test_description='Test cloning a repository larger than 2 gigabyte'
. ./test-lib.sh
-if test -z "$GIT_TEST_CLONE_2GB"
+if ! test_bool_env GIT_TEST_CLONE_2GB false
then
say 'Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t'
else
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index b91ef548f8..9a9178fd28 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -42,8 +42,16 @@ test_expect_success 'do partial clone 1' '
test_cmp expect_1.oids observed.oids &&
test "$(git -C pc1 config --local core.repositoryformatversion)" = "1" &&
- test "$(git -C pc1 config --local extensions.partialclone)" = "origin" &&
- test "$(git -C pc1 config --local core.partialclonefilter)" = "blob:none"
+ test "$(git -C pc1 config --local remote.origin.promisor)" = "true" &&
+ test "$(git -C pc1 config --local remote.origin.partialclonefilter)" = "blob:none"
+'
+
+test_expect_success 'verify that .promisor file contains refs fetched' '
+ ls pc1/.git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 1 promisorlist &&
+ git -C srv.bare rev-list HEAD >headhash &&
+ grep "$(cat headhash) HEAD" $(cat promisorlist) &&
+ grep "$(cat headhash) refs/heads/master" $(cat promisorlist)
'
# checkout master to force dynamic object fetch of blobs at HEAD.
@@ -208,6 +216,25 @@ test_expect_success 'use fsck before and after manually fetching a missing subtr
test_cmp unique_types.expected unique_types.observed
'
+test_expect_success 'implicitly construct combine: filter with repeated flags' '
+ GIT_TRACE=$(pwd)/trace git clone --bare \
+ --filter=blob:none --filter=tree:1 \
+ "file://$(pwd)/srv.bare" pc2 &&
+ grep "trace:.* git pack-objects .*--filter=combine:blob:none+tree:1" \
+ trace &&
+ git -C pc2 rev-list --objects --missing=allow-any HEAD >objects &&
+
+ # We should have gotten some root trees.
+ grep " $" objects &&
+ # Should not have gotten any non-root trees or blobs.
+ ! grep " ." objects &&
+
+ xargs -n 1 git -C pc2 cat-file -t <objects >types &&
+ sort -u types >unique_types.actual &&
+ test_write_lines commit tree >unique_types.expected &&
+ test_cmp unique_types.expected unique_types.actual
+'
+
test_expect_success 'partial clone fetches blobs pointed to by refs even if normally filtered out' '
rm -rf src dst &&
git init src &&
@@ -241,6 +268,122 @@ test_expect_success 'fetch what is specified on CLI even if already promised' '
! grep "?$(cat blob)" missing_after
'
+test_expect_success 'setup src repo for sparse filter' '
+ git init sparse-src &&
+ git -C sparse-src config --local uploadpack.allowfilter 1 &&
+ git -C sparse-src config --local uploadpack.allowanysha1inwant 1 &&
+ test_commit -C sparse-src one &&
+ test_commit -C sparse-src two &&
+ echo /one.t >sparse-src/only-one &&
+ git -C sparse-src add . &&
+ git -C sparse-src commit -m "add sparse checkout files"
+'
+
+test_expect_success 'partial clone with sparse filter succeeds' '
+ rm -rf dst.git &&
+ git clone --no-local --bare \
+ --filter=sparse:oid=master:only-one \
+ sparse-src dst.git &&
+ (
+ cd dst.git &&
+ git rev-list --objects --missing=print HEAD >out &&
+ grep "^$(git rev-parse HEAD:one.t)" out &&
+ grep "^?$(git rev-parse HEAD:two.t)" out
+ )
+'
+
+test_expect_success 'partial clone with unresolvable sparse filter fails cleanly' '
+ rm -rf dst.git &&
+ test_must_fail git clone --no-local --bare \
+ --filter=sparse:oid=master:no-such-name \
+ sparse-src dst.git 2>err &&
+ test_i18ngrep "unable to access sparse blob in .master:no-such-name" err &&
+ test_must_fail git clone --no-local --bare \
+ --filter=sparse:oid=master \
+ sparse-src dst.git 2>err &&
+ test_i18ngrep "unable to parse sparse filter data in" err
+'
+
+setup_triangle () {
+ rm -rf big-blob.txt server client promisor-remote &&
+
+ printf "line %d\n" $(test_seq 1 100) >big-blob.txt &&
+
+ # Create a server with 2 commits: a commit with a big tree and a child
+ # commit with an incremental change. Also, create a partial clone
+ # client that only contains the first commit.
+ git init server &&
+ git -C server config --local uploadpack.allowfilter 1 &&
+ for i in $(test_seq 1 100)
+ do
+ echo "make the tree big" >server/file$i &&
+ git -C server add file$i
+ done &&
+ git -C server commit -m "initial" &&
+ git clone --bare --filter=tree:0 "file://$(pwd)/server" client &&
+ echo another line >>server/file1 &&
+ git -C server commit -am "incremental change" &&
+
+ # Create a promisor remote that only contains the tree and blob from
+ # the first commit.
+ git init promisor-remote &&
+ git -C server config --local uploadpack.allowanysha1inwant 1 &&
+ TREE_HASH=$(git -C server rev-parse HEAD~1^{tree}) &&
+ git -C promisor-remote fetch --keep "file://$(pwd)/server" "$TREE_HASH" &&
+ git -C promisor-remote count-objects -v >object-count &&
+ test_i18ngrep "count: 0" object-count &&
+ test_i18ngrep "in-pack: 2" object-count &&
+
+ # Set it as the promisor remote of client. Thus, whenever
+ # the client lazy fetches, the lazy fetch will succeed only if it is
+ # for this tree or blob.
+ test_commit -C promisor-remote one && # so that ref advertisement is not empty
+ git -C promisor-remote config --local uploadpack.allowanysha1inwant 1 &&
+ git -C client remote set-url origin "file://$(pwd)/promisor-remote"
+}
+
+# NEEDSWORK: The tests beginning with "fetch lazy-fetches" below only
+# test that "fetch" avoid fetching trees and blobs, but not commits or
+# tags. Revisit this if Git is ever taught to support partial clones
+# with commits and/or tags filtered out.
+
+test_expect_success 'fetch lazy-fetches only to resolve deltas' '
+ setup_triangle &&
+
+ # Exercise to make sure it works. Git will not fetch anything from the
+ # promisor remote other than for the big tree (because it needs to
+ # resolve the delta).
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client \
+ fetch "file://$(pwd)/server" master &&
+
+ # Verify the assumption that the client needed to fetch the delta base
+ # to resolve the delta.
+ git -C server rev-parse HEAD~1^{tree} >hash &&
+ grep "want $(cat hash)" trace
+'
+
+test_expect_success 'fetch lazy-fetches only to resolve deltas, protocol v2' '
+ setup_triangle &&
+
+ git -C server config --local protocol.version 2 &&
+ git -C client config --local protocol.version 2 &&
+ git -C promisor-remote config --local protocol.version 2 &&
+
+ # Exercise to make sure it works. Git will not fetch anything from the
+ # promisor remote other than for the big blob (because it needs to
+ # resolve the delta).
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client \
+ fetch "file://$(pwd)/server" master &&
+
+ # Verify that protocol version 2 was used.
+ grep "fetch< version 2" trace &&
+
+ # Verify the assumption that the client needed to fetch the delta base
+ # to resolve the delta.
+ git -C server rev-parse HEAD~1^{tree} >hash &&
+ grep "want $(cat hash)" trace
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@@ -417,4 +560,7 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
! test -e "$HTTPD_ROOT_PATH/one-time-sed"
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5700-protocol-v1.sh b/t/t5700-protocol-v1.sh
index 7c9511c593..022901b9eb 100755
--- a/t/t5700-protocol-v1.sh
+++ b/t/t5700-protocol-v1.sh
@@ -5,7 +5,8 @@ test_description='test git wire-protocol transition'
TEST_NO_CREATE_REPO=1
# This is a protocol-specific test.
-GIT_TEST_PROTOCOL_VERSION=
+GIT_TEST_PROTOCOL_VERSION=0
+export GIT_TEST_PROTOCOL_VERSION
. ./test-lib.sh
@@ -292,4 +293,7 @@ test_expect_success 'push with http:// using protocol v1' '
grep "git< version 1" log
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 011b81d4fc..7fd7102c87 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -32,7 +32,7 @@ test_expect_success 'list refs with git:// using protocol v2' '
test_cmp expect actual
'
-test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' '
+test_expect_success 'ref advertisement is filtered with ls-remote using protocol v2' '
test_when_finished "rm -f log" &&
GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
@@ -154,7 +154,7 @@ test_expect_success 'list refs with file:// using protocol v2' '
test_cmp expect actual
'
-test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' '
+test_expect_success 'ref advertisement is filtered with ls-remote using protocol v2' '
test_when_finished "rm -f log" &&
GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
@@ -225,7 +225,7 @@ test_expect_success 'fetch with file:// using protocol v2' '
grep "fetch< version 2" log
'
-test_expect_success 'ref advertisment is filtered during fetch using protocol v2' '
+test_expect_success 'ref advertisement is filtered during fetch using protocol v2' '
test_when_finished "rm -f log" &&
test_commit -C file_parent three &&
@@ -631,6 +631,19 @@ test_expect_success 'fetch with http:// using protocol v2' '
grep "git< version 2" log
'
+test_expect_success 'fetch with http:// by hash without tag following with protocol v2 does not list refs' '
+ test_when_finished "rm -f log" &&
+
+ test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two_a &&
+ git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" rev-parse two_a >two_a_hash &&
+
+ GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \
+ fetch --no-tags origin $(cat two_a_hash) &&
+
+ grep "fetch< version 2" log &&
+ ! grep "fetch> command=ls-refs" log
+'
+
test_expect_success 'fetch from namespaced repo respects namespaces' '
test_when_finished "rm -f log" &&
@@ -652,6 +665,18 @@ test_expect_success 'fetch from namespaced repo respects namespaces' '
test_cmp expect actual
'
+test_expect_success 'ls-remote with v2 http sends only one POST' '
+ test_when_finished "rm -f log" &&
+
+ git ls-remote "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" >expect &&
+ GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \
+ ls-remote "$HTTPD_URL/smart/http_parent" >actual &&
+ test_cmp expect actual &&
+
+ grep "Send header: POST" log >posts &&
+ test_line_count = 1 posts
+'
+
test_expect_success 'push with http:// and a config of v2 does not request v2' '
test_when_finished "rm -f log" &&
# Till v2 for push is designed, make sure that if a client has
@@ -669,9 +694,9 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect &&
test_cmp expect actual &&
- # Client didnt request to use protocol v2
+ # Client did not request to use protocol v2
! grep "Git-Protocol: version=2" log &&
- # Server didnt respond using protocol v2
+ # Server did not respond using protocol v2
! grep "git< version 2" log
'
@@ -723,4 +748,7 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
test_i18ngrep "expected no other sections to be sent after no .ready." err
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index de4b6106ef..1424fabd4a 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -18,14 +18,16 @@ get_actual_commits () {
p
}' <out | test-tool pkt-line unpack-sideband >o.pack &&
git index-pack o.pack &&
- git verify-pack -v o.idx | grep commit | cut -c-40 | sort >actual_commits
+ git verify-pack -v o.idx >objs &&
+ grep commit objs | cut -c-40 | sort >actual_commits
}
check_output () {
get_actual_refs &&
test_cmp expected_refs actual_refs &&
get_actual_commits &&
- test_cmp expected_commits actual_commits
+ sort expected_commits >sorted_commits &&
+ test_cmp sorted_commits actual_commits
}
# c(o/foo) d(o/bar)
@@ -75,17 +77,19 @@ test_expect_success 'invalid want-ref line' '
'
test_expect_success 'basic want-ref' '
+ oid=$(git rev-parse f) &&
cat >expected_refs <<-EOF &&
- $(git rev-parse f) refs/heads/master
+ $oid refs/heads/master
EOF
- git rev-parse f | sort >expected_commits &&
+ git rev-parse f >expected_commits &&
+ oid=$(git rev-parse a) &&
test-tool pkt-line pack >in <<-EOF &&
command=fetch
0001
no-progress
want-ref refs/heads/master
- have $(git rev-parse a)
+ have $oid
done
0000
EOF
@@ -95,19 +99,22 @@ test_expect_success 'basic want-ref' '
'
test_expect_success 'multiple want-ref lines' '
+ oid_c=$(git rev-parse c) &&
+ oid_d=$(git rev-parse d) &&
cat >expected_refs <<-EOF &&
- $(git rev-parse c) refs/heads/o/foo
- $(git rev-parse d) refs/heads/o/bar
+ $oid_c refs/heads/o/foo
+ $oid_d refs/heads/o/bar
EOF
- git rev-parse c d | sort >expected_commits &&
+ git rev-parse c d >expected_commits &&
+ oid=$(git rev-parse b) &&
test-tool pkt-line pack >in <<-EOF &&
command=fetch
0001
no-progress
want-ref refs/heads/o/foo
want-ref refs/heads/o/bar
- have $(git rev-parse b)
+ have $oid
done
0000
EOF
@@ -117,10 +124,11 @@ test_expect_success 'multiple want-ref lines' '
'
test_expect_success 'mix want and want-ref' '
+ oid=$(git rev-parse f) &&
cat >expected_refs <<-EOF &&
- $(git rev-parse f) refs/heads/master
+ $oid refs/heads/master
EOF
- git rev-parse e f | sort >expected_commits &&
+ git rev-parse e f >expected_commits &&
test-tool pkt-line pack >in <<-EOF &&
command=fetch
@@ -138,17 +146,19 @@ test_expect_success 'mix want and want-ref' '
'
test_expect_success 'want-ref with ref we already have commit for' '
+ oid=$(git rev-parse c) &&
cat >expected_refs <<-EOF &&
- $(git rev-parse c) refs/heads/o/foo
+ $oid refs/heads/o/foo
EOF
>expected_commits &&
+ oid=$(git rev-parse c) &&
test-tool pkt-line pack >in <<-EOF &&
command=fetch
0001
no-progress
want-ref refs/heads/o/foo
- have $(git rev-parse c)
+ have $oid
done
0000
EOF
@@ -157,106 +167,6 @@ test_expect_success 'want-ref with ref we already have commit for' '
check_output
'
-. "$TEST_DIRECTORY"/lib-httpd.sh
-start_httpd
-
-REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
-LOCAL_PRISTINE="$(pwd)/local_pristine"
-
-test_expect_success 'setup repos for change-while-negotiating test' '
- (
- git init "$REPO" &&
- cd "$REPO" &&
- >.git/git-daemon-export-ok &&
- test_commit m1 &&
- git tag -d m1 &&
-
- # Local repo with many commits (so that negotiation will take
- # more than 1 request/response pair)
- git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
- cd "$LOCAL_PRISTINE" &&
- git checkout -b side &&
- test_commit_bulk --id=s 33 &&
-
- # Add novel commits to upstream
- git checkout master &&
- cd "$REPO" &&
- test_commit m2 &&
- test_commit m3 &&
- git tag -d m2 m3
- ) &&
- git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo" &&
- git -C "$LOCAL_PRISTINE" config protocol.version 2
-'
-
-inconsistency () {
- # Simulate that the server initially reports $2 as the ref
- # corresponding to $1, and after that, $1 as the ref corresponding to
- # $1. This corresponds to the real-life situation where the server's
- # repository appears to change during negotiation, for example, when
- # different servers in a load-balancing arrangement serve (stateless)
- # RPCs during a single negotiation.
- printf "s/%s/%s/" \
- $(git -C "$REPO" rev-parse $1 | tr -d "\n") \
- $(git -C "$REPO" rev-parse $2 | tr -d "\n") \
- >"$HTTPD_ROOT_PATH/one-time-sed"
-}
-
-test_expect_success 'server is initially ahead - no ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant false &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master 1234567890123456789012345678901234567890 &&
- test_must_fail git -C local fetch 2>err &&
- test_i18ngrep "fatal: remote error: upload-pack: not our ref" err
-'
-
-test_expect_success 'server is initially ahead - ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant true &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master 1234567890123456789012345678901234567890 &&
- git -C local fetch &&
-
- git -C "$REPO" rev-parse --verify master >expected &&
- git -C local rev-parse --verify refs/remotes/origin/master >actual &&
- test_cmp expected actual
-'
-
-test_expect_success 'server is initially behind - no ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant false &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master "master^" &&
- git -C local fetch &&
-
- git -C "$REPO" rev-parse --verify "master^" >expected &&
- git -C local rev-parse --verify refs/remotes/origin/master >actual &&
- test_cmp expected actual
-'
-
-test_expect_success 'server is initially behind - ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant true &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master "master^" &&
- git -C local fetch &&
-
- git -C "$REPO" rev-parse --verify "master" >expected &&
- git -C local rev-parse --verify refs/remotes/origin/master >actual &&
- test_cmp expected actual
-'
-
-test_expect_success 'server loses a ref - ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant true &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" &&
- test_must_fail git -C local fetch 2>err &&
-
- test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
-'
-
REPO="$(pwd)/repo"
LOCAL_PRISTINE="$(pwd)/local_pristine"
@@ -311,13 +221,14 @@ test_expect_success 'fetching with exact OID' '
rm -rf local &&
cp -r "$LOCAL_PRISTINE" local &&
+ oid=$(git -C "$REPO" rev-parse d) &&
GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \
- $(git -C "$REPO" rev-parse d):refs/heads/actual &&
+ "$oid":refs/heads/actual &&
git -C "$REPO" rev-parse "d" >expected &&
git -C local rev-parse refs/heads/actual >actual &&
test_cmp expected actual &&
- grep "want $(git -C "$REPO" rev-parse d)" log
+ grep "want $oid" log
'
test_expect_success 'fetching multiple refs' '
@@ -339,13 +250,14 @@ test_expect_success 'fetching ref and exact OID' '
rm -rf local &&
cp -r "$LOCAL_PRISTINE" local &&
+ oid=$(git -C "$REPO" rev-parse b) &&
GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \
- master $(git -C "$REPO" rev-parse b):refs/heads/actual &&
+ master "$oid":refs/heads/actual &&
git -C "$REPO" rev-parse "master" "b" >expected &&
git -C local rev-parse refs/remotes/origin/master refs/heads/actual >actual &&
test_cmp expected actual &&
- grep "want $(git -C "$REPO" rev-parse b)" log &&
+ grep "want $oid" log &&
grep "want-ref refs/heads/master" log
'
@@ -372,4 +284,107 @@ test_expect_success 'fetching with wildcard that matches multiple refs' '
grep "want-ref refs/heads/o/bar" log
'
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
+LOCAL_PRISTINE="$(pwd)/local_pristine"
+
+test_expect_success 'setup repos for change-while-negotiating test' '
+ (
+ git init "$REPO" &&
+ cd "$REPO" &&
+ >.git/git-daemon-export-ok &&
+ test_commit m1 &&
+ git tag -d m1 &&
+
+ # Local repo with many commits (so that negotiation will take
+ # more than 1 request/response pair)
+ rm -rf "$LOCAL_PRISTINE" &&
+ git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
+ cd "$LOCAL_PRISTINE" &&
+ git checkout -b side &&
+ test_commit_bulk --id=s 33 &&
+
+ # Add novel commits to upstream
+ git checkout master &&
+ cd "$REPO" &&
+ test_commit m2 &&
+ test_commit m3 &&
+ git tag -d m2 m3
+ ) &&
+ git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo" &&
+ git -C "$LOCAL_PRISTINE" config protocol.version 2
+'
+
+inconsistency () {
+ # Simulate that the server initially reports $2 as the ref
+ # corresponding to $1, and after that, $1 as the ref corresponding to
+ # $1. This corresponds to the real-life situation where the server's
+ # repository appears to change during negotiation, for example, when
+ # different servers in a load-balancing arrangement serve (stateless)
+ # RPCs during a single negotiation.
+ oid1=$(git -C "$REPO" rev-parse $1) &&
+ oid2=$(git -C "$REPO" rev-parse $2) &&
+ echo "s/$oid1/$oid2/" >"$HTTPD_ROOT_PATH/one-time-sed"
+}
+
+test_expect_success 'server is initially ahead - no ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant false &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master 1234567890123456789012345678901234567890 &&
+ test_must_fail git -C local fetch 2>err &&
+ test_i18ngrep "fatal: remote error: upload-pack: not our ref" err
+'
+
+test_expect_success 'server is initially ahead - ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant true &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master 1234567890123456789012345678901234567890 &&
+ git -C local fetch &&
+
+ git -C "$REPO" rev-parse --verify master >expected &&
+ git -C local rev-parse --verify refs/remotes/origin/master >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'server is initially behind - no ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant false &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master "master^" &&
+ git -C local fetch &&
+
+ git -C "$REPO" rev-parse --verify "master^" >expected &&
+ git -C local rev-parse --verify refs/remotes/origin/master >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'server is initially behind - ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant true &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master "master^" &&
+ git -C local fetch &&
+
+ git -C "$REPO" rev-parse --verify "master" >expected &&
+ git -C local rev-parse --verify refs/remotes/origin/master >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'server loses a ref - ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant true &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" &&
+ test_must_fail git -C local fetch 2>err &&
+
+ test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
+'
+
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 2d6c4a281e..121e5c6edb 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -247,7 +247,6 @@ clean_mark () {
test_expect_success 'proper failure checks for fetching' '
(cd local &&
test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git fetch 2>error &&
- cat error &&
test_i18ngrep -q "error while running fast-import" error
)
'
diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh
index 52a9e38d66..b8cf82349b 100755
--- a/t/t6000-rev-list-misc.sh
+++ b/t/t6000-rev-list-misc.sh
@@ -140,4 +140,12 @@ test_expect_success '--header shows a NUL after each commit' '
test_cmp expect actual
'
+test_expect_success 'rev-list --end-of-options' '
+ git update-ref refs/heads/--output=yikes HEAD &&
+ git rev-list --end-of-options --output=yikes >actual &&
+ test_path_is_missing yikes &&
+ git rev-list HEAD >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index da113d975b..ebdc49c496 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -109,31 +109,35 @@ commit $head1
EOF
# we don't test relative here
-test_format author %an%n%ae%n%ad%n%aD%n%at <<EOF
+test_format author %an%n%ae%n%al%n%ad%n%aD%n%at <<EOF
commit $head2
-A U Thor
-author@example.com
+$GIT_AUTHOR_NAME
+$GIT_AUTHOR_EMAIL
+$TEST_AUTHOR_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
commit $head1
-A U Thor
-author@example.com
+$GIT_AUTHOR_NAME
+$GIT_AUTHOR_EMAIL
+$TEST_AUTHOR_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
EOF
-test_format committer %cn%n%ce%n%cd%n%cD%n%ct <<EOF
+test_format committer %cn%n%ce%n%cl%n%cd%n%cD%n%ct <<EOF
commit $head2
-C O Mitter
-committer@example.com
+$GIT_COMMITTER_NAME
+$GIT_COMMITTER_EMAIL
+$TEST_COMMITTER_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
commit $head1
-C O Mitter
-committer@example.com
+$GIT_COMMITTER_NAME
+$GIT_COMMITTER_EMAIL
+$TEST_COMMITTER_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
@@ -410,7 +414,7 @@ test_expect_success 'empty email' '
test_tick &&
C=$(GIT_AUTHOR_EMAIL= git commit-tree HEAD^{tree} </dev/null) &&
A=$(git show --pretty=format:%an,%ae,%ad%n -s $C) &&
- verbose test "$A" = "A U Thor,,Thu Apr 7 15:14:13 2005 -0700"
+ verbose test "$A" = "$GIT_AUTHOR_NAME,,Thu Apr 7 15:14:13 2005 -0700"
'
test_expect_success 'del LF before empty (1)' '
@@ -495,15 +499,14 @@ test_expect_success '%gd shortens ref name' '
'
test_expect_success 'reflog identity' '
- echo "C O Mitter:committer@example.com" >expect &&
+ echo "$GIT_COMMITTER_NAME:$GIT_COMMITTER_EMAIL" >expect &&
git log -g -1 --format="%gn:%ge" >actual &&
test_cmp expect actual
'
test_expect_success 'oneline with empty message' '
- git commit -m "dummy" --allow-empty &&
- git commit -m "dummy" --allow-empty &&
- git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. &&
+ git commit --allow-empty --cleanup=verbatim -m "$LF" &&
+ git commit --allow-empty --allow-empty-message &&
git rev-list --oneline HEAD >test.txt &&
test_line_count = 5 test.txt &&
git rev-list --oneline --graph HEAD >testg.txt &&
diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh
index 545b461e51..bad02cf5b8 100755
--- a/t/t6011-rev-list-with-bad-commit.sh
+++ b/t/t6011-rev-list-with-bad-commit.sh
@@ -42,7 +42,7 @@ test_expect_success 'corrupt second commit object' \
'
test_expect_success 'rev-list should fail' '
- test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git rev-list --all > /dev/null
+ test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git -c core.commitGraph=false rev-list --all > /dev/null
'
test_expect_success 'git repack _MUST_ fail' \
diff --git a/t/t6016-rev-list-graph-simplify-history.sh b/t/t6016-rev-list-graph-simplify-history.sh
index f7181d1d6a..f5e6e92f5b 100755
--- a/t/t6016-rev-list-graph-simplify-history.sh
+++ b/t/t6016-rev-list-graph-simplify-history.sh
@@ -67,11 +67,10 @@ test_expect_success '--graph --all' '
echo "| * $C4" >> expected &&
echo "| * $C3" >> expected &&
echo "* | $A5" >> expected &&
- echo "| | " >> expected &&
- echo "| \\ " >> expected &&
- echo "*-. \\ $A4" >> expected &&
- echo "|\\ \\ \\ " >> expected &&
- echo "| | |/ " >> expected &&
+ echo "| | " >> expected &&
+ echo "| \\ " >> expected &&
+ echo "*-. | $A4" >> expected &&
+ echo "|\\ \\| " >> expected &&
echo "| | * $C2" >> expected &&
echo "| | * $C1" >> expected &&
echo "| * | $B2" >> expected &&
@@ -97,11 +96,10 @@ test_expect_success '--graph --simplify-by-decoration' '
echo "| * $C4" >> expected &&
echo "| * $C3" >> expected &&
echo "* | $A5" >> expected &&
- echo "| | " >> expected &&
- echo "| \\ " >> expected &&
- echo "*-. \\ $A4" >> expected &&
- echo "|\\ \\ \\ " >> expected &&
- echo "| | |/ " >> expected &&
+ echo "| | " >> expected &&
+ echo "| \\ " >> expected &&
+ echo "*-. | $A4" >> expected &&
+ echo "|\\ \\| " >> expected &&
echo "| | * $C2" >> expected &&
echo "| | * $C1" >> expected &&
echo "| * | $B2" >> expected &&
@@ -131,9 +129,8 @@ test_expect_success '--graph --simplify-by-decoration prune branch B' '
echo "| * $C4" >> expected &&
echo "| * $C3" >> expected &&
echo "* | $A5" >> expected &&
- echo "* | $A4" >> expected &&
- echo "|\\ \\ " >> expected &&
- echo "| |/ " >> expected &&
+ echo "* | $A4" >> expected &&
+ echo "|\\| " >> expected &&
echo "| * $C2" >> expected &&
echo "| * $C1" >> expected &&
echo "* | $A3" >> expected &&
@@ -151,9 +148,8 @@ test_expect_success '--graph --full-history -- bar.txt' '
echo "|\\ " >> expected &&
echo "| * $C4" >> expected &&
echo "* | $A5" >> expected &&
- echo "* | $A4" >> expected &&
- echo "|\\ \\ " >> expected &&
- echo "| |/ " >> expected &&
+ echo "* | $A4" >> expected &&
+ echo "|\\| " >> expected &&
echo "* | $A3" >> expected &&
echo "|/ " >> expected &&
echo "* $A2" >> expected &&
@@ -255,7 +251,7 @@ test_expect_success '--graph --boundary ^C3' '
echo "* | | | $A3" >> expected &&
echo "o | | | $A2" >> expected &&
echo "|/ / / " >> expected &&
- echo "o | | $A1" >> expected &&
+ echo "o / / $A1" >> expected &&
echo " / / " >> expected &&
echo "| o $C3" >> expected &&
echo "|/ " >> expected &&
diff --git a/t/t6019-rev-list-ancestry-path.sh b/t/t6019-rev-list-ancestry-path.sh
index beadaf6cca..353f84313f 100755
--- a/t/t6019-rev-list-ancestry-path.sh
+++ b/t/t6019-rev-list-ancestry-path.sh
@@ -143,14 +143,14 @@ test_expect_success 'setup criss-cross' '
test_expect_success 'criss-cross: rev-list --ancestry-path cb..bc' '
(cd criss-cross &&
git rev-list --ancestry-path xcb..xbc > actual &&
- test -z "$(cat actual)")
+ test_must_be_empty actual)
'
# no commits in repository descend from cb
test_expect_success 'criss-cross: rev-list --ancestry-path --all ^cb' '
(cd criss-cross &&
git rev-list --ancestry-path --all ^xcb > actual &&
- test -z "$(cat actual)")
+ test_must_be_empty actual)
'
test_done
diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh
index 213deecab1..d254e020b6 100755
--- a/t/t6021-merge-criss-cross.sh
+++ b/t/t6021-merge-criss-cross.sh
@@ -3,7 +3,7 @@
# Copyright (c) 2005 Fredrik Kuivinen
#
-# See http://marc.info/?l=git&m=111463358500362&w=2 for a
+# See https://lore.kernel.org/git/Pine.LNX.4.44.0504271254120.4678-100000@wax.eds.org/ for a
# nice description of what this is about.
diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh
index 27c7de90ce..0c9e3c20e8 100755
--- a/t/t6024-recursive-merge.sh
+++ b/t/t6024-recursive-merge.sh
@@ -14,85 +14,90 @@ test_description='Test merge without common ancestors'
GIT_COMMITTER_DATE="2006-12-12 23:28:00 +0100"
export GIT_COMMITTER_DATE
-test_expect_success "setup tests" '
-echo 1 > a1 &&
-git add a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:00" git commit -m 1 a1 &&
-
-git checkout -b A master &&
-echo A > a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:01" git commit -m A a1 &&
-
-git checkout -b B master &&
-echo B > a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:02" git commit -m B a1 &&
-
-git checkout -b D A &&
-git rev-parse B > .git/MERGE_HEAD &&
-echo D > a1 &&
-git update-index a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:03" git commit -m D &&
-
-git symbolic-ref HEAD refs/heads/other &&
-echo 2 > a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:04" git commit -m 2 a1 &&
-
-git checkout -b C &&
-echo C > a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:05" git commit -m C a1 &&
-
-git checkout -b E C &&
-git rev-parse B > .git/MERGE_HEAD &&
-echo E > a1 &&
-git update-index a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:06" git commit -m E &&
-
-git checkout -b G E &&
-git rev-parse A > .git/MERGE_HEAD &&
-echo G > a1 &&
-git update-index a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:07" git commit -m G &&
-
-git checkout -b F D &&
-git rev-parse C > .git/MERGE_HEAD &&
-echo F > a1 &&
-git update-index a1 &&
-GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F
+test_expect_success 'setup tests' '
+ echo 1 >a1 &&
+ git add a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:00" git commit -m 1 a1 &&
+
+ git checkout -b A master &&
+ echo A >a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:01" git commit -m A a1 &&
+
+ git checkout -b B master &&
+ echo B >a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:02" git commit -m B a1 &&
+
+ git checkout -b D A &&
+ git rev-parse B >.git/MERGE_HEAD &&
+ echo D >a1 &&
+ git update-index a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:03" git commit -m D &&
+
+ git symbolic-ref HEAD refs/heads/other &&
+ echo 2 >a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:04" git commit -m 2 a1 &&
+
+ git checkout -b C &&
+ echo C >a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:05" git commit -m C a1 &&
+
+ git checkout -b E C &&
+ git rev-parse B >.git/MERGE_HEAD &&
+ echo E >a1 &&
+ git update-index a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:06" git commit -m E &&
+
+ git checkout -b G E &&
+ git rev-parse A >.git/MERGE_HEAD &&
+ echo G >a1 &&
+ git update-index a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:07" git commit -m G &&
+
+ git checkout -b F D &&
+ git rev-parse C >.git/MERGE_HEAD &&
+ echo F >a1 &&
+ git update-index a1 &&
+ GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F
'
test_expect_success 'combined merge conflicts' '
test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git merge -m final G
'
-cat > expect << EOF
-<<<<<<< HEAD
-F
-=======
-G
->>>>>>> G
-EOF
+test_expect_success 'result contains a conflict' '
+ cat >expect <<-\EOF &&
+ <<<<<<< HEAD
+ F
+ =======
+ G
+ >>>>>>> G
+ EOF
-test_expect_success "result contains a conflict" "test_cmp expect a1"
+ test_cmp expect a1
+'
+
+test_expect_success 'virtual trees were processed' '
+ git ls-files --stage >out &&
-git ls-files --stage > out
-cat > expect << EOF
-100644 ec3fe2a791706733f2d8fa7ad45d9a9672031f5e 1 a1
-100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1
-100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1
-EOF
+ cat >expect <<-\EOF &&
+ 100644 ec3fe2a791706733f2d8fa7ad45d9a9672031f5e 1 a1
+ 100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1
+ 100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1
+ EOF
-test_expect_success "virtual trees were processed" "test_cmp expect out"
+ test_cmp expect out
+'
test_expect_success 'refuse to merge binary files' '
git reset --hard &&
- printf "\0" > binary-file &&
+ printf "\0" >binary-file &&
git add binary-file &&
git commit -m binary &&
git checkout G &&
- printf "\0\0" > binary-file &&
+ printf "\0\0" >binary-file &&
git add binary-file &&
git commit -m binary2 &&
- test_must_fail git merge F > merge.out 2> merge.err &&
+ test_must_fail git merge F >merge.out 2>merge.err &&
grep "Cannot merge binary files: binary-file (HEAD vs. F)" merge.err
'
@@ -116,7 +121,6 @@ test_expect_success 'mark rename/delete as unmerged' '
test 1 = $(git ls-files --unmerged | wc -l) &&
test_must_fail git rev-parse --verify :2:a2 &&
git rev-parse --verify :3:a2
-
'
test_done
diff --git a/t/t6025-merge-symlinks.sh b/t/t6025-merge-symlinks.sh
index 433c4de08f..6c0a90d044 100755
--- a/t/t6025-merge-symlinks.sh
+++ b/t/t6025-merge-symlinks.sh
@@ -10,52 +10,53 @@ if core.symlinks is false.'
. ./test-lib.sh
-test_expect_success \
-'setup' '
-git config core.symlinks false &&
-> file &&
-git add file &&
-git commit -m initial &&
-git branch b-symlink &&
-git branch b-file &&
-l=$(printf file | git hash-object -t blob -w --stdin) &&
-echo "120000 $l symlink" | git update-index --index-info &&
-git commit -m master &&
-git checkout b-symlink &&
-l=$(printf file-different | git hash-object -t blob -w --stdin) &&
-echo "120000 $l symlink" | git update-index --index-info &&
-git commit -m b-symlink &&
-git checkout b-file &&
-echo plain-file > symlink &&
-git add symlink &&
-git commit -m b-file'
-
-test_expect_success \
-'merge master into b-symlink, which has a different symbolic link' '
-git checkout b-symlink &&
-test_must_fail git merge master'
-
-test_expect_success \
-'the merge result must be a file' '
-test -f symlink'
-
-test_expect_success \
-'merge master into b-file, which has a file instead of a symbolic link' '
-git reset --hard && git checkout b-file &&
-test_must_fail git merge master'
-
-test_expect_success \
-'the merge result must be a file' '
-test -f symlink'
-
-test_expect_success \
-'merge b-file, which has a file instead of a symbolic link, into master' '
-git reset --hard &&
-git checkout master &&
-test_must_fail git merge b-file'
-
-test_expect_success \
-'the merge result must be a file' '
-test -f symlink'
+test_expect_success 'setup' '
+ git config core.symlinks false &&
+ >file &&
+ git add file &&
+ git commit -m initial &&
+ git branch b-symlink &&
+ git branch b-file &&
+ l=$(printf file | git hash-object -t blob -w --stdin) &&
+ echo "120000 $l symlink" | git update-index --index-info &&
+ git commit -m master &&
+ git checkout b-symlink &&
+ l=$(printf file-different | git hash-object -t blob -w --stdin) &&
+ echo "120000 $l symlink" | git update-index --index-info &&
+ git commit -m b-symlink &&
+ git checkout b-file &&
+ echo plain-file >symlink &&
+ git add symlink &&
+ git commit -m b-file
+'
+
+test_expect_success 'merge master into b-symlink, which has a different symbolic link' '
+ git checkout b-symlink &&
+ test_must_fail git merge master
+'
+
+test_expect_success 'the merge result must be a file' '
+ test_path_is_file symlink
+'
+
+test_expect_success 'merge master into b-file, which has a file instead of a symbolic link' '
+ git reset --hard &&
+ git checkout b-file &&
+ test_must_fail git merge master
+'
+
+test_expect_success 'the merge result must be a file' '
+ test_path_is_file symlink
+'
+
+test_expect_success 'merge b-file, which has a file instead of a symbolic link, into master' '
+ git reset --hard &&
+ git checkout master &&
+ test_must_fail git merge b-file
+'
+
+test_expect_success 'the merge result must be a file' '
+ test_path_is_file symlink
+'
test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index bdc42e9440..821a0c88cf 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -482,7 +482,7 @@ test_expect_success 'optimized merge base checks' '
git bisect good > my_bisect_log2.txt &&
test -f ".git/BISECT_ANCESTORS_OK" &&
test "$HASH6" = $(git rev-parse --verify HEAD) &&
- git bisect bad > my_bisect_log3.txt &&
+ git bisect bad &&
git bisect good "$A_HASH" > my_bisect_log4.txt &&
test_i18ngrep "merge base must be tested" my_bisect_log4.txt &&
test_must_fail test -f ".git/BISECT_ANCESTORS_OK"
diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh
index d23b948f27..7d73afdcda 100755
--- a/t/t6036-recursive-corner-cases.sh
+++ b/t/t6036-recursive-corner-cases.sh
@@ -1532,7 +1532,7 @@ test_expect_success 'setup nested conflicts' '
mv -f b_R1 b &&
mv -f a_R1 a &&
git add b a &&
- test_tick && git commit -m "verson R1 of files" &&
+ test_tick && git commit -m "version R1 of files" &&
git tag R1 &&
# Create first merge on left side
@@ -1562,6 +1562,7 @@ test_expect_success 'check nested conflicts' '
cd nested_conflicts &&
git clean -f &&
+ MASTER=$(git rev-parse --short master) &&
git checkout L2^0 &&
# Merge must fail; there is a conflict
@@ -1582,7 +1583,7 @@ test_expect_success 'check nested conflicts' '
git cat-file -p R1:a >theirs &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
- -L "merged common ancestors" \
+ -L "$MASTER" \
-L "Temporary merge branch 2" \
ours \
base \
@@ -1594,7 +1595,7 @@ test_expect_success 'check nested conflicts' '
git cat-file -p R1:b >theirs &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
- -L "merged common ancestors" \
+ -L "$MASTER" \
-L "Temporary merge branch 2" \
ours \
base \
@@ -1695,7 +1696,7 @@ test_expect_success 'setup virtual merge base with nested conflicts' '
git checkout R &&
echo right >>content &&
git add content &&
- test_tick && git commit -m "verson R1 of content" &&
+ test_tick && git commit -m "version R1 of content" &&
git tag R1 &&
# Create L2
@@ -1732,6 +1733,7 @@ test_expect_success 'check virtual merge base with nested conflicts' '
(
cd virtual_merge_base_has_nested_conflicts &&
+ MASTER=$(git rev-parse --short master) &&
git checkout L3^0 &&
# Merge must fail; there is a conflict
@@ -1760,7 +1762,7 @@ test_expect_success 'check virtual merge base with nested conflicts' '
cp left merged-once &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
- -L "merged common ancestors" \
+ -L "$MASTER" \
-L "Temporary merge branch 2" \
merged-once \
base \
diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh
index c5b57f40c3..b047cf1c1c 100755
--- a/t/t6042-merge-rename-corner-cases.sh
+++ b/t/t6042-merge-rename-corner-cases.sh
@@ -5,7 +5,7 @@ test_description="recursive merge corner cases w/ renames but not criss-crosses"
. ./test-lib.sh
-test_expect_success 'setup rename/delete + untracked file' '
+test_setup_rename_delete_untracked () {
test_create_repo rename-delete-untracked &&
(
cd rename-delete-untracked &&
@@ -29,9 +29,10 @@ test_expect_success 'setup rename/delete + untracked file' '
git commit -m track-people-instead-of-objects &&
echo "Myyy PRECIOUSSS" >ring
)
-'
+}
test_expect_success "Does git preserve Gollum's precious artifact?" '
+ test_setup_rename_delete_untracked &&
(
cd rename-delete-untracked &&
@@ -49,7 +50,7 @@ test_expect_success "Does git preserve Gollum's precious artifact?" '
#
# We should be able to merge B & C cleanly
-test_expect_success 'setup rename/modify/add-source conflict' '
+test_setup_rename_modify_add_source () {
test_create_repo rename-modify-add-source &&
(
cd rename-modify-add-source &&
@@ -70,9 +71,10 @@ test_expect_success 'setup rename/modify/add-source conflict' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'rename/modify/add-source conflict resolvable' '
+ test_setup_rename_modify_add_source &&
(
cd rename-modify-add-source &&
@@ -88,7 +90,7 @@ test_expect_failure 'rename/modify/add-source conflict resolvable' '
)
'
-test_expect_success 'setup resolvable conflict missed if rename missed' '
+test_setup_break_detection_1 () {
test_create_repo break-detection-1 &&
(
cd break-detection-1 &&
@@ -110,9 +112,10 @@ test_expect_success 'setup resolvable conflict missed if rename missed' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'conflict caused if rename not detected' '
+ test_setup_break_detection_1 &&
(
cd break-detection-1 &&
@@ -135,7 +138,7 @@ test_expect_failure 'conflict caused if rename not detected' '
)
'
-test_expect_success 'setup conflict resolved wrong if rename missed' '
+test_setup_break_detection_2 () {
test_create_repo break-detection-2 &&
(
cd break-detection-2 &&
@@ -160,9 +163,10 @@ test_expect_success 'setup conflict resolved wrong if rename missed' '
git add a &&
git commit -m E
)
-'
+}
test_expect_failure 'missed conflict if rename not detected' '
+ test_setup_break_detection_2 &&
(
cd break-detection-2 &&
@@ -182,7 +186,7 @@ test_expect_failure 'missed conflict if rename not detected' '
# Commit B: rename a->b
# Commit C: rename a->b, add unrelated a
-test_expect_success 'setup undetected rename/add-source causes data loss' '
+test_setup_break_detection_3 () {
test_create_repo break-detection-3 &&
(
cd break-detection-3 &&
@@ -202,9 +206,10 @@ test_expect_success 'setup undetected rename/add-source causes data loss' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'detect rename/add-source and preserve all data' '
+ test_setup_break_detection_3 &&
(
cd break-detection-3 &&
@@ -231,6 +236,7 @@ test_expect_failure 'detect rename/add-source and preserve all data' '
'
test_expect_failure 'detect rename/add-source and preserve all data, merge other way' '
+ test_setup_break_detection_3 &&
(
cd break-detection-3 &&
@@ -256,10 +262,10 @@ test_expect_failure 'detect rename/add-source and preserve all data, merge other
)
'
-test_expect_success 'setup content merge + rename/directory conflict' '
- test_create_repo rename-directory-1 &&
+test_setup_rename_directory () {
+ test_create_repo rename-directory-$1 &&
(
- cd rename-directory-1 &&
+ cd rename-directory-$1 &&
printf "1\n2\n3\n4\n5\n6\n" >file &&
git add file &&
@@ -290,11 +296,12 @@ test_expect_success 'setup content merge + rename/directory conflict' '
test_tick &&
git commit -m left
)
-'
+}
test_expect_success 'rename/directory conflict + clean content merge' '
+ test_setup_rename_directory 1a &&
(
- cd rename-directory-1 &&
+ cd rename-directory-1a &&
git checkout left-clean^0 &&
@@ -320,8 +327,9 @@ test_expect_success 'rename/directory conflict + clean content merge' '
'
test_expect_success 'rename/directory conflict + content merge conflict' '
+ test_setup_rename_directory 1b &&
(
- cd rename-directory-1 &&
+ cd rename-directory-1b &&
git reset --hard &&
git clean -fdqx &&
@@ -358,7 +366,7 @@ test_expect_success 'rename/directory conflict + content merge conflict' '
)
'
-test_expect_success 'setup content merge + rename/directory conflict w/ disappearing dir' '
+test_setup_rename_directory_2 () {
test_create_repo rename-directory-2 &&
(
cd rename-directory-2 &&
@@ -385,9 +393,10 @@ test_expect_success 'setup content merge + rename/directory conflict w/ disappea
test_tick &&
git commit -m left
)
-'
+}
test_expect_success 'disappearing dir in rename/directory conflict handled' '
+ test_setup_rename_directory_2 &&
(
cd rename-directory-2 &&
@@ -416,10 +425,10 @@ test_expect_success 'disappearing dir in rename/directory conflict handled' '
# Commit A: rename a->b, modifying b too
# Commit B: modify a, add different b
-test_expect_success 'setup rename-with-content-merge vs. add' '
- test_create_repo rename-with-content-merge-and-add &&
+test_setup_rename_with_content_merge_and_add () {
+ test_create_repo rename-with-content-merge-and-add-$1 &&
(
- cd rename-with-content-merge-and-add &&
+ cd rename-with-content-merge-and-add-$1 &&
test_seq 1 5 >a &&
git add a &&
@@ -438,11 +447,12 @@ test_expect_success 'setup rename-with-content-merge vs. add' '
git add a b &&
git commit -m B
)
-'
+}
test_expect_success 'handle rename-with-content-merge vs. add' '
+ test_setup_rename_with_content_merge_and_add AB &&
(
- cd rename-with-content-merge-and-add &&
+ cd rename-with-content-merge-and-add-AB &&
git checkout A^0 &&
@@ -483,8 +493,9 @@ test_expect_success 'handle rename-with-content-merge vs. add' '
'
test_expect_success 'handle rename-with-content-merge vs. add, merge other way' '
+ test_setup_rename_with_content_merge_and_add BA &&
(
- cd rename-with-content-merge-and-add &&
+ cd rename-with-content-merge-and-add-BA &&
git reset --hard &&
git clean -fdx &&
@@ -539,7 +550,7 @@ test_expect_success 'handle rename-with-content-merge vs. add, merge other way'
# * The working copy should have two files, both of form c~<unique>; does it?
# * Nothing else should be present. Is anything?
-test_expect_success 'setup rename/rename (2to1) + modify/modify' '
+test_setup_rename_rename_2to1 () {
test_create_repo rename-rename-2to1 &&
(
cd rename-rename-2to1 &&
@@ -562,9 +573,10 @@ test_expect_success 'setup rename/rename (2to1) + modify/modify' '
git add a &&
git commit -m C
)
-'
+}
test_expect_success 'handle rename/rename (2to1) conflict correctly' '
+ test_setup_rename_rename_2to1 &&
(
cd rename-rename-2to1 &&
@@ -610,7 +622,7 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' '
# Commit A: new file: a
# Commit B: rename a->b
# Commit C: rename a->c
-test_expect_success 'setup simple rename/rename (1to2) conflict' '
+test_setup_rename_rename_1to2 () {
test_create_repo rename-rename-1to2 &&
(
cd rename-rename-1to2 &&
@@ -631,9 +643,10 @@ test_expect_success 'setup simple rename/rename (1to2) conflict' '
test_tick &&
git commit -m C
)
-'
+}
test_expect_success 'merge has correct working tree contents' '
+ test_setup_rename_rename_1to2 &&
(
cd rename-rename-1to2 &&
@@ -667,7 +680,7 @@ test_expect_success 'merge has correct working tree contents' '
#
# Merging of B & C should NOT be clean; there's a rename/rename conflict
-test_expect_success 'setup rename/rename(1to2)/add-source conflict' '
+test_setup_rename_rename_1to2_add_source_1 () {
test_create_repo rename-rename-1to2-add-source-1 &&
(
cd rename-rename-1to2-add-source-1 &&
@@ -687,9 +700,10 @@ test_expect_success 'setup rename/rename(1to2)/add-source conflict' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge' '
+ test_setup_rename_rename_1to2_add_source_1 &&
(
cd rename-rename-1to2-add-source-1 &&
@@ -714,7 +728,7 @@ test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge'
)
'
-test_expect_success 'setup rename/rename(1to2)/add-source resolvable conflict' '
+test_setup_rename_rename_1to2_add_source_2 () {
test_create_repo rename-rename-1to2-add-source-2 &&
(
cd rename-rename-1to2-add-source-2 &&
@@ -737,9 +751,10 @@ test_expect_success 'setup rename/rename(1to2)/add-source resolvable conflict' '
test_tick &&
git commit -m two
)
-'
+}
test_expect_failure 'rename/rename/add-source still tracks new a file' '
+ test_setup_rename_rename_1to2_add_source_2 &&
(
cd rename-rename-1to2-add-source-2 &&
@@ -759,7 +774,7 @@ test_expect_failure 'rename/rename/add-source still tracks new a file' '
)
'
-test_expect_success 'setup rename/rename(1to2)/add-dest conflict' '
+test_setup_rename_rename_1to2_add_dest () {
test_create_repo rename-rename-1to2-add-dest &&
(
cd rename-rename-1to2-add-dest &&
@@ -784,9 +799,10 @@ test_expect_success 'setup rename/rename(1to2)/add-dest conflict' '
test_tick &&
git commit -m two
)
-'
+}
test_expect_success 'rename/rename/add-dest merge still knows about conflicting file versions' '
+ test_setup_rename_rename_1to2_add_dest &&
(
cd rename-rename-1to2-add-dest &&
@@ -838,7 +854,7 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting
# Commit B: rename foo->bar
# Expected: CONFLICT (rename/add/delete), two-way merged bar
-test_expect_success 'rad-setup: rename/add/delete conflict' '
+test_setup_rad () {
test_create_repo rad &&
(
cd rad &&
@@ -860,9 +876,10 @@ test_expect_success 'rad-setup: rename/add/delete conflict' '
git mv foo bar &&
git commit -m "rename foo to bar"
)
-'
+}
test_expect_failure 'rad-check: rename/add/delete conflict' '
+ test_setup_rad &&
(
cd rad &&
@@ -904,7 +921,7 @@ test_expect_failure 'rad-check: rename/add/delete conflict' '
# Commit B: rename bar->baz, rm foo
# Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz
-test_expect_success 'rrdd-setup: rename/rename(2to1)/delete/delete conflict' '
+test_setup_rrdd () {
test_create_repo rrdd &&
(
cd rrdd &&
@@ -927,9 +944,10 @@ test_expect_success 'rrdd-setup: rename/rename(2to1)/delete/delete conflict' '
git rm foo &&
git commit -m "Rename bar, remove foo"
)
-'
+}
test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
+ test_setup_rrdd &&
(
cd rrdd &&
@@ -973,7 +991,7 @@ test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
# Expected: six CONFLICT(rename/rename) messages, each path in two of the
# multi-way merged contents found in two, four, six
-test_expect_success 'mod6-setup: chains of rename/rename(1to2) and rename/rename(2to1)' '
+test_setup_mod6 () {
test_create_repo mod6 &&
(
cd mod6 &&
@@ -1009,9 +1027,10 @@ test_expect_success 'mod6-setup: chains of rename/rename(1to2) and rename/rename
test_tick &&
git commit -m "B"
)
-'
+}
test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '
+ test_setup_mod6 &&
(
cd mod6 &&
@@ -1108,7 +1127,8 @@ test_conflicts_with_adds_and_renames() {
# files. Is it present?
# 4) There should not be any three~* files in the working
# tree
- test_expect_success "setup simple $sideL/$sideR conflict" '
+ test_setup_collision_conflict () {
+ #test_expect_success "setup simple $sideL/$sideR conflict" '
test_create_repo simple_${sideL}_${sideR} &&
(
cd simple_${sideL}_${sideR} &&
@@ -1185,9 +1205,11 @@ test_conflicts_with_adds_and_renames() {
fi &&
test_tick && git commit -m R
)
- '
+ #'
+ }
test_expect_success "check simple $sideL/$sideR conflict" '
+ test_setup_collision_conflict &&
(
cd simple_${sideL}_${sideR} &&
@@ -1254,7 +1276,7 @@ test_conflicts_with_adds_and_renames add add
#
# So, we have four different conflicting files that all end up at path
# 'three'.
-test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
+test_setup_nested_conflicts_from_rename_rename () {
test_create_repo nested_conflicts_from_rename_rename &&
(
cd nested_conflicts_from_rename_rename &&
@@ -1305,9 +1327,10 @@ test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
git add one three &&
test_tick && git commit -m german
)
-'
+}
test_expect_success 'check nested conflicts from rename/rename(2to1)' '
+ test_setup_nested_conflicts_from_rename_rename &&
(
cd nested_conflicts_from_rename_rename &&
diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh
index c966147d5d..83792c5ef1 100755
--- a/t/t6043-merge-rename-directories.sh
+++ b/t/t6043-merge-rename-directories.sh
@@ -38,7 +38,7 @@ test_description="recursive merge with directory renames"
# Commit B: z/{b,c,d,e/f}
# Expected: y/{b,c,d,e/f}
-test_expect_success '1a-setup: Simple directory rename detection' '
+test_setup_1a () {
test_create_repo 1a &&
(
cd 1a &&
@@ -67,9 +67,10 @@ test_expect_success '1a-setup: Simple directory rename detection' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1a-check: Simple directory rename detection' '
+test_expect_success '1a: Simple directory rename detection' '
+ test_setup_1a &&
(
cd 1a &&
@@ -103,7 +104,7 @@ test_expect_success '1a-check: Simple directory rename detection' '
# Commit B: y/{b,c,d}
# Expected: y/{b,c,d,e}
-test_expect_success '1b-setup: Merge a directory with another' '
+test_setup_1b () {
test_create_repo 1b &&
(
cd 1b &&
@@ -134,9 +135,10 @@ test_expect_success '1b-setup: Merge a directory with another' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1b-check: Merge a directory with another' '
+test_expect_success '1b: Merge a directory with another' '
+ test_setup_1b &&
(
cd 1b &&
@@ -165,7 +167,7 @@ test_expect_success '1b-check: Merge a directory with another' '
# Commit B: z/{b,c,d}
# Expected: y/{b,c,d} (because x/d -> z/d -> y/d)
-test_expect_success '1c-setup: Transitive renaming' '
+test_setup_1c () {
test_create_repo 1c &&
(
cd 1c &&
@@ -193,9 +195,10 @@ test_expect_success '1c-setup: Transitive renaming' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1c-check: Transitive renaming' '
+test_expect_success '1c: Transitive renaming' '
+ test_setup_1c &&
(
cd 1c &&
@@ -227,7 +230,7 @@ test_expect_success '1c-check: Transitive renaming' '
# Note: y/m & z/n should definitely move into x. By the same token, both
# y/wham_1 & z/wham_2 should too...giving us a conflict.
-test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) conflict' '
+test_setup_1d () {
test_create_repo 1d &&
(
cd 1d &&
@@ -262,9 +265,10 @@ test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) con
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) conflict' '
+test_expect_success '1d: Directory renames cause a rename/rename(2to1) conflict' '
+ test_setup_1d &&
(
cd 1d &&
@@ -313,7 +317,7 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con
# Commit B: z/{oldb,oldc,d}
# Expected: y/{newb,newc,d}
-test_expect_success '1e-setup: Renamed directory, with all files being renamed too' '
+test_setup_1e () {
test_create_repo 1e &&
(
cd 1e &&
@@ -342,9 +346,10 @@ test_expect_success '1e-setup: Renamed directory, with all files being renamed t
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1e-check: Renamed directory, with all files being renamed too' '
+test_expect_success '1e: Renamed directory, with all files being renamed too' '
+ test_setup_1e &&
(
cd 1e &&
@@ -371,7 +376,7 @@ test_expect_success '1e-check: Renamed directory, with all files being renamed t
# Commit B: y/{b,c}, x/{d,e,f}
# Expected: y/{b,c}, x/{d,e,f,g}
-test_expect_success '1f-setup: Split a directory into two other directories' '
+test_setup_1f () {
test_create_repo 1f &&
(
cd 1f &&
@@ -408,9 +413,10 @@ test_expect_success '1f-setup: Split a directory into two other directories' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1f-check: Split a directory into two other directories' '
+test_expect_success '1f: Split a directory into two other directories' '
+ test_setup_1f &&
(
cd 1f &&
@@ -459,7 +465,7 @@ test_expect_success '1f-check: Split a directory into two other directories' '
# Commit A: y/b, w/c
# Commit B: z/{b,c,d}
# Expected: y/b, w/c, z/d, with warning about z/ -> (y/ vs. w/) conflict
-test_expect_success '2a-setup: Directory split into two on one side, with equal numbers of paths' '
+test_setup_2a () {
test_create_repo 2a &&
(
cd 2a &&
@@ -489,9 +495,10 @@ test_expect_success '2a-setup: Directory split into two on one side, with equal
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2a-check: Directory split into two on one side, with equal numbers of paths' '
+test_expect_success '2a: Directory split into two on one side, with equal numbers of paths' '
+ test_setup_2a &&
(
cd 2a &&
@@ -520,7 +527,7 @@ test_expect_success '2a-check: Directory split into two on one side, with equal
# Commit A: y/b, w/c
# Commit B: z/{b,c}, x/d
# Expected: y/b, w/c, x/d; No warning about z/ -> (y/ vs. w/) conflict
-test_expect_success '2b-setup: Directory split into two on one side, with equal numbers of paths' '
+test_setup_2b () {
test_create_repo 2b &&
(
cd 2b &&
@@ -551,9 +558,10 @@ test_expect_success '2b-setup: Directory split into two on one side, with equal
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2b-check: Directory split into two on one side, with equal numbers of paths' '
+test_expect_success '2b: Directory split into two on one side, with equal numbers of paths' '
+ test_setup_2b &&
(
cd 2b &&
@@ -601,7 +609,7 @@ test_expect_success '2b-check: Directory split into two on one side, with equal
# Commit A: z/{b,c,d} (no change)
# Commit B: y/{b,c}, x/d
# Expected: y/{b,c}, x/d
-test_expect_success '3a-setup: Avoid implicit rename if involved as source on other side' '
+test_setup_3a () {
test_create_repo 3a &&
(
cd 3a &&
@@ -632,9 +640,10 @@ test_expect_success '3a-setup: Avoid implicit rename if involved as source on ot
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3a-check: Avoid implicit rename if involved as source on other side' '
+test_expect_success '3a: Avoid implicit rename if involved as source on other side' '
+ test_setup_3a &&
(
cd 3a &&
@@ -664,7 +673,7 @@ test_expect_success '3a-check: Avoid implicit rename if involved as source on ot
# get it involved in directory rename detection. If it were, we might
# end up with CONFLICT:(z/d -> y/d vs. x/d vs. w/d), i.e. a
# rename/rename/rename(1to3) conflict, which is just weird.
-test_expect_success '3b-setup: Avoid implicit rename if involved as source on current side' '
+test_setup_3b () {
test_create_repo 3b &&
(
cd 3b &&
@@ -697,9 +706,10 @@ test_expect_success '3b-setup: Avoid implicit rename if involved as source on cu
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3b-check: Avoid implicit rename if involved as source on current side' '
+test_expect_success '3b: Avoid implicit rename if involved as source on current side' '
+ test_setup_3b &&
(
cd 3b &&
@@ -744,7 +754,7 @@ test_expect_success '3b-check: Avoid implicit rename if involved as source on cu
#
# What if we were to attempt to do directory rename detection when someone
# "mostly" moved a directory but still left some files around, or,
-# equivalently, fully renamed a directory in one commmit and then recreated
+# equivalently, fully renamed a directory in one commit and then recreated
# that directory in a later commit adding some new files and then tried to
# merge?
#
@@ -786,7 +796,7 @@ test_expect_success '3b-check: Avoid implicit rename if involved as source on cu
# Expected: y/{b,c,d}, z/{e,f}
# NOTE: Even though most files from z moved to y, we don't want f to follow.
-test_expect_success '4a-setup: Directory split, with original directory still present' '
+test_setup_4a () {
test_create_repo 4a &&
(
cd 4a &&
@@ -818,9 +828,10 @@ test_expect_success '4a-setup: Directory split, with original directory still pr
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '4a-check: Directory split, with original directory still present' '
+test_expect_success '4a: Directory split, with original directory still present' '
+ test_setup_4a &&
(
cd 4a &&
@@ -874,7 +885,7 @@ test_expect_success '4a-check: Directory split, with original directory still pr
# of history, giving us no way to represent this conflict in the
# index.
-test_expect_success '5a-setup: Merge directories, other side adds files to original and target' '
+test_setup_5a () {
test_create_repo 5a &&
(
cd 5a &&
@@ -907,9 +918,10 @@ test_expect_success '5a-setup: Merge directories, other side adds files to origi
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5a-check: Merge directories, other side adds files to original and target' '
+test_expect_success '5a: Merge directories, other side adds files to original and target' '
+ test_setup_5a &&
(
cd 5a &&
@@ -941,14 +953,14 @@ test_expect_success '5a-check: Merge directories, other side adds files to origi
# Commit B: z/{b,c,d_1,e}, y/d_3
# Expected: y/{b,c,e}, CONFLICT(add/add: y/d_2 vs. y/d_3)
# NOTE: If z/d_1 in commit B were to be involved in dir rename detection, as
-# we normaly would since z/ is being renamed to y/, then this would be
+# we normally would since z/ is being renamed to y/, then this would be
# a rename/delete (z/d_1 -> y/d_1 vs. deleted) AND an add/add/add
# conflict of y/d_1 vs. y/d_2 vs. y/d_3. Add/add/add is not
# representable in the index, so the existence of y/d_3 needs to
# cause us to bail on directory rename detection for that path, falling
# back to git behavior without the directory rename detection.
-test_expect_success '5b-setup: Rename/delete in order to get add/add/add conflict' '
+test_setup_5b () {
test_create_repo 5b &&
(
cd 5b &&
@@ -981,9 +993,10 @@ test_expect_success '5b-setup: Rename/delete in order to get add/add/add conflic
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5b-check: Rename/delete in order to get add/add/add conflict' '
+test_expect_success '5b: Rename/delete in order to get add/add/add conflict' '
+ test_setup_5b &&
(
cd 5b &&
@@ -1024,7 +1037,7 @@ test_expect_success '5b-check: Rename/delete in order to get add/add/add conflic
# y/d are y/d_2 and y/d_4. We still do the move from z/e to y/e,
# though, because it doesn't have anything in the way.
-test_expect_success '5c-setup: Transitive rename would cause rename/rename/rename/add/add/add' '
+test_setup_5c () {
test_create_repo 5c &&
(
cd 5c &&
@@ -1061,9 +1074,10 @@ test_expect_success '5c-setup: Transitive rename would cause rename/rename/renam
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5c-check: Transitive rename would cause rename/rename/rename/add/add/add' '
+test_expect_success '5c: Transitive rename would cause rename/rename/rename/add/add/add' '
+ test_setup_5c &&
(
cd 5c &&
@@ -1113,7 +1127,7 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam
# detection for z/d_2, but that doesn't prevent us from applying the
# directory rename detection for z/f -> y/f.
-test_expect_success '5d-setup: Directory/file/file conflict due to directory rename' '
+test_setup_5d () {
test_create_repo 5d &&
(
cd 5d &&
@@ -1145,9 +1159,10 @@ test_expect_success '5d-setup: Directory/file/file conflict due to directory ren
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5d-check: Directory/file/file conflict due to directory rename' '
+test_expect_success '5d: Directory/file/file conflict due to directory rename' '
+ test_setup_5d &&
(
cd 5d &&
@@ -1205,7 +1220,7 @@ test_expect_success '5d-check: Directory/file/file conflict due to directory ren
# them under y/ doesn't accidentally catch z/d and make it look like
# it is also involved in a rename/delete conflict.
-test_expect_success '6a-setup: Tricky rename/delete' '
+test_setup_6a () {
test_create_repo 6a &&
(
cd 6a &&
@@ -1235,9 +1250,10 @@ test_expect_success '6a-setup: Tricky rename/delete' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6a-check: Tricky rename/delete' '
+test_expect_success '6a: Tricky rename/delete' '
+ test_setup_6a &&
(
cd 6a &&
@@ -1271,7 +1287,7 @@ test_expect_success '6a-check: Tricky rename/delete' '
# but B did that rename and still decided to put the file into z/,
# so we probably shouldn't apply directory rename detection for it.
-test_expect_success '6b-setup: Same rename done on both sides' '
+test_setup_6b () {
test_create_repo 6b &&
(
cd 6b &&
@@ -1300,9 +1316,10 @@ test_expect_success '6b-setup: Same rename done on both sides' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6b-check: Same rename done on both sides' '
+test_expect_success '6b: Same rename done on both sides' '
+ test_setup_6b &&
(
cd 6b &&
@@ -1334,7 +1351,7 @@ test_expect_success '6b-check: Same rename done on both sides' '
# NOTE: Seems obvious, but just checking that the implementation doesn't
# "accidentally detect a rename" and give us y/{b,c,d}.
-test_expect_success '6c-setup: Rename only done on same side' '
+test_setup_6c () {
test_create_repo 6c &&
(
cd 6c &&
@@ -1362,9 +1379,10 @@ test_expect_success '6c-setup: Rename only done on same side' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6c-check: Rename only done on same side' '
+test_expect_success '6c: Rename only done on same side' '
+ test_setup_6c &&
(
cd 6c &&
@@ -1396,7 +1414,7 @@ test_expect_success '6c-check: Rename only done on same side' '
# NOTE: Again, this seems obvious but just checking that the implementation
# doesn't "accidentally detect a rename" and give us y/{b,c,d}.
-test_expect_success '6d-setup: We do not always want transitive renaming' '
+test_setup_6d () {
test_create_repo 6d &&
(
cd 6d &&
@@ -1424,9 +1442,10 @@ test_expect_success '6d-setup: We do not always want transitive renaming' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6d-check: We do not always want transitive renaming' '
+test_expect_success '6d: We do not always want transitive renaming' '
+ test_setup_6d &&
(
cd 6d &&
@@ -1458,7 +1477,7 @@ test_expect_success '6d-check: We do not always want transitive renaming' '
# doesn't "accidentally detect a rename" and give us y/{b,c} +
# add/add conflict on y/d_1 vs y/d_2.
-test_expect_success '6e-setup: Add/add from one side' '
+test_setup_6e () {
test_create_repo 6e &&
(
cd 6e &&
@@ -1487,9 +1506,10 @@ test_expect_success '6e-setup: Add/add from one side' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6e-check: Add/add from one side' '
+test_expect_success '6e: Add/add from one side' '
+ test_setup_6e &&
(
cd 6e &&
@@ -1552,7 +1572,7 @@ test_expect_success '6e-check: Add/add from one side' '
# Expected: y/d, CONFLICT(rename/rename for both z/b and z/c)
# NOTE: There's a rename of z/ here, y/ has more renames, so z/d -> y/d.
-test_expect_success '7a-setup: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+test_setup_7a () {
test_create_repo 7a &&
(
cd 7a &&
@@ -1583,9 +1603,10 @@ test_expect_success '7a-setup: rename-dir vs. rename-dir (NOT split evenly) PLUS
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+test_expect_success '7a: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+ test_setup_7a &&
(
cd 7a &&
@@ -1623,7 +1644,7 @@ test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS
# Commit B: z/{b,c,d_1}, w/d_2
# Expected: y/{b,c}, CONFLICT(rename/rename(2to1): x/d_1, w/d_2 -> y_d)
-test_expect_success '7b-setup: rename/rename(2to1), but only due to transitive rename' '
+test_setup_7b () {
test_create_repo 7b &&
(
cd 7b &&
@@ -1655,9 +1676,10 @@ test_expect_success '7b-setup: rename/rename(2to1), but only due to transitive r
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7b-check: rename/rename(2to1), but only due to transitive rename' '
+test_expect_success '7b: rename/rename(2to1), but only due to transitive rename' '
+ test_setup_7b &&
(
cd 7b &&
@@ -1702,7 +1724,7 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r
# neither CONFLICT(x/d -> w/d vs. z/d)
# nor CONFLiCT x/d -> w/d vs. y/d vs. z/d)
-test_expect_success '7c-setup: rename/rename(1to...2or3); transitive rename may add complexity' '
+test_setup_7c () {
test_create_repo 7c &&
(
cd 7c &&
@@ -1732,9 +1754,10 @@ test_expect_success '7c-setup: rename/rename(1to...2or3); transitive rename may
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may add complexity' '
+test_expect_success '7c: rename/rename(1to...2or3); transitive rename may add complexity' '
+ test_setup_7c &&
(
cd 7c &&
@@ -1766,7 +1789,7 @@ test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may
# Expected: y/{b,c}, CONFLICT(delete x/d vs rename to y/d)
# NOTE: z->y so NOT CONFLICT(delete x/d vs rename to z/d)
-test_expect_success '7d-setup: transitive rename involved in rename/delete; how is it reported?' '
+test_setup_7d () {
test_create_repo 7d &&
(
cd 7d &&
@@ -1796,9 +1819,10 @@ test_expect_success '7d-setup: transitive rename involved in rename/delete; how
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7d-check: transitive rename involved in rename/delete; how is it reported?' '
+test_expect_success '7d: transitive rename involved in rename/delete; how is it reported?' '
+ test_setup_7d &&
(
cd 7d &&
@@ -1851,7 +1875,7 @@ test_expect_success '7d-check: transitive rename involved in rename/delete; how
# see testcases 9c and 9d for further discussion of this issue and
# how it's resolved.
-test_expect_success '7e-setup: transitive rename in rename/delete AND dirs in the way' '
+test_setup_7e () {
test_create_repo 7e &&
(
cd 7e &&
@@ -1886,9 +1910,10 @@ test_expect_success '7e-setup: transitive rename in rename/delete AND dirs in th
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7e-check: transitive rename in rename/delete AND dirs in the way' '
+test_expect_success '7e: transitive rename in rename/delete AND dirs in the way' '
+ test_setup_7e &&
(
cd 7e &&
@@ -1945,7 +1970,7 @@ test_expect_success '7e-check: transitive rename in rename/delete AND dirs in th
# simple rule from section 5 prevents me from handling this as optimally as
# we potentially could.
-test_expect_success '8a-setup: Dual-directory rename, one into the others way' '
+test_setup_8a () {
test_create_repo 8a &&
(
cd 8a &&
@@ -1977,9 +2002,10 @@ test_expect_success '8a-setup: Dual-directory rename, one into the others way' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8a-check: Dual-directory rename, one into the others way' '
+test_expect_success '8a: Dual-directory rename, one into the others way' '
+ test_setup_8a &&
(
cd 8a &&
@@ -2023,7 +2049,7 @@ test_expect_success '8a-check: Dual-directory rename, one into the others way' '
# making us fall back to pre-directory-rename-detection behavior for both
# e_1 and e_2.
-test_expect_success '8b-setup: Dual-directory rename, one into the others way, with conflicting filenames' '
+test_setup_8b () {
test_create_repo 8b &&
(
cd 8b &&
@@ -2055,9 +2081,10 @@ test_expect_success '8b-setup: Dual-directory rename, one into the others way, w
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8b-check: Dual-directory rename, one into the others way, with conflicting filenames' '
+test_expect_success '8b: Dual-directory rename, one into the others way, with conflicting filenames' '
+ test_setup_8b &&
(
cd 8b &&
@@ -2089,14 +2116,14 @@ test_expect_success '8b-check: Dual-directory rename, one into the others way, w
#
# Note: It could easily be argued that the correct resolution here is
# y/{b,c,e}, CONFLICT(rename/delete: z/d -> y/d vs deleted)
-# and that the modifed version of d should be present in y/ after
+# and that the modified version of d should be present in y/ after
# the merge, just marked as conflicted. Indeed, I previously did
# argue that. But applying directory renames to the side of
# history where a file is merely modified results in spurious
# rename/rename(1to2) conflicts -- see testcase 9h. See also
# notes in 8d.
-test_expect_success '8c-setup: modify/delete or rename+modify/delete?' '
+test_setup_8c () {
test_create_repo 8c &&
(
cd 8c &&
@@ -2127,9 +2154,10 @@ test_expect_success '8c-setup: modify/delete or rename+modify/delete?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8c-check: modify/delete or rename+modify/delete' '
+test_expect_success '8c: modify/delete or rename+modify/delete' '
+ test_setup_8c &&
(
cd 8c &&
@@ -2175,7 +2203,7 @@ test_expect_success '8c-check: modify/delete or rename+modify/delete' '
# during merging are supposed to be about opposite sides doing things
# differently.
-test_expect_success '8d-setup: rename/delete...or not?' '
+test_setup_8d () {
test_create_repo 8d &&
(
cd 8d &&
@@ -2204,9 +2232,10 @@ test_expect_success '8d-setup: rename/delete...or not?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8d-check: rename/delete...or not?' '
+test_expect_success '8d: rename/delete...or not?' '
+ test_setup_8d &&
(
cd 8d &&
@@ -2250,7 +2279,7 @@ test_expect_success '8d-check: rename/delete...or not?' '
# about the ramifications of doing that, I didn't know how to rule out
# that opening other weird edge and corner cases so I just punted.
-test_expect_success '8e-setup: Both sides rename, one side adds to original directory' '
+test_setup_8e () {
test_create_repo 8e &&
(
cd 8e &&
@@ -2279,9 +2308,10 @@ test_expect_success '8e-setup: Both sides rename, one side adds to original dire
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8e-check: Both sides rename, one side adds to original directory' '
+test_expect_success '8e: Both sides rename, one side adds to original directory' '
+ test_setup_8e &&
(
cd 8e &&
@@ -2333,7 +2363,7 @@ test_expect_success '8e-check: Both sides rename, one side adds to original dire
# of which one had the most paths going to it. A naive implementation
# of that could take the new file in commit B at z/i to x/w/i or x/i.
-test_expect_success '9a-setup: Inner renamed directory within outer renamed directory' '
+test_setup_9a () {
test_create_repo 9a &&
(
cd 9a &&
@@ -2366,9 +2396,10 @@ test_expect_success '9a-setup: Inner renamed directory within outer renamed dire
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9a-check: Inner renamed directory within outer renamed directory' '
+test_expect_success '9a: Inner renamed directory within outer renamed directory' '
+ test_setup_9a &&
(
cd 9a &&
@@ -2404,7 +2435,7 @@ test_expect_success '9a-check: Inner renamed directory within outer renamed dire
# Commit B: z/{b,c,d_3}
# Expected: y/{b,c,d_merged}
-test_expect_success '9b-setup: Transitive rename with content merge' '
+test_setup_9b () {
test_create_repo 9b &&
(
cd 9b &&
@@ -2436,9 +2467,10 @@ test_expect_success '9b-setup: Transitive rename with content merge' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9b-check: Transitive rename with content merge' '
+test_expect_success '9b: Transitive rename with content merge' '
+ test_setup_9b &&
(
cd 9b &&
@@ -2491,7 +2523,7 @@ test_expect_success '9b-check: Transitive rename with content merge' '
# away, then ignore that particular rename from the other side of
# history for any implicit directory renames.
-test_expect_success '9c-setup: Doubly transitive rename?' '
+test_setup_9c () {
test_create_repo 9c &&
(
cd 9c &&
@@ -2526,9 +2558,10 @@ test_expect_success '9c-setup: Doubly transitive rename?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9c-check: Doubly transitive rename?' '
+test_expect_success '9c: Doubly transitive rename?' '
+ test_setup_9c &&
(
cd 9c &&
@@ -2579,7 +2612,7 @@ test_expect_success '9c-check: Doubly transitive rename?' '
# simple rules that are consistent with what we need for all the other
# testcases and simplifies things for the user.
-test_expect_success '9d-setup: N-way transitive rename?' '
+test_setup_9d () {
test_create_repo 9d &&
(
cd 9d &&
@@ -2614,9 +2647,10 @@ test_expect_success '9d-setup: N-way transitive rename?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9d-check: N-way transitive rename?' '
+test_expect_success '9d: N-way transitive rename?' '
+ test_setup_9d &&
(
cd 9d &&
@@ -2653,7 +2687,7 @@ test_expect_success '9d-check: N-way transitive rename?' '
# Expected: combined/{a,b,c,d,e,f,g,h,i,j,k,l}, CONFLICT(Nto1) warnings,
# dir1/yo, dir2/yo, dir3/yo, dirN/yo
-test_expect_success '9e-setup: N-to-1 whammo' '
+test_setup_9e () {
test_create_repo 9e &&
(
cd 9e &&
@@ -2696,9 +2730,10 @@ test_expect_success '9e-setup: N-to-1 whammo' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' '
+test_expect_success C_LOCALE_OUTPUT '9e: N-to-1 whammo' '
+ test_setup_9e &&
(
cd 9e &&
@@ -2745,7 +2780,7 @@ test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' '
# Commit B: goal/{a,b}/$more_files, goal/c
# Expected: priority/{a,b}/$more_files, priority/c
-test_expect_success '9f-setup: Renamed directory that only contained immediate subdirs' '
+test_setup_9f () {
test_create_repo 9f &&
(
cd 9f &&
@@ -2774,9 +2809,10 @@ test_expect_success '9f-setup: Renamed directory that only contained immediate s
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9f-check: Renamed directory that only contained immediate subdirs' '
+test_expect_success '9f: Renamed directory that only contained immediate subdirs' '
+ test_setup_9f &&
(
cd 9f &&
@@ -2809,7 +2845,7 @@ test_expect_success '9f-check: Renamed directory that only contained immediate s
# Commit B: goal/{a,b}/$more_files, goal/c
# Expected: priority/{alpha,bravo}/$more_files, priority/c
-test_expect_success '9g-setup: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
+test_setup_9g () {
test_create_repo 9g &&
(
cd 9g &&
@@ -2841,9 +2877,9 @@ test_expect_success '9g-setup: Renamed directory that only contained immediate s
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_failure '9g-check: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
+test_expect_failure '9g: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
(
cd 9g &&
@@ -2877,7 +2913,7 @@ test_expect_failure '9g-check: Renamed directory that only contained immediate s
# Expected: y/{b,c}, x/d_2
# NOTE: If we applied the z/ -> y/ rename to z/d, then we'd end up with
# a rename/rename(1to2) conflict (z/d -> y/d vs. x/d)
-test_expect_success '9h-setup: Avoid dir rename on merely modified path' '
+test_setup_9h () {
test_create_repo 9h &&
(
cd 9h &&
@@ -2910,9 +2946,10 @@ test_expect_success '9h-setup: Avoid dir rename on merely modified path' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9h-check: Avoid dir rename on merely modified path' '
+test_expect_success '9h: Avoid dir rename on merely modified path' '
+ test_setup_9h &&
(
cd 9h &&
@@ -2957,7 +2994,7 @@ test_expect_success '9h-check: Avoid dir rename on merely modified path' '
# Expected: Aborted Merge +
# ERROR_MSG(untracked working tree files would be overwritten by merge)
-test_expect_success '10a-setup: Overwrite untracked with normal rename/delete' '
+test_setup_10a () {
test_create_repo 10a &&
(
cd 10a &&
@@ -2983,9 +3020,10 @@ test_expect_success '10a-setup: Overwrite untracked with normal rename/delete' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10a-check: Overwrite untracked with normal rename/delete' '
+test_expect_success '10a: Overwrite untracked with normal rename/delete' '
+ test_setup_10a &&
(
cd 10a &&
@@ -3021,7 +3059,7 @@ test_expect_success '10a-check: Overwrite untracked with normal rename/delete' '
# z/c_1 -> z/d_1 rename recorded at stage 3 for y/d +
# ERROR_MSG(refusing to lose untracked file at 'y/d')
-test_expect_success '10b-setup: Overwrite untracked with dir rename + delete' '
+test_setup_10b () {
test_create_repo 10b &&
(
cd 10b &&
@@ -3050,9 +3088,10 @@ test_expect_success '10b-setup: Overwrite untracked with dir rename + delete' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10b-check: Overwrite untracked with dir rename + delete' '
+test_expect_success '10b: Overwrite untracked with dir rename + delete' '
+ test_setup_10b &&
(
cd 10b &&
@@ -3098,10 +3137,10 @@ test_expect_success '10b-check: Overwrite untracked with dir rename + delete' '
# y/c~B^0 +
# ERROR_MSG(Refusing to lose untracked file at y/c)
-test_expect_success '10c-setup: Overwrite untracked with dir rename/rename(1to2)' '
- test_create_repo 10c &&
+test_setup_10c () {
+ test_create_repo 10c_$1 &&
(
- cd 10c &&
+ cd 10c_$1 &&
mkdir z x &&
echo a >z/a &&
@@ -3128,11 +3167,12 @@ test_expect_success '10c-setup: Overwrite untracked with dir rename/rename(1to2)
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)' '
+test_expect_success '10c1: Overwrite untracked with dir rename/rename(1to2)' '
+ test_setup_10c 1 &&
(
- cd 10c &&
+ cd 10c_1 &&
git checkout A^0 &&
echo important >y/c &&
@@ -3163,9 +3203,10 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
)
'
-test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2), other direction' '
+test_expect_success '10c2: Overwrite untracked with dir rename/rename(1to2), other direction' '
+ test_setup_10c 2 &&
(
- cd 10c &&
+ cd 10c_2 &&
git reset --hard &&
git clean -fdqx &&
@@ -3208,7 +3249,7 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
# CONFLICT(rename/rename) z/c_1 vs x/f_2 -> y/wham
# ERROR_MSG(Refusing to lose untracked file at y/wham)
-test_expect_success '10d-setup: Delete untracked with dir rename/rename(2to1)' '
+test_setup_10d () {
test_create_repo 10d &&
(
cd 10d &&
@@ -3240,9 +3281,10 @@ test_expect_success '10d-setup: Delete untracked with dir rename/rename(2to1)' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
+test_expect_success '10d: Delete untracked with dir rename/rename(2to1)' '
+ test_setup_10d &&
(
cd 10d &&
@@ -3290,7 +3332,7 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
# Commit B: z/{a,b,c}
# Expected: y/{a,b,c} + untracked z/c
-test_expect_success '10e-setup: Does git complain about untracked file that is not really in the way?' '
+test_setup_10e () {
test_create_repo 10e &&
(
cd 10e &&
@@ -3317,9 +3359,9 @@ test_expect_success '10e-setup: Does git complain about untracked file that is n
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_failure '10e-check: Does git complain about untracked file that is not really in the way?' '
+test_expect_failure '10e: Does git complain about untracked file that is not really in the way?' '
(
cd 10e &&
@@ -3371,7 +3413,7 @@ test_expect_failure '10e-check: Does git complain about untracked file that is n
# z/c~HEAD with contents of B:z/b_v2,
# z/c with uncommitted mods on top of A:z/c_v1
-test_expect_success '11a-setup: Avoid losing dirty contents with simple rename' '
+test_setup_11a () {
test_create_repo 11a &&
(
cd 11a &&
@@ -3398,9 +3440,10 @@ test_expect_success '11a-setup: Avoid losing dirty contents with simple rename'
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11a-check: Avoid losing dirty contents with simple rename' '
+test_expect_success '11a: Avoid losing dirty contents with simple rename' '
+ test_setup_11a &&
(
cd 11a &&
@@ -3441,7 +3484,7 @@ test_expect_success '11a-check: Avoid losing dirty contents with simple rename'
# ERROR_MSG(Refusing to lose dirty file at z/c)
-test_expect_success '11b-setup: Avoid losing dirty file involved in directory rename' '
+test_setup_11b () {
test_create_repo 11b &&
(
cd 11b &&
@@ -3470,9 +3513,10 @@ test_expect_success '11b-setup: Avoid losing dirty file involved in directory re
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11b-check: Avoid losing dirty file involved in directory rename' '
+test_expect_success '11b: Avoid losing dirty file involved in directory rename' '
+ test_setup_11b &&
(
cd 11b &&
@@ -3515,7 +3559,7 @@ test_expect_success '11b-check: Avoid losing dirty file involved in directory re
# Expected: Abort_msg("following files would be overwritten by merge") +
# y/c left untouched (still has uncommitted mods)
-test_expect_success '11c-setup: Avoid losing not-uptodate with rename + D/F conflict' '
+test_setup_11c () {
test_create_repo 11c &&
(
cd 11c &&
@@ -3545,9 +3589,10 @@ test_expect_success '11c-setup: Avoid losing not-uptodate with rename + D/F conf
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conflict' '
+test_expect_success '11c: Avoid losing not-uptodate with rename + D/F conflict' '
+ test_setup_11c &&
(
cd 11c &&
@@ -3581,7 +3626,7 @@ test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conf
# Warning_Msg("Refusing to lose dirty file at z/c) +
# y/{a,c~HEAD,c/d}, x/b, now-untracked z/c_v1 with uncommitted mods
-test_expect_success '11d-setup: Avoid losing not-uptodate with rename + D/F conflict' '
+test_setup_11d () {
test_create_repo 11d &&
(
cd 11d &&
@@ -3612,9 +3657,10 @@ test_expect_success '11d-setup: Avoid losing not-uptodate with rename + D/F conf
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conflict' '
+test_expect_success '11d: Avoid losing not-uptodate with rename + D/F conflict' '
+ test_setup_11d &&
(
cd 11d &&
@@ -3659,7 +3705,7 @@ test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conf
# y/c~HEAD has A:y/c_2 contents
# y/c has dirty file from before merge
-test_expect_success '11e-setup: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+test_setup_11e () {
test_create_repo 11e &&
(
cd 11e &&
@@ -3691,9 +3737,10 @@ test_expect_success '11e-setup: Avoid deleting not-uptodate with dir rename/rena
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+test_expect_success '11e: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+ test_setup_11e &&
(
cd 11e &&
@@ -3744,7 +3791,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
# CONFLICT(rename/rename) x/c vs x/d -> y/wham
# ERROR_MSG(Refusing to lose dirty file at y/wham)
-test_expect_success '11f-setup: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+test_setup_11f () {
test_create_repo 11f &&
(
cd 11f &&
@@ -3773,9 +3820,10 @@ test_expect_success '11f-setup: Avoid deleting not-uptodate with dir rename/rena
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+test_expect_success '11f: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+ test_setup_11f &&
(
cd 11f &&
@@ -3832,7 +3880,7 @@ test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rena
# Commit B: node1/{leaf1,leaf2,leaf5}, node2/{leaf3,leaf4,leaf6}
# Expected: node1/{leaf1,leaf2,leaf5,node2/{leaf3,leaf4,leaf6}}
-test_expect_success '12a-setup: Moving one directory hierarchy into another' '
+test_setup_12a () {
test_create_repo 12a &&
(
cd 12a &&
@@ -3862,9 +3910,10 @@ test_expect_success '12a-setup: Moving one directory hierarchy into another' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '12a-check: Moving one directory hierarchy into another' '
+test_expect_success '12a: Moving one directory hierarchy into another' '
+ test_setup_12a &&
(
cd 12a &&
@@ -3910,7 +3959,7 @@ test_expect_success '12a-check: Moving one directory hierarchy into another' '
# To which, I can do no more than shrug my shoulders and say that
# even simple rules give weird results when given weird inputs.
-test_expect_success '12b-setup: Moving two directory hierarchies into each other' '
+test_setup_12b () {
test_create_repo 12b &&
(
cd 12b &&
@@ -3938,9 +3987,10 @@ test_expect_success '12b-setup: Moving two directory hierarchies into each other
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '12b-check: Moving two directory hierarchies into each other' '
+test_expect_success '12b: Moving two directory hierarchies into each other' '
+ test_setup_12b &&
(
cd 12b &&
@@ -3976,7 +4026,7 @@ test_expect_success '12b-check: Moving two directory hierarchies into each other
# NOTE: This is *exactly* like 12c, except that every path is modified on
# each side of the merge.
-test_expect_success '12c-setup: Moving one directory hierarchy into another w/ content merge' '
+test_setup_12c () {
test_create_repo 12c &&
(
cd 12c &&
@@ -4008,9 +4058,10 @@ test_expect_success '12c-setup: Moving one directory hierarchy into another w/ c
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '12c-check: Moving one directory hierarchy into another w/ content merge' '
+test_expect_success '12c: Moving one directory hierarchy into another w/ content merge' '
+ test_setup_12c &&
(
cd 12c &&
@@ -4051,6 +4102,122 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c
)
'
+# Testcase 12d, Rename/merge of subdirectory into the root
+# Commit O: a/b/subdir/foo
+# Commit A: subdir/foo
+# Commit B: a/b/subdir/foo, a/b/bar
+# Expected: subdir/foo, bar
+
+test_setup_12d () {
+ test_create_repo 12d &&
+ (
+ cd 12d &&
+
+ mkdir -p a/b/subdir &&
+ test_commit a/b/subdir/foo &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ mkdir subdir &&
+ git mv a/b/subdir/foo.t subdir/foo.t &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ test_commit a/b/bar
+ )
+}
+
+test_expect_success '12d: Rename/merge subdir into the root, variant 1' '
+ test_setup_12d &&
+ (
+ cd 12d &&
+
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
+
+ git ls-files -s >out &&
+ test_line_count = 2 out &&
+
+ git rev-parse >actual \
+ HEAD:subdir/foo.t HEAD:bar.t &&
+ git rev-parse >expect \
+ O:a/b/subdir/foo.t B:a/b/bar.t &&
+ test_cmp expect actual &&
+
+ git hash-object bar.t >actual &&
+ git rev-parse B:a/b/bar.t >expect &&
+ test_cmp expect actual &&
+
+ test_must_fail git rev-parse HEAD:a/b/subdir/foo.t &&
+ test_must_fail git rev-parse HEAD:a/b/bar.t &&
+ test_path_is_missing a/ &&
+ test_path_is_file bar.t
+ )
+'
+
+# Testcase 12e, Rename/merge of subdirectory into the root
+# Commit O: a/b/foo
+# Commit A: foo
+# Commit B: a/b/foo, a/b/bar
+# Expected: foo, bar
+
+test_setup_12e () {
+ test_create_repo 12e &&
+ (
+ cd 12e &&
+
+ mkdir -p a/b &&
+ test_commit a/b/foo &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ mkdir subdir &&
+ git mv a/b/foo.t foo.t &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ test_commit a/b/bar
+ )
+}
+
+test_expect_success '12e: Rename/merge subdir into the root, variant 2' '
+ test_setup_12e &&
+ (
+ cd 12e &&
+
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
+
+ git ls-files -s >out &&
+ test_line_count = 2 out &&
+
+ git rev-parse >actual \
+ HEAD:foo.t HEAD:bar.t &&
+ git rev-parse >expect \
+ O:a/b/foo.t B:a/b/bar.t &&
+ test_cmp expect actual &&
+
+ git hash-object bar.t >actual &&
+ git rev-parse B:a/b/bar.t >expect &&
+ test_cmp expect actual &&
+
+ test_must_fail git rev-parse HEAD:a/b/foo.t &&
+ test_must_fail git rev-parse HEAD:a/b/bar.t &&
+ test_path_is_missing a/ &&
+ test_path_is_file bar.t
+ )
+'
+
###########################################################################
# SECTION 13: Checking informational and conflict messages
#
@@ -4068,10 +4235,10 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c
# Commit B: z/{b,c,d,e/f}
# Expected: y/{b,c,d,e/f}, with notices/conflicts for both y/d and y/e/f
-test_expect_success '13a-setup: messages for newly added files' '
- test_create_repo 13a &&
+test_setup_13a () {
+ test_create_repo 13a_$1 &&
(
- cd 13a &&
+ cd 13a_$1 &&
mkdir z &&
echo b >z/b &&
@@ -4097,11 +4264,12 @@ test_expect_success '13a-setup: messages for newly added files' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13a-check(conflict): messages for newly added files' '
+test_expect_success '13a(conflict): messages for newly added files' '
+ test_setup_13a conflict &&
(
- cd 13a &&
+ cd 13a_conflict &&
git checkout A^0 &&
@@ -4121,9 +4289,10 @@ test_expect_success '13a-check(conflict): messages for newly added files' '
)
'
-test_expect_success '13a-check(info): messages for newly added files' '
+test_expect_success '13a(info): messages for newly added files' '
+ test_setup_13a info &&
(
- cd 13a &&
+ cd 13a_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4153,10 +4322,10 @@ test_expect_success '13a-check(info): messages for newly added files' '
# Expected: y/{b,c,d_merged}, with two conflict messages for y/d,
# one about content, and one about file location
-test_expect_success '13b-setup: messages for transitive rename with conflicted content' '
- test_create_repo 13b &&
+test_setup_13b () {
+ test_create_repo 13b_$1 &&
(
- cd 13b &&
+ cd 13b_$1 &&
mkdir x &&
mkdir z &&
@@ -4185,11 +4354,12 @@ test_expect_success '13b-setup: messages for transitive rename with conflicted c
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13b-check(conflict): messages for transitive rename with conflicted content' '
+test_expect_success '13b(conflict): messages for transitive rename with conflicted content' '
+ test_setup_13b conflict &&
(
- cd 13b &&
+ cd 13b_conflict &&
git checkout A^0 &&
@@ -4207,9 +4377,10 @@ test_expect_success '13b-check(conflict): messages for transitive rename with co
)
'
-test_expect_success '13b-check(info): messages for transitive rename with conflicted content' '
+test_expect_success '13b(info): messages for transitive rename with conflicted content' '
+ test_setup_13b info &&
(
- cd 13b &&
+ cd 13b_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4238,10 +4409,10 @@ test_expect_success '13b-check(info): messages for transitive rename with confli
# d and B had full knowledge, but that's a slippery slope as
# shown in testcase 13d.
-test_expect_success '13c-setup: messages for rename/rename(1to1) via transitive rename' '
- test_create_repo 13c &&
+test_setup_13c () {
+ test_create_repo 13c_$1 &&
(
- cd 13c &&
+ cd 13c_$1 &&
mkdir x &&
mkdir z &&
@@ -4269,11 +4440,12 @@ test_expect_success '13c-setup: messages for rename/rename(1to1) via transitive
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13c-check(conflict): messages for rename/rename(1to1) via transitive rename' '
+test_expect_success '13c(conflict): messages for rename/rename(1to1) via transitive rename' '
+ test_setup_13c conflict &&
(
- cd 13c &&
+ cd 13c_conflict &&
git checkout A^0 &&
@@ -4290,9 +4462,10 @@ test_expect_success '13c-check(conflict): messages for rename/rename(1to1) via t
)
'
-test_expect_success '13c-check(info): messages for rename/rename(1to1) via transitive rename' '
+test_expect_success '13c(info): messages for rename/rename(1to1) via transitive rename' '
+ test_setup_13c info &&
(
- cd 13c &&
+ cd 13c_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4324,10 +4497,10 @@ test_expect_success '13c-check(info): messages for rename/rename(1to1) via trans
# * B renames a/y to c/y, and A renames c/->d/ => a/y -> d/y
# No conflict in where a/y ends up, so put it in d/y.
-test_expect_success '13d-setup: messages for rename/rename(1to1) via dual transitive rename' '
- test_create_repo 13d &&
+test_setup_13d () {
+ test_create_repo 13d_$1 &&
(
- cd 13d &&
+ cd 13d_$1 &&
mkdir a &&
mkdir b &&
@@ -4356,11 +4529,12 @@ test_expect_success '13d-setup: messages for rename/rename(1to1) via dual transi
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13d-check(conflict): messages for rename/rename(1to1) via dual transitive rename' '
+test_expect_success '13d(conflict): messages for rename/rename(1to1) via dual transitive rename' '
+ test_setup_13d conflict &&
(
- cd 13d &&
+ cd 13d_conflict &&
git checkout A^0 &&
@@ -4380,9 +4554,10 @@ test_expect_success '13d-check(conflict): messages for rename/rename(1to1) via d
)
'
-test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual transitive rename' '
+test_expect_success '13d(info): messages for rename/rename(1to1) via dual transitive rename' '
+ test_setup_13d info &&
(
- cd 13d &&
+ cd 13d_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4448,7 +4623,7 @@ test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual
# in the outer merge for this special kind of setup, but it at
# least avoids hitting a BUG().
#
-test_expect_success '13e-setup: directory rename detection in recursive case' '
+test_setup_13e () {
test_create_repo 13e &&
(
cd 13e &&
@@ -4493,9 +4668,10 @@ test_expect_success '13e-setup: directory rename detection in recursive case' '
test_tick &&
git commit -m "D"
)
-'
+}
-test_expect_success '13e-check: directory rename detection in recursive case' '
+test_expect_success '13e: directory rename detection in recursive case' '
+ test_setup_13e &&
(
cd 13e &&
diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh
index 3a47623ed3..b7e4669832 100755
--- a/t/t6046-merge-skip-unneeded-updates.sh
+++ b/t/t6046-merge-skip-unneeded-updates.sh
@@ -36,10 +36,10 @@ test_description="merge cases"
# Commit B: b_3
# Expected: b_2
-test_expect_success '1a-setup: Modify(A)/Modify(B), change on B subset of A' '
- test_create_repo 1a &&
+test_setup_1a () {
+ test_create_repo 1a_$1 &&
(
- cd 1a &&
+ cd 1a_$1 &&
test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
git add b &&
@@ -62,13 +62,12 @@ test_expect_success '1a-setup: Modify(A)/Modify(B), change on B subset of A' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1a-check-L: Modify(A)/Modify(B), change on B subset of A' '
- test_when_finished "git -C 1a reset --hard" &&
- test_when_finished "git -C 1a clean -fd" &&
+test_expect_success '1a-L: Modify(A)/Modify(B), change on B subset of A' '
+ test_setup_1a L &&
(
- cd 1a &&
+ cd 1a_L &&
git checkout A^0 &&
@@ -96,11 +95,10 @@ test_expect_success '1a-check-L: Modify(A)/Modify(B), change on B subset of A' '
)
'
-test_expect_success '1a-check-R: Modify(A)/Modify(B), change on B subset of A' '
- test_when_finished "git -C 1a reset --hard" &&
- test_when_finished "git -C 1a clean -fd" &&
+test_expect_success '1a-R: Modify(A)/Modify(B), change on B subset of A' '
+ test_setup_1a R &&
(
- cd 1a &&
+ cd 1a_R &&
git checkout B^0 &&
@@ -133,10 +131,10 @@ test_expect_success '1a-check-R: Modify(A)/Modify(B), change on B subset of A' '
# Commit B: c_1
# Expected: c_2
-test_expect_success '2a-setup: Modify(A)/rename(B)' '
- test_create_repo 2a &&
+test_setup_2a () {
+ test_create_repo 2a_$1 &&
(
- cd 2a &&
+ cd 2a_$1 &&
test_seq 1 10 >b &&
git add b &&
@@ -158,13 +156,12 @@ test_expect_success '2a-setup: Modify(A)/rename(B)' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2a-check-L: Modify/rename, merge into modify side' '
- test_when_finished "git -C 2a reset --hard" &&
- test_when_finished "git -C 2a clean -fd" &&
+test_expect_success '2a-L: Modify/rename, merge into modify side' '
+ test_setup_2a L &&
(
- cd 2a &&
+ cd 2a_L &&
git checkout A^0 &&
@@ -189,11 +186,10 @@ test_expect_success '2a-check-L: Modify/rename, merge into modify side' '
)
'
-test_expect_success '2a-check-R: Modify/rename, merge into rename side' '
- test_when_finished "git -C 2a reset --hard" &&
- test_when_finished "git -C 2a clean -fd" &&
+test_expect_success '2a-R: Modify/rename, merge into rename side' '
+ test_setup_2a R &&
(
- cd 2a &&
+ cd 2a_R &&
git checkout B^0 &&
@@ -224,10 +220,10 @@ test_expect_success '2a-check-R: Modify/rename, merge into rename side' '
# Commit B: b_3
# Expected: c_2
-test_expect_success '2b-setup: Rename+Mod(A)/Mod(B), B mods subset of A' '
- test_create_repo 2b &&
+test_setup_2b () {
+ test_create_repo 2b_$1 &&
(
- cd 2b &&
+ cd 2b_$1 &&
test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
git add b &&
@@ -251,13 +247,12 @@ test_expect_success '2b-setup: Rename+Mod(A)/Mod(B), B mods subset of A' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2b-check-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
- test_when_finished "git -C 2b reset --hard" &&
- test_when_finished "git -C 2b clean -fd" &&
+test_expect_success '2b-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
+ test_setup_2b L &&
(
- cd 2b &&
+ cd 2b_L &&
git checkout A^0 &&
@@ -288,11 +283,10 @@ test_expect_success '2b-check-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
)
'
-test_expect_success '2b-check-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
- test_when_finished "git -C 2b reset --hard" &&
- test_when_finished "git -C 2b clean -fd" &&
+test_expect_success '2b-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
+ test_setup_2b R &&
(
- cd 2b &&
+ cd 2b_R &&
git checkout B^0 &&
@@ -332,7 +326,7 @@ test_expect_success '2b-check-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
# skip the update, then we're in trouble. This test verifies we do
# not make that particular mistake.
-test_expect_success '2c-setup: Modify b & add c VS rename b->c' '
+test_setup_2c () {
test_create_repo 2c &&
(
cd 2c &&
@@ -358,9 +352,10 @@ test_expect_success '2c-setup: Modify b & add c VS rename b->c' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2c-check: Modify b & add c VS rename b->c' '
+test_expect_success '2c: Modify b & add c VS rename b->c' '
+ test_setup_2c &&
(
cd 2c &&
@@ -428,10 +423,10 @@ test_expect_success '2c-check: Modify b & add c VS rename b->c' '
# Commit B: bq_1, bar/whatever
# Expected: bar/{bq_2, whatever}
-test_expect_success '3a-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_create_repo 3a &&
+test_setup_3a () {
+ test_create_repo 3a_$1 &&
(
- cd 3a &&
+ cd 3a_$1 &&
mkdir foo &&
test_seq 1 10 >bq &&
@@ -456,13 +451,12 @@ test_expect_success '3a-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3a reset --hard" &&
- test_when_finished "git -C 3a clean -fd" &&
+test_expect_success '3a-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3a L &&
(
- cd 3a &&
+ cd 3a_L &&
git checkout A^0 &&
@@ -487,11 +481,10 @@ test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
)
'
-test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3a reset --hard" &&
- test_when_finished "git -C 3a clean -fd" &&
+test_expect_success '3a-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3a R &&
(
- cd 3a &&
+ cd 3a_R &&
git checkout B^0 &&
@@ -522,10 +515,10 @@ test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
# Commit B: bq_2, bar/whatever
# Expected: bar/{bq_2, whatever}
-test_expect_success '3b-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_create_repo 3b &&
+test_setup_3b () {
+ test_create_repo 3b_$1 &&
(
- cd 3b &&
+ cd 3b_$1 &&
mkdir foo &&
test_seq 1 10 >bq &&
@@ -550,13 +543,12 @@ test_expect_success '3b-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3b reset --hard" &&
- test_when_finished "git -C 3b clean -fd" &&
+test_expect_success '3b-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3b L &&
(
- cd 3b &&
+ cd 3b_L &&
git checkout A^0 &&
@@ -581,11 +573,10 @@ test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
)
'
-test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3b reset --hard" &&
- test_when_finished "git -C 3b clean -fd" &&
+test_expect_success '3b-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3b R &&
(
- cd 3b &&
+ cd 3b_R &&
git checkout B^0 &&
@@ -621,7 +612,7 @@ test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
# Working copy: b_4
# Expected: b_2 for merge, b_4 in working copy
-test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods present' '
+test_setup_4a () {
test_create_repo 4a &&
(
cd 4a &&
@@ -647,7 +638,7 @@ test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods
test_tick &&
git commit -m "B"
)
-'
+}
# NOTE: For as long as we continue using unpack_trees() without index_only
# set to true, it will error out on a case like this claiming the the locally
@@ -655,9 +646,8 @@ test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods
# correct requires doing the merge in-memory first, then realizing that no
# updates to the file are necessary, and thus that we can just leave the path
# alone.
-test_expect_failure '4a-check: Change on A, change on B subset of A, dirty mods present' '
- test_when_finished "git -C 4a reset --hard" &&
- test_when_finished "git -C 4a clean -fd" &&
+test_expect_failure '4a: Change on A, change on B subset of A, dirty mods present' '
+ test_setup_4a &&
(
cd 4a &&
@@ -695,7 +685,7 @@ test_expect_failure '4a-check: Change on A, change on B subset of A, dirty mods
# Working copy: c_4
# Expected: c_2
-test_expect_success '4b-setup: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
+test_setup_4b () {
test_create_repo 4b &&
(
cd 4b &&
@@ -722,11 +712,10 @@ test_expect_success '4b-setup: Rename+Mod(A)/Mod(B), change on B subset of A, di
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '4b-check: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
- test_when_finished "git -C 4b reset --hard" &&
- test_when_finished "git -C 4b clean -fd" &&
+test_expect_success '4b: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
+ test_setup_4b &&
(
cd 4b &&
diff --git a/t/t6047-diff3-conflict-markers.sh b/t/t6047-diff3-conflict-markers.sh
new file mode 100755
index 0000000000..860542aad0
--- /dev/null
+++ b/t/t6047-diff3-conflict-markers.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+
+test_description='recursive merge diff3 style conflict markers'
+
+. ./test-lib.sh
+
+# Setup:
+# L1
+# \
+# ?
+# /
+# R1
+#
+# Where:
+# L1 and R1 both have a file named 'content' but have no common history
+#
+
+test_expect_success 'setup no merge base' '
+ test_create_repo no_merge_base &&
+ (
+ cd no_merge_base &&
+
+ git checkout -b L &&
+ test_commit A content A &&
+
+ git checkout --orphan R &&
+ test_commit B content B
+ )
+'
+
+test_expect_success 'check no merge base' '
+ (
+ cd no_merge_base &&
+
+ git checkout L^0 &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge --allow-unrelated-histories -s recursive R^0 &&
+
+ grep "|||||| empty tree" content
+ )
+'
+
+# Setup:
+# L1
+# / \
+# master ?
+# \ /
+# R1
+#
+# Where:
+# L1 and R1 have modified the same file ('content') in conflicting ways
+#
+
+test_expect_success 'setup unique merge base' '
+ test_create_repo unique_merge_base &&
+ (
+ cd unique_merge_base &&
+
+ test_commit base content "1
+2
+3
+4
+5
+" &&
+
+ git branch L &&
+ git branch R &&
+
+ git checkout L &&
+ test_commit L content "1
+2
+3
+4
+5
+7" &&
+
+ git checkout R &&
+ git rm content &&
+ test_commit R renamed "1
+2
+3
+4
+5
+six"
+ )
+'
+
+test_expect_success 'check unique merge base' '
+ (
+ cd unique_merge_base &&
+
+ git checkout L^0 &&
+ MASTER=$(git rev-parse --short master) &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R^0 &&
+
+ grep "|||||| $MASTER:content" renamed
+ )
+'
+
+# Setup:
+# L1---L2--L3
+# / \ / \
+# master X1 ?
+# \ / \ /
+# R1---R2--R3
+#
+# Where:
+# commits L1 and R1 have modified the same file in non-conflicting ways
+# X1 is an auto-generated merge-base used when merging L1 and R1
+# commits L2 and R2 are merges of R1 and L1 into L1 and R1, respectively
+# commits L3 and R3 both modify 'content' in conflicting ways
+#
+
+test_expect_success 'setup multiple merge bases' '
+ test_create_repo multiple_merge_bases &&
+ (
+ cd multiple_merge_bases &&
+
+ test_commit initial content "1
+2
+3
+4
+5" &&
+
+ git branch L &&
+ git branch R &&
+
+ # Create L1
+ git checkout L &&
+ test_commit L1 content "0
+1
+2
+3
+4
+5" &&
+
+ # Create R1
+ git checkout R &&
+ test_commit R1 content "1
+2
+3
+4
+5
+6" &&
+
+ # Create L2
+ git checkout L &&
+ git merge R1 &&
+
+ # Create R2
+ git checkout R &&
+ git merge L1 &&
+
+ # Create L3
+ git checkout L &&
+ test_commit L3 content "0
+1
+2
+3
+4
+5
+A" &&
+
+ # Create R3
+ git checkout R &&
+ git rm content &&
+ test_commit R3 renamed "0
+2
+3
+4
+5
+six"
+ )
+'
+
+test_expect_success 'check multiple merge bases' '
+ (
+ cd multiple_merge_bases &&
+
+ git checkout L^0 &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R^0 &&
+
+ grep "|||||| merged common ancestors:content" renamed
+ )
+'
+
+test_expect_success 'rebase describes fake ancestor base' '
+ test_create_repo rebase &&
+ (
+ cd rebase &&
+ test_commit base file &&
+ test_commit master file &&
+ git checkout -b side HEAD^ &&
+ test_commit side file &&
+ test_must_fail git -c merge.conflictstyle=diff3 rebase master &&
+ grep "||||||| constructed merge base" file
+ )
+'
+
+test_done
diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh
index 28611c978e..52cde097dd 100755
--- a/t/t6102-rev-list-unexpected-objects.sh
+++ b/t/t6102-rev-list-unexpected-objects.sh
@@ -52,7 +52,7 @@ test_expect_success 'traverse unexpected non-commit parent (lone)' '
'
test_expect_success 'traverse unexpected non-commit parent (seen)' '
- test_must_fail git rev-list --objects $commit $broken_commit \
+ test_must_fail git rev-list --objects $blob $broken_commit \
>output 2>&1 &&
test_i18ngrep "not a commit" output
'
diff --git a/t/t6112-rev-list-filters-objects.sh b/t/t6112-rev-list-filters-objects.sh
index acd7f5ab80..de0e5a5d36 100755
--- a/t/t6112-rev-list-filters-objects.sh
+++ b/t/t6112-rev-list-filters-objects.sh
@@ -278,7 +278,19 @@ test_expect_success 'verify skipping tree iteration when not collecting omits' '
test_line_count = 2 actual &&
# Make sure no other trees were considered besides the root.
- ! grep "Skipping contents of tree [^.]" filter_trace
+ ! grep "Skipping contents of tree [^.]" filter_trace &&
+
+ # Try this again with "combine:". If both sub-filters are skipping
+ # trees, the composite filter should also skip trees. This is not
+ # important unless the user does combine:tree:X+tree:Y or another filter
+ # besides "tree:" is implemented in the future which can skip trees.
+ GIT_TRACE=1 git -C r3 rev-list \
+ --objects --filter=combine:tree:1+tree:3 HEAD 2>filter_trace &&
+
+ # Only skip the dir1/ tree, which is shared between the two commits.
+ grep "Skipping contents of tree " filter_trace >actual &&
+ test_write_lines "Skipping contents of tree dir1/..." >expected &&
+ test_cmp expected actual
'
# Test tree:# filters.
@@ -330,6 +342,148 @@ test_expect_success 'verify tree:3 includes everything expected' '
test_line_count = 10 actual
'
+test_expect_success 'combine:... for a simple combination' '
+ git -C r3 rev-list --objects --filter=combine:tree:2+blob:none HEAD \
+ >actual &&
+
+ expect_has HEAD "" &&
+ expect_has HEAD~1 "" &&
+ expect_has HEAD dir1 &&
+
+ # There are also 2 commit objects
+ test_line_count = 5 actual &&
+
+ cp actual expected &&
+
+ # Try again using repeated --filter - this is equivalent to a manual
+ # combine with "combine:...+..."
+ git -C r3 rev-list --objects --filter=combine:tree:2 \
+ --filter=blob:none HEAD >actual &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'combine:... with URL encoding' '
+ git -C r3 rev-list --objects \
+ --filter=combine:tree%3a2+blob:%6Eon%65 HEAD >actual &&
+
+ expect_has HEAD "" &&
+ expect_has HEAD~1 "" &&
+ expect_has HEAD dir1 &&
+
+ # There are also 2 commit objects
+ test_line_count = 5 actual
+'
+
+expect_invalid_filter_spec () {
+ spec="$1" &&
+ err="$2" &&
+
+ test_must_fail git -C r3 rev-list --objects --filter="$spec" HEAD \
+ >actual 2>actual_stderr &&
+ test_must_be_empty actual &&
+ test_i18ngrep "$err" actual_stderr
+}
+
+test_expect_success 'combine:... while URL-encoding things that should not be' '
+ expect_invalid_filter_spec combine%3Atree:2+blob:none \
+ "invalid filter-spec"
+'
+
+test_expect_success 'combine: with nothing after the :' '
+ expect_invalid_filter_spec combine: "expected something after combine:"
+'
+
+test_expect_success 'parse error in first sub-filter in combine:' '
+ expect_invalid_filter_spec combine:tree:asdf+blob:none \
+ "expected .tree:<depth>."
+'
+
+test_expect_success 'combine:... with non-encoded reserved chars' '
+ expect_invalid_filter_spec combine:tree:2+sparse:@xyz \
+ "must escape char in sub-filter-spec: .@." &&
+ expect_invalid_filter_spec combine:tree:2+sparse:\` \
+ "must escape char in sub-filter-spec: .\`." &&
+ expect_invalid_filter_spec combine:tree:2+sparse:~abc \
+ "must escape char in sub-filter-spec: .\~."
+'
+
+test_expect_success 'validate err msg for "combine:<valid-filter>+"' '
+ expect_invalid_filter_spec combine:tree:2+ "expected .tree:<depth>."
+'
+
+test_expect_success 'combine:... with edge-case hex digits: Ff Aa 0 9' '
+ git -C r3 rev-list --objects --filter="combine:tree:2+bl%6Fb:n%6fne" \
+ HEAD >actual &&
+ test_line_count = 5 actual &&
+ git -C r3 rev-list --objects --filter="combine:tree%3A2+blob%3anone" \
+ HEAD >actual &&
+ test_line_count = 5 actual &&
+ git -C r3 rev-list --objects --filter="combine:tree:%30" HEAD >actual &&
+ test_line_count = 2 actual &&
+ git -C r3 rev-list --objects --filter="combine:tree:%39+blob:none" \
+ HEAD >actual &&
+ test_line_count = 5 actual
+'
+
+test_expect_success 'add sparse pattern blobs whose paths have reserved chars' '
+ cp r3/pattern r3/pattern1+renamed% &&
+ cp r3/pattern "r3/p;at%ter+n" &&
+ cp r3/pattern r3/^~pattern &&
+ git -C r3 add pattern1+renamed% "p;at%ter+n" ^~pattern &&
+ git -C r3 commit -m "add sparse pattern files with reserved chars"
+'
+
+test_expect_success 'combine:... with more than two sub-filters' '
+ git -C r3 rev-list --objects \
+ --filter=combine:tree:3+blob:limit=40+sparse:oid=master:pattern \
+ HEAD >actual &&
+
+ expect_has HEAD "" &&
+ expect_has HEAD~1 "" &&
+ expect_has HEAD~2 "" &&
+ expect_has HEAD dir1 &&
+ expect_has HEAD dir1/sparse1 &&
+ expect_has HEAD dir1/sparse2 &&
+
+ # Should also have 3 commits
+ test_line_count = 9 actual &&
+
+ # Try again, this time making sure the last sub-filter is only
+ # URL-decoded once.
+ cp actual expect &&
+
+ git -C r3 rev-list --objects \
+ --filter=combine:tree:3+blob:limit=40+sparse:oid=master:pattern1%2brenamed%25 \
+ HEAD >actual &&
+ test_cmp expect actual &&
+
+ # Use the same composite filter again, but with a pattern file name that
+ # requires encoding multiple characters, and use implicit filter
+ # combining.
+ test_when_finished "rm -f trace1" &&
+ GIT_TRACE=$(pwd)/trace1 git -C r3 rev-list --objects \
+ --filter=tree:3 --filter=blob:limit=40 \
+ --filter=sparse:oid="master:p;at%ter+n" \
+ HEAD >actual &&
+
+ test_cmp expect actual &&
+ grep "Add to combine filter-spec: sparse:oid=master:p%3bat%25ter%2bn" \
+ trace1 &&
+
+ # Repeat the above test, but this time, the characters to encode are in
+ # the LHS of the combined filter.
+ test_when_finished "rm -f trace2" &&
+ GIT_TRACE=$(pwd)/trace2 git -C r3 rev-list --objects \
+ --filter=sparse:oid=master:^~pattern \
+ --filter=tree:3 --filter=blob:limit=40 \
+ HEAD >actual &&
+
+ test_cmp expect actual &&
+ grep "Add to combine filter-spec: sparse:oid=master:%5e%7epattern" \
+ trace2
+'
+
# Test provisional omit collection logic with a repo that has objects appearing
# at multiple depths - first deeper than the filter's threshold, then shallow.
@@ -373,6 +527,37 @@ test_expect_success 'verify skipping tree iteration when collecting omits' '
test_cmp expect actual
'
+test_expect_success 'setup r5' '
+ git init r5 &&
+ mkdir -p r5/subdir &&
+
+ echo 1 >r5/short-root &&
+ echo 12345 >r5/long-root &&
+ echo a >r5/subdir/short-subdir &&
+ echo abcde >r5/subdir/long-subdir &&
+
+ git -C r5 add short-root long-root subdir &&
+ git -C r5 commit -m "commit msg"
+'
+
+test_expect_success 'verify collecting omits in combined: filter' '
+ # Note that this test guards against the naive implementation of simply
+ # giving both filters the same "omits" set and expecting it to
+ # automatically merge them.
+ git -C r5 rev-list --objects --quiet --filter-print-omitted \
+ --filter=combine:tree:2+blob:limit=3 HEAD >actual &&
+
+ # Expect 0 trees/commits, 3 blobs omitted (all blobs except short-root)
+ omitted_1=$(echo 12345 | git hash-object --stdin) &&
+ omitted_2=$(echo a | git hash-object --stdin) &&
+ omitted_3=$(echo abcde | git hash-object --stdin) &&
+
+ grep ~$omitted_1 actual &&
+ grep ~$omitted_2 actual &&
+ grep ~$omitted_3 actual &&
+ test_line_count = 3 actual
+'
+
# Test tree:<depth> where a tree is iterated to twice - once where a subentry is
# too deep to be included, and again where the blob inside it is shallow enough
# to be included. This makes sure we don't use LOFR_MARK_SEEN incorrectly (we
@@ -441,11 +626,4 @@ test_expect_success 'expand blob limit in protocol' '
grep "blob:limit=1024" trace
'
-test_expect_success 'expand tree depth limit in protocol' '
- GIT_TRACE_PACKET="$(pwd)/tree_trace" git -c protocol.version=2 clone \
- --filter=tree:0k "file://$(pwd)/r2" tree &&
- ! grep "tree:0k" tree_trace &&
- grep "tree:0" tree_trace
-'
-
test_done
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 2b883d8174..09c50f3f04 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -1,28 +1,27 @@
#!/bin/sh
-test_description='test describe
+test_description='test describe'
+
+# o---o-----o----o----o-------o----x
+# \ D,R e /
+# \---o-------------o-'
+# \ B /
+# `-o----o----o-'
+# A c
+#
+# First parent of a merge commit is on the same line, second parent below.
- B
- .--------------o----o----o----x
- / / /
- o----o----o----o----o----. /
- \ A c /
- .------------o---o---o
- D,R e
-'
. ./test-lib.sh
check_describe () {
expect="$1"
shift
- R=$(git describe "$@" 2>err.actual)
- S=$?
- cat err.actual >&3
- test_expect_success "describe $*" '
- test $S = 0 &&
+ describe_opts="$@"
+ test_expect_success "describe $describe_opts" '
+ R=$(git describe $describe_opts 2>err.actual) &&
case "$R" in
$expect) echo happy ;;
- *) echo "Oops - $R is not $expect";
+ *) echo "Oops - $R is not $expect" &&
false ;;
esac
'
@@ -382,7 +381,7 @@ test_expect_success 'describe tag object' '
test_i18ngrep "fatal: test-blob-1 is neither a commit nor blob" actual
'
-test_expect_failure ULIMIT_STACK_SIZE 'name-rev works in a deep repo' '
+test_expect_success ULIMIT_STACK_SIZE 'name-rev works in a deep repo' '
i=1 &&
while test $i -lt 8000
do
@@ -424,4 +423,60 @@ test_expect_success 'describe complains about missing object' '
test_must_fail git describe $ZERO_OID
'
+test_expect_success 'name-rev a rev shortly after epoch' '
+ test_when_finished "git checkout master" &&
+
+ git checkout --orphan no-timestamp-underflow &&
+ # Any date closer to epoch than the CUTOFF_DATE_SLOP constant
+ # in builtin/name-rev.c.
+ GIT_COMMITTER_DATE="@1234 +0000" \
+ git commit -m "committer date shortly after epoch" &&
+ old_commit_oid=$(git rev-parse HEAD) &&
+
+ echo "$old_commit_oid no-timestamp-underflow" >expect &&
+ git name-rev $old_commit_oid >actual &&
+ test_cmp expect actual
+'
+
+# A--------------master
+# \ /
+# \----------M2
+# \ /
+# \---M1-C
+# \ /
+# B
+test_expect_success 'name-rev covers all conditions while looking at parents' '
+ git init repo &&
+ (
+ cd repo &&
+
+ echo A >file &&
+ git add file &&
+ git commit -m A &&
+ A=$(git rev-parse HEAD) &&
+
+ git checkout --detach &&
+ echo B >file &&
+ git commit -m B file &&
+ B=$(git rev-parse HEAD) &&
+
+ git checkout $A &&
+ git merge --no-ff $B && # M1
+
+ echo C >file &&
+ git commit -m C file &&
+
+ git checkout $A &&
+ git merge --no-ff HEAD@{1} && # M2
+
+ git checkout master &&
+ git merge --no-ff HEAD@{1} &&
+
+ echo "$B master^2^2~1^2" >expect &&
+ git name-rev $B >actual &&
+
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index ab69aa176d..9c910ce746 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -526,6 +526,25 @@ test_expect_success 'Check ambiguous head and tag refs II (loose)' '
test_cmp expected actual
'
+test_expect_success 'create tag without tagger' '
+ git tag -a -m "Broken tag" taggerless &&
+ git tag -f taggerless $(git cat-file tag taggerless |
+ sed -e "/^tagger /d" |
+ git hash-object --stdin -w -t tag)
+'
+
+test_atom refs/tags/taggerless type 'commit'
+test_atom refs/tags/taggerless tag 'taggerless'
+test_atom refs/tags/taggerless tagger ''
+test_atom refs/tags/taggerless taggername ''
+test_atom refs/tags/taggerless taggeremail ''
+test_atom refs/tags/taggerless taggerdate ''
+test_atom refs/tags/taggerless committer ''
+test_atom refs/tags/taggerless committername ''
+test_atom refs/tags/taggerless committeremail ''
+test_atom refs/tags/taggerless committerdate ''
+test_atom refs/tags/taggerless subject 'Broken tag'
+
test_expect_success 'an unusual tag with an incomplete line' '
git tag -m "bogo" bogo &&
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index c0f04dc6b0..0a69a67117 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -103,14 +103,14 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre
'
test_expect_success 'gc --no-quiet' '
- git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
+ GIT_PROGRESS_DELAY=0 git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
test_must_be_empty stdout &&
- test_line_count = 1 stderr &&
test_i18ngrep "Computing commit graph generation numbers" stderr
'
test_expect_success TTY 'with TTY: gc --no-quiet' '
- test_terminal git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
+ test_terminal env GIT_PROGRESS_DELAY=0 \
+ git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
test_must_be_empty stdout &&
test_i18ngrep "Enumerating objects" stderr &&
test_i18ngrep "Computing commit graph generation numbers" stderr
diff --git a/t/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh
index 033871ee5f..f30b4849b6 100755
--- a/t/t6501-freshen-objects.sh
+++ b/t/t6501-freshen-objects.sh
@@ -137,7 +137,7 @@ test_expect_success 'do not complain about existing broken links (commit)' '
some message
EOF
commit=$(git hash-object -t commit -w broken-commit) &&
- git gc 2>stderr &&
+ git gc -q 2>stderr &&
verbose git cat-file -e $commit &&
test_must_be_empty stderr
'
@@ -147,7 +147,7 @@ test_expect_success 'do not complain about existing broken links (tree)' '
100644 blob 0000000000000000000000000000000000000003 foo
EOF
tree=$(git mktree --missing <broken-tree) &&
- git gc 2>stderr &&
+ git gc -q 2>stderr &&
git cat-file -e $tree &&
test_must_be_empty stderr
'
@@ -162,7 +162,7 @@ test_expect_success 'do not complain about existing broken links (tag)' '
this is a broken tag
EOF
tag=$(git hash-object -t tag -w broken-tag) &&
- git gc 2>stderr &&
+ git gc -q 2>stderr &&
git cat-file -e $tag &&
test_must_be_empty stderr
'
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 80eb13d94e..6db92bd3ba 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -227,10 +227,10 @@ test_expect_success \
test_expect_success \
'trying to delete two tags, existing and not, should fail in the 2nd' '
tag_exists mytag &&
- ! tag_exists myhead &&
- test_must_fail git tag -d mytag anothertag &&
+ ! tag_exists nonexistingtag &&
+ test_must_fail git tag -d mytag nonexistingtag &&
! tag_exists mytag &&
- ! tag_exists myhead
+ ! tag_exists nonexistingtag
'
test_expect_success 'trying to delete an already deleted tag should fail' \
@@ -517,7 +517,6 @@ test_expect_success \
test_expect_success \
'trying to create tags giving both -m or -F options should fail' '
echo "message file 1" >msgfile1 &&
- echo "message file 2" >msgfile2 &&
! tag_exists msgtag &&
test_must_fail git tag -m "message 1" -F msgfile1 msgtag &&
! tag_exists msgtag &&
@@ -1420,7 +1419,7 @@ test_expect_success \
get_tag_header reuse $commit commit $time >expect
echo "An annotation to be reused" >> expect
test_expect_success \
- 'overwriting an annoted tag should use its previous body' '
+ 'overwriting an annotated tag should use its previous body' '
git tag -a -m "An annotation to be reused" reuse &&
GIT_EDITOR=true git tag -f -a reuse &&
get_tag_msg reuse >actual &&
diff --git a/t/t7009-filter-branch-null-sha1.sh b/t/t7008-filter-branch-null-sha1.sh
index 9ba9f24ad2..9ba9f24ad2 100755
--- a/t/t7009-filter-branch-null-sha1.sh
+++ b/t/t7008-filter-branch-null-sha1.sh
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index 9d1abe50ef..7476781979 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -134,6 +134,21 @@ test_expect_success 'git-clean, dirty case' '
test_i18ncmp expected result
'
+test_expect_success '--ignore-skip-worktree-entries leaves worktree alone' '
+ test_commit keep-me &&
+ git update-index --skip-worktree keep-me.t &&
+ rm keep-me.t &&
+
+ : ignoring the worktree &&
+ git update-index --remove --ignore-skip-worktree-entries keep-me.t &&
+ git diff-index --cached --exit-code HEAD &&
+
+ : not ignoring the worktree, a deletion is staged &&
+ git update-index --remove keep-me.t &&
+ test_must_fail git diff-index --cached --exit-code HEAD \
+ --diff-filter=D -- keep-me.t
+'
+
#TODO test_expect_failure 'git-apply adds file' false
#TODO test_expect_failure 'git-apply updates file' false
#TODO test_expect_failure 'git-apply removes file' false
diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh
index 041e319e79..5c5bc32ccb 100755
--- a/t/t7030-verify-tag.sh
+++ b/t/t7030-verify-tag.sh
@@ -44,8 +44,8 @@ test_expect_success GPG 'create signed tags' '
test_expect_success GPGSM 'create signed tags x509 ' '
test_config gpg.format x509 &&
test_config user.signingkey $GIT_COMMITTER_EMAIL &&
- echo 9 >file && test_tick && git commit -a -m "nineth gpgsm-signed" &&
- git tag -s -m nineth nineth-signed-x509
+ echo 9 >file && test_tick && git commit -a -m "ninth gpgsm-signed" &&
+ git tag -s -m ninth ninth-signed-x509
'
test_expect_success GPG 'verify and show signatures' '
@@ -80,10 +80,34 @@ test_expect_success GPG 'verify and show signatures' '
'
test_expect_success GPGSM 'verify and show signatures x509' '
- git verify-tag nineth-signed-x509 2>actual &&
+ git verify-tag ninth-signed-x509 2>actual &&
grep "Good signature from" actual &&
! grep "BAD signature from" actual &&
- echo nineth-signed-x509 OK
+ echo ninth-signed-x509 OK
+'
+
+test_expect_success GPGSM 'verify and show signatures x509 with low minTrustLevel' '
+ test_config gpg.minTrustLevel undefined &&
+ git verify-tag ninth-signed-x509 2>actual &&
+ grep "Good signature from" actual &&
+ ! grep "BAD signature from" actual &&
+ echo ninth-signed-x509 OK
+'
+
+test_expect_success GPGSM 'verify and show signatures x509 with matching minTrustLevel' '
+ test_config gpg.minTrustLevel fully &&
+ git verify-tag ninth-signed-x509 2>actual &&
+ grep "Good signature from" actual &&
+ ! grep "BAD signature from" actual &&
+ echo ninth-signed-x509 OK
+'
+
+test_expect_success GPGSM 'verify and show signatures x509 with high minTrustLevel' '
+ test_config gpg.minTrustLevel ultimate &&
+ test_must_fail git verify-tag ninth-signed-x509 2>actual &&
+ grep "Good signature from" actual &&
+ ! grep "BAD signature from" actual &&
+ echo ninth-signed-x509 OK
'
test_expect_success GPG 'detect fudged signature' '
@@ -127,10 +151,10 @@ test_expect_success GPG 'verify signatures with --raw' '
'
test_expect_success GPGSM 'verify signatures with --raw x509' '
- git verify-tag --raw nineth-signed-x509 2>actual &&
+ git verify-tag --raw ninth-signed-x509 2>actual &&
grep "GOODSIG" actual &&
! grep "BADSIG" actual &&
- echo nineth-signed-x509 OK
+ echo ninth-signed-x509 OK
'
test_expect_success GPG 'verify multiple tags' '
@@ -147,7 +171,7 @@ test_expect_success GPG 'verify multiple tags' '
'
test_expect_success GPGSM 'verify multiple tags x509' '
- tags="seventh-signed nineth-signed-x509" &&
+ tags="seventh-signed ninth-signed-x509" &&
for i in $tags
do
git verify-tag -v --raw $i || return 1
diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh
index 0c394cf995..e4cf5484f9 100755
--- a/t/t7061-wtstatus-ignore.sh
+++ b/t/t7061-wtstatus-ignore.sh
@@ -43,11 +43,16 @@ test_expect_success 'status untracked directory with --ignored -u' '
test_cmp expected actual
'
cat >expected <<\EOF
-?? untracked/uncommitted
+?? untracked/
!! untracked/ignored
EOF
-test_expect_success 'status prefixed untracked directory with --ignored' '
+test_expect_success 'status of untracked directory with --ignored works with or without prefix' '
+ git status --porcelain --ignored >tmp &&
+ grep untracked/ tmp >actual &&
+ rm tmp &&
+ test_cmp expected actual &&
+
git status --porcelain --ignored untracked/ >actual &&
test_cmp expected actual
'
diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh
index bd10a96727..fc2a6cf5c7 100755
--- a/t/t7105-reset-patch.sh
+++ b/t/t7105-reset-patch.sh
@@ -38,6 +38,27 @@ test_expect_success PERL 'git reset -p HEAD^' '
test_i18ngrep "Apply" output
'
+test_expect_success PERL 'git reset -p HEAD^^{tree}' '
+ test_write_lines n y | git reset -p HEAD^^{tree} >output &&
+ verify_state dir/foo work parent &&
+ verify_saved_state bar &&
+ test_i18ngrep "Apply" output
+'
+
+test_expect_success PERL 'git reset -p HEAD^:dir/foo (blob fails)' '
+ set_and_save_state dir/foo work work &&
+ test_must_fail git reset -p HEAD^:dir/foo &&
+ verify_saved_state dir/foo &&
+ verify_saved_state bar
+'
+
+test_expect_success PERL 'git reset -p aaaaaaaa (unknown fails)' '
+ set_and_save_state dir/foo work work &&
+ test_must_fail git reset -p aaaaaaaa &&
+ verify_saved_state dir/foo &&
+ verify_saved_state bar
+'
+
# The idea in the rest is that bar sorts first, so we always say 'y'
# first and if the path limiter fails it'll apply to bar instead of
# dir/foo. There's always an extra 'n' to reject edits to dir/foo in
diff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh
new file mode 100755
index 0000000000..cad3a9de9e
--- /dev/null
+++ b/t/t7107-reset-pathspec-file.sh
@@ -0,0 +1,173 @@
+#!/bin/sh
+
+test_description='reset --pathspec-from-file'
+
+. ./test-lib.sh
+
+test_tick
+
+test_expect_success setup '
+ echo A >fileA.t &&
+ echo B >fileB.t &&
+ echo C >fileC.t &&
+ echo D >fileD.t &&
+ git add . &&
+ git commit --include . -m "Commit" &&
+ git tag checkpoint
+'
+
+restore_checkpoint () {
+ git reset --hard checkpoint
+}
+
+verify_expect () {
+ git status --porcelain -- fileA.t fileB.t fileC.t fileD.t >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success '--pathspec-from-file from stdin' '
+ restore_checkpoint &&
+
+ git rm fileA.t &&
+ echo fileA.t | git reset --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success '--pathspec-from-file from file' '
+ restore_checkpoint &&
+
+ git rm fileA.t &&
+ echo fileA.t >list &&
+ git reset --pathspec-from-file=list &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'NUL delimiters' '
+ restore_checkpoint &&
+
+ git rm fileA.t fileB.t &&
+ printf "fileA.t\0fileB.t\0" | git reset --pathspec-from-file=- --pathspec-file-nul &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ D fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'LF delimiters' '
+ restore_checkpoint &&
+
+ git rm fileA.t fileB.t &&
+ printf "fileA.t\nfileB.t\n" | git reset --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ D fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'no trailing delimiter' '
+ restore_checkpoint &&
+
+ git rm fileA.t fileB.t &&
+ printf "fileA.t\nfileB.t" | git reset --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ D fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'CRLF delimiters' '
+ restore_checkpoint &&
+
+ git rm fileA.t fileB.t &&
+ printf "fileA.t\r\nfileB.t\r\n" | git reset --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ D fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ git rm fileA.t &&
+ git reset --pathspec-from-file=list &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes not compatible with --pathspec-file-nul' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ # Note: "git reset" has not yet learned to fail on wrong pathspecs
+ git reset --pathspec-from-file=list --pathspec-file-nul &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ EOF
+ test_must_fail verify_expect
+'
+
+test_expect_success 'only touches what was listed' '
+ restore_checkpoint &&
+
+ git rm fileA.t fileB.t fileC.t fileD.t &&
+ printf "fileB.t\nfileC.t\n" | git reset --pathspec-from-file=- &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ D fileB.t
+ D fileC.t
+ D fileD.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'error conditions' '
+ restore_checkpoint &&
+ echo fileA.t >list &&
+ git rm fileA.t &&
+
+ test_must_fail git reset --pathspec-from-file=list --patch 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err &&
+
+ test_must_fail git reset --pathspec-from-file=list -- fileA.t 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err &&
+
+ test_must_fail git reset --pathspec-file-nul 2>err &&
+ test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err &&
+
+ test_must_fail git reset --soft --pathspec-from-file=list 2>err &&
+ test_i18ngrep -e "fatal: Cannot do soft reset with paths" err &&
+
+ test_must_fail git reset --hard --pathspec-from-file=list 2>err &&
+ test_i18ngrep -e "fatal: Cannot do hard reset with paths" err
+'
+
+test_done
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index a2c45d1902..cb5e34d94c 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -117,6 +117,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
would_clean=$(
cd docs &&
git clean -n ../src |
+ grep part3 |
sed -n -e "s|^Would remove ||p"
) &&
verbose test "$would_clean" = ../src/part3.c
@@ -129,6 +130,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with absolute path' '
would_clean=$(
cd docs &&
git clean -n "$(pwd)/../src" |
+ grep part3 |
sed -n -e "s|^Would remove ||p"
) &&
verbose test "$would_clean" = ../src/part3.c
@@ -547,7 +549,7 @@ test_expect_failure 'nested (non-empty) bare repositories should be cleaned even
test_path_is_missing strange_bare
'
-test_expect_success 'giving path in nested git work tree will remove it' '
+test_expect_success 'giving path in nested git work tree will NOT remove it' '
rm -fr repo &&
mkdir repo &&
(
@@ -559,7 +561,7 @@ test_expect_success 'giving path in nested git work tree will remove it' '
git clean -f -d repo/bar/baz &&
test_path_is_file repo/.git/HEAD &&
test_path_is_dir repo/bar/ &&
- test_path_is_missing repo/bar/baz
+ test_path_is_file repo/bar/baz/hello.world
'
test_expect_success 'giving path to nested .git will not remove it' '
@@ -577,7 +579,7 @@ test_expect_success 'giving path to nested .git will not remove it' '
test_path_is_dir untracked/
'
-test_expect_success 'giving path to nested .git/ will remove contents' '
+test_expect_success 'giving path to nested .git/ will NOT remove contents' '
rm -fr repo untracked &&
mkdir repo untracked &&
(
@@ -587,7 +589,7 @@ test_expect_success 'giving path to nested .git/ will remove contents' '
) &&
git clean -f -d repo/.git/ &&
test_path_is_dir repo/.git &&
- test_dir_is_empty repo/.git &&
+ test_path_is_file repo/.git/HEAD &&
test_path_is_dir untracked/
'
@@ -669,6 +671,60 @@ test_expect_success 'git clean -d skips untracked dirs containing ignored files'
test_path_is_missing foo/b/bb
'
+test_expect_success 'git clean -d skips nested repo containing ignored files' '
+ test_when_finished "rm -rf nested-repo-with-ignored-file" &&
+
+ git init nested-repo-with-ignored-file &&
+ (
+ cd nested-repo-with-ignored-file &&
+ >file &&
+ git add file &&
+ git commit -m Initial &&
+
+ # This file is ignored by a .gitignore rule in the outer repo
+ # added in the previous test.
+ >ignoreme
+ ) &&
+
+ git clean -fd &&
+
+ test_path_is_file nested-repo-with-ignored-file/.git/index &&
+ test_path_is_file nested-repo-with-ignored-file/ignoreme &&
+ test_path_is_file nested-repo-with-ignored-file/file
+'
+
+test_expect_success 'git clean handles being told what to clean' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -f */ut &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
+test_expect_success 'git clean handles being told what to clean, with -d' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -ffd */ut &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
+test_expect_success 'git clean works if a glob is passed without -d' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -f "*ut" &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
+test_expect_success 'git clean works if a glob is passed with -d' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -ffd "*ut" &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
test_expect_success MINGW 'handle clean & core.longpaths = false nicely' '
test_config core.longpaths false &&
a50=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
@@ -681,4 +737,13 @@ test_expect_success MINGW 'handle clean & core.longpaths = false nicely' '
test_i18ngrep "too long" .git/err
'
+test_expect_success 'clean untracked paths by pathspec' '
+ git init untracked &&
+ mkdir untracked/dir &&
+ echo >untracked/dir/file.txt &&
+ git -C untracked clean -f dir/file.txt &&
+ ls untracked/dir >actual &&
+ test_must_be_empty actual
+'
+
test_done
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index a208cb26e1..7e8925a8ee 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -156,9 +156,11 @@ test_expect_success 'submodule add to .gitignored path fails' '
(
cd addtest-ignore &&
cat <<-\EOF >expect &&
- The following path is ignored by one of your .gitignore files:
+ The following paths are ignored by one of your .gitignore files:
submod
- Use -f if you really want to add it.
+ hint: Use -f if you really want to add them.
+ hint: Turn this message off by running
+ hint: "git config advice.addIgnoredFile false"
EOF
# Does not use test_commit due to the ignore
echo "*" > .gitignore &&
@@ -191,6 +193,17 @@ test_expect_success 'submodule add to reconfigure existing submodule with --forc
)
'
+test_expect_success 'submodule add relays add --dry-run stderr' '
+ test_when_finished "rm -rf addtest/.git/index.lock" &&
+ (
+ cd addtest &&
+ : >.git/index.lock &&
+ ! git submodule add "$submodurl" sub-while-locked 2>output.err &&
+ test_i18ngrep "^fatal: .*index\.lock" output.err &&
+ test_path_is_missing sub-while-locked
+ )
+'
+
test_expect_success 'submodule add --branch' '
echo "refs/heads/initial" >expect-head &&
cat <<-\EOF >expect-heads &&
@@ -356,6 +369,28 @@ test_expect_success 'status should only print one line' '
test_line_count = 1 lines
'
+test_expect_success 'status from subdirectory should have the same SHA1' '
+ test_when_finished "rmdir addtest/subdir" &&
+ (
+ cd addtest &&
+ mkdir subdir &&
+ git submodule status >output &&
+ awk "{print \$1}" <output >expect &&
+ cd subdir &&
+ git submodule status >../output &&
+ awk "{print \$1}" <../output >../actual &&
+ test_cmp ../expect ../actual &&
+ git -C ../submod checkout HEAD^ &&
+ git submodule status >../output &&
+ awk "{print \$1}" <../output >../actual2 &&
+ cd .. &&
+ git submodule status >output &&
+ awk "{print \$1}" <output >expect2 &&
+ test_cmp expect2 actual2 &&
+ ! test_cmp actual actual2
+ )
+'
+
test_expect_success 'setup - fetch commit name from submodule' '
rev1=$(cd .subrepo && git rev-parse HEAD) &&
printf "rev1: %s\n" "$rev1" &&
@@ -527,7 +562,6 @@ test_expect_success 'update --init' '
test_must_fail git config submodule.example.url &&
git submodule update init 2> update.out &&
- cat update.out &&
test_i18ngrep "not initialized" update.out &&
test_must_fail git rev-parse --resolve-git-dir init/.git &&
@@ -545,7 +579,6 @@ test_expect_success 'update --init from subdirectory' '
(
cd sub &&
git submodule update ../init 2>update.out &&
- cat update.out &&
test_i18ngrep "not initialized" update.out &&
test_must_fail git rev-parse --resolve-git-dir ../init/.git &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index bce9138d7f..4fb447a143 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -158,7 +158,6 @@ test_expect_success 'submodule update --init from and of subdirectory' '
test_i18ncmp expect2 actual2
'
-apos="'";
test_expect_success 'submodule update does not fetch already present commits' '
(cd submodule &&
echo line3 >> file &&
@@ -168,7 +167,7 @@ test_expect_success 'submodule update does not fetch already present commits' '
) &&
(cd super/submodule &&
head=$(git rev-parse --verify HEAD) &&
- echo "Submodule path ${apos}submodule$apos: checked out $apos$head$apos" > ../../expected &&
+ echo "Submodule path ${SQ}submodule$SQ: checked out $SQ$head$SQ" > ../../expected &&
git reset --hard HEAD~1
) &&
(cd super &&
@@ -961,7 +960,7 @@ test_expect_success 'submodule update clone shallow submodule outside of depth'
mv -f .gitmodules.tmp .gitmodules &&
# Some protocol versions (e.g. 2) support fetching
# unadvertised objects, so restrict this test to v0.
- test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
git submodule update --init --depth=1 2>actual &&
test_i18ngrep "Direct fetching of that commit failed." actual &&
git -C ../submodule config uploadpack.allowReachableSHA1InWant true &&
diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh
deleted file mode 100755
index f1b492ebc4..0000000000
--- a/t/t7410-submodule-checkout-to.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/bin/sh
-
-test_description='Combination of submodules and multiple workdirs'
-
-. ./test-lib.sh
-
-base_path=$(pwd -P)
-
-test_expect_success 'setup: make origin' '
- mkdir -p origin/sub &&
- (
- cd origin/sub && git init &&
- echo file1 >file1 &&
- git add file1 &&
- git commit -m file1
- ) &&
- mkdir -p origin/main &&
- (
- cd origin/main && git init &&
- git submodule add ../sub &&
- git commit -m "add sub"
- ) &&
- (
- cd origin/sub &&
- echo file1updated >file1 &&
- git add file1 &&
- git commit -m "file1 updated"
- ) &&
- git -C origin/main/sub pull &&
- (
- cd origin/main &&
- git add sub &&
- git commit -m "sub updated"
- )
-'
-
-test_expect_success 'setup: clone' '
- mkdir clone &&
- git -C clone clone --recursive "$base_path/origin/main"
-'
-
-rev1_hash_main=$(git --git-dir=origin/main/.git show --pretty=format:%h -q "HEAD~1")
-rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1")
-
-test_expect_success 'checkout main' '
- mkdir default_checkout &&
- git -C clone/main worktree add "$base_path/default_checkout/main" "$rev1_hash_main"
-'
-
-test_expect_failure 'can see submodule diffs just after checkout' '
- git -C default_checkout/main diff --submodule master"^!" >out &&
- grep "file1 updated" out
-'
-
-test_expect_success 'checkout main and initialize independent clones' '
- mkdir fully_cloned_submodule &&
- git -C clone/main worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main" &&
- git -C fully_cloned_submodule/main submodule update
-'
-
-test_expect_success 'can see submodule diffs after independent cloning' '
- git -C fully_cloned_submodule/main diff --submodule master"^!" >out &&
- grep "file1 updated" out
-'
-
-test_expect_success 'checkout sub manually' '
- mkdir linked_submodule &&
- git -C clone/main worktree add "$base_path/linked_submodule/main" "$rev1_hash_main" &&
- git -C clone/main/sub worktree add "$base_path/linked_submodule/main/sub" "$rev1_hash_sub"
-'
-
-test_expect_success 'can see submodule diffs after manual checkout of linked submodule' '
- git -C linked_submodule/main diff --submodule master"^!" >out &&
- grep "file1 updated" out
-'
-
-test_done
diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh
index 905a557585..f70368bc2e 100755
--- a/t/t7415-submodule-names.sh
+++ b/t/t7415-submodule-names.sh
@@ -207,6 +207,9 @@ test_expect_success MINGW 'prevent git~1 squatting on Windows' '
git hash-object -w --stdin)" &&
rev="$(git rev-parse --verify HEAD)" &&
hash="$(echo x | git hash-object -w --stdin)" &&
+ test_must_fail git update-index --add \
+ --cacheinfo 160000,$rev,d\\a 2>err &&
+ test_i18ngrep "Invalid path" err &&
git -c core.protectNTFS=false update-index --add \
--cacheinfo 100644,$modules,.gitmodules \
--cacheinfo 160000,$rev,c \
@@ -214,9 +217,7 @@ test_expect_success MINGW 'prevent git~1 squatting on Windows' '
--cacheinfo 100644,$hash,d./a/x \
--cacheinfo 100644,$hash,d./a/..git &&
test_tick &&
- git -c core.protectNTFS=false commit -m "module" &&
- test_must_fail git show HEAD: 2>err &&
- test_i18ngrep backslash err
+ git -c core.protectNTFS=false commit -m "module"
) &&
test_must_fail git -c core.protectNTFS=false \
clone --recurse-submodules squatting squatting-clone 2>err &&
diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh
index c4b370ea85..fd25f786a3 100755
--- a/t/t7419-submodule-set-branch.sh
+++ b/t/t7419-submodule-set-branch.sh
@@ -34,7 +34,7 @@ test_expect_success 'submodule config cache setup' '
test_expect_success 'ensure submodule branch is unset' '
(cd super &&
- test_must_fail grep branch .gitmodules
+ ! grep branch .gitmodules
)
'
@@ -54,7 +54,7 @@ test_expect_success 'test submodule set-branch --branch' '
test_expect_success 'test submodule set-branch --default' '
(cd super &&
git submodule set-branch --default submodule &&
- test_must_fail grep branch .gitmodules &&
+ ! grep branch .gitmodules &&
git submodule update --remote &&
cat <<-\EOF >expect &&
a
@@ -80,7 +80,7 @@ test_expect_success 'test submodule set-branch -b' '
test_expect_success 'test submodule set-branch -d' '
(cd super &&
git submodule set-branch -d submodule &&
- test_must_fail grep branch .gitmodules &&
+ ! grep branch .gitmodules &&
git submodule update --remote &&
cat <<-\EOF >expect &&
a
diff --git a/t/t7420-submodule-set-url.sh b/t/t7420-submodule-set-url.sh
new file mode 100755
index 0000000000..ef0cb6e8e1
--- /dev/null
+++ b/t/t7420-submodule-set-url.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='Test submodules set-url subcommand
+
+This test verifies that the set-url subcommand of git-submodule is working
+as expected.
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+
+test_expect_success 'submodule config cache setup' '
+ mkdir submodule &&
+ (
+ cd submodule &&
+ git init &&
+ echo a >file &&
+ git add file &&
+ git commit -ma
+ ) &&
+ mkdir super &&
+ (
+ cd super &&
+ git init &&
+ git submodule add ../submodule &&
+ git commit -m "add submodule"
+ )
+'
+
+test_expect_success 'test submodule set-url' '
+ # add a commit and move the submodule (change the url)
+ (
+ cd submodule &&
+ echo b >>file &&
+ git add file &&
+ git commit -mb
+ ) &&
+ mv submodule newsubmodule &&
+
+ git -C newsubmodule show >expect &&
+ (
+ cd super &&
+ test_must_fail git submodule update --remote &&
+ git submodule set-url submodule ../newsubmodule &&
+ grep -F "url = ../newsubmodule" .gitmodules &&
+ git submodule update --remote
+ ) &&
+ git -C super/submodule show >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh
index 46a5cd4b73..6d19ece05d 100755
--- a/t/t7500-commit-template-squash-signoff.sh
+++ b/t/t7500-commit-template-squash-signoff.sh
@@ -382,4 +382,13 @@ test_expect_success 'check commit with unstaged rename and copy' '
)
'
+test_expect_success 'commit without staging files fails and displays hints' '
+ echo "initial" >file &&
+ git add file &&
+ git commit -m initial &&
+ echo "changes" >>file &&
+ test_must_fail git commit -m update >actual &&
+ test_i18ngrep "no changes added to commit (use \"git add\" and/or \"git commit -a\")" actual
+'
+
test_done
diff --git a/t/t7501-commit-basic-functionality.sh b/t/t7501-commit-basic-functionality.sh
index f1349af56e..110b4bf459 100755
--- a/t/t7501-commit-basic-functionality.sh
+++ b/t/t7501-commit-basic-functionality.sh
@@ -150,7 +150,7 @@ test_expect_success 'setup: commit message from file' '
test_expect_success 'amend commit' '
cat >editor <<-\EOF &&
#!/bin/sh
- sed -e "s/a file/an amend commit/g" < "$1" > "$1-"
+ sed -e "s/a file/an amend commit/g" <"$1" >"$1-"
mv "$1-" "$1"
EOF
chmod 755 editor &&
@@ -263,7 +263,7 @@ test_expect_success 'using message from other commit' '
test_expect_success 'editing message from other commit' '
cat >editor <<-\EOF &&
#!/bin/sh
- sed -e "s/amend/older/g" < "$1" > "$1-"
+ sed -e "s/amend/older/g" <"$1" >"$1-"
mv "$1-" "$1"
EOF
chmod 755 editor &&
@@ -285,9 +285,8 @@ test_expect_success 'overriding author from command line' '
'
test_expect_success PERL 'interactive add' '
- echo 7 |
- git commit --interactive |
- grep "What now"
+ echo 7 | test_must_fail git commit --interactive >out &&
+ grep "What now" out
'
test_expect_success PERL "commit --interactive doesn't change index if editor aborts" '
@@ -362,12 +361,12 @@ test_expect_success 'amend commit to fix author' '
oldtick=$GIT_AUTHOR_DATE &&
test_tick &&
git reset --hard &&
- git cat-file -p HEAD |
+ git cat-file -p HEAD >commit &&
sed -e "s/author.*/author $author $oldtick/" \
- -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
- expected &&
+ -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \
+ commit >expected &&
git commit --amend --author="$author" &&
- git cat-file -p HEAD > current &&
+ git cat-file -p HEAD >current &&
test_cmp expected current
'
@@ -377,12 +376,12 @@ test_expect_success 'amend commit to fix date' '
test_tick &&
newtick=$GIT_AUTHOR_DATE &&
git reset --hard &&
- git cat-file -p HEAD |
+ git cat-file -p HEAD >commit &&
sed -e "s/author.*/author $author $newtick/" \
- -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
- expected &&
+ -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \
+ commit >expected &&
git commit --amend --date="$newtick" &&
- git cat-file -p HEAD > current &&
+ git cat-file -p HEAD >current &&
test_cmp expected current
'
@@ -409,12 +408,13 @@ test_expect_success 'sign off (1)' '
echo 1 >positive &&
git add positive &&
git commit -s -m "thank you" &&
- git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+ git cat-file commit HEAD >commit &&
+ sed -e "1,/^\$/d" commit >actual &&
(
echo thank you &&
echo &&
- git var GIT_COMMITTER_IDENT |
- sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
+ git var GIT_COMMITTER_IDENT >ident &&
+ sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
) >expected &&
test_cmp expected actual
@@ -428,13 +428,14 @@ test_expect_success 'sign off (2)' '
git commit -s -m "thank you
$existing" &&
- git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+ git cat-file commit HEAD >commit &&
+ sed -e "1,/^\$/d" commit >actual &&
(
echo thank you &&
echo &&
echo $existing &&
- git var GIT_COMMITTER_IDENT |
- sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
+ git var GIT_COMMITTER_IDENT >ident &&
+ sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
) >expected &&
test_cmp expected actual
@@ -448,13 +449,14 @@ test_expect_success 'signoff gap' '
git commit -s -m "welcome
$alt" &&
- git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
+ git cat-file commit HEAD >commit &&
+ sed -e "1,/^\$/d" commit >actual &&
(
echo welcome &&
echo &&
echo $alt &&
- git var GIT_COMMITTER_IDENT |
- sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
+ git var GIT_COMMITTER_IDENT >ident &&
+ sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
) >expected &&
test_cmp expected actual
'
@@ -468,15 +470,16 @@ test_expect_success 'signoff gap 2' '
We have now
$alt" &&
- git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
+ git cat-file commit HEAD >commit &&
+ sed -e "1,/^\$/d" commit >actual &&
(
echo welcome &&
echo &&
echo We have now &&
echo $alt &&
echo &&
- git var GIT_COMMITTER_IDENT |
- sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
+ git var GIT_COMMITTER_IDENT >ident &&
+ sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
) >expected &&
test_cmp expected actual
'
@@ -489,7 +492,8 @@ test_expect_success 'signoff respects trailer config' '
non-trailer line
Myfooter: x" &&
- git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
+ git cat-file commit HEAD >commit &&
+ sed -e "1,/^\$/d" commit >actual &&
(
echo subject &&
echo &&
@@ -506,7 +510,8 @@ Myfooter: x" &&
non-trailer line
Myfooter: x" &&
- git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
+ git cat-file commit HEAD >commit &&
+ sed -e "1,/^\$/d" commit >actual &&
(
echo subject &&
echo &&
@@ -538,7 +543,8 @@ test_expect_success 'multiple -m' '
>negative &&
git add negative &&
git commit -m "one" -m "two" -m "three" &&
- git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+ git cat-file commit HEAD >commit &&
+ sed -e "1,/^\$/d" commit >actual &&
(
echo one &&
echo &&
@@ -555,23 +561,25 @@ test_expect_success 'amend commit to fix author' '
oldtick=$GIT_AUTHOR_DATE &&
test_tick &&
git reset --hard &&
- git cat-file -p HEAD |
+ git cat-file -p HEAD >commit &&
sed -e "s/author.*/author $author $oldtick/" \
- -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
- expected &&
+ -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \
+ commit >expected &&
git commit --amend --author="$author" &&
- git cat-file -p HEAD > current &&
+ git cat-file -p HEAD >current &&
test_cmp expected current
'
test_expect_success 'git commit <file> with dirty index' '
- echo tacocat > elif &&
- echo tehlulz > chz &&
+ echo tacocat >elif &&
+ echo tehlulz >chz &&
git add chz &&
git commit elif -m "tacocat is a palindrome" &&
- git show --stat | grep elif &&
- git diff --cached | grep chz
+ git show --stat >stat &&
+ grep elif stat &&
+ git diff --cached >diff &&
+ grep chz diff
'
test_expect_success 'same tree (single parent)' '
@@ -584,7 +592,8 @@ test_expect_success 'same tree (single parent)' '
test_expect_success 'same tree (single parent) --allow-empty' '
git commit --allow-empty -m "forced empty" &&
- git cat-file commit HEAD | grep forced
+ git cat-file commit HEAD >commit &&
+ grep forced commit
'
diff --git a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
new file mode 100755
index 0000000000..b3485450a2
--- /dev/null
+++ b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
@@ -0,0 +1,281 @@
+#!/bin/sh
+
+test_description='pre-commit and pre-merge-commit hooks'
+
+. ./test-lib.sh
+
+HOOKDIR="$(git rev-parse --git-dir)/hooks"
+PRECOMMIT="$HOOKDIR/pre-commit"
+PREMERGE="$HOOKDIR/pre-merge-commit"
+
+# Prepare sample scripts that write their $0 to actual_hooks
+test_expect_success 'sample script setup' '
+ mkdir -p "$HOOKDIR" &&
+ write_script "$HOOKDIR/success.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ exit 0
+ EOF
+ write_script "$HOOKDIR/fail.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ exit 1
+ EOF
+ write_script "$HOOKDIR/non-exec.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ exit 1
+ EOF
+ chmod -x "$HOOKDIR/non-exec.sample" &&
+ write_script "$HOOKDIR/require-prefix.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ test $GIT_PREFIX = "success/"
+ EOF
+ write_script "$HOOKDIR/check-author.sample" <<-\EOF
+ echo $0 >>actual_hooks
+ test "$GIT_AUTHOR_NAME" = "New Author" &&
+ test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
+ EOF
+'
+
+test_expect_success 'root commit' '
+ echo "root" >file &&
+ git add file &&
+ git commit -m "zeroth" &&
+ git checkout -b side &&
+ echo "foo" >foo &&
+ git add foo &&
+ git commit -m "make it non-ff" &&
+ git branch side-orig side &&
+ git checkout master
+'
+
+test_expect_success 'setup conflicting branches' '
+ test_when_finished "git checkout master" &&
+ git checkout -b conflicting-a master &&
+ echo a >conflicting &&
+ git add conflicting &&
+ git commit -m conflicting-a &&
+ git checkout -b conflicting-b master &&
+ echo b >conflicting &&
+ git add conflicting &&
+ git commit -m conflicting-b
+'
+
+test_expect_success 'with no hook' '
+ test_when_finished "rm -f actual_hooks" &&
+ echo "foo" >file &&
+ git add file &&
+ git commit -m "first" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with no hook (merge)' '
+ test_when_finished "rm -f actual_hooks" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success '--no-verify with no hook' '
+ test_when_finished "rm -f actual_hooks" &&
+ echo "bar" >file &&
+ git add file &&
+ git commit --no-verify -m "bar" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success '--no-verify with no hook (merge)' '
+ test_when_finished "rm -f actual_hooks" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with succeeding hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "more" >>file &&
+ git add file &&
+ git commit -m "more" &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'with succeeding hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PREMERGE" &&
+ echo "$PREMERGE" >expected_hooks &&
+ git checkout side &&
+ git merge -m "merge master" master &&
+ git checkout master &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'automatic merge fails; both hooks are available' '
+ test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" &&
+ test_when_finished "rm -f expected_hooks actual_hooks" &&
+ test_when_finished "git checkout master" &&
+ cp "$HOOKDIR/success.sample" "$PREMERGE" &&
+ cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+
+ git checkout conflicting-a &&
+ test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
+ test_path_is_missing actual_hooks &&
+
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo a+b >conflicting &&
+ git add conflicting &&
+ git commit -m "resolve conflict" &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success '--no-verify with succeeding hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+ echo "even more" >>file &&
+ git add file &&
+ git commit --no-verify -m "even more" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success '--no-verify with succeeding hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with failing hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "another" >>file &&
+ git add file &&
+ test_must_fail git commit -m "another" &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success '--no-verify with failing hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
+ echo "stuff" >>file &&
+ git add file &&
+ git commit --no-verify -m "stuff" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with failing hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
+ echo "$PREMERGE" >expected_hooks &&
+ git checkout side &&
+ test_must_fail git merge -m "merge master" master &&
+ git checkout master &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success '--no-verify with failing hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM 'with non-executable hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
+ echo "content" >>file &&
+ git add file &&
+ git commit -m "content" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM '--no-verify with non-executable hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
+ echo "more content" >>file &&
+ git add file &&
+ git commit --no-verify -m "more content" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM 'with non-executable hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with hook requiring GIT_PREFIX' '
+ test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" &&
+ cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "more content" >>file &&
+ git add file &&
+ mkdir success &&
+ (
+ cd success &&
+ git commit -m "hook requires GIT_PREFIX = success/"
+ ) &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'with failing hook requiring GIT_PREFIX' '
+ test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" &&
+ cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "more content" >>file &&
+ git add file &&
+ mkdir fail &&
+ (
+ cd fail &&
+ test_must_fail git commit -m "hook must fail"
+ ) &&
+ git checkout -- file &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'check the author in hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" &&
+ cat >expected_hooks <<-EOF &&
+ $PRECOMMIT
+ $PRECOMMIT
+ $PRECOMMIT
+ EOF
+ test_must_fail git commit --allow-empty -m "by a.u.thor" &&
+ (
+ GIT_AUTHOR_NAME="New Author" &&
+ GIT_AUTHOR_EMAIL="newauthor@example.com" &&
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
+ git commit --allow-empty -m "by new.author via env" &&
+ git show -s
+ ) &&
+ git commit --author="New Author <newauthor@example.com>" \
+ --allow-empty -m "by new.author via command line" &&
+ git show -s &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_done
diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-hook.sh
deleted file mode 100755
index 984889b39d..0000000000
--- a/t/t7503-pre-commit-hook.sh
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/bin/sh
-
-test_description='pre-commit hook'
-
-. ./test-lib.sh
-
-test_expect_success 'with no hook' '
-
- echo "foo" > file &&
- git add file &&
- git commit -m "first"
-
-'
-
-test_expect_success '--no-verify with no hook' '
-
- echo "bar" > file &&
- git add file &&
- git commit --no-verify -m "bar"
-
-'
-
-# now install hook that always succeeds
-HOOKDIR="$(git rev-parse --git-dir)/hooks"
-HOOK="$HOOKDIR/pre-commit"
-mkdir -p "$HOOKDIR"
-cat > "$HOOK" <<EOF
-#!/bin/sh
-exit 0
-EOF
-chmod +x "$HOOK"
-
-test_expect_success 'with succeeding hook' '
-
- echo "more" >> file &&
- git add file &&
- git commit -m "more"
-
-'
-
-test_expect_success '--no-verify with succeeding hook' '
-
- echo "even more" >> file &&
- git add file &&
- git commit --no-verify -m "even more"
-
-'
-
-# now a hook that fails
-cat > "$HOOK" <<EOF
-#!/bin/sh
-exit 1
-EOF
-
-test_expect_success 'with failing hook' '
-
- echo "another" >> file &&
- git add file &&
- test_must_fail git commit -m "another"
-
-'
-
-test_expect_success '--no-verify with failing hook' '
-
- echo "stuff" >> file &&
- git add file &&
- git commit --no-verify -m "stuff"
-
-'
-
-chmod -x "$HOOK"
-test_expect_success POSIXPERM 'with non-executable hook' '
-
- echo "content" >> file &&
- git add file &&
- git commit -m "content"
-
-'
-
-test_expect_success POSIXPERM '--no-verify with non-executable hook' '
-
- echo "more content" >> file &&
- git add file &&
- git commit --no-verify -m "more content"
-
-'
-chmod +x "$HOOK"
-
-# a hook that checks $GIT_PREFIX and succeeds inside the
-# success/ subdirectory only
-cat > "$HOOK" <<EOF
-#!/bin/sh
-test \$GIT_PREFIX = success/
-EOF
-
-test_expect_success 'with hook requiring GIT_PREFIX' '
-
- echo "more content" >> file &&
- git add file &&
- mkdir success &&
- (
- cd success &&
- git commit -m "hook requires GIT_PREFIX = success/"
- ) &&
- rmdir success
-'
-
-test_expect_success 'with failing hook requiring GIT_PREFIX' '
-
- echo "more content" >> file &&
- git add file &&
- mkdir fail &&
- (
- cd fail &&
- test_must_fail git commit -m "hook must fail"
- ) &&
- rmdir fail &&
- git checkout -- file
-'
-
-test_expect_success 'check the author in hook' '
- write_script "$HOOK" <<-\EOF &&
- test "$GIT_AUTHOR_NAME" = "New Author" &&
- test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
- EOF
- test_must_fail git commit --allow-empty -m "by a.u.thor" &&
- (
- GIT_AUTHOR_NAME="New Author" &&
- GIT_AUTHOR_EMAIL="newauthor@example.com" &&
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
- git commit --allow-empty -m "by new.author via env" &&
- git show -s
- ) &&
- git commit --author="New Author <newauthor@example.com>" \
- --allow-empty -m "by new.author via command line" &&
- git show -s
-'
-
-test_done
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index ba8bd1b514..94f85cdf83 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -241,13 +241,7 @@ test_rebase () {
git add b &&
git rebase --continue
) &&
- if test "$mode" = -p # reword amended after pick
- then
- n=18
- else
- n=17
- fi &&
- git log --pretty=%s -g -n$n HEAD@{1} >actual &&
+ git log --pretty=%s -g -n18 HEAD@{1} >actual &&
test_cmp "$TEST_DIRECTORY/t7505/expected-rebase${mode:--i}" actual
'
}
diff --git a/t/t7505/expected-rebase-i b/t/t7505/expected-rebase-i
index c514bdbb94..93bada596e 100644
--- a/t/t7505/expected-rebase-i
+++ b/t/t7505/expected-rebase-i
@@ -7,7 +7,8 @@ message (no editor) [edit rebase-10]
message [fixup rebase-9]
message (no editor) [fixup rebase-8]
message (no editor) [squash rebase-7]
-message [reword rebase-6]
+HEAD [reword rebase-6]
+message (no editor) [reword rebase-6]
message [squash rebase-5]
message (no editor) [fixup rebase-4]
message (no editor) [pick rebase-3]
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index 4e676cdce8..482ce3510e 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -1571,7 +1571,7 @@ test_expect_success '"status.showStash=true" weaker than "--no-show-stash"' '
test_cmp expected_without_stash actual
'
-test_expect_success 'no additionnal info if no stash entries' '
+test_expect_success 'no additional info if no stash entries' '
git stash clear &&
git -c status.showStash=true status >actual &&
test_cmp expected_without_stash actual
diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh
index 682b23a068..0c06d22a00 100755
--- a/t/t7510-signed-commit.sh
+++ b/t/t7510-signed-commit.sh
@@ -109,6 +109,21 @@ test_expect_success GPG 'verify-commit exits success on untrusted signature' '
grep "not certified" actual
'
+test_expect_success GPG 'verify-commit exits success with matching minTrustLevel' '
+ test_config gpg.minTrustLevel ultimate &&
+ git verify-commit sixth-signed
+'
+
+test_expect_success GPG 'verify-commit exits success with low minTrustLevel' '
+ test_config gpg.minTrustLevel fully &&
+ git verify-commit sixth-signed
+'
+
+test_expect_success GPG 'verify-commit exits failure with high minTrustLevel' '
+ test_config gpg.minTrustLevel ultimate &&
+ test_must_fail git verify-commit eighth-signed-alt
+'
+
test_expect_success GPG 'verify signatures with --raw' '
(
for commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed
@@ -219,6 +234,30 @@ test_expect_success GPG 'show untrusted signature with custom format' '
test_cmp expect actual
'
+test_expect_success GPG 'show untrusted signature with undefined trust level' '
+ cat >expect <<-\EOF &&
+ undefined
+ 65A0EEA02E30CAD7
+ Eris Discordia <discord@example.net>
+ F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7
+ D4BE22311AD3131E5EDA29A461092E85B7227189
+ EOF
+ git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success GPG 'show untrusted signature with ultimate trust level' '
+ cat >expect <<-\EOF &&
+ ultimate
+ 13B6F51ECDDE430D
+ C O Mitter <committer@example.com>
+ 73D758744BE721698EC54E8713B6F51ECDDE430D
+ 73D758744BE721698EC54E8713B6F51ECDDE430D
+ EOF
+ git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
+ test_cmp expect actual
+'
+
test_expect_success GPG 'show unknown signature with custom format' '
cat >expect <<-\EOF &&
E
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index e01c285cbf..66d7a62797 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -733,6 +733,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '
On branch cherry_branch
You are currently cherry-picking commit $TO_CHERRY_PICK.
(fix conflicts and run "git cherry-pick --continue")
+ (use "git cherry-pick --skip" to skip this patch)
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
Unmerged paths:
@@ -757,6 +758,7 @@ test_expect_success 'status when cherry-picking after resolving conflicts' '
On branch cherry_branch
You are currently cherry-picking commit $TO_CHERRY_PICK.
(all conflicts fixed: run "git cherry-pick --continue")
+ (use "git cherry-pick --skip" to skip this patch)
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
Changes to be committed:
@@ -778,6 +780,7 @@ test_expect_success 'status when cherry-picking after committing conflict resolu
On branch cherry_branch
Cherry-pick currently in progress.
(run "git cherry-pick --continue" to continue)
+ (use "git cherry-pick --skip" to skip this patch)
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
nothing to commit (use -u to show untracked files)
@@ -835,6 +838,7 @@ test_expect_success 'status while reverting commit (conflicts)' '
On branch master
You are currently reverting commit $TO_REVERT.
(fix conflicts and run "git revert --continue")
+ (use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
Unmerged paths:
@@ -855,6 +859,7 @@ test_expect_success 'status while reverting commit (conflicts resolved)' '
On branch master
You are currently reverting commit $TO_REVERT.
(all conflicts fixed: run "git revert --continue")
+ (use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
Changes to be committed:
@@ -887,6 +892,7 @@ test_expect_success 'status while reverting after committing conflict resolution
On branch master
Revert currently in progress.
(run "git revert --continue" to continue)
+ (use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
nothing to commit (use -u to show untracked files)
diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh
index f19202b509..6602790b5f 100755
--- a/t/t7513-interpret-trailers.sh
+++ b/t/t7513-interpret-trailers.sh
@@ -1234,7 +1234,7 @@ test_expect_success 'with simple command' '
test_cmp expected actual
'
-test_expect_success 'with command using commiter information' '
+test_expect_success 'with command using committer information' '
git config trailer.sign.ifExists "addIfDifferent" &&
git config trailer.sign.command "echo \"\$GIT_COMMITTER_NAME <\$GIT_COMMITTER_EMAIL>\"" &&
cat complex_message_body >expected &&
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 81a375fa0f..fbfdcca000 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -32,11 +32,12 @@ write_integration_script () {
echo "$0: exactly 2 arguments expected"
exit 2
fi
- if test "$1" != 1
+ if test "$1" != 2
then
echo "Unsupported core.fsmonitor hook version." >&2
exit 1
fi
+ printf "last_update_token\0"
printf "untracked\0"
printf "dir1/untracked\0"
printf "dir2/untracked\0"
@@ -106,6 +107,9 @@ EOF
# test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
+ EOF
git update-index --fsmonitor &&
git update-index --fsmonitor-valid dir1/modified &&
git update-index --fsmonitor-valid dir2/modified &&
@@ -164,6 +168,9 @@ EOF
# test that newly added files are marked valid
test_expect_success 'newly added files are marked valid' '
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
+ EOF
git add new &&
git add dir1/new &&
git add dir2/new &&
@@ -203,6 +210,7 @@ EOF
# test that *only* files returned by the integration script get flagged as invalid
test_expect_success '*only* files returned by the integration script get flagged as invalid' '
write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
printf "dir1/modified\0"
EOF
clean_repo &&
@@ -218,11 +226,12 @@ test_expect_success '*only* files returned by the integration script get flagged
# Ensure commands that call refresh_index() to move the index back in time
# properly invalidate the fsmonitor cache
test_expect_success 'refresh_index() invalidates fsmonitor cache' '
- write_script .git/hooks/fsmonitor-test<<-\EOF &&
- EOF
clean_repo &&
dirty_repo &&
+ write_integration_script &&
git add . &&
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ EOF
git commit -m "to reset" &&
git reset HEAD~1 &&
git status >actual &&
@@ -271,6 +280,7 @@ do
# (if enabled) files unless it is told about them.
test_expect_success "status doesn't detect unreported modifications" '
write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
:>marker
EOF
clean_repo &&
@@ -294,7 +304,7 @@ do
done
done
-# test that splitting the index dosn't interfere
+# test that splitting the index doesn't interfere
test_expect_success 'splitting the index results in the same state' '
write_integration_script &&
dirty_repo &&
@@ -354,4 +364,23 @@ test_expect_success 'discard_index() also discards fsmonitor info' '
test_cmp expect actual
'
+# Test unstaging entries that:
+# - Are not flagged with CE_FSMONITOR_VALID
+# - Have a position in the index >= the number of entries present in the index
+# after unstaging.
+test_expect_success 'status succeeds after staging/unstaging' '
+ test_create_repo fsmonitor-stage-unstage &&
+ (
+ cd fsmonitor-stage-unstage &&
+ test_commit initial &&
+ git update-index --fsmonitor &&
+ removed=$(test_seq 1 100 | sed "s/^/z/") &&
+ touch $removed &&
+ git add $removed &&
+ git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" &&
+ FSMONITOR_LIST="$removed" git restore -S $removed &&
+ FSMONITOR_LIST="$removed" git status
+ )
+'
+
test_done
diff --git a/t/t7519/fsmonitor-all b/t/t7519/fsmonitor-all
index 691bc94dc2..94ab66bd3d 100755
--- a/t/t7519/fsmonitor-all
+++ b/t/t7519/fsmonitor-all
@@ -17,7 +17,6 @@ fi
if test "$1" != 1
then
- echo "Unsupported core.fsmonitor hook version." >&2
exit 1
fi
diff --git a/t/t7519/fsmonitor-all-v2 b/t/t7519/fsmonitor-all-v2
new file mode 100755
index 0000000000..061907e88b
--- /dev/null
+++ b/t/t7519/fsmonitor-all-v2
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+#
+# An test hook script to integrate with git to test fsmonitor.
+#
+# The hook is passed a version (currently 2) and since token
+# formatted as a string and outputs to stdout all files that have been
+# modified since the given time. Paths must be relative to the root of
+# the working tree and separated by a single NUL.
+#
+#echo "$0 $*" >&2
+my ($version, $last_update_token) = @ARGV;
+
+if ($version ne 2) {
+ print "Unsupported query-fsmonitor hook version '$version'.\n";
+ exit 1;
+}
+
+print "last_update_token\0/\0"
diff --git a/t/t7519/fsmonitor-env b/t/t7519/fsmonitor-env
new file mode 100755
index 0000000000..8f1f7ab164
--- /dev/null
+++ b/t/t7519/fsmonitor-env
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An test hook script to integrate with git to test fsmonitor.
+#
+# The hook is passed a version (currently 1) and a time in nanoseconds
+# formatted as a string and outputs to stdout all files that have been
+# modified since the given time. Paths must be relative to the root of
+# the working tree and separated by a single NUL.
+#
+#echo "$0 $*" >&2
+
+if test "$#" -ne 2
+then
+ echo "$0: exactly 2 arguments expected" >&2
+ exit 2
+fi
+
+if test "$1" != 1
+then
+ echo "Unsupported core.fsmonitor hook version." >&2
+ exit 1
+fi
+
+printf '%s\n' $FSMONITOR_LIST
diff --git a/t/t7519/fsmonitor-watchman b/t/t7519/fsmonitor-watchman
index 5514edcf68..264b9daf83 100755
--- a/t/t7519/fsmonitor-watchman
+++ b/t/t7519/fsmonitor-watchman
@@ -23,10 +23,10 @@ my ($version, $time) = @ARGV;
if ($version == 1) {
# convert nanoseconds to seconds
- $time = int $time / 1000000000;
+ # subtract one second to make sure watchman will return all changes
+ $time = int ($time / 1000000000) - 1;
} else {
- die "Unsupported query-fsmonitor hook version '$version'.\n" .
- "Falling back to scanning...\n";
+ exit 1;
}
my $git_work_tree;
@@ -54,18 +54,12 @@ sub launch_watchman {
#
# To accomplish this, we're using the "since" generator to use the
# recency index to select candidate nodes and "fields" to limit the
- # output to file names only. Then we're using the "expression" term to
- # further constrain the results.
- #
- # The category of transient files that we want to ignore will have a
- # creation clock (cclock) newer than $time_t value and will also not
- # currently exist.
+ # output to file names only.
my $query = <<" END";
["query", "$git_work_tree", {
"since": $time,
- "fields": ["name"],
- "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]]
+ "fields": ["name"]
}]
END
diff --git a/t/t7519/fsmonitor-watchman-v2 b/t/t7519/fsmonitor-watchman-v2
new file mode 100755
index 0000000000..14ed0aa42d
--- /dev/null
+++ b/t/t7519/fsmonitor-watchman-v2
@@ -0,0 +1,173 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use IPC::Open2;
+
+# An example hook script to integrate Watchman
+# (https://facebook.github.io/watchman/) with git to speed up detecting
+# new and modified files.
+#
+# The hook is passed a version (currently 2) and last update token
+# formatted as a string and outputs to stdout a new update token and
+# all files that have been modified since the update token. Paths must
+# be relative to the root of the working tree and separated by a single NUL.
+#
+# To enable this hook, rename this file to "query-watchman" and set
+# 'git config core.fsmonitor .git/hooks/query-watchman'
+#
+my ($version, $last_update_token) = @ARGV;
+
+# Uncomment for debugging
+# print STDERR "$0 $version $last_update_token\n";
+
+# Check the hook interface version
+if ($version ne 2) {
+ die "Unsupported query-fsmonitor hook version '$version'.\n" .
+ "Falling back to scanning...\n";
+}
+
+my $git_work_tree = get_working_dir();
+
+my $retry = 1;
+
+my $json_pkg;
+eval {
+ require JSON::XS;
+ $json_pkg = "JSON::XS";
+ 1;
+} or do {
+ require JSON::PP;
+ $json_pkg = "JSON::PP";
+};
+
+launch_watchman();
+
+sub launch_watchman {
+ my $o = watchman_query();
+ if (is_work_tree_watched($o)) {
+ output_result($o->{clock}, @{$o->{files}});
+ }
+}
+
+sub output_result {
+ my ($clockid, @files) = @_;
+
+ # Uncomment for debugging watchman output
+ # open (my $fh, ">", ".git/watchman-output.out");
+ # binmode $fh, ":utf8";
+ # print $fh "$clockid\n@files\n";
+ # close $fh;
+
+ binmode STDOUT, ":utf8";
+ print $clockid;
+ print "\0";
+ local $, = "\0";
+ print @files;
+}
+
+sub watchman_clock {
+ my $response = qx/watchman clock "$git_work_tree"/;
+ die "Failed to get clock id on '$git_work_tree'.\n" .
+ "Falling back to scanning...\n" if $? != 0;
+
+ return $json_pkg->new->utf8->decode($response);
+}
+
+sub watchman_query {
+ my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
+ or die "open2() failed: $!\n" .
+ "Falling back to scanning...\n";
+
+ # In the query expression below we're asking for names of files that
+ # changed since $last_update_token but not from the .git folder.
+ #
+ # To accomplish this, we're using the "since" generator to use the
+ # recency index to select candidate nodes and "fields" to limit the
+ # output to file names only. Then we're using the "expression" term to
+ # further constrain the results.
+ if (substr($last_update_token, 0, 1) eq "c") {
+ $last_update_token = "\"$last_update_token\"";
+ }
+ my $query = <<" END";
+ ["query", "$git_work_tree", {
+ "since": $last_update_token,
+ "fields": ["name"],
+ "expression": ["not", ["dirname", ".git"]]
+ }]
+ END
+
+ # Uncomment for debugging the watchman query
+ # open (my $fh, ">", ".git/watchman-query.json");
+ # print $fh $query;
+ # close $fh;
+
+ print CHLD_IN $query;
+ close CHLD_IN;
+ my $response = do {local $/; <CHLD_OUT>};
+
+ # Uncomment for debugging the watch response
+ # open ($fh, ">", ".git/watchman-response.json");
+ # print $fh $response;
+ # close $fh;
+
+ die "Watchman: command returned no output.\n" .
+ "Falling back to scanning...\n" if $response eq "";
+ die "Watchman: command returned invalid output: $response\n" .
+ "Falling back to scanning...\n" unless $response =~ /^\{/;
+
+ return $json_pkg->new->utf8->decode($response);
+}
+
+sub is_work_tree_watched {
+ my ($output) = @_;
+ my $error = $output->{error};
+ if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {
+ $retry--;
+ my $response = qx/watchman watch "$git_work_tree"/;
+ die "Failed to make watchman watch '$git_work_tree'.\n" .
+ "Falling back to scanning...\n" if $? != 0;
+ $output = $json_pkg->new->utf8->decode($response);
+ $error = $output->{error};
+ die "Watchman: $error.\n" .
+ "Falling back to scanning...\n" if $error;
+
+ # Uncomment for debugging watchman output
+ # open (my $fh, ">", ".git/watchman-output.out");
+ # close $fh;
+
+ # Watchman will always return all files on the first query so
+ # return the fast "everything is dirty" flag to git and do the
+ # Watchman query just to get it over with now so we won't pay
+ # the cost in git to look up each individual file.
+ my $o = watchman_clock();
+ $error = $output->{error};
+
+ die "Watchman: $error.\n" .
+ "Falling back to scanning...\n" if $error;
+
+ output_result($o->{clock}, ("/"));
+ $last_update_token = $o->{clock};
+
+ eval { launch_watchman() };
+ return 0;
+ }
+
+ die "Watchman: $error.\n" .
+ "Falling back to scanning...\n" if $error;
+
+ return 1;
+}
+
+sub get_working_dir {
+ my $working_dir;
+ if ($^O =~ 'msys' || $^O =~ 'cygwin') {
+ $working_dir = Win32::GetCwd();
+ $working_dir =~ tr/\\/\//;
+ } else {
+ require Cwd;
+ $working_dir = Cwd::cwd();
+ }
+
+ return $working_dir;
+}
diff --git a/t/t7526-commit-pathspec-file.sh b/t/t7526-commit-pathspec-file.sh
new file mode 100755
index 0000000000..5fbe47ebcd
--- /dev/null
+++ b/t/t7526-commit-pathspec-file.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+
+test_description='commit --pathspec-from-file'
+
+. ./test-lib.sh
+
+test_tick
+
+test_expect_success setup '
+ test_commit file0 &&
+ git tag checkpoint &&
+
+ echo A >fileA.t &&
+ echo B >fileB.t &&
+ echo C >fileC.t &&
+ echo D >fileD.t &&
+ git add fileA.t fileB.t fileC.t fileD.t
+'
+
+restore_checkpoint () {
+ git reset --soft checkpoint
+}
+
+verify_expect () {
+ git diff-tree --no-commit-id --name-status -r HEAD >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success '--pathspec-from-file from stdin' '
+ restore_checkpoint &&
+
+ echo fileA.t | git commit --pathspec-from-file=- -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success '--pathspec-from-file from file' '
+ restore_checkpoint &&
+
+ echo fileA.t >list &&
+ git commit --pathspec-from-file=list -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'NUL delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\0fileB.t\0" | git commit --pathspec-from-file=- --pathspec-file-nul -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'LF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t\n" | git commit --pathspec-from-file=- -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'no trailing delimiter' '
+ restore_checkpoint &&
+
+ printf "fileA.t\nfileB.t" | git commit --pathspec-from-file=- -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'CRLF delimiters' '
+ restore_checkpoint &&
+
+ printf "fileA.t\r\nfileB.t\r\n" | git commit --pathspec-from-file=- -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ A fileB.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'quotes' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ git commit --pathspec-from-file=list -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileA.t
+ EOF
+ verify_expect expect
+'
+
+test_expect_success 'quotes not compatible with --pathspec-file-nul' '
+ restore_checkpoint &&
+
+ cat >list <<-\EOF &&
+ "file\101.t"
+ EOF
+
+ test_must_fail git commit --pathspec-from-file=list --pathspec-file-nul -m "Commit"
+'
+
+test_expect_success 'only touches what was listed' '
+ restore_checkpoint &&
+
+ printf "fileB.t\nfileC.t\n" | git commit --pathspec-from-file=- -m "Commit" &&
+
+ cat >expect <<-\EOF &&
+ A fileB.t
+ A fileC.t
+ EOF
+ verify_expect
+'
+
+test_expect_success 'error conditions' '
+ restore_checkpoint &&
+ echo fileA.t >list &&
+ >empty_list &&
+
+ test_must_fail git commit --pathspec-from-file=list --interactive -m "Commit" 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err &&
+
+ test_must_fail git commit --pathspec-from-file=list --patch -m "Commit" 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err &&
+
+ test_must_fail git commit --pathspec-from-file=list --all -m "Commit" 2>err &&
+ test_i18ngrep -e "--pathspec-from-file with -a does not make sense" err &&
+
+ test_must_fail git commit --pathspec-from-file=list -m "Commit" -- fileA.t 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err &&
+
+ test_must_fail git commit --pathspec-file-nul -m "Commit" 2>err &&
+ test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err &&
+
+ test_must_fail git commit --pathspec-from-file=empty_list --include -m "Commit" 2>err &&
+ test_i18ngrep -e "No paths with --include/--only does not make sense." err &&
+
+ test_must_fail git commit --pathspec-from-file=empty_list --only -m "Commit" 2>err &&
+ test_i18ngrep -e "No paths with --include/--only does not make sense." err
+'
+
+test_done
diff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh
index d99218a725..a426f3a89a 100755
--- a/t/t7612-merge-verify-signatures.sh
+++ b/t/t7612-merge-verify-signatures.sh
@@ -66,6 +66,20 @@ test_expect_success GPG 'merge commit with untrusted signature with verification
test_i18ngrep "has an untrusted GPG signature" mergeerror
'
+test_expect_success GPG 'merge commit with untrusted signature with verification and high minTrustLevel' '
+ test_when_finished "git reset --hard && git checkout initial" &&
+ test_config gpg.minTrustLevel marginal &&
+ test_must_fail git merge --ff-only --verify-signatures side-untrusted 2>mergeerror &&
+ test_i18ngrep "has an untrusted GPG signature" mergeerror
+'
+
+test_expect_success GPG 'merge commit with untrusted signature with verification and low minTrustLevel' '
+ test_when_finished "git reset --hard && git checkout initial" &&
+ test_config gpg.minTrustLevel undefined &&
+ git merge --ff-only --verify-signatures side-untrusted >mergeoutput &&
+ test_i18ngrep "has a good GPG signature" mergeoutput
+'
+
test_expect_success GPG 'merge commit with untrusted signature with merge.verifySignatures=true' '
test_when_finished "git reset --hard && git checkout initial" &&
test_config merge.verifySignatures true &&
@@ -73,6 +87,14 @@ test_expect_success GPG 'merge commit with untrusted signature with merge.verify
test_i18ngrep "has an untrusted GPG signature" mergeerror
'
+test_expect_success GPG 'merge commit with untrusted signature with merge.verifySignatures=true and minTrustLevel' '
+ test_when_finished "git reset --hard && git checkout initial" &&
+ test_config merge.verifySignatures true &&
+ test_config gpg.minTrustLevel marginal &&
+ test_must_fail git merge --ff-only side-untrusted 2>mergeerror &&
+ test_i18ngrep "has an untrusted GPG signature" mergeerror
+'
+
test_expect_success GPG 'merge signed commit with verification' '
test_when_finished "git reset --hard && git checkout initial" &&
git merge --verbose --ff-only --verify-signatures side-signed >mergeoutput &&
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 4e855bc21b..25b235c063 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -4,129 +4,104 @@ test_description='git repack works correctly'
. ./test-lib.sh
-commit_and_pack() {
- test_commit "$@" >/dev/null &&
- SHA1=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) &&
- echo pack-${SHA1}.pack
+commit_and_pack () {
+ test_commit "$@" 1>&2 &&
+ incrpackid=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) &&
+ echo pack-${incrpackid}.pack
+}
+
+test_no_missing_in_packs () {
+ myidx=$(ls -1 .git/objects/pack/*.idx) &&
+ test_path_is_file "$myidx" &&
+ git verify-pack -v alt_objects/pack/*.idx >orig.raw &&
+ sed -n -e "s/^\($OID_REGEX\).*/\1/p" orig.raw | sort >orig &&
+ git verify-pack -v $myidx >dest.raw &&
+ cut -d" " -f1 dest.raw | sort >dest &&
+ comm -23 orig dest >missing &&
+ test_must_be_empty missing
+}
+
+# we expect $packid and $oid to be defined
+test_has_duplicate_object () {
+ want_duplicate_object="$1"
+ found_duplicate_object=false
+ for p in .git/objects/pack/*.idx
+ do
+ idx=$(basename $p)
+ test "pack-$packid.idx" = "$idx" && continue
+ git verify-pack -v $p >packlist || return $?
+ if grep "^$oid" packlist
+ then
+ found_duplicate_object=true
+ echo "DUPLICATE OBJECT FOUND"
+ break
+ fi
+ done &&
+ test "$want_duplicate_object" = "$found_duplicate_object"
}
test_expect_success 'objects in packs marked .keep are not repacked' '
- echo content1 > file1 &&
- echo content2 > file2 &&
+ echo content1 >file1 &&
+ echo content2 >file2 &&
git add . &&
test_tick &&
git commit -m initial_commit &&
# Create two packs
# The first pack will contain all of the objects except one
- git rev-list --objects --all | grep -v file2 |
- git pack-objects pack > /dev/null &&
+ git rev-list --objects --all >objs &&
+ grep -v file2 objs | git pack-objects pack &&
# The second pack will contain the excluded object
- packsha1=$(git rev-list --objects --all | grep file2 |
- git pack-objects pack) &&
- >pack-$packsha1.keep &&
- objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 |
- sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") &&
+ packid=$(grep file2 objs | git pack-objects pack) &&
+ >pack-$packid.keep &&
+ git verify-pack -v pack-$packid.idx >packlist &&
+ oid=$(head -n 1 packlist | sed -e "s/^\($OID_REGEX\).*/\1/") &&
mv pack-* .git/objects/pack/ &&
git repack -A -d -l &&
git prune-packed &&
- for p in .git/objects/pack/*.idx; do
- idx=$(basename $p)
- test "pack-$packsha1.idx" = "$idx" && continue
- if git verify-pack -v $p | egrep "^$objsha1"; then
- found_duplicate_object=1
- echo "DUPLICATE OBJECT FOUND"
- break
- fi
- done &&
- test -z "$found_duplicate_object"
+ test_has_duplicate_object false
'
test_expect_success 'writing bitmaps via command-line can duplicate .keep objects' '
- # build on $objsha1, $packsha1, and .keep state from previous
+ # build on $oid, $packid, and .keep state from previous
git repack -Adbl &&
- test_when_finished "found_duplicate_object=" &&
- for p in .git/objects/pack/*.idx; do
- idx=$(basename $p)
- test "pack-$packsha1.idx" = "$idx" && continue
- if git verify-pack -v $p | egrep "^$objsha1"; then
- found_duplicate_object=1
- echo "DUPLICATE OBJECT FOUND"
- break
- fi
- done &&
- test "$found_duplicate_object" = 1
+ test_has_duplicate_object true
'
test_expect_success 'writing bitmaps via config can duplicate .keep objects' '
- # build on $objsha1, $packsha1, and .keep state from previous
+ # build on $oid, $packid, and .keep state from previous
git -c repack.writebitmaps=true repack -Adl &&
- test_when_finished "found_duplicate_object=" &&
- for p in .git/objects/pack/*.idx; do
- idx=$(basename $p)
- test "pack-$packsha1.idx" = "$idx" && continue
- if git verify-pack -v $p | egrep "^$objsha1"; then
- found_duplicate_object=1
- echo "DUPLICATE OBJECT FOUND"
- break
- fi
- done &&
- test "$found_duplicate_object" = 1
+ test_has_duplicate_object true
'
test_expect_success 'loose objects in alternate ODB are not repacked' '
mkdir alt_objects &&
- echo $(pwd)/alt_objects > .git/objects/info/alternates &&
- echo content3 > file3 &&
- objsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) &&
+ echo $(pwd)/alt_objects >.git/objects/info/alternates &&
+ echo content3 >file3 &&
+ oid=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) &&
git add file3 &&
test_tick &&
git commit -m commit_file3 &&
git repack -a -d -l &&
git prune-packed &&
- for p in .git/objects/pack/*.idx; do
- if git verify-pack -v $p | egrep "^$objsha1"; then
- found_duplicate_object=1
- echo "DUPLICATE OBJECT FOUND"
- break
- fi
- done &&
- test -z "$found_duplicate_object"
+ test_has_duplicate_object false
'
test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' '
mkdir alt_objects/pack &&
mv .git/objects/pack/* alt_objects/pack &&
git repack -a &&
- 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_no_missing_in_packs
'
test_expect_success 'packed obs in alt ODB are repacked when local repo has packs' '
rm -f .git/objects/pack/* &&
- echo new_content >> file1 &&
+ echo new_content >>file1 &&
git add file1 &&
test_tick &&
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_no_missing_in_packs
'
test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
@@ -134,7 +109,7 @@ test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
for p in alt_objects/pack/*.pack
do
base_name=$(basename $p .pack) &&
- if test -f alt_objects/pack/$base_name.keep
+ if test_path_is_file alt_objects/pack/$base_name.keep
then
rm alt_objects/pack/$base_name.keep
else
@@ -142,22 +117,13 @@ test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
fi
done &&
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_no_missing_in_packs
'
test_expect_success 'packed unreachable obs in alternate ODB are not loosened' '
rm -f alt_objects/pack/*.keep &&
mv .git/objects/pack/* alt_objects/pack/ &&
- csha1=$(git rev-parse HEAD^{commit}) &&
+ coid=$(git rev-parse HEAD^{commit}) &&
git reset --hard HEAD^ &&
test_tick &&
git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
@@ -167,15 +133,15 @@ test_expect_success 'packed unreachable obs in alternate ODB are not loosened' '
--unpack-unreachable </dev/null pack &&
rm -f .git/objects/pack/* &&
mv pack-* .git/objects/pack/ &&
- test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
- egrep "^$csha1 " | sort | uniq | wc -l) &&
- echo > .git/objects/info/alternates &&
- test_must_fail git show $csha1
+ git verify-pack -v -- .git/objects/pack/*.idx >packlist &&
+ ! grep "^$coid " packlist &&
+ echo >.git/objects/info/alternates &&
+ test_must_fail git show $coid
'
test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' '
- echo $(pwd)/alt_objects > .git/objects/info/alternates &&
- echo "$csha1" | git pack-objects --non-empty --all --reflog pack &&
+ echo $(pwd)/alt_objects >.git/objects/info/alternates &&
+ echo "$coid" | git pack-objects --non-empty --all --reflog pack &&
rm -f .git/objects/pack/* &&
mv pack-* .git/objects/pack/ &&
# The pack-objects call on the next line is equivalent to
@@ -184,10 +150,10 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar
--unpack-unreachable </dev/null pack &&
rm -f .git/objects/pack/* &&
mv pack-* .git/objects/pack/ &&
- test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
- egrep "^$csha1 " | sort | uniq | wc -l) &&
- echo > .git/objects/info/alternates &&
- test_must_fail git show $csha1
+ git verify-pack -v -- .git/objects/pack/*.idx >packlist &&
+ ! grep "^$coid " &&
+ echo >.git/objects/info/alternates &&
+ test_must_fail git show $coid
'
test_expect_success 'objects made unreachable by grafts only are kept' '
@@ -196,7 +162,7 @@ test_expect_success 'objects made unreachable by grafts only are kept' '
H0=$(git rev-parse HEAD) &&
H1=$(git rev-parse HEAD^) &&
H2=$(git rev-parse HEAD^^) &&
- echo "$H0 $H2" > .git/info/grafts &&
+ echo "$H0 $H2" >.git/info/grafts &&
git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
git repack -a -d &&
git cat-file -t $H1
@@ -235,7 +201,7 @@ test_expect_success 'incremental repack does not complain' '
test_expect_success 'bitmaps can be disabled on bare repos' '
git -c repack.writeBitmaps=false -C bare.git repack -ad &&
- bitmap=$(ls bare.git/objects/pack/*.bitmap 2>/dev/null || :) &&
+ bitmap=$(ls bare.git/objects/pack/*.bitmap || :) &&
test -z "$bitmap"
'
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 6bac9ed180..29b92907e2 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -125,15 +125,14 @@ test_expect_success 'difftool stops on error with --trust-exit-code' '
test_when_finished "rm -f for-diff .git/fail-right-file" &&
test_when_finished "git reset -- for-diff" &&
write_script .git/fail-right-file <<-\EOF &&
- echo "$2"
+ echo failed
exit 1
EOF
>for-diff &&
git add for-diff &&
- echo file >expect &&
test_must_fail git difftool -y --trust-exit-code \
--extcmd .git/fail-right-file branch >actual &&
- test_cmp expect actual
+ test_line_count = 1 actual
'
test_expect_success 'difftool honors exit status if command not found' '
diff --git a/t/t7811-grep-open.sh b/t/t7811-grep-open.sh
index d1ebfd88c7..a98785da79 100755
--- a/t/t7811-grep-open.sh
+++ b/t/t7811-grep-open.sh
@@ -113,7 +113,6 @@ test_expect_success 'modified file' '
subdir/grep.c
unrelated
EOF
- >empty &&
echo "enum grep_pat_token" >unrelated &&
test_when_finished "git checkout HEAD unrelated" &&
diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh
index 0c685d3598..03dba6685a 100755
--- a/t/t7812-grep-icase-non-ascii.sh
+++ b/t/t7812-grep-icase-non-ascii.sh
@@ -53,4 +53,35 @@ test_expect_success REGEX_LOCALE 'pickaxe -i on non-ascii' '
test_cmp expected actual
'
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: setup invalid UTF-8 data' '
+ printf "\\200\\n" >invalid-0x80 &&
+ echo "ævar" >expected &&
+ cat expected >>invalid-0x80 &&
+ git add invalid-0x80
+'
+
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep ASCII from invalid UTF-8 data' '
+ git grep -h "var" invalid-0x80 >actual &&
+ test_cmp expected actual &&
+ git grep -h "(*NO_JIT)var" invalid-0x80 >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-ASCII from invalid UTF-8 data' '
+ git grep -h "æ" invalid-0x80 >actual &&
+ test_cmp expected actual &&
+ git grep -h "(*NO_JIT)æ" invalid-0x80 >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-ASCII from invalid UTF-8 data with -i' '
+ test_might_fail git grep -hi "Æ" invalid-0x80 >actual &&
+ if test -s actual
+ then
+ test_cmp expected actual
+ fi &&
+ test_must_fail git grep -hi "(*NO_JIT)Æ" invalid-0x80 >actual &&
+ ! test_cmp expected actual
+'
+
test_done
diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index a11366b4ce..828cb3ba58 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -345,7 +345,16 @@ test_incompatible_with_recurse_submodules ()
}
test_incompatible_with_recurse_submodules --untracked
-test_incompatible_with_recurse_submodules --no-index
+
+test_expect_success 'grep --recurse-submodules --no-index ignores --recurse-submodules' '
+ git grep --recurse-submodules --no-index -e "^(.|.)[\d]" >actual &&
+ cat >expect <<-\EOF &&
+ a:(1|2)d(3|4)
+ submodule/a:(1|2)d(3|4)
+ submodule/sub/a:(1|2)d(3|4)
+ EOF
+ test_cmp expect actual
+'
test_expect_success 'grep --recurse-submodules should pass the pattern type along' '
# Fixed
@@ -408,4 +417,25 @@ test_expect_success 'grep --recurse-submodules with submodules without .gitmodul
test_cmp expect actual
'
+reset_and_clean () {
+ git reset --hard &&
+ git clean -fd &&
+ git submodule foreach --recursive 'git reset --hard' &&
+ git submodule foreach --recursive 'git clean -fd'
+}
+
+test_expect_success 'grep --recurse-submodules without --cached considers worktree modifications' '
+ reset_and_clean &&
+ echo "A modified line in submodule" >>submodule/a &&
+ echo "submodule/a:A modified line in submodule" >expect &&
+ git grep --recurse-submodules "A modified line in submodule" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep --recurse-submodules with --cached ignores worktree modifications' '
+ reset_and_clean &&
+ echo "A modified line in submodule" >>submodule/a &&
+ test_must_fail git grep --recurse-submodules --cached "A modified line in submodule" >actual 2>&1 &&
+ test_must_be_empty actual
+'
test_done
diff --git a/t/t7008-grep-binary.sh b/t/t7815-grep-binary.sh
index 2d87c49b75..90ebb64f46 100755
--- a/t/t7008-grep-binary.sh
+++ b/t/t7815-grep-binary.sh
@@ -4,41 +4,6 @@ test_description='git grep in binary files'
. ./test-lib.sh
-nul_match () {
- matches=$1
- flags=$2
- pattern=$3
- pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g')
-
- if test "$matches" = 1
- then
- test_expect_success "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- git grep -f f $flags a
- "
- elif test "$matches" = 0
- then
- test_expect_success "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- test_must_fail git grep -f f $flags a
- "
- elif test "$matches" = T1
- then
- test_expect_failure "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- git grep -f f $flags a
- "
- elif test "$matches" = T0
- then
- test_expect_failure "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- test_must_fail git grep -f f $flags a
- "
- else
- test_expect_success "PANIC: Test framework error. Unknown matches value $matches" 'false'
- fi
-}
-
test_expect_success 'setup' "
echo 'binaryQfileQm[*]cQ*æQð' | q_to_nul >a &&
git add a &&
@@ -102,72 +67,6 @@ test_expect_failure 'git grep .fi a' '
git grep .fi a
'
-nul_match 1 '-F' 'yQf'
-nul_match 0 '-F' 'yQx'
-nul_match 1 '-Fi' 'YQf'
-nul_match 0 '-Fi' 'YQx'
-nul_match 1 '' 'yQf'
-nul_match 0 '' 'yQx'
-nul_match 1 '' 'æQð'
-nul_match 1 '-F' 'eQm[*]c'
-nul_match 1 '-Fi' 'EQM[*]C'
-
-# Regex patterns that would match but shouldn't with -F
-nul_match 0 '-F' 'yQ[f]'
-nul_match 0 '-F' '[y]Qf'
-nul_match 0 '-Fi' 'YQ[F]'
-nul_match 0 '-Fi' '[Y]QF'
-nul_match 0 '-F' 'æQ[ð]'
-nul_match 0 '-F' '[æ]Qð'
-nul_match 0 '-Fi' 'ÆQ[Ð]'
-nul_match 0 '-Fi' '[Æ]QÐ'
-
-# kwset is disabled on -i & non-ASCII. No way to match non-ASCII \0
-# patterns case-insensitively.
-nul_match T1 '-i' 'ÆQÐ'
-
-# \0 implicitly disables regexes. This is an undocumented internal
-# limitation.
-nul_match T1 '' 'yQ[f]'
-nul_match T1 '' '[y]Qf'
-nul_match T1 '-i' 'YQ[F]'
-nul_match T1 '-i' '[Y]Qf'
-nul_match T1 '' 'æQ[ð]'
-nul_match T1 '' '[æ]Qð'
-nul_match T1 '-i' 'ÆQ[Ð]'
-
-# ... because of \0 implicitly disabling regexes regexes that
-# should/shouldn't match don't do the right thing.
-nul_match T1 '' 'eQm.*cQ'
-nul_match T1 '-i' 'EQM.*cQ'
-nul_match T0 '' 'eQm[*]c'
-nul_match T0 '-i' 'EQM[*]C'
-
-# Due to the REG_STARTEND extension when kwset() is disabled on -i &
-# non-ASCII the string will be matched in its entirety, but the
-# pattern will be cut off at the first \0.
-nul_match 0 '-i' 'NOMATCHQð'
-nul_match T0 '-i' '[Æ]QNOMATCH'
-nul_match T0 '-i' '[æ]QNOMATCH'
-# Matches, but for the wrong reasons, just stops at [æ]
-nul_match 1 '-i' '[Æ]Qð'
-nul_match 1 '-i' '[æ]Qð'
-
-# Ensure that the matcher doesn't regress to something that stops at
-# \0
-nul_match 0 '-F' 'yQ[f]'
-nul_match 0 '-Fi' 'YQ[F]'
-nul_match 0 '' 'yQNOMATCH'
-nul_match 0 '' 'QNOMATCH'
-nul_match 0 '-i' 'YQNOMATCH'
-nul_match 0 '-i' 'QNOMATCH'
-nul_match 0 '-F' 'æQ[ð]'
-nul_match 0 '-Fi' 'ÆQ[Ð]'
-nul_match 0 '' 'yQNÓMATCH'
-nul_match 0 '' 'QNÓMATCH'
-nul_match 0 '-i' 'YQNÓMATCH'
-nul_match 0 '-i' 'QNÓMATCH'
-
test_expect_success 'grep respects binary diff attribute' '
echo text >t &&
git add t &&
diff --git a/t/t7816-grep-binary-pattern.sh b/t/t7816-grep-binary-pattern.sh
new file mode 100755
index 0000000000..60bab291e4
--- /dev/null
+++ b/t/t7816-grep-binary-pattern.sh
@@ -0,0 +1,127 @@
+#!/bin/sh
+
+test_description='git grep with a binary pattern files'
+
+. ./lib-gettext.sh
+
+nul_match_internal () {
+ matches=$1
+ prereqs=$2
+ lc_all=$3
+ extra_flags=$4
+ flags=$5
+ pattern=$6
+ pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g')
+
+ if test "$matches" = 1
+ then
+ test_expect_success $prereqs "LC_ALL='$lc_all' git grep $extra_flags -f f $flags '$pattern_human' a" "
+ printf '$pattern' | q_to_nul >f &&
+ LC_ALL='$lc_all' git grep $extra_flags -f f $flags a
+ "
+ elif test "$matches" = 0
+ then
+ test_expect_success $prereqs "LC_ALL='$lc_all' git grep $extra_flags -f f $flags '$pattern_human' a" "
+ >stderr &&
+ printf '$pattern' | q_to_nul >f &&
+ test_must_fail env LC_ALL=\"$lc_all\" git grep $extra_flags -f f $flags a 2>stderr &&
+ test_i18ngrep ! 'This is only supported with -P under PCRE v2' stderr
+ "
+ elif test "$matches" = P
+ then
+ test_expect_success $prereqs "error, PCRE v2 only: LC_ALL='$lc_all' git grep -f f $flags '$pattern_human' a" "
+ >stderr &&
+ printf '$pattern' | q_to_nul >f &&
+ test_must_fail env LC_ALL=\"$lc_all\" git grep -f f $flags a 2>stderr &&
+ test_i18ngrep 'This is only supported with -P under PCRE v2' stderr
+ "
+ else
+ test_expect_success "PANIC: Test framework error. Unknown matches value $matches" 'false'
+ fi
+}
+
+nul_match () {
+ matches=$1
+ matches_pcre2=$2
+ matches_pcre2_locale=$3
+ flags=$4
+ pattern=$5
+ pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g')
+
+ nul_match_internal "$matches" "" "C" "" "$flags" "$pattern"
+ nul_match_internal "$matches_pcre2" "LIBPCRE2" "C" "-P" "$flags" "$pattern"
+ nul_match_internal "$matches_pcre2_locale" "LIBPCRE2,GETTEXT_LOCALE" "$is_IS_locale" "-P" "$flags" "$pattern"
+}
+
+test_expect_success 'setup' "
+ echo 'binaryQfileQm[*]cQ*æQð' | q_to_nul >a &&
+ git add a &&
+ git commit -m.
+"
+
+# Simple fixed-string matching that can use kwset (no -i && non-ASCII)
+nul_match P P P '-F' 'yQf'
+nul_match P P P '-F' 'yQx'
+nul_match P P P '-Fi' 'YQf'
+nul_match P P P '-Fi' 'YQx'
+nul_match P P 1 '' 'yQf'
+nul_match P P 0 '' 'yQx'
+nul_match P P 1 '' 'æQð'
+nul_match P P P '-F' 'eQm[*]c'
+nul_match P P P '-Fi' 'EQM[*]C'
+
+# Regex patterns that would match but shouldn't with -F
+nul_match P P P '-F' 'yQ[f]'
+nul_match P P P '-F' '[y]Qf'
+nul_match P P P '-Fi' 'YQ[F]'
+nul_match P P P '-Fi' '[Y]QF'
+nul_match P P P '-F' 'æQ[ð]'
+nul_match P P P '-F' '[æ]Qð'
+
+# The -F kwset codepath can't handle -i && non-ASCII...
+nul_match P 1 1 '-i' '[æ]Qð'
+
+# ...PCRE v2 only matches non-ASCII with -i casefolding under UTF-8
+# semantics
+nul_match P P P '-Fi' 'ÆQ[Ð]'
+nul_match P 0 1 '-i' 'ÆQ[Ð]'
+nul_match P 0 1 '-i' '[Æ]QÐ'
+nul_match P 0 1 '-i' '[Æ]Qð'
+nul_match P 0 1 '-i' 'ÆQÐ'
+
+# \0 in regexes can only work with -P & PCRE v2
+nul_match P P 1 '' 'yQ[f]'
+nul_match P P 1 '' '[y]Qf'
+nul_match P P 1 '-i' 'YQ[F]'
+nul_match P P 1 '-i' '[Y]Qf'
+nul_match P P 1 '' 'æQ[ð]'
+nul_match P P 1 '' '[æ]Qð'
+nul_match P P 1 '-i' 'ÆQ[Ð]'
+nul_match P P 1 '' 'eQm.*cQ'
+nul_match P P 1 '-i' 'EQM.*cQ'
+nul_match P P 0 '' 'eQm[*]c'
+nul_match P P 0 '-i' 'EQM[*]C'
+
+# Assert that we're using REG_STARTEND and the pattern doesn't match
+# just because it's cut off at the first \0.
+nul_match P P 0 '-i' 'NOMATCHQð'
+nul_match P P 0 '-i' '[Æ]QNOMATCH'
+nul_match P P 0 '-i' '[æ]QNOMATCH'
+
+# Ensure that the matcher doesn't regress to something that stops at
+# \0
+nul_match P P P '-F' 'yQ[f]'
+nul_match P P P '-Fi' 'YQ[F]'
+nul_match P P 0 '' 'yQNOMATCH'
+nul_match P P 0 '' 'QNOMATCH'
+nul_match P P 0 '-i' 'YQNOMATCH'
+nul_match P P 0 '-i' 'QNOMATCH'
+nul_match P P P '-F' 'æQ[ð]'
+nul_match P P P '-Fi' 'ÆQ[Ð]'
+nul_match P P 1 '-i' 'ÆQ[Ð]'
+nul_match P P 0 '' 'yQNÓMATCH'
+nul_match P P 0 '' 'QNÓMATCH'
+nul_match P P 0 '-i' 'YQNÓMATCH'
+nul_match P P 0 '-i' 'QNÓMATCH'
+
+test_done
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 997f90b42b..a834afab4d 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -1260,7 +1260,7 @@ test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous i
grep "To: default@example.com" stdout
'
-test_expect_success $PREREQ 'sendemail.identity: bool identity variable existance overrides' '
+test_expect_success $PREREQ 'sendemail.identity: bool identity variable existence overrides' '
git -c sendemail.identity=cloud \
-c sendemail.xmailer=true \
-c sendemail.cloud.xmailer=false \
@@ -2066,7 +2066,7 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
TO1=$(echo "QTo 1 <to1@example.com>" | q_to_tab) &&
TO2=$(echo "QZto2" | qz_to_tab_space) &&
CC1=$(echo "cc1" | append_cr) &&
- BCC1=$(echo "Q bcc1@example.com Q" | q_to_nul) &&
+ BCC1=$(echo " bcc1@example.com Q" | q_to_nul) &&
git send-email \
--dry-run \
--from=" Example <from@example.com>" \
diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index 0b20b07e68..c90fdc5c89 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -53,8 +53,6 @@ text_no_props () {
printf "%s\n" "$text"
}
->empty
-
test_expect_success 'empty dump' '
reinit_git &&
echo "SVN-fs-dump-format-version: 2" >input &&
@@ -208,7 +206,7 @@ test_expect_failure 'timestamp and empty file' '
test_cmp expect.date actual.date &&
test_cmp expect.files actual.files &&
git checkout HEAD empty-file &&
- test_cmp empty file
+ test_must_be_empty file
'
test_expect_success 'directory with files' '
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 2ea479595f..ae9950a9c2 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -85,6 +85,36 @@ test_expect_success 'A: create pack from stdin' '
An annotated tag that annotates a blob.
EOF
+ tag to-be-deleted
+ from :3
+ data <<EOF
+ Another annotated tag that annotates a blob.
+ EOF
+
+ reset refs/tags/to-be-deleted
+ from 0000000000000000000000000000000000000000
+
+ tag nested
+ mark :6
+ from :4
+ data <<EOF
+ Tag of our lovely commit
+ EOF
+
+ reset refs/tags/nested
+ from 0000000000000000000000000000000000000000
+
+ tag nested
+ mark :7
+ from :6
+ data <<EOF
+ Tag of tag of our lovely commit
+ EOF
+
+ alias
+ mark :8
+ to :5
+
INPUT_END
git fast-import --export-marks=marks.out <input &&
git whatchanged master
@@ -157,12 +187,19 @@ test_expect_success 'A: verify tag/series-A-blob' '
test_cmp expect actual
'
+test_expect_success 'A: verify tag deletion is successful' '
+ test_must_fail git rev-parse --verify refs/tags/to-be-deleted
+'
+
test_expect_success 'A: verify marks output' '
cat >expect <<-EOF &&
:2 $(git rev-parse --verify master:file2)
:3 $(git rev-parse --verify master:file3)
:4 $(git rev-parse --verify master:file4)
:5 $(git rev-parse --verify master^0)
+ :6 $(git cat-file tag nested | grep object | cut -d" " -f 2)
+ :7 $(git rev-parse --verify nested)
+ :8 $(git rev-parse --verify master^0)
EOF
test_cmp expect marks.out
'
@@ -2470,9 +2507,6 @@ test_expect_success PIPE 'R: copy using cat-file' '
echo $expect_id blob $expect_len >expect.response &&
rm -f blobs &&
- cat >frontend <<-\FRONTEND_END &&
- #!/bin/sh
- FRONTEND_END
mkfifo blobs &&
(
@@ -2811,7 +2845,6 @@ test_expect_success 'S: filemodify with garbage after mark must fail' '
COMMIT
M 100644 :403x hello.c
EOF
- cat err &&
test_i18ngrep "space after mark" err
'
@@ -2828,7 +2861,6 @@ test_expect_success 'S: filemodify with garbage after inline must fail' '
inline
BLOB
EOF
- cat err &&
test_i18ngrep "nvalid dataref" err
'
@@ -2842,7 +2874,6 @@ test_expect_success 'S: filemodify with garbage after sha1 must fail' '
COMMIT
M 100644 ${sha1}x hello.c
EOF
- cat err &&
test_i18ngrep "space after SHA1" err
'
@@ -2858,7 +2889,6 @@ test_expect_success 'S: notemodify with garbage after mark dataref must fail' '
COMMIT
N :202x :302
EOF
- cat err &&
test_i18ngrep "space after mark" err
'
@@ -2874,7 +2904,6 @@ test_expect_success 'S: notemodify with garbage after inline dataref must fail'
note blob
BLOB
EOF
- cat err &&
test_i18ngrep "nvalid dataref" err
'
@@ -2888,7 +2917,6 @@ test_expect_success 'S: notemodify with garbage after sha1 dataref must fail' '
COMMIT
N ${sha1}x :302
EOF
- cat err &&
test_i18ngrep "space after SHA1" err
'
@@ -2904,7 +2932,6 @@ test_expect_success 'S: notemodify with garbage after mark commit-ish must fail'
COMMIT
N :202 :302x
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2938,7 +2965,6 @@ test_expect_success 'S: from with garbage after mark must fail' '
EOF
# now evaluate the error
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2958,7 +2984,6 @@ test_expect_success 'S: merge with garbage after mark must fail' '
merge :303x
M 100644 :403 hello.c
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2974,7 +2999,6 @@ test_expect_success 'S: tag with garbage after mark must fail' '
tag S
TAG
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2985,7 +3009,6 @@ test_expect_success 'S: cat-blob with garbage after mark must fail' '
test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
cat-blob :403x
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2996,7 +3019,6 @@ test_expect_success 'S: ls with garbage after mark must fail' '
test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
ls :302x hello.c
EOF
- cat err &&
test_i18ngrep "space after mark" err
'
@@ -3005,7 +3027,6 @@ test_expect_success 'S: ls with garbage after sha1 must fail' '
test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
ls ${sha1}x hello.c
EOF
- cat err &&
test_i18ngrep "space after tree-ish" err
'
@@ -3170,13 +3191,22 @@ background_import_then_checkpoint () {
exec 9<>V.output
rm V.output
- git fast-import $options <&8 >&9 &
- echo $! >V.pid
+ (
+ git fast-import $options <&8 >&9 &
+ echo $! >&9
+ wait $!
+ echo >&2 "background fast-import terminated too early with exit code $?"
+ # Un-block the read loop in the main shell process.
+ echo >&9 UNEXPECTED
+ ) &
+ sh_pid=$!
+ read fi_pid <&9
# We don't mind if fast-import has already died by the time the test
# ends.
test_when_finished "
exec 8>&-; exec 9>&-;
- kill $(cat V.pid) && wait $(cat V.pid)
+ kill $sh_pid && wait $sh_pid
+ kill $fi_pid && wait $fi_pid
true"
# Start in the background to ensure we adhere strictly to (blocking)
@@ -3196,6 +3226,9 @@ background_import_then_checkpoint () {
then
error=0
break
+ elif test "$output" = "UNEXPECTED"
+ then
+ break
fi
# otherwise ignore cruft
echo >&2 "cruft: $output"
@@ -3208,7 +3241,7 @@ background_import_then_checkpoint () {
}
background_import_still_running () {
- if ! kill -0 "$(cat V.pid)"
+ if ! kill -0 "$fi_pid"
then
echo >&2 "background fast-import terminated too early"
false
diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh
index dadc70b7d5..ca223dca98 100755
--- a/t/t9301-fast-import-notes.sh
+++ b/t/t9301-fast-import-notes.sh
@@ -275,7 +275,7 @@ $whitespace
third note for first commit
EXPECT_END
-test_expect_success 'add concatentation notes with M command' '
+test_expect_success 'add concatenation notes with M command' '
git fast-import <input &&
GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 67ea5699c6..690c90fb82 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -53,6 +53,33 @@ test_expect_success 'fast-export | fast-import' '
'
+test_expect_success 'fast-export ^muss^{commit} muss' '
+ git fast-export --tag-of-filtered-object=rewrite ^muss^{commit} muss >actual &&
+ cat >expected <<-EOF &&
+ tag muss
+ from $(git rev-parse --verify muss^{commit})
+ $(git cat-file tag muss | grep tagger)
+ data 9
+ valentin
+
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'fast-export --mark-tags ^muss^{commit} muss' '
+ git fast-export --mark-tags --tag-of-filtered-object=rewrite ^muss^{commit} muss >actual &&
+ cat >expected <<-EOF &&
+ tag muss
+ mark :1
+ from $(git rev-parse --verify muss^{commit})
+ $(git cat-file tag muss | grep tagger)
+ data 9
+ valentin
+
+ EOF
+ test_cmp expected actual
+'
+
test_expect_success 'fast-export master~2..master' '
git fast-export master~2..master >actual &&
@@ -513,10 +540,41 @@ test_expect_success 'tree_tag' '
'
# NEEDSWORK: not just check return status, but validate the output
+# Note that these tests DO NOTHING other than print a warning that
+# they are omitting the one tag we asked them to export (because the
+# tags resolve to a tree). They exist just to make sure we do not
+# abort but instead just warn.
test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj'
test_expect_success 'tag-obj_tag' 'git fast-export tag-obj_tag'
test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj'
+test_expect_success 'handling tags of blobs' '
+ git tag -a -m "Tag of a blob" blobtag $(git rev-parse master:file) &&
+ git fast-export blobtag >actual &&
+ cat >expect <<-EOF &&
+ blob
+ mark :1
+ data 9
+ die Luft
+
+ tag blobtag
+ from :1
+ tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data 14
+ Tag of a blob
+
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'handling nested tags' '
+ git tag -a -m "This is a nested tag" nested muss &&
+ git fast-export --mark-tags nested >output &&
+ grep "^from $ZERO_OID$" output &&
+ grep "^tag nested$" output >tag_lines &&
+ test_line_count = 2 tag_lines
+'
+
test_expect_success 'directory becomes symlink' '
git init dirtosymlink &&
git init result &&
@@ -568,17 +626,15 @@ test_expect_success 'fast-export quotes pathnames' '
'
test_expect_success 'test bidirectionality' '
- >marks-cur &&
- >marks-new &&
git init marks-test &&
- git fast-export --export-marks=marks-cur --import-marks=marks-cur --branches | \
- git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks=marks-new &&
+ git fast-export --export-marks=marks-cur --import-marks-if-exists=marks-cur --branches | \
+ git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks-if-exists=marks-new &&
(cd marks-test &&
git reset --hard &&
echo Wohlauf > file &&
git commit -a -m "back in time") &&
- git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks=marks-new --branches | \
- git fast-import --export-marks=marks-cur --import-marks=marks-cur
+ git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks-if-exists=marks-new --branches | \
+ git fast-import --export-marks=marks-cur --import-marks-if-exists=marks-cur
'
cat > expected << EOF
diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh
index 0796a438bc..e38cbc97d3 100755
--- a/t/t9502-gitweb-standalone-parse-output.sh
+++ b/t/t9502-gitweb-standalone-parse-output.sh
@@ -188,8 +188,8 @@ test_expect_success 'forks: project_index lists all projects (incl. forks)' '
'
xss() {
- echo >&2 "Checking $1..." &&
- gitweb_run "$1" &&
+ echo >&2 "Checking $*..." &&
+ gitweb_run "$@" &&
if grep "$TAG" gitweb.body; then
echo >&2 "xss: $TAG should have been quoted in output"
return 1
@@ -200,7 +200,8 @@ xss() {
test_expect_success 'xss checks' '
TAG="<magic-xss-tag>" &&
xss "a=rss&p=$TAG" &&
- xss "a=rss&p=foo.git&f=$TAG"
+ xss "a=rss&p=foo.git&f=$TAG" &&
+ xss "" "$TAG+"
'
test_done
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 3cff1fce1b..9c9710d8c7 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -407,7 +407,7 @@ test_expect_success 'reinit depot' '
'
#
-# What happens when two files of the same name are overlayed together?
+# What happens when two files of the same name are overlaid together?
# The last-listed file should take preference.
#
# //depot
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 75512c3403..5505e5aa24 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -28,10 +28,10 @@ complete ()
#
# (2) A test makes sure that common subcommands are included in the
# completion for "git <TAB>", and a plumbing is excluded. "add",
-# "filter-branch" and "ls-files" are listed for this.
+# "rebase" and "ls-files" are listed for this.
-GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr filter-branch ls-files'
-GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout filter-branch'
+GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr rebase ls-files'
+GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout rebase'
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
@@ -378,7 +378,7 @@ test_expect_success '__gitdir - finds repo' '
'
-test_expect_success '__gitdir - returns error when cant find repo' '
+test_expect_success '__gitdir - returns error when cannot find repo' '
(
__git_dir="non-existing" &&
test_must_fail __gitdir >"$actual"
@@ -945,7 +945,7 @@ test_expect_success 'setup for filtering matching refs' '
rm -f .git/FETCH_HEAD
'
-test_expect_success '__git_refs - dont filter refs unless told so' '
+test_expect_success '__git_refs - do not filter refs unless told so' '
cat >expected <<-EOF &&
HEAD
master
@@ -1257,7 +1257,7 @@ test_path_completion ()
# In the following tests calling this function we only
# care about how __git_complete_index_file() deals with
# unusual characters in path names. By requesting only
- # untracked files we dont have to bother adding any
+ # untracked files we do not have to bother adding any
# paths to the index in those tests.
__git_complete_index_file --others &&
print_comp
@@ -1363,6 +1363,63 @@ test_expect_success 'teardown after path completion tests' '
BS\\dir '$'separators\034in\035dir''
'
+test_expect_success '__git_find_on_cmdline - single match' '
+ echo list >expect &&
+ (
+ words=(git command --opt list) &&
+ cword=${#words[@]} &&
+ __git_find_on_cmdline "add list remove" >actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_expect_success '__git_find_on_cmdline - multiple matches' '
+ echo remove >expect &&
+ (
+ words=(git command -o --opt remove list add) &&
+ cword=${#words[@]} &&
+ __git_find_on_cmdline "add list remove" >actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_expect_success '__git_find_on_cmdline - no match' '
+ (
+ words=(git command --opt branch) &&
+ cword=${#words[@]} &&
+ __git_find_on_cmdline "add list remove" >actual
+ ) &&
+ test_must_be_empty actual
+'
+
+test_expect_success '__git_find_on_cmdline - single match with index' '
+ echo "3 list" >expect &&
+ (
+ words=(git command --opt list) &&
+ cword=${#words[@]} &&
+ __git_find_on_cmdline --show-idx "add list remove" >actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_expect_success '__git_find_on_cmdline - multiple matches with index' '
+ echo "4 remove" >expect &&
+ (
+ words=(git command -o --opt remove list add) &&
+ cword=${#words[@]} &&
+ __git_find_on_cmdline --show-idx "add list remove" >actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_expect_success '__git_find_on_cmdline - no match with index' '
+ (
+ words=(git command --opt branch) &&
+ cword=${#words[@]} &&
+ __git_find_on_cmdline --show-idx "add list remove" >actual
+ ) &&
+ test_must_be_empty actual
+'
test_expect_success '__git_get_config_variables' '
cat >expect <<-EOF &&
@@ -1392,12 +1449,12 @@ test_expect_success 'basic' '
# built-in
grep -q "^add \$" out &&
# script
- grep -q "^filter-branch \$" out &&
+ grep -q "^rebase \$" out &&
# plumbing
! grep -q "^ls-files \$" out &&
- run_completion "git f" &&
- ! grep -q -v "^f" out
+ run_completion "git r" &&
+ ! grep -q -v "^r" out
'
test_expect_success 'double dash "git" itself' '
@@ -1438,6 +1495,8 @@ test_expect_success 'double dash "git checkout"' '
--no-guess Z
--no-... Z
--overlay Z
+ --pathspec-file-nul Z
+ --pathspec-from-file=Z
EOF
'
@@ -1548,7 +1607,10 @@ test_expect_success 'complete tree filename with metacharacters' '
'
test_expect_success PERL 'send-email' '
- test_completion "git send-email --cov" "--cover-letter " &&
+ test_completion "git send-email --cov" <<-\EOF &&
+ --cover-from-description=Z
+ --cover-letter Z
+ EOF
test_completion "git send-email ma" "master "
'
@@ -1698,6 +1760,69 @@ do
'
done
+test_expect_success 'git config - section' '
+ test_completion "git config br" <<-\EOF
+ branch.Z
+ browser.Z
+ EOF
+'
+
+test_expect_success 'git config - variable name' '
+ test_completion "git config log.d" <<-\EOF
+ log.date Z
+ log.decorate Z
+ EOF
+'
+
+test_expect_success 'git config - value' '
+ test_completion "git config color.pager " <<-\EOF
+ false Z
+ true Z
+ EOF
+'
+
+test_expect_success 'git -c - section' '
+ test_completion "git -c br" <<-\EOF
+ branch.Z
+ browser.Z
+ EOF
+'
+
+test_expect_success 'git -c - variable name' '
+ test_completion "git -c log.d" <<-\EOF
+ log.date=Z
+ log.decorate=Z
+ EOF
+'
+
+test_expect_success 'git -c - value' '
+ test_completion "git -c color.pager=" <<-\EOF
+ false Z
+ true Z
+ EOF
+'
+
+test_expect_success 'git clone --config= - section' '
+ test_completion "git clone --config=br" <<-\EOF
+ branch.Z
+ browser.Z
+ EOF
+'
+
+test_expect_success 'git clone --config= - variable name' '
+ test_completion "git clone --config=log.d" <<-\EOF
+ log.date=Z
+ log.decorate=Z
+ EOF
+'
+
+test_expect_success 'git clone --config= - value' '
+ test_completion "git clone --config=color.pager=" <<-\EOF
+ false Z
+ true Z
+ EOF
+'
+
test_expect_success 'sourcing the completion script clears cached commands' '
__git_compute_all_commands &&
verbose test -n "$__git_all_commands" &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index e0b3f28d3a..284c52d076 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -228,9 +228,11 @@ test_commit () {
# can be a tag pointing to the commit-to-merge.
test_merge () {
+ label="$1" &&
+ shift &&
test_tick &&
- git merge -m "$1" "$2" &&
- git tag "$1"
+ git merge -m "$label" "$@" &&
+ git tag "$label"
}
# Efficiently create <nr> commits, each with a unique number (from 1 to <nr>
@@ -306,7 +308,7 @@ test_commit_bulk () {
total=$1
add_from=
- if git -C "$indir" rev-parse --verify "$ref"
+ if git -C "$indir" rev-parse --quiet --verify "$ref"
then
add_from=t
fi
@@ -580,7 +582,7 @@ test_expect_failure () {
export test_prereq
if ! test_skip "$@"
then
- say >&3 "checking known breakage: $2"
+ say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2"
if test_run_ "$2" expecting_failure
then
test_known_broken_ok_ "$1"
@@ -600,7 +602,7 @@ test_expect_success () {
export test_prereq
if ! test_skip "$@"
then
- say >&3 "expecting success: $2"
+ say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2"
if test_run_ "$2"
then
test_ok_ "$1"
@@ -1010,19 +1012,30 @@ test_must_be_empty () {
fi
}
-# Tests that its two parameters refer to the same revision
+# Tests that its two parameters refer to the same revision, or if '!' is
+# provided first, that its other two parameters refer to different
+# revisions.
test_cmp_rev () {
+ local op='=' wrong_result=different
+
+ if test $# -ge 1 && test "x$1" = 'x!'
+ then
+ op='!='
+ wrong_result='the same'
+ shift
+ fi
if test $# != 2
then
error "bug in the test script: test_cmp_rev requires two revisions, but got $#"
else
local r1 r2
r1=$(git rev-parse --verify "$1") &&
- r2=$(git rev-parse --verify "$2") &&
- if test "$r1" != "$r2"
+ r2=$(git rev-parse --verify "$2") || return 1
+
+ if ! test "$r1" "$op" "$r2"
then
cat >&4 <<-EOF
- error: two revisions point to different objects:
+ error: two revisions point to $wrong_result objects:
'$1': $r1
'$2': $r2
EOF
@@ -1173,6 +1186,34 @@ perl () {
command "$PERL_PATH" "$@" 2>&7
} 7>&2 2>&4
+# Given the name of an environment variable with a bool value, normalize
+# its value to a 0 (true) or 1 (false or empty string) return code.
+#
+# test_bool_env GIT_TEST_HTTPD <default-value>
+#
+# Return with code corresponding to the given default value if the variable
+# is unset.
+# Abort the test script if either the value of the variable or the default
+# are not valid bool values.
+
+test_bool_env () {
+ if test $# != 2
+ then
+ BUG "test_bool_env requires two parameters (variable name and default value)"
+ fi
+
+ git env--helper --type=bool --default="$2" --exit-code "$1"
+ ret=$?
+ case $ret in
+ 0|1) # unset or valid bool value
+ ;;
+ *) # invalid bool value or something unexpected
+ error >&7 "test_bool_env requires bool values both for \$$1 and for the default fallback"
+ ;;
+ esac
+ return $ret
+}
+
# Exit the test suite, either by skipping all remaining tests or by
# exiting with an error. If our prerequisite variable $1 falls back
# on a default assume we were opportunistically trying to set up some
@@ -1181,7 +1222,7 @@ perl () {
# The error/skip message should be given by $2.
#
test_skip_or_die () {
- if ! git env--helper --type=bool --default=false --exit-code $1
+ if ! test_bool_env "$1" false
then
skip_all=$2
test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 30b07e310f..44df51be8f 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -212,6 +212,8 @@ fi
TEST_STRESS_JOB_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
TEST_NAME="$(basename "$0" .sh)"
+TEST_NUMBER="${TEST_NAME%%-*}"
+TEST_NUMBER="${TEST_NUMBER#t}"
TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
@@ -402,9 +404,13 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
unset XDG_CACHE_HOME
unset XDG_CONFIG_HOME
unset GITPERLLIB
-GIT_AUTHOR_EMAIL=author@example.com
+TEST_AUTHOR_LOCALNAME=author
+TEST_AUTHOR_DOMAIN=example.com
+GIT_AUTHOR_EMAIL=${TEST_AUTHOR_LOCALNAME}@${TEST_AUTHOR_DOMAIN}
GIT_AUTHOR_NAME='A U Thor'
-GIT_COMMITTER_EMAIL=committer@example.com
+TEST_COMMITTER_LOCALNAME=committer
+TEST_COMMITTER_DOMAIN=example.com
+GIT_COMMITTER_EMAIL=${TEST_COMMITTER_LOCALNAME}@${TEST_COMMITTER_DOMAIN}
GIT_COMMITTER_NAME='C O Mitter'
GIT_MERGE_VERBOSITY=5
GIT_MERGE_AUTOEDIT=no
@@ -507,6 +513,9 @@ EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
LF='
'
+# Single quote
+SQ=\'
+
# UTF-8 ZERO WIDTH NON-JOINER, which HFS+ ignores
# when case-folding filenames
u200c=$(printf '\342\200\214')
@@ -567,6 +576,7 @@ export TERM
error () {
say_color error "error: $*"
+ finalize_junit_xml
GIT_EXIT_OK=t
exit 1
}
@@ -695,7 +705,7 @@ test_failure_ () {
say_color error "not ok $test_count - $1"
shift
printf '%s\n' "$*" | sed -e 's/^/# /'
- test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
+ test "$immediate" = "" || { finalize_junit_xml; GIT_EXIT_OK=t; exit 1; }
}
test_known_broken_ok_ () {
@@ -994,6 +1004,12 @@ test_skip () {
to_skip=t
skipped_reason="GIT_SKIP_TESTS"
fi
+ if test -z "$to_skip" && test -n "$run_list" &&
+ ! match_test_selector_list '--run' $test_count "$run_list"
+ then
+ to_skip=t
+ skipped_reason="--run"
+ fi
if test -z "$to_skip" && test -n "$test_prereq" &&
! test_have_prereq "$test_prereq"
then
@@ -1006,12 +1022,6 @@ test_skip () {
fi
skipped_reason="missing $missing_prereq${of_prereq}"
fi
- if test -z "$to_skip" && test -n "$run_list" &&
- ! match_test_selector_list '--run' $test_count "$run_list"
- then
- to_skip=t
- skipped_reason="--run"
- fi
case "$to_skip" in
t)
@@ -1063,6 +1073,25 @@ write_junit_xml_testcase () {
junit_have_testcase=t
}
+finalize_junit_xml () {
+ if test -n "$write_junit_xml" && test -n "$junit_xml_path"
+ then
+ test -n "$junit_have_testcase" || {
+ junit_start=$(test-tool date getnanos)
+ write_junit_xml_testcase "all tests skipped"
+ }
+
+ # adjust the overall time
+ junit_time=$(test-tool date getnanos $junit_suite_start)
+ sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ <"$junit_xml_path" >"$junit_xml_path.new"
+ mv "$junit_xml_path.new" "$junit_xml_path"
+
+ write_junit_xml " </testsuite>" "</testsuites>"
+ write_junit_xml=
+ fi
+}
+
test_atexit_cleanup=:
test_atexit_handler () {
# In a succeeding test script 'test_atexit_handler' is invoked
@@ -1085,21 +1114,7 @@ test_done () {
# removed, so the commands can access pidfiles and socket files.
test_atexit_handler
- if test -n "$write_junit_xml" && test -n "$junit_xml_path"
- then
- test -n "$junit_have_testcase" || {
- junit_start=$(test-tool date getnanos)
- write_junit_xml_testcase "all tests skipped"
- }
-
- # adjust the overall time
- junit_time=$(test-tool date getnanos $junit_suite_start)
- sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
- <"$junit_xml_path" >"$junit_xml_path.new"
- mv "$junit_xml_path.new" "$junit_xml_path"
-
- write_junit_xml " </testsuite>" "</testsuites>"
- fi
+ finalize_junit_xml
if test -z "$HARNESS_ACTIVE"
then
@@ -1391,23 +1406,23 @@ yes () {
# The GIT_TEST_FAIL_PREREQS code hooks into test_set_prereq(), and
# thus needs to be set up really early, and set an internal variable
# for convenience so the hot test_set_prereq() codepath doesn't need
-# to call "git env--helper". Only do that work if needed by seeing if
-# GIT_TEST_FAIL_PREREQS is set at all.
+# to call "git env--helper" (via test_bool_env). Only do that work
+# if needed by seeing if GIT_TEST_FAIL_PREREQS is set at all.
GIT_TEST_FAIL_PREREQS_INTERNAL=
if test -n "$GIT_TEST_FAIL_PREREQS"
then
- if git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS
+ if test_bool_env GIT_TEST_FAIL_PREREQS false
then
GIT_TEST_FAIL_PREREQS_INTERNAL=true
test_set_prereq FAIL_PREREQS
fi
else
test_lazy_prereq FAIL_PREREQS '
- git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS
+ test_bool_env GIT_TEST_FAIL_PREREQS false
'
fi
-# Fix some commands on Windows
+# Fix some commands on Windows, and other OS-specific things
uname_s=$(uname -s)
case $uname_s in
*MINGW*)
@@ -1438,6 +1453,12 @@ case $uname_s in
test_set_prereq SED_STRIPS_CR
test_set_prereq GREP_STRIPS_CR
;;
+FreeBSD)
+ test_set_prereq REGEX_ILLSEQ
+ test_set_prereq POSIXPERM
+ test_set_prereq BSLASHPSPEC
+ test_set_prereq EXECKEEPSPID
+ ;;
*)
test_set_prereq POSIXPERM
test_set_prereq BSLASHPSPEC
@@ -1462,7 +1483,7 @@ then
fi
test_lazy_prereq C_LOCALE_OUTPUT '
- ! git env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON
+ ! test_bool_env GIT_TEST_GETTEXT_POISON false
'
if test -z "$GIT_TEST_CHECK_CACHE_TREE"