summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/helper/.gitignore9
-rw-r--r--t/helper/test-date.c27
-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-run-command.c153
-rw-r--r--t/helper/test-tool.c1
-rw-r--r--t/helper/test-tool.h1
-rw-r--r--t/lib-rebase.sh28
-rwxr-xr-xt/t0000-basic.sh38
-rwxr-xr-xt/t0014-alias.sh7
-rwxr-xr-xt/t0028-working-tree-encoding.sh41
-rwxr-xr-xt/t0050-filesystem.sh20
-rwxr-xr-xt/t0060-path-utils.sh2
-rwxr-xr-xt/t0061-run-command.sh21
-rwxr-xr-xt/t0212-trace2-event.sh19
-rwxr-xr-xt/t0410-partial-clone.sh27
-rwxr-xr-xt/t0500-progress-display.sh286
-rwxr-xr-xt/t1308-config-set.sh8
-rwxr-xr-xt/t1450-fsck.sh16
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh8
-rwxr-xr-xt/t1600-index.sh4
-rwxr-xr-xt/t3030-merge-recursive.sh37
-rwxr-xr-xt/t3206-range-diff.sh44
-rw-r--r--t/t3206/history.export31
-rwxr-xr-xt/t3301-notes.sh46
-rwxr-xr-xt/t3404-rebase-interactive.sh606
-rwxr-xr-xt/t3429-rebase-edit-todo.sh21
-rwxr-xr-xt/t3701-add-interactive.sh2
-rwxr-xr-xt/t3903-stash.sh27
-rwxr-xr-xt/t3906-stash-submodule.sh42
-rwxr-xr-xt/t3908-stash-in-worktree.sh27
-rwxr-xr-xt/t4014-format-patch.sh203
-rw-r--r--t/t4018/dts-nodes-boolean-prop9
-rw-r--r--t/t4018/dts-nodes-multiline-prop13
-rw-r--r--t/t4018/dts-root2
-rw-r--r--t/t4018/dts-root-comment8
-rwxr-xr-xt/t4038-diff-combined.sh2
-rwxr-xr-xt/t4108-apply-threeway.sh55
-rwxr-xr-xt/t4202-log.sh15
-rwxr-xr-xt/t4203-mailmap.sh122
-rwxr-xr-xt/t4210-log-i18n.sh41
-rwxr-xr-xt/t4214-log-graph-octopus.sh329
-rwxr-xr-xt/t5318-commit-graph.sh79
-rwxr-xr-xt/t5319-multi-pack-index.sh69
-rwxr-xr-xt/t5324-split-commit-graph.sh2
-rwxr-xr-xt/t5500-fetch-pack.sh38
-rwxr-xr-xt/t5510-fetch.sh16
-rwxr-xr-xt/t5514-fetch-multiple.sh11
-rwxr-xr-xt/t5541-http-push-smart.sh46
-rwxr-xr-xt/t5616-partial-clone.sh44
-rwxr-xr-xt/t5801-remote-helpers.sh1
-rwxr-xr-xt/t6006-rev-list-format.sh28
-rwxr-xr-xt/t6036-recursive-corner-cases.sh8
-rwxr-xr-xt/t6042-merge-rename-corner-cases.sh111
-rwxr-xr-xt/t6043-merge-rename-directories.sh568
-rwxr-xr-xt/t6046-merge-skip-unneeded-updates.sh135
-rwxr-xr-xt/t6047-diff3-conflict-markers.sh202
-rwxr-xr-xt/t6120-describe.sh15
-rwxr-xr-xt/t7008-filter-branch-null-sha1.sh (renamed from t/t7009-filter-branch-null-sha1.sh)0
-rwxr-xr-xt/t7012-skip-worktree-writing.sh15
-rwxr-xr-xt/t7300-clean.sh44
-rwxr-xr-xt/t7400-submodule-basic.sh2
-rwxr-xr-xt/t7419-submodule-set-branch.sh6
-rwxr-xr-xt/t7505-prepare-commit-msg-hook.sh8
-rw-r--r--t/t7505/expected-rebase-i3
-rwxr-xr-xt/t7519-status-fsmonitor.sh19
-rwxr-xr-xt/t7519/fsmonitor-env24
-rwxr-xr-xt/t7812-grep-icase-non-ascii.sh28
-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.sh5
-rw-r--r--t/test-lib-functions.sh6
-rw-r--r--t/test-lib.sh46
76 files changed, 3552 insertions, 914 deletions
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-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-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 ce7e89028c..19ee26d931 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -42,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 f805bb39ae..c2aa56ef50 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -32,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-rebase.sh b/t/lib-rebase.sh
index 6d87961e41..b72c051f47 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -119,3 +119,31 @@ make_empty () {
git commit --allow-empty -m "$1" &&
git tag "$1"
}
+
+# Call this (inside test_expect_success) at the end of a test file to
+# check that no tests have changed editor related environment
+# variables or config settings
+test_editor_unchanged () {
+ # We're only interested in exported variables hence 'sh -c'
+ sh -c 'cat >actual <<-EOF
+ EDITOR=$EDITOR
+ FAKE_COMMIT_AMEND=$FAKE_COMMIT_AMEND
+ FAKE_COMMIT_MESSAGE=$FAKE_COMMIT_MESSAGE
+ FAKE_LINES=$FAKE_LINES
+ GIT_EDITOR=$GIT_EDITOR
+ GIT_SEQUENCE_EDITOR=$GIT_SEQUENCE_EDITOR
+ core.editor=$(git config core.editor)
+ sequence.editor=$(git config sequence.editor)
+ EOF'
+ cat >expect <<-\EOF
+ EDITOR=:
+ FAKE_COMMIT_AMEND=
+ FAKE_COMMIT_MESSAGE=
+ FAKE_LINES=
+ GIT_EDITOR=
+ GIT_SEQUENCE_EDITOR=
+ core.editor=
+ sequence.editor=
+ EOF
+ test_cmp expect actual
+}
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 4c01f60dd3..4d3f7ba295 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -391,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 &&
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/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/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 192c94eccd..608673fb77 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -131,4 +131,24 @@ $test_unicode 'merge (silent unicode normalization)' '
git merge topic
'
+test_expect_success CASE_INSENSITIVE_FS 'checkout with no pathspec and a case insensitive fs' '
+ git init repo &&
+ (
+ cd repo &&
+
+ >Gitweb &&
+ git add Gitweb &&
+ git commit -m "add Gitweb" &&
+
+ git checkout --orphan todo &&
+ git reset --hard &&
+ mkdir -p gitweb/subdir &&
+ >gitweb/subdir/file &&
+ git add gitweb &&
+ git commit -m "add gitweb/subdir/file" &&
+
+ git checkout master
+ )
+'
+
test_done
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index c7b53e494b..501e1a288d 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -288,6 +288,8 @@ test_git_path GIT_COMMON_DIR=bar index .git/index
test_git_path GIT_COMMON_DIR=bar HEAD .git/HEAD
test_git_path GIT_COMMON_DIR=bar logs/HEAD .git/logs/HEAD
test_git_path GIT_COMMON_DIR=bar logs/refs/bisect/foo .git/logs/refs/bisect/foo
+test_git_path GIT_COMMON_DIR=bar logs/refs bar/logs/refs
+test_git_path GIT_COMMON_DIR=bar logs/refs/ bar/logs/refs/
test_git_path GIT_COMMON_DIR=bar logs/refs/bisec/foo bar/logs/refs/bisec/foo
test_git_path GIT_COMMON_DIR=bar logs/refs/bisec bar/logs/refs/bisec
test_git_path GIT_COMMON_DIR=bar logs/refs/bisectfoo bar/logs/refs/bisectfoo
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index 015fac8b5d..17c9c0f3bb 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -210,10 +210,23 @@ test_expect_success MINGW 'verify curlies are quoted properly' '
test_cmp expect actual
'
-test_expect_success MINGW 'can spawn with argv[0] containing spaces' '
- cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" ./ &&
- test_must_fail "$PWD/test-fake-ssh$X" 2>err &&
- grep TRASH_DIRECTORY err
+test_expect_success MINGW 'can spawn .bat with argv[0] containing spaces' '
+ bat="$TRASH_DIRECTORY/bat with spaces in name.bat" &&
+
+ # Every .bat invocation will log its arguments to file "out"
+ rm -f out &&
+ echo "echo %* >>out" >"$bat" &&
+
+ # Ask git to invoke .bat; clone will fail due to fake SSH helper
+ test_must_fail env GIT_SSH="$bat" git clone myhost:src ssh-clone &&
+
+ # Spawning .bat can fail if there are two quoted cmd.exe arguments.
+ # .bat itself is first (due to spaces in name), so just one more is
+ # needed to verify. GIT_SSH will invoke .bat multiple times:
+ # 1) -G myhost
+ # 2) myhost "git-upload-pack src"
+ # First invocation will always succeed. Test the second one.
+ grep "git-upload-pack" out
'
test_done
diff --git a/t/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 d4b7e535ea..a3988bd4b8 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -429,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 &&
@@ -540,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
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/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/t1450-fsck.sh b/t/t1450-fsck.sh
index b36e0528d0..50d28e6fdb 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -70,7 +70,6 @@ test_expect_success 'object with bad sha1' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "$sha.*corrupt" out
'
@@ -78,7 +77,6 @@ test_expect_success 'branch pointing to non-commit' '
git rev-parse HEAD^{tree} >.git/refs/heads/invalid &&
test_when_finished "git update-ref -d refs/heads/invalid" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "not a commit" out
'
@@ -88,7 +86,6 @@ test_expect_success 'HEAD link pointing at a funny object' '
echo $ZERO_OID >.git/HEAD &&
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
- cat out &&
test_i18ngrep "detached HEAD points" out
'
@@ -98,7 +95,6 @@ test_expect_success 'HEAD link pointing at a funny place' '
echo "ref: refs/funny/place" >.git/HEAD &&
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
- cat out &&
test_i18ngrep "HEAD points to something strange" out
'
@@ -157,7 +153,6 @@ test_expect_success 'email with embedded > is not okay' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new" out
'
@@ -169,7 +164,6 @@ test_expect_success 'missing < email delimiter is reported nicely' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.* - bad name" out
'
@@ -181,7 +175,6 @@ test_expect_success 'missing email is reported nicely' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.* - missing email" out
'
@@ -193,7 +186,6 @@ test_expect_success '> in name is reported' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new" out
'
@@ -207,7 +199,6 @@ test_expect_success 'integer overflow in timestamps is reported' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.*integer overflow" out
'
@@ -219,7 +210,6 @@ test_expect_success 'commit with NUL in header' '
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
- cat out &&
test_i18ngrep "error in commit $new.*unterminated header: NUL at offset" out
'
@@ -297,7 +287,6 @@ test_expect_success 'tag pointing to nonexistent' '
echo $tag >.git/refs/tags/invalid &&
test_when_finished "git update-ref -d refs/tags/invalid" &&
test_must_fail git fsck --tags >out &&
- cat out &&
test_i18ngrep "broken link" out
'
@@ -378,7 +367,6 @@ test_expect_success 'tag with NUL in header' '
echo $tag >.git/refs/tags/wrong &&
test_when_finished "git update-ref -d refs/tags/wrong" &&
test_must_fail git fsck --tags 2>out &&
- cat out &&
test_i18ngrep "error in tag $tag.*unterminated header: NUL at offset" out
'
@@ -409,7 +397,6 @@ test_expect_success 'rev-list --verify-objects with bad sha1' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out &&
- cat out &&
test_i18ngrep -q "error: hash mismatch $(dirname $new)$(test_oid ff_2)" out
'
@@ -433,7 +420,6 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' '
sha=$(printf "100644 file$_bz$_bzoid" |
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*null sha1" out
)
'
@@ -444,7 +430,6 @@ test_expect_success 'fsck notices submodule entry pointing to null sha1' '
sha=$(printf "160000 submodule$_bz$_bzoid" |
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
- cat out &&
test_i18ngrep "warning.*null sha1" out
)
'
@@ -465,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
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index 21a9c8ffb2..624d0a588f 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -214,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/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/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/t3206-range-diff.sh b/t/t3206-range-diff.sh
index 0120f769f1..0579cd9969 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -333,6 +333,46 @@ test_expect_success 'renamed file' '
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 &&
@@ -461,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 7bb3814962..4c808e5b3b 100644
--- a/t/t3206/history.export
+++ b/t/t3206/history.export
@@ -55,7 +55,7 @@ A
19
20
-commit refs/heads/topic
+commit refs/heads/mode-only-change
mark :4
author Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
committer Thomas Rast <trast@inf.ethz.ch> 1374485014 +0200
@@ -678,3 +678,32 @@ s/12/B/
from :55
M 100644 :9 renamed-file
+commit refs/heads/mode-only-change
+mark :57
+author Thomas Rast <trast@inf.ethz.ch> 1374485024 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473767 +0100
+data 24
+s/4/A/ + add other-file
+from :4
+M 100644 :5 file
+M 100644 :49 other-file
+
+commit refs/heads/mode-only-change
+mark :58
+author Thomas Rast <trast@inf.ethz.ch> 1374485036 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473768 +0100
+data 33
+s/11/B/ + mode change other-file
+from :57
+M 100644 :7 file
+M 100755 :49 other-file
+
+commit refs/heads/mode-only-change
+mark :59
+author Thomas Rast <trast@inf.ethz.ch> 1374485044 +0200
+committer Thomas Gummerer <t.gummerer@gmail.com> 1570473768 +0100
+data 8
+s/12/B/
+from :58
+M 100644 :9 file
+
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index d3fa298c6a..d66a5f6faa 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -864,6 +864,24 @@ test_expect_success 'append to note from other note with "git notes append -c"'
'
test_expect_success 'copy note with "git notes copy"' '
+ commit=$(git rev-parse 4th) &&
+ cat >expect <<-EOF &&
+ commit $commit
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:16:13 2005 -0700
+
+ ${indent}4th
+
+ Notes:
+ ${indent}This is a blob object
+ EOF
+ git notes copy 8th 4th &&
+ git log 3rd..4th >actual &&
+ test_cmp expect actual &&
+ test "$(git note list 4th)" = "$(git note list 8th)"
+'
+
+test_expect_success 'copy note with "git notes copy" with default' '
test_commit 11th &&
commit=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
@@ -878,7 +896,7 @@ test_expect_success 'copy note with "git notes copy"' '
${indent}
${indent}yet another note
EOF
- git notes copy HEAD^ HEAD &&
+ git notes copy HEAD^ &&
git log -1 >actual &&
test_cmp expect actual &&
test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
@@ -901,11 +919,29 @@ test_expect_success 'allow overwrite with "git notes copy -f"' '
${indent}11th
Notes:
+ ${indent}This is a blob object
+ EOF
+ git notes copy -f HEAD~3 HEAD &&
+ git log -1 >actual &&
+ test_cmp expect actual &&
+ test "$(git notes list HEAD)" = "$(git notes list HEAD~3)"
+'
+
+test_expect_success 'allow overwrite with "git notes copy -f" with default' '
+ commit=$(git rev-parse HEAD) &&
+ cat >expect <<-EOF &&
+ commit $commit
+ Author: A U Thor <author@example.com>
+ Date: Thu Apr 7 15:23:13 2005 -0700
+
+ ${indent}11th
+
+ Notes:
${indent}yet another note
${indent}
${indent}yet another note
EOF
- git notes copy -f HEAD~2 HEAD &&
+ git notes copy -f HEAD~2 &&
git log -1 >actual &&
test_cmp expect actual &&
test "$(git notes list HEAD)" = "$(git notes list HEAD~2)"
@@ -1167,8 +1203,10 @@ test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '
'
test_expect_success 'git notes copy diagnoses too many or too few parameters' '
- test_must_fail git notes copy &&
- test_must_fail git notes copy one two three
+ test_must_fail git notes copy 2>error &&
+ test_i18ngrep "too few parameters" error &&
+ test_must_fail git notes copy one two three 2>error &&
+ test_i18ngrep "too many parameters" error
'
test_expect_success 'git notes get-ref expands refs/heads/master to refs/notes/refs/heads/master' '
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 29a35840ed..bf0dc756d2 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -76,8 +76,11 @@ test_expect_success 'rebase -i with empty HEAD' '
cat >expect <<-\EOF &&
error: nothing to do
EOF
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 exec_true" git rebase -i HEAD^ >actual 2>&1 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 exec_true" \
+ git rebase -i HEAD^ >actual 2>&1
+ ) &&
test_i18ncmp expect actual
'
@@ -136,8 +139,11 @@ test_expect_success 'rebase -i sets work tree properly' '
test_expect_success 'rebase -i with the exec command checks tree cleanness' '
git checkout master &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="exec_echo_foo_>file1 1" git rebase -i HEAD^ &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="exec_echo_foo_>file1 1" \
+ git rebase -i HEAD^
+ ) &&
test_cmp_rev master^ HEAD &&
git reset --hard &&
git rebase --continue
@@ -163,9 +169,11 @@ test_expect_success 'rebase -x with newline in command fails' '
test_expect_success 'rebase -i with exec of inexistent command' '
git checkout master &&
test_when_finished "git rebase --abort" &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="exec_this-command-does-not-exist 1" \
- git rebase -i HEAD^ >actual 2>&1 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="exec_this-command-does-not-exist 1" \
+ git rebase -i HEAD^ >actual 2>&1
+ ) &&
! grep "Maybe git-rebase is broken" actual
'
@@ -176,7 +184,6 @@ test_expect_success 'implicit interactive rebase does not invoke sequence editor
test_expect_success 'no changes are a nop' '
git checkout branch2 &&
- set_fake_editor &&
git rebase -i F &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&
test $(git rev-parse I) = $(git rev-parse HEAD)
@@ -186,7 +193,6 @@ test_expect_success 'test the [branch] option' '
git checkout -b dead-end &&
git rm file6 &&
git commit -m "stop here" &&
- set_fake_editor &&
git rebase -i F branch2 &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&
test $(git rev-parse I) = $(git rev-parse branch2) &&
@@ -195,7 +201,6 @@ test_expect_success 'test the [branch] option' '
test_expect_success 'test --onto <branch>' '
git checkout -b test-onto branch2 &&
- set_fake_editor &&
git rebase -i --onto branch1 F &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/test-onto" &&
test $(git rev-parse HEAD^) = $(git rev-parse branch1) &&
@@ -205,7 +210,6 @@ test_expect_success 'test --onto <branch>' '
test_expect_success 'rebase on top of a non-conflicting commit' '
git checkout branch1 &&
git tag original-branch1 &&
- set_fake_editor &&
git rebase -i branch2 &&
test file6 = $(git diff --name-only original-branch1) &&
test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" &&
@@ -225,8 +229,10 @@ test_expect_success 'reflog for the branch shows correct finish message' '
'
test_expect_success 'exchange two commits' '
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2
+ ) &&
test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test G = $(git cat-file commit HEAD | sed -ne \$p) &&
blob1=$(git rev-parse --short HEAD^:file1) &&
@@ -252,7 +258,6 @@ test_expect_success 'stop on conflicting pick' '
>>>>>>> $commit... G
EOF
git tag new-branch1 &&
- set_fake_editor &&
test_must_fail git rebase -i master &&
test "$(git rev-parse HEAD~3)" = "$(git rev-parse master)" &&
test_cmp expect .git/rebase-merge/patch &&
@@ -281,7 +286,6 @@ test_expect_success 'abort' '
test_expect_success 'abort with error when new base cannot be checked out' '
git rm --cached file1 &&
git commit -m "remove file in base" &&
- set_fake_editor &&
test_must_fail git rebase -i master > output 2>&1 &&
test_i18ngrep "The following untracked working tree files would be overwritten by checkout:" \
output &&
@@ -296,7 +300,6 @@ test_expect_success 'retain authorship' '
test_tick &&
GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
git tag twerp &&
- set_fake_editor &&
git rebase -i --onto master HEAD^ &&
git show HEAD | grep "^Author: Twerp Snog"
'
@@ -314,7 +317,6 @@ test_expect_success 'retain authorship w/ conflicts' '
test_commit b conflict b conflict-b &&
GIT_AUTHOR_NAME=$oGIT_AUTHOR_NAME &&
- set_fake_editor &&
test_must_fail git rebase -i conflict-a &&
echo resolved >conflict &&
git add conflict &&
@@ -330,9 +332,11 @@ test_expect_success 'squash' '
test_tick &&
GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 &&
echo "******************************" &&
- set_fake_editor &&
- FAKE_LINES="1 squash 2" EXPECT_HEADER_COUNT=2 \
- git rebase -i --onto master HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 squash 2" EXPECT_HEADER_COUNT=2 \
+ git rebase -i --onto master HEAD~2
+ ) &&
test B = $(cat file7) &&
test $(git rev-parse HEAD^) = $(git rev-parse master)
'
@@ -343,7 +347,6 @@ test_expect_success 'retain authorship when squashing' '
test_expect_success REBASE_P '-p handles "no changes" gracefully' '
HEAD=$(git rev-parse HEAD) &&
- set_fake_editor &&
git rebase -i -p HEAD^ &&
git update-index --refresh &&
git diff-files --quiet &&
@@ -353,8 +356,10 @@ test_expect_success REBASE_P '-p handles "no changes" gracefully' '
test_expect_failure REBASE_P 'exchange two commits with -p' '
git checkout H &&
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i -p HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i -p HEAD~2
+ ) &&
test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test G = $(git cat-file commit HEAD | sed -ne \$p)
'
@@ -388,7 +393,6 @@ test_expect_success REBASE_P 'preserve merges with -p' '
git commit -m M file1 &&
git checkout -b to-be-rebased &&
test_tick &&
- set_fake_editor &&
git rebase -i -p --onto branch1 master &&
git update-index --refresh &&
git diff-files --quiet &&
@@ -403,8 +407,10 @@ test_expect_success REBASE_P 'preserve merges with -p' '
'
test_expect_success REBASE_P 'edit ancestor with -p' '
- set_fake_editor &&
- FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3
+ ) &&
echo 2 > unrelated-file &&
test_tick &&
git commit -m L2-modified --amend unrelated-file &&
@@ -418,11 +424,13 @@ test_expect_success REBASE_P 'edit ancestor with -p' '
test_expect_success '--continue tries to commit' '
git reset --hard D &&
test_tick &&
- set_fake_editor &&
- test_must_fail git rebase -i --onto new-branch1 HEAD^ &&
- echo resolved > file1 &&
- git add file1 &&
- FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail git rebase -i --onto new-branch1 HEAD^ &&
+ echo resolved > file1 &&
+ git add file1 &&
+ FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue
+ ) &&
test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&
git show HEAD | grep chouette
'
@@ -430,7 +438,6 @@ test_expect_success '--continue tries to commit' '
test_expect_success 'verbose flag is heeded, even after --continue' '
git reset --hard master@{1} &&
test_tick &&
- set_fake_editor &&
test_must_fail git rebase -v -i --onto new-branch1 HEAD^ &&
echo resolved > file1 &&
git add file1 &&
@@ -440,10 +447,13 @@ test_expect_success 'verbose flag is heeded, even after --continue' '
test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 squash 2 squash 3 squash 4" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="1 squash 2 squash 3 squash 4" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l)
'
@@ -451,9 +461,12 @@ test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '
git checkout -b multi-fixup E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="NEVER" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="NEVER" \
+ FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 0 = $(git show | grep NEVER | wc -l) &&
git checkout @{-1} &&
@@ -463,12 +476,15 @@ test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '
test_expect_success 'commit message used after conflict' '
git checkout -b conflict-fixup conflict-branch &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 fixup 3 fixup 4" git rebase -i $base &&
- echo three > conflict &&
- git add conflict &&
- FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \
- git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 fixup 3 fixup 4" \
+ git rebase -i $base &&
+ echo three > conflict &&
+ git add conflict &&
+ FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \
+ git rebase --continue
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
git checkout @{-1} &&
@@ -478,12 +494,15 @@ test_expect_success 'commit message used after conflict' '
test_expect_success 'commit message retained after conflict' '
git checkout -b conflict-squash conflict-branch &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 fixup 3 squash 4" git rebase -i $base &&
- echo three > conflict &&
- git add conflict &&
- FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \
- git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 fixup 3 squash 4" \
+ git rebase -i $base &&
+ echo three > conflict &&
+ git add conflict &&
+ FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \
+ git rebase --continue
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 2 = $(git show | grep TWICE | wc -l) &&
git checkout @{-1} &&
@@ -500,10 +519,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa
EOF
git checkout -b squash-fixup E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 squash 3 fixup 4" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="1 fixup 2 squash 3 fixup 4" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup &&
test_cmp expect-squash-fixup actual-squash-fixup &&
git cat-file commit HEAD@{2} |
@@ -517,10 +539,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa
test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
git checkout -b skip-comments E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
git checkout @{-1} &&
@@ -530,10 +555,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '
git checkout -b skip-blank-lines E &&
base=$(git rev-parse HEAD~4) &&
- set_fake_editor &&
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \
- EXPECT_HEADER_COUNT=4 \
- git rebase -i $base &&
+ (
+ set_fake_editor &&
+ FAKE_COMMIT_AMEND="ONCE" \
+ FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \
+ EXPECT_HEADER_COUNT=4 \
+ git rebase -i $base
+ ) &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
git checkout @{-1} &&
@@ -543,17 +571,21 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '
test_expect_success 'squash works as expected' '
git checkout -b squash-works no-conflict-branch &&
one=$(git rev-parse HEAD~3) &&
- set_fake_editor &&
- FAKE_LINES="1 s 3 2" EXPECT_HEADER_COUNT=2 \
- git rebase -i HEAD~3 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 s 3 2" EXPECT_HEADER_COUNT=2 git rebase -i HEAD~3
+ ) &&
test $one = $(git rev-parse HEAD~2)
'
test_expect_success 'interrupted squash works as expected' '
git checkout -b interrupted-squash conflict-branch &&
one=$(git rev-parse HEAD~3) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 squash 3 2" git rebase -i HEAD~3 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 squash 3 2" \
+ git rebase -i HEAD~3
+ ) &&
test_write_lines one two four > conflict &&
git add conflict &&
test_must_fail git rebase --continue &&
@@ -566,8 +598,11 @@ test_expect_success 'interrupted squash works as expected' '
test_expect_success 'interrupted squash works as expected (case 2)' '
git checkout -b interrupted-squash2 conflict-branch &&
one=$(git rev-parse HEAD~3) &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="3 squash 1 2" git rebase -i HEAD~3 &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="3 squash 1 2" \
+ git rebase -i HEAD~3
+ ) &&
test_write_lines one four > conflict &&
git add conflict &&
test_must_fail git rebase --continue &&
@@ -587,11 +622,13 @@ test_expect_success '--continue tries to commit, even for "edit"' '
git commit -m "unrelated change" &&
parent=$(git rev-parse HEAD^) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i HEAD^ &&
- echo edited > file7 &&
- git add file7 &&
- FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+ echo edited > file7 &&
+ git add file7 &&
+ FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue
+ ) &&
test edited = $(git show HEAD:file7) &&
git show HEAD | grep chouette &&
test $parent = $(git rev-parse HEAD^)
@@ -600,34 +637,41 @@ test_expect_success '--continue tries to commit, even for "edit"' '
test_expect_success 'aborted --continue does not squash commits after "edit"' '
old=$(git rev-parse HEAD) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i HEAD^ &&
- echo "edited again" > file7 &&
- git add file7 &&
- test_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+ echo "edited again" > file7 &&
+ git add file7 &&
+ test_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue
+ ) &&
test $old = $(git rev-parse HEAD) &&
git rebase --abort
'
test_expect_success 'auto-amend only edited commits after "edit"' '
test_tick &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i HEAD^ &&
- echo "edited again" > file7 &&
- git add file7 &&
- FAKE_COMMIT_MESSAGE="edited file7 again" git commit &&
- echo "and again" > file7 &&
- git add file7 &&
- test_tick &&
- test_must_fail env FAKE_COMMIT_MESSAGE="and again" git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+ echo "edited again" > file7 &&
+ git add file7 &&
+ FAKE_COMMIT_MESSAGE="edited file7 again" git commit &&
+ echo "and again" > file7 &&
+ git add file7 &&
+ test_tick &&
+ test_must_fail env FAKE_COMMIT_MESSAGE="and again" \
+ git rebase --continue
+ ) &&
git rebase --abort
'
test_expect_success 'clean error after failed "exec"' '
test_tick &&
test_when_finished "git rebase --abort || :" &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 exec_false" git rebase -i HEAD^ &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 exec_false" git rebase -i HEAD^
+ ) &&
echo "edited again" > file7 &&
git add file7 &&
test_must_fail git rebase --continue 2>error &&
@@ -638,8 +682,10 @@ test_expect_success 'rebase a detached HEAD' '
grandparent=$(git rev-parse HEAD~2) &&
git checkout $(git rev-parse HEAD) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2
+ ) &&
test $grandparent = $(git rev-parse HEAD~2)
'
@@ -654,9 +700,10 @@ test_expect_success 'rebase a commit violating pre-commit' '
test_must_fail git commit -m doesnt-verify file1 &&
git commit -m doesnt-verify --no-verify file1 &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES=2 git rebase -i HEAD~2
-
+ (
+ set_fake_editor &&
+ FAKE_LINES=2 git rebase -i HEAD~2
+ )
'
test_expect_success 'rebase with a file named HEAD in worktree' '
@@ -676,8 +723,10 @@ test_expect_success 'rebase with a file named HEAD in worktree' '
git commit -m "Add body"
) &&
- set_fake_editor &&
- FAKE_LINES="1 squash 2" git rebase -i @{-1} &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 squash 2" git rebase -i @{-1}
+ ) &&
test "$(git show -s --pretty=format:%an)" = "Squashed Away"
'
@@ -688,7 +737,6 @@ test_expect_success 'do "noop" when there is nothing to cherry-pick' '
GIT_EDITOR=: git commit --amend \
--author="Somebody else <somebody@else.com>" &&
test $(git rev-parse branch3) != $(git rev-parse branch4) &&
- set_fake_editor &&
git rebase -i branch3 &&
test $(git rev-parse branch3) = $(git rev-parse branch4)
@@ -713,13 +761,14 @@ test_expect_success 'submodule rebase setup' '
git commit -a -m "submodule second"
) &&
test_tick &&
- set_fake_editor &&
git commit -a -m "Three changes submodule"
'
test_expect_success 'submodule rebase -i' '
- set_fake_editor &&
- FAKE_LINES="1 squash 2 3" git rebase -i A
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 squash 2 3" git rebase -i A
+ )
'
test_expect_success 'submodule conflict setup' '
@@ -736,7 +785,6 @@ test_expect_success 'submodule conflict setup' '
'
test_expect_success 'rebase -i continue with only submodule staged' '
- set_fake_editor &&
test_must_fail git rebase -i submodule-base &&
git add sub &&
git rebase --continue &&
@@ -746,7 +794,6 @@ test_expect_success 'rebase -i continue with only submodule staged' '
test_expect_success 'rebase -i continue with unstaged submodule' '
git checkout submodule-topic &&
git reset --hard &&
- set_fake_editor &&
test_must_fail git rebase -i submodule-base &&
git reset &&
git rebase --continue &&
@@ -759,7 +806,6 @@ test_expect_success 'avoid unnecessary reset' '
test-tool chmtime =123456789 file3 &&
git update-index --refresh &&
HEAD=$(git rev-parse HEAD) &&
- set_fake_editor &&
git rebase -i HEAD~4 &&
test $HEAD = $(git rev-parse HEAD) &&
MTIME=$(test-tool chmtime --get file3) &&
@@ -768,16 +814,22 @@ test_expect_success 'avoid unnecessary reset' '
test_expect_success 'reword' '
git checkout -b reword-branch master &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" git rebase -i A &&
- git show HEAD | grep "E changed" &&
- test $(git rev-parse master) != $(git rev-parse HEAD) &&
- test $(git rev-parse master^) = $(git rev-parse HEAD^) &&
- FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" git rebase -i A &&
- git show HEAD^ | grep "D changed" &&
- FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" git rebase -i A &&
- git show HEAD~3 | grep "B changed" &&
- FAKE_LINES="1 r 2 pick 3 p 4" FAKE_COMMIT_MESSAGE="C changed" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" \
+ git rebase -i A &&
+ git show HEAD | grep "E changed" &&
+ test $(git rev-parse master) != $(git rev-parse HEAD) &&
+ test $(git rev-parse master^) = $(git rev-parse HEAD^) &&
+ FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" \
+ git rebase -i A &&
+ git show HEAD^ | grep "D changed" &&
+ FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" \
+ git rebase -i A &&
+ git show HEAD~3 | grep "B changed" &&
+ FAKE_LINES="1 r 2 pick 3 p 4" FAKE_COMMIT_MESSAGE="C changed" \
+ git rebase -i A
+ ) &&
git show HEAD~2 | grep "C changed"
'
@@ -788,7 +840,6 @@ test_expect_success 'rebase -i can copy notes' '
test_commit n2 &&
test_commit n3 &&
git notes add -m"a note" n3 &&
- set_fake_editor &&
git rebase -i --onto n1 n2 &&
test "a note" = "$(git notes show HEAD)"
'
@@ -801,8 +852,11 @@ test_expect_success 'rebase -i can copy notes over a fixup' '
EOF
git reset --hard n3 &&
git notes add -m"an earlier note" n2 &&
- set_fake_editor &&
- GIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES="1 f 2" git rebase -i n1 &&
+ (
+ set_fake_editor &&
+ GIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES="1 f 2" \
+ git rebase -i n1
+ ) &&
git notes show > output &&
test_cmp expect output
'
@@ -811,8 +865,10 @@ test_expect_success 'rebase while detaching HEAD' '
git symbolic-ref HEAD &&
grandparent=$(git rev-parse HEAD~2) &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0
+ ) &&
test $grandparent = $(git rev-parse HEAD~2) &&
test_must_fail git symbolic-ref HEAD
'
@@ -821,7 +877,6 @@ test_tick # Ensure that the rebased commits get a different timestamp.
test_expect_success 'always cherry-pick with --no-ff' '
git checkout no-ff-branch &&
git tag original-no-ff-branch &&
- set_fake_editor &&
git rebase -i --no-ff A &&
for p in 0 1 2
do
@@ -853,8 +908,10 @@ test_expect_success 'set up commits with funny messages' '
test_expect_success 'rebase-i history with funny messages' '
git rev-list A..funny >expect &&
test_tick &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 4" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 4" git rebase -i A
+ ) &&
git rev-list A.. >actual &&
test_cmp expect actual
'
@@ -868,9 +925,9 @@ test_expect_success 'prepare for rebase -i --exec' '
'
test_expect_success 'running "git rebase -i --exec git show HEAD"' '
- set_fake_editor &&
- git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -881,9 +938,9 @@ test_expect_success 'running "git rebase -i --exec git show HEAD"' '
test_expect_success 'running "git rebase --exec git show HEAD -i"' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -894,9 +951,9 @@ test_expect_success 'running "git rebase --exec git show HEAD -i"' '
test_expect_success 'running "git rebase -ix git show HEAD"' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase -ix "git show HEAD" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -ix "git show HEAD" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -908,9 +965,9 @@ test_expect_success 'running "git rebase -ix git show HEAD"' '
test_expect_success 'rebase -ix with several <CMD>' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
export FAKE_LINES &&
git rebase -i HEAD~2 >expect
@@ -921,9 +978,9 @@ test_expect_success 'rebase -ix with several <CMD>' '
test_expect_success 'rebase -ix with several instances of --exec' '
git reset --hard execute &&
- set_fake_editor &&
- git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
(
+ set_fake_editor &&
+ git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
exec_git_show_HEAD exec_pwd" &&
export FAKE_LINES &&
@@ -942,13 +999,11 @@ test_expect_success C_LOCALE_OUTPUT 'rebase -ix with --autosquash' '
echo bis >bis.txt &&
git add bis.txt &&
git commit -m "fixup! two_exec" &&
- set_fake_editor &&
- (
- git checkout -b autosquash_actual &&
- git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
- ) &&
+ git checkout -b autosquash_actual &&
+ git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual &&
git checkout autosquash &&
(
+ set_fake_editor &&
git checkout -b autosquash_expected &&
FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
export FAKE_LINES &&
@@ -969,7 +1024,6 @@ test_expect_success 'rebase --exec works without -i ' '
test_expect_success 'rebase -i --exec without <CMD>' '
git reset --hard execute &&
- set_fake_editor &&
test_must_fail git rebase -i --exec 2>actual &&
test_i18ngrep "requires a value" actual &&
git checkout master
@@ -977,8 +1031,10 @@ test_expect_success 'rebase -i --exec without <CMD>' '
test_expect_success 'rebase -i --root re-order and drop commits' '
git checkout E &&
- set_fake_editor &&
- FAKE_LINES="3 1 2 5" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="3 1 2 5" git rebase -i --root
+ ) &&
test E = $(git cat-file commit HEAD | sed -ne \$p) &&
test B = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test A = $(git cat-file commit HEAD^^ | sed -ne \$p) &&
@@ -991,39 +1047,59 @@ test_expect_success 'rebase -i --root retain root commit author and message' '
echo B >file7 &&
git add file7 &&
GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
- set_fake_editor &&
- FAKE_LINES="2" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2" git rebase -i --root
+ ) &&
git cat-file commit HEAD | grep -q "^author Twerp Snog" &&
git cat-file commit HEAD | grep -q "^different author$"
'
test_expect_success 'rebase -i --root temporary sentinel commit' '
git checkout B &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="2" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="2" git rebase -i --root
+ ) &&
git cat-file commit HEAD | grep "^tree $EMPTY_TREE" &&
git rebase --abort
'
test_expect_success 'rebase -i --root fixup root commit' '
git checkout B &&
- set_fake_editor &&
- FAKE_LINES="1 fixup 2" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 fixup 2" git rebase -i --root
+ ) &&
test A = $(git cat-file commit HEAD | sed -ne \$p) &&
test B = $(git show HEAD:file1) &&
test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
'
-test_expect_success 'rebase -i --root reword root commit' '
+test_expect_success 'rebase -i --root reword original root commit' '
test_when_finished "test_might_fail git rebase --abort" &&
- git checkout -b reword-root-branch master &&
- set_fake_editor &&
- FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
- git rebase -i --root &&
+ git checkout -b reword-original-root-branch master &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
+ git rebase -i --root
+ ) &&
git show HEAD^ | grep "A changed" &&
test -z "$(git show -s --format=%p HEAD^)"
'
+test_expect_success 'rebase -i --root reword new root commit' '
+ test_when_finished "test_might_fail git rebase --abort" &&
+ git checkout -b reword-now-root-branch master &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="reword 3 1" FAKE_COMMIT_MESSAGE="C changed" \
+ git rebase -i --root
+ ) &&
+ git show HEAD^ | grep "C changed" &&
+ test -z "$(git show -s --format=%p HEAD^)"
+'
+
test_expect_success 'rebase -i --root when root has untracked file conflict' '
test_when_finished "reset_rebase" &&
git checkout -b failing-root-pick A &&
@@ -1031,8 +1107,10 @@ test_expect_success 'rebase -i --root when root has untracked file conflict' '
git rm file1 &&
git commit -m "remove file 1 add file 2" &&
echo z >file1 &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2" git rebase -i --root
+ ) &&
rm file1 &&
git rebase --continue &&
test "$(git log -1 --format=%B)" = "remove file 1 add file 2" &&
@@ -1042,32 +1120,38 @@ test_expect_success 'rebase -i --root when root has untracked file conflict' '
test_expect_success 'rebase -i --root reword root when root has untracked file conflict' '
test_when_finished "reset_rebase" &&
echo z>file1 &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="reword 1 2" \
- FAKE_COMMIT_MESSAGE="Modified A" git rebase -i --root &&
- rm file1 &&
- FAKE_COMMIT_MESSAGE="Reworded A" git rebase --continue &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="reword 1 2" \
+ FAKE_COMMIT_MESSAGE="Modified A" git rebase -i --root &&
+ rm file1 &&
+ FAKE_COMMIT_MESSAGE="Reworded A" git rebase --continue
+ ) &&
test "$(git log -1 --format=%B HEAD^)" = "Reworded A" &&
test "$(git rev-list --count HEAD)" = 2
'
test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' '
- git checkout reword-root-branch &&
+ git checkout reword-original-root-branch &&
git reset --hard &&
git checkout conflict-branch &&
- set_fake_editor &&
- test_must_fail git rebase -f --onto HEAD~2 HEAD~ &&
- test_must_fail git rebase --edit-todo &&
+ (
+ set_fake_editor &&
+ test_must_fail git rebase -f --onto HEAD~2 HEAD~ &&
+ test_must_fail git rebase --edit-todo
+ ) &&
git rebase --abort
'
test_expect_success 'rebase --edit-todo can be used to modify todo' '
git reset --hard &&
git checkout no-conflict-branch^0 &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2 3" git rebase -i HEAD~3 &&
- FAKE_LINES="2 1" git rebase --edit-todo &&
- git rebase --continue &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2 3" git rebase -i HEAD~3 &&
+ FAKE_LINES="2 1" git rebase --edit-todo &&
+ git rebase --continue
+ ) &&
test M = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test L = $(git cat-file commit HEAD | sed -ne \$p)
'
@@ -1075,7 +1159,6 @@ test_expect_success 'rebase --edit-todo can be used to modify todo' '
test_expect_success 'rebase -i produces readable reflog' '
git reset --hard &&
git branch -f branch-reflog-test H &&
- set_fake_editor &&
git rebase -i --onto I F branch-reflog-test &&
cat >expect <<-\EOF &&
rebase -i (finish): returning to refs/heads/branch-reflog-test
@@ -1096,8 +1179,10 @@ test_expect_success 'rebase -i respects core.commentchar' '
sed -e "2,\$s/^/\\\\/" "$1" >"$1.tmp" &&
mv "$1.tmp" "$1"
EOF
- test_set_editor "$(pwd)/remove-all-but-first.sh" &&
- git rebase -i B &&
+ (
+ test_set_editor "$(pwd)/remove-all-but-first.sh" &&
+ git rebase -i B
+ ) &&
test B = $(git cat-file commit HEAD^ | sed -ne \$p)
'
@@ -1106,9 +1191,11 @@ test_expect_success 'rebase -i respects core.commentchar=auto' '
write_script copy-edit-script.sh <<-\EOF &&
cp "$1" edit-script
EOF
- test_set_editor "$(pwd)/copy-edit-script.sh" &&
test_when_finished "git rebase --abort || :" &&
- git rebase -i HEAD^ &&
+ (
+ test_set_editor "$(pwd)/copy-edit-script.sh" &&
+ git rebase -i HEAD^
+ ) &&
test -z "$(grep -ve "^#" -e "^\$" -e "^pick" edit-script)"
'
@@ -1143,8 +1230,11 @@ test_expect_success 'interrupted rebase -i with --strategy and -X' '
echo five >conflict &&
echo Z >file1 &&
git commit -a -m "one file conflict" &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2" git rebase -i --strategy=recursive -Xours conflict-branch &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2" git rebase -i --strategy=recursive \
+ -Xours conflict-branch
+ ) &&
git rebase --continue &&
test $(git show conflict-branch:conflict) = $(cat conflict) &&
test $(cat file1) = Z
@@ -1185,8 +1275,10 @@ test_expect_success SHA1 'short SHA-1 collide' '
test_expect_success 'respect core.abbrev' '
git config core.abbrev 12 &&
- set_cat_todo_editor &&
- test_must_fail git rebase -i HEAD~4 >todo-list &&
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase -i HEAD~4 >todo-list
+ ) &&
test 4 = $(grep -c "pick [0-9a-f]\{12,\}" todo-list)
'
@@ -1194,16 +1286,20 @@ test_expect_success 'todo count' '
write_script dump-raw.sh <<-\EOF &&
cat "$1"
EOF
- test_set_editor "$(pwd)/dump-raw.sh" &&
- git rebase -i HEAD~4 >actual &&
+ (
+ test_set_editor "$(pwd)/dump-raw.sh" &&
+ git rebase -i HEAD~4 >actual
+ ) &&
test_i18ngrep "^# Rebase ..* onto ..* ([0-9]" actual
'
test_expect_success 'rebase -i commits that overwrite untracked files (pick)' '
git checkout --force branch2 &&
git clean -f &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2" git rebase -i A
+ ) &&
test_cmp_rev HEAD F &&
test_path_is_missing file6 &&
>file6 &&
@@ -1218,8 +1314,10 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)'
git checkout --force branch2 &&
git clean -f &&
git tag original-branch2 &&
- set_fake_editor &&
- FAKE_LINES="edit 1 squash 2" git rebase -i A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 squash 2" git rebase -i A
+ ) &&
test_cmp_rev HEAD F &&
test_path_is_missing file6 &&
>file6 &&
@@ -1234,8 +1332,10 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)'
test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' '
git checkout --force branch2 &&
git clean -f &&
- set_fake_editor &&
- FAKE_LINES="edit 1 2" git rebase -i --no-ff A &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1 2" git rebase -i --no-ff A
+ ) &&
test $(git cat-file commit HEAD | sed -ne \$p) = F &&
test_path_is_missing file6 &&
>file6 &&
@@ -1258,8 +1358,10 @@ test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' '
git tag seq-onto &&
git reset --hard HEAD~2 &&
git cherry-pick seq-onto &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES= git rebase -i seq-onto &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES= git rebase -i seq-onto
+ ) &&
test -d .git/rebase-merge &&
git rebase --continue &&
git diff --exit-code seq-onto &&
@@ -1278,8 +1380,10 @@ rebase_setup_and_clean () {
test_expect_success 'drop' '
rebase_setup_and_clean drop-test &&
- set_fake_editor &&
- FAKE_LINES="1 drop 2 3 d 4 5" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 drop 2 3 d 4 5" git rebase -i --root
+ ) &&
test E = $(git cat-file commit HEAD | sed -ne \$p) &&
test C = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test A = $(git cat-file commit HEAD^^ | sed -ne \$p)
@@ -1288,9 +1392,10 @@ test_expect_success 'drop' '
test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '
test_config rebase.missingCommitsCheck ignore &&
rebase_setup_and_clean missing-commit &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 4" \
- git rebase -i --root 2>actual &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 4" git rebase -i --root 2>actual
+ ) &&
test D = $(git cat-file commit HEAD | sed -ne \$p) &&
test_i18ngrep \
"Successfully rebased and updated refs/heads/missing-commit" \
@@ -1306,9 +1411,10 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' '
EOF
test_config rebase.missingCommitsCheck warn &&
rebase_setup_and_clean missing-commit &&
- set_fake_editor &&
- FAKE_LINES="1 2 3 4" \
- git rebase -i --root 2>actual.2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="1 2 3 4" git rebase -i --root 2>actual.2
+ ) &&
head -n4 actual.2 >actual &&
test_i18ncmp expect actual &&
test D = $(git cat-file commit HEAD | sed -ne \$p)
@@ -1330,14 +1436,15 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '
EOF
test_config rebase.missingCommitsCheck error &&
rebase_setup_and_clean missing-commit &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2 4" \
- git rebase -i --root 2>actual &&
- test_i18ncmp expect actual &&
- cp .git/rebase-merge/git-rebase-todo.backup \
- .git/rebase-merge/git-rebase-todo &&
- FAKE_LINES="1 2 drop 3 4 drop 5" \
- git rebase --edit-todo &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 4" \
+ git rebase -i --root 2>actual &&
+ test_i18ncmp expect actual &&
+ cp .git/rebase-merge/git-rebase-todo.backup \
+ .git/rebase-merge/git-rebase-todo &&
+ FAKE_LINES="1 2 drop 3 4 drop 5" git rebase --edit-todo
+ ) &&
git rebase --continue &&
test D = $(git cat-file commit HEAD | sed -ne \$p) &&
test B = $(git cat-file commit HEAD^ | sed -ne \$p)
@@ -1358,21 +1465,27 @@ test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and e
x git show HEAD
EOF
git checkout abbrevcmd &&
- set_cat_todo_editor &&
test_config rebase.abbreviateCommands true &&
- test_must_fail git rebase -i --exec "git show HEAD" \
- --autosquash master >actual &&
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase -i --exec "git show HEAD" \
+ --autosquash master >actual
+ ) &&
test_cmp expected actual
'
test_expect_success 'static check of bad command' '
rebase_setup_and_clean bad-cmd &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \
git rebase -i --root 2>actual &&
- test_i18ngrep "badcmd $(git rev-list --oneline -1 master~1)" actual &&
- test_i18ngrep "You can fix this with .git rebase --edit-todo.." actual &&
- FAKE_LINES="1 2 3 drop 4 5" git rebase --edit-todo &&
+ test_i18ngrep "badcmd $(git rev-list --oneline -1 master~1)" \
+ actual &&
+ test_i18ngrep "You can fix this with .git rebase --edit-todo.." \
+ actual &&
+ FAKE_LINES="1 2 3 drop 4 5" git rebase --edit-todo
+ ) &&
git rebase --continue &&
test E = $(git cat-file commit HEAD | sed -ne \$p) &&
test C = $(git cat-file commit HEAD^ | sed -ne \$p)
@@ -1388,19 +1501,24 @@ test_expect_success 'tabs and spaces are accepted in the todolist' '
) >"$1.new"
mv "$1.new" "$1"
EOF
- test_set_editor "$(pwd)/add-indent.sh" &&
- git rebase -i HEAD^^^ &&
+ (
+ test_set_editor "$(pwd)/add-indent.sh" &&
+ git rebase -i HEAD^^^
+ ) &&
test E = $(git cat-file commit HEAD | sed -ne \$p)
'
test_expect_success 'static check of bad SHA-1' '
rebase_setup_and_clean bad-sha &&
- set_fake_editor &&
- test_must_fail env FAKE_LINES="1 2 edit fakesha 3 4 5 #" \
- git rebase -i --root 2>actual &&
- test_i18ngrep "edit XXXXXXX False commit" actual &&
- test_i18ngrep "You can fix this with .git rebase --edit-todo.." actual &&
- FAKE_LINES="1 2 4 5 6" git rebase --edit-todo &&
+ (
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 edit fakesha 3 4 5 #" \
+ git rebase -i --root 2>actual &&
+ test_i18ngrep "edit XXXXXXX False commit" actual &&
+ test_i18ngrep "You can fix this with .git rebase --edit-todo.." \
+ actual &&
+ FAKE_LINES="1 2 4 5 6" git rebase --edit-todo
+ ) &&
git rebase --continue &&
test E = $(git cat-file commit HEAD | sed -ne \$p)
'
@@ -1419,39 +1537,71 @@ test_expect_success 'editor saves as CR/LF' '
test_expect_success 'rebase -i --gpg-sign=<key-id>' '
test_when_finished "test_might_fail git rebase --abort" &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" HEAD^ \
- >out 2>err &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" \
+ HEAD^ >out 2>err
+ ) &&
test_i18ngrep "$SQ-S\"S I Gner\"$SQ" err
'
test_expect_success 'rebase -i --gpg-sign=<key-id> overrides commit.gpgSign' '
test_when_finished "test_might_fail git rebase --abort" &&
test_config commit.gpgsign true &&
- set_fake_editor &&
- FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" HEAD^ \
- >out 2>err &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 1" git rebase -i --gpg-sign="\"S I Gner\"" \
+ HEAD^ >out 2>err
+ ) &&
test_i18ngrep "$SQ-S\"S I Gner\"$SQ" err
'
test_expect_success 'valid author header after --root swap' '
rebase_setup_and_clean author-header no-conflict-branch &&
- set_fake_editor &&
git commit --amend --author="Au ${SQ}thor <author@example.com>" --no-edit &&
git cat-file commit HEAD | grep ^author >expected &&
- FAKE_LINES="5 1" git rebase -i --root &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="5 1" git rebase -i --root
+ ) &&
git cat-file commit HEAD^ | grep ^author >actual &&
test_cmp expected actual
'
test_expect_success 'valid author header when author contains single quote' '
rebase_setup_and_clean author-header no-conflict-branch &&
- set_fake_editor &&
git commit --amend --author="Au ${SQ}thor <author@example.com>" --no-edit &&
git cat-file commit HEAD | grep ^author >expected &&
- FAKE_LINES="2" git rebase -i HEAD~2 &&
+ (
+ set_fake_editor &&
+ FAKE_LINES="2" git rebase -i HEAD~2
+ ) &&
git cat-file commit HEAD | grep ^author >actual &&
test_cmp expected actual
'
+test_expect_success 'post-commit hook is called' '
+ test_when_finished "rm -f .git/hooks/post-commit" &&
+ >actual &&
+ mkdir -p .git/hooks &&
+ write_script .git/hooks/post-commit <<-\EOS &&
+ git rev-parse HEAD >>actual
+ EOS
+ (
+ set_fake_editor &&
+ FAKE_LINES="edit 4 1 reword 2 fixup 3" git rebase -i A E &&
+ echo x>file3 &&
+ git add file3 &&
+ FAKE_COMMIT_MESSAGE=edited git rebase --continue
+ ) &&
+ git rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \
+ >expect &&
+ test_cmp expect actual
+'
+
+# This must be the last test in this file
+test_expect_success '$EDITOR and friends are unchanged' '
+ test_editor_unchanged
+'
+
test_done
diff --git a/t/t3429-rebase-edit-todo.sh b/t/t3429-rebase-edit-todo.sh
index 63edf17114..aaeac6eade 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 '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/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/t3903-stash.sh b/t/t3903-stash.sh
index 820b350aeb..a4da72f0ab 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -1253,4 +1253,31 @@ test_expect_success 'stash --keep-index with file deleted in index does not resu
test_path_is_missing to-remove
'
+test_expect_success 'stash apply should succeed with unmodified file' '
+ echo base >file &&
+ git add file &&
+ git commit -m base &&
+
+ # now stash a modification
+ echo modified >file &&
+ git stash &&
+
+ # make the file stat dirty
+ cp file other &&
+ mv other file &&
+
+ git stash apply
+'
+
+test_expect_success 'stash handles skip-worktree entries nicely' '
+ test_commit A &&
+ echo changed >A.t &&
+ git add A.t &&
+ git update-index --skip-worktree A.t &&
+ rm A.t &&
+ git stash &&
+
+ git rev-parse --verify refs/stash:A.t
+'
+
test_done
diff --git a/t/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/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 83f52614d3..69267b16f0 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -1517,6 +1517,178 @@ test_expect_success 'format patch ignores color.ui' '
test_cmp expect actual
'
+test_expect_success 'cover letter with invalid --cover-from-description and config' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_must_fail git format-patch --cover-letter --cover-from-description garbage master &&
+ test_config format.coverFromDescription garbage &&
+ test_must_fail git format-patch --cover-letter master
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = default' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription default &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description default' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description default master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = none' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription none &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ ! grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description none' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description none master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ ! grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = message' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription message &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description message' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description message master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = subject' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription subject &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description subject' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description subject master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = auto (short subject line)' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription auto &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description auto (short subject line)' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description auto master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with format.coverFromDescription = auto (long subject line)' '
+ test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
+
+body" &&
+ test_config format.coverFromDescription auto &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with --cover-from-description auto (long subject line)' '
+ test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
+
+body" &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description auto master >actual &&
+ grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
+ grep "^body$" actual
+'
+
+test_expect_success 'cover letter with command-line --cover-from-description overrides config' '
+ test_config branch.rebuild-1.description "config subject
+
+body" &&
+ test_config format.coverFromDescription none &&
+ git checkout rebuild-1 &&
+ git format-patch --stdout --cover-letter --cover-from-description subject master >actual &&
+ grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
+ ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
+ ! grep "^config subject$" actual &&
+ grep "^body$" actual
+'
+
test_expect_success 'cover letter using branch description (1)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
@@ -1606,12 +1778,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 &&
- git rev-list master..side >list &&
- test_line_count = $(ls patches | wc -l) list
+ count=$(git rev-list --count master..side) &&
+ ls patches >list &&
+ test_line_count = $count list
'
test_expect_success 'format-patch -o overrides format.outputDirectory' '
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-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-root b/t/t4018/dts-root
index 2ef9e6ffaa..4353b8220c 100644
--- a/t/t4018/dts-root
+++ b/t/t4018/dts-root
@@ -1,4 +1,4 @@
-/RIGHT { /* Technically just supposed to be a slash */
+/ { 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/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index 15fc054fdb..b5a56895e8 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -516,7 +516,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 "$head\0::100644 100644 100644 $side1df $side2df $headf RR\0file\twith\ttabs\0i\tam\ttabbed\0fickle\tnaming\0" >expect &&
git diff-tree -c -M --raw --combined-all-paths -z HEAD >actual &&
- test_cmp -a expect actual
+ test_cmp expect actual
'
test_expect_success FUNNYNAMES '--combined-all-paths and --cc and funny names' '
diff --git a/t/t4108-apply-threeway.sh b/t/t4108-apply-threeway.sh
index fa5d4efb89..d7349ced6b 100755
--- a/t/t4108-apply-threeway.sh
+++ b/t/t4108-apply-threeway.sh
@@ -4,23 +4,17 @@ test_description='git apply --3way'
. ./test-lib.sh
-create_file () {
- for i
- do
- echo "$i"
- done
-}
-
-sanitize_conflicted_diff () {
+print_sanitized_conflicted_diff () {
+ git diff HEAD >diff.raw &&
sed -e '
/^index /d
- s/^\(+[<>][<>][<>][<>]*\) .*/\1/
- '
+ s/^\(+[<>|][<>|][<>|][<>|]*\) .*/\1/
+ ' diff.raw
}
test_expect_success setup '
test_tick &&
- create_file >one 1 2 3 4 5 6 7 &&
+ test_write_lines 1 2 3 4 5 6 7 >one &&
cat one >two &&
git add one two &&
git commit -m initial &&
@@ -28,13 +22,13 @@ test_expect_success setup '
git branch side &&
test_tick &&
- create_file >one 1 two 3 4 5 six 7 &&
- create_file >two 1 two 3 4 5 6 7 &&
+ test_write_lines 1 two 3 4 5 six 7 >one &&
+ test_write_lines 1 two 3 4 5 6 7 >two &&
git commit -a -m master &&
git checkout side &&
- create_file >one 1 2 3 4 five 6 7 &&
- create_file >two 1 2 3 4 five 6 7 &&
+ test_write_lines 1 2 3 4 five 6 7 >one &&
+ test_write_lines 1 2 3 4 five 6 7 >two &&
git commit -a -m side &&
git checkout master
@@ -52,7 +46,7 @@ test_expect_success 'apply without --3way' '
git diff-index --exit-code --cached HEAD
'
-test_expect_success 'apply with --3way' '
+test_apply_with_3way () {
# Merging side should be similar to applying this patch
git diff ...side >P.diff &&
@@ -61,22 +55,31 @@ test_expect_success 'apply with --3way' '
git checkout master^0 &&
test_must_fail git merge --no-commit side &&
git ls-files -s >expect.ls &&
- git diff HEAD | sanitize_conflicted_diff >expect.diff &&
+ print_sanitized_conflicted_diff >expect.diff &&
# should fail to apply
git reset --hard &&
git checkout master^0 &&
test_must_fail git apply --index --3way P.diff &&
git ls-files -s >actual.ls &&
- git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+ print_sanitized_conflicted_diff >actual.diff &&
# The result should resemble the corresponding merge
test_cmp expect.ls actual.ls &&
test_cmp expect.diff actual.diff
+}
+
+test_expect_success 'apply with --3way' '
+ test_apply_with_3way
+'
+
+test_expect_success 'apply with --3way with merge.conflictStyle = diff3' '
+ test_config merge.conflictStyle diff3 &&
+ test_apply_with_3way
'
test_expect_success 'apply with --3way with rerere enabled' '
- git config rerere.enabled true &&
+ test_config rerere.enabled true &&
# Merging side should be similar to applying this patch
git diff ...side >P.diff &&
@@ -87,7 +90,7 @@ test_expect_success 'apply with --3way with rerere enabled' '
test_must_fail git merge --no-commit side &&
# Manually resolve and record the resolution
- create_file 1 two 3 4 five six 7 >one &&
+ test_write_lines 1 two 3 4 five six 7 >one &&
git rerere &&
cat one >expect &&
@@ -104,14 +107,14 @@ test_expect_success 'apply -3 with add/add conflict setup' '
git reset --hard &&
git checkout -b adder &&
- create_file 1 2 3 4 5 6 7 >three &&
- create_file 1 2 3 4 5 6 7 >four &&
+ test_write_lines 1 2 3 4 5 6 7 >three &&
+ test_write_lines 1 2 3 4 5 6 7 >four &&
git add three four &&
git commit -m "add three and four" &&
git checkout -b another adder^ &&
- create_file 1 2 3 4 5 6 7 >three &&
- create_file 1 2 3 four 5 6 7 >four &&
+ test_write_lines 1 2 3 4 5 6 7 >three &&
+ test_write_lines 1 2 3 four 5 6 7 >four &&
git add three four &&
git commit -m "add three and four" &&
@@ -121,7 +124,7 @@ test_expect_success 'apply -3 with add/add conflict setup' '
git checkout adder^0 &&
test_must_fail git merge --no-commit another &&
git ls-files -s >expect.ls &&
- git diff HEAD | sanitize_conflicted_diff >expect.diff
+ print_sanitized_conflicted_diff >expect.diff
'
test_expect_success 'apply -3 with add/add conflict' '
@@ -131,7 +134,7 @@ test_expect_success 'apply -3 with add/add conflict' '
test_must_fail git apply --index --3way P.diff &&
# ... and leave conflicts in the index and in the working tree
git ls-files -s >actual.ls &&
- git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+ print_sanitized_conflicted_diff >actual.diff &&
# The result should resemble the corresponding merge
test_cmp expect.ls actual.ls &&
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index e88ccb04a9..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 &&
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 918ada69eb..586c3a86b1 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -13,8 +13,8 @@ fuzz_blame () {
}
test_expect_success setup '
- cat >contacts <<-\EOF &&
- A U Thor <author@example.com>
+ cat >contacts <<- EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
@@ -33,19 +33,19 @@ test_expect_success 'check-mailmap no arguments' '
'
test_expect_success 'check-mailmap arguments' '
- cat >expect <<-\EOF &&
- A U Thor <author@example.com>
+ cat >expect <<- EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
git check-mailmap \
- "A U Thor <author@example.com>" \
+ "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" \
"nick1 <bugs@company.xx>" >actual &&
test_cmp expect actual
'
test_expect_success 'check-mailmap --stdin' '
- cat >expect <<-\EOF &&
- A U Thor <author@example.com>
+ cat >expect <<- EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
git check-mailmap --stdin <contacts >actual &&
@@ -66,8 +66,8 @@ test_expect_success 'check-mailmap bogus contact' '
test_must_fail git check-mailmap bogus
'
-cat >expect <<\EOF
-A U Thor (1):
+cat >expect << EOF
+$GIT_AUTHOR_NAME (1):
initial
nick1 (1):
@@ -90,7 +90,7 @@ nick1 (1):
EOF
test_expect_success 'default .mailmap' '
- echo "Repo Guy <author@example.com>" > .mailmap &&
+ echo "Repo Guy <$GIT_AUTHOR_EMAIL>" > .mailmap &&
git shortlog HEAD >actual &&
test_cmp expect actual
'
@@ -122,7 +122,7 @@ Internal Guy (1):
EOF
test_expect_success 'mailmap.file override' '
- echo "External Guy <author@example.com>" >> internal_mailmap/.mailmap &&
+ echo "External Guy <$GIT_AUTHOR_EMAIL>" >> internal_mailmap/.mailmap &&
git config mailmap.file internal_mailmap/.mailmap &&
git shortlog HEAD >actual &&
test_cmp expect actual
@@ -178,8 +178,8 @@ test_expect_success 'name entry after email entry, case-insensitive' '
test_cmp expect actual
'
-cat >expect <<\EOF
-A U Thor (1):
+cat >expect << EOF
+$GIT_AUTHOR_NAME (1):
initial
nick1 (1):
@@ -195,18 +195,18 @@ test_expect_success 'No mailmap files, but configured' '
test_expect_success 'setup mailmap blob tests' '
git checkout -b map &&
test_when_finished "git checkout master" &&
- cat >just-bugs <<-\EOF &&
+ cat >just-bugs <<- EOF &&
Blob Guy <bugs@company.xx>
EOF
- cat >both <<-\EOF &&
- Blob Guy <author@example.com>
+ cat >both <<- EOF &&
+ Blob Guy <$GIT_AUTHOR_EMAIL>
Blob Guy <bugs@company.xx>
EOF
- printf "Tricky Guy <author@example.com>" >no-newline &&
+ printf "Tricky Guy <$GIT_AUTHOR_EMAIL>" >no-newline &&
git add just-bugs both no-newline &&
git commit -m "my mailmaps" &&
- echo "Repo Guy <author@example.com>" >.mailmap &&
- echo "Internal Guy <author@example.com>" >internal.map
+ echo "Repo Guy <$GIT_AUTHOR_EMAIL>" >.mailmap &&
+ echo "Internal Guy <$GIT_AUTHOR_EMAIL>" >internal.map
'
test_expect_success 'mailmap.blob set' '
@@ -266,12 +266,12 @@ test_expect_success 'mailmap.blob defaults to off in non-bare repo' '
git init non-bare &&
(
cd non-bare &&
- test_commit one .mailmap "Fake Name <author@example.com>" &&
+ test_commit one .mailmap "Fake Name <$GIT_AUTHOR_EMAIL>" &&
echo " 1 Fake Name" >expect &&
git shortlog -ns HEAD >actual &&
test_cmp expect actual &&
rm .mailmap &&
- echo " 1 A U Thor" >expect &&
+ echo " 1 $GIT_AUTHOR_NAME" >expect &&
git shortlog -ns HEAD >actual &&
test_cmp expect actual
)
@@ -305,26 +305,26 @@ test_expect_success 'cleanup after mailmap.blob tests' '
'
test_expect_success 'single-character name' '
- echo " 1 A <author@example.com>" >expect &&
+ echo " 1 A <$GIT_AUTHOR_EMAIL>" >expect &&
echo " 1 nick1 <bugs@company.xx>" >>expect &&
- echo "A <author@example.com>" >.mailmap &&
+ echo "A <$GIT_AUTHOR_EMAIL>" >.mailmap &&
test_when_finished "rm .mailmap" &&
git shortlog -es HEAD >actual &&
test_cmp expect actual
'
test_expect_success 'preserve canonical email case' '
- echo " 1 A U Thor <AUTHOR@example.com>" >expect &&
+ echo " 1 $GIT_AUTHOR_NAME <AUTHOR@example.com>" >expect &&
echo " 1 nick1 <bugs@company.xx>" >>expect &&
- echo "<AUTHOR@example.com> <author@example.com>" >.mailmap &&
+ echo "<AUTHOR@example.com> <$GIT_AUTHOR_EMAIL>" >.mailmap &&
test_when_finished "rm .mailmap" &&
git shortlog -es HEAD >actual &&
test_cmp expect actual
'
# Extended mailmap configurations should give us the following output for shortlog
-cat >expect <<\EOF
-A U Thor <author@example.com> (1):
+cat >expect << EOF
+$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> (1):
initial
CTO <cto@company.xx> (1):
@@ -370,7 +370,7 @@ test_expect_success 'Shortlog output (complex mapping)' '
git commit --author "CTO <cto@coompany.xx>" -m seventh &&
mkdir -p internal_mailmap &&
- echo "Committed <committer@example.com>" > internal_mailmap/.mailmap &&
+ echo "Committed <$GIT_COMMITTER_EMAIL>" > internal_mailmap/.mailmap &&
echo "<cto@company.xx> <cto@coompany.xx>" >> internal_mailmap/.mailmap &&
echo "Some Dude <some@dude.xx> nick1 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
echo "Other Author <other@author.xx> nick2 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
@@ -384,27 +384,27 @@ test_expect_success 'Shortlog output (complex mapping)' '
'
# git log with --pretty format which uses the name and email mailmap placemarkers
-cat >expect <<\EOF
+cat >expect << EOF
Author CTO <cto@coompany.xx> maps to CTO <cto@company.xx>
-Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
Author claus <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
-Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
Author santa <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
-Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
Author nick2 <nick2@company.xx> maps to Other Author <other@author.xx>
-Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
Author nick2 <bugs@company.xx> maps to Other Author <other@author.xx>
-Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
Author nick1 <bugs@company.xx> maps to Some Dude <some@dude.xx>
-Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-Author A U Thor <author@example.com> maps to A U Thor <author@example.com>
-Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
+Author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> maps to $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
EOF
test_expect_success 'Log output (complex mapping)' '
@@ -412,14 +412,42 @@ test_expect_success 'Log output (complex mapping)' '
test_cmp expect actual
'
-cat >expect <<\EOF
+cat >expect << EOF
+Author email cto@coompany.xx has local-part cto
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email me@company.xx has local-part me
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email me@company.xx has local-part me
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email nick2@company.xx has local-part nick2
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email bugs@company.xx has local-part bugs
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email bugs@company.xx has local-part bugs
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+
+Author email author@example.com has local-part author
+Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+EOF
+
+test_expect_success 'Log output (local-part email address)' '
+ git log --pretty=format:"Author email %ae has local-part %al%nCommitter email %ce has local-part %cl%n" >actual &&
+ test_cmp expect actual
+'
+
+cat >expect << EOF
Author: CTO <cto@company.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Other Author <other@author.xx>
Author: Other Author <other@author.xx>
Author: Some Dude <some@dude.xx>
-Author: A U Thor <author@example.com>
+Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
test_expect_success 'Log output with --use-mailmap' '
@@ -427,14 +455,14 @@ test_expect_success 'Log output with --use-mailmap' '
test_cmp expect actual
'
-cat >expect <<\EOF
+cat >expect << EOF
Author: CTO <cto@company.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Santa Claus <santa.claus@northpole.xx>
Author: Other Author <other@author.xx>
Author: Other Author <other@author.xx>
Author: Some Dude <some@dude.xx>
-Author: A U Thor <author@example.com>
+Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
test_expect_success 'Log output with log.mailmap' '
@@ -443,28 +471,28 @@ test_expect_success 'Log output with log.mailmap' '
'
test_expect_success 'log.mailmap=false disables mailmap' '
- cat >expect <<-\EOF &&
+ cat >expect <<- EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
Author: nick2 <nick2@company.xx>
Author: nick2 <bugs@company.xx>
Author: nick1 <bugs@company.xx>
- Author: A U Thor <author@example.com>
+ Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
git -c log.mailmap=False log | grep Author > actual &&
test_cmp expect actual
'
test_expect_success '--no-use-mailmap disables mailmap' '
- cat >expect <<-\EOF &&
+ cat >expect <<- EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
Author: nick2 <nick2@company.xx>
Author: nick2 <bugs@company.xx>
Author: nick1 <bugs@company.xx>
- Author: A U Thor <author@example.com>
+ Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
git log --no-use-mailmap | grep Author > actual &&
test_cmp expect actual
@@ -500,8 +528,8 @@ test_expect_success 'Only grep replaced author with --use-mailmap' '
'
# git blame
-cat >expect <<\EOF
-^OBJI (A U Thor DATE 1) one
+cat >expect <<EOF
+^OBJI ($GIT_AUTHOR_NAME DATE 1) one
OBJID (Some Dude DATE 2) two
OBJID (Other Author DATE 3) three
OBJID (Other Author DATE 4) four
diff --git a/t/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/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/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index ab3eccf0fa..d42b3efe39 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -124,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___
@@ -585,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/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index c72ca04399..cd2f87be6a 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -147,6 +147,21 @@ test_expect_success 'write midx with two packs' '
compare_results_with_midx "two packs"
+test_expect_success 'write progress off for redirected stderr' '
+ git multi-pack-index --object-dir=$objdir write 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'write force progress on for stderr' '
+ git multi-pack-index --object-dir=$objdir --progress write 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'write with the --no-progress option' '
+ git multi-pack-index --object-dir=$objdir --no-progress write 2>err &&
+ test_line_count = 0 err
+'
+
test_expect_success 'add more packs' '
for j in $(test_seq 11 20)
do
@@ -169,6 +184,21 @@ test_expect_success 'verify multi-pack-index success' '
git multi-pack-index verify --object-dir=$objdir
'
+test_expect_success 'verify progress off for redirected stderr' '
+ git multi-pack-index verify --object-dir=$objdir 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'verify force progress on for stderr' '
+ git multi-pack-index verify --object-dir=$objdir --progress 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'verify with the --no-progress option' '
+ git multi-pack-index verify --object-dir=$objdir --no-progress 2>err &&
+ test_line_count = 0 err
+'
+
# usage: corrupt_midx_and_verify <pos> <data> <objdir> <string>
corrupt_midx_and_verify() {
POS=$1 &&
@@ -284,6 +314,21 @@ test_expect_success 'git-fsck incorrect offset' '
"git -c core.multipackindex=true fsck"
'
+test_expect_success 'repack progress off for redirected stderr' '
+ git multi-pack-index --object-dir=$objdir repack 2>err &&
+ test_line_count = 0 err
+'
+
+test_expect_success 'repack force progress on for stderr' '
+ git multi-pack-index --object-dir=$objdir --progress repack 2>err &&
+ test_file_not_empty err
+'
+
+test_expect_success 'repack with the --no-progress option' '
+ git multi-pack-index --object-dir=$objdir --no-progress repack 2>err &&
+ test_line_count = 0 err
+'
+
test_expect_success 'repack removes multi-pack-index' '
test_path_is_file $objdir/pack/multi-pack-index &&
GIT_TEST_MULTI_PACK_INDEX=0 git repack -adf &&
@@ -413,6 +458,30 @@ test_expect_success 'expire does not remove any packs' '
)
'
+test_expect_success 'expire progress off for redirected stderr' '
+ (
+ cd dup &&
+ git multi-pack-index expire 2>err &&
+ test_line_count = 0 err
+ )
+'
+
+test_expect_success 'expire force progress on for stderr' '
+ (
+ cd dup &&
+ git multi-pack-index --progress expire 2>err &&
+ test_file_not_empty err
+ )
+'
+
+test_expect_success 'expire with the --no-progress option' '
+ (
+ cd dup &&
+ git multi-pack-index --no-progress expire 2>err &&
+ test_line_count = 0 err
+ )
+'
+
test_expect_success 'expire removes unreferenced packs' '
(
cd dup &&
diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh
index e2c39533d3..115aabd141 100755
--- a/t/t5324-split-commit-graph.sh
+++ b/t/t5324-split-commit-graph.sh
@@ -320,7 +320,7 @@ test_expect_success 'add octopus merge' '
git merge commits/3 commits/4 &&
git branch merge/octopus &&
git commit-graph write --reachable --split &&
- git commit-graph verify 2>err &&
+ git commit-graph verify --progress 2>err &&
test_line_count = 3 err &&
test_i18ngrep ! warning err &&
test_line_count = 3 $graphdir/commit-graph-chain
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 5115711562..6b97923964 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -792,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 &&
(
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index ecabbe1616..4b60282689 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -583,6 +583,22 @@ test_expect_success 'fetch.writeCommitGraph' '
)
'
+test_expect_success 'fetch.writeCommitGraph with submodules' '
+ git clone dups super &&
+ (
+ cd super &&
+ git submodule add "file://$TRASH_DIRECTORY/three" &&
+ git commit -m "add submodule"
+ ) &&
+ git clone "super" super-clone &&
+ (
+ cd super-clone &&
+ rm -rf .git/objects/info &&
+ git -c fetch.writeCommitGraph=true fetch origin &&
+ test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain
+ )
+'
+
# configured prune tests
set_config_tristate () {
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/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index b86ddb60f2..4c970787b0 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -184,11 +184,12 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
test_config -C "$d" http.receivepack true &&
up="$HTTPD_URL"/smart/atomic-branches.git &&
- # Tell "$up" about two branches for now
+ # Tell "$up" about three branches for now
test_commit atomic1 &&
test_commit atomic2 &&
git branch collateral &&
- git push "$up" master collateral &&
+ git branch other &&
+ git push "$up" master collateral other &&
# collateral is a valid push, but should be failed by atomic push
git checkout collateral &&
@@ -226,6 +227,41 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output
'
+test_expect_success 'push --atomic fails on server-side errors' '
+ # Use previously set up repository
+ d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
+ test_config -C "$d" http.receivepack true &&
+ up="$HTTPD_URL"/smart/atomic-branches.git &&
+
+ # break ref updates for other on the remote site
+ mkdir "$d/refs/heads/other.lock" &&
+
+ # add the new commit to other
+ git branch -f other collateral &&
+
+ # --atomic should cause entire push to be rejected
+ test_must_fail git push --atomic "$up" atomic other 2>output &&
+
+ # the new branch should not have been created upstream
+ test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
+
+ # upstream should still reflect atomic2, the last thing we pushed
+ # successfully
+ git rev-parse atomic2 >expected &&
+ # ...to other.
+ git -C "$d" rev-parse refs/heads/other >actual &&
+ test_cmp expected actual &&
+
+ # the new branch should not have been created upstream
+ test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
+
+ # the failed refs should be indicated to the user
+ grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output &&
+
+ # the collateral failure refs should be indicated to the user
+ grep "^ ! .*rejected.* atomic -> atomic .*atomic transaction failed" output
+'
+
test_expect_success 'push --all can push to empty repo' '
d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
git init --bare "$d" &&
@@ -262,7 +298,7 @@ test_expect_success TTY 'push shows progress when stderr is a tty' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit noisy &&
test_terminal git push >output 2>&1 &&
- test_i18ngrep "Writing objects" output
+ test_i18ngrep "^Writing objects" output
'
test_expect_success TTY 'push --quiet silences status and progress' '
@@ -277,7 +313,7 @@ test_expect_success TTY 'push --no-progress silences progress but not status' '
test_commit no-progress &&
test_terminal git push --no-progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
- test_i18ngrep ! "Writing objects" output
+ test_i18ngrep ! "^Writing objects" output
'
test_expect_success 'push --progress shows progress to non-tty' '
@@ -285,7 +321,7 @@ test_expect_success 'push --progress shows progress to non-tty' '
test_commit progress &&
git push --progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
- test_i18ngrep "Writing objects" output
+ test_i18ngrep "^Writing objects" output
'
test_expect_success 'http push gives sane defaults to reflog' '
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index fc634a56b2..eaa33a852b 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -46,6 +46,14 @@ test_expect_success 'do partial clone 1' '
test "$(git -C pc1 config --local remote.origin.partialclonefilter)" = "blob:none"
'
+test_expect_success 'verify that .promisor file contains refs fetched' '
+ ls pc1/.git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 1 promisorlist &&
+ git -C srv.bare rev-list HEAD >headhash &&
+ grep "$(cat headhash) HEAD" $(cat promisorlist) &&
+ grep "$(cat headhash) refs/heads/master" $(cat promisorlist)
+'
+
# checkout master to force dynamic object fetch of blobs at HEAD.
test_expect_success 'verify checkout with dynamic object fetch' '
git -C pc1 rev-list --quiet --objects --missing=print HEAD >observed &&
@@ -260,6 +268,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
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/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index cfb74d0e03..ebdc49c496 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -109,31 +109,35 @@ commit $head1
EOF
# we don't test relative here
-test_format author %an%n%ae%n%ad%n%aD%n%at <<EOF
+test_format author %an%n%ae%n%al%n%ad%n%aD%n%at <<EOF
commit $head2
-A U Thor
-author@example.com
+$GIT_AUTHOR_NAME
+$GIT_AUTHOR_EMAIL
+$TEST_AUTHOR_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
commit $head1
-A U Thor
-author@example.com
+$GIT_AUTHOR_NAME
+$GIT_AUTHOR_EMAIL
+$TEST_AUTHOR_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
EOF
-test_format committer %cn%n%ce%n%cd%n%cD%n%ct <<EOF
+test_format committer %cn%n%ce%n%cl%n%cd%n%cD%n%ct <<EOF
commit $head2
-C O Mitter
-committer@example.com
+$GIT_COMMITTER_NAME
+$GIT_COMMITTER_EMAIL
+$TEST_COMMITTER_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
commit $head1
-C O Mitter
-committer@example.com
+$GIT_COMMITTER_NAME
+$GIT_COMMITTER_EMAIL
+$TEST_COMMITTER_LOCALNAME
Thu Apr 7 15:13:13 2005 -0700
Thu, 7 Apr 2005 15:13:13 -0700
1112911993
@@ -410,7 +414,7 @@ test_expect_success 'empty email' '
test_tick &&
C=$(GIT_AUTHOR_EMAIL= git commit-tree HEAD^{tree} </dev/null) &&
A=$(git show --pretty=format:%an,%ae,%ad%n -s $C) &&
- verbose test "$A" = "A U Thor,,Thu Apr 7 15:14:13 2005 -0700"
+ verbose test "$A" = "$GIT_AUTHOR_NAME,,Thu Apr 7 15:14:13 2005 -0700"
'
test_expect_success 'del LF before empty (1)' '
@@ -495,7 +499,7 @@ test_expect_success '%gd shortens ref name' '
'
test_expect_success 'reflog identity' '
- echo "C O Mitter:committer@example.com" >expect &&
+ echo "$GIT_COMMITTER_NAME:$GIT_COMMITTER_EMAIL" >expect &&
git log -g -1 --format="%gn:%ge" >actual &&
test_cmp expect actual
'
diff --git a/t/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/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh
index c5b57f40c3..b047cf1c1c 100755
--- a/t/t6042-merge-rename-corner-cases.sh
+++ b/t/t6042-merge-rename-corner-cases.sh
@@ -5,7 +5,7 @@ test_description="recursive merge corner cases w/ renames but not criss-crosses"
. ./test-lib.sh
-test_expect_success 'setup rename/delete + untracked file' '
+test_setup_rename_delete_untracked () {
test_create_repo rename-delete-untracked &&
(
cd rename-delete-untracked &&
@@ -29,9 +29,10 @@ test_expect_success 'setup rename/delete + untracked file' '
git commit -m track-people-instead-of-objects &&
echo "Myyy PRECIOUSSS" >ring
)
-'
+}
test_expect_success "Does git preserve Gollum's precious artifact?" '
+ test_setup_rename_delete_untracked &&
(
cd rename-delete-untracked &&
@@ -49,7 +50,7 @@ test_expect_success "Does git preserve Gollum's precious artifact?" '
#
# We should be able to merge B & C cleanly
-test_expect_success 'setup rename/modify/add-source conflict' '
+test_setup_rename_modify_add_source () {
test_create_repo rename-modify-add-source &&
(
cd rename-modify-add-source &&
@@ -70,9 +71,10 @@ test_expect_success 'setup rename/modify/add-source conflict' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'rename/modify/add-source conflict resolvable' '
+ test_setup_rename_modify_add_source &&
(
cd rename-modify-add-source &&
@@ -88,7 +90,7 @@ test_expect_failure 'rename/modify/add-source conflict resolvable' '
)
'
-test_expect_success 'setup resolvable conflict missed if rename missed' '
+test_setup_break_detection_1 () {
test_create_repo break-detection-1 &&
(
cd break-detection-1 &&
@@ -110,9 +112,10 @@ test_expect_success 'setup resolvable conflict missed if rename missed' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'conflict caused if rename not detected' '
+ test_setup_break_detection_1 &&
(
cd break-detection-1 &&
@@ -135,7 +138,7 @@ test_expect_failure 'conflict caused if rename not detected' '
)
'
-test_expect_success 'setup conflict resolved wrong if rename missed' '
+test_setup_break_detection_2 () {
test_create_repo break-detection-2 &&
(
cd break-detection-2 &&
@@ -160,9 +163,10 @@ test_expect_success 'setup conflict resolved wrong if rename missed' '
git add a &&
git commit -m E
)
-'
+}
test_expect_failure 'missed conflict if rename not detected' '
+ test_setup_break_detection_2 &&
(
cd break-detection-2 &&
@@ -182,7 +186,7 @@ test_expect_failure 'missed conflict if rename not detected' '
# Commit B: rename a->b
# Commit C: rename a->b, add unrelated a
-test_expect_success 'setup undetected rename/add-source causes data loss' '
+test_setup_break_detection_3 () {
test_create_repo break-detection-3 &&
(
cd break-detection-3 &&
@@ -202,9 +206,10 @@ test_expect_success 'setup undetected rename/add-source causes data loss' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'detect rename/add-source and preserve all data' '
+ test_setup_break_detection_3 &&
(
cd break-detection-3 &&
@@ -231,6 +236,7 @@ test_expect_failure 'detect rename/add-source and preserve all data' '
'
test_expect_failure 'detect rename/add-source and preserve all data, merge other way' '
+ test_setup_break_detection_3 &&
(
cd break-detection-3 &&
@@ -256,10 +262,10 @@ test_expect_failure 'detect rename/add-source and preserve all data, merge other
)
'
-test_expect_success 'setup content merge + rename/directory conflict' '
- test_create_repo rename-directory-1 &&
+test_setup_rename_directory () {
+ test_create_repo rename-directory-$1 &&
(
- cd rename-directory-1 &&
+ cd rename-directory-$1 &&
printf "1\n2\n3\n4\n5\n6\n" >file &&
git add file &&
@@ -290,11 +296,12 @@ test_expect_success 'setup content merge + rename/directory conflict' '
test_tick &&
git commit -m left
)
-'
+}
test_expect_success 'rename/directory conflict + clean content merge' '
+ test_setup_rename_directory 1a &&
(
- cd rename-directory-1 &&
+ cd rename-directory-1a &&
git checkout left-clean^0 &&
@@ -320,8 +327,9 @@ test_expect_success 'rename/directory conflict + clean content merge' '
'
test_expect_success 'rename/directory conflict + content merge conflict' '
+ test_setup_rename_directory 1b &&
(
- cd rename-directory-1 &&
+ cd rename-directory-1b &&
git reset --hard &&
git clean -fdqx &&
@@ -358,7 +366,7 @@ test_expect_success 'rename/directory conflict + content merge conflict' '
)
'
-test_expect_success 'setup content merge + rename/directory conflict w/ disappearing dir' '
+test_setup_rename_directory_2 () {
test_create_repo rename-directory-2 &&
(
cd rename-directory-2 &&
@@ -385,9 +393,10 @@ test_expect_success 'setup content merge + rename/directory conflict w/ disappea
test_tick &&
git commit -m left
)
-'
+}
test_expect_success 'disappearing dir in rename/directory conflict handled' '
+ test_setup_rename_directory_2 &&
(
cd rename-directory-2 &&
@@ -416,10 +425,10 @@ test_expect_success 'disappearing dir in rename/directory conflict handled' '
# Commit A: rename a->b, modifying b too
# Commit B: modify a, add different b
-test_expect_success 'setup rename-with-content-merge vs. add' '
- test_create_repo rename-with-content-merge-and-add &&
+test_setup_rename_with_content_merge_and_add () {
+ test_create_repo rename-with-content-merge-and-add-$1 &&
(
- cd rename-with-content-merge-and-add &&
+ cd rename-with-content-merge-and-add-$1 &&
test_seq 1 5 >a &&
git add a &&
@@ -438,11 +447,12 @@ test_expect_success 'setup rename-with-content-merge vs. add' '
git add a b &&
git commit -m B
)
-'
+}
test_expect_success 'handle rename-with-content-merge vs. add' '
+ test_setup_rename_with_content_merge_and_add AB &&
(
- cd rename-with-content-merge-and-add &&
+ cd rename-with-content-merge-and-add-AB &&
git checkout A^0 &&
@@ -483,8 +493,9 @@ test_expect_success 'handle rename-with-content-merge vs. add' '
'
test_expect_success 'handle rename-with-content-merge vs. add, merge other way' '
+ test_setup_rename_with_content_merge_and_add BA &&
(
- cd rename-with-content-merge-and-add &&
+ cd rename-with-content-merge-and-add-BA &&
git reset --hard &&
git clean -fdx &&
@@ -539,7 +550,7 @@ test_expect_success 'handle rename-with-content-merge vs. add, merge other way'
# * The working copy should have two files, both of form c~<unique>; does it?
# * Nothing else should be present. Is anything?
-test_expect_success 'setup rename/rename (2to1) + modify/modify' '
+test_setup_rename_rename_2to1 () {
test_create_repo rename-rename-2to1 &&
(
cd rename-rename-2to1 &&
@@ -562,9 +573,10 @@ test_expect_success 'setup rename/rename (2to1) + modify/modify' '
git add a &&
git commit -m C
)
-'
+}
test_expect_success 'handle rename/rename (2to1) conflict correctly' '
+ test_setup_rename_rename_2to1 &&
(
cd rename-rename-2to1 &&
@@ -610,7 +622,7 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' '
# Commit A: new file: a
# Commit B: rename a->b
# Commit C: rename a->c
-test_expect_success 'setup simple rename/rename (1to2) conflict' '
+test_setup_rename_rename_1to2 () {
test_create_repo rename-rename-1to2 &&
(
cd rename-rename-1to2 &&
@@ -631,9 +643,10 @@ test_expect_success 'setup simple rename/rename (1to2) conflict' '
test_tick &&
git commit -m C
)
-'
+}
test_expect_success 'merge has correct working tree contents' '
+ test_setup_rename_rename_1to2 &&
(
cd rename-rename-1to2 &&
@@ -667,7 +680,7 @@ test_expect_success 'merge has correct working tree contents' '
#
# Merging of B & C should NOT be clean; there's a rename/rename conflict
-test_expect_success 'setup rename/rename(1to2)/add-source conflict' '
+test_setup_rename_rename_1to2_add_source_1 () {
test_create_repo rename-rename-1to2-add-source-1 &&
(
cd rename-rename-1to2-add-source-1 &&
@@ -687,9 +700,10 @@ test_expect_success 'setup rename/rename(1to2)/add-source conflict' '
git add a &&
git commit -m C
)
-'
+}
test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge' '
+ test_setup_rename_rename_1to2_add_source_1 &&
(
cd rename-rename-1to2-add-source-1 &&
@@ -714,7 +728,7 @@ test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge'
)
'
-test_expect_success 'setup rename/rename(1to2)/add-source resolvable conflict' '
+test_setup_rename_rename_1to2_add_source_2 () {
test_create_repo rename-rename-1to2-add-source-2 &&
(
cd rename-rename-1to2-add-source-2 &&
@@ -737,9 +751,10 @@ test_expect_success 'setup rename/rename(1to2)/add-source resolvable conflict' '
test_tick &&
git commit -m two
)
-'
+}
test_expect_failure 'rename/rename/add-source still tracks new a file' '
+ test_setup_rename_rename_1to2_add_source_2 &&
(
cd rename-rename-1to2-add-source-2 &&
@@ -759,7 +774,7 @@ test_expect_failure 'rename/rename/add-source still tracks new a file' '
)
'
-test_expect_success 'setup rename/rename(1to2)/add-dest conflict' '
+test_setup_rename_rename_1to2_add_dest () {
test_create_repo rename-rename-1to2-add-dest &&
(
cd rename-rename-1to2-add-dest &&
@@ -784,9 +799,10 @@ test_expect_success 'setup rename/rename(1to2)/add-dest conflict' '
test_tick &&
git commit -m two
)
-'
+}
test_expect_success 'rename/rename/add-dest merge still knows about conflicting file versions' '
+ test_setup_rename_rename_1to2_add_dest &&
(
cd rename-rename-1to2-add-dest &&
@@ -838,7 +854,7 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting
# Commit B: rename foo->bar
# Expected: CONFLICT (rename/add/delete), two-way merged bar
-test_expect_success 'rad-setup: rename/add/delete conflict' '
+test_setup_rad () {
test_create_repo rad &&
(
cd rad &&
@@ -860,9 +876,10 @@ test_expect_success 'rad-setup: rename/add/delete conflict' '
git mv foo bar &&
git commit -m "rename foo to bar"
)
-'
+}
test_expect_failure 'rad-check: rename/add/delete conflict' '
+ test_setup_rad &&
(
cd rad &&
@@ -904,7 +921,7 @@ test_expect_failure 'rad-check: rename/add/delete conflict' '
# Commit B: rename bar->baz, rm foo
# Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz
-test_expect_success 'rrdd-setup: rename/rename(2to1)/delete/delete conflict' '
+test_setup_rrdd () {
test_create_repo rrdd &&
(
cd rrdd &&
@@ -927,9 +944,10 @@ test_expect_success 'rrdd-setup: rename/rename(2to1)/delete/delete conflict' '
git rm foo &&
git commit -m "Rename bar, remove foo"
)
-'
+}
test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
+ test_setup_rrdd &&
(
cd rrdd &&
@@ -973,7 +991,7 @@ test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
# Expected: six CONFLICT(rename/rename) messages, each path in two of the
# multi-way merged contents found in two, four, six
-test_expect_success 'mod6-setup: chains of rename/rename(1to2) and rename/rename(2to1)' '
+test_setup_mod6 () {
test_create_repo mod6 &&
(
cd mod6 &&
@@ -1009,9 +1027,10 @@ test_expect_success 'mod6-setup: chains of rename/rename(1to2) and rename/rename
test_tick &&
git commit -m "B"
)
-'
+}
test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '
+ test_setup_mod6 &&
(
cd mod6 &&
@@ -1108,7 +1127,8 @@ test_conflicts_with_adds_and_renames() {
# files. Is it present?
# 4) There should not be any three~* files in the working
# tree
- test_expect_success "setup simple $sideL/$sideR conflict" '
+ test_setup_collision_conflict () {
+ #test_expect_success "setup simple $sideL/$sideR conflict" '
test_create_repo simple_${sideL}_${sideR} &&
(
cd simple_${sideL}_${sideR} &&
@@ -1185,9 +1205,11 @@ test_conflicts_with_adds_and_renames() {
fi &&
test_tick && git commit -m R
)
- '
+ #'
+ }
test_expect_success "check simple $sideL/$sideR conflict" '
+ test_setup_collision_conflict &&
(
cd simple_${sideL}_${sideR} &&
@@ -1254,7 +1276,7 @@ test_conflicts_with_adds_and_renames add add
#
# So, we have four different conflicting files that all end up at path
# 'three'.
-test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
+test_setup_nested_conflicts_from_rename_rename () {
test_create_repo nested_conflicts_from_rename_rename &&
(
cd nested_conflicts_from_rename_rename &&
@@ -1305,9 +1327,10 @@ test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
git add one three &&
test_tick && git commit -m german
)
-'
+}
test_expect_success 'check nested conflicts from rename/rename(2to1)' '
+ test_setup_nested_conflicts_from_rename_rename &&
(
cd nested_conflicts_from_rename_rename &&
diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh
index c966147d5d..bd2f97ba95 100755
--- a/t/t6043-merge-rename-directories.sh
+++ b/t/t6043-merge-rename-directories.sh
@@ -38,7 +38,7 @@ test_description="recursive merge with directory renames"
# Commit B: z/{b,c,d,e/f}
# Expected: y/{b,c,d,e/f}
-test_expect_success '1a-setup: Simple directory rename detection' '
+test_setup_1a () {
test_create_repo 1a &&
(
cd 1a &&
@@ -67,9 +67,10 @@ test_expect_success '1a-setup: Simple directory rename detection' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1a-check: Simple directory rename detection' '
+test_expect_success '1a: Simple directory rename detection' '
+ test_setup_1a &&
(
cd 1a &&
@@ -103,7 +104,7 @@ test_expect_success '1a-check: Simple directory rename detection' '
# Commit B: y/{b,c,d}
# Expected: y/{b,c,d,e}
-test_expect_success '1b-setup: Merge a directory with another' '
+test_setup_1b () {
test_create_repo 1b &&
(
cd 1b &&
@@ -134,9 +135,10 @@ test_expect_success '1b-setup: Merge a directory with another' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1b-check: Merge a directory with another' '
+test_expect_success '1b: Merge a directory with another' '
+ test_setup_1b &&
(
cd 1b &&
@@ -165,7 +167,7 @@ test_expect_success '1b-check: Merge a directory with another' '
# Commit B: z/{b,c,d}
# Expected: y/{b,c,d} (because x/d -> z/d -> y/d)
-test_expect_success '1c-setup: Transitive renaming' '
+test_setup_1c () {
test_create_repo 1c &&
(
cd 1c &&
@@ -193,9 +195,10 @@ test_expect_success '1c-setup: Transitive renaming' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1c-check: Transitive renaming' '
+test_expect_success '1c: Transitive renaming' '
+ test_setup_1c &&
(
cd 1c &&
@@ -227,7 +230,7 @@ test_expect_success '1c-check: Transitive renaming' '
# Note: y/m & z/n should definitely move into x. By the same token, both
# y/wham_1 & z/wham_2 should too...giving us a conflict.
-test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) conflict' '
+test_setup_1d () {
test_create_repo 1d &&
(
cd 1d &&
@@ -262,9 +265,10 @@ test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) con
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) conflict' '
+test_expect_success '1d: Directory renames cause a rename/rename(2to1) conflict' '
+ test_setup_1d &&
(
cd 1d &&
@@ -313,7 +317,7 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con
# Commit B: z/{oldb,oldc,d}
# Expected: y/{newb,newc,d}
-test_expect_success '1e-setup: Renamed directory, with all files being renamed too' '
+test_setup_1e () {
test_create_repo 1e &&
(
cd 1e &&
@@ -342,9 +346,10 @@ test_expect_success '1e-setup: Renamed directory, with all files being renamed t
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1e-check: Renamed directory, with all files being renamed too' '
+test_expect_success '1e: Renamed directory, with all files being renamed too' '
+ test_setup_1e &&
(
cd 1e &&
@@ -371,7 +376,7 @@ test_expect_success '1e-check: Renamed directory, with all files being renamed t
# Commit B: y/{b,c}, x/{d,e,f}
# Expected: y/{b,c}, x/{d,e,f,g}
-test_expect_success '1f-setup: Split a directory into two other directories' '
+test_setup_1f () {
test_create_repo 1f &&
(
cd 1f &&
@@ -408,9 +413,10 @@ test_expect_success '1f-setup: Split a directory into two other directories' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1f-check: Split a directory into two other directories' '
+test_expect_success '1f: Split a directory into two other directories' '
+ test_setup_1f &&
(
cd 1f &&
@@ -459,7 +465,7 @@ test_expect_success '1f-check: Split a directory into two other directories' '
# Commit A: y/b, w/c
# Commit B: z/{b,c,d}
# Expected: y/b, w/c, z/d, with warning about z/ -> (y/ vs. w/) conflict
-test_expect_success '2a-setup: Directory split into two on one side, with equal numbers of paths' '
+test_setup_2a () {
test_create_repo 2a &&
(
cd 2a &&
@@ -489,9 +495,10 @@ test_expect_success '2a-setup: Directory split into two on one side, with equal
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2a-check: Directory split into two on one side, with equal numbers of paths' '
+test_expect_success '2a: Directory split into two on one side, with equal numbers of paths' '
+ test_setup_2a &&
(
cd 2a &&
@@ -520,7 +527,7 @@ test_expect_success '2a-check: Directory split into two on one side, with equal
# Commit A: y/b, w/c
# Commit B: z/{b,c}, x/d
# Expected: y/b, w/c, x/d; No warning about z/ -> (y/ vs. w/) conflict
-test_expect_success '2b-setup: Directory split into two on one side, with equal numbers of paths' '
+test_setup_2b () {
test_create_repo 2b &&
(
cd 2b &&
@@ -551,9 +558,10 @@ test_expect_success '2b-setup: Directory split into two on one side, with equal
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2b-check: Directory split into two on one side, with equal numbers of paths' '
+test_expect_success '2b: Directory split into two on one side, with equal numbers of paths' '
+ test_setup_2b &&
(
cd 2b &&
@@ -601,7 +609,7 @@ test_expect_success '2b-check: Directory split into two on one side, with equal
# Commit A: z/{b,c,d} (no change)
# Commit B: y/{b,c}, x/d
# Expected: y/{b,c}, x/d
-test_expect_success '3a-setup: Avoid implicit rename if involved as source on other side' '
+test_setup_3a () {
test_create_repo 3a &&
(
cd 3a &&
@@ -632,9 +640,10 @@ test_expect_success '3a-setup: Avoid implicit rename if involved as source on ot
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3a-check: Avoid implicit rename if involved as source on other side' '
+test_expect_success '3a: Avoid implicit rename if involved as source on other side' '
+ test_setup_3a &&
(
cd 3a &&
@@ -664,7 +673,7 @@ test_expect_success '3a-check: Avoid implicit rename if involved as source on ot
# get it involved in directory rename detection. If it were, we might
# end up with CONFLICT:(z/d -> y/d vs. x/d vs. w/d), i.e. a
# rename/rename/rename(1to3) conflict, which is just weird.
-test_expect_success '3b-setup: Avoid implicit rename if involved as source on current side' '
+test_setup_3b () {
test_create_repo 3b &&
(
cd 3b &&
@@ -697,9 +706,10 @@ test_expect_success '3b-setup: Avoid implicit rename if involved as source on cu
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3b-check: Avoid implicit rename if involved as source on current side' '
+test_expect_success '3b: Avoid implicit rename if involved as source on current side' '
+ test_setup_3b &&
(
cd 3b &&
@@ -786,7 +796,7 @@ test_expect_success '3b-check: Avoid implicit rename if involved as source on cu
# Expected: y/{b,c,d}, z/{e,f}
# NOTE: Even though most files from z moved to y, we don't want f to follow.
-test_expect_success '4a-setup: Directory split, with original directory still present' '
+test_setup_4a () {
test_create_repo 4a &&
(
cd 4a &&
@@ -818,9 +828,10 @@ test_expect_success '4a-setup: Directory split, with original directory still pr
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '4a-check: Directory split, with original directory still present' '
+test_expect_success '4a: Directory split, with original directory still present' '
+ test_setup_4a &&
(
cd 4a &&
@@ -874,7 +885,7 @@ test_expect_success '4a-check: Directory split, with original directory still pr
# of history, giving us no way to represent this conflict in the
# index.
-test_expect_success '5a-setup: Merge directories, other side adds files to original and target' '
+test_setup_5a () {
test_create_repo 5a &&
(
cd 5a &&
@@ -907,9 +918,10 @@ test_expect_success '5a-setup: Merge directories, other side adds files to origi
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5a-check: Merge directories, other side adds files to original and target' '
+test_expect_success '5a: Merge directories, other side adds files to original and target' '
+ test_setup_5a &&
(
cd 5a &&
@@ -948,7 +960,7 @@ test_expect_success '5a-check: Merge directories, other side adds files to origi
# cause us to bail on directory rename detection for that path, falling
# back to git behavior without the directory rename detection.
-test_expect_success '5b-setup: Rename/delete in order to get add/add/add conflict' '
+test_setup_5b () {
test_create_repo 5b &&
(
cd 5b &&
@@ -981,9 +993,10 @@ test_expect_success '5b-setup: Rename/delete in order to get add/add/add conflic
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5b-check: Rename/delete in order to get add/add/add conflict' '
+test_expect_success '5b: Rename/delete in order to get add/add/add conflict' '
+ test_setup_5b &&
(
cd 5b &&
@@ -1024,7 +1037,7 @@ test_expect_success '5b-check: Rename/delete in order to get add/add/add conflic
# y/d are y/d_2 and y/d_4. We still do the move from z/e to y/e,
# though, because it doesn't have anything in the way.
-test_expect_success '5c-setup: Transitive rename would cause rename/rename/rename/add/add/add' '
+test_setup_5c () {
test_create_repo 5c &&
(
cd 5c &&
@@ -1061,9 +1074,10 @@ test_expect_success '5c-setup: Transitive rename would cause rename/rename/renam
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5c-check: Transitive rename would cause rename/rename/rename/add/add/add' '
+test_expect_success '5c: Transitive rename would cause rename/rename/rename/add/add/add' '
+ test_setup_5c &&
(
cd 5c &&
@@ -1113,7 +1127,7 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam
# detection for z/d_2, but that doesn't prevent us from applying the
# directory rename detection for z/f -> y/f.
-test_expect_success '5d-setup: Directory/file/file conflict due to directory rename' '
+test_setup_5d () {
test_create_repo 5d &&
(
cd 5d &&
@@ -1145,9 +1159,10 @@ test_expect_success '5d-setup: Directory/file/file conflict due to directory ren
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '5d-check: Directory/file/file conflict due to directory rename' '
+test_expect_success '5d: Directory/file/file conflict due to directory rename' '
+ test_setup_5d &&
(
cd 5d &&
@@ -1205,7 +1220,7 @@ test_expect_success '5d-check: Directory/file/file conflict due to directory ren
# them under y/ doesn't accidentally catch z/d and make it look like
# it is also involved in a rename/delete conflict.
-test_expect_success '6a-setup: Tricky rename/delete' '
+test_setup_6a () {
test_create_repo 6a &&
(
cd 6a &&
@@ -1235,9 +1250,10 @@ test_expect_success '6a-setup: Tricky rename/delete' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6a-check: Tricky rename/delete' '
+test_expect_success '6a: Tricky rename/delete' '
+ test_setup_6a &&
(
cd 6a &&
@@ -1271,7 +1287,7 @@ test_expect_success '6a-check: Tricky rename/delete' '
# but B did that rename and still decided to put the file into z/,
# so we probably shouldn't apply directory rename detection for it.
-test_expect_success '6b-setup: Same rename done on both sides' '
+test_setup_6b () {
test_create_repo 6b &&
(
cd 6b &&
@@ -1300,9 +1316,10 @@ test_expect_success '6b-setup: Same rename done on both sides' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6b-check: Same rename done on both sides' '
+test_expect_success '6b: Same rename done on both sides' '
+ test_setup_6b &&
(
cd 6b &&
@@ -1334,7 +1351,7 @@ test_expect_success '6b-check: Same rename done on both sides' '
# NOTE: Seems obvious, but just checking that the implementation doesn't
# "accidentally detect a rename" and give us y/{b,c,d}.
-test_expect_success '6c-setup: Rename only done on same side' '
+test_setup_6c () {
test_create_repo 6c &&
(
cd 6c &&
@@ -1362,9 +1379,10 @@ test_expect_success '6c-setup: Rename only done on same side' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6c-check: Rename only done on same side' '
+test_expect_success '6c: Rename only done on same side' '
+ test_setup_6c &&
(
cd 6c &&
@@ -1396,7 +1414,7 @@ test_expect_success '6c-check: Rename only done on same side' '
# NOTE: Again, this seems obvious but just checking that the implementation
# doesn't "accidentally detect a rename" and give us y/{b,c,d}.
-test_expect_success '6d-setup: We do not always want transitive renaming' '
+test_setup_6d () {
test_create_repo 6d &&
(
cd 6d &&
@@ -1424,9 +1442,10 @@ test_expect_success '6d-setup: We do not always want transitive renaming' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6d-check: We do not always want transitive renaming' '
+test_expect_success '6d: We do not always want transitive renaming' '
+ test_setup_6d &&
(
cd 6d &&
@@ -1458,7 +1477,7 @@ test_expect_success '6d-check: We do not always want transitive renaming' '
# doesn't "accidentally detect a rename" and give us y/{b,c} +
# add/add conflict on y/d_1 vs y/d_2.
-test_expect_success '6e-setup: Add/add from one side' '
+test_setup_6e () {
test_create_repo 6e &&
(
cd 6e &&
@@ -1487,9 +1506,10 @@ test_expect_success '6e-setup: Add/add from one side' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '6e-check: Add/add from one side' '
+test_expect_success '6e: Add/add from one side' '
+ test_setup_6e &&
(
cd 6e &&
@@ -1552,7 +1572,7 @@ test_expect_success '6e-check: Add/add from one side' '
# Expected: y/d, CONFLICT(rename/rename for both z/b and z/c)
# NOTE: There's a rename of z/ here, y/ has more renames, so z/d -> y/d.
-test_expect_success '7a-setup: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+test_setup_7a () {
test_create_repo 7a &&
(
cd 7a &&
@@ -1583,9 +1603,10 @@ test_expect_success '7a-setup: rename-dir vs. rename-dir (NOT split evenly) PLUS
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+test_expect_success '7a: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+ test_setup_7a &&
(
cd 7a &&
@@ -1623,7 +1644,7 @@ test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS
# Commit B: z/{b,c,d_1}, w/d_2
# Expected: y/{b,c}, CONFLICT(rename/rename(2to1): x/d_1, w/d_2 -> y_d)
-test_expect_success '7b-setup: rename/rename(2to1), but only due to transitive rename' '
+test_setup_7b () {
test_create_repo 7b &&
(
cd 7b &&
@@ -1655,9 +1676,10 @@ test_expect_success '7b-setup: rename/rename(2to1), but only due to transitive r
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7b-check: rename/rename(2to1), but only due to transitive rename' '
+test_expect_success '7b: rename/rename(2to1), but only due to transitive rename' '
+ test_setup_7b &&
(
cd 7b &&
@@ -1702,7 +1724,7 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r
# neither CONFLICT(x/d -> w/d vs. z/d)
# nor CONFLiCT x/d -> w/d vs. y/d vs. z/d)
-test_expect_success '7c-setup: rename/rename(1to...2or3); transitive rename may add complexity' '
+test_setup_7c () {
test_create_repo 7c &&
(
cd 7c &&
@@ -1732,9 +1754,10 @@ test_expect_success '7c-setup: rename/rename(1to...2or3); transitive rename may
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may add complexity' '
+test_expect_success '7c: rename/rename(1to...2or3); transitive rename may add complexity' '
+ test_setup_7c &&
(
cd 7c &&
@@ -1766,7 +1789,7 @@ test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may
# Expected: y/{b,c}, CONFLICT(delete x/d vs rename to y/d)
# NOTE: z->y so NOT CONFLICT(delete x/d vs rename to z/d)
-test_expect_success '7d-setup: transitive rename involved in rename/delete; how is it reported?' '
+test_setup_7d () {
test_create_repo 7d &&
(
cd 7d &&
@@ -1796,9 +1819,10 @@ test_expect_success '7d-setup: transitive rename involved in rename/delete; how
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7d-check: transitive rename involved in rename/delete; how is it reported?' '
+test_expect_success '7d: transitive rename involved in rename/delete; how is it reported?' '
+ test_setup_7d &&
(
cd 7d &&
@@ -1851,7 +1875,7 @@ test_expect_success '7d-check: transitive rename involved in rename/delete; how
# see testcases 9c and 9d for further discussion of this issue and
# how it's resolved.
-test_expect_success '7e-setup: transitive rename in rename/delete AND dirs in the way' '
+test_setup_7e () {
test_create_repo 7e &&
(
cd 7e &&
@@ -1886,9 +1910,10 @@ test_expect_success '7e-setup: transitive rename in rename/delete AND dirs in th
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '7e-check: transitive rename in rename/delete AND dirs in the way' '
+test_expect_success '7e: transitive rename in rename/delete AND dirs in the way' '
+ test_setup_7e &&
(
cd 7e &&
@@ -1945,7 +1970,7 @@ test_expect_success '7e-check: transitive rename in rename/delete AND dirs in th
# simple rule from section 5 prevents me from handling this as optimally as
# we potentially could.
-test_expect_success '8a-setup: Dual-directory rename, one into the others way' '
+test_setup_8a () {
test_create_repo 8a &&
(
cd 8a &&
@@ -1977,9 +2002,10 @@ test_expect_success '8a-setup: Dual-directory rename, one into the others way' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8a-check: Dual-directory rename, one into the others way' '
+test_expect_success '8a: Dual-directory rename, one into the others way' '
+ test_setup_8a &&
(
cd 8a &&
@@ -2023,7 +2049,7 @@ test_expect_success '8a-check: Dual-directory rename, one into the others way' '
# making us fall back to pre-directory-rename-detection behavior for both
# e_1 and e_2.
-test_expect_success '8b-setup: Dual-directory rename, one into the others way, with conflicting filenames' '
+test_setup_8b () {
test_create_repo 8b &&
(
cd 8b &&
@@ -2055,9 +2081,10 @@ test_expect_success '8b-setup: Dual-directory rename, one into the others way, w
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8b-check: Dual-directory rename, one into the others way, with conflicting filenames' '
+test_expect_success '8b: Dual-directory rename, one into the others way, with conflicting filenames' '
+ test_setup_8b &&
(
cd 8b &&
@@ -2096,7 +2123,7 @@ test_expect_success '8b-check: Dual-directory rename, one into the others way, w
# rename/rename(1to2) conflicts -- see testcase 9h. See also
# notes in 8d.
-test_expect_success '8c-setup: modify/delete or rename+modify/delete?' '
+test_setup_8c () {
test_create_repo 8c &&
(
cd 8c &&
@@ -2127,9 +2154,10 @@ test_expect_success '8c-setup: modify/delete or rename+modify/delete?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8c-check: modify/delete or rename+modify/delete' '
+test_expect_success '8c: modify/delete or rename+modify/delete' '
+ test_setup_8c &&
(
cd 8c &&
@@ -2175,7 +2203,7 @@ test_expect_success '8c-check: modify/delete or rename+modify/delete' '
# during merging are supposed to be about opposite sides doing things
# differently.
-test_expect_success '8d-setup: rename/delete...or not?' '
+test_setup_8d () {
test_create_repo 8d &&
(
cd 8d &&
@@ -2204,9 +2232,10 @@ test_expect_success '8d-setup: rename/delete...or not?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8d-check: rename/delete...or not?' '
+test_expect_success '8d: rename/delete...or not?' '
+ test_setup_8d &&
(
cd 8d &&
@@ -2250,7 +2279,7 @@ test_expect_success '8d-check: rename/delete...or not?' '
# about the ramifications of doing that, I didn't know how to rule out
# that opening other weird edge and corner cases so I just punted.
-test_expect_success '8e-setup: Both sides rename, one side adds to original directory' '
+test_setup_8e () {
test_create_repo 8e &&
(
cd 8e &&
@@ -2279,9 +2308,10 @@ test_expect_success '8e-setup: Both sides rename, one side adds to original dire
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '8e-check: Both sides rename, one side adds to original directory' '
+test_expect_success '8e: Both sides rename, one side adds to original directory' '
+ test_setup_8e &&
(
cd 8e &&
@@ -2333,7 +2363,7 @@ test_expect_success '8e-check: Both sides rename, one side adds to original dire
# of which one had the most paths going to it. A naive implementation
# of that could take the new file in commit B at z/i to x/w/i or x/i.
-test_expect_success '9a-setup: Inner renamed directory within outer renamed directory' '
+test_setup_9a () {
test_create_repo 9a &&
(
cd 9a &&
@@ -2366,9 +2396,10 @@ test_expect_success '9a-setup: Inner renamed directory within outer renamed dire
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9a-check: Inner renamed directory within outer renamed directory' '
+test_expect_success '9a: Inner renamed directory within outer renamed directory' '
+ test_setup_9a &&
(
cd 9a &&
@@ -2404,7 +2435,7 @@ test_expect_success '9a-check: Inner renamed directory within outer renamed dire
# Commit B: z/{b,c,d_3}
# Expected: y/{b,c,d_merged}
-test_expect_success '9b-setup: Transitive rename with content merge' '
+test_setup_9b () {
test_create_repo 9b &&
(
cd 9b &&
@@ -2436,9 +2467,10 @@ test_expect_success '9b-setup: Transitive rename with content merge' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9b-check: Transitive rename with content merge' '
+test_expect_success '9b: Transitive rename with content merge' '
+ test_setup_9b &&
(
cd 9b &&
@@ -2491,7 +2523,7 @@ test_expect_success '9b-check: Transitive rename with content merge' '
# away, then ignore that particular rename from the other side of
# history for any implicit directory renames.
-test_expect_success '9c-setup: Doubly transitive rename?' '
+test_setup_9c () {
test_create_repo 9c &&
(
cd 9c &&
@@ -2526,9 +2558,10 @@ test_expect_success '9c-setup: Doubly transitive rename?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9c-check: Doubly transitive rename?' '
+test_expect_success '9c: Doubly transitive rename?' '
+ test_setup_9c &&
(
cd 9c &&
@@ -2579,7 +2612,7 @@ test_expect_success '9c-check: Doubly transitive rename?' '
# simple rules that are consistent with what we need for all the other
# testcases and simplifies things for the user.
-test_expect_success '9d-setup: N-way transitive rename?' '
+test_setup_9d () {
test_create_repo 9d &&
(
cd 9d &&
@@ -2614,9 +2647,10 @@ test_expect_success '9d-setup: N-way transitive rename?' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9d-check: N-way transitive rename?' '
+test_expect_success '9d: N-way transitive rename?' '
+ test_setup_9d &&
(
cd 9d &&
@@ -2653,7 +2687,7 @@ test_expect_success '9d-check: N-way transitive rename?' '
# Expected: combined/{a,b,c,d,e,f,g,h,i,j,k,l}, CONFLICT(Nto1) warnings,
# dir1/yo, dir2/yo, dir3/yo, dirN/yo
-test_expect_success '9e-setup: N-to-1 whammo' '
+test_setup_9e () {
test_create_repo 9e &&
(
cd 9e &&
@@ -2696,9 +2730,10 @@ test_expect_success '9e-setup: N-to-1 whammo' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' '
+test_expect_success C_LOCALE_OUTPUT '9e: N-to-1 whammo' '
+ test_setup_9e &&
(
cd 9e &&
@@ -2745,7 +2780,7 @@ test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' '
# Commit B: goal/{a,b}/$more_files, goal/c
# Expected: priority/{a,b}/$more_files, priority/c
-test_expect_success '9f-setup: Renamed directory that only contained immediate subdirs' '
+test_setup_9f () {
test_create_repo 9f &&
(
cd 9f &&
@@ -2774,9 +2809,10 @@ test_expect_success '9f-setup: Renamed directory that only contained immediate s
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9f-check: Renamed directory that only contained immediate subdirs' '
+test_expect_success '9f: Renamed directory that only contained immediate subdirs' '
+ test_setup_9f &&
(
cd 9f &&
@@ -2809,7 +2845,7 @@ test_expect_success '9f-check: Renamed directory that only contained immediate s
# Commit B: goal/{a,b}/$more_files, goal/c
# Expected: priority/{alpha,bravo}/$more_files, priority/c
-test_expect_success '9g-setup: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
+test_setup_9g () {
test_create_repo 9g &&
(
cd 9g &&
@@ -2841,9 +2877,9 @@ test_expect_success '9g-setup: Renamed directory that only contained immediate s
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_failure '9g-check: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
+test_expect_failure '9g: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
(
cd 9g &&
@@ -2877,7 +2913,7 @@ test_expect_failure '9g-check: Renamed directory that only contained immediate s
# Expected: y/{b,c}, x/d_2
# NOTE: If we applied the z/ -> y/ rename to z/d, then we'd end up with
# a rename/rename(1to2) conflict (z/d -> y/d vs. x/d)
-test_expect_success '9h-setup: Avoid dir rename on merely modified path' '
+test_setup_9h () {
test_create_repo 9h &&
(
cd 9h &&
@@ -2910,9 +2946,10 @@ test_expect_success '9h-setup: Avoid dir rename on merely modified path' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '9h-check: Avoid dir rename on merely modified path' '
+test_expect_success '9h: Avoid dir rename on merely modified path' '
+ test_setup_9h &&
(
cd 9h &&
@@ -2957,7 +2994,7 @@ test_expect_success '9h-check: Avoid dir rename on merely modified path' '
# Expected: Aborted Merge +
# ERROR_MSG(untracked working tree files would be overwritten by merge)
-test_expect_success '10a-setup: Overwrite untracked with normal rename/delete' '
+test_setup_10a () {
test_create_repo 10a &&
(
cd 10a &&
@@ -2983,9 +3020,10 @@ test_expect_success '10a-setup: Overwrite untracked with normal rename/delete' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10a-check: Overwrite untracked with normal rename/delete' '
+test_expect_success '10a: Overwrite untracked with normal rename/delete' '
+ test_setup_10a &&
(
cd 10a &&
@@ -3021,7 +3059,7 @@ test_expect_success '10a-check: Overwrite untracked with normal rename/delete' '
# z/c_1 -> z/d_1 rename recorded at stage 3 for y/d +
# ERROR_MSG(refusing to lose untracked file at 'y/d')
-test_expect_success '10b-setup: Overwrite untracked with dir rename + delete' '
+test_setup_10b () {
test_create_repo 10b &&
(
cd 10b &&
@@ -3050,9 +3088,10 @@ test_expect_success '10b-setup: Overwrite untracked with dir rename + delete' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10b-check: Overwrite untracked with dir rename + delete' '
+test_expect_success '10b: Overwrite untracked with dir rename + delete' '
+ test_setup_10b &&
(
cd 10b &&
@@ -3098,10 +3137,10 @@ test_expect_success '10b-check: Overwrite untracked with dir rename + delete' '
# y/c~B^0 +
# ERROR_MSG(Refusing to lose untracked file at y/c)
-test_expect_success '10c-setup: Overwrite untracked with dir rename/rename(1to2)' '
- test_create_repo 10c &&
+test_setup_10c () {
+ test_create_repo 10c_$1 &&
(
- cd 10c &&
+ cd 10c_$1 &&
mkdir z x &&
echo a >z/a &&
@@ -3128,11 +3167,12 @@ test_expect_success '10c-setup: Overwrite untracked with dir rename/rename(1to2)
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)' '
+test_expect_success '10c1: Overwrite untracked with dir rename/rename(1to2)' '
+ test_setup_10c 1 &&
(
- cd 10c &&
+ cd 10c_1 &&
git checkout A^0 &&
echo important >y/c &&
@@ -3163,9 +3203,10 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
)
'
-test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2), other direction' '
+test_expect_success '10c2: Overwrite untracked with dir rename/rename(1to2), other direction' '
+ test_setup_10c 2 &&
(
- cd 10c &&
+ cd 10c_2 &&
git reset --hard &&
git clean -fdqx &&
@@ -3208,7 +3249,7 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
# CONFLICT(rename/rename) z/c_1 vs x/f_2 -> y/wham
# ERROR_MSG(Refusing to lose untracked file at y/wham)
-test_expect_success '10d-setup: Delete untracked with dir rename/rename(2to1)' '
+test_setup_10d () {
test_create_repo 10d &&
(
cd 10d &&
@@ -3240,9 +3281,10 @@ test_expect_success '10d-setup: Delete untracked with dir rename/rename(2to1)' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
+test_expect_success '10d: Delete untracked with dir rename/rename(2to1)' '
+ test_setup_10d &&
(
cd 10d &&
@@ -3290,7 +3332,7 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
# Commit B: z/{a,b,c}
# Expected: y/{a,b,c} + untracked z/c
-test_expect_success '10e-setup: Does git complain about untracked file that is not really in the way?' '
+test_setup_10e () {
test_create_repo 10e &&
(
cd 10e &&
@@ -3317,9 +3359,9 @@ test_expect_success '10e-setup: Does git complain about untracked file that is n
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_failure '10e-check: Does git complain about untracked file that is not really in the way?' '
+test_expect_failure '10e: Does git complain about untracked file that is not really in the way?' '
(
cd 10e &&
@@ -3371,7 +3413,7 @@ test_expect_failure '10e-check: Does git complain about untracked file that is n
# z/c~HEAD with contents of B:z/b_v2,
# z/c with uncommitted mods on top of A:z/c_v1
-test_expect_success '11a-setup: Avoid losing dirty contents with simple rename' '
+test_setup_11a () {
test_create_repo 11a &&
(
cd 11a &&
@@ -3398,9 +3440,10 @@ test_expect_success '11a-setup: Avoid losing dirty contents with simple rename'
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11a-check: Avoid losing dirty contents with simple rename' '
+test_expect_success '11a: Avoid losing dirty contents with simple rename' '
+ test_setup_11a &&
(
cd 11a &&
@@ -3441,7 +3484,7 @@ test_expect_success '11a-check: Avoid losing dirty contents with simple rename'
# ERROR_MSG(Refusing to lose dirty file at z/c)
-test_expect_success '11b-setup: Avoid losing dirty file involved in directory rename' '
+test_setup_11b () {
test_create_repo 11b &&
(
cd 11b &&
@@ -3470,9 +3513,10 @@ test_expect_success '11b-setup: Avoid losing dirty file involved in directory re
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11b-check: Avoid losing dirty file involved in directory rename' '
+test_expect_success '11b: Avoid losing dirty file involved in directory rename' '
+ test_setup_11b &&
(
cd 11b &&
@@ -3515,7 +3559,7 @@ test_expect_success '11b-check: Avoid losing dirty file involved in directory re
# Expected: Abort_msg("following files would be overwritten by merge") +
# y/c left untouched (still has uncommitted mods)
-test_expect_success '11c-setup: Avoid losing not-uptodate with rename + D/F conflict' '
+test_setup_11c () {
test_create_repo 11c &&
(
cd 11c &&
@@ -3545,9 +3589,10 @@ test_expect_success '11c-setup: Avoid losing not-uptodate with rename + D/F conf
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conflict' '
+test_expect_success '11c: Avoid losing not-uptodate with rename + D/F conflict' '
+ test_setup_11c &&
(
cd 11c &&
@@ -3581,7 +3626,7 @@ test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conf
# Warning_Msg("Refusing to lose dirty file at z/c) +
# y/{a,c~HEAD,c/d}, x/b, now-untracked z/c_v1 with uncommitted mods
-test_expect_success '11d-setup: Avoid losing not-uptodate with rename + D/F conflict' '
+test_setup_11d () {
test_create_repo 11d &&
(
cd 11d &&
@@ -3612,9 +3657,10 @@ test_expect_success '11d-setup: Avoid losing not-uptodate with rename + D/F conf
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conflict' '
+test_expect_success '11d: Avoid losing not-uptodate with rename + D/F conflict' '
+ test_setup_11d &&
(
cd 11d &&
@@ -3659,7 +3705,7 @@ test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conf
# y/c~HEAD has A:y/c_2 contents
# y/c has dirty file from before merge
-test_expect_success '11e-setup: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+test_setup_11e () {
test_create_repo 11e &&
(
cd 11e &&
@@ -3691,9 +3737,10 @@ test_expect_success '11e-setup: Avoid deleting not-uptodate with dir rename/rena
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+test_expect_success '11e: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+ test_setup_11e &&
(
cd 11e &&
@@ -3744,7 +3791,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
# CONFLICT(rename/rename) x/c vs x/d -> y/wham
# ERROR_MSG(Refusing to lose dirty file at y/wham)
-test_expect_success '11f-setup: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+test_setup_11f () {
test_create_repo 11f &&
(
cd 11f &&
@@ -3773,9 +3820,10 @@ test_expect_success '11f-setup: Avoid deleting not-uptodate with dir rename/rena
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+test_expect_success '11f: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+ test_setup_11f &&
(
cd 11f &&
@@ -3832,7 +3880,7 @@ test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rena
# Commit B: node1/{leaf1,leaf2,leaf5}, node2/{leaf3,leaf4,leaf6}
# Expected: node1/{leaf1,leaf2,leaf5,node2/{leaf3,leaf4,leaf6}}
-test_expect_success '12a-setup: Moving one directory hierarchy into another' '
+test_setup_12a () {
test_create_repo 12a &&
(
cd 12a &&
@@ -3862,9 +3910,10 @@ test_expect_success '12a-setup: Moving one directory hierarchy into another' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '12a-check: Moving one directory hierarchy into another' '
+test_expect_success '12a: Moving one directory hierarchy into another' '
+ test_setup_12a &&
(
cd 12a &&
@@ -3910,7 +3959,7 @@ test_expect_success '12a-check: Moving one directory hierarchy into another' '
# To which, I can do no more than shrug my shoulders and say that
# even simple rules give weird results when given weird inputs.
-test_expect_success '12b-setup: Moving two directory hierarchies into each other' '
+test_setup_12b () {
test_create_repo 12b &&
(
cd 12b &&
@@ -3938,9 +3987,10 @@ test_expect_success '12b-setup: Moving two directory hierarchies into each other
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '12b-check: Moving two directory hierarchies into each other' '
+test_expect_success '12b: Moving two directory hierarchies into each other' '
+ test_setup_12b &&
(
cd 12b &&
@@ -3976,7 +4026,7 @@ test_expect_success '12b-check: Moving two directory hierarchies into each other
# NOTE: This is *exactly* like 12c, except that every path is modified on
# each side of the merge.
-test_expect_success '12c-setup: Moving one directory hierarchy into another w/ content merge' '
+test_setup_12c () {
test_create_repo 12c &&
(
cd 12c &&
@@ -4008,9 +4058,10 @@ test_expect_success '12c-setup: Moving one directory hierarchy into another w/ c
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '12c-check: Moving one directory hierarchy into another w/ content merge' '
+test_expect_success '12c: Moving one directory hierarchy into another w/ content merge' '
+ test_setup_12c &&
(
cd 12c &&
@@ -4051,6 +4102,122 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c
)
'
+# Testcase 12d, Rename/merge of subdirectory into the root
+# Commit O: a/b/subdir/foo
+# Commit A: subdir/foo
+# Commit B: a/b/subdir/foo, a/b/bar
+# Expected: subdir/foo, bar
+
+test_setup_12d () {
+ test_create_repo 12d &&
+ (
+ cd 12d &&
+
+ mkdir -p a/b/subdir &&
+ test_commit a/b/subdir/foo &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ mkdir subdir &&
+ git mv a/b/subdir/foo.t subdir/foo.t &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ test_commit a/b/bar
+ )
+}
+
+test_expect_success '12d: Rename/merge subdir into the root, variant 1' '
+ test_setup_12d &&
+ (
+ cd 12d &&
+
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
+
+ git ls-files -s >out &&
+ test_line_count = 2 out &&
+
+ git rev-parse >actual \
+ HEAD:subdir/foo.t HEAD:bar.t &&
+ git rev-parse >expect \
+ O:a/b/subdir/foo.t B:a/b/bar.t &&
+ test_cmp expect actual &&
+
+ git hash-object bar.t >actual &&
+ git rev-parse B:a/b/bar.t >expect &&
+ test_cmp expect actual &&
+
+ test_must_fail git rev-parse HEAD:a/b/subdir/foo.t &&
+ test_must_fail git rev-parse HEAD:a/b/bar.t &&
+ test_path_is_missing a/ &&
+ test_path_is_file bar.t
+ )
+'
+
+# Testcase 12e, Rename/merge of subdirectory into the root
+# Commit O: a/b/foo
+# Commit A: foo
+# Commit B: a/b/foo, a/b/bar
+# Expected: foo, bar
+
+test_setup_12e () {
+ test_create_repo 12e &&
+ (
+ cd 12e &&
+
+ mkdir -p a/b &&
+ test_commit a/b/foo &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ mkdir subdir &&
+ git mv a/b/foo.t foo.t &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ test_commit a/b/bar
+ )
+}
+
+test_expect_success '12e: Rename/merge subdir into the root, variant 2' '
+ test_setup_12e &&
+ (
+ cd 12e &&
+
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
+
+ git ls-files -s >out &&
+ test_line_count = 2 out &&
+
+ git rev-parse >actual \
+ HEAD:foo.t HEAD:bar.t &&
+ git rev-parse >expect \
+ O:a/b/foo.t B:a/b/bar.t &&
+ test_cmp expect actual &&
+
+ git hash-object bar.t >actual &&
+ git rev-parse B:a/b/bar.t >expect &&
+ test_cmp expect actual &&
+
+ test_must_fail git rev-parse HEAD:a/b/foo.t &&
+ test_must_fail git rev-parse HEAD:a/b/bar.t &&
+ test_path_is_missing a/ &&
+ test_path_is_file bar.t
+ )
+'
+
###########################################################################
# SECTION 13: Checking informational and conflict messages
#
@@ -4068,10 +4235,10 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c
# Commit B: z/{b,c,d,e/f}
# Expected: y/{b,c,d,e/f}, with notices/conflicts for both y/d and y/e/f
-test_expect_success '13a-setup: messages for newly added files' '
- test_create_repo 13a &&
+test_setup_13a () {
+ test_create_repo 13a_$1 &&
(
- cd 13a &&
+ cd 13a_$1 &&
mkdir z &&
echo b >z/b &&
@@ -4097,11 +4264,12 @@ test_expect_success '13a-setup: messages for newly added files' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13a-check(conflict): messages for newly added files' '
+test_expect_success '13a(conflict): messages for newly added files' '
+ test_setup_13a conflict &&
(
- cd 13a &&
+ cd 13a_conflict &&
git checkout A^0 &&
@@ -4121,9 +4289,10 @@ test_expect_success '13a-check(conflict): messages for newly added files' '
)
'
-test_expect_success '13a-check(info): messages for newly added files' '
+test_expect_success '13a(info): messages for newly added files' '
+ test_setup_13a info &&
(
- cd 13a &&
+ cd 13a_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4153,10 +4322,10 @@ test_expect_success '13a-check(info): messages for newly added files' '
# Expected: y/{b,c,d_merged}, with two conflict messages for y/d,
# one about content, and one about file location
-test_expect_success '13b-setup: messages for transitive rename with conflicted content' '
- test_create_repo 13b &&
+test_setup_13b () {
+ test_create_repo 13b_$1 &&
(
- cd 13b &&
+ cd 13b_$1 &&
mkdir x &&
mkdir z &&
@@ -4185,11 +4354,12 @@ test_expect_success '13b-setup: messages for transitive rename with conflicted c
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13b-check(conflict): messages for transitive rename with conflicted content' '
+test_expect_success '13b(conflict): messages for transitive rename with conflicted content' '
+ test_setup_13b conflict &&
(
- cd 13b &&
+ cd 13b_conflict &&
git checkout A^0 &&
@@ -4207,9 +4377,10 @@ test_expect_success '13b-check(conflict): messages for transitive rename with co
)
'
-test_expect_success '13b-check(info): messages for transitive rename with conflicted content' '
+test_expect_success '13b(info): messages for transitive rename with conflicted content' '
+ test_setup_13b info &&
(
- cd 13b &&
+ cd 13b_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4238,10 +4409,10 @@ test_expect_success '13b-check(info): messages for transitive rename with confli
# d and B had full knowledge, but that's a slippery slope as
# shown in testcase 13d.
-test_expect_success '13c-setup: messages for rename/rename(1to1) via transitive rename' '
- test_create_repo 13c &&
+test_setup_13c () {
+ test_create_repo 13c_$1 &&
(
- cd 13c &&
+ cd 13c_$1 &&
mkdir x &&
mkdir z &&
@@ -4269,11 +4440,12 @@ test_expect_success '13c-setup: messages for rename/rename(1to1) via transitive
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13c-check(conflict): messages for rename/rename(1to1) via transitive rename' '
+test_expect_success '13c(conflict): messages for rename/rename(1to1) via transitive rename' '
+ test_setup_13c conflict &&
(
- cd 13c &&
+ cd 13c_conflict &&
git checkout A^0 &&
@@ -4290,9 +4462,10 @@ test_expect_success '13c-check(conflict): messages for rename/rename(1to1) via t
)
'
-test_expect_success '13c-check(info): messages for rename/rename(1to1) via transitive rename' '
+test_expect_success '13c(info): messages for rename/rename(1to1) via transitive rename' '
+ test_setup_13c info &&
(
- cd 13c &&
+ cd 13c_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4324,10 +4497,10 @@ test_expect_success '13c-check(info): messages for rename/rename(1to1) via trans
# * B renames a/y to c/y, and A renames c/->d/ => a/y -> d/y
# No conflict in where a/y ends up, so put it in d/y.
-test_expect_success '13d-setup: messages for rename/rename(1to1) via dual transitive rename' '
- test_create_repo 13d &&
+test_setup_13d () {
+ test_create_repo 13d_$1 &&
(
- cd 13d &&
+ cd 13d_$1 &&
mkdir a &&
mkdir b &&
@@ -4356,11 +4529,12 @@ test_expect_success '13d-setup: messages for rename/rename(1to1) via dual transi
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '13d-check(conflict): messages for rename/rename(1to1) via dual transitive rename' '
+test_expect_success '13d(conflict): messages for rename/rename(1to1) via dual transitive rename' '
+ test_setup_13d conflict &&
(
- cd 13d &&
+ cd 13d_conflict &&
git checkout A^0 &&
@@ -4380,9 +4554,10 @@ test_expect_success '13d-check(conflict): messages for rename/rename(1to1) via d
)
'
-test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual transitive rename' '
+test_expect_success '13d(info): messages for rename/rename(1to1) via dual transitive rename' '
+ test_setup_13d info &&
(
- cd 13d &&
+ cd 13d_info &&
git reset --hard &&
git checkout A^0 &&
@@ -4448,7 +4623,7 @@ test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual
# in the outer merge for this special kind of setup, but it at
# least avoids hitting a BUG().
#
-test_expect_success '13e-setup: directory rename detection in recursive case' '
+test_setup_13e () {
test_create_repo 13e &&
(
cd 13e &&
@@ -4493,9 +4668,10 @@ test_expect_success '13e-setup: directory rename detection in recursive case' '
test_tick &&
git commit -m "D"
)
-'
+}
-test_expect_success '13e-check: directory rename detection in recursive case' '
+test_expect_success '13e: directory rename detection in recursive case' '
+ test_setup_13e &&
(
cd 13e &&
diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh
index 3a47623ed3..b7e4669832 100755
--- a/t/t6046-merge-skip-unneeded-updates.sh
+++ b/t/t6046-merge-skip-unneeded-updates.sh
@@ -36,10 +36,10 @@ test_description="merge cases"
# Commit B: b_3
# Expected: b_2
-test_expect_success '1a-setup: Modify(A)/Modify(B), change on B subset of A' '
- test_create_repo 1a &&
+test_setup_1a () {
+ test_create_repo 1a_$1 &&
(
- cd 1a &&
+ cd 1a_$1 &&
test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
git add b &&
@@ -62,13 +62,12 @@ test_expect_success '1a-setup: Modify(A)/Modify(B), change on B subset of A' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '1a-check-L: Modify(A)/Modify(B), change on B subset of A' '
- test_when_finished "git -C 1a reset --hard" &&
- test_when_finished "git -C 1a clean -fd" &&
+test_expect_success '1a-L: Modify(A)/Modify(B), change on B subset of A' '
+ test_setup_1a L &&
(
- cd 1a &&
+ cd 1a_L &&
git checkout A^0 &&
@@ -96,11 +95,10 @@ test_expect_success '1a-check-L: Modify(A)/Modify(B), change on B subset of A' '
)
'
-test_expect_success '1a-check-R: Modify(A)/Modify(B), change on B subset of A' '
- test_when_finished "git -C 1a reset --hard" &&
- test_when_finished "git -C 1a clean -fd" &&
+test_expect_success '1a-R: Modify(A)/Modify(B), change on B subset of A' '
+ test_setup_1a R &&
(
- cd 1a &&
+ cd 1a_R &&
git checkout B^0 &&
@@ -133,10 +131,10 @@ test_expect_success '1a-check-R: Modify(A)/Modify(B), change on B subset of A' '
# Commit B: c_1
# Expected: c_2
-test_expect_success '2a-setup: Modify(A)/rename(B)' '
- test_create_repo 2a &&
+test_setup_2a () {
+ test_create_repo 2a_$1 &&
(
- cd 2a &&
+ cd 2a_$1 &&
test_seq 1 10 >b &&
git add b &&
@@ -158,13 +156,12 @@ test_expect_success '2a-setup: Modify(A)/rename(B)' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2a-check-L: Modify/rename, merge into modify side' '
- test_when_finished "git -C 2a reset --hard" &&
- test_when_finished "git -C 2a clean -fd" &&
+test_expect_success '2a-L: Modify/rename, merge into modify side' '
+ test_setup_2a L &&
(
- cd 2a &&
+ cd 2a_L &&
git checkout A^0 &&
@@ -189,11 +186,10 @@ test_expect_success '2a-check-L: Modify/rename, merge into modify side' '
)
'
-test_expect_success '2a-check-R: Modify/rename, merge into rename side' '
- test_when_finished "git -C 2a reset --hard" &&
- test_when_finished "git -C 2a clean -fd" &&
+test_expect_success '2a-R: Modify/rename, merge into rename side' '
+ test_setup_2a R &&
(
- cd 2a &&
+ cd 2a_R &&
git checkout B^0 &&
@@ -224,10 +220,10 @@ test_expect_success '2a-check-R: Modify/rename, merge into rename side' '
# Commit B: b_3
# Expected: c_2
-test_expect_success '2b-setup: Rename+Mod(A)/Mod(B), B mods subset of A' '
- test_create_repo 2b &&
+test_setup_2b () {
+ test_create_repo 2b_$1 &&
(
- cd 2b &&
+ cd 2b_$1 &&
test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
git add b &&
@@ -251,13 +247,12 @@ test_expect_success '2b-setup: Rename+Mod(A)/Mod(B), B mods subset of A' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2b-check-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
- test_when_finished "git -C 2b reset --hard" &&
- test_when_finished "git -C 2b clean -fd" &&
+test_expect_success '2b-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
+ test_setup_2b L &&
(
- cd 2b &&
+ cd 2b_L &&
git checkout A^0 &&
@@ -288,11 +283,10 @@ test_expect_success '2b-check-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
)
'
-test_expect_success '2b-check-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
- test_when_finished "git -C 2b reset --hard" &&
- test_when_finished "git -C 2b clean -fd" &&
+test_expect_success '2b-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
+ test_setup_2b R &&
(
- cd 2b &&
+ cd 2b_R &&
git checkout B^0 &&
@@ -332,7 +326,7 @@ test_expect_success '2b-check-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
# skip the update, then we're in trouble. This test verifies we do
# not make that particular mistake.
-test_expect_success '2c-setup: Modify b & add c VS rename b->c' '
+test_setup_2c () {
test_create_repo 2c &&
(
cd 2c &&
@@ -358,9 +352,10 @@ test_expect_success '2c-setup: Modify b & add c VS rename b->c' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '2c-check: Modify b & add c VS rename b->c' '
+test_expect_success '2c: Modify b & add c VS rename b->c' '
+ test_setup_2c &&
(
cd 2c &&
@@ -428,10 +423,10 @@ test_expect_success '2c-check: Modify b & add c VS rename b->c' '
# Commit B: bq_1, bar/whatever
# Expected: bar/{bq_2, whatever}
-test_expect_success '3a-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_create_repo 3a &&
+test_setup_3a () {
+ test_create_repo 3a_$1 &&
(
- cd 3a &&
+ cd 3a_$1 &&
mkdir foo &&
test_seq 1 10 >bq &&
@@ -456,13 +451,12 @@ test_expect_success '3a-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3a reset --hard" &&
- test_when_finished "git -C 3a clean -fd" &&
+test_expect_success '3a-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3a L &&
(
- cd 3a &&
+ cd 3a_L &&
git checkout A^0 &&
@@ -487,11 +481,10 @@ test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
)
'
-test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3a reset --hard" &&
- test_when_finished "git -C 3a clean -fd" &&
+test_expect_success '3a-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3a R &&
(
- cd 3a &&
+ cd 3a_R &&
git checkout B^0 &&
@@ -522,10 +515,10 @@ test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
# Commit B: bq_2, bar/whatever
# Expected: bar/{bq_2, whatever}
-test_expect_success '3b-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_create_repo 3b &&
+test_setup_3b () {
+ test_create_repo 3b_$1 &&
(
- cd 3b &&
+ cd 3b_$1 &&
mkdir foo &&
test_seq 1 10 >bq &&
@@ -550,13 +543,12 @@ test_expect_success '3b-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3b reset --hard" &&
- test_when_finished "git -C 3b clean -fd" &&
+test_expect_success '3b-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3b L &&
(
- cd 3b &&
+ cd 3b_L &&
git checkout A^0 &&
@@ -581,11 +573,10 @@ test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
)
'
-test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
- test_when_finished "git -C 3b reset --hard" &&
- test_when_finished "git -C 3b clean -fd" &&
+test_expect_success '3b-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+ test_setup_3b R &&
(
- cd 3b &&
+ cd 3b_R &&
git checkout B^0 &&
@@ -621,7 +612,7 @@ test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
# Working copy: b_4
# Expected: b_2 for merge, b_4 in working copy
-test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods present' '
+test_setup_4a () {
test_create_repo 4a &&
(
cd 4a &&
@@ -647,7 +638,7 @@ test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods
test_tick &&
git commit -m "B"
)
-'
+}
# NOTE: For as long as we continue using unpack_trees() without index_only
# set to true, it will error out on a case like this claiming the the locally
@@ -655,9 +646,8 @@ test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods
# correct requires doing the merge in-memory first, then realizing that no
# updates to the file are necessary, and thus that we can just leave the path
# alone.
-test_expect_failure '4a-check: Change on A, change on B subset of A, dirty mods present' '
- test_when_finished "git -C 4a reset --hard" &&
- test_when_finished "git -C 4a clean -fd" &&
+test_expect_failure '4a: Change on A, change on B subset of A, dirty mods present' '
+ test_setup_4a &&
(
cd 4a &&
@@ -695,7 +685,7 @@ test_expect_failure '4a-check: Change on A, change on B subset of A, dirty mods
# Working copy: c_4
# Expected: c_2
-test_expect_success '4b-setup: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
+test_setup_4b () {
test_create_repo 4b &&
(
cd 4b &&
@@ -722,11 +712,10 @@ test_expect_success '4b-setup: Rename+Mod(A)/Mod(B), change on B subset of A, di
test_tick &&
git commit -m "B"
)
-'
+}
-test_expect_success '4b-check: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
- test_when_finished "git -C 4b reset --hard" &&
- test_when_finished "git -C 4b clean -fd" &&
+test_expect_success '4b: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
+ test_setup_4b &&
(
cd 4b &&
diff --git a/t/t6047-diff3-conflict-markers.sh b/t/t6047-diff3-conflict-markers.sh
new file mode 100755
index 0000000000..860542aad0
--- /dev/null
+++ b/t/t6047-diff3-conflict-markers.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+
+test_description='recursive merge diff3 style conflict markers'
+
+. ./test-lib.sh
+
+# Setup:
+# L1
+# \
+# ?
+# /
+# R1
+#
+# Where:
+# L1 and R1 both have a file named 'content' but have no common history
+#
+
+test_expect_success 'setup no merge base' '
+ test_create_repo no_merge_base &&
+ (
+ cd no_merge_base &&
+
+ git checkout -b L &&
+ test_commit A content A &&
+
+ git checkout --orphan R &&
+ test_commit B content B
+ )
+'
+
+test_expect_success 'check no merge base' '
+ (
+ cd no_merge_base &&
+
+ git checkout L^0 &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge --allow-unrelated-histories -s recursive R^0 &&
+
+ grep "|||||| empty tree" content
+ )
+'
+
+# Setup:
+# L1
+# / \
+# master ?
+# \ /
+# R1
+#
+# Where:
+# L1 and R1 have modified the same file ('content') in conflicting ways
+#
+
+test_expect_success 'setup unique merge base' '
+ test_create_repo unique_merge_base &&
+ (
+ cd unique_merge_base &&
+
+ test_commit base content "1
+2
+3
+4
+5
+" &&
+
+ git branch L &&
+ git branch R &&
+
+ git checkout L &&
+ test_commit L content "1
+2
+3
+4
+5
+7" &&
+
+ git checkout R &&
+ git rm content &&
+ test_commit R renamed "1
+2
+3
+4
+5
+six"
+ )
+'
+
+test_expect_success 'check unique merge base' '
+ (
+ cd unique_merge_base &&
+
+ git checkout L^0 &&
+ MASTER=$(git rev-parse --short master) &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R^0 &&
+
+ grep "|||||| $MASTER:content" renamed
+ )
+'
+
+# Setup:
+# L1---L2--L3
+# / \ / \
+# master X1 ?
+# \ / \ /
+# R1---R2--R3
+#
+# Where:
+# commits L1 and R1 have modified the same file in non-conflicting ways
+# X1 is an auto-generated merge-base used when merging L1 and R1
+# commits L2 and R2 are merges of R1 and L1 into L1 and R1, respectively
+# commits L3 and R3 both modify 'content' in conflicting ways
+#
+
+test_expect_success 'setup multiple merge bases' '
+ test_create_repo multiple_merge_bases &&
+ (
+ cd multiple_merge_bases &&
+
+ test_commit initial content "1
+2
+3
+4
+5" &&
+
+ git branch L &&
+ git branch R &&
+
+ # Create L1
+ git checkout L &&
+ test_commit L1 content "0
+1
+2
+3
+4
+5" &&
+
+ # Create R1
+ git checkout R &&
+ test_commit R1 content "1
+2
+3
+4
+5
+6" &&
+
+ # Create L2
+ git checkout L &&
+ git merge R1 &&
+
+ # Create R2
+ git checkout R &&
+ git merge L1 &&
+
+ # Create L3
+ git checkout L &&
+ test_commit L3 content "0
+1
+2
+3
+4
+5
+A" &&
+
+ # Create R3
+ git checkout R &&
+ git rm content &&
+ test_commit R3 renamed "0
+2
+3
+4
+5
+six"
+ )
+'
+
+test_expect_success 'check multiple merge bases' '
+ (
+ cd multiple_merge_bases &&
+
+ git checkout L^0 &&
+
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R^0 &&
+
+ grep "|||||| merged common ancestors:content" renamed
+ )
+'
+
+test_expect_success 'rebase describes fake ancestor base' '
+ test_create_repo rebase &&
+ (
+ cd rebase &&
+ test_commit base file &&
+ test_commit master file &&
+ git checkout -b side HEAD^ &&
+ test_commit side file &&
+ test_must_fail git -c merge.conflictstyle=diff3 rebase master &&
+ grep "||||||| constructed merge base" file
+ )
+'
+
+test_done
diff --git a/t/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/t7009-filter-branch-null-sha1.sh b/t/t7008-filter-branch-null-sha1.sh
index 9ba9f24ad2..9ba9f24ad2 100755
--- a/t/t7009-filter-branch-null-sha1.sh
+++ b/t/t7008-filter-branch-null-sha1.sh
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index 9d1abe50ef..7476781979 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -134,6 +134,21 @@ test_expect_success 'git-clean, dirty case' '
test_i18ncmp expected result
'
+test_expect_success '--ignore-skip-worktree-entries leaves worktree alone' '
+ test_commit keep-me &&
+ git update-index --skip-worktree keep-me.t &&
+ rm keep-me.t &&
+
+ : ignoring the worktree &&
+ git update-index --remove --ignore-skip-worktree-entries keep-me.t &&
+ git diff-index --cached --exit-code HEAD &&
+
+ : not ignoring the worktree, a deletion is staged &&
+ git update-index --remove keep-me.t &&
+ test_must_fail git diff-index --cached --exit-code HEAD \
+ --diff-filter=D -- keep-me.t
+'
+
#TODO test_expect_failure 'git-apply adds file' false
#TODO test_expect_failure 'git-apply updates file' false
#TODO test_expect_failure 'git-apply removes file' false
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index d01fd120ab..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,7 +671,7 @@ test_expect_success 'git clean -d skips untracked dirs containing ignored files'
test_path_is_missing foo/b/bb
'
-test_expect_failure 'git clean -d skips nested repo containing ignored files' '
+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 &&
@@ -691,6 +693,38 @@ test_expect_failure 'git clean -d skips nested repo containing ignored files' '
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 &&
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/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/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/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/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/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 54f8ce18cb..e90ac565e1 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -1548,7 +1548,10 @@ test_expect_success 'complete tree filename with metacharacters' '
'
test_expect_success PERL 'send-email' '
- test_completion "git send-email --cov" "--cover-letter " &&
+ test_completion "git send-email --cov" <<-\EOF &&
+ --cover-from-description=Z
+ --cover-letter Z
+ EOF
test_completion "git send-email ma" "master "
'
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 87bf3a2287..b299ecc326 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -228,9 +228,11 @@ test_commit () {
# can be a tag pointing to the commit-to-merge.
test_merge () {
+ label="$1" &&
+ shift &&
test_tick &&
- git merge -m "$1" "$2" &&
- git tag "$1"
+ git merge -m "$label" "$@" &&
+ git tag "$label"
}
# Efficiently create <nr> commits, each with a unique number (from 1 to <nr>
diff --git a/t/test-lib.sh b/t/test-lib.sh
index ee602c4d9c..46c4440843 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -404,9 +404,13 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
unset XDG_CACHE_HOME
unset XDG_CONFIG_HOME
unset GITPERLLIB
-GIT_AUTHOR_EMAIL=author@example.com
+TEST_AUTHOR_LOCALNAME=author
+TEST_AUTHOR_DOMAIN=example.com
+GIT_AUTHOR_EMAIL=${TEST_AUTHOR_LOCALNAME}@${TEST_AUTHOR_DOMAIN}
GIT_AUTHOR_NAME='A U Thor'
-GIT_COMMITTER_EMAIL=committer@example.com
+TEST_COMMITTER_LOCALNAME=committer
+TEST_COMMITTER_DOMAIN=example.com
+GIT_COMMITTER_EMAIL=${TEST_COMMITTER_LOCALNAME}@${TEST_COMMITTER_DOMAIN}
GIT_COMMITTER_NAME='C O Mitter'
GIT_MERGE_VERBOSITY=5
GIT_MERGE_AUTOEDIT=no
@@ -572,6 +576,7 @@ export TERM
error () {
say_color error "error: $*"
+ finalize_junit_xml
GIT_EXIT_OK=t
exit 1
}
@@ -700,7 +705,7 @@ test_failure_ () {
say_color error "not ok $test_count - $1"
shift
printf '%s\n' "$*" | sed -e 's/^/# /'
- test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
+ test "$immediate" = "" || { finalize_junit_xml; GIT_EXIT_OK=t; exit 1; }
}
test_known_broken_ok_ () {
@@ -1068,6 +1073,25 @@ write_junit_xml_testcase () {
junit_have_testcase=t
}
+finalize_junit_xml () {
+ if test -n "$write_junit_xml" && test -n "$junit_xml_path"
+ then
+ test -n "$junit_have_testcase" || {
+ junit_start=$(test-tool date getnanos)
+ write_junit_xml_testcase "all tests skipped"
+ }
+
+ # adjust the overall time
+ junit_time=$(test-tool date getnanos $junit_suite_start)
+ sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ <"$junit_xml_path" >"$junit_xml_path.new"
+ mv "$junit_xml_path.new" "$junit_xml_path"
+
+ write_junit_xml " </testsuite>" "</testsuites>"
+ write_junit_xml=
+ fi
+}
+
test_atexit_cleanup=:
test_atexit_handler () {
# In a succeeding test script 'test_atexit_handler' is invoked
@@ -1090,21 +1114,7 @@ test_done () {
# removed, so the commands can access pidfiles and socket files.
test_atexit_handler
- if test -n "$write_junit_xml" && test -n "$junit_xml_path"
- then
- test -n "$junit_have_testcase" || {
- junit_start=$(test-tool date getnanos)
- write_junit_xml_testcase "all tests skipped"
- }
-
- # adjust the overall time
- junit_time=$(test-tool date getnanos $junit_suite_start)
- sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
- <"$junit_xml_path" >"$junit_xml_path.new"
- mv "$junit_xml_path.new" "$junit_xml_path"
-
- write_junit_xml " </testsuite>" "</testsuites>"
- fi
+ finalize_junit_xml
if test -z "$HARNESS_ACTIVE"
then