summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README12
-rw-r--r--t/helper/.gitignore9
-rw-r--r--t/helper/test-date.c27
-rw-r--r--t/helper/test-dir-iterator.c65
-rw-r--r--t/helper/test-hashmap.c50
-rw-r--r--t/helper/test-lazy-init-name-hash.c12
-rw-r--r--t/helper/test-progress.c81
-rw-r--r--t/helper/test-read-cache.c5
-rw-r--r--t/helper/test-run-command.c153
-rw-r--r--t/helper/test-tool.c2
-rw-r--r--t/helper/test-tool.h2
-rw-r--r--t/lib-git-daemon.sh7
-rw-r--r--t/lib-git-svn.sh11
-rw-r--r--t/lib-httpd.sh15
-rw-r--r--t/lib-rebase.sh9
-rwxr-xr-xt/perf/p5601-clone-reference.sh (renamed from t/perf/p5600-clone-reference.sh)0
-rwxr-xr-xt/t0000-basic.sh82
-rwxr-xr-xt/t0011-hashmap.sh58
-rwxr-xr-xt/t0014-alias.sh7
-rwxr-xr-xt/t0016-oidmap.sh30
-rwxr-xr-xt/t0017-env-helper.sh99
-rwxr-xr-xt/t0021-conversion.sh3
-rwxr-xr-xt/t0027-auto-crlf.sh6
-rwxr-xr-xt/t0028-working-tree-encoding.sh41
-rwxr-xr-xt/t0040-parse-options.sh7
-rwxr-xr-xt/t0050-filesystem.sh20
-rwxr-xr-xt/t0061-run-command.sh19
-rwxr-xr-xt/t0066-dir-iterator.sh148
-rwxr-xr-xt/t0090-cache-tree.sh4
-rwxr-xr-xt/t0205-gettext-poison.sh7
-rwxr-xr-xt/t0211-trace2-perf.sh4
-rwxr-xr-xt/t0212-trace2-event.sh19
-rwxr-xr-xt/t0410-partial-clone.sh91
-rwxr-xr-xt/t0500-progress-display.sh286
-rwxr-xr-xt/t1007-hash-object.sh58
-rwxr-xr-xt/t1300-config.sh9
-rwxr-xr-xt/t1305-config-include.sh21
-rwxr-xr-xt/t1308-config-set.sh8
-rwxr-xr-xt/t1309-early-config.sh10
-rwxr-xr-xt/t1404-update-ref-errors.sh64
-rwxr-xr-xt/t1410-reflog.sh16
-rwxr-xr-xt/t1414-reflog-walk.sh3
-rwxr-xr-xt/t1450-fsck.sh57
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh13
-rwxr-xr-xt/t1507-rev-parse-upstream.sh12
-rwxr-xr-xt/t1600-index.sh4
-rwxr-xr-xt/t1700-split-index.sh51
-rwxr-xr-xt/t2022-checkout-paths.sh11
-rwxr-xr-xt/t2070-restore.sh11
-rwxr-xr-xt/t2203-add-intent.sh6
-rwxr-xr-xt/t3005-ls-files-relative.sh12
-rwxr-xr-xt/t3030-merge-recursive.sh37
-rwxr-xr-xt/t3201-branch-contains.sh8
-rwxr-xr-xt/t3206-range-diff.sh379
-rw-r--r--t/t3206/history.export115
-rwxr-xr-xt/t3301-notes.sh140
-rwxr-xr-xt/t3305-notes-fanout.sh22
-rwxr-xr-xt/t3306-notes-prune.sh45
-rwxr-xr-xt/t3311-notes-merge-fanout.sh10
-rwxr-xr-xt/t3400-rebase.sh38
-rwxr-xr-xt/t3404-rebase-interactive.sh43
-rwxr-xr-xt/t3416-rebase-onto-threedots.sh57
-rwxr-xr-xt/t3418-rebase-continue.sh14
-rwxr-xr-xt/t3420-rebase-autostash.sh12
-rwxr-xr-xt/t3421-rebase-topology-linear.sh29
-rwxr-xr-xt/t3422-rebase-incompatible-options.sh10
-rwxr-xr-xt/t3427-rebase-subtree.sh160
-rwxr-xr-xt/t3429-rebase-edit-todo.sh21
-rwxr-xr-xt/t3430-rebase-merges.sh45
-rwxr-xr-xt/t3431-rebase-fork-point.sh57
-rwxr-xr-xt/t3432-rebase-fast-forward.sh125
-rwxr-xr-xt/t3506-cherry-pick-ff.sh8
-rwxr-xr-xt/t3600-rm.sh17
-rwxr-xr-xt/t3701-add-interactive.sh2
-rwxr-xr-xt/t3800-mktag.sh49
-rwxr-xr-xt/t3903-stash.sh55
-rwxr-xr-xt/t3906-stash-submodule.sh42
-rwxr-xr-xt/t3908-stash-in-worktree.sh27
-rwxr-xr-xt/t4000-diff-format.sh2
-rwxr-xr-xt/t4002-diff-basic.sh367
-rwxr-xr-xt/t4009-diff-rename-4.sh19
-rwxr-xr-xt/t4013-diff-various.sh3
-rwxr-xr-xt/t4014-format-patch.sh841
-rwxr-xr-xt/t4015-diff-whitespace.sh22
-rwxr-xr-xt/t4018-diff-funcname.sh1
-rw-r--r--t/t4018/dts-labels9
-rw-r--r--t/t4018/dts-node-unitless8
-rw-r--r--t/t4018/dts-nodes8
-rw-r--r--t/t4018/dts-nodes-boolean-prop9
-rw-r--r--t/t4018/dts-nodes-comment18
-rw-r--r--t/t4018/dts-nodes-comment28
-rw-r--r--t/t4018/dts-nodes-multiline-prop13
-rw-r--r--t/t4018/dts-reference9
-rw-r--r--t/t4018/dts-root5
-rw-r--r--t/t4018/dts-root-comment8
-rwxr-xr-xt/t4034-diff-words.sh1
-rw-r--r--t/t4034/dts/expect37
-rw-r--r--t/t4034/dts/post32
-rw-r--r--t/t4034/dts/pre32
-rwxr-xr-xt/t4038-diff-combined.sh2
-rwxr-xr-xt/t4067-diff-partial-clone.sh31
-rwxr-xr-xt/t4150-am.sh52
-rwxr-xr-xt/t4202-log.sh22
-rwxr-xr-xt/t4203-mailmap.sh33
-rwxr-xr-xt/t4210-log-i18n.sh41
-rwxr-xr-xt/t4211-line-log.sh82
-rwxr-xr-xt/t4214-log-graph-octopus.sh329
-rwxr-xr-xt/t5000-tar-tree.sh16
-rw-r--r--t/t5000/huge-object (renamed from t/t5000/19f9c8273ec45a8938e6999cb59b3ff66739902a)bin2048 -> 2048 bytes
-rwxr-xr-xt/t5004-archive-corner-cases.sh19
-rwxr-xr-xt/t5310-pack-bitmaps.sh15
-rwxr-xr-xt/t5318-commit-graph.sh93
-rwxr-xr-xt/t5324-split-commit-graph.sh4
-rwxr-xr-xt/t5500-fetch-pack.sh54
-rwxr-xr-xt/t5510-fetch.sh47
-rwxr-xr-xt/t5512-ls-remote.sh3
-rwxr-xr-xt/t5514-fetch-multiple.sh11
-rwxr-xr-xt/t5515-fetch-merge-logic.sh3
-rwxr-xr-xt/t5517-push-mirror.sh10
-rwxr-xr-xt/t5537-fetch-shallow.sh3
-rwxr-xr-xt/t5541-http-push-smart.sh91
-rwxr-xr-xt/t5545-push-options.sh3
-rwxr-xr-xt/t5553-set-upstream.sh178
-rwxr-xr-xt/t5601-clone.sh7
-rwxr-xr-xt/t5604-clone-reference.sh133
-rwxr-xr-xt/t5607-clone-bundle.sh11
-rwxr-xr-xt/t5616-partial-clone.sh62
-rwxr-xr-xt/t5700-protocol-v1.sh3
-rwxr-xr-xt/t5702-protocol-v2.sh26
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh206
-rwxr-xr-xt/t5801-remote-helpers.sh1
-rwxr-xr-xt/t6000-rev-list-misc.sh8
-rwxr-xr-xt/t6006-rev-list-format.sh5
-rwxr-xr-xt/t6030-bisect-porcelain.sh31
-rwxr-xr-xt/t6036-recursive-corner-cases.sh8
-rwxr-xr-xt/t6040-tracking-info.sh6
-rwxr-xr-xt/t6043-merge-rename-directories.sh111
-rwxr-xr-xt/t6047-diff3-conflict-markers.sh202
-rwxr-xr-xt/t6112-rev-list-filters-objects.sh194
-rwxr-xr-xt/t6120-describe.sh15
-rwxr-xr-xt/t6200-fmt-merge-msg.sh7
-rwxr-xr-xt/t6300-for-each-ref.sh19
-rwxr-xr-xt/t7008-filter-branch-null-sha1.sh (renamed from t/t7009-filter-branch-null-sha1.sh)0
-rwxr-xr-xt/t7201-co.sh2
-rwxr-xr-xt/t7300-clean.sh76
-rwxr-xr-xt/t7400-submodule-basic.sh2
-rwxr-xr-xt/t7406-submodule-update.sh3
-rwxr-xr-xt/t7419-submodule-set-branch.sh6
-rwxr-xr-xt/t7503-pre-commit-and-pre-merge-commit-hooks.sh281
-rwxr-xr-xt/t7503-pre-commit-hook.sh139
-rwxr-xr-xt/t7505-prepare-commit-msg-hook.sh8
-rw-r--r--t/t7505/expected-rebase-i3
-rwxr-xr-xt/t7512-status-help.sh6
-rwxr-xr-xt/t7519-status-fsmonitor.sh19
-rwxr-xr-xt/t7519/fsmonitor-env24
-rwxr-xr-xt/t7700-repack.sh15
-rwxr-xr-xt/t7812-grep-icase-non-ascii.sh28
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh21
-rwxr-xr-xt/t7815-grep-binary.sh (renamed from t/t7008-grep-binary.sh)101
-rwxr-xr-xt/t7816-grep-binary-pattern.sh127
-rwxr-xr-xt/t9300-fast-import.sh50
-rwxr-xr-xt/t9350-fast-export.sh68
-rwxr-xr-xt/t9902-completion.sh77
-rw-r--r--t/test-lib-functions.sh198
-rw-r--r--t/test-lib.sh74
165 files changed, 6502 insertions, 1789 deletions
diff --git a/t/README b/t/README
index 9747971d58..60d5b77bcc 100644
--- a/t/README
+++ b/t/README
@@ -334,7 +334,7 @@ that cannot be easily covered by a few specific test cases. These
could be enabled by running the test suite with correct GIT_TEST_
environment set.
-GIT_TEST_FAIL_PREREQS<non-empty?> fails all prerequisites. This is
+GIT_TEST_FAIL_PREREQS=<boolean> fails all prerequisites. This is
useful for discovering issues with the tests where say a later test
implicitly depends on an optional earlier test.
@@ -343,11 +343,11 @@ whether this mode is active, and e.g. skip some tests that are hard to
refactor to deal with it. The "SYMLINKS" prerequisite is currently
excluded as so much relies on it, but this might change in the future.
-GIT_TEST_GETTEXT_POISON=<non-empty?> turns all strings marked for
-translation into gibberish if non-empty (think "test -n"). Used for
-spotting those tests that need to be marked with a C_LOCALE_OUTPUT
-prerequisite when adding more strings for translation. See "Testing
-marked strings" in po/README for details.
+GIT_TEST_GETTEXT_POISON=<boolean> turns all strings marked for
+translation into gibberish if true. Used for spotting those tests that
+need to be marked with a C_LOCALE_OUTPUT prerequisite when adding more
+strings for translation. See "Testing marked strings" in po/README for
+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.
diff --git a/t/helper/.gitignore b/t/helper/.gitignore
index 2bad28af92..48c7bb0bbb 100644
--- a/t/helper/.gitignore
+++ b/t/helper/.gitignore
@@ -1,5 +1,4 @@
-*
-!*.sh
-!*.[ch]
-!*.gitignore
-
+/test-tool
+/test-fake-ssh
+/test-line-buffer
+/test-svn-fe
diff --git a/t/helper/test-date.c b/t/helper/test-date.c
index 585347ea48..099eff4f0f 100644
--- a/t/helper/test-date.c
+++ b/t/helper/test-date.c
@@ -12,13 +12,13 @@ static const char *usage_msg = "\n"
" test-tool date is64bit\n"
" test-tool date time_t-is64bit\n";
-static void show_relative_dates(const char **argv, struct timeval *now)
+static void show_relative_dates(const char **argv)
{
struct strbuf buf = STRBUF_INIT;
for (; *argv; argv++) {
time_t t = atoi(*argv);
- show_date_relative(t, now, &buf);
+ show_date_relative(t, &buf);
printf("%s -> %s\n", *argv, buf.buf);
}
strbuf_release(&buf);
@@ -74,20 +74,20 @@ static void parse_dates(const char **argv)
strbuf_release(&result);
}
-static void parse_approxidate(const char **argv, struct timeval *now)
+static void parse_approxidate(const char **argv)
{
for (; *argv; argv++) {
timestamp_t t;
- t = approxidate_relative(*argv, now);
+ t = approxidate_relative(*argv);
printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(ISO8601)));
}
}
-static void parse_approx_timestamp(const char **argv, struct timeval *now)
+static void parse_approx_timestamp(const char **argv)
{
for (; *argv; argv++) {
timestamp_t t;
- t = approxidate_relative(*argv, now);
+ t = approxidate_relative(*argv);
printf("%s -> %"PRItime"\n", *argv, t);
}
}
@@ -103,22 +103,13 @@ static void getnanos(const char **argv)
int cmd__date(int argc, const char **argv)
{
- struct timeval now;
const char *x;
- x = getenv("GIT_TEST_DATE_NOW");
- if (x) {
- now.tv_sec = atoi(x);
- now.tv_usec = 0;
- }
- else
- gettimeofday(&now, NULL);
-
argv++;
if (!*argv)
usage(usage_msg);
if (!strcmp(*argv, "relative"))
- show_relative_dates(argv+1, &now);
+ show_relative_dates(argv+1);
else if (!strcmp(*argv, "human"))
show_human_dates(argv+1);
else if (skip_prefix(*argv, "show:", &x))
@@ -126,9 +117,9 @@ int cmd__date(int argc, const char **argv)
else if (!strcmp(*argv, "parse"))
parse_dates(argv+1);
else if (!strcmp(*argv, "approxidate"))
- parse_approxidate(argv+1, &now);
+ parse_approxidate(argv+1);
else if (!strcmp(*argv, "timestamp"))
- parse_approx_timestamp(argv+1, &now);
+ parse_approx_timestamp(argv+1);
else if (!strcmp(*argv, "getnanos"))
getnanos(argv+1);
else if (!strcmp(*argv, "is64bit"))
diff --git a/t/helper/test-dir-iterator.c b/t/helper/test-dir-iterator.c
new file mode 100644
index 0000000000..659b6bfa81
--- /dev/null
+++ b/t/helper/test-dir-iterator.c
@@ -0,0 +1,65 @@
+#include "test-tool.h"
+#include "git-compat-util.h"
+#include "strbuf.h"
+#include "iterator.h"
+#include "dir-iterator.h"
+
+static const char *error_name(int error_number)
+{
+ switch (error_number) {
+ case ENOENT: return "ENOENT";
+ case ENOTDIR: return "ENOTDIR";
+ default: return "ESOMETHINGELSE";
+ }
+}
+
+/*
+ * usage:
+ * tool-test dir-iterator [--follow-symlinks] [--pedantic] directory_path
+ */
+int cmd__dir_iterator(int argc, const char **argv)
+{
+ struct dir_iterator *diter;
+ unsigned int flags = 0;
+ int iter_status;
+
+ for (++argv, --argc; *argv && starts_with(*argv, "--"); ++argv, --argc) {
+ if (strcmp(*argv, "--follow-symlinks") == 0)
+ flags |= DIR_ITERATOR_FOLLOW_SYMLINKS;
+ else if (strcmp(*argv, "--pedantic") == 0)
+ flags |= DIR_ITERATOR_PEDANTIC;
+ else
+ die("invalid option '%s'", *argv);
+ }
+
+ if (!*argv || argc != 1)
+ die("dir-iterator needs exactly one non-option argument");
+
+ diter = dir_iterator_begin(*argv, flags);
+
+ if (!diter) {
+ printf("dir_iterator_begin failure: %s\n", error_name(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ while ((iter_status = dir_iterator_advance(diter)) == ITER_OK) {
+ if (S_ISDIR(diter->st.st_mode))
+ printf("[d] ");
+ else if (S_ISREG(diter->st.st_mode))
+ printf("[f] ");
+ else if (S_ISLNK(diter->st.st_mode))
+ printf("[s] ");
+ else
+ printf("[?] ");
+
+ printf("(%s) [%s] %s\n", diter->relative_path, diter->basename,
+ diter->path.buf);
+ }
+
+ if (iter_status != ITER_DONE) {
+ printf("dir_iterator_advance failure\n");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c
index aaf17b0ddf..f38706216f 100644
--- a/t/helper/test-hashmap.c
+++ b/t/helper/test-hashmap.c
@@ -5,6 +5,7 @@
struct test_entry
{
+ int padding; /* hashmap entry no longer needs to be the first member */
struct hashmap_entry ent;
/* key and value as two \0-terminated strings */
char key[FLEX_ARRAY];
@@ -16,15 +17,17 @@ static const char *get_value(const struct test_entry *e)
}
static int test_entry_cmp(const void *cmp_data,
- const void *entry,
- const void *entry_or_key,
+ const struct hashmap_entry *eptr,
+ const struct hashmap_entry *entry_or_key,
const void *keydata)
{
const int ignore_case = cmp_data ? *((int *)cmp_data) : 0;
- const struct test_entry *e1 = entry;
- const struct test_entry *e2 = entry_or_key;
+ const struct test_entry *e1, *e2;
const char *key = keydata;
+ e1 = container_of(eptr, const struct test_entry, ent);
+ e2 = container_of(entry_or_key, const struct test_entry, ent);
+
if (ignore_case)
return strcasecmp(e1->key, key ? key : e2->key);
else
@@ -37,7 +40,7 @@ static struct test_entry *alloc_test_entry(unsigned int hash,
size_t klen = strlen(key);
size_t vlen = strlen(value);
struct test_entry *entry = xmalloc(st_add4(sizeof(*entry), klen, vlen, 2));
- hashmap_entry_init(entry, hash);
+ hashmap_entry_init(&entry->ent, hash);
memcpy(entry->key, key, klen + 1);
memcpy(entry->key + klen + 1, value, vlen + 1);
return entry;
@@ -103,11 +106,11 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
/* add entries */
for (i = 0; i < TEST_SIZE; i++) {
- hashmap_entry_init(entries[i], hashes[i]);
- hashmap_add(&map, entries[i]);
+ hashmap_entry_init(&entries[i]->ent, hashes[i]);
+ hashmap_add(&map, &entries[i]->ent);
}
- hashmap_free(&map, 0);
+ hashmap_free(&map);
}
} else {
/* test map lookups */
@@ -116,8 +119,8 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
/* fill the map (sparsely if specified) */
j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
for (i = 0; i < j; i++) {
- hashmap_entry_init(entries[i], hashes[i]);
- hashmap_add(&map, entries[i]);
+ hashmap_entry_init(&entries[i]->ent, hashes[i]);
+ hashmap_add(&map, &entries[i]->ent);
}
for (j = 0; j < rounds; j++) {
@@ -127,7 +130,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
}
}
- hashmap_free(&map, 0);
+ hashmap_free(&map);
}
}
@@ -179,7 +182,7 @@ int cmd__hashmap(int argc, const char **argv)
entry = alloc_test_entry(hash, p1, p2);
/* add to hashmap */
- hashmap_add(&map, entry);
+ hashmap_add(&map, &entry->ent);
} else if (!strcmp("put", cmd) && p1 && p2) {
@@ -187,43 +190,44 @@ int cmd__hashmap(int argc, const char **argv)
entry = alloc_test_entry(hash, p1, p2);
/* add / replace entry */
- entry = hashmap_put(&map, entry);
+ entry = hashmap_put_entry(&map, entry, ent);
/* print and free replaced entry, if any */
puts(entry ? get_value(entry) : "NULL");
free(entry);
} else if (!strcmp("get", cmd) && p1) {
-
/* lookup entry in hashmap */
- entry = hashmap_get_from_hash(&map, hash, p1);
+ entry = hashmap_get_entry_from_hash(&map, hash, p1,
+ struct test_entry, ent);
/* print result */
if (!entry)
puts("NULL");
- while (entry) {
+ hashmap_for_each_entry_from(&map, entry, ent)
puts(get_value(entry));
- entry = hashmap_get_next(&map, entry);
- }
} else if (!strcmp("remove", cmd) && p1) {
/* setup static key */
struct hashmap_entry key;
+ struct hashmap_entry *rm;
hashmap_entry_init(&key, hash);
/* remove entry from hashmap */
- entry = hashmap_remove(&map, &key, p1);
+ rm = hashmap_remove(&map, &key, p1);
+ entry = rm ? container_of(rm, struct test_entry, ent)
+ : NULL;
/* print result and free entry*/
puts(entry ? get_value(entry) : "NULL");
free(entry);
} else if (!strcmp("iterate", cmd)) {
-
struct hashmap_iter iter;
- hashmap_iter_init(&map, &iter);
- while ((entry = hashmap_iter_next(&iter)))
+
+ hashmap_for_each_entry(&map, &iter, entry,
+ ent /* member name */)
printf("%s %s\n", entry->key, get_value(entry));
} else if (!strcmp("size", cmd)) {
@@ -258,6 +262,6 @@ int cmd__hashmap(int argc, const char **argv)
}
strbuf_release(&line);
- hashmap_free(&map, 1);
+ hashmap_free_entries(&map, struct test_entry, ent);
return 0;
}
diff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c
index b99a37080d..cd1b4c9736 100644
--- a/t/helper/test-lazy-init-name-hash.c
+++ b/t/helper/test-lazy-init-name-hash.c
@@ -41,17 +41,13 @@ static void dump_run(void)
die("non-threaded code path used");
}
- dir = hashmap_iter_first(&the_index.dir_hash, &iter_dir);
- while (dir) {
+ hashmap_for_each_entry(&the_index.dir_hash, &iter_dir, dir,
+ ent /* member name */)
printf("dir %08x %7d %s\n", dir->ent.hash, dir->nr, dir->name);
- dir = hashmap_iter_next(&iter_dir);
- }
- ce = hashmap_iter_first(&the_index.name_hash, &iter_cache);
- while (ce) {
+ hashmap_for_each_entry(&the_index.name_hash, &iter_cache, ce,
+ ent /* member name */)
printf("name %08x %s\n", ce->ent.hash, ce->name);
- ce = hashmap_iter_next(&iter_cache);
- }
discard_cache();
}
diff --git a/t/helper/test-progress.c b/t/helper/test-progress.c
new file mode 100644
index 0000000000..42b96cb103
--- /dev/null
+++ b/t/helper/test-progress.c
@@ -0,0 +1,81 @@
+/*
+ * A test helper to exercise the progress display.
+ *
+ * Reads instructions from standard input, one instruction per line:
+ *
+ * "progress <items>" - Call display_progress() with the given item count
+ * as parameter.
+ * "throughput <bytes> <millis> - Call display_throughput() with the given
+ * byte count as parameter. The 'millis'
+ * specify the time elapsed since the
+ * start_progress() call.
+ * "update" - Set the 'progress_update' flag.
+ *
+ * See 't0500-progress-display.sh' for examples.
+ */
+#include "test-tool.h"
+#include "gettext.h"
+#include "parse-options.h"
+#include "progress.h"
+#include "strbuf.h"
+
+/*
+ * These are defined in 'progress.c', but are not exposed in 'progress.h',
+ * because they are exclusively for testing.
+ */
+extern int progress_testing;
+extern uint64_t progress_test_ns;
+void progress_test_force_update(void);
+
+int cmd__progress(int argc, const char **argv)
+{
+ int total = 0;
+ const char *title;
+ struct strbuf line = STRBUF_INIT;
+ struct progress *progress;
+
+ const char *usage[] = {
+ "test-tool progress [--total=<n>] <progress-title>",
+ NULL
+ };
+ struct option options[] = {
+ OPT_INTEGER(0, "total", &total, "total number of items"),
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, NULL, options, usage, 0);
+ if (argc != 1)
+ die("need a title for the progress output");
+ title = argv[0];
+
+ progress_testing = 1;
+ progress = start_progress(title, total);
+ while (strbuf_getline(&line, stdin) != EOF) {
+ char *end;
+
+ if (skip_prefix(line.buf, "progress ", (const char **) &end)) {
+ uint64_t item_count = strtoull(end, &end, 10);
+ if (*end != '\0')
+ die("invalid input: '%s'\n", line.buf);
+ display_progress(progress, item_count);
+ } else if (skip_prefix(line.buf, "throughput ",
+ (const char **) &end)) {
+ uint64_t byte_count, test_ms;
+
+ byte_count = strtoull(end, &end, 10);
+ if (*end != ' ')
+ die("invalid input: '%s'\n", line.buf);
+ test_ms = strtoull(end + 1, &end, 10);
+ if (*end != '\0')
+ die("invalid input: '%s'\n", line.buf);
+ progress_test_ns = test_ms * 1000 * 1000;
+ display_throughput(progress, byte_count);
+ } else if (!strcmp(line.buf, "update"))
+ progress_test_force_update();
+ else
+ die("invalid input: '%s'\n", line.buf);
+ }
+ stop_progress(&progress);
+
+ return 0;
+}
diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c
index 7e79b555de..244977a29b 100644
--- a/t/helper/test-read-cache.c
+++ b/t/helper/test-read-cache.c
@@ -4,11 +4,10 @@
int cmd__read_cache(int argc, const char **argv)
{
- int i, cnt = 1, namelen;
+ int i, cnt = 1;
const char *name = NULL;
if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) {
- namelen = strlen(name);
argc--;
argv++;
}
@@ -24,7 +23,7 @@ int cmd__read_cache(int argc, const char **argv)
refresh_index(&the_index, REFRESH_QUIET,
NULL, NULL, NULL);
- pos = index_name_pos(&the_index, name, namelen);
+ pos = index_name_pos(&the_index, name, strlen(name));
if (pos < 0)
die("%s not in index", name);
printf("%s is%s up to date\n", name,
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index 2cc93bb69c..ead6dc611a 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -10,9 +10,14 @@
#include "test-tool.h"
#include "git-compat-util.h"
+#include "cache.h"
#include "run-command.h"
#include "argv-array.h"
#include "strbuf.h"
+#include "parse-options.h"
+#include "string-list.h"
+#include "thread-utils.h"
+#include "wildmatch.h"
#include <string.h>
#include <errno.h>
@@ -50,11 +55,159 @@ static int task_finished(int result,
return 1;
}
+struct testsuite {
+ struct string_list tests, failed;
+ int next;
+ int quiet, immediate, verbose, verbose_log, trace, write_junit_xml;
+};
+#define TESTSUITE_INIT \
+ { STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, -1, 0, 0, 0, 0, 0, 0 }
+
+static int next_test(struct child_process *cp, struct strbuf *err, void *cb,
+ void **task_cb)
+{
+ struct testsuite *suite = cb;
+ const char *test;
+ if (suite->next >= suite->tests.nr)
+ return 0;
+
+ test = suite->tests.items[suite->next++].string;
+ argv_array_pushl(&cp->args, "sh", test, NULL);
+ if (suite->quiet)
+ argv_array_push(&cp->args, "--quiet");
+ if (suite->immediate)
+ argv_array_push(&cp->args, "-i");
+ if (suite->verbose)
+ argv_array_push(&cp->args, "-v");
+ if (suite->verbose_log)
+ argv_array_push(&cp->args, "-V");
+ if (suite->trace)
+ argv_array_push(&cp->args, "-x");
+ if (suite->write_junit_xml)
+ argv_array_push(&cp->args, "--write-junit-xml");
+
+ strbuf_addf(err, "Output of '%s':\n", test);
+ *task_cb = (void *)test;
+
+ return 1;
+}
+
+static int test_finished(int result, struct strbuf *err, void *cb,
+ void *task_cb)
+{
+ struct testsuite *suite = cb;
+ const char *name = (const char *)task_cb;
+
+ if (result)
+ string_list_append(&suite->failed, name);
+
+ strbuf_addf(err, "%s: '%s'\n", result ? "FAIL" : "SUCCESS", name);
+
+ return 0;
+}
+
+static int test_failed(struct strbuf *out, void *cb, void *task_cb)
+{
+ struct testsuite *suite = cb;
+ const char *name = (const char *)task_cb;
+
+ string_list_append(&suite->failed, name);
+ strbuf_addf(out, "FAILED TO START: '%s'\n", name);
+
+ return 0;
+}
+
+static const char * const testsuite_usage[] = {
+ "test-run-command testsuite [<options>] [<pattern>...]",
+ NULL
+};
+
+static int testsuite(int argc, const char **argv)
+{
+ struct testsuite suite = TESTSUITE_INIT;
+ int max_jobs = 1, i, ret;
+ DIR *dir;
+ struct dirent *d;
+ struct option options[] = {
+ OPT_BOOL('i', "immediate", &suite.immediate,
+ "stop at first failed test case(s)"),
+ OPT_INTEGER('j', "jobs", &max_jobs, "run <N> jobs in parallel"),
+ OPT_BOOL('q', "quiet", &suite.quiet, "be terse"),
+ OPT_BOOL('v', "verbose", &suite.verbose, "be verbose"),
+ OPT_BOOL('V', "verbose-log", &suite.verbose_log,
+ "be verbose, redirected to a file"),
+ OPT_BOOL('x', "trace", &suite.trace, "trace shell commands"),
+ OPT_BOOL(0, "write-junit-xml", &suite.write_junit_xml,
+ "write JUnit-style XML files"),
+ OPT_END()
+ };
+
+ memset(&suite, 0, sizeof(suite));
+ suite.tests.strdup_strings = suite.failed.strdup_strings = 1;
+
+ argc = parse_options(argc, argv, NULL, options,
+ testsuite_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+
+ if (max_jobs <= 0)
+ max_jobs = online_cpus();
+
+ dir = opendir(".");
+ if (!dir)
+ die("Could not open the current directory");
+ while ((d = readdir(dir))) {
+ const char *p = d->d_name;
+
+ if (*p != 't' || !isdigit(p[1]) || !isdigit(p[2]) ||
+ !isdigit(p[3]) || !isdigit(p[4]) || p[5] != '-' ||
+ !ends_with(p, ".sh"))
+ continue;
+
+ /* No pattern: match all */
+ if (!argc) {
+ string_list_append(&suite.tests, p);
+ continue;
+ }
+
+ for (i = 0; i < argc; i++)
+ if (!wildmatch(argv[i], p, 0)) {
+ string_list_append(&suite.tests, p);
+ break;
+ }
+ }
+ closedir(dir);
+
+ if (!suite.tests.nr)
+ die("No tests match!");
+ if (max_jobs > suite.tests.nr)
+ max_jobs = suite.tests.nr;
+
+ fprintf(stderr, "Running %d tests (%d at a time)\n",
+ suite.tests.nr, max_jobs);
+
+ ret = run_processes_parallel(max_jobs, next_test, test_failed,
+ test_finished, &suite);
+
+ if (suite.failed.nr > 0) {
+ ret = 1;
+ fprintf(stderr, "%d tests failed:\n\n", suite.failed.nr);
+ for (i = 0; i < suite.failed.nr; i++)
+ fprintf(stderr, "\t%s\n", suite.failed.items[i].string);
+ }
+
+ string_list_clear(&suite.tests, 0);
+ string_list_clear(&suite.failed, 0);
+
+ return !!ret;
+}
+
int cmd__run_command(int argc, const char **argv)
{
struct child_process proc = CHILD_PROCESS_INIT;
int jobs;
+ if (argc > 1 && !strcmp(argv[1], "testsuite"))
+ exit(testsuite(argc - 1, argv + 1));
+
if (argc < 3)
return 1;
while (!strcmp(argv[1], "env")) {
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 1eac25233f..19ee26d931 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -19,6 +19,7 @@ static struct test_cmd cmds[] = {
{ "ctype", cmd__ctype },
{ "date", cmd__date },
{ "delta", cmd__delta },
+ { "dir-iterator", cmd__dir_iterator },
{ "drop-caches", cmd__drop_caches },
{ "dump-cache-tree", cmd__dump_cache_tree },
{ "dump-fsmonitor", cmd__dump_fsmonitor },
@@ -41,6 +42,7 @@ static struct test_cmd cmds[] = {
{ "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-midx", cmd__read_midx },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index c7a46dc320..c2aa56ef50 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -9,6 +9,7 @@ int cmd__config(int argc, const char **argv);
int cmd__ctype(int argc, const char **argv);
int cmd__date(int argc, const char **argv);
int cmd__delta(int argc, const char **argv);
+int cmd__dir_iterator(int argc, const char **argv);
int cmd__drop_caches(int argc, const char **argv);
int cmd__dump_cache_tree(int argc, const char **argv);
int cmd__dump_fsmonitor(int argc, const char **argv);
@@ -31,6 +32,7 @@ int cmd__parse_options(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_midx(int argc, const char **argv);
diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
index 7b3407134e..fb8f887080 100644
--- a/t/lib-git-daemon.sh
+++ b/t/lib-git-daemon.sh
@@ -15,8 +15,7 @@
#
# test_done
-test_tristate GIT_TEST_GIT_DAEMON
-if test "$GIT_TEST_GIT_DAEMON" = false
+if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON
then
skip_all="git-daemon testing disabled (unset GIT_TEST_GIT_DAEMON to enable)"
test_done
@@ -24,7 +23,7 @@ fi
if test_have_prereq !PIPE
then
- test_skip_or_die $GIT_TEST_GIT_DAEMON "file system does not support FIFOs"
+ test_skip_or_die GIT_TEST_GIT_DAEMON "file system does not support FIFOs"
fi
test_set_port LIB_GIT_DAEMON_PORT
@@ -73,7 +72,7 @@ start_git_daemon() {
kill "$GIT_DAEMON_PID"
wait "$GIT_DAEMON_PID"
unset GIT_DAEMON_PID
- test_skip_or_die $GIT_TEST_GIT_DAEMON \
+ test_skip_or_die GIT_TEST_GIT_DAEMON \
"git daemon failed to start"
fi
}
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index c1271d6863..bc0b9c71f8 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -69,14 +69,12 @@ svn_cmd () {
maybe_start_httpd () {
loc=${1-svn}
- test_tristate GIT_SVN_TEST_HTTPD
- case $GIT_SVN_TEST_HTTPD in
- true)
+ if git env--helper --type=bool --default=false --exit-code GIT_TEST_SVN_HTTPD
+ then
. "$TEST_DIRECTORY"/lib-httpd.sh
LIB_HTTPD_SVN="$loc"
start_httpd
- ;;
- esac
+ fi
}
convert_to_rev_db () {
@@ -106,8 +104,7 @@ EOF
}
require_svnserve () {
- test_tristate GIT_TEST_SVNSERVE
- if ! test "$GIT_TEST_SVNSERVE" = true
+ if ! git env--helper --type=bool --default=false --exit-code GIT_TEST_SVNSERVE
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 b3cc62bd36..0d985758c6 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -41,15 +41,14 @@ then
test_done
fi
-test_tristate GIT_TEST_HTTPD
-if test "$GIT_TEST_HTTPD" = false
+if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_HTTPD
then
skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)"
test_done
fi
if ! test_have_prereq NOT_ROOT; then
- test_skip_or_die $GIT_TEST_HTTPD \
+ test_skip_or_die GIT_TEST_HTTPD \
"Cannot run httpd tests as root"
fi
@@ -95,7 +94,7 @@ GIT_TRACE=$GIT_TRACE; export GIT_TRACE
if ! test -x "$LIB_HTTPD_PATH"
then
- test_skip_or_die $GIT_TEST_HTTPD "no web server found at '$LIB_HTTPD_PATH'"
+ test_skip_or_die GIT_TEST_HTTPD "no web server found at '$LIB_HTTPD_PATH'"
fi
HTTPD_VERSION=$($LIB_HTTPD_PATH -v | \
@@ -107,19 +106,19 @@ then
then
if ! test $HTTPD_VERSION -ge 2
then
- test_skip_or_die $GIT_TEST_HTTPD \
+ test_skip_or_die GIT_TEST_HTTPD \
"at least Apache version 2 is required"
fi
if ! test -d "$DEFAULT_HTTPD_MODULE_PATH"
then
- test_skip_or_die $GIT_TEST_HTTPD \
+ test_skip_or_die GIT_TEST_HTTPD \
"Apache module directory not found"
fi
LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH"
fi
else
- test_skip_or_die $GIT_TEST_HTTPD \
+ test_skip_or_die GIT_TEST_HTTPD \
"Could not identify web server at '$LIB_HTTPD_PATH'"
fi
@@ -184,7 +183,7 @@ start_httpd() {
if test $? -ne 0
then
cat "$HTTPD_ROOT_PATH"/error.log >&4 2>/dev/null
- test_skip_or_die $GIT_TEST_HTTPD "web server setup failed"
+ test_skip_or_die GIT_TEST_HTTPD "web server setup failed"
fi
}
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 7ea30e5006..6d87961e41 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -44,10 +44,10 @@ set_fake_editor () {
rm -f "$1"
echo 'rebase -i script before editing:'
cat "$1".tmp
- action=pick
+ action=\&
for line in $FAKE_LINES; do
case $line in
- pick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)
+ pick|p|squash|s|fixup|f|edit|e|reword|r|drop|d|label|l|reset|r|merge|m)
action="$line";;
exec_*|x_*|break|b)
echo "$line" | sed 's/_/ /g' >> "$1";;
@@ -58,11 +58,12 @@ set_fake_editor () {
bad)
action="badcmd";;
fakesha)
+ test \& != "$action" || action=pick
echo "$action XXXXXXX False commit" >> "$1"
action=pick;;
*)
- sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
- action=pick;;
+ sed -n "${line}s/^[a-z][a-z]*/$action/p" < "$1".tmp >> "$1"
+ action=\&;;
esac
done
echo 'rebase -i script after editing:'
diff --git a/t/perf/p5600-clone-reference.sh b/t/perf/p5601-clone-reference.sh
index 68fed66347..68fed66347 100755
--- a/t/perf/p5600-clone-reference.sh
+++ b/t/perf/p5601-clone-reference.sh
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 31de7e90f3..4d3f7ba295 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -25,16 +25,14 @@ try_local_x () {
echo "$x"
}
-# This test is an experiment to check whether any Git users are using
-# Shells that don't support the "local" keyword. "local" is not
+# Check whether the shell supports the "local" keyword. "local" is not
# POSIX-standard, but it is very widely supported by POSIX-compliant
-# shells, and if it doesn't cause problems for people, we would like
-# to be able to use it in Git code.
+# shells, and we rely on it within Git's test framework.
#
-# For now, this is the only test that requires "local". If your shell
-# fails this test, you can ignore the failure, but please report the
-# problem to the Git mailing list <git@vger.kernel.org>, as it might
-# convince us to continue avoiding the use of "local".
+# If your shell fails this test, the results of other tests may be
+# unreliable. You may wish to report the problem to the Git mailing
+# list <git@vger.kernel.org>, as it could cause us to reconsider
+# relying on "local".
test_expect_success 'verify that the running shell supports "local"' '
x="notlocal" &&
echo "local" >expected1 &&
@@ -276,23 +274,23 @@ test_expect_success 'pretend we have a mix of all possible results' "
test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
test_must_fail run_sub_test_lib_test \
- test-verbose "test verbose" --verbose <<-\EOF &&
+ t1234-verbose "test verbose" --verbose <<-\EOF &&
test_expect_success "passing test" true
test_expect_success "test with output" "echo foo"
test_expect_success "failing test" false
test_done
EOF
- mv test-verbose/out test-verbose/out+ &&
- grep -v "^Initialized empty" test-verbose/out+ >test-verbose/out &&
- check_sub_test_lib_test test-verbose <<-\EOF
- > expecting success: true
+ mv t1234-verbose/out t1234-verbose/out+ &&
+ grep -v "^Initialized empty" t1234-verbose/out+ >t1234-verbose/out &&
+ check_sub_test_lib_test t1234-verbose <<-\EOF
+ > expecting success of 1234.1 '\''passing test'\'': true
> ok 1 - passing test
> Z
- > expecting success: echo foo
+ > expecting success of 1234.2 '\''test with output'\'': echo foo
> foo
> ok 2 - test with output
> Z
- > expecting success: false
+ > expecting success of 1234.3 '\''failing test'\'': false
> not ok 3 - failing test
> # false
> Z
@@ -303,17 +301,17 @@ test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
test_expect_success 'test --verbose-only' '
test_must_fail run_sub_test_lib_test \
- test-verbose-only-2 "test verbose-only=2" \
+ t2345-verbose-only-2 "test verbose-only=2" \
--verbose-only=2 <<-\EOF &&
test_expect_success "passing test" true
test_expect_success "test with output" "echo foo"
test_expect_success "failing test" false
test_done
EOF
- check_sub_test_lib_test test-verbose-only-2 <<-\EOF
+ check_sub_test_lib_test t2345-verbose-only-2 <<-\EOF
> ok 1 - passing test
> Z
- > expecting success: echo foo
+ > expecting success of 2345.2 '\''test with output'\'': echo foo
> foo
> ok 2 - test with output
> Z
@@ -393,6 +391,44 @@ test_expect_success 'GIT_SKIP_TESTS sh pattern' "
)
"
+test_expect_success 'GIT_SKIP_TESTS entire suite' "
+ (
+ GIT_SKIP_TESTS='git' && export GIT_SKIP_TESTS &&
+ run_sub_test_lib_test git-skip-tests-entire-suite \
+ 'GIT_SKIP_TESTS entire suite' <<-\\EOF &&
+ for i in 1 2 3
+ do
+ test_expect_success \"passing test #\$i\" 'true'
+ done
+ test_done
+ EOF
+ check_sub_test_lib_test git-skip-tests-entire-suite <<-\\EOF
+ > 1..0 # SKIP skip all tests in git
+ EOF
+ )
+"
+
+test_expect_success 'GIT_SKIP_TESTS does not skip unmatched suite' "
+ (
+ GIT_SKIP_TESTS='notgit' && export GIT_SKIP_TESTS &&
+ run_sub_test_lib_test git-skip-tests-unmatched-suite \
+ 'GIT_SKIP_TESTS does not skip unmatched suite' <<-\\EOF &&
+ for i in 1 2 3
+ do
+ test_expect_success \"passing test #\$i\" 'true'
+ done
+ test_done
+ EOF
+ check_sub_test_lib_test git-skip-tests-unmatched-suite <<-\\EOF
+ > ok 1 - passing test #1
+ > ok 2 - passing test #2
+ > ok 3 - passing test #3
+ > # passed all 3 test(s)
+ > 1..3
+ EOF
+ )
+"
+
test_expect_success '--run basic' "
run_sub_test_lib_test run-basic \
'--run basic' --run='1 3 5' <<-\\EOF &&
@@ -726,7 +762,7 @@ donthaveit=yes
test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' '
donthaveit=no
'
-if test -z "$GIT_TEST_FAIL_PREREQS" -a $haveit$donthaveit != yesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $haveit$donthaveit != yesyes
then
say "bug in test framework: prerequisite tags do not work reliably"
exit 1
@@ -747,7 +783,7 @@ donthaveiteither=yes
test_expect_success DONTHAVEIT,HAVEIT 'unmet prerequisites causes test to be skipped' '
donthaveiteither=no
'
-if test -z "$GIT_TEST_FAIL_PREREQS" -a $haveit$donthaveit$donthaveiteither != yesyesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $haveit$donthaveit$donthaveiteither != yesyesyes
then
say "bug in test framework: multiple prerequisite tags do not work reliably"
exit 1
@@ -763,7 +799,7 @@ test_expect_success !LAZY_TRUE 'missing lazy prereqs skip tests' '
donthavetrue=no
'
-if test -z "$GIT_TEST_FAIL_PREREQS" -a "$havetrue$donthavetrue" != yesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a "$havetrue$donthavetrue" != yesyes
then
say 'bug in test framework: lazy prerequisites do not work'
exit 1
@@ -779,7 +815,7 @@ test_expect_success LAZY_FALSE 'missing negative lazy prereqs will skip' '
havefalse=no
'
-if test -z "$GIT_TEST_FAIL_PREREQS" -a "$nothavefalse$havefalse" != yesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a "$nothavefalse$havefalse" != yesyes
then
say 'bug in test framework: negative lazy prerequisites do not work'
exit 1
@@ -790,7 +826,7 @@ test_expect_success 'tests clean up after themselves' '
test_when_finished clean=yes
'
-if test -z "$GIT_TEST_FAIL_PREREQS" -a $clean != yes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $clean != yes
then
say "bug in test framework: basic cleanup command does not work reliably"
exit 1
diff --git a/t/t0011-hashmap.sh b/t/t0011-hashmap.sh
index 9c96b3e3b1..5343ffd3f9 100755
--- a/t/t0011-hashmap.sh
+++ b/t/t0011-hashmap.sh
@@ -170,31 +170,45 @@ NULL
'
test_expect_success 'iterate' '
-
-test_hashmap "put key1 value1
-put key2 value2
-put fooBarFrotz value3
-iterate" "NULL
-NULL
-NULL
-key2 value2
-key1 value1
-fooBarFrotz value3"
-
+ test-tool hashmap >actual.raw <<-\EOF &&
+ put key1 value1
+ put key2 value2
+ put fooBarFrotz value3
+ iterate
+ EOF
+
+ cat >expect <<-\EOF &&
+ NULL
+ NULL
+ NULL
+ fooBarFrotz value3
+ key1 value1
+ key2 value2
+ EOF
+
+ sort <actual.raw >actual &&
+ test_cmp expect actual
'
test_expect_success 'iterate (case insensitive)' '
-
-test_hashmap "put key1 value1
-put key2 value2
-put fooBarFrotz value3
-iterate" "NULL
-NULL
-NULL
-fooBarFrotz value3
-key2 value2
-key1 value1" ignorecase
-
+ test-tool hashmap ignorecase >actual.raw <<-\EOF &&
+ put key1 value1
+ put key2 value2
+ put fooBarFrotz value3
+ iterate
+ EOF
+
+ cat >expect <<-\EOF &&
+ NULL
+ NULL
+ NULL
+ fooBarFrotz value3
+ key1 value1
+ key2 value2
+ EOF
+
+ sort <actual.raw >actual &&
+ test_cmp expect actual
'
test_expect_success 'grow / shrink' '
diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh
index a070e645d7..2694c81afd 100755
--- a/t/t0014-alias.sh
+++ b/t/t0014-alias.sh
@@ -37,4 +37,11 @@ test_expect_success 'looping aliases - internal execution' '
# test_i18ngrep "^fatal: alias loop detected: expansion of" output
#'
+test_expect_success 'run-command formats empty args properly' '
+ GIT_TRACE=1 git frotz a "" b " " c 2>&1 |
+ sed -ne "/run_command:/s/.*trace: run_command: //p" >actual &&
+ echo "git-frotz a '\'''\'' b '\'' '\'' c" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t0016-oidmap.sh b/t/t0016-oidmap.sh
index bbe719e950..31f8276ba8 100755
--- a/t/t0016-oidmap.sh
+++ b/t/t0016-oidmap.sh
@@ -86,17 +86,25 @@ NULL"
'
test_expect_success 'iterate' '
-
-test_oidmap "put one 1
-put two 2
-put three 3
-iterate" "NULL
-NULL
-NULL
-$(git rev-parse two) 2
-$(git rev-parse one) 1
-$(git rev-parse three) 3"
-
+ test-tool oidmap >actual.raw <<-\EOF &&
+ put one 1
+ put two 2
+ put three 3
+ iterate
+ EOF
+
+ # sort "expect" too so we do not rely on the order of particular oids
+ sort >expect <<-EOF &&
+ NULL
+ NULL
+ NULL
+ $(git rev-parse one) 1
+ $(git rev-parse two) 2
+ $(git rev-parse three) 3
+ EOF
+
+ sort <actual.raw >actual &&
+ test_cmp expect actual
'
test_done
diff --git a/t/t0017-env-helper.sh b/t/t0017-env-helper.sh
new file mode 100755
index 0000000000..c1ecf6aeac
--- /dev/null
+++ b/t/t0017-env-helper.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+test_description='test env--helper'
+
+. ./test-lib.sh
+
+
+test_expect_success 'env--helper usage' '
+ test_must_fail git env--helper &&
+ test_must_fail git env--helper --type=bool &&
+ test_must_fail git env--helper --type=ulong &&
+ test_must_fail git env--helper --type=bool &&
+ test_must_fail git env--helper --type=bool --default &&
+ test_must_fail git env--helper --type=bool --default= &&
+ test_must_fail git env--helper --defaultxyz
+'
+
+test_expect_success 'env--helper bad default values' '
+ test_must_fail git env--helper --type=bool --default=1xyz MISSING &&
+ test_must_fail git env--helper --type=ulong --default=1xyz MISSING
+'
+
+test_expect_success 'env--helper --type=bool' '
+ # Test various --default bool values
+ echo true >expected &&
+ git env--helper --type=bool --default=1 MISSING >actual &&
+ test_cmp expected actual &&
+ git env--helper --type=bool --default=yes MISSING >actual &&
+ test_cmp expected actual &&
+ git env--helper --type=bool --default=true MISSING >actual &&
+ test_cmp expected actual &&
+ echo false >expected &&
+ test_must_fail git env--helper --type=bool --default=0 MISSING >actual &&
+ test_cmp expected actual &&
+ test_must_fail git env--helper --type=bool --default=no MISSING >actual &&
+ test_cmp expected actual &&
+ test_must_fail git env--helper --type=bool --default=false MISSING >actual &&
+ test_cmp expected actual &&
+
+ # No output with --exit-code
+ git env--helper --type=bool --default=true --exit-code MISSING >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_must_be_empty actual.err &&
+ test_must_fail git env--helper --type=bool --default=false --exit-code MISSING >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_must_be_empty actual.err &&
+
+ # Existing variable
+ EXISTS=true git env--helper --type=bool --default=false --exit-code EXISTS >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_must_be_empty actual.err &&
+ test_must_fail \
+ env EXISTS=false \
+ git env--helper --type=bool --default=true --exit-code EXISTS >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_must_be_empty actual.err
+'
+
+test_expect_success 'env--helper --type=ulong' '
+ echo 1234567890 >expected &&
+ git env--helper --type=ulong --default=1234567890 MISSING >actual.out 2>actual.err &&
+ test_cmp expected actual.out &&
+ test_must_be_empty actual.err &&
+
+ echo 0 >expected &&
+ test_must_fail git env--helper --type=ulong --default=0 MISSING >actual &&
+ test_cmp expected actual &&
+
+ git env--helper --type=ulong --default=1234567890 --exit-code MISSING >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_must_be_empty actual.err &&
+
+ EXISTS=1234567890 git env--helper --type=ulong --default=0 EXISTS --exit-code >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_must_be_empty actual.err &&
+
+ echo 1234567890 >expected &&
+ EXISTS=1234567890 git env--helper --type=ulong --default=0 EXISTS >actual.out 2>actual.err &&
+ test_cmp expected actual.out &&
+ test_must_be_empty actual.err
+'
+
+test_expect_success 'env--helper reads config thanks to trace2' '
+ mkdir home &&
+ git config -f home/.gitconfig include.path cycle &&
+ git config -f home/cycle include.path .gitconfig &&
+
+ test_must_fail \
+ env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=false \
+ git config -l 2>err &&
+ grep "exceeded maximum include depth" err &&
+
+ test_must_fail \
+ env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=true \
+ git -C cycle env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON 2>err &&
+ grep "# GETTEXT POISON #" err
+'
+
+test_done
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index e10f5f787f..c954c709ad 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -390,6 +390,9 @@ test_expect_success PERL 'required process filter should filter data' '
EOF
test_cmp_exclude_clean expected.log debug.log &&
+ # Make sure that the file appears dirty, so checkout below has to
+ # run the configured filter.
+ touch test.r &&
filter_git checkout --quiet --no-progress empty-branch &&
cat >expected.log <<-EOF &&
START
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index 3587e454f1..959b6da449 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -15,8 +15,10 @@ compare_ws_file () {
pfx=$1
exp=$2.expect
act=$pfx.actual.$3
- tr '\015\000abcdef0123456789' QN00000000000000000 <"$2" >"$exp" &&
- tr '\015\000abcdef0123456789' QN00000000000000000 <"$3" >"$act" &&
+ tr '\015\000abcdef0123456789' QN00000000000000000 <"$2" |
+ sed -e "s/0000*/$ZERO_OID/" >"$exp" &&
+ tr '\015\000abcdef0123456789' QN00000000000000000 <"$3" |
+ sed -e "s/0000*/$ZERO_OID/" >"$act" &&
test_cmp "$exp" "$act" &&
rm "$exp" "$act"
}
diff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh
index 1090e650ed..7aa0945d8d 100755
--- a/t/t0028-working-tree-encoding.sh
+++ b/t/t0028-working-tree-encoding.sh
@@ -40,7 +40,7 @@ test_expect_success 'setup test files' '
printf "$text" | write_utf16 >test.utf16.raw &&
printf "$text" | write_utf32 >test.utf32.raw &&
printf "\377\376" >test.utf16lebom.raw &&
- printf "$text" | iconv -f UTF-8 -t UTF-32LE >>test.utf16lebom.raw &&
+ printf "$text" | iconv -f UTF-8 -t UTF-16LE >>test.utf16lebom.raw &&
# Line ending tests
printf "one\ntwo\nthree\n" >lf.utf8.raw &&
@@ -280,4 +280,43 @@ test_expect_success ICONV_SHIFT_JIS 'check roundtrip encoding' '
git reset
'
+# $1: checkout encoding
+# $2: test string
+# $3: binary test string in checkout encoding
+test_commit_utf8_checkout_other () {
+ encoding="$1"
+ orig_string="$2"
+ expect_bytes="$3"
+
+ test_expect_success "Commit UTF-8, checkout $encoding" '
+ test_when_finished "git checkout HEAD -- .gitattributes" &&
+
+ test_ext="commit_utf8_checkout_$encoding" &&
+ test_file="test.$test_ext" &&
+
+ # Commit as UTF-8
+ echo "*.$test_ext text working-tree-encoding=UTF-8" >.gitattributes &&
+ printf "$orig_string" >$test_file &&
+ git add $test_file &&
+ git commit -m "Test data" &&
+
+ # Checkout in tested encoding
+ rm $test_file &&
+ echo "*.$test_ext text working-tree-encoding=$encoding" >.gitattributes &&
+ git checkout HEAD -- $test_file &&
+
+ # Test
+ printf $expect_bytes >$test_file.raw &&
+ test_cmp_bin $test_file.raw $test_file
+ '
+}
+
+test_commit_utf8_checkout_other "UTF-8" "Test Тест" "\124\145\163\164\040\320\242\320\265\321\201\321\202"
+test_commit_utf8_checkout_other "UTF-16LE" "Test Тест" "\124\000\145\000\163\000\164\000\040\000\042\004\065\004\101\004\102\004"
+test_commit_utf8_checkout_other "UTF-16BE" "Test Тест" "\000\124\000\145\000\163\000\164\000\040\004\042\004\065\004\101\004\102"
+test_commit_utf8_checkout_other "UTF-16LE-BOM" "Test Тест" "\377\376\124\000\145\000\163\000\164\000\040\000\042\004\065\004\101\004\102\004"
+test_commit_utf8_checkout_other "UTF-16BE-BOM" "Test Тест" "\376\377\000\124\000\145\000\163\000\164\000\040\004\042\004\065\004\101\004\102"
+test_commit_utf8_checkout_other "UTF-32LE" "Test Тест" "\124\000\000\000\145\000\000\000\163\000\000\000\164\000\000\000\040\000\000\000\042\004\000\000\065\004\000\000\101\004\000\000\102\004\000\000"
+test_commit_utf8_checkout_other "UTF-32BE" "Test Тест" "\000\000\000\124\000\000\000\145\000\000\000\163\000\000\000\164\000\000\000\040\000\000\004\042\000\000\004\065\000\000\004\101\000\000\004\102"
+
test_done
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index cebc77fab0..705a136ed9 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -399,4 +399,11 @@ test_expect_success 'GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS works' '
test-tool parse-options --ye
'
+test_expect_success '--end-of-options treats remainder as args' '
+ test-tool parse-options \
+ --expect="verbose: -1" \
+ --expect="arg 00: --verbose" \
+ --end-of-options --verbose
+'
+
test_done
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 192c94eccd..608673fb77 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -131,4 +131,24 @@ $test_unicode 'merge (silent unicode normalization)' '
git merge topic
'
+test_expect_success CASE_INSENSITIVE_FS 'checkout with no pathspec and a case insensitive fs' '
+ git init repo &&
+ (
+ cd repo &&
+
+ >Gitweb &&
+ git add Gitweb &&
+ git commit -m "add Gitweb" &&
+
+ git checkout --orphan todo &&
+ git reset --hard &&
+ mkdir -p gitweb/subdir &&
+ >gitweb/subdir/file &&
+ git add gitweb &&
+ git commit -m "add gitweb/subdir/file" &&
+
+ git checkout master
+ )
+'
+
test_done
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index ebc49561ac..17c9c0f3bb 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -210,4 +210,23 @@ test_expect_success MINGW 'verify curlies are quoted properly' '
test_cmp expect actual
'
+test_expect_success MINGW 'can spawn .bat with argv[0] containing spaces' '
+ bat="$TRASH_DIRECTORY/bat with spaces in name.bat" &&
+
+ # Every .bat invocation will log its arguments to file "out"
+ rm -f out &&
+ echo "echo %* >>out" >"$bat" &&
+
+ # Ask git to invoke .bat; clone will fail due to fake SSH helper
+ test_must_fail env GIT_SSH="$bat" git clone myhost:src ssh-clone &&
+
+ # Spawning .bat can fail if there are two quoted cmd.exe arguments.
+ # .bat itself is first (due to spaces in name), so just one more is
+ # needed to verify. GIT_SSH will invoke .bat multiple times:
+ # 1) -G myhost
+ # 2) myhost "git-upload-pack src"
+ # First invocation will always succeed. Test the second one.
+ grep "git-upload-pack" out
+'
+
test_done
diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh
new file mode 100755
index 0000000000..92910e4e6c
--- /dev/null
+++ b/t/t0066-dir-iterator.sh
@@ -0,0 +1,148 @@
+#!/bin/sh
+
+test_description='Test the dir-iterator functionality'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir -p dir &&
+ mkdir -p dir/a/b/c/ &&
+ >dir/b &&
+ >dir/c &&
+ mkdir -p dir/d/e/d/ &&
+ >dir/a/b/c/d &&
+ >dir/a/e &&
+ >dir/d/e/d/a &&
+
+ mkdir -p dir2/a/b/c/ &&
+ >dir2/a/b/c/d
+'
+
+test_expect_success 'dir-iterator should iterate through all files' '
+ cat >expected-iteration-sorted-output <<-EOF &&
+ [d] (a) [a] ./dir/a
+ [d] (a/b) [b] ./dir/a/b
+ [d] (a/b/c) [c] ./dir/a/b/c
+ [d] (d) [d] ./dir/d
+ [d] (d/e) [e] ./dir/d/e
+ [d] (d/e/d) [d] ./dir/d/e/d
+ [f] (a/b/c/d) [d] ./dir/a/b/c/d
+ [f] (a/e) [e] ./dir/a/e
+ [f] (b) [b] ./dir/b
+ [f] (c) [c] ./dir/c
+ [f] (d/e/d/a) [a] ./dir/d/e/d/a
+ EOF
+
+ test-tool dir-iterator ./dir >out &&
+ sort out >./actual-iteration-sorted-output &&
+
+ test_cmp expected-iteration-sorted-output actual-iteration-sorted-output
+'
+
+test_expect_success 'dir-iterator should list files in the correct order' '
+ cat >expected-pre-order-output <<-EOF &&
+ [d] (a) [a] ./dir2/a
+ [d] (a/b) [b] ./dir2/a/b
+ [d] (a/b/c) [c] ./dir2/a/b/c
+ [f] (a/b/c/d) [d] ./dir2/a/b/c/d
+ EOF
+
+ test-tool dir-iterator ./dir2 >actual-pre-order-output &&
+
+ test_cmp expected-pre-order-output actual-pre-order-output
+'
+
+test_expect_success 'begin should fail upon inexistent paths' '
+ test_must_fail test-tool dir-iterator ./inexistent-path \
+ >actual-inexistent-path-output &&
+ echo "dir_iterator_begin failure: ENOENT" >expected-inexistent-path-output &&
+ test_cmp expected-inexistent-path-output actual-inexistent-path-output
+'
+
+test_expect_success 'begin should fail upon non directory paths' '
+ test_must_fail test-tool dir-iterator ./dir/b >actual-non-dir-output &&
+ echo "dir_iterator_begin failure: ENOTDIR" >expected-non-dir-output &&
+ test_cmp expected-non-dir-output actual-non-dir-output
+'
+
+test_expect_success POSIXPERM,SANITY 'advance should not fail on errors by default' '
+ cat >expected-no-permissions-output <<-EOF &&
+ [d] (a) [a] ./dir3/a
+ EOF
+
+ mkdir -p dir3/a &&
+ >dir3/a/b &&
+ chmod 0 dir3/a &&
+
+ test-tool dir-iterator ./dir3 >actual-no-permissions-output &&
+ test_cmp expected-no-permissions-output actual-no-permissions-output &&
+ chmod 755 dir3/a &&
+ rm -rf dir3
+'
+
+test_expect_success POSIXPERM,SANITY 'advance should fail on errors, w/ pedantic flag' '
+ cat >expected-no-permissions-pedantic-output <<-EOF &&
+ [d] (a) [a] ./dir3/a
+ dir_iterator_advance failure
+ EOF
+
+ mkdir -p dir3/a &&
+ >dir3/a/b &&
+ chmod 0 dir3/a &&
+
+ test_must_fail test-tool dir-iterator --pedantic ./dir3 \
+ >actual-no-permissions-pedantic-output &&
+ test_cmp expected-no-permissions-pedantic-output \
+ actual-no-permissions-pedantic-output &&
+ chmod 755 dir3/a &&
+ rm -rf dir3
+'
+
+test_expect_success SYMLINKS 'setup dirs with symlinks' '
+ mkdir -p dir4/a &&
+ mkdir -p dir4/b/c &&
+ >dir4/a/d &&
+ ln -s d dir4/a/e &&
+ ln -s ../b dir4/a/f &&
+
+ mkdir -p dir5/a/b &&
+ mkdir -p dir5/a/c &&
+ ln -s ../c dir5/a/b/d &&
+ ln -s ../ dir5/a/b/e &&
+ ln -s ../../ dir5/a/b/f
+'
+
+test_expect_success SYMLINKS 'dir-iterator should not follow symlinks by default' '
+ cat >expected-no-follow-sorted-output <<-EOF &&
+ [d] (a) [a] ./dir4/a
+ [d] (b) [b] ./dir4/b
+ [d] (b/c) [c] ./dir4/b/c
+ [f] (a/d) [d] ./dir4/a/d
+ [s] (a/e) [e] ./dir4/a/e
+ [s] (a/f) [f] ./dir4/a/f
+ EOF
+
+ test-tool dir-iterator ./dir4 >out &&
+ sort out >actual-no-follow-sorted-output &&
+
+ test_cmp expected-no-follow-sorted-output actual-no-follow-sorted-output
+'
+
+test_expect_success SYMLINKS 'dir-iterator should follow symlinks w/ follow flag' '
+ cat >expected-follow-sorted-output <<-EOF &&
+ [d] (a) [a] ./dir4/a
+ [d] (a/f) [f] ./dir4/a/f
+ [d] (a/f/c) [c] ./dir4/a/f/c
+ [d] (b) [b] ./dir4/b
+ [d] (b/c) [c] ./dir4/b/c
+ [f] (a/d) [d] ./dir4/a/d
+ [f] (a/e) [e] ./dir4/a/e
+ EOF
+
+ test-tool dir-iterator --follow-symlinks ./dir4 >out &&
+ sort out >actual-follow-sorted-output &&
+
+ test_cmp expected-follow-sorted-output actual-follow-sorted-output
+'
+
+test_done
diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh
index 504334e552..ce9a4a5f32 100755
--- a/t/t0090-cache-tree.sh
+++ b/t/t0090-cache-tree.sh
@@ -162,8 +162,8 @@ test_expect_success PERL 'commit --interactive gives cache-tree on partial commi
'
test_expect_success PERL 'commit -p with shrinking cache-tree' '
- mkdir -p deep/subdir &&
- echo content >deep/subdir/file &&
+ mkdir -p deep/very-long-subdir &&
+ echo content >deep/very-long-subdir/file &&
git add deep &&
git commit -m add &&
git rm -r deep &&
diff --git a/t/t0205-gettext-poison.sh b/t/t0205-gettext-poison.sh
index a06269f38a..f9fa16ad83 100755
--- a/t/t0205-gettext-poison.sh
+++ b/t/t0205-gettext-poison.sh
@@ -5,7 +5,7 @@
test_description='Gettext Shell poison'
-GIT_TEST_GETTEXT_POISON=YesPlease
+GIT_TEST_GETTEXT_POISON=true
export GIT_TEST_GETTEXT_POISON
. ./lib-gettext.sh
@@ -31,4 +31,9 @@ test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semant
test_cmp expect actual
'
+test_expect_success "gettext: invalid GIT_TEST_GETTEXT_POISON value doesn't infinitely loop" "
+ test_must_fail env GIT_TEST_GETTEXT_POISON=xyz git version 2>error &&
+ grep \"fatal: bad numeric config value 'xyz' for 'GIT_TEST_GETTEXT_POISON': invalid unit\" error
+"
+
test_done
diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh
index 2c3ad6e8c1..6ee8ee3b67 100755
--- a/t/t0211-trace2-perf.sh
+++ b/t/t0211-trace2-perf.sh
@@ -130,11 +130,11 @@ test_expect_success 'perf stream, child processes' '
d0|main|version|||||$V
d0|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 004child test-tool trace2 001return 0
d0|main|cmd_name|||||trace2 (trace2)
- d0|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 004child test-tool trace2 001return 0
+ d0|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 004child test-tool trace2 001return 0]
d1|main|version|||||$V
d1|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 001return 0
d1|main|cmd_name|||||trace2 (trace2/trace2)
- d1|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 001return 0
+ d1|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 001return 0]
d2|main|version|||||$V
d2|main|start||_T_ABS_|||_EXE_ trace2 001return 0
d2|main|cmd_name|||||trace2 (trace2/trace2/trace2)
diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh
index ff5b9cc729..7065a1b937 100755
--- a/t/t0212-trace2-event.sh
+++ b/t/t0212-trace2-event.sh
@@ -265,4 +265,23 @@ test_expect_success JSON_PP 'using global config, event stream, error event' '
test_cmp expect actual
'
+test_expect_success 'discard traces when there are too many files' '
+ mkdir trace_target_dir &&
+ test_when_finished "rm -r trace_target_dir" &&
+ (
+ GIT_TRACE2_MAX_FILES=5 &&
+ export GIT_TRACE2_MAX_FILES &&
+ cd trace_target_dir &&
+ test_seq $GIT_TRACE2_MAX_FILES >../expected_filenames.txt &&
+ xargs touch <../expected_filenames.txt &&
+ cd .. &&
+ GIT_TRACE2_EVENT="$(pwd)/trace_target_dir" test-tool trace2 001return 0
+ ) &&
+ echo git-trace2-discard >>expected_filenames.txt &&
+ ls trace_target_dir >ls_output.txt &&
+ test_cmp expected_filenames.txt ls_output.txt &&
+ head -n1 trace_target_dir/git-trace2-discard | grep \"event\":\"version\" &&
+ head -n2 trace_target_dir/git-trace2-discard | tail -n1 | grep \"event\":\"too_many_files\"
+'
+
test_done
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh
index 181ffa44e9..a3988bd4b8 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -26,7 +26,7 @@ promise_and_delete () {
test_expect_success 'extensions.partialclone without filter' '
test_create_repo server &&
git clone --filter="blob:none" "file://$(pwd)/server" client &&
- git -C client config --unset core.partialclonefilter &&
+ git -C client config --unset remote.origin.partialclonefilter &&
git -C client fetch origin
'
@@ -166,8 +166,9 @@ test_expect_success 'fetching of missing objects' '
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
- IDX=$(cat promisorlist | sed "s/promisor$/idx/") &&
- git verify-pack --verbose "$IDX" | grep "$HASH"
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH" out
'
test_expect_success 'fetching of missing objects works with ref-in-want enabled' '
@@ -182,8 +183,55 @@ test_expect_success 'fetching of missing objects works with ref-in-want enabled'
grep "git< fetch=.*ref-in-want" trace
'
+test_expect_success 'fetching of missing objects from another promisor remote' '
+ git clone "file://$(pwd)/server" server2 &&
+ test_commit -C server2 bar &&
+ git -C server2 repack -a -d --write-bitmap-index &&
+ HASH2=$(git -C server2 rev-parse bar) &&
+
+ git -C repo remote add server2 "file://$(pwd)/server2" &&
+ git -C repo config remote.server2.promisor true &&
+ git -C repo cat-file -p "$HASH2" &&
+
+ git -C repo fetch server2 &&
+ rm -rf repo/.git/objects/* &&
+ git -C repo cat-file -p "$HASH2" &&
+
+ # Ensure that the .promisor file is written, and check that its
+ # associated packfile contains the object
+ ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 1 promisorlist &&
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH2" out
+'
+
+test_expect_success 'fetching of missing objects configures a promisor remote' '
+ git clone "file://$(pwd)/server" server3 &&
+ test_commit -C server3 baz &&
+ git -C server3 repack -a -d --write-bitmap-index &&
+ HASH3=$(git -C server3 rev-parse baz) &&
+ git -C server3 config uploadpack.allowfilter 1 &&
+
+ rm repo/.git/objects/pack/pack-*.promisor &&
+
+ git -C repo remote add server3 "file://$(pwd)/server3" &&
+ git -C repo fetch --filter="blob:none" server3 $HASH3 &&
+
+ test_cmp_config -C repo true remote.server3.promisor &&
+
+ # Ensure that the .promisor file is written, and check that its
+ # associated packfile contains the object
+ ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 1 promisorlist &&
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH3" out
+'
+
test_expect_success 'fetching of missing blobs works' '
- rm -rf server repo &&
+ rm -rf server server2 repo &&
+ rm -rf server server3 repo &&
test_create_repo server &&
test_commit -C server foo &&
git -C server repack -a -d --write-bitmap-index &&
@@ -381,6 +429,19 @@ test_expect_success 'rev-list dies for missing objects on cmd line' '
done
'
+test_expect_success 'single promisor remote can be re-initialized gracefully' '
+ # ensure one promisor is in the promisors list
+ rm -rf repo &&
+ test_create_repo repo &&
+ test_create_repo other &&
+ git -C repo remote add foo "file://$(pwd)/other" &&
+ git -C repo config remote.foo.promisor true &&
+ git -C repo config extensions.partialclone foo &&
+
+ # reinitialize the promisors list
+ git -C repo fetch --filter=blob:none foo
+'
+
test_expect_success 'gc repacks promisor objects separately from non-promisor objects' '
rm -rf repo &&
test_create_repo repo &&
@@ -492,6 +553,20 @@ test_expect_success 'gc stops traversal when a missing but promised object is re
! grep "$TREE_HASH" out
'
+test_expect_success 'do not fetch when checking existence of tree we construct ourselves' '
+ rm -rf repo &&
+ test_create_repo repo &&
+ test_commit -C repo base &&
+ test_commit -C repo side1 &&
+ git -C repo checkout base &&
+ test_commit -C repo side2 &&
+
+ git -C repo config core.repositoryformatversion 1 &&
+ git -C repo config extensions.partialclone "arbitrary string" &&
+
+ git -C repo cherry-pick side1
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@@ -514,8 +589,12 @@ test_expect_success 'fetching of missing objects from an HTTP server' '
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
- IDX=$(cat promisorlist | sed "s/promisor$/idx/") &&
- git verify-pack --verbose "$IDX" | grep "$HASH"
+ IDX=$(sed "s/promisor$/idx/" promisorlist) &&
+ git verify-pack --verbose "$IDX" >out &&
+ grep "$HASH" out
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh
new file mode 100755
index 0000000000..24ccbd8d3b
--- /dev/null
+++ b/t/t0500-progress-display.sh
@@ -0,0 +1,286 @@
+#!/bin/sh
+
+test_description='progress display'
+
+. ./test-lib.sh
+
+show_cr () {
+ tr '\015' Q | sed -e "s/Q/<CR>\\$LF/g"
+}
+
+test_expect_success 'simple progress display' '
+ cat >expect <<-\EOF &&
+ Working hard: 1<CR>
+ Working hard: 2<CR>
+ Working hard: 5<CR>
+ Working hard: 5, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ update
+ progress 1
+ update
+ progress 2
+ progress 3
+ progress 4
+ update
+ progress 5
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display with total' '
+ cat >expect <<-\EOF &&
+ Working hard: 33% (1/3)<CR>
+ Working hard: 66% (2/3)<CR>
+ Working hard: 100% (3/3)<CR>
+ Working hard: 100% (3/3), done.
+ EOF
+
+ cat >in <<-\EOF &&
+ progress 1
+ progress 2
+ progress 3
+ EOF
+ test-tool progress --total=3 "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #1' '
+ sed -e "s/Z$//" >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6: 0% (100/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: 1% (1000/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: Z
+ 10% (10000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ progress 100
+ progress 1000
+ progress 10000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6" \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #2' '
+ # Note: we dont need that many spaces after the title to cover up
+ # the last line before breaking the progress line.
+ sed -e "s/Z$//" >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6: 0% (1/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: 0% (2/100000)<CR>
+Working hard.......2.........3.........4.........5.........6: Z
+ 10% (10000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ update
+ progress 1
+ update
+ progress 2
+ progress 10000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6" \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #3 - even the first is too long' '
+ # Note: we dont actually need any spaces at the end of the title
+ # line, because there is no previous progress line to cover up.
+ sed -e "s/Z$//" >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6: Z
+ 25% (25000/100000)<CR>
+ 50% (50000/100000)<CR>
+ 75% (75000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ progress 25000
+ progress 50000
+ progress 75000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6" \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display breaks long lines #4 - title line matches terminal width' '
+ cat >expect <<\EOF &&
+Working hard.......2.........3.........4.........5.........6.........7.........:
+ 25% (25000/100000)<CR>
+ 50% (50000/100000)<CR>
+ 75% (75000/100000)<CR>
+ 100% (100000/100000)<CR>
+ 100% (100000/100000), done.
+EOF
+
+ cat >in <<-\EOF &&
+ progress 25000
+ progress 50000
+ progress 75000
+ progress 100000
+ EOF
+ test-tool progress --total=100000 \
+ "Working hard.......2.........3.........4.........5.........6.........7........." \
+ <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+# Progress counter goes backwards, this should not happen in practice.
+test_expect_success 'progress shortens - crazy caller' '
+ cat >expect <<-\EOF &&
+ Working hard: 10% (100/1000)<CR>
+ Working hard: 20% (200/1000)<CR>
+ Working hard: 0% (1/1000) <CR>
+ Working hard: 100% (1000/1000)<CR>
+ Working hard: 100% (1000/1000), done.
+ EOF
+
+ cat >in <<-\EOF &&
+ progress 100
+ progress 200
+ progress 1
+ progress 1000
+ EOF
+ test-tool progress --total=1000 "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display with throughput' '
+ cat >expect <<-\EOF &&
+ Working hard: 10<CR>
+ Working hard: 20, 200.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 30, 300.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 40, 400.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 40, 400.00 KiB | 100.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 102400 1000
+ update
+ progress 10
+ throughput 204800 2000
+ update
+ progress 20
+ throughput 307200 3000
+ update
+ progress 30
+ throughput 409600 4000
+ update
+ progress 40
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'progress display with throughput and total' '
+ cat >expect <<-\EOF &&
+ Working hard: 25% (10/40)<CR>
+ Working hard: 50% (20/40), 200.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 75% (30/40), 300.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s<CR>
+ Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 102400 1000
+ progress 10
+ throughput 204800 2000
+ progress 20
+ throughput 307200 3000
+ progress 30
+ throughput 409600 4000
+ progress 40
+ EOF
+ test-tool progress --total=40 "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'cover up after throughput shortens' '
+ cat >expect <<-\EOF &&
+ Working hard: 1<CR>
+ Working hard: 2, 800.00 KiB | 400.00 KiB/s<CR>
+ Working hard: 3, 1.17 MiB | 400.00 KiB/s <CR>
+ Working hard: 4, 1.56 MiB | 400.00 KiB/s<CR>
+ Working hard: 4, 1.56 MiB | 400.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 409600 1000
+ update
+ progress 1
+ throughput 819200 2000
+ update
+ progress 2
+ throughput 1228800 3000
+ update
+ progress 3
+ throughput 1638400 4000
+ update
+ progress 4
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_expect_success 'cover up after throughput shortens a lot' '
+ cat >expect <<-\EOF &&
+ Working hard: 1<CR>
+ Working hard: 2, 1000.00 KiB | 1000.00 KiB/s<CR>
+ Working hard: 3, 3.00 MiB | 1.50 MiB/s <CR>
+ Working hard: 3, 3.00 MiB | 1024.00 KiB/s, done.
+ EOF
+
+ cat >in <<-\EOF &&
+ throughput 1 1000
+ update
+ progress 1
+ throughput 1024000 2000
+ update
+ progress 2
+ throughput 3145728 3000
+ update
+ progress 3
+ EOF
+ test-tool progress "Working hard" <in 2>stderr &&
+
+ show_cr <stderr >out &&
+ test_i18ncmp expect out
+'
+
+test_done
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index 7099d33508..64b340f227 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -9,22 +9,19 @@ echo_without_newline() {
}
test_blob_does_not_exist() {
- test_expect_success SHA1 'blob does not exist in database' "
+ test_expect_success 'blob does not exist in database' "
test_must_fail git cat-file blob $1
"
}
test_blob_exists() {
- test_expect_success SHA1 'blob exists in database' "
+ test_expect_success 'blob exists in database' "
git cat-file blob $1
"
}
hello_content="Hello World"
-hello_sha1=5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689
-
example_content="This is an example"
-example_sha1=ddd3f836d3e3fbb7ae289aa9ae83536f76956399
setup_repo() {
echo_without_newline "$hello_content" > hello
@@ -44,7 +41,16 @@ pop_repo() {
rm -rf $test_repo
}
-setup_repo
+test_expect_success 'setup' '
+ setup_repo &&
+ test_oid_cache <<-EOF
+ hello sha1:5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689
+ hello sha256:1e3b6c04d2eeb2b3e45c8a330445404c0b7cc7b257e2b097167d26f5230090c4
+
+ example sha1:ddd3f836d3e3fbb7ae289aa9ae83536f76956399
+ example sha256:b44fe1fe65589848253737db859bd490453510719d7424daab03daf0767b85ae
+ EOF
+'
# Argument checking
@@ -73,23 +79,23 @@ test_expect_success "Can't use --path with --no-filters" '
push_repo
-test_expect_success SHA1 'hash a file' '
- test $hello_sha1 = $(git hash-object hello)
+test_expect_success 'hash a file' '
+ test "$(test_oid hello)" = $(git hash-object hello)
'
-test_blob_does_not_exist $hello_sha1
+test_blob_does_not_exist "$(test_oid hello)"
-test_expect_success SHA1 'hash from stdin' '
- test $example_sha1 = $(git hash-object --stdin < example)
+test_expect_success 'hash from stdin' '
+ test "$(test_oid example)" = $(git hash-object --stdin < example)
'
-test_blob_does_not_exist $example_sha1
+test_blob_does_not_exist "$(test_oid example)"
-test_expect_success SHA1 'hash a file and write to database' '
- test $hello_sha1 = $(git hash-object -w hello)
+test_expect_success 'hash a file and write to database' '
+ test "$(test_oid hello)" = $(git hash-object -w hello)
'
-test_blob_exists $hello_sha1
+test_blob_exists "$(test_oid hello)"
test_expect_success 'git hash-object --stdin file1 <file0 first operates on file0, then file1' '
echo foo > file1 &&
@@ -161,11 +167,11 @@ pop_repo
for args in "-w --stdin" "--stdin -w"; do
push_repo
- test_expect_success SHA1 "hash from stdin and write to database ($args)" '
- test $example_sha1 = $(git hash-object $args < example)
+ test_expect_success "hash from stdin and write to database ($args)" '
+ test "$(test_oid example)" = $(git hash-object $args < example)
'
- test_blob_exists $example_sha1
+ test_blob_exists "$(test_oid example)"
pop_repo
done
@@ -173,22 +179,22 @@ done
filenames="hello
example"
-sha1s="$hello_sha1
-$example_sha1"
+oids="$(test_oid hello)
+$(test_oid example)"
-test_expect_success SHA1 "hash two files with names on stdin" '
- test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)"
+test_expect_success "hash two files with names on stdin" '
+ test "$oids" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)"
'
for args in "-w --stdin-paths" "--stdin-paths -w"; do
push_repo
- test_expect_success SHA1 "hash two files with names on stdin and write to database ($args)" '
- test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object $args)"
+ test_expect_success "hash two files with names on stdin and write to database ($args)" '
+ test "$oids" = "$(echo_without_newline "$filenames" | git hash-object $args)"
'
- test_blob_exists $hello_sha1
- test_blob_exists $example_sha1
+ test_blob_exists "$(test_oid hello)"
+ test_blob_exists "$(test_oid example)"
pop_repo
done
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 428177c390..983a0a1583 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -1294,26 +1294,25 @@ test_expect_success 'git -c is not confused by empty environment' '
GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list
'
-sq="'"
test_expect_success 'detect bogus GIT_CONFIG_PARAMETERS' '
cat >expect <<-\EOF &&
env.one one
env.two two
EOF
- GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq} ${sq}env.two=two${sq}" \
+ GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ} ${SQ}env.two=two${SQ}" \
git config --get-regexp "env.*" >actual &&
test_cmp expect actual &&
cat >expect <<-EOF &&
- env.one one${sq}
+ env.one one${SQ}
env.two two
EOF
- GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq}\\$sq$sq$sq ${sq}env.two=two${sq}" \
+ GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ$SQ$SQ ${SQ}env.two=two${SQ}" \
git config --get-regexp "env.*" >actual &&
test_cmp expect actual &&
test_must_fail env \
- GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq}\\$sq ${sq}env.two=two${sq}" \
+ GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ ${SQ}env.two=two${SQ}" \
git config --get-regexp "env.*"
'
diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index 9571e366f8..d20b4d150d 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -349,20 +349,13 @@ test_expect_success 'conditional include, onbranch, implicit /** for /' '
'
test_expect_success 'include cycles are detected' '
- cat >.gitconfig <<-\EOF &&
- [test]value = gitconfig
- [include]path = cycle
- EOF
- cat >cycle <<-\EOF &&
- [test]value = cycle
- [include]path = .gitconfig
- EOF
- cat >expect <<-\EOF &&
- gitconfig
- cycle
- EOF
- test_must_fail git config --get-all test.value 2>stderr &&
- test_i18ngrep "exceeded maximum include depth" stderr
+ git init --bare cycle &&
+ git -C cycle config include.path cycle &&
+ git config -f cycle/cycle include.path config &&
+ test_must_fail \
+ env GIT_TEST_GETTEXT_POISON=false \
+ git -C cycle config --get-all test.value 2>stderr &&
+ grep "exceeded maximum include depth" stderr
'
test_done
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index d0a2727b85..7b4e1a63eb 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -166,14 +166,14 @@ test_expect_success 'find value with highest priority from a configset' '
'
test_expect_success 'find value_list for a key from a configset' '
- cat >except <<-\EOF &&
+ cat >expect <<-\EOF &&
+ lama
+ ball
sam
bat
hask
- lama
- ball
EOF
- test-tool config configset_get_value case.baz config2 .git/config >actual &&
+ test-tool config configset_get_value_multi case.baz config2 .git/config >actual &&
test_cmp expect actual
'
diff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh
index 413642aa56..3a0de0ddaa 100755
--- a/t/t1309-early-config.sh
+++ b/t/t1309-early-config.sh
@@ -89,4 +89,14 @@ test_expect_failure 'ignore .git/ with invalid config' '
test_with_config "["
'
+test_expect_success 'early config and onbranch' '
+ echo "[broken" >broken &&
+ test_with_config "[includeif \"onbranch:master\"]path=../broken"
+'
+
+test_expect_success 'onbranch config outside of git repo' '
+ test_config_global includeIf.onbranch:master.path non-existent &&
+ nongit git help
+'
+
test_done
diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh
index 970c5c36b9..2d142e5535 100755
--- a/t/t1404-update-ref-errors.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -32,8 +32,6 @@ test_update_rejected () {
test_cmp unchanged actual
}
-Q="'"
-
# Test adding and deleting D/F-conflicting references in a single
# transaction.
df_test() {
@@ -93,7 +91,7 @@ df_test() {
delname="$delref"
fi &&
cat >expected-err <<-EOF &&
- fatal: cannot lock ref $Q$addname$Q: $Q$delref$Q exists; cannot create $Q$addref$Q
+ fatal: cannot lock ref $SQ$addname$SQ: $SQ$delref$SQ exists; cannot create $SQ$addref$SQ
EOF
$pack &&
if $add_del
@@ -123,7 +121,7 @@ test_expect_success 'existing loose ref is a simple prefix of new' '
prefix=refs/1l &&
test_update_rejected "a c e" false "b c/x d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
'
@@ -131,7 +129,7 @@ test_expect_success 'existing packed ref is a simple prefix of new' '
prefix=refs/1p &&
test_update_rejected "a c e" true "b c/x d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
'
@@ -139,7 +137,7 @@ test_expect_success 'existing loose ref is a deeper prefix of new' '
prefix=refs/2l &&
test_update_rejected "a c e" false "b c/x/y d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
'
@@ -147,7 +145,7 @@ test_expect_success 'existing packed ref is a deeper prefix of new' '
prefix=refs/2p &&
test_update_rejected "a c e" true "b c/x/y d" \
- "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
+ "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
'
@@ -155,7 +153,7 @@ test_expect_success 'new ref is a simple prefix of existing loose' '
prefix=refs/3l &&
test_update_rejected "a c/x e" false "b c d" \
- "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -163,7 +161,7 @@ test_expect_success 'new ref is a simple prefix of existing packed' '
prefix=refs/3p &&
test_update_rejected "a c/x e" true "b c d" \
- "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -171,7 +169,7 @@ test_expect_success 'new ref is a deeper prefix of existing loose' '
prefix=refs/4l &&
test_update_rejected "a c/x/y e" false "b c d" \
- "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -179,7 +177,7 @@ test_expect_success 'new ref is a deeper prefix of existing packed' '
prefix=refs/4p &&
test_update_rejected "a c/x/y e" true "b c d" \
- "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
+ "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
'
@@ -187,7 +185,7 @@ test_expect_success 'one new ref is a simple prefix of another' '
prefix=refs/5 &&
test_update_rejected "a e" false "b c c/x d" \
- "cannot process $Q$prefix/c$Q and $Q$prefix/c/x$Q at the same time"
+ "cannot process $SQ$prefix/c$SQ and $SQ$prefix/c/x$SQ at the same time"
'
@@ -334,7 +332,7 @@ test_expect_success 'D/F conflict prevents indirect delete long packed + indirec
test_expect_success 'missing old value blocks update' '
prefix=refs/missing-update &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/foo $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -345,7 +343,7 @@ test_expect_success 'incorrect old value blocks update' '
prefix=refs/incorrect-update &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
EOF
printf "%s\n" "update $prefix/foo $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -356,7 +354,7 @@ test_expect_success 'existing old value blocks create' '
prefix=refs/existing-create &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: reference already exists
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: reference already exists
EOF
printf "%s\n" "create $prefix/foo $E" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -367,7 +365,7 @@ test_expect_success 'incorrect old value blocks delete' '
prefix=refs/incorrect-delete &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
EOF
printf "%s\n" "delete $prefix/foo $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -378,7 +376,7 @@ test_expect_success 'missing old value blocks indirect update' '
prefix=refs/missing-indirect-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -390,7 +388,7 @@ test_expect_success 'incorrect old value blocks indirect update' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -402,7 +400,7 @@ test_expect_success 'existing old value blocks indirect create' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
EOF
printf "%s\n" "create $prefix/symref $E" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -414,7 +412,7 @@ test_expect_success 'incorrect old value blocks indirect delete' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "delete $prefix/symref $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -425,7 +423,7 @@ test_expect_success 'missing old value blocks indirect no-deref update' '
prefix=refs/missing-noderef-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: reference is missing but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: reference is missing but expected $D
EOF
printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -437,7 +435,7 @@ test_expect_success 'incorrect old value blocks indirect no-deref update' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -449,7 +447,7 @@ test_expect_success 'existing old value blocks indirect no-deref create' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
EOF
printf "%s\n" "option no-deref" "create $prefix/symref $E" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -461,7 +459,7 @@ test_expect_success 'incorrect old value blocks indirect no-deref delete' '
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
EOF
printf "%s\n" "option no-deref" "delete $prefix/symref $D" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -474,13 +472,13 @@ test_expect_success 'non-empty directory blocks create' '
: >.git/$prefix/foo/bar/baz.lock &&
test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/foo $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/foo $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -493,13 +491,13 @@ test_expect_success 'broken reference blocks create' '
echo "gobbledigook" >.git/$prefix/foo &&
test_when_finished "rm -f .git/$prefix/foo" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/foo $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/foo $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -513,13 +511,13 @@ test_expect_success 'non-empty directory blocks indirect create' '
: >.git/$prefix/foo/bar/baz.lock &&
test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/symref $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ
EOF
printf "%s\n" "update $prefix/symref $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -532,13 +530,13 @@ test_expect_success 'broken reference blocks indirect create' '
echo "gobbledigook" >.git/$prefix/foo &&
test_when_finished "rm -f .git/$prefix/foo" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/symref $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+ fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
EOF
printf "%s\n" "update $prefix/symref $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
@@ -614,7 +612,7 @@ test_expect_success 'delete fails cleanly if packed-refs file is locked' '
test_when_finished "rm -f .git/packed-refs.lock" &&
test_must_fail git update-ref -d $prefix/foo >out 2>err &&
git for-each-ref $prefix >actual &&
- test_i18ngrep "Unable to create $Q.*packed-refs.lock$Q: " err &&
+ test_i18ngrep "Unable to create $SQ.*packed-refs.lock$SQ: " err &&
test_cmp unchanged actual
'
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 79f731db37..82950c0282 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -30,14 +30,13 @@ check_fsck () {
}
corrupt () {
- aa=${1%??????????????????????????????????????} zz=${1#??}
- mv .git/objects/$aa/$zz .git/$aa$zz
+ mv .git/objects/$(test_oid_to_path $1) .git/$1
}
recover () {
- aa=${1%??????????????????????????????????????} zz=${1#??}
+ aa=$(echo $1 | cut -c 1-2)
mkdir -p .git/objects/$aa
- mv .git/$aa$zz .git/objects/$aa/$zz
+ mv .git/$1 .git/objects/$(test_oid_to_path $1)
}
check_dont_have () {
@@ -55,6 +54,7 @@ check_dont_have () {
}
test_expect_success setup '
+ test_oid_init &&
mkdir -p A/B &&
echo rat >C &&
echo ox >A/D &&
@@ -313,12 +313,12 @@ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' '
# Each line is 114 characters, so we need 75 to still have a few before the
# last 8K. The 89-character padding on the final entry lines up our
# newline exactly.
-test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' '
+test_expect_success SHA1 'parsing reverse reflogs at BUFSIZ boundaries' '
git checkout -b reflogskip &&
- z38=00000000000000000000000000000000000000 &&
+ zf=$(test_oid zero_2) &&
ident="abc <xyz> 0000000001 +0000" &&
for i in $(test_seq 1 75); do
- printf "$z38%02d $z38%02d %s\t" $i $(($i+1)) "$ident" &&
+ printf "$zf%02d $zf%02d %s\t" $i $(($i+1)) "$ident" &&
if test $i = 75; then
for j in $(test_seq 1 89); do
printf X
@@ -329,7 +329,7 @@ test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' '
printf "\n"
done >.git/logs/refs/heads/reflogskip &&
git rev-parse reflogskip@{73} >actual &&
- echo ${z38}03 >expect &&
+ echo ${zf}03 >expect &&
test_cmp expect actual
'
diff --git a/t/t1414-reflog-walk.sh b/t/t1414-reflog-walk.sh
index feb1efd8ff..1181a9fb28 100755
--- a/t/t1414-reflog-walk.sh
+++ b/t/t1414-reflog-walk.sh
@@ -18,10 +18,9 @@ do_walk () {
git log -g --format="%gd %gs" "$@"
}
-sq="'"
test_expect_success 'set up expected reflog' '
cat >expect.all <<-EOF
- HEAD@{0} commit (merge): Merge branch ${sq}master${sq} into side
+ HEAD@{0} commit (merge): Merge branch ${SQ}master${SQ} into side
HEAD@{1} commit: three
HEAD@{2} checkout: moving from master to side
HEAD@{3} commit: two
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 0f268a3664..50d28e6fdb 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -9,6 +9,7 @@ test_description='git fsck random collection of tests
. ./test-lib.sh
test_expect_success setup '
+ test_oid_init &&
git config gc.auto 0 &&
git config i18n.commitencoding ISO-8859-1 &&
test_commit A fileA one &&
@@ -54,8 +55,8 @@ test_expect_success 'setup: helpers for corruption tests' '
test_expect_success 'object with bad sha1' '
sha=$(echo blob | git hash-object -w --stdin) &&
- old=$(echo $sha | sed "s+^..+&/+") &&
- new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff &&
+ old=$(test_oid_to_path "$sha") &&
+ new=$(dirname $old)/$(test_oid ff_2) &&
sha="$(dirname $new)$(basename $new)" &&
mv .git/objects/$old .git/objects/$new &&
test_when_finished "remove_object $sha" &&
@@ -69,7 +70,6 @@ test_expect_success 'object with bad sha1' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "$sha.*corrupt" out
'
@@ -77,17 +77,15 @@ test_expect_success 'branch pointing to non-commit' '
git rev-parse HEAD^{tree} >.git/refs/heads/invalid &&
test_when_finished "git update-ref -d refs/heads/invalid" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "not a commit" out
'
test_expect_success 'HEAD link pointing at a funny object' '
test_when_finished "mv .git/SAVED_HEAD .git/HEAD" &&
mv .git/HEAD .git/SAVED_HEAD &&
- echo 0000000000000000000000000000000000000000 >.git/HEAD &&
+ echo $ZERO_OID >.git/HEAD &&
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
- cat out &&
test_i18ngrep "detached HEAD points" out
'
@@ -97,7 +95,6 @@ test_expect_success 'HEAD link pointing at a funny place' '
echo "ref: refs/funny/place" >.git/HEAD &&
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
- cat out &&
test_i18ngrep "HEAD points to something strange" out
'
@@ -156,7 +153,6 @@ test_expect_success 'email with embedded > is not okay' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new" out
'
@@ -168,7 +164,6 @@ test_expect_success 'missing < email delimiter is reported nicely' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.* - bad name" out
'
@@ -180,7 +175,6 @@ test_expect_success 'missing email is reported nicely' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.* - missing email" out
'
@@ -192,7 +186,6 @@ test_expect_success '> in name is reported' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new" out
'
@@ -206,7 +199,6 @@ test_expect_success 'integer overflow in timestamps is reported' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.*integer overflow" out
'
@@ -218,7 +210,6 @@ test_expect_success 'commit with NUL in header' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.*unterminated header: NUL at offset" out
'
@@ -244,10 +235,16 @@ test_expect_success 'tree object with duplicate entries' '
'
test_expect_success 'unparseable tree object' '
+ test_oid_cache <<-\EOF &&
+ junk sha1:twenty-bytes-of-junk
+ junk sha256:twenty-bytes-of-junk-twelve-more
+ EOF
+
test_when_finished "git update-ref -d refs/heads/wrong" &&
test_when_finished "remove_object \$tree_sha1" &&
test_when_finished "remove_object \$commit_sha1" &&
- tree_sha1=$(printf "100644 \0twenty-bytes-of-junk" | git hash-object -t tree --stdin -w --literally) &&
+ junk=$(test_oid junk) &&
+ tree_sha1=$(printf "100644 \0$junk" | git hash-object -t tree --stdin -w --literally) &&
commit_sha1=$(git commit-tree $tree_sha1) &&
git update-ref refs/heads/wrong $commit_sha1 &&
test_must_fail git fsck 2>out &&
@@ -275,8 +272,9 @@ test_expect_success 'tree entry with type mismatch' '
'
test_expect_success 'tag pointing to nonexistent' '
- cat >invalid-tag <<-\EOF &&
- object ffffffffffffffffffffffffffffffffffffffff
+ badoid=$(test_oid deadbeef) &&
+ cat >invalid-tag <<-EOF &&
+ object $badoid
type commit
tag invalid
tagger T A Gger <tagger@example.com> 1234567890 -0000
@@ -289,7 +287,6 @@ test_expect_success 'tag pointing to nonexistent' '
echo $tag >.git/refs/tags/invalid &&
test_when_finished "git update-ref -d refs/tags/invalid" &&
test_must_fail git fsck --tags >out &&
- cat out &&
test_i18ngrep "broken link" out
'
@@ -370,7 +367,6 @@ test_expect_success 'tag with NUL in header' '
echo $tag >.git/refs/tags/wrong &&
test_when_finished "git update-ref -d refs/tags/wrong" &&
test_must_fail git fsck --tags 2>out &&
- cat out &&
test_i18ngrep "error in tag $tag.*unterminated header: NUL at offset" out
'
@@ -386,8 +382,8 @@ test_expect_success 'rev-list --verify-objects' '
test_expect_success 'rev-list --verify-objects with bad sha1' '
sha=$(echo blob | git hash-object -w --stdin) &&
- old=$(echo $sha | sed "s+^..+&/+") &&
- new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff &&
+ old=$(test_oid_to_path $sha) &&
+ new=$(dirname $old)/$(test_oid ff_2) &&
sha="$(dirname $new)$(basename $new)" &&
mv .git/objects/$old .git/objects/$new &&
test_when_finished "remove_object $sha" &&
@@ -401,8 +397,7 @@ test_expect_success 'rev-list --verify-objects with bad sha1' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out &&
- cat out &&
- test_i18ngrep -q "error: hash mismatch 63ffffffffffffffffffffffffffffffffffffff" out
+ test_i18ngrep -q "error: hash mismatch $(dirname $new)$(test_oid ff_2)" out
'
test_expect_success 'force fsck to ignore double author' '
@@ -417,16 +412,14 @@ test_expect_success 'force fsck to ignore double author' '
'
_bz='\0'
-_bz5="$_bz$_bz$_bz$_bz$_bz"
-_bz20="$_bz5$_bz5$_bz5$_bz5"
+_bzoid=$(printf $ZERO_OID | sed -e 's/00/\\0/g')
test_expect_success 'fsck notices blob entry pointing to null sha1' '
(git init null-blob &&
cd null-blob &&
- sha=$(printf "100644 file$_bz$_bz20" |
+ sha=$(printf "100644 file$_bz$_bzoid" |
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*null sha1" out
)
'
@@ -434,10 +427,9 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' '
test_expect_success 'fsck notices submodule entry pointing to null sha1' '
(git init null-commit &&
cd null-commit &&
- sha=$(printf "160000 submodule$_bz$_bz20" |
+ sha=$(printf "160000 submodule$_bz$_bzoid" |
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*null sha1" out
)
'
@@ -458,7 +450,6 @@ while read name path pretty; do
printf "$mode $type %s\t%s" "$value" "$path" >bad &&
bad_tree=$(git mktree <bad) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*tree $bad_tree" out
)'
done <<-\EOF
@@ -586,7 +577,7 @@ test_expect_success 'fsck --connectivity-only' '
# its type. That lets us see that --connectivity-only is
# not actually looking at the contents, but leaves it
# free to examine the type if it chooses.
- empty=.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 &&
+ empty=.git/objects/$(test_oid_to_path $EMPTY_BLOB) &&
blob=$(echo unrelated | git hash-object -w --stdin) &&
mv -f $(sha1_file $blob) $empty &&
@@ -631,10 +622,12 @@ test_expect_success 'fsck --name-objects' '
test_expect_success 'alternate objects are correctly blamed' '
test_when_finished "rm -rf alt.git .git/objects/info/alternates" &&
+ name=$(test_oid numeric) &&
+ path=$(test_oid_to_path "$name") &&
git init --bare alt.git &&
echo "../../alt.git/objects" >.git/objects/info/alternates &&
- mkdir alt.git/objects/12 &&
- >alt.git/objects/12/34567890123456789012345678901234567890 &&
+ mkdir alt.git/objects/$(dirname $path) &&
+ >alt.git/objects/$(dirname $path)/$(basename $path) &&
test_must_fail git fsck >out 2>&1 &&
test_i18ngrep alt.git out
'
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index 4ee009da66..624d0a588f 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -8,10 +8,9 @@ exec </dev/null
test_did_you_mean ()
{
- sq="'" &&
cat >expected <<-EOF &&
- fatal: Path '$2$3' $4, but not ${5:-$sq$3$sq}.
- Did you mean '$1:$2$3'${2:+ aka $sq$1:./$3$sq}?
+ fatal: Path '$2$3' $4, but not ${5:-$SQ$3$SQ}.
+ Did you mean '$1:$2$3'${2:+ aka $SQ$1:./$3$SQ}?
EOF
test_cmp expected error
}
@@ -215,4 +214,12 @@ test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
test_cmp expect actual
'
+test_expect_success 'reject Nth parent if N is too high' '
+ test_must_fail git rev-parse HEAD^100000000000000000000000000000000
+'
+
+test_expect_success 'reject Nth ancestor if N is too high' '
+ test_must_fail git rev-parse HEAD~100000000000000000000000000000000
+'
+
test_done
diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh
index fa3e499641..8b4cf8a6e3 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -28,8 +28,6 @@ test_expect_success 'setup' '
)
'
-sq="'"
-
full_name () {
(cd clone &&
git rev-parse --symbolic-full-name "$@")
@@ -129,7 +127,7 @@ test_expect_success 'merge my-side@{u} records the correct name' '
git branch -t new my-side@{u} &&
git merge -s ours new@{u} &&
git show -s --pretty=tformat:%s >actual &&
- echo "Merge remote-tracking branch ${sq}origin/side${sq}" >expect &&
+ echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect &&
test_cmp expect actual
)
'
@@ -156,7 +154,7 @@ test_expect_success 'branch@{u} works when tracking a local branch' '
test_expect_success 'branch@{u} error message when no upstream' '
cat >expect <<-EOF &&
- fatal: no upstream configured for branch ${sq}non-tracking${sq}
+ fatal: no upstream configured for branch ${SQ}non-tracking${SQ}
EOF
error_message non-tracking@{u} &&
test_i18ncmp expect error
@@ -164,7 +162,7 @@ test_expect_success 'branch@{u} error message when no upstream' '
test_expect_success '@{u} error message when no upstream' '
cat >expect <<-EOF &&
- fatal: no upstream configured for branch ${sq}master${sq}
+ fatal: no upstream configured for branch ${SQ}master${SQ}
EOF
test_must_fail git rev-parse --verify @{u} 2>actual &&
test_i18ncmp expect actual
@@ -172,7 +170,7 @@ test_expect_success '@{u} error message when no upstream' '
test_expect_success 'branch@{u} error message with misspelt branch' '
cat >expect <<-EOF &&
- fatal: no such branch: ${sq}no-such-branch${sq}
+ fatal: no such branch: ${SQ}no-such-branch${SQ}
EOF
error_message no-such-branch@{u} &&
test_i18ncmp expect error
@@ -189,7 +187,7 @@ test_expect_success '@{u} error message when not on a branch' '
test_expect_success 'branch@{u} error message if upstream branch not fetched' '
cat >expect <<-EOF &&
- fatal: upstream branch ${sq}refs/heads/side${sq} not stored as a remote-tracking branch
+ fatal: upstream branch ${SQ}refs/heads/side${SQ} not stored as a remote-tracking branch
EOF
error_message bad-upstream@{u} &&
test_i18ncmp expect error
diff --git a/t/t1600-index.sh b/t/t1600-index.sh
index c77721b580..b7c31aa86a 100755
--- a/t/t1600-index.sh
+++ b/t/t1600-index.sh
@@ -87,6 +87,10 @@ test_index_version () {
}
test_expect_success 'index version config precedence' '
+ test_index_version 0 false 0 2 &&
+ test_index_version 2 false 0 2 &&
+ test_index_version 3 false 0 2 &&
+ test_index_version 4 false 0 4 &&
test_index_version 2 false 4 4 &&
test_index_version 2 true 0 2 &&
test_index_version 0 true 0 4 &&
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index 4f2f84f309..12a5568844 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -20,6 +20,22 @@ create_non_racy_file () {
test-tool chmtime =-5 "$1"
}
+test_expect_success 'setup' '
+ test_oid_cache <<-EOF
+ own_v3 sha1:8299b0bcd1ac364e5f1d7768efb62fa2da79a339
+ own_v3 sha256:38a6d2925e3eceec33ad7b34cbff4e0086caa0daf28f31e51f5bd94b4a7af86b
+
+ base_v3 sha1:39d890139ee5356c7ef572216cebcd27aa41f9df
+ base_v3 sha256:c9baeadf905112bf6c17aefbd7d02267afd70ded613c30cafed2d40cb506e1ed
+
+ own_v4 sha1:432ef4b63f32193984f339431fd50ca796493569
+ own_v4 sha256:6738ac6319c25b694afa7bcc313deb182d1a59b68bf7a47b4296de83478c0420
+
+ base_v4 sha1:508851a7f0dfa8691e9f69c7f055865389012491
+ base_v4 sha256:3177d4adfdd4b6904f7e921d91d715a471c0dde7cf6a4bba574927f02b699508
+ EOF
+'
+
test_expect_success 'enable split index' '
git config splitIndex.maxPercentChange 100 &&
git update-index --split-index &&
@@ -29,11 +45,11 @@ test_expect_success 'enable split index' '
# NEEDSWORK: Stop hard-coding checksums.
if test "$indexversion" = "4"
then
- own=432ef4b63f32193984f339431fd50ca796493569
- base=508851a7f0dfa8691e9f69c7f055865389012491
+ own=$(test_oid own_v4)
+ base=$(test_oid base_v4)
else
- own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
- base=39d890139ee5356c7ef572216cebcd27aa41f9df
+ own=$(test_oid own_v3)
+ base=$(test_oid base_v3)
fi &&
cat >expect <<-EOF &&
@@ -99,17 +115,18 @@ test_expect_success 'enable split index again, "one" now belongs to base index"'
test_expect_success 'modify original file, base index untouched' '
echo modified | create_non_racy_file one &&
+ file1_blob=$(git hash-object one) &&
git update-index one &&
git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF &&
- 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
+ 100644 $file1_blob 0 one
EOF
test_cmp ls-files.expect ls-files.actual &&
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
q_to_tab >expect <<-EOF &&
$BASE
- 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
+ 100644 $file1_blob 0Q
replacements: 0
deletions:
EOF
@@ -121,7 +138,7 @@ test_expect_success 'add another file, which stays index' '
git update-index --add two &&
git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF &&
- 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
+ 100644 $file1_blob 0 one
100644 $EMPTY_BLOB 0 two
EOF
test_cmp ls-files.expect ls-files.actual &&
@@ -129,7 +146,7 @@ test_expect_success 'add another file, which stays index' '
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
q_to_tab >expect <<-EOF &&
$BASE
- 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
+ 100644 $file1_blob 0Q
100644 $EMPTY_BLOB 0 two
replacements: 0
deletions:
@@ -141,14 +158,14 @@ test_expect_success 'remove file not in base index' '
git update-index --force-remove two &&
git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF &&
- 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
+ 100644 $file1_blob 0 one
EOF
test_cmp ls-files.expect ls-files.actual &&
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
q_to_tab >expect <<-EOF &&
$BASE
- 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
+ 100644 $file1_blob 0Q
replacements: 0
deletions:
EOF
@@ -237,9 +254,9 @@ test_expect_success 'set core.splitIndex config variable to true' '
git update-index --add three &&
git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF &&
- 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
- 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 three
- 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
+ 100644 $EMPTY_BLOB 0 one
+ 100644 $EMPTY_BLOB 0 three
+ 100644 $EMPTY_BLOB 0 two
EOF
test_cmp ls-files.expect ls-files.actual &&
BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
@@ -257,8 +274,8 @@ test_expect_success 'set core.splitIndex config variable to false' '
git update-index --force-remove three &&
git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF &&
- 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
- 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
+ 100644 $EMPTY_BLOB 0 one
+ 100644 $EMPTY_BLOB 0 two
EOF
test_cmp ls-files.expect ls-files.actual &&
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
@@ -285,7 +302,7 @@ test_expect_success 'set core.splitIndex config variable back to true' '
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
cat >expect <<-EOF &&
$BASE
- 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 four
+ 100644 $EMPTY_BLOB 0 four
replacements:
deletions:
EOF
@@ -309,7 +326,7 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
cat >expect <<-EOF &&
$BASE
- 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 six
+ 100644 $EMPTY_BLOB 0 six
replacements:
deletions:
EOF
diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh
index fc3eb43b89..6844afafc0 100755
--- a/t/t2022-checkout-paths.sh
+++ b/t/t2022-checkout-paths.sh
@@ -78,4 +78,15 @@ test_expect_success 'do not touch files that are already up-to-date' '
test_cmp expect actual
'
+test_expect_success 'checkout HEAD adds deleted intent-to-add file back to index' '
+ echo "nonempty" >nonempty &&
+ >empty &&
+ git add nonempty empty &&
+ git commit -m "create files to be deleted" &&
+ git rm --cached nonempty empty &&
+ git add -N nonempty empty &&
+ git checkout HEAD nonempty empty &&
+ git diff --cached --exit-code
+'
+
test_done
diff --git a/t/t2070-restore.sh b/t/t2070-restore.sh
index 2650df1966..21c3f84459 100755
--- a/t/t2070-restore.sh
+++ b/t/t2070-restore.sh
@@ -95,4 +95,15 @@ test_expect_success 'restore --ignore-unmerged ignores unmerged entries' '
)
'
+test_expect_success 'restore --staged adds deleted intent-to-add file back to index' '
+ echo "nonempty" >nonempty &&
+ >empty &&
+ git add nonempty empty &&
+ git commit -m "create files to be deleted" &&
+ git rm --cached nonempty empty &&
+ git add -N nonempty empty &&
+ git restore --staged nonempty empty &&
+ git diff --cached --exit-code
+'
+
test_done
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index 68e54d5c44..5bbe8dcce4 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -247,12 +247,14 @@ test_expect_success 'diff-files/diff-cached shows ita as new/not-new files' '
test_expect_success '"diff HEAD" includes ita as new files' '
git reset --hard &&
echo new >new-ita &&
+ oid=$(git hash-object new-ita) &&
+ oid=$(git rev-parse --short $oid) &&
git add -N new-ita &&
git diff HEAD >actual &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
diff --git a/new-ita b/new-ita
new file mode 100644
- index 0000000..3e75765
+ index 0000000..$oid
--- /dev/null
+++ b/new-ita
@@ -0,0 +1 @@
diff --git a/t/t3005-ls-files-relative.sh b/t/t3005-ls-files-relative.sh
index 209b4c7cd8..2ec69a8a26 100755
--- a/t/t3005-ls-files-relative.sh
+++ b/t/t3005-ls-files-relative.sh
@@ -7,10 +7,6 @@ This test runs git ls-files with various relative path arguments.
. ./test-lib.sh
-new_line='
-'
-sq=\'
-
test_expect_success 'prepare' '
: >never-mind-me &&
git add never-mind-me &&
@@ -44,9 +40,9 @@ test_expect_success 'ls-files -c' '
cd top/sub &&
for f in ../y*
do
- echo "error: pathspec $sq$f$sq did not match any file(s) known to git"
+ echo "error: pathspec $SQ$f$SQ did not match any file(s) known to git"
done >expect.err &&
- echo "Did you forget to ${sq}git add${sq}?" >>expect.err &&
+ echo "Did you forget to ${SQ}git add${SQ}?" >>expect.err &&
ls ../x* >expect.out &&
test_must_fail git ls-files -c --error-unmatch ../[xy]* >actual.out 2>actual.err &&
test_cmp expect.out actual.out &&
@@ -59,9 +55,9 @@ test_expect_success 'ls-files -o' '
cd top/sub &&
for f in ../x*
do
- echo "error: pathspec $sq$f$sq did not match any file(s) known to git"
+ echo "error: pathspec $SQ$f$SQ did not match any file(s) known to git"
done >expect.err &&
- echo "Did you forget to ${sq}git add${sq}?" >>expect.err &&
+ echo "Did you forget to ${SQ}git add${SQ}?" >>expect.err &&
ls ../y* >expect.out &&
test_must_fail git ls-files -o --error-unmatch ../[xy]* >actual.out 2>actual.err &&
test_cmp expect.out actual.out &&
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index ff641b348a..2170758e38 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -452,6 +452,34 @@ test_expect_success 'merge-recursive d/f conflict result' '
'
+test_expect_success SYMLINKS 'dir in working tree with symlink ancestor does not produce d/f conflict' '
+ git init sym &&
+ (
+ cd sym &&
+ ln -s . foo &&
+ mkdir bar &&
+ >bar/file &&
+ git add foo bar/file &&
+ git commit -m "foo symlink" &&
+
+ git checkout -b branch1 &&
+ git commit --allow-empty -m "empty commit" &&
+
+ git checkout master &&
+ git rm foo &&
+ mkdir foo &&
+ >foo/bar &&
+ git add foo/bar &&
+ git commit -m "replace foo symlink with real foo dir and foo/bar file" &&
+
+ git checkout branch1 &&
+
+ git cherry-pick master &&
+ test_path_is_dir foo &&
+ test_path_is_file foo/bar
+ )
+'
+
test_expect_success 'reset and 3-way merge' '
git reset --hard "$c2" &&
@@ -667,15 +695,22 @@ test_expect_success 'merging with triple rename across D/F conflict' '
test_expect_success 'merge-recursive remembers the names of all base trees' '
git reset --hard HEAD &&
+ # make the index match $c1 so that merge-recursive below does not
+ # fail early
+ git diff --binary HEAD $c1 -- | git apply --cached &&
+
# more trees than static slots used by oid_to_hex()
for commit in $c0 $c2 $c4 $c5 $c6 $c7
do
git rev-parse "$commit^{tree}"
done >trees &&
- # ignore the return code -- it only fails because the input is weird
+ # ignore the return code; it only fails because the input is weird...
test_must_fail git -c merge.verbosity=5 merge-recursive $(cat trees) -- $c1 $c3 >out &&
+ # ...but make sure it fails in the expected way
+ test_i18ngrep CONFLICT.*rename/rename out &&
+
# merge-recursive prints in reverse order, but we do not care
sort <trees >expect &&
sed -n "s/^virtual //p" out | sort >actual &&
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 0ea4fc4694..40251c9f8f 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -192,10 +192,10 @@ test_expect_success 'branch --merged with --verbose' '
EOF
test_cmp expect actual &&
git branch --verbose --merged topic >actual &&
- cat >expect <<-\EOF &&
- master c77a0a9 second on master
- * topic 2c939f4 [ahead 1] foo
- zzz c77a0a9 second on master
+ cat >expect <<-EOF &&
+ master $(git rev-parse --short master) second on master
+ * topic $(git rev-parse --short topic ) [ahead 1] foo
+ zzz $(git rev-parse --short zzz ) second on master
EOF
test_i18ncmp expect actual
'
diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index 048feaf6dd..0579cd9969 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -8,17 +8,124 @@ test_description='range-diff tests'
# harm than good. We need some real history.
test_expect_success 'setup' '
- git fast-import < "$TEST_DIRECTORY"/t3206/history.export
+ git fast-import < "$TEST_DIRECTORY"/t3206/history.export &&
+ test_oid_cache <<-EOF
+ # topic
+ t1 sha1:4de457d
+ t2 sha1:fccce22
+ t3 sha1:147e64e
+ t4 sha1:a63e992
+ t1 sha256:b89f8b9
+ t2 sha256:5f12aad
+ t3 sha256:ea8b273
+ t4 sha256:14b7336
+
+ # unmodified
+ u1 sha1:35b9b25
+ u2 sha1:de345ab
+ u3 sha1:9af6654
+ u4 sha1:2901f77
+ u1 sha256:e3731be
+ u2 sha256:14fadf8
+ u3 sha256:736c4bc
+ u4 sha256:673e77d
+
+ # reordered
+ r1 sha1:aca177a
+ r2 sha1:14ad629
+ r3 sha1:ee58208
+ r4 sha1:307b27a
+ r1 sha256:f59d3aa
+ r2 sha256:fb261a8
+ r3 sha256:cb2649b
+ r4 sha256:958577e
+
+ # removed (deleted)
+ d1 sha1:7657159
+ d2 sha1:43d84d3
+ d3 sha1:a740396
+ d1 sha256:e312513
+ d2 sha256:eb19258
+ d3 sha256:1ccb3c1
+
+ # added
+ a1 sha1:2716022
+ a2 sha1:b62accd
+ a3 sha1:df46cfa
+ a4 sha1:3e64548
+ a5 sha1:12b4063
+ a1 sha256:d724f4d
+ a2 sha256:1de7762
+ a3 sha256:e159431
+ a4 sha256:b3e483c
+ a5 sha256:90866a7
+
+ # rebased
+ b1 sha1:cc9c443
+ b2 sha1:c5d9641
+ b3 sha1:28cc2b6
+ b4 sha1:5628ab7
+ b5 sha1:a31b12e
+ b1 sha256:a1a8717
+ b2 sha256:20a5862
+ b3 sha256:587172a
+ b4 sha256:2721c5d
+ b5 sha256:7b57864
+
+ # changed
+ c1 sha1:a4b3333
+ c2 sha1:f51d370
+ c3 sha1:0559556
+ c4 sha1:d966c5c
+ c1 sha256:f8c2b9d
+ c2 sha256:3fb6318
+ c3 sha256:168ab68
+ c4 sha256:3526539
+
+ # changed-message
+ m1 sha1:f686024
+ m2 sha1:4ab067d
+ m3 sha1:b9cb956
+ m4 sha1:8add5f1
+ m1 sha256:31e6281
+ m2 sha256:a06bf1b
+ m3 sha256:82dc654
+ m4 sha256:48470c5
+
+ # renamed
+ n1 sha1:f258d75
+ n2 sha1:017b62d
+ n3 sha1:3ce7af6
+ n4 sha1:1e6226b
+ n1 sha256:ad52114
+ n2 sha256:3b54c8f
+ n3 sha256:3b0a644
+ n4 sha256:e461653
+
+ # added and removed
+ s1 sha1:096b1ba
+ s2 sha1:d92e698
+ s3 sha1:9a1db4d
+ s4 sha1:fea3b5c
+ s1 sha256:a7f9134
+ s2 sha256:b4c2580
+ s3 sha256:1d62aa2
+ s4 sha256:48160e8
+
+ # Empty delimiter (included so lines match neatly)
+ __ sha1:-------
+ __ sha256:-------
+ EOF
'
test_expect_success 'simple A..B A..C (unmodified)' '
git range-diff --no-color master..topic master..unmodified \
>actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: 35b9b25 s/5/A/
- 2: fccce22 = 2: de345ab s/4/A/
- 3: 147e64e = 3: 9af6654 s/11/B/
- 4: a63e992 = 4: 2901f77 s/12/B/
+ 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
'
@@ -38,10 +145,10 @@ test_expect_success 'simple A B C (unmodified)' '
test_expect_success 'trivial reordering' '
git range-diff --no-color master topic reordered >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: aca177a s/5/A/
- 3: 147e64e = 2: 14ad629 s/11/B/
- 4: a63e992 = 3: ee58208 s/12/B/
- 2: fccce22 = 4: 307b27a s/4/A/
+ 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
'
@@ -49,10 +156,10 @@ test_expect_success 'trivial reordering' '
test_expect_success 'removed a commit' '
git range-diff --no-color master topic removed >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: 7657159 s/5/A/
- 2: fccce22 < -: ------- s/4/A/
- 3: 147e64e = 2: 43d84d3 s/11/B/
- 4: a63e992 = 3: a740396 s/12/B/
+ 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
'
@@ -60,11 +167,11 @@ test_expect_success 'removed a commit' '
test_expect_success 'added a commit' '
git range-diff --no-color master topic added >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: 2716022 s/5/A/
- 2: fccce22 = 2: b62accd s/4/A/
- -: ------- > 3: df46cfa s/6/A/
- 3: 147e64e = 4: 3e64548 s/11/B/
- 4: a63e992 = 5: 12b4063 s/12/B/
+ 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
'
@@ -72,10 +179,10 @@ test_expect_success 'added a commit' '
test_expect_success 'new base, A B C' '
git range-diff --no-color master topic rebased >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: cc9c443 s/5/A/
- 2: fccce22 = 2: c5d9641 s/4/A/
- 3: 147e64e = 3: 28cc2b6 s/11/B/
- 4: a63e992 = 4: 5628ab7 s/12/B/
+ 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
'
@@ -84,11 +191,11 @@ test_expect_success 'new base, B...C' '
# this syntax includes the commits from master!
git range-diff --no-color topic...rebased >actual &&
cat >expected <<-EOF &&
- -: ------- > 1: a31b12e unrelated
- 1: 4de457d = 2: cc9c443 s/5/A/
- 2: fccce22 = 3: c5d9641 s/4/A/
- 3: 147e64e = 4: 28cc2b6 s/11/B/
- 4: a63e992 = 5: 5628ab7 s/12/B/
+ -: $(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
'
@@ -96,10 +203,10 @@ test_expect_success 'new base, B...C' '
test_expect_success 'changed commit' '
git range-diff --no-color topic...changed >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
- 2: fccce22 = 2: f51d370 s/4/A/
- 3: 147e64e ! 3: 0559556 s/11/B/
- @@ -10,7 +10,7 @@
+ 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
+ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
+ @@ file: A
9
10
-11
@@ -108,9 +215,9 @@ test_expect_success 'changed commit' '
12
13
14
- 4: a63e992 ! 4: d966c5c s/12/B/
- @@ -8,7 +8,7 @@
- @@
+ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
+ @@ file
+ @@ file: A
9
10
- B
@@ -125,10 +232,10 @@ test_expect_success 'changed commit' '
test_expect_success 'changed commit with --no-patch diff option' '
git range-diff --no-color --no-patch topic...changed >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
- 2: fccce22 = 2: f51d370 s/4/A/
- 3: 147e64e ! 3: 0559556 s/11/B/
- 4: a63e992 ! 4: d966c5c s/12/B/
+ 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
'
@@ -136,16 +243,16 @@ test_expect_success 'changed commit with --no-patch diff option' '
test_expect_success 'changed commit with --stat diff option' '
git range-diff --no-color --stat topic...changed >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
+ 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
- 2: fccce22 = 2: f51d370 s/4/A/
+ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
- 3: 147e64e ! 3: 0559556 s/11/B/
+ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
- 4: a63e992 ! 4: d966c5c s/12/B/
+ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
a => b | 0
1 file changed, 0 insertions(+), 0 deletions(-)
EOF
@@ -155,10 +262,10 @@ test_expect_success 'changed commit with --stat diff option' '
test_expect_success 'changed commit with sm config' '
git range-diff --no-color --submodule=log topic...changed >actual &&
cat >expected <<-EOF &&
- 1: 4de457d = 1: a4b3333 s/5/A/
- 2: fccce22 = 2: f51d370 s/4/A/
- 3: 147e64e ! 3: 0559556 s/11/B/
- @@ -10,7 +10,7 @@
+ 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
+ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
+ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
+ @@ file: A
9
10
-11
@@ -167,9 +274,9 @@ test_expect_success 'changed commit with sm config' '
12
13
14
- 4: a63e992 ! 4: d966c5c s/12/B/
- @@ -8,7 +8,7 @@
- @@
+ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
+ @@ file
+ @@ file: A
9
10
- B
@@ -181,6 +288,132 @@ test_expect_success 'changed commit with sm config' '
test_cmp expected actual
'
+test_expect_success 'renamed file' '
+ git range-diff --no-color --submodule=log topic...renamed-file >actual &&
+ sed s/Z/\ /g >expected <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid n1) s/5/A/
+ 2: $(test_oid t2) ! 2: $(test_oid n2) s/4/A/
+ @@ Metadata
+ ZAuthor: Thomas Rast <trast@inf.ethz.ch>
+ Z
+ Z ## Commit message ##
+ - s/4/A/
+ + s/4/A/ + rename file
+ Z
+ - ## file ##
+ + ## file => renamed-file ##
+ Z@@
+ Z 1
+ Z 2
+ 3: $(test_oid t3) ! 3: $(test_oid n3) s/11/B/
+ @@ Metadata
+ Z ## Commit message ##
+ Z s/11/B/
+ Z
+ - ## file ##
+ -@@ file: A
+ + ## renamed-file ##
+ +@@ renamed-file: A
+ Z 8
+ Z 9
+ Z 10
+ 4: $(test_oid t4) ! 4: $(test_oid n4) s/12/B/
+ @@ Metadata
+ Z ## Commit message ##
+ Z s/12/B/
+ Z
+ - ## file ##
+ -@@ file: A
+ + ## renamed-file ##
+ +@@ renamed-file: A
+ Z 9
+ Z 10
+ Z B
+ EOF
+ test_cmp expected 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/
+ @@ Metadata
+ ZAuthor: Thomas Rast <trast@inf.ethz.ch>
+ Z
+ Z ## Commit message ##
+ - s/4/A/
+ + s/4/A/ + add other-file
+ Z
+ Z ## file ##
+ Z@@
+ @@ file
+ Z A
+ Z 6
+ Z 7
+ +
+ + ## other-file (new) ##
+ 2: 147e64e ! 2: 26c107f s/11/B/
+ @@ Metadata
+ ZAuthor: Thomas Rast <trast@inf.ethz.ch>
+ Z
+ Z ## Commit message ##
+ - s/11/B/
+ + s/11/B/ + mode change other-file
+ Z
+ Z ## file ##
+ Z@@ file: A
+ @@ file: A
+ Z 12
+ Z 13
+ Z 14
+ +
+ + ## other-file (mode change 100644 => 100755) ##
+ 3: a63e992 = 3: 4c1e0f5 s/12/B/
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'file added and later removed' '
+ git range-diff --no-color --submodule=log topic...added-removed >actual &&
+ sed s/Z/\ /g >expected <<-EOF &&
+ 1: $(test_oid t1) = 1: $(test_oid s1) s/5/A/
+ 2: $(test_oid t2) ! 2: $(test_oid s2) s/4/A/
+ @@ Metadata
+ ZAuthor: Thomas Rast <trast@inf.ethz.ch>
+ Z
+ Z ## Commit message ##
+ - s/4/A/
+ + s/4/A/ + new-file
+ Z
+ Z ## file ##
+ Z@@
+ @@ file
+ Z A
+ Z 6
+ Z 7
+ +
+ + ## new-file (new) ##
+ 3: $(test_oid t3) ! 3: $(test_oid s3) s/11/B/
+ @@ Metadata
+ ZAuthor: Thomas Rast <trast@inf.ethz.ch>
+ Z
+ Z ## Commit message ##
+ - s/11/B/
+ + s/11/B/ + remove file
+ Z
+ Z ## file ##
+ Z@@ file: A
+ @@ file: A
+ Z 12
+ Z 13
+ Z 14
+ +
+ + ## new-file (deleted) ##
+ 4: $(test_oid t4) = 4: $(test_oid s4) s/12/B/
+ EOF
+ test_cmp expected actual
+'
+
test_expect_success 'no commits on one side' '
git commit --amend -m "new message" &&
git range-diff master HEAD@{1} HEAD
@@ -189,38 +422,38 @@ test_expect_success 'no commits on one side' '
test_expect_success 'changed message' '
git range-diff --no-color topic...changed-message >actual &&
sed s/Z/\ /g >expected <<-EOF &&
- 1: 4de457d = 1: f686024 s/5/A/
- 2: fccce22 ! 2: 4ab067d s/4/A/
- @@ -2,6 +2,8 @@
- Z
+ 1: $(test_oid t1) = 1: $(test_oid m1) s/5/A/
+ 2: $(test_oid t2) ! 2: $(test_oid m2) s/4/A/
+ @@ Metadata
+ Z ## Commit message ##
Z s/4/A/
Z
+ Also a silly comment here!
+
- Z diff --git a/file b/file
- Z --- a/file
- Z +++ b/file
- 3: 147e64e = 3: b9cb956 s/11/B/
- 4: a63e992 = 4: 8add5f1 s/12/B/
+ Z ## file ##
+ Z@@
+ Z 1
+ 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_expect_success 'dual-coloring' '
- sed -e "s|^:||" >expect <<-\EOF &&
- :<YELLOW>1: a4b3333 = 1: f686024 s/5/A/<RESET>
- :<RED>2: f51d370 <RESET><YELLOW>!<RESET><GREEN> 2: 4ab067d<RESET><YELLOW> s/4/A/<RESET>
- : <REVERSE><CYAN>@@ -2,6 +2,8 @@<RESET>
- : <RESET>
+ sed -e "s|^:||" >expect <<-EOF &&
+ :<YELLOW>1: $(test_oid c1) = 1: $(test_oid m1) s/5/A/<RESET>
+ :<RED>2: $(test_oid c2) <RESET><YELLOW>!<RESET><GREEN> 2: $(test_oid m2)<RESET><YELLOW> s/4/A/<RESET>
+ : <REVERSE><CYAN>@@<RESET> <RESET>Metadata<RESET>
+ : ## Commit message ##<RESET>
: s/4/A/<RESET>
: <RESET>
: <REVERSE><GREEN>+<RESET><BOLD> Also a silly comment here!<RESET>
: <REVERSE><GREEN>+<RESET>
- : diff --git a/file b/file<RESET>
- : --- a/file<RESET>
- : +++ b/file<RESET>
- :<RED>3: 0559556 <RESET><YELLOW>!<RESET><GREEN> 3: b9cb956<RESET><YELLOW> s/11/B/<RESET>
- : <REVERSE><CYAN>@@ -10,7 +10,7 @@<RESET>
+ : ## file ##<RESET>
+ : <CYAN> @@<RESET>
+ : 1<RESET>
+ :<RED>3: $(test_oid c3) <RESET><YELLOW>!<RESET><GREEN> 3: $(test_oid m3)<RESET><YELLOW> s/11/B/<RESET>
+ : <REVERSE><CYAN>@@<RESET> <RESET>file: A<RESET>
: 9<RESET>
: 10<RESET>
: <RED> -11<RESET>
@@ -229,9 +462,9 @@ test_expect_success 'dual-coloring' '
: 12<RESET>
: 13<RESET>
: 14<RESET>
- :<RED>4: d966c5c <RESET><YELLOW>!<RESET><GREEN> 4: 8add5f1<RESET><YELLOW> s/12/B/<RESET>
- : <REVERSE><CYAN>@@ -8,7 +8,7 @@<RESET>
- : <CYAN> @@<RESET>
+ :<RED>4: $(test_oid c4) <RESET><YELLOW>!<RESET><GREEN> 4: $(test_oid m4)<RESET><YELLOW> s/12/B/<RESET>
+ : <REVERSE><CYAN>@@<RESET> <RESET>file<RESET>
+ : <CYAN> @@ file: A<RESET>
: 9<RESET>
: 10<RESET>
: <REVERSE><RED>-<RESET><FAINT> BB<RESET>
@@ -268,4 +501,8 @@ test_expect_success 'format-patch --range-diff as commentary' '
grep "> 1: .* new message" 0001-*
'
+test_expect_success 'range-diff overrides diff.noprefix internally' '
+ git -c diff.noprefix=true range-diff HEAD^...
+'
+
test_done
diff --git a/t/t3206/history.export b/t/t3206/history.export
index b8ffff0940..4c808e5b3b 100644
--- a/t/t3206/history.export
+++ b/t/t3206/history.export
@@ -22,8 +22,8 @@ data 51
19
20
-reset refs/heads/removed
-commit refs/heads/removed
+reset refs/heads/renamed-file
+commit refs/heads/renamed-file
mark :2
author Thomas Rast <trast@inf.ethz.ch> 1374424921 +0200
committer Thomas Rast <trast@inf.ethz.ch> 1374484724 +0200
@@ -55,7 +55,7 @@ A
19
20
-commit refs/heads/topic
+commit refs/heads/mode-only-change
mark :4
author Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
committer Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
@@ -599,6 +599,111 @@ s/12/B/
from :46
M 100644 :28 file
-reset refs/heads/removed
-from :47
+commit refs/heads/added-removed
+mark :48
+author Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574151 +0100
+data 7
+s/5/A/
+from :2
+M 100644 :3 file
+
+blob
+mark :49
+data 0
+
+commit refs/heads/added-removed
+mark :50
+author Thomas Rast <trast@inf.ethz.ch> 1374485024 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574177 +0100
+data 18
+s/4/A/ + new-file
+from :48
+M 100644 :5 file
+M 100644 :49 new-file
+
+commit refs/heads/added-removed
+mark :51
+author Thomas Rast <trast@inf.ethz.ch> 1374485036 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574177 +0100
+data 22
+s/11/B/ + remove file
+from :50
+M 100644 :7 file
+D new-file
+
+commit refs/heads/added-removed
+mark :52
+author Thomas Rast <trast@inf.ethz.ch> 1374485044 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574177 +0100
+data 8
+s/12/B/
+from :51
+M 100644 :9 file
+
+commit refs/heads/renamed-file
+mark :53
+author Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574309 +0100
+data 7
+s/5/A/
+from :2
+M 100644 :3 file
+
+commit refs/heads/renamed-file
+mark :54
+author Thomas Rast <trast@inf.ethz.ch> 1374485024 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574312 +0100
+data 21
+s/4/A/ + rename file
+from :53
+D file
+M 100644 :5 renamed-file
+
+commit refs/heads/renamed-file
+mark :55
+author Thomas Rast <trast@inf.ethz.ch> 1374485036 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574319 +0100
+data 8
+s/11/B/
+from :54
+M 100644 :7 renamed-file
+
+commit refs/heads/renamed-file
+mark :56
+author Thomas Rast <trast@inf.ethz.ch> 1374485044 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1556574319 +0100
+data 8
+s/12/B/
+from :55
+M 100644 :9 renamed-file
+
+commit refs/heads/mode-only-change
+mark :57
+author Thomas Rast <trast@inf.ethz.ch> 1374485024 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473767 +0100
+data 24
+s/4/A/ + add other-file
+from :4
+M 100644 :5 file
+M 100644 :49 other-file
+
+commit refs/heads/mode-only-change
+mark :58
+author Thomas Rast <trast@inf.ethz.ch> 1374485036 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473768 +0100
+data 33
+s/11/B/ + mode change other-file
+from :57
+M 100644 :7 file
+M 100755 :49 other-file
+
+commit refs/heads/mode-only-change
+mark :59
+author Thomas Rast <trast@inf.ethz.ch> 1374485044 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473768 +0100
+data 8
+s/12/B/
+from :58
+M 100644 :9 file
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index 704bbc6541..d3fa298c6a 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -66,8 +66,9 @@ test_expect_success 'show notes entry with %N' '
'
test_expect_success 'create reflog entry' '
+ ref=$(git rev-parse --short refs/notes/commits) &&
cat <<-EOF >expect &&
- a1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
+ $ref refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
EOF
git reflog show refs/notes/commits >actual &&
test_cmp expect actual
@@ -134,8 +135,9 @@ test_expect_success 'can overwrite existing note with "git notes add -f"' '
'
test_expect_success 'show notes' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 7a4ca6ee52a974a66cbaa78e33214535dff1d691
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:14:13 2005 -0700
@@ -152,8 +154,9 @@ test_expect_success 'show notes' '
test_expect_success 'show multi-line notes' '
test_commit 3rd &&
MSG="b3${LF}c3c3c3c3${LF}d3d3d3" git notes add &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-multiline <<-EOF &&
- commit d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:15:13 2005 -0700
@@ -174,8 +177,9 @@ test_expect_success 'show -F notes' '
test_commit 4th &&
echo "xyzzy" >note5 &&
git notes add -F note5 &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-F <<-EOF &&
- commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:16:13 2005 -0700
@@ -198,10 +202,13 @@ test_expect_success 'Re-adding -F notes without -f fails' '
'
test_expect_success 'git log --pretty=raw does not show notes' '
+ commit=$(git rev-parse HEAD) &&
+ tree=$(git rev-parse HEAD^{tree}) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
- tree 05ac65288c4c4b3b709a020ae94b2ece2f2201ae
- parent d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit $commit
+ tree $tree
+ parent $parent
author A U Thor <author@example.com> 1112912173 -0700
committer C O Mitter <committer@example.com> 1112912173 -0700
@@ -291,8 +298,9 @@ test_expect_success 'git log --no-notes resets ref list' '
test_expect_success 'show -m notes' '
test_commit 5th &&
git notes add -m spam -m "foo${LF}bar${LF}baz" &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-m <<-EOF &&
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -313,8 +321,9 @@ test_expect_success 'show -m notes' '
test_expect_success 'remove note with add -f -F /dev/null' '
git notes add -f -F /dev/null &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-rm-F <<-EOF &&
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -356,14 +365,16 @@ test_expect_success 'create note with combination of -m and -F' '
test_expect_success 'remove note with "git notes remove"' '
git notes remove HEAD^ &&
git notes remove &&
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect-rm-remove <<-EOF &&
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
${indent}5th
- commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:16:13 2005 -0700
@@ -459,9 +470,11 @@ test_expect_success 'removing with --stdin --ignore-missing' '
'
test_expect_success 'list notes with "git notes list"' '
- cat >expect <<-EOF &&
- c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
- c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit_2=$(git rev-parse 2nd) &&
+ commit_3=$(git rev-parse 3rd) &&
+ 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
EOF
git notes list >actual &&
test_cmp expect actual
@@ -474,7 +487,7 @@ test_expect_success 'list notes with "git notes"' '
test_expect_success 'list specific note with "git notes list <object>"' '
cat >expect <<-EOF &&
- c18dc024e14f08d18d14eea0d747ff692d66d6a3
+ $(git rev-parse refs/notes/commits:$commit_3)
EOF
git notes list HEAD^^ >actual &&
test_cmp expect actual
@@ -498,10 +511,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"' '
- cat >expect_list <<-EOF &&
- c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
- 4b6ad22357cc8a1296720574b8d2fbc22fab0671 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
- c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+ commit_5=$(git rev-parse 5th) &&
+ 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
EOF
git notes list >actual &&
test_cmp expect_list actual
@@ -531,8 +545,9 @@ test_expect_success 'appending empty string to non-existing note does not create
test_expect_success 'create other note on a different notes ref (setup)' '
test_commit 6th &&
GIT_NOTES_REF="refs/notes/other" git notes add -m "other note" &&
+ commit=$(git rev-parse HEAD) &&
cat >expect-not-other <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -569,8 +584,10 @@ test_expect_success 'Do not show note when core.notesRef is overridden' '
'
test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect-both <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -582,7 +599,7 @@ test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
Notes (other):
${indent}other note
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -616,8 +633,9 @@ test_expect_success 'notes.displayRef can be given more than once' '
'
test_expect_success 'notes.displayRef respects order' '
+ commit=$(git rev-parse HEAD) &&
cat >expect-both-reversed <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -642,14 +660,16 @@ test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
'
test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect-none <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
${indent}6th
- commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:17:13 2005 -0700
@@ -666,8 +686,9 @@ test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
'
test_expect_success '--no-standard-notes' '
+ commit=$(git rev-parse HEAD) &&
cat >expect-commits <<-EOF &&
- commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:18:13 2005 -0700
@@ -712,8 +733,10 @@ test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
'
test_expect_success 'create note from other note with "git notes add -C"' '
+ test_commit 7th &&
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit fb01e0ca8c33b6cc0c6451dde747f97df567cb5c
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:19:13 2005 -0700
@@ -722,7 +745,6 @@ test_expect_success 'create note from other note with "git notes add -C"' '
Notes:
${indent}order test
EOF
- test_commit 7th &&
git notes add -C $(git notes list HEAD^) &&
git log -1 >actual &&
test_cmp expect actual &&
@@ -744,8 +766,9 @@ test_expect_success 'create note from non-blob with "git notes add -C" fails' '
'
test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 9a4c31c7f722b5d517e92c64e932dd751e1413bf
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:20:13 2005 -0700
@@ -762,8 +785,10 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i
'
test_expect_success 'create note from other note with "git notes add -c"' '
+ test_commit 9th &&
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:21:13 2005 -0700
@@ -772,7 +797,6 @@ test_expect_success 'create note from other note with "git notes add -c"' '
Notes:
${indent}yet another note
EOF
- test_commit 9th &&
MSG="yet another note" git notes add -c $(git notes list HEAD^^) &&
git log -1 >actual &&
test_cmp expect actual
@@ -785,8 +809,9 @@ test_expect_success 'create note from non-existing note with "git notes add -c"
'
test_expect_success 'append to note from other note with "git notes append -C"' '
+ commit=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:21:13 2005 -0700
@@ -803,8 +828,9 @@ test_expect_success 'append to note from other note with "git notes append -C"'
'
test_expect_success 'create note from other note with "git notes append -c"' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:22:13 2005 -0700
@@ -819,8 +845,9 @@ test_expect_success 'create note from other note with "git notes append -c"' '
'
test_expect_success 'append to note from other note with "git notes append -c"' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:22:13 2005 -0700
@@ -837,8 +864,10 @@ test_expect_success 'append to note from other note with "git notes append -c"'
'
test_expect_success 'copy note with "git notes copy"' '
+ test_commit 11th &&
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:23:13 2005 -0700
@@ -849,7 +878,6 @@ test_expect_success 'copy note with "git notes copy"' '
${indent}
${indent}yet another note
EOF
- test_commit 11th &&
git notes copy HEAD^ HEAD &&
git log -1 >actual &&
test_cmp expect actual &&
@@ -864,8 +892,9 @@ test_expect_success 'prevent overwrite with "git notes copy"' '
'
test_expect_success 'allow overwrite with "git notes copy -f"' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:23:13 2005 -0700
@@ -889,8 +918,10 @@ test_expect_success 'cannot copy note from object without notes' '
'
test_expect_success 'git notes copy --stdin' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit e871aa61182b1d95d0a6fb75445d891722863b6b
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:25:13 2005 -0700
@@ -901,7 +932,7 @@ test_expect_success 'git notes copy --stdin' '
${indent}
${indent}yet another note
- commit 65e263ded02ae4e8839bc151095113737579dc12
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:24:13 2005 -0700
@@ -922,21 +953,23 @@ test_expect_success 'git notes copy --stdin' '
'
test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
+ test_commit 14th &&
+ test_commit 15th &&
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
${indent}15th
- commit 07c85d77059393ed0154b8c96906547a59dfcddd
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:26:13 2005 -0700
${indent}14th
EOF
- test_commit 14th &&
- test_commit 15th &&
(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
git notes copy --for-rewrite=foo &&
@@ -945,8 +978,10 @@ test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
'
test_expect_success 'git notes copy --for-rewrite (enabled)' '
+ commit=$(git rev-parse HEAD) &&
+ parent=$(git rev-parse HEAD^) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -957,7 +992,7 @@ test_expect_success 'git notes copy --for-rewrite (enabled)' '
${indent}
${indent}yet another note
- commit 07c85d77059393ed0154b8c96906547a59dfcddd
+ commit $parent
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:26:13 2005 -0700
@@ -986,8 +1021,9 @@ test_expect_success 'git notes copy --for-rewrite (disabled)' '
'
test_expect_success 'git notes copy --for-rewrite (overwrite)' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1015,8 +1051,9 @@ test_expect_success 'git notes copy --for-rewrite (ignore)' '
'
test_expect_success 'git notes copy --for-rewrite (append)' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1037,8 +1074,9 @@ test_expect_success 'git notes copy --for-rewrite (append)' '
'
test_expect_success 'git notes copy --for-rewrite (append two to one)' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1075,8 +1113,9 @@ test_expect_success 'git notes copy --for-rewrite (append empty)' '
'
test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
@@ -1095,8 +1134,9 @@ test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
'
test_expect_success 'GIT_NOTES_REWRITE_REF works' '
+ commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
- commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+ commit $commit
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:27:13 2005 -0700
diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh
index 54460beec4..831f83d211 100755
--- a/t/t3305-notes-fanout.sh
+++ b/t/t3305-notes-fanout.sh
@@ -35,15 +35,10 @@ test_expect_success 'many notes created with git-notes triggers fanout' '
git ls-tree -r --name-only refs/notes/commits |
while read path
do
- case "$path" in
- ??/??????????????????????????????????????)
- : true
- ;;
- *)
+ echo $path | grep "^../[0-9a-f]*$" || {
echo "Invalid path \"$path\"" &&
- return 1
- ;;
- esac
+ return 1;
+ }
done
'
@@ -77,15 +72,10 @@ test_expect_success 'deleting most notes triggers fanout consolidation' '
git ls-tree -r --name-only refs/notes/commits |
while read path
do
- case "$path" in
- ????????????????????????????????????????)
- : true
- ;;
- *)
+ echo $path | grep -v "^../.*" || {
echo "Invalid path \"$path\"" &&
- return 1
- ;;
- esac
+ return 1;
+ }
done
'
diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh
index 61748088eb..8f4102ff9e 100755
--- a/t/t3306-notes-prune.sh
+++ b/t/t3306-notes-prune.sh
@@ -11,23 +11,26 @@ test_expect_success 'setup: create a few commits with notes' '
test_tick &&
git commit -m 1st &&
git notes add -m "Note #1" &&
+ first=$(git rev-parse HEAD) &&
: > file2 &&
git add file2 &&
test_tick &&
git commit -m 2nd &&
git notes add -m "Note #2" &&
+ second=$(git rev-parse HEAD) &&
: > file3 &&
git add file3 &&
test_tick &&
git commit -m 3rd &&
- COMMIT_FILE=.git/objects/5e/e1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+ third=$(git rev-parse HEAD) &&
+ COMMIT_FILE=$(echo $third | sed "s!^..!.git/objects/&/!") &&
test -f $COMMIT_FILE &&
test-tool chmtime =+0 $COMMIT_FILE &&
git notes add -m "Note #3"
'
cat > expect <<END_OF_LOG
-commit 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
+commit $third
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:15:13 2005 -0700
@@ -36,7 +39,7 @@ Date: Thu Apr 7 15:15:13 2005 -0700
Notes:
Note #3
-commit 08341ad9e94faa089d60fd3f523affb25c6da189
+commit $second
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:14:13 2005 -0700
@@ -45,7 +48,7 @@ Date: Thu Apr 7 15:14:13 2005 -0700
Notes:
Note #2
-commit ab5f302035f2e7aaf04265f08b42034c23256e1f
+commit $first
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:13:13 2005 -0700
@@ -70,16 +73,16 @@ test_expect_success 'remove some commits' '
test_expect_success 'verify that commits are gone' '
- test_must_fail git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f
+ test_must_fail git cat-file -p $third &&
+ git cat-file -p $second &&
+ git cat-file -p $first
'
test_expect_success 'verify that notes are still present' '
- git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+ git notes show $third &&
+ git notes show $second &&
+ git notes show $first
'
test_expect_success 'prune -n does not remove notes' '
@@ -90,13 +93,10 @@ test_expect_success 'prune -n does not remove notes' '
test_cmp expect actual
'
-cat > expect <<EOF
-5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
-EOF
test_expect_success 'prune -n lists prunable notes' '
-
+ echo $third >expect &&
git notes prune -n > actual &&
test_cmp expect actual
'
@@ -109,9 +109,9 @@ test_expect_success 'prune notes' '
test_expect_success 'verify that notes are gone' '
- test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+ test_must_fail git notes show $third &&
+ git notes show $second &&
+ git notes show $first
'
test_expect_success 'remove some commits' '
@@ -121,21 +121,18 @@ test_expect_success 'remove some commits' '
git gc --prune=now
'
-cat > expect <<EOF
-08341ad9e94faa089d60fd3f523affb25c6da189
-EOF
-
test_expect_success 'prune -v notes' '
+ echo $second >expect &&
git notes prune -v > actual &&
test_cmp expect actual
'
test_expect_success 'verify that notes are gone' '
- test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
- test_must_fail git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
- git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+ test_must_fail git notes show $third &&
+ test_must_fail git notes show $second &&
+ git notes show $first
'
test_done
diff --git a/t/t3311-notes-merge-fanout.sh b/t/t3311-notes-merge-fanout.sh
index 93516ef67c..37151a3adc 100755
--- a/t/t3311-notes-merge-fanout.sh
+++ b/t/t3311-notes-merge-fanout.sh
@@ -114,12 +114,12 @@ cp expect_log_x expect_log_y
test_expect_success 'Add a few hundred commits w/notes to trigger fanout (x -> y)' '
git update-ref refs/notes/y refs/notes/x &&
git config core.notesRef refs/notes/y &&
- i=5 &&
- while test $i -lt $num
+ test_commit_bulk --start=6 --id=commit $((num - 5)) &&
+ i=0 &&
+ while test $i -lt $((num - 5))
do
- i=$(($i + 1)) &&
- test_commit "commit$i" >/dev/null &&
- git notes add -m "notes for commit$i" || return 1
+ git notes add -m "notes for commit$i" HEAD~$i || return 1
+ i=$((i + 1))
done &&
test "$(git rev-parse refs/notes/y)" != "$(git rev-parse refs/notes/x)" &&
# Expected number of commits and notes
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 80b23fd326..ab18ac5f28 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -295,12 +295,48 @@ test_expect_success 'rebase --am and --show-current-patch' '
echo two >>init.t &&
git commit -a -m two &&
git tag two &&
- test_must_fail git rebase --onto init HEAD^ &&
+ test_must_fail git rebase -f --onto init HEAD^ &&
GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&
grep "show.*$(git rev-parse two)" stderr
)
'
+test_expect_success 'rebase --am and .gitattributes' '
+ test_create_repo attributes &&
+ (
+ cd attributes &&
+ test_commit init &&
+ git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
+ git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
+
+ test_commit second &&
+ git checkout -b test HEAD^ &&
+
+ echo "*.txt filter=test" >.gitattributes &&
+ git add .gitattributes &&
+ test_commit third &&
+
+ echo "This text is smudged." >a.txt &&
+ git add a.txt &&
+ test_commit fourth &&
+
+ git checkout -b removal HEAD^ &&
+ git rm .gitattributes &&
+ git add -u &&
+ test_commit fifth &&
+ git cherry-pick test &&
+
+ git checkout test &&
+ git rebase master &&
+ grep "smudged" a.txt &&
+
+ git checkout removal &&
+ git reset --hard &&
+ git rebase master &&
+ grep "clean" a.txt
+ )
+'
+
test_expect_success 'rebase--merge.sh and --show-current-patch' '
test_create_repo conflict-merge &&
(
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 461dd539ff..d2dfbe46b9 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -29,9 +29,6 @@ Initial setup:
. "$TEST_DIRECTORY"/lib-rebase.sh
-# WARNING: Modifications to the initial repository can change the SHA ID used
-# in the expect2 file for the 'stop on conflicting pick' test.
-
test_expect_success 'setup' '
test_commit A file1 &&
test_commit B file1 &&
@@ -155,8 +152,6 @@ test_expect_success 'rebase -x with empty command fails' '
test_i18ncmp expected actual
'
-LF='
-'
test_expect_success 'rebase -x with newline in command fails' '
test_when_finished "git rebase --abort ||:" &&
test_must_fail env git rebase -x "a${LF}b" @ 2>actual &&
@@ -233,25 +228,28 @@ test_expect_success 'exchange two commits' '
set_fake_editor &&
FAKE_LINES="2 1" git rebase -i HEAD~2 &&
test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
- test G = $(git cat-file commit HEAD | sed -ne \$p)
+ test G = $(git cat-file commit HEAD | sed -ne \$p) &&
+ blob1=$(git rev-parse --short HEAD^:file1) &&
+ blob2=$(git rev-parse --short HEAD:file1) &&
+ commit=$(git rev-parse --short HEAD)
'
test_expect_success 'stop on conflicting pick' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
diff --git a/file1 b/file1
- index f70f10e..fd79235 100644
+ index $blob1..$blob2 100644
--- a/file1
+++ b/file1
@@ -1 +1 @@
-A
+G
EOF
- cat >expect2 <<-\EOF &&
+ cat >expect2 <<-EOF &&
<<<<<<< HEAD
D
=======
G
- >>>>>>> 5d18e54... G
+ >>>>>>> $commit... G
EOF
git tag new-branch1 &&
set_fake_editor &&
@@ -1003,7 +1001,7 @@ test_expect_success 'rebase -i --root temporary sentinel commit' '
git checkout B &&
set_fake_editor &&
test_must_fail env FAKE_LINES="2" git rebase -i --root &&
- git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
+ git cat-file commit HEAD | grep "^tree $EMPTY_TREE" &&
git rebase --abort
'
@@ -1016,9 +1014,9 @@ test_expect_success 'rebase -i --root fixup root commit' '
test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
'
-test_expect_success 'rebase -i --root reword root commit' '
+test_expect_success 'rebase -i --root reword original root commit' '
test_when_finished "test_might_fail git rebase --abort" &&
- git checkout -b reword-root-branch master &&
+ 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 &&
@@ -1026,6 +1024,16 @@ test_expect_success 'rebase -i --root reword root commit' '
test -z "$(git show -s --format=%p HEAD^)"
'
+test_expect_success 'rebase -i --root reword new root commit' '
+ test_when_finished "test_might_fail git rebase --abort" &&
+ git checkout -b reword-now-root-branch master &&
+ set_fake_editor &&
+ FAKE_LINES="reword 3 1" FAKE_COMMIT_MESSAGE="C changed" \
+ git rebase -i --root &&
+ git show HEAD^ | grep "C changed" &&
+ test -z "$(git show -s --format=%p HEAD^)"
+'
+
test_expect_success 'rebase -i --root when root has untracked file conflict' '
test_when_finished "reset_rebase" &&
git checkout -b failing-root-pick A &&
@@ -1054,11 +1062,11 @@ test_expect_success 'rebase -i --root reword root when root has untracked file c
'
test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' '
- git checkout reword-root-branch &&
+ git checkout reword-original-root-branch &&
git reset --hard &&
git checkout conflict-branch &&
set_fake_editor &&
- test_must_fail git rebase --onto HEAD~2 HEAD~ &&
+ test_must_fail git rebase -f --onto HEAD~2 HEAD~ &&
test_must_fail git rebase --edit-todo &&
git rebase --abort
'
@@ -1161,7 +1169,7 @@ test_expect_success 'rebase -i error on commits with \ in message' '
test_expect_code 1 grep " emp" error
'
-test_expect_success 'short SHA-1 setup' '
+test_expect_success SHA1 'short SHA-1 setup' '
test_when_finished "git checkout master" &&
git checkout --orphan collide &&
git rm -rf . &&
@@ -1173,7 +1181,7 @@ test_expect_success 'short SHA-1 setup' '
)
'
-test_expect_success 'short SHA-1 collide' '
+test_expect_success SHA1 'short SHA-1 collide' '
test_when_finished "reset_rebase && git checkout master" &&
git checkout collide &&
(
@@ -1419,7 +1427,6 @@ test_expect_success 'editor saves as CR/LF' '
)
'
-SQ="'"
test_expect_success 'rebase -i --gpg-sign=<key-id>' '
test_when_finished "test_might_fail git rebase --abort" &&
set_fake_editor &&
diff --git a/t/t3416-rebase-onto-threedots.sh b/t/t3416-rebase-onto-threedots.sh
index ddf2f64853..9c2548423b 100755
--- a/t/t3416-rebase-onto-threedots.sh
+++ b/t/t3416-rebase-onto-threedots.sh
@@ -99,7 +99,64 @@ test_expect_success 'rebase -i --onto master...side' '
git checkout side &&
git reset --hard K &&
+ set_fake_editor &&
test_must_fail git rebase -i --onto master...side J
'
+test_expect_success 'rebase --keep-base --onto incompatible' '
+ test_must_fail git rebase --keep-base --onto master...
+'
+
+test_expect_success 'rebase --keep-base --root incompatible' '
+ test_must_fail git rebase --keep-base --root
+'
+
+test_expect_success 'rebase --keep-base master from topic' '
+ git reset --hard &&
+ git checkout topic &&
+ git reset --hard G &&
+
+ git rebase --keep-base master &&
+ git rev-parse C >base.expect &&
+ git merge-base master HEAD >base.actual &&
+ test_cmp base.expect base.actual &&
+
+ git rev-parse HEAD~2 >actual &&
+ git rev-parse C^0 >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --keep-base master from side' '
+ git reset --hard &&
+ git checkout side &&
+ git reset --hard K &&
+
+ test_must_fail git rebase --keep-base master
+'
+
+test_expect_success 'rebase -i --keep-base master from topic' '
+ git reset --hard &&
+ git checkout topic &&
+ git reset --hard G &&
+
+ set_fake_editor &&
+ EXPECT_COUNT=2 git rebase -i --keep-base master &&
+ git rev-parse C >base.expect &&
+ git merge-base master HEAD >base.actual &&
+ test_cmp base.expect base.actual &&
+
+ git rev-parse HEAD~2 >actual &&
+ git rev-parse C^0 >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase -i --keep-base master from side' '
+ git reset --hard &&
+ git checkout side &&
+ git reset --hard K &&
+
+ set_fake_editor &&
+ test_must_fail git rebase -i --keep-base master
+'
+
test_done
diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
index 4eff14dae5..7a2da972fd 100755
--- a/t/t3418-rebase-continue.sh
+++ b/t/t3418-rebase-continue.sh
@@ -120,6 +120,20 @@ test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '
git rebase --continue
'
+test_expect_success 'rebase -r passes merge strategy options correctly' '
+ rm -fr .git/rebase-* &&
+ git reset --hard commit-new-file-F3-on-topic-branch &&
+ test_commit merge-theirs &&
+ git reset --hard HEAD^ &&
+ test_commit some-other-commit &&
+ test_tick &&
+ git merge --no-ff merge-theirs &&
+ FAKE_LINES="1 3 edit 4 5 7 8 9" git rebase -i -f -r -m \
+ -s recursive --strategy-option=theirs HEAD~2 &&
+ test_commit force-change-ours &&
+ git rebase --continue
+'
+
test_expect_success '--skip after failed fixup cleans commit message' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout -b with-conflicting-fixup &&
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index b8f4d03467..5f7e73cf83 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -37,7 +37,6 @@ test_expect_success setup '
create_expected_success_am () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
First, rewinding head to replay your work on top of it...
Applying: second commit
Applying: third commit
@@ -48,7 +47,6 @@ create_expected_success_am () {
create_expected_success_interactive () {
q_to_cr >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
Applied autostash.
Successfully rebased and updated refs/heads/rebased-feature-branch.
EOF
@@ -57,7 +55,6 @@ create_expected_success_interactive () {
create_expected_failure_am () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
First, rewinding head to replay your work on top of it...
Applying: second commit
Applying: third commit
@@ -70,7 +67,6 @@ create_expected_failure_am () {
create_expected_failure_interactive () {
cat >expected <<-EOF
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
- HEAD is now at $(git rev-parse --short feature-branch) third commit
Applying autostash resulted in conflicts.
Your changes are safe in the stash.
You can run "git stash pop" or "git stash drop" at any time.
@@ -306,4 +302,12 @@ test_expect_success 'branch is left alone when possible' '
test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
'
+test_expect_success 'never change active branch' '
+ git checkout -b not-the-feature-branch unrelated-onto-branch &&
+ test_when_finished "git reset --hard && git checkout master" &&
+ echo changed >file0 &&
+ git rebase --autostash not-the-feature-branch feature-branch &&
+ test_cmp_rev not-the-feature-branch unrelated-onto-branch
+'
+
test_done
diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh
index 7274dca40b..b847064f91 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -31,6 +31,16 @@ test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
+test_expect_success 'setup branches and remote tracking' '
+ git tag -l >tags &&
+ for tag in $(cat tags)
+ do
+ git branch branch-$tag $tag || return 1
+ done &&
+ git remote add origin "file://$PWD" &&
+ git fetch origin
+'
+
test_run_rebase () {
result=$1
shift
@@ -57,6 +67,7 @@ test_run_rebase () {
"
}
test_run_rebase success ''
+test_run_rebase success --fork-point
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase failure -p
@@ -64,6 +75,23 @@ test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
shift
+ test_expect_$result "rebase $* -f rewrites even if remote upstream is an ancestor" "
+ reset_rebase &&
+ git rebase $* -f branch-b branch-e &&
+ ! test_cmp_rev branch-e origin/branch-e &&
+ test_cmp_rev branch-b HEAD~2 &&
+ test_linear_range 'd e' branch-b..
+ "
+}
+test_run_rebase success ''
+test_run_rebase success --fork-point
+test_run_rebase success -m
+test_run_rebase success -i
+test_have_prereq !REBASE_P || test_run_rebase success -p
+
+test_run_rebase () {
+ result=$1
+ shift
test_expect_$result "rebase $* fast-forwards from ancestor of upstream" "
reset_rebase &&
git rebase $* e b &&
@@ -71,6 +99,7 @@ test_run_rebase () {
"
}
test_run_rebase success ''
+test_run_rebase success --fork-point
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh
index a5868ea152..50e7960702 100755
--- a/t/t3422-rebase-incompatible-options.sh
+++ b/t/t3422-rebase-incompatible-options.sh
@@ -76,14 +76,4 @@ test_expect_success REBASE_P \
test_must_fail git rebase --preserve-merges --rebase-merges A
'
-test_expect_success '--rebase-merges incompatible with --strategy' '
- git checkout B^0 &&
- test_must_fail git rebase --rebase-merges -s resolve A
-'
-
-test_expect_success '--rebase-merges incompatible with --strategy-option' '
- git checkout B^0 &&
- test_must_fail git rebase --rebase-merges -Xignore-space-change A
-'
-
test_done
diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh
index d8640522a0..bec48e6a1f 100755
--- a/t/t3427-rebase-subtree.sh
+++ b/t/t3427-rebase-subtree.sh
@@ -11,113 +11,99 @@ commit_message() {
git log --pretty=format:%s -1 "$1"
}
+# There are a few bugs in the rebase with regards to the subtree strategy, and
+# this test script tries to document them. First, the following commit history
+# is generated (the onelines are shown, time flows from left to right):
+#
+# master1 - master2 - master3
+# \
+# README ---------------------- Add subproject master - master4 - files_subtree/master5
+#
+# Where the merge moves the files master[123].t into the subdirectory
+# files_subtree/ and master4 as well as files_subtree/master5 add files to that
+# directory directly.
+#
+# Then, in subsequent test cases, `git filter-branch` is used to distill just
+# the commits that touch files_subtree/. To give it a final pre-rebase touch,
+# an empty commit is added on top. The pre-rebase commit history looks like
+# this:
+#
+# Add subproject master - master4 - files_subtree/master5 - Empty commit
+#
+# where the root commit adds three files: master1.t, master2.t and master3.t.
+#
+# This commit history is then rebased onto `master3` with the
+# `-Xsubtree=files_subtree` option in three different ways:
+#
+# 1. using `--preserve-merges`
+# 2. using `--preserve-merges` and --keep-empty
+# 3. without specifying a rebase backend
+
test_expect_success 'setup' '
test_commit README &&
- mkdir files &&
- (
- cd files &&
- git init &&
- test_commit master1 &&
- test_commit master2 &&
- test_commit master3
- ) &&
- git fetch files master &&
- git branch files-master FETCH_HEAD &&
- git read-tree --prefix=files_subtree files-master &&
- git checkout -- files_subtree &&
- tree=$(git write-tree) &&
- head=$(git rev-parse HEAD) &&
- rev=$(git rev-parse --verify files-master^0) &&
- commit=$(git commit-tree -p $head -p $rev -m "Add subproject master" $tree) &&
- git update-ref HEAD $commit &&
- (
- cd files_subtree &&
- test_commit master4
- ) &&
- test_commit files_subtree/master5
-'
-# FAILURE: Does not preserve master4.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --preserve-merges --onto commit 4' '
- reset_rebase &&
- git checkout -b rebase-preserve-merges-4 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&
- verbose test "$(commit_message HEAD~)" = "files_subtree/master4"
+ git init files &&
+ test_commit -C files master1 &&
+ test_commit -C files master2 &&
+ test_commit -C files master3 &&
+
+ : perform subtree merge into files_subtree/ &&
+ git fetch files refs/heads/master:refs/heads/files-master &&
+ git merge -s ours --no-commit --allow-unrelated-histories \
+ files-master &&
+ git read-tree --prefix=files_subtree -u files-master &&
+ git commit -m "Add subproject master" &&
+
+ : add two extra commits to rebase &&
+ test_commit -C files_subtree master4 &&
+ test_commit files_subtree/master5 &&
+
+ git checkout -b to-rebase &&
+ git fast-export --no-data HEAD -- files_subtree/ |
+ sed -e "s%\([0-9a-f]\{40\} \)files_subtree/%\1%" |
+ git fast-import --force --quiet &&
+ git reset --hard &&
+ git commit -m "Empty commit" --allow-empty
'
-# FAILURE: Does not preserve master5.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --preserve-merges --onto commit 5' '
+# FAILURE: Does not preserve master4.
+test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '
reset_rebase &&
- git checkout -b rebase-preserve-merges-5 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
+ git checkout -b rebase-preserve-merges to-rebase &&
git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&
+ verbose test "$(commit_message HEAD~)" = "master4" &&
verbose test "$(commit_message HEAD)" = "files_subtree/master5"
'
# FAILURE: Does not preserve master4.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '
- reset_rebase &&
- git checkout -b rebase-keep-empty-4 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
- verbose test "$(commit_message HEAD~2)" = "files_subtree/master4"
-'
-
-# FAILURE: Does not preserve master5.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '
- reset_rebase &&
- git checkout -b rebase-keep-empty-5 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
- verbose test "$(commit_message HEAD~)" = "files_subtree/master5"
-'
-
-# FAILURE: Does not preserve Empty.
-test_expect_failure REBASE_P \
- 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '
+test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '
reset_rebase &&
- git checkout -b rebase-keep-empty-empty master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
+ git checkout -b rebase-keep-empty to-rebase &&
git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
verbose test "$(commit_message HEAD)" = "Empty commit"
'
-# FAILURE: fatal: Could not parse object
-test_expect_failure 'Rebase -Xsubtree --onto commit 4' '
+test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '
reset_rebase &&
- git checkout -b rebase-onto-4 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --onto files-master master &&
- verbose test "$(commit_message HEAD~2)" = "files_subtree/master4"
+ git checkout -b rebase-onto to-rebase &&
+ test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&
+ : first pick results in no changes &&
+ git rebase --continue &&
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
+ verbose test "$(commit_message HEAD)" = "Empty commit"
'
-# FAILURE: fatal: Could not parse object
-test_expect_failure 'Rebase -Xsubtree --onto commit 5' '
- reset_rebase &&
- git checkout -b rebase-onto-5 master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --onto files-master master &&
- verbose test "$(commit_message HEAD~)" = "files_subtree/master5"
-'
-# FAILURE: fatal: Could not parse object
-test_expect_failure 'Rebase -Xsubtree --onto empty commit' '
+test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' '
reset_rebase &&
- git checkout -b rebase-onto-empty master &&
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
- git commit -m "Empty commit" --allow-empty &&
- git rebase -Xsubtree=files_subtree --onto files-master master &&
+ git checkout -b rebase-merges-onto to-rebase &&
+ test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root &&
+ : first pick results in no changes &&
+ git rebase --continue &&
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
verbose test "$(commit_message HEAD)" = "Empty commit"
'
diff --git a/t/t3429-rebase-edit-todo.sh b/t/t3429-rebase-edit-todo.sh
index 76f6d306ea..8739cb60a7 100755
--- a/t/t3429-rebase-edit-todo.sh
+++ b/t/t3429-rebase-edit-todo.sh
@@ -3,9 +3,15 @@
test_description='rebase should reread the todo file if an exec modifies it'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+test_expect_success 'setup' '
+ test_commit first file &&
+ test_commit second file &&
+ test_commit third file
+'
test_expect_success 'rebase exec modifies rebase-todo' '
- test_commit initial &&
todo=.git/rebase-merge/git-rebase-todo &&
git rebase HEAD -x "echo exec touch F >>$todo" &&
test -e F
@@ -33,4 +39,17 @@ test_expect_success SHA1 'loose object cache vs re-reading todo list' '
git rebase HEAD -x "./append-todo.sh 5 6"
'
+test_expect_success 'todo is re-read after reword and squash' '
+ write_script reword-editor.sh <<-\EOS &&
+ GIT_SEQUENCE_EDITOR="echo \"exec echo $(cat file) >>actual\" >>" \
+ git rebase --edit-todo
+ EOS
+
+ test_write_lines first third >expected &&
+ set_fake_editor &&
+ GIT_SEQUENCE_EDITOR="$EDITOR" FAKE_LINES="reword 1 squash 2 fixup 3" \
+ GIT_EDITOR=./reword-editor.sh git rebase -i --root third &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 7b6c4847ad..9efcf4808a 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -37,20 +37,27 @@ test_expect_success 'setup' '
test_commit A &&
git checkout -b first &&
test_commit B &&
+ b=$(git rev-parse --short HEAD) &&
git checkout master &&
test_commit C &&
+ c=$(git rev-parse --short HEAD) &&
test_commit D &&
+ d=$(git rev-parse --short HEAD) &&
git merge --no-commit B &&
test_tick &&
git commit -m E &&
git tag -m E E &&
+ e=$(git rev-parse --short HEAD) &&
git checkout -b second C &&
test_commit F &&
+ f=$(git rev-parse --short HEAD) &&
test_commit G &&
+ g=$(git rev-parse --short HEAD) &&
git checkout master &&
git merge --no-commit G &&
test_tick &&
git commit -m H &&
+ h=$(git rev-parse --short HEAD) &&
git tag -m H H &&
git checkout A &&
test_commit conflicting-G G.t
@@ -93,24 +100,24 @@ test_expect_success 'create completely different structure' '
'
test_expect_success 'generate correct todo list' '
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
label onto
reset onto
- pick d9df450 B
+ pick $b B
label E
reset onto
- pick 5dee784 C
+ pick $c C
label branch-point
- pick ca2c861 F
- pick 088b00a G
+ pick $f F
+ pick $g G
label H
reset branch-point # C
- pick 12bd07b D
- merge -C 2051b56 E # E
- merge -C 233d48a H # H
+ pick $d D
+ merge -C $e E # E
+ merge -C $h H # H
EOF
@@ -151,7 +158,6 @@ test_expect_success 'failed `merge -C` writes patch (may be rescheduled, too)' '
test_path_is_file .git/rebase-merge/patch
'
-SQ="'"
test_expect_success 'failed `merge <branch>` does not crash' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout conflicting-G &&
@@ -441,4 +447,25 @@ test_expect_success '--continue after resolving conflicts after a merge' '
test_path_is_missing .git/MERGE_HEAD
'
+test_expect_success '--rebase-merges with strategies' '
+ git checkout -b with-a-strategy F &&
+ test_tick &&
+ git merge -m "Merge conflicting-G" conflicting-G &&
+
+ : first, test with a merge strategy option &&
+ git rebase -ir -Xtheirs G &&
+ echo conflicting-G >expect &&
+ test_cmp expect G.t &&
+
+ : now, try with a merge strategy other than recursive &&
+ git reset --hard @{1} &&
+ write_script git-merge-override <<-\EOF &&
+ echo overridden$1 >>G.t
+ git add G.t
+ EOF
+ PATH="$PWD:$PATH" git rebase -ir -s override -Xxopt G &&
+ test_write_lines G overridden--xopt >expect &&
+ test_cmp expect G.t
+'
+
test_done
diff --git a/t/t3431-rebase-fork-point.sh b/t/t3431-rebase-fork-point.sh
new file mode 100755
index 0000000000..78851b9a2a
--- /dev/null
+++ b/t/t3431-rebase-fork-point.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='git rebase --fork-point test'
+
+. ./test-lib.sh
+
+# A---B---D---E (master)
+# \
+# C*---F---G (side)
+#
+# C was formerly part of master but master was rewound to remove C
+#
+test_expect_success setup '
+ test_commit A &&
+ test_commit B &&
+ test_commit C &&
+ git branch -t side &&
+ git reset --hard HEAD^ &&
+ test_commit D &&
+ test_commit E &&
+ git checkout side &&
+ test_commit F &&
+ test_commit G
+'
+
+test_rebase () {
+ expected="$1" &&
+ shift &&
+ test_expect_success "git rebase $*" "
+ git checkout master &&
+ git reset --hard E &&
+ git checkout side &&
+ git reset --hard G &&
+ git rebase $* &&
+ test_write_lines $expected >expect &&
+ git log --pretty=%s >actual &&
+ test_cmp expect actual
+ "
+}
+
+test_rebase 'G F E D B A'
+test_rebase 'G F D B A' --onto D
+test_rebase 'G F B A' --keep-base
+test_rebase 'G F C E D B A' --no-fork-point
+test_rebase 'G F C D B A' --no-fork-point --onto D
+test_rebase 'G F C B A' --no-fork-point --keep-base
+test_rebase 'G F E D B A' --fork-point refs/heads/master
+test_rebase 'G F D B A' --fork-point --onto D refs/heads/master
+test_rebase 'G F B A' --fork-point --keep-base refs/heads/master
+test_rebase 'G F C E D B A' refs/heads/master
+test_rebase 'G F C D B A' --onto D refs/heads/master
+test_rebase 'G F C B A' --keep-base refs/heads/master
+
+test_done
diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh
new file mode 100755
index 0000000000..034ffc7e76
--- /dev/null
+++ b/t/t3432-rebase-fast-forward.sh
@@ -0,0 +1,125 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='ensure rebase fast-forwards commits when possible'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ test_commit A &&
+ test_commit B &&
+ test_commit C &&
+ test_commit D &&
+ git checkout -t -b side
+'
+
+test_rebase_same_head () {
+ status_n="$1" &&
+ shift &&
+ what_n="$1" &&
+ shift &&
+ cmp_n="$1" &&
+ shift &&
+ status_f="$1" &&
+ shift &&
+ what_f="$1" &&
+ shift &&
+ cmp_f="$1" &&
+ shift &&
+ test_rebase_same_head_ $status_n $what_n $cmp_n "" "$*" &&
+ test_rebase_same_head_ $status_f $what_f $cmp_f " --no-ff" "$*"
+}
+
+test_rebase_same_head_ () {
+ status="$1" &&
+ shift &&
+ what="$1" &&
+ shift &&
+ cmp="$1" &&
+ shift &&
+ flag="$1"
+ shift &&
+ test_expect_$status "git rebase$flag $* with $changes is $what with $cmp HEAD" "
+ oldhead=\$(git rev-parse HEAD) &&
+ test_when_finished 'git reset --hard \$oldhead' &&
+ git rebase$flag $* >stdout &&
+ if test $what = work
+ then
+ # Must check this case first, for 'is up to
+ # date, rebase forced[...]rewinding head' cases
+ test_i18ngrep 'rewinding head' stdout
+ elif test $what = noop
+ then
+ test_i18ngrep 'is up to date' stdout &&
+ test_i18ngrep ! 'rebase forced' stdout
+ elif test $what = noop-force
+ then
+ test_i18ngrep 'is up to date, rebase forced' stdout
+ fi &&
+ newhead=\$(git rev-parse HEAD) &&
+ if test $cmp = same
+ then
+ test_cmp_rev \$oldhead \$newhead
+ elif test $cmp = diff
+ then
+ ! test_cmp_rev \$oldhead \$newhead
+ fi
+ "
+}
+
+changes='no changes'
+test_rebase_same_head success noop same success work same
+test_rebase_same_head success noop same success noop-force same master
+test_rebase_same_head success noop same success noop-force diff --onto B B
+test_rebase_same_head success noop same success noop-force diff --onto B... B
+test_rebase_same_head success noop same success noop-force same --onto master... master
+test_rebase_same_head success noop same success noop-force same --keep-base master
+test_rebase_same_head success noop same success noop-force same --keep-base
+test_rebase_same_head success noop same success noop-force same --no-fork-point
+test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point
+test_rebase_same_head success noop same success work same --fork-point master
+test_rebase_same_head success noop same success work diff --fork-point --onto B B
+test_rebase_same_head success noop same success work diff --fork-point --onto B... B
+test_rebase_same_head success noop same success work same --fork-point --onto master... master
+test_rebase_same_head success noop same success work same --keep-base --keep-base master
+
+test_expect_success 'add work same to side' '
+ test_commit E
+'
+
+changes='our changes'
+test_rebase_same_head success noop same success work same
+test_rebase_same_head success noop same success noop-force same master
+test_rebase_same_head success noop same success noop-force diff --onto B B
+test_rebase_same_head success noop same success noop-force diff --onto B... B
+test_rebase_same_head success noop same success noop-force same --onto master... master
+test_rebase_same_head success noop same success noop-force same --keep-base master
+test_rebase_same_head success noop same success noop-force same --keep-base
+test_rebase_same_head success noop same success noop-force same --no-fork-point
+test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point
+test_rebase_same_head success noop same success work same --fork-point master
+test_rebase_same_head success noop same success work diff --fork-point --onto B B
+test_rebase_same_head success noop same success work diff --fork-point --onto B... B
+test_rebase_same_head success noop same success work same --fork-point --onto master... master
+test_rebase_same_head success noop same success work same --fork-point --keep-base master
+
+test_expect_success 'add work same to upstream' '
+ git checkout master &&
+ test_commit F &&
+ git checkout side
+'
+
+changes='our and their changes'
+test_rebase_same_head success noop same success noop-force diff --onto B B
+test_rebase_same_head success noop same success noop-force diff --onto B... B
+test_rebase_same_head success noop same success work diff --onto master... master
+test_rebase_same_head success noop same success work diff --keep-base master
+test_rebase_same_head success noop same success work diff --keep-base
+test_rebase_same_head failure work same success work diff --fork-point --onto B B
+test_rebase_same_head failure work same success work diff --fork-point --onto B... B
+test_rebase_same_head success noop same success work diff --fork-point --onto master... master
+test_rebase_same_head success noop same success work diff --fork-point --keep-base master
+
+test_done
diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index 127dd0082f..9d5adbc130 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -16,7 +16,11 @@ test_expect_success setup '
git add file1 &&
test_tick &&
git commit -m "second" &&
- git tag second
+ git tag second &&
+ test_oid_cache <<-EOF
+ cp_ff sha1:1df192cd8bc58a2b275d842cede4d221ad9000d1
+ cp_ff sha256:e70d6b7fc064bddb516b8d512c9057094b96ce6ff08e12080acc4fe7f1d60a1d
+ EOF
'
test_expect_success 'cherry-pick using --ff fast forwards' '
@@ -102,7 +106,7 @@ test_expect_success 'cherry pick a root commit with --ff' '
git add file2 &&
git commit --amend -m "file2" &&
git cherry-pick --ff first &&
- test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
+ test "$(git rev-parse --verify HEAD)" = "$(test_oid cp_ff)"
'
test_expect_success 'cherry-pick --ff on unborn branch' '
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 85ae7dc1e4..8c8cca5bfb 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -240,18 +240,33 @@ test_expect_success 'refresh index before checking if it is up-to-date' '
'
test_expect_success 'choking "git rm" should not let it die with cruft' '
+ test_oid_init &&
git reset -q --hard &&
test_when_finished "rm -f .git/index.lock && git reset -q --hard" &&
i=0 &&
+ hash=$(test_oid deadbeef) &&
while test $i -lt 12000
do
- echo "100644 1234567890123456789012345678901234567890 0 some-file-$i"
+ echo "100644 $hash 0 some-file-$i"
i=$(( $i + 1 ))
done | git update-index --index-info &&
git rm -n "some-file-*" | : &&
test_path_is_missing .git/index.lock
'
+test_expect_success 'Resolving by removal is not a warning-worthy event' '
+ git reset -q --hard &&
+ test_when_finished "rm -f .git/index.lock msg && git reset -q --hard" &&
+ blob=$(echo blob | git hash-object -w --stdin) &&
+ for stage in 1 2 3
+ do
+ echo "100644 $blob $stage blob"
+ done | git update-index --index-info &&
+ git rm blob >msg 2>&1 &&
+ test_i18ngrep ! "needs merge" msg &&
+ test_must_fail git ls-files -s --error-unmatch blob
+'
+
test_expect_success 'rm removes subdirectories recursively' '
mkdir -p dir/subdir/subsubdir &&
echo content >dir/subdir/subsubdir/file &&
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 69991a3168..d50e165ca8 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -314,7 +314,7 @@ test_expect_success C_LOCALE_OUTPUT 'add first line works' '
git commit -am "clear local changes" &&
git apply patch &&
printf "%s\n" s y y | git add -p file 2>error |
- sed -n -e "s/^Stage this hunk[^@]*\(@@ .*\)/\1/" \
+ sed -n -e "s/^([1-2]\/[1-2]) Stage this hunk[^@]*\(@@ .*\)/\1/" \
-e "/^[-+@ \\\\]"/p >output &&
test_must_be_empty error &&
git diff --cached >diff &&
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 8eb47942e2..64dcc5ec28 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -23,6 +23,7 @@ check_verify_failure () {
# first create a commit, so we have a valid object/type
# for the tag.
test_expect_success 'setup' '
+ test_oid_init &&
echo Hello >A &&
git update-index --add A &&
git commit -m "Initial commit" &&
@@ -69,28 +70,28 @@ check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
# 4. type line label check
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
xxxx tag
tag mytag
tagger . <> 0 +0000
EOF
-check_verify_failure '"type" line label check' '^error: char47: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
############################################################
# 5. type line eol check
-echo "object 779e9b33986b1c2670fff52c5067603117b3e895" >tag.sig
+echo "object $head" >tag.sig
printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
-check_verify_failure '"type" line eol check' '^error: char48: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
############################################################
# 6. tag line label check #1
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
type tag
xxx mytag
tagger . <> 0 +0000
@@ -98,37 +99,37 @@ tagger . <> 0 +0000
EOF
check_verify_failure '"tag" line label check #1' \
- '^error: char57: no "tag " found$'
+ '^error: char.*: no "tag " found$'
############################################################
# 7. tag line label check #2
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
type taggggggggggggggggggggggggggggggg
tag
EOF
check_verify_failure '"tag" line label check #2' \
- '^error: char87: no "tag " found$'
+ '^error: char.*: no "tag " found$'
############################################################
# 8. type line type-name length check
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
type taggggggggggggggggggggggggggggggg
tag mytag
EOF
check_verify_failure '"type" line type-name length check' \
- '^error: char53: type too long$'
+ '^error: char.*: type too long$'
############################################################
# 9. verify object (SHA1/type) check
cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $(test_oid deadbeef)
type tagggg
tag mytag
tagger . <> 0 +0000
@@ -150,7 +151,7 @@ tagger . <> 0 +0000
EOF
check_verify_failure 'verify tag-name check' \
- '^error: char67: could not verify tag name$'
+ '^error: char.*: could not verify tag name$'
############################################################
# 11. tagger line label check #1
@@ -164,7 +165,7 @@ This is filler
EOF
check_verify_failure '"tagger" line label check #1' \
- '^error: char70: could not find "tagger "$'
+ '^error: char.*: could not find "tagger "$'
############################################################
# 12. tagger line label check #2
@@ -179,7 +180,7 @@ This is filler
EOF
check_verify_failure '"tagger" line label check #2' \
- '^error: char70: could not find "tagger "$'
+ '^error: char.*: could not find "tagger "$'
############################################################
# 13. disallow missing tag author name
@@ -194,7 +195,7 @@ This is filler
EOF
check_verify_failure 'disallow missing tag author name' \
- '^error: char77: missing tagger name$'
+ '^error: char.*: missing tagger name$'
############################################################
# 14. disallow missing tag author name
@@ -209,7 +210,7 @@ tagger T A Gger <
EOF
check_verify_failure 'disallow malformed tagger' \
- '^error: char77: malformed tagger field$'
+ '^error: char.*: malformed tagger field$'
############################################################
# 15. allow empty tag email
@@ -238,7 +239,7 @@ tagger T A Gger <tag ger@example.com> 0 +0000
EOF
check_verify_failure 'disallow spaces in tag email' \
- '^error: char77: malformed tagger field$'
+ '^error: char.*: malformed tagger field$'
############################################################
# 17. disallow missing tag timestamp
@@ -252,7 +253,7 @@ tagger T A Gger <tagger@example.com>__
EOF
check_verify_failure 'disallow missing tag timestamp' \
- '^error: char107: missing tag timestamp$'
+ '^error: char.*: missing tag timestamp$'
############################################################
# 18. detect invalid tag timestamp1
@@ -266,7 +267,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
EOF
check_verify_failure 'detect invalid tag timestamp1' \
- '^error: char107: missing tag timestamp$'
+ '^error: char.*: missing tag timestamp$'
############################################################
# 19. detect invalid tag timestamp2
@@ -280,7 +281,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
EOF
check_verify_failure 'detect invalid tag timestamp2' \
- '^error: char111: malformed tag timestamp$'
+ '^error: char.*: malformed tag timestamp$'
############################################################
# 20. detect invalid tag timezone1
@@ -294,7 +295,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
EOF
check_verify_failure 'detect invalid tag timezone1' \
- '^error: char118: malformed tag timezone$'
+ '^error: char.*: malformed tag timezone$'
############################################################
# 21. detect invalid tag timezone2
@@ -308,7 +309,7 @@ tagger T A Gger <tagger@example.com> 1206478233 + 30
EOF
check_verify_failure 'detect invalid tag timezone2' \
- '^error: char118: malformed tag timezone$'
+ '^error: char.*: malformed tag timezone$'
############################################################
# 22. detect invalid tag timezone3
@@ -322,7 +323,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
EOF
check_verify_failure 'detect invalid tag timezone3' \
- '^error: char118: malformed tag timezone$'
+ '^error: char.*: malformed tag timezone$'
############################################################
# 23. detect invalid header entry
@@ -337,7 +338,7 @@ this line should not be here
EOF
check_verify_failure 'detect invalid header entry' \
- '^error: char124: trailing garbage in tag header$'
+ '^error: char.*: trailing garbage in tag header$'
############################################################
# 24. create valid tag
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index b22e671608..580bfbdc23 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -7,6 +7,18 @@ test_description='Test git stash'
. ./test-lib.sh
+diff_cmp () {
+ for i in "$1" "$2"
+ do
+ sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \
+ -e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \
+ -e 's/^index [0-9a-f]*,[0-9a-f]*\.\.[0-9a-f]*/index 1234567,7654321..89abcde/' \
+ "$i" >"$i.compare" || return 1
+ done &&
+ test_cmp "$1.compare" "$2.compare" &&
+ rm -f "$1.compare" "$2.compare"
+}
+
test_expect_success 'stash some dirty working directory' '
echo 1 >file &&
git add file &&
@@ -36,7 +48,7 @@ EOF
test_expect_success 'parents of stash' '
test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
git diff stash^2..stash >output &&
- test_cmp expect output
+ diff_cmp expect output
'
test_expect_success 'applying bogus stash does nothing' '
@@ -210,13 +222,13 @@ test_expect_success 'stash branch' '
test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
test $(git rev-parse HEAD) = $(git rev-parse master^) &&
git diff --cached >output &&
- test_cmp expect output &&
+ diff_cmp expect output &&
git diff >output &&
- test_cmp expect1 output &&
+ diff_cmp expect1 output &&
git add file &&
git commit -m alternate\ second &&
git diff master..stashbranch >output &&
- test_cmp output expect2 &&
+ diff_cmp output expect2 &&
test 0 = $(git stash list | wc -l)
'
@@ -577,7 +589,7 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
+bar
EOF
git stash show -p ${STASH_ID} >actual &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'stash show - no stashes on stack, stash-like argument' '
@@ -609,7 +621,7 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
+foo
EOF
git stash show -p ${STASH_ID} >actual &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'stash show --patience shows diff' '
@@ -627,7 +639,7 @@ test_expect_success 'stash show --patience shows diff' '
+foo
EOF
git stash show --patience ${STASH_ID} >actual &&
- test_cmp expected actual
+ diff_cmp expected actual
'
test_expect_success 'drop: fail early if specified stash is not a stash ref' '
@@ -791,7 +803,7 @@ test_expect_success 'stash where working directory contains "HEAD" file' '
git diff-index --cached --quiet HEAD &&
test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
git diff stash^..stash >output &&
- test_cmp expect output
+ diff_cmp expect output
'
test_expect_success 'store called with invalid commit' '
@@ -847,7 +859,7 @@ test_expect_success 'stash list implies --first-parent -m' '
+working
EOF
git stash list --format=%gd -p >actual &&
- test_cmp expect actual
+ diff_cmp expect actual
'
test_expect_success 'stash list --cc shows combined diff' '
@@ -864,7 +876,7 @@ test_expect_success 'stash list --cc shows combined diff' '
++working
EOF
git stash list --format=%gd -p --cc >actual &&
- test_cmp expect actual
+ diff_cmp expect actual
'
test_expect_success 'stash is not confused by partial renames' '
@@ -1234,4 +1246,27 @@ test_expect_success 'stash works when user.name and user.email are not set' '
)
'
+test_expect_success 'stash --keep-index with file deleted in index does not resurrect it on disk' '
+ test_commit to-remove to-remove &&
+ git rm to-remove &&
+ git stash --keep-index &&
+ test_path_is_missing to-remove
+'
+
+test_expect_success 'stash apply should succeed with unmodified file' '
+ echo base >file &&
+ git add file &&
+ git commit -m base &&
+
+ # now stash a modification
+ echo modified >file &&
+ git stash &&
+
+ # make the file stat dirty
+ cp file other &&
+ mv other file &&
+
+ git stash apply
+'
+
test_done
diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh
index d7219d6f8f..b93d1d74da 100755
--- a/t/t3906-stash-submodule.sh
+++ b/t/t3906-stash-submodule.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='stash apply can handle submodules'
+test_description='stash can handle submodules'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-submodule-update.sh
@@ -21,4 +21,44 @@ KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1
KNOWN_FAILURE_NOFF_MERGE_DOESNT_CREATE_EMPTY_SUBMODULE_DIR=1
test_submodule_switch "git_stash"
+setup_basic () {
+ test_when_finished "rm -rf main sub" &&
+ git init sub &&
+ (
+ cd sub &&
+ test_commit sub_file
+ ) &&
+ git init main &&
+ (
+ cd main &&
+ git submodule add ../sub &&
+ test_commit main_file
+ )
+}
+
+test_expect_success 'stash push with submodule.recurse=true preserves dirty submodule worktree' '
+ setup_basic &&
+ (
+ cd main &&
+ git config submodule.recurse true &&
+ echo "x" >main_file.t &&
+ echo "y" >sub/sub_file.t &&
+ git stash push &&
+ test_must_fail git -C sub diff --quiet
+ )
+'
+
+test_expect_success 'stash push and pop with submodule.recurse=true preserves dirty submodule worktree' '
+ setup_basic &&
+ (
+ cd main &&
+ git config submodule.recurse true &&
+ echo "x" >main_file.t &&
+ echo "y" >sub/sub_file.t &&
+ git stash push &&
+ git stash pop &&
+ test_must_fail git -C sub diff --quiet
+ )
+'
+
test_done
diff --git a/t/t3908-stash-in-worktree.sh b/t/t3908-stash-in-worktree.sh
new file mode 100755
index 0000000000..2b2b366ef9
--- /dev/null
+++ b/t/t3908-stash-in-worktree.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Johannes E Schindelin
+#
+
+test_description='Test git stash in a worktree'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit initial &&
+ git worktree add wt &&
+ test_commit -C wt in-worktree
+'
+
+test_expect_success 'apply in subdirectory' '
+ mkdir wt/subdir &&
+ (
+ cd wt/subdir &&
+ echo modified >../initial.t &&
+ git stash &&
+ git stash apply >out
+ ) &&
+ grep "\.\.\/initial\.t" wt/subdir/out
+'
+
+test_done
diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh
index 8de36b7d12..e5116a76a1 100755
--- a/t/t4000-diff-format.sh
+++ b/t/t4000-diff-format.sh
@@ -78,7 +78,7 @@ test_expect_success 'git diff-files --no-patch --patch shows the patch' '
test_expect_success 'git diff-files --no-patch --patch-with-raw shows the patch and raw data' '
git diff-files --no-patch --patch-with-raw >actual &&
- grep -q "^:100644 100755 .* 0000000000000000000000000000000000000000 M path0\$" actual &&
+ grep -q "^:100644 100755 .* $ZERO_OID M path0\$" actual &&
tail -n +4 actual >actual-patch &&
compare_diff_patch expected actual-patch
'
diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh
index 3a6c21e825..cbcdd10464 100755
--- a/t/t4002-diff-basic.sh
+++ b/t/t4002-diff-basic.sh
@@ -7,123 +7,272 @@ test_description='Test diff raw-output.
'
. ./test-lib.sh
+
. "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh
-cat >.test-plain-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 040000 0000000000000000000000000000000000000000 6d50f65d3bdab91c63444294d38f08aeff328e42 A DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 5e5f22072bb39f6e12cf663a57cb634c76eefb49 M Z
+test_oid_init
+
+test_oid_cache <<\EOF
+aa_1 sha1:ccba72ad3888a3520b39efcf780b9ee64167535d
+aa_1 sha256:9febfbf18197819b2735c45291f138525d2476d59470f98239647544586ba403
+
+aa_2 sha1:6aa2b5335b16431a0ef71e5c0a28be69183cf6a2
+aa_2 sha256:6eaa3437de83f145a4aaa6ba355303075ade547b128ec6a2cd00a81ff7ce7a56
+
+an_1 sha1:7e426fb079479fd67f6d81f984e4ec649a44bc25
+an_1 sha256:8f92a0bec99e399a38e3bd0e1bf19fbf121e0160efb29b857df79d439f1c4536
+
+dd_1 sha1:bcc68ef997017466d5c9094bcf7692295f588c9a
+dd_1 sha256:07e17428b00639b85485d2b01083d219e2f3e3ba8579e9ca44e9cc8dd554d952
+
+df_1 sha1:6d50f65d3bdab91c63444294d38f08aeff328e42
+df_1 sha256:e367cecc27e9bf5451b1c65828cb21938d36a5f8e39c1b03ad6509cc36bb8e9d
+
+df_2 sha1:71420ab81e254145d26d6fc0cddee64c1acd4787
+df_2 sha256:0f0a86d10347ff6921d03a3c954679f3f1d14fa3d5cd82f57b32c09755f3a47d
+
+dfd1 sha1:68a6d8b91da11045cf4aa3a5ab9f2a781c701249
+dfd1 sha256:f3bd3265b02b6978ce86490d8ad026c573639c974b3de1d9faf30d8d5a77d3d5
+
+dm_1 sha1:141c1f1642328e4bc46a7d801a71da392e66791e
+dm_1 sha256:c89f8656e7b94e21ee5fbaf0e2149bbf783c51edbe2ce110349cac13059ee7ed
+
+dm_2 sha1:3c4d8de5fbad08572bab8e10eef8dbb264cf0231
+dm_2 sha256:83a572e37e0c94086294dae2cecc43d9131afd6f6c906e495c78972230b54988
+
+dn_1 sha1:35abde1506ddf806572ff4d407bd06885d0f8ee9
+dn_1 sha256:775d5852582070e620be63327bfa515fab8f71c7ac3e4f0c3cd6267b4377ba28
+
+ll_2 sha1:1d41122ebdd7a640f29d3c9cc4f9d70094374762
+ll_2 sha256:7917b4948a883cfed0a77d3d5a625dc8577d6ddcc3c6c3bbc56c4d4226a2246d
+
+md_1 sha1:03f24c8c4700babccfd28b654e7e8eac402ad6cd
+md_1 sha256:fc9f30369b978595ad685ba11ca9a17de0af16d79cd4b629975f4f1590033902
+
+md_2 sha1:103d9f89b50b9aad03054b579be5e7aa665f2d57
+md_2 sha256:fc78ec75275628762fe520479a6b2398dec295ce7aabcb1d15e5963c7b4e9317
+
+mm_1 sha1:b258508afb7ceb449981bd9d63d2d3e971bf8d34
+mm_1 sha256:a4b7847d228e900e3000285e240c20fd96f9dd41ce1445305f6eada126d4a04a
+
+mm_2 sha1:b431b272d829ff3aa4d1a5085f4394ab4d3305b6
+mm_2 sha256:3f8b83ea36aacf689bcf1a1290a9a8ed341564d32682ea6f76fea9a979186782
+
+mm_3 sha1:19989d4559aae417fedee240ccf2ba315ea4dc2b
+mm_3 sha256:71b3bfc5747ac033fff9ea0ab39ee453a3af2969890e75d6ef547b87544e2681
+
+mn_1 sha1:bd084b0c27c7b6cc34f11d6d0509a29be3caf970
+mn_1 sha256:47a67450583d7a329eb01a7c4ba644945af72c0ed2c7c95eb5a00d6e46d4d483
+
+mn_2 sha1:a716d58de4a570e0038f5c307bd8db34daea021f
+mn_2 sha256:f95104c1ebe27acb84bac25a7be98c71f6b8d3054b21f357a5be0c524ad97e08
+
+nm_1 sha1:c8f25781e8f1792e3e40b74225e20553041b5226
+nm_1 sha256:09baddc7afaa62e62e152c23c9c3ab94bf15a3894031e227e9be7fe68e1f4e49
+
+nm_2 sha1:cdb9a8c3da571502ac30225e9c17beccb8387983
+nm_2 sha256:58b5227956ac2d2a08d0efa513c0ae37430948b16791ea3869a1308dbf05536d
+
+na_1 sha1:15885881ea69115351c09b38371f0348a3fb8c67
+na_1 sha256:18e4fdd1670cd7968ee23d35bfd29e5418d56fb190c840094c1c57ceee0aad8f
+
+nd_1 sha1:a4e179e4291e5536a5e1c82e091052772d2c5a93
+nd_1 sha256:07dac9b01d00956ea0c65bd993d7de4864aeef2ed3cbb1255d9f1d949fcd6df6
+
+ss_1 sha1:40c959f984c8b89a2b02520d17f00d717f024397
+ss_1 sha256:50fc1b5df74d9910db2f9270993484235f15b69b75b01bcfb53e059289d14af9
+
+ss_2 sha1:2ac547ae9614a00d1b28275de608131f7a0e259f
+ss_2 sha256:a90f02e6044f1497d13db587d22ab12f90150a7d1e084afcf96065fab35ae2bc
+
+tt_1 sha1:4ac13458899ab908ef3b1128fa378daefc88d356
+tt_1 sha256:c53113c7dd5060e86b5b251428bd058f6726f66273c6a24bff1c61a04f498dd3
+
+tt_2 sha1:4c86f9a85fbc5e6804ee2e17a797538fbe785bca
+tt_2 sha256:0775f2a296129a7cf2862b46bc0e88c14d593f2773a3e3fb1c5193db6f5a7e77
+
+tt_3 sha1:c4e4a12231b9fa79a0053cb6077fcb21bb5b135a
+tt_3 sha256:47860f93cdd211f96443e0560f21c57ab6c2f4b0ac27ff03651a352e53fe8484
+
+z__1 sha1:7d670fdcdb9929f6c7dac196ff78689cd1c566a1
+z__1 sha256:44d0f37aff5e51cfcfdd1134c93a6419bcca7b9964f792ffcd5f9b4fcba1ee63
+
+z__2 sha1:5e5f22072bb39f6e12cf663a57cb634c76eefb49
+z__2 sha256:d29de162113190fed104eb5f010820cef4e315f89b9326e8497f7219fb737894
+
+z__3 sha1:1ba523955d5160681af65cb776411f574c1e8155
+z__3 sha256:07422d772b07794ab4369a5648e617719f89c2d2212cbeab05d97214b6471636
+
+zaa1 sha1:8acb8e9750e3f644bf323fcf3d338849db106c77
+zaa1 sha256:e79b029282c8abec2d9f3f7faceaf2a1405e02d1f368e66450ae66cf5b68d1f4
+
+zaa2 sha1:6c0b99286d0bce551ac4a7b3dff8b706edff3715
+zaa2 sha256:c82bd78c3e69ea1796e6b1a7a3ba45bb106c50e819296475b862123d3f5cc5a0
+
+zan1 sha1:087494262084cefee7ed484d20c8dc0580791272
+zan1 sha256:4b159eb3804d05599023dd074f771d06d02870f4ab24a7165add8ac3d703b8d3
+
+zdd1 sha1:879007efae624d2b1307214b24a956f0a8d686a8
+zdd1 sha256:eecfdd4d8092dd0363fb6d4548b54c6afc8982c3ed9b34e393f1d6a921d8eaa3
+
+zdm1 sha1:9b541b2275c06e3a7b13f28badf5294e2ae63df4
+zdm1 sha256:ab136e88e19a843c4bf7713d2090d5a2186ba16a6a80dacc12eeddd256a8e556
+
+zdm2 sha1:d77371d15817fcaa57eeec27f770c505ba974ec1
+zdm2 sha256:1c1a5f57363f46a15d95ce8527b3c2c158d88d16853b4acbf81bd20fd2c89a46
+
+zdn1 sha1:beb5d38c55283d280685ea21a0e50cfcc0ca064a
+zdn1 sha256:0f0eca66183617b0aa5ad74b256540329f841470922ca6760263c996d825eb18
+
+zmd1 sha1:d41fda41b7ec4de46b43cb7ea42a45001ae393d5
+zmd1 sha256:1ed32d481852eddf31a0ce12652a0ad14bf5b7a842667b5dbb0b50f35bf1c80a
+
+zmd2 sha1:a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9
+zmd2 sha256:b238da211b404f8917df2d9c6f7030535e904b2186131007a3c292ec6902f933
+
+zmm1 sha1:4ca22bae2527d3d9e1676498a0fba3b355bd1278
+zmm1 sha256:072b1d85b5f34fabc99dfa46008c5418df68302d3e317430006f49b32d244226
+
+zmm2 sha1:61422ba9c2c873416061a88cd40a59a35b576474
+zmm2 sha256:81dd5d2b3c5cda16fef552256aed4e2ea0802a8450a08f308a92142112ff6dda
+
+zmm3 sha1:697aad7715a1e7306ca76290a3dd4208fbaeddfa
+zmm3 sha256:8b10fab49e9be3414aa5e9a93d0e46f9569053440138a7c19a5eb5536d8e95bf
+
+zmn1 sha1:b16d7b25b869f2beb124efa53467d8a1550ad694
+zmn1 sha256:609e4f75d1295e844c826feeba213acb0b6cfc609adfe8ff705b19e3829ae3e9
+
+zmn2 sha1:a5c544c21cfcb07eb80a4d89a5b7d1570002edfd
+zmn2 sha256:d6d03edf2dc1a3b267a8205de5f41a2ff4b03def8c7ae02052b543fb09d589fc
+
+zna1 sha1:d12979c22fff69c59ca9409e7a8fe3ee25eaee80
+zna1 sha256:b37b80e789e8ea32aa323f004628f02013f632124b0282c7fe00a127d3c64c3c
+
+znd1 sha1:a18393c636b98e9bd7296b8b437ea4992b72440c
+znd1 sha256:af92a22eee8c38410a0c9d2b5135a10aeb052cbc7cf675541ed9a67bfcaf7cf9
+
+znm1 sha1:3fdbe17fd013303a2e981e1ca1c6cd6e72789087
+znm1 sha256:f75aeaa0c11e76918e381c105f0752932c6150e941fec565d24fa31098a13dc1
+
+znm2 sha1:7e09d6a3a14bd630913e8c75693cea32157b606d
+znm2 sha256:938d73cfbaa1c902a84fb5b3afd9736aa0590367fb9bd59c6c4d072ce70fcd6d
+EOF
+
+cat >.test-plain-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 040000 $(test_oid zero) $(test_oid df_1) A DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M TT
+:040000 040000 $(test_oid z__1) $(test_oid z__2) M Z
EOF
-cat >.test-recursive-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 100644 0000000000000000000000000000000000000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 A DF/DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M TT
-:000000 100644 0000000000000000000000000000000000000000 8acb8e9750e3f644bf323fcf3d338849db106c77 A Z/AA
-:000000 100644 0000000000000000000000000000000000000000 087494262084cefee7ed484d20c8dc0580791272 A Z/AN
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D Z/DD
-:100644 000000 9b541b2275c06e3a7b13f28badf5294e2ae63df4 0000000000000000000000000000000000000000 D Z/DM
-:100644 000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a 0000000000000000000000000000000000000000 D Z/DN
-:100644 100644 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 M Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 61422ba9c2c873416061a88cd40a59a35b576474 M Z/MM
-:100644 100644 b16d7b25b869f2beb124efa53467d8a1550ad694 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd M Z/MN
+cat >.test-recursive-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 100644 $(test_oid zero) $(test_oid dfd1) A DF/DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M TT
+:000000 100644 $(test_oid zero) $(test_oid zaa1) A Z/AA
+:000000 100644 $(test_oid zero) $(test_oid zan1) A Z/AN
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D Z/DD
+:100644 000000 $(test_oid zdm1) $(test_oid zero) D Z/DM
+:100644 000000 $(test_oid zdn1) $(test_oid zero) D Z/DN
+:100644 100644 $(test_oid zmd1) $(test_oid zmd2) M Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm2) M Z/MM
+:100644 100644 $(test_oid zmn1) $(test_oid zmn2) M Z/MN
EOF
-cat >.test-plain-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 1ba523955d5160681af65cb776411f574c1e8155 M Z
+cat >.test-plain-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M TT
+:040000 040000 $(test_oid z__1) $(test_oid z__3) M Z
EOF
-cat >.test-recursive-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:000000 100644 0000000000000000000000000000000000000000 6c0b99286d0bce551ac4a7b3dff8b706edff3715 A Z/AA
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D Z/DD
-:100644 100644 9b541b2275c06e3a7b13f28badf5294e2ae63df4 d77371d15817fcaa57eeec27f770c505ba974ec1 M Z/DM
-:100644 000000 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 0000000000000000000000000000000000000000 D Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 697aad7715a1e7306ca76290a3dd4208fbaeddfa M Z/MM
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M Z/NM
+cat >.test-recursive-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M TT
+:000000 100644 $(test_oid zero) $(test_oid zaa2) A Z/AA
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D Z/DD
+:100644 100644 $(test_oid zdm1) $(test_oid zdm2) M Z/DM
+:100644 000000 $(test_oid zmd1) $(test_oid zero) D Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm3) M Z/MM
+:000000 100644 $(test_oid zero) $(test_oid zna1) A Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M Z/NM
EOF
-cat >.test-plain-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:040000 000000 6d50f65d3bdab91c63444294d38f08aeff328e42 0000000000000000000000000000000000000000 D DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:040000 040000 5e5f22072bb39f6e12cf663a57cb634c76eefb49 1ba523955d5160681af65cb776411f574c1e8155 M Z
+cat >.test-plain-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:040000 000000 $(test_oid df_1) $(test_oid zero) D DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M TT
+:040000 040000 $(test_oid z__2) $(test_oid z__3) M Z
EOF
-cat >.test-recursive-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF
-:100644 000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 0000000000000000000000000000000000000000 D DF/DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT
-:100644 100644 8acb8e9750e3f644bf323fcf3d338849db106c77 6c0b99286d0bce551ac4a7b3dff8b706edff3715 M Z/AA
-:100644 000000 087494262084cefee7ed484d20c8dc0580791272 0000000000000000000000000000000000000000 D Z/AN
-:000000 100644 0000000000000000000000000000000000000000 d77371d15817fcaa57eeec27f770c505ba974ec1 A Z/DM
-:000000 100644 0000000000000000000000000000000000000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a A Z/DN
-:100644 000000 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 0000000000000000000000000000000000000000 D Z/MD
-:100644 100644 61422ba9c2c873416061a88cd40a59a35b576474 697aad7715a1e7306ca76290a3dd4208fbaeddfa M Z/MM
-:100644 100644 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd b16d7b25b869f2beb124efa53467d8a1550ad694 M Z/MN
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M Z/NM
+cat >.test-recursive-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A DF
+:100644 000000 $(test_oid dfd1) $(test_oid zero) D DF/DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M TT
+:100644 100644 $(test_oid zaa1) $(test_oid zaa2) M Z/AA
+:100644 000000 $(test_oid zan1) $(test_oid zero) D Z/AN
+:000000 100644 $(test_oid zero) $(test_oid zdm2) A Z/DM
+:000000 100644 $(test_oid zero) $(test_oid zdn1) A Z/DN
+:100644 000000 $(test_oid zmd2) $(test_oid zero) D Z/MD
+:100644 100644 $(test_oid zmm2) $(test_oid zmm3) M Z/MM
+:100644 100644 $(test_oid zmn2) $(test_oid zmn1) M Z/MN
+:000000 100644 $(test_oid zero) $(test_oid zna1) A Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M Z/NM
EOF
cmp_diff_files_output () {
diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh
index 3641fd84d6..b63bdf031f 100755
--- a/t/t4009-diff-rename-4.sh
+++ b/t/t4009-diff-rename-4.sh
@@ -14,6 +14,7 @@ test_expect_success \
'cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
echo frotz >rezrov &&
git update-index --add COPYING rezrov &&
+ orig=$(git hash-object COPYING) &&
tree=$(git write-tree) &&
echo $tree'
@@ -22,6 +23,8 @@ test_expect_success \
'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 &&
sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 &&
rm -f COPYING &&
+ c1=$(git hash-object COPYING.1) &&
+ c2=$(git hash-object COPYING.2) &&
git update-index --add --remove COPYING COPYING.?'
# tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2,
@@ -31,11 +34,11 @@ test_expect_success \
git diff-index -z -C $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
COPYING
COPYING.1
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 R1234
+:100644 100644 $orig $c2 R1234
COPYING
COPYING.2
EOF
@@ -57,10 +60,10 @@ test_expect_success \
# about rezrov.
git diff-index -z -C $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M
+cat >expected <<EOF
+:100644 100644 $orig $c2 M
COPYING
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+:100644 100644 $orig $c1 C1234
COPYING
COPYING.1
EOF
@@ -82,8 +85,8 @@ test_expect_success \
git update-index --add --remove COPYING COPYING.1'
git diff-index -z -C --find-copies-harder $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
COPYING
COPYING.1
EOF
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index a9054d2db1..5ac94b390d 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -7,9 +7,6 @@ test_description='Various diff formatting options'
. ./test-lib.sh
-LF='
-'
-
test_expect_success setup '
GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" &&
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index ca7debf1d4..b8969998b5 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -9,7 +9,6 @@ test_description='various format-patch tests'
. "$TEST_DIRECTORY"/lib-terminal.sh
test_expect_success setup '
-
for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
cat file >elif &&
git add file elif &&
@@ -34,7 +33,8 @@ test_expect_success setup '
git commit -m "Side changes #3 with \\n backslash-n in it." &&
git checkout master &&
- git diff-tree -p C2 | git apply --index &&
+ git diff-tree -p C2 >patch &&
+ git apply --index <patch &&
test_tick &&
git commit -m "Master accepts moral equivalent of #2" &&
@@ -59,33 +59,28 @@ test_expect_success setup '
git checkout master
'
-test_expect_success "format-patch --ignore-if-in-upstream" '
-
+test_expect_success 'format-patch --ignore-if-in-upstream' '
git format-patch --stdout master..side >patch0 &&
- cnt=$(grep "^From " patch0 | wc -l) &&
- test $cnt = 3
-
+ grep "^From " patch0 >from0 &&
+ test_line_count = 3 from0
'
-test_expect_success "format-patch --ignore-if-in-upstream" '
-
+test_expect_success 'format-patch --ignore-if-in-upstream' '
git format-patch --stdout \
--ignore-if-in-upstream master..side >patch1 &&
- cnt=$(grep "^From " patch1 | wc -l) &&
- test $cnt = 2
-
+ grep "^From " patch1 >from1 &&
+ test_line_count = 2 from1
'
-test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
+test_expect_success 'format-patch --ignore-if-in-upstream handles tags' '
git tag -a v1 -m tag side &&
git tag -a v2 -m tag master &&
git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
- cnt=$(grep "^From " patch1 | wc -l) &&
- test $cnt = 2
+ grep "^From " patch1 >from1 &&
+ test_line_count = 2 from1
'
test_expect_success "format-patch doesn't consider merge commits" '
-
git checkout -b slave master &&
echo "Another line" >>file &&
test_tick &&
@@ -96,148 +91,138 @@ test_expect_success "format-patch doesn't consider merge commits" '
git checkout -b merger master &&
test_tick &&
git merge --no-ff slave &&
- cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
- test $cnt = 3
+ git format-patch -3 --stdout >patch &&
+ grep "^From " patch >from &&
+ test_line_count = 3 from
'
-test_expect_success "format-patch result applies" '
-
+test_expect_success 'format-patch result applies' '
git checkout -b rebuild-0 master &&
git am -3 patch0 &&
- cnt=$(git rev-list master.. | wc -l) &&
- test $cnt = 2
+ git rev-list master.. >list &&
+ test_line_count = 2 list
'
-test_expect_success "format-patch --ignore-if-in-upstream result applies" '
-
+test_expect_success 'format-patch --ignore-if-in-upstream result applies' '
git checkout -b rebuild-1 master &&
git am -3 patch1 &&
- cnt=$(git rev-list master.. | wc -l) &&
- test $cnt = 2
+ git rev-list master.. >list &&
+ test_line_count = 2 list
'
test_expect_success 'commit did not screw up the log message' '
-
- git cat-file commit side | grep "^Side .* with .* backslash-n"
-
+ git cat-file commit side >actual &&
+ grep "^Side .* with .* backslash-n" actual
'
test_expect_success 'format-patch did not screw up the log message' '
-
grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
-
'
test_expect_success 'replay did not screw up the log message' '
-
- git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
-
+ git cat-file commit rebuild-1 >actual &&
+ grep "^Side .* with .* backslash-n" actual
'
test_expect_success 'extra headers' '
-
git config format.headers "To: R E Cipient <rcipient@example.com>
" &&
git config --add format.headers "Cc: S E Cipient <scipient@example.com>
" &&
- git format-patch --stdout master..side > patch2 &&
- sed -e "/^\$/q" patch2 > hdrs2 &&
+ git format-patch --stdout master..side >patch2 &&
+ sed -e "/^\$/q" patch2 >hdrs2 &&
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
-
'
test_expect_success 'extra headers without newlines' '
-
git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
git format-patch --stdout master..side >patch3 &&
- sed -e "/^\$/q" patch3 > hdrs3 &&
+ sed -e "/^\$/q" patch3 >hdrs3 &&
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
-
'
test_expect_success 'extra headers with multiple To:s' '
-
git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
- git format-patch --stdout master..side > patch4 &&
- sed -e "/^\$/q" patch4 > hdrs4 &&
+ git format-patch --stdout master..side >patch4 &&
+ sed -e "/^\$/q" patch4 >hdrs4 &&
grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
'
test_expect_success 'additional command line cc (ascii)' '
-
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
- git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
- grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
- grep "^ *S E Cipient <scipient@example.com>\$" patch5
+ git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side >patch5 &&
+ sed -e "/^\$/q" patch5 >hdrs5 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
+ grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
'
test_expect_failure 'additional command line cc (rfc822)' '
-
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
- git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
- grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
- grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
+ git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side >patch5 &&
+ sed -e "/^\$/q" patch5 >hdrs5 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
+ grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
'
test_expect_success 'command line headers' '
-
git config --unset-all format.headers &&
- git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
- grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
+ git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side >patch6 &&
+ sed -e "/^\$/q" patch6 >hdrs6 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
'
test_expect_success 'configuration headers and command line headers' '
-
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
- git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
- grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
- grep "^ *S E Cipient <scipient@example.com>\$" patch7
+ git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side >patch7 &&
+ sed -e "/^\$/q" patch7 >hdrs7 &&
+ grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
+ grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
'
test_expect_success 'command line To: header (ascii)' '
-
git config --unset-all format.headers &&
- git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: R E Cipient <rcipient@example.com>\$" patch8
+ git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
+ sed -e "/^\$/q" patch8 >hdrs8 &&
+ grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
'
test_expect_failure 'command line To: header (rfc822)' '
-
- git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
+ git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
+ sed -e "/^\$/q" patch8 >hdrs8 &&
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
'
test_expect_failure 'command line To: header (rfc2047)' '
-
- git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
+ git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
+ sed -e "/^\$/q" patch8 >hdrs8 &&
+ grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
'
test_expect_success 'configuration To: header (ascii)' '
-
git config format.to "R E Cipient <rcipient@example.com>" &&
- git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: R E Cipient <rcipient@example.com>\$" patch9
+ git format-patch --stdout master..side >patch9 &&
+ sed -e "/^\$/q" patch9 >hdrs9 &&
+ grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
'
test_expect_failure 'configuration To: header (rfc822)' '
-
git config format.to "R. E. Cipient <rcipient@example.com>" &&
- git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
+ git format-patch --stdout master..side >patch9 &&
+ sed -e "/^\$/q" patch9 >hdrs9 &&
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
'
test_expect_failure 'configuration To: header (rfc2047)' '
-
git config format.to "R Ä Cipient <rcipient@example.com>" &&
- git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
+ git format-patch --stdout master..side >patch9 &&
+ sed -e "/^\$/q" patch9 >hdrs9 &&
+ grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
'
# check_patch <patch>: Verify that <patch> looks like a half-sane
@@ -249,89 +234,79 @@ check_patch () {
}
test_expect_success 'format.from=false' '
-
- git -c format.from=false format-patch --stdout master..side |
- sed -e "/^\$/q" >patch &&
+ git -c format.from=false format-patch --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
check_patch patch &&
- ! grep "^From: C O Mitter <committer@example.com>\$" patch
+ ! grep "^From: C O Mitter <committer@example.com>\$" hdrs
'
test_expect_success 'format.from=true' '
-
- git -c format.from=true format-patch --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- grep "^From: C O Mitter <committer@example.com>\$" patch
+ git -c format.from=true format-patch --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ grep "^From: C O Mitter <committer@example.com>\$" hdrs
'
test_expect_success 'format.from with address' '
-
- git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- grep "^From: F R Om <from@example.com>\$" patch
+ git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ grep "^From: F R Om <from@example.com>\$" hdrs
'
test_expect_success '--no-from overrides format.from' '
-
- git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- ! grep "^From: F R Om <from@example.com>\$" patch
+ git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ ! grep "^From: F R Om <from@example.com>\$" hdrs
'
test_expect_success '--from overrides format.from' '
-
- git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side |
- sed -e "/^\$/q" >patch &&
- check_patch patch &&
- ! grep "^From: F R Om <from@example.com>\$" patch
+ git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side >patch &&
+ sed -e "/^\$/q" patch >hdrs &&
+ check_patch hdrs &&
+ ! grep "^From: F R Om <from@example.com>\$" hdrs
'
test_expect_success '--no-to overrides config.to' '
-
git config --replace-all format.to \
"R E Cipient <rcipient@example.com>" &&
- git format-patch --no-to --stdout master..side |
- sed -e "/^\$/q" >patch10 &&
- check_patch patch10 &&
- ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
+ git format-patch --no-to --stdout master..side >patch10 &&
+ sed -e "/^\$/q" patch10 >hdrs10 &&
+ check_patch hdrs10 &&
+ ! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
'
test_expect_success '--no-to and --to replaces config.to' '
-
git config --replace-all format.to \
"Someone <someone@out.there>" &&
git format-patch --no-to --to="Someone Else <else@out.there>" \
- --stdout master..side |
- sed -e "/^\$/q" >patch11 &&
- check_patch patch11 &&
- ! grep "^To: Someone <someone@out.there>\$" patch11 &&
- grep "^To: Someone Else <else@out.there>\$" patch11
+ --stdout master..side >patch11 &&
+ sed -e "/^\$/q" patch11 >hdrs11 &&
+ check_patch hdrs11 &&
+ ! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
+ grep "^To: Someone Else <else@out.there>\$" hdrs11
'
test_expect_success '--no-cc overrides config.cc' '
-
git config --replace-all format.cc \
"C E Cipient <rcipient@example.com>" &&
- git format-patch --no-cc --stdout master..side |
- sed -e "/^\$/q" >patch12 &&
- check_patch patch12 &&
- ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
+ git format-patch --no-cc --stdout master..side >patch12 &&
+ sed -e "/^\$/q" patch12 >hdrs12 &&
+ check_patch hdrs12 &&
+ ! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
'
test_expect_success '--no-add-header overrides config.headers' '
-
git config --replace-all format.headers \
"Header1: B E Cipient <rcipient@example.com>" &&
- git format-patch --no-add-header --stdout master..side |
- sed -e "/^\$/q" >patch13 &&
- check_patch patch13 &&
- ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
+ git format-patch --no-add-header --stdout master..side >patch13 &&
+ sed -e "/^\$/q" patch13 >hdrs13 &&
+ check_patch hdrs13 &&
+ ! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
'
test_expect_success 'multiple files' '
-
rm -rf patches/ &&
git checkout side &&
git format-patch -o patches/ master &&
@@ -357,7 +332,7 @@ test_expect_success 'reroll count (-v)' '
check_threading () {
expect="$1" &&
shift &&
- (git format-patch --stdout "$@"; echo $? > status.out) |
+ git format-patch --stdout "$@" >patch &&
# Prints everything between the Message-ID and In-Reply-To,
# and replaces all Message-ID-lookalikes by a sequence number
perl -ne '
@@ -372,12 +347,11 @@ check_threading () {
print;
}
print "---\n" if /^From /i;
- ' > actual &&
- test 0 = "$(cat status.out)" &&
+ ' <patch >actual &&
test_cmp "$expect" actual
}
-cat >> expect.no-threading <<EOF
+cat >>expect.no-threading <<EOF
---
---
---
@@ -388,7 +362,7 @@ test_expect_success 'no threading' '
check_threading expect.no-threading master
'
-cat > expect.thread <<EOF
+cat >expect.thread <<EOF
---
Message-Id: <0>
---
@@ -405,7 +379,7 @@ test_expect_success 'thread' '
check_threading expect.thread --thread master
'
-cat > expect.in-reply-to <<EOF
+cat >expect.in-reply-to <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -425,7 +399,7 @@ test_expect_success 'thread in-reply-to' '
--thread master
'
-cat > expect.cover-letter <<EOF
+cat >expect.cover-letter <<EOF
---
Message-Id: <0>
---
@@ -446,7 +420,7 @@ test_expect_success 'thread cover-letter' '
check_threading expect.cover-letter --cover-letter --thread master
'
-cat > expect.cl-irt <<EOF
+cat >expect.cl-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -478,7 +452,7 @@ test_expect_success 'thread explicit shallow' '
--in-reply-to="<test.message>" --thread=shallow master
'
-cat > expect.deep <<EOF
+cat >expect.deep <<EOF
---
Message-Id: <0>
---
@@ -496,7 +470,7 @@ test_expect_success 'thread deep' '
check_threading expect.deep --thread=deep master
'
-cat > expect.deep-irt <<EOF
+cat >expect.deep-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -519,7 +493,7 @@ test_expect_success 'thread deep in-reply-to' '
--in-reply-to="<test.message>" master
'
-cat > expect.deep-cl <<EOF
+cat >expect.deep-cl <<EOF
---
Message-Id: <0>
---
@@ -543,7 +517,7 @@ test_expect_success 'thread deep cover-letter' '
check_threading expect.deep-cl --cover-letter --thread=deep master
'
-cat > expect.deep-cl-irt <<EOF
+cat >expect.deep-cl-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
@@ -594,7 +568,6 @@ test_expect_success 'thread config + --no-thread' '
'
test_expect_success 'excessive subject' '
-
rm -rf patches/ &&
git checkout side &&
before=$(git hash-object file) &&
@@ -622,10 +595,9 @@ test_expect_success 'cover-letter inherits diff options' '
! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
git format-patch --cover-letter -1 -M &&
grep "file => foo .* 0 *\$" 0000-cover-letter.patch
-
'
-cat > expect << EOF
+cat >expect <<EOF
This is an excessively long subject line for a message due to the
habit some projects have of not having a short, one-line subject at
the start of the commit message, but rather sticking a whole
@@ -636,14 +608,12 @@ cat > expect << EOF
EOF
test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
-
git format-patch --cover-letter -2 &&
- sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
+ sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
test_cmp expect output
-
'
-cat > expect << EOF
+cat >expect <<EOF
index $before..$after 100644
--- a/file
+++ b/file
@@ -656,16 +626,14 @@ index $before..$after 100644
EOF
test_expect_success 'format-patch respects -U' '
-
git format-patch -U4 -2 &&
sed -e "1,/^diff/d" -e "/^+5/q" \
<0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
>output &&
test_cmp expect output
-
'
-cat > expect << EOF
+cat >expect <<EOF
diff --git a/file b/file
index $before..$after 100644
@@ -679,11 +647,9 @@ index $before..$after 100644
EOF
test_expect_success 'format-patch -p suppresses stat' '
-
git format-patch -p -2 &&
- sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
+ sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
test_cmp expect output
-
'
test_expect_success 'format-patch from a subdirectory (1)' '
@@ -736,7 +702,7 @@ test_expect_success 'format-patch from a subdirectory (3)' '
'
test_expect_success 'format-patch --in-reply-to' '
- git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
+ git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
grep "^References: <baz@foo.bar>" patch8
'
@@ -827,21 +793,24 @@ test_expect_success 'format-patch with multiple notes refs' '
! grep "this is note 2" out
'
-echo "fatal: --name-only does not make sense" > expect.name-only
-echo "fatal: --name-status does not make sense" > expect.name-status
-echo "fatal: --check does not make sense" > expect.check
+echo "fatal: --name-only does not make sense" >expect.name-only
+echo "fatal: --name-status does not make sense" >expect.name-status
+echo "fatal: --check does not make sense" >expect.check
test_expect_success 'options no longer allowed for format-patch' '
- test_must_fail git format-patch --name-only 2> output &&
+ test_must_fail git format-patch --name-only 2>output &&
test_i18ncmp expect.name-only output &&
- test_must_fail git format-patch --name-status 2> output &&
+ test_must_fail git format-patch --name-status 2>output &&
test_i18ncmp expect.name-status output &&
- test_must_fail git format-patch --check 2> output &&
- test_i18ncmp expect.check output'
+ test_must_fail git format-patch --check 2>output &&
+ test_i18ncmp expect.check output
+'
test_expect_success 'format-patch --numstat should produce a patch' '
- git format-patch --numstat --stdout master..side > output &&
- test 5 = $(grep "^diff --git a/" output | wc -l)'
+ git format-patch --numstat --stdout master..side >output &&
+ grep "^diff --git a/" output >diff &&
+ test_line_count = 5 diff
+'
test_expect_success 'format-patch -- <path>' '
git format-patch master..side -- file 2>error &&
@@ -852,20 +821,25 @@ test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
git format-patch --ignore-if-in-upstream HEAD
'
-git_version="$(git --version | sed "s/.* //")"
+test_expect_success 'get git version' '
+ git_version=$(git --version) &&
+ git_version=${git_version##* }
+'
signature() {
printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
}
test_expect_success 'format-patch default signature' '
- git format-patch --stdout -1 | tail -n 3 >output &&
+ git format-patch --stdout -1 >patch &&
+ tail -n 3 patch >output &&
signature >expect &&
test_cmp expect output
'
test_expect_success 'format-patch --signature' '
- git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
+ git format-patch --stdout --signature="my sig" -1 >patch &&
+ tail -n 3 patch >output &&
signature "my sig" >expect &&
test_cmp expect output
'
@@ -897,8 +871,8 @@ test_expect_success 'format-patch --signature --cover-letter' '
git config --unset-all format.signature &&
git format-patch --stdout --signature="my sig" --cover-letter \
-1 >output &&
- grep "my sig" output &&
- test 2 = $(grep "my sig" output | wc -l)
+ grep "my sig" output >sig &&
+ test_line_count = 2 sig
'
test_expect_success 'format.signature="" suppresses signatures' '
@@ -935,7 +909,7 @@ test_expect_success 'prepare mail-signature input' '
test_expect_success '--signature-file=file works' '
git format-patch --stdout --signature-file=mail-signature -1 >output &&
check_patch output &&
- sed -e "1,/^-- \$/d" <output >actual &&
+ sed -e "1,/^-- \$/d" output >actual &&
{
cat mail-signature && echo
} >expect &&
@@ -946,7 +920,7 @@ test_expect_success 'format.signaturefile works' '
test_config format.signaturefile mail-signature &&
git format-patch --stdout -1 >output &&
check_patch output &&
- sed -e "1,/^-- \$/d" <output >actual &&
+ sed -e "1,/^-- \$/d" output >actual &&
{
cat mail-signature && echo
} >expect &&
@@ -968,7 +942,7 @@ test_expect_success '--signature-file overrides format.signaturefile' '
git format-patch --stdout \
--signature-file=other-mail-signature -1 >output &&
check_patch output &&
- sed -e "1,/^-- \$/d" <output >actual &&
+ sed -e "1,/^-- \$/d" output >actual &&
{
cat other-mail-signature && echo
} >expect &&
@@ -1037,7 +1011,7 @@ test_expect_success 'format-patch wraps extremely long subject (ascii)' '
git add file &&
git commit -m "$M512" &&
git format-patch --stdout -1 >patch &&
- sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
+ sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
test_cmp expect subject
'
@@ -1076,7 +1050,7 @@ test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
git add file &&
git commit -m "$M512" &&
git format-patch --stdout -1 >patch &&
- sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
+ sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
test_cmp expect subject
'
@@ -1085,7 +1059,7 @@ check_author() {
git add file &&
GIT_AUTHOR_NAME=$1 git commit -m author-check &&
git format-patch --stdout -1 >patch &&
- sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
+ sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
test_cmp expect actual
}
@@ -1205,7 +1179,7 @@ test_expect_success '--from=ident replaces author' '
From: A U Thor <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1217,7 +1191,7 @@ test_expect_success '--from uses committer ident' '
From: A U Thor <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1227,7 +1201,7 @@ test_expect_success '--from omits redundant in-body header' '
From: A U Thor <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1242,7 +1216,7 @@ test_expect_success 'in-body headers trigger content encoding' '
From: éxötìc <author@example.com>
EOF
- sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
+ sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
test_cmp expect patch.head
'
@@ -1256,283 +1230,283 @@ append_signoff()
test_expect_success 'signoff: commit with no body' '
append_signoff </dev/null >actual &&
- cat <<\EOF | sed "s/EOL$//" >expected &&
-4:Subject: [PATCH] EOL
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat <<-\EOF | sed "s/EOL$//" >expect &&
+ 4:Subject: [PATCH] EOL
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: commit with only subject' '
echo subject | append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: commit with only subject that does not end with NL' '
printf subject | append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: no existing signoffs' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ body
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: no existing signoffs and no trailing NL' '
printf "subject\n\nbody" | append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: some random signoff' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: my@house
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: my@house
-12:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Signed-off-by: my@house
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: my@house
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: misc conforming footer elements' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: my@house
-(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
-Tested-by: Some One <someone@example.com>
-Bug: 1234
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: my@house
-15:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Signed-off-by: my@house
+ (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
+ Tested-by: Some One <someone@example.com>
+ Bug: 1234
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: my@house
+ 15:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: some random signoff-alike' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
-Fooled-by-me: my@house
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-11:
-12:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ body
+ Fooled-by-me: my@house
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 11:
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: not really a signoff' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-I want to mention about Signed-off-by: here.
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:I want to mention about Signed-off-by: here.
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ I want to mention about Signed-off-by: here.
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:I want to mention about Signed-off-by: here.
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: not really a signoff (2)' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-My unfortunate
-Signed-off-by: example happens to be wrapped here.
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:Signed-off-by: example happens to be wrapped here.
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ My unfortunate
+ Signed-off-by: example happens to be wrapped here.
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:Signed-off-by: example happens to be wrapped here.
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-Signed-off-by: my@house
-Signed-off-by: your@house
+ Signed-off-by: my@house
+ Signed-off-by: your@house
-A lot of houses.
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: my@house
-10:Signed-off-by: your@house
-11:
-13:
-14:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ A lot of houses.
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: my@house
+ 10:Signed-off-by: your@house
+ 11:
+ 13:
+ 14:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: the same signoff at the end' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: C O Mitter <committer@example.com>
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
append_signoff >actual &&
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-9:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: the same signoff NOT at the end' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Signed-off-by: C O Mitter <committer@example.com>
-Signed-off-by: my@house
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-11:Signed-off-by: C O Mitter <committer@example.com>
-12:Signed-off-by: my@house
-EOF
- test_cmp expected actual
+ Signed-off-by: C O Mitter <committer@example.com>
+ Signed-off-by: my@house
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ 12:Signed-off-by: my@house
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: tolerate garbage in conforming footer' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Tested-by: my@house
-Some Trash
-Signed-off-by: C O Mitter <committer@example.com>
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-13:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Tested-by: my@house
+ Some Trash
+ Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 13:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: respect trailer config' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-Myfooter: x
-Some Trash
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-11:
-12:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual &&
+ Myfooter: x
+ Some Trash
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 11:
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual &&
test_config trailer.Myfooter.ifexists add &&
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-Myfooter: x
-Some Trash
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-11:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Myfooter: x
+ Some Trash
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
- append_signoff <<\EOF >actual &&
-subject
+ append_signoff <<-\EOF >actual &&
+ subject
-body
+ body
-Reviewed-id: Noone
-Tested-by: my@house
-Change-id: Ideadbeef
-Signed-off-by: C O Mitter <committer@example.com>
-Bug: 1234
-EOF
- cat >expected <<\EOF &&
-4:Subject: [PATCH] subject
-8:
-10:
-14:Signed-off-by: C O Mitter <committer@example.com>
-EOF
- test_cmp expected actual
+ Reviewed-id: Noone
+ Tested-by: my@house
+ Change-id: Ideadbeef
+ Signed-off-by: C O Mitter <committer@example.com>
+ Bug: 1234
+ EOF
+ cat >expect <<-\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 14:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expect actual
'
test_expect_success 'format patch ignores color.ui' '
@@ -1547,42 +1521,42 @@ test_expect_success 'cover letter using branch description (1)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter master >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (2)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (3)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (4)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter master.. >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (5)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter -2 HEAD >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter using branch description (6)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter -2 >actual &&
- grep hello actual >/dev/null
+ grep hello actual
'
test_expect_success 'cover letter with nothing' '
@@ -1632,11 +1606,39 @@ test_expect_success 'From line has expected format' '
test_cmp from filtered
'
+test_expect_success 'format-patch -o with no leading directories' '
+ rm -fr patches &&
+ git format-patch -o patches master..side &&
+ count=$(git rev-list --count master..side) &&
+ ls patches >list &&
+ test_line_count = $count list
+'
+
+test_expect_success 'format-patch -o with leading existing directories' '
+ rm -rf existing-dir &&
+ mkdir existing-dir &&
+ git format-patch -o existing-dir/patches master..side &&
+ count=$(git rev-list --count master..side) &&
+ ls existing-dir/patches >list &&
+ test_line_count = $count list
+'
+
+test_expect_success 'format-patch -o with leading non-existing directories' '
+ rm -rf non-existing-dir &&
+ git format-patch -o non-existing-dir/patches master..side &&
+ count=$(git rev-list --count master..side) &&
+ test_path_is_dir non-existing-dir &&
+ ls non-existing-dir/patches >list &&
+ test_line_count = $count list
+'
+
test_expect_success 'format-patch format.outputDirectory option' '
test_config format.outputDirectory patches &&
rm -fr patches &&
git format-patch master..side &&
- test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
+ count=$(git rev-list --count master..side) &&
+ ls patches >list &&
+ test_line_count = $count list
'
test_expect_success 'format-patch -o overrides format.outputDirectory' '
@@ -1649,20 +1651,41 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' '
test_expect_success 'format-patch --base' '
git checkout patchid &&
- git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 &&
- git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 &&
- echo >expected &&
- echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
- signature >> expected &&
- test_cmp expected actual1 &&
- test_cmp expected actual2 &&
+
+ git format-patch --stdout --base=HEAD~3 -1 >patch &&
+ tail -n 7 patch >actual1 &&
+
+ git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
+ tail -n 7 patch >actual2 &&
+
+ echo >expect &&
+ git rev-parse HEAD~3 >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >>expect &&
+
+ git show --patch HEAD~2 >patch &&
+ git patch-id --stable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
+
+ git show --patch HEAD~1 >patch &&
+ git patch-id --stable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
+
+ signature >>expect &&
+ test_cmp expect actual1 &&
+ test_cmp expect actual2 &&
+
echo >fail &&
- echo "base-commit: $(git rev-parse HEAD~3)" >>fail &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
- echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
- signature >> fail &&
+ echo "base-commit: $(cat commit-id-base)" >>fail &&
+
+ git show --patch HEAD~2 >patch &&
+ git patch-id --unstable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
+
+ git show --patch HEAD~1 >patch &&
+ git patch-id --unstable <patch >patch.id.raw &&
+ awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
+
+ signature >>fail &&
! test_cmp fail actual1 &&
! test_cmp fail actual2
'
@@ -1672,8 +1695,9 @@ test_expect_success 'format-patch --base errors out when base commit is in revis
test_must_fail git format-patch --base=HEAD~1 -2 &&
git format-patch --stdout --base=HEAD~2 -2 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
- test_cmp expected actual
+ git rev-parse HEAD~2 >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
@@ -1699,8 +1723,8 @@ test_expect_success 'format-patch --base errors out when base commit is not ance
test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(cat commit-id-base)" >expected &&
- test_cmp expected actual
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch --base=auto' '
@@ -1711,8 +1735,9 @@ test_expect_success 'format-patch --base=auto' '
test_commit N2 &&
git format-patch --stdout --base=auto -2 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse upstream)" >expected &&
- test_cmp expected actual
+ git rev-parse upstream >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch errors out when history involves criss-cross' '
@@ -1748,8 +1773,9 @@ test_expect_success 'format-patch format.useAutoBaseoption' '
git config format.useAutoBase true &&
git format-patch --stdout -1 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse upstream)" >expected &&
- test_cmp expected actual
+ git rev-parse upstream >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch --base overrides format.useAutoBase' '
@@ -1757,8 +1783,9 @@ test_expect_success 'format-patch --base overrides format.useAutoBase' '
git config format.useAutoBase true &&
git format-patch --stdout --base=HEAD~1 -1 >patch &&
grep "^base-commit:" patch >actual &&
- echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
- test_cmp expected actual
+ git rev-parse HEAD~1 >commit-id-base &&
+ echo "base-commit: $(cat commit-id-base)" >expect &&
+ test_cmp expect actual
'
test_expect_success 'format-patch --base with --attach' '
@@ -1833,7 +1860,7 @@ test_expect_success 'interdiff: cover-letter' '
git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
- sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
+ sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
test_cmp expect actual
'
@@ -1849,7 +1876,7 @@ test_expect_success 'interdiff: solo-patch' '
EOF
git format-patch --interdiff=boop~2 -1 boop &&
test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
- sed "1,/^ @@ /d; /^$/q" <0001-fleep.patch >actual &&
+ sed "1,/^ @@ /d; /^$/q" 0001-fleep.patch >actual &&
test_cmp expect actual
'
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index ab4670d236..6b087df3dc 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -2008,4 +2008,26 @@ 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 &&
+ 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 &&
+ @@ -1,6 +1,4 @@
+ 1
+ 2
+ 3
+ 4
+ -5
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index 9261d6d3a0..6f5ef0035e 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -31,6 +31,7 @@ diffpatterns="
cpp
csharp
css
+ dts
fortran
fountain
golang
diff --git a/t/t4018/dts-labels b/t/t4018/dts-labels
new file mode 100644
index 0000000000..b21ef8737b
--- /dev/null
+++ b/t/t4018/dts-labels
@@ -0,0 +1,9 @@
+/ {
+ label_1: node1@ff00 {
+ label2: RIGHT {
+ vendor,some-property;
+
+ ChangeMe = <0x45-30>;
+ };
+ };
+};
diff --git a/t/t4018/dts-node-unitless b/t/t4018/dts-node-unitless
new file mode 100644
index 0000000000..c5287d9141
--- /dev/null
+++ b/t/t4018/dts-node-unitless
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1 {
+ RIGHT {
+ prop-array = <1>, <4>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes b/t/t4018/dts-nodes
new file mode 100644
index 0000000000..5a4334bb16
--- /dev/null
+++ b/t/t4018/dts-nodes
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 {
+ #size-cells = <1>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-boolean-prop b/t/t4018/dts-nodes-boolean-prop
new file mode 100644
index 0000000000..afc6b5b404
--- /dev/null
+++ b/t/t4018/dts-nodes-boolean-prop
@@ -0,0 +1,9 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 {
+ boolean-prop1;
+
+ ChangeMe;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-comment1 b/t/t4018/dts-nodes-comment1
new file mode 100644
index 0000000000..559dfce9b3
--- /dev/null
+++ b/t/t4018/dts-nodes-comment1
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 /* &a comment */ {
+ #size-cells = <1>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-comment2 b/t/t4018/dts-nodes-comment2
new file mode 100644
index 0000000000..27e9718b31
--- /dev/null
+++ b/t/t4018/dts-nodes-comment2
@@ -0,0 +1,8 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 { /* a trailing comment */
+ #size-cells = <1>;
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-nodes-multiline-prop b/t/t4018/dts-nodes-multiline-prop
new file mode 100644
index 0000000000..072d58b69d
--- /dev/null
+++ b/t/t4018/dts-nodes-multiline-prop
@@ -0,0 +1,13 @@
+/ {
+ label_1: node1@ff00 {
+ RIGHT@deadf00,4000 {
+ multilineprop = <3>,
+ <4>,
+ <5>,
+ <6>,
+ <7>;
+
+ ChangeMe = <0xffeedd00>;
+ };
+ };
+};
diff --git a/t/t4018/dts-reference b/t/t4018/dts-reference
new file mode 100644
index 0000000000..8f0c87d863
--- /dev/null
+++ b/t/t4018/dts-reference
@@ -0,0 +1,9 @@
+&label_1 {
+ TEST = <455>;
+};
+
+&RIGHT {
+ vendor,some-property;
+
+ ChangeMe = <0x45-30>;
+};
diff --git a/t/t4018/dts-root b/t/t4018/dts-root
new file mode 100644
index 0000000000..4353b8220c
--- /dev/null
+++ b/t/t4018/dts-root
@@ -0,0 +1,5 @@
+/ { RIGHT /* Technically just supposed to be a slash and brace */
+ #size-cells = <1>;
+
+ ChangeMe = <0xffeedd00>;
+};
diff --git a/t/t4018/dts-root-comment b/t/t4018/dts-root-comment
new file mode 100644
index 0000000000..333a625c70
--- /dev/null
+++ b/t/t4018/dts-root-comment
@@ -0,0 +1,8 @@
+/ { RIGHT /* Technically just supposed to be a slash and brace */
+ #size-cells = <1>;
+
+ /* This comment should be ignored */
+
+ some-property = <40+2>;
+ ChangeMe = <0xffeedd00>;
+};
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
index 912df91226..9a93c2a3e0 100755
--- a/t/t4034-diff-words.sh
+++ b/t/t4034-diff-words.sh
@@ -303,6 +303,7 @@ test_language_driver bibtex
test_language_driver cpp
test_language_driver csharp
test_language_driver css
+test_language_driver dts
test_language_driver fortran
test_language_driver html
test_language_driver java
diff --git a/t/t4034/dts/expect b/t/t4034/dts/expect
new file mode 100644
index 0000000000..560fc99184
--- /dev/null
+++ b/t/t4034/dts/expect
@@ -0,0 +1,37 @@
+<BOLD>diff --git a/pre b/post<RESET>
+<BOLD>index b6a9051..7803aee 100644<RESET>
+<BOLD>--- a/pre<RESET>
+<BOLD>+++ b/post<RESET>
+<CYAN>@@ -1,32 +1,32 @@<RESET>
+/ {<RESET>
+ <RED>this_handle<RESET><GREEN>HANDLE_2<RESET>: <RED>node<RESET><GREEN>new-node<RESET>@<RED>f00<RESET><GREEN>eeda<RESET> {
+ compatible = "<RED>mydev<RESET><GREEN>vendor,compat<RESET>";
+ string-prop = <RED>start<RESET><GREEN>end<RESET>: "hello <RED>world!<RESET><GREEN>world?<RESET>" <RED>end<RESET><GREEN>start<RESET>: ;
+ <RED>#size-cells<RESET><GREEN>#address-cells<RESET> = <<RED>0+0<RESET><GREEN>0+40<RESET>>;
+ reg = <<RED>0xf00<RESET><GREEN>0xeeda<RESET>>;
+ prop = <<GREEN>(<RESET>1<GREEN>)<RESET>>;
+ prop = <<GREEN>(<RESET>-1e10<GREEN>)<RESET>>;
+ prop = <(!<RED>3<RESET><GREEN>1<RESET>)>;
+ prop = <(~<RED>3<RESET><GREEN>1<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>*<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>&<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>*<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>/<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>%<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3+4<RESET><GREEN>1+2<RESET>)>;
+ prop = <(<RED>3-4<RESET><GREEN>1-2<RESET>)>;
+ prop = /bits/ <RED>64<RESET><GREEN>32<RESET> <(<RED>3<RESET><GREEN>1<RESET><<<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>>><RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>&<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>^<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>|<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>&&<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>3<RESET><GREEN>1<RESET>||<RED>4<RESET><GREEN>2<RESET>)>;
+ prop = <(<RED>4?5<RESET><GREEN>1?2<RESET>:3)>;
+ list = <&<RED>this_handle<RESET><GREEN>HANDLE_2<RESET>>, <0 0 0 <RED>0<RESET><GREEN>1<RESET>>;
+ };<RESET>
+
+ &<RED>phandle<RESET><GREEN>phandle2<RESET> {
+ <RED>pre-phandle<RESET><GREEN>prop_handle<RESET> = <&<RED>this_handle<RESET><GREEN>HANDLE_2<RESET>>;
+ };<RESET>
+};<RESET>
diff --git a/t/t4034/dts/post b/t/t4034/dts/post
new file mode 100644
index 0000000000..7803aee280
--- /dev/null
+++ b/t/t4034/dts/post
@@ -0,0 +1,32 @@
+/ {
+ HANDLE_2: new-node@eeda {
+ compatible = "vendor,compat";
+ string-prop = end: "hello world?" start: ;
+ #address-cells = <0+40>;
+ reg = <0xeeda>;
+ prop = <(1)>;
+ prop = <(-1e10)>;
+ prop = <(!1)>;
+ prop = <(~1)>;
+ prop = <(1*2)>;
+ prop = <(1&2)>;
+ prop = <(1*2)>;
+ prop = <(1/2)>;
+ prop = <(1%2)>;
+ prop = <(1+2)>;
+ prop = <(1-2)>;
+ prop = /bits/ 32 <(1<<2)>;
+ prop = <(1>>2)>;
+ prop = <(1&2)>;
+ prop = <(1^2)>;
+ prop = <(1|2)>;
+ prop = <(1&&2)>;
+ prop = <(1||2)>;
+ prop = <(1?2:3)>;
+ list = <&HANDLE_2>, <0 0 0 1>;
+ };
+
+ &phandle2 {
+ prop_handle = <&HANDLE_2>;
+ };
+};
diff --git a/t/t4034/dts/pre b/t/t4034/dts/pre
new file mode 100644
index 0000000000..b6a905113c
--- /dev/null
+++ b/t/t4034/dts/pre
@@ -0,0 +1,32 @@
+/ {
+ this_handle: node@f00 {
+ compatible = "mydev";
+ string-prop = start: "hello world!" end: ;
+ #size-cells = <0+0>;
+ reg = <0xf00>;
+ prop = <1>;
+ prop = <-1e10>;
+ prop = <(!3)>;
+ prop = <(~3)>;
+ prop = <(3*4)>;
+ prop = <(3&4)>;
+ prop = <(3*4)>;
+ prop = <(3/4)>;
+ prop = <(3%4)>;
+ prop = <(3+4)>;
+ prop = <(3-4)>;
+ prop = /bits/ 64 <(3<<4)>;
+ prop = <(3>>4)>;
+ prop = <(3&4)>;
+ prop = <(3^4)>;
+ prop = <(3|4)>;
+ prop = <(3&&4)>;
+ prop = <(3||4)>;
+ prop = <(4?5:3)>;
+ list = <&this_handle>, <0 0 0 0>;
+ };
+
+ &phandle {
+ pre-phandle = <&this_handle>;
+ };
+};
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index d4afe12554..b9d876efa2 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -509,7 +509,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 &&
git diff-tree -c -M --raw --combined-all-paths -z HEAD >actual &&
- test_cmp -a expect actual
+ test_cmp expect actual
'
test_expect_success FUNNYNAMES '--combined-all-paths and --cc and funny names' '
diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh
index 90c8fb2901..4831ad35e6 100755
--- a/t/t4067-diff-partial-clone.sh
+++ b/t/t4067-diff-partial-clone.sh
@@ -75,6 +75,37 @@ test_expect_success 'diff skips same-OID blobs' '
! grep "want $(cat hash-b)" trace
'
+test_expect_success 'when fetching missing objects, diff skips GITLINKs' '
+ test_when_finished "rm -rf sub server client trace" &&
+
+ test_create_repo sub &&
+ test_commit -C sub first &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ git -C server add a &&
+ git -C server submodule add "file://$(pwd)/sub" &&
+ git -C server commit -m x &&
+
+ test_commit -C server/sub second &&
+ echo another-a >server/a &&
+ git -C server add a sub &&
+ git -C server commit -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ echo a | git hash-object --stdin >hash-old-a &&
+ echo another-a | git hash-object --stdin >hash-new-a &&
+
+ # Ensure that a and another-a are fetched, and check (by successful
+ # execution of the diff) that no invalid OIDs are sent.
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD &&
+ grep "want $(cat hash-old-a)" trace &&
+ grep "want $(cat hash-new-a)" trace
+'
+
test_expect_success 'diff with rename detection batches blobs' '
test_when_finished "rm -rf server client trace" &&
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 3f7f750cc8..4f1e24ecbe 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -1061,4 +1061,56 @@ test_expect_success 'am --quit keeps HEAD where it is' '
test_cmp expected actual
'
+test_expect_success 'am and .gitattibutes' '
+ test_create_repo attributes &&
+ (
+ cd attributes &&
+ test_commit init &&
+ git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
+ git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
+
+ test_commit second &&
+ git checkout -b test HEAD^ &&
+
+ echo "*.txt filter=test conflict-marker-size=10" >.gitattributes &&
+ git add .gitattributes &&
+ test_commit third &&
+
+ echo "This text is smudged." >a.txt &&
+ git add a.txt &&
+ test_commit fourth &&
+
+ git checkout -b removal HEAD^ &&
+ git rm .gitattributes &&
+ git add -u &&
+ test_commit fifth &&
+ git cherry-pick test &&
+
+ git checkout -b conflict third &&
+ echo "This text is different." >a.txt &&
+ git add a.txt &&
+ test_commit sixth &&
+
+ git checkout test &&
+ git format-patch --stdout master..HEAD >patches &&
+ git reset --hard master &&
+ git am patches &&
+ grep "smudged" a.txt &&
+
+ git checkout removal &&
+ git reset --hard &&
+ git format-patch --stdout master..HEAD >patches &&
+ git reset --hard master &&
+ git am patches &&
+ grep "clean" a.txt &&
+
+ git checkout conflict &&
+ git reset --hard &&
+ git format-patch --stdout master..HEAD >patches &&
+ git reset --hard fourth &&
+ test_must_fail git am -3 patches &&
+ grep "<<<<<<<<<<" a.txt
+ )
+'
+
test_done
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index c20209324c..e803ba402e 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -837,6 +837,21 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' '
test_cmp expect.decorate actual
'
+test_expect_success 'decorate-refs-exclude and simplify-by-decoration' '
+ cat >expect.decorate <<-\EOF &&
+ Merge-tag-reach (HEAD -> master)
+ reach (tag: reach, reach)
+ seventh (tag: seventh)
+ Merge-branch-tangle
+ Merge-branch-side-early-part-into-tangle (tangle)
+ tangle-a (tag: tangle-a)
+ EOF
+ git log -n6 --decorate=short --pretty="tformat:%f%d" \
+ --decorate-refs-exclude="*octopus*" \
+ --simplify-by-decoration >actual &&
+ test_cmp expect.decorate actual
+'
+
test_expect_success 'log.decorate config parsing' '
git log --oneline --decorate=full >expect.full &&
git log --oneline --decorate=short >expect.short &&
@@ -1707,4 +1722,11 @@ test_expect_success '--exclude-promisor-objects does not BUG-crash' '
test_must_fail git log --exclude-promisor-objects source-a
'
+test_expect_success 'log --end-of-options' '
+ git update-ref refs/heads/--source HEAD &&
+ git log --end-of-options --source >actual &&
+ git log >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 43b1522ea2..918ada69eb 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -442,6 +442,34 @@ test_expect_success 'Log output with log.mailmap' '
test_cmp expect actual
'
+test_expect_success 'log.mailmap=false disables mailmap' '
+ 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>
+ 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 &&
+ 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>
+ EOF
+ git log --no-use-mailmap | grep Author > actual &&
+ test_cmp expect actual
+'
+
cat >expect <<\EOF
Author: Santa Claus <santa.claus@northpole.xx>
Author: Santa Claus <santa.claus@northpole.xx>
@@ -461,6 +489,11 @@ test_expect_success 'Grep author with log.mailmap' '
test_cmp expect actual
'
+test_expect_success 'log.mailmap is true by default these days' '
+ git log --author Santa | grep Author >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'Only grep replaced author with --use-mailmap' '
git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
test_must_be_empty actual
diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh
index 7c519436ef..6e61f57f09 100755
--- a/t/t4210-log-i18n.sh
+++ b/t/t4210-log-i18n.sh
@@ -1,12 +1,15 @@
#!/bin/sh
test_description='test log with i18n features'
-. ./test-lib.sh
+. ./lib-gettext.sh
# two forms of é
utf8_e=$(printf '\303\251')
latin1_e=$(printf '\351')
+# invalid UTF-8
+invalid_e=$(printf '\303\50)') # ")" at end to close opening "("
+
test_expect_success 'create commits in different encodings' '
test_tick &&
cat >msg <<-EOF &&
@@ -48,9 +51,43 @@ test_expect_success !MINGW 'log --grep does not find non-reencoded values (utf8)
test_must_be_empty actual
'
-test_expect_success 'log --grep does not find non-reencoded values (latin1)' '
+test_expect_success !MINGW 'log --grep does not find non-reencoded values (latin1)' '
git log --encoding=ISO-8859-1 --format=%s --grep=$utf8_e >actual &&
test_must_be_empty actual
'
+for engine in fixed basic extended perl
+do
+ prereq=
+ if test $engine = "perl"
+ then
+ prereq="PCRE"
+ else
+ prereq=""
+ fi
+ force_regex=
+ if test $engine != "fixed"
+ then
+ force_regex=.*
+ fi
+ test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" "
+ cat >expect <<-\EOF &&
+ latin1
+ utf8
+ EOF
+ LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$latin1_e\" >actual &&
+ test_cmp expect actual
+ "
+
+ test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" "
+ LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$utf8_e\" >actual &&
+ test_must_be_empty actual
+ "
+
+ test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" "
+ LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$invalid_e\" >actual &&
+ test_must_be_empty actual
+ "
+done
+
test_done
diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh
index 1db7bd0f59..8319163744 100755
--- a/t/t4211-line-log.sh
+++ b/t/t4211-line-log.sh
@@ -132,4 +132,86 @@ test_expect_success '--raw is forbidden' '
test_must_fail git log -L1,24:b.c --raw
'
+test_expect_success 'setup for checking fancy rename following' '
+ git checkout --orphan moves-start &&
+ git reset --hard &&
+
+ printf "%s\n" 12 13 14 15 b c d e >file-1 &&
+ printf "%s\n" 22 23 24 25 B C D E >file-2 &&
+ git add file-1 file-2 &&
+ test_tick &&
+ git commit -m "Add file-1 and file-2" &&
+ oid_add_f1_f2=$(git rev-parse --short HEAD) &&
+
+ git checkout -b moves-main &&
+ printf "%s\n" 11 12 13 14 15 b c d e >file-1 &&
+ git commit -a -m "Modify file-1 on main" &&
+ oid_mod_f1_main=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 21 22 23 24 25 B C D E >file-2 &&
+ git commit -a -m "Modify file-2 on main #1" &&
+ oid_mod_f2_main_1=$(git rev-parse --short HEAD) &&
+
+ git mv file-1 renamed-1 &&
+ git commit -m "Rename file-1 to renamed-1 on main" &&
+
+ printf "%s\n" 11 12 13 14 15 b c d e f >renamed-1 &&
+ git commit -a -m "Modify renamed-1 on main" &&
+ oid_mod_r1_main=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 21 22 23 24 25 B C D E F >file-2 &&
+ git commit -a -m "Modify file-2 on main #2" &&
+ oid_mod_f2_main_2=$(git rev-parse --short HEAD) &&
+
+ git checkout -b moves-side moves-start &&
+ printf "%s\n" 12 13 14 15 16 b c d e >file-1 &&
+ git commit -a -m "Modify file-1 on side #1" &&
+ oid_mod_f1_side_1=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 22 23 24 25 26 B C D E >file-2 &&
+ git commit -a -m "Modify file-2 on side" &&
+ oid_mod_f2_side=$(git rev-parse --short HEAD) &&
+
+ git mv file-2 renamed-2 &&
+ git commit -m "Rename file-2 to renamed-2 on side" &&
+
+ printf "%s\n" 12 13 14 15 16 a b c d e >file-1 &&
+ git commit -a -m "Modify file-1 on side #2" &&
+ oid_mod_f1_side_2=$(git rev-parse --short HEAD) &&
+
+ printf "%s\n" 22 23 24 25 26 A B C D E >renamed-2 &&
+ git commit -a -m "Modify renamed-2 on side" &&
+ oid_mod_r2_side=$(git rev-parse --short HEAD) &&
+
+ git checkout moves-main &&
+ git merge moves-side &&
+ oid_merge=$(git rev-parse --short HEAD)
+'
+
+test_expect_success 'fancy rename following #1' '
+ cat >expect <<-EOF &&
+ $oid_merge Merge branch '\''moves-side'\'' into moves-main
+ $oid_mod_f1_side_2 Modify file-1 on side #2
+ $oid_mod_f1_side_1 Modify file-1 on side #1
+ $oid_mod_r1_main Modify renamed-1 on main
+ $oid_mod_f1_main Modify file-1 on main
+ $oid_add_f1_f2 Add file-1 and file-2
+ EOF
+ git log -L1:renamed-1 --oneline --no-patch >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'fancy rename following #2' '
+ cat >expect <<-EOF &&
+ $oid_merge Merge branch '\''moves-side'\'' into moves-main
+ $oid_mod_r2_side Modify renamed-2 on side
+ $oid_mod_f2_side Modify file-2 on side
+ $oid_mod_f2_main_2 Modify file-2 on main #2
+ $oid_mod_f2_main_1 Modify file-2 on main #1
+ $oid_add_f1_f2 Add file-1 and file-2
+ EOF
+ git log -L1:renamed-2 --oneline --no-patch >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4214-log-graph-octopus.sh b/t/t4214-log-graph-octopus.sh
index dab96c89aa..3ae8e51e50 100755
--- a/t/t4214-log-graph-octopus.sh
+++ b/t/t4214-log-graph-octopus.sh
@@ -5,6 +5,25 @@ test_description='git log --graph of skewed left octopus merge.'
. ./test-lib.sh
test_expect_success 'set up merge history' '
+ test_commit initial &&
+ for i in 1 2 3 4 ; do
+ git checkout master -b $i || return $?
+ # Make tag name different from branch name, to avoid
+ # ambiguity error when calling checkout.
+ test_commit $i $i $i tag$i || return $?
+ done &&
+ git checkout 1 -b merge &&
+ test_merge octopus-merge 1 2 3 4 &&
+ test_commit after-merge &&
+ git checkout 1 -b L &&
+ test_commit left &&
+ git checkout 4 -b crossover &&
+ test_commit after-4 &&
+ git checkout initial -b more-L &&
+ test_commit after-initial
+'
+
+test_expect_success 'log --graph with tricky octopus merge, no color' '
cat >expect.uncolored <<-\EOF &&
* left
| *---. octopus-merge
@@ -19,6 +38,13 @@ test_expect_success 'set up merge history' '
|/
* 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
@@ -33,33 +59,11 @@ test_expect_success 'set up merge history' '
<MAGENTA>|<RESET><MAGENTA>/<RESET>
* initial
EOF
- test_commit initial &&
- for i in 1 2 3 4 ; do
- git checkout master -b $i || return $?
- # Make tag name different from branch name, to avoid
- # ambiguity error when calling checkout.
- test_commit $i $i $i tag$i || return $?
- done &&
- git checkout 1 -b merge &&
- test_tick &&
- git merge -m octopus-merge 1 2 3 4 &&
- git checkout 1 -b L &&
- test_commit left
-'
-
-test_expect_success 'log --graph with tricky octopus merge with colors' '
- test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
- git log --color=always --graph --date-order --pretty=tformat:%s --all >actual.colors.raw &&
+ git log --color=always --graph --date-order --pretty=tformat:%s left octopus-merge >actual.colors.raw &&
test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
test_cmp expect.colors actual.colors
'
-test_expect_success 'log --graph with tricky octopus merge, no color' '
- git log --color=never --graph --date-order --pretty=tformat:%s --all >actual.raw &&
- sed "s/ *\$//" actual.raw >actual &&
- test_cmp expect.uncolored actual
-'
-
# Repeat the previous two tests with "normal" octopus merge (i.e.,
# without the first parent skewing to the "left" branch column).
@@ -76,7 +80,7 @@ test_expect_success 'log --graph with normal octopus merge, no color' '
|/
* initial
EOF
- git log --color=never --graph --date-order --pretty=tformat:%s merge >actual.raw &&
+ git log --color=never --graph --date-order --pretty=tformat:%s octopus-merge >actual.raw &&
sed "s/ *\$//" actual.raw >actual &&
test_cmp expect.uncolored actual
'
@@ -95,8 +99,283 @@ test_expect_success 'log --graph with normal octopus merge with colors' '
* initial
EOF
test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
- git log --color=always --graph --date-order --pretty=tformat:%s merge >actual.colors.raw &&
+ git log --color=always --graph --date-order --pretty=tformat:%s octopus-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with normal octopus merge and child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-merge
+ *---. octopus-merge
+ |\ \ \
+ | | | * 4
+ | | * | 3
+ | | |/
+ | * | 2
+ | |/
+ * | 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_failure 'log --graph with normal octopus and child merge with colors' '
+ cat >expect.colors <<-\EOF &&
+ * after-merge
+ *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge
+ <GREEN>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <MAGENTA>\<RESET>
+ <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4
+ <GREEN>|<RESET> <YELLOW>|<RESET> * <MAGENTA>|<RESET> 3
+ <GREEN>|<RESET> <YELLOW>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ <GREEN>|<RESET> * <MAGENTA>|<RESET> 2
+ <GREEN>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ * <MAGENTA>|<RESET> 1
+ <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ * initial
+ EOF
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ git log --color=always --graph --date-order --pretty=tformat:%s after-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with tricky octopus merge and its child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * left
+ | * after-merge
+ | *---. octopus-merge
+ | |\ \ \
+ |/ / / /
+ | | | * 4
+ | | * | 3
+ | | |/
+ | * | 2
+ | |/
+ * | 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s left after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_failure '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> <BLUE>|<RESET> <MAGENTA>|<RESET> * 4
+ <RED>|<RESET> <BLUE>|<RESET> * <CYAN>|<RESET> 3
+ <RED>|<RESET> <BLUE>|<RESET> <CYAN>|<RESET><CYAN>/<RESET>
+ <RED>|<RESET> * <CYAN>|<RESET> 2
+ <RED>|<RESET> <CYAN>|<RESET><CYAN>/<RESET>
+ * <CYAN>|<RESET> 1
+ <CYAN>|<RESET><CYAN>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s left after-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with crossover in octopus merge, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-4
+ | *---. octopus-merge
+ | |\ \ \
+ | |_|_|/
+ |/| | |
+ * | | | 4
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-4 octopus-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_failure 'log --graph with crossover in octopus merge with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-4
+ <RED>|<RESET> *<BLUE>-<RESET><BLUE>-<RESET><RED>-<RESET><RED>.<RESET> octopus-merge
+ <RED>|<RESET> <GREEN>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <RED>\<RESET>
+ <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET>
+ * <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> 4
+ <MAGENTA>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 3
+ <MAGENTA>|<RESET> <GREEN>|<RESET><MAGENTA>_<RESET><YELLOW>|<RESET><MAGENTA>/<RESET>
+ <MAGENTA>|<RESET><MAGENTA>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET>
+ <MAGENTA>|<RESET> <GREEN>|<RESET> * 2
+ <MAGENTA>|<RESET> <GREEN>|<RESET><MAGENTA>/<RESET>
+ <MAGENTA>|<RESET><MAGENTA>/<RESET><GREEN>|<RESET>
+ <MAGENTA>|<RESET> * 1
+ <MAGENTA>|<RESET><MAGENTA>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-4 octopus-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with crossover in octopus merge and its child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-4
+ | * after-merge
+ | *---. octopus-merge
+ | |\ \ \
+ | |_|_|/
+ |/| | |
+ * | | | 4
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-4 after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_failure 'log --graph with crossover in octopus merge and its child with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-4
+ <RED>|<RESET> * after-merge
+ <RED>|<RESET> *<MAGENTA>-<RESET><MAGENTA>-<RESET><RED>-<RESET><RED>.<RESET> octopus-merge
+ <RED>|<RESET> <YELLOW>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET> <RED>\<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>_<RESET><MAGENTA>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET>
+ * <YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET> 4
+ <CYAN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 3
+ <CYAN>|<RESET> <YELLOW>|<RESET><CYAN>_<RESET><BLUE>|<RESET><CYAN>/<RESET>
+ <CYAN>|<RESET><CYAN>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET>
+ <CYAN>|<RESET> <YELLOW>|<RESET> * 2
+ <CYAN>|<RESET> <YELLOW>|<RESET><CYAN>/<RESET>
+ <CYAN>|<RESET><CYAN>/<RESET><YELLOW>|<RESET>
+ <CYAN>|<RESET> * 1
+ <CYAN>|<RESET><CYAN>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-4 after-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with unrelated commit and octopus tip, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-initial
+ | *---. octopus-merge
+ | |\ \ \
+ | | | | * 4
+ | |_|_|/
+ |/| | |
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-initial octopus-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_success 'log --graph with unrelated commit and octopus tip with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-initial
+ <RED>|<RESET> *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge
+ <RED>|<RESET> <GREEN>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <MAGENTA>\<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4
+ <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 3
+ <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET>
+ <RED>|<RESET> <GREEN>|<RESET> * 2
+ <RED>|<RESET> <GREEN>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><GREEN>|<RESET>
+ <RED>|<RESET> * 1
+ <RED>|<RESET><RED>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-initial octopus-merge >actual.colors.raw &&
+ test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
+ test_cmp expect.colors actual.colors
+'
+
+test_expect_success 'log --graph with unrelated commit and octopus child, no color' '
+ cat >expect.uncolored <<-\EOF &&
+ * after-initial
+ | * after-merge
+ | *---. octopus-merge
+ | |\ \ \
+ | | | | * 4
+ | |_|_|/
+ |/| | |
+ | | | * 3
+ | |_|/
+ |/| |
+ | | * 2
+ | |/
+ |/|
+ | * 1
+ |/
+ * initial
+ EOF
+ git log --color=never --graph --date-order --pretty=tformat:%s after-initial after-merge >actual.raw &&
+ sed "s/ *\$//" actual.raw >actual &&
+ test_cmp expect.uncolored actual
+'
+
+test_expect_failure 'log --graph with unrelated commit and octopus child with colors' '
+ test_config log.graphColors red,green,yellow,blue,magenta,cyan &&
+ cat >expect.colors <<-\EOF &&
+ * after-initial
+ <RED>|<RESET> * after-merge
+ <RED>|<RESET> *<MAGENTA>-<RESET><MAGENTA>-<RESET><CYAN>-<RESET><CYAN>.<RESET> octopus-merge
+ <RED>|<RESET> <YELLOW>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET> <CYAN>\<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET> * 4
+ <RED>|<RESET> <YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>_<RESET><MAGENTA>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 3
+ <RED>|<RESET> <YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET>
+ <RED>|<RESET> <YELLOW>|<RESET> * 2
+ <RED>|<RESET> <YELLOW>|<RESET><RED>/<RESET>
+ <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET>
+ <RED>|<RESET> * 1
+ <RED>|<RESET><RED>/<RESET>
+ * initial
+ EOF
+ git log --color=always --graph --date-order --pretty=tformat:%s after-initial after-merge >actual.colors.raw &&
test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors &&
test_cmp expect.colors actual.colors
'
+
test_done
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 602bfd9574..37655a237c 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -94,6 +94,13 @@ check_tar() {
'
}
+test_expect_success 'setup' '
+ test_oid_cache <<-EOF
+ obj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a
+ obj sha256:3c666f798798601571f5cec0adb57ce4aba8546875e7693177e0535f34d2c49b
+ EOF
+'
+
test_expect_success \
'populate workdir' \
'mkdir a &&
@@ -369,11 +376,10 @@ test_lazy_prereq TAR_HUGE '
'
test_expect_success LONG_IS_64BIT 'set up repository with huge blob' '
- obj_d=19 &&
- obj_f=f9c8273ec45a8938e6999cb59b3ff66739902a &&
- obj=${obj_d}${obj_f} &&
- mkdir -p .git/objects/$obj_d &&
- cp "$TEST_DIRECTORY"/t5000/$obj .git/objects/$obj_d/$obj_f &&
+ obj=$(test_oid obj) &&
+ path=$(test_oid_to_path $obj) &&
+ mkdir -p .git/objects/$(dirname $path) &&
+ cp "$TEST_DIRECTORY"/t5000/huge-object .git/objects/$path &&
rm -f .git/index &&
git update-index --add --cacheinfo 100644,$obj,huge &&
git commit -m huge
diff --git a/t/t5000/19f9c8273ec45a8938e6999cb59b3ff66739902a b/t/t5000/huge-object
index 5cbe9ec312..5cbe9ec312 100644
--- a/t/t5000/19f9c8273ec45a8938e6999cb59b3ff66739902a
+++ b/t/t5000/huge-object
Binary files differ
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
index 271eb5a1fd..3e7b23cb32 100755
--- a/t/t5004-archive-corner-cases.sh
+++ b/t/t5004-archive-corner-cases.sh
@@ -204,4 +204,23 @@ test_expect_success EXPENSIVE,LONG_IS_64BIT,UNZIP,UNZIP_ZIP64_SUPPORT,ZIPINFO \
grep $size big.lst
'
+build_tree() {
+ perl -e '
+ my $hash = $ARGV[0];
+ foreach my $order (2..6) {
+ $first = 10 ** $order;
+ foreach my $i (-13..-9) {
+ my $name = "a" x ($first + $i);
+ print "100644 blob $hash\t$name\n"
+ }
+ }
+ ' "$1"
+}
+
+test_expect_success 'tar archive with long paths' '
+ blob=$(echo foo | git hash-object -w --stdin) &&
+ tree=$(build_tree $blob | git mktree) &&
+ git archive -o long_paths.tar $tree
+'
+
test_done
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index a26c8ba9a2..6640329ebf 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -21,15 +21,9 @@ has_any () {
}
test_expect_success 'setup repo with moderate-sized history' '
- for i in $(test_seq 1 10)
- do
- test_commit $i
- done &&
+ test_commit_bulk --id=file 100 &&
git checkout -b other HEAD~5 &&
- for i in $(test_seq 1 10)
- do
- test_commit side-$i
- done &&
+ test_commit_bulk --id=side 10 &&
git checkout master &&
bitmaptip=$(git rev-parse master) &&
blob=$(echo tagged-blob | git hash-object -w --stdin) &&
@@ -106,10 +100,7 @@ test_expect_success 'clone from bitmapped repository' '
'
test_expect_success 'setup further non-bitmapped commits' '
- for i in $(test_seq 1 10)
- do
- test_commit further-$i
- done
+ test_commit_bulk --id=further 10
'
rev_list_tests 'partial bitmap'
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index 22cb9d6643..d42b3efe39 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -23,11 +23,10 @@ test_expect_success 'write graph with no packs' '
test_path_is_missing info/commit-graph
'
-test_expect_success 'close with correct error on bad input' '
+test_expect_success 'exit with correct error on bad input to --stdin-packs' '
cd "$TRASH_DIRECTORY/full" &&
echo doesnotexist >in &&
- { git commit-graph write --stdin-packs <in 2>stderr; ret=$?; } &&
- test "$ret" = 1 &&
+ test_expect_code 1 git commit-graph write --stdin-packs <in 2>stderr &&
test_i18ngrep "error adding pack" stderr
'
@@ -41,6 +40,15 @@ test_expect_success 'create commits and repack' '
git repack
'
+test_expect_success 'exit with correct error on bad input to --stdin-commits' '
+ cd "$TRASH_DIRECTORY/full" &&
+ echo HEAD | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
+ test_i18ngrep "invalid commit object id" stderr &&
+ # valid tree OID, but not a commit OID
+ git rev-parse HEAD^{tree} | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
+ test_i18ngrep "invalid commit object id" stderr
+'
+
graph_git_two_modes() {
git -c core.commitGraph=true $1 >output
git -c core.commitGraph=false $1 >expect
@@ -116,6 +124,42 @@ test_expect_success 'Add more commits' '
git repack
'
+test_expect_success 'commit-graph write progress off for redirected stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph write 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'commit-graph write force progress on for stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph write --progress 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'commit-graph write with the --no-progress option' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph write --no-progress 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'commit-graph verify progress off for redirected stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph verify 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'commit-graph verify force progress on for stderr' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph verify --progress 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'commit-graph verify with the --no-progress option' '
+ cd "$TRASH_DIRECTORY/full" &&
+ git commit-graph verify --no-progress 2>err &&
+ test_line_count = 0 err
+'
+
# Current graph structure:
#
# __M3___
@@ -577,4 +621,47 @@ test_expect_success 'get_commit_tree_in_graph works for non-the_repository' '
test_cmp expect actual
'
+test_expect_success 'corrupt commit-graph write (broken parent)' '
+ rm -rf repo &&
+ git init repo &&
+ (
+ cd repo &&
+ empty="$(git mktree </dev/null)" &&
+ cat >broken <<-EOF &&
+ tree $empty
+ parent 0000000000000000000000000000000000000000
+ author whatever <whatever@example.com> 1234 -0000
+ committer whatever <whatever@example.com> 1234 -0000
+
+ broken commit
+ EOF
+ broken="$(git hash-object -w -t commit --literally broken)" &&
+ git commit-tree -p "$broken" -m "good commit" "$empty" >good &&
+ test_must_fail git commit-graph write --stdin-commits \
+ <good 2>test_err &&
+ test_i18ngrep "unable to parse commit" test_err
+ )
+'
+
+test_expect_success 'corrupt commit-graph write (missing tree)' '
+ rm -rf repo &&
+ git init repo &&
+ (
+ cd repo &&
+ tree="$(git mktree </dev/null)" &&
+ cat >broken <<-EOF &&
+ parent 0000000000000000000000000000000000000000
+ author whatever <whatever@example.com> 1234 -0000
+ committer whatever <whatever@example.com> 1234 -0000
+
+ broken commit
+ EOF
+ broken="$(git hash-object -w -t commit --literally broken)" &&
+ git commit-tree -p "$broken" -m "good" "$tree" >good &&
+ test_must_fail git commit-graph write --stdin-commits \
+ <good 2>test_err &&
+ test_i18ngrep "unable to get tree for" test_err
+ )
+'
+
test_done
diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh
index 19aa40de15..115aabd141 100755
--- a/t/t5324-split-commit-graph.sh
+++ b/t/t5324-split-commit-graph.sh
@@ -320,7 +320,9 @@ test_expect_success 'add octopus merge' '
git merge commits/3 commits/4 &&
git branch merge/octopus &&
git commit-graph write --reachable --split &&
- git commit-graph verify &&
+ git commit-graph verify --progress 2>err &&
+ test_line_count = 3 err &&
+ test_i18ngrep ! warning err &&
test_line_count = 3 $graphdir/commit-graph-chain
'
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 1c71c0ec77..6b97923964 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -708,13 +708,22 @@ do
# file with scheme
for p in file
do
- test_expect_success "fetch-pack --diag-url $p://$h/$r" '
+ test_expect_success !MINGW "fetch-pack --diag-url $p://$h/$r" '
check_prot_path $p://$h/$r $p "/$r"
'
+ test_expect_success MINGW "fetch-pack --diag-url $p://$h/$r" '
+ check_prot_path $p://$h/$r $p "//$h/$r"
+ '
+ test_expect_success MINGW "fetch-pack --diag-url $p:///$r" '
+ check_prot_path $p:///$r $p "/$r"
+ '
# No "/~" -> "~" conversion for file
- test_expect_success "fetch-pack --diag-url $p://$h/~$r" '
+ test_expect_success !MINGW "fetch-pack --diag-url $p://$h/~$r" '
check_prot_path $p://$h/~$r $p "/~$r"
'
+ test_expect_success MINGW "fetch-pack --diag-url $p://$h/~$r" '
+ check_prot_path $p://$h/~$r $p "//$h/~$r"
+ '
done
# file without scheme
for h in nohost nohost:12 [::1] [::1]:23 [ [:aa
@@ -783,6 +792,44 @@ test_expect_success 'clone shallow since selects no commits' '
)
'
+# A few subtle things about the request in this test:
+#
+# - the server must have commit-graphs present and enabled
+#
+# - the history is such that our want/have share a common ancestor ("base"
+# here)
+#
+# - we send only a single have, which is fewer than a normal client would
+# send. This ensures that we don't parse "base" up front with
+# parse_object(), but rather traverse to it as a parent while deciding if we
+# can stop the "have" negotiation, and call parse_commit(). The former
+# sees the actual object data and so always loads the three oid, whereas the
+# latter will try to load it lazily.
+#
+# - we must use protocol v2, because it handles the "have" negotiation before
+# processing the shallow directives
+#
+test_expect_success 'shallow since with commit graph and already-seen commit' '
+ test_create_repo shallow-since-graph &&
+ (
+ cd shallow-since-graph &&
+ test_commit base &&
+ test_commit master &&
+ git checkout -b other HEAD^ &&
+ test_commit other &&
+ git commit-graph write --reachable &&
+ git config core.commitGraph true &&
+
+ GIT_PROTOCOL=version=2 git upload-pack . <<-EOF >/dev/null
+ 0012command=fetch
+ 00010013deepen-since 1
+ 0032want $(git rev-parse other)
+ 0032have $(git rev-parse master)
+ 0000
+ EOF
+ )
+'
+
test_expect_success 'shallow clone exclude tag two' '
test_create_repo shallow-exclude &&
(
@@ -920,4 +967,7 @@ test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 8248923df2..4b60282689 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -931,6 +931,29 @@ test_expect_success C_LOCALE_OUTPUT 'fetch compact output' '
test_cmp expect actual
'
+test_expect_success '--no-show-forced-updates' '
+ mkdir forced-updates &&
+ (
+ cd forced-updates &&
+ git init &&
+ test_commit 1 &&
+ test_commit 2
+ ) &&
+ git clone forced-updates forced-update-clone &&
+ git clone forced-updates no-forced-update-clone &&
+ git -C forced-updates reset --hard HEAD~1 &&
+ (
+ cd forced-update-clone &&
+ git fetch --show-forced-updates origin 2>output &&
+ test_i18ngrep "(forced update)" output
+ ) &&
+ (
+ cd no-forced-update-clone &&
+ git fetch --no-show-forced-updates origin 2>output &&
+ test_i18ngrep ! "(forced update)" output
+ )
+'
+
setup_negotiation_tip () {
SERVER="$1"
URL="$2"
@@ -1007,27 +1030,7 @@ test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protoc
check_negotiation_tip
'
-test_expect_success '--no-show-forced-updates' '
- mkdir forced-updates &&
- (
- cd forced-updates &&
- git init &&
- test_commit 1 &&
- test_commit 2
- ) &&
- git clone forced-updates forced-update-clone &&
- git clone forced-updates no-forced-update-clone &&
- git -C forced-updates reset --hard HEAD~1 &&
- (
- cd forced-update-clone &&
- git fetch --show-forced-updates origin 2>output &&
- test_i18ngrep "(forced update)" output
- ) &&
- (
- cd no-forced-update-clone &&
- git fetch --no-show-forced-updates origin 2>output &&
- ! test_i18ngrep "(forced update)" output
- )
-'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
test_done
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index e3c4a48c85..43e1d8d4d2 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -267,8 +267,7 @@ test_expect_success 'ls-remote --symref omits filtered-out matches' '
'
test_lazy_prereq GIT_DAEMON '
- test_tristate GIT_TEST_GIT_DAEMON &&
- test "$GIT_TEST_GIT_DAEMON" != false
+ git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON
'
# This test spawns a daemon, so run it only if the user would be OK with
diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh
index 5426d4b5ab..de8e2f1531 100755
--- a/t/t5514-fetch-multiple.sh
+++ b/t/t5514-fetch-multiple.sh
@@ -183,4 +183,15 @@ test_expect_success 'git fetch --all --tags' '
test_cmp expect test8/output
'
+test_expect_success 'parallel' '
+ git remote add one ./bogus1 &&
+ git remote add two ./bogus2 &&
+
+ test_must_fail env GIT_TRACE="$PWD/trace" \
+ git fetch --jobs=2 --multiple one two 2>err &&
+ grep "preparing to run up to 2 tasks" trace &&
+ test_i18ngrep "could not fetch .one.*128" err &&
+ test_i18ngrep "could not fetch .two.*128" err
+'
+
test_done
diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh
index e55d8474ef..961eb35c99 100755
--- a/t/t5515-fetch-merge-logic.sh
+++ b/t/t5515-fetch-merge-logic.sh
@@ -12,9 +12,6 @@ GIT_TEST_PROTOCOL_VERSION=
. ./test-lib.sh
-LF='
-'
-
test_expect_success setup '
GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" &&
GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" &&
diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh
index c05a661400..e4edd56404 100755
--- a/t/t5517-push-mirror.sh
+++ b/t/t5517-push-mirror.sh
@@ -265,4 +265,14 @@ test_expect_success 'remote.foo.mirror=no has no effect' '
'
+test_expect_success 'push to mirrored repository with refspec fails' '
+ mk_repo_pair &&
+ (
+ cd master &&
+ echo one >foo && git add foo && git commit -m one &&
+ git config --add remote.up.mirror true &&
+ test_must_fail git push up master
+ )
+'
+
test_done
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 66f0b64d39..97a67728ca 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -255,4 +255,7 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
git -C client fsck
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 2e4802e206..4c970787b0 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -177,6 +177,91 @@ test_expect_success 'push (chunked)' '
test $HEAD = $(git rev-parse --verify HEAD))
'
+test_expect_success 'push --atomic also prevents branch creation, reports collateral' '
+ # Setup upstream repo - empty for now
+ d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
+ git init --bare "$d" &&
+ test_config -C "$d" http.receivepack true &&
+ up="$HTTPD_URL"/smart/atomic-branches.git &&
+
+ # Tell "$up" about three branches for now
+ test_commit atomic1 &&
+ test_commit atomic2 &&
+ git branch collateral &&
+ git branch other &&
+ git push "$up" master collateral other &&
+
+ # collateral is a valid push, but should be failed by atomic push
+ git checkout collateral &&
+ test_commit collateral1 &&
+
+ # Make master incompatible with upstream to provoke atomic
+ git checkout master &&
+ git reset --hard HEAD^ &&
+
+ # Add a new branch which should be failed by atomic push. This is a
+ # regression case.
+ git branch atomic &&
+
+ # --atomic should cause entire push to be rejected
+ test_must_fail git push --atomic "$up" master atomic collateral 2>output &&
+
+ # the new branch should not have been created upstream
+ test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
+
+ # upstream should still reflect atomic2, the last thing we pushed
+ # successfully
+ git rev-parse atomic2 >expected &&
+ # on master...
+ git -C "$d" rev-parse refs/heads/master >actual &&
+ test_cmp expected actual &&
+ # ...and collateral.
+ git -C "$d" rev-parse refs/heads/collateral >actual &&
+ test_cmp expected actual &&
+
+ # the failed refs should be indicated to the user
+ grep "^ ! .*rejected.* master -> master" output &&
+
+ # the collateral failure refs should be indicated to the user
+ grep "^ ! .*rejected.* atomic -> atomic .*atomic push failed" output &&
+ grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output
+'
+
+test_expect_success 'push --atomic fails on server-side errors' '
+ # Use previously set up repository
+ d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
+ test_config -C "$d" http.receivepack true &&
+ up="$HTTPD_URL"/smart/atomic-branches.git &&
+
+ # break ref updates for other on the remote site
+ mkdir "$d/refs/heads/other.lock" &&
+
+ # add the new commit to other
+ git branch -f other collateral &&
+
+ # --atomic should cause entire push to be rejected
+ test_must_fail git push --atomic "$up" atomic other 2>output &&
+
+ # the new branch should not have been created upstream
+ test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
+
+ # upstream should still reflect atomic2, the last thing we pushed
+ # successfully
+ git rev-parse atomic2 >expected &&
+ # ...to other.
+ git -C "$d" rev-parse refs/heads/other >actual &&
+ test_cmp expected actual &&
+
+ # the new branch should not have been created upstream
+ test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
+
+ # the failed refs should be indicated to the user
+ grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output &&
+
+ # the collateral failure refs should be indicated to the user
+ grep "^ ! .*rejected.* atomic -> atomic .*atomic transaction failed" output
+'
+
test_expect_success 'push --all can push to empty repo' '
d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
git init --bare "$d" &&
@@ -213,7 +298,7 @@ test_expect_success TTY 'push shows progress when stderr is a tty' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit noisy &&
test_terminal git push >output 2>&1 &&
- test_i18ngrep "Writing objects" output
+ test_i18ngrep "^Writing objects" output
'
test_expect_success TTY 'push --quiet silences status and progress' '
@@ -228,7 +313,7 @@ test_expect_success TTY 'push --no-progress silences progress but not status' '
test_commit no-progress &&
test_terminal git push --no-progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
- test_i18ngrep ! "Writing objects" output
+ test_i18ngrep ! "^Writing objects" output
'
test_expect_success 'push --progress shows progress to non-tty' '
@@ -236,7 +321,7 @@ test_expect_success 'push --progress shows progress to non-tty' '
test_commit progress &&
git push --progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
- test_i18ngrep "Writing objects" output
+ test_i18ngrep "^Writing objects" output
'
test_expect_success 'http push gives sane defaults to reflog' '
diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh
index 6d1d59c9b1..04b34c4de1 100755
--- a/t/t5545-push-options.sh
+++ b/t/t5545-push-options.sh
@@ -278,4 +278,7 @@ test_expect_success 'push options keep quoted characters intact (http)' '
test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git/hooks/pre-receive.push_options
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh
new file mode 100755
index 0000000000..81975ad8f9
--- /dev/null
+++ b/t/t5553-set-upstream.sh
@@ -0,0 +1,178 @@
+#!/bin/sh
+
+test_description='"git fetch/pull --set-upstream" basic tests.'
+. ./test-lib.sh
+
+check_config () {
+ printf "%s\n" "$2" "$3" >"expect.$1" &&
+ {
+ git config "branch.$1.remote" && git config "branch.$1.merge"
+ } >"actual.$1" &&
+ test_cmp "expect.$1" "actual.$1"
+}
+
+check_config_missing () {
+ test_expect_code 1 git config "branch.$1.remote" &&
+ test_expect_code 1 git config "branch.$1.merge"
+}
+
+clear_config () {
+ for branch in "$@"; do
+ test_might_fail git config --unset-all "branch.$branch.remote"
+ test_might_fail git config --unset-all "branch.$branch.merge"
+ done
+}
+
+ensure_fresh_upstream () {
+ rm -rf parent && git init --bare parent
+}
+
+test_expect_success 'setup bare parent fetch' '
+ ensure_fresh_upstream &&
+ git remote add upstream parent
+'
+
+test_expect_success 'setup commit on master and other fetch' '
+ test_commit one &&
+ git push upstream master &&
+ git checkout -b other &&
+ test_commit two &&
+ git push upstream other
+'
+
+# tests for fetch --set-upstream
+
+test_expect_success 'fetch --set-upstream does not set upstream w/o branch' '
+ clear_config master other &&
+ git checkout master &&
+ git fetch --set-upstream upstream &&
+ check_config_missing master &&
+ check_config_missing other
+'
+
+test_expect_success 'fetch --set-upstream upstream master sets branch master but not other' '
+ clear_config master other &&
+ git fetch --set-upstream upstream master &&
+ check_config master upstream refs/heads/master &&
+ check_config_missing other
+'
+
+test_expect_success 'fetch --set-upstream upstream other sets branch other' '
+ clear_config master other &&
+ git fetch --set-upstream upstream other &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other
+'
+
+test_expect_success 'fetch --set-upstream master:other does not set the branch other2' '
+ clear_config other2 &&
+ git fetch --set-upstream upstream master:other2 &&
+ check_config_missing other2
+'
+
+test_expect_success 'fetch --set-upstream http://nosuchdomain.example.com fails with invalid url' '
+ # master explicitly not cleared, we check that it is not touched from previous value
+ clear_config other other2 &&
+ test_must_fail git fetch --set-upstream http://nosuchdomain.example.com &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+test_expect_success 'fetch --set-upstream with valid URL sets upstream to URL' '
+ clear_config other other2 &&
+ url="file://'"$PWD"'" &&
+ git fetch --set-upstream "$url" &&
+ check_config master "$url" HEAD &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+# tests for pull --set-upstream
+
+test_expect_success 'setup bare parent pull' '
+ git remote rm upstream &&
+ ensure_fresh_upstream &&
+ git remote add upstream parent
+'
+
+test_expect_success 'setup commit on master and other pull' '
+ test_commit three &&
+ git push --tags upstream master &&
+ test_commit four &&
+ git push upstream other
+'
+
+test_expect_success 'pull --set-upstream upstream master sets branch master but not other' '
+ clear_config master other &&
+ git pull --set-upstream upstream master &&
+ check_config master upstream refs/heads/master &&
+ check_config_missing other
+'
+
+test_expect_success 'pull --set-upstream master:other2 does not set the branch other2' '
+ clear_config other2 &&
+ git pull --set-upstream upstream master:other2 &&
+ check_config_missing other2
+'
+
+test_expect_success 'pull --set-upstream upstream other sets branch master' '
+ clear_config master other &&
+ git pull --set-upstream upstream other &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other
+'
+
+test_expect_success 'pull --set-upstream upstream tag does not set the tag' '
+ clear_config three &&
+ git pull --tags --set-upstream upstream three &&
+ check_config_missing three
+'
+
+test_expect_success 'pull --set-upstream http://nosuchdomain.example.com fails with invalid url' '
+ # master explicitly not cleared, we check that it is not touched from previous value
+ clear_config other other2 three &&
+ test_must_fail git pull --set-upstream http://nosuchdomain.example.com &&
+ check_config master upstream refs/heads/other &&
+ check_config_missing other &&
+ check_config_missing other2 &&
+ check_config_missing three
+'
+
+test_expect_success 'pull --set-upstream upstream HEAD sets branch HEAD' '
+ clear_config master other &&
+ git pull --set-upstream upstream HEAD &&
+ check_config master upstream HEAD &&
+ git checkout other &&
+ git pull --set-upstream upstream HEAD &&
+ check_config other upstream HEAD
+'
+
+test_expect_success 'pull --set-upstream upstream with more than one branch does nothing' '
+ clear_config master three &&
+ git pull --set-upstream upstream master three &&
+ check_config_missing master &&
+ check_config_missing three
+'
+
+test_expect_success 'pull --set-upstream with valid URL sets upstream to URL' '
+ clear_config master other other2 &&
+ git checkout master &&
+ url="file://'"$PWD"'" &&
+ git pull --set-upstream "$url" &&
+ check_config master "$url" HEAD &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+test_expect_success 'pull --set-upstream with valid URL and branch sets branch' '
+ clear_config master other other2 &&
+ git checkout master &&
+ url="file://'"$PWD"'" &&
+ git pull --set-upstream "$url" master &&
+ check_config master "$url" refs/heads/master &&
+ check_config_missing other &&
+ check_config_missing other2
+'
+
+test_done
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 37d76808d4..ad8c41176e 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -434,7 +434,6 @@ test_expect_success 'double quoted plink.exe in GIT_SSH_COMMAND' '
expect_ssh "-v -P 123" myhost src
'
-SQ="'"
test_expect_success 'single quoted plink.exe in GIT_SSH_COMMAND' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
GIT_SSH_COMMAND="$SQ$TRASH_DIRECTORY/plink.exe$SQ -v" \
@@ -654,7 +653,8 @@ partial_clone () {
git -C client fsck &&
# Ensure that unneeded blobs are not inadvertently fetched.
- test_config -C client extensions.partialclone "not a remote" &&
+ test_config -C client remote.origin.promisor "false" &&
+ git -C client config --unset remote.origin.partialclonefilter &&
test_must_fail git -C client cat-file -e "$HASH1" &&
# But this blob was fetched, because clone performs an initial checkout
@@ -739,4 +739,7 @@ test_expect_success 'partial clone using HTTP' '
partial_clone "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh
index 4320082b1b..4894237ab8 100755
--- a/t/t5604-clone-reference.sh
+++ b/t/t5604-clone-reference.sh
@@ -221,4 +221,137 @@ test_expect_success 'clone, dissociate from alternates' '
( cd C && git fsck )
'
+test_expect_success 'setup repo with garbage in objects/*' '
+ git init S &&
+ (
+ cd S &&
+ test_commit A &&
+
+ cd .git/objects &&
+ >.some-hidden-file &&
+ >some-file &&
+ mkdir .some-hidden-dir &&
+ >.some-hidden-dir/some-file &&
+ >.some-hidden-dir/.some-dot-file &&
+ mkdir some-dir &&
+ >some-dir/some-file &&
+ >some-dir/.some-dot-file
+ )
+'
+
+test_expect_success 'clone a repo with garbage in objects/*' '
+ for option in --local --no-hardlinks --shared --dissociate
+ do
+ git clone $option S S$option || return 1 &&
+ git -C S$option fsck || return 1
+ done &&
+ find S-* -name "*some*" | sort >actual &&
+ cat >expected <<-EOF &&
+ S--dissociate/.git/objects/.some-hidden-dir
+ S--dissociate/.git/objects/.some-hidden-dir/.some-dot-file
+ S--dissociate/.git/objects/.some-hidden-dir/some-file
+ S--dissociate/.git/objects/.some-hidden-file
+ S--dissociate/.git/objects/some-dir
+ S--dissociate/.git/objects/some-dir/.some-dot-file
+ S--dissociate/.git/objects/some-dir/some-file
+ S--dissociate/.git/objects/some-file
+ S--local/.git/objects/.some-hidden-dir
+ S--local/.git/objects/.some-hidden-dir/.some-dot-file
+ S--local/.git/objects/.some-hidden-dir/some-file
+ S--local/.git/objects/.some-hidden-file
+ S--local/.git/objects/some-dir
+ S--local/.git/objects/some-dir/.some-dot-file
+ S--local/.git/objects/some-dir/some-file
+ S--local/.git/objects/some-file
+ S--no-hardlinks/.git/objects/.some-hidden-dir
+ S--no-hardlinks/.git/objects/.some-hidden-dir/.some-dot-file
+ S--no-hardlinks/.git/objects/.some-hidden-dir/some-file
+ S--no-hardlinks/.git/objects/.some-hidden-file
+ S--no-hardlinks/.git/objects/some-dir
+ S--no-hardlinks/.git/objects/some-dir/.some-dot-file
+ S--no-hardlinks/.git/objects/some-dir/some-file
+ S--no-hardlinks/.git/objects/some-file
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success SYMLINKS 'setup repo with manually symlinked or unknown files at objects/' '
+ git init T &&
+ (
+ cd T &&
+ git config gc.auto 0 &&
+ test_commit A &&
+ git gc &&
+ test_commit B &&
+
+ cd .git/objects &&
+ mv pack packs &&
+ ln -s packs pack &&
+ find ?? -type d >loose-dirs &&
+ last_loose=$(tail -n 1 loose-dirs) &&
+ mv $last_loose a-loose-dir &&
+ ln -s a-loose-dir $last_loose &&
+ first_loose=$(head -n 1 loose-dirs) &&
+ rm -f loose-dirs &&
+
+ cd $first_loose &&
+ obj=$(ls *) &&
+ mv $obj ../an-object &&
+ ln -s ../an-object $obj &&
+
+ cd ../ &&
+ find . -type f | sort >../../../T.objects-files.raw &&
+ find . -type l | sort >../../../T.objects-symlinks.raw &&
+ echo unknown_content >unknown_file
+ ) &&
+ git -C T fsck &&
+ git -C T rev-list --all --objects >T.objects
+'
+
+
+test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at objects/' '
+ for option in --local --no-hardlinks --shared --dissociate
+ do
+ git clone $option T T$option || return 1 &&
+ git -C T$option fsck || return 1 &&
+ git -C T$option rev-list --all --objects >T$option.objects &&
+ test_cmp T.objects T$option.objects &&
+ (
+ cd T$option/.git/objects &&
+ find . -type f | sort >../../../T$option.objects-files.raw &&
+ find . -type l | sort >../../../T$option.objects-symlinks.raw
+ )
+ done &&
+
+ 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
+ done &&
+
+ cat >expected-files <<-EOF &&
+ ./Y/Z
+ ./Y/Z
+ ./a-loose-dir/Z
+ ./an-object
+ ./Y/Z
+ ./info/packs
+ ./pack/pack-Z.idx
+ ./pack/pack-Z.pack
+ ./packs/pack-Z.idx
+ ./packs/pack-Z.pack
+ ./unknown_file
+ EOF
+
+ for option in --local --no-hardlinks --dissociate
+ do
+ test_cmp expected-files T$option.objects-files.raw.de-sha || return 1 &&
+ test_must_be_empty T$option.objects-symlinks.raw.de-sha || return 1
+ done &&
+
+ echo ./info/alternates >expected-files &&
+ test_cmp expected-files T--shared.objects-files.raw &&
+ test_must_be_empty T--shared.objects-symlinks.raw
+'
+
test_done
diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh
index 2a0fb15cf1..b7a3fdf02d 100755
--- a/t/t5607-clone-bundle.sh
+++ b/t/t5607-clone-bundle.sh
@@ -83,4 +83,15 @@ test_expect_success 'failed bundle creation does not leave cruft' '
test_path_is_missing fail.bundle.lock
'
+test_expect_success 'fetch SHA-1 from bundle' '
+ test_create_repo foo &&
+ test_commit -C foo x &&
+ git -C foo bundle create tip.bundle -1 master &&
+ git -C foo rev-parse HEAD >hash &&
+
+ # Exercise to ensure that fetching a SHA-1 from a bundle works with no
+ # errors
+ git fetch --no-tags foo/tip.bundle "$(cat hash)"
+'
+
test_done
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index b91ef548f8..79f7b65f8c 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -42,8 +42,8 @@ test_expect_success 'do partial clone 1' '
test_cmp expect_1.oids observed.oids &&
test "$(git -C pc1 config --local core.repositoryformatversion)" = "1" &&
- test "$(git -C pc1 config --local extensions.partialclone)" = "origin" &&
- test "$(git -C pc1 config --local core.partialclonefilter)" = "blob:none"
+ test "$(git -C pc1 config --local remote.origin.promisor)" = "true" &&
+ test "$(git -C pc1 config --local remote.origin.partialclonefilter)" = "blob:none"
'
# checkout master to force dynamic object fetch of blobs at HEAD.
@@ -208,6 +208,25 @@ test_expect_success 'use fsck before and after manually fetching a missing subtr
test_cmp unique_types.expected unique_types.observed
'
+test_expect_success 'implicitly construct combine: filter with repeated flags' '
+ GIT_TRACE=$(pwd)/trace git clone --bare \
+ --filter=blob:none --filter=tree:1 \
+ "file://$(pwd)/srv.bare" pc2 &&
+ grep "trace:.* git pack-objects .*--filter=combine:blob:none+tree:1" \
+ trace &&
+ git -C pc2 rev-list --objects --missing=allow-any HEAD >objects &&
+
+ # We should have gotten some root trees.
+ grep " $" objects &&
+ # Should not have gotten any non-root trees or blobs.
+ ! grep " ." objects &&
+
+ xargs -n 1 git -C pc2 cat-file -t <objects >types &&
+ sort -u types >unique_types.actual &&
+ test_write_lines commit tree >unique_types.expected &&
+ test_cmp unique_types.expected unique_types.actual
+'
+
test_expect_success 'partial clone fetches blobs pointed to by refs even if normally filtered out' '
rm -rf src dst &&
git init src &&
@@ -241,6 +260,42 @@ test_expect_success 'fetch what is specified on CLI even if already promised' '
! grep "?$(cat blob)" missing_after
'
+test_expect_success 'setup src repo for sparse filter' '
+ git init sparse-src &&
+ git -C sparse-src config --local uploadpack.allowfilter 1 &&
+ git -C sparse-src config --local uploadpack.allowanysha1inwant 1 &&
+ test_commit -C sparse-src one &&
+ test_commit -C sparse-src two &&
+ echo /one.t >sparse-src/only-one &&
+ git -C sparse-src add . &&
+ git -C sparse-src commit -m "add sparse checkout files"
+'
+
+test_expect_success 'partial clone with sparse filter succeeds' '
+ rm -rf dst.git &&
+ git clone --no-local --bare \
+ --filter=sparse:oid=master:only-one \
+ sparse-src dst.git &&
+ (
+ cd dst.git &&
+ git rev-list --objects --missing=print HEAD >out &&
+ grep "^$(git rev-parse HEAD:one.t)" out &&
+ grep "^?$(git rev-parse HEAD:two.t)" out
+ )
+'
+
+test_expect_success 'partial clone with unresolvable sparse filter fails cleanly' '
+ rm -rf dst.git &&
+ test_must_fail git clone --no-local --bare \
+ --filter=sparse:oid=master:no-such-name \
+ sparse-src dst.git 2>err &&
+ test_i18ngrep "unable to access sparse blob in .master:no-such-name" err &&
+ test_must_fail git clone --no-local --bare \
+ --filter=sparse:oid=master \
+ sparse-src dst.git 2>err &&
+ test_i18ngrep "unable to parse sparse filter data in" err
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@@ -417,4 +472,7 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
! test -e "$HTTPD_ROOT_PATH/one-time-sed"
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5700-protocol-v1.sh b/t/t5700-protocol-v1.sh
index 7c9511c593..2571eb90b7 100755
--- a/t/t5700-protocol-v1.sh
+++ b/t/t5700-protocol-v1.sh
@@ -292,4 +292,7 @@ test_expect_success 'push with http:// using protocol v1' '
grep "git< version 1" log
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 5b33f625dd..ae9175cedf 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -499,10 +499,7 @@ test_expect_success 'upload-pack respects client shallows' '
# Add extra commits to the client so that the whole fetch takes more
# than 1 request (due to negotiation)
- for i in $(test_seq 1 32)
- do
- test_commit -C client c$i
- done &&
+ test_commit_bulk -C client --id=c 32 &&
git -C server checkout -b newbranch base &&
test_commit -C server client_wants &&
@@ -634,6 +631,19 @@ test_expect_success 'fetch with http:// using protocol v2' '
grep "git< version 2" log
'
+test_expect_success 'fetch with http:// by hash without tag following with protocol v2 does not list refs' '
+ test_when_finished "rm -f log" &&
+
+ test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two_a &&
+ git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" rev-parse two_a >two_a_hash &&
+
+ GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \
+ fetch --no-tags origin $(cat two_a_hash) &&
+
+ grep "fetch< version 2" log &&
+ ! grep "fetch> command=ls-refs" log
+'
+
test_expect_success 'fetch from namespaced repo respects namespaces' '
test_when_finished "rm -f log" &&
@@ -711,10 +721,7 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
# Create many commits to extend the negotiation phase across multiple
# requests, so that the server does not send "ready" in the first
# request.
- for i in $(test_seq 1 32)
- do
- test_commit -C http_child c$i
- done &&
+ test_commit_bulk -C http_child --id=c 32 &&
# After the acknowledgments section, pretend that a DELIM
# (0001) was sent instead of a FLUSH (0000).
@@ -729,4 +736,7 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
test_i18ngrep "expected no other sections to be sent after no .ready." err
'
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index 0951d1bbdc..3a2c143c6d 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -157,106 +157,6 @@ test_expect_success 'want-ref with ref we already have commit for' '
check_output
'
-. "$TEST_DIRECTORY"/lib-httpd.sh
-start_httpd
-
-REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
-LOCAL_PRISTINE="$(pwd)/local_pristine"
-
-test_expect_success 'setup repos for change-while-negotiating test' '
- (
- git init "$REPO" &&
- cd "$REPO" &&
- >.git/git-daemon-export-ok &&
- test_commit m1 &&
- git tag -d m1 &&
-
- # Local repo with many commits (so that negotiation will take
- # more than 1 request/response pair)
- git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
- cd "$LOCAL_PRISTINE" &&
- git checkout -b side &&
- for i in $(test_seq 1 33); do test_commit s$i; done &&
-
- # Add novel commits to upstream
- git checkout master &&
- cd "$REPO" &&
- test_commit m2 &&
- test_commit m3 &&
- git tag -d m2 m3
- ) &&
- git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo" &&
- git -C "$LOCAL_PRISTINE" config protocol.version 2
-'
-
-inconsistency () {
- # Simulate that the server initially reports $2 as the ref
- # corresponding to $1, and after that, $1 as the ref corresponding to
- # $1. This corresponds to the real-life situation where the server's
- # repository appears to change during negotiation, for example, when
- # different servers in a load-balancing arrangement serve (stateless)
- # RPCs during a single negotiation.
- printf "s/%s/%s/" \
- $(git -C "$REPO" rev-parse $1 | tr -d "\n") \
- $(git -C "$REPO" rev-parse $2 | tr -d "\n") \
- >"$HTTPD_ROOT_PATH/one-time-sed"
-}
-
-test_expect_success 'server is initially ahead - no ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant false &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master 1234567890123456789012345678901234567890 &&
- test_must_fail git -C local fetch 2>err &&
- test_i18ngrep "fatal: remote error: upload-pack: not our ref" err
-'
-
-test_expect_success 'server is initially ahead - ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant true &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master 1234567890123456789012345678901234567890 &&
- git -C local fetch &&
-
- git -C "$REPO" rev-parse --verify master >expected &&
- git -C local rev-parse --verify refs/remotes/origin/master >actual &&
- test_cmp expected actual
-'
-
-test_expect_success 'server is initially behind - no ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant false &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master "master^" &&
- git -C local fetch &&
-
- git -C "$REPO" rev-parse --verify "master^" >expected &&
- git -C local rev-parse --verify refs/remotes/origin/master >actual &&
- test_cmp expected actual
-'
-
-test_expect_success 'server is initially behind - ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant true &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- inconsistency master "master^" &&
- git -C local fetch &&
-
- git -C "$REPO" rev-parse --verify "master" >expected &&
- git -C local rev-parse --verify refs/remotes/origin/master >actual &&
- test_cmp expected actual
-'
-
-test_expect_success 'server loses a ref - ref in want' '
- git -C "$REPO" config uploadpack.allowRefInWant true &&
- rm -rf local &&
- cp -r "$LOCAL_PRISTINE" local &&
- echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" &&
- test_must_fail git -C local fetch 2>err &&
-
- test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
-'
-
REPO="$(pwd)/repo"
LOCAL_PRISTINE="$(pwd)/local_pristine"
@@ -287,7 +187,7 @@ test_expect_success 'setup repos for fetching with ref-in-want tests' '
git clone "file://$REPO" "$LOCAL_PRISTINE" &&
cd "$LOCAL_PRISTINE" &&
git checkout -b side &&
- for i in $(test_seq 1 33); do test_commit s$i; done &&
+ test_commit_bulk --id=s 33 &&
# Add novel commits to upstream
git checkout master &&
@@ -372,4 +272,108 @@ test_expect_success 'fetching with wildcard that matches multiple refs' '
grep "want-ref refs/heads/o/bar" log
'
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
+LOCAL_PRISTINE="$(pwd)/local_pristine"
+
+test_expect_success 'setup repos for change-while-negotiating test' '
+ (
+ git init "$REPO" &&
+ cd "$REPO" &&
+ >.git/git-daemon-export-ok &&
+ test_commit m1 &&
+ git tag -d m1 &&
+
+ # Local repo with many commits (so that negotiation will take
+ # more than 1 request/response pair)
+ rm -rf "$LOCAL_PRISTINE" &&
+ git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
+ cd "$LOCAL_PRISTINE" &&
+ git checkout -b side &&
+ test_commit_bulk --id=s 33 &&
+
+ # Add novel commits to upstream
+ git checkout master &&
+ cd "$REPO" &&
+ test_commit m2 &&
+ test_commit m3 &&
+ git tag -d m2 m3
+ ) &&
+ git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo" &&
+ git -C "$LOCAL_PRISTINE" config protocol.version 2
+'
+
+inconsistency () {
+ # Simulate that the server initially reports $2 as the ref
+ # corresponding to $1, and after that, $1 as the ref corresponding to
+ # $1. This corresponds to the real-life situation where the server's
+ # repository appears to change during negotiation, for example, when
+ # different servers in a load-balancing arrangement serve (stateless)
+ # RPCs during a single negotiation.
+ printf "s/%s/%s/" \
+ $(git -C "$REPO" rev-parse $1 | tr -d "\n") \
+ $(git -C "$REPO" rev-parse $2 | tr -d "\n") \
+ >"$HTTPD_ROOT_PATH/one-time-sed"
+}
+
+test_expect_success 'server is initially ahead - no ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant false &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master 1234567890123456789012345678901234567890 &&
+ test_must_fail git -C local fetch 2>err &&
+ test_i18ngrep "fatal: remote error: upload-pack: not our ref" err
+'
+
+test_expect_success 'server is initially ahead - ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant true &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master 1234567890123456789012345678901234567890 &&
+ git -C local fetch &&
+
+ git -C "$REPO" rev-parse --verify master >expected &&
+ git -C local rev-parse --verify refs/remotes/origin/master >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'server is initially behind - no ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant false &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master "master^" &&
+ git -C local fetch &&
+
+ git -C "$REPO" rev-parse --verify "master^" >expected &&
+ git -C local rev-parse --verify refs/remotes/origin/master >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'server is initially behind - ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant true &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ inconsistency master "master^" &&
+ git -C local fetch &&
+
+ git -C "$REPO" rev-parse --verify "master" >expected &&
+ git -C local rev-parse --verify refs/remotes/origin/master >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'server loses a ref - ref in want' '
+ git -C "$REPO" config uploadpack.allowRefInWant true &&
+ rm -rf local &&
+ cp -r "$LOCAL_PRISTINE" local &&
+ echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" &&
+ test_must_fail git -C local fetch 2>err &&
+
+ test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
+'
+
+# DO NOT add non-httpd-specific tests here, because the last part of this
+# test script is only executed when httpd is available and enabled.
+
test_done
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 2d6c4a281e..121e5c6edb 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -247,7 +247,6 @@ clean_mark () {
test_expect_success 'proper failure checks for fetching' '
(cd local &&
test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git fetch 2>error &&
- cat error &&
test_i18ngrep -q "error while running fast-import" error
)
'
diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh
index 52a9e38d66..b8cf82349b 100755
--- a/t/t6000-rev-list-misc.sh
+++ b/t/t6000-rev-list-misc.sh
@@ -140,4 +140,12 @@ test_expect_success '--header shows a NUL after each commit' '
test_cmp expect actual
'
+test_expect_success 'rev-list --end-of-options' '
+ git update-ref refs/heads/--output=yikes HEAD &&
+ git rev-list --end-of-options --output=yikes >actual &&
+ test_path_is_missing yikes &&
+ git rev-list HEAD >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index da113d975b..cfb74d0e03 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -501,9 +501,8 @@ test_expect_success 'reflog identity' '
'
test_expect_success 'oneline with empty message' '
- git commit -m "dummy" --allow-empty &&
- git commit -m "dummy" --allow-empty &&
- git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. &&
+ git commit --allow-empty --cleanup=verbatim -m "$LF" &&
+ git commit --allow-empty --allow-empty-message &&
git rev-list --oneline HEAD >test.txt &&
test_line_count = 5 test.txt &&
git rev-list --oneline --graph HEAD >testg.txt &&
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 49a394bd75..bdc42e9440 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -615,6 +615,7 @@ test_expect_success 'broken branch creation' '
git add missing/MISSING &&
git commit -m "6(broken): Added file that will be deleted" &&
git tag BROKEN_HASH6 &&
+ deleted=$(git rev-parse --verify HEAD:missing) &&
add_line_into_file "7(broken): second line on a broken branch" hello2 &&
git tag BROKEN_HASH7 &&
add_line_into_file "8(broken): third line on a broken branch" hello2 &&
@@ -622,12 +623,12 @@ test_expect_success 'broken branch creation' '
git rm missing/MISSING &&
git commit -m "9(broken): Remove missing file" &&
git tag BROKEN_HASH9 &&
- rm .git/objects/39/f7e61a724187ab767d2e08442d9b6b9dab587d
+ rm .git/objects/$(test_oid_to_path $deleted)
'
echo "" > expected.ok
cat > expected.missing-tree.default <<EOF
-fatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d
+fatal: unable to read tree $deleted
EOF
test_expect_success 'bisect fails if tree is broken on start commit' '
@@ -713,12 +714,12 @@ test_expect_success 'bisect: demonstrate identification of damage boundary' "
"
cat > expected.bisect-log <<EOF
-# bad: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>.
-# good: [7b7f204a749c3125d5224ed61ea2ae1187ad046f] Add <2: A new day for git> into <hello>.
-git bisect start '32a594a3fdac2d57cf6d02987e30eec68511498c' '7b7f204a749c3125d5224ed61ea2ae1187ad046f'
-# good: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>.
-git bisect good 3de952f2416b6084f557ec417709eac740c6818c
-# first bad commit: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>.
+# bad: [$HASH4] Add <4: Ciao for now> into <hello>.
+# good: [$HASH2] Add <2: A new day for git> into <hello>.
+git bisect start '$HASH4' '$HASH2'
+# good: [$HASH3] Add <3: Another new day for git> into <hello>.
+git bisect good $HASH3
+# first bad commit: [$HASH4] Add <4: Ciao for now> into <hello>.
EOF
test_expect_success 'bisect log: successful result' '
@@ -731,14 +732,14 @@ test_expect_success 'bisect log: successful result' '
'
cat > expected.bisect-skip-log <<EOF
-# bad: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>.
-# good: [7b7f204a749c3125d5224ed61ea2ae1187ad046f] Add <2: A new day for git> into <hello>.
-git bisect start '32a594a3fdac2d57cf6d02987e30eec68511498c' '7b7f204a749c3125d5224ed61ea2ae1187ad046f'
-# skip: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>.
-git bisect skip 3de952f2416b6084f557ec417709eac740c6818c
+# bad: [$HASH4] Add <4: Ciao for now> into <hello>.
+# good: [$HASH2] Add <2: A new day for git> into <hello>.
+git bisect start '$HASH4' '$HASH2'
+# skip: [$HASH3] Add <3: Another new day for git> into <hello>.
+git bisect skip $HASH3
# only skipped commits left to test
-# possible first bad commit: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>.
-# possible first bad commit: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>.
+# possible first bad commit: [$HASH4] Add <4: Ciao for now> into <hello>.
+# possible first bad commit: [$HASH3] Add <3: Another new day for git> into <hello>.
EOF
test_expect_success 'bisect log: only skip commits left' '
diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh
index d23b948f27..7fddcc8c73 100755
--- a/t/t6036-recursive-corner-cases.sh
+++ b/t/t6036-recursive-corner-cases.sh
@@ -1562,6 +1562,7 @@ test_expect_success 'check nested conflicts' '
cd nested_conflicts &&
git clean -f &&
+ MASTER=$(git rev-parse --short master) &&
git checkout L2^0 &&
# Merge must fail; there is a conflict
@@ -1582,7 +1583,7 @@ test_expect_success 'check nested conflicts' '
git cat-file -p R1:a >theirs &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
- -L "merged common ancestors" \
+ -L "$MASTER" \
-L "Temporary merge branch 2" \
ours \
base \
@@ -1594,7 +1595,7 @@ test_expect_success 'check nested conflicts' '
git cat-file -p R1:b >theirs &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
- -L "merged common ancestors" \
+ -L "$MASTER" \
-L "Temporary merge branch 2" \
ours \
base \
@@ -1732,6 +1733,7 @@ test_expect_success 'check virtual merge base with nested conflicts' '
(
cd virtual_merge_base_has_nested_conflicts &&
+ MASTER=$(git rev-parse --short master) &&
git checkout L3^0 &&
# Merge must fail; there is a conflict
@@ -1760,7 +1762,7 @@ test_expect_success 'check virtual merge base with nested conflicts' '
cp left merged-once &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
- -L "merged common ancestors" \
+ -L "$MASTER" \
-L "Temporary merge branch 2" \
merged-once \
base \
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index febf63f28a..ad1922b999 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -38,7 +38,7 @@ test_expect_success setup '
advance h
'
-script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p'
+t6040_script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p'
cat >expect <<\EOF
b1 [ahead 1, behind 1] d
b2 [ahead 1, behind 1] d
@@ -53,7 +53,7 @@ test_expect_success 'branch -v' '
cd test &&
git branch -v
) |
- sed -n -e "$script" >actual &&
+ sed -n -e "$t6040_script" >actual &&
test_i18ncmp expect actual
'
@@ -71,7 +71,7 @@ test_expect_success 'branch -vv' '
cd test &&
git branch -vv
) |
- sed -n -e "$script" >actual &&
+ sed -n -e "$t6040_script" >actual &&
test_i18ncmp expect actual
'
diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh
index 50b7543483..c966147d5d 100755
--- a/t/t6043-merge-rename-directories.sh
+++ b/t/t6043-merge-rename-directories.sh
@@ -4403,4 +4403,115 @@ test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual
)
'
+# Testcase 13e, directory rename in virtual merge base
+#
+# This testcase has a slightly different setup than all the above cases, in
+# order to include a recursive case:
+#
+# A C
+# o - o
+# / \ / \
+# O o X ?
+# \ / \ /
+# o o
+# B D
+#
+# Commit O: a/{z,y}
+# Commit A: b/{z,y}
+# Commit B: a/{z,y,x}
+# Commit C: b/{z,y,x}
+# Commit D: b/{z,y}, a/x
+# Expected: b/{z,y,x} (sort of; see below for why this might not be expected)
+#
+# NOTES: 'X' represents a virtual merge base. With the default of
+# directory rename detection yielding conflicts, merging A and B
+# results in a conflict complaining about whether 'x' should be
+# under 'a/' or 'b/'. However, when creating the virtual merge
+# base 'X', since virtual merge bases need to be written out as a
+# tree, we cannot have a conflict, so some resolution has to be
+# picked.
+#
+# In choosing the right resolution, it's worth noting here that
+# commits C & D are merges of A & B that choose different
+# locations for 'x' (i.e. they resolve the conflict differently),
+# and so it would be nice when merging C & D if git could detect
+# this difference of opinion and report a conflict. But the only
+# way to do so that I can think of would be to have the virtual
+# merge base place 'x' in some directory other than either 'a/' or
+# 'b/', which seems a little weird -- especially since it'd result
+# in a rename/rename(1to2) conflict with a source path that never
+# existed in any version.
+#
+# So, for now, when directory rename detection is set to
+# 'conflict' just avoid doing directory rename detection at all in
+# the recursive case. This will not allow us to detect a conflict
+# 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_create_repo 13e &&
+ (
+ cd 13e &&
+
+ mkdir a &&
+ echo z >a/z &&
+ echo y >a/y &&
+ git add a &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv a/ b/ &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ echo x >a/x &&
+ git add a &&
+ test_tick &&
+ git commit -m "B" &&
+
+ git branch C A &&
+ git branch D B &&
+
+ git checkout C &&
+ test_must_fail git -c merge.directoryRenames=conflict merge B &&
+ git add b/x &&
+ test_tick &&
+ git commit -m "C" &&
+
+
+ git checkout D &&
+ test_must_fail git -c merge.directoryRenames=conflict merge A &&
+ git add b/x &&
+ mkdir a &&
+ git mv b/x a/x &&
+ test_tick &&
+ git commit -m "D"
+ )
+'
+
+test_expect_success '13e-check: directory rename detection in recursive case' '
+ (
+ cd 13e &&
+
+ git checkout --quiet D^0 &&
+
+ git -c merge.directoryRenames=conflict merge -s recursive C^0 >out 2>err &&
+
+ test_i18ngrep ! CONFLICT out &&
+ test_i18ngrep ! BUG: err &&
+ test_i18ngrep ! core.dumped err &&
+ test_must_be_empty err &&
+
+ git ls-files >paths &&
+ ! grep a/x paths &&
+ grep b/x paths
+ )
+'
+
test_done
diff --git a/t/t6047-diff3-conflict-markers.sh b/t/t6047-diff3-conflict-markers.sh
new file mode 100755
index 0000000000..860542aad0
--- /dev/null
+++ b/t/t6047-diff3-conflict-markers.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+
+test_description='recursive merge diff3 style conflict markers'
+
+. ./test-lib.sh
+
+# Setup:
+# L1
+# \
+# ?
+# /
+# R1
+#
+# Where:
+# L1 and R1 both have a file named 'content' but have no common history
+#
+
+test_expect_success 'setup no merge base' '
+ test_create_repo no_merge_base &&
+ (
+ cd no_merge_base &&
+
+ git checkout -b L &&
+ test_commit A content A &&
+
+ git checkout --orphan R &&
+ test_commit B content B
+ )
+'
+
+test_expect_success 'check no merge base' '
+ (
+ cd no_merge_base &&
+
+ git checkout L^0 &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge --allow-unrelated-histories -s recursive R^0 &&
+
+ grep "|||||| empty tree" content
+ )
+'
+
+# Setup:
+# L1
+# / \
+# master ?
+# \ /
+# R1
+#
+# Where:
+# L1 and R1 have modified the same file ('content') in conflicting ways
+#
+
+test_expect_success 'setup unique merge base' '
+ test_create_repo unique_merge_base &&
+ (
+ cd unique_merge_base &&
+
+ test_commit base content "1
+2
+3
+4
+5
+" &&
+
+ git branch L &&
+ git branch R &&
+
+ git checkout L &&
+ test_commit L content "1
+2
+3
+4
+5
+7" &&
+
+ git checkout R &&
+ git rm content &&
+ test_commit R renamed "1
+2
+3
+4
+5
+six"
+ )
+'
+
+test_expect_success 'check unique merge base' '
+ (
+ cd unique_merge_base &&
+
+ git checkout L^0 &&
+ MASTER=$(git rev-parse --short master) &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R^0 &&
+
+ grep "|||||| $MASTER:content" renamed
+ )
+'
+
+# Setup:
+# L1---L2--L3
+# / \ / \
+# master X1 ?
+# \ / \ /
+# R1---R2--R3
+#
+# Where:
+# commits L1 and R1 have modified the same file in non-conflicting ways
+# X1 is an auto-generated merge-base used when merging L1 and R1
+# commits L2 and R2 are merges of R1 and L1 into L1 and R1, respectively
+# commits L3 and R3 both modify 'content' in conflicting ways
+#
+
+test_expect_success 'setup multiple merge bases' '
+ test_create_repo multiple_merge_bases &&
+ (
+ cd multiple_merge_bases &&
+
+ test_commit initial content "1
+2
+3
+4
+5" &&
+
+ git branch L &&
+ git branch R &&
+
+ # Create L1
+ git checkout L &&
+ test_commit L1 content "0
+1
+2
+3
+4
+5" &&
+
+ # Create R1
+ git checkout R &&
+ test_commit R1 content "1
+2
+3
+4
+5
+6" &&
+
+ # Create L2
+ git checkout L &&
+ git merge R1 &&
+
+ # Create R2
+ git checkout R &&
+ git merge L1 &&
+
+ # Create L3
+ git checkout L &&
+ test_commit L3 content "0
+1
+2
+3
+4
+5
+A" &&
+
+ # Create R3
+ git checkout R &&
+ git rm content &&
+ test_commit R3 renamed "0
+2
+3
+4
+5
+six"
+ )
+'
+
+test_expect_success 'check multiple merge bases' '
+ (
+ cd multiple_merge_bases &&
+
+ git checkout L^0 &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R^0 &&
+
+ grep "|||||| merged common ancestors:content" renamed
+ )
+'
+
+test_expect_success 'rebase describes fake ancestor base' '
+ test_create_repo rebase &&
+ (
+ cd rebase &&
+ test_commit base file &&
+ test_commit master file &&
+ git checkout -b side HEAD^ &&
+ test_commit side file &&
+ test_must_fail git -c merge.conflictstyle=diff3 rebase master &&
+ grep "||||||| constructed merge base" file
+ )
+'
+
+test_done
diff --git a/t/t6112-rev-list-filters-objects.sh b/t/t6112-rev-list-filters-objects.sh
index acd7f5ab80..de0e5a5d36 100755
--- a/t/t6112-rev-list-filters-objects.sh
+++ b/t/t6112-rev-list-filters-objects.sh
@@ -278,7 +278,19 @@ test_expect_success 'verify skipping tree iteration when not collecting omits' '
test_line_count = 2 actual &&
# Make sure no other trees were considered besides the root.
- ! grep "Skipping contents of tree [^.]" filter_trace
+ ! grep "Skipping contents of tree [^.]" filter_trace &&
+
+ # Try this again with "combine:". If both sub-filters are skipping
+ # trees, the composite filter should also skip trees. This is not
+ # important unless the user does combine:tree:X+tree:Y or another filter
+ # besides "tree:" is implemented in the future which can skip trees.
+ GIT_TRACE=1 git -C r3 rev-list \
+ --objects --filter=combine:tree:1+tree:3 HEAD 2>filter_trace &&
+
+ # Only skip the dir1/ tree, which is shared between the two commits.
+ grep "Skipping contents of tree " filter_trace >actual &&
+ test_write_lines "Skipping contents of tree dir1/..." >expected &&
+ test_cmp expected actual
'
# Test tree:# filters.
@@ -330,6 +342,148 @@ test_expect_success 'verify tree:3 includes everything expected' '
test_line_count = 10 actual
'
+test_expect_success 'combine:... for a simple combination' '
+ git -C r3 rev-list --objects --filter=combine:tree:2+blob:none HEAD \
+ >actual &&
+
+ expect_has HEAD "" &&
+ expect_has HEAD~1 "" &&
+ expect_has HEAD dir1 &&
+
+ # There are also 2 commit objects
+ test_line_count = 5 actual &&
+
+ cp actual expected &&
+
+ # Try again using repeated --filter - this is equivalent to a manual
+ # combine with "combine:...+..."
+ git -C r3 rev-list --objects --filter=combine:tree:2 \
+ --filter=blob:none HEAD >actual &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'combine:... with URL encoding' '
+ git -C r3 rev-list --objects \
+ --filter=combine:tree%3a2+blob:%6Eon%65 HEAD >actual &&
+
+ expect_has HEAD "" &&
+ expect_has HEAD~1 "" &&
+ expect_has HEAD dir1 &&
+
+ # There are also 2 commit objects
+ test_line_count = 5 actual
+'
+
+expect_invalid_filter_spec () {
+ spec="$1" &&
+ err="$2" &&
+
+ test_must_fail git -C r3 rev-list --objects --filter="$spec" HEAD \
+ >actual 2>actual_stderr &&
+ test_must_be_empty actual &&
+ test_i18ngrep "$err" actual_stderr
+}
+
+test_expect_success 'combine:... while URL-encoding things that should not be' '
+ expect_invalid_filter_spec combine%3Atree:2+blob:none \
+ "invalid filter-spec"
+'
+
+test_expect_success 'combine: with nothing after the :' '
+ expect_invalid_filter_spec combine: "expected something after combine:"
+'
+
+test_expect_success 'parse error in first sub-filter in combine:' '
+ expect_invalid_filter_spec combine:tree:asdf+blob:none \
+ "expected .tree:<depth>."
+'
+
+test_expect_success 'combine:... with non-encoded reserved chars' '
+ expect_invalid_filter_spec combine:tree:2+sparse:@xyz \
+ "must escape char in sub-filter-spec: .@." &&
+ expect_invalid_filter_spec combine:tree:2+sparse:\` \
+ "must escape char in sub-filter-spec: .\`." &&
+ expect_invalid_filter_spec combine:tree:2+sparse:~abc \
+ "must escape char in sub-filter-spec: .\~."
+'
+
+test_expect_success 'validate err msg for "combine:<valid-filter>+"' '
+ expect_invalid_filter_spec combine:tree:2+ "expected .tree:<depth>."
+'
+
+test_expect_success 'combine:... with edge-case hex digits: Ff Aa 0 9' '
+ git -C r3 rev-list --objects --filter="combine:tree:2+bl%6Fb:n%6fne" \
+ HEAD >actual &&
+ test_line_count = 5 actual &&
+ git -C r3 rev-list --objects --filter="combine:tree%3A2+blob%3anone" \
+ HEAD >actual &&
+ test_line_count = 5 actual &&
+ git -C r3 rev-list --objects --filter="combine:tree:%30" HEAD >actual &&
+ test_line_count = 2 actual &&
+ git -C r3 rev-list --objects --filter="combine:tree:%39+blob:none" \
+ HEAD >actual &&
+ test_line_count = 5 actual
+'
+
+test_expect_success 'add sparse pattern blobs whose paths have reserved chars' '
+ cp r3/pattern r3/pattern1+renamed% &&
+ cp r3/pattern "r3/p;at%ter+n" &&
+ cp r3/pattern r3/^~pattern &&
+ git -C r3 add pattern1+renamed% "p;at%ter+n" ^~pattern &&
+ git -C r3 commit -m "add sparse pattern files with reserved chars"
+'
+
+test_expect_success 'combine:... with more than two sub-filters' '
+ git -C r3 rev-list --objects \
+ --filter=combine:tree:3+blob:limit=40+sparse:oid=master:pattern \
+ HEAD >actual &&
+
+ expect_has HEAD "" &&
+ expect_has HEAD~1 "" &&
+ expect_has HEAD~2 "" &&
+ expect_has HEAD dir1 &&
+ expect_has HEAD dir1/sparse1 &&
+ expect_has HEAD dir1/sparse2 &&
+
+ # Should also have 3 commits
+ test_line_count = 9 actual &&
+
+ # Try again, this time making sure the last sub-filter is only
+ # URL-decoded once.
+ cp actual expect &&
+
+ git -C r3 rev-list --objects \
+ --filter=combine:tree:3+blob:limit=40+sparse:oid=master:pattern1%2brenamed%25 \
+ HEAD >actual &&
+ test_cmp expect actual &&
+
+ # Use the same composite filter again, but with a pattern file name that
+ # requires encoding multiple characters, and use implicit filter
+ # combining.
+ test_when_finished "rm -f trace1" &&
+ GIT_TRACE=$(pwd)/trace1 git -C r3 rev-list --objects \
+ --filter=tree:3 --filter=blob:limit=40 \
+ --filter=sparse:oid="master:p;at%ter+n" \
+ HEAD >actual &&
+
+ test_cmp expect actual &&
+ grep "Add to combine filter-spec: sparse:oid=master:p%3bat%25ter%2bn" \
+ trace1 &&
+
+ # Repeat the above test, but this time, the characters to encode are in
+ # the LHS of the combined filter.
+ test_when_finished "rm -f trace2" &&
+ GIT_TRACE=$(pwd)/trace2 git -C r3 rev-list --objects \
+ --filter=sparse:oid=master:^~pattern \
+ --filter=tree:3 --filter=blob:limit=40 \
+ HEAD >actual &&
+
+ test_cmp expect actual &&
+ grep "Add to combine filter-spec: sparse:oid=master:%5e%7epattern" \
+ trace2
+'
+
# Test provisional omit collection logic with a repo that has objects appearing
# at multiple depths - first deeper than the filter's threshold, then shallow.
@@ -373,6 +527,37 @@ test_expect_success 'verify skipping tree iteration when collecting omits' '
test_cmp expect actual
'
+test_expect_success 'setup r5' '
+ git init r5 &&
+ mkdir -p r5/subdir &&
+
+ echo 1 >r5/short-root &&
+ echo 12345 >r5/long-root &&
+ echo a >r5/subdir/short-subdir &&
+ echo abcde >r5/subdir/long-subdir &&
+
+ git -C r5 add short-root long-root subdir &&
+ git -C r5 commit -m "commit msg"
+'
+
+test_expect_success 'verify collecting omits in combined: filter' '
+ # Note that this test guards against the naive implementation of simply
+ # giving both filters the same "omits" set and expecting it to
+ # automatically merge them.
+ git -C r5 rev-list --objects --quiet --filter-print-omitted \
+ --filter=combine:tree:2+blob:limit=3 HEAD >actual &&
+
+ # Expect 0 trees/commits, 3 blobs omitted (all blobs except short-root)
+ omitted_1=$(echo 12345 | git hash-object --stdin) &&
+ omitted_2=$(echo a | git hash-object --stdin) &&
+ omitted_3=$(echo abcde | git hash-object --stdin) &&
+
+ grep ~$omitted_1 actual &&
+ grep ~$omitted_2 actual &&
+ grep ~$omitted_3 actual &&
+ test_line_count = 3 actual
+'
+
# Test tree:<depth> where a tree is iterated to twice - once where a subentry is
# too deep to be included, and again where the blob inside it is shallow enough
# to be included. This makes sure we don't use LOFR_MARK_SEEN incorrectly (we
@@ -441,11 +626,4 @@ test_expect_success 'expand blob limit in protocol' '
grep "blob:limit=1024" trace
'
-test_expect_success 'expand tree depth limit in protocol' '
- GIT_TRACE_PACKET="$(pwd)/tree_trace" git -c protocol.version=2 clone \
- --filter=tree:0k "file://$(pwd)/r2" tree &&
- ! grep "tree:0k" tree_trace &&
- grep "tree:0" tree_trace
-'
-
test_done
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 2b883d8174..45047d0a72 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -424,4 +424,19 @@ test_expect_success 'describe complains about missing object' '
test_must_fail git describe $ZERO_OID
'
+test_expect_success 'name-rev a rev shortly after epoch' '
+ test_when_finished "git checkout master" &&
+
+ git checkout --orphan no-timestamp-underflow &&
+ # Any date closer to epoch than the CUTOFF_DATE_SLOP constant
+ # in builtin/name-rev.c.
+ GIT_COMMITTER_DATE="@1234 +0000" \
+ git commit -m "committer date shortly after epoch" &&
+ old_commit_oid=$(git rev-parse HEAD) &&
+
+ echo "$old_commit_oid no-timestamp-underflow" >expect &&
+ git name-rev $old_commit_oid >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index 93f23cfa82..8a72b4c43a 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -66,12 +66,7 @@ test_expect_success setup '
git commit -a -m "Right #5" &&
git checkout -b long &&
- i=0 &&
- while test $i -lt 30
- do
- test_commit $i one &&
- i=$(($i+1))
- done &&
+ test_commit_bulk --start=0 --message=%s --filename=one 30 &&
git show-branch &&
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index ab69aa176d..9c910ce746 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -526,6 +526,25 @@ test_expect_success 'Check ambiguous head and tag refs II (loose)' '
test_cmp expected actual
'
+test_expect_success 'create tag without tagger' '
+ git tag -a -m "Broken tag" taggerless &&
+ git tag -f taggerless $(git cat-file tag taggerless |
+ sed -e "/^tagger /d" |
+ git hash-object --stdin -w -t tag)
+'
+
+test_atom refs/tags/taggerless type 'commit'
+test_atom refs/tags/taggerless tag 'taggerless'
+test_atom refs/tags/taggerless tagger ''
+test_atom refs/tags/taggerless taggername ''
+test_atom refs/tags/taggerless taggeremail ''
+test_atom refs/tags/taggerless taggerdate ''
+test_atom refs/tags/taggerless committer ''
+test_atom refs/tags/taggerless committername ''
+test_atom refs/tags/taggerless committeremail ''
+test_atom refs/tags/taggerless committerdate ''
+test_atom refs/tags/taggerless subject 'Broken tag'
+
test_expect_success 'an unusual tag with an incomplete line' '
git tag -m "bogo" bogo &&
diff --git a/t/t7009-filter-branch-null-sha1.sh b/t/t7008-filter-branch-null-sha1.sh
index 9ba9f24ad2..9ba9f24ad2 100755
--- a/t/t7009-filter-branch-null-sha1.sh
+++ b/t/t7008-filter-branch-null-sha1.sh
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 5990299fc9..b696bae5f5 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -249,7 +249,7 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' '
test_expect_success 'checkout to detach HEAD' '
git config advice.detachedHead true &&
git checkout -f renamer && git clean -f &&
- GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
+ GIT_TEST_GETTEXT_POISON=false git checkout renamer^ 2>messages &&
grep "HEAD is now at 7329388" messages &&
test_line_count -gt 1 messages &&
H=$(git rev-parse --verify HEAD) &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 7b36954d63..6e6d24c1c3 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -117,6 +117,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
would_clean=$(
cd docs &&
git clean -n ../src |
+ grep part3 |
sed -n -e "s|^Would remove ||p"
) &&
verbose test "$would_clean" = ../src/part3.c
@@ -129,6 +130,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with absolute path' '
would_clean=$(
cd docs &&
git clean -n "$(pwd)/../src" |
+ grep part3 |
sed -n -e "s|^Would remove ||p"
) &&
verbose test "$would_clean" = ../src/part3.c
@@ -547,7 +549,7 @@ test_expect_failure 'nested (non-empty) bare repositories should be cleaned even
test_path_is_missing strange_bare
'
-test_expect_success 'giving path in nested git work tree will remove it' '
+test_expect_success 'giving path in nested git work tree will NOT remove it' '
rm -fr repo &&
mkdir repo &&
(
@@ -559,7 +561,7 @@ test_expect_success 'giving path in nested git work tree will remove it' '
git clean -f -d repo/bar/baz &&
test_path_is_file repo/.git/HEAD &&
test_path_is_dir repo/bar/ &&
- test_path_is_missing repo/bar/baz
+ test_path_is_file repo/bar/baz/hello.world
'
test_expect_success 'giving path to nested .git will not remove it' '
@@ -577,7 +579,7 @@ test_expect_success 'giving path to nested .git will not remove it' '
test_path_is_dir untracked/
'
-test_expect_success 'giving path to nested .git/ will remove contents' '
+test_expect_success 'giving path to nested .git/ will NOT remove contents' '
rm -fr repo untracked &&
mkdir repo untracked &&
(
@@ -587,7 +589,7 @@ test_expect_success 'giving path to nested .git/ will remove contents' '
) &&
git clean -f -d repo/.git/ &&
test_path_is_dir repo/.git &&
- test_dir_is_empty repo/.git &&
+ test_path_is_file repo/.git/HEAD &&
test_path_is_dir untracked/
'
@@ -669,4 +671,70 @@ test_expect_success 'git clean -d skips untracked dirs containing ignored files'
test_path_is_missing foo/b/bb
'
+test_expect_success 'git clean -d skips nested repo containing ignored files' '
+ test_when_finished "rm -rf nested-repo-with-ignored-file" &&
+
+ git init nested-repo-with-ignored-file &&
+ (
+ cd nested-repo-with-ignored-file &&
+ >file &&
+ git add file &&
+ git commit -m Initial &&
+
+ # This file is ignored by a .gitignore rule in the outer repo
+ # added in the previous test.
+ >ignoreme
+ ) &&
+
+ git clean -fd &&
+
+ test_path_is_file nested-repo-with-ignored-file/.git/index &&
+ test_path_is_file nested-repo-with-ignored-file/ignoreme &&
+ test_path_is_file nested-repo-with-ignored-file/file
+'
+
+test_expect_success 'git clean handles being told what to clean' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -f */ut &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
+test_expect_success 'git clean handles being told what to clean, with -d' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -ffd */ut &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
+test_expect_success 'git clean works if a glob is passed without -d' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -f "*ut" &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
+test_expect_success 'git clean works if a glob is passed with -d' '
+ mkdir -p d1 d2 &&
+ touch d1/ut d2/ut &&
+ git clean -ffd "*ut" &&
+ test_path_is_missing d1/ut &&
+ test_path_is_missing d2/ut
+'
+
+test_expect_success MINGW 'handle clean & core.longpaths = false nicely' '
+ test_config core.longpaths false &&
+ a50=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+ mkdir -p $a50$a50/$a50$a50/$a50$a50 &&
+ : >"$a50$a50/test.txt" 2>"$a50$a50/$a50$a50/$a50$a50/test.txt" &&
+ # create a temporary outside the working tree to hide from "git clean"
+ test_must_fail git clean -xdf 2>.git/err &&
+ # grepping for a strerror string is unportable but it is OK here with
+ # MINGW prereq
+ test_i18ngrep "too long" .git/err
+'
+
test_done
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index a208cb26e1..691b5fc3bf 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -527,7 +527,6 @@ test_expect_success 'update --init' '
test_must_fail git config submodule.example.url &&
git submodule update init 2> update.out &&
- cat update.out &&
test_i18ngrep "not initialized" update.out &&
test_must_fail git rev-parse --resolve-git-dir init/.git &&
@@ -545,7 +544,6 @@ test_expect_success 'update --init from subdirectory' '
(
cd sub &&
git submodule update ../init 2>update.out &&
- cat update.out &&
test_i18ngrep "not initialized" update.out &&
test_must_fail git rev-parse --resolve-git-dir ../init/.git &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index c973278300..df34c994d2 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -158,7 +158,6 @@ test_expect_success 'submodule update --init from and of subdirectory' '
test_i18ncmp expect2 actual2
'
-apos="'";
test_expect_success 'submodule update does not fetch already present commits' '
(cd submodule &&
echo line3 >> file &&
@@ -168,7 +167,7 @@ test_expect_success 'submodule update does not fetch already present commits' '
) &&
(cd super/submodule &&
head=$(git rev-parse --verify HEAD) &&
- echo "Submodule path ${apos}submodule$apos: checked out $apos$head$apos" > ../../expected &&
+ echo "Submodule path ${SQ}submodule$SQ: checked out $SQ$head$SQ" > ../../expected &&
git reset --hard HEAD~1
) &&
(cd super &&
diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh
index c4b370ea85..fd25f786a3 100755
--- a/t/t7419-submodule-set-branch.sh
+++ b/t/t7419-submodule-set-branch.sh
@@ -34,7 +34,7 @@ test_expect_success 'submodule config cache setup' '
test_expect_success 'ensure submodule branch is unset' '
(cd super &&
- test_must_fail grep branch .gitmodules
+ ! grep branch .gitmodules
)
'
@@ -54,7 +54,7 @@ test_expect_success 'test submodule set-branch --branch' '
test_expect_success 'test submodule set-branch --default' '
(cd super &&
git submodule set-branch --default submodule &&
- test_must_fail grep branch .gitmodules &&
+ ! grep branch .gitmodules &&
git submodule update --remote &&
cat <<-\EOF >expect &&
a
@@ -80,7 +80,7 @@ test_expect_success 'test submodule set-branch -b' '
test_expect_success 'test submodule set-branch -d' '
(cd super &&
git submodule set-branch -d submodule &&
- test_must_fail grep branch .gitmodules &&
+ ! grep branch .gitmodules &&
git submodule update --remote &&
cat <<-\EOF >expect &&
a
diff --git a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
new file mode 100755
index 0000000000..b3485450a2
--- /dev/null
+++ b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh
@@ -0,0 +1,281 @@
+#!/bin/sh
+
+test_description='pre-commit and pre-merge-commit hooks'
+
+. ./test-lib.sh
+
+HOOKDIR="$(git rev-parse --git-dir)/hooks"
+PRECOMMIT="$HOOKDIR/pre-commit"
+PREMERGE="$HOOKDIR/pre-merge-commit"
+
+# Prepare sample scripts that write their $0 to actual_hooks
+test_expect_success 'sample script setup' '
+ mkdir -p "$HOOKDIR" &&
+ write_script "$HOOKDIR/success.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ exit 0
+ EOF
+ write_script "$HOOKDIR/fail.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ exit 1
+ EOF
+ write_script "$HOOKDIR/non-exec.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ exit 1
+ EOF
+ chmod -x "$HOOKDIR/non-exec.sample" &&
+ write_script "$HOOKDIR/require-prefix.sample" <<-\EOF &&
+ echo $0 >>actual_hooks
+ test $GIT_PREFIX = "success/"
+ EOF
+ write_script "$HOOKDIR/check-author.sample" <<-\EOF
+ echo $0 >>actual_hooks
+ test "$GIT_AUTHOR_NAME" = "New Author" &&
+ test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
+ EOF
+'
+
+test_expect_success 'root commit' '
+ echo "root" >file &&
+ git add file &&
+ git commit -m "zeroth" &&
+ git checkout -b side &&
+ echo "foo" >foo &&
+ git add foo &&
+ git commit -m "make it non-ff" &&
+ git branch side-orig side &&
+ git checkout master
+'
+
+test_expect_success 'setup conflicting branches' '
+ test_when_finished "git checkout master" &&
+ git checkout -b conflicting-a master &&
+ echo a >conflicting &&
+ git add conflicting &&
+ git commit -m conflicting-a &&
+ git checkout -b conflicting-b master &&
+ echo b >conflicting &&
+ git add conflicting &&
+ git commit -m conflicting-b
+'
+
+test_expect_success 'with no hook' '
+ test_when_finished "rm -f actual_hooks" &&
+ echo "foo" >file &&
+ git add file &&
+ git commit -m "first" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with no hook (merge)' '
+ test_when_finished "rm -f actual_hooks" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success '--no-verify with no hook' '
+ test_when_finished "rm -f actual_hooks" &&
+ echo "bar" >file &&
+ git add file &&
+ git commit --no-verify -m "bar" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success '--no-verify with no hook (merge)' '
+ test_when_finished "rm -f actual_hooks" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with succeeding hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "more" >>file &&
+ git add file &&
+ git commit -m "more" &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'with succeeding hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PREMERGE" &&
+ echo "$PREMERGE" >expected_hooks &&
+ git checkout side &&
+ git merge -m "merge master" master &&
+ git checkout master &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'automatic merge fails; both hooks are available' '
+ test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" &&
+ test_when_finished "rm -f expected_hooks actual_hooks" &&
+ test_when_finished "git checkout master" &&
+ cp "$HOOKDIR/success.sample" "$PREMERGE" &&
+ cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+
+ git checkout conflicting-a &&
+ test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
+ test_path_is_missing actual_hooks &&
+
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo a+b >conflicting &&
+ git add conflicting &&
+ git commit -m "resolve conflict" &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success '--no-verify with succeeding hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
+ echo "even more" >>file &&
+ git add file &&
+ git commit --no-verify -m "even more" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success '--no-verify with succeeding hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/success.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with failing hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "another" >>file &&
+ git add file &&
+ test_must_fail git commit -m "another" &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success '--no-verify with failing hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
+ echo "stuff" >>file &&
+ git add file &&
+ git commit --no-verify -m "stuff" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with failing hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
+ echo "$PREMERGE" >expected_hooks &&
+ git checkout side &&
+ test_must_fail git merge -m "merge master" master &&
+ git checkout master &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success '--no-verify with failing hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM 'with non-executable hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
+ echo "content" >>file &&
+ git add file &&
+ git commit -m "content" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM '--no-verify with non-executable hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
+ echo "more content" >>file &&
+ git add file &&
+ git commit --no-verify -m "more content" &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM 'with non-executable hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
+ cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
+ git branch -f side side-orig &&
+ git checkout side &&
+ git merge --no-verify -m "merge master" master &&
+ git checkout master &&
+ test_path_is_missing actual_hooks
+'
+
+test_expect_success 'with hook requiring GIT_PREFIX' '
+ test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" &&
+ cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "more content" >>file &&
+ git add file &&
+ mkdir success &&
+ (
+ cd success &&
+ git commit -m "hook requires GIT_PREFIX = success/"
+ ) &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'with failing hook requiring GIT_PREFIX' '
+ test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" &&
+ cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
+ echo "$PRECOMMIT" >expected_hooks &&
+ echo "more content" >>file &&
+ git add file &&
+ mkdir fail &&
+ (
+ cd fail &&
+ test_must_fail git commit -m "hook must fail"
+ ) &&
+ git checkout -- file &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_expect_success 'check the author in hook' '
+ test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
+ cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" &&
+ cat >expected_hooks <<-EOF &&
+ $PRECOMMIT
+ $PRECOMMIT
+ $PRECOMMIT
+ EOF
+ test_must_fail git commit --allow-empty -m "by a.u.thor" &&
+ (
+ GIT_AUTHOR_NAME="New Author" &&
+ GIT_AUTHOR_EMAIL="newauthor@example.com" &&
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
+ git commit --allow-empty -m "by new.author via env" &&
+ git show -s
+ ) &&
+ git commit --author="New Author <newauthor@example.com>" \
+ --allow-empty -m "by new.author via command line" &&
+ git show -s &&
+ test_cmp expected_hooks actual_hooks
+'
+
+test_done
diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-hook.sh
deleted file mode 100755
index 984889b39d..0000000000
--- a/t/t7503-pre-commit-hook.sh
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/bin/sh
-
-test_description='pre-commit hook'
-
-. ./test-lib.sh
-
-test_expect_success 'with no hook' '
-
- echo "foo" > file &&
- git add file &&
- git commit -m "first"
-
-'
-
-test_expect_success '--no-verify with no hook' '
-
- echo "bar" > file &&
- git add file &&
- git commit --no-verify -m "bar"
-
-'
-
-# now install hook that always succeeds
-HOOKDIR="$(git rev-parse --git-dir)/hooks"
-HOOK="$HOOKDIR/pre-commit"
-mkdir -p "$HOOKDIR"
-cat > "$HOOK" <<EOF
-#!/bin/sh
-exit 0
-EOF
-chmod +x "$HOOK"
-
-test_expect_success 'with succeeding hook' '
-
- echo "more" >> file &&
- git add file &&
- git commit -m "more"
-
-'
-
-test_expect_success '--no-verify with succeeding hook' '
-
- echo "even more" >> file &&
- git add file &&
- git commit --no-verify -m "even more"
-
-'
-
-# now a hook that fails
-cat > "$HOOK" <<EOF
-#!/bin/sh
-exit 1
-EOF
-
-test_expect_success 'with failing hook' '
-
- echo "another" >> file &&
- git add file &&
- test_must_fail git commit -m "another"
-
-'
-
-test_expect_success '--no-verify with failing hook' '
-
- echo "stuff" >> file &&
- git add file &&
- git commit --no-verify -m "stuff"
-
-'
-
-chmod -x "$HOOK"
-test_expect_success POSIXPERM 'with non-executable hook' '
-
- echo "content" >> file &&
- git add file &&
- git commit -m "content"
-
-'
-
-test_expect_success POSIXPERM '--no-verify with non-executable hook' '
-
- echo "more content" >> file &&
- git add file &&
- git commit --no-verify -m "more content"
-
-'
-chmod +x "$HOOK"
-
-# a hook that checks $GIT_PREFIX and succeeds inside the
-# success/ subdirectory only
-cat > "$HOOK" <<EOF
-#!/bin/sh
-test \$GIT_PREFIX = success/
-EOF
-
-test_expect_success 'with hook requiring GIT_PREFIX' '
-
- echo "more content" >> file &&
- git add file &&
- mkdir success &&
- (
- cd success &&
- git commit -m "hook requires GIT_PREFIX = success/"
- ) &&
- rmdir success
-'
-
-test_expect_success 'with failing hook requiring GIT_PREFIX' '
-
- echo "more content" >> file &&
- git add file &&
- mkdir fail &&
- (
- cd fail &&
- test_must_fail git commit -m "hook must fail"
- ) &&
- rmdir fail &&
- git checkout -- file
-'
-
-test_expect_success 'check the author in hook' '
- write_script "$HOOK" <<-\EOF &&
- test "$GIT_AUTHOR_NAME" = "New Author" &&
- test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
- EOF
- test_must_fail git commit --allow-empty -m "by a.u.thor" &&
- (
- GIT_AUTHOR_NAME="New Author" &&
- GIT_AUTHOR_EMAIL="newauthor@example.com" &&
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
- git commit --allow-empty -m "by new.author via env" &&
- git show -s
- ) &&
- git commit --author="New Author <newauthor@example.com>" \
- --allow-empty -m "by new.author via command line" &&
- git show -s
-'
-
-test_done
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index ba8bd1b514..94f85cdf83 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -241,13 +241,7 @@ test_rebase () {
git add b &&
git rebase --continue
) &&
- if test "$mode" = -p # reword amended after pick
- then
- n=18
- else
- n=17
- fi &&
- git log --pretty=%s -g -n$n HEAD@{1} >actual &&
+ git log --pretty=%s -g -n18 HEAD@{1} >actual &&
test_cmp "$TEST_DIRECTORY/t7505/expected-rebase${mode:--i}" actual
'
}
diff --git a/t/t7505/expected-rebase-i b/t/t7505/expected-rebase-i
index c514bdbb94..93bada596e 100644
--- a/t/t7505/expected-rebase-i
+++ b/t/t7505/expected-rebase-i
@@ -7,7 +7,8 @@ message (no editor) [edit rebase-10]
message [fixup rebase-9]
message (no editor) [fixup rebase-8]
message (no editor) [squash rebase-7]
-message [reword rebase-6]
+HEAD [reword rebase-6]
+message (no editor) [reword rebase-6]
message [squash rebase-5]
message (no editor) [fixup rebase-4]
message (no editor) [pick rebase-3]
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index e01c285cbf..66d7a62797 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -733,6 +733,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '
On branch cherry_branch
You are currently cherry-picking commit $TO_CHERRY_PICK.
(fix conflicts and run "git cherry-pick --continue")
+ (use "git cherry-pick --skip" to skip this patch)
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
Unmerged paths:
@@ -757,6 +758,7 @@ test_expect_success 'status when cherry-picking after resolving conflicts' '
On branch cherry_branch
You are currently cherry-picking commit $TO_CHERRY_PICK.
(all conflicts fixed: run "git cherry-pick --continue")
+ (use "git cherry-pick --skip" to skip this patch)
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
Changes to be committed:
@@ -778,6 +780,7 @@ test_expect_success 'status when cherry-picking after committing conflict resolu
On branch cherry_branch
Cherry-pick currently in progress.
(run "git cherry-pick --continue" to continue)
+ (use "git cherry-pick --skip" to skip this patch)
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
nothing to commit (use -u to show untracked files)
@@ -835,6 +838,7 @@ test_expect_success 'status while reverting commit (conflicts)' '
On branch master
You are currently reverting commit $TO_REVERT.
(fix conflicts and run "git revert --continue")
+ (use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
Unmerged paths:
@@ -855,6 +859,7 @@ test_expect_success 'status while reverting commit (conflicts resolved)' '
On branch master
You are currently reverting commit $TO_REVERT.
(all conflicts fixed: run "git revert --continue")
+ (use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
Changes to be committed:
@@ -887,6 +892,7 @@ test_expect_success 'status while reverting after committing conflict resolution
On branch master
Revert currently in progress.
(run "git revert --continue" to continue)
+ (use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
nothing to commit (use -u to show untracked files)
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 81a375fa0f..997d5fb349 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -354,4 +354,23 @@ test_expect_success 'discard_index() also discards fsmonitor info' '
test_cmp expect actual
'
+# Test unstaging entries that:
+# - Are not flagged with CE_FSMONITOR_VALID
+# - Have a position in the index >= the number of entries present in the index
+# after unstaging.
+test_expect_success 'status succeeds after staging/unstaging' '
+ test_create_repo fsmonitor-stage-unstage &&
+ (
+ cd fsmonitor-stage-unstage &&
+ test_commit initial &&
+ git update-index --fsmonitor &&
+ removed=$(test_seq 1 100 | sed "s/^/z/") &&
+ touch $removed &&
+ git add $removed &&
+ git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" &&
+ FSMONITOR_LIST="$removed" git restore -S $removed &&
+ FSMONITOR_LIST="$removed" git status
+ )
+'
+
test_done
diff --git a/t/t7519/fsmonitor-env b/t/t7519/fsmonitor-env
new file mode 100755
index 0000000000..8f1f7ab164
--- /dev/null
+++ b/t/t7519/fsmonitor-env
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An test hook script to integrate with git to test fsmonitor.
+#
+# The hook is passed a version (currently 1) and a time in nanoseconds
+# formatted as a string and outputs to stdout all files that have been
+# modified since the given time. Paths must be relative to the root of
+# the working tree and separated by a single NUL.
+#
+#echo "$0 $*" >&2
+
+if test "$#" -ne 2
+then
+ echo "$0: exactly 2 arguments expected" >&2
+ exit 2
+fi
+
+if test "$1" != 1
+then
+ echo "Unsupported core.fsmonitor hook version." >&2
+ exit 1
+fi
+
+printf '%s\n' $FSMONITOR_LIST
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 0e9af832c9..4e855bc21b 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -243,10 +243,23 @@ test_expect_success 'no bitmaps created if .keep files present' '
pack=$(ls bare.git/objects/pack/*.pack) &&
test_path_is_file "$pack" &&
keep=${pack%.pack}.keep &&
+ test_when_finished "rm -f \"\$keep\"" &&
>"$keep" &&
- git -C bare.git repack -ad &&
+ git -C bare.git repack -ad 2>stderr &&
+ test_must_be_empty stderr &&
find bare.git/objects/pack/ -type f -name "*.bitmap" >actual &&
test_must_be_empty actual
'
+test_expect_success 'auto-bitmaps do not complain if unavailable' '
+ test_config -C bare.git pack.packSizeLimit 1M &&
+ blob=$(test-tool genrandom big $((1024*1024)) |
+ git -C bare.git hash-object -w --stdin) &&
+ git -C bare.git update-ref refs/tags/big $blob &&
+ git -C bare.git repack -ad 2>stderr &&
+ test_must_be_empty stderr &&
+ find bare.git/objects/pack -type f -name "*.bitmap" >actual &&
+ test_must_be_empty actual
+'
+
test_done
diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh
index 0c685d3598..531eb59d57 100755
--- a/t/t7812-grep-icase-non-ascii.sh
+++ b/t/t7812-grep-icase-non-ascii.sh
@@ -53,4 +53,32 @@ test_expect_success REGEX_LOCALE 'pickaxe -i on non-ascii' '
test_cmp expected actual
'
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: setup invalid UTF-8 data' '
+ printf "\\200\\n" >invalid-0x80 &&
+ echo "ævar" >expected &&
+ cat expected >>invalid-0x80 &&
+ git add invalid-0x80
+'
+
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep ASCII from invalid UTF-8 data' '
+ git grep -h "var" invalid-0x80 >actual &&
+ test_cmp expected actual &&
+ git grep -h "(*NO_JIT)var" invalid-0x80 >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-ASCII from invalid UTF-8 data' '
+ git grep -h "æ" invalid-0x80 >actual &&
+ test_cmp expected actual &&
+ git grep -h "(*NO_JIT)æ" invalid-0x80 &&
+ 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
+'
+
test_done
diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index a11366b4ce..946f91fa57 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -408,4 +408,25 @@ test_expect_success 'grep --recurse-submodules with submodules without .gitmodul
test_cmp expect actual
'
+reset_and_clean () {
+ git reset --hard &&
+ git clean -fd &&
+ git submodule foreach --recursive 'git reset --hard' &&
+ git submodule foreach --recursive 'git clean -fd'
+}
+
+test_expect_success 'grep --recurse-submodules without --cached considers worktree modifications' '
+ reset_and_clean &&
+ echo "A modified line in submodule" >>submodule/a &&
+ echo "submodule/a:A modified line in submodule" >expect &&
+ git grep --recurse-submodules "A modified line in submodule" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep --recurse-submodules with --cached ignores worktree modifications' '
+ reset_and_clean &&
+ echo "A modified line in submodule" >>submodule/a &&
+ test_must_fail git grep --recurse-submodules --cached "A modified line in submodule" >actual 2>&1 &&
+ test_must_be_empty actual
+'
test_done
diff --git a/t/t7008-grep-binary.sh b/t/t7815-grep-binary.sh
index 2d87c49b75..90ebb64f46 100755
--- a/t/t7008-grep-binary.sh
+++ b/t/t7815-grep-binary.sh
@@ -4,41 +4,6 @@ test_description='git grep in binary files'
. ./test-lib.sh
-nul_match () {
- matches=$1
- flags=$2
- pattern=$3
- pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g')
-
- if test "$matches" = 1
- then
- test_expect_success "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- git grep -f f $flags a
- "
- elif test "$matches" = 0
- then
- test_expect_success "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- test_must_fail git grep -f f $flags a
- "
- elif test "$matches" = T1
- then
- test_expect_failure "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- git grep -f f $flags a
- "
- elif test "$matches" = T0
- then
- test_expect_failure "git grep -f f $flags '$pattern_human' a" "
- printf '$pattern' | q_to_nul >f &&
- test_must_fail git grep -f f $flags a
- "
- else
- test_expect_success "PANIC: Test framework error. Unknown matches value $matches" 'false'
- fi
-}
-
test_expect_success 'setup' "
echo 'binaryQfileQm[*]cQ*æQð' | q_to_nul >a &&
git add a &&
@@ -102,72 +67,6 @@ test_expect_failure 'git grep .fi a' '
git grep .fi a
'
-nul_match 1 '-F' 'yQf'
-nul_match 0 '-F' 'yQx'
-nul_match 1 '-Fi' 'YQf'
-nul_match 0 '-Fi' 'YQx'
-nul_match 1 '' 'yQf'
-nul_match 0 '' 'yQx'
-nul_match 1 '' 'æQð'
-nul_match 1 '-F' 'eQm[*]c'
-nul_match 1 '-Fi' 'EQM[*]C'
-
-# Regex patterns that would match but shouldn't with -F
-nul_match 0 '-F' 'yQ[f]'
-nul_match 0 '-F' '[y]Qf'
-nul_match 0 '-Fi' 'YQ[F]'
-nul_match 0 '-Fi' '[Y]QF'
-nul_match 0 '-F' 'æQ[ð]'
-nul_match 0 '-F' '[æ]Qð'
-nul_match 0 '-Fi' 'ÆQ[Ð]'
-nul_match 0 '-Fi' '[Æ]QÐ'
-
-# kwset is disabled on -i & non-ASCII. No way to match non-ASCII \0
-# patterns case-insensitively.
-nul_match T1 '-i' 'ÆQÐ'
-
-# \0 implicitly disables regexes. This is an undocumented internal
-# limitation.
-nul_match T1 '' 'yQ[f]'
-nul_match T1 '' '[y]Qf'
-nul_match T1 '-i' 'YQ[F]'
-nul_match T1 '-i' '[Y]Qf'
-nul_match T1 '' 'æQ[ð]'
-nul_match T1 '' '[æ]Qð'
-nul_match T1 '-i' 'ÆQ[Ð]'
-
-# ... because of \0 implicitly disabling regexes regexes that
-# should/shouldn't match don't do the right thing.
-nul_match T1 '' 'eQm.*cQ'
-nul_match T1 '-i' 'EQM.*cQ'
-nul_match T0 '' 'eQm[*]c'
-nul_match T0 '-i' 'EQM[*]C'
-
-# Due to the REG_STARTEND extension when kwset() is disabled on -i &
-# non-ASCII the string will be matched in its entirety, but the
-# pattern will be cut off at the first \0.
-nul_match 0 '-i' 'NOMATCHQð'
-nul_match T0 '-i' '[Æ]QNOMATCH'
-nul_match T0 '-i' '[æ]QNOMATCH'
-# Matches, but for the wrong reasons, just stops at [æ]
-nul_match 1 '-i' '[Æ]Qð'
-nul_match 1 '-i' '[æ]Qð'
-
-# Ensure that the matcher doesn't regress to something that stops at
-# \0
-nul_match 0 '-F' 'yQ[f]'
-nul_match 0 '-Fi' 'YQ[F]'
-nul_match 0 '' 'yQNOMATCH'
-nul_match 0 '' 'QNOMATCH'
-nul_match 0 '-i' 'YQNOMATCH'
-nul_match 0 '-i' 'QNOMATCH'
-nul_match 0 '-F' 'æQ[ð]'
-nul_match 0 '-Fi' 'ÆQ[Ð]'
-nul_match 0 '' 'yQNÓMATCH'
-nul_match 0 '' 'QNÓMATCH'
-nul_match 0 '-i' 'YQNÓMATCH'
-nul_match 0 '-i' 'QNÓMATCH'
-
test_expect_success 'grep respects binary diff attribute' '
echo text >t &&
git add t &&
diff --git a/t/t7816-grep-binary-pattern.sh b/t/t7816-grep-binary-pattern.sh
new file mode 100755
index 0000000000..60bab291e4
--- /dev/null
+++ b/t/t7816-grep-binary-pattern.sh
@@ -0,0 +1,127 @@
+#!/bin/sh
+
+test_description='git grep with a binary pattern files'
+
+. ./lib-gettext.sh
+
+nul_match_internal () {
+ matches=$1
+ prereqs=$2
+ lc_all=$3
+ extra_flags=$4
+ flags=$5
+ pattern=$6
+ pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g')
+
+ if test "$matches" = 1
+ then
+ test_expect_success $prereqs "LC_ALL='$lc_all' git grep $extra_flags -f f $flags '$pattern_human' a" "
+ printf '$pattern' | q_to_nul >f &&
+ LC_ALL='$lc_all' git grep $extra_flags -f f $flags a
+ "
+ elif test "$matches" = 0
+ then
+ test_expect_success $prereqs "LC_ALL='$lc_all' git grep $extra_flags -f f $flags '$pattern_human' a" "
+ >stderr &&
+ printf '$pattern' | q_to_nul >f &&
+ test_must_fail env LC_ALL=\"$lc_all\" git grep $extra_flags -f f $flags a 2>stderr &&
+ test_i18ngrep ! 'This is only supported with -P under PCRE v2' stderr
+ "
+ elif test "$matches" = P
+ then
+ test_expect_success $prereqs "error, PCRE v2 only: LC_ALL='$lc_all' git grep -f f $flags '$pattern_human' a" "
+ >stderr &&
+ printf '$pattern' | q_to_nul >f &&
+ test_must_fail env LC_ALL=\"$lc_all\" git grep -f f $flags a 2>stderr &&
+ test_i18ngrep 'This is only supported with -P under PCRE v2' stderr
+ "
+ else
+ test_expect_success "PANIC: Test framework error. Unknown matches value $matches" 'false'
+ fi
+}
+
+nul_match () {
+ matches=$1
+ matches_pcre2=$2
+ matches_pcre2_locale=$3
+ flags=$4
+ pattern=$5
+ pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g')
+
+ nul_match_internal "$matches" "" "C" "" "$flags" "$pattern"
+ nul_match_internal "$matches_pcre2" "LIBPCRE2" "C" "-P" "$flags" "$pattern"
+ nul_match_internal "$matches_pcre2_locale" "LIBPCRE2,GETTEXT_LOCALE" "$is_IS_locale" "-P" "$flags" "$pattern"
+}
+
+test_expect_success 'setup' "
+ echo 'binaryQfileQm[*]cQ*æQð' | q_to_nul >a &&
+ git add a &&
+ git commit -m.
+"
+
+# Simple fixed-string matching that can use kwset (no -i && non-ASCII)
+nul_match P P P '-F' 'yQf'
+nul_match P P P '-F' 'yQx'
+nul_match P P P '-Fi' 'YQf'
+nul_match P P P '-Fi' 'YQx'
+nul_match P P 1 '' 'yQf'
+nul_match P P 0 '' 'yQx'
+nul_match P P 1 '' 'æQð'
+nul_match P P P '-F' 'eQm[*]c'
+nul_match P P P '-Fi' 'EQM[*]C'
+
+# Regex patterns that would match but shouldn't with -F
+nul_match P P P '-F' 'yQ[f]'
+nul_match P P P '-F' '[y]Qf'
+nul_match P P P '-Fi' 'YQ[F]'
+nul_match P P P '-Fi' '[Y]QF'
+nul_match P P P '-F' 'æQ[ð]'
+nul_match P P P '-F' '[æ]Qð'
+
+# The -F kwset codepath can't handle -i && non-ASCII...
+nul_match P 1 1 '-i' '[æ]Qð'
+
+# ...PCRE v2 only matches non-ASCII with -i casefolding under UTF-8
+# semantics
+nul_match P P P '-Fi' 'ÆQ[Ð]'
+nul_match P 0 1 '-i' 'ÆQ[Ð]'
+nul_match P 0 1 '-i' '[Æ]QÐ'
+nul_match P 0 1 '-i' '[Æ]Qð'
+nul_match P 0 1 '-i' 'ÆQÐ'
+
+# \0 in regexes can only work with -P & PCRE v2
+nul_match P P 1 '' 'yQ[f]'
+nul_match P P 1 '' '[y]Qf'
+nul_match P P 1 '-i' 'YQ[F]'
+nul_match P P 1 '-i' '[Y]Qf'
+nul_match P P 1 '' 'æQ[ð]'
+nul_match P P 1 '' '[æ]Qð'
+nul_match P P 1 '-i' 'ÆQ[Ð]'
+nul_match P P 1 '' 'eQm.*cQ'
+nul_match P P 1 '-i' 'EQM.*cQ'
+nul_match P P 0 '' 'eQm[*]c'
+nul_match P P 0 '-i' 'EQM[*]C'
+
+# Assert that we're using REG_STARTEND and the pattern doesn't match
+# just because it's cut off at the first \0.
+nul_match P P 0 '-i' 'NOMATCHQð'
+nul_match P P 0 '-i' '[Æ]QNOMATCH'
+nul_match P P 0 '-i' '[æ]QNOMATCH'
+
+# Ensure that the matcher doesn't regress to something that stops at
+# \0
+nul_match P P P '-F' 'yQ[f]'
+nul_match P P P '-Fi' 'YQ[F]'
+nul_match P P 0 '' 'yQNOMATCH'
+nul_match P P 0 '' 'QNOMATCH'
+nul_match P P 0 '-i' 'YQNOMATCH'
+nul_match P P 0 '-i' 'QNOMATCH'
+nul_match P P P '-F' 'æQ[ð]'
+nul_match P P P '-Fi' 'ÆQ[Ð]'
+nul_match P P 1 '-i' 'ÆQ[Ð]'
+nul_match P P 0 '' 'yQNÓMATCH'
+nul_match P P 0 '' 'QNÓMATCH'
+nul_match P P 0 '-i' 'YQNÓMATCH'
+nul_match P P 0 '-i' 'QNÓMATCH'
+
+test_done
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 141b7fa35e..e707fb861e 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -85,6 +85,36 @@ test_expect_success 'A: create pack from stdin' '
An annotated tag that annotates a blob.
EOF
+ tag to-be-deleted
+ from :3
+ data <<EOF
+ Another annotated tag that annotates a blob.
+ EOF
+
+ reset refs/tags/to-be-deleted
+ from 0000000000000000000000000000000000000000
+
+ tag nested
+ mark :6
+ from :4
+ data <<EOF
+ Tag of our lovely commit
+ EOF
+
+ reset refs/tags/nested
+ from 0000000000000000000000000000000000000000
+
+ tag nested
+ mark :7
+ from :6
+ data <<EOF
+ Tag of tag of our lovely commit
+ EOF
+
+ alias
+ mark :8
+ to :5
+
INPUT_END
git fast-import --export-marks=marks.out <input &&
git whatchanged master
@@ -157,12 +187,19 @@ test_expect_success 'A: verify tag/series-A-blob' '
test_cmp expect actual
'
+test_expect_success 'A: verify tag deletion is successful' '
+ test_must_fail git rev-parse --verify refs/tags/to-be-deleted
+'
+
test_expect_success 'A: verify marks output' '
cat >expect <<-EOF &&
:2 $(git rev-parse --verify master:file2)
:3 $(git rev-parse --verify master:file3)
:4 $(git rev-parse --verify master:file4)
:5 $(git rev-parse --verify master^0)
+ :6 $(git cat-file tag nested | grep object | cut -d" " -f 2)
+ :7 $(git rev-parse --verify nested)
+ :8 $(git rev-parse --verify master^0)
EOF
test_cmp expect marks.out
'
@@ -2781,7 +2818,6 @@ test_expect_success 'S: filemodify with garbage after mark must fail' '
COMMIT
M 100644 :403x hello.c
EOF
- cat err &&
test_i18ngrep "space after mark" err
'
@@ -2798,7 +2834,6 @@ test_expect_success 'S: filemodify with garbage after inline must fail' '
inline
BLOB
EOF
- cat err &&
test_i18ngrep "nvalid dataref" err
'
@@ -2812,7 +2847,6 @@ test_expect_success 'S: filemodify with garbage after sha1 must fail' '
COMMIT
M 100644 ${sha1}x hello.c
EOF
- cat err &&
test_i18ngrep "space after SHA1" err
'
@@ -2828,7 +2862,6 @@ test_expect_success 'S: notemodify with garbage after mark dataref must fail' '
COMMIT
N :202x :302
EOF
- cat err &&
test_i18ngrep "space after mark" err
'
@@ -2844,7 +2877,6 @@ test_expect_success 'S: notemodify with garbage after inline dataref must fail'
note blob
BLOB
EOF
- cat err &&
test_i18ngrep "nvalid dataref" err
'
@@ -2858,7 +2890,6 @@ test_expect_success 'S: notemodify with garbage after sha1 dataref must fail' '
COMMIT
N ${sha1}x :302
EOF
- cat err &&
test_i18ngrep "space after SHA1" err
'
@@ -2874,7 +2905,6 @@ test_expect_success 'S: notemodify with garbage after mark commit-ish must fail'
COMMIT
N :202 :302x
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2908,7 +2938,6 @@ test_expect_success 'S: from with garbage after mark must fail' '
EOF
# now evaluate the error
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2928,7 +2957,6 @@ test_expect_success 'S: merge with garbage after mark must fail' '
merge :303x
M 100644 :403 hello.c
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2944,7 +2972,6 @@ test_expect_success 'S: tag with garbage after mark must fail' '
tag S
TAG
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2955,7 +2982,6 @@ test_expect_success 'S: cat-blob with garbage after mark must fail' '
test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
cat-blob :403x
EOF
- cat err &&
test_i18ngrep "after mark" err
'
@@ -2966,7 +2992,6 @@ test_expect_success 'S: ls with garbage after mark must fail' '
test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
ls :302x hello.c
EOF
- cat err &&
test_i18ngrep "space after mark" err
'
@@ -2975,7 +3000,6 @@ test_expect_success 'S: ls with garbage after sha1 must fail' '
test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
ls ${sha1}x hello.c
EOF
- cat err &&
test_i18ngrep "space after tree-ish" err
'
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index b4004e05c2..2e4e214815 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -53,6 +53,33 @@ test_expect_success 'fast-export | fast-import' '
'
+test_expect_success 'fast-export ^muss^{commit} muss' '
+ git fast-export --tag-of-filtered-object=rewrite ^muss^{commit} muss >actual &&
+ cat >expected <<-EOF &&
+ tag muss
+ from $(git rev-parse --verify muss^{commit})
+ $(git cat-file tag muss | grep tagger)
+ data 9
+ valentin
+
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'fast-export --mark-tags ^muss^{commit} muss' '
+ git fast-export --mark-tags --tag-of-filtered-object=rewrite ^muss^{commit} muss >actual &&
+ cat >expected <<-EOF &&
+ tag muss
+ mark :1
+ from $(git rev-parse --verify muss^{commit})
+ $(git cat-file tag muss | grep tagger)
+ data 9
+ valentin
+
+ EOF
+ test_cmp expected actual
+'
+
test_expect_success 'fast-export master~2..master' '
git fast-export master~2..master >actual &&
@@ -513,10 +540,41 @@ test_expect_success 'tree_tag' '
'
# NEEDSWORK: not just check return status, but validate the output
+# Note that these tests DO NOTHING other than print a warning that
+# they are ommitting the one tag we asked them to export (because the
+# tags resolve to a tree). They exist just to make sure we do not
+# abort but instead just warn.
test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj'
test_expect_success 'tag-obj_tag' 'git fast-export tag-obj_tag'
test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj'
+test_expect_success 'handling tags of blobs' '
+ git tag -a -m "Tag of a blob" blobtag $(git rev-parse master:file) &&
+ git fast-export blobtag >actual &&
+ cat >expect <<-EOF &&
+ blob
+ mark :1
+ data 9
+ die Luft
+
+ tag blobtag
+ from :1
+ tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data 14
+ Tag of a blob
+
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'handling nested tags' '
+ git tag -a -m "This is a nested tag" nested muss &&
+ git fast-export --mark-tags nested >output &&
+ grep "^from $ZERO_OID$" output &&
+ grep "^tag nested$" output >tag_lines &&
+ test_line_count = 2 tag_lines
+'
+
test_expect_success 'directory becomes symlink' '
git init dirtosymlink &&
git init result &&
@@ -567,17 +625,15 @@ test_expect_success 'fast-export quotes pathnames' '
'
test_expect_success 'test bidirectionality' '
- >marks-cur &&
- >marks-new &&
git init marks-test &&
- git fast-export --export-marks=marks-cur --import-marks=marks-cur --branches | \
- git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks=marks-new &&
+ git fast-export --export-marks=marks-cur --import-marks-if-exists=marks-cur --branches | \
+ git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks-if-exists=marks-new &&
(cd marks-test &&
git reset --hard &&
echo Wohlauf > file &&
git commit -a -m "back in time") &&
- git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks=marks-new --branches | \
- git fast-import --export-marks=marks-cur --import-marks=marks-cur
+ git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks-if-exists=marks-new --branches | \
+ git fast-import --export-marks=marks-cur --import-marks-if-exists=marks-cur
'
cat > expected << EOF
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 43cf313a1c..54f8ce18cb 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -28,10 +28,10 @@ complete ()
#
# (2) A test makes sure that common subcommands are included in the
# completion for "git <TAB>", and a plumbing is excluded. "add",
-# "filter-branch" and "ls-files" are listed for this.
+# "rebase" and "ls-files" are listed for this.
-GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr filter-branch ls-files'
-GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout filter-branch'
+GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr rebase ls-files'
+GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout rebase'
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
@@ -1392,12 +1392,12 @@ test_expect_success 'basic' '
# built-in
grep -q "^add \$" out &&
# script
- grep -q "^filter-branch \$" out &&
+ grep -q "^rebase \$" out &&
# plumbing
! grep -q "^ls-files \$" out &&
- run_completion "git f" &&
- ! grep -q -v "^f" out
+ run_completion "git r" &&
+ ! grep -q -v "^r" out
'
test_expect_success 'double dash "git" itself' '
@@ -1698,6 +1698,69 @@ do
'
done
+test_expect_success 'git config - section' '
+ test_completion "git config br" <<-\EOF
+ branch.Z
+ browser.Z
+ EOF
+'
+
+test_expect_success 'git config - variable name' '
+ test_completion "git config log.d" <<-\EOF
+ log.date Z
+ log.decorate Z
+ EOF
+'
+
+test_expect_success 'git config - value' '
+ test_completion "git config color.pager " <<-\EOF
+ false Z
+ true Z
+ EOF
+'
+
+test_expect_success 'git -c - section' '
+ test_completion "git -c br" <<-\EOF
+ branch.Z
+ browser.Z
+ EOF
+'
+
+test_expect_success 'git -c - variable name' '
+ test_completion "git -c log.d" <<-\EOF
+ log.date=Z
+ log.decorate=Z
+ EOF
+'
+
+test_expect_success 'git -c - value' '
+ test_completion "git -c color.pager=" <<-\EOF
+ false Z
+ true Z
+ EOF
+'
+
+test_expect_success 'git clone --config= - section' '
+ test_completion "git clone --config=br" <<-\EOF
+ branch.Z
+ browser.Z
+ EOF
+'
+
+test_expect_success 'git clone --config= - variable name' '
+ test_completion "git clone --config=log.d" <<-\EOF
+ log.date=Z
+ log.decorate=Z
+ EOF
+'
+
+test_expect_success 'git clone --config= - value' '
+ test_completion "git clone --config=color.pager=" <<-\EOF
+ false Z
+ true Z
+ EOF
+'
+
test_expect_success 'sourcing the completion script clears cached commands' '
__git_compute_all_commands &&
verbose test -n "$__git_all_commands" &&
@@ -1706,7 +1769,7 @@ test_expect_success 'sourcing the completion script clears cached commands' '
'
test_expect_success 'sourcing the completion script clears cached merge strategies' '
- GIT_TEST_GETTEXT_POISON= &&
+ GIT_TEST_GETTEXT_POISON=false &&
__git_compute_merge_strategies &&
verbose test -n "$__git_merge_strategies" &&
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 7308f67922..b299ecc326 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -228,9 +228,134 @@ test_commit () {
# can be a tag pointing to the commit-to-merge.
test_merge () {
+ label="$1" &&
+ shift &&
test_tick &&
- git merge -m "$1" "$2" &&
- git tag "$1"
+ git merge -m "$label" "$@" &&
+ git tag "$label"
+}
+
+# Efficiently create <nr> commits, each with a unique number (from 1 to <nr>
+# by default) in the commit message.
+#
+# Usage: test_commit_bulk [options] <nr>
+# -C <dir>:
+# Run all git commands in directory <dir>
+# --ref=<n>:
+# ref on which to create commits (default: HEAD)
+# --start=<n>:
+# number commit messages from <n> (default: 1)
+# --message=<msg>:
+# use <msg> as the commit mesasge (default: "commit %s")
+# --filename=<fn>:
+# modify <fn> in each commit (default: %s.t)
+# --contents=<string>:
+# place <string> in each file (default: "content %s")
+# --id=<string>:
+# shorthand to use <string> and %s in message, filename, and contents
+#
+# The message, filename, and contents strings are evaluated by printf, with the
+# first "%s" replaced by the current commit number. So you can do:
+#
+# test_commit_bulk --filename=file --contents="modification %s"
+#
+# to have every commit touch the same file, but with unique content.
+#
+test_commit_bulk () {
+ tmpfile=.bulk-commit.input
+ indir=.
+ ref=HEAD
+ n=1
+ message='commit %s'
+ filename='%s.t'
+ contents='content %s'
+ while test $# -gt 0
+ do
+ case "$1" in
+ -C)
+ indir=$2
+ shift
+ ;;
+ --ref=*)
+ ref=${1#--*=}
+ ;;
+ --start=*)
+ n=${1#--*=}
+ ;;
+ --message=*)
+ message=${1#--*=}
+ ;;
+ --filename=*)
+ filename=${1#--*=}
+ ;;
+ --contents=*)
+ contents=${1#--*=}
+ ;;
+ --id=*)
+ message="${1#--*=} %s"
+ filename="${1#--*=}-%s.t"
+ contents="${1#--*=} %s"
+ ;;
+ -*)
+ BUG "invalid test_commit_bulk option: $1"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done
+ total=$1
+
+ add_from=
+ if git -C "$indir" rev-parse --verify "$ref"
+ then
+ add_from=t
+ fi
+
+ while test "$total" -gt 0
+ do
+ test_tick &&
+ echo "commit $ref"
+ printf 'author %s <%s> %s\n' \
+ "$GIT_AUTHOR_NAME" \
+ "$GIT_AUTHOR_EMAIL" \
+ "$GIT_AUTHOR_DATE"
+ printf 'committer %s <%s> %s\n' \
+ "$GIT_COMMITTER_NAME" \
+ "$GIT_COMMITTER_EMAIL" \
+ "$GIT_COMMITTER_DATE"
+ echo "data <<EOF"
+ printf "$message\n" $n
+ echo "EOF"
+ if test -n "$add_from"
+ then
+ echo "from $ref^0"
+ add_from=
+ fi
+ printf "M 644 inline $filename\n" $n
+ echo "data <<EOF"
+ printf "$contents\n" $n
+ echo "EOF"
+ echo
+ n=$((n + 1))
+ total=$((total - 1))
+ done >"$tmpfile"
+
+ git -C "$indir" \
+ -c fastimport.unpacklimit=0 \
+ fast-import <"$tmpfile" || return 1
+
+ # This will be left in place on failure, which may aid debugging.
+ rm -f "$tmpfile"
+
+ # If we updated HEAD, then be nice and update the index and working
+ # tree, too.
+ if test "$ref" = "HEAD"
+ then
+ git -C "$indir" checkout -f HEAD || return 1
+ fi
+
}
# This function helps systems where core.filemode=false is set.
@@ -309,7 +434,7 @@ test_unset_prereq () {
}
test_set_prereq () {
- if test -n "$GIT_TEST_FAIL_PREREQS"
+ if test -n "$GIT_TEST_FAIL_PREREQS_INTERNAL"
then
case "$1" in
# The "!" case is handled below with
@@ -457,7 +582,7 @@ test_expect_failure () {
export test_prereq
if ! test_skip "$@"
then
- say >&3 "checking known breakage: $2"
+ say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2"
if test_run_ "$2" expecting_failure
then
test_known_broken_ok_ "$1"
@@ -477,7 +602,7 @@ test_expect_success () {
export test_prereq
if ! test_skip "$@"
then
- say >&3 "expecting success: $2"
+ say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2"
if test_run_ "$2"
then
test_ok_ "$1"
@@ -1050,62 +1175,20 @@ perl () {
command "$PERL_PATH" "$@" 2>&7
} 7>&2 2>&4
-# Is the value one of the various ways to spell a boolean true/false?
-test_normalize_bool () {
- git -c magic.variable="$1" config --bool magic.variable 2>/dev/null
-}
-
-# Given a variable $1, normalize the value of it to one of "true",
-# "false", or "auto" and store the result to it.
-#
-# test_tristate GIT_TEST_HTTPD
-#
-# A variable set to an empty string is set to 'false'.
-# A variable set to 'false' or 'auto' keeps its value.
-# Anything else is set to 'true'.
-# An unset variable defaults to 'auto'.
-#
-# The last rule is to allow people to set the variable to an empty
-# string and export it to decline testing the particular feature
-# for versions both before and after this change. We used to treat
-# both unset and empty variable as a signal for "do not test" and
-# took any non-empty string as "please test".
-
-test_tristate () {
- if eval "test x\"\${$1+isset}\" = xisset"
- then
- # explicitly set
- eval "
- case \"\$$1\" in
- '') $1=false ;;
- auto) ;;
- *) $1=\$(test_normalize_bool \$$1 || echo true) ;;
- esac
- "
- else
- eval "$1=auto"
- fi
-}
-
# Exit the test suite, either by skipping all remaining tests or by
-# exiting with an error. If "$1" is "auto", we then we assume we were
-# opportunistically trying to set up some tests and we skip. If it is
-# "true", then we report a failure.
+# exiting with an error. If our prerequisite variable $1 falls back
+# on a default assume we were opportunistically trying to set up some
+# tests and we skip. If it is explicitly "true", then we report a failure.
#
# The error/skip message should be given by $2.
#
test_skip_or_die () {
- case "$1" in
- auto)
+ if ! git env--helper --type=bool --default=false --exit-code $1
+ then
skip_all=$2
test_done
- ;;
- true)
- error "$2"
- ;;
- *)
- error "BUG: test tristate is '$1' (real error: $2)"
- esac
+ fi
+ error "$2"
}
# The following mingw_* functions obey POSIX shell syntax, but are actually
@@ -1349,6 +1432,13 @@ test_oid () {
eval "printf '%s' \"\${$var}\""
}
+# Insert a slash into an object ID so it can be used to reference a location
+# under ".git/objects". For example, "deadbeef..." becomes "de/adbeef..".
+test_oid_to_path () {
+ local basename=${1#??}
+ echo "${1%$basename}/$basename"
+}
+
# Choose a port number based on the test script's number and store it in
# the given variable name, unless that variable already contains a number.
test_set_port () {
diff --git a/t/test-lib.sh b/t/test-lib.sh
index d1ba33745a..e06fa02a0e 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -212,6 +212,8 @@ fi
TEST_STRESS_JOB_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
TEST_NAME="$(basename "$0" .sh)"
+TEST_NUMBER="${TEST_NAME%%-*}"
+TEST_NUMBER="${TEST_NUMBER#t}"
TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
@@ -507,6 +509,9 @@ EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
LF='
'
+# Single quote
+SQ=\'
+
# UTF-8 ZERO WIDTH NON-JOINER, which HFS+ ignores
# when case-folding filenames
u200c=$(printf '\342\200\214')
@@ -567,6 +572,7 @@ export TERM
error () {
say_color error "error: $*"
+ finalize_junit_xml
GIT_EXIT_OK=t
exit 1
}
@@ -695,7 +701,7 @@ test_failure_ () {
say_color error "not ok $test_count - $1"
shift
printf '%s\n' "$*" | sed -e 's/^/# /'
- test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
+ test "$immediate" = "" || { finalize_junit_xml; GIT_EXIT_OK=t; exit 1; }
}
test_known_broken_ok_ () {
@@ -1063,6 +1069,25 @@ write_junit_xml_testcase () {
junit_have_testcase=t
}
+finalize_junit_xml () {
+ if test -n "$write_junit_xml" && test -n "$junit_xml_path"
+ then
+ test -n "$junit_have_testcase" || {
+ junit_start=$(test-tool date getnanos)
+ write_junit_xml_testcase "all tests skipped"
+ }
+
+ # adjust the overall time
+ junit_time=$(test-tool date getnanos $junit_suite_start)
+ sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ <"$junit_xml_path" >"$junit_xml_path.new"
+ mv "$junit_xml_path.new" "$junit_xml_path"
+
+ write_junit_xml " </testsuite>" "</testsuites>"
+ write_junit_xml=
+ fi
+}
+
test_atexit_cleanup=:
test_atexit_handler () {
# In a succeeding test script 'test_atexit_handler' is invoked
@@ -1085,21 +1110,7 @@ test_done () {
# removed, so the commands can access pidfiles and socket files.
test_atexit_handler
- if test -n "$write_junit_xml" && test -n "$junit_xml_path"
- then
- test -n "$junit_have_testcase" || {
- junit_start=$(test-tool date getnanos)
- write_junit_xml_testcase "all tests skipped"
- }
-
- # adjust the overall time
- junit_time=$(test-tool date getnanos $junit_suite_start)
- sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
- <"$junit_xml_path" >"$junit_xml_path.new"
- mv "$junit_xml_path.new" "$junit_xml_path"
-
- write_junit_xml " </testsuite>" "</testsuites>"
- fi
+ finalize_junit_xml
if test -z "$HARNESS_ACTIVE"
then
@@ -1388,6 +1399,25 @@ yes () {
done
}
+# 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.
+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
+ 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
+ '
+fi
+
# Fix some commands on Windows
uname_s=$(uname -s)
case $uname_s in
@@ -1442,11 +1472,9 @@ then
unset GIT_TEST_GETTEXT_POISON_ORIG
fi
-# Can we rely on git's output in the C locale?
-if test -z "$GIT_TEST_GETTEXT_POISON"
-then
- test_set_prereq C_LOCALE_OUTPUT
-fi
+test_lazy_prereq C_LOCALE_OUTPUT '
+ ! git env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON
+'
if test -z "$GIT_TEST_CHECK_CACHE_TREE"
then
@@ -1606,7 +1634,3 @@ test_lazy_prereq SHA1 '
test_lazy_prereq REBASE_P '
test -z "$GIT_TEST_SKIP_REBASE_P"
'
-
-test_lazy_prereq FAIL_PREREQS '
- test -n "$GIT_TEST_FAIL_PREREQS"
-'