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/test-advise.c22
-rw-r--r--t/helper/test-config.c18
-rw-r--r--t/helper/test-drop-caches.c11
-rw-r--r--t/helper/test-dump-fsmonitor.c2
-rw-r--r--t/helper/test-dump-split-index.c2
-rw-r--r--t/helper/test-parse-options.c2
-rw-r--r--t/helper/test-parse-pathspec-file.c33
-rw-r--r--t/helper/test-path-utils.c118
-rw-r--r--t/helper/test-read-graph.c53
-rw-r--r--t/helper/test-repository.c14
-rw-r--r--t/helper/test-run-command.c182
-rw-r--r--t/helper/test-tool.c3
-rw-r--r--t/helper/test-tool.h3
-rw-r--r--t/helper/test-windows-named-pipe.c2
-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.sh4
-rw-r--r--t/lib-httpd/apache.conf6
-rw-r--r--t/lib-httpd/apply-one-time-perl.sh27
-rw-r--r--t/lib-httpd/apply-one-time-sed.sh22
-rwxr-xr-xt/lib-log-graph.sh28
-rw-r--r--t/lib-pack.sh35
-rw-r--r--t/lib-rebase.sh28
-rwxr-xr-xt/lib-submodule-update.sh68
-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/p5310-pack-bitmaps.sh22
-rw-r--r--t/perf/perf-lib.sh4
-rwxr-xr-xt/t0000-basic.sh65
-rwxr-xr-xt/t0003-attributes.sh47
-rwxr-xr-xt/t0008-ignores.sh39
-rwxr-xr-xt/t0014-alias.sh4
-rwxr-xr-xt/t0018-advice.sh32
-rwxr-xr-xt/t0020-crlf.sh18
-rwxr-xr-xt/t0021-conversion.sh203
-rw-r--r--t/t0021/rot13-filter.pl6
-rwxr-xr-xt/t0027-auto-crlf.sh2
-rwxr-xr-xt/t0028-working-tree-encoding.sh4
-rwxr-xr-xt/t0040-parse-options.sh22
-rwxr-xr-xt/t0060-path-utils.sh45
-rwxr-xr-xt/t0061-run-command.sh4
-rwxr-xr-xt/t0067-parse_pathspec_file.sh108
-rwxr-xr-xt/t0090-cache-tree.sh5
-rwxr-xr-xt/t0300-credentials.sh128
-rwxr-xr-xt/t0500-progress-display.sh4
-rwxr-xr-xt/t1011-read-tree-sparse-checkout.sh3
-rwxr-xr-xt/t1014-read-tree-confusing.sh1
-rwxr-xr-xt/t1050-large.sh16
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh524
-rwxr-xr-xt/t1300-config.sh246
-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.sh18
-rwxr-xr-xt/t1309-early-config.sh2
-rwxr-xr-xt/t1400-update-ref.sh62
-rwxr-xr-xt/t1406-submodule-ref-store.sh2
-rwxr-xr-xt/t1409-avoid-packing-refs.sh16
-rwxr-xr-xt/t1410-reflog.sh4
-rwxr-xr-xt/t1450-fsck.sh28
-rwxr-xr-xt/t1500-rev-parse.sh25
-rwxr-xr-xt/t1501-work-tree.sh2
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh70
-rwxr-xr-xt/t1507-rev-parse-upstream.sh104
-rwxr-xr-xt/t1512-rev-parse-disambiguation.sh4
-rwxr-xr-xt/t2018-checkout-branch.sh75
-rwxr-xr-xt/t2024-checkout-dwim.sh28
-rwxr-xr-xt/t2026-checkout-pathspec-file.sh163
-rwxr-xr-xt/t2070-restore.sh17
-rwxr-xr-xt/t2072-restore-pathspec-file.sh164
-rwxr-xr-xt/t2107-update-index-basic.sh1
-rwxr-xr-xt/t2400-worktree-add.sh37
-rwxr-xr-xt/t2402-worktree-list.sh6
-rwxr-xr-xt/t2405-worktree-submodule.sh90
-rwxr-xr-xt/t3007-ls-files-recurse-submodules.sh1
-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.sh2
-rwxr-xr-xt/t3035-merge-sparse.sh4
-rwxr-xr-xt/t3060-ls-files-with-tree.sh4
-rwxr-xr-xt/t3206-range-diff.sh280
-rwxr-xr-xt/t3210-pack-refs.sh2
-rwxr-xr-xt/t3301-notes.sh272
-rwxr-xr-xt/t3305-notes-fanout.sh107
-rwxr-xr-xt/t3308-notes-merge.sh83
-rwxr-xr-xt/t3309-notes-merge-auto-resolve.sh228
-rwxr-xr-xt/t3310-notes-merge-manual-resolve.sh106
-rwxr-xr-xt/t3311-notes-merge-fanout.sh60
-rwxr-xr-xt/t3400-rebase.sh68
-rwxr-xr-xt/t3401-rebase-and-am-rename.sh4
-rwxr-xr-xt/t3403-rebase-skip.sh111
-rwxr-xr-xt/t3404-rebase-interactive.sh817
-rwxr-xr-xt/t3406-rebase-message.sh19
-rwxr-xr-xt/t3407-rebase-abort.sh6
-rwxr-xr-xt/t3415-rebase-autosquash.sh153
-rwxr-xr-xt/t3419-rebase-patch-id.sh5
-rwxr-xr-xt/t3420-rebase-autostash.sh22
-rwxr-xr-xt/t3421-rebase-topology-linear.sh54
-rwxr-xr-xt/t3424-rebase-empty.sh134
-rwxr-xr-xt/t3425-rebase-topology-merges.sh8
-rwxr-xr-xt/t3427-rebase-subtree.sh12
-rwxr-xr-xt/t3429-rebase-edit-todo.sh32
-rwxr-xr-xt/t3430-rebase-merges.sh36
-rwxr-xr-xt/t3432-rebase-fast-forward.sh56
-rwxr-xr-xt/t3433-rebase-across-mode-change.sh48
-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/t3504-cherry-pick-rerere.sh6
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh51
-rwxr-xr-xt/t3508-cherry-pick-many-commits.sh2
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh3
-rwxr-xr-xt/t3600-rm.sh21
-rwxr-xr-xt/t3601-rm-pathspec-file.sh79
-rwxr-xr-xt/t3700-add.sh4
-rwxr-xr-xt/t3701-add-interactive.sh179
-rwxr-xr-xt/t3704-add-pathspec-file.sh159
-rwxr-xr-xt/t3900-i18n-commit.sh37
-rwxr-xr-xt/t3903-stash.sh23
-rwxr-xr-xt/t3905-stash-include-untracked.sh4
-rwxr-xr-xt/t3909-stash-pathspec-file.sh100
-rwxr-xr-xt/t4010-diff-pathspec.sh20
-rwxr-xr-xt/t4011-diff-symlink.sh40
-rwxr-xr-xt/t4013-diff-various.sh44
-rwxr-xr-xt/t4014-format-patch.sh218
-rwxr-xr-xt/t4015-diff-whitespace.sh213
-rwxr-xr-xt/t4018-diff-funcname.sh2
-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/t4026-color.sh12
-rwxr-xr-xt/t4027-diff-submodule.sh16
-rwxr-xr-xt/t4034-diff-words.sh93
-rwxr-xr-xt/t4038-diff-combined.sh21
-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/t4060-diff-submodule-option-diff-format.sh126
-rwxr-xr-xt/t4066-diff-emit-delay.sh10
-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/t4117-apply-reject.sh6
-rwxr-xr-xt/t4124-apply-ws-rule.sh10
-rwxr-xr-xt/t4134-apply-submodule.sh5
-rwxr-xr-xt/t4138-apply-ws-expansion.sh16
-rwxr-xr-xt/t4150-am.sh20
-rwxr-xr-xt/t4200-rerere.sh3
-rwxr-xr-xt/t4202-log.sh327
-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.sh4
-rwxr-xr-xt/t4211-line-log.sh3
-rw-r--r--t/t4211/sha1/expect.beginning-of-file (renamed from t/t4211/expect.beginning-of-file)0
-rw-r--r--t/t4211/sha1/expect.end-of-file (renamed from t/t4211/expect.end-of-file)0
-rw-r--r--t/t4211/sha1/expect.move-support-f (renamed from t/t4211/expect.move-support-f)0
-rw-r--r--t/t4211/sha1/expect.multiple (renamed from t/t4211/expect.multiple)0
-rw-r--r--t/t4211/sha1/expect.multiple-overlapping (renamed from t/t4211/expect.multiple-overlapping)0
-rw-r--r--t/t4211/sha1/expect.multiple-superset (renamed from t/t4211/expect.multiple-superset)0
-rw-r--r--t/t4211/sha1/expect.parallel-change-f-to-main (renamed from t/t4211/expect.parallel-change-f-to-main)0
-rw-r--r--t/t4211/sha1/expect.simple-f (renamed from t/t4211/expect.simple-f)0
-rw-r--r--t/t4211/sha1/expect.simple-f-to-main (renamed from t/t4211/expect.simple-f-to-main)0
-rw-r--r--t/t4211/sha1/expect.simple-main (renamed from t/t4211/expect.simple-main)0
-rw-r--r--t/t4211/sha1/expect.simple-main-to-end (renamed from t/t4211/expect.simple-main-to-end)0
-rw-r--r--t/t4211/sha1/expect.two-ranges (renamed from t/t4211/expect.two-ranges)0
-rw-r--r--t/t4211/sha1/expect.vanishes-early (renamed from t/t4211/expect.vanishes-early)0
-rw-r--r--t/t4211/sha256/expect.beginning-of-file43
-rw-r--r--t/t4211/sha256/expect.end-of-file62
-rw-r--r--t/t4211/sha256/expect.move-support-f80
-rw-r--r--t/t4211/sha256/expect.multiple104
-rw-r--r--t/t4211/sha256/expect.multiple-overlapping187
-rw-r--r--t/t4211/sha256/expect.multiple-superset187
-rw-r--r--t/t4211/sha256/expect.parallel-change-f-to-main160
-rw-r--r--t/t4211/sha256/expect.simple-f59
-rw-r--r--t/t4211/sha256/expect.simple-f-to-main100
-rw-r--r--t/t4211/sha256/expect.simple-main68
-rw-r--r--t/t4211/sha256/expect.simple-main-to-end70
-rw-r--r--t/t4211/sha256/expect.two-ranges102
-rw-r--r--t/t4211/sha256/expect.vanishes-early39
-rwxr-xr-xt/t4213-log-tabexpand.sh2
-rwxr-xr-xt/t4214-log-graph-octopus.sh144
-rwxr-xr-xt/t4215-log-skewed-merges.sh373
-rwxr-xr-xt/t4256-am-format-flowed.sh2
-rwxr-xr-xt/t4300-merge-tree.sh188
-rwxr-xr-xt/t5100-mailinfo.sh15
-rwxr-xr-xt/t5150-request-pull.sh8
-rwxr-xr-xt/t5302-pack-index.sh21
-rwxr-xr-xt/t5309-pack-delta-cycles.sh18
-rwxr-xr-xt/t5310-pack-bitmaps.sh36
-rwxr-xr-xt/t5313-pack-bounds-checks.sh19
-rwxr-xr-xt/t5314-pack-cycle-detection.sh2
-rwxr-xr-xt/t5317-pack-objects-filter-objects.sh34
-rwxr-xr-xt/t5318-commit-graph.sh18
-rwxr-xr-xt/t5319-multi-pack-index.sh95
-rwxr-xr-xt/t5321-pack-large-objects.sh4
-rwxr-xr-xt/t5324-split-commit-graph.sh15
-rwxr-xr-xt/t5400-send-pack.sh2
-rwxr-xr-xt/t5407-post-rewrite-hook.sh16
-rwxr-xr-xt/t5409-colorize-remote-messages.sh3
-rwxr-xr-xt/t5500-fetch-pack.sh23
-rwxr-xr-xt/t5504-fetch-receive-strict.sh17
-rwxr-xr-xt/t5505-remote.sh88
-rwxr-xr-xt/t5509-fetch-push-namespaces.sh13
-rwxr-xr-xt/t5510-fetch.sh34
-rwxr-xr-xt/t5512-ls-remote.sh29
-rwxr-xr-xt/t5515-fetch-merge-logic.sh62
-rwxr-xr-xt/t5516-fetch-push.sh23
-rwxr-xr-xt/t5520-pull.sh366
-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.sh18
-rwxr-xr-xt/t5539-fetch-http-shallow.sh2
-rwxr-xr-xt/t5540-http-push-webdav.sh6
-rwxr-xr-xt/t5541-http-push-smart.sh4
-rwxr-xr-xt/t5545-push-options.sh2
-rwxr-xr-xt/t5551-http-fetch-smart.sh12
-rwxr-xr-xt/t5552-skipping-fetch-negotiator.sh18
-rwxr-xr-xt/t5562-http-backend-content-length.sh2
-rwxr-xr-xt/t5573-pull-verify-signatures.sh64
-rwxr-xr-xt/t5580-unc-paths.sh (renamed from t/t5580-clone-push-unc.sh)14
-rwxr-xr-xt/t5601-clone.sh4
-rwxr-xr-xt/t5604-clone-reference.sh5
-rwxr-xr-xt/t5607-clone-bundle.sh2
-rwxr-xr-xt/t5608-clone-2gb.sh2
-rwxr-xr-xt/t5616-partial-clone.sh157
-rwxr-xr-xt/t5617-clone-submodules-remote.sh13
-rwxr-xr-xt/t5700-protocol-v1.sh3
-rwxr-xr-xt/t5702-protocol-v2.sh34
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh62
-rwxr-xr-xt/t6000-rev-list-misc.sh25
-rwxr-xr-xt/t6006-rev-list-format.sh32
-rwxr-xr-xt/t6016-rev-list-graph-simplify-history.sh30
-rwxr-xr-xt/t6019-rev-list-ancestry-path.sh4
-rwxr-xr-xt/t6020-merge-df.sh55
-rwxr-xr-xt/t6021-merge-criss-cross.sh137
-rwxr-xr-xt/t6022-merge-rename.sh393
-rwxr-xr-xt/t6023-merge-file.sh568
-rwxr-xr-xt/t6024-recursive-merge.sh135
-rwxr-xr-xt/t6025-merge-symlinks.sh95
-rwxr-xr-xt/t6026-merge-attr.sh46
-rwxr-xr-xt/t6030-bisect-porcelain.sh2
-rwxr-xr-xt/t6034-merge-rename-nocruft.sh122
-rwxr-xr-xt/t6035-merge-dir-to-symlink.sh28
-rwxr-xr-xt/t6036-recursive-corner-cases.sh43
-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.sh217
-rwxr-xr-xt/t6047-diff3-conflict-markers.sh13
-rwxr-xr-xt/t6102-rev-list-unexpected-objects.sh2
-rwxr-xr-xt/t6113-rev-list-bitmap-filters.sh56
-rwxr-xr-xt/t6120-describe.sh123
-rwxr-xr-xt/t6130-pathspec-noglob.sh1
-rwxr-xr-xt/t6136-pathspec-in-bare.sh38
-rwxr-xr-xt/t6200-fmt-merge-msg.sh23
-rwxr-xr-xt/t6300-for-each-ref.sh27
-rwxr-xr-xt/t6500-gc.sh6
-rwxr-xr-xt/t7004-tag.sh10
-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/t7112-reset-submodule.sh1
-rwxr-xr-xt/t7300-clean.sh9
-rwxr-xr-xt/t7400-submodule-basic.sh62
-rwxr-xr-xt/t7406-submodule-update.sh30
-rwxr-xr-xt/t7410-submodule-checkout-to.sh77
-rwxr-xr-xt/t7415-submodule-names.sh57
-rwxr-xr-xt/t7416-submodule-dash-url.sh14
-rwxr-xr-xt/t7417-submodule-path-url.sh17
-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/t7508-status.sh2
-rwxr-xr-xt/t7510-signed-commit.sh55
-rwxr-xr-xt/t7512-status-help.sh12
-rwxr-xr-xt/t7513-interpret-trailers.sh2
-rwxr-xr-xt/t7519-status-fsmonitor.sh18
-rwxr-xr-xt/t7519/fsmonitor-all1
-rwxr-xr-xt/t7519/fsmonitor-all-v221
-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.sh11
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh11
-rwxr-xr-xt/t8003-blame-corner-cases.sh1
-rwxr-xr-xt/t9001-send-email.sh8
-rwxr-xr-xt/t9010-svn-fe.sh4
-rwxr-xr-xt/t9106-git-svn-commit-diff-clobber.sh3
-rwxr-xr-xt/t9116-git-svn-log.sh12
-rwxr-xr-xt/t9300-fast-import.sh191
-rwxr-xr-xt/t9301-fast-import-notes.sh2
-rwxr-xr-xt/t9350-fast-export.sh5
-rwxr-xr-xt/t9502-gitweb-standalone-parse-output.sh7
-rwxr-xr-xt/t9800-git-p4-basic.sh1
-rwxr-xr-xt/t9809-git-p4-client-view.sh2
-rwxr-xr-xt/t9810-git-p4-rcs.sh1
-rwxr-xr-xt/t9902-completion.sh70
-rwxr-xr-xt/t9903-bash-prompt.sh8
-rw-r--r--t/test-lib-functions.sh78
-rw-r--r--t/test-lib.sh70
334 files changed, 12965 insertions, 3828 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/test-advise.c b/t/helper/test-advise.c
new file mode 100644
index 0000000000..38cdc2884e
--- /dev/null
+++ b/t/helper/test-advise.c
@@ -0,0 +1,22 @@
+#include "test-tool.h"
+#include "cache.h"
+#include "advice.h"
+#include "config.h"
+
+int cmd__advise_if_enabled(int argc, const char **argv)
+{
+ if (!argv[1])
+ die("usage: %s <advice>", argv[0]);
+
+ setup_git_directory();
+ git_config(git_default_config, NULL);
+
+ /*
+ * Any advice type can be used for testing, but NESTED_TAG was
+ * selected here and in t0018 where this command is being
+ * executed.
+ */
+ advise_if_enabled(ADVICE_NESTED_TAG, argv[1]);
+
+ return 0;
+}
diff --git a/t/helper/test-config.c b/t/helper/test-config.c
index 214003d5b2..234c722b48 100644
--- a/t/helper/test-config.c
+++ b/t/helper/test-config.c
@@ -37,21 +37,6 @@
*
*/
-static const char *scope_name(enum config_scope scope)
-{
- switch (scope) {
- case CONFIG_SCOPE_SYSTEM:
- return "system";
- case CONFIG_SCOPE_GLOBAL:
- return "global";
- case CONFIG_SCOPE_REPO:
- return "repo";
- case CONFIG_SCOPE_CMDLINE:
- return "cmdline";
- default:
- return "unknown";
- }
-}
static int iterate_cb(const char *var, const char *value, void *data)
{
static int nr;
@@ -63,7 +48,8 @@ static int iterate_cb(const char *var, const char *value, void *data)
printf("value=%s\n", value ? value : "(null)");
printf("origin=%s\n", current_config_origin_type());
printf("name=%s\n", current_config_name());
- printf("scope=%s\n", scope_name(current_config_scope()));
+ printf("lno=%d\n", current_config_line());
+ printf("scope=%s\n", config_scope_name(current_config_scope()));
return 0;
}
diff --git a/t/helper/test-drop-caches.c b/t/helper/test-drop-caches.c
index f65e301f9d..7b4278462b 100644
--- a/t/helper/test-drop-caches.c
+++ b/t/helper/test-drop-caches.c
@@ -8,18 +8,21 @@ static int cmd_sync(void)
{
char Buffer[MAX_PATH];
DWORD dwRet;
- char szVolumeAccessPath[] = "\\\\.\\X:";
+ char szVolumeAccessPath[] = "\\\\.\\XXXX:";
HANDLE hVolWrite;
- int success = 0;
+ int success = 0, dos_drive_prefix;
dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
if ((0 == dwRet) || (dwRet > MAX_PATH))
return error("Error getting current directory");
- if (!has_dos_drive_prefix(Buffer))
+ dos_drive_prefix = has_dos_drive_prefix(Buffer);
+ if (!dos_drive_prefix)
return error("'%s': invalid drive letter", Buffer);
- szVolumeAccessPath[4] = Buffer[0];
+ memcpy(szVolumeAccessPath, Buffer, dos_drive_prefix);
+ szVolumeAccessPath[dos_drive_prefix] = '\0';
+
hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == hVolWrite)
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-dump-split-index.c b/t/helper/test-dump-split-index.c
index 63c689d6ee..a209880eb3 100644
--- a/t/helper/test-dump-split-index.c
+++ b/t/helper/test-dump-split-index.c
@@ -13,6 +13,8 @@ int cmd__dump_split_index(int ac, const char **av)
struct split_index *si;
int i;
+ setup_git_directory();
+
do_read_index(&the_index, av[1], 1);
printf("own %s\n", oid_to_hex(&the_index.oid));
si = the_index.split_index;
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index af82db06ac..2051ce57db 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -121,6 +121,8 @@ int cmd__parse_options(int argc, const char **argv)
OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
OPT_MAGNITUDE('m', "magnitude", &magnitude, "get a magnitude"),
OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
+ OPT_CMDMODE(0, "mode1", &integer, "set integer to 1 (cmdmode option)", 1),
+ OPT_CMDMODE(0, "mode2", &integer, "set integer to 2 (cmdmode option)", 2),
OPT_CALLBACK('L', "length", &integer, "str",
"get length of <str>", length_callback),
OPT_FILENAME('F', "file", &file, "set file to <file>"),
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-path-utils.c b/t/helper/test-path-utils.c
index 5d543ad21f..313a153209 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -185,6 +185,99 @@ static int cmp_by_st_size(const void *a, const void *b)
return x > y ? -1 : (x < y ? +1 : 0);
}
+/*
+ * A very simple, reproducible pseudo-random generator. Copied from
+ * `test-genrandom.c`.
+ */
+static uint64_t my_random_value = 1234;
+
+static uint64_t my_random(void)
+{
+ my_random_value = my_random_value * 1103515245 + 12345;
+ return my_random_value;
+}
+
+/*
+ * A fast approximation of the square root, without requiring math.h.
+ *
+ * It uses Newton's method to approximate the solution of 0 = x^2 - value.
+ */
+static double my_sqrt(double value)
+{
+ const double epsilon = 1e-6;
+ double x = value;
+
+ if (value == 0)
+ return 0;
+
+ for (;;) {
+ double delta = (value / x - x) / 2;
+ if (delta < epsilon && delta > -epsilon)
+ return x + delta;
+ x += delta;
+ }
+}
+
+static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
+{
+ size_t i, j, nr, min_len = 3, max_len = 20;
+ char **names;
+ int repetitions = 15, file_mode = 0100644;
+ uint64_t begin, end;
+ double m[3][2], v[3][2];
+ uint64_t cumul;
+ double cumul2;
+
+ if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) {
+ file_mode = 0120000;
+ argc--;
+ argv++;
+ }
+
+ nr = argc > 1 ? strtoul(argv[1], NULL, 0) : 1000000;
+ ALLOC_ARRAY(names, nr);
+
+ if (argc > 2) {
+ min_len = strtoul(argv[2], NULL, 0);
+ if (argc > 3)
+ max_len = strtoul(argv[3], NULL, 0);
+ if (min_len > max_len)
+ die("min_len > max_len");
+ }
+
+ for (i = 0; i < nr; i++) {
+ size_t len = min_len + (my_random() % (max_len + 1 - min_len));
+
+ names[i] = xmallocz(len);
+ while (len > 0)
+ names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' ')));
+ }
+
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) {
+ cumul = 0;
+ cumul2 = 0;
+ for (i = 0; i < repetitions; i++) {
+ begin = getnanotime();
+ for (j = 0; j < nr; j++)
+ verify_path(names[j], file_mode);
+ end = getnanotime();
+ printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6);
+ cumul += end - begin;
+ cumul2 += (end - begin) * (end - begin);
+ }
+ m[protect_ntfs][protect_hfs] = cumul / (double)repetitions;
+ v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]);
+ printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6);
+ }
+
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++)
+ printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]);
+
+ return 0;
+}
+
int cmd__path_utils(int argc, const char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@@ -197,11 +290,14 @@ int cmd__path_utils(int argc, const char **argv)
}
if (argc >= 2 && !strcmp(argv[1], "real_path")) {
+ struct strbuf realpath = STRBUF_INIT;
while (argc > 2) {
- puts(real_path(argv[2]));
+ strbuf_realpath(&realpath, argv[2], 1);
+ puts(realpath.buf);
argc--;
argv++;
}
+ strbuf_release(&realpath);
return 0;
}
@@ -355,6 +451,26 @@ int cmd__path_utils(int argc, const char **argv)
return !!res;
}
+ if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs"))
+ return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1);
+
+ if (argc > 1 && !strcmp(argv[1], "is_valid_path")) {
+ int res = 0, expect = 1, i;
+
+ for (i = 2; i < argc; i++)
+ if (!strcmp("--not", argv[i]))
+ expect = 0;
+ else if (expect != is_valid_path(argv[i]))
+ res = error("'%s' is%s a valid path",
+ argv[i], expect ? " not" : "");
+ else
+ fprintf(stderr,
+ "'%s' is%s a valid path\n",
+ argv[i], expect ? "" : " not");
+
+ return !!res;
+ }
+
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;
diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c
new file mode 100644
index 0000000000..f8a461767c
--- /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;
+ struct object_directory *odb;
+
+ setup_git_directory();
+ odb = the_repository->objects->odb;
+
+ graph_name = get_commit_graph_filename(odb);
+
+ 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, odb);
+ 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-repository.c b/t/helper/test-repository.c
index f7f8618445..56f0e3c1be 100644
--- a/t/helper/test-repository.c
+++ b/t/helper/test-repository.c
@@ -19,12 +19,11 @@ static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
memset(the_repository, 0, sizeof(*the_repository));
- /* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
-
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");
+ repo_set_hash_algo(the_repository, hash_algo_by_ptr(r.hash_algo));
+
c = lookup_commit(&r, commit_oid);
if (!parse_commit_in_graph(&r, c))
@@ -50,12 +49,11 @@ static void test_get_commit_tree_in_graph(const char *gitdir,
memset(the_repository, 0, sizeof(*the_repository));
- /* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
-
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");
+ repo_set_hash_algo(the_repository, hash_algo_by_ptr(r.hash_algo));
+
c = lookup_commit(&r, commit_oid);
/*
@@ -75,6 +73,10 @@ static void test_get_commit_tree_in_graph(const char *gitdir,
int cmd__repository(int argc, const char **argv)
{
+ int nongit_ok = 0;
+
+ setup_git_directory_gently(&nongit_ok);
+
if (argc < 2)
die("must have at least 2 arguments");
if (!strcmp(argv[1], "parse_commit_in_graph")) {
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index ead6dc611a..1646aa25d8 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -18,8 +18,8 @@
#include "string-list.h"
#include "thread-utils.h"
#include "wildmatch.h"
-#include <string.h>
-#include <errno.h>
+#include "gettext.h"
+#include "parse-options.h"
static int number_callbacks;
static int parallel_next(struct child_process *cp,
@@ -200,6 +200,174 @@ static int testsuite(int argc, const char **argv)
return !!ret;
}
+static uint64_t my_random_next = 1234;
+
+static uint64_t my_random(void)
+{
+ uint64_t res = my_random_next;
+ my_random_next = my_random_next * 1103515245 + 12345;
+ return res;
+}
+
+static int quote_stress_test(int argc, const char **argv)
+{
+ /*
+ * We are running a quote-stress test.
+ * spawn a subprocess that runs quote-stress with a
+ * special option that echoes back the arguments that
+ * were passed in.
+ */
+ char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a";
+ int i, j, k, trials = 100, skip = 0, msys2 = 0;
+ struct strbuf out = STRBUF_INIT;
+ struct argv_array args = ARGV_ARRAY_INIT;
+ struct option options[] = {
+ OPT_INTEGER('n', "trials", &trials, "Number of trials"),
+ OPT_INTEGER('s', "skip", &skip, "Skip <n> trials"),
+ OPT_BOOL('m', "msys2", &msys2, "Test quoting for MSYS2's sh"),
+ OPT_END()
+ };
+ const char * const usage[] = {
+ "test-tool run-command quote-stress-test <options>",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, NULL, options, usage, 0);
+
+ setenv("MSYS_NO_PATHCONV", "1", 0);
+
+ for (i = 0; i < trials; i++) {
+ struct child_process cp = CHILD_PROCESS_INIT;
+ size_t arg_count, arg_offset;
+ int ret = 0;
+
+ argv_array_clear(&args);
+ if (msys2)
+ argv_array_pushl(&args, "sh", "-c",
+ "printf %s\\\\0 \"$@\"", "skip", NULL);
+ else
+ argv_array_pushl(&args, "test-tool", "run-command",
+ "quote-echo", NULL);
+ arg_offset = args.argc;
+
+ if (argc > 0) {
+ trials = 1;
+ arg_count = argc;
+ for (j = 0; j < arg_count; j++)
+ argv_array_push(&args, argv[j]);
+ } else {
+ arg_count = 1 + (my_random() % 5);
+ for (j = 0; j < arg_count; j++) {
+ char buf[20];
+ size_t min_len = 1;
+ size_t arg_len = min_len +
+ (my_random() % (ARRAY_SIZE(buf) - min_len));
+
+ for (k = 0; k < arg_len; k++)
+ buf[k] = special[my_random() %
+ ARRAY_SIZE(special)];
+ buf[arg_len] = '\0';
+
+ argv_array_push(&args, buf);
+ }
+ }
+
+ if (i < skip)
+ continue;
+
+ cp.argv = args.argv;
+ strbuf_reset(&out);
+ if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0)
+ return error("Failed to spawn child process");
+
+ for (j = 0, k = 0; j < arg_count; j++) {
+ const char *arg = args.argv[j + arg_offset];
+
+ if (strcmp(arg, out.buf + k))
+ ret = error("incorrectly quoted arg: '%s', "
+ "echoed back as '%s'",
+ arg, out.buf + k);
+ k += strlen(out.buf + k) + 1;
+ }
+
+ if (k != out.len)
+ ret = error("got %d bytes, but consumed only %d",
+ (int)out.len, (int)k);
+
+ if (ret) {
+ fprintf(stderr, "Trial #%d failed. Arguments:\n", i);
+ for (j = 0; j < arg_count; j++)
+ fprintf(stderr, "arg #%d: '%s'\n",
+ (int)j, args.argv[j + arg_offset]);
+
+ strbuf_release(&out);
+ argv_array_clear(&args);
+
+ return ret;
+ }
+
+ if (i && (i % 100) == 0)
+ fprintf(stderr, "Trials completed: %d\n", (int)i);
+ }
+
+ strbuf_release(&out);
+ argv_array_clear(&args);
+
+ return 0;
+}
+
+static int quote_echo(int argc, const char **argv)
+{
+ while (argc > 1) {
+ fwrite(argv[1], strlen(argv[1]), 1, stdout);
+ fputc('\0', stdout);
+ argv++;
+ argc--;
+ }
+
+ 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;
@@ -207,6 +375,16 @@ int cmd__run_command(int argc, const char **argv)
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);
+
+ if (argc >= 2 && !strcmp(argv[1], "quote-echo"))
+ return !!quote_echo(argc - 1, argv + 1);
if (argc < 3)
return 1;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 19ee26d931..31eedcd241 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -14,6 +14,7 @@ struct test_cmd {
};
static struct test_cmd cmds[] = {
+ { "advise", cmd__advise_if_enabled },
{ "chmtime", cmd__chmtime },
{ "config", cmd__config },
{ "ctype", cmd__ctype },
@@ -39,12 +40,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 c2aa56ef50..4eb5e6609e 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -4,6 +4,7 @@
#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "git-compat-util.h"
+int cmd__advise_if_enabled(int argc, const char **argv);
int cmd__chmtime(int argc, const char **argv);
int cmd__config(int argc, const char **argv);
int cmd__ctype(int argc, const char **argv);
@@ -29,12 +30,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/helper/test-windows-named-pipe.c b/t/helper/test-windows-named-pipe.c
index b4b752b01a..ae52183e63 100644
--- a/t/helper/test-windows-named-pipe.c
+++ b/t/helper/test-windows-named-pipe.c
@@ -19,7 +19,7 @@ int cmd__windows_named_pipe(int argc, const char **argv)
if (argc < 2)
goto print_usage;
filename = argv[1];
- if (strchr(filename, '/') || strchr(filename, '\\'))
+ if (strpbrk(filename, "/\\"))
goto print_usage;
strbuf_addf(&pathname, "//./pipe/%s", filename);
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 bc0b9c71f8..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_SVN_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..1449ee95e9 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
@@ -132,7 +132,7 @@ prepare_httpd() {
install_script broken-smart-http.sh
install_script error-smart-http.sh
install_script error.sh
- install_script apply-one-time-sed.sh
+ install_script apply-one-time-perl.sh
ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules"
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 5c1c86c193..994e5290d6 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -113,7 +113,7 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
</LocationMatch>
-<LocationMatch /one_time_sed/>
+<LocationMatch /one_time_perl/>
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
</LocationMatch>
@@ -122,7 +122,7 @@ ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
ScriptAlias /broken_smart/ broken-smart-http.sh/
ScriptAlias /error_smart/ error-smart-http.sh/
ScriptAlias /error/ error.sh/
-ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1
+ScriptAliasMatch /one_time_perl/(.*) apply-one-time-perl.sh/$1
<Directory ${GIT_EXEC_PATH}>
Options FollowSymlinks
</Directory>
@@ -135,7 +135,7 @@ ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1
<Files error.sh>
Options ExecCGI
</Files>
-<Files apply-one-time-sed.sh>
+<Files apply-one-time-perl.sh>
Options ExecCGI
</Files>
<Files ${GIT_EXEC_PATH}/git-http-backend>
diff --git a/t/lib-httpd/apply-one-time-perl.sh b/t/lib-httpd/apply-one-time-perl.sh
new file mode 100644
index 0000000000..09a0abdff7
--- /dev/null
+++ b/t/lib-httpd/apply-one-time-perl.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# If "one-time-perl" exists in $HTTPD_ROOT_PATH, run perl on the HTTP response,
+# using the contents of "one-time-perl" as the perl command to be run. If the
+# response was modified as a result, delete "one-time-perl" so that subsequent
+# HTTP responses are no longer modified.
+#
+# This can be used to simulate the effects of the repository changing in
+# between HTTP request-response pairs.
+if test -f one-time-perl
+then
+ LC_ALL=C
+ export LC_ALL
+
+ "$GIT_EXEC_PATH/git-http-backend" >out
+ perl -pe "$(cat one-time-perl)" out >out_modified
+
+ if cmp -s out out_modified
+ then
+ cat out
+ else
+ cat out_modified
+ rm one-time-perl
+ fi
+else
+ "$GIT_EXEC_PATH/git-http-backend"
+fi
diff --git a/t/lib-httpd/apply-one-time-sed.sh b/t/lib-httpd/apply-one-time-sed.sh
deleted file mode 100644
index fcef728925..0000000000
--- a/t/lib-httpd/apply-one-time-sed.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-# If "one-time-sed" exists in $HTTPD_ROOT_PATH, run sed on the HTTP response,
-# using the contents of "one-time-sed" as the sed command to be run. If the
-# response was modified as a result, delete "one-time-sed" so that subsequent
-# HTTP responses are no longer modified.
-#
-# This can be used to simulate the effects of the repository changing in
-# between HTTP request-response pairs.
-if [ -e one-time-sed ]; then
- "$GIT_EXEC_PATH/git-http-backend" >out
- sed "$(cat one-time-sed)" <out >out_modified
-
- if diff out out_modified >/dev/null; then
- cat out
- else
- cat out_modified
- rm one-time-sed
- fi
-else
- "$GIT_EXEC_PATH/git-http-backend"
-fi
diff --git a/t/lib-log-graph.sh b/t/lib-log-graph.sh
new file mode 100755
index 0000000000..1184cceef2
--- /dev/null
+++ b/t/lib-log-graph.sh
@@ -0,0 +1,28 @@
+# Helps shared by the test scripts for comparing log graphs.
+
+sanitize_log_output () {
+ sed -e 's/ *$//' \
+ -e 's/commit [0-9a-f]*$/commit COMMIT_OBJECT_NAME/' \
+ -e 's/Merge: [ 0-9a-f]*$/Merge: MERGE_PARENTS/' \
+ -e 's/Merge tag.*/Merge HEADS DESCRIPTION/' \
+ -e 's/Merge commit.*/Merge HEADS DESCRIPTION/' \
+ -e 's/index [0-9a-f]*\.\.[0-9a-f]*/index BEFORE..AFTER/'
+}
+
+lib_test_cmp_graph () {
+ git log --graph "$@" >output &&
+ sed 's/ *$//' >output.sanitized <output &&
+ test_i18ncmp expect output.sanitized
+}
+
+lib_test_cmp_short_graph () {
+ git log --graph --pretty=short "$@" >output &&
+ sanitize_log_output >output.sanitized <output &&
+ test_i18ncmp expect output.sanitized
+}
+
+lib_test_cmp_colored_graph () {
+ git log --graph --color=always "$@" >output.colors.raw &&
+ test_decode_color <output.colors.raw | sed "s/ *\$//" >output.colors &&
+ test_cmp expect.colors output.colors
+}
diff --git a/t/lib-pack.sh b/t/lib-pack.sh
index c4d907a450..f3463170b3 100644
--- a/t/lib-pack.sh
+++ b/t/lib-pack.sh
@@ -35,9 +35,11 @@ pack_header () {
# have hardcoded some well-known objects. See the case statements below for the
# complete list.
pack_obj () {
+ test_oid_init
+
case "$1" in
# empty blob
- e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)
+ $EMPTY_BLOB)
case "$2" in
'')
printf '\060\170\234\003\0\0\0\0\1'
@@ -47,7 +49,7 @@ pack_obj () {
;;
# blob containing "\7\76"
- e68fe8129b546b101aee9510c5328e7f21ca1d18)
+ $(test_oid packlib_7_76))
case "$2" in
'')
printf '\062\170\234\143\267\3\0\0\116\0\106'
@@ -59,11 +61,18 @@ pack_obj () {
printf '\234\143\142\142\142\267\003\0\0\151\0\114'
return
;;
+ 37c8e2c15bb22b912e59b43fd51a4f7e9465ed0b5084c5a1411d991cbe630683)
+ printf '\165\67\310\342\301\133\262\53\221\56\131' &&
+ printf '\264\77\325\32\117\176\224\145\355\13\120' &&
+ printf '\204\305\241\101\35\231\34\276\143\6\203\170' &&
+ printf '\234\143\142\142\142\267\003\0\0\151\0\114'
+ return
+ ;;
esac
;;
# blob containing "\7\0"
- 01d7713666f4de822776c7622c10f1b07de280dc)
+ $(test_oid packlib_7_0))
case "$2" in
'')
printf '\062\170\234\143\147\0\0\0\20\0\10'
@@ -75,6 +84,13 @@ pack_obj () {
printf '\143\142\142\142\147\0\0\0\53\0\16'
return
;;
+ 5d8e6fc40f2dab00e6983a48523fe57e621f46434cb58dbd4422fba03380d886)
+ printf '\165\135\216\157\304\17\55\253\0\346\230\72' &&
+ printf '\110\122\77\345\176\142\37\106\103\114\265' &&
+ printf '\215\275\104\42\373\240\63\200\330\206\170\234' &&
+ printf '\143\142\142\142\147\0\0\0\53\0\16'
+ return
+ ;;
esac
;;
esac
@@ -86,7 +102,7 @@ pack_obj () {
then
echo "$1" | git pack-objects --stdout >pack_obj.tmp &&
size=$(wc -c <pack_obj.tmp) &&
- dd if=pack_obj.tmp bs=1 count=$((size - 20 - 12)) skip=12 &&
+ dd if=pack_obj.tmp bs=1 count=$((size - $(test_oid rawsz) - 12)) skip=12 &&
rm -f pack_obj.tmp
return
fi
@@ -97,7 +113,8 @@ pack_obj () {
# Compute and append pack trailer to "$1"
pack_trailer () {
- test-tool sha1 -b <"$1" >trailer.tmp &&
+ test_oid_init &&
+ test-tool $(test_oid algo) -b <"$1" >trailer.tmp &&
cat trailer.tmp >>"$1" &&
rm -f trailer.tmp
}
@@ -108,3 +125,11 @@ pack_trailer () {
clear_packs () {
rm -f .git/objects/pack/*
}
+
+test_oid_cache <<-EOF
+packlib_7_0 sha1:01d7713666f4de822776c7622c10f1b07de280dc
+packlib_7_0 sha256:37c8e2c15bb22b912e59b43fd51a4f7e9465ed0b5084c5a1411d991cbe630683
+
+packlib_7_76 sha1:e68fe8129b546b101aee9510c5328e7f21ca1d18
+packlib_7_76 sha256:5d8e6fc40f2dab00e6983a48523fe57e621f46434cb58dbd4422fba03380d886
+EOF
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 6d87961e41..b72c051f47 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -119,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/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 1dd17fc03e..64fc6487dd 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -297,7 +297,7 @@ test_submodule_content () {
# - Directory containing tracked files replaced by submodule
# - Submodule replaced by tracked files in directory
# - Submodule replaced by tracked file with the same name
-# - tracked file replaced by submodule
+# - Tracked file replaced by submodule
#
# The default is that submodule contents aren't changed until "git submodule
# update" is run. And even then that command doesn't delete the work tree of
@@ -621,11 +621,13 @@ test_submodule_forced_switch () {
# - Directory containing tracked files replaced by submodule
# - Submodule replaced by tracked files in directory
# - Submodule replaced by tracked file with the same name
-# - tracked file replaced by submodule
+# - Tracked file replaced by submodule
#
# New test cases
# - Removing a submodule with a git directory absorbs the submodules
# git directory first into the superproject.
+# - Switching from no submodule to nested submodules
+# - Switching from nested submodules to no submodule
# Internal function; use test_submodule_switch_recursing_with_args() or
# test_submodule_forced_switch_recursing_with_args() instead.
@@ -658,22 +660,6 @@ test_submodule_recursing_with_args_common() {
test_submodule_content sub1 origin/add_sub1
)
'
- test_expect_success "$command: submodule branch is not changed, detach HEAD instead" '
- prolog &&
- reset_work_tree_to_interested add_sub1 &&
- (
- cd submodule_update &&
- git -C sub1 checkout -b keep_branch &&
- git -C sub1 rev-parse HEAD >expect &&
- git branch -t modify_sub1 origin/modify_sub1 &&
- $command modify_sub1 &&
- test_superproject_content origin/modify_sub1 &&
- test_submodule_content sub1 origin/modify_sub1 &&
- git -C sub1 rev-parse keep_branch >actual &&
- test_cmp expect actual &&
- test_must_fail git -C sub1 symbolic-ref HEAD
- )
- '
# Replacing a tracked file with a submodule produces a checked out submodule
test_expect_success "$command: replace tracked file with submodule checks out submodule" '
@@ -699,6 +685,19 @@ test_submodule_recursing_with_args_common() {
test_submodule_content sub1 origin/replace_directory_with_sub1
)
'
+ # Switching to a commit with nested submodules recursively checks them out
+ test_expect_success "$command: nested submodules are checked out" '
+ prolog &&
+ reset_work_tree_to_interested no_submodule &&
+ (
+ cd submodule_update &&
+ git branch -t modify_sub1_recursively origin/modify_sub1_recursively &&
+ $command modify_sub1_recursively &&
+ test_superproject_content origin/modify_sub1_recursively &&
+ test_submodule_content sub1 origin/modify_sub1_recursively &&
+ test_submodule_content -C sub1 sub2 origin/modify_sub1_recursively
+ )
+ '
######################## Disappearing submodule #######################
# Removing a submodule removes its work tree ...
@@ -762,6 +761,21 @@ test_submodule_recursing_with_args_common() {
)
'
+ # Switching to a commit without nested submodules removes their worktrees
+ test_expect_success "$command: worktrees of nested submodules are removed" '
+ prolog &&
+ reset_work_tree_to_interested add_nested_sub &&
+ (
+ cd submodule_update &&
+ git branch -t no_submodule origin/no_submodule &&
+ $command no_submodule &&
+ test_superproject_content origin/no_submodule &&
+ ! test_path_is_dir sub1 &&
+ test_must_fail git config -f .git/modules/sub1/config core.worktree &&
+ test_must_fail git config -f .git/modules/sub1/modules/sub2/config core.worktree
+ )
+ '
+
########################## Modified submodule #########################
# Updating a submodule sha1 updates the submodule's work tree
test_expect_success "$command: modified submodule updates submodule work tree" '
@@ -789,6 +803,23 @@ test_submodule_recursing_with_args_common() {
test_submodule_content sub1 origin/add_sub1
)
'
+ # Updating a submodule does not touch the currently checked out branch in the submodule
+ test_expect_success "$command: submodule branch is not changed, detach HEAD instead" '
+ prolog &&
+ reset_work_tree_to_interested add_sub1 &&
+ (
+ cd submodule_update &&
+ git -C sub1 checkout -b keep_branch &&
+ git -C sub1 rev-parse HEAD >expect &&
+ git branch -t modify_sub1 origin/modify_sub1 &&
+ $command modify_sub1 &&
+ test_superproject_content origin/modify_sub1 &&
+ test_submodule_content sub1 origin/modify_sub1 &&
+ git -C sub1 rev-parse keep_branch >actual &&
+ test_cmp expect actual &&
+ test_must_fail git -C sub1 symbolic-ref HEAD
+ )
+ '
}
# Declares and invokes several tests that, in various situations, checks that
@@ -908,7 +939,6 @@ test_submodule_switch_recursing_with_args () {
)
'
- # recursing deeper than one level doesn't work yet.
test_expect_success "$command: modified submodule updates submodule recursively" '
prolog &&
reset_work_tree_to_interested add_nested_sub &&
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/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh
index 6a3a42531b..7743f4f4c9 100755
--- a/t/perf/p5310-pack-bitmaps.sh
+++ b/t/perf/p5310-pack-bitmaps.sh
@@ -39,6 +39,28 @@ test_perf 'pack to file (bitmap)' '
git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null
'
+test_perf 'rev-list (commits)' '
+ git rev-list --all --use-bitmap-index >/dev/null
+'
+
+test_perf 'rev-list (objects)' '
+ git rev-list --all --use-bitmap-index --objects >/dev/null
+'
+
+test_perf 'rev-list count with blob:none' '
+ git rev-list --use-bitmap-index --count --objects --all \
+ --filter=blob:none >/dev/null
+'
+
+test_perf 'rev-list count with blob:limit=1k' '
+ git rev-list --use-bitmap-index --count --objects --all \
+ --filter=blob:limit=1k >/dev/null
+'
+
+test_perf 'simulated partial clone' '
+ git pack-objects --stdout --all --filter=blob:none </dev/null >/dev/null
+'
+
test_expect_success 'create partial bitmap state' '
# pick a commit to represent the repo tip in the past
cutoff=$(git rev-list HEAD~100 -1) &&
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 4d3f7ba295..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,7 +274,7 @@ 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 \
+ 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"
@@ -300,7 +301,7 @@ test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
'
test_expect_success 'test --verbose-only' '
- test_must_fail run_sub_test_lib_test \
+ run_sub_test_lib_test_err \
t2345-verbose-only-2 "test verbose-only=2" \
--verbose-only=2 <<-\EOF &&
test_expect_success "passing test" true
@@ -833,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 &&
@@ -862,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 &&
@@ -916,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/t0008-ignores.sh b/t/t0008-ignores.sh
index 1744cee5e9..370a389e5c 100755
--- a/t/t0008-ignores.sh
+++ b/t/t0008-ignores.sh
@@ -424,9 +424,24 @@ test_expect_success 'local ignore inside a sub-directory with --verbose' '
)
'
-test_expect_success_multi 'nested include' \
- 'a/b/.gitignore:8:!on* a/b/one' '
- test_check_ignore "a/b/one"
+test_expect_success 'nested include of negated pattern' '
+ expect "" &&
+ test_check_ignore "a/b/one" 1
+'
+
+test_expect_success 'nested include of negated pattern with -q' '
+ expect "" &&
+ test_check_ignore "-q a/b/one" 1
+'
+
+test_expect_success 'nested include of negated pattern with -v' '
+ expect "a/b/.gitignore:8:!on* a/b/one" &&
+ test_check_ignore "-v a/b/one" 0
+'
+
+test_expect_success 'nested include of negated pattern with -v -n' '
+ expect "a/b/.gitignore:8:!on* a/b/one" &&
+ test_check_ignore "-v -n a/b/one" 0
'
############################################################################
@@ -460,7 +475,6 @@ test_expect_success 'cd to ignored sub-directory' '
expect_from_stdin <<-\EOF &&
foo
twoooo
- ../one
seven
../../one
EOF
@@ -543,7 +557,6 @@ test_expect_success 'global ignore' '
globalthree
a/globalthree
a/per-repo
- globaltwo
EOF
test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
'
@@ -586,17 +599,7 @@ EOF
cat <<-\EOF >expected-default
one
a/one
- a/b/on
- a/b/one
- a/b/one one
- a/b/one two
- "a/b/one\"three"
- a/b/two
a/b/twooo
- globaltwo
- a/globaltwo
- a/b/globaltwo
- b/globaltwo
EOF
cat <<-EOF >expected-verbose
.gitignore:1:one one
@@ -696,8 +699,12 @@ cat <<-EOF >expected-all
$global_excludes:2:!globaltwo ../b/globaltwo
:: c/not-ignored
EOF
+cat <<-EOF >expected-default
+../one
+one
+b/twooo
+EOF
grep -v '^:: ' expected-all >expected-verbose
-sed -e 's/.* //' expected-verbose >expected-default
broken_c_unquote stdin >stdin0
diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh
index 2694c81afd..8d3d9144c0 100755
--- a/t/t0014-alias.sh
+++ b/t/t0014-alias.sh
@@ -38,8 +38,8 @@ test_expect_success 'looping aliases - internal execution' '
#'
test_expect_success 'run-command formats empty args properly' '
- GIT_TRACE=1 git frotz a "" b " " c 2>&1 |
- sed -ne "/run_command:/s/.*trace: run_command: //p" >actual &&
+ 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
'
diff --git a/t/t0018-advice.sh b/t/t0018-advice.sh
new file mode 100755
index 0000000000..e03554d2f3
--- /dev/null
+++ b/t/t0018-advice.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+test_description='Test advise_if_enabled functionality'
+
+. ./test-lib.sh
+
+test_expect_success 'advice should be printed when config variable is unset' '
+ cat >expect <<-\EOF &&
+ hint: This is a piece of advice
+ hint: Disable this message with "git config advice.nestedTag false"
+ EOF
+ test-tool advise "This is a piece of advice" 2>actual &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'advice should be printed when config variable is set to true' '
+ cat >expect <<-\EOF &&
+ hint: This is a piece of advice
+ hint: Disable this message with "git config advice.nestedTag false"
+ EOF
+ test_config advice.nestedTag true &&
+ test-tool advise "This is a piece of advice" 2>actual &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'advice should not be printed when config variable is set to false' '
+ test_config advice.nestedTag false &&
+ test-tool advise "This is a piece of advice" 2>actual &&
+ test_must_be_empty 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 c954c709ad..4bfffa9c31 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
@@ -364,6 +364,10 @@ test_expect_success PERL 'required process filter should filter data' '
S=$(file_size test.r) &&
S2=$(file_size test2.r) &&
S3=$(file_size "testsubdir/test3 '\''sq'\'',\$x=.r") &&
+ M=$(git hash-object test.r) &&
+ M2=$(git hash-object test2.r) &&
+ M3=$(git hash-object "testsubdir/test3 '\''sq'\'',\$x=.r") &&
+ EMPTY=$(git hash-object /dev/null) &&
filter_git add . &&
cat >expected.log <<-EOF &&
@@ -378,14 +382,16 @@ test_expect_success PERL 'required process filter should filter data' '
test_cmp_count expected.log debug.log &&
git commit -m "test commit 2" &&
+ MASTER=$(git rev-parse --verify master) &&
+ META="ref=refs/heads/master treeish=$MASTER" &&
rm -f test2.r "testsubdir/test3 '\''sq'\'',\$x=.r" &&
filter_git checkout --quiet --no-progress . &&
cat >expected.log <<-EOF &&
START
init handshake complete
- IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
- IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $S3 [OK] -- OUT: $S3 . [OK]
+ IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@@ -406,10 +412,10 @@ test_expect_success PERL 'required process filter should filter data' '
cat >expected.log <<-EOF &&
START
init handshake complete
- IN: smudge test.r $S [OK] -- OUT: $S . [OK]
- IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
- IN: smudge test4-empty.r 0 [OK] -- OUT: 0 [OK]
- IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $S3 [OK] -- OUT: $S3 . [OK]
+ IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@@ -420,6 +426,117 @@ test_expect_success PERL 'required process filter should filter data' '
)
'
+test_expect_success PERL 'required process filter should filter data for various subcommands' '
+ test_config_global filter.protocol.process "rot13-filter.pl debug.log clean smudge" &&
+ test_config_global filter.protocol.required true &&
+ (
+ cd repo &&
+
+ S=$(file_size test.r) &&
+ S2=$(file_size test2.r) &&
+ S3=$(file_size "testsubdir/test3 '\''sq'\'',\$x=.r") &&
+ M=$(git hash-object test.r) &&
+ M2=$(git hash-object test2.r) &&
+ M3=$(git hash-object "testsubdir/test3 '\''sq'\'',\$x=.r") &&
+ EMPTY=$(git hash-object /dev/null) &&
+
+ MASTER=$(git rev-parse --verify master) &&
+
+ cp "$TEST_ROOT/test.o" test5.r &&
+ git add test5.r &&
+ git commit -m "test commit 3" &&
+ git checkout empty-branch &&
+ filter_git rebase --onto empty-branch master^^ master &&
+ MASTER2=$(git rev-parse --verify master) &&
+ META="ref=refs/heads/master treeish=$MASTER2" &&
+ cat >expected.log <<-EOF &&
+ START
+ init handshake complete
+ IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
+ IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
+ STOP
+ EOF
+ test_cmp_exclude_clean expected.log debug.log &&
+
+ git reset --hard empty-branch &&
+ filter_git reset --hard $MASTER &&
+ META="treeish=$MASTER" &&
+ cat >expected.log <<-EOF &&
+ START
+ init handshake complete
+ IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
+ STOP
+ EOF
+ test_cmp_exclude_clean expected.log debug.log &&
+
+ git branch old-master $MASTER &&
+ git reset --hard empty-branch &&
+ filter_git reset --hard old-master &&
+ META="ref=refs/heads/old-master treeish=$MASTER" &&
+ cat >expected.log <<-EOF &&
+ START
+ init handshake complete
+ IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
+ STOP
+ EOF
+ test_cmp_exclude_clean expected.log debug.log &&
+
+ git checkout -b merge empty-branch &&
+ git branch -f master $MASTER2 &&
+ filter_git merge master &&
+ META="treeish=$MASTER2" &&
+ cat >expected.log <<-EOF &&
+ START
+ init handshake complete
+ IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
+ IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
+ STOP
+ EOF
+ test_cmp_exclude_clean expected.log debug.log &&
+
+ filter_git archive master >/dev/null &&
+ META="ref=refs/heads/master treeish=$MASTER2" &&
+ cat >expected.log <<-EOF &&
+ START
+ init handshake complete
+ IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
+ IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
+ STOP
+ EOF
+ test_cmp_exclude_clean expected.log debug.log &&
+
+ TREE="$(git rev-parse $MASTER2^{tree})" &&
+ filter_git archive $TREE >/dev/null &&
+ META="treeish=$TREE" &&
+ cat >expected.log <<-EOF &&
+ START
+ init handshake complete
+ IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
+ IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
+ STOP
+ EOF
+ test_cmp_exclude_clean expected.log debug.log
+ )
+'
+
test_expect_success PERL 'required process filter takes precedence' '
test_config_global filter.protocol.clean false &&
test_config_global filter.protocol.process "rot13-filter.pl debug.log clean" &&
@@ -519,17 +636,22 @@ test_expect_success PERL 'required process filter should process multiple packet
EOF
test_cmp_count expected.log debug.log &&
- rm -f *.file &&
+ M1="blob=$(git hash-object 1pkt_1__.file)" &&
+ M2="blob=$(git hash-object 2pkt_1+1.file)" &&
+ M3="blob=$(git hash-object 2pkt_2-1.file)" &&
+ M4="blob=$(git hash-object 2pkt_2__.file)" &&
+ M5="blob=$(git hash-object 3pkt_2+1.file)" &&
+ rm -f *.file debug.log &&
filter_git checkout --quiet --no-progress -- *.file &&
cat >expected.log <<-EOF &&
START
init handshake complete
- IN: smudge 1pkt_1__.file $(($S )) [OK] -- OUT: $(($S )) . [OK]
- IN: smudge 2pkt_1+1.file $(($S +1)) [OK] -- OUT: $(($S +1)) .. [OK]
- IN: smudge 2pkt_2-1.file $(($S*2-1)) [OK] -- OUT: $(($S*2-1)) .. [OK]
- IN: smudge 2pkt_2__.file $(($S*2 )) [OK] -- OUT: $(($S*2 )) .. [OK]
- IN: smudge 3pkt_2+1.file $(($S*2+1)) [OK] -- OUT: $(($S*2+1)) ... [OK]
+ IN: smudge 1pkt_1__.file $M1 $(($S )) [OK] -- OUT: $(($S )) . [OK]
+ IN: smudge 2pkt_1+1.file $M2 $(($S +1)) [OK] -- OUT: $(($S +1)) .. [OK]
+ IN: smudge 2pkt_2-1.file $M3 $(($S*2-1)) [OK] -- OUT: $(($S*2-1)) .. [OK]
+ IN: smudge 2pkt_2__.file $M4 $(($S*2 )) [OK] -- OUT: $(($S*2 )) .. [OK]
+ IN: smudge 3pkt_2+1.file $M5 $(($S*2+1)) [OK] -- OUT: $(($S*2+1)) ... [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@@ -578,6 +700,10 @@ test_expect_success PERL 'process filter should restart after unexpected write f
S=$(file_size test.r) &&
S2=$(file_size test2.r) &&
SF=$(file_size smudge-write-fail.r) &&
+ M=$(git hash-object test.r) &&
+ M2=$(git hash-object test2.r) &&
+ MF=$(git hash-object smudge-write-fail.r) &&
+ rm -f debug.log &&
git add . &&
rm -f *.r &&
@@ -591,11 +717,11 @@ test_expect_success PERL 'process filter should restart after unexpected write f
cat >expected.log <<-EOF &&
START
init handshake complete
- IN: smudge smudge-write-fail.r $SF [OK] -- [WRITE FAIL]
+ IN: smudge smudge-write-fail.r blob=$MF $SF [OK] -- [WRITE FAIL]
START
init handshake complete
- IN: smudge test.r $S [OK] -- OUT: $S . [OK]
- IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge test.r blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@@ -629,6 +755,10 @@ test_expect_success PERL 'process filter should not be restarted if it signals a
S=$(file_size test.r) &&
S2=$(file_size test2.r) &&
SE=$(file_size error.r) &&
+ M=$(git hash-object test.r) &&
+ M2=$(git hash-object test2.r) &&
+ ME=$(git hash-object error.r) &&
+ rm -f debug.log &&
git add . &&
rm -f *.r &&
@@ -637,9 +767,9 @@ test_expect_success PERL 'process filter should not be restarted if it signals a
cat >expected.log <<-EOF &&
START
init handshake complete
- IN: smudge error.r $SE [OK] -- [ERROR]
- IN: smudge test.r $S [OK] -- OUT: $S . [OK]
- IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
+ IN: smudge error.r blob=$ME $SE [OK] -- [ERROR]
+ IN: smudge test.r blob=$M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@@ -665,18 +795,21 @@ test_expect_success PERL 'process filter abort stops processing of all further f
echo "error this blob and all future blobs" >abort.o &&
cp abort.o abort.r &&
+ M="blob=$(git hash-object abort.r)" &&
+ rm -f debug.log &&
SA=$(file_size abort.r) &&
git add . &&
rm -f *.r &&
+
# Note: This test assumes that Git filters files in alphabetical
# order ("abort.r" before "test.r").
filter_git checkout --quiet --no-progress . &&
cat >expected.log <<-EOF &&
START
init handshake complete
- IN: smudge abort.r $SA [OK] -- [ABORT]
+ IN: smudge abort.r $M $SA [OK] -- [ABORT]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@@ -727,27 +860,29 @@ test_expect_success PERL 'delayed checkout in process filter' '
) &&
S=$(file_size "$TEST_ROOT/test.o") &&
+ PM="ref=refs/heads/master treeish=$(git -C repo rev-parse --verify master) " &&
+ M="${PM}blob=$(git -C repo rev-parse --verify master:test.a)" &&
cat >a.exp <<-EOF &&
START
init handshake complete
- IN: smudge test.a $S [OK] -- OUT: $S . [OK]
- IN: smudge test-delay10.a $S [OK] -- [DELAYED]
- IN: smudge test-delay11.a $S [OK] -- [DELAYED]
- IN: smudge test-delay20.a $S [OK] -- [DELAYED]
+ IN: smudge test.a $M $S [OK] -- OUT: $S . [OK]
+ IN: smudge test-delay10.a $M $S [OK] -- [DELAYED]
+ IN: smudge test-delay11.a $M $S [OK] -- [DELAYED]
+ IN: smudge test-delay20.a $M $S [OK] -- [DELAYED]
IN: list_available_blobs test-delay10.a test-delay11.a [OK]
- IN: smudge test-delay10.a 0 [OK] -- OUT: $S . [OK]
- IN: smudge test-delay11.a 0 [OK] -- OUT: $S . [OK]
+ IN: smudge test-delay10.a $M 0 [OK] -- OUT: $S . [OK]
+ IN: smudge test-delay11.a $M 0 [OK] -- OUT: $S . [OK]
IN: list_available_blobs test-delay20.a [OK]
- IN: smudge test-delay20.a 0 [OK] -- OUT: $S . [OK]
+ IN: smudge test-delay20.a $M 0 [OK] -- OUT: $S . [OK]
IN: list_available_blobs [OK]
STOP
EOF
cat >b.exp <<-EOF &&
START
init handshake complete
- IN: smudge test-delay10.b $S [OK] -- [DELAYED]
+ IN: smudge test-delay10.b $M $S [OK] -- [DELAYED]
IN: list_available_blobs test-delay10.b [OK]
- IN: smudge test-delay10.b 0 [OK] -- OUT: $S . [OK]
+ IN: smudge test-delay10.b $M 0 [OK] -- OUT: $S . [OK]
IN: list_available_blobs [OK]
STOP
EOF
@@ -767,8 +902,11 @@ test_expect_success PERL 'delayed checkout in process filter' '
rm *.a *.b &&
filter_git checkout . &&
- test_cmp_count ../a.exp a.log &&
- test_cmp_count ../b.exp b.log &&
+ # We are not checking out a ref here, so filter out ref metadata.
+ sed -e "s!$PM!!" ../a.exp >a.exp.filtered &&
+ sed -e "s!$PM!!" ../b.exp >b.exp.filtered &&
+ test_cmp_count a.exp.filtered a.log &&
+ test_cmp_count b.exp.filtered b.log &&
test_cmp_committed_rot13 "$TEST_ROOT/test.o" test.a &&
test_cmp_committed_rot13 "$TEST_ROOT/test.o" test-delay10.a &&
@@ -795,7 +933,6 @@ test_expect_success PERL 'missing file in delayed checkout' '
rm -rf repo-cloned &&
test_must_fail git clone repo repo-cloned 2>git-stderr.log &&
- cat git-stderr.log &&
grep "error: .missing-delay\.a. was not filtered properly" git-stderr.log
'
diff --git a/t/t0021/rot13-filter.pl b/t/t0021/rot13-filter.pl
index 470107248e..cd32a82da5 100644
--- a/t/t0021/rot13-filter.pl
+++ b/t/t0021/rot13-filter.pl
@@ -135,7 +135,13 @@ while (1) {
if ( exists $DELAY{$pathname} and $DELAY{$pathname}{"requested"} == 0 ) {
$DELAY{$pathname}{"requested"} = 1;
}
+ } elsif ($buffer =~ /^(ref|treeish|blob)=/) {
+ print $debug " $buffer";
} else {
+ # In general, filters need to be graceful about
+ # new metadata, since it's documented that we
+ # can pass any key-value pairs, but for tests,
+ # let's be a little stricter.
die "Unknown message '$buffer'";
}
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 7aa0945d8d..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
}
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 705a136ed9..3483b72db4 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -23,6 +23,8 @@ usage: test-tool parse-options <options>
-j <n> get a integer, too
-m, --magnitude <n> get a magnitude
--set23 set integer to 23
+ --mode1 set integer to 1 (cmdmode option)
+ --mode2 set integer to 2 (cmdmode option)
-L, --length <str> get length of <str>
-F, --file <file> set file to <file>
@@ -242,7 +244,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 +254,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' '
@@ -324,6 +326,22 @@ test_expect_success 'OPT_NEGBIT() works' '
test-tool parse-options --expect="boolean: 6" -bb --no-neg-or4
'
+test_expect_success 'OPT_CMDMODE() works' '
+ test-tool parse-options --expect="integer: 1" --mode1
+'
+
+test_expect_success 'OPT_CMDMODE() detects incompatibility' '
+ test_must_fail test-tool parse-options --mode1 --mode2 >output 2>output.err &&
+ test_must_be_empty output &&
+ test_i18ngrep "incompatible with --mode" output.err
+'
+
+test_expect_success 'OPT_CMDMODE() detects incompatibility with something else' '
+ test_must_fail test-tool parse-options --set23 --mode2 >output 2>output.err &&
+ test_must_be_empty output &&
+ test_i18ngrep "incompatible with something else" output.err
+'
+
test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' '
test-tool parse-options --expect="boolean: 6" + + + + + +
'
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index c7b53e494b..2ea2d00c39 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -165,6 +165,15 @@ test_expect_success 'absolute path rejects the empty string' '
test_must_fail test-tool path-utils absolute_path ""
'
+test_expect_success MINGW '<drive-letter>:\\abc is an absolute path' '
+ for letter in : \" C Z 1 ä
+ do
+ path=$letter:\\abc &&
+ absolute="$(test-tool path-utils absolute_path "$path")" &&
+ test "$path" = "$absolute" || return 1
+ done
+'
+
test_expect_success 'real path rejects the empty string' '
test_must_fail test-tool path-utils real_path ""
'
@@ -285,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
@@ -423,6 +436,9 @@ test_expect_success 'match .gitmodules' '
~1000000 \
~9999999 \
\
+ .gitmodules:\$DATA \
+ "gitmod~4 . :\$DATA" \
+ \
--not \
".gitmodules x" \
".gitmodules .x" \
@@ -447,7 +463,34 @@ test_expect_success 'match .gitmodules' '
\
GI7EB~1 \
GI7EB~01 \
- GI7EB~1X
+ GI7EB~1X \
+ \
+ .gitmodules,:\$DATA
+'
+
+test_expect_success MINGW 'is_valid_path() on Windows' '
+ test-tool path-utils is_valid_path \
+ win32 \
+ "win32 x" \
+ ../hello.txt \
+ C:\\git \
+ comm \
+ conout.c \
+ lptN \
+ \
+ --not \
+ "win32 " \
+ "win32 /x " \
+ "win32." \
+ "win32 . ." \
+ .../hello.txt \
+ 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 17c9c0f3bb..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
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/t0300-credentials.sh b/t/t0300-credentials.sh
index 82eaaea0f4..39f097ea9e 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -240,6 +240,57 @@ test_expect_success 'do not match configured credential' '
EOF
'
+test_expect_success 'match multiple configured helpers' '
+ test_config credential.helper "verbatim \"\" \"\"" &&
+ test_config credential.https://example.com.helper "$HELPER" &&
+ check fill <<-\EOF
+ protocol=https
+ host=example.com
+ path=repo.git
+ --
+ protocol=https
+ host=example.com
+ username=foo
+ password=bar
+ --
+ verbatim: get
+ verbatim: protocol=https
+ verbatim: host=example.com
+ EOF
+'
+
+test_expect_success 'match multiple configured helpers with URLs' '
+ test_config credential.https://example.com/repo.git.helper "verbatim \"\" \"\"" &&
+ test_config credential.https://example.com.helper "$HELPER" &&
+ check fill <<-\EOF
+ protocol=https
+ host=example.com
+ path=repo.git
+ --
+ protocol=https
+ host=example.com
+ username=foo
+ password=bar
+ --
+ verbatim: get
+ verbatim: protocol=https
+ verbatim: host=example.com
+ EOF
+'
+
+test_expect_success 'match percent-encoded values' '
+ test_config credential.https://example.com/%2566.git.helper "$HELPER" &&
+ check fill <<-\EOF
+ url=https://example.com/%2566.git
+ --
+ protocol=https
+ host=example.com
+ username=foo
+ password=bar
+ --
+ EOF
+'
+
test_expect_success 'pull username from config' '
test_config credential.https://example.com.username foo &&
check fill <<-\EOF
@@ -255,6 +306,63 @@ test_expect_success 'pull username from config' '
EOF
'
+test_expect_success 'honors username from URL over helper (URL)' '
+ test_config credential.https://example.com.username bob &&
+ test_config credential.https://example.com.helper "verbatim \"\" bar" &&
+ check fill <<-\EOF
+ url=https://alice@example.com
+ --
+ protocol=https
+ host=example.com
+ username=alice
+ password=bar
+ --
+ verbatim: get
+ verbatim: protocol=https
+ verbatim: host=example.com
+ verbatim: username=alice
+ EOF
+'
+
+test_expect_success 'honors username from URL over helper (components)' '
+ test_config credential.https://example.com.username bob &&
+ test_config credential.https://example.com.helper "verbatim \"\" bar" &&
+ check fill <<-\EOF
+ protocol=https
+ host=example.com
+ username=alice
+ --
+ protocol=https
+ host=example.com
+ username=alice
+ password=bar
+ --
+ verbatim: get
+ verbatim: protocol=https
+ verbatim: host=example.com
+ verbatim: username=alice
+ EOF
+'
+
+test_expect_success 'last matching username wins' '
+ test_config credential.https://example.com/path.git.username bob &&
+ test_config credential.https://example.com.username alice &&
+ test_config credential.https://example.com.helper "verbatim \"\" bar" &&
+ check fill <<-\EOF
+ url=https://example.com/path.git
+ --
+ protocol=https
+ host=example.com
+ username=alice
+ password=bar
+ --
+ verbatim: get
+ verbatim: protocol=https
+ verbatim: host=example.com
+ verbatim: username=alice
+ EOF
+'
+
test_expect_success 'http paths can be part of context' '
check fill "verbatim foo bar" <<-\EOF &&
protocol=https
@@ -289,6 +397,26 @@ test_expect_success 'http paths can be part of context' '
EOF
'
+test_expect_success 'context uses urlmatch' '
+ test_config "credential.https://*.org.useHttpPath" true &&
+ check fill "verbatim foo bar" <<-\EOF
+ protocol=https
+ host=example.org
+ path=foo.git
+ --
+ protocol=https
+ host=example.org
+ path=foo.git
+ username=foo
+ password=bar
+ --
+ verbatim: get
+ verbatim: protocol=https
+ verbatim: host=example.org
+ verbatim: path=foo.git
+ EOF
+'
+
test_expect_success 'helpers can abort the process' '
test_must_fail git \
-c credential.helper="!f() { echo quit=1; }; f" \
diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh
index 24ccbd8d3b..d2d088d9a0 100755
--- a/t/t0500-progress-display.sh
+++ b/t/t0500-progress-display.sh
@@ -76,7 +76,7 @@ EOF
'
test_expect_success 'progress display breaks long lines #2' '
- # Note: we dont need that many spaces after the title to cover up
+ # 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>
@@ -104,7 +104,7 @@ EOF
'
test_expect_success 'progress display breaks long lines #3 - even the first is too long' '
- # Note: we dont actually need any spaces at the end of the title
+ # 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
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/t1014-read-tree-confusing.sh b/t/t1014-read-tree-confusing.sh
index 2f5a25d503..da3376b3bb 100755
--- a/t/t1014-read-tree-confusing.sh
+++ b/t/t1014-read-tree-confusing.sh
@@ -49,6 +49,7 @@ git~1
.git.SPACE .git.{space}
.\\\\.GIT\\\\foobar backslashes
.git\\\\foobar backslashes2
+.git...:alternate-stream
EOF
test_expect_success 'utf-8 paths allowed with core.protectHFS off' '
diff --git a/t/t1050-large.sh b/t/t1050-large.sh
index dcb4dbba67..184b479a21 100755
--- a/t/t1050-large.sh
+++ b/t/t1050-large.sh
@@ -53,7 +53,8 @@ test_expect_success 'add a large file or two' '
for p in .git/objects/pack/pack-*.pack
do
count=$(( $count + 1 ))
- if test -f "$p" && idx=${p%.pack}.idx && test -f "$idx"
+ if test_path_is_file "$p" &&
+ idx=${p%.pack}.idx && test_path_is_file "$idx"
then
continue
fi
@@ -65,7 +66,7 @@ test_expect_success 'add a large file or two' '
test $cnt = 2 &&
for l in .git/objects/??/??????????????????????????????????????
do
- test -f "$l" || continue
+ test_path_is_file "$l" || continue
bad=t
done &&
test -z "$bad" &&
@@ -76,7 +77,8 @@ test_expect_success 'add a large file or two' '
for p in .git/objects/pack/pack-*.pack
do
count=$(( $count + 1 ))
- if test -f "$p" && idx=${p%.pack}.idx && test -f "$idx"
+ if test_path_is_file "$p" &&
+ idx=${p%.pack}.idx && test_path_is_file "$idx"
then
continue
fi
@@ -111,7 +113,7 @@ test_expect_success 'packsize limit' '
count=0 &&
for pi in .git/objects/pack/pack-*.idx
do
- test -f "$pi" && count=$(( $count + 1 ))
+ test_path_is_file "$pi" && count=$(( $count + 1 ))
done &&
test $count = 2 &&
@@ -194,15 +196,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..44a91205d6
--- /dev/null
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -0,0 +1,524 @@
+#!/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' *)
+}
+
+check_files() {
+ list_files "$1" >actual &&
+ shift &&
+ printf "%s\n" $@ >expect &&
+ test_cmp expect actual
+}
+
+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 &&
+ check_files repo a
+'
+
+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 &&
+ check_files repo a folder1 folder2
+'
+
+test_expect_success 'clone --sparse' '
+ git clone --sparse "file://$(pwd)/repo" clone &&
+ git -C clone sparse-checkout list >actual &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ EOF
+ test_cmp expect actual &&
+ check_files clone a
+'
+
+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 &&
+ check_files repo a folder1 folder2
+'
+
+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 &&
+ check_files repo "a folder1 folder2"
+'
+
+test_expect_success 'add to sparse-checkout' '
+ cat repo/.git/info/sparse-checkout >expect &&
+ cat >add <<-\EOF &&
+ pattern1
+ /folder1/
+ pattern2
+ EOF
+ cat add >>expect &&
+ git -C repo sparse-checkout add --stdin <add &&
+ git -C repo sparse-checkout list >actual &&
+ test_cmp expect actual &&
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ check_files repo "a folder1 folder2"
+'
+
+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 &&
+ check_files repo a folder1 folder2
+'
+
+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 &&
+ check_files repo a deep folder1 folder2
+'
+
+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 &&
+ check_files repo a deep &&
+ check_files repo/deep a deeper1 &&
+ check_files repo/deep/deeper1 a deepest &&
+ 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 &&
+ check_files repo a folder1 folder2
+'
+
+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 'cone mode: add independent path' '
+ git -C repo sparse-checkout set deep/deeper1 &&
+ git -C repo sparse-checkout add folder1 &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ /deep/
+ !/deep/*/
+ /deep/deeper1/
+ /folder1/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ check_files repo a deep folder1
+'
+
+test_expect_success 'cone mode: add sibling path' '
+ git -C repo sparse-checkout set deep/deeper1 &&
+ git -C repo sparse-checkout add deep/deeper2 &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ /deep/
+ !/deep/*/
+ /deep/deeper1/
+ /deep/deeper2/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ check_files repo a deep
+'
+
+test_expect_success 'cone mode: add parent path' '
+ git -C repo sparse-checkout set deep/deeper1 folder1 &&
+ git -C repo sparse-checkout add deep &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ /deep/
+ /folder1/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ check_files repo a deep folder1
+'
+
+test_expect_success 'revert to old sparse-checkout on bad update' '
+ test_when_finished git -C repo reset --hard &&
+ git -C repo sparse-checkout set deep &&
+ 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 &&
+ check_files repo/deep a deeper1 deeper2
+'
+
+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 "Unable to create .*\.lock" 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 &&
+ check_files repo a folder1
+'
+
+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
+ ) &&
+ check_files super a folder1 modules &&
+ check_files super/modules/child a deep folder1 folder2
+'
+
+test_expect_success 'different sparse-checkouts with worktrees' '
+ git -C repo worktree add --detach ../worktree &&
+ check_files worktree "a deep folder1 folder2" &&
+ git -C worktree sparse-checkout init --cone &&
+ git -C repo sparse-checkout set folder1 &&
+ git -C worktree sparse-checkout set deep/deeper1 &&
+ check_files repo a folder1 &&
+ check_files worktree a deep
+'
+
+test_expect_success 'set using filename keeps file on-disk' '
+ git -C repo sparse-checkout set a deep &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ /a/
+ /deep/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ check_files repo a deep
+'
+
+check_read_tree_errors () {
+ REPO=$1
+ FILES=$2
+ ERRORS=$3
+ git -C $REPO -c core.sparseCheckoutCone=false read-tree -mu HEAD 2>err &&
+ test_must_be_empty err &&
+ check_files $REPO "$FILES" &&
+ git -C $REPO read-tree -mu HEAD 2>err &&
+ if test -z "$ERRORS"
+ then
+ test_must_be_empty err
+ else
+ test_i18ngrep "$ERRORS" err
+ fi &&
+ check_files $REPO $FILES
+}
+
+test_expect_success 'pattern-checks: /A/**' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ /folder1/**
+ EOF
+ check_read_tree_errors repo "a folder1" "disabling cone pattern matching"
+'
+
+test_expect_success 'pattern-checks: /A/**/B/' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ /deep/**/deepest
+ EOF
+ check_read_tree_errors repo "a deep" "disabling cone pattern matching" &&
+ check_files repo/deep "deeper1" &&
+ check_files repo/deep/deeper1 "deepest"
+'
+
+test_expect_success 'pattern-checks: too short' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ /
+ EOF
+ check_read_tree_errors repo "a" "disabling cone pattern matching"
+'
+test_expect_success 'pattern-checks: not too short' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ /b/
+ EOF
+ git -C repo read-tree -mu HEAD 2>err &&
+ test_must_be_empty err &&
+ check_files repo a
+'
+
+test_expect_success 'pattern-checks: trailing "*"' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ /a*
+ EOF
+ check_read_tree_errors repo "a" "disabling cone pattern matching"
+'
+
+test_expect_success 'pattern-checks: starting "*"' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ *eep/
+ EOF
+ check_read_tree_errors repo "a deep" "disabling cone pattern matching"
+'
+
+test_expect_success 'pattern-checks: contained glob characters' '
+ for c in "[a]" "\\" "?" "*"
+ do
+ cat >repo/.git/info/sparse-checkout <<-EOF &&
+ /*
+ !/*/
+ something$c-else/
+ EOF
+ check_read_tree_errors repo "a" "disabling cone pattern matching"
+ done
+'
+
+test_expect_success BSLASHPSPEC 'pattern-checks: escaped characters' '
+ git clone repo escaped &&
+ TREEOID=$(git -C escaped rev-parse HEAD:folder1) &&
+ NEWTREE=$(git -C escaped mktree <<-EOF
+ $(git -C escaped ls-tree HEAD)
+ 040000 tree $TREEOID zbad\\dir
+ 040000 tree $TREEOID zdoes*exist
+ 040000 tree $TREEOID zglob[!a]?
+ EOF
+ ) &&
+ COMMIT=$(git -C escaped commit-tree $NEWTREE -p HEAD) &&
+ git -C escaped reset --hard $COMMIT &&
+ check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? &&
+ git -C escaped sparse-checkout init --cone &&
+ git -C escaped sparse-checkout set zbad\\dir/bogus "zdoes*not*exist" "zdoes*exist" "zglob[!a]?" &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ /zbad\\dir/
+ !/zbad\\dir/*/
+ /zbad\\dir/bogus/
+ /zdoes\*exist/
+ /zdoes\*not\*exist/
+ /zglob\[!a]\?/
+ EOF
+ test_cmp expect escaped/.git/info/sparse-checkout &&
+ check_read_tree_errors escaped "a zbad\\dir zdoes*exist zglob[!a]?" &&
+ git -C escaped ls-tree -d --name-only HEAD >list-expect &&
+ git -C escaped sparse-checkout set --stdin <list-expect &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ /deep/
+ /folder1/
+ /folder2/
+ /zbad\\dir/
+ /zdoes\*exist/
+ /zglob\[!a]\?/
+ EOF
+ test_cmp expect escaped/.git/info/sparse-checkout &&
+ check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? &&
+ git -C escaped sparse-checkout list >list-actual &&
+ test_cmp list-expect list-actual
+'
+
+test_expect_success MINGW 'cone mode replaces backslashes with slashes' '
+ git -C repo sparse-checkout set deep\\deeper1 &&
+ cat >expect <<-\EOF &&
+ /*
+ !/*/
+ /deep/
+ !/deep/*/
+ /deep/deeper1/
+ EOF
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ check_files repo a deep &&
+ check_files repo/deep a deeper1
+'
+
+test_done
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 983a0a1583..97ebfe1f9d 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -1191,47 +1191,47 @@ test_expect_success 'old-fashioned settings are case insensitive' '
test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
cat >testConfig_actual <<-EOF &&
- [V.A]
- r = value1
+ [V.A]
+ r = value1
EOF
q_to_tab >testConfig_expect <<-EOF &&
- [V.A]
- Qr = value2
+ [V.A]
+ Qr = value2
EOF
git config -f testConfig_actual "v.a.r" value2 &&
test_cmp testConfig_expect testConfig_actual &&
cat >testConfig_actual <<-EOF &&
- [V.A]
- r = value1
+ [V.A]
+ r = value1
EOF
q_to_tab >testConfig_expect <<-EOF &&
- [V.A]
- QR = value2
+ [V.A]
+ QR = value2
EOF
git config -f testConfig_actual "V.a.R" value2 &&
test_cmp testConfig_expect testConfig_actual &&
cat >testConfig_actual <<-EOF &&
- [V.A]
- r = value1
+ [V.A]
+ r = value1
EOF
q_to_tab >testConfig_expect <<-EOF &&
- [V.A]
- r = value1
- Qr = value2
+ [V.A]
+ r = value1
+ Qr = value2
EOF
git config -f testConfig_actual "V.A.r" value2 &&
test_cmp testConfig_expect testConfig_actual &&
cat >testConfig_actual <<-EOF &&
- [V.A]
- r = value1
+ [V.A]
+ r = value1
EOF
q_to_tab >testConfig_expect <<-EOF &&
- [V.A]
- r = value1
- Qr = value2
+ [V.A]
+ r = value1
+ Qr = value2
EOF
git config -f testConfig_actual "v.A.r" value2 &&
test_cmp testConfig_expect testConfig_actual
@@ -1241,26 +1241,26 @@ test_expect_success 'setting different case sensitive subsections ' '
test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
cat >testConfig_actual <<-EOF &&
- [V "A"]
- R = v1
- [K "E"]
- Y = v1
- [a "b"]
- c = v1
- [d "e"]
- f = v1
+ [V "A"]
+ R = v1
+ [K "E"]
+ Y = v1
+ [a "b"]
+ c = v1
+ [d "e"]
+ f = v1
EOF
q_to_tab >testConfig_expect <<-EOF &&
- [V "A"]
- Qr = v2
- [K "E"]
- Qy = v2
- [a "b"]
- Qc = v2
- [d "e"]
- f = v1
- [d "E"]
- Qf = v2
+ [V "A"]
+ Qr = v2
+ [K "E"]
+ Qy = v2
+ [a "b"]
+ Qc = v2
+ [d "e"]
+ f = v1
+ [d "E"]
+ Qf = v2
EOF
# exact match
git config -f testConfig_actual a.b.c v2 &&
@@ -1408,6 +1408,8 @@ test_expect_success 'urlmatch favors more specific URLs' '
cookieFile = /tmp/wildcard.txt
[http "https://*.example.com/wildcardwithsubdomain"]
cookieFile = /tmp/wildcardwithsubdomain.txt
+ [http "https://*.example.*"]
+ cookieFile = /tmp/multiwildcard.txt
[http "https://trailing.example.com"]
cookieFile = /tmp/trailing.txt
[http "https://user@*.example.com/"]
@@ -1454,6 +1456,10 @@ test_expect_success 'urlmatch favors more specific URLs' '
echo http.cookiefile /tmp/sub.txt >expect &&
git config --get-urlmatch HTTP https://user@sub.example.com >actual &&
+ test_cmp expect actual &&
+
+ echo http.cookiefile /tmp/multiwildcard.txt >expect &&
+ git config --get-urlmatch HTTP https://wildcard.example.org >actual &&
test_cmp expect actual
'
@@ -1622,40 +1628,40 @@ test_expect_success 'set up --show-origin tests' '
INCLUDE_DIR="$HOME/include" &&
mkdir -p "$INCLUDE_DIR" &&
cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
- [user]
- absolute = include
+ [user]
+ absolute = include
EOF
cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
- [user]
- relative = include
+ [user]
+ relative = include
EOF
cat >"$HOME"/.gitconfig <<-EOF &&
- [user]
- global = true
- override = global
- [include]
- path = "$INCLUDE_DIR/absolute.include"
+ [user]
+ global = true
+ override = global
+ [include]
+ path = "$INCLUDE_DIR/absolute.include"
EOF
cat >.git/config <<-\EOF
- [user]
- local = true
- override = local
- [include]
- path = ../include/relative.include
+ [user]
+ local = true
+ override = local
+ [include]
+ path = ../include/relative.include
EOF
'
test_expect_success '--show-origin with --list' '
cat >expect <<-EOF &&
- file:$HOME/.gitconfig user.global=true
- file:$HOME/.gitconfig user.override=global
- file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
- file:$INCLUDE_DIR/absolute.include user.absolute=include
- file:.git/config user.local=true
- file:.git/config user.override=local
- file:.git/config include.path=../include/relative.include
- file:.git/../include/relative.include user.relative=include
- command line: user.cmdline=true
+ file:$HOME/.gitconfig user.global=true
+ file:$HOME/.gitconfig user.override=global
+ file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
+ file:$INCLUDE_DIR/absolute.include user.absolute=include
+ file:.git/config user.local=true
+ file:.git/config user.override=local
+ file:.git/config include.path=../include/relative.include
+ file:.git/../include/relative.include user.relative=include
+ command line: user.cmdline=true
EOF
git -c user.cmdline=true config --list --show-origin >output &&
test_cmp expect output
@@ -1663,16 +1669,16 @@ test_expect_success '--show-origin with --list' '
test_expect_success '--show-origin with --list --null' '
cat >expect <<-EOF &&
- file:$HOME/.gitconfigQuser.global
- trueQfile:$HOME/.gitconfigQuser.override
- globalQfile:$HOME/.gitconfigQinclude.path
- $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
- includeQfile:.git/configQuser.local
- trueQfile:.git/configQuser.override
- localQfile:.git/configQinclude.path
- ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
- includeQcommand line:Quser.cmdline
- trueQ
+ file:$HOME/.gitconfigQuser.global
+ trueQfile:$HOME/.gitconfigQuser.override
+ globalQfile:$HOME/.gitconfigQinclude.path
+ $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
+ includeQfile:.git/configQuser.local
+ trueQfile:.git/configQuser.override
+ localQfile:.git/configQinclude.path
+ ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
+ includeQcommand line:Quser.cmdline
+ trueQ
EOF
git -c user.cmdline=true config --null --list --show-origin >output.raw &&
nul_to_q <output.raw >output &&
@@ -1684,9 +1690,9 @@ test_expect_success '--show-origin with --list --null' '
test_expect_success '--show-origin with single file' '
cat >expect <<-\EOF &&
- file:.git/config user.local=true
- file:.git/config user.override=local
- file:.git/config include.path=../include/relative.include
+ file:.git/config user.local=true
+ file:.git/config user.override=local
+ file:.git/config include.path=../include/relative.include
EOF
git config --local --list --show-origin >output &&
test_cmp expect output
@@ -1694,8 +1700,8 @@ test_expect_success '--show-origin with single file' '
test_expect_success '--show-origin with --get-regexp' '
cat >expect <<-EOF &&
- file:$HOME/.gitconfig user.global true
- file:.git/config user.local true
+ file:$HOME/.gitconfig user.global true
+ file:.git/config user.local true
EOF
git config --show-origin --get-regexp "user\.[g|l].*" >output &&
test_cmp expect output
@@ -1703,31 +1709,36 @@ test_expect_success '--show-origin with --get-regexp' '
test_expect_success '--show-origin getting a single key' '
cat >expect <<-\EOF &&
- file:.git/config local
+ file:.git/config local
EOF
git config --show-origin user.override >output &&
test_cmp expect output
'
test_expect_success 'set up custom config file' '
- CUSTOM_CONFIG_FILE="file\" (dq) and spaces.conf" &&
+ CUSTOM_CONFIG_FILE="custom.conf" &&
cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
- [user]
- custom = true
+ [user]
+ custom = true
EOF
'
+test_expect_success !MINGW 'set up custom config file with special name characters' '
+ WEIRDLY_NAMED_FILE="file\" (dq) and spaces.conf" &&
+ cp "$CUSTOM_CONFIG_FILE" "$WEIRDLY_NAMED_FILE"
+'
+
test_expect_success !MINGW '--show-origin escape special file name characters' '
cat >expect <<-\EOF &&
- file:"file\" (dq) and spaces.conf" user.custom=true
+ file:"file\" (dq) and spaces.conf" user.custom=true
EOF
- git config --file "$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
+ git config --file "$WEIRDLY_NAMED_FILE" --show-origin --list >output &&
test_cmp expect output
'
test_expect_success '--show-origin stdin' '
cat >expect <<-\EOF &&
- standard input: user.custom=true
+ standard input: user.custom=true
EOF
git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
test_cmp expect output
@@ -1735,11 +1746,11 @@ test_expect_success '--show-origin stdin' '
test_expect_success '--show-origin stdin with file include' '
cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
- [user]
- stdin = include
+ [user]
+ stdin = include
EOF
cat >expect <<-EOF &&
- file:$INCLUDE_DIR/stdin.include include
+ file:$INCLUDE_DIR/stdin.include include
EOF
echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" |
git config --show-origin --includes --file - user.stdin >output &&
@@ -1747,18 +1758,18 @@ test_expect_success '--show-origin stdin with file include' '
test_cmp expect output
'
-test_expect_success !MINGW '--show-origin blob' '
+test_expect_success '--show-origin blob' '
blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
cat >expect <<-EOF &&
- blob:$blob user.custom=true
+ blob:$blob user.custom=true
EOF
git config --blob=$blob --show-origin --list >output &&
test_cmp expect output
'
-test_expect_success !MINGW '--show-origin blob ref' '
+test_expect_success '--show-origin blob ref' '
cat >expect <<-\EOF &&
- blob:"master:file\" (dq) and spaces.conf" user.custom=true
+ blob:master:custom.conf user.custom=true
EOF
git add "$CUSTOM_CONFIG_FILE" &&
git commit -m "new config file" &&
@@ -1766,6 +1777,65 @@ test_expect_success !MINGW '--show-origin blob ref' '
test_cmp expect output
'
+test_expect_success '--show-scope with --list' '
+ cat >expect <<-EOF &&
+ global user.global=true
+ global user.override=global
+ global include.path=$INCLUDE_DIR/absolute.include
+ global user.absolute=include
+ local user.local=true
+ local user.override=local
+ local include.path=../include/relative.include
+ local user.relative=include
+ command user.cmdline=true
+ EOF
+ git -c user.cmdline=true config --list --show-scope >output &&
+ test_cmp expect output
+'
+
+test_expect_success !MINGW '--show-scope with --blob' '
+ blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
+ cat >expect <<-EOF &&
+ command user.custom=true
+ EOF
+ git config --blob=$blob --show-scope --list >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-scope with --local' '
+ cat >expect <<-\EOF &&
+ local user.local=true
+ local user.override=local
+ local include.path=../include/relative.include
+ EOF
+ git config --local --list --show-scope >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-scope getting a single value' '
+ cat >expect <<-\EOF &&
+ local true
+ EOF
+ git config --show-scope --get user.local >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-scope with --show-origin' '
+ cat >expect <<-EOF &&
+ global file:$HOME/.gitconfig user.global=true
+ global file:$HOME/.gitconfig user.override=global
+ global file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
+ global file:$INCLUDE_DIR/absolute.include user.absolute=include
+ local file:.git/config user.local=true
+ local file:.git/config user.override=local
+ local file:.git/config include.path=../include/relative.include
+ local file:.git/../include/relative.include user.relative=include
+ command command line: user.cmdline=true
+ EOF
+ git -c user.cmdline=true config --list --show-origin --show-scope >output &&
+ test_cmp expect output
+'
+
test_expect_success '--local requires a repo' '
# we expect 128 to ensure that we do not simply
# fail to find anything and return code "1"
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 7b4e1a63eb..3a527e3a84 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -238,8 +238,8 @@ test_expect_success 'error on modifying repo config without repo' '
cmdline_config="'foo.bar=from-cmdline'"
test_expect_success 'iteration shows correct origins' '
- echo "[foo]bar = from-repo" >.git/config &&
- echo "[foo]bar = from-home" >.gitconfig &&
+ printf "[ignore]\n\tthis = please\n[foo]bar = from-repo\n" >.git/config &&
+ printf "[foo]\n\tbar = from-home\n" >.gitconfig &&
if test_have_prereq MINGW
then
# Use Windows path (i.e. *not* $HOME)
@@ -253,19 +253,29 @@ test_expect_success 'iteration shows correct origins' '
value=from-home
origin=file
name=$HOME_GITCONFIG
+ lno=2
scope=global
+ key=ignore.this
+ value=please
+ origin=file
+ name=.git/config
+ lno=2
+ scope=local
+
key=foo.bar
value=from-repo
origin=file
name=.git/config
- scope=repo
+ lno=3
+ scope=local
key=foo.bar
value=from-cmdline
origin=command line
name=
- scope=cmdline
+ lno=-1
+ scope=command
EOF
GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual &&
test_cmp expect actual
diff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh
index 3a0de0ddaa..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' '
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 1fbd940408..a6224ef65f 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"
@@ -359,55 +361,67 @@ ld="Thu, 26 May 2005 18:43:00 -0500"
test_expect_success 'Query "master@{May 25 2005}" (before history)' '
test_when_finished "rm -f o e" &&
git rev-parse --verify "master@{May 25 2005}" >o 2>e &&
- test $C = $(cat o) &&
- test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"
+ echo "$C" >expect &&
+ test_cmp expect o &&
+ echo "warning: log for '\''master'\'' only goes back to $ed" >expect &&
+ test_i18ncmp expect e
'
test_expect_success 'Query master@{2005-05-25} (before history)' '
test_when_finished "rm -f o e" &&
git rev-parse --verify master@{2005-05-25} >o 2>e &&
- test $C = $(cat o) &&
- test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"
+ echo "$C" >expect &&
+ test_cmp expect o &&
+ echo "warning: log for '\''master'\'' only goes back to $ed" >expect &&
+ test_i18ncmp expect e
'
test_expect_success 'Query "master@{May 26 2005 23:31:59}" (1 second before history)' '
test_when_finished "rm -f o e" &&
git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
- test $C = $(cat o) &&
- test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"
+ echo "$C" >expect &&
+ test_cmp expect o &&
+ echo "warning: log for '\''master'\'' only goes back to $ed" >expect &&
+ test_i18ncmp expect e
'
test_expect_success 'Query "master@{May 26 2005 23:32:00}" (exactly history start)' '
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)"
+ echo "$C" >expect &&
+ test_cmp expect o &&
+ 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)"
+ echo "$A" >expect &&
+ test_cmp expect o &&
+ 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" &&
git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e &&
- test $B = $(cat o) &&
+ echo "$B" >expect &&
+ test_cmp expect o &&
test_i18ngrep -F "warning: log for ref $m has gap after $gd" e
'
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)"
+ echo "$Z" >expect &&
+ test_cmp expect o &&
+ 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)"
+ echo "$E" >expect &&
+ test_cmp expect o &&
+ test_must_be_empty e
'
test_expect_success 'Query "master@{2005-05-28}" (past end of history)' '
test_when_finished "rm -f o e" &&
git rev-parse --verify "master@{2005-05-28}" >o 2>e &&
- test $D = $(cat o) &&
+ echo "$D" >expect &&
+ test_cmp expect o &&
test_i18ngrep -F "warning: log for ref $m unexpectedly ended on $ld" e
'
diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh
index d199d872fb..36b7ef5046 100755
--- a/t/t1406-submodule-ref-store.sh
+++ b/t/t1406-submodule-ref-store.sh
@@ -75,7 +75,7 @@ test_expect_success 'for_each_reflog()' '
'
test_expect_success 'for_each_reflog_ent()' '
- $RUN for-each-reflog-ent HEAD >actual && cat actual &&
+ $RUN for-each-reflog-ent HEAD >actual &&
head -n1 actual | grep first &&
tail -n2 actual | head -n1 | grep master.to.new
'
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/t1450-fsck.sh b/t/t1450-fsck.sh
index 50d28e6fdb..449ebc5657 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -133,6 +133,30 @@ test_expect_success 'other worktree HEAD link pointing at a funny place' '
test_i18ngrep "worktrees/other/HEAD points to something strange" out
'
+test_expect_success 'commit with multiple signatures is okay' '
+ git cat-file commit HEAD >basis &&
+ cat >sigs <<-EOF &&
+ gpgsig -----BEGIN PGP SIGNATURE-----
+ VGhpcyBpcyBub3QgcmVhbGx5IGEgc2lnbmF0dXJlLg==
+ -----END PGP SIGNATURE-----
+ gpgsig-sha256 -----BEGIN PGP SIGNATURE-----
+ VGhpcyBpcyBub3QgcmVhbGx5IGEgc2lnbmF0dXJlLg==
+ -----END PGP SIGNATURE-----
+ EOF
+ sed -e "/^committer/q" basis >okay &&
+ cat sigs >>okay &&
+ echo >>okay &&
+ sed -e "1,/^$/d" basis >>okay &&
+ cat okay &&
+ new=$(git hash-object -t commit -w --stdin <okay) &&
+ test_when_finished "remove_object $new" &&
+ git update-ref refs/heads/bogus "$new" &&
+ test_when_finished "git update-ref -d refs/heads/bogus" &&
+ git fsck 2>out &&
+ cat out &&
+ ! grep "commit $new" out
+'
+
test_expect_success 'email without @ is okay' '
git cat-file commit HEAD >basis &&
sed "s/@/AT/" basis >okay &&
@@ -141,7 +165,6 @@ test_expect_success 'email without @ is okay' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
git fsck 2>out &&
- cat out &&
! grep "commit $new" out
'
@@ -441,6 +464,7 @@ while read name path pretty; do
(
git init $name-$type &&
cd $name-$type &&
+ git config core.protectNTFS false &&
echo content >file &&
git add file &&
git commit -m base &&
@@ -616,7 +640,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 624d0a588f..52edcbdcc3 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -9,10 +9,10 @@ exec </dev/null
test_did_you_mean ()
{
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}
+ hint: Did you mean '$1:$2$3'${2:+ aka $SQ$1:./$3$SQ}?
EOF
- test_cmp expected error
+ test_i18ncmp expected error
}
HASH_file=
@@ -103,66 +103,66 @@ test_expect_success 'correct relative file objects (6)' '
test_expect_success 'incorrect revision id' '
test_must_fail git rev-parse foobar:file.txt 2>error &&
- grep "Invalid object name '"'"'foobar'"'"'." error &&
- test_must_fail git rev-parse foobar 2> error &&
+ test_i18ngrep "invalid object name .foobar." error &&
+ test_must_fail git rev-parse foobar 2>error &&
test_i18ngrep "unknown revision or path not in the working tree." error
'
test_expect_success 'incorrect file in sha1:path' '
- test_must_fail git rev-parse HEAD:nothing.txt 2> error &&
- grep "fatal: Path '"'"'nothing.txt'"'"' does not exist in '"'"'HEAD'"'"'" error &&
- test_must_fail git rev-parse HEAD:index-only.txt 2> error &&
- grep "fatal: Path '"'"'index-only.txt'"'"' exists on disk, but not in '"'"'HEAD'"'"'." error &&
+ test_must_fail git rev-parse HEAD:nothing.txt 2>error &&
+ test_i18ngrep "path .nothing.txt. does not exist in .HEAD." error &&
+ test_must_fail git rev-parse HEAD:index-only.txt 2>error &&
+ test_i18ngrep "path .index-only.txt. exists on disk, but not in .HEAD." error &&
(cd subdir &&
- test_must_fail git rev-parse HEAD:file2.txt 2> error &&
+ test_must_fail git rev-parse HEAD:file2.txt 2>error &&
test_did_you_mean HEAD subdir/ file2.txt exists )
'
test_expect_success 'incorrect file in :path and :N:path' '
- test_must_fail git rev-parse :nothing.txt 2> error &&
- grep "fatal: Path '"'"'nothing.txt'"'"' does not exist (neither on disk nor in the index)." error &&
- test_must_fail git rev-parse :1:nothing.txt 2> error &&
- grep "Path '"'"'nothing.txt'"'"' does not exist (neither on disk nor in the index)." error &&
- test_must_fail git rev-parse :1:file.txt 2> error &&
+ test_must_fail git rev-parse :nothing.txt 2>error &&
+ test_i18ngrep "path .nothing.txt. does not exist (neither on disk nor in the index)" error &&
+ test_must_fail git rev-parse :1:nothing.txt 2>error &&
+ test_i18ngrep "path .nothing.txt. does not exist (neither on disk nor in the index)" error &&
+ test_must_fail git rev-parse :1:file.txt 2>error &&
test_did_you_mean ":0" "" file.txt "is in the index" "at stage 1" &&
(cd subdir &&
- test_must_fail git rev-parse :1:file.txt 2> error &&
+ test_must_fail git rev-parse :1:file.txt 2>error &&
test_did_you_mean ":0" "" file.txt "is in the index" "at stage 1" &&
- test_must_fail git rev-parse :file2.txt 2> error &&
+ test_must_fail git rev-parse :file2.txt 2>error &&
test_did_you_mean ":0" subdir/ file2.txt "is in the index" &&
- test_must_fail git rev-parse :2:file2.txt 2> error &&
+ test_must_fail git rev-parse :2:file2.txt 2>error &&
test_did_you_mean :0 subdir/ file2.txt "is in the index") &&
- test_must_fail git rev-parse :disk-only.txt 2> error &&
- grep "fatal: Path '"'"'disk-only.txt'"'"' exists on disk, but not in the index." error
+ test_must_fail git rev-parse :disk-only.txt 2>error &&
+ test_i18ngrep "path .disk-only.txt. exists on disk, but not in the index" error
'
test_expect_success 'invalid @{n} reference' '
test_must_fail git rev-parse master@{99999} >output 2>error &&
- test -z "$(cat output)" &&
- grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error &&
+ test_must_be_empty output &&
+ test_i18ngrep "log for [^ ]* only has [0-9][0-9]* entries" error &&
test_must_fail git rev-parse --verify master@{99999} >output 2>error &&
- test -z "$(cat output)" &&
- grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error
+ test_must_be_empty output &&
+ test_i18ngrep "log for [^ ]* only has [0-9][0-9]* entries" error
'
test_expect_success 'relative path not found' '
(
cd subdir &&
test_must_fail git rev-parse HEAD:./nonexistent.txt 2>error &&
- grep subdir/nonexistent.txt error
+ test_i18ngrep subdir/nonexistent.txt error
)
'
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)" &&
- grep "relative path syntax can.t be used outside working tree." error
+ test_must_be_empty output &&
+ test_i18ngrep "relative path syntax can.t be used outside working tree" error
'
test_expect_success '<commit>:file correctly diagnosed after a pathname' '
@@ -222,4 +222,18 @@ 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 8b4cf8a6e3..dfc0d96d8a 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -28,14 +28,9 @@ test_expect_success 'setup' '
)
'
-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 () {
@@ -44,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' '
@@ -149,7 +159,9 @@ 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' '
@@ -203,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/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index 822381dd9d..bbca7ef8da 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -1,50 +1,76 @@
#!/bin/sh
-test_description='checkout '
+test_description='checkout'
. ./test-lib.sh
-# Arguments: <branch> <sha> [<checkout options>]
+# Arguments: [!] <branch> <oid> [<checkout options>]
#
# Runs "git checkout" to switch to <branch>, testing that
#
# 1) we are on the specified branch, <branch>;
-# 2) HEAD is <sha>; if <sha> is not specified, the old HEAD is used.
+# 2) HEAD is <oid>; if <oid> is not specified, the old HEAD is used.
#
# If <checkout options> is not specified, "git checkout" is run with -b.
-do_checkout() {
+#
+# If the first argument is `!`, "git checkout" is expected to fail when
+# it is run.
+do_checkout () {
+ should_fail= &&
+ if test "x$1" = "x!"
+ then
+ should_fail=yes &&
+ shift
+ fi &&
exp_branch=$1 &&
exp_ref="refs/heads/$exp_branch" &&
- # if <sha> is not specified, use HEAD.
- exp_sha=${2:-$(git rev-parse --verify HEAD)} &&
+ # if <oid> is not specified, use HEAD.
+ exp_oid=${2:-$(git rev-parse --verify HEAD)} &&
# default options for git checkout: -b
- if [ -z "$3" ]; then
+ if test -z "$3"
+ then
opts="-b"
else
opts="$3"
fi
- git checkout $opts $exp_branch $exp_sha &&
+ if test -n "$should_fail"
+ then
+ test_must_fail git checkout $opts $exp_branch $exp_oid
+ else
+ git checkout $opts $exp_branch $exp_oid &&
+ echo "$exp_ref" >ref.expect &&
+ git rev-parse --symbolic-full-name HEAD >ref.actual &&
+ test_cmp ref.expect ref.actual &&
+ echo "$exp_oid" >oid.expect &&
+ git rev-parse --verify HEAD >oid.actual &&
+ test_cmp oid.expect oid.actual
+ fi
+}
- test $exp_ref = $(git rev-parse --symbolic-full-name HEAD) &&
- test $exp_sha = $(git rev-parse --verify HEAD)
+test_dirty_unmergeable () {
+ test_expect_code 1 git diff --exit-code
}
-test_dirty_unmergeable() {
- ! git diff --exit-code >/dev/null
+test_dirty_unmergeable_discards_changes () {
+ git diff --exit-code
}
-setup_dirty_unmergeable() {
+setup_dirty_unmergeable () {
echo >>file1 change2
}
-test_dirty_mergeable() {
- ! git diff --cached --exit-code >/dev/null
+test_dirty_mergeable () {
+ test_expect_code 1 git diff --cached --exit-code
+}
+
+test_dirty_mergeable_discards_changes () {
+ git diff --cached --exit-code
}
-setup_dirty_mergeable() {
+setup_dirty_mergeable () {
echo >file2 file2 &&
git add file2
}
@@ -82,7 +108,7 @@ test_expect_success 'checkout -b to a new branch, set to an explicit ref' '
test_expect_success 'checkout -b to a new branch with unmergeable changes fails' '
setup_dirty_unmergeable &&
- test_must_fail do_checkout branch2 $HEAD1 &&
+ do_checkout ! branch2 $HEAD1 &&
test_dirty_unmergeable
'
@@ -93,7 +119,7 @@ test_expect_success 'checkout -f -b to a new branch with unmergeable changes dis
# still dirty and on branch1
do_checkout branch2 $HEAD1 "-f -b" &&
- test_must_fail test_dirty_unmergeable
+ test_dirty_unmergeable_discards_changes
'
test_expect_success 'checkout -b to a new branch preserves mergeable changes' '
@@ -111,12 +137,12 @@ test_expect_success 'checkout -f -b to a new branch with mergeable changes disca
test_when_finished git reset --hard HEAD &&
setup_dirty_mergeable &&
do_checkout branch2 $HEAD1 "-f -b" &&
- test_must_fail test_dirty_mergeable
+ test_dirty_mergeable_discards_changes
'
test_expect_success 'checkout -b to an existing branch fails' '
test_when_finished git reset --hard HEAD &&
- test_must_fail do_checkout branch2 $HEAD2
+ do_checkout ! branch2 $HEAD2
'
test_expect_success 'checkout -b to @{-1} fails with the right branch name' '
@@ -140,7 +166,8 @@ test_expect_success 'checkout -B to a merge base' '
'
test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' '
- git checkout $(git rev-parse --verify HEAD) &&
+ head=$(git rev-parse --verify HEAD) &&
+ git checkout "$head" &&
do_checkout branch2 "" -B
'
@@ -155,14 +182,14 @@ test_expect_success 'checkout -B to an existing branch with unmergeable changes
git checkout branch1 &&
setup_dirty_unmergeable &&
- test_must_fail do_checkout branch2 $HEAD1 -B &&
+ do_checkout ! branch2 $HEAD1 -B &&
test_dirty_unmergeable
'
test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' '
# still dirty and on branch1
do_checkout branch2 $HEAD1 "-f -B" &&
- test_must_fail test_dirty_unmergeable
+ test_dirty_unmergeable_discards_changes
'
test_expect_success 'checkout -B to an existing branch preserves mergeable changes' '
@@ -179,7 +206,7 @@ test_expect_success 'checkout -f -B to an existing branch with mergeable changes
setup_dirty_mergeable &&
do_checkout branch2 $HEAD1 "-f -B" &&
- test_must_fail test_dirty_mergeable
+ test_dirty_mergeable_discards_changes
'
test_expect_success 'checkout -b <describe>' '
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 21c3f84459..076d0df7fc 100755
--- a/t/t2070-restore.sh
+++ b/t/t2070-restore.sh
@@ -106,4 +106,21 @@ test_expect_success 'restore --staged adds deleted intent-to-add file back to in
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/t2107-update-index-basic.sh b/t/t2107-update-index-basic.sh
index 2242cd098e..a30b7ca6bc 100755
--- a/t/t2107-update-index-basic.sh
+++ b/t/t2107-update-index-basic.sh
@@ -9,7 +9,6 @@ Tests for command-line parsing and basic operation.
test_expect_success 'update-index --nonsense fails' '
test_must_fail git update-index --nonsense 2>msg &&
- cat msg &&
test -s msg
'
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index e819ba741e..5a7495474a 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
)
'
@@ -570,6 +570,15 @@ test_expect_success '"add" an existing locked but missing worktree' '
git worktree add --force --force --detach gnoo
'
+test_expect_success '"add" not tripped up by magic worktree matching"' '
+ # if worktree "sub1/bar" exists, "git worktree add bar" in distinct
+ # directory `sub2` should not mistakenly complain that `bar` is an
+ # already-registered worktree
+ mkdir sub1 sub2 &&
+ git -C sub1 --git-dir=../.git worktree add --detach bozo &&
+ git -C sub2 --git-dir=../.git worktree add --detach bozo
+'
+
test_expect_success FUNNYNAMES 'sanitize generated worktree name' '
git worktree add --detach ". weird*..?.lock.lock" &&
test -d .git/worktrees/---weird-.-
@@ -587,4 +596,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/t2402-worktree-list.sh b/t/t2402-worktree-list.sh
index bb6fb9b12c..69ffe865b4 100755
--- a/t/t2402-worktree-list.sh
+++ b/t/t2402-worktree-list.sh
@@ -151,4 +151,10 @@ test_expect_success 'linked worktrees are sorted' '
test_cmp expected sorted/main/actual
'
+test_expect_success 'worktree path when called in .git directory' '
+ git worktree list >list1&&
+ git -C .git worktree list >list2 &&
+ test_cmp list1 list2
+'
+
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/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh
index 318b5bce7e..4a08000713 100755
--- a/t/t3007-ls-files-recurse-submodules.sh
+++ b/t/t3007-ls-files-recurse-submodules.sh
@@ -130,7 +130,6 @@ test_expect_success '--recurse-submodules and pathspecs setup' '
git ls-files --recurse-submodules >actual &&
test_cmp expect actual &&
- cat actual &&
git ls-files --recurse-submodules "*" >actual &&
test_cmp expect actual
'
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 2170758e38..d48d211a95 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -604,7 +604,7 @@ test_expect_success 'merge removes empty directories' '
git commit -mremoved-d/e &&
git checkout master &&
git merge -s recursive rm &&
- test_must_fail test -d d
+ test_path_is_missing d
'
test_expect_success 'merge-recursive simple w/submodule' '
diff --git a/t/t3035-merge-sparse.sh b/t/t3035-merge-sparse.sh
index c4b4a94324..74562e1235 100755
--- a/t/t3035-merge-sparse.sh
+++ b/t/t3035-merge-sparse.sh
@@ -28,7 +28,7 @@ test_expect_success 'setup' '
git config core.sparseCheckout true &&
echo "/checked-out" >.git/info/sparse-checkout &&
git reset --hard &&
- ! git merge theirs
+ test_must_fail git merge theirs
'
test_expect_success 'reset --hard works after the conflict' '
@@ -42,7 +42,7 @@ test_expect_success 'is reset properly' '
'
test_expect_success 'setup: conflict back' '
- ! git merge theirs
+ test_must_fail git merge theirs
'
test_expect_success 'Merge abort works after the conflict' '
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/t3206-range-diff.sh b/t/t3206-range-diff.sh
index 0579cd9969..bd808f87ed 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -8,8 +8,8 @@ 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 &&
- test_oid_cache <<-EOF
+ git fast-import <"$TEST_DIRECTORY"/t3206/history.export &&
+ test_oid_cache <<-\EOF
# topic
t1 sha1:4de457d
t2 sha1:fccce22
@@ -102,6 +102,14 @@ test_expect_success 'setup' '
n3 sha256:3b0a644
n4 sha256:e461653
+ # mode change
+ o1 sha1:4d39cb3
+ o2 sha1:26c107f
+ o3 sha1:4c1e0f5
+ o1 sha256:d0dd598
+ o2 sha256:c4a279e
+ o3 sha256:78459d7
+
# added and removed
s1 sha1:096b1ba
s2 sha1:d92e698
@@ -121,88 +129,88 @@ test_expect_success 'setup' '
test_expect_success 'simple A..B A..C (unmodified)' '
git range-diff --no-color master..topic master..unmodified \
>actual &&
- cat >expected <<-EOF &&
+ 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 &&
+ 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 &&
+ 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 &&
+ 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 &&
+ 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 &&
+ 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 &&
+ 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/
@@ -226,23 +234,23 @@ 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 &&
+ 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 &&
+ cat >expect <<-EOF &&
1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
@@ -256,12 +264,12 @@ test_expect_success 'changed commit with --stat diff option' '
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 &&
+ 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/
@@ -285,12 +293,12 @@ 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 &&
+ 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
@@ -330,13 +338,13 @@ 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 >expected <<-EOF &&
- 1: fccce22 ! 1: 4d39cb3 s/4/A/
+ sed s/Z/\ /g >expect <<-EOF &&
+ 1: $(test_oid t2) ! 1: $(test_oid o1) s/4/A/
@@ Metadata
ZAuthor: Thomas Rast <trast@inf.ethz.ch>
Z
@@ -352,7 +360,7 @@ test_expect_success 'file with mode only change' '
Z 7
+
+ ## other-file (new) ##
- 2: 147e64e ! 2: 26c107f s/11/B/
+ 2: $(test_oid t3) ! 2: $(test_oid o2) s/11/B/
@@ Metadata
ZAuthor: Thomas Rast <trast@inf.ethz.ch>
Z
@@ -368,14 +376,14 @@ test_expect_success 'file with mode only change' '
Z 14
+
+ ## other-file (mode change 100644 => 100755) ##
- 3: a63e992 = 3: 4c1e0f5 s/12/B/
+ 3: $(test_oid t4) = 3: $(test_oid o3) s/12/B/
EOF
- test_cmp expected actual
+ 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 &&
+ 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
@@ -411,7 +419,7 @@ test_expect_success 'file added and later removed' '
+ ## new-file (deleted) ##
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' '
@@ -421,7 +429,7 @@ 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 &&
+ 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
@@ -436,7 +444,7 @@ test_expect_success 'changed message' '
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' '
@@ -505,4 +513,202 @@ 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/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 d3fa298c6a..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^
'
@@ -79,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' '
@@ -99,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^
'
@@ -109,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^
'
@@ -119,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^
'
@@ -129,7 +144,9 @@ 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^
'
@@ -146,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
'
@@ -472,9 +490,11 @@ test_expect_success 'removing with --stdin --ignore-missing' '
test_expect_success 'list notes with "git notes list"' '
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 &&
- $(git rev-parse refs/notes/commits:$commit_2) $commit_2
- $(git rev-parse refs/notes/commits:$commit_3) $commit_3
+ $note_2 $commit_2
+ $note_3 $commit_3
EOF
git notes list >actual &&
test_cmp expect actual
@@ -486,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 &&
- $(git rev-parse refs/notes/commits:$commit_3)
- EOF
+ git rev-parse refs/notes/commits:$commit_3 >expect &&
git notes list HEAD^^ >actual &&
test_cmp expect actual
'
@@ -512,10 +530,11 @@ 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"' '
commit_5=$(git rev-parse 5th) &&
+ note_5=$(git rev-parse refs/notes/commits:$commit_5) &&
sort -t" " -k2 >expect_list <<-EOF &&
- $(git rev-parse refs/notes/commits:$commit_2) $commit_2
- $(git rev-parse refs/notes/commits:$commit_3) $commit_3
- $(git rev-parse refs/notes/commits:$commit_5) $commit_5
+ $note_2 $commit_2
+ $note_3 $commit_3
+ $note_5 $commit_5
EOF
git notes list >actual &&
test_cmp expect_list actual
@@ -721,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 &&
@@ -745,10 +765,13 @@ test_expect_success 'create note from other note with "git notes add -C"' '
Notes:
${indent}order test
EOF
- 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' '
@@ -777,11 +800,12 @@ 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"' '
@@ -797,7 +821,8 @@ test_expect_success 'create note from other note with "git notes add -c"' '
Notes:
${indent}yet another note
EOF
- 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
'
@@ -822,7 +847,8 @@ 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
'
@@ -839,7 +865,8 @@ 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
'
@@ -858,12 +885,33 @@ 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 $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 &&
@@ -878,17 +926,33 @@ test_expect_success 'copy note with "git notes copy"' '
${indent}
${indent}yet another note
EOF
- 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"' '
@@ -901,14 +965,36 @@ test_expect_success 'allow overwrite with "git notes copy -f"' '
${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 $commit
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:23:13 2005 -0700
+
+ ${indent}11th
+
+ Notes:
${indent}yet another note
${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' '
@@ -943,13 +1029,21 @@ 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)' '
@@ -970,9 +1064,13 @@ test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
${indent}14th
EOF
- (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
'
@@ -1005,17 +1103,23 @@ 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
'
@@ -1035,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
'
@@ -1044,8 +1150,10 @@ 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
'
@@ -1067,8 +1175,10 @@ 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
'
@@ -1095,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
'
@@ -1106,8 +1220,10 @@ 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
'
@@ -1127,8 +1243,10 @@ 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
'
@@ -1148,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
'
@@ -1159,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 831f83d211..3b4753e1b4 100755
--- a/t/t3305-notes-fanout.sh
+++ b/t/t3305-notes-fanout.sh
@@ -4,6 +4,38 @@ test_description='Test that adding/removing many notes triggers automatic fanout
. ./test-lib.sh
+path_has_fanout() {
+ path=$1 &&
+ fanout=$2 &&
+ after_last_slash=$((40 - $fanout * 2)) &&
+ echo $path | grep -q "^\([0-9a-f]\{2\}/\)\{$fanout\}[0-9a-f]\{$after_last_slash\}$"
+}
+
+touched_one_note_with_fanout() {
+ notes_commit=$1 &&
+ modification=$2 && # 'A' for addition, 'D' for deletion
+ fanout=$3 &&
+ diff=$(git diff-tree --no-commit-id --name-status --root -r $notes_commit) &&
+ path=$(echo $diff | sed -e "s/^$modification[\t ]//") &&
+ path_has_fanout "$path" $fanout;
+}
+
+all_notes_have_fanout() {
+ notes_commit=$1 &&
+ fanout=$2 &&
+ git ls-tree -r --name-only $notes_commit 2>/dev/null |
+ while read path
+ do
+ path_has_fanout $path $fanout || return 1
+ done
+}
+
+test_expect_success 'tweak test environment' '
+ git checkout -b nondeterminism &&
+ test_commit A &&
+ git checkout --orphan with_notes;
+'
+
test_expect_success 'creating many notes with git-notes' '
num_notes=300 &&
i=0 &&
@@ -20,7 +52,7 @@ test_expect_success 'creating many notes with git-notes' '
test_expect_success 'many notes created correctly with git-notes' '
git log | grep "^ " > output &&
- i=300 &&
+ i=$num_notes &&
while test $i -gt 0
do
echo " commit #$i" &&
@@ -30,34 +62,46 @@ test_expect_success 'many notes created correctly with git-notes' '
test_cmp expect output
'
-test_expect_success 'many notes created with git-notes triggers fanout' '
- # Expect entire notes tree to have a fanout == 1
- git ls-tree -r --name-only refs/notes/commits |
- while read path
+test_expect_success 'stable fanout 0 is followed by stable fanout 1' '
+ i=$num_notes &&
+ fanout=0 &&
+ while test $i -gt 0
do
- echo $path | grep "^../[0-9a-f]*$" || {
- echo "Invalid path \"$path\"" &&
- return 1;
- }
- done
+ i=$(($i - 1)) &&
+ if touched_one_note_with_fanout refs/notes/commits~$i A $fanout
+ then
+ continue
+ elif test $fanout -eq 0
+ then
+ fanout=1 &&
+ if all_notes_have_fanout refs/notes/commits~$i $fanout
+ then
+ echo "Fanout 0 -> 1 at refs/notes/commits~$i" &&
+ continue
+ fi
+ fi &&
+ echo "Failed fanout=$fanout check at refs/notes/commits~$i" &&
+ git ls-tree -r --name-only refs/notes/commits~$i &&
+ return 1
+ done &&
+ all_notes_have_fanout refs/notes/commits 1
'
test_expect_success 'deleting most notes with git-notes' '
- num_notes=250 &&
+ remove_notes=285 &&
i=0 &&
git rev-list HEAD |
- while test $i -lt $num_notes && read sha1
+ while test $i -lt $remove_notes && read sha1
do
i=$(($i + 1)) &&
test_tick &&
- git notes remove "$sha1" ||
- exit 1
+ git notes remove "$sha1" 2>/dev/null || return 1
done
'
test_expect_success 'most notes deleted correctly with git-notes' '
- git log HEAD~250 | grep "^ " > output &&
- i=50 &&
+ git log HEAD~$remove_notes | grep "^ " > output &&
+ i=$(($num_notes - $remove_notes)) &&
while test $i -gt 0
do
echo " commit #$i" &&
@@ -67,16 +111,29 @@ test_expect_success 'most notes deleted correctly with git-notes' '
test_cmp expect output
'
-test_expect_success 'deleting most notes triggers fanout consolidation' '
- # Expect entire notes tree to have a fanout == 0
- git ls-tree -r --name-only refs/notes/commits |
- while read path
+test_expect_success 'stable fanout 1 is followed by stable fanout 0' '
+ i=$remove_notes &&
+ fanout=1 &&
+ while test $i -gt 0
do
- echo $path | grep -v "^../.*" || {
- echo "Invalid path \"$path\"" &&
- return 1;
- }
- done
+ i=$(($i - 1)) &&
+ if touched_one_note_with_fanout refs/notes/commits~$i D $fanout
+ then
+ continue
+ elif test $fanout -eq 1
+ then
+ fanout=0 &&
+ if all_notes_have_fanout refs/notes/commits~$i $fanout
+ then
+ echo "Fanout 1 -> 0 at refs/notes/commits~$i" &&
+ continue
+ fi
+ fi &&
+ echo "Failed fanout=$fanout check at refs/notes/commits~$i" &&
+ git ls-tree -r --name-only refs/notes/commits~$i &&
+ return 1
+ done &&
+ all_notes_have_fanout refs/notes/commits 0
'
test_done
diff --git a/t/t3308-notes-merge.sh b/t/t3308-notes-merge.sh
index d60588ec8f..790e292966 100755
--- a/t/t3308-notes-merge.sh
+++ b/t/t3308-notes-merge.sh
@@ -20,7 +20,34 @@ test_expect_success setup '
git notes add -m "Notes on 3rd commit" 3rd &&
git notes add -m "Notes on 4th commit" 4th &&
# Copy notes to remote-notes
- git fetch . refs/notes/*:refs/remote-notes/origin/*
+ git fetch . refs/notes/*:refs/remote-notes/origin/* &&
+
+ test_oid_init &&
+ test_oid_cache <<-EOF
+ hash4a sha1:5e93d24084d32e1cb61f7070505b9d2530cca987
+ hash3a sha1:8366731eeee53787d2bdf8fc1eff7d94757e8da0
+ hash2a sha1:eede89064cd42441590d6afec6c37b321ada3389
+ hash1a sha1:daa55ffad6cb99bf64226532147ffcaf5ce8bdd1
+ hash5b sha1:0f2efbd00262f2fd41dfae33df8765618eeacd99
+ hash4b sha1:dec2502dac3ea161543f71930044deff93fa945c
+ hash3b sha1:4069cdb399fd45463ec6eef8e051a16a03592d91
+ hash2c sha1:d000d30e6ddcfce3a8122c403226a2ce2fd04d9d
+ hash1c sha1:43add6bd0c8c0bc871ac7991e0f5573cfba27804
+ hash4d sha1:1f257a3a90328557c452f0817d6cc50c89d315d4
+ hash3d sha1:05a4927951bcef347f51486575b878b2b60137f2
+
+ hash4a sha256:eef876be1d32ac2e2e42240e0429325cec116e55e88cb2969899fac695aa762f
+ hash3a sha256:cf7cd1bc091d7ba4166a86df864110e42087cd893a5ae96bc50d637e0290939d
+ hash2a sha256:21ddde7ebce2c285213898cb04deca0fd3209610cf7aaf8222e4e2f45262fae2
+ hash1a sha256:f9fe0eda16c6027732ed9d4295689a03abd16f893be69b3dcbf4037ddb191921
+ hash5b sha256:20046f2244577797a9e3d3f790ea9eca4d8a6bafb2a5570bcb0e03aa02ce100b
+ hash4b sha256:f90563d134c61a95bb88afbd45d48ccc9e919c62aa6fbfcd483302b3e4d8dbcb
+ hash3b sha256:988f2aca9f2d87e93e6a73197c2bb99560cc44a2f92d18653968f956f01221e0
+ hash2c sha256:84153b777b4d42827a756c6578dcdb59d8ae5d1360b874fb37c430150c825c26
+ hash1c sha256:9beb2bc4eef72e4c4087be168a20573e34d993d9ab1883055f23e322afa06567
+ hash4d sha256:32de39dc06e679a7abb2d4a55ede7709b3124340a4a90aa305971b1c72ac319d
+ hash3d sha256:fa73b20e41cbb7541c4c81d1535016131dbfbeb05bf6a71f6115e9cad31c7af5
+ EOF
'
commit_sha1=$(git rev-parse 1st^{commit})
@@ -40,10 +67,10 @@ verify_notes () {
}
cat <<EOF | sort >expect_notes_x
-5e93d24084d32e1cb61f7070505b9d2530cca987 $commit_sha4
-8366731eeee53787d2bdf8fc1eff7d94757e8da0 $commit_sha3
-eede89064cd42441590d6afec6c37b321ada3389 $commit_sha2
-daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1
+$(test_oid hash4a) $commit_sha4
+$(test_oid hash3a) $commit_sha3
+$(test_oid hash2a) $commit_sha2
+$(test_oid hash1a) $commit_sha1
EOF
cat >expect_log_x <<EOF
@@ -126,10 +153,10 @@ test_expect_success 'merge previous notes commit (y^ => y) => No-op' '
'
cat <<EOF | sort >expect_notes_y
-0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5
-dec2502dac3ea161543f71930044deff93fa945c $commit_sha4
-4069cdb399fd45463ec6eef8e051a16a03592d91 $commit_sha3
-daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1
+$(test_oid hash5b) $commit_sha5
+$(test_oid hash4b) $commit_sha4
+$(test_oid hash3b) $commit_sha3
+$(test_oid hash1a) $commit_sha1
EOF
cat >expect_log_y <<EOF
@@ -193,11 +220,11 @@ test_expect_success 'merge empty notes ref (z => y)' '
'
cat <<EOF | sort >expect_notes_y
-0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5
-dec2502dac3ea161543f71930044deff93fa945c $commit_sha4
-4069cdb399fd45463ec6eef8e051a16a03592d91 $commit_sha3
-d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2
-43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1
+$(test_oid hash5b) $commit_sha5
+$(test_oid hash4b) $commit_sha4
+$(test_oid hash3b) $commit_sha3
+$(test_oid hash2c) $commit_sha2
+$(test_oid hash1c) $commit_sha1
EOF
cat >expect_log_y <<EOF
@@ -231,9 +258,9 @@ test_expect_success 'change notes on other notes ref (y)' '
'
cat <<EOF | sort >expect_notes_x
-0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5
-1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4
-daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1
+$(test_oid hash5b) $commit_sha5
+$(test_oid hash4d) $commit_sha4
+$(test_oid hash1a) $commit_sha1
EOF
cat >expect_log_x <<EOF
@@ -262,10 +289,10 @@ test_expect_success 'change notes on notes ref (x)' '
'
cat <<EOF | sort >expect_notes_x
-0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5
-1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4
-d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2
-43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1
+$(test_oid hash5b) $commit_sha5
+$(test_oid hash4d) $commit_sha4
+$(test_oid hash2c) $commit_sha2
+$(test_oid hash1c) $commit_sha1
EOF
cat >expect_log_x <<EOF
@@ -296,8 +323,8 @@ test_expect_success 'merge y into x => Non-conflicting 3-way merge' '
'
cat <<EOF | sort >expect_notes_w
-05a4927951bcef347f51486575b878b2b60137f2 $commit_sha3
-d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2
+$(test_oid hash3d) $commit_sha3
+$(test_oid hash2c) $commit_sha2
EOF
cat >expect_log_w <<EOF
@@ -326,11 +353,11 @@ test_expect_success 'create notes on new, separate notes ref (w)' '
'
cat <<EOF | sort >expect_notes_x
-0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5
-1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4
-05a4927951bcef347f51486575b878b2b60137f2 $commit_sha3
-d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2
-43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1
+$(test_oid hash5b) $commit_sha5
+$(test_oid hash4d) $commit_sha4
+$(test_oid hash3d) $commit_sha3
+$(test_oid hash2c) $commit_sha2
+$(test_oid hash1c) $commit_sha1
EOF
cat >expect_log_x <<EOF
diff --git a/t/t3309-notes-merge-auto-resolve.sh b/t/t3309-notes-merge-auto-resolve.sh
index 14c2adf970..141d3e4ca4 100755
--- a/t/t3309-notes-merge-auto-resolve.sh
+++ b/t/t3309-notes-merge-auto-resolve.sh
@@ -23,7 +23,67 @@ test_expect_success 'setup commits' '
test_commit 12th &&
test_commit 13th &&
test_commit 14th &&
- test_commit 15th
+ test_commit 15th &&
+
+ test_oid_cache <<-EOF
+ hash15a sha1:457a85d6c814ea208550f15fcc48f804ac8dc023
+ hash14a sha1:b0c95b954301d69da2bc3723f4cb1680d355937c
+ hash13a sha1:5d30216a129eeffa97d9694ffe8c74317a560315
+ hash12a sha1:dd161bc149470fd890dd4ab52a4cbd79bbd18c36
+ hash11a sha1:7abbc45126d680336fb24294f013a7cdfa3ed545
+ hash10a sha1:b8d03e173f67f6505a76f6e00cf93440200dd9be
+ hash09a sha1:20c613c835011c48a5abe29170a2402ca6354910
+ hash08a sha1:a3daf8a1e4e5dc3409a303ad8481d57bfea7f5d6
+ hash07a sha1:897003322b53bc6ca098e9324ee508362347e734
+ hash06a sha1:11d97fdebfa5ceee540a3da07bce6fa0222bc082
+ hash15b sha1:68b8630d25516028bed862719855b3d6768d7833
+ hash14b sha1:5de7ea7ad4f47e7ff91989fb82234634730f75df
+ hash13b sha1:3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc
+ hash12b sha1:a66055fa82f7a03fe0c02a6aba3287a85abf7c62
+ hash05b sha1:154508c7a0bcad82b6fe4b472bc4c26b3bf0825b
+ hash04b sha1:e2bfd06a37dd2031684a59a6e2b033e212239c78
+ hash03b sha1:5772f42408c0dd6f097a7ca2d24de0e78d1c46b1
+ hash15c sha1:9b4b2c61f0615412da3c10f98ff85b57c04ec765
+ hash11c sha1:7e3c53503a3db8dd996cb62e37c66e070b44b54d
+ hash08c sha1:851e1638784a884c7dd26c5d41f3340f6387413a
+ hash05c sha1:99fc34adfc400b95c67b013115e37e31aa9a6d23
+ hash02c sha1:283b48219aee9a4105f6cab337e789065c82c2b9
+ hash15d sha1:7c4e546efd0fe939f876beb262ece02797880b54
+ hash05d sha1:6c841cc36ea496027290967ca96bd2bef54dbb47
+ hash15e sha1:d682107b8bf7a7aea1e537a8d5cb6a12b60135f1
+ hash05e sha1:357b6ca14c7afd59b7f8b8aaaa6b8b723771135b
+ hash15f sha1:6be90240b5f54594203e25d9f2f64b7567175aee
+ hash05f sha1:660311d7f78dc53db12ac373a43fca7465381a7e
+
+ hash15a sha256:45b1558e5c1b75f570010fa48aaa67bb2289fcd431b34ad81cb4c8b95f4f872a
+ hash14a sha256:6e7af179ea4dd28afdc83ae6912ba0098cdeff764b26a8b750b157dd81749092
+ hash13a sha256:7353089961baf555388e1bac68c67c8ea94b08ccbd97532201cf7f6790703052
+ hash12a sha256:5863e4521689ee1879ceab3b38d39e93ab5b51ec70aaf6a96ad388fbdedfa25e
+ hash11a sha256:82a0ec0338b4ecf8b44304badf4ad38d7469dc41827f38d7ba6c42e3bae3ee98
+ hash10a sha256:e84f2564e92de9792c93b8d197262c735d7ccb1de6025cef8759af8f6c3308eb
+ hash09a sha256:4dd07764bcec696f195c0ea71ae89e174876403af1637e4642b8f4453fd23028
+ hash08a sha256:02132c4546cd88a1d0aa5854dd55da120927f7904ba16afe36fe03e91a622067
+ hash07a sha256:369baf7d00c6720efdc10273493555f943051f84a4706fb24caeb353fa4789db
+ hash06a sha256:52d32c10353583b2d96a5849b1f1f43c8018e76f3e8ef1b0d46eb5cff7cdefaf
+ hash15b sha256:345e6660b345fa174738a31a7a59423c394bdf414804e200bc510c65d971ae96
+ hash14b sha256:7653a6596021c52e405cba979eea15a729993e7102b9a61ba4667e34f0ead4a1
+ hash13b sha256:0f202a0b6b9690de2349c173dfd766a37e82744f61c14f1c389306f1d69f470b
+ hash12b sha256:eb00f219c026136ea6535b16ff8ec3efa510e6bf50098ca041e1a2a1d4b79840
+ hash05b sha256:993b2290cd0c24c27c849d99f1904f3b590f77af0f539932734ad05679ac5a2f
+ hash04b sha256:c7fba0d6104917fbf35258f40b9fa4fc697cfa992deecd1570a3b08d0a5587a9
+ hash03b sha256:7287a2d78a3766c181b08df38951d784b08b72a44f571ed6d855bd0be22c70f6
+ hash15c sha256:62316660a22bf97857dc4a16709ec4d93a224e8c9f37d661ef91751e1f4c4166
+ hash11c sha256:51c3763de9b08309370adc5036d58debb331980e73097902957c444602551daa
+ hash08c sha256:22cf1fa29599898a7218c51135d66ed85d22aad584f77db3305dedce4c3d4798
+ hash05c sha256:2508fd86db980f0508893a1c1571bdf3b2ee113dc25ddb1a3a2fb94bd6cd0d58
+ hash02c sha256:63bb527e0b4e1c8e1dd0d54dd778ca7c3718689fd6e37c473044cfbcf1cacfdb
+ hash15d sha256:667acb4e2d5f8df15e5aea4506dfd16d25bc7feca70fdb0d965a7222f983bb88
+ hash05d sha256:09e6b5a6fe666c4a027674b6611a254b7d2528cd211c6b5288d1b4db6c741dfa
+ hash15e sha256:e8cbf52f6fcadc6de3c7761e64a89e9fe38d19a03d3e28ef6ca8596d93fc4f3a
+ hash05e sha256:cdb1e19f7ba1539f95af51a57edeb88a7ecc97d3c2f52da8c4c86af308595607
+ hash15f sha256:29c14cb92da448a923963b8a43994268b19c2e57913de73f3667421fd2c0eeec
+ hash05f sha256:14a6e641b2c0a9f398ebac6b4d34afa5efea4c52d2631382f45f8f662266903b
+ EOF
'
commit_sha1=$(git rev-parse 1st^{commit})
@@ -68,16 +128,16 @@ test_expect_success 'setup merge base (x)' '
'
cat <<EOF | sort >expect_notes_x
-457a85d6c814ea208550f15fcc48f804ac8dc023 $commit_sha15
-b0c95b954301d69da2bc3723f4cb1680d355937c $commit_sha14
-5d30216a129eeffa97d9694ffe8c74317a560315 $commit_sha13
-dd161bc149470fd890dd4ab52a4cbd79bbd18c36 $commit_sha12
-7abbc45126d680336fb24294f013a7cdfa3ed545 $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-20c613c835011c48a5abe29170a2402ca6354910 $commit_sha9
-a3daf8a1e4e5dc3409a303ad8481d57bfea7f5d6 $commit_sha8
-897003322b53bc6ca098e9324ee508362347e734 $commit_sha7
-11d97fdebfa5ceee540a3da07bce6fa0222bc082 $commit_sha6
+$(test_oid hash15a) $commit_sha15
+$(test_oid hash14a) $commit_sha14
+$(test_oid hash13a) $commit_sha13
+$(test_oid hash12a) $commit_sha12
+$(test_oid hash11a) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash09a) $commit_sha9
+$(test_oid hash08a) $commit_sha8
+$(test_oid hash07a) $commit_sha7
+$(test_oid hash06a) $commit_sha6
EOF
cat >expect_log_x <<EOF
@@ -141,16 +201,16 @@ test_expect_success 'setup local branch (y)' '
'
cat <<EOF | sort >expect_notes_y
-68b8630d25516028bed862719855b3d6768d7833 $commit_sha15
-5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14
-3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13
-a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12
-7abbc45126d680336fb24294f013a7cdfa3ed545 $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-20c613c835011c48a5abe29170a2402ca6354910 $commit_sha9
-154508c7a0bcad82b6fe4b472bc4c26b3bf0825b $commit_sha5
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
+$(test_oid hash15b) $commit_sha15
+$(test_oid hash14b) $commit_sha14
+$(test_oid hash13b) $commit_sha13
+$(test_oid hash12b) $commit_sha12
+$(test_oid hash11a) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash09a) $commit_sha9
+$(test_oid hash05b) $commit_sha5
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash03b) $commit_sha3
EOF
cat >expect_log_y <<EOF
@@ -214,16 +274,16 @@ test_expect_success 'setup remote branch (z)' '
'
cat <<EOF | sort >expect_notes_z
-9b4b2c61f0615412da3c10f98ff85b57c04ec765 $commit_sha15
-5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14
-5d30216a129eeffa97d9694ffe8c74317a560315 $commit_sha13
-7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8
-897003322b53bc6ca098e9324ee508362347e734 $commit_sha7
-99fc34adfc400b95c67b013115e37e31aa9a6d23 $commit_sha5
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
+$(test_oid hash15c) $commit_sha15
+$(test_oid hash14b) $commit_sha14
+$(test_oid hash13a) $commit_sha13
+$(test_oid hash11c) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash08c) $commit_sha8
+$(test_oid hash07a) $commit_sha7
+$(test_oid hash05c) $commit_sha5
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash02c) $commit_sha2
EOF
cat >expect_log_z <<EOF
@@ -306,16 +366,16 @@ test_expect_success 'merge z into y with invalid configuration option => Fail/No
'
cat <<EOF | sort >expect_notes_ours
-68b8630d25516028bed862719855b3d6768d7833 $commit_sha15
-5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14
-3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13
-a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12
-7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-154508c7a0bcad82b6fe4b472bc4c26b3bf0825b $commit_sha5
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
+$(test_oid hash15b) $commit_sha15
+$(test_oid hash14b) $commit_sha14
+$(test_oid hash13b) $commit_sha13
+$(test_oid hash12b) $commit_sha12
+$(test_oid hash11c) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash05b) $commit_sha5
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash02c) $commit_sha2
EOF
cat >expect_log_ours <<EOF
@@ -395,16 +455,16 @@ test_expect_success 'reset to pre-merge state (y)' '
'
cat <<EOF | sort >expect_notes_theirs
-9b4b2c61f0615412da3c10f98ff85b57c04ec765 $commit_sha15
-5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14
-3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13
-7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8
-99fc34adfc400b95c67b013115e37e31aa9a6d23 $commit_sha5
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
+$(test_oid hash15c) $commit_sha15
+$(test_oid hash14b) $commit_sha14
+$(test_oid hash13b) $commit_sha13
+$(test_oid hash11c) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash08c) $commit_sha8
+$(test_oid hash05c) $commit_sha5
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash02c) $commit_sha2
EOF
cat >expect_log_theirs <<EOF
@@ -473,17 +533,17 @@ test_expect_success 'reset to pre-merge state (y)' '
'
cat <<EOF | sort >expect_notes_union
-7c4e546efd0fe939f876beb262ece02797880b54 $commit_sha15
-5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14
-3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13
-a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12
-7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8
-6c841cc36ea496027290967ca96bd2bef54dbb47 $commit_sha5
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
+$(test_oid hash15d) $commit_sha15
+$(test_oid hash14b) $commit_sha14
+$(test_oid hash13b) $commit_sha13
+$(test_oid hash12b) $commit_sha12
+$(test_oid hash11c) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash08c) $commit_sha8
+$(test_oid hash05d) $commit_sha5
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash02c) $commit_sha2
EOF
cat >expect_log_union <<EOF
@@ -574,17 +634,17 @@ test_expect_success 'merge z into y with "manual" per-ref only checks specific r
'
cat <<EOF | sort >expect_notes_union2
-d682107b8bf7a7aea1e537a8d5cb6a12b60135f1 $commit_sha15
-5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14
-3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13
-a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12
-7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8
-357b6ca14c7afd59b7f8b8aaaa6b8b723771135b $commit_sha5
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
+$(test_oid hash15e) $commit_sha15
+$(test_oid hash14b) $commit_sha14
+$(test_oid hash13b) $commit_sha13
+$(test_oid hash12b) $commit_sha12
+$(test_oid hash11c) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash08c) $commit_sha8
+$(test_oid hash05e) $commit_sha5
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash02c) $commit_sha2
EOF
cat >expect_log_union2 <<EOF
@@ -648,17 +708,17 @@ test_expect_success 'reset to pre-merge state (z)' '
'
cat <<EOF | sort >expect_notes_cat_sort_uniq
-6be90240b5f54594203e25d9f2f64b7567175aee $commit_sha15
-5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14
-3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13
-a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12
-7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11
-b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10
-851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8
-660311d7f78dc53db12ac373a43fca7465381a7e $commit_sha5
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
+$(test_oid hash15f) $commit_sha15
+$(test_oid hash14b) $commit_sha14
+$(test_oid hash13b) $commit_sha13
+$(test_oid hash12b) $commit_sha12
+$(test_oid hash11c) $commit_sha11
+$(test_oid hash10a) $commit_sha10
+$(test_oid hash08c) $commit_sha8
+$(test_oid hash05f) $commit_sha5
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash02c) $commit_sha2
EOF
cat >expect_log_cat_sort_uniq <<EOF
diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh
index 2dea846e25..d3d72e25fe 100755
--- a/t/t3310-notes-merge-manual-resolve.sh
+++ b/t/t3310-notes-merge-manual-resolve.sh
@@ -13,7 +13,39 @@ test_expect_success 'setup commits' '
test_commit 2nd &&
test_commit 3rd &&
test_commit 4th &&
- test_commit 5th
+ test_commit 5th &&
+
+ test_oid_cache <<-EOF
+ hash04a sha1:6e8e3febca3c2bb896704335cc4d0c34cb2f8715
+ hash03a sha1:e5388c10860456ee60673025345fe2e153eb8cf8
+ hash02a sha1:ceefa674873670e7ecd131814d909723cce2b669
+ hash04b sha1:e2bfd06a37dd2031684a59a6e2b033e212239c78
+ hash03b sha1:5772f42408c0dd6f097a7ca2d24de0e78d1c46b1
+ hash01b sha1:b0a6021ec006d07e80e9b20ec9b444cbd9d560d3
+ hash04c sha1:cff59c793c20bb49a4e01bc06fb06bad642e0d54
+ hash02c sha1:283b48219aee9a4105f6cab337e789065c82c2b9
+ hash01c sha1:0a81da8956346e19bcb27a906f04af327e03e31b
+ hash04d sha1:00494adecf2d9635a02fa431308d67993f853968
+ hash01e sha1:f75d1df88cbfe4258d49852f26cfc83f2ad4494b
+ hash04f sha1:021faa20e931fb48986ffc6282b4bb05553ac946
+ hash01f sha1:0a59e787e6d688aa6309e56e8c1b89431a0fc1c1
+ hash05g sha1:304dfb4325cf243025b9957486eb605a9b51c199
+
+ hash04a sha256:f18a935e65866345098b3b754071dbf9f3aa3520eb27a7b036b278c5e2f1ed7e
+ hash03a sha256:713035dc94067a64e5fa6e4e1821b7c3bde49a77c7cb3f80eaadefa1ca41b3d2
+ hash02a sha256:f160a67e048b6fa75bec3952184154045076692cf5dccd3da21e3fd34b7a3f0f
+ hash04b sha256:c7fba0d6104917fbf35258f40b9fa4fc697cfa992deecd1570a3b08d0a5587a9
+ hash03b sha256:7287a2d78a3766c181b08df38951d784b08b72a44f571ed6d855bd0be22c70f6
+ hash01b sha256:da96cf778c15d0a2bb76f98b2a62f6c9c01730fa7030e8f08ef0191048e7d620
+ hash04c sha256:cb615d2def4b834d5f55b2351df97dc92bee4f5009d285201427f349081c8aca
+ hash02c sha256:63bb527e0b4e1c8e1dd0d54dd778ca7c3718689fd6e37c473044cfbcf1cacfdb
+ hash01c sha256:5b87237ac1fbae0246256fed9f9a1f077c4140fb7e6444925f8dbfa5ae406cd8
+ hash04d sha256:eeddc9f9f6cb3d6b39b861659853f10891dc373e0b6eecb09e03e39b6ce64714
+ hash01e sha256:108f521b1a74c2e6d0b52a4eda87e09162bf847f7d190cfce496ee1af0b29a5a
+ hash04f sha256:901acda0454502b3bbd281f130c419e6c8de78afcf72a8def8d45ad31462bce4
+ hash01f sha256:a2d99d1b8bf23c8af7d9d91368454adc110dfd5cc068a4cebb486ee8f5a1e16c
+ hash05g sha256:4fef015b01da8efe929a68e3bb9b8fbad81f53995f097befe8ebc93f12ab98ec
+ EOF
'
commit_sha1=$(git rev-parse 1st^{commit})
@@ -32,10 +64,16 @@ verify_notes () {
test_cmp "expect_log_$notes_ref" "output_log_$notes_ref"
}
+notes_merge_files_gone () {
+ # No .git/NOTES_MERGE_* files left
+ { ls .git/NOTES_MERGE_* >output || :; } &&
+ test_must_be_empty output
+}
+
cat <<EOF | sort >expect_notes_x
-6e8e3febca3c2bb896704335cc4d0c34cb2f8715 $commit_sha4
-e5388c10860456ee60673025345fe2e153eb8cf8 $commit_sha3
-ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2
+$(test_oid hash04a) $commit_sha4
+$(test_oid hash03a) $commit_sha3
+$(test_oid hash02a) $commit_sha2
EOF
cat >expect_log_x <<EOF
@@ -63,9 +101,9 @@ test_expect_success 'setup merge base (x)' '
'
cat <<EOF | sort >expect_notes_y
-e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
-b0a6021ec006d07e80e9b20ec9b444cbd9d560d3 $commit_sha1
+$(test_oid hash04b) $commit_sha4
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash01b) $commit_sha1
EOF
cat >expect_log_y <<EOF
@@ -95,9 +133,9 @@ test_expect_success 'setup local branch (y)' '
'
cat <<EOF | sort >expect_notes_z
-cff59c793c20bb49a4e01bc06fb06bad642e0d54 $commit_sha4
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
-0a81da8956346e19bcb27a906f04af327e03e31b $commit_sha1
+$(test_oid hash04c) $commit_sha4
+$(test_oid hash02c) $commit_sha2
+$(test_oid hash01c) $commit_sha1
EOF
cat >expect_log_z <<EOF
@@ -193,9 +231,9 @@ test_expect_success 'merge z into m (== y) with default ("manual") resolver => C
'
cat <<EOF | sort >expect_notes_z
-00494adecf2d9635a02fa431308d67993f853968 $commit_sha4
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
-0a81da8956346e19bcb27a906f04af327e03e31b $commit_sha1
+$(test_oid hash04d) $commit_sha4
+$(test_oid hash02c) $commit_sha2
+$(test_oid hash01c) $commit_sha1
EOF
cat >expect_log_z <<EOF
@@ -231,8 +269,8 @@ test_expect_success 'cannot do merge w/conflicts when previous merge is unfinish
# Setup non-conflicting merge between x and new notes ref w
cat <<EOF | sort >expect_notes_w
-ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2
-f75d1df88cbfe4258d49852f26cfc83f2ad4494b $commit_sha1
+$(test_oid hash02a) $commit_sha2
+$(test_oid hash01e) $commit_sha1
EOF
cat >expect_log_w <<EOF
@@ -258,10 +296,10 @@ test_expect_success 'setup unrelated notes ref (w)' '
'
cat <<EOF | sort >expect_notes_w
-6e8e3febca3c2bb896704335cc4d0c34cb2f8715 $commit_sha4
-e5388c10860456ee60673025345fe2e153eb8cf8 $commit_sha3
-ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2
-f75d1df88cbfe4258d49852f26cfc83f2ad4494b $commit_sha1
+$(test_oid hash04a) $commit_sha4
+$(test_oid hash03a) $commit_sha3
+$(test_oid hash02a) $commit_sha2
+$(test_oid hash01e) $commit_sha1
EOF
cat >expect_log_w <<EOF
@@ -291,10 +329,10 @@ test_expect_success 'can do merge without conflicts even if previous merge is un
'
cat <<EOF | sort >expect_notes_m
-021faa20e931fb48986ffc6282b4bb05553ac946 $commit_sha4
-5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
-0a59e787e6d688aa6309e56e8c1b89431a0fc1c1 $commit_sha1
+$(test_oid hash04f) $commit_sha4
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash02c) $commit_sha2
+$(test_oid hash01f) $commit_sha1
EOF
cat >expect_log_m <<EOF
@@ -335,9 +373,7 @@ EOF
y and z notes on 4th commit
EOF
git notes merge --commit &&
- # No .git/NOTES_MERGE_* files left
- test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
- test_must_be_empty output &&
+ notes_merge_files_gone &&
# Merge commit has pre-merge y and pre-merge z as parents
test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" &&
test "$(git rev-parse refs/notes/m^2)" = "$(cat pre_merge_z)" &&
@@ -397,9 +433,7 @@ test_expect_success 'redo merge of z into m (== y) with default ("manual") resol
test_expect_success 'abort notes merge' '
git notes merge --abort &&
- # No .git/NOTES_MERGE_* files left
- test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
- test_must_be_empty output &&
+ notes_merge_files_gone &&
# m has not moved (still == y)
test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" &&
# Verify that other notes refs has not changed (w, x, y and z)
@@ -430,9 +464,9 @@ test_expect_success 'redo merge of z into m (== y) with default ("manual") resol
'
cat <<EOF | sort >expect_notes_m
-304dfb4325cf243025b9957486eb605a9b51c199 $commit_sha5
-283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2
-0a59e787e6d688aa6309e56e8c1b89431a0fc1c1 $commit_sha1
+$(test_oid hash05g) $commit_sha5
+$(test_oid hash02c) $commit_sha2
+$(test_oid hash01f) $commit_sha1
EOF
cat >expect_log_m <<EOF
@@ -464,9 +498,7 @@ EOF
echo "new note on 5th commit" > .git/NOTES_MERGE_WORKTREE/$commit_sha5 &&
# Finalize merge
git notes merge --commit &&
- # No .git/NOTES_MERGE_* files left
- test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
- test_must_be_empty output &&
+ notes_merge_files_gone &&
# Merge commit has pre-merge y and pre-merge z as parents
test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" &&
test "$(git rev-parse refs/notes/m^2)" = "$(cat pre_merge_z)" &&
@@ -553,9 +585,7 @@ EOF
test_expect_success 'resolve situation by aborting the notes merge' '
git notes merge --abort &&
- # No .git/NOTES_MERGE_* files left
- test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
- test_must_be_empty output &&
+ notes_merge_files_gone &&
# m has not moved (still == w)
test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" &&
# Verify that other notes refs has not changed (w, x, y and z)
diff --git a/t/t3311-notes-merge-fanout.sh b/t/t3311-notes-merge-fanout.sh
index 37151a3adc..5b675417e9 100755
--- a/t/t3311-notes-merge-fanout.sh
+++ b/t/t3311-notes-merge-fanout.sh
@@ -29,15 +29,10 @@ verify_fanout () {
git ls-tree -r --name-only "refs/notes/$notes_ref" |
while read path
do
- case "$path" in
- ??/??????????????????????????????????????)
- : true
- ;;
- *)
+ echo "$path" | grep "^../[0-9a-f]*$" || {
echo "Invalid path \"$path\"" &&
- return 1
- ;;
- esac
+ return 1;
+ }
done
}
@@ -48,15 +43,10 @@ verify_no_fanout () {
git ls-tree -r --name-only "refs/notes/$notes_ref" |
while read path
do
- case "$path" in
- ????????????????????????????????????????)
- : true
- ;;
- *)
+ echo "$path" | grep -v "^../.*" || {
echo "Invalid path \"$path\"" &&
- return 1
- ;;
- esac
+ return 1;
+ }
done
}
@@ -67,7 +57,27 @@ test_expect_success 'setup a few initial commits with notes (notes ref: x)' '
do
test_commit "commit$i" >/dev/null &&
git notes add -m "notes for commit$i" || return 1
- done
+ done &&
+
+ git log --format=oneline &&
+
+ test_oid_cache <<-EOF
+ hash05a sha1:aed91155c7a72c2188e781fdf40e0f3761b299db
+ hash04a sha1:99fab268f9d7ee7b011e091a436c78def8eeee69
+ hash03a sha1:953c20ae26c7aa0b428c20693fe38bc687f9d1a9
+ hash02a sha1:6358796131b8916eaa2dde6902642942a1cb37e1
+ hash01a sha1:b02d459c32f0e68f2fe0981033bb34f38776ba47
+ hash03b sha1:9f506ee70e20379d7f78204c77b334f43d77410d
+ hash02b sha1:23a47d6ea7d589895faf800752054818e1e7627b
+
+ hash05a sha256:3aae5d26619d96dba93795f66325716e4cbc486884f95a6adee8fb0615a76d12
+ hash04a sha256:07e43dd3d89fe634d3252e253b426aacc7285a995dcdbcf94ac284060a1122cf
+ hash03a sha256:26fb52eaa7f4866bf735254587be7b31209ec10e525912ffd8e8ba549ba892ff
+ hash02a sha256:b57ebdf23634e750dcbc4b9a37991d70f90830d568a0e4529ce9de0a3f8d605c
+ hash01a sha256:377903b1572bd5117087a5518fcb1011b5053cccbc59e3c7c823a8615204173b
+ hash03b sha256:04e7b392fda7c185bfa17c9179b56db732edc2dc2b3bf887308dcaabb717270d
+ hash02b sha256:66099aaaec49a485ed990acadd9a9b81232ea592079964113d8f581ff69ef50b
+ EOF
'
commit_sha1=$(git rev-parse commit1^{commit})
@@ -77,11 +87,11 @@ commit_sha4=$(git rev-parse commit4^{commit})
commit_sha5=$(git rev-parse commit5^{commit})
cat <<EOF | sort >expect_notes_x
-aed91155c7a72c2188e781fdf40e0f3761b299db $commit_sha5
-99fab268f9d7ee7b011e091a436c78def8eeee69 $commit_sha4
-953c20ae26c7aa0b428c20693fe38bc687f9d1a9 $commit_sha3
-6358796131b8916eaa2dde6902642942a1cb37e1 $commit_sha2
-b02d459c32f0e68f2fe0981033bb34f38776ba47 $commit_sha1
+$(test_oid hash05a) $commit_sha5
+$(test_oid hash04a) $commit_sha4
+$(test_oid hash03a) $commit_sha3
+$(test_oid hash02a) $commit_sha2
+$(test_oid hash01a) $commit_sha1
EOF
cat >expect_log_x <<EOF
@@ -145,9 +155,9 @@ test_expect_success 'Fast-forward merge (y => x)' '
'
cat <<EOF | sort >expect_notes_z
-9f506ee70e20379d7f78204c77b334f43d77410d $commit_sha3
-23a47d6ea7d589895faf800752054818e1e7627b $commit_sha2
-b02d459c32f0e68f2fe0981033bb34f38776ba47 $commit_sha1
+$(test_oid hash03b) $commit_sha3
+$(test_oid hash02b) $commit_sha2
+$(test_oid hash01a) $commit_sha1
EOF
cat >expect_log_z <<EOF
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index ab18ac5f28..40d2975995 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' '
@@ -143,11 +143,11 @@ test_expect_success 'setup: recover' '
test_expect_success 'Show verbose error when HEAD could not be detached' '
>B &&
+ test_when_finished "rm -f B" &&
test_must_fail git rebase topic 2>output.err >output.out &&
test_i18ngrep "The following untracked working tree files would be overwritten by checkout:" output.err &&
test_i18ngrep B output.err
'
-rm -f B
test_expect_success 'fail when upstream arg is missing and not on branch' '
git checkout topic &&
@@ -159,19 +159,43 @@ test_expect_success 'fail when upstream arg is missing and not configured' '
test_must_fail git rebase
'
-test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' '
+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 (--merge)' '
git checkout -b default-base master &&
git checkout -b default topic &&
git config branch.default.remote . &&
git config branch.default.merge refs/heads/default-base &&
- git rebase &&
+ git rebase --merge &&
git rev-parse --verify default-base >expect &&
git rev-parse default~1 >actual &&
test_cmp expect actual &&
git checkout default-base &&
git reset --hard HEAD^ &&
git checkout default &&
- git rebase &&
+ git rebase --merge &&
+ git rev-parse --verify default-base >expect &&
+ git rev-parse default~1 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg (--apply)' '
+ git checkout -B default-base master &&
+ git checkout -B default topic &&
+ git config branch.default.remote . &&
+ git config branch.default.merge refs/heads/default-base &&
+ git rebase --apply &&
+ git rev-parse --verify default-base >expect &&
+ git rev-parse default~1 >actual &&
+ test_cmp expect actual &&
+ git checkout default-base &&
+ git reset --hard HEAD^ &&
+ git checkout default &&
+ git rebase --apply &&
git rev-parse --verify default-base >expect &&
git rev-parse default~1 >actual &&
test_cmp expect actual
@@ -200,9 +224,15 @@ test_expect_success 'cherry-picked commits and fork-point work together' '
test_cmp expect D
'
-test_expect_success 'rebase -q is quiet' '
+test_expect_success 'rebase --apply -q is quiet' '
git checkout -b quiet topic &&
- git rebase -q master >output.out 2>&1 &&
+ git rebase --apply -q master >output.out 2>&1 &&
+ test_must_be_empty output.out
+'
+
+test_expect_success 'rebase --merge -q is quiet' '
+ git checkout -B quiet topic &&
+ git rebase --merge -q master >output.out 2>&1 &&
test_must_be_empty output.out
'
@@ -285,7 +315,7 @@ EOF
test_cmp From_.msg out
'
-test_expect_success 'rebase --am and --show-current-patch' '
+test_expect_success 'rebase --apply and --show-current-patch' '
test_create_repo conflict-apply &&
(
cd conflict-apply &&
@@ -295,13 +325,13 @@ 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 -f --onto init HEAD^ &&
+ test_must_fail git rebase --apply -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_expect_success 'rebase --apply and .gitattributes' '
test_create_repo attributes &&
(
cd attributes &&
@@ -371,4 +401,22 @@ test_expect_success 'rebase -c rebase.useBuiltin=false warning' '
test_must_be_empty err
'
+test_expect_success 'switch to branch checked out here' '
+ git checkout master &&
+ git rebase master master
+'
+
+test_expect_success 'switch to branch not checked out' '
+ git checkout master &&
+ git branch other &&
+ git rebase master other
+'
+
+test_expect_success 'refuse to switch to branch checked out elsewhere' '
+ git checkout master &&
+ git worktree add wt &&
+ test_must_fail git -C wt rebase master master 2>err &&
+ test_i18ngrep "already checked out" err
+'
+
test_done
diff --git a/t/t3401-rebase-and-am-rename.sh b/t/t3401-rebase-and-am-rename.sh
index a0b9438b22..f18bae9450 100755
--- a/t/t3401-rebase-and-am-rename.sh
+++ b/t/t3401-rebase-and-am-rename.sh
@@ -52,13 +52,13 @@ test_expect_success 'rebase --interactive: directory rename detected' '
)
'
-test_expect_failure 'rebase (am): directory rename detected' '
+test_expect_failure 'rebase --apply: directory rename detected' '
(
cd dir-rename &&
git checkout B^0 &&
- git -c merge.directoryRenames=true rebase A &&
+ git -c merge.directoryRenames=true rebase --apply A &&
git ls-files -s >out &&
test_line_count = 5 out &&
diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh
index 1f5122b632..a927774910 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,20 @@ 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 goodbye &&
+ test_tick &&
+ GIT_AUTHOR_NAME="Another Author" \
+ GIT_AUTHOR_EMAIL="another.author@example.com" \
+ git commit --amend --no-edit -m amended-goodbye &&
+ test_tick &&
+ git tag amended-goodbye &&
git checkout -f skip-reference &&
echo moo > hello &&
@@ -76,4 +92,99 @@ test_expect_success 'moved back to branch correctly' '
test_debug 'gitk --all & sleep 1'
+test_expect_success 'correct advice upon picking empty commit' '
+ test_when_finished "git rebase --abort" &&
+ test_must_fail git rebase -i --onto goodbye \
+ amended-goodbye^ amended-goodbye 2>err &&
+ test_i18ngrep "previous cherry-pick is now empty" err &&
+ test_i18ngrep "git rebase --skip" err &&
+ test_must_fail git commit &&
+ test_i18ngrep "git rebase --skip" err
+'
+
+test_expect_success 'correct authorship when committing empty pick' '
+ test_when_finished "git rebase --abort" &&
+ test_must_fail git rebase -i --onto goodbye \
+ amended-goodbye^ amended-goodbye &&
+ git commit --allow-empty &&
+ git log --pretty=format:"%an <%ae>%n%ad%B" -1 amended-goodbye >expect &&
+ git log --pretty=format:"%an <%ae>%n%ad%B" -1 HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'correct advice upon rewording empty commit' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="reword 1" git rebase -i \
+ --onto goodbye amended-goodbye^ amended-goodbye 2>err
+ ) &&
+ test_i18ngrep "previous cherry-pick is now empty" err &&
+ test_i18ngrep "git rebase --skip" err &&
+ test_must_fail git commit &&
+ test_i18ngrep "git rebase --skip" err
+'
+
+test_expect_success 'correct advice upon editing empty commit' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="edit 1" git rebase -i \
+ --onto goodbye amended-goodbye^ amended-goodbye 2>err
+ ) &&
+ test_i18ngrep "previous cherry-pick is now empty" err &&
+ test_i18ngrep "git rebase --skip" err &&
+ test_must_fail git commit &&
+ test_i18ngrep "git rebase --skip" err
+'
+
+test_expect_success 'correct advice upon cherry-picking an empty commit during a rebase' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 exec_git_cherry-pick_amended-goodbye" \
+ git rebase -i goodbye^ goodbye 2>err
+ ) &&
+ test_i18ngrep "previous cherry-pick is now empty" err &&
+ test_i18ngrep "git cherry-pick --skip" err &&
+ test_must_fail git commit 2>err &&
+ test_i18ngrep "git cherry-pick --skip" err
+'
+
+test_expect_success 'correct advice upon multi cherry-pick picking an empty commit during a rebase' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 exec_git_cherry-pick_goodbye_amended-goodbye" \
+ git rebase -i goodbye^^ goodbye 2>err
+ ) &&
+ test_i18ngrep "previous cherry-pick is now empty" err &&
+ test_i18ngrep "git cherry-pick --skip" err &&
+ test_must_fail git commit 2>err &&
+ test_i18ngrep "git cherry-pick --skip" err
+'
+
+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 d2dfbe46b9..4a7d21f898 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -72,12 +72,16 @@ test_expect_success 'rebase --keep-empty' '
test_line_count = 6 actual
'
-test_expect_success 'rebase -i with empty HEAD' '
+test_expect_success 'rebase -i with empty todo list' '
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="#" \
+ git rebase -i HEAD^ >output 2>&1
+ ) &&
+ tail -n 1 output >actual && # Ignore output about changing todo list
test_i18ncmp expect actual
'
@@ -136,8 +140,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
@@ -163,9 +170,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
'
@@ -176,57 +185,55 @@ 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)
+ test_cmp_rev I HEAD
'
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) &&
- test $(git rev-parse I) = $(git rev-parse HEAD)
+ test_cmp_rev I branch2 &&
+ test_cmp_rev I HEAD
'
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) &&
- test $(git rev-parse I) = $(git rev-parse branch2)
+ test_cmp_rev HEAD^ branch1 &&
+ test_cmp_rev I branch2
'
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" &&
- test $(git rev-parse I) = $(git rev-parse branch2) &&
- test $(git rev-parse I) = $(git rev-parse HEAD~2)
+ test_cmp_rev I branch2 &&
+ test_cmp_rev I HEAD~2
'
test_expect_success 'reflog for the branch shows state before rebase' '
- test $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1)
+ test_cmp_rev branch1@{1} original-branch1
'
test_expect_success 'reflog for the branch shows correct finish message' '
- printf "rebase -i (finish): refs/heads/branch1 onto %s\n" \
+ printf "rebase (finish): refs/heads/branch1 onto %s\n" \
"$(git rev-parse branch2)" >expected &&
git log -g --pretty=%gs -1 refs/heads/branch1 >actual &&
test_cmp expected actual
'
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) &&
blob1=$(git rev-parse --short HEAD^:file1) &&
@@ -252,7 +259,6 @@ test_expect_success 'stop on conflicting pick' '
>>>>>>> $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 &&
@@ -273,7 +279,7 @@ test_expect_success 'show conflicted patch' '
test_expect_success 'abort' '
git rebase --abort &&
- test $(git rev-parse new-branch1) = $(git rev-parse HEAD) &&
+ test_cmp_rev new-branch1 HEAD &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" &&
test_path_is_missing .git/rebase-merge
'
@@ -281,7 +287,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 &&
@@ -296,7 +301,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"
'
@@ -314,12 +318,11 @@ 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 &&
git rebase --continue &&
- test $(git rev-parse conflict-a^0) = $(git rev-parse HEAD^) &&
+ test_cmp_rev conflict-a^0 HEAD^ &&
git show >out &&
grep AttributeMe out
'
@@ -330,11 +333,13 @@ 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)
+ test_cmp_rev HEAD^ master
'
test_expect_success 'retain authorship when squashing' '
@@ -343,7 +348,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 &&
@@ -353,8 +357,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)
'
@@ -388,14 +394,13 @@ 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 &&
git diff-index --quiet --cached HEAD -- &&
- test $(git rev-parse HEAD~6) = $(git rev-parse branch1) &&
- test $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) &&
- test $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) &&
+ test_cmp_rev HEAD~6 branch1 &&
+ test_cmp_rev HEAD~4^2 to-be-preserved &&
+ test_cmp_rev HEAD^^2^ HEAD^^^ &&
test $(git show HEAD~5:file1) = B &&
test $(git show HEAD~3:file1) = C &&
test $(git show HEAD:file1) = E &&
@@ -403,8 +408,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 &&
@@ -418,19 +425,20 @@ 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 &&
- test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&
+ (
+ 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_cmp_rev HEAD^ new-branch1 &&
git show HEAD | grep chouette
'
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 &&
@@ -440,10 +448,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)
'
@@ -451,9 +462,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} &&
@@ -463,12 +477,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} &&
@@ -478,12 +495,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} &&
@@ -500,10 +520,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} |
@@ -517,10 +540,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} &&
@@ -530,10 +556,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} &&
@@ -543,17 +572,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 &&
@@ -566,8 +599,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 &&
@@ -587,11 +623,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^)
@@ -600,34 +638,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 &&
@@ -638,8 +683,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)
'
@@ -654,9 +701,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' '
@@ -676,8 +724,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"
'
@@ -688,9 +738,8 @@ 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)
+ test_cmp_rev branch3 branch4
'
@@ -713,13 +762,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' '
@@ -736,7 +786,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 &&
@@ -746,11 +795,10 @@ 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 &&
- test $(git rev-parse submodule-base) = $(git rev-parse HEAD)
+ test_cmp_rev submodule-base HEAD
'
test_expect_success 'avoid unnecessary reset' '
@@ -759,7 +807,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) &&
@@ -768,16 +815,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_cmp_rev master^ 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"
'
@@ -788,7 +841,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)"
'
@@ -801,8 +853,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
'
@@ -811,8 +866,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
'
@@ -821,7 +878,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
@@ -829,7 +885,7 @@ test_expect_success 'always cherry-pick with --no-ff' '
git diff HEAD~$p original-no-ff-branch~$p > out &&
test_must_be_empty out
done &&
- test $(git rev-parse HEAD~3) = $(git rev-parse original-no-ff-branch~3) &&
+ test_cmp_rev HEAD~3 original-no-ff-branch~3 &&
git diff HEAD~3 original-no-ff-branch~3 > out &&
test_must_be_empty out
'
@@ -853,8 +909,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
'
@@ -868,9 +926,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
@@ -881,9 +939,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
@@ -894,9 +952,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
@@ -908,9 +966,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
@@ -921,9 +979,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 &&
@@ -942,13 +1000,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 &&
@@ -969,7 +1025,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
@@ -977,8 +1032,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) &&
@@ -991,24 +1048,30 @@ 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 &&
+ (
+ 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\ )
@@ -1017,9 +1080,11 @@ test_expect_success 'rebase -i --root fixup 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-original-root-branch master &&
- set_fake_editor &&
- FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
- git rebase -i --root &&
+ (
+ 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^)"
'
@@ -1027,9 +1092,11 @@ test_expect_success 'rebase -i --root reword original root commit' '
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 &&
+ (
+ 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^)"
'
@@ -1041,8 +1108,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" &&
@@ -1052,11 +1121,13 @@ 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
'
@@ -1065,19 +1136,23 @@ test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-int
git checkout reword-original-root-branch &&
git reset --hard &&
git checkout conflict-branch &&
- set_fake_editor &&
- test_must_fail git rebase -f --onto HEAD~2 HEAD~ &&
- test_must_fail git rebase --edit-todo &&
+ (
+ set_fake_editor &&
+ test_must_fail git rebase -f --apply --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)
'
@@ -1085,13 +1160,12 @@ 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
- rebase -i (pick): H
- rebase -i (pick): G
- rebase -i (start): checkout I
+ rebase (finish): returning to refs/heads/branch-reflog-test
+ rebase (pick): H
+ rebase (pick): G
+ rebase (start): checkout I
EOF
git reflog -n4 HEAD |
sed "s/[^:]*: //" >actual &&
@@ -1106,8 +1180,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)
'
@@ -1116,9 +1192,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)"
'
@@ -1153,8 +1231,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
@@ -1184,19 +1265,34 @@ test_expect_success SHA1 'short SHA-1 setup' '
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)
'
@@ -1204,16 +1300,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 &&
@@ -1228,8 +1328,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 &&
@@ -1244,8 +1346,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 &&
@@ -1268,8 +1372,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 &&
@@ -1288,8 +1394,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)
@@ -1298,9 +1406,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" \
@@ -1316,9 +1425,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)
@@ -1340,19 +1450,141 @@ 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)
'
+test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = ignore' '
+ test_config rebase.missingCommitsCheck ignore &&
+ rebase_setup_and_clean missing-commit &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="break 1 2 3 4 5" git rebase -i --root &&
+ FAKE_LINES="1 2 3 4" git rebase --edit-todo &&
+ git rebase --continue 2>actual
+ ) &&
+ test D = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test_i18ngrep \
+ "Successfully rebased and updated refs/heads/missing-commit" \
+ actual
+'
+
+test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = warn' '
+ cat >expect <<-EOF &&
+ error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 master~4)
+ Warning: some commits may have been dropped accidentally.
+ Dropped commits (newer to older):
+ - $(git rev-list --pretty=oneline --abbrev-commit -1 master)
+ - $(git rev-list --pretty=oneline --abbrev-commit -1 master~4)
+ To avoid this message, use "drop" to explicitly remove a commit.
+ EOF
+ head -n4 expect >expect.2 &&
+ tail -n1 expect >>expect.2 &&
+ tail -n4 expect.2 >expect.3 &&
+ test_config rebase.missingCommitsCheck warn &&
+ rebase_setup_and_clean missing-commit &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="bad 1 2 3 4 5" \
+ git rebase -i --root &&
+ cp .git/rebase-merge/git-rebase-todo.backup orig &&
+ FAKE_LINES="2 3 4" git rebase --edit-todo 2>actual.2 &&
+ head -n6 actual.2 >actual &&
+ test_i18ncmp expect actual &&
+ cp orig .git/rebase-merge/git-rebase-todo &&
+ FAKE_LINES="1 2 3 4" git rebase --edit-todo 2>actual.2 &&
+ head -n4 actual.2 >actual &&
+ test_i18ncmp expect.3 actual &&
+ git rebase --continue 2>actual
+ ) &&
+ test D = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test_i18ngrep \
+ "Successfully rebased and updated refs/heads/missing-commit" \
+ actual
+'
+
+test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = error' '
+ cat >expect <<-EOF &&
+ error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 master~4)
+ Warning: some commits may have been dropped accidentally.
+ Dropped commits (newer to older):
+ - $(git rev-list --pretty=oneline --abbrev-commit -1 master)
+ - $(git rev-list --pretty=oneline --abbrev-commit -1 master~4)
+ To avoid this message, use "drop" to explicitly remove a commit.
+
+ Use '\''git config rebase.missingCommitsCheck'\'' to change the level of warnings.
+ The possible behaviours are: ignore, warn, error.
+
+ You can fix this with '\''git rebase --edit-todo'\'' and then run '\''git rebase --continue'\''.
+ Or you can abort the rebase with '\''git rebase --abort'\''.
+ EOF
+ tail -n11 expect >expect.2 &&
+ head -n3 expect.2 >expect.3 &&
+ tail -n7 expect.2 >>expect.3 &&
+ test_config rebase.missingCommitsCheck error &&
+ rebase_setup_and_clean missing-commit &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="bad 1 2 3 4 5" \
+ git rebase -i --root &&
+ cp .git/rebase-merge/git-rebase-todo.backup orig &&
+ test_must_fail env FAKE_LINES="2 3 4" \
+ git rebase --edit-todo 2>actual &&
+ test_i18ncmp expect actual &&
+ test_must_fail git rebase --continue 2>actual &&
+ test_i18ncmp expect.2 actual &&
+ test_must_fail git rebase --edit-todo &&
+ cp orig .git/rebase-merge/git-rebase-todo &&
+ test_must_fail env FAKE_LINES="1 2 3 4" \
+ git rebase --edit-todo 2>actual &&
+ test_i18ncmp expect.3 actual &&
+ test_must_fail git rebase --continue 2>actual &&
+ test_i18ncmp expect.3 actual &&
+ cp orig .git/rebase-merge/git-rebase-todo &&
+ FAKE_LINES="1 2 3 4 drop 5" git rebase --edit-todo &&
+ git rebase --continue 2>actual
+ ) &&
+ test D = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test_i18ngrep \
+ "Successfully rebased and updated refs/heads/missing-commit" \
+ actual
+'
+
+test_expect_success 'rebase.missingCommitsCheck = error after resolving conflicts' '
+ test_config rebase.missingCommitsCheck error &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="drop 1 break 2 3 4" git rebase -i A E
+ ) &&
+ git rebase --edit-todo &&
+ test_must_fail git rebase --continue &&
+ echo x >file1 &&
+ git add file1 &&
+ git rebase --continue
+'
+
+test_expect_success 'rebase.missingCommitsCheck = error when editing for a second time' '
+ test_config rebase.missingCommitsCheck error &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 break 2 3" git rebase -i A D &&
+ cp .git/rebase-merge/git-rebase-todo todo &&
+ test_must_fail env FAKE_LINES=2 git rebase --edit-todo &&
+ GIT_SEQUENCE_EDITOR="cp todo" git rebase --edit-todo &&
+ git rebase --continue
+ )
+'
+
test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and exec' '
rebase_setup_and_clean abbrevcmd &&
test_commit "first" file1.txt "first line" first &&
@@ -1368,21 +1600,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)
@@ -1398,19 +1636,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)
'
@@ -1429,39 +1672,97 @@ test_expect_success 'editor saves as CR/LF' '
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
+'
+
+test_expect_success 'correct error message for partial commit after empty pick' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1 1" &&
+ export FAKE_LINES &&
+ test_must_fail git rebase -i A D
+ ) &&
+ echo x >file1 &&
+ test_must_fail git commit file1 2>err &&
+ test_i18ngrep "cannot do a partial commit during a rebase." err
+'
+
+test_expect_success 'correct error message for commit --amend after empty pick' '
+ test_when_finished "git rebase --abort" &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 1" &&
+ export FAKE_LINES &&
+ test_must_fail git rebase -i A D
+ ) &&
+ echo x>file1 &&
+ test_must_fail git commit -a --amend 2>err &&
+ test_i18ngrep "middle of a rebase -- cannot amend." err
+'
+
+# 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/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index b393e1e9fe..61b76f3301 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -18,32 +18,29 @@ test_expect_success 'setup' '
'
test_expect_success 'rebase -m' '
- git rebase -m master >report &&
- >expect &&
- sed -n -e "/^Already applied: /p" \
- -e "/^Committed: /p" report >actual &&
- test_cmp expect actual
+ git rebase -m master >actual &&
+ test_must_be_empty actual
'
test_expect_success 'rebase against master twice' '
- git rebase master >out &&
+ git rebase --apply master >out &&
test_i18ngrep "Current branch topic is up to date" out
'
test_expect_success 'rebase against master twice with --force' '
- git rebase --force-rebase master >out &&
+ git rebase --force-rebase --apply master >out &&
test_i18ngrep "Current branch topic is up to date, rebase forced" out
'
test_expect_success 'rebase against master twice from another branch' '
git checkout topic^ &&
- git rebase master topic >out &&
+ git rebase --apply master topic >out &&
test_i18ngrep "Current branch topic is up to date" out
'
test_expect_success 'rebase fast-forward to master' '
git checkout topic^ &&
- git rebase topic >out &&
+ git rebase --apply topic >out &&
test_i18ngrep "Fast-forwarded HEAD to topic" out
'
@@ -92,7 +89,7 @@ test_expect_success 'GIT_REFLOG_ACTION' '
git checkout -b reflog-topic start &&
test_commit reflog-to-rebase &&
- git rebase reflog-onto &&
+ git rebase --apply reflog-onto &&
git log -g --format=%gs -3 >actual &&
cat >expect <<-\EOF &&
rebase finished: returning to refs/heads/reflog-topic
@@ -102,7 +99,7 @@ test_expect_success 'GIT_REFLOG_ACTION' '
test_cmp expect actual &&
git checkout -b reflog-prefix reflog-to-rebase &&
- GIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&
+ GIT_REFLOG_ACTION=change-the-reflog git rebase --apply reflog-onto &&
git log -g --format=%gs -3 >actual &&
cat >expect <<-\EOF &&
rebase finished: returning to refs/heads/reflog-prefix
diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh
index 910f218284..97efea0f56 100755
--- a/t/t3407-rebase-abort.sh
+++ b/t/t3407-rebase-abort.sh
@@ -96,14 +96,14 @@ testrebase() {
'
}
-testrebase "" .git/rebase-apply
+testrebase " --apply" .git/rebase-apply
testrebase " --merge" .git/rebase-merge
-test_expect_success 'rebase --quit' '
+test_expect_success 'rebase --apply --quit' '
cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
- test_must_fail git rebase master &&
+ test_must_fail git rebase --apply master &&
test_path_is_dir .git/rebase-apply &&
head_before=$(git rev-parse HEAD) &&
git rebase --quit &&
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 22d218698e..093de9005b 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -25,6 +25,13 @@ test_expect_success setup '
'
test_auto_fixup () {
+ no_squash= &&
+ if test "x$1" = 'x!'
+ then
+ no_squash=true
+ shift
+ fi &&
+
git reset --hard base &&
echo 1 >file1 &&
git add -u &&
@@ -35,10 +42,19 @@ test_auto_fixup () {
test_tick &&
git rebase $2 -i HEAD^^^ &&
git log --oneline >actual &&
- test_line_count = 3 actual &&
- git diff --exit-code $1 &&
- test 1 = "$(git cat-file blob HEAD^:file1)" &&
- test 1 = $(git cat-file commit HEAD^ | grep first | wc -l)
+ if test -n "$no_squash"
+ then
+ test_line_count = 4 actual
+ else
+ test_line_count = 3 actual &&
+ git diff --exit-code $1 &&
+ echo 1 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep first commit >actual &&
+ test_line_count = 1 actual
+ fi
}
test_expect_success 'auto fixup (option)' '
@@ -48,12 +64,19 @@ test_expect_success 'auto fixup (option)' '
test_expect_success 'auto fixup (config)' '
git config rebase.autosquash true &&
test_auto_fixup final-fixup-config-true &&
- test_must_fail test_auto_fixup fixup-config-true-no --no-autosquash &&
+ test_auto_fixup ! fixup-config-true-no --no-autosquash &&
git config rebase.autosquash false &&
- test_must_fail test_auto_fixup final-fixup-config-false
+ test_auto_fixup ! final-fixup-config-false
'
test_auto_squash () {
+ no_squash= &&
+ if test "x$1" = 'x!'
+ then
+ no_squash=true
+ shift
+ fi &&
+
git reset --hard base &&
echo 1 >file1 &&
git add -u &&
@@ -64,10 +87,19 @@ test_auto_squash () {
test_tick &&
git rebase $2 -i HEAD^^^ &&
git log --oneline >actual &&
- test_line_count = 3 actual &&
- git diff --exit-code $1 &&
- test 1 = "$(git cat-file blob HEAD^:file1)" &&
- test 2 = $(git cat-file commit HEAD^ | grep first | wc -l)
+ if test -n "$no_squash"
+ then
+ test_line_count = 4 actual
+ else
+ test_line_count = 3 actual &&
+ git diff --exit-code $1 &&
+ echo 1 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep first commit >actual &&
+ test_line_count = 2 actual
+ fi
}
test_expect_success 'auto squash (option)' '
@@ -77,9 +109,9 @@ test_expect_success 'auto squash (option)' '
test_expect_success 'auto squash (config)' '
git config rebase.autosquash true &&
test_auto_squash final-squash-config-true &&
- test_must_fail test_auto_squash squash-config-true-no --no-autosquash &&
+ test_auto_squash ! squash-config-true-no --no-autosquash &&
git config rebase.autosquash false &&
- test_must_fail test_auto_squash final-squash-config-false
+ test_auto_squash ! final-squash-config-false
'
test_expect_success 'misspelled auto squash' '
@@ -94,7 +126,8 @@ test_expect_success 'misspelled auto squash' '
git log --oneline >actual &&
test_line_count = 4 actual &&
git diff --exit-code final-missquash &&
- test 0 = $(git rev-list final-missquash...HEAD | wc -l)
+ git rev-list final-missquash...HEAD >list &&
+ test_must_be_empty list
'
test_expect_success 'auto squash that matches 2 commits' '
@@ -113,9 +146,15 @@ test_expect_success 'auto squash that matches 2 commits' '
git log --oneline >actual &&
test_line_count = 4 actual &&
git diff --exit-code final-multisquash &&
- test 1 = "$(git cat-file blob HEAD^^:file1)" &&
- test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) &&
- test 1 = $(git cat-file commit HEAD | grep first | wc -l)
+ echo 1 >expect &&
+ git cat-file blob HEAD^^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^^ >commit &&
+ grep first commit >actual &&
+ test_line_count = 2 actual &&
+ git cat-file commit HEAD >commit &&
+ grep first commit >actual &&
+ test_line_count = 1 actual
'
test_expect_success 'auto squash that matches a commit after the squash' '
@@ -134,25 +173,38 @@ test_expect_success 'auto squash that matches a commit after the squash' '
git log --oneline >actual &&
test_line_count = 5 actual &&
git diff --exit-code final-presquash &&
- test 0 = "$(git cat-file blob HEAD^^:file1)" &&
- test 1 = "$(git cat-file blob HEAD^:file1)" &&
- test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
- test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
+ echo 0 >expect &&
+ git cat-file blob HEAD^^:file1 >actual &&
+ test_cmp expect actual &&
+ echo 1 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD >commit &&
+ grep third commit >actual &&
+ test_line_count = 1 actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep third commit >actual &&
+ test_line_count = 1 actual
'
test_expect_success 'auto squash that matches a sha1' '
git reset --hard base &&
echo 1 >file1 &&
git add -u &&
test_tick &&
- git commit -m "squash! $(git rev-parse --short HEAD^)" &&
+ oid=$(git rev-parse --short HEAD^) &&
+ git commit -m "squash! $oid" &&
git tag final-shasquash &&
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
test_line_count = 3 actual &&
git diff --exit-code final-shasquash &&
- test 1 = "$(git cat-file blob HEAD^:file1)" &&
- test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+ echo 1 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep squash commit >actual &&
+ test_line_count = 1 actual
'
test_expect_success 'auto squash that matches longer sha1' '
@@ -160,15 +212,20 @@ test_expect_success 'auto squash that matches longer sha1' '
echo 1 >file1 &&
git add -u &&
test_tick &&
- git commit -m "squash! $(git rev-parse --short=11 HEAD^)" &&
+ oid=$(git rev-parse --short=11 HEAD^) &&
+ git commit -m "squash! $oid" &&
git tag final-longshasquash &&
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
test_line_count = 3 actual &&
git diff --exit-code final-longshasquash &&
- test 1 = "$(git cat-file blob HEAD^:file1)" &&
- test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+ echo 1 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep squash commit >actual &&
+ test_line_count = 1 actual
'
test_auto_commit_flags () {
@@ -183,8 +240,12 @@ test_auto_commit_flags () {
git log --oneline >actual &&
test_line_count = 3 actual &&
git diff --exit-code final-commit-$1 &&
- test 1 = "$(git cat-file blob HEAD^:file1)" &&
- test $2 = $(git cat-file commit HEAD^ | grep first | wc -l)
+ echo 1 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep first commit >actual &&
+ test_line_count = $2 actual
}
test_expect_success 'use commit --fixup' '
@@ -210,11 +271,15 @@ test_auto_fixup_fixup () {
(
set_cat_todo_editor &&
test_must_fail git rebase --autosquash -i HEAD^^^^ >actual &&
+ head=$(git rev-parse --short HEAD) &&
+ parent1=$(git rev-parse --short HEAD^) &&
+ parent2=$(git rev-parse --short HEAD^^) &&
+ parent3=$(git rev-parse --short HEAD^^^) &&
cat >expected <<-EOF &&
- pick $(git rev-parse --short HEAD^^^) first commit
- $1 $(git rev-parse --short HEAD^) $1! first
- $1 $(git rev-parse --short HEAD) $1! $2! first
- pick $(git rev-parse --short HEAD^^) second commit
+ pick $parent3 first commit
+ $1 $parent1 $1! first
+ $1 $head $1! $2! first
+ pick $parent2 second commit
EOF
test_cmp expected actual
) &&
@@ -222,13 +287,17 @@ test_auto_fixup_fixup () {
git log --oneline >actual &&
test_line_count = 3 actual
git diff --exit-code "final-$1-$2" &&
- test 2 = "$(git cat-file blob HEAD^:file1)" &&
+ echo 2 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep first commit >actual &&
if test "$1" = "fixup"
then
- test 1 = $(git cat-file commit HEAD^ | grep first | wc -l)
+ test_line_count = 1 actual
elif test "$1" = "squash"
then
- test 3 = $(git cat-file commit HEAD^ | grep first | wc -l)
+ test_line_count = 3 actual
else
false
fi
@@ -256,19 +325,25 @@ test_expect_success C_LOCALE_OUTPUT 'autosquash with custom inst format' '
echo 2 >file1 &&
git add -u &&
test_tick &&
- git commit -m "squash! $(git rev-parse --short HEAD^)" &&
+ oid=$(git rev-parse --short HEAD^) &&
+ git commit -m "squash! $oid" &&
echo 1 >file1 &&
git add -u &&
test_tick &&
- git commit -m "squash! $(git log -n 1 --format=%s HEAD~2)" &&
+ subject=$(git log -n 1 --format=%s HEAD~2) &&
+ git commit -m "squash! $subject" &&
git tag final-squash-instFmt &&
test_tick &&
git rebase --autosquash -i HEAD~4 &&
git log --oneline >actual &&
test_line_count = 3 actual &&
git diff --exit-code final-squash-instFmt &&
- test 1 = "$(git cat-file blob HEAD^:file1)" &&
- test 2 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+ echo 1 >expect &&
+ git cat-file blob HEAD^:file1 >actual &&
+ test_cmp expect actual &&
+ git cat-file commit HEAD^ >commit &&
+ grep squash commit >actual &&
+ test_line_count = 2 actual
'
test_expect_success 'autosquash with empty custom instructionFormat' '
diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh
index 49f548cdb9..d934583776 100755
--- a/t/t3419-rebase-patch-id.sh
+++ b/t/t3419-rebase-patch-id.sh
@@ -80,7 +80,8 @@ do_tests () {
git commit -q -m "change big file again" &&
git checkout -q other^{} &&
git rebase master &&
- test_must_fail test -n "$(git rev-list master...HEAD~)"
+ git rev-list master...HEAD~ >revs &&
+ test_must_be_empty revs
'
test_expect_success $pr 'do not drop patch' '
@@ -90,7 +91,7 @@ do_tests () {
git commit -q -m squashed &&
git checkout -q other^{} &&
test_must_fail git rebase squashed &&
- rm -rf .git/rebase-apply
+ git rebase --quit
'
}
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index 5f7e73cf83..b97ea62363 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -34,7 +34,7 @@ test_expect_success setup '
remove_progress_re="$(printf "s/.*\\r//")"
'
-create_expected_success_am () {
+create_expected_success_apply () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
First, rewinding head to replay your work on top of it...
@@ -44,7 +44,7 @@ create_expected_success_am () {
EOF
}
-create_expected_success_interactive () {
+create_expected_success_merge () {
q_to_cr >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
Applied autostash.
@@ -52,7 +52,7 @@ create_expected_success_interactive () {
EOF
}
-create_expected_failure_am () {
+create_expected_failure_apply () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
First, rewinding head to replay your work on top of it...
@@ -64,7 +64,7 @@ create_expected_failure_am () {
EOF
}
-create_expected_failure_interactive () {
+create_expected_failure_merge () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
Applying autostash resulted in conflicts.
@@ -101,9 +101,9 @@ testrebase () {
test_expect_success "rebase$type --autostash: check output" '
test_when_finished git branch -D rebased-feature-branch &&
- suffix=${type#\ --} && suffix=${suffix:-am} &&
- if test ${suffix} = "merge"; then
- suffix=interactive
+ suffix=${type#\ --} && suffix=${suffix:-apply} &&
+ if test ${suffix} = "interactive"; then
+ suffix=merge
fi &&
create_expected_success_$suffix &&
sed "$remove_progress_re" <actual >actual2 &&
@@ -202,9 +202,9 @@ testrebase () {
test_expect_success "rebase$type: check output with conflicting stash" '
test_when_finished git branch -D rebased-feature-branch &&
- suffix=${type#\ --} && suffix=${suffix:-am} &&
- if test ${suffix} = "merge"; then
- suffix=interactive
+ suffix=${type#\ --} && suffix=${suffix:-apply} &&
+ if test ${suffix} = "interactive"; then
+ suffix=merge
fi &&
create_expected_failure_$suffix &&
sed "$remove_progress_re" <actual >actual2 &&
@@ -234,7 +234,7 @@ test_expect_success "rebase: noop rebase" '
git checkout feature-branch
'
-testrebase "" .git/rebase-apply
+testrebase " --apply" .git/rebase-apply
testrebase " --merge" .git/rebase-merge
testrebase " --interactive" .git/rebase-merge
diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh
index b847064f91..cf8dfd6c20 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -26,7 +26,7 @@ test_run_rebase () {
test_linear_range 'd e' c..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -50,7 +50,7 @@ test_run_rebase () {
test_cmp_rev e HEAD
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -61,12 +61,12 @@ 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 --apply
test_run_rebase success --fork-point
test_run_rebase success -m
test_run_rebase success -i
@@ -78,12 +78,12 @@ test_run_rebase () {
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-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 --apply
test_run_rebase success --fork-point
test_run_rebase success -m
test_run_rebase success -i
@@ -98,7 +98,7 @@ test_run_rebase () {
test_cmp_rev e HEAD
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success --fork-point
test_run_rebase success -m
test_run_rebase success -i
@@ -139,7 +139,7 @@ test_run_rebase () {
test_linear_range 'd i' h..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -154,7 +154,7 @@ test_run_rebase () {
test_linear_range 'd' h..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -169,7 +169,7 @@ test_run_rebase () {
test_linear_range 'd i' f..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -184,7 +184,7 @@ test_run_rebase () {
test_linear_range 'd gp i' h..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -205,17 +205,17 @@ test_expect_success 'setup of linear history for empty commit tests' '
test_run_rebase () {
result=$1
shift
- test_expect_$result "rebase $* drops empty commit" "
+ test_expect_$result "rebase $* keeps begin-empty commits" "
reset_rebase &&
- git rebase $* c l &&
- test_cmp_rev c HEAD~2 &&
- test_linear_range 'd l' c..
+ git rebase $* j l &&
+ test_cmp_rev c HEAD~4 &&
+ test_linear_range 'j d k l' c..
"
}
-test_run_rebase success ''
+test_run_rebase failure --apply
test_run_rebase success -m
test_run_rebase success -i
-test_have_prereq !REBASE_P || test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
@@ -227,10 +227,10 @@ test_run_rebase () {
test_linear_range 'd k l' c..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
-test_have_prereq !REBASE_P || test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -242,10 +242,10 @@ test_run_rebase () {
test_linear_range 'd k l' j..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
-test_have_prereq !REBASE_P || test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase success --rebase-merges
# m
@@ -282,7 +282,7 @@ test_run_rebase () {
test_linear_range 'x y' c..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -297,7 +297,7 @@ test_run_rebase () {
test_linear_range 'x y' c..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase failure -p
@@ -312,7 +312,7 @@ test_run_rebase () {
test_linear_range 'x y' m..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -328,7 +328,7 @@ test_run_rebase () {
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase failure -p
@@ -343,7 +343,7 @@ test_run_rebase () {
test_linear_range 'x y' m..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase failure -p
@@ -368,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/t3424-rebase-empty.sh b/t/t3424-rebase-empty.sh
new file mode 100755
index 0000000000..e1e30517ea
--- /dev/null
+++ b/t/t3424-rebase-empty.sh
@@ -0,0 +1,134 @@
+#!/bin/sh
+
+test_description='git rebase of commits that start or become empty'
+
+. ./test-lib.sh
+
+test_expect_success 'setup test repository' '
+ test_write_lines 1 2 3 4 5 6 7 8 9 10 >numbers &&
+ test_write_lines A B C D E F G H I J >letters &&
+ git add numbers letters &&
+ git commit -m A &&
+
+ git branch upstream &&
+ git branch localmods &&
+
+ git checkout upstream &&
+ test_write_lines A B C D E >letters &&
+ git add letters &&
+ git commit -m B &&
+
+ test_write_lines 1 2 3 4 five 6 7 8 9 ten >numbers &&
+ git add numbers &&
+ git commit -m C &&
+
+ git checkout localmods &&
+ test_write_lines 1 2 3 4 five 6 7 8 9 10 >numbers &&
+ git add numbers &&
+ git commit -m C2 &&
+
+ git commit --allow-empty -m D &&
+
+ test_write_lines A B C D E >letters &&
+ git add letters &&
+ git commit -m "Five letters ought to be enough for anybody"
+'
+
+test_expect_failure 'rebase (apply-backend)' '
+ test_when_finished "git rebase --abort" &&
+ git checkout -B testing localmods &&
+ # rebase (--apply) should not drop commits that start empty
+ git rebase --apply upstream &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge --empty=drop' '
+ git checkout -B testing localmods &&
+ git rebase --merge --empty=drop upstream &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge uses default of --empty=drop' '
+ git checkout -B testing localmods &&
+ git rebase --merge upstream &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge --empty=keep' '
+ git checkout -B testing localmods &&
+ git rebase --merge --empty=keep upstream &&
+
+ test_write_lines D C2 C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge --empty=ask' '
+ git checkout -B testing localmods &&
+ test_must_fail git rebase --merge --empty=ask upstream &&
+
+ git rebase --skip &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --interactive --empty=drop' '
+ git checkout -B testing localmods &&
+ git rebase --interactive --empty=drop upstream &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --interactive --empty=keep' '
+ git checkout -B testing localmods &&
+ git rebase --interactive --empty=keep upstream &&
+
+ test_write_lines D C2 C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --interactive --empty=ask' '
+ git checkout -B testing localmods &&
+ test_must_fail git rebase --interactive --empty=ask upstream &&
+
+ git rebase --skip &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --interactive uses default of --empty=ask' '
+ git checkout -B testing localmods &&
+ test_must_fail git rebase --interactive upstream &&
+
+ git rebase --skip &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge does not leave state laying around' '
+ git checkout -B testing localmods~2 &&
+ git rebase --merge upstream &&
+
+ test_path_is_missing .git/CHERRY_PICK_HEAD &&
+ test_path_is_missing .git/MERGE_MSG
+'
+
+test_done
diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh
index fd8efe84fe..e42faa44e7 100755
--- a/t/t3425-rebase-topology-merges.sh
+++ b/t/t3425-rebase-topology-merges.sh
@@ -54,7 +54,7 @@ test_run_rebase () {
test_linear_range 'n o' e..
"
}
-test_run_rebase success ''
+test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
@@ -70,7 +70,7 @@ test_run_rebase () {
test_linear_range "\'"$expected"\'" d..
"
}
-test_run_rebase success 'n o e' ''
+test_run_rebase success 'n o e' --apply
test_run_rebase success 'n o e' -m
test_run_rebase success 'n o e' -i
@@ -86,7 +86,7 @@ test_run_rebase () {
test_linear_range "\'"$expected"\'" c..
"
}
-test_run_rebase success 'd n o e' ''
+test_run_rebase success 'd n o e' --apply
test_run_rebase success 'd n o e' -m
test_run_rebase success 'd n o e' -i
@@ -102,7 +102,7 @@ test_run_rebase () {
test_linear_range "\'"$expected"\'" c..
"
}
-test_run_rebase success 'd n o e' ''
+test_run_rebase success 'd n o e' --apply
test_run_rebase success 'd n o e' -m
test_run_rebase success 'd n o e' -i
diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh
index bec48e6a1f..79e43a370b 100755
--- a/t/t3427-rebase-subtree.sh
+++ b/t/t3427-rebase-subtree.sh
@@ -85,23 +85,23 @@ test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --
verbose test "$(commit_message HEAD)" = "Empty commit"
'
-test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '
+test_expect_success 'Rebase -Xsubtree --empty=ask --onto commit' '
reset_rebase &&
git checkout -b rebase-onto to-rebase &&
- test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&
+ test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --onto files-master master &&
: first pick results in no changes &&
- git rebase --continue &&
+ git rebase --skip &&
verbose test "$(commit_message HEAD~2)" = "master4" &&
verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
verbose test "$(commit_message HEAD)" = "Empty commit"
'
-test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' '
+test_expect_success 'Rebase -Xsubtree --empty=ask --rebase-merges --onto commit' '
reset_rebase &&
git checkout -b rebase-merges-onto to-rebase &&
- test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root &&
+ test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --rebase-merges --onto files-master --root &&
: first pick results in no changes &&
- git rebase --continue &&
+ git rebase --skip &&
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 8739cb60a7..7024d49ae7 100755
--- a/t/t3429-rebase-edit-todo.sh
+++ b/t/t3429-rebase-edit-todo.sh
@@ -17,7 +17,7 @@ test_expect_success 'rebase exec modifies rebase-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 &&
@@ -52,4 +52,34 @@ test_expect_success 'todo is re-read after reword and squash' '
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 9efcf4808a..a1bc3e2001 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -20,12 +20,11 @@ Initial setup:
'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
+. "$TEST_DIRECTORY"/lib-log-graph.sh
test_cmp_graph () {
cat >expect &&
- git log --graph --boundary --format=%s "$@" >output &&
- sed "s/ *$//" <output >output.trimmed &&
- test_cmp expect output.trimmed
+ lib_test_cmp_graph --boundary --format=%s "$@"
}
test_expect_success 'setup' '
@@ -346,7 +345,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
|\
@@ -408,7 +407,7 @@ test_expect_success 'octopus merges' '
| | * three
| * | two
| |/
- * | one
+ * / one
|/
o before-octopus
EOF
@@ -468,4 +467,31 @@ test_expect_success '--rebase-merges with strategies' '
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/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh
index 034ffc7e76..6c9d4a1375 100755
--- a/t/t3432-rebase-fast-forward.sh
+++ b/t/t3432-rebase-fast-forward.sh
@@ -28,8 +28,10 @@ test_rebase_same_head () {
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_n $what_n $cmp_n " --apply" "$*" &&
+ test_rebase_same_head_ $status_f $what_f $cmp_f " --apply --no-ff" "$*"
+ test_rebase_same_head_ $status_n $what_n $cmp_n " --merge" "$*" &&
+ test_rebase_same_head_ $status_f $what_f $cmp_f " --merge --no-ff" "$*"
}
test_rebase_same_head_ () {
@@ -44,19 +46,15 @@ test_rebase_same_head_ () {
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' &&
+ cp .git/logs/HEAD expect &&
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
+ old=\$(wc -l <expect) &&
+ test_line_count '-gt' \$old .git/logs/HEAD
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
+ test_cmp expect .git/logs/HEAD
fi &&
newhead=\$(git rev-parse HEAD) &&
if test $cmp = same
@@ -64,21 +62,21 @@ test_rebase_same_head_ () {
test_cmp_rev \$oldhead \$newhead
elif test $cmp = diff
then
- ! test_cmp_rev \$oldhead \$newhead
+ 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 master
+test_rebase_same_head success noop same success work diff --onto B B
+test_rebase_same_head success noop same success work diff --onto B... B
+test_rebase_same_head success noop same success work same --onto master... master
+test_rebase_same_head success noop same success work same --keep-base master
+test_rebase_same_head success noop same success work same --keep-base
+test_rebase_same_head success noop same success work same --no-fork-point
+test_rebase_same_head success noop same success work 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
@@ -91,14 +89,14 @@ test_expect_success 'add work same to side' '
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 master
+test_rebase_same_head success noop same success work diff --onto B B
+test_rebase_same_head success noop same success work diff --onto B... B
+test_rebase_same_head success noop same success work same --onto master... master
+test_rebase_same_head success noop same success work same --keep-base master
+test_rebase_same_head success noop same success work same --keep-base
+test_rebase_same_head success noop same success work same --no-fork-point
+test_rebase_same_head success noop same success work 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
@@ -112,8 +110,8 @@ test_expect_success 'add work same to upstream' '
'
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 B B
+test_rebase_same_head success noop same success work 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
diff --git a/t/t3433-rebase-across-mode-change.sh b/t/t3433-rebase-across-mode-change.sh
new file mode 100755
index 0000000000..05df964670
--- /dev/null
+++ b/t/t3433-rebase-across-mode-change.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+test_description='git rebase across mode change'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir DS &&
+ >DS/whatever &&
+ git add DS &&
+ git commit -m base &&
+
+ git branch side1 &&
+ git branch side2 &&
+
+ git checkout side1 &&
+ git rm -rf DS &&
+ test_ln_s_add unrelated DS &&
+ git commit -m side1 &&
+
+ git checkout side2 &&
+ >unrelated &&
+ git add unrelated &&
+ git commit -m commit1 &&
+
+ echo >>unrelated &&
+ git commit -am commit2
+'
+
+test_expect_success 'rebase changes with the apply backend' '
+ test_when_finished "git rebase --abort || true" &&
+ git checkout -b apply-backend side2 &&
+ git rebase side1
+'
+
+test_expect_success 'rebase changes with the merge backend' '
+ test_when_finished "git rebase --abort || true" &&
+ git checkout -b merge-backend side2 &&
+ git rebase -m side1
+'
+
+test_expect_success 'rebase changes with the merge backend with a delay' '
+ test_when_finished "git rebase --abort || true" &&
+ git checkout -b merge-delay-backend side2 &&
+ git rebase -m --exec "sleep 1" side1
+'
+
+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 @@
+ÄËÑÏÖ
+
+Ábçdèfg
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/t3504-cherry-pick-rerere.sh b/t/t3504-cherry-pick-rerere.sh
index a267b2d144..80a0d08706 100755
--- a/t/t3504-cherry-pick-rerere.sh
+++ b/t/t3504-cherry-pick-rerere.sh
@@ -94,8 +94,10 @@ test_expect_success 'cherry-pick --rerere-autoupdate more than once' '
test_expect_success 'cherry-pick conflict without rerere' '
test_config rerere.enabled false &&
- test_must_fail git cherry-pick master &&
- test_must_fail test_cmp expect foo
+ test_must_fail git cherry-pick foo-master &&
+ grep ===== foo &&
+ grep foo-dev foo &&
+ grep foo-master foo
'
test_done
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 9b9b4ca8d4..752bc43487 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -161,6 +161,29 @@ test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
'
+
+test_expect_success 'partial commit of cherry-pick fails' '
+ pristine_detach initial &&
+
+ test_must_fail git cherry-pick picked &&
+ echo resolved >foo &&
+ git add foo &&
+ test_must_fail git commit foo 2>err &&
+
+ test_i18ngrep "cannot do a partial commit during a cherry-pick." err
+'
+
+test_expect_success 'commit --amend of cherry-pick fails' '
+ pristine_detach initial &&
+
+ test_must_fail git cherry-pick picked &&
+ echo resolved >foo &&
+ git add foo &&
+ test_must_fail git commit --amend 2>err &&
+
+ test_i18ngrep "in the middle of a cherry-pick -- cannot amend." err
+'
+
test_expect_success 'successful final commit clears cherry-pick state' '
pristine_detach initial &&
@@ -168,7 +191,7 @@ test_expect_success 'successful final commit clears cherry-pick state' '
echo resolved >foo &&
test_path_is_file .git/sequencer/todo &&
git commit -a &&
- test_must_fail test_path_exists .git/sequencer
+ test_path_is_missing .git/sequencer
'
test_expect_success 'reset after final pick clears cherry-pick state' '
@@ -178,7 +201,7 @@ test_expect_success 'reset after final pick clears cherry-pick state' '
echo resolved >foo &&
test_path_is_file .git/sequencer/todo &&
git reset &&
- test_must_fail test_path_exists .git/sequencer
+ test_path_is_missing .git/sequencer
'
test_expect_success 'failed cherry-pick produces dirty index' '
@@ -381,23 +404,23 @@ test_expect_success 'failed commit does not clear REVERT_HEAD' '
'
test_expect_success 'successful final commit clears revert state' '
- pristine_detach picked-signed &&
+ pristine_detach picked-signed &&
- test_must_fail git revert picked-signed base &&
- echo resolved >foo &&
- test_path_is_file .git/sequencer/todo &&
- git commit -a &&
- test_must_fail test_path_exists .git/sequencer
+ test_must_fail git revert picked-signed base &&
+ echo resolved >foo &&
+ test_path_is_file .git/sequencer/todo &&
+ git commit -a &&
+ test_path_is_missing .git/sequencer
'
test_expect_success 'reset after final pick clears revert state' '
- pristine_detach picked-signed &&
+ pristine_detach picked-signed &&
- test_must_fail git revert picked-signed base &&
- echo resolved >foo &&
- test_path_is_file .git/sequencer/todo &&
- git reset &&
- test_must_fail test_path_exists .git/sequencer
+ test_must_fail git revert picked-signed base &&
+ echo resolved >foo &&
+ test_path_is_file .git/sequencer/todo &&
+ git reset &&
+ test_path_is_missing .git/sequencer
'
test_expect_success 'revert conflict, diff3 -m style' '
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/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index 793bcc7fe3..5b94fdaa67 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -123,7 +123,8 @@ test_expect_success 'revert --skip to skip commit' '
test_expect_success 'skip "empty" commit' '
pristine_detach picked &&
test_commit dummy foo d &&
- test_must_fail git cherry-pick anotherpick &&
+ test_must_fail git cherry-pick anotherpick 2>err &&
+ test_i18ngrep "git cherry-pick --skip" err &&
git cherry-pick --skip &&
test_cmp_rev dummy HEAD
'
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 8c8cca5bfb..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"
'
@@ -250,6 +251,7 @@ test_expect_success 'choking "git rm" should not let it die with cruft' '
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
'
@@ -303,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 &&
@@ -422,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 &&
@@ -622,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/t3601-rm-pathspec-file.sh b/t/t3601-rm-pathspec-file.sh
new file mode 100755
index 0000000000..7de21f8bcf
--- /dev/null
+++ b/t/t3601-rm-pathspec-file.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+test_description='rm --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 fileA.t fileB.t fileC.t fileD.t &&
+ git commit -m "files" &&
+
+ 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 'simplest' '
+ restore_checkpoint &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ EOF
+
+ echo fileA.t | git rm --pathspec-from-file=- &&
+ verify_expect
+'
+
+test_expect_success '--pathspec-file-nul' '
+ restore_checkpoint &&
+
+ cat >expect <<-\EOF &&
+ D fileA.t
+ D fileB.t
+ EOF
+
+ printf "fileA.t\0fileB.t\0" | git rm --pathspec-from-file=- --pathspec-file-nul &&
+ verify_expect
+'
+
+test_expect_success 'only touches what was listed' '
+ restore_checkpoint &&
+
+ cat >expect <<-\EOF &&
+ D fileB.t
+ D fileC.t
+ EOF
+
+ printf "fileB.t\nfileC.t\n" | git rm --pathspec-from-file=- &&
+ verify_expect
+'
+
+test_expect_success 'error conditions' '
+ restore_checkpoint &&
+ echo fileA.t >list &&
+
+ test_must_fail git rm --pathspec-from-file=list -- fileA.t 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err &&
+
+ test_must_fail git rm --pathspec-file-nul 2>err &&
+ test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err &&
+
+ >empty_list &&
+ test_must_fail git rm --pathspec-from-file=empty_list 2>err &&
+ test_i18ngrep -e "No pathspec was given. Which files should I remove?" err
+'
+
+test_done
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 d50e165ca8..5bae6e50f1 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 &&
@@ -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,61 @@ 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 'colorized diffs respect diff.wsErrorHighlight' '
+ git reset --hard &&
+
+ echo "old " >test &&
+ git add test &&
+ echo "new " >test &&
+
+ printf y >y &&
+ force_color git -c diff.wsErrorHighlight=all add -p >output.raw 2>&1 <y &&
+ test_decode_color <output.raw >output &&
+ grep "old<" output
+'
+
+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 +785,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/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 580bfbdc23..3ad23e2502 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -244,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
'
@@ -254,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
'
@@ -280,6 +285,11 @@ test_expect_success 'stash --no-keep-index' '
test bar,bar2 = $(cat file),$(cat file2)
'
+test_expect_success 'dont assume push with non-option args' '
+ test_must_fail git stash -q drop 2>err &&
+ test_i18ngrep -e "subcommand wasn'\''t specified; '\''push'\'' can'\''t be assumed due to unexpected token '\''drop'\''" err
+'
+
test_expect_success 'stash --invalid-option' '
echo bar5 >file &&
echo bar6 >file2 &&
@@ -1269,4 +1279,15 @@ test_expect_success 'stash apply should succeed with unmodified 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/t3909-stash-pathspec-file.sh b/t/t3909-stash-pathspec-file.sh
new file mode 100755
index 0000000000..55e050cfd4
--- /dev/null
+++ b/t/t3909-stash-pathspec-file.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+test_description='stash --pathspec-from-file'
+
+. ./test-lib.sh
+
+test_tick
+
+test_expect_success setup '
+ >fileA.t &&
+ >fileB.t &&
+ >fileC.t &&
+ >fileD.t &&
+ git add fileA.t fileB.t fileC.t fileD.t &&
+ git commit -m "Files" &&
+
+ git tag checkpoint
+'
+
+restore_checkpoint () {
+ git reset --hard checkpoint
+}
+
+verify_expect () {
+ git stash show --name-status >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'simplest' '
+ restore_checkpoint &&
+
+ # More files are written to make sure that git didnt ignore
+ # --pathspec-from-file, stashing everything
+ echo A >fileA.t &&
+ echo B >fileB.t &&
+ echo C >fileC.t &&
+ echo D >fileD.t &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ EOF
+
+ echo fileA.t | git stash push --pathspec-from-file=- &&
+ verify_expect
+'
+
+test_expect_success '--pathspec-file-nul' '
+ restore_checkpoint &&
+
+ # More files are written to make sure that git didnt ignore
+ # --pathspec-from-file, stashing everything
+ echo A >fileA.t &&
+ echo B >fileB.t &&
+ echo C >fileC.t &&
+ echo D >fileD.t &&
+
+ cat >expect <<-\EOF &&
+ M fileA.t
+ M fileB.t
+ EOF
+
+ printf "fileA.t\0fileB.t\0" | git stash push --pathspec-from-file=- --pathspec-file-nul &&
+ verify_expect
+'
+
+test_expect_success 'only touches what was listed' '
+ restore_checkpoint &&
+
+ # More files are written to make sure that git didnt ignore
+ # --pathspec-from-file, stashing everything
+ echo A >fileA.t &&
+ echo B >fileB.t &&
+ echo C >fileC.t &&
+ echo D >fileD.t &&
+
+ cat >expect <<-\EOF &&
+ M fileB.t
+ M fileC.t
+ EOF
+
+ printf "fileB.t\nfileC.t\n" | git stash push --pathspec-from-file=- &&
+ verify_expect
+'
+
+test_expect_success 'error conditions' '
+ restore_checkpoint &&
+ echo A >fileA.t &&
+ echo fileA.t >list &&
+
+ test_must_fail git stash push --pathspec-from-file=list --patch 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err &&
+
+ test_must_fail git stash push --pathspec-from-file=list -- fileA.t 2>err &&
+ test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err &&
+
+ test_must_fail git stash push --pathspec-file-nul 2>err &&
+ test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err
+'
+
+test_done
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 5ac94b390d..dde3f11fec 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -120,6 +120,30 @@ test_expect_success setup '
+*++ [initial] Initial
EOF
+process_diffs () {
+ _x04="[0-9a-f][0-9a-f][0-9a-f][0-9a-f]" &&
+ _x07="$_x05[0-9a-f][0-9a-f]" &&
+ sed -e "s/$OID_REGEX/$ZERO_OID/g" \
+ -e "s/From $_x40 /From $ZERO_OID /" \
+ -e "s/from $_x40)/from $ZERO_OID)/" \
+ -e "s/commit $_x40\$/commit $ZERO_OID/" \
+ -e "s/commit $_x40 (/commit $ZERO_OID (/" \
+ -e "s/$_x40 $_x40 $_x40/$ZERO_OID $ZERO_OID $ZERO_OID/" \
+ -e "s/$_x40 $_x40 /$ZERO_OID $ZERO_OID /" \
+ -e "s/^$_x40 $_x40$/$ZERO_OID $ZERO_OID/" \
+ -e "s/^$_x40 /$ZERO_OID /" \
+ -e "s/^$_x40$/$ZERO_OID/" \
+ -e "s/$_x07\.\.$_x07/fffffff..fffffff/g" \
+ -e "s/$_x07,$_x07\.\.$_x07/fffffff,fffffff..fffffff/g" \
+ -e "s/$_x07 $_x07 $_x07/fffffff fffffff fffffff/g" \
+ -e "s/$_x07 $_x07 /fffffff fffffff /g" \
+ -e "s/Merge: $_x07 $_x07/Merge: fffffff fffffff/g" \
+ -e "s/$_x07\.\.\./fffffff.../g" \
+ -e "s/ $_x04\.\.\./ ffff.../g" \
+ -e "s/ $_x04/ ffff/g" \
+ "$1"
+}
+
V=$(git version | sed -e 's/^git version //' -e 's/\./\\./g')
while read magic cmd
do
@@ -158,13 +182,15 @@ do
} >"$actual" &&
if test -f "$expect"
then
+ process_diffs "$actual" >actual &&
+ process_diffs "$expect" >expect &&
case $cmd in
*format-patch* | *-stat*)
- test_i18ncmp "$expect" "$actual";;
+ test_i18ncmp expect actual;;
*)
- test_cmp "$expect" "$actual";;
+ test_cmp expect actual;;
esac &&
- rm -f "$actual"
+ rm -f "$actual" actual expect
else
# this is to help developing new tests.
cp "$actual" "$expect"
@@ -383,16 +409,22 @@ test_expect_success 'log -S requires an argument' '
test_expect_success 'diff --cached on unborn branch' '
echo ref: refs/heads/unborn >.git/HEAD &&
git diff --cached >result &&
- test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached" result
+ process_diffs result >actual &&
+ process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--cached" >expected &&
+ test_cmp expected actual
'
test_expect_success 'diff --cached -- file on unborn branch' '
git diff --cached -- file0 >result &&
- test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" result
+ process_diffs result >actual &&
+ process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" >expected &&
+ test_cmp expected actual
'
test_expect_success 'diff --line-prefix with spaces' '
git diff --line-prefix="| | | " --cached -- file0 >result &&
- test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--line-prefix_--cached_--_file0" result
+ process_diffs result >actual &&
+ process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--line-prefix_--cached_--_file0" >expected &&
+ test_cmp expected actual
'
test_expect_success 'diff-tree --stdin with log formatting' '
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index b8969998b5..b653dd7d44 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -793,6 +793,38 @@ test_expect_success 'format-patch with multiple notes refs' '
! grep "this is note 2" out
'
+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
@@ -1517,6 +1549,178 @@ 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 &&
@@ -1767,10 +1971,9 @@ 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 &&
git rev-parse upstream >commit-id-base &&
@@ -1779,8 +1982,7 @@ test_expect_success 'format-patch format.useAutoBaseoption' '
'
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 &&
git rev-parse HEAD~1 >commit-id-base &&
@@ -1788,6 +1990,12 @@ test_expect_success 'format-patch --base overrides format.useAutoBase' '
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' '
git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
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 6f5ef0035e..02255a08bf 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -32,6 +32,7 @@ diffpatterns="
csharp
css
dts
+ elixir
fortran
fountain
golang
@@ -105,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/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/t4026-color.sh b/t/t4026-color.sh
index 671e951ee5..c0b642c1ab 100755
--- a/t/t4026-color.sh
+++ b/t/t4026-color.sh
@@ -30,6 +30,14 @@ test_expect_success 'attribute before color name' '
color "bold red" "[1;31m"
'
+test_expect_success 'aixterm bright fg color' '
+ color "brightred" "[91m"
+'
+
+test_expect_success 'aixterm bright bg color' '
+ color "green brightblue" "[32;104m"
+'
+
test_expect_success 'color name before attribute' '
color "red bold" "[1;31m"
'
@@ -74,6 +82,10 @@ test_expect_success '0-7 are aliases for basic ANSI color names' '
color "0 7" "[30;47m"
'
+test_expect_success '8-15 are aliases for aixterm color names' '
+ color "12 13" "[94;105m"
+'
+
test_expect_success '256 colors' '
color "254 bold 255" "[1;38;5;254;48;5;255m"
'
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 9a93c2a3e0..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 @@
@@ -317,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
@@ -337,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/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index b9d876efa2..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,7 +514,7 @@ 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 expect actual
'
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/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh
index 9dcb69df5c..fc8229c726 100755
--- a/t/t4060-diff-submodule-option-diff-format.sh
+++ b/t/t4060-diff-submodule-option-diff-format.sh
@@ -42,6 +42,17 @@ commit_file () {
git commit "$@" -m "Commit $*" >/dev/null
}
+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/' \
+ "$i" >"$i.compare" || return 1
+ done &&
+ test_cmp "$1.compare" "$2.compare" &&
+ rm -f "$1.compare" "$2.compare"
+}
+
test_expect_success 'setup repository' '
test_create_repo sm1 &&
add_file . foo &&
@@ -69,7 +80,7 @@ test_expect_success 'added submodule' '
@@ -0,0 +1 @@
+foo2
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'added submodule, set diff.submodule' '
@@ -93,7 +104,7 @@ test_expect_success 'added submodule, set diff.submodule' '
@@ -0,0 +1 @@
+foo2
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success '--submodule=short overrides diff.submodule' '
@@ -109,7 +120,7 @@ test_expect_success '--submodule=short overrides diff.submodule' '
@@ -0,0 +1 @@
+Subproject commit $fullhead1
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'diff.submodule does not affect plumbing' '
@@ -124,7 +135,7 @@ test_expect_success 'diff.submodule does not affect plumbing' '
@@ -0,0 +1 @@
+Subproject commit $fullhead1
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
commit_file sm1 &&
@@ -142,7 +153,7 @@ test_expect_success 'modified submodule(forward)' '
@@ -0,0 +1 @@
+foo3
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule(forward)' '
@@ -157,7 +168,7 @@ test_expect_success 'modified submodule(forward)' '
@@ -0,0 +1 @@
+foo3
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule(forward) --submodule' '
@@ -166,7 +177,7 @@ test_expect_success 'modified submodule(forward) --submodule' '
Submodule sm1 $head1..$head2:
> Add foo3 ($added foo3)
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
fullhead2=$(cd sm1; git rev-parse --verify HEAD)
@@ -181,7 +192,7 @@ test_expect_success 'modified submodule(forward) --submodule=short' '
-Subproject commit $fullhead1
+Subproject commit $fullhead2
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
commit_file sm1 &&
@@ -210,7 +221,7 @@ test_expect_success 'modified submodule(backward)' '
@@ -1 +0,0 @@
-foo3
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
head4=$(add_file sm1 foo4 foo5)
@@ -247,7 +258,7 @@ test_expect_success 'modified submodule(backward and forward)' '
@@ -0,0 +1 @@
+foo5
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
commit_file sm1 &&
@@ -291,7 +302,7 @@ test_expect_success 'typechanged submodule(submodule->blob), --cached' '
@@ -0,0 +1 @@
+sm1
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'typechanged submodule(submodule->blob)' '
@@ -327,7 +338,7 @@ test_expect_success 'typechanged submodule(submodule->blob)' '
@@ -0,0 +1 @@
+foo5
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
rm -rf sm1 &&
@@ -344,7 +355,7 @@ test_expect_success 'typechanged submodule(submodule->blob)' '
@@ -0,0 +1 @@
+sm1
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
rm -f sm1 &&
@@ -356,7 +367,7 @@ test_expect_success 'nonexistent commit' '
cat >expected <<-EOF &&
Submodule sm1 $head4...$head6 (commits not present)
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
commit_file
@@ -386,11 +397,12 @@ test_expect_success 'typechanged submodule(blob->submodule)' '
@@ -0,0 +1 @@
+foo7
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
commit_file sm1 &&
test_expect_success 'submodule is up to date' '
+ head7=$(git -C sm1 rev-parse --short --verify HEAD) &&
git diff-index -p --submodule=diff HEAD >actual &&
test_must_be_empty actual
'
@@ -401,7 +413,7 @@ test_expect_success 'submodule contains untracked content' '
cat >expected <<-EOF &&
Submodule sm1 contains untracked content
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'submodule contains untracked content (untracked ignored)' '
@@ -433,7 +445,7 @@ test_expect_success 'submodule contains untracked and modified content' '
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
# NOT OK
@@ -450,7 +462,7 @@ test_expect_success 'submodule contains untracked and modified content (untracke
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'submodule contains untracked and modified content (dirty ignored)' '
@@ -478,7 +490,7 @@ test_expect_success 'submodule contains modified content' '
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
(cd sm1; git commit -mchange foo6 >/dev/null) &&
@@ -486,7 +498,7 @@ head8=$(cd sm1; git rev-parse --short --verify HEAD) &&
test_expect_success 'submodule is modified' '
git diff-index -p --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9..$head8:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..3e75765 100644
--- a/sm1/foo6
@@ -495,7 +507,7 @@ test_expect_success 'submodule is modified' '
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule contains untracked content' '
@@ -503,7 +515,7 @@ test_expect_success 'modified submodule contains untracked content' '
git diff-index -p --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
Submodule sm1 contains untracked content
- Submodule sm1 17243c9..$head8:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..3e75765 100644
--- a/sm1/foo6
@@ -512,13 +524,13 @@ test_expect_success 'modified submodule contains untracked content' '
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule contains untracked content (untracked ignored)' '
git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9..$head8:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..3e75765 100644
--- a/sm1/foo6
@@ -527,13 +539,13 @@ test_expect_success 'modified submodule contains untracked content (untracked ig
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule contains untracked content (dirty ignored)' '
git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9..cfce562:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..3e75765 100644
--- a/sm1/foo6
@@ -542,7 +554,7 @@ test_expect_success 'modified submodule contains untracked content (dirty ignore
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule contains untracked content (all ignored)' '
@@ -556,7 +568,7 @@ test_expect_success 'modified submodule contains untracked and modified content'
cat >expected <<-EOF &&
Submodule sm1 contains untracked content
Submodule sm1 contains modified content
- Submodule sm1 17243c9..cfce562:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..dfda541 100644
--- a/sm1/foo6
@@ -566,7 +578,7 @@ test_expect_success 'modified submodule contains untracked and modified content'
+new
+modification
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule contains untracked and modified content (untracked ignored)' '
@@ -574,7 +586,7 @@ test_expect_success 'modified submodule contains untracked and modified content
git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
Submodule sm1 contains modified content
- Submodule sm1 17243c9..cfce562:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..e20e2d9 100644
--- a/sm1/foo6
@@ -585,14 +597,14 @@ test_expect_success 'modified submodule contains untracked and modified content
+modification
+modification
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule contains untracked and modified content (dirty ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9..cfce562:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..3e75765 100644
--- a/sm1/foo6
@@ -601,7 +613,7 @@ test_expect_success 'modified submodule contains untracked and modified content
-foo6
+new
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'modified submodule contains untracked and modified content (all ignored)' '
@@ -616,7 +628,7 @@ test_expect_success 'modified submodule contains modified content' '
git diff-index -p --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
Submodule sm1 contains modified content
- Submodule sm1 17243c9..cfce562:
+ Submodule sm1 $head7..$head8:
diff --git a/sm1/foo6 b/sm1/foo6
index 462398b..ac466ca 100644
--- a/sm1/foo6
@@ -629,29 +641,29 @@ test_expect_success 'modified submodule contains modified content' '
+modification
+modification
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
rm -rf sm1
test_expect_success 'deleted submodule' '
git diff-index -p --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9...0000000 (submodule deleted)
+ Submodule sm1 $head7...0000000 (submodule deleted)
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'create second submodule' '
test_create_repo sm2 &&
- head7=$(add_file sm2 foo8 foo9) &&
+ head9=$(add_file sm2 foo8 foo9) &&
git add sm2
'
test_expect_success 'multiple submodules' '
git diff-index -p --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9...0000000 (submodule deleted)
- Submodule sm2 0000000...a5a65c9 (new submodule)
+ Submodule sm1 $head7...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head9 (new submodule)
diff --git a/sm2/foo8 b/sm2/foo8
new file mode 100644
index 0000000..db9916b
@@ -667,13 +679,13 @@ test_expect_success 'multiple submodules' '
@@ -0,0 +1 @@
+foo9
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'path filter' '
git diff-index -p --submodule=diff HEAD sm2 >actual &&
cat >expected <<-EOF &&
- Submodule sm2 0000000...a5a65c9 (new submodule)
+ Submodule sm2 0000000...$head9 (new submodule)
diff --git a/sm2/foo8 b/sm2/foo8
new file mode 100644
index 0000000..db9916b
@@ -689,15 +701,15 @@ test_expect_success 'path filter' '
@@ -0,0 +1 @@
+foo9
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
commit_file sm2
test_expect_success 'given commit' '
git diff-index -p --submodule=diff HEAD^ >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9...0000000 (submodule deleted)
- Submodule sm2 0000000...a5a65c9 (new submodule)
+ Submodule sm1 $head7...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head9 (new submodule)
diff --git a/sm2/foo8 b/sm2/foo8
new file mode 100644
index 0000000..db9916b
@@ -713,7 +725,7 @@ test_expect_success 'given commit' '
@@ -0,0 +1 @@
+foo9
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'setup .git file for sm2' '
@@ -726,8 +738,8 @@ test_expect_success 'setup .git file for sm2' '
test_expect_success 'diff --submodule=diff with .git file' '
git diff --submodule=diff HEAD^ >actual &&
cat >expected <<-EOF &&
- Submodule sm1 17243c9...0000000 (submodule deleted)
- Submodule sm2 0000000...a5a65c9 (new submodule)
+ Submodule sm1 $head7...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head9 (new submodule)
diff --git a/sm2/foo8 b/sm2/foo8
new file mode 100644
index 0000000..db9916b
@@ -743,25 +755,27 @@ test_expect_success 'diff --submodule=diff with .git file' '
@@ -0,0 +1 @@
+foo9
EOF
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'setup nested submodule' '
git submodule add -f ./sm2 &&
git commit -a -m "add sm2" &&
git -C sm2 submodule add ../sm2 nested &&
- git -C sm2 commit -a -m "nested sub"
+ git -C sm2 commit -a -m "nested sub" &&
+ head10=$(git -C sm2 rev-parse --short --verify HEAD)
'
test_expect_success 'move nested submodule HEAD' '
echo "nested content" >sm2/nested/file &&
git -C sm2/nested add file &&
- git -C sm2/nested commit --allow-empty -m "new HEAD"
+ git -C sm2/nested commit --allow-empty -m "new HEAD" &&
+ head11=$(git -C sm2/nested rev-parse --short --verify HEAD)
'
test_expect_success 'diff --submodule=diff with moved nested submodule HEAD' '
cat >expected <<-EOF &&
- Submodule nested a5a65c9..b55928c:
+ Submodule nested $head9..$head11:
diff --git a/nested/file b/nested/file
new file mode 100644
index 0000000..ca281f5
@@ -772,13 +786,13 @@ test_expect_success 'diff --submodule=diff with moved nested submodule HEAD' '
EOF
git -C sm2 diff --submodule=diff >actual 2>err &&
test_must_be_empty err &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'diff --submodule=diff recurses into nested submodules' '
cat >expected <<-EOF &&
Submodule sm2 contains modified content
- Submodule sm2 a5a65c9..280969a:
+ Submodule sm2 $head9..$head10:
diff --git a/sm2/.gitmodules b/sm2/.gitmodules
new file mode 100644
index 0000000..3a816b8
@@ -788,7 +802,7 @@ test_expect_success 'diff --submodule=diff recurses into nested submodules' '
+[submodule "nested"]
+ path = nested
+ url = ../sm2
- Submodule nested 0000000...b55928c (new submodule)
+ Submodule nested 0000000...$head11 (new submodule)
diff --git a/sm2/nested/file b/sm2/nested/file
new file mode 100644
index 0000000..ca281f5
@@ -813,7 +827,7 @@ test_expect_success 'diff --submodule=diff recurses into nested submodules' '
EOF
git diff --submodule=diff >actual 2>err &&
test_must_be_empty err &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_done
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/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/t4117-apply-reject.sh b/t/t4117-apply-reject.sh
index f7de6f077a..0ee93fe845 100755
--- a/t/t4117-apply-reject.sh
+++ b/t/t4117-apply-reject.sh
@@ -74,7 +74,7 @@ test_expect_success 'apply with --reject should fail but update the file' '
test_must_fail git apply --reject patch.1 &&
test_cmp expected file1 &&
- cat file1.rej &&
+ test_path_is_file file1.rej &&
test_path_is_missing file2.rej
'
@@ -87,7 +87,7 @@ test_expect_success 'apply with --reject should fail but update the file' '
test_path_is_missing file1 &&
test_cmp expected file2 &&
- cat file2.rej &&
+ test_path_is_file file2.rej &&
test_path_is_missing file1.rej
'
@@ -101,7 +101,7 @@ test_expect_success 'the same test with --verbose' '
test_path_is_missing file1 &&
test_cmp expected file2 &&
- cat file2.rej &&
+ test_path_is_file file2.rej &&
test_path_is_missing file1.rej
'
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index ff51e9e789..971a5a7512 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -35,9 +35,15 @@ prepare_test_file () {
}
apply_patch () {
+ cmd_prefix= &&
+ if test "x$1" = 'x!'
+ then
+ cmd_prefix=test_must_fail &&
+ shift
+ fi &&
>target &&
sed -e "s|\([ab]\)/file|\1/target|" <patch |
- git apply "$@"
+ $cmd_prefix git apply "$@"
}
test_fix () {
@@ -99,7 +105,7 @@ test_expect_success 'whitespace=warn, default rule' '
test_expect_success 'whitespace=error-all, default rule' '
- test_must_fail apply_patch --whitespace=error-all &&
+ apply_patch ! --whitespace=error-all &&
test_must_be_empty target
'
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 4f1e24ecbe..cb45271457 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -666,6 +666,26 @@ test_expect_success 'am --show-current-patch' '
test_cmp .git/rebase-apply/0001 actual.patch
'
+test_expect_success 'am --show-current-patch=raw' '
+ git am --show-current-patch=raw >actual.patch &&
+ test_cmp .git/rebase-apply/0001 actual.patch
+'
+
+test_expect_success 'am --show-current-patch=diff' '
+ git am --show-current-patch=diff >actual.patch &&
+ test_cmp .git/rebase-apply/patch actual.patch
+'
+
+test_expect_success 'am accepts repeated --show-current-patch' '
+ git am --show-current-patch --show-current-patch=raw >actual.patch &&
+ test_cmp .git/rebase-apply/0001 actual.patch
+'
+
+test_expect_success 'am detects incompatible --show-current-patch' '
+ test_must_fail git am --show-current-patch=raw --show-current-patch=diff &&
+ test_must_fail git am --show-current-patch --show-current-patch=diff
+'
+
test_expect_success 'am --skip works' '
echo goodbye >expected &&
git am --skip &&
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 e803ba402e..5eeb739f3e 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -5,6 +5,11 @@ test_description='git log'
. ./test-lib.sh
. "$TEST_DIRECTORY/lib-gpg.sh"
. "$TEST_DIRECTORY/lib-terminal.sh"
+. "$TEST_DIRECTORY/lib-log-graph.sh"
+
+test_cmp_graph () {
+ lib_test_cmp_graph --format=%s "$@"
+}
test_expect_success setup '
@@ -87,12 +92,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 +178,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
'
@@ -450,8 +457,7 @@ cat > expect <<EOF
EOF
test_expect_success 'simple log --graph' '
- git log --graph --pretty=tformat:%s >actual &&
- test_cmp expect actual
+ test_cmp_graph
'
cat > expect <<EOF
@@ -465,8 +471,7 @@ cat > expect <<EOF
EOF
test_expect_success 'simple log --graph --line-prefix="123 "' '
- git log --graph --line-prefix="123 " --pretty=tformat:%s >actual &&
- test_cmp expect actual
+ test_cmp_graph --line-prefix="123 "
'
test_expect_success 'set up merge history' '
@@ -493,9 +498,7 @@ cat > expect <<\EOF
EOF
test_expect_success 'log --graph with merge' '
- git log --graph --date-order --pretty=tformat:%s |
- sed "s/ *\$//" >actual &&
- test_cmp expect actual
+ test_cmp_graph --date-order
'
cat > expect <<\EOF
@@ -514,9 +517,7 @@ cat > expect <<\EOF
EOF
test_expect_success 'log --graph --line-prefix="| | | " with merge' '
- git log --line-prefix="| | | " --graph --date-order --pretty=tformat:%s |
- sed "s/ *\$//" >actual &&
- test_cmp expect actual
+ test_cmp_graph --line-prefix="| | | " --date-order
'
cat > expect.colors <<\EOF
@@ -536,9 +537,7 @@ EOF
test_expect_success 'log --graph with merge with log.graphColors' '
test_config log.graphColors " blue,invalid-color, cyan, red , " &&
- git log --color=always --graph --date-order --pretty=tformat:%s |
- test_decode_color | sed "s/ *\$//" >actual &&
- test_cmp expect.colors actual
+ lib_test_cmp_colored_graph --date-order --format=%s
'
test_expect_success 'log --raw --graph -m with merge' '
@@ -667,16 +666,14 @@ cat > expect <<\EOF
* | | fifth
* | | fourth
|/ /
-* | third
+* / third
|/
* second
* initial
EOF
test_expect_success 'log --graph with merge' '
- git log --graph --date-order --pretty=tformat:%s |
- sed "s/ *\$//" >actual &&
- test_cmp expect actual
+ test_cmp_graph --date-order
'
test_expect_success 'log.decorate configuration' '
@@ -957,7 +954,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 @@
@@ -980,7 +977,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 @@
@@ -996,7 +993,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 @@
@@ -1012,7 +1009,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 @@
@@ -1046,7 +1043,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 @@
@@ -1068,7 +1065,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 @@
@@ -1084,7 +1081,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 @@
@@ -1100,7 +1097,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 @@
@@ -1116,7 +1113,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 @@
@@ -1132,7 +1129,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 @@
@@ -1148,7 +1145,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 @@
@@ -1165,14 +1162,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 @@
@@ -1187,7 +1184,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 @@
@@ -1204,30 +1201,15 @@ 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 @@
+one
EOF
-sanitize_output () {
- sed -e 's/ *$//' \
- -e 's/commit [0-9a-f]*$/commit COMMIT_OBJECT_NAME/' \
- -e 's/Merge: [ 0-9a-f]*$/Merge: MERGE_PARENTS/' \
- -e 's/Merge tag.*/Merge HEADS DESCRIPTION/' \
- -e 's/Merge commit.*/Merge HEADS DESCRIPTION/' \
- -e 's/, 0 deletions(-)//' \
- -e 's/, 0 insertions(+)//' \
- -e 's/ 1 files changed, / 1 file changed, /' \
- -e 's/, 1 deletions(-)/, 1 deletion(-)/' \
- -e 's/, 1 insertions(+)/, 1 insertion(+)/'
-}
-
test_expect_success 'log --graph with diff and stats' '
- git log --no-renames --graph --pretty=short --stat -p >actual &&
- sanitize_output >actual.sanitized <actual &&
- test_i18ncmp expect actual.sanitized
+ lib_test_cmp_short_graph --no-renames --stat -p
'
cat >expect <<\EOF
@@ -1247,7 +1229,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 @@
@@ -1270,7 +1252,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 @@
@@ -1286,7 +1268,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 @@
@@ -1302,7 +1284,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 @@
@@ -1336,7 +1318,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 @@
@@ -1358,7 +1340,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 @@
@@ -1374,7 +1356,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 @@
@@ -1390,7 +1372,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 @@
@@ -1406,7 +1388,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 @@
@@ -1422,7 +1404,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 @@
@@ -1438,7 +1420,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 @@
@@ -1455,14 +1437,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 @@
@@ -1477,7 +1459,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 @@
@@ -1494,7 +1476,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 @@
@@ -1502,9 +1484,7 @@ cat >expect <<\EOF
EOF
test_expect_success 'log --line-prefix="*** " --graph with diff and stats' '
- git log --line-prefix="*** " --no-renames --graph --pretty=short --stat -p >actual &&
- sanitize_output >actual.sanitized <actual &&
- test_i18ncmp expect actual.sanitized
+ lib_test_cmp_short_graph --line-prefix="*** " --no-renames --stat -p
'
cat >expect <<-\EOF
@@ -1526,9 +1506,7 @@ cat >expect <<-\EOF
EOF
test_expect_success 'log --graph with --name-status' '
- git log --graph --format=%s --name-status tangle..reach >actual &&
- sanitize_output <actual >actual.sanitized &&
- test_cmp expect actual.sanitized
+ test_cmp_graph --name-status tangle..reach
'
cat >expect <<-\EOF
@@ -1550,9 +1528,7 @@ cat >expect <<-\EOF
EOF
test_expect_success 'log --graph with --name-only' '
- git log --graph --format=%s --name-only tangle..reach >actual &&
- sanitize_output <actual >actual.sanitized &&
- test_cmp expect actual.sanitized
+ test_cmp_graph --name-only tangle..reach
'
test_expect_success 'dotdot is a parent directory' '
@@ -1570,6 +1546,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 &&
@@ -1580,6 +1564,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 &&
@@ -1611,6 +1607,86 @@ test_expect_success GPG 'log --graph --show-signature for merged tag' '
grep "^| | gpg: Good signature" actual
'
+test_expect_success GPG 'log --graph --show-signature for merged tag in shallow clone' '
+ test_when_finished "git reset --hard && git checkout master" &&
+ git checkout -b plain-shallow master &&
+ echo aaa >bar &&
+ git add bar &&
+ git commit -m bar_commit &&
+ git checkout --detach master &&
+ echo bbb >baz &&
+ git add baz &&
+ git commit -m baz_commit &&
+ git tag -s -m signed_tag_msg signed_tag_shallow &&
+ hash=$(git rev-parse HEAD) &&
+ git checkout plain-shallow &&
+ git merge --no-ff -m msg signed_tag_shallow &&
+ git clone --depth 1 --no-local . shallow &&
+ test_when_finished "rm -rf shallow" &&
+ git -C shallow log --graph --show-signature -n1 plain-shallow >actual &&
+ grep "tag signed_tag_shallow names a non-parent $hash" actual
+'
+
+test_expect_success GPG 'log --graph --show-signature for merged tag with missing key' '
+ test_when_finished "git reset --hard && git checkout master" &&
+ git checkout -b plain-nokey master &&
+ echo aaa >bar &&
+ git add bar &&
+ git commit -m bar_commit &&
+ git checkout -b tagged-nokey master &&
+ echo bbb >baz &&
+ git add baz &&
+ git commit -m baz_commit &&
+ git tag -s -m signed_tag_msg signed_tag_nokey &&
+ git checkout plain-nokey &&
+ git merge --no-ff -m msg signed_tag_nokey &&
+ GNUPGHOME=. git log --graph --show-signature -n1 plain-nokey >actual &&
+ grep "^|\\\ merged tag" actual &&
+ grep "^| | gpg: Signature made" actual &&
+ grep "^| | gpg: Can'"'"'t check signature: \(public key not found\|No public key\)" actual
+'
+
+test_expect_success GPG 'log --graph --show-signature for merged tag with bad signature' '
+ test_when_finished "git reset --hard && git checkout master" &&
+ git checkout -b plain-bad master &&
+ echo aaa >bar &&
+ git add bar &&
+ git commit -m bar_commit &&
+ git checkout -b tagged-bad master &&
+ echo bbb >baz &&
+ git add baz &&
+ git commit -m baz_commit &&
+ git tag -s -m signed_tag_msg signed_tag_bad &&
+ git cat-file tag signed_tag_bad >raw &&
+ sed -e "s/signed_tag_msg/forged/" raw >forged &&
+ git hash-object -w -t tag forged >forged.tag &&
+ git checkout plain-bad &&
+ git merge --no-ff -m msg "$(cat forged.tag)" &&
+ git log --graph --show-signature -n1 plain-bad >actual &&
+ grep "^|\\\ merged tag" actual &&
+ grep "^| | gpg: Signature made" actual &&
+ grep "^| | gpg: BAD signature from" actual
+'
+
+test_expect_success GPG 'log --show-signature for merged tag with GPG failure' '
+ test_when_finished "git reset --hard && git checkout master" &&
+ git checkout -b plain-fail master &&
+ echo aaa >bar &&
+ git add bar &&
+ git commit -m bar_commit &&
+ git checkout -b tagged-fail master &&
+ echo bbb >baz &&
+ git add baz &&
+ git commit -m baz_commit &&
+ git tag -s -m signed_tag_msg signed_tag_fail &&
+ git checkout plain-fail &&
+ git merge --no-ff -m msg signed_tag_fail &&
+ TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual &&
+ grep "^merged tag" actual &&
+ grep "^No signature" actual &&
+ ! grep "^gpg: Signature made" actual
+'
+
test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '
test_when_finished "git reset --hard && git checkout master" &&
test_config gpg.format x509 &&
@@ -1632,6 +1708,51 @@ test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '
grep "^| | gpgsm: Good signature" actual
'
+test_expect_success GPGSM 'log --graph --show-signature for merged tag x509 missing key' '
+ test_when_finished "git reset --hard && git checkout master" &&
+ test_config gpg.format x509 &&
+ test_config user.signingkey $GIT_COMMITTER_EMAIL &&
+ git checkout -b plain-x509-nokey master &&
+ echo aaa >bar &&
+ git add bar &&
+ git commit -m bar_commit &&
+ git checkout -b tagged-x509-nokey master &&
+ echo bbb >baz &&
+ git add baz &&
+ git commit -m baz_commit &&
+ git tag -s -m signed_tag_msg signed_tag_x509_nokey &&
+ git checkout plain-x509-nokey &&
+ git merge --no-ff -m msg signed_tag_x509_nokey &&
+ GNUPGHOME=. git log --graph --show-signature -n1 plain-x509-nokey >actual &&
+ grep "^|\\\ merged tag" actual &&
+ grep "^| | gpgsm: certificate not found" actual
+'
+
+test_expect_success GPGSM 'log --graph --show-signature for merged tag x509 bad signature' '
+ test_when_finished "git reset --hard && git checkout master" &&
+ test_config gpg.format x509 &&
+ test_config user.signingkey $GIT_COMMITTER_EMAIL &&
+ git checkout -b plain-x509-bad master &&
+ echo aaa >bar &&
+ git add bar &&
+ git commit -m bar_commit &&
+ git checkout -b tagged-x509-bad master &&
+ echo bbb >baz &&
+ git add baz &&
+ git commit -m baz_commit &&
+ git tag -s -m signed_tag_msg signed_tag_x509_bad &&
+ git cat-file tag signed_tag_x509_bad >raw &&
+ sed -e "s/signed_tag_msg/forged/" raw >forged &&
+ git hash-object -w -t tag forged >forged.tag &&
+ git checkout plain-x509-bad &&
+ git merge --no-ff -m msg "$(cat forged.tag)" &&
+ git log --graph --show-signature -n1 plain-x509-bad >actual &&
+ grep "^|\\\ merged tag" actual &&
+ grep "^| | gpgsm: Signature made" actual &&
+ grep "^| | gpgsm: invalid signature" actual
+'
+
+
test_expect_success GPG '--no-show-signature overrides --show-signature' '
git log -1 --show-signature --no-show-signature signed >actual &&
! grep "^gpg:" actual
@@ -1689,10 +1810,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
@@ -1700,19 +1821,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
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 6e61f57f09..c3792081e6 100755
--- a/t/t4210-log-i18n.sh
+++ b/t/t4210-log-i18n.sh
@@ -70,7 +70,7 @@ do
then
force_regex=.*
fi
- test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" "
+ 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
@@ -84,7 +84,7 @@ do
test_must_be_empty actual
"
- test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" "
+ 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
"
diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh
index 8319163744..cda58186c2 100755
--- a/t/t4211-line-log.sh
+++ b/t/t4211-line-log.sh
@@ -4,6 +4,7 @@ test_description='test log -L'
. ./test-lib.sh
test_expect_success 'setup (import history)' '
+ test_oid_init &&
git fast-import < "$TEST_DIRECTORY"/t4211/history.export &&
git reset --hard
'
@@ -11,7 +12,7 @@ test_expect_success 'setup (import history)' '
canned_test_1 () {
test_expect_$1 "$2" "
git log $2 >actual &&
- test_cmp \"\$TEST_DIRECTORY\"/t4211/expect.$3 actual
+ test_cmp \"\$TEST_DIRECTORY\"/t4211/$(test_oid algo)/expect.$3 actual
"
}
diff --git a/t/t4211/expect.beginning-of-file b/t/t4211/sha1/expect.beginning-of-file
index 91b4054898..91b4054898 100644
--- a/t/t4211/expect.beginning-of-file
+++ b/t/t4211/sha1/expect.beginning-of-file
diff --git a/t/t4211/expect.end-of-file b/t/t4211/sha1/expect.end-of-file
index bd25bb2f59..bd25bb2f59 100644
--- a/t/t4211/expect.end-of-file
+++ b/t/t4211/sha1/expect.end-of-file
diff --git a/t/t4211/expect.move-support-f b/t/t4211/sha1/expect.move-support-f
index c905e01bc2..c905e01bc2 100644
--- a/t/t4211/expect.move-support-f
+++ b/t/t4211/sha1/expect.move-support-f
diff --git a/t/t4211/expect.multiple b/t/t4211/sha1/expect.multiple
index 76ad5b598c..76ad5b598c 100644
--- a/t/t4211/expect.multiple
+++ b/t/t4211/sha1/expect.multiple
diff --git a/t/t4211/expect.multiple-overlapping b/t/t4211/sha1/expect.multiple-overlapping
index d930b6eec4..d930b6eec4 100644
--- a/t/t4211/expect.multiple-overlapping
+++ b/t/t4211/sha1/expect.multiple-overlapping
diff --git a/t/t4211/expect.multiple-superset b/t/t4211/sha1/expect.multiple-superset
index d930b6eec4..d930b6eec4 100644
--- a/t/t4211/expect.multiple-superset
+++ b/t/t4211/sha1/expect.multiple-superset
diff --git a/t/t4211/expect.parallel-change-f-to-main b/t/t4211/sha1/expect.parallel-change-f-to-main
index 052def8074..052def8074 100644
--- a/t/t4211/expect.parallel-change-f-to-main
+++ b/t/t4211/sha1/expect.parallel-change-f-to-main
diff --git a/t/t4211/expect.simple-f b/t/t4211/sha1/expect.simple-f
index a1f5bc49c8..a1f5bc49c8 100644
--- a/t/t4211/expect.simple-f
+++ b/t/t4211/sha1/expect.simple-f
diff --git a/t/t4211/expect.simple-f-to-main b/t/t4211/sha1/expect.simple-f-to-main
index a475768710..a475768710 100644
--- a/t/t4211/expect.simple-f-to-main
+++ b/t/t4211/sha1/expect.simple-f-to-main
diff --git a/t/t4211/expect.simple-main b/t/t4211/sha1/expect.simple-main
index 39ce39bebe..39ce39bebe 100644
--- a/t/t4211/expect.simple-main
+++ b/t/t4211/sha1/expect.simple-main
diff --git a/t/t4211/expect.simple-main-to-end b/t/t4211/sha1/expect.simple-main-to-end
index 8480bd9cc4..8480bd9cc4 100644
--- a/t/t4211/expect.simple-main-to-end
+++ b/t/t4211/sha1/expect.simple-main-to-end
diff --git a/t/t4211/expect.two-ranges b/t/t4211/sha1/expect.two-ranges
index 6109aa0dce..6109aa0dce 100644
--- a/t/t4211/expect.two-ranges
+++ b/t/t4211/sha1/expect.two-ranges
diff --git a/t/t4211/expect.vanishes-early b/t/t4211/sha1/expect.vanishes-early
index 1f7cd06941..1f7cd06941 100644
--- a/t/t4211/expect.vanishes-early
+++ b/t/t4211/sha1/expect.vanishes-early
diff --git a/t/t4211/sha256/expect.beginning-of-file b/t/t4211/sha256/expect.beginning-of-file
new file mode 100644
index 0000000000..5adfdfc1a1
--- /dev/null
+++ b/t/t4211/sha256/expect.beginning-of-file
@@ -0,0 +1,43 @@
+commit 62a40b38fa4f00800004aee81ef287b7201317594ebcb990f38cbe493b01d200
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:47:40 2013 +0100
+
+ change at very beginning
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -1,3 +1,4 @@
++#include <unistd.h>
+ #include <stdio.h>
+
+ long f(long x)
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -1,3 +1,3 @@
+ #include <stdio.h>
+
+-int f(int x)
++long f(long x)
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +1,3 @@
++#include <stdio.h>
++
++int f(int x)
diff --git a/t/t4211/sha256/expect.end-of-file b/t/t4211/sha256/expect.end-of-file
new file mode 100644
index 0000000000..03ab5c1784
--- /dev/null
+++ b/t/t4211/sha256/expect.end-of-file
@@ -0,0 +1,62 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -20,3 +20,5 @@
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
++
++/* incomplete lines are bad! */
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -20,3 +20,3 @@
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -19,3 +19,3 @@
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +18,3 @@
++ printf("%d\n", f(15));
++ return 0;
++}
diff --git a/t/t4211/sha256/expect.move-support-f b/t/t4211/sha256/expect.move-support-f
new file mode 100644
index 0000000000..223b4ed2a0
--- /dev/null
+++ b/t/t4211/sha256/expect.move-support-f
@@ -0,0 +1,80 @@
+commit 4f7a58195a92c400e28a2354328587f1ff14fb77f5cf894536f17ccbc72931b9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:49:50 2013 +0100
+
+ another simple change
+
+diff --git a/b.c b/b.c
+--- a/b.c
++++ b/b.c
+@@ -4,9 +4,9 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+- x >>= 1;
++ x /= 2;
+ s++;
+ }
+ return s;
+ }
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,9 +3,9 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,8 +3,9 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,8 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
diff --git a/t/t4211/sha256/expect.multiple b/t/t4211/sha256/expect.multiple
new file mode 100644
index 0000000000..ca00409b9a
--- /dev/null
+++ b/t/t4211/sha256/expect.multiple
@@ -0,0 +1,104 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,7 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
++
++/* incomplete lines are bad! */
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,5 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,9 +3,9 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+@@ -17,5 +17,5 @@
+ int main ()
+ {
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,8 +3,9 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,8 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
diff --git a/t/t4211/sha256/expect.multiple-overlapping b/t/t4211/sha256/expect.multiple-overlapping
new file mode 100644
index 0000000000..9015a45a25
--- /dev/null
+++ b/t/t4211/sha256/expect.multiple-overlapping
@@ -0,0 +1,187 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -4,19 +4,21 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
++
++/* incomplete lines are bad! */
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -4,19 +4,19 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:41 2013 +0100
+
+ touch comment
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,19 +3,19 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+- * A comment.
++ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,19 +3,19 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+ int main ()
+ {
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,18 +3,19 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+ int main ()
+ {
+ printf("%d\n", f(15));
+ return 0;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,18 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
++
++/*
++ * A comment.
++ */
++
++int main ()
++{
++ printf("%d\n", f(15));
++ return 0;
++}
diff --git a/t/t4211/sha256/expect.multiple-superset b/t/t4211/sha256/expect.multiple-superset
new file mode 100644
index 0000000000..9015a45a25
--- /dev/null
+++ b/t/t4211/sha256/expect.multiple-superset
@@ -0,0 +1,187 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -4,19 +4,21 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
++
++/* incomplete lines are bad! */
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -4,19 +4,19 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:41 2013 +0100
+
+ touch comment
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,19 +3,19 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+- * A comment.
++ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,19 +3,19 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+ int main ()
+ {
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,18 +3,19 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+ int main ()
+ {
+ printf("%d\n", f(15));
+ return 0;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,18 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
++
++/*
++ * A comment.
++ */
++
++int main ()
++{
++ printf("%d\n", f(15));
++ return 0;
++}
diff --git a/t/t4211/sha256/expect.parallel-change-f-to-main b/t/t4211/sha256/expect.parallel-change-f-to-main
new file mode 100644
index 0000000000..e68f8928ea
--- /dev/null
+++ b/t/t4211/sha256/expect.parallel-change-f-to-main
@@ -0,0 +1,160 @@
+commit 98117c2059b76c36995748fb97b02542aef477fe26379e94c18fd70f7790bc67
+Merge: b511694 4f7a581
+Author: Thomas Rast <trast@inf.ethz.ch>
+Date: Fri Apr 12 16:16:24 2013 +0200
+
+ Merge across the rename
+
+
+commit 4f7a58195a92c400e28a2354328587f1ff14fb77f5cf894536f17ccbc72931b9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:49:50 2013 +0100
+
+ another simple change
+
+diff --git a/b.c b/b.c
+--- a/b.c
++++ b/b.c
+@@ -4,14 +4,14 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+- x >>= 1;
++ x /= 2;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * This is only an example!
+ */
+
+
+commit b511694f5337663fbd697622993a5f8e1099eca84be4df313f2b3ee94a098b42
+Author: Thomas Rast <trast@inf.ethz.ch>
+Date: Fri Apr 12 16:15:57 2013 +0200
+
+ change on another line of history while rename happens
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -4,14 +4,14 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+- * This is only an example!
++ * This is only a short example!
+ */
+
+
+commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:41 2013 +0100
+
+ touch comment
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,14 +3,14 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+- * A comment.
++ * This is only an example!
+ */
+
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,14 +3,14 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,13 +3,14 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,13 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
++
++/*
++ * A comment.
++ */
++
diff --git a/t/t4211/sha256/expect.simple-f b/t/t4211/sha256/expect.simple-f
new file mode 100644
index 0000000000..65508d7c0b
--- /dev/null
+++ b/t/t4211/sha256/expect.simple-f
@@ -0,0 +1,59 @@
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,9 +3,9 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,8 +3,9 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,8 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
diff --git a/t/t4211/sha256/expect.simple-f-to-main b/t/t4211/sha256/expect.simple-f-to-main
new file mode 100644
index 0000000000..77b721c196
--- /dev/null
+++ b/t/t4211/sha256/expect.simple-f-to-main
@@ -0,0 +1,100 @@
+commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:41 2013 +0100
+
+ touch comment
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,14 +3,14 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+- * A comment.
++ * This is only an example!
+ */
+
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,14 +3,14 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,13 +3,14 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+ /*
+ * A comment.
+ */
+
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,13 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
++
++/*
++ * A comment.
++ */
++
diff --git a/t/t4211/sha256/expect.simple-main b/t/t4211/sha256/expect.simple-main
new file mode 100644
index 0000000000..d20708c9f9
--- /dev/null
+++ b/t/t4211/sha256/expect.simple-main
@@ -0,0 +1,68 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,5 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,5 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -17,5 +17,5 @@
+ int main ()
+ {
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +16,5 @@
++int main ()
++{
++ printf("%d\n", f(15));
++ return 0;
++}
diff --git a/t/t4211/sha256/expect.simple-main-to-end b/t/t4211/sha256/expect.simple-main-to-end
new file mode 100644
index 0000000000..617cdf3481
--- /dev/null
+++ b/t/t4211/sha256/expect.simple-main-to-end
@@ -0,0 +1,70 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,7 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
++
++/* incomplete lines are bad! */
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,5 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -17,5 +17,5 @@
+ int main ()
+ {
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +16,5 @@
++int main ()
++{
++ printf("%d\n", f(15));
++ return 0;
++}
diff --git a/t/t4211/sha256/expect.two-ranges b/t/t4211/sha256/expect.two-ranges
new file mode 100644
index 0000000000..af57c8b997
--- /dev/null
+++ b/t/t4211/sha256/expect.two-ranges
@@ -0,0 +1,102 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,5 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -18,5 +18,5 @@
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:16 2013 +0100
+
+ touch both functions
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,9 +3,9 @@
+-int f(int x)
++long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+@@ -17,5 +17,5 @@
+ int main ()
+ {
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
+
+commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:55 2013 +0100
+
+ change f()
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,8 +3,9 @@
+ int f(int x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
++ return s;
+ }
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +3,8 @@
++int f(int x)
++{
++ int s = 0;
++ while (x) {
++ x >>= 1;
++ s++;
++ }
++}
diff --git a/t/t4211/sha256/expect.vanishes-early b/t/t4211/sha256/expect.vanishes-early
new file mode 100644
index 0000000000..11ec9bdecf
--- /dev/null
+++ b/t/t4211/sha256/expect.vanishes-early
@@ -0,0 +1,39 @@
+commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -22,1 +24,1 @@
+-}
+\ No newline at end of file
++/* incomplete lines are bad! */
+
+commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -22,1 +22,1 @@
+-}
++}
+\ No newline at end of file
+
+commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:44:48 2013 +0100
+
+ initial
+
+diff --git a/a.c b/a.c
+--- /dev/null
++++ b/a.c
+@@ -0,0 +20,1 @@
++}
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 3ae8e51e50..a080325098 100755
--- a/t/t4214-log-graph-octopus.sh
+++ b/t/t4214-log-graph-octopus.sh
@@ -3,6 +3,16 @@
test_description='git log --graph of skewed left octopus merge.'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-log-graph.sh
+
+test_cmp_graph () {
+ cat >expect &&
+ lib_test_cmp_graph --color=never --date-order --format=%s "$@"
+}
+
+test_cmp_colored_graph () {
+ lib_test_cmp_colored_graph --date-order --format=%s "$@"
+}
test_expect_success 'set up merge history' '
test_commit initial &&
@@ -24,65 +34,55 @@ test_expect_success 'set up merge history' '
'
test_expect_success 'log --graph with tricky octopus merge, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph left octopus-merge <<-\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
- 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_cmp_colored_graph left octopus-merge
'
# Repeat the previous two tests with "normal" octopus merge (i.e.,
# without the first parent skewing to the "left" branch column).
test_expect_success 'log --graph with normal octopus merge, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph octopus-merge <<-\EOF
*---. octopus-merge
|\ \ \
| | | * 4
| | * | 3
| | |/
- | * | 2
+ | * / 2
| |/
- * | 1
+ * / 1
|/
* initial
EOF
- git log --color=never --graph --date-order --pretty=tformat:%s octopus-merge >actual.raw &&
- sed "s/ *\$//" actual.raw >actual &&
- test_cmp expect.uncolored actual
'
test_expect_success 'log --graph with normal octopus merge with colors' '
@@ -92,38 +92,33 @@ 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 octopus-merge >actual.colors.raw &&
- test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
- test_cmp expect.colors actual.colors
+ test_cmp_colored_graph octopus-merge
'
test_expect_success 'log --graph with normal octopus merge and child, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph after-merge <<-\EOF
* after-merge
*---. octopus-merge
|\ \ \
| | | * 4
| | * | 3
| | |/
- | * | 2
+ | * / 2
| |/
- * | 1
+ * / 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_failure 'log --graph with normal octopus and child merge with colors' '
+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
@@ -131,63 +126,54 @@ test_expect_failure 'log --graph with normal octopus and child merge with colors
<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> 2
<GREEN>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET>
- * <MAGENTA>|<RESET> 1
+ * <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_cmp_colored_graph after-merge
'
test_expect_success 'log --graph with tricky octopus merge and its child, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph left after-merge <<-\EOF
* left
| * after-merge
- | *---. octopus-merge
- | |\ \ \
- |/ / / /
+ | *-. octopus-merge
+ |/|\ \
| | | * 4
| | * | 3
| | |/
- | * | 2
+ | * / 2
| |/
- * | 1
+ * / 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_failure 'log --graph with tricky octopus merge and its child with colors' '
+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> *<MAGENTA>-<RESET><MAGENTA>-<RESET><CYAN>-<RESET><CYAN>.<RESET> octopus-merge
- <RED>|<RESET> <RED>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET> <CYAN>\<RESET>
- <RED>|<RESET><RED>/<RESET> <BLUE>/<RESET> <MAGENTA>/<RESET> <CYAN>/<RESET>
+ <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> 2
<RED>|<RESET> <CYAN>|<RESET><CYAN>/<RESET>
- * <CYAN>|<RESET> 1
+ * <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_cmp_colored_graph left after-merge
'
test_expect_success 'log --graph with crossover in octopus merge, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph after-4 octopus-merge <<-\EOF
* after-4
| *---. octopus-merge
| |\ \ \
@@ -204,12 +190,9 @@ test_expect_success 'log --graph with crossover in octopus merge, no color' '
|/
* 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_failure 'log --graph with crossover in octopus merge with colors' '
+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
@@ -228,13 +211,11 @@ test_expect_failure 'log --graph with crossover in octopus merge with colors' '
<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_cmp_colored_graph after-4 octopus-merge
'
test_expect_success 'log --graph with crossover in octopus merge and its child, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph after-4 after-merge <<-\EOF
* after-4
| * after-merge
| *---. octopus-merge
@@ -252,12 +233,9 @@ test_expect_success 'log --graph with crossover in octopus merge and its child,
|/
* 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_failure 'log --graph with crossover in octopus merge and its child with colors' '
+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
@@ -277,13 +255,11 @@ test_expect_failure 'log --graph with crossover in octopus merge and its child w
<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_cmp_colored_graph after-4 after-merge
'
test_expect_success 'log --graph with unrelated commit and octopus tip, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph after-initial octopus-merge <<-\EOF
* after-initial
| *---. octopus-merge
| |\ \ \
@@ -300,9 +276,6 @@ test_expect_success 'log --graph with unrelated commit and octopus tip, no color
|/
* 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' '
@@ -324,13 +297,11 @@ test_expect_success 'log --graph with unrelated commit and octopus tip with colo
<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_cmp_colored_graph after-initial octopus-merge
'
test_expect_success 'log --graph with unrelated commit and octopus child, no color' '
- cat >expect.uncolored <<-\EOF &&
+ test_cmp_graph after-initial after-merge <<-\EOF
* after-initial
| * after-merge
| *---. octopus-merge
@@ -348,12 +319,9 @@ test_expect_success 'log --graph with unrelated commit and octopus child, no col
|/
* 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_failure 'log --graph with unrelated commit and octopus child with colors' '
+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
@@ -373,9 +341,7 @@ test_expect_failure 'log --graph with unrelated commit and octopus child with co
<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_cmp_colored_graph after-initial after-merge
'
test_done
diff --git a/t/t4215-log-skewed-merges.sh b/t/t4215-log-skewed-merges.sh
new file mode 100755
index 0000000000..28d0779a8c
--- /dev/null
+++ b/t/t4215-log-skewed-merges.sh
@@ -0,0 +1,373 @@
+#!/bin/sh
+
+test_description='git log --graph of skewed merges'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-log-graph.sh
+
+check_graph () {
+ cat >expect &&
+ lib_test_cmp_graph --format=%s "$@"
+}
+
+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
+ lib_test_cmp_colored_graph --date-order --pretty=tformat:%s 6_1 6_3 6_5
+'
+
+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/t5100-mailinfo.sh b/t/t5100-mailinfo.sh
index 9690dcad4f..147e616533 100755
--- a/t/t5100-mailinfo.sh
+++ b/t/t5100-mailinfo.sh
@@ -213,4 +213,19 @@ test_expect_failure 'mailinfo -b separated double [PATCH]' '
test z"$subj" = z"Subject: [other] message"
'
+test_expect_success 'mailinfo handles unusual header whitespace' '
+ git mailinfo /dev/null /dev/null >actual <<-\EOF &&
+ From:Real Name <user@example.com>
+ Subject: extra spaces
+ EOF
+
+ cat >expect <<-\EOF &&
+ Author: Real Name
+ Email: user@example.com
+ Subject: extra spaces
+
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index 852dcd913f..c1811ea0f4 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 &&
@@ -144,7 +150,6 @@ test_expect_success 'pull request after push' '
git request-pull initial origin master:for-upstream >../request
) &&
sed -nf read-request.sed <request >digest &&
- cat digest &&
{
read task &&
read repository &&
@@ -173,7 +178,6 @@ test_expect_success 'request asks HEAD to be pulled' '
git request-pull initial "$downstream_url" >../request
) &&
sed -nf read-request.sed <request >digest &&
- cat digest &&
{
read task &&
read repository &&
diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh
index 91d51b35f9..ad07f2f7fc 100755
--- a/t/t5302-pack-index.sh
+++ b/t/t5302-pack-index.sh
@@ -6,9 +6,10 @@
test_description='pack index with 64-bit offsets and object CRC'
. ./test-lib.sh
-test_expect_success \
- 'setup' \
- 'rm -rf .git &&
+test_expect_success 'setup' '
+ test_oid_init &&
+ rawsz=$(test_oid rawsz) &&
+ rm -rf .git &&
git init &&
git config pack.threads 1 &&
i=1 &&
@@ -32,7 +33,8 @@ test_expect_success \
echo $tree &&
git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/"
} >obj-list &&
- git update-ref HEAD $commit'
+ git update-ref HEAD $commit
+'
test_expect_success \
'pack-objects with index version 1' \
@@ -157,10 +159,11 @@ test_expect_success \
offs_101=$(index_obj_offset 1.idx $sha1_101) &&
nr_099=$(index_obj_nr 1.idx $sha1_099) &&
chmod +w ".git/objects/pack/pack-${pack1}.pack" &&
+ recordsz=$((rawsz + 4)) &&
dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($offs_101 + 1)) \
if=".git/objects/pack/pack-${pack1}.idx" \
- skip=$((4 + 256 * 4 + $nr_099 * 24)) \
- bs=1 count=20 conv=notrunc &&
+ skip=$((4 + 256 * 4 + $nr_099 * recordsz)) \
+ bs=1 count=$rawsz conv=notrunc &&
git cat-file blob $sha1_101 > file_101_foo1'
test_expect_success \
@@ -200,8 +203,8 @@ test_expect_success \
chmod +w ".git/objects/pack/pack-${pack1}.pack" &&
dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($offs_101 + 1)) \
if=".git/objects/pack/pack-${pack1}.idx" \
- skip=$((8 + 256 * 4 + $nr_099 * 20)) \
- bs=1 count=20 conv=notrunc &&
+ skip=$((8 + 256 * 4 + $nr_099 * rawsz)) \
+ bs=1 count=$rawsz conv=notrunc &&
git cat-file blob $sha1_101 > file_101_foo2'
test_expect_success \
@@ -226,7 +229,7 @@ test_expect_success \
nr=$(index_obj_nr ".git/objects/pack/pack-${pack1}.idx" $obj) &&
chmod +w ".git/objects/pack/pack-${pack1}.idx" &&
printf xxxx | dd of=".git/objects/pack/pack-${pack1}.idx" conv=notrunc \
- bs=1 count=4 seek=$((8 + 256 * 4 + $(wc -l <obj-list) * 20 + $nr * 4)) &&
+ bs=1 count=4 seek=$((8 + 256 * 4 + $(wc -l <obj-list) * rawsz + $nr * 4)) &&
( while read obj
do git cat-file -p $obj >/dev/null || exit 1
done <obj-list ) &&
diff --git a/t/t5309-pack-delta-cycles.sh b/t/t5309-pack-delta-cycles.sh
index 491556dad9..55b787630f 100755
--- a/t/t5309-pack-delta-cycles.sh
+++ b/t/t5309-pack-delta-cycles.sh
@@ -4,15 +4,9 @@ test_description='test index-pack handling of delta cycles in packfiles'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-pack.sh
-if ! test_have_prereq SHA1
-then
- skip_all='not using SHA-1 for objects'
- test_done
-fi
-
# Two similar-ish objects that we have computed deltas between.
-A=01d7713666f4de822776c7622c10f1b07de280dc
-B=e68fe8129b546b101aee9510c5328e7f21ca1d18
+A=$(test_oid packlib_7_0)
+B=$(test_oid packlib_7_76)
# double-check our hand-constucted packs
test_expect_success 'index-pack works with a single delta (A->B)' '
@@ -62,13 +56,13 @@ test_expect_success 'index-pack detects REF_DELTA cycles' '
test_must_fail git index-pack --fix-thin --stdin <cycle.pack
'
-test_expect_failure 'failover to an object in another pack' '
+test_expect_success 'failover to an object in another pack' '
clear_packs &&
git index-pack --stdin <ab.pack &&
- git index-pack --stdin --fix-thin <cycle.pack
+ test_must_fail git index-pack --stdin --fix-thin <cycle.pack
'
-test_expect_failure 'failover to a duplicate object in the same pack' '
+test_expect_success 'failover to a duplicate object in the same pack' '
clear_packs &&
{
pack_header 3 &&
@@ -77,7 +71,7 @@ test_expect_failure 'failover to a duplicate object in the same pack' '
pack_obj $A
} >recoverable.pack &&
pack_trailer recoverable.pack &&
- git index-pack --fix-thin --stdin <recoverable.pack
+ test_must_fail git index-pack --fix-thin --stdin <recoverable.pack
'
test_done
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index 6640329ebf..8318781d2b 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -74,16 +74,24 @@ rev_list_tests() {
test_cmp expect actual
'
- test_expect_success "enumerate --objects ($state)" '
- git rev-list --objects --use-bitmap-index HEAD >tmp &&
- cut -d" " -f1 <tmp >tmp2 &&
- sort <tmp2 >actual &&
- git rev-list --objects HEAD >tmp &&
- cut -d" " -f1 <tmp >tmp2 &&
- sort <tmp2 >expect &&
+ test_expect_success "counting objects via bitmap ($state)" '
+ git rev-list --count --objects HEAD >expect &&
+ git rev-list --use-bitmap-index --count --objects HEAD >actual &&
test_cmp expect actual
'
+ test_expect_success "enumerate commits ($state)" '
+ git rev-list --use-bitmap-index HEAD >actual &&
+ git rev-list HEAD >expect &&
+ test_bitmap_traversal --no-confirm-bitmaps expect actual
+ '
+
+ test_expect_success "enumerate --objects ($state)" '
+ git rev-list --objects --use-bitmap-index HEAD >actual &&
+ git rev-list --objects HEAD >expect &&
+ test_bitmap_traversal expect actual
+ '
+
test_expect_success "bitmap --objects handles non-commit objects ($state)" '
git rev-list --objects --use-bitmap-index HEAD tagged-blob >actual &&
grep $blob actual
@@ -99,6 +107,20 @@ test_expect_success 'clone from bitmapped repository' '
test_cmp expect actual
'
+test_expect_success 'partial clone from bitmapped repository' '
+ test_config uploadpack.allowfilter true &&
+ git clone --no-local --bare --filter=blob:none . partial-clone.git &&
+ (
+ cd partial-clone.git &&
+ pack=$(echo objects/pack/*.pack) &&
+ git verify-pack -v "$pack" >have &&
+ awk "/blob/ { print \$1 }" <have >blobs &&
+ # we expect this single blob because of the direct ref
+ git rev-parse refs/tags/tagged-blob >expect &&
+ test_cmp expect blobs
+ )
+'
+
test_expect_success 'setup further non-bitmapped commits' '
test_commit_bulk --id=further 10
'
diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh
index f1708d415e..2a4557efc2 100755
--- a/t/t5313-pack-bounds-checks.sh
+++ b/t/t5313-pack-bounds-checks.sh
@@ -38,16 +38,27 @@ munge () {
# for the initial, and another ofs(4*nr) past that for the extended.
#
ofs_table () {
- echo $((4 + 4 + 4*256 + 20*$1 + 4*$1))
+ echo $((4 + 4 + 4*256 + $(test_oid rawsz)*$1 + 4*$1))
}
extended_table () {
echo $(($(ofs_table "$1") + 4*$1))
}
+test_expect_success 'setup' '
+ test_oid_init &&
+ test_oid_cache <<-EOF
+ oid000 sha1:1485
+ oid000 sha256:4222
+
+ oidfff sha1:74
+ oidfff sha256:1350
+ EOF
+'
+
test_expect_success 'set up base packfile and variables' '
# the hash of this content starts with ff, which
# makes some later computations much simpler
- echo 74 >file &&
+ echo $(test_oid oidfff) >file &&
git add file &&
git commit -m base &&
git repack -ad &&
@@ -140,10 +151,10 @@ test_expect_success 'bogus offset inside v2 extended table' '
# an extended table (if the first object were larger than 2^31).
#
# Note that the value is important here. We want $object as
- # the second entry in sorted-sha1 order. The sha1 of 1485 starts
+ # the second entry in sorted-hash order. The hash of this object starts
# with "000", which sorts before that of $object (which starts
# with "fff").
- second=$(echo 1485 | git hash-object -w --stdin) &&
+ second=$(test_oid oid000 | git hash-object -w --stdin) &&
do_pack "$object $second" --index-version=2 &&
# We have to make extra room for the table, so we cannot
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 d42b3efe39..9bf920ae17 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -19,8 +19,8 @@ test_expect_success 'verify graph with no graph file' '
test_expect_success 'write graph with no packs' '
cd "$TRASH_DIRECTORY/full" &&
- git commit-graph write --object-dir . &&
- test_path_is_missing info/commit-graph
+ git commit-graph write --object-dir $objdir &&
+ test_path_is_missing $objdir/info/commit-graph
'
test_expect_success 'exit with correct error on bad input to --stdin-packs' '
@@ -85,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
}
@@ -132,7 +132,7 @@ test_expect_success 'commit-graph write progress off for redirected stderr' '
test_expect_success 'commit-graph write force progress on for stderr' '
cd "$TRASH_DIRECTORY/full" &&
- git commit-graph write --progress 2>err &&
+ GIT_PROGRESS_DELAY=0 git commit-graph write --progress 2>err &&
test_file_not_empty err
'
@@ -150,7 +150,7 @@ test_expect_success 'commit-graph verify progress off for redirected stderr' '
test_expect_success 'commit-graph verify force progress on for stderr' '
cd "$TRASH_DIRECTORY/full" &&
- git commit-graph verify --progress 2>err &&
+ GIT_PROGRESS_DELAY=0 git commit-graph verify --progress 2>err &&
test_file_not_empty err
'
@@ -481,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"
'
@@ -629,7 +629,7 @@ test_expect_success 'corrupt commit-graph write (broken parent)' '
empty="$(git mktree </dev/null)" &&
cat >broken <<-EOF &&
tree $empty
- parent 0000000000000000000000000000000000000000
+ parent $ZERO_OID
author whatever <whatever@example.com> 1234 -0000
committer whatever <whatever@example.com> 1234 -0000
@@ -650,7 +650,7 @@ test_expect_success 'corrupt commit-graph write (missing tree)' '
cd repo &&
tree="$(git mktree </dev/null)" &&
cat >broken <<-EOF &&
- parent 0000000000000000000000000000000000000000
+ parent $ZERO_OID
author whatever <whatever@example.com> 1234 -0000
committer whatever <whatever@example.com> 1234 -0000
@@ -660,7 +660,7 @@ test_expect_success 'corrupt commit-graph write (missing tree)' '
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 get tree for" test_err
+ test_i18ngrep "unable to parse commit" test_err
)
'
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/t5321-pack-large-objects.sh b/t/t5321-pack-large-objects.sh
index a75eab87d3..8a56d98a0e 100755
--- a/t/t5321-pack-large-objects.sh
+++ b/t/t5321-pack-large-objects.sh
@@ -10,8 +10,8 @@ test_description='git pack-object with "large" deltas
. "$TEST_DIRECTORY"/lib-pack.sh
# Two similar-ish objects that we have computed deltas between.
-A=01d7713666f4de822776c7622c10f1b07de280dc
-B=e68fe8129b546b101aee9510c5328e7f21ca1d18
+A=$(test_oid packlib_7_0)
+B=$(test_oid packlib_7_76)
test_expect_success 'setup' '
clear_packs &&
diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh
index 115aabd141..53b2e6b455 100755
--- a/t/t5324-split-commit-graph.sh
+++ b/t/t5324-split-commit-graph.sh
@@ -11,7 +11,14 @@ test_expect_success 'setup repo' '
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() {
@@ -25,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
}
@@ -248,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
@@ -275,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
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/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index 7344253bfb..80750a817e 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -53,10 +53,10 @@ test_expect_success 'git commit --amend --no-post-rewrite' '
test ! -f post-rewrite.data
'
-test_expect_success 'git rebase' '
+test_expect_success 'git rebase --apply' '
git reset --hard D &&
clear_hook_input &&
- test_must_fail git rebase --onto A B &&
+ test_must_fail git rebase --apply --onto A B &&
echo C > foo &&
git add foo &&
git rebase --continue &&
@@ -68,10 +68,10 @@ test_expect_success 'git rebase' '
verify_hook_input
'
-test_expect_success 'git rebase --skip' '
+test_expect_success 'git rebase --apply --skip' '
git reset --hard D &&
clear_hook_input &&
- test_must_fail git rebase --onto A B &&
+ test_must_fail git rebase --apply --onto A B &&
test_must_fail git rebase --skip &&
echo D > foo &&
git add foo &&
@@ -84,10 +84,10 @@ test_expect_success 'git rebase --skip' '
verify_hook_input
'
-test_expect_success 'git rebase --skip the last one' '
+test_expect_success 'git rebase --apply --skip the last one' '
git reset --hard F &&
clear_hook_input &&
- test_must_fail git rebase --onto D A &&
+ test_must_fail git rebase --apply --onto D A &&
git rebase --skip &&
echo rebase >expected.args &&
cat >expected.data <<-EOF &&
@@ -128,7 +128,7 @@ test_expect_success 'git rebase -m --skip' '
verify_hook_input
'
-test_expect_success 'git rebase with implicit use of interactive backend' '
+test_expect_success 'git rebase with implicit use of merge backend' '
git reset --hard D &&
clear_hook_input &&
test_must_fail git rebase --keep-empty --onto A B &&
@@ -143,7 +143,7 @@ test_expect_success 'git rebase with implicit use of interactive backend' '
verify_hook_input
'
-test_expect_success 'git rebase --skip with implicit use of interactive backend' '
+test_expect_success 'git rebase --skip with implicit use of merge backend' '
git reset --hard D &&
clear_hook_input &&
test_must_fail git rebase --keep-empty --onto A B &&
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
index 2a8c449661..5d8f401d8e 100755
--- a/t/t5409-colorize-remote-messages.sh
+++ b/t/t5409-colorize-remote-messages.sh
@@ -56,14 +56,13 @@ test_expect_success 'short line' '
test_expect_success 'case-insensitive' '
git --git-dir child/.git -c color.remote=always push -f origin HEAD:refs/heads/case-insensitive 2>output &&
- cat output &&
test_decode_color <output >decoded &&
grep "<BOLD;RED>error<RESET>: error" decoded &&
grep "<BOLD;RED>ERROR<RESET>: also highlighted" decoded
'
test_expect_success 'leading space' '
- git --git-dir child/.git -c color.remote=always push -f origin HEAD:refs/heads/leading-space 2>output && cat output &&
+ git --git-dir child/.git -c color.remote=always push -f origin HEAD:refs/heads/leading-space 2>output &&
test_decode_color <output >decoded &&
grep " <BOLD;RED>error<RESET>: leading space" decoded
'
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 6b97923964..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
'
@@ -917,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' '
@@ -929,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
'
@@ -951,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' '
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/t5505-remote.sh b/t/t5505-remote.sh
index 883b32efa0..dda81b7d07 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -734,15 +734,53 @@ test_expect_success 'reject adding remote with an invalid name' '
# the last two ones check if the config is updated.
test_expect_success 'rename a remote' '
+ test_config_global remote.pushDefault origin &&
git clone one four &&
(
cd four &&
+ git config branch.master.pushRemote origin &&
git remote rename origin upstream &&
test -z "$(git for-each-ref refs/remotes/origin)" &&
test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" &&
test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" &&
test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" &&
- test "$(git config branch.master.remote)" = "upstream"
+ test "$(git config branch.master.remote)" = "upstream" &&
+ test "$(git config branch.master.pushRemote)" = "upstream" &&
+ test "$(git config --global remote.pushDefault)" = "origin"
+ )
+'
+
+test_expect_success 'rename a remote renames repo remote.pushDefault' '
+ git clone one four.1 &&
+ (
+ cd four.1 &&
+ git config remote.pushDefault origin &&
+ git remote rename origin upstream &&
+ test "$(git config --local remote.pushDefault)" = "upstream"
+ )
+'
+
+test_expect_success 'rename a remote renames repo remote.pushDefault but ignores global' '
+ test_config_global remote.pushDefault other &&
+ git clone one four.2 &&
+ (
+ cd four.2 &&
+ git config remote.pushDefault origin &&
+ git remote rename origin upstream &&
+ test "$(git config --global remote.pushDefault)" = "other" &&
+ test "$(git config --local remote.pushDefault)" = "upstream"
+ )
+'
+
+test_expect_success 'rename a remote renames repo remote.pushDefault but keeps global' '
+ test_config_global remote.pushDefault origin &&
+ git clone one four.3 &&
+ (
+ cd four.3 &&
+ git config remote.pushDefault origin &&
+ git remote rename origin upstream &&
+ test "$(git config --global remote.pushDefault)" = "origin" &&
+ test "$(git config --local remote.pushDefault)" = "upstream"
)
'
@@ -784,6 +822,54 @@ test_expect_success 'rename succeeds with existing remote.<target>.prune' '
git -C four.four remote rename origin upstream
'
+test_expect_success 'remove a remote' '
+ test_config_global remote.pushDefault origin &&
+ git clone one four.five &&
+ (
+ cd four.five &&
+ git config branch.master.pushRemote origin &&
+ git remote remove origin &&
+ test -z "$(git for-each-ref refs/remotes/origin)" &&
+ test_must_fail git config branch.master.remote &&
+ test_must_fail git config branch.master.pushRemote &&
+ test "$(git config --global remote.pushDefault)" = "origin"
+ )
+'
+
+test_expect_success 'remove a remote removes repo remote.pushDefault' '
+ git clone one four.five.1 &&
+ (
+ cd four.five.1 &&
+ git config remote.pushDefault origin &&
+ git remote remove origin &&
+ test_must_fail git config --local remote.pushDefault
+ )
+'
+
+test_expect_success 'remove a remote removes repo remote.pushDefault but ignores global' '
+ test_config_global remote.pushDefault other &&
+ git clone one four.five.2 &&
+ (
+ cd four.five.2 &&
+ git config remote.pushDefault origin &&
+ git remote remove origin &&
+ test "$(git config --global remote.pushDefault)" = "other" &&
+ test_must_fail git config --local remote.pushDefault
+ )
+'
+
+test_expect_success 'remove a remote removes repo remote.pushDefault but keeps global' '
+ test_config_global remote.pushDefault origin &&
+ git clone one four.five.3 &&
+ (
+ cd four.five.3 &&
+ git config remote.pushDefault origin &&
+ git remote remove origin &&
+ test "$(git config --global remote.pushDefault)" = "origin" &&
+ test_must_fail git config --local remote.pushDefault
+ )
+'
+
cat >remotes_origin <<EOF
URL: $(pwd)/one
Push: refs/heads/master:refs/heads/upstream
diff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh
index 75cbfcc392..a67f792adf 100755
--- a/t/t5509-fetch-push-namespaces.sh
+++ b/t/t5509-fetch-push-namespaces.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
) &&
commit0=$(cd original && git rev-parse HEAD^) &&
commit1=$(cd original && git rev-parse HEAD) &&
- git init pushee &&
+ git init --bare pushee &&
git init puller
'
@@ -152,4 +152,15 @@ test_expect_success 'clone chooses correct HEAD (v2)' '
test_cmp expect actual
'
+test_expect_success 'denyCurrentBranch and unborn branch with ref namespace' '
+ (
+ cd original &&
+ git init unborn &&
+ git remote add unborn-namespaced "ext::git --namespace=namespace %s unborn" &&
+ test_must_fail git push unborn-namespaced HEAD:master &&
+ git -C unborn config receive.denyCurrentBranch updateInstead &&
+ git push unborn-namespaced HEAD:master
+ )
+'
+
test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 4b60282689..a66dbe0bde 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' '
@@ -354,7 +379,6 @@ test_expect_success 'fetch from GIT URL with a non-applying branch.<name>.merge
# the strange name is: a\!'b
test_expect_success 'quoting of a strangely named repo' '
test_must_fail git fetch "a\\!'\''b" > result 2>&1 &&
- cat result &&
grep "fatal: '\''a\\\\!'\''b'\''" result
'
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/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh
index 961eb35c99..9d6a46ff56 100755
--- a/t/t5515-fetch-merge-logic.sh
+++ b/t/t5515-fetch-merge-logic.sh
@@ -8,15 +8,60 @@ 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
+build_script () {
+ script="$1" &&
+ for i in one three_file master master2 one_tree three two two2 three2
+ do
+ echo "s/$(test_oid --hash=sha1 "$i")/$(test_oid "$i")/g" >>"$script"
+ done
+}
+
+convert_expected () {
+ file="$1" &&
+ script="$2" &&
+ sed -f "$script" "$file" >"$file.tmp" &&
+ mv "$file.tmp" "$file"
+}
+
test_expect_success setup '
GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" &&
GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" &&
export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
+ test_oid_cache <<-EOF &&
+ one sha1:8e32a6d901327a23ef831511badce7bf3bf46689
+ one sha256:8739546433ab1ac72ee93088dce611210effee072b2b586ceac6dde43ebec9ce
+
+ three_file sha1:0e3b14047d3ee365f4f2a1b673db059c3972589c
+ three_file sha256:bc4447d50c07497a8bfe6eef817f2364ecca9d471452e43b52756cc1a908bd32
+
+ master sha1:6c9dec2b923228c9ff994c6cfe4ae16c12408dc5
+ master sha256:8521c3072461fcfe8f32d67f95cc6e6b832a2db2fa29769ffc788bce85ebcd75
+
+ one_tree sha1:22feea448b023a2d864ef94b013735af34d238ba
+ one_tree sha256:6e4743f4ef2356b881dda5e91f5c7cdffe870faf350bf7b312f80a20935f5d83
+
+ three sha1:c61a82b60967180544e3c19f819ddbd0c9f89899
+ three sha256:0cc6d1eda617ded715170786e31ba4e2d0185404ec5a3508dd0d73b324860c6a
+
+ two sha1:525b7fb068d59950d185a8779dc957c77eed73ba
+ two sha256:3b21de3440cd38c2a9e9b464adb923f7054949ed4c918e1a0ac4c95cd52774db
+
+ master2 sha1:754b754407bf032e9a2f9d5a9ad05ca79a6b228f
+ master2 sha256:6c7abaea8a6d8ef4d89877e68462758dc6774690fbbbb0e6d7dd57415c9abde0
+
+ two2 sha1:6134ee8f857693b96ff1cc98d3e2fd62b199e5a8
+ two2 sha256:87a2d3ee29c83a3dc7afd41c0606b11f67603120b910a7be7840accdc18344d4
+
+ three2 sha1:0567da4d5edd2ff4bb292a465ba9e64dcad9536b
+ three2 sha256:cceb3e8eca364fa9a0a39a1efbebecacc664af86cbbd8070571f5faeb5f0e8c3
+ EOF
+
echo >file original &&
git add file &&
git commit -a -m One &&
@@ -86,7 +131,8 @@ test_expect_success setup '
git config branch.br-$remote-octopus.remote $remote &&
git config branch.br-$remote-octopus.merge refs/heads/one &&
git config --add branch.br-$remote-octopus.merge two
- done
+ done &&
+ build_script sed_script
'
# Merge logic depends on branch properties and Pull: or .fetch lines
@@ -137,6 +183,10 @@ do
actual_r="$pfx-refs.$test"
test_expect_success "$cmd" '
+ cp "$expect_f" expect_f &&
+ convert_expected expect_f sed_script &&
+ cp "$expect_r" expect_r &&
+ convert_expected expect_r sed_script &&
{
echo "# $cmd"
set x $cmd; shift
@@ -152,18 +202,18 @@ do
cat .git/FETCH_HEAD
} >"$actual_f" &&
git show-ref >"$actual_r" &&
- if test -f "$expect_f"
+ if test -f "expect_f"
then
- test_cmp "$expect_f" "$actual_f" &&
+ test_cmp "expect_f" "$actual_f" &&
rm -f "$actual_f"
else
# this is to help developing new tests.
cp "$actual_f" "$expect_f"
false
fi &&
- if test -f "$expect_r"
+ if test -f "expect_r"
then
- test_cmp "$expect_r" "$actual_r" &&
+ test_cmp "expect_r" "$actual_r" &&
rm -f "$actual_r"
else
# this is to help developing new tests.
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index c81ca360ac..9ff041a093 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
'
@@ -1712,4 +1712,15 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
)
'
+test_expect_success 'denyCurrentBranch and worktrees' '
+ git worktree add new-wt &&
+ git clone . cloned &&
+ test_commit -C cloned first &&
+ test_config receive.denyCurrentBranch refuse &&
+ test_must_fail git -C cloned push origin HEAD:new-wt &&
+ test_config receive.denyCurrentBranch updateInstead &&
+ git -C cloned push origin HEAD:new-wt &&
+ test_must_fail git -C cloned push --delete origin new-wt
+'
+
test_done
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index cf4cc32fd0..2f86fca042 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,47 +239,66 @@ 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' '
+test_expect_success '--rebase (merge) fast forward' '
git reset --hard before-rebase &&
git checkout -b ff &&
echo another modification >file &&
git commit -m third file &&
git checkout to-rebase &&
- git pull --rebase . ff &&
- test "$(git rev-parse HEAD)" = "$(git rev-parse ff)" &&
+ git -c rebase.backend=merge pull --rebase . ff &&
+ test_cmp_rev HEAD ff &&
+
+ # The above only validates the result. Did we actually bypass rebase?
+ git reflog -1 >reflog.actual &&
+ sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
+ echo "OBJID HEAD@{0}: pull --rebase . ff: Fast-forward" >reflog.expected &&
+ test_cmp reflog.expected reflog.fuzzy
+'
+
+test_expect_success '--rebase (am) fast forward' '
+ git reset --hard before-rebase &&
+
+ git -c rebase.backend=apply pull --rebase . ff &&
+ test_cmp_rev HEAD ff &&
# The above only validates the result. Did we actually bypass rebase?
git reflog -1 >reflog.actual &&
@@ -287,7 +322,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' '
@@ -305,7 +340,7 @@ test_expect_success '--rebase with conflicts shows advice' '
test_tick &&
git commit -m "Create conflict" seq.txt &&
test_must_fail git pull --rebase . seq 2>err >out &&
- test_i18ngrep "Resolve all conflicts manually" out
+ test_i18ngrep "Resolve all conflicts manually" err
'
test_expect_success 'failed --rebase shows advice' '
@@ -319,15 +354,17 @@ test_expect_success 'failed --rebase shows advice' '
git checkout -f -b fails-to-rebase HEAD^ &&
test_commit v2-without-cr file "2" file2-lf &&
test_must_fail git pull --rebase . diverging 2>err >out &&
- test_i18ngrep "Resolve all conflicts manually" out
+ test_i18ngrep "Resolve all conflicts manually" err
'
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 +414,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 +434,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 +445,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 +487,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 +519,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 +531,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 +543,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 +579,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 +645,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 +660,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 +688,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 +706,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 +715,79 @@ 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 &&
+ cat .git/rebase-merge/done .git/rebase-merge/git-rebase-todo >work &&
+ grep -v -e \# -e ^$ work >patches &&
+ test_line_count = 1 patches &&
+ rm -f work
)
'
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 97a67728ca..4f681dbbe1 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
+ perl sha1:s/0034shallow %s/0036unshallow %s/
+ perl sha256:s/004cshallow %s/004eunshallow %s/
+ EOF
'
test_expect_success 'setup shallow clone' '
@@ -233,22 +237,22 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
git -C "$REPO" config protocol.version 2 &&
git -C client config protocol.version 2 &&
- git -C client fetch --depth=2 "$HTTPD_URL/one_time_sed/repo" master:a_branch &&
+ git -C client fetch --depth=2 "$HTTPD_URL/one_time_perl/repo" master:a_branch &&
# Craft a situation in which the server sends back an unshallow request
# 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 perl)" \
"$(git -C "$REPO" rev-parse HEAD)" \
"$(git -C "$REPO" rev-parse HEAD^)" \
- >"$HTTPD_ROOT_PATH/one-time-sed" &&
+ >"$HTTPD_ROOT_PATH/one-time-perl" &&
test_must_fail env GIT_TEST_SIDEBAND_ALL=0 git -C client \
- fetch --depth=1 "$HTTPD_URL/one_time_sed/repo" \
+ fetch --depth=1 "$HTTPD_URL/one_time_perl/repo" \
master:a_branch &&
- # Ensure that the one-time-sed script was used.
- ! test -e "$HTTPD_ROOT_PATH/one-time-sed" &&
+ # Ensure that the one-time-perl script was used.
+ ! test -e "$HTTPD_ROOT_PATH/one-time-perl" &&
# Ensure that the resulting repo is consistent, despite our failure to
# fetch.
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 4c970787b0..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
diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh
index 04b34c4de1..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 &&
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 f70cbcc9ca..156c704040 100755
--- a/t/t5552-skipping-fetch-negotiator.sh
+++ b/t/t5552-skipping-fetch-negotiator.sh
@@ -107,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^^^
'
@@ -169,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/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-unc-paths.sh
index b3c8a92450..cf768b3a27 100755
--- a/t/t5580-clone-push-unc.sh
+++ b/t/t5580-unc-paths.sh
@@ -40,11 +40,23 @@ test_expect_success clone '
git clone "file://$UNCPATH" clone
'
+test_expect_success 'clone without file://' '
+ git clone "$UNCPATH" clone-without-file
+'
+
test_expect_success 'clone with backslashed path' '
BACKSLASHED="$(echo "$UNCPATH" | tr / \\\\)" &&
git clone "$BACKSLASHED" backslashed
'
+test_expect_success fetch '
+ git init to-fetch &&
+ (
+ cd to-fetch &&
+ git fetch "$UNCPATH" master
+ )
+'
+
test_expect_success push '
(
cd clone &&
@@ -58,7 +70,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 ad8c41176e..84ea2a3eb7 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -635,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
}
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 b7a3fdf02d..9108ff6fbd 100755
--- a/t/t5607-clone-bundle.sh
+++ b/t/t5607-clone-bundle.sh
@@ -64,7 +64,7 @@ test_expect_success 'ridiculously long subject in boundary' '
test -s heads &&
git fetch long-subject-bundle.bdl &&
sed -n "/^-/{p;q;}" long-subject-bundle.bdl >boundary &&
- grep "^-[0-9a-f]\\{40\\} " boundary
+ grep "^-$OID_REGEX " boundary
'
test_expect_success 'prerequisites with an empty commit message' '
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 79f7b65f8c..77bb91e976 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -46,6 +46,14 @@ test_expect_success 'do partial clone 1' '
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.
test_expect_success 'verify checkout with dynamic object fetch' '
git -C pc1 rev-list --quiet --objects --missing=print HEAD >observed &&
@@ -296,6 +304,117 @@ test_expect_success 'partial clone with unresolvable sparse filter fails cleanly
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
+'
+
+# The following two tests must be in this order, or else
+# the first will not fail. It is important that the srv.bare
+# repository did not have tags during clone, but has tags
+# in the fetch.
+
+test_expect_failure 'verify fetch succeeds when asking for new tags' '
+ git clone --filter=blob:none "file://$(pwd)/srv.bare" tag-test &&
+ for i in I J K
+ do
+ test_commit -C src $i &&
+ git -C src branch $i || return 1
+ done &&
+ git -C srv.bare fetch --tags origin +refs/heads/*:refs/heads/* &&
+ git -C tag-test -c protocol.version=2 fetch --tags origin
+'
+
+test_expect_success 'verify fetch downloads only one pack when updating refs' '
+ git clone --filter=blob:none "file://$(pwd)/srv.bare" pack-test &&
+ ls pack-test/.git/objects/pack/*pack >pack-list &&
+ test_line_count = 2 pack-list &&
+ for i in A B C
+ do
+ test_commit -C src $i &&
+ git -C src branch $i || return 1
+ done &&
+ git -C srv.bare fetch origin +refs/heads/*:refs/heads/* &&
+ git -C pack-test fetch origin &&
+ ls pack-test/.git/objects/pack/*pack >pack-list &&
+ test_line_count = 3 pack-list
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@@ -310,14 +429,18 @@ intersperse () {
sed 's/\(..\)/'$1'\1/g'
}
-# Create a one-time-sed command to replace the existing packfile with $1.
+# Create a one-time-perl command to replace the existing packfile with $1.
replace_packfile () {
# The protocol requires that the packfile be sent in sideband 1, hence
# the extra \x01 byte at the beginning.
- printf "1,/packfile/!c %04x\\\\x01%s0000" \
- "$(($(wc -c <$1) + 5))" \
- "$(hex_unpack <$1 | intersperse '\\x')" \
- >"$HTTPD_ROOT_PATH/one-time-sed"
+ cp $1 "$HTTPD_ROOT_PATH/one-time-pack" &&
+ echo 'if (/packfile/) {
+ print;
+ my $length = -s "one-time-pack";
+ printf "%04x\x01", $length + 5;
+ print `cat one-time-pack` . "0000";
+ last
+ }' >"$HTTPD_ROOT_PATH/one-time-perl"
}
test_expect_success 'upon cloning, check that all refs point to objects' '
@@ -341,16 +464,16 @@ test_expect_success 'upon cloning, check that all refs point to objects' '
# \x01 byte at the beginning.
replace_packfile incomplete.pack &&
- # Use protocol v2 because the sed command looks for the "packfile"
+ # Use protocol v2 because the perl command looks for the "packfile"
# section header.
test_config -C "$SERVER" protocol.version 2 &&
test_must_fail git -c protocol.version=2 clone \
- --filter=blob:none $HTTPD_URL/one_time_sed/server repo 2>err &&
+ --filter=blob:none $HTTPD_URL/one_time_perl/server repo 2>err &&
test_i18ngrep "did not send all necessary objects" err &&
- # Ensure that the one-time-sed script was used.
- ! test -e "$HTTPD_ROOT_PATH/one-time-sed"
+ # Ensure that the one-time-perl script was used.
+ ! test -e "$HTTPD_ROOT_PATH/one-time-perl"
'
test_expect_success 'when partial cloning, tolerate server not sending target of tag' '
@@ -381,17 +504,17 @@ test_expect_success 'when partial cloning, tolerate server not sending target of
# \x01 byte at the beginning.
replace_packfile incomplete.pack &&
- # Use protocol v2 because the sed command looks for the "packfile"
+ # Use protocol v2 because the perl command looks for the "packfile"
# section header.
test_config -C "$SERVER" protocol.version 2 &&
# Exercise to make sure it works.
git -c protocol.version=2 clone \
- --filter=blob:none $HTTPD_URL/one_time_sed/server repo 2> err &&
+ --filter=blob:none $HTTPD_URL/one_time_perl/server repo 2> err &&
! grep "missing object referenced by" err &&
- # Ensure that the one-time-sed script was used.
- ! test -e "$HTTPD_ROOT_PATH/one-time-sed"
+ # Ensure that the one-time-perl script was used.
+ ! test -e "$HTTPD_ROOT_PATH/one-time-perl"
'
test_expect_success 'tolerate server sending REF_DELTA against missing promisor objects' '
@@ -414,7 +537,7 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
# Clone. The client has deltabase_have but not deltabase_missing.
git -c protocol.version=2 clone --no-checkout \
- --filter=blob:none $HTTPD_URL/one_time_sed/server repo &&
+ --filter=blob:none $HTTPD_URL/one_time_perl/server repo &&
git -C repo hash-object -w -- "$SERVER/have.txt" &&
# Sanity check to ensure that the client does not have
@@ -455,7 +578,7 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
replace_packfile thin.pack &&
- # Use protocol v2 because the sed command looks for the "packfile"
+ # Use protocol v2 because the perl command looks for the "packfile"
# section header.
test_config -C "$SERVER" protocol.version 2 &&
@@ -468,8 +591,8 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
grep "want $(cat deltabase_missing)" trace &&
! grep "want $(cat deltabase_have)" trace &&
- # Ensure that the one-time-sed script was used.
- ! test -e "$HTTPD_ROOT_PATH/one-time-sed"
+ # Ensure that the one-time-perl script was used.
+ ! test -e "$HTTPD_ROOT_PATH/one-time-perl"
'
# DO NOT add non-httpd-specific tests here, because the last part of this
diff --git a/t/t5617-clone-submodules-remote.sh b/t/t5617-clone-submodules-remote.sh
index 37fcce9c40..1a041df10b 100755
--- a/t/t5617-clone-submodules-remote.sh
+++ b/t/t5617-clone-submodules-remote.sh
@@ -14,7 +14,8 @@ test_expect_success 'setup' '
cd sub &&
git init &&
test_commit subcommit1 &&
- git tag sub_when_added_to_super
+ git tag sub_when_added_to_super &&
+ git branch other
) &&
git submodule add "file://$pwd/sub" sub &&
git commit -m "add submodule" &&
@@ -51,4 +52,14 @@ test_expect_success 'check the default is --no-remote-submodules' '
)
'
+test_expect_success 'clone with --single-branch' '
+ test_when_finished "rm -rf super_clone" &&
+ git clone --recurse-submodules --single-branch "file://$pwd/." super_clone &&
+ (
+ cd super_clone/sub &&
+ git rev-parse --verify origin/master &&
+ test_must_fail git rev-parse --verify origin/other
+ )
+'
+
test_done
diff --git a/t/t5700-protocol-v1.sh b/t/t5700-protocol-v1.sh
index 2571eb90b7..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
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index ae9175cedf..5039e66dc4 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 &&
@@ -665,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
@@ -682,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
'
@@ -700,11 +712,11 @@ test_expect_success 'when server sends "ready", expect DELIM' '
# After "ready" in the acknowledgments section, pretend that a FLUSH
# (0000) was sent instead of a DELIM (0001).
- printf "/ready/,$ s/0001/0000/" \
- >"$HTTPD_ROOT_PATH/one-time-sed" &&
+ printf "\$ready = 1 if /ready/; \$ready && s/0001/0000/" \
+ >"$HTTPD_ROOT_PATH/one-time-perl" &&
test_must_fail git -C http_child -c protocol.version=2 \
- fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
+ fetch "$HTTPD_URL/one_time_perl/http_parent" 2> err &&
test_i18ngrep "expected packfile to be sent after .ready." err
'
@@ -725,12 +737,12 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
# After the acknowledgments section, pretend that a DELIM
# (0001) was sent instead of a FLUSH (0000).
- printf "/acknowledgments/,$ s/0000/0001/" \
- >"$HTTPD_ROOT_PATH/one-time-sed" &&
+ printf "\$ack = 1 if /acknowledgments/; \$ack && s/0000/0001/" \
+ >"$HTTPD_ROOT_PATH/one-time-perl" &&
test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" git -C http_child \
-c protocol.version=2 \
- fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
+ fetch "$HTTPD_URL/one_time_perl/http_parent" 2> err &&
grep "fetch< .*acknowledgments" log &&
! grep "fetch< .*ready" log &&
test_i18ngrep "expected no other sections to be sent after no .ready." err
diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index 3a2c143c6d..7fba3063bf 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 -d" " -f1 | 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)
@@ -35,6 +37,7 @@ check_output () {
# \ | /
# a
test_expect_success 'setup repository' '
+ test_oid_init &&
test_commit a &&
git checkout -b o/foo &&
test_commit b &&
@@ -75,17 +78,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 +100,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 +125,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 +147,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
@@ -211,13 +222,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' '
@@ -239,13 +251,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
'
@@ -301,7 +314,7 @@ test_expect_success 'setup repos for change-while-negotiating test' '
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" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_perl/repo" &&
git -C "$LOCAL_PRISTINE" config protocol.version 2
'
@@ -312,17 +325,16 @@ inconsistency () {
# 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"
+ oid1=$(git -C "$REPO" rev-parse $1) &&
+ oid2=$(git -C "$REPO" rev-parse $2) &&
+ echo "s/$oid1/$oid2/" >"$HTTPD_ROOT_PATH/one-time-perl"
}
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 &&
+ inconsistency master $(test_oid numeric) &&
test_must_fail git -C local fetch 2>err &&
test_i18ngrep "fatal: remote error: upload-pack: not our ref" err
'
@@ -331,7 +343,7 @@ 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 &&
+ inconsistency master $(test_oid numeric) &&
git -C local fetch &&
git -C "$REPO" rev-parse --verify master >expected &&
@@ -367,7 +379,7 @@ 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" &&
+ echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-perl" &&
test_must_fail git -C local fetch 2>err &&
test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh
index b8cf82349b..3dc1ad8f71 100755
--- a/t/t6000-rev-list-misc.sh
+++ b/t/t6000-rev-list-misc.sh
@@ -104,13 +104,16 @@ test_expect_success 'rev-list can show index objects' '
# - we do not show the root tree; since we updated the index, it
# does not have a valid cache tree
#
- cat >expect <<-\EOF &&
- 8e4020bb5a8d8c873b25de15933e75cc0fc275df one
- d9d3a7417b9605cfd88ee6306b28dadc29e6ab08 only-in-index
- 9200b628cf9dc883a85a7abc8d6e6730baee589c two
- EOF
echo only-in-index >only-in-index &&
test_when_finished "git reset --hard" &&
+ rev1=$(git rev-parse HEAD:one) &&
+ rev2=$(git rev-parse HEAD:two) &&
+ revi=$(git hash-object only-in-index) &&
+ cat >expect <<-EOF &&
+ $rev1 one
+ $revi only-in-index
+ $rev2 two
+ EOF
git add only-in-index &&
git rev-list --objects --indexed-objects >actual &&
test_cmp expect actual
@@ -148,4 +151,16 @@ test_expect_success 'rev-list --end-of-options' '
test_cmp expect actual
'
+test_expect_success 'rev-list --count' '
+ count=$(git rev-list --count HEAD) &&
+ git rev-list HEAD >actual &&
+ test_line_count = $count actual
+'
+
+test_expect_success 'rev-list --count --objects' '
+ count=$(git rev-list --count --objects HEAD) &&
+ git rev-list --objects HEAD >actual &&
+ test_line_count = $count actual
+'
+
test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index cfb74d0e03..7e82e43a63 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -32,6 +32,7 @@ changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding)
truncate_count=20
test_expect_success 'setup' '
+ test_oid_init &&
: >foo &&
git add foo &&
git config i18n.commitEncoding $test_encoding &&
@@ -109,31 +110,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 +415,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)' '
@@ -459,9 +464,10 @@ test_expect_success '--abbrev' '
'
test_expect_success '%H is not affected by --abbrev-commit' '
+ expected=$(($(test_oid hexsz) + 1)) &&
git log -1 --format=%H --abbrev-commit --abbrev=20 HEAD >actual &&
len=$(wc -c <actual) &&
- test $len = 41
+ test $len = $expected
'
test_expect_success '%h is not affected by --abbrev-commit' '
@@ -495,7 +501,7 @@ 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
'
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/t6020-merge-df.sh b/t/t6020-merge-df.sh
index 46b506b3b7..400a4cd139 100755
--- a/t/t6020-merge-df.sh
+++ b/t/t6020-merge-df.sh
@@ -83,9 +83,9 @@ test_expect_success 'modify/delete + directory/file conflict' '
test 4 -eq $(git ls-files -u | wc -l) &&
test 1 -eq $(git ls-files -o | wc -l) &&
- test -f letters/file &&
- test -f letters.txt &&
- test -f letters~modify
+ test_path_is_file letters/file &&
+ test_path_is_file letters.txt &&
+ test_path_is_file letters~modify
'
test_expect_success 'modify/delete + directory/file conflict; other way' '
@@ -99,9 +99,52 @@ test_expect_success 'modify/delete + directory/file conflict; other way' '
test 4 -eq $(git ls-files -u | wc -l) &&
test 1 -eq $(git ls-files -o | wc -l) &&
- test -f letters/file &&
- test -f letters.txt &&
- test -f letters~HEAD
+ test_path_is_file letters/file &&
+ test_path_is_file letters.txt &&
+ test_path_is_file letters~HEAD
+'
+
+test_expect_success 'Simple merge in repo with interesting pathnames' '
+ # Simple lexicographic ordering of files and directories would be:
+ # foo
+ # foo/bar
+ # foo/bar-2
+ # foo/bar/baz
+ # foo/bar-2/baz
+ # The fact that foo/bar-2 appears between foo/bar and foo/bar/baz
+ # can trip up some codepaths, and is the point of this test.
+ test_create_repo name-ordering &&
+ (
+ cd name-ordering &&
+
+ mkdir -p foo/bar &&
+ mkdir -p foo/bar-2 &&
+ >foo/bar/baz &&
+ >foo/bar-2/baz &&
+ git add . &&
+ git commit -m initial &&
+
+ git branch main &&
+ git branch other &&
+
+ git checkout other &&
+ echo other >foo/bar-2/baz &&
+ git add -u &&
+ git commit -m other &&
+
+ git checkout main &&
+ echo main >foo/bar/baz &&
+ git add -u &&
+ git commit -m main &&
+
+ git merge other &&
+ git ls-files -s >out &&
+ test_line_count = 2 out &&
+ git rev-parse :0:foo/bar/baz :0:foo/bar-2/baz >actual &&
+ git rev-parse HEAD~1:foo/bar/baz other:foo/bar-2/baz >expect &&
+ test_cmp expect actual
+ )
+
'
test_done
diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh
index 213deecab1..9d5e992878 100755
--- a/t/t6021-merge-criss-cross.sh
+++ b/t/t6021-merge-criss-cross.sh
@@ -3,94 +3,65 @@
# 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.
test_description='Test criss-cross merge'
. ./test-lib.sh
-test_expect_success 'prepare repository' \
-'echo "1
-2
-3
-4
-5
-6
-7
-8
-9" > file &&
-git add file &&
-git commit -m "Initial commit" file &&
-git branch A &&
-git branch B &&
-git checkout A &&
-echo "1
-2
-3
-4
-5
-6
-7
-8 changed in B8, branch A
-9" > file &&
-git commit -m "B8" file &&
-git checkout B &&
-echo "1
-2
-3 changed in C3, branch B
-4
-5
-6
-7
-8
-9
-" > file &&
-git commit -m "C3" file &&
-git branch C3 &&
-git merge -m "pre E3 merge" A &&
-echo "1
-2
-3 changed in E3, branch B. New file size
-4
-5
-6
-7
-8 changed in B8, branch A
-9
-" > file &&
-git commit -m "E3" file &&
-git checkout A &&
-git merge -m "pre D8 merge" C3 &&
-echo "1
-2
-3 changed in C3, branch B
-4
-5
-6
-7
-8 changed in D8, branch A. New file size 2
-9" > file &&
-git commit -m D8 file'
-
-test_expect_success 'Criss-cross merge' 'git merge -m "final merge" B'
-
-cat > file-expect <<EOF
-1
-2
-3 changed in E3, branch B. New file size
-4
-5
-6
-7
-8 changed in D8, branch A. New file size 2
-9
-EOF
-
-test_expect_success 'Criss-cross merge result' 'cmp file file-expect'
-
-test_expect_success 'Criss-cross merge fails (-s resolve)' \
-'git reset --hard A^ &&
-test_must_fail git merge -s resolve -m "final merge" B'
+test_expect_success 'prepare repository' '
+ test_write_lines 1 2 3 4 5 6 7 8 9 >file &&
+ git add file &&
+ git commit -m "Initial commit" file &&
+
+ git branch A &&
+ git branch B &&
+ git checkout A &&
+
+ test_write_lines 1 2 3 4 5 6 7 "8 changed in B8, branch A" 9 >file &&
+ git commit -m "B8" file &&
+ git checkout B &&
+
+ test_write_lines 1 2 "3 changed in C3, branch B" 4 5 6 7 8 9 >file &&
+ git commit -m "C3" file &&
+ git branch C3 &&
+
+ git merge -m "pre E3 merge" A &&
+
+ test_write_lines 1 2 "3 changed in E3, branch B. New file size" 4 5 6 7 "8 changed in B8, branch A" 9 >file &&
+ git commit -m "E3" file &&
+
+ git checkout A &&
+ git merge -m "pre D8 merge" C3 &&
+ test_write_lines 1 2 "3 changed in C3, branch B" 4 5 6 7 "8 changed in D8, branch A. New file size 2" 9 >file &&
+
+ git commit -m D8 file
+'
+
+test_expect_success 'Criss-cross merge' '
+ git merge -m "final merge" B
+'
+
+test_expect_success 'Criss-cross merge result' '
+ cat <<-\EOF >file-expect &&
+ 1
+ 2
+ 3 changed in E3, branch B. New file size
+ 4
+ 5
+ 6
+ 7
+ 8 changed in D8, branch A. New file size 2
+ 9
+ EOF
+
+ test_cmp file-expect file
+'
+
+test_expect_success 'Criss-cross merge fails (-s resolve)' '
+ git reset --hard A^ &&
+ test_must_fail git merge -s resolve -m "final merge" B
+'
test_done
diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh
index 53cc9b2ffb..bbbba3dcbf 100755
--- a/t/t6022-merge-rename.sh
+++ b/t/t6022-merge-rename.sh
@@ -8,94 +8,94 @@ modify () {
mv "$2.x" "$2"
}
-test_expect_success setup \
-'
-cat >A <<\EOF &&
-a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-c cccccccccccccccccccccccccccccccccccccccccccccccc
-d dddddddddddddddddddddddddddddddddddddddddddddddd
-e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
-f ffffffffffffffffffffffffffffffffffffffffffffffff
-g gggggggggggggggggggggggggggggggggggggggggggggggg
-h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
-i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
-j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
-k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
-l llllllllllllllllllllllllllllllllllllllllllllllll
-m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
-n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
-o oooooooooooooooooooooooooooooooooooooooooooooooo
-EOF
-
-cat >M <<\EOF &&
-A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
-C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
-D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
-E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
-F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
-G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
-H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
-I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
-J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
-K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
-L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
-M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
-N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
-O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
-EOF
-
-git add A M &&
-git commit -m "initial has A and M" &&
-git branch white &&
-git branch red &&
-git branch blue &&
-git branch yellow &&
-git branch change &&
-git branch change+rename &&
-
-sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
-mv A+ A &&
-git commit -a -m "master updates A" &&
-
-git checkout yellow &&
-rm -f M &&
-git commit -a -m "yellow removes M" &&
-
-git checkout white &&
-sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
-sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
-rm -f A M &&
-git update-index --add --remove A B M N &&
-git commit -m "white renames A->B, M->N" &&
-
-git checkout red &&
-sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
-sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
-rm -f A M &&
-git update-index --add --remove A B M N &&
-git commit -m "red renames A->B, M->N" &&
-
-git checkout blue &&
-sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
-sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
-rm -f A M &&
-git update-index --add --remove A C M N &&
-git commit -m "blue renames A->C, M->N" &&
-
-git checkout change &&
-sed -e "/^g /s/.*/g : changed line/" <A >A+ &&
-mv A+ A &&
-git commit -q -a -m "changed" &&
-
-git checkout change+rename &&
-sed -e "/^g /s/.*/g : changed line/" <A >B &&
-rm A &&
-git update-index --add B &&
-git commit -q -a -m "changed and renamed" &&
-
-git checkout master'
+test_expect_success 'setup' '
+ cat >A <<-\EOF &&
+ a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ c cccccccccccccccccccccccccccccccccccccccccccccccc
+ d dddddddddddddddddddddddddddddddddddddddddddddddd
+ e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ f ffffffffffffffffffffffffffffffffffffffffffffffff
+ g gggggggggggggggggggggggggggggggggggggggggggggggg
+ h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+ k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ l llllllllllllllllllllllllllllllllllllllllllllllll
+ m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+ n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
+ o oooooooooooooooooooooooooooooooooooooooooooooooo
+ EOF
+
+ cat >M <<-\EOF &&
+ A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+ C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+ D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+ E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+ F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
+ H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
+ I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+ J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+ K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+ L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+ M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+ N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+ O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
+ EOF
+
+ git add A M &&
+ git commit -m "initial has A and M" &&
+ git branch white &&
+ git branch red &&
+ git branch blue &&
+ git branch yellow &&
+ git branch change &&
+ git branch change+rename &&
+
+ sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
+ mv A+ A &&
+ git commit -a -m "master updates A" &&
+
+ git checkout yellow &&
+ rm -f M &&
+ git commit -a -m "yellow removes M" &&
+
+ git checkout white &&
+ sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
+ sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
+ rm -f A M &&
+ git update-index --add --remove A B M N &&
+ git commit -m "white renames A->B, M->N" &&
+
+ git checkout red &&
+ sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
+ sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
+ rm -f A M &&
+ git update-index --add --remove A B M N &&
+ git commit -m "red renames A->B, M->N" &&
+
+ git checkout blue &&
+ sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
+ sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
+ rm -f A M &&
+ git update-index --add --remove A C M N &&
+ git commit -m "blue renames A->C, M->N" &&
+
+ git checkout change &&
+ sed -e "/^g /s/.*/g : changed line/" <A >A+ &&
+ mv A+ A &&
+ git commit -q -a -m "changed" &&
+
+ git checkout change+rename &&
+ sed -e "/^g /s/.*/g : changed line/" <A >B &&
+ rm A &&
+ git update-index --add B &&
+ git commit -q -a -m "changed and renamed" &&
+
+ git checkout master
+'
test_expect_success 'pull renaming branch into unrenaming one' \
'
@@ -242,12 +242,24 @@ test_expect_success 'merge of identical changes in a renamed file' '
rm -f A M N &&
git reset --hard &&
git checkout change+rename &&
+
+ test-tool chmtime --get -3600 B >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge change >out &&
- test_i18ngrep "^Skipped B" out &&
+
+ test-tool chmtime --get B >new-mtime &&
+ test_cmp old-mtime new-mtime &&
+
git reset --hard HEAD^ &&
git checkout change &&
+
+ # A will be renamed to B; we check mtimes and file presence
+ test_path_is_missing B &&
+ test-tool chmtime --get -3600 A >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge change+rename >out &&
- test_i18ngrep ! "^Skipped B" out
+
+ test_path_is_missing A &&
+ test-tool chmtime --get B >new-mtime &&
+ test $(cat old-mtime) -lt $(cat new-mtime)
'
test_expect_success 'setup for rename + d/f conflicts' '
@@ -288,14 +300,15 @@ test_expect_success 'setup for rename + d/f conflicts' '
git commit -m "Conflicting change"
'
-printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n11\n" >expected
-
test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' '
git reset --hard &&
git checkout -q renamed-file-has-no-conflicts^0 &&
+
git merge --strategy=recursive dir-not-in-way &&
+
git diff --quiet &&
- test -f dir &&
+ test_path_is_file dir &&
+ test_write_lines 1 2 3 4 5555 6 7 8 9 10 11 >expected &&
test_cmp expected dir
'
@@ -315,8 +328,8 @@ test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '
test_must_fail git diff --quiet &&
test_must_fail git diff --cached --quiet &&
- test -f dir/file-in-the-way &&
- test -f dir~HEAD &&
+ test_path_is_file dir/file-in-the-way &&
+ test_path_is_file dir~HEAD &&
test_cmp expected dir~HEAD
'
@@ -337,29 +350,11 @@ test_expect_success 'Same as previous, but merged other way' '
test_must_fail git diff --quiet &&
test_must_fail git diff --cached --quiet &&
- test -f dir/file-in-the-way &&
- test -f dir~renamed-file-has-no-conflicts &&
+ test_path_is_file dir/file-in-the-way &&
+ test_path_is_file dir~renamed-file-has-no-conflicts &&
test_cmp expected dir~renamed-file-has-no-conflicts
'
-cat >expected <<\EOF &&
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-<<<<<<< HEAD:dir
-12
-=======
-11
->>>>>>> dir-not-in-way:sub/file
-EOF
-
test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' '
git reset --hard &&
rm -rf dir~* &&
@@ -372,7 +367,24 @@ test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in
test_must_fail git diff --quiet &&
test_must_fail git diff --cached --quiet &&
- test -f dir &&
+ test_path_is_file dir &&
+ cat >expected <<-\EOF &&
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ <<<<<<< HEAD:dir
+ 12
+ =======
+ 11
+ >>>>>>> dir-not-in-way:sub/file
+ EOF
test_cmp expected dir
'
@@ -391,29 +403,11 @@ test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in t
test_must_fail git diff --quiet &&
test_must_fail git diff --cached --quiet &&
- test -f dir/file-in-the-way &&
- test -f dir~HEAD &&
+ test_path_is_file dir/file-in-the-way &&
+ test_path_is_file dir~HEAD &&
test_cmp expected dir~HEAD
'
-cat >expected <<\EOF &&
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-<<<<<<< HEAD:sub/file
-11
-=======
-12
->>>>>>> renamed-file-has-conflicts:dir
-EOF
-
test_expect_success 'Same as previous, but merged other way' '
git reset --hard &&
rm -rf dir~* &&
@@ -427,8 +421,25 @@ test_expect_success 'Same as previous, but merged other way' '
test_must_fail git diff --quiet &&
test_must_fail git diff --cached --quiet &&
- test -f dir/file-in-the-way &&
- test -f dir~renamed-file-has-conflicts &&
+ test_path_is_file dir/file-in-the-way &&
+ test_path_is_file dir~renamed-file-has-conflicts &&
+ cat >expected <<-\EOF &&
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ <<<<<<< HEAD:sub/file
+ 11
+ =======
+ 12
+ >>>>>>> renamed-file-has-conflicts:dir
+ EOF
test_cmp expected dir~renamed-file-has-conflicts
'
@@ -464,9 +475,9 @@ test_expect_success 'both rename source and destination involved in D/F conflict
test_must_fail git diff --quiet &&
- test -f destdir/foo &&
- test -f one &&
- test -f destdir~HEAD &&
+ test_path_is_file destdir/foo &&
+ test_path_is_file one &&
+ test_path_is_file destdir~HEAD &&
test "stuff" = "$(cat destdir~HEAD)"
'
@@ -507,9 +518,9 @@ test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked
test 4 -eq $(find . | grep -v .git | wc -l) &&
- test -d one &&
- test -f one~rename-two &&
- test -f two &&
+ test_path_is_dir one &&
+ test_path_is_file one~rename-two &&
+ test_path_is_file two &&
test "other" = $(cat one~rename-two) &&
test "stuff" = $(cat two)
'
@@ -527,8 +538,8 @@ test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean sta
test 3 -eq $(find . | grep -v .git | wc -l) &&
- test -f one &&
- test -f two &&
+ test_path_is_file one &&
+ test_path_is_file two &&
test "other" = $(cat one) &&
test "stuff" = $(cat two)
'
@@ -568,11 +579,11 @@ test_expect_success 'check handling of differently renamed file with D/F conflic
test 1 -eq "$(git ls-files -u original | wc -l)" &&
test 2 -eq "$(git ls-files -o | wc -l)" &&
- test -f one/file &&
- test -f two/file &&
- test -f one~HEAD &&
- test -f two~second-rename &&
- ! test -f original
+ test_path_is_file one/file &&
+ test_path_is_file two/file &&
+ test_path_is_file one~HEAD &&
+ test_path_is_file two~second-rename &&
+ test_path_is_missing original
'
test_expect_success 'setup rename one file to two; directories moving out of the way' '
@@ -607,9 +618,9 @@ test_expect_success 'check handling of differently renamed file with D/F conflic
test 1 -eq "$(git ls-files -u original | wc -l)" &&
test 0 -eq "$(git ls-files -o | wc -l)" &&
- test -f one &&
- test -f two &&
- ! test -f original
+ test_path_is_file one &&
+ test_path_is_file two &&
+ test_path_is_missing original
'
test_expect_success 'setup avoid unnecessary update, normal rename' '
@@ -635,7 +646,7 @@ test_expect_success 'setup avoid unnecessary update, normal rename' '
test_expect_success 'avoid unnecessary update, normal rename' '
git checkout -q avoid-unnecessary-update-1^0 &&
- test-tool chmtime --get =1000000000 rename >expect &&
+ test-tool chmtime --get -3600 rename >expect &&
git merge merge-branch-1 &&
test-tool chmtime --get rename >actual &&
test_cmp expect actual # "rename" should have stayed intact
@@ -667,7 +678,7 @@ test_expect_success 'setup to test avoiding unnecessary update, with D/F conflic
test_expect_success 'avoid unnecessary update, with D/F conflict' '
git checkout -q avoid-unnecessary-update-2^0 &&
- test-tool chmtime --get =1000000000 df >expect &&
+ test-tool chmtime --get -3600 df >expect &&
git merge merge-branch-2 &&
test-tool chmtime --get df >actual &&
test_cmp expect actual # "df" should have stayed intact
@@ -698,7 +709,7 @@ test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '
test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '
git checkout -q master^0 &&
- test-tool chmtime --get =1000000000 df >expect &&
+ test-tool chmtime --get -3600 df >expect &&
git merge side &&
test-tool chmtime --get df >actual &&
test_cmp expect actual # "df" should have stayed intact
@@ -727,7 +738,7 @@ test_expect_success 'setup avoid unnecessary update, modify/delete' '
test_expect_success 'avoid unnecessary update, modify/delete' '
git checkout -q master^0 &&
- test-tool chmtime --get =1000000000 file >expect &&
+ test-tool chmtime --get -3600 file >expect &&
test_must_fail git merge side &&
test-tool chmtime --get file >actual &&
test_cmp expect actual # "file" should have stayed intact
@@ -755,7 +766,7 @@ test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
test_expect_success 'avoid unnecessary update, rename/add-dest' '
git checkout -q master^0 &&
- test-tool chmtime --get =1000000000 newfile >expect &&
+ test-tool chmtime --get -3600 newfile >expect &&
git merge side &&
test-tool chmtime --get newfile >actual &&
test_cmp expect actual # "file" should have stayed intact
@@ -810,48 +821,48 @@ test_expect_success 'setup for use of extended merge markers' '
git commit -mC
'
-cat >expected <<\EOF &&
-1
-2
-3
-4
-5
-6
-7
-8
-<<<<<<< HEAD:renamed_file
-9
-=======
-8.5
->>>>>>> master^0:original_file
-EOF
-
test_expect_success 'merge master into rename has correct extended markers' '
git checkout rename^0 &&
test_must_fail git merge -s recursive master^0 &&
+
+ cat >expected <<-\EOF &&
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ <<<<<<< HEAD:renamed_file
+ 9
+ =======
+ 8.5
+ >>>>>>> master^0:original_file
+ EOF
test_cmp expected renamed_file
'
-cat >expected <<\EOF &&
-1
-2
-3
-4
-5
-6
-7
-8
-<<<<<<< HEAD:original_file
-8.5
-=======
-9
->>>>>>> rename^0:renamed_file
-EOF
-
test_expect_success 'merge rename into master has correct extended markers' '
git reset --hard &&
git checkout master^0 &&
test_must_fail git merge -s recursive rename^0 &&
+
+ cat >expected <<-\EOF &&
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ <<<<<<< HEAD:original_file
+ 8.5
+ =======
+ 9
+ >>>>>>> rename^0:renamed_file
+ EOF
test_cmp expected renamed_file
'
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index 51ee887a77..2f421d967a 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -3,56 +3,59 @@
test_description='RCS merge replacement: merge-file'
. ./test-lib.sh
-cat > orig.txt << EOF
-Dominus regit me,
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-EOF
-
-cat > new1.txt << EOF
-Dominus regit me,
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam tu mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
-
-cat > new2.txt << EOF
-Dominus regit me, et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-EOF
-
-cat > new3.txt << EOF
-DOMINUS regit me,
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-EOF
-
-cat > new4.txt << EOF
-Dominus regit me, et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-EOF
-printf "propter nomen suum." >> new4.txt
+test_expect_success 'setup' '
+ cat >orig.txt <<-\EOF &&
+ Dominus regit me,
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ EOF
+
+ cat >new1.txt <<-\EOF &&
+ Dominus regit me,
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam tu mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
+
+ cat >new2.txt <<-\EOF &&
+ Dominus regit me, et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ EOF
+
+ cat >new3.txt <<-\EOF &&
+ DOMINUS regit me,
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ EOF
+
+ cat >new4.txt <<-\EOF &&
+ Dominus regit me, et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ EOF
+
+ printf "propter nomen suum." >>new4.txt
+'
test_expect_success 'merge with no changes' '
cp orig.txt test.txt &&
@@ -60,9 +63,10 @@ test_expect_success 'merge with no changes' '
test_cmp test.txt orig.txt
'
-cp new1.txt test.txt
-test_expect_success "merge without conflict" \
- "git merge-file test.txt orig.txt new2.txt"
+test_expect_success "merge without conflict" '
+ cp new1.txt test.txt &&
+ git merge-file test.txt orig.txt new2.txt
+'
test_expect_success 'works in subdirectory' '
mkdir dir &&
@@ -73,151 +77,176 @@ test_expect_success 'works in subdirectory' '
test_path_is_missing a.txt
'
-cp new1.txt test.txt
-test_expect_success "merge without conflict (--quiet)" \
- "git merge-file --quiet test.txt orig.txt new2.txt"
-
-cp new1.txt test2.txt
-test_expect_failure "merge without conflict (missing LF at EOF)" \
- "git merge-file test2.txt orig.txt new4.txt"
-
-test_expect_failure "merge result added missing LF" \
- "test_cmp test.txt test2.txt"
-
-cp new4.txt test3.txt
-test_expect_success "merge without conflict (missing LF at EOF, away from change in the other file)" \
- "git merge-file --quiet test3.txt new2.txt new3.txt"
-
-cat > expect.txt << EOF
-DOMINUS regit me,
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-EOF
-printf "propter nomen suum." >> expect.txt
-
-test_expect_success "merge does not add LF away of change" \
- "test_cmp expect.txt test3.txt"
-
-cp test.txt backup.txt
-test_expect_success "merge with conflicts" \
- "test_must_fail git merge-file test.txt orig.txt new3.txt"
-
-cat > expect.txt << EOF
-<<<<<<< test.txt
-Dominus regit me, et nihil mihi deerit.
-=======
-DOMINUS regit me,
-et nihil mihi deerit.
->>>>>>> new3.txt
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam tu mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
-
-test_expect_success "expected conflict markers" "test_cmp expect.txt test.txt"
-
-cp backup.txt test.txt
-
-cat > expect.txt << EOF
-Dominus regit me, et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam tu mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
-test_expect_success "merge conflicting with --ours" \
- "git merge-file --ours test.txt orig.txt new3.txt && test_cmp expect.txt test.txt"
-cp backup.txt test.txt
-
-cat > expect.txt << EOF
-DOMINUS regit me,
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam tu mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
-test_expect_success "merge conflicting with --theirs" \
- "git merge-file --theirs test.txt orig.txt new3.txt && test_cmp expect.txt test.txt"
-cp backup.txt test.txt
-
-cat > expect.txt << EOF
-Dominus regit me, et nihil mihi deerit.
-DOMINUS regit me,
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam tu mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
-test_expect_success "merge conflicting with --union" \
- "git merge-file --union test.txt orig.txt new3.txt && test_cmp expect.txt test.txt"
-cp backup.txt test.txt
-
-test_expect_success "merge with conflicts, using -L" \
- "test_must_fail git merge-file -L 1 -L 2 test.txt orig.txt new3.txt"
-
-cat > expect.txt << EOF
-<<<<<<< 1
-Dominus regit me, et nihil mihi deerit.
-=======
-DOMINUS regit me,
-et nihil mihi deerit.
->>>>>>> new3.txt
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam tu mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
-
-test_expect_success "expected conflict markers, with -L" \
- "test_cmp expect.txt test.txt"
-
-sed "s/ tu / TU /" < new1.txt > new5.txt
-test_expect_success "conflict in removed tail" \
- "test_must_fail git merge-file -p orig.txt new1.txt new5.txt > out"
-
-cat > expect << EOF
-Dominus regit me,
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-<<<<<<< orig.txt
-=======
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam TU mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
->>>>>>> new5.txt
-EOF
-
-test_expect_success "expected conflict markers" "test_cmp expect out"
+test_expect_success "merge without conflict (--quiet)" '
+ cp new1.txt test.txt &&
+ git merge-file --quiet test.txt orig.txt new2.txt
+'
+
+test_expect_failure "merge without conflict (missing LF at EOF)" '
+ cp new1.txt test2.txt &&
+ git merge-file test2.txt orig.txt new4.txt
+'
+
+test_expect_failure "merge result added missing LF" '
+ test_cmp test.txt test2.txt
+'
+
+test_expect_success "merge without conflict (missing LF at EOF, away from change in the other file)" '
+ cp new4.txt test3.txt &&
+ git merge-file --quiet test3.txt new2.txt new3.txt
+'
+
+test_expect_success "merge does not add LF away of change" '
+ cat >expect.txt <<-\EOF &&
+ DOMINUS regit me,
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ EOF
+ printf "propter nomen suum." >>expect.txt &&
+
+ test_cmp expect.txt test3.txt
+'
+
+test_expect_success "merge with conflicts" '
+ cp test.txt backup.txt &&
+ test_must_fail git merge-file test.txt orig.txt new3.txt
+'
+
+test_expect_success "expected conflict markers" '
+ cat >expect.txt <<-\EOF &&
+ <<<<<<< test.txt
+ Dominus regit me, et nihil mihi deerit.
+ =======
+ DOMINUS regit me,
+ et nihil mihi deerit.
+ >>>>>>> new3.txt
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam tu mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
+
+ test_cmp expect.txt test.txt
+'
+
+test_expect_success "merge conflicting with --ours" '
+ cp backup.txt test.txt &&
+
+ cat >expect.txt <<-\EOF &&
+ Dominus regit me, et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam tu mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
+
+ git merge-file --ours test.txt orig.txt new3.txt &&
+ test_cmp expect.txt test.txt
+'
+
+test_expect_success "merge conflicting with --theirs" '
+ cp backup.txt test.txt &&
+
+ cat >expect.txt <<-\EOF &&
+ DOMINUS regit me,
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam tu mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
+
+ git merge-file --theirs test.txt orig.txt new3.txt &&
+ test_cmp expect.txt test.txt
+'
+
+test_expect_success "merge conflicting with --union" '
+ cp backup.txt test.txt &&
+
+ cat >expect.txt <<-\EOF &&
+ Dominus regit me, et nihil mihi deerit.
+ DOMINUS regit me,
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam tu mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
+
+ git merge-file --union test.txt orig.txt new3.txt &&
+ test_cmp expect.txt test.txt
+'
+
+test_expect_success "merge with conflicts, using -L" '
+ cp backup.txt test.txt &&
+
+ test_must_fail git merge-file -L 1 -L 2 test.txt orig.txt new3.txt
+'
+
+test_expect_success "expected conflict markers, with -L" '
+ cat >expect.txt <<-\EOF &&
+ <<<<<<< 1
+ Dominus regit me, et nihil mihi deerit.
+ =======
+ DOMINUS regit me,
+ et nihil mihi deerit.
+ >>>>>>> new3.txt
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam tu mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
+
+ test_cmp expect.txt test.txt
+'
+
+test_expect_success "conflict in removed tail" '
+ sed "s/ tu / TU /" <new1.txt >new5.txt &&
+ test_must_fail git merge-file -p orig.txt new1.txt new5.txt >out
+'
+
+test_expect_success "expected conflict markers" '
+ cat >expect <<-\EOF &&
+ Dominus regit me,
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ <<<<<<< orig.txt
+ =======
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam TU mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ >>>>>>> new5.txt
+ EOF
+
+ test_cmp expect out
+'
test_expect_success 'binary files cannot be merged' '
test_must_fail git merge-file -p \
@@ -225,59 +254,55 @@ test_expect_success 'binary files cannot be merged' '
grep "Cannot merge binary files" merge.err
'
-sed -e "s/deerit.\$/deerit;/" -e "s/me;\$/me./" < new5.txt > new6.txt
-sed -e "s/deerit.\$/deerit,/" -e "s/me;\$/me,/" < new5.txt > new7.txt
-
test_expect_success 'MERGE_ZEALOUS simplifies non-conflicts' '
+ sed -e "s/deerit.\$/deerit;/" -e "s/me;\$/me./" <new5.txt >new6.txt &&
+ sed -e "s/deerit.\$/deerit,/" -e "s/me;\$/me,/" <new5.txt >new7.txt &&
test_must_fail git merge-file -p new6.txt new5.txt new7.txt > output &&
- test 1 = $(grep ======= < output | wc -l)
-
+ test 1 = $(grep ======= <output | wc -l)
'
-sed -e 's/deerit./&%%%%/' -e "s/locavit,/locavit;/"< new6.txt | tr '%' '\012' > new8.txt
-sed -e 's/deerit./&%%%%/' -e "s/locavit,/locavit --/" < new7.txt | tr '%' '\012' > new9.txt
-
test_expect_success 'ZEALOUS_ALNUM' '
+ sed -e "s/deerit./&%%%%/" -e "s/locavit,/locavit;/" <new6.txt | tr % "\012" >new8.txt &&
+ sed -e "s/deerit./&%%%%/" -e "s/locavit,/locavit --/" <new7.txt | tr % "\012" >new9.txt &&
test_must_fail git merge-file -p \
- new8.txt new5.txt new9.txt > merge.out &&
- test 1 = $(grep ======= < merge.out | wc -l)
-
+ new8.txt new5.txt new9.txt >merge.out &&
+ test 1 = $(grep ======= <merge.out | wc -l)
'
-cat >expect <<\EOF
-Dominus regit me,
-<<<<<<< new8.txt
-et nihil mihi deerit;
+test_expect_success '"diff3 -m" style output (1)' '
+ cat >expect <<-\EOF &&
+ Dominus regit me,
+ <<<<<<< new8.txt
+ et nihil mihi deerit;
-In loco pascuae ibi me collocavit;
-super aquam refectionis educavit me.
-||||||| new5.txt
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-=======
-et nihil mihi deerit,
+ In loco pascuae ibi me collocavit;
+ super aquam refectionis educavit me.
+ ||||||| new5.txt
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ =======
+ et nihil mihi deerit,
-In loco pascuae ibi me collocavit --
-super aquam refectionis educavit me,
->>>>>>> new9.txt
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam TU mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
+ In loco pascuae ibi me collocavit --
+ super aquam refectionis educavit me,
+ >>>>>>> new9.txt
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam TU mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
-test_expect_success '"diff3 -m" style output (1)' '
test_must_fail git merge-file -p --diff3 \
new8.txt new5.txt new9.txt >actual &&
test_cmp expect actual
@@ -290,61 +315,64 @@ test_expect_success '"diff3 -m" style output (2)' '
test_cmp expect actual
'
-cat >expect <<\EOF
-Dominus regit me,
-<<<<<<<<<< new8.txt
-et nihil mihi deerit;
+test_expect_success 'marker size' '
+ cat >expect <<-\EOF &&
+ Dominus regit me,
+ <<<<<<<<<< new8.txt
+ et nihil mihi deerit;
-In loco pascuae ibi me collocavit;
-super aquam refectionis educavit me.
-|||||||||| new5.txt
-et nihil mihi deerit.
-In loco pascuae ibi me collocavit,
-super aquam refectionis educavit me;
-==========
-et nihil mihi deerit,
+ In loco pascuae ibi me collocavit;
+ super aquam refectionis educavit me.
+ |||||||||| new5.txt
+ et nihil mihi deerit.
+ In loco pascuae ibi me collocavit,
+ super aquam refectionis educavit me;
+ ==========
+ et nihil mihi deerit,
-In loco pascuae ibi me collocavit --
-super aquam refectionis educavit me,
->>>>>>>>>> new9.txt
-animam meam convertit,
-deduxit me super semitas jusitiae,
-propter nomen suum.
-Nam et si ambulavero in medio umbrae mortis,
-non timebo mala, quoniam TU mecum es:
-virga tua et baculus tuus ipsa me consolata sunt.
-EOF
+ In loco pascuae ibi me collocavit --
+ super aquam refectionis educavit me,
+ >>>>>>>>>> new9.txt
+ animam meam convertit,
+ deduxit me super semitas jusitiae,
+ propter nomen suum.
+ Nam et si ambulavero in medio umbrae mortis,
+ non timebo mala, quoniam TU mecum es:
+ virga tua et baculus tuus ipsa me consolata sunt.
+ EOF
-test_expect_success 'marker size' '
test_must_fail git merge-file -p --marker-size=10 \
new8.txt new5.txt new9.txt >actual &&
test_cmp expect actual
'
-printf "line1\nline2\nline3" >nolf-orig.txt
-printf "line1\nline2\nline3x" >nolf-diff1.txt
-printf "line1\nline2\nline3y" >nolf-diff2.txt
+test_expect_success 'conflict at EOF without LF resolved by --ours' '
+ printf "line1\nline2\nline3" >nolf-orig.txt &&
+ printf "line1\nline2\nline3x" >nolf-diff1.txt &&
+ printf "line1\nline2\nline3y" >nolf-diff2.txt &&
-test_expect_success 'conflict at EOF without LF resolved by --ours' \
- 'git merge-file -p --ours nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
- printf "line1\nline2\nline3x" >expect.txt &&
- test_cmp expect.txt output.txt'
+ git merge-file -p --ours nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
+ printf "line1\nline2\nline3x" >expect.txt &&
+ test_cmp expect.txt output.txt
+'
-test_expect_success 'conflict at EOF without LF resolved by --theirs' \
- 'git merge-file -p --theirs nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
- printf "line1\nline2\nline3y" >expect.txt &&
- test_cmp expect.txt output.txt'
+test_expect_success 'conflict at EOF without LF resolved by --theirs' '
+ git merge-file -p --theirs nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
+ printf "line1\nline2\nline3y" >expect.txt &&
+ test_cmp expect.txt output.txt
+'
-test_expect_success 'conflict at EOF without LF resolved by --union' \
- 'git merge-file -p --union nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
- printf "line1\nline2\nline3x\nline3y" >expect.txt &&
- test_cmp expect.txt output.txt'
+test_expect_success 'conflict at EOF without LF resolved by --union' '
+ git merge-file -p --union nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
+ printf "line1\nline2\nline3x\nline3y" >expect.txt &&
+ test_cmp expect.txt output.txt
+'
test_expect_success 'conflict sections match existing line endings' '
printf "1\\r\\n2\\r\\n3" >crlf-orig.txt &&
diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh
index 27c7de90ce..332cfc53fd 100755
--- a/t/t6024-recursive-merge.sh
+++ b/t/t6024-recursive-merge.sh
@@ -14,85 +14,95 @@ 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_oid_cache <<-EOF
+ idxstage1 sha1:ec3fe2a791706733f2d8fa7ad45d9a9672031f5e
+ idxstage1 sha256:b3c8488929903aaebdeb22270cb6d36e5b8724b01ae0d4da24632f158c99676f
+ EOF
'
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 $(test_oid idxstage1) 1 a1
+ 100644 $(git rev-parse F:a1) 2 a1
+ 100644 $(git rev-parse G:a1) 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 +126,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/t6026-merge-attr.sh b/t/t6026-merge-attr.sh
index 8f9b48a493..5900358ce9 100755
--- a/t/t6026-merge-attr.sh
+++ b/t/t6026-merge-attr.sh
@@ -32,7 +32,29 @@ test_expect_success setup '
test_tick &&
git commit -m Side &&
- git tag anchor
+ git tag anchor &&
+
+ cat >./custom-merge <<-\EOF &&
+ #!/bin/sh
+
+ orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
+ (
+ echo "orig is $orig"
+ echo "ours is $ours"
+ echo "theirs is $theirs"
+ echo "path is $path"
+ echo "=== orig ==="
+ cat "$orig"
+ echo "=== ours ==="
+ cat "$ours"
+ echo "=== theirs ==="
+ cat "$theirs"
+ ) >"$ours+"
+ cat "$ours+" >"$ours"
+ rm -f "$ours+"
+ exit "$exit"
+ EOF
+ chmod +x ./custom-merge
'
test_expect_success merge '
@@ -82,28 +104,6 @@ test_expect_success 'retry the merge with longer context' '
grep "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" actual
'
-cat >./custom-merge <<\EOF
-#!/bin/sh
-
-orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
-(
- echo "orig is $orig"
- echo "ours is $ours"
- echo "theirs is $theirs"
- echo "path is $path"
- echo "=== orig ==="
- cat "$orig"
- echo "=== ours ==="
- cat "$ours"
- echo "=== theirs ==="
- cat "$theirs"
-) >"$ours+"
-cat "$ours+" >"$ours"
-rm -f "$ours+"
-exit "$exit"
-EOF
-chmod +x ./custom-merge
-
test_expect_success 'custom merge backend' '
echo "* merge=union" >.gitattributes &&
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/t6034-merge-rename-nocruft.sh b/t/t6034-merge-rename-nocruft.sh
index 89871aa5b0..a25e730460 100755
--- a/t/t6034-merge-rename-nocruft.sh
+++ b/t/t6034-merge-rename-nocruft.sh
@@ -3,74 +3,73 @@
test_description='Merge-recursive merging renames'
. ./test-lib.sh
-test_expect_success setup \
-'
-cat >A <<\EOF &&
-a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-c cccccccccccccccccccccccccccccccccccccccccccccccc
-d dddddddddddddddddddddddddddddddddddddddddddddddd
-e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
-f ffffffffffffffffffffffffffffffffffffffffffffffff
-g gggggggggggggggggggggggggggggggggggggggggggggggg
-h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
-i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
-j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
-k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
-l llllllllllllllllllllllllllllllllllllllllllllllll
-m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
-n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
-o oooooooooooooooooooooooooooooooooooooooooooooooo
-EOF
+test_expect_success 'setup' '
+ cat >A <<-\EOF &&
+ a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ c cccccccccccccccccccccccccccccccccccccccccccccccc
+ d dddddddddddddddddddddddddddddddddddddddddddddddd
+ e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ f ffffffffffffffffffffffffffffffffffffffffffffffff
+ g gggggggggggggggggggggggggggggggggggggggggggggggg
+ h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+ k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ l llllllllllllllllllllllllllllllllllllllllllllllll
+ m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+ n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
+ o oooooooooooooooooooooooooooooooooooooooooooooooo
+ EOF
-cat >M <<\EOF &&
-A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
-C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
-D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
-E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
-F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
-G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
-H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
-I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
-J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
-K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
-L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
-M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
-N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
-O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
-EOF
+ cat >M <<-\EOF &&
+ A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+ C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+ D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+ E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+ F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
+ H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
+ I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+ J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+ K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+ L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+ M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+ N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+ O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
+ EOF
-git add A M &&
-git commit -m "initial has A and M" &&
-git branch white &&
-git branch red &&
-git branch blue &&
+ git add A M &&
+ git commit -m "initial has A and M" &&
+ git branch white &&
+ git branch red &&
+ git branch blue &&
-git checkout white &&
-sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
-sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
-rm -f A M &&
-git update-index --add --remove A B M N &&
-git commit -m "white renames A->B, M->N" &&
+ git checkout white &&
+ sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
+ sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
+ rm -f A M &&
+ git update-index --add --remove A B M N &&
+ git commit -m "white renames A->B, M->N" &&
-git checkout red &&
-echo created by red >R &&
-git update-index --add R &&
-git commit -m "red creates R" &&
+ git checkout red &&
+ echo created by red >R &&
+ git update-index --add R &&
+ git commit -m "red creates R" &&
-git checkout blue &&
-sed -e "/^o /s/.*/g : blue changes a line/" <A >B &&
-rm -f A &&
-mv B A &&
-git update-index A &&
-git commit -m "blue modify A" &&
+ git checkout blue &&
+ sed -e "/^o /s/.*/g : blue changes a line/" <A >B &&
+ rm -f A &&
+ mv B A &&
+ git update-index A &&
+ git commit -m "blue modify A" &&
-git checkout master'
+ git checkout master
+'
# This test broke in 65ac6e9c3f47807cb603af07a6a9e1a43bc119ae
-test_expect_success 'merge white into red (A->B,M->N)' \
-'
+test_expect_success 'merge white into red (A->B,M->N)' '
git checkout -b red-white red &&
git merge white &&
git write-tree &&
@@ -82,8 +81,7 @@ test_expect_success 'merge white into red (A->B,M->N)' \
'
# This test broke in 8371234ecaaf6e14fe3f2082a855eff1bbd79ae9
-test_expect_success 'merge blue into white (A->B, mod A, A untracked)' \
-'
+test_expect_success 'merge blue into white (A->B, mod A, A untracked)' '
git checkout -b white-blue white &&
echo dirty >A &&
git merge blue &&
diff --git a/t/t6035-merge-dir-to-symlink.sh b/t/t6035-merge-dir-to-symlink.sh
index 9324ea4416..2eddcc7664 100755
--- a/t/t6035-merge-dir-to-symlink.sh
+++ b/t/t6035-merge-dir-to-symlink.sh
@@ -31,19 +31,19 @@ test_expect_success 'a/b-2/c/d is kept when clobbering symlink b' '
git rm --cached a/b &&
git commit -m "untracked symlink remains" &&
git checkout -f start^0 &&
- test -f a/b-2/c/d
+ test_path_is_file a/b-2/c/d
'
test_expect_success 'checkout should not have deleted a/b-2/c/d' '
git checkout HEAD^0 &&
git reset --hard master &&
git checkout start^0 &&
- test -f a/b-2/c/d
+ test_path_is_file a/b-2/c/d
'
test_expect_success 'setup for merge test' '
git reset --hard &&
- test -f a/b-2/c/d &&
+ test_path_is_file a/b-2/c/d &&
echo x > a/x &&
git add a/x &&
git commit -m x &&
@@ -54,7 +54,7 @@ test_expect_success 'Handle D/F conflict, do not lose a/b-2/c/d in merge (resolv
git reset --hard &&
git checkout baseline^0 &&
git merge -s resolve master &&
- test -f a/b-2/c/d
+ test_path_is_file a/b-2/c/d
'
test_expect_success SYMLINKS 'a/b was resolved as symlink' '
@@ -65,7 +65,7 @@ test_expect_success 'Handle D/F conflict, do not lose a/b-2/c/d in merge (recurs
git reset --hard &&
git checkout baseline^0 &&
git merge -s recursive master &&
- test -f a/b-2/c/d
+ test_path_is_file a/b-2/c/d
'
test_expect_success SYMLINKS 'a/b was resolved as symlink' '
@@ -76,7 +76,7 @@ test_expect_success 'Handle F/D conflict, do not lose a/b-2/c/d in merge (resolv
git reset --hard &&
git checkout master^0 &&
git merge -s resolve baseline^0 &&
- test -f a/b-2/c/d
+ test_path_is_file a/b-2/c/d
'
test_expect_success SYMLINKS 'a/b was resolved as symlink' '
@@ -87,7 +87,7 @@ test_expect_success 'Handle F/D conflict, do not lose a/b-2/c/d in merge (recurs
git reset --hard &&
git checkout master^0 &&
git merge -s recursive baseline^0 &&
- test -f a/b-2/c/d
+ test_path_is_file a/b-2/c/d
'
test_expect_success SYMLINKS 'a/b was resolved as symlink' '
@@ -99,8 +99,8 @@ test_expect_failure 'do not lose untracked in merge (resolve)' '
git checkout baseline^0 &&
>a/b/c/e &&
test_must_fail git merge -s resolve master &&
- test -f a/b/c/e &&
- test -f a/b-2/c/d
+ test_path_is_file a/b/c/e &&
+ test_path_is_file a/b-2/c/d
'
test_expect_success 'do not lose untracked in merge (recursive)' '
@@ -108,8 +108,8 @@ test_expect_success 'do not lose untracked in merge (recursive)' '
git checkout baseline^0 &&
>a/b/c/e &&
test_must_fail git merge -s recursive master &&
- test -f a/b/c/e &&
- test -f a/b-2/c/d
+ test_path_is_file a/b/c/e &&
+ test_path_is_file a/b-2/c/d
'
test_expect_success 'do not lose modifications in merge (resolve)' '
@@ -140,7 +140,7 @@ test_expect_success 'merge should not have D/F conflicts (resolve)' '
git reset --hard &&
git checkout baseline^0 &&
git merge -s resolve test2 &&
- test -f a/b/c/d
+ test_path_is_file a/b/c/d
'
test_expect_success SYMLINKS 'a/b-2 was resolved as symlink' '
@@ -151,7 +151,7 @@ test_expect_success 'merge should not have D/F conflicts (recursive)' '
git reset --hard &&
git checkout baseline^0 &&
git merge -s recursive test2 &&
- test -f a/b/c/d
+ test_path_is_file a/b/c/d
'
test_expect_success SYMLINKS 'a/b-2 was resolved as symlink' '
@@ -162,7 +162,7 @@ test_expect_success 'merge should not have F/D conflicts (recursive)' '
git reset --hard &&
git checkout -b foo test2 &&
git merge -s recursive baseline^0 &&
- test -f a/b/c/d
+ test_path_is_file a/b/c/d
'
test_expect_success SYMLINKS 'a/b-2 was resolved as symlink' '
diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh
index 7fddcc8c73..b3bf462617 100755
--- a/t/t6036-recursive-corner-cases.sh
+++ b/t/t6036-recursive-corner-cases.sh
@@ -60,9 +60,9 @@ test_expect_success 'merge simple rename+criss-cross with no modifications' '
test_must_fail git merge -s recursive R2^0 &&
git ls-files -s >out &&
- test_line_count = 2 out &&
+ test_line_count = 5 out &&
git ls-files -u >out &&
- test_line_count = 2 out &&
+ test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
@@ -133,9 +133,9 @@ test_expect_success 'merge criss-cross + rename merges with basic modification'
test_must_fail git merge -s recursive R2^0 &&
git ls-files -s >out &&
- test_line_count = 2 out &&
+ test_line_count = 5 out &&
git ls-files -u >out &&
- test_line_count = 2 out &&
+ test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
@@ -218,8 +218,18 @@ test_expect_success 'git detects differently handled merges conflict' '
git ls-files -o >out &&
test_line_count = 1 out &&
- git rev-parse >expect \
- C:new_a D:new_a E:new_a &&
+ git cat-file -p C:new_a >ours &&
+ git cat-file -p C:a >theirs &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "Temporary merge branch 1" \
+ -L "" \
+ -L "Temporary merge branch 2" \
+ ours empty theirs &&
+ sed -e "s/^\([<=>]\)/\1\1\1/" ours >ours-tweaked &&
+ git hash-object ours-tweaked >expect &&
+ git rev-parse >>expect \
+ D:new_a E:new_a &&
git rev-parse >actual \
:1:new_a :2:new_a :3:new_a &&
test_cmp expect actual &&
@@ -257,7 +267,8 @@ test_expect_success 'git detects differently handled merges conflict, swapped' '
ctime=$(git log --no-walk --date=raw --format=%cd C | awk "{print \$1}") &&
newctime=$(($btime+1)) &&
git fast-export --no-data --all | sed -e s/$ctime/$newctime/ | git fast-import --force --quiet &&
- # End of differences; rest is copy-paste of last test
+ # End of most differences; rest is copy-paste of last test,
+ # other than swapping C:a and C:new_a due to order switch
git checkout D^0 &&
test_must_fail git merge -s recursive E^0 &&
@@ -269,8 +280,18 @@ test_expect_success 'git detects differently handled merges conflict, swapped' '
git ls-files -o >out &&
test_line_count = 1 out &&
- git rev-parse >expect \
- C:new_a D:new_a E:new_a &&
+ git cat-file -p C:a >ours &&
+ git cat-file -p C:new_a >theirs &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "Temporary merge branch 1" \
+ -L "" \
+ -L "Temporary merge branch 2" \
+ ours empty theirs &&
+ sed -e "s/^\([<=>]\)/\1\1\1/" ours >ours-tweaked &&
+ git hash-object ours-tweaked >expect &&
+ git rev-parse >>expect \
+ D:new_a E:new_a &&
git rev-parse >actual \
:1:new_a :2:new_a :3:new_a &&
test_cmp expect actual &&
@@ -1532,7 +1553,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
@@ -1696,7 +1717,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
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..1ddc9e6626 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,26 +62,24 @@ 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 &&
- test-tool chmtime =31337 b &&
- test-tool chmtime -v +0 b >expected-mtime &&
+ test-tool chmtime --get -3600 b >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
- test_i18ngrep "Skipped b" out &&
test_must_be_empty err &&
- test-tool chmtime -v +0 b >actual-mtime &&
- test_cmp expected-mtime actual-mtime &&
+ # Make sure b was NOT updated
+ test-tool chmtime --get b >new-mtime &&
+ test_cmp old-mtime new-mtime &&
git ls-files -s >index_files &&
test_line_count = 1 index_files &&
@@ -96,17 +94,20 @@ 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 &&
+ test-tool chmtime --get -3600 b >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
- test_i18ngrep "Auto-merging b" out &&
+ # Make sure b WAS updated
+ test-tool chmtime --get b >new-mtime &&
+ test $(cat old-mtime) -lt $(cat new-mtime) &&
+
test_must_be_empty err &&
git ls-files -s >index_files &&
@@ -133,10 +134,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,20 +159,19 @@ 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 &&
+ test_path_is_missing c &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
- test_i18ngrep ! "Skipped c" out &&
- test_must_be_empty err &&
+ test_path_is_file c &&
git ls-files -s >index_files &&
test_line_count = 1 index_files &&
@@ -189,17 +189,20 @@ 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 &&
+ test-tool chmtime --get -3600 c >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
- test_i18ngrep ! "Skipped c" out &&
+ # Make sure c WAS updated
+ test-tool chmtime --get c >new-mtime &&
+ test $(cat old-mtime) -lt $(cat new-mtime) &&
+
test_must_be_empty err &&
git ls-files -s >index_files &&
@@ -224,10 +227,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,26 +254,23 @@ 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 &&
- test-tool chmtime =31337 c &&
- test-tool chmtime -v +0 c >expected-mtime &&
-
+ test-tool chmtime --get -3600 c >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
- test_i18ngrep "Skipped c" out &&
test_must_be_empty err &&
- test-tool chmtime -v +0 c >actual-mtime &&
- test_cmp expected-mtime actual-mtime &&
+ # Make sure c WAS updated
+ test-tool chmtime --get c >new-mtime &&
+ test_cmp old-mtime new-mtime &&
git ls-files -s >index_files &&
test_line_count = 1 index_files &&
@@ -288,17 +288,19 @@ 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 &&
+ test_path_is_missing c &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
- test_i18ngrep "Auto-merging c" out &&
+ # Make sure c now present (and thus was updated)
+ test_path_is_file c &&
+
test_must_be_empty err &&
git ls-files -s >index_files &&
@@ -332,7 +334,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,21 +360,26 @@ 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 &&
git checkout A^0 &&
+ test-tool chmtime --get -3600 c >old-mtime &&
GIT_MERGE_VERBOSITY=3 &&
export GIT_MERGE_VERBOSITY &&
test_must_fail git merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/add): Rename b->c" out &&
- test_i18ngrep ! "Skipped c" out &&
- test_must_be_empty err
+ test_must_be_empty err &&
+
+ # Make sure c WAS updated
+ test-tool chmtime --get c >new-mtime &&
+ test $(cat old-mtime) -lt $(cat new-mtime)
# FIXME: rename/add conflicts are horribly broken right now;
# when I get back to my patch series fixing it and
@@ -428,10 +435,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,21 +463,22 @@ 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 &&
+ test_path_is_missing bar/bq &&
GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
- test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
+ test_path_is_file bar/bq &&
+
git ls-files -s >index_files &&
test_line_count = 2 index_files &&
@@ -487,19 +495,20 @@ 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 &&
+ test_path_is_missing bar/bq &&
GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
- test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
+ test_path_is_file bar/bq &&
+
git ls-files -s >index_files &&
test_line_count = 2 index_files &&
@@ -522,10 +531,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,21 +559,22 @@ 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 &&
+ test_path_is_missing bar/bq &&
GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
- test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
+ test_path_is_file bar/bq &&
+
git ls-files -s >index_files &&
test_line_count = 2 index_files &&
@@ -581,19 +591,20 @@ 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 &&
+ test_path_is_missing bar/bq &&
GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
- test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
+ test_path_is_file bar/bq &&
+
git ls-files -s >index_files &&
test_line_count = 2 index_files &&
@@ -621,7 +632,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 +658,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,25 +666,23 @@ 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 &&
git checkout A^0 &&
echo "File rewritten" >b &&
- test-tool chmtime =31337 b &&
- test-tool chmtime -v +0 b >expected-mtime &&
+ test-tool chmtime --get -3600 b >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
- test_i18ngrep "Skipped b" out &&
test_must_be_empty err &&
- test-tool chmtime -v +0 b >actual-mtime &&
- test_cmp expected-mtime actual-mtime &&
+ # Make sure b was NOT updated
+ test-tool chmtime --get b >new-mtime &&
+ test_cmp old-mtime new-mtime &&
git ls-files -s >index_files &&
test_line_count = 1 index_files &&
@@ -695,7 +704,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,27 +731,25 @@ 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 &&
git checkout A^0 &&
echo "File rewritten" >c &&
- test-tool chmtime =31337 c &&
- test-tool chmtime -v +0 c >expected-mtime &&
+ test-tool chmtime --get -3600 c >old-mtime &&
GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
- test_i18ngrep "Skipped c" out &&
test_must_be_empty err &&
- test-tool chmtime -v +0 c >actual-mtime &&
- test_cmp expected-mtime actual-mtime &&
+ # Make sure c was NOT updated
+ test-tool chmtime --get c >new-mtime &&
+ test_cmp old-mtime new-mtime &&
git ls-files -s >index_files &&
test_line_count = 1 index_files &&
diff --git a/t/t6047-diff3-conflict-markers.sh b/t/t6047-diff3-conflict-markers.sh
index 860542aad0..f4655bb358 100755
--- a/t/t6047-diff3-conflict-markers.sh
+++ b/t/t6047-diff3-conflict-markers.sh
@@ -186,7 +186,7 @@ test_expect_success 'check multiple merge bases' '
)
'
-test_expect_success 'rebase describes fake ancestor base' '
+test_expect_success 'rebase --merge describes parent of commit being picked' '
test_create_repo rebase &&
(
cd rebase &&
@@ -194,7 +194,16 @@ test_expect_success 'rebase describes fake ancestor base' '
test_commit master file &&
git checkout -b side HEAD^ &&
test_commit side file &&
- test_must_fail git -c merge.conflictstyle=diff3 rebase master &&
+ test_must_fail git -c merge.conflictstyle=diff3 rebase --merge master &&
+ grep "||||||| parent of" file
+ )
+'
+
+test_expect_success 'rebase --apply describes fake ancestor base' '
+ (
+ cd rebase &&
+ git rebase --abort &&
+ test_must_fail git -c merge.conflictstyle=diff3 rebase --apply master &&
grep "||||||| constructed merge base" file
)
'
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/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh
new file mode 100755
index 0000000000..145603f124
--- /dev/null
+++ b/t/t6113-rev-list-bitmap-filters.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+test_description='rev-list combining bitmaps and filters'
+. ./test-lib.sh
+
+test_expect_success 'set up bitmapped repo' '
+ # one commit will have bitmaps, the other will not
+ test_commit one &&
+ test_commit much-larger-blob-one &&
+ git repack -adb &&
+ test_commit two &&
+ test_commit much-larger-blob-two
+'
+
+test_expect_success 'filters fallback to non-bitmap traversal' '
+ # use a path-based filter, since they are inherently incompatible with
+ # bitmaps (i.e., this test will never get confused by later code to
+ # combine the features)
+ filter=$(echo "!one" | git hash-object -w --stdin) &&
+ git rev-list --objects --filter=sparse:oid=$filter HEAD >expect &&
+ git rev-list --use-bitmap-index \
+ --objects --filter=sparse:oid=$filter HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'blob:none filter' '
+ git rev-list --objects --filter=blob:none HEAD >expect &&
+ git rev-list --use-bitmap-index \
+ --objects --filter=blob:none HEAD >actual &&
+ test_bitmap_traversal expect actual
+'
+
+test_expect_success 'blob:none filter with specified blob' '
+ git rev-list --objects --filter=blob:none HEAD HEAD:two.t >expect &&
+ git rev-list --use-bitmap-index \
+ --objects --filter=blob:none HEAD HEAD:two.t >actual &&
+ test_bitmap_traversal expect actual
+'
+
+test_expect_success 'blob:limit filter' '
+ git rev-list --objects --filter=blob:limit=5 HEAD >expect &&
+ git rev-list --use-bitmap-index \
+ --objects --filter=blob:limit=5 HEAD >actual &&
+ test_bitmap_traversal expect actual
+'
+
+test_expect_success 'blob:limit filter with specified blob' '
+ git rev-list --objects --filter=blob:limit=5 \
+ HEAD HEAD:much-larger-blob-two.t >expect &&
+ git rev-list --use-bitmap-index \
+ --objects --filter=blob:limit=5 \
+ HEAD HEAD:much-larger-blob-two.t >actual &&
+ test_bitmap_traversal expect actual
+'
+
+test_done
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 45047d0a72..34502e3a50 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
@@ -439,4 +438,96 @@ test_expect_success 'name-rev a rev shortly after epoch' '
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
+ )
+'
+
+# B
+# o
+# \
+# o-----o---o----x
+# A
+#
+test_expect_success 'describe commits with disjoint bases' '
+ git init disjoint1 &&
+ (
+ cd disjoint1 &&
+
+ echo o >> file && git add file && git commit -m o &&
+ echo A >> file && git add file && git commit -m A &&
+ git tag A -a -m A &&
+ echo o >> file && git add file && git commit -m o &&
+
+ git checkout --orphan branch && rm file &&
+ echo B > file2 && git add file2 && git commit -m B &&
+ git tag B -a -m B &&
+ git merge --no-ff --allow-unrelated-histories master -m x &&
+
+ check_describe "A-3-*" HEAD
+ )
+'
+
+# B
+# o---o---o------------.
+# \
+# o---o---x
+# A
+#
+test_expect_success 'describe commits with disjoint bases 2' '
+ git init disjoint2 &&
+ (
+ cd disjoint2 &&
+
+ echo A >> file && git add file && GIT_COMMITTER_DATE="2020-01-01 18:00" git commit -m A &&
+ git tag A -a -m A &&
+ echo o >> file && git add file && GIT_COMMITTER_DATE="2020-01-01 18:01" git commit -m o &&
+
+ git checkout --orphan branch &&
+ echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o &&
+ echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o &&
+ echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B &&
+ git tag B -a -m B &&
+ git merge --no-ff --allow-unrelated-histories master -m x &&
+
+ check_describe "B-3-*" HEAD
+ )
+'
+
test_done
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
index 37760233a5..ba7902c9cd 100755
--- a/t/t6130-pathspec-noglob.sh
+++ b/t/t6130-pathspec-noglob.sh
@@ -10,6 +10,7 @@ test_expect_success 'create commits with glob characters' '
# the name "f*" in the worktree, because it is not allowed
# on Windows (the tests below do not depend on the presence
# of the file in the worktree)
+ git config core.protectNTFS false &&
git update-index --add --cacheinfo 100644 "$(git rev-parse HEAD:foo)" "f*" &&
test_tick &&
git commit -m star &&
diff --git a/t/t6136-pathspec-in-bare.sh b/t/t6136-pathspec-in-bare.sh
new file mode 100755
index 0000000000..b117251366
--- /dev/null
+++ b/t/t6136-pathspec-in-bare.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+test_description='diagnosing out-of-scope pathspec'
+
+. ./test-lib.sh
+
+test_expect_success 'setup a bare and non-bare repository' '
+ test_commit file1 &&
+ git clone --bare . bare
+'
+
+test_expect_success 'log and ls-files in a bare repository' '
+ (
+ cd bare &&
+ test_must_fail git log -- .. >out 2>err &&
+ test_must_be_empty out &&
+ test_i18ngrep "outside repository" err &&
+
+ test_must_fail git ls-files -- .. >out 2>err &&
+ test_must_be_empty out &&
+ test_i18ngrep "outside repository" err
+ )
+'
+
+test_expect_success 'log and ls-files in .git directory' '
+ (
+ cd .git &&
+ test_must_fail git log -- .. >out 2>err &&
+ test_must_be_empty out &&
+ test_i18ngrep "outside repository" err &&
+
+ test_must_fail git ls-files -- .. >out 2>err &&
+ test_must_be_empty out &&
+ test_i18ngrep "outside repository" err
+ )
+'
+
+test_done
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index 8a72b4c43a..b15582a7a2 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -6,6 +6,7 @@
test_description='fmt-merge-msg test'
. ./test-lib.sh
+. "$TEST_DIRECTORY/lib-gpg.sh"
test_expect_success setup '
echo one >one &&
@@ -73,6 +74,10 @@ test_expect_success setup '
apos="'\''"
'
+test_expect_success GPG 'set up a signed tag' '
+ git tag -s -m signed-tag-msg signed-good-tag left
+'
+
test_expect_success 'message for merging local branch' '
echo "Merge branch ${apos}left${apos}" >expected &&
@@ -83,6 +88,24 @@ test_expect_success 'message for merging local branch' '
test_cmp expected actual
'
+test_expect_success GPG 'message for merging local tag signed by good key' '
+ git checkout master &&
+ git fetch . signed-good-tag &&
+ git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
+ grep "^Merge tag ${apos}signed-good-tag${apos}" actual &&
+ grep "^# gpg: Signature made" actual &&
+ grep "^# gpg: Good signature from" actual
+'
+
+test_expect_success GPG 'message for merging local tag signed by unknown key' '
+ git checkout master &&
+ git fetch . signed-good-tag &&
+ GNUPGHOME=. git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
+ grep "^Merge tag ${apos}signed-good-tag${apos}" actual &&
+ grep "^# gpg: Signature made" actual &&
+ grep "^# gpg: Can${apos}t check signature: \(public key not found\|No public key\)" actual
+'
+
test_expect_success 'message for merging external branch' '
echo "Merge branch ${apos}left${apos} of $(pwd)" >expected &&
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 9c910ce746..b3c1092338 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -20,6 +20,10 @@ setdate_and_increment () {
}
test_expect_success setup '
+ test_oid_cache <<-EOF &&
+ disklen sha1:138
+ disklen sha256:154
+ EOF
setdate_and_increment &&
echo "Using $datestamp" > one &&
git add one &&
@@ -50,6 +54,9 @@ test_atom() {
"
}
+hexlen=$(test_oid hexsz)
+disklen=$(test_oid disklen)
+
test_atom head refname refs/heads/master
test_atom head refname: refs/heads/master
test_atom head refname:short master
@@ -82,9 +89,9 @@ test_atom head push:rstrip=-1 refs
test_atom head push:strip=1 remotes/myfork/master
test_atom head push:strip=-1 master
test_atom head objecttype commit
-test_atom head objectsize 171
-test_atom head objectsize:disk 138
-test_atom head deltabase 0000000000000000000000000000000000000000
+test_atom head objectsize $((131 + hexlen))
+test_atom head objectsize:disk $disklen
+test_atom head deltabase $ZERO_OID
test_atom head objectname $(git rev-parse refs/heads/master)
test_atom head objectname:short $(git rev-parse --short refs/heads/master)
test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master)
@@ -125,11 +132,11 @@ test_atom tag refname:short testtag
test_atom tag upstream ''
test_atom tag push ''
test_atom tag objecttype tag
-test_atom tag objectsize 154
-test_atom tag objectsize:disk 138
-test_atom tag '*objectsize:disk' 138
-test_atom tag deltabase 0000000000000000000000000000000000000000
-test_atom tag '*deltabase' 0000000000000000000000000000000000000000
+test_atom tag objectsize $((114 + hexlen))
+test_atom tag objectsize:disk $disklen
+test_atom tag '*objectsize:disk' $disklen
+test_atom tag deltabase $ZERO_OID
+test_atom tag '*deltabase' $ZERO_OID
test_atom tag objectname $(git rev-parse refs/tags/testtag)
test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag)
test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master)
@@ -139,7 +146,7 @@ test_atom tag parent ''
test_atom tag numparent ''
test_atom tag object $(git rev-parse refs/tags/testtag^0)
test_atom tag type 'commit'
-test_atom tag '*objectname' 'ea122842f48be4afb2d1fc6a4b96c05885ab7463'
+test_atom tag '*objectname' $(git rev-parse refs/tags/testtag^{})
test_atom tag '*objecttype' 'commit'
test_atom tag author ''
test_atom tag authorname ''
@@ -643,7 +650,7 @@ test_atom refs/tags/signed-long contents "subject line
body contents
$sig"
-cat >expected <<EOF
+sort >expected <<EOF
$(git rev-parse refs/tags/bogo) <committer@example.com> refs/tags/bogo
$(git rev-parse refs/tags/master) <committer@example.com> refs/tags/master
EOF
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/t7004-tag.sh b/t/t7004-tag.sh
index 80eb13d94e..74b637deb2 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 &&
@@ -1727,6 +1726,7 @@ test_expect_success 'recursive tagging should give advice' '
hint: already a tag. If you meant to tag the object that it points to, use:
hint: |
hint: git tag -f nested annotated-v4.0^{}
+ hint: Disable this message with "git config advice.nestedTag false"
EOF
git tag -m nested nested annotated-v4.0 2>actual &&
test_i18ncmp expect actual
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/t7112-reset-submodule.sh b/t/t7112-reset-submodule.sh
index a1cb9ff858..67346424a5 100755
--- a/t/t7112-reset-submodule.sh
+++ b/t/t7112-reset-submodule.sh
@@ -5,7 +5,6 @@ test_description='reset can handle submodules'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-submodule-update.sh
-KNOWN_FAILURE_SUBMODULE_RECURSIVE_NESTED=1
KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1
KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED=1
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 6e6d24c1c3..cb5e34d94c 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -737,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 691b5fc3bf..e3e2aab3b0 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -55,6 +55,21 @@ test_expect_success 'add aborts on repository with no commits' '
test_i18ncmp expect actual
'
+test_expect_success 'status should ignore inner git repo when not added' '
+ rm -fr inner &&
+ mkdir inner &&
+ (
+ cd inner &&
+ git init &&
+ >t &&
+ git add t &&
+ git commit -m "initial"
+ ) &&
+ test_must_fail git submodule status inner 2>output.err &&
+ rm -fr inner &&
+ test_i18ngrep "^error: .*did not match any file(s) known to git" output.err
+'
+
test_expect_success 'setup - repository in init subdirectory' '
mkdir init &&
(
@@ -156,9 +171,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 +208,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 +384,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" &&
@@ -377,6 +427,14 @@ test_expect_success 'init should register submodule url in .git/config' '
test_cmp expect url
'
+test_expect_success 'status should still be "missing" after initializing' '
+ rm -fr init &&
+ mkdir init &&
+ git submodule status >lines &&
+ rm -fr init &&
+ grep "^-$rev1" lines
+'
+
test_failure_with_unknown_submodule () {
test_must_fail git submodule $1 no-such-submodule 2>output.err &&
test_i18ngrep "^error: .*no-such-submodule" output.err
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index df34c994d2..4fb447a143 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -406,12 +406,26 @@ test_expect_success 'submodule update - command in .git/config' '
)
'
-test_expect_success 'submodule update - command in .gitmodules is ignored' '
+test_expect_success 'submodule update - command in .gitmodules is rejected' '
test_when_finished "git -C super reset --hard HEAD^" &&
git -C super config -f .gitmodules submodule.submodule.update "!false" &&
git -C super commit -a -m "add command to .gitmodules file" &&
git -C super/submodule reset --hard $submodulesha1^ &&
- git -C super submodule update submodule
+ test_must_fail git -C super submodule update submodule
+'
+
+test_expect_success 'fsck detects command in .gitmodules' '
+ git init command-in-gitmodules &&
+ (
+ cd command-in-gitmodules &&
+ git submodule add ../submodule submodule &&
+ test_commit adding-submodule &&
+
+ git config -f .gitmodules submodule.submodule.update "!false" &&
+ git add .gitmodules &&
+ test_commit configuring-update &&
+ test_must_fail git fsck
+ )
'
cat << EOF >expect
@@ -480,6 +494,9 @@ test_expect_success 'recursive submodule update - command in .git/config catches
'
test_expect_success 'submodule init does not copy command into .git/config' '
+ test_when_finished "git -C super update-index --force-remove submodule1" &&
+ test_when_finished git config -f super/.gitmodules \
+ --remove-section submodule.submodule1 &&
(cd super &&
git ls-files -s submodule >out &&
H=$(cut -d" " -f2 out) &&
@@ -488,10 +505,9 @@ test_expect_success 'submodule init does not copy command into .git/config' '
git config -f .gitmodules submodule.submodule1.path submodule1 &&
git config -f .gitmodules submodule.submodule1.url ../submodule &&
git config -f .gitmodules submodule.submodule1.update !false &&
- git submodule init submodule1 &&
- echo "none" >expect &&
- git config submodule.submodule1.update >actual &&
- test_cmp expect actual
+ test_must_fail git submodule init submodule1 &&
+ test_expect_code 1 git config submodule.submodule1.update >actual &&
+ test_must_be_empty actual
)
'
@@ -944,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 49a37efe9c..f70368bc2e 100755
--- a/t/t7415-submodule-names.sh
+++ b/t/t7415-submodule-names.sh
@@ -191,4 +191,61 @@ test_expect_success 'fsck detects corrupt .gitmodules' '
)
'
+test_expect_success MINGW 'prevent git~1 squatting on Windows' '
+ git init squatting &&
+ (
+ cd squatting &&
+ mkdir a &&
+ touch a/..git &&
+ git add a/..git &&
+ test_tick &&
+ git commit -m initial &&
+
+ modules="$(test_write_lines \
+ "[submodule \"b.\"]" "url = ." "path = c" \
+ "[submodule \"b\"]" "url = ." "path = d\\\\a" |
+ 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 \
+ --cacheinfo 160000,$rev,d\\a \
+ --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 -c core.protectNTFS=false \
+ clone --recurse-submodules squatting squatting-clone 2>err &&
+ test_i18ngrep -e "directory not empty" -e "not an empty directory" err &&
+ ! grep gitdir squatting-clone/d/a/git~2
+'
+
+test_expect_success 'git dirs of sibling submodules must not be nested' '
+ git init nested &&
+ test_commit -C nested nested &&
+ (
+ cd nested &&
+ cat >.gitmodules <<-EOF &&
+ [submodule "hippo"]
+ url = .
+ path = thing1
+ [submodule "hippo/hooks"]
+ url = .
+ path = thing2
+ EOF
+ git clone . thing1 &&
+ git clone . thing2 &&
+ git add .gitmodules thing1 thing2 &&
+ test_tick &&
+ git commit -m nested
+ ) &&
+ test_must_fail git clone --recurse-submodules nested clone 2>err &&
+ test_i18ngrep "is inside git dir" err
+'
+
test_done
diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh
index 1cd2c1c1ea..5ba041f537 100755
--- a/t/t7416-submodule-dash-url.sh
+++ b/t/t7416-submodule-dash-url.sh
@@ -46,4 +46,18 @@ test_expect_success 'fsck rejects unprotected dash' '
grep gitmodulesUrl err
'
+test_expect_success 'trailing backslash is handled correctly' '
+ git init testmodule &&
+ test_commit -C testmodule c &&
+ git submodule add ./testmodule &&
+ : ensure that the name ends in a double backslash &&
+ sed -e "s|\\(submodule \"testmodule\\)\"|\\1\\\\\\\\\"|" \
+ -e "s|url = .*|url = \" --should-not-be-an-option\"|" \
+ <.gitmodules >.new &&
+ mv .new .gitmodules &&
+ git commit -am "Add testmodule" &&
+ test_must_fail git clone --verbose --recurse-submodules . dolly 2>err &&
+ test_i18ngrep ! "unknown option" err
+'
+
test_done
diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh
index 756af8c4d6..f7e7e94d7b 100755
--- a/t/t7417-submodule-path-url.sh
+++ b/t/t7417-submodule-path-url.sh
@@ -25,4 +25,21 @@ test_expect_success 'fsck rejects unprotected dash' '
grep gitmodulesPath err
'
+test_expect_success MINGW 'submodule paths disallows trailing spaces' '
+ git init super &&
+ test_must_fail git -C super submodule add ../upstream "sub " &&
+
+ : add "sub", then rename "sub" to "sub ", the hard way &&
+ git -C super submodule add ../upstream sub &&
+ tree=$(git -C super write-tree) &&
+ git -C super ls-tree $tree >tree &&
+ sed "s/sub/sub /" <tree >tree.new &&
+ tree=$(git -C super mktree <tree.new) &&
+ commit=$(echo with space | git -C super commit-tree $tree) &&
+ git -C super update-ref refs/heads/master $commit &&
+
+ test_must_fail git clone --recurse-submodules super dst 2>err &&
+ test_i18ngrep "sub " err
+'
+
test_done
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/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..6baaa1ad91 100755
--- a/t/t7510-signed-commit.sh
+++ b/t/t7510-signed-commit.sh
@@ -6,6 +6,11 @@ GNUPGHOME_NOT_USED=$GNUPGHOME
. "$TEST_DIRECTORY/lib-gpg.sh"
test_expect_success GPG 'create signed commits' '
+ test_oid_cache <<-\EOF &&
+ header sha1:gpgsig
+ header sha256:gpgsig-sha256
+ EOF
+
test_when_finished "test_unconfig commit.gpgsign" &&
echo 1 >file && git add file &&
@@ -109,6 +114,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
@@ -140,6 +160,11 @@ test_expect_success GPG 'verify signatures with --raw' '
)
'
+test_expect_success GPG 'proper header is used for hash algorithm' '
+ git cat-file commit fourth-signed >output &&
+ grep "^$(test_oid header) -----BEGIN PGP SIGNATURE-----" output
+'
+
test_expect_success GPG 'show signed commit with signature' '
git show -s initial >commit &&
git show -s --show-signature initial >show &&
@@ -147,7 +172,7 @@ test_expect_success GPG 'show signed commit with signature' '
git cat-file commit initial >cat &&
grep -v -e "gpg: " -e "Warning: " show >show.commit &&
grep -e "gpg: " -e "Warning: " show >show.gpg &&
- grep -v "^ " cat | grep -v "^gpgsig " >cat.commit &&
+ grep -v "^ " cat | grep -v "^$(test_oid header) " >cat.commit &&
test_cmp show.commit commit &&
test_cmp show.gpg verify.2 &&
test_cmp cat.commit verify.1
@@ -219,6 +244,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
@@ -260,10 +309,10 @@ test_expect_success GPG 'check config gpg.format values' '
test_expect_success GPG 'detect fudged commit with double signature' '
sed -e "/gpgsig/,/END PGP/d" forged1 >double-base &&
sed -n -e "/gpgsig/,/END PGP/p" forged1 | \
- sed -e "s/^gpgsig//;s/^ //" | gpg --dearmor >double-sig1.sig &&
+ sed -e "s/^$(test_oid header)//;s/^ //" | gpg --dearmor >double-sig1.sig &&
gpg -o double-sig2.sig -u 29472784 --detach-sign double-base &&
cat double-sig1.sig double-sig2.sig | gpg --enarmor >double-combined.asc &&
- sed -e "s/^\(-.*\)ARMORED FILE/\1SIGNATURE/;1s/^/gpgsig /;2,\$s/^/ /" \
+ sed -e "s/^\(-.*\)ARMORED FILE/\1SIGNATURE/;1s/^/$(test_oid header) /;2,\$s/^/ /" \
double-combined.asc > double-gpgsig &&
sed -e "/committer/r double-gpgsig" double-base >double-commit &&
git hash-object -w -t commit double-commit >double-commit.commit &&
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index 66d7a62797..29518e0949 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -71,10 +71,10 @@ test_expect_success 'prepare for rebase conflicts' '
'
-test_expect_success 'status when rebase in progress before resolving conflicts' '
+test_expect_success 'status when rebase --apply in progress before resolving conflicts' '
test_when_finished "git rebase --abort" &&
ONTO=$(git rev-parse --short HEAD^^) &&
- test_must_fail git rebase HEAD^ --onto HEAD^^ &&
+ test_must_fail git rebase --apply HEAD^ --onto HEAD^^ &&
cat >expected <<EOF &&
rebase in progress; onto $ONTO
You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
@@ -94,11 +94,11 @@ EOF
'
-test_expect_success 'status when rebase in progress before rebase --continue' '
+test_expect_success 'status when rebase --apply in progress before rebase --continue' '
git reset --hard rebase_conflicts &&
test_when_finished "git rebase --abort" &&
ONTO=$(git rev-parse --short HEAD^^) &&
- test_must_fail git rebase HEAD^ --onto HEAD^^ &&
+ test_must_fail git rebase --apply HEAD^ --onto HEAD^^ &&
echo three >main.txt &&
git add main.txt &&
cat >expected <<EOF &&
@@ -688,7 +688,7 @@ EOF
'
-test_expect_success 'status when rebase conflicts with statushints disabled' '
+test_expect_success 'status when rebase --apply conflicts with statushints disabled' '
git reset --hard master &&
git checkout -b statushints_disabled &&
test_when_finished "git config --local advice.statushints true" &&
@@ -698,7 +698,7 @@ test_expect_success 'status when rebase conflicts with statushints disabled' '
test_commit three_statushints main.txt three &&
test_when_finished "git rebase --abort" &&
ONTO=$(git rev-parse --short HEAD^^) &&
- test_must_fail git rebase HEAD^ --onto HEAD^^ &&
+ test_must_fail git rebase --apply HEAD^ --onto HEAD^^ &&
cat >expected <<EOF &&
rebase in progress; onto $ONTO
You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''.
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 997d5fb349..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 &&
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-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 531eb59d57..03dba6685a 100755
--- a/t/t7812-grep-icase-non-ascii.sh
+++ b/t/t7812-grep-icase-non-ascii.sh
@@ -70,15 +70,18 @@ test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep ASCII from invalid UT
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 &&
+ 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 &&
- test_cmp expected actual &&
- test_must_fail git grep -hi "(*NO_JIT)Æ" invalid-0x80 &&
- test_cmp expected 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 946f91fa57..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
diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh
index 1c5fb1d1f8..9130b887d2 100755
--- a/t/t8003-blame-corner-cases.sh
+++ b/t/t8003-blame-corner-cases.sh
@@ -173,7 +173,6 @@ test_expect_success 'blame during cherry-pick with file rename conflict' '
git show HEAD@{1}:rodent > rodent &&
git add rodent &&
git blame -f -C -C1 rodent | sed -e "$pick_fc" >current &&
- cat current &&
cat >expected <<-\EOF &&
mouse-Initial
mouse-Second
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 997f90b42b..90f61c3400 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -1194,8 +1194,8 @@ test_expect_success $PREREQ 'in-reply-to but no threading' '
--to=nobody@example.com \
--in-reply-to="<in-reply-id@example.com>" \
--no-thread \
- $patches |
- grep "In-Reply-To: <in-reply-id@example.com>"
+ $patches >out &&
+ grep "In-Reply-To: <in-reply-id@example.com>" out
'
test_expect_success $PREREQ 'no in-reply-to and no threading' '
@@ -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/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index dbe8deac0d..aec45bca3b 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -92,7 +92,8 @@ test_expect_success 'multiple dcommit from git svn will not clobber svn' "
test_expect_success 'check that rebase really failed' '
- test -d .git/rebase-apply
+ git status >output &&
+ grep currently.rebasing output
'
test_expect_success 'resolve, continue the rebase and dcommit' "
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 45773ee560..0a9f1ef366 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -43,14 +43,18 @@ test_expect_success 'setup repository and import' '
test_expect_success 'run log' "
git reset --hard origin/a &&
- git svn log -r2 origin/trunk | grep ^r2 &&
- git svn log -r4 origin/trunk | grep ^r4 &&
- git svn log -r3 | grep ^r3
+ git svn log -r2 origin/trunk >out &&
+ grep ^r2 out &&
+ git svn log -r4 origin/trunk >out &&
+ grep ^r4 out &&
+ git svn log -r3 >out &&
+ grep ^r3 out
"
test_expect_success 'run log against a from trunk' "
git reset --hard origin/trunk &&
- git svn log -r3 origin/a | grep ^r3
+ git svn log -r3 origin/a >out &&
+ grep ^r3 out
"
printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index e707fb861e..768257b29e 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1047,7 +1047,6 @@ test_expect_success 'M: rename root to subdirectory' '
EOF
git fast-import <input &&
git diff-tree -M -r M4^ M4 >actual &&
- cat actual &&
compare_diff_raw expect actual
'
@@ -2143,12 +2142,27 @@ test_expect_success 'R: abort on receiving feature after data command' '
test_must_fail git fast-import <input
'
+test_expect_success 'R: import-marks features forbidden by default' '
+ >git.marks &&
+ echo "feature import-marks=git.marks" >input &&
+ test_must_fail git fast-import <input &&
+ echo "feature import-marks-if-exists=git.marks" >input &&
+ test_must_fail git fast-import <input
+'
+
test_expect_success 'R: only one import-marks feature allowed per stream' '
+ >git.marks &&
+ >git2.marks &&
cat >input <<-EOF &&
feature import-marks=git.marks
feature import-marks=git2.marks
EOF
+ test_must_fail git fast-import --allow-unsafe-features <input
+'
+
+test_expect_success 'R: export-marks feature forbidden by default' '
+ echo "feature export-marks=git.marks" >input &&
test_must_fail git fast-import <input
'
@@ -2162,19 +2176,29 @@ test_expect_success 'R: export-marks feature results in a marks file being creat
EOF
- cat input | git fast-import &&
+ git fast-import --allow-unsafe-features <input &&
grep :1 git.marks
'
test_expect_success 'R: export-marks options can be overridden by commandline options' '
- cat input | git fast-import --export-marks=other.marks &&
- grep :1 other.marks
+ cat >input <<-\EOF &&
+ feature export-marks=feature-sub/git.marks
+ blob
+ mark :1
+ data 3
+ hi
+
+ EOF
+ git fast-import --allow-unsafe-features \
+ --export-marks=cmdline-sub/other.marks <input &&
+ grep :1 cmdline-sub/other.marks &&
+ test_path_is_missing feature-sub
'
test_expect_success 'R: catch typo in marks file name' '
test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null &&
echo "feature import-marks=nonexistent.marks" |
- test_must_fail git fast-import
+ test_must_fail git fast-import --allow-unsafe-features
'
test_expect_success 'R: import and output marks can be the same file' '
@@ -2229,7 +2253,8 @@ test_expect_success 'R: --import-marks-if-exists' '
test_expect_success 'R: feature import-marks-if-exists' '
rm -f io.marks &&
- git fast-import --export-marks=io.marks <<-\EOF &&
+ git fast-import --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=not_io.marks
EOF
test_must_be_empty io.marks &&
@@ -2240,7 +2265,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
echo ":1 $blob" >expect &&
echo ":2 $blob" >>expect &&
- git fast-import --export-marks=io.marks <<-\EOF &&
+ git fast-import --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=io.marks
blob
mark :2
@@ -2253,7 +2279,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
echo ":3 $blob" >>expect &&
git fast-import --import-marks=io.marks \
- --export-marks=io.marks <<-\EOF &&
+ --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=not_io.marks
blob
mark :3
@@ -2264,7 +2291,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
test_cmp expect io.marks &&
git fast-import --import-marks-if-exists=not_io.marks \
- --export-marks=io.marks <<-\EOF &&
+ --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=io.marks
EOF
test_must_be_empty io.marks
@@ -2276,7 +2304,7 @@ test_expect_success 'R: import to output marks works without any content' '
feature export-marks=marks.new
EOF
- cat input | git fast-import &&
+ git fast-import --allow-unsafe-features <input &&
test_cmp marks.out marks.new
'
@@ -2286,7 +2314,7 @@ test_expect_success 'R: import marks prefers commandline marks file over the str
feature export-marks=marks.new
EOF
- cat input | git fast-import --import-marks=marks.out &&
+ git fast-import --import-marks=marks.out --allow-unsafe-features <input &&
test_cmp marks.out marks.new
'
@@ -2299,7 +2327,8 @@ test_expect_success 'R: multiple --import-marks= should be honoured' '
head -n2 marks.out > one.marks &&
tail -n +3 marks.out > two.marks &&
- git fast-import --import-marks=one.marks --import-marks=two.marks <input &&
+ git fast-import --import-marks=one.marks --import-marks=two.marks \
+ --allow-unsafe-features <input &&
test_cmp marks.out combined.marks
'
@@ -2312,7 +2341,7 @@ test_expect_success 'R: feature relative-marks should be honoured' '
mkdir -p .git/info/fast-import/ &&
cp marks.new .git/info/fast-import/relative.in &&
- git fast-import <input &&
+ git fast-import --allow-unsafe-features <input &&
test_cmp marks.new .git/info/fast-import/relative.out
'
@@ -2324,7 +2353,7 @@ test_expect_success 'R: feature no-relative-marks should be honoured' '
feature export-marks=non-relative.out
EOF
- git fast-import <input &&
+ git fast-import --allow-unsafe-features <input &&
test_cmp marks.new non-relative.out
'
@@ -2477,9 +2506,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 &&
(
@@ -2594,7 +2620,7 @@ test_expect_success 'R: quiet option results in no stats being output' '
EOF
- cat input | git fast-import 2> output &&
+ git fast-import 2>output <input &&
test_must_be_empty output
'
@@ -3164,13 +3190,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)
@@ -3190,6 +3225,9 @@ background_import_then_checkpoint () {
then
error=0
break
+ elif test "$output" = "UNEXPECTED"
+ then
+ break
fi
# otherwise ignore cruft
echo >&2 "cruft: $output"
@@ -3202,7 +3240,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
@@ -3343,4 +3381,113 @@ test_expect_success 'X: handling encoding' '
git log -1 --format=%B encoding | grep $(printf "\317\200")
'
+###
+### series Y (submodules and hash algorithms)
+###
+
+cat >Y-sub-input <<\Y_INPUT_END
+blob
+mark :1
+data 4
+foo
+
+reset refs/heads/master
+commit refs/heads/master
+mark :2
+author Full Name <user@company.tld> 1000000000 +0100
+committer Full Name <user@company.tld> 1000000000 +0100
+data 24
+Test submodule commit 1
+M 100644 :1 file
+
+blob
+mark :3
+data 8
+foo
+bar
+
+commit refs/heads/master
+mark :4
+author Full Name <user@company.tld> 1000000001 +0100
+committer Full Name <user@company.tld> 1000000001 +0100
+data 24
+Test submodule commit 2
+from :2
+M 100644 :3 file
+Y_INPUT_END
+
+# Note that the submodule object IDs are intentionally not translated.
+cat >Y-main-input <<\Y_INPUT_END
+blob
+mark :1
+data 4
+foo
+
+reset refs/heads/master
+commit refs/heads/master
+mark :2
+author Full Name <user@company.tld> 2000000000 +0100
+committer Full Name <user@company.tld> 2000000000 +0100
+data 14
+Test commit 1
+M 100644 :1 file
+
+blob
+mark :3
+data 73
+[submodule "sub1"]
+ path = sub1
+ url = https://void.example.com/main.git
+
+commit refs/heads/master
+mark :4
+author Full Name <user@company.tld> 2000000001 +0100
+committer Full Name <user@company.tld> 2000000001 +0100
+data 14
+Test commit 2
+from :2
+M 100644 :3 .gitmodules
+M 160000 0712c5be7cf681388e355ef47525aaf23aee1a6d sub1
+
+blob
+mark :5
+data 8
+foo
+bar
+
+commit refs/heads/master
+mark :6
+author Full Name <user@company.tld> 2000000002 +0100
+committer Full Name <user@company.tld> 2000000002 +0100
+data 14
+Test commit 3
+from :4
+M 100644 :5 file
+M 160000 ff729f5e62f72c0c3978207d9a80e5f3a65f14d7 sub1
+Y_INPUT_END
+
+cat >Y-marks <<\Y_INPUT_END
+:2 0712c5be7cf681388e355ef47525aaf23aee1a6d
+:4 ff729f5e62f72c0c3978207d9a80e5f3a65f14d7
+Y_INPUT_END
+
+test_expect_success 'Y: setup' '
+ test_oid_cache <<-EOF
+ Ymaster sha1:9afed2f9161ddf416c0a1863b8b0725b00070504
+ Ymaster sha256:c0a1010da1df187b2e287654793df01b464bd6f8e3f17fc1481a7dadf84caee3
+ EOF
+'
+
+test_expect_success 'Y: rewrite submodules' '
+ git init main1 &&
+ (
+ cd main1 &&
+ git init sub2 &&
+ git -C sub2 fast-import --export-marks=../sub2-marks <../Y-sub-input &&
+ git fast-import --rewrite-submodules-from=sub:../Y-marks \
+ --rewrite-submodules-to=sub:sub2-marks <../Y-main-input &&
+ test "$(git rev-parse master)" = "$(test_oid Ymaster)"
+ )
+'
+
test_done
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 2e4e214815..690c90fb82 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -541,7 +541,7 @@ 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 ommitting the one tag we asked them to export (because the
+# 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'
@@ -600,9 +600,10 @@ test_expect_success 'directory becomes symlink' '
test_expect_success 'fast-export quotes pathnames' '
git init crazy-paths &&
+ test_config -C crazy-paths core.protectNTFS false &&
(cd crazy-paths &&
blob=$(echo foo | git hash-object -w --stdin) &&
- git update-index --add \
+ git -c core.protectNTFS=false update-index --add \
--cacheinfo 100644 $blob "$(printf "path with\\nnewline")" \
--cacheinfo 100644 $blob "path with \"quote\"" \
--cacheinfo 100644 $blob "path with \\backslash" \
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/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 5856563068..c98c1dfc23 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -202,7 +202,6 @@ test_expect_success 'exit when p4 fails to produce marshaled output' '
export PATH &&
test_expect_code 1 git p4 clone --dest="$git" //depot >errs 2>&1
) &&
- cat errs &&
test_i18ngrep ! Traceback errs
'
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/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh
index 57b533dc6f..e3836888ec 100755
--- a/t/t9810-git-p4-rcs.sh
+++ b/t/t9810-git-p4-rcs.sh
@@ -294,7 +294,6 @@ test_expect_success 'cope with rcs keyword file deletion' '
echo "\$Revision\$" >kwdelfile.c &&
p4 add -t ktext kwdelfile.c &&
p4 submit -d "Add file to be deleted" &&
- cat kwdelfile.c &&
grep 1 kwdelfile.c
) &&
git p4 clone --dest="$git" //depot &&
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 54f8ce18cb..5505e5aa24 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -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 &&
@@ -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 "
'
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index 88bc733ad6..ab5da2cabc 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -163,7 +163,7 @@ test_expect_success 'prompt - inside bare repository' '
'
test_expect_success 'prompt - interactive rebase' '
- printf " (b1|REBASE-i 2/3)" >expected &&
+ printf " (b1|REBASE 2/3)" >expected &&
write_script fake_editor.sh <<-\EOF &&
echo "exec echo" >"$1"
echo "edit $(git log -1 --format="%h")" >>"$1"
@@ -180,7 +180,7 @@ test_expect_success 'prompt - interactive rebase' '
'
test_expect_success 'prompt - rebase merge' '
- printf " (b2|REBASE-i 1/3)" >expected &&
+ printf " (b2|REBASE 1/3)" >expected &&
git checkout b2 &&
test_when_finished "git checkout master" &&
test_must_fail git rebase --merge b1 b2 &&
@@ -189,11 +189,11 @@ test_expect_success 'prompt - rebase merge' '
test_cmp expected "$actual"
'
-test_expect_success 'prompt - rebase' '
+test_expect_success 'prompt - rebase am' '
printf " (b2|REBASE 1/3)" >expected &&
git checkout b2 &&
test_when_finished "git checkout master" &&
- test_must_fail git rebase b1 b2 &&
+ test_must_fail git rebase --apply b1 b2 &&
test_when_finished "git rebase --abort" &&
__git_ps1 >"$actual" &&
test_cmp expected "$actual"
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index b299ecc326..352c213d52 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -308,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
@@ -1012,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
@@ -1175,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
@@ -1183,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
@@ -1477,3 +1516,30 @@ test_set_port () {
port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0}))
eval $var=$port
}
+
+# Compare a file containing rev-list bitmap traversal output to its non-bitmap
+# counterpart. You can't just use test_cmp for this, because the two produce
+# subtly different output:
+#
+# - regular output is in traversal order, whereas bitmap is split by type,
+# with non-packed objects at the end
+#
+# - regular output has a space and the pathname appended to non-commit
+# objects; bitmap output omits this
+#
+# This function normalizes and compares the two. The second file should
+# always be the bitmap output.
+test_bitmap_traversal () {
+ if test "$1" = "--no-confirm-bitmaps"
+ then
+ shift
+ elif cmp "$1" "$2"
+ then
+ echo >&2 "identical raw outputs; are you sure bitmaps were used?"
+ return 1
+ fi &&
+ cut -d' ' -f1 "$1" | sort >"$1.normalized" &&
+ sort "$2" >"$2.normalized" &&
+ test_cmp "$1.normalized" "$2.normalized" &&
+ rm -f "$1.normalized" "$2.normalized"
+}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index e06fa02a0e..9fe390bd5a 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -404,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
@@ -490,21 +494,6 @@ case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
;;
esac
-# Convenience
-#
-# A regexp to match 5, 35 and 40 hexdigits
-_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x35="$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
-_x40="$_x35$_x05"
-
-# Zero SHA-1
-_z40=0000000000000000000000000000000000000000
-
-OID_REGEX="$_x40"
-ZERO_OID=$_z40
-EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
-
# Line feed
LF='
'
@@ -1000,6 +989,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
@@ -1012,12 +1007,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)
@@ -1079,7 +1068,8 @@ finalize_junit_xml () {
# adjust the overall time
junit_time=$(test-tool date getnanos $junit_suite_start)
- sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \
+ -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
<"$junit_xml_path" >"$junit_xml_path.new"
mv "$junit_xml_path.new" "$junit_xml_path"
@@ -1378,6 +1368,20 @@ then
fi
fi
+# Convenience
+# A regexp to match 5, 35 and 40 hexdigits
+_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x35="$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
+_x40="$_x35$_x05"
+
+test_oid_init
+
+ZERO_OID=$(test_oid zero)
+OID_REGEX=$(echo $ZERO_OID | sed -e 's/0/[0-9a-f]/g')
+EMPTY_TREE=$(test_oid empty_tree)
+EMPTY_BLOB=$(test_oid empty_blob)
+_z40=$ZERO_OID
+
# Provide an implementation of the 'yes' utility; the upper bound
# limit is there to help Windows that cannot stop this loop from
# wasting cycles when the downstream stops reading, so do not be
@@ -1402,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*)
@@ -1449,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
@@ -1473,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"