aboutsummaryrefslogtreecommitdiffstats
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README4
-rw-r--r--t/helper/test-bitmap.c8
-rw-r--r--t/helper/test-bloom.c8
-rw-r--r--t/helper/test-find-pack.c2
-rw-r--r--t/helper/test-pack-mtimes.c2
-rw-r--r--t/helper/test-parse-options.c17
-rw-r--r--t/helper/test-partial-clone.c4
-rw-r--r--t/helper/test-path-walk.c2
-rw-r--r--t/helper/test-read-graph.c8
-rw-r--r--t/helper/test-read-midx.c2
-rw-r--r--t/helper/test-ref-store.c4
-rw-r--r--t/helper/test-string-list.c96
-rw-r--r--t/meson.build8
-rwxr-xr-xt/perf/p1501-rev-parse-oneline.sh71
-rwxr-xr-xt/perf/p5313-pack-objects.sh37
-rwxr-xr-xt/t0000-basic.sh39
-rwxr-xr-xt/t0001-init.sh45
-rwxr-xr-xt/t0021-conversion.sh4
-rwxr-xr-xt/t0050-filesystem.sh30
-rwxr-xr-xt/t0063-string-list.sh142
-rwxr-xr-xt/t0411-clone-from-partial.sh6
-rw-r--r--t/t0450/adoc-help-mismatches1
-rwxr-xr-xt/t0602-reffiles-fsck.sh19
-rwxr-xr-xt/t0610-reftable-basics.sh6
-rwxr-xr-xt/t0612-reftable-jgit-compatibility.sh13
-rwxr-xr-xt/t0613-reftable-write-options.sh24
-rwxr-xr-xt/t1006-cat-file.sh111
-rwxr-xr-xt/t1007-hash-object.sh6
-rwxr-xr-xt/t1021-rerere-in-workdir.sh58
-rwxr-xr-xt/t1300-config.sh11
-rwxr-xr-xt/t1400-update-ref.sh74
-rwxr-xr-xt/t1410-reflog.sh28
-rwxr-xr-xt/t1416-ref-transaction-hooks.sh2
-rwxr-xr-xt/t1517-outside-repo.sh7
-rwxr-xr-xt/t2400-worktree-add.sh20
-rwxr-xr-xt/t3000-ls-files-others.sh19
-rwxr-xr-xt/t3418-rebase-continue.sh13
-rwxr-xr-xt/t3600-rm.sh5
-rwxr-xr-xt/t3903-stash.sh173
-rwxr-xr-xt/t4000-diff-format.sh2
-rwxr-xr-xt/t4013-diff-various.sh27
-rw-r--r--t/t4018/r-indent6
-rw-r--r--t/t4018/r-indent-nested10
-rw-r--r--t/t4018/r-noindent6
-rwxr-xr-xt/t4041-diff-submodule-option.sh22
-rwxr-xr-xt/t4042-diff-textconv-caching.sh12
-rwxr-xr-xt/t4053-diff-no-index.sh75
-rwxr-xr-xt/t4060-diff-submodule-option-diff-format.sh9
-rwxr-xr-xt/t4140-apply-ita.sh31
-rwxr-xr-xt/t4150-am.sh2
-rwxr-xr-xt/t4202-log.sh40
-rwxr-xr-xt/t4203-mailmap.sh33
-rwxr-xr-xt/t4216-log-bloom.sh23
-rwxr-xr-xt/t5004-archive-corner-cases.sh5
-rwxr-xr-xt/t5300-pack-object.sh25
-rwxr-xr-xt/t5306-pack-nobase.sh5
-rwxr-xr-xt/t5310-pack-bitmaps.sh43
-rwxr-xr-xt/t5316-pack-delta-depth.sh9
-rwxr-xr-xt/t5323-pack-redundant.sh5
-rwxr-xr-xt/t5331-pack-objects-stdin.sh122
-rwxr-xr-xt/t5332-multi-pack-reuse.sh7
-rwxr-xr-xt/t5333-pseudo-merge-bitmaps.sh21
-rwxr-xr-xt/t5408-send-pack-stdin.sh15
-rwxr-xr-xt/t5410-receive-pack.sh17
-rwxr-xr-xt/t5505-remote.sh14
-rwxr-xr-xt/t5516-fetch-push.sh27
-rwxr-xr-xt/t5520-pull.sh60
-rwxr-xr-xt/t5538-push-shallow.sh41
-rwxr-xr-xt/t5558-clone-bundle-uri.sh23
-rwxr-xr-xt/t6422-merge-rename-corner-cases.sh10
-rwxr-xr-xt/t6601-path-walk.sh20
-rwxr-xr-xt/t7007-show.sh24
-rwxr-xr-xt/t7401-submodule-summary.sh18
-rwxr-xr-xt/t7406-submodule-update.sh64
-rwxr-xr-xt/t7422-submodule-output.sh9
-rwxr-xr-xt/t7450-bad-git-dotfiles.sh33
-rwxr-xr-xt/t7528-signed-commit-ssh.sh32
-rwxr-xr-xt/t7600-merge.sh74
-rwxr-xr-xt/t7704-repack-cruft.sh145
-rwxr-xr-xt/t7815-grep-binary.sh2
-rwxr-xr-xt/t7900-maintenance.sh19
-rwxr-xr-xt/t9001-send-email.sh7
-rwxr-xr-xt/t9300-fast-import.sh12
-rwxr-xr-xt/t9301-fast-import-notes.sh2
-rwxr-xr-xt/t9350-fast-export.sh122
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh16
-rwxr-xr-xt/t9822-git-p4-path-encoding.sh13
-rwxr-xr-xt/t9835-git-p4-metadata-encoding-python2.sh24
-rwxr-xr-xt/t9836-git-p4-metadata-encoding-python3.sh24
-rwxr-xr-xt/t9903-bash-prompt.sh4
-rw-r--r--t/test-lib-functions.sh21
-rw-r--r--t/test-lib.sh33
-rw-r--r--t/unit-tests/u-prio-queue.c23
-rw-r--r--t/unit-tests/u-string-list.c227
94 files changed, 2165 insertions, 679 deletions
diff --git a/t/README b/t/README
index e9ffd9a81c..adbbd9acf4 100644
--- a/t/README
+++ b/t/README
@@ -415,6 +415,10 @@ GIT_TEST_PACK_SPARSE=<boolean> if disabled will default the pack-objects
builtin to use the non-sparse object walk. This can still be overridden by
the --sparse command-line argument.
+GIT_TEST_PACK_PATH_WALK=<boolean> if enabled will default the pack-objects
+builtin to use the path-walk API for the object walk. This can still be
+overridden by the --no-path-walk command-line argument.
+
GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
by overriding the minimum number of cache entries required per thread.
diff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c
index 3f23f21072..16a01669e4 100644
--- a/t/helper/test-bitmap.c
+++ b/t/helper/test-bitmap.c
@@ -10,6 +10,11 @@ static int bitmap_list_commits(void)
return test_bitmap_commits(the_repository);
}
+static int bitmap_list_commits_with_offset(void)
+{
+ return test_bitmap_commits_with_offset(the_repository);
+}
+
static int bitmap_dump_hashes(void)
{
return test_bitmap_hashes(the_repository);
@@ -36,6 +41,8 @@ int cmd__bitmap(int argc, const char **argv)
if (argc == 2 && !strcmp(argv[1], "list-commits"))
return bitmap_list_commits();
+ if (argc == 2 && !strcmp(argv[1], "list-commits-with-offset"))
+ return bitmap_list_commits_with_offset();
if (argc == 2 && !strcmp(argv[1], "dump-hashes"))
return bitmap_dump_hashes();
if (argc == 2 && !strcmp(argv[1], "dump-pseudo-merges"))
@@ -46,6 +53,7 @@ int cmd__bitmap(int argc, const char **argv)
return bitmap_dump_pseudo_merge_objects(atoi(argv[2]));
usage("\ttest-tool bitmap list-commits\n"
+ "\ttest-tool bitmap list-commits-with-offset\n"
"\ttest-tool bitmap dump-hashes\n"
"\ttest-tool bitmap dump-pseudo-merges\n"
"\ttest-tool bitmap dump-pseudo-merge-commits <n>\n"
diff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c
index 9aa2c5a592..3283544bd3 100644
--- a/t/helper/test-bloom.c
+++ b/t/helper/test-bloom.c
@@ -12,13 +12,13 @@ static struct bloom_filter_settings settings = DEFAULT_BLOOM_FILTER_SETTINGS;
static void add_string_to_filter(const char *data, struct bloom_filter *filter) {
struct bloom_key key;
- fill_bloom_key(data, strlen(data), &key, &settings);
+ bloom_key_fill(&key, data, strlen(data), &settings);
printf("Hashes:");
for (size_t i = 0; i < settings.num_hashes; i++)
printf("0x%08x|", key.hashes[i]);
printf("\n");
add_key_to_filter(&key, filter, &settings);
- clear_bloom_key(&key);
+ bloom_key_clear(&key);
}
static void print_bloom_filter(struct bloom_filter *filter) {
@@ -61,13 +61,13 @@ int cmd__bloom(int argc, const char **argv)
uint32_t hashed;
if (argc < 3)
usage(bloom_usage);
- hashed = murmur3_seeded_v2(0, argv[2], strlen(argv[2]));
+ hashed = test_bloom_murmur3_seeded(0, argv[2], strlen(argv[2]), 2);
printf("Murmur3 Hash with seed=0:0x%08x\n", hashed);
}
if (!strcmp(argv[1], "get_murmur3_seven_highbit")) {
uint32_t hashed;
- hashed = murmur3_seeded_v2(0, "\x99\xaa\xbb\xcc\xdd\xee\xff", 7);
+ hashed = test_bloom_murmur3_seeded(0, "\x99\xaa\xbb\xcc\xdd\xee\xff", 7, 2);
printf("Murmur3 Hash with seed=0:0x%08x\n", hashed);
}
diff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c
index 76c2f4eba8..611a13a326 100644
--- a/t/helper/test-find-pack.c
+++ b/t/helper/test-find-pack.c
@@ -2,7 +2,7 @@
#include "test-tool.h"
#include "object-name.h"
-#include "object-store.h"
+#include "odb.h"
#include "packfile.h"
#include "parse-options.h"
#include "setup.h"
diff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c
index fdf1b13437..d51aaa3dc4 100644
--- a/t/helper/test-pack-mtimes.c
+++ b/t/helper/test-pack-mtimes.c
@@ -3,7 +3,7 @@
#include "test-tool.h"
#include "hex.h"
#include "strbuf.h"
-#include "object-store.h"
+#include "odb.h"
#include "packfile.h"
#include "pack-mtimes.h"
#include "setup.h"
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index f2663dd0c0..68579d83f3 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -131,6 +131,7 @@ int cmd__parse_options(int argc, const char **argv)
.short_name = 'B',
.long_name = "no-fear",
.value = &boolean,
+ .precision = sizeof(boolean),
.help = "be brave",
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
.defval = 1,
@@ -148,9 +149,16 @@ int cmd__parse_options(int argc, const char **argv)
OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
OPT_CMDMODE(0, "mode1", &integer, "set integer to 1 (cmdmode option)", 1),
OPT_CMDMODE(0, "mode2", &integer, "set integer to 2 (cmdmode option)", 2),
- OPT_CALLBACK_F(0, "mode34", &integer, "(3|4)",
- "set integer to 3 or 4 (cmdmode option)",
- PARSE_OPT_CMDMODE, mode34_callback),
+ {
+ .type = OPTION_CALLBACK,
+ .long_name = "mode34",
+ .value = &integer,
+ .precision = sizeof(integer),
+ .argh = "(3|4)",
+ .help = "set integer to 3 or 4 (cmdmode option)",
+ .flags = PARSE_OPT_CMDMODE,
+ .callback = mode34_callback,
+ },
OPT_CALLBACK('L', "length", &integer, "str",
"get length of <str>", length_callback),
OPT_FILENAME('F', "file", &file, "set file to <file>"),
@@ -170,6 +178,7 @@ int cmd__parse_options(int argc, const char **argv)
.type = OPTION_COUNTUP,
.short_name = '+',
.value = &boolean,
+ .precision = sizeof(boolean),
.help = "same as -b",
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
},
@@ -177,6 +186,7 @@ int cmd__parse_options(int argc, const char **argv)
.type = OPTION_COUNTUP,
.long_name = "ambiguous",
.value = &ambiguous,
+ .precision = sizeof(ambiguous),
.help = "positive ambiguity",
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
},
@@ -184,6 +194,7 @@ int cmd__parse_options(int argc, const char **argv)
.type = OPTION_COUNTUP,
.long_name = "no-ambiguous",
.value = &ambiguous,
+ .precision = sizeof(ambiguous),
.help = "negative ambiguity",
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
},
diff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c
index 34f1aee558..d848800749 100644
--- a/t/helper/test-partial-clone.c
+++ b/t/helper/test-partial-clone.c
@@ -1,7 +1,7 @@
#include "test-tool.h"
#include "hex.h"
#include "repository.h"
-#include "object-store.h"
+#include "odb.h"
#include "setup.h"
/*
@@ -23,7 +23,7 @@ static void object_info(const char *gitdir, const char *oid_hex)
die("could not init repo");
if (parse_oid_hex_algop(oid_hex, &oid, &p, r.hash_algo))
die("could not parse oid");
- if (oid_object_info_extended(&r, &oid, &oi, 0))
+ if (odb_read_object_info_extended(r.objects, &oid, &oi, 0))
die("could not obtain object info");
printf("%d\n", (int) size);
diff --git a/t/helper/test-path-walk.c b/t/helper/test-path-walk.c
index 61e845e5ec..fe63002c2b 100644
--- a/t/helper/test-path-walk.c
+++ b/t/helper/test-path-walk.c
@@ -82,6 +82,8 @@ int cmd__path_walk(int argc, const char **argv)
N_("toggle inclusion of tree objects")),
OPT_BOOL(0, "prune", &info.prune_all_uninteresting,
N_("toggle pruning of uninteresting paths")),
+ OPT_BOOL(0, "edge-aggressive", &info.edge_aggressive,
+ N_("toggle aggressive edge walk")),
OPT_BOOL(0, "stdin-pl", &stdin_pl,
N_("read a pattern list over stdin")),
OPT_END(),
diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c
index 8b413b644b..ef5339bbee 100644
--- a/t/helper/test-read-graph.c
+++ b/t/helper/test-read-graph.c
@@ -3,7 +3,7 @@
#include "test-tool.h"
#include "commit-graph.h"
#include "repository.h"
-#include "object-store.h"
+#include "odb.h"
#include "bloom.h"
#include "setup.h"
@@ -73,15 +73,15 @@ static void dump_graph_bloom_filters(struct commit_graph *graph)
int cmd__read_graph(int argc, const char **argv)
{
struct commit_graph *graph = NULL;
- struct object_directory *odb;
+ struct odb_source *source;
int ret = 0;
setup_git_directory();
- odb = the_repository->objects->odb;
+ source = the_repository->objects->sources;
prepare_repo_settings(the_repository);
- graph = read_commit_graph_one(the_repository, odb);
+ graph = read_commit_graph_one(the_repository, source);
if (!graph) {
ret = 1;
goto done;
diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c
index ac81390899..da2aa036b5 100644
--- a/t/helper/test-read-midx.c
+++ b/t/helper/test-read-midx.c
@@ -4,7 +4,7 @@
#include "hex.h"
#include "midx.h"
#include "repository.h"
-#include "object-store.h"
+#include "odb.h"
#include "pack-bitmap.h"
#include "packfile.h"
#include "setup.h"
diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c
index 4cfc7c90b5..8d9a271845 100644
--- a/t/helper/test-ref-store.c
+++ b/t/helper/test-ref-store.c
@@ -5,7 +5,7 @@
#include "refs.h"
#include "setup.h"
#include "worktree.h"
-#include "object-store.h"
+#include "odb.h"
#include "path.h"
#include "repository.h"
#include "strbuf.h"
@@ -79,7 +79,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
if (!repo_submodule_path_append(the_repository,
&sb, gitdir, "objects/"))
die("computing submodule path failed");
- add_to_alternates_memory(sb.buf);
+ odb_add_to_alternates_memory(the_repository->objects, sb.buf);
strbuf_release(&sb);
*refs = repo_get_submodule_ref_store(the_repository, gitdir);
diff --git a/t/helper/test-string-list.c b/t/helper/test-string-list.c
index 6f10c5a435..6be0cdb8e2 100644
--- a/t/helper/test-string-list.c
+++ b/t/helper/test-string-list.c
@@ -1,105 +1,9 @@
-#define DISABLE_SIGN_COMPARE_WARNINGS
-
#include "test-tool.h"
#include "strbuf.h"
#include "string-list.h"
-/*
- * Parse an argument into a string list. arg should either be a
- * ':'-separated list of strings, or "-" to indicate an empty string
- * list (as opposed to "", which indicates a string list containing a
- * single empty string). list->strdup_strings must be set.
- */
-static void parse_string_list(struct string_list *list, const char *arg)
-{
- if (!strcmp(arg, "-"))
- return;
-
- (void)string_list_split(list, arg, ':', -1);
-}
-
-static void write_list(const struct string_list *list)
-{
- int i;
- for (i = 0; i < list->nr; i++)
- printf("[%d]: \"%s\"\n", i, list->items[i].string);
-}
-
-static void write_list_compact(const struct string_list *list)
-{
- int i;
- if (!list->nr)
- printf("-\n");
- else {
- printf("%s", list->items[0].string);
- for (i = 1; i < list->nr; i++)
- printf(":%s", list->items[i].string);
- printf("\n");
- }
-}
-
-static int prefix_cb(struct string_list_item *item, void *cb_data)
-{
- const char *prefix = (const char *)cb_data;
- return starts_with(item->string, prefix);
-}
-
int cmd__string_list(int argc, const char **argv)
{
- if (argc == 5 && !strcmp(argv[1], "split")) {
- struct string_list list = STRING_LIST_INIT_DUP;
- int i;
- const char *s = argv[2];
- int delim = *argv[3];
- int maxsplit = atoi(argv[4]);
-
- i = string_list_split(&list, s, delim, maxsplit);
- printf("%d\n", i);
- write_list(&list);
- string_list_clear(&list, 0);
- return 0;
- }
-
- if (argc == 5 && !strcmp(argv[1], "split_in_place")) {
- struct string_list list = STRING_LIST_INIT_NODUP;
- int i;
- char *s = xstrdup(argv[2]);
- const char *delim = argv[3];
- int maxsplit = atoi(argv[4]);
-
- i = string_list_split_in_place(&list, s, delim, maxsplit);
- printf("%d\n", i);
- write_list(&list);
- string_list_clear(&list, 0);
- free(s);
- return 0;
- }
-
- if (argc == 4 && !strcmp(argv[1], "filter")) {
- /*
- * Retain only the items that have the specified prefix.
- * Arguments: list|- prefix
- */
- struct string_list list = STRING_LIST_INIT_DUP;
- const char *prefix = argv[3];
-
- parse_string_list(&list, argv[2]);
- filter_string_list(&list, 0, prefix_cb, (void *)prefix);
- write_list_compact(&list);
- string_list_clear(&list, 0);
- return 0;
- }
-
- if (argc == 3 && !strcmp(argv[1], "remove_duplicates")) {
- struct string_list list = STRING_LIST_INIT_DUP;
-
- parse_string_list(&list, argv[2]);
- string_list_remove_duplicates(&list, 0);
- write_list_compact(&list);
- string_list_clear(&list, 0);
- return 0;
- }
-
if (argc == 2 && !strcmp(argv[1], "sort")) {
struct string_list list = STRING_LIST_INIT_NODUP;
struct strbuf sb = STRBUF_INIT;
diff --git a/t/meson.build b/t/meson.build
index be96a9639f..09f3068f98 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -19,6 +19,7 @@ clar_test_suites = [
'unit-tests/u-reftable-tree.c',
'unit-tests/u-strbuf.c',
'unit-tests/u-strcmp-offset.c',
+ 'unit-tests/u-string-list.c',
'unit-tests/u-strvec.c',
'unit-tests/u-trailer.c',
'unit-tests/u-urlmatch-normalization.c',
@@ -60,7 +61,7 @@ clar_unit_tests = executable('unit-tests',
sources: clar_sources + clar_test_suites,
dependencies: [libgit_commonmain],
)
-test('unit-tests', clar_unit_tests)
+test('unit-tests', clar_unit_tests, kwargs: test_kwargs)
subdir('helper')
@@ -105,7 +106,6 @@ integration_tests = [
't0060-path-utils.sh',
't0061-run-command.sh',
't0062-revision-walking.sh',
- 't0063-string-list.sh',
't0066-dir-iterator.sh',
't0067-parse_pathspec_file.sh',
't0068-for-each-repo.sh',
@@ -160,7 +160,6 @@ integration_tests = [
't1015-read-index-unmerged.sh',
't1016-compatObjectFormat.sh',
't1020-subdirectory.sh',
- 't1021-rerere-in-workdir.sh',
't1022-read-tree-partial-clone.sh',
't1050-large.sh',
't1051-large-conversion.sh',
@@ -1099,6 +1098,7 @@ benchmarks = [
'perf/p1450-fsck.sh',
'perf/p1451-fsck-skip-list.sh',
'perf/p1500-graph-walks.sh',
+ 'perf/p1501-rev-parse-oneline.sh',
'perf/p2000-sparse-operations.sh',
'perf/p3400-rebase.sh',
'perf/p3404-rebase-interactive.sh',
@@ -1192,7 +1192,7 @@ foreach integration_test : integration_tests
workdir: meson.current_source_dir(),
env: test_environment,
depends: test_dependencies + bin_wrappers,
- timeout: 0,
+ kwargs: test_kwargs,
)
endforeach
diff --git a/t/perf/p1501-rev-parse-oneline.sh b/t/perf/p1501-rev-parse-oneline.sh
new file mode 100755
index 0000000000..538fa9c404
--- /dev/null
+++ b/t/perf/p1501-rev-parse-oneline.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='Test :/ object name notation'
+
+. ./perf-lib.sh
+
+test_perf_fresh_repo
+
+#
+# Creates lots of merges to make history traversal costly. In
+# particular it creates 2^($max_level-1)-1 2-way merges on top of
+# 2^($max_level-1) root commits. E.g., the commit history looks like
+# this for a $max_level of 3:
+#
+# _1_
+# / \
+# 2 3
+# / \ / \
+# 4 5 6 7
+#
+# The numbers are the fast-import marks, which also are the commit
+# messages. 1 is the HEAD commit and a merge, 2 and 3 are also merges,
+# 4-7 are the root commits.
+#
+build_history () {
+ local max_level="$1" &&
+ local level="${2:-1}" &&
+ local mark="${3:-1}" &&
+ if test $level -eq $max_level
+ then
+ echo "reset refs/heads/master" &&
+ echo "from $ZERO_OID" &&
+ echo "commit refs/heads/master" &&
+ echo "mark :$mark" &&
+ echo "committer C <c@example.com> 1234567890 +0000" &&
+ echo "data <<EOF" &&
+ echo "$mark" &&
+ echo "EOF"
+ else
+ local level1=$((level+1)) &&
+ local mark1=$((2*mark)) &&
+ local mark2=$((2*mark+1)) &&
+ build_history $max_level $level1 $mark1 &&
+ build_history $max_level $level1 $mark2 &&
+ echo "commit refs/heads/master" &&
+ echo "mark :$mark" &&
+ echo "committer C <c@example.com> 1234567890 +0000" &&
+ echo "data <<EOF" &&
+ echo "$mark" &&
+ echo "EOF" &&
+ echo "from :$mark1" &&
+ echo "merge :$mark2"
+ fi
+}
+
+test_expect_success 'setup' '
+ build_history 16 | git fast-import &&
+ git log --format="%H %s" --reverse >commits &&
+ sed -n -e "s/ .*$//p" -e "q" <commits >expect &&
+ sed -n -e "s/^.* //p" -e "q" <commits >needle
+'
+
+test_perf "rev-parse :/$(cat needle)" '
+ git rev-parse :/$(cat needle) >actual
+'
+
+test_expect_success 'verify result' '
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/perf/p5313-pack-objects.sh b/t/perf/p5313-pack-objects.sh
index 786a2c1c6f..46a6cd32d2 100755
--- a/t/perf/p5313-pack-objects.sh
+++ b/t/perf/p5313-pack-objects.sh
@@ -22,46 +22,53 @@ test_expect_success 'create rev input' '
EOF
'
-for version in 1 2
-do
- export version
+test_all_with_args () {
+ parameter=$1
+ export parameter
- test_perf "thin pack with version $version" '
+ test_perf "thin pack with $parameter" '
git pack-objects --thin --stdout --revs --sparse \
- --name-hash-version=$version <in-thin >out
+ $parameter <in-thin >out
'
- test_size "thin pack size with version $version" '
+ test_size "thin pack size with $parameter" '
test_file_size out
'
- test_perf "big pack with version $version" '
+ test_perf "big pack with $parameter" '
git pack-objects --stdout --revs --sparse \
- --name-hash-version=$version <in-big >out
+ $parameter <in-big >out
'
- test_size "big pack size with version $version" '
+ test_size "big pack size with $parameter" '
test_file_size out
'
- test_perf "shallow fetch pack with version $version" '
+ test_perf "shallow fetch pack with $parameter" '
git pack-objects --stdout --revs --sparse --shallow \
- --name-hash-version=$version <in-shallow >out
+ $parameter <in-shallow >out
'
- test_size "shallow pack size with version $version" '
+ test_size "shallow pack size with $parameter" '
test_file_size out
'
- test_perf "repack with version $version" '
- git repack -adf --name-hash-version=$version
+ test_perf "repack with $parameter" '
+ git repack -adf $parameter
'
- test_size "repack size with version $version" '
+ test_size "repack size with $parameter" '
gitdir=$(git rev-parse --git-dir) &&
pack=$(ls $gitdir/objects/pack/pack-*.pack) &&
test_file_size "$pack"
'
+}
+
+for version in 1 2
+do
+ test_all_with_args --name-hash-version=$version
done
+test_all_with_args --path-walk
+
test_done
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 35c5c2b4f9..2b63e1c86c 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -130,7 +130,7 @@ test_expect_success 'subtest: a failing TODO test' '
'
test_expect_success 'subtest: a passing TODO test' '
- write_and_run_sub_test_lib_test passing-todo <<-\EOF &&
+ write_and_run_sub_test_lib_test_err passing-todo <<-\EOF &&
test_expect_failure "pretend we have fixed a known breakage" "true"
test_done
EOF
@@ -142,7 +142,7 @@ test_expect_success 'subtest: a passing TODO test' '
'
test_expect_success 'subtest: 2 TODO tests, one passin' '
- write_and_run_sub_test_lib_test partially-passing-todos <<-\EOF &&
+ write_and_run_sub_test_lib_test_err partially-passing-todos <<-\EOF &&
test_expect_failure "pretend we have a known breakage" "false"
test_expect_success "pretend we have a passing test" "true"
test_expect_failure "pretend we have fixed another known breakage" "true"
@@ -219,41 +219,44 @@ test_expect_success 'subtest: --verbose option' '
test_expect_success "failing test" false
test_done
EOF
- mv t1234-verbose/out t1234-verbose/out+ &&
- grep -v "^Initialized empty" t1234-verbose/out+ >t1234-verbose/out &&
- check_sub_test_lib_test t1234-verbose <<-\EOF
- > expecting success of 1234.1 '\''passing test'\'': true
+ mv t1234-verbose/err t1234-verbose/err+ &&
+ grep -v "^Initialized empty" t1234-verbose/err+ >t1234-verbose/err &&
+ check_sub_test_lib_test_err t1234-verbose \
+ <<-\EOF_OUT 3<<-\EOF_ERR
> ok 1 - passing test
+ > ok 2 - test with output
+ > not ok 3 - failing test
+ > # false
+ > # failed 1 among 3 test(s)
+ > 1..3
+ EOF_OUT
+ > expecting success of 1234.1 '\''passing test'\'': true
> Z
> expecting success of 1234.2 '\''test with output'\'': echo foo
> foo
- > ok 2 - test with output
> Z
> expecting success of 1234.3 '\''failing test'\'': false
- > not ok 3 - failing test
- > # false
> Z
- > # failed 1 among 3 test(s)
- > 1..3
- EOF
+ EOF_ERR
'
test_expect_success 'subtest: --verbose-only option' '
run_sub_test_lib_test_err \
t1234-verbose \
--verbose-only=2 &&
- check_sub_test_lib_test t1234-verbose <<-\EOF
+ check_sub_test_lib_test_err t1234-verbose <<-\EOF_OUT 3<<-\EOF_ERR
> ok 1 - passing test
- > Z
- > expecting success of 1234.2 '\''test with output'\'': echo foo
- > foo
> ok 2 - test with output
- > Z
> not ok 3 - failing test
> # false
> # failed 1 among 3 test(s)
> 1..3
- EOF
+ EOF_OUT
+ > Z
+ > expecting success of 1234.2 '\''test with output'\'': echo foo
+ > foo
+ > Z
+ EOF_ERR
'
test_expect_success 'subtest: skip one with GIT_SKIP_TESTS' '
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index f11a40811f..f593c53687 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -658,6 +658,17 @@ test_expect_success 'init warns about invalid init.defaultRefFormat' '
test_cmp expected actual
'
+test_expect_success 'default ref format' '
+ test_when_finished "rm -rf refformat" &&
+ (
+ sane_unset GIT_DEFAULT_REF_FORMAT &&
+ git init refformat
+ ) &&
+ git version --build-options | sed -ne "s/^default-ref-format: //p" >expect &&
+ git -C refformat rev-parse --show-ref-format >actual &&
+ test_cmp expect actual
+'
+
backends="files reftable"
for format in $backends
do
@@ -738,6 +749,40 @@ test_expect_success "GIT_DEFAULT_REF_FORMAT= overrides init.defaultRefFormat" '
test_cmp expect actual
'
+test_expect_success "init with feature.experimental=true" '
+ test_when_finished "rm -rf refformat" &&
+ test_config_global feature.experimental true &&
+ (
+ sane_unset GIT_DEFAULT_REF_FORMAT &&
+ git init refformat
+ ) &&
+ echo reftable >expect &&
+ git -C refformat rev-parse --show-ref-format >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success "init.defaultRefFormat overrides feature.experimental=true" '
+ test_when_finished "rm -rf refformat" &&
+ test_config_global feature.experimental true &&
+ test_config_global init.defaultRefFormat files &&
+ (
+ sane_unset GIT_DEFAULT_REF_FORMAT &&
+ git init refformat
+ ) &&
+ echo files >expect &&
+ git -C refformat rev-parse --show-ref-format >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success "GIT_DEFAULT_REF_FORMAT= overrides feature.experimental=true" '
+ test_when_finished "rm -rf refformat" &&
+ test_config_global feature.experimental true &&
+ GIT_DEFAULT_REF_FORMAT=files git init refformat &&
+ echo files >expect &&
+ git -C refformat rev-parse --show-ref-format >actual &&
+ test_cmp expect actual
+'
+
for from_format in $backends
do
test_expect_success "re-init with same format ($from_format)" '
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index bf10d253ec..f0d50d769e 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -281,7 +281,7 @@ test_expect_success 'required filter with absent smudge field' '
test_expect_success 'filtering large input to small output should use little memory' '
test_config filter.devnull.clean "cat >/dev/null" &&
test_config filter.devnull.required true &&
- for i in $(test_seq 1 30); do printf "%1048576d" 1 || return 1; done >30MB &&
+ test_seq -f "%1048576d" 1 30 >30MB &&
echo "30MB filter=devnull" >.gitattributes &&
GIT_MMAP_LIMIT=1m GIT_ALLOC_LIMIT=1m git add 30MB
'
@@ -299,7 +299,7 @@ test_expect_success 'filter that does not read is fine' '
test_expect_success EXPENSIVE 'filter large file' '
test_config filter.largefile.smudge cat &&
test_config filter.largefile.clean cat &&
- for i in $(test_seq 1 2048); do printf "%1048576d" 1 || return 1; done >2GB &&
+ test_seq -f "%1048576d" 1 2048 >2GB &&
echo "2GB filter=largefile" >.gitattributes &&
git add 2GB 2>err &&
test_must_be_empty err &&
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 5c9dc90d0b..ca8568067d 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -10,53 +10,35 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
auml=$(printf '\303\244')
aumlcdiar=$(printf '\141\314\210')
-if test_have_prereq CASE_INSENSITIVE_FS
-then
- say "will test on a case insensitive filesystem"
- test_case=test_expect_failure
-else
- test_case=test_expect_success
-fi
-
if test_have_prereq UTF8_NFD_TO_NFC
then
- say "will test on a unicode corrupting filesystem"
test_unicode=test_expect_failure
else
test_unicode=test_expect_success
fi
-test_have_prereq SYMLINKS ||
- say "will test on a filesystem lacking symbolic links"
-
-if test_have_prereq CASE_INSENSITIVE_FS
-then
-test_expect_success "detection of case insensitive filesystem during repo init" '
+test_expect_success CASE_INSENSITIVE_FS "detection of case insensitive filesystem during repo init" '
test $(git config --bool core.ignorecase) = true
'
-else
-test_expect_success "detection of case insensitive filesystem during repo init" '
+
+test_expect_success !CASE_INSENSITIVE_FS "detection of case insensitive filesystem during repo init" '
{
test_must_fail git config --bool core.ignorecase >/dev/null ||
test $(git config --bool core.ignorecase) = false
}
'
-fi
-if test_have_prereq SYMLINKS
-then
-test_expect_success "detection of filesystem w/o symlink support during repo init" '
+test_expect_success SYMLINKS "detection of filesystem w/o symlink support during repo init" '
{
test_must_fail git config --bool core.symlinks ||
test "$(git config --bool core.symlinks)" = true
}
'
-else
-test_expect_success "detection of filesystem w/o symlink support during repo init" '
+
+test_expect_success !SYMLINKS "detection of filesystem w/o symlink support during repo init" '
v=$(git config --bool core.symlinks) &&
test "$v" = false
'
-fi
test_expect_success "setup case tests" '
git config core.ignorecase true &&
diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh
deleted file mode 100755
index aac63ba506..0000000000
--- a/t/t0063-string-list.sh
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2012 Michael Haggerty
-#
-
-test_description='Test string list functionality'
-
-. ./test-lib.sh
-
-test_split () {
- cat >expected &&
- test_expect_success "split $1 at $2, max $3" "
- test-tool string-list split '$1' '$2' '$3' >actual &&
- test_cmp expected actual &&
- test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
- test_cmp expected actual
- "
-}
-
-test_split_in_place() {
- cat >expected &&
- test_expect_success "split (in place) $1 at $2, max $3" "
- test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
- test_cmp expected actual
- "
-}
-
-test_split "foo:bar:baz" ":" "-1" <<EOF
-3
-[0]: "foo"
-[1]: "bar"
-[2]: "baz"
-EOF
-
-test_split "foo:bar:baz" ":" "0" <<EOF
-1
-[0]: "foo:bar:baz"
-EOF
-
-test_split "foo:bar:baz" ":" "1" <<EOF
-2
-[0]: "foo"
-[1]: "bar:baz"
-EOF
-
-test_split "foo:bar:baz" ":" "2" <<EOF
-3
-[0]: "foo"
-[1]: "bar"
-[2]: "baz"
-EOF
-
-test_split "foo:bar:" ":" "-1" <<EOF
-3
-[0]: "foo"
-[1]: "bar"
-[2]: ""
-EOF
-
-test_split "" ":" "-1" <<EOF
-1
-[0]: ""
-EOF
-
-test_split ":" ":" "-1" <<EOF
-2
-[0]: ""
-[1]: ""
-EOF
-
-test_split_in_place "foo:;:bar:;:baz:;:" ":;" "-1" <<EOF
-10
-[0]: "foo"
-[1]: ""
-[2]: ""
-[3]: "bar"
-[4]: ""
-[5]: ""
-[6]: "baz"
-[7]: ""
-[8]: ""
-[9]: ""
-EOF
-
-test_split_in_place "foo:;:bar:;:baz" ":;" "0" <<EOF
-1
-[0]: "foo:;:bar:;:baz"
-EOF
-
-test_split_in_place "foo:;:bar:;:baz" ":;" "1" <<EOF
-2
-[0]: "foo"
-[1]: ";:bar:;:baz"
-EOF
-
-test_split_in_place "foo:;:bar:;:baz" ":;" "2" <<EOF
-3
-[0]: "foo"
-[1]: ""
-[2]: ":bar:;:baz"
-EOF
-
-test_split_in_place "foo:;:bar:;:" ":;" "-1" <<EOF
-7
-[0]: "foo"
-[1]: ""
-[2]: ""
-[3]: "bar"
-[4]: ""
-[5]: ""
-[6]: ""
-EOF
-
-test_expect_success "test filter_string_list" '
- test "x-" = "x$(test-tool string-list filter - y)" &&
- test "x-" = "x$(test-tool string-list filter no y)" &&
- test yes = "$(test-tool string-list filter yes y)" &&
- test yes = "$(test-tool string-list filter no:yes y)" &&
- test yes = "$(test-tool string-list filter yes:no y)" &&
- test y1:y2 = "$(test-tool string-list filter y1:y2 y)" &&
- test y2:y1 = "$(test-tool string-list filter y2:y1 y)" &&
- test "x-" = "x$(test-tool string-list filter x1:x2 y)"
-'
-
-test_expect_success "test remove_duplicates" '
- test "x-" = "x$(test-tool string-list remove_duplicates -)" &&
- test "x" = "x$(test-tool string-list remove_duplicates "")" &&
- test a = "$(test-tool string-list remove_duplicates a)" &&
- test a = "$(test-tool string-list remove_duplicates a:a)" &&
- test a = "$(test-tool string-list remove_duplicates a:a:a:a:a)" &&
- test a:b = "$(test-tool string-list remove_duplicates a:b)" &&
- test a:b = "$(test-tool string-list remove_duplicates a:a:b)" &&
- test a:b = "$(test-tool string-list remove_duplicates a:b:b)" &&
- test a:b:c = "$(test-tool string-list remove_duplicates a:b:c)" &&
- test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:c)" &&
- test a:b:c = "$(test-tool string-list remove_duplicates a:b:b:c)" &&
- test a:b:c = "$(test-tool string-list remove_duplicates a:b:c:c)" &&
- test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:b:c:c)" &&
- test a:b:c = "$(test-tool string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
-'
-
-test_done
diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh
index 196fc61784..9e6bca5625 100755
--- a/t/t0411-clone-from-partial.sh
+++ b/t/t0411-clone-from-partial.sh
@@ -59,6 +59,12 @@ test_expect_success 'pack-objects should fetch from promisor remote and execute
test_expect_success 'clone from promisor remote does not lazy-fetch by default' '
rm -f script-executed &&
+
+ # The --path-walk feature of "git pack-objects" is not
+ # compatible with this kind of fetch from an incomplete repo.
+ GIT_TEST_PACK_PATH_WALK=0 &&
+ export GIT_TEST_PACK_PATH_WALK &&
+
test_must_fail git clone evil no-lazy 2>err &&
test_grep "lazy fetching disabled" err &&
test_path_is_missing script-executed
diff --git a/t/t0450/adoc-help-mismatches b/t/t0450/adoc-help-mismatches
index c4a15fd0cb..06b469bdee 100644
--- a/t/t0450/adoc-help-mismatches
+++ b/t/t0450/adoc-help-mismatches
@@ -38,7 +38,6 @@ merge-one-file
multi-pack-index
name-rev
notes
-pack-objects
push
range-diff
rebase
diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh
index f671ac4d3a..0ef483659d 100755
--- a/t/t0602-reffiles-fsck.sh
+++ b/t/t0602-reffiles-fsck.sh
@@ -110,6 +110,25 @@ test_expect_success 'ref name check should be adapted into fsck messages' '
)
'
+test_expect_success 'no refs directory of worktree should not cause problems' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
+ (
+ cd repo &&
+ test_commit initial &&
+ git worktree add --detach ./worktree &&
+
+ (
+ cd worktree &&
+ worktree_refdir="$(git rev-parse --git-dir)/refs" &&
+ # Simulate old directory layout
+ rmdir "$worktree_refdir" &&
+ git refs verify 2>err &&
+ test_must_be_empty err
+ )
+ )
+'
+
test_expect_success 'ref name check should work for multiple worktrees' '
test_when_finished "rm -rf repo" &&
git init repo &&
diff --git a/t/t0610-reftable-basics.sh b/t/t0610-reftable-basics.sh
index 1be534a895..3ea5d51532 100755
--- a/t/t0610-reftable-basics.sh
+++ b/t/t0610-reftable-basics.sh
@@ -477,11 +477,7 @@ test_expect_success !CYGWIN 'ref transaction: many concurrent writers' '
test_commit --no-tag initial &&
head=$(git rev-parse HEAD) &&
- for i in $(test_seq 100)
- do
- printf "%s commit\trefs/heads/branch-%s\n" "$head" "$i" ||
- return 1
- done >expect &&
+ test_seq -f "$head commit\trefs/heads/branch-%d" 100 >expect &&
printf "%s commit\trefs/heads/main\n" "$head" >>expect &&
for i in $(test_seq 100)
diff --git a/t/t0612-reftable-jgit-compatibility.sh b/t/t0612-reftable-jgit-compatibility.sh
index d0d7e80b49..7df2ad5817 100755
--- a/t/t0612-reftable-jgit-compatibility.sh
+++ b/t/t0612-reftable-jgit-compatibility.sh
@@ -112,14 +112,11 @@ test_expect_success 'JGit can read multi-level index' '
cd repo &&
test_commit A &&
- awk "
- BEGIN {
- print \"start\";
- for (i = 0; i < 10000; i++)
- printf \"create refs/heads/branch-%d HEAD\n\", i;
- print \"commit\";
- }
- " >input &&
+ {
+ echo start &&
+ test_seq -f "create refs/heads/branch-%d HEAD" 10000 &&
+ echo commit
+ } >input &&
git update-ref --stdin <input &&
test_same_refs &&
diff --git a/t/t0613-reftable-write-options.sh b/t/t0613-reftable-write-options.sh
index 6447920c9b..d77e601111 100755
--- a/t/t0613-reftable-write-options.sh
+++ b/t/t0613-reftable-write-options.sh
@@ -66,11 +66,7 @@ test_expect_success 'many refs results in multiple blocks' '
(
cd repo &&
test_commit initial &&
- for i in $(test_seq 200)
- do
- printf "update refs/heads/branch-%d HEAD\n" "$i" ||
- return 1
- done >input &&
+ test_seq -f "update refs/heads/branch-%d HEAD" 200 >input &&
git update-ref --stdin <input &&
git pack-refs &&
@@ -180,11 +176,7 @@ test_expect_success 'restart interval at every single record' '
(
cd repo &&
test_commit initial &&
- for i in $(test_seq 10)
- do
- printf "update refs/heads/branch-%d HEAD\n" "$i" ||
- return 1
- done >input &&
+ test_seq -f "update refs/heads/branch-%d HEAD" 10 >input &&
git update-ref --stdin <input &&
git -c reftable.restartInterval=1 pack-refs &&
@@ -224,11 +216,7 @@ test_expect_success 'object index gets written by default with ref index' '
(
cd repo &&
test_commit initial &&
- for i in $(test_seq 5)
- do
- printf "update refs/heads/branch-%d HEAD\n" "$i" ||
- return 1
- done >input &&
+ test_seq -f "update refs/heads/branch-%d HEAD" 5 >input &&
git update-ref --stdin <input &&
git -c reftable.blockSize=100 pack-refs &&
@@ -263,11 +251,7 @@ test_expect_success 'object index can be disabled' '
(
cd repo &&
test_commit initial &&
- for i in $(test_seq 5)
- do
- printf "update refs/heads/branch-%d HEAD\n" "$i" ||
- return 1
- done >input &&
+ test_seq -f "update refs/heads/branch-%d HEAD" 5 >input &&
git update-ref --stdin <input &&
git -c reftable.blockSize=100 -c reftable.indexObjects=false pack-refs &&
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 317da6869c..1f61b666a7 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -113,53 +113,55 @@ strlen () {
run_tests () {
type=$1
- oid=$2
- size=$3
- content=$4
- pretty_content=$5
+ object_name="$2"
+ mode=$3
+ size=$4
+ content=$5
+ pretty_content=$6
+ oid=${7:-"$object_name"}
batch_output="$oid $type $size
$content"
test_expect_success "$type exists" '
- git cat-file -e $oid
+ git cat-file -e "$object_name"
'
test_expect_success "Type of $type is correct" '
echo $type >expect &&
- git cat-file -t $oid >actual &&
+ git cat-file -t "$object_name" >actual &&
test_cmp expect actual
'
test_expect_success "Size of $type is correct" '
echo $size >expect &&
- git cat-file -s $oid >actual &&
+ git cat-file -s "$object_name" >actual &&
test_cmp expect actual
'
test -z "$content" ||
test_expect_success "Content of $type is correct" '
echo_without_newline "$content" >expect &&
- git cat-file $type $oid >actual &&
+ git cat-file $type "$object_name" >actual &&
test_cmp expect actual
'
test_expect_success "Pretty content of $type is correct" '
echo_without_newline "$pretty_content" >expect &&
- git cat-file -p $oid >actual &&
+ git cat-file -p "$object_name" >actual &&
test_cmp expect actual
'
test -z "$content" ||
test_expect_success "--batch output of $type is correct" '
echo "$batch_output" >expect &&
- echo $oid | git cat-file --batch >actual &&
+ echo "$object_name" | git cat-file --batch >actual &&
test_cmp expect actual
'
test_expect_success "--batch-check output of $type is correct" '
echo "$oid $type $size" >expect &&
- echo_without_newline $oid | git cat-file --batch-check >actual &&
+ echo_without_newline "$object_name" | git cat-file --batch-check >actual &&
test_cmp expect actual
'
@@ -168,13 +170,13 @@ $content"
test -z "$content" ||
test_expect_success "--batch-command $opt output of $type content is correct" '
echo "$batch_output" >expect &&
- test_write_lines "contents $oid" | git cat-file --batch-command $opt >actual &&
+ test_write_lines "contents $object_name" | git cat-file --batch-command $opt >actual &&
test_cmp expect actual
'
test_expect_success "--batch-command $opt output of $type info is correct" '
echo "$oid $type $size" >expect &&
- test_write_lines "info $oid" |
+ test_write_lines "info $object_name" |
git cat-file --batch-command $opt >actual &&
test_cmp expect actual
'
@@ -182,30 +184,45 @@ $content"
test_expect_success "custom --batch-check format" '
echo "$type $oid" >expect &&
- echo $oid | git cat-file --batch-check="%(objecttype) %(objectname)" >actual &&
+ echo "$object_name" | git cat-file --batch-check="%(objecttype) %(objectname)" >actual &&
test_cmp expect actual
'
test_expect_success "custom --batch-command format" '
echo "$type $oid" >expect &&
- echo "info $oid" | git cat-file --batch-command="%(objecttype) %(objectname)" >actual &&
+ echo "info $object_name" | git cat-file --batch-command="%(objecttype) %(objectname)" >actual &&
test_cmp expect actual
'
- test_expect_success '--batch-check with %(rest)' '
+ # FIXME: %(rest) is incompatible with object names that include whitespace,
+ # e.g. HEAD:path/to/a/file with spaces. Use the resolved OID as input to
+ # test this instead of the raw object name.
+ if echo "$object_name" | grep -q " "; then
+ test_rest=test_expect_failure
+ else
+ test_rest=test_expect_success
+ fi
+
+ $test_rest '--batch-check with %(rest)' '
echo "$type this is some extra content" >expect &&
- echo "$oid this is some extra content" |
+ echo "$object_name this is some extra content" |
git cat-file --batch-check="%(objecttype) %(rest)" >actual &&
test_cmp expect actual
'
+ test_expect_success '--batch-check with %(objectmode)' '
+ echo "$mode $oid" >expect &&
+ echo $object_name | git cat-file --batch-check="%(objectmode) %(objectname)" >actual &&
+ test_cmp expect actual
+ '
+
test -z "$content" ||
test_expect_success "--batch without type ($type)" '
{
echo "$size" &&
echo "$content"
} >expect &&
- echo $oid | git cat-file --batch="%(objectsize)" >actual &&
+ echo "$object_name" | git cat-file --batch="%(objectsize)" >actual &&
test_cmp expect actual
'
@@ -215,7 +232,7 @@ $content"
echo "$type" &&
echo "$content"
} >expect &&
- echo $oid | git cat-file --batch="%(objecttype)" >actual &&
+ echo "$object_name" | git cat-file --batch="%(objecttype)" >actual &&
test_cmp expect actual
'
}
@@ -230,13 +247,14 @@ test_expect_success "setup" '
git config extensions.compatobjectformat $test_compat_hash_algo &&
echo_without_newline "$hello_content" > hello &&
git update-index --add hello &&
+ echo_without_newline "$hello_content" > "path with spaces" &&
+ git update-index --add --chmod=+x "path with spaces" &&
git commit -m "add hello file"
'
run_blob_tests () {
oid=$1
-
- run_tests 'blob' $oid $hello_size "$hello_content" "$hello_content"
+ run_tests 'blob' $oid "" $hello_size "$hello_content" "$hello_content"
test_expect_success '--batch-command --buffer with flush for blob info' '
echo "$oid blob $hello_size" >expect &&
@@ -269,13 +287,17 @@ test_expect_success '--batch-check without %(rest) considers whole line' '
tree_oid=$(git write-tree)
tree_compat_oid=$(git rev-parse --output-object-format=$test_compat_hash_algo $tree_oid)
-tree_size=$(($(test_oid rawsz) + 13))
-tree_compat_size=$(($(test_oid --hash=compat rawsz) + 13))
-tree_pretty_content="100644 blob $hello_oid hello${LF}"
-tree_compat_pretty_content="100644 blob $hello_compat_oid hello${LF}"
-
-run_tests 'tree' $tree_oid $tree_size "" "$tree_pretty_content"
-run_tests 'tree' $tree_compat_oid $tree_compat_size "" "$tree_compat_pretty_content"
+tree_size=$((2 * $(test_oid rawsz) + 13 + 24))
+tree_compat_size=$((2 * $(test_oid --hash=compat rawsz) + 13 + 24))
+tree_pretty_content="100644 blob $hello_oid hello${LF}100755 blob $hello_oid path with spaces${LF}"
+tree_compat_pretty_content="100644 blob $hello_compat_oid hello${LF}100755 blob $hello_compat_oid path with spaces${LF}"
+
+run_tests 'tree' $tree_oid "" $tree_size "" "$tree_pretty_content"
+run_tests 'tree' $tree_compat_oid "" $tree_compat_size "" "$tree_compat_pretty_content"
+run_tests 'blob' "$tree_oid:hello" "100644" $hello_size "" "$hello_content" $hello_oid
+run_tests 'blob' "$tree_compat_oid:hello" "100644" $hello_size "" "$hello_content" $hello_compat_oid
+run_tests 'blob' "$tree_oid:path with spaces" "100755" $hello_size "" "$hello_content" $hello_oid
+run_tests 'blob' "$tree_compat_oid:path with spaces" "100755" $hello_size "" "$hello_content" $hello_compat_oid
commit_message="Initial commit"
commit_oid=$(echo_without_newline "$commit_message" | git commit-tree $tree_oid)
@@ -294,8 +316,8 @@ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
$commit_message"
-run_tests 'commit' $commit_oid $commit_size "$commit_content" "$commit_content"
-run_tests 'commit' $commit_compat_oid $commit_compat_size "$commit_compat_content" "$commit_compat_content"
+run_tests 'commit' $commit_oid "" $commit_size "$commit_content" "$commit_content"
+run_tests 'commit' $commit_compat_oid "" $commit_compat_size "$commit_compat_content" "$commit_compat_content"
tag_header_without_oid="type blob
tag hellotag
@@ -318,8 +340,8 @@ tag_size=$(strlen "$tag_content")
tag_compat_oid=$(git rev-parse --output-object-format=$test_compat_hash_algo $tag_oid)
tag_compat_size=$(strlen "$tag_compat_content")
-run_tests 'tag' $tag_oid $tag_size "$tag_content" "$tag_content"
-run_tests 'tag' $tag_compat_oid $tag_compat_size "$tag_compat_content" "$tag_compat_content"
+run_tests 'tag' $tag_oid "" $tag_size "$tag_content" "$tag_content"
+run_tests 'tag' $tag_compat_oid "" $tag_compat_size "$tag_compat_content" "$tag_compat_content"
test_expect_success "Reach a blob from a tag pointing to it" '
echo_without_newline "$hello_content" >expect &&
@@ -1198,6 +1220,31 @@ test_expect_success 'cat-file --batch-check respects replace objects' '
test_cmp expect actual
'
+test_expect_success 'batch-check with a submodule' '
+ # FIXME: this call to mktree is incompatible with compatObjectFormat
+ # because the submodule OID cannot be mapped to the compat hash algo.
+ test_unconfig extensions.compatobjectformat &&
+ printf "160000 commit $(test_oid deadbeef)\tsub\n" >tree-with-sub &&
+ tree=$(git mktree <tree-with-sub) &&
+ test_config extensions.compatobjectformat $test_compat_hash_algo &&
+
+ git cat-file --batch-check >actual <<-EOF &&
+ $tree:sub
+ EOF
+ printf "$(test_oid deadbeef) submodule\n" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'batch-check with a submodule, object exists' '
+ printf "160000 commit $commit_oid\tsub\n" >tree-with-sub &&
+ tree=$(git mktree <tree-with-sub) &&
+ git cat-file --batch-check >actual <<-EOF &&
+ $tree:sub
+ EOF
+ printf "$commit_oid commit $commit_size\n" >expect &&
+ test_cmp expect actual
+'
+
# Pull the entry for object with oid "$1" out of the output of
# "cat-file --batch", including its object content (which requires
# parsing and reading a set amount of bytes, hence perl).
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index dbbe9fb0d4..de076293b6 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -30,7 +30,7 @@ setup_repo() {
test_repo=test
push_repo() {
- test_create_repo $test_repo
+ git init --quiet $test_repo
cd $test_repo
setup_repo
@@ -252,9 +252,9 @@ test_expect_success '--literally complains about non-standard types' '
test_must_fail git hash-object -t bogus --literally --stdin
'
-test_expect_success '--stdin outside of repository (uses SHA-1)' '
+test_expect_success '--stdin outside of repository (uses default hash)' '
nongit git hash-object --stdin <hello >actual &&
- echo "$(test_oid --hash=sha1 hello)" >expect &&
+ echo "$(test_oid --hash=builtin hello)" >expect &&
test_cmp expect actual
'
diff --git a/t/t1021-rerere-in-workdir.sh b/t/t1021-rerere-in-workdir.sh
deleted file mode 100755
index 0b892894eb..0000000000
--- a/t/t1021-rerere-in-workdir.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/sh
-
-test_description='rerere run in a workdir'
-GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
-export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
-
-. ./test-lib.sh
-
-test_expect_success SYMLINKS setup '
- git config rerere.enabled true &&
- >world &&
- git add world &&
- test_tick &&
- git commit -m initial &&
-
- echo hello >world &&
- test_tick &&
- git commit -a -m hello &&
-
- git checkout -b side HEAD^ &&
- echo goodbye >world &&
- test_tick &&
- git commit -a -m goodbye &&
-
- git checkout main
-'
-
-test_expect_success SYMLINKS 'rerere in workdir' '
- rm -rf .git/rr-cache &&
- "$SHELL_PATH" "$TEST_DIRECTORY/../contrib/workdir/git-new-workdir" . work &&
- (
- cd work &&
- test_must_fail git merge side &&
- git rerere status >actual &&
- echo world >expect &&
- test_cmp expect actual
- )
-'
-
-# This fails because we don't resolve relative symlink in mkdir_in_gitdir()
-# For the purpose of helping contrib/workdir/git-new-workdir users, we do not
-# have to support relative symlinks, but it might be nicer to make this work
-# with a relative symbolic link someday.
-test_expect_failure SYMLINKS 'rerere in workdir (relative)' '
- rm -rf .git/rr-cache &&
- "$SHELL_PATH" "$TEST_DIRECTORY/../contrib/workdir/git-new-workdir" . krow &&
- (
- cd krow &&
- rm -f .git/rr-cache &&
- ln -s ../.git/rr-cache .git/rr-cache &&
- test_must_fail git merge side &&
- git rerere status >actual &&
- echo world >expect &&
- test_cmp expect actual
- )
-'
-
-test_done
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 51a85e83c2..f856821839 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -2851,4 +2851,15 @@ test_expect_success 'writing to stdin is rejected' '
done
+test_expect_success 'writing value with trailing CR not stripped on read' '
+ test_when_finished "rm -rf cr-test" &&
+
+ printf "bar\r\n" >expect &&
+ git init cr-test &&
+ git -C cr-test config set core.foo $(printf "bar\r") &&
+ git -C cr-test config get core.foo >actual &&
+
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index d29d23cb89..96648a6e5d 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -1380,10 +1380,7 @@ test_expect_success 'fails with duplicate ref update via symref' '
test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' '
(
- for i in $(test_seq 33)
- do
- echo "create refs/heads/$i HEAD" || exit 1
- done >large_input &&
+ test_seq -f "create refs/heads/%d HEAD" 33 >large_input &&
run_with_limited_open_files git update-ref --stdin <large_input &&
git rev-parse --verify -q refs/heads/33
)
@@ -1391,10 +1388,7 @@ test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches
test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' '
(
- for i in $(test_seq 33)
- do
- echo "delete refs/heads/$i HEAD" || exit 1
- done >large_input &&
+ test_seq -f "delete refs/heads/%d HEAD" 33 >large_input &&
run_with_limited_open_files git update-ref --stdin <large_input &&
test_must_fail git rev-parse --verify -q refs/heads/33
)
@@ -2299,6 +2293,51 @@ do
test_grep -q "refname conflict" stdout
)
'
+
+ test_expect_success "stdin $type batch-updates delete incorrect symbolic ref" '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ test_commit c1 &&
+ head=$(git rev-parse HEAD) &&
+ git symbolic-ref refs/heads/symbolic refs/heads/non-existent &&
+
+ format_command $type "delete refs/heads/symbolic" "$head" >stdin &&
+ git update-ref $type --stdin --batch-updates <stdin >stdout &&
+ test_grep "reference does not exist" stdout
+ )
+ '
+
+ test_expect_success "stdin $type batch-updates delete with incorrect old_oid" '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ test_commit c1 &&
+ git branch new-branch &&
+ test_commit c2 &&
+ head=$(git rev-parse HEAD) &&
+
+ format_command $type "delete refs/heads/new-branch" "$head" >stdin &&
+ git update-ref $type --stdin --batch-updates <stdin >stdout &&
+ test_grep "incorrect old value provided" stdout
+ )
+ '
+
+ test_expect_success "stdin $type batch-updates delete non-existent ref" '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ test_commit commit &&
+ head=$(git rev-parse HEAD) &&
+
+ format_command $type "delete refs/heads/non-existent" "$head" >stdin &&
+ git update-ref $type --stdin --batch-updates <stdin >stdout &&
+ test_grep "reference does not exist" stdout
+ )
+ '
done
test_expect_success 'update-ref should also create reflog for HEAD' '
@@ -2310,4 +2349,23 @@ test_expect_success 'update-ref should also create reflog for HEAD' '
test_cmp expect actual
'
+test_expect_success REFFILES 'empty directories are pruned when aborting a transaction' '
+ test_path_is_missing .git/refs/heads/nested &&
+ git update-ref --stdin <<-EOF &&
+ create refs/heads/nested/something HEAD
+ prepare
+ abort
+ EOF
+ test_path_is_missing .git/refs/heads/nested
+'
+
+test_expect_success REFFILES 'empty directories are pruned when not committing' '
+ test_path_is_missing .git/refs/heads/nested &&
+ git update-ref --stdin <<-EOF &&
+ create refs/heads/nested/something HEAD
+ prepare
+ EOF
+ test_path_is_missing .git/refs/heads/nested
+'
+
test_done
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 42b501f163..e30f87a358 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -673,4 +673,32 @@ test_expect_success 'reflog drop --all with reference' '
)
'
+test_expect_success 'expire with pattern config' '
+ # Split refs/heads/ into two roots so we can apply config to each. Make
+ # two branches per root to verify that config is applied correctly
+ # multiple times.
+ git branch root1/branch1 &&
+ git branch root1/branch2 &&
+ git branch root2/branch1 &&
+ git branch root2/branch2 &&
+
+ test_config "gc.reflogexpire" "never" &&
+ test_config "gc.refs/heads/root2/*.reflogExpire" "now" &&
+ git reflog expire \
+ root1/branch1 root1/branch2 \
+ root2/branch1 root2/branch2 &&
+
+ cat >expect <<-\EOF &&
+ root1/branch1@{0}
+ root1/branch2@{0}
+ EOF
+ git log -g --branches="root*" --format=%gD >actual.raw &&
+ # The sole reflog entry of each branch points to the same commit, so
+ # the order in which they are shown is nondeterministic. We just care
+ # about the what was expired (and what was not), so sort to get a known
+ # order.
+ sort <actual.raw >actual.sorted &&
+ test_cmp expect actual.sorted
+'
+
test_done
diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
index 8c777f7cf8..d91dd3a3b5 100755
--- a/t/t1416-ref-transaction-hooks.sh
+++ b/t/t1416-ref-transaction-hooks.sh
@@ -120,8 +120,6 @@ test_expect_success 'interleaving hook calls succeed' '
cat >expect <<-EOF &&
hooks/update refs/tags/PRE $ZERO_OID $PRE_OID
- hooks/reference-transaction prepared
- hooks/reference-transaction committed
hooks/update refs/tags/POST $ZERO_OID $POST_OID
hooks/reference-transaction prepared
hooks/reference-transaction committed
diff --git a/t/t1517-outside-repo.sh b/t/t1517-outside-repo.sh
index 6824581317..8f59b867f2 100755
--- a/t/t1517-outside-repo.sh
+++ b/t/t1517-outside-repo.sh
@@ -114,4 +114,11 @@ test_expect_success 'update-server-info does not crash with -h' '
test_grep "[Uu]sage: git update-server-info " usage
'
+test_expect_success 'prune does not crash with -h' '
+ test_expect_code 129 git prune -h >usage &&
+ test_grep "[Uu]sage: git prune " usage &&
+ test_expect_code 129 nongit git prune -h >usage &&
+ test_grep "[Uu]sage: git prune " usage
+'
+
test_done
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index 90638fa886..023e1301c8 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -42,8 +42,8 @@ test_expect_success '"add" using - shorthand' '
test_expect_success '"add" refuses to checkout locked branch' '
test_must_fail git worktree add zere main &&
- ! test -d zere &&
- ! test -d .git/worktrees/zere
+ test_path_is_missing zere &&
+ test_path_is_missing .git/worktrees/zere
'
test_expect_success 'checking out paths not complaining about linked checkouts' '
@@ -70,14 +70,14 @@ test_expect_success '"add" worktree' '
test_expect_success '"add" worktree with lock' '
git worktree add --detach --lock here-with-lock main &&
test_when_finished "git worktree unlock here-with-lock || :" &&
- test -f .git/worktrees/here-with-lock/locked
+ test_path_is_file .git/worktrees/here-with-lock/locked
'
test_expect_success '"add" worktree with lock and reason' '
lock_reason="why not" &&
git worktree add --detach --lock --reason "$lock_reason" here-with-lock-reason main &&
test_when_finished "git worktree unlock here-with-lock-reason || :" &&
- test -f .git/worktrees/here-with-lock-reason/locked &&
+ test_path_is_file .git/worktrees/here-with-lock-reason/locked &&
echo "$lock_reason" >expect &&
test_cmp expect .git/worktrees/here-with-lock-reason/locked
'
@@ -412,14 +412,14 @@ test_expect_success '"add --orphan" with empty repository' '
test_expect_success '"add" worktree with orphan branch and lock' '
git worktree add --lock --orphan -b orphanbr orphan-with-lock &&
test_when_finished "git worktree unlock orphan-with-lock || :" &&
- test -f .git/worktrees/orphan-with-lock/locked
+ test_path_is_file .git/worktrees/orphan-with-lock/locked
'
test_expect_success '"add" worktree with orphan branch, lock, and reason' '
lock_reason="why not" &&
git worktree add --detach --lock --reason "$lock_reason" orphan-with-lock-reason main &&
test_when_finished "git worktree unlock orphan-with-lock-reason || :" &&
- test -f .git/worktrees/orphan-with-lock-reason/locked &&
+ test_path_is_file .git/worktrees/orphan-with-lock-reason/locked &&
echo "$lock_reason" >expect &&
test_cmp expect .git/worktrees/orphan-with-lock-reason/locked
'
@@ -474,7 +474,7 @@ test_expect_success 'local clone --shared from linked checkout' '
test_expect_success '"add" worktree with --no-checkout' '
git worktree add --no-checkout -b swamp swamp &&
- ! test -e swamp/init.t &&
+ test_path_is_missing swamp/init.t &&
git -C swamp reset --hard &&
test_cmp init.t swamp/init.t
'
@@ -497,7 +497,7 @@ test_expect_success 'put a worktree under rebase' '
test_expect_success 'add a worktree, checking out a rebased branch' '
test_must_fail git worktree add new-rebase under-rebase &&
- ! test -d new-rebase
+ test_path_is_missing new-rebase
'
test_expect_success 'checking out a rebased branch from another worktree' '
@@ -535,7 +535,7 @@ test_expect_success 'checkout a branch under bisect' '
git worktree list >actual &&
grep "under-bisect.*detached HEAD" actual &&
test_must_fail git worktree add new-bisect under-bisect &&
- ! test -d new-bisect
+ test_path_is_missing new-bisect
)
'
@@ -1165,7 +1165,7 @@ test_expect_success '"add" not tripped up by magic worktree matching"' '
test_expect_success FUNNYNAMES 'sanitize generated worktree name' '
git worktree add --detach ". weird*..?.lock.lock" &&
- test -d .git/worktrees/---weird-.-
+ test_path_is_dir .git/worktrees/---weird-.-
'
test_expect_success '"add" should not fail because of another bad worktree' '
diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh
index 13f66fd649..b41e7f0daa 100755
--- a/t/t3000-ls-files-others.sh
+++ b/t/t3000-ls-files-others.sh
@@ -73,25 +73,6 @@ test_expect_success 'ls-files --others handles non-submodule .git' '
test_cmp expected1 output
'
-test_expect_success SYMLINKS 'ls-files --others with symlinked submodule' '
- git init super &&
- git init sub &&
- (
- cd sub &&
- >a &&
- git add a &&
- git commit -m sub &&
- git pack-refs --all
- ) &&
- (
- cd super &&
- "$SHELL_PATH" "$TEST_DIRECTORY/../contrib/workdir/git-new-workdir" ../sub sub &&
- git ls-files --others --exclude-standard >../actual
- ) &&
- echo sub/ >expect &&
- test_cmp expect actual
-'
-
test_expect_success 'setup nested pathspec search' '
test_create_repo nested &&
(
diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
index 127216f722..b8a8dd77e7 100755
--- a/t/t3418-rebase-continue.sh
+++ b/t/t3418-rebase-continue.sh
@@ -328,6 +328,19 @@ test_expect_success 'there is no --no-reschedule-failed-exec in an ongoing rebas
test_expect_code 129 git rebase --edit-todo --no-reschedule-failed-exec
'
+test_expect_success 'no change in comment character due to conflicts markers with core.commentChar=auto' '
+ git checkout -b branch-a &&
+ test_commit A F1 &&
+ git checkout -b branch-b HEAD^ &&
+ test_commit B F1 &&
+ test_must_fail git rebase branch-a &&
+ printf "B\nA\n" >F1 &&
+ git add F1 &&
+ GIT_EDITOR="cat >actual" git -c core.commentChar=auto rebase --continue &&
+ # Check that "#" is still the comment character.
+ test_grep "^# Changes to be committed" actual
+'
+
test_orig_head_helper () {
test_when_finished 'git rebase --abort &&
git checkout topic &&
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 98259e2ada..1f16e6b522 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -17,11 +17,6 @@ test_expect_success 'Initialize test directory' '
git commit -m "add normal files"
'
-if test_have_prereq !FUNNYNAMES
-then
- say 'Your filesystem does not allow tabs in filenames.'
-fi
-
test_expect_success FUNNYNAMES 'add files with funny names' '
touch -- "tab embedded" "newline${LF}embedded" &&
git add -- "tab embedded" "newline${LF}embedded" &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 74666ff3e4..0bb4648e36 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -11,6 +11,13 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-unique-files.sh
+test_expect_success 'setup' '
+ test_oid_cache <<-EOF
+ export_base sha1:73c9bab443d1f88ac61aa533d2eeaaa15451239c
+ export_base sha256:f210fa6346e3e2ce047bdb570426b17075980c1ac01fec8fc4b75bd3ab4bcfe4
+ EOF
+'
+
test_expect_success 'usage on cmd and subcommand invalid option' '
test_expect_code 129 git stash --invalid-option 2>usage &&
grep "or: git stash" usage &&
@@ -1177,6 +1184,28 @@ test_expect_success 'stash -- <pathspec> stashes and restores the file' '
test_path_is_file bar
'
+test_expect_success 'stash --patch <pathspec> stash and restores the file' '
+ test_write_lines b c >file &&
+ git commit -m "add a few lines" file &&
+ test_write_lines a b c d >file &&
+ test_write_lines b c d >expect-file &&
+ echo changed-other-file >other-file &&
+ test_write_lines s y n | git stash -m "stash bar" --patch file &&
+ test_cmp expect-file file &&
+ echo changed-other-file >expect &&
+ test_cmp expect other-file &&
+ git checkout HEAD -- file &&
+ git stash pop &&
+ test_cmp expect other-file &&
+ test_write_lines a b c >expect &&
+ test_cmp expect file
+'
+
+test_expect_success 'stash <pathspec> -p is rejected' '
+ test_must_fail git stash file -p 2>err &&
+ test_grep "subcommand wasn${SQ}t specified; ${SQ}push${SQ} can${SQ}t be assumed due to unexpected token ${SQ}file${SQ}" err
+'
+
test_expect_success 'stash -- <pathspec> stashes in subdirectory' '
mkdir sub &&
>foo &&
@@ -1412,6 +1441,100 @@ test_expect_success 'stash --keep-index --include-untracked with empty tree' '
)
'
+test_expect_success 'stash export and import round-trip stashes' '
+ git reset &&
+ >untracked &&
+ >tracked1 &&
+ >tracked2 &&
+ git add tracked* &&
+ git stash -- &&
+ >subdir/untracked &&
+ >subdir/tracked1 &&
+ >subdir/tracked2 &&
+ git add subdir/tracked* &&
+ git stash --include-untracked -- subdir/ &&
+ git tag t-stash0 stash@{0} &&
+ git tag t-stash1 stash@{1} &&
+ simple=$(git stash export --print) &&
+ git stash clear &&
+ git stash import "$simple" &&
+ test_cmp_rev stash@{0} t-stash0 &&
+ test_cmp_rev stash@{1} t-stash1 &&
+ git stash export --to-ref refs/heads/foo &&
+ test_cmp_rev "$(test_oid empty_tree)" foo: &&
+ test_cmp_rev "$(test_oid empty_tree)" foo^: &&
+ test_cmp_rev t-stash0 foo^2 &&
+ test_cmp_rev t-stash1 foo^^2 &&
+ git log --first-parent --format="%s" refs/heads/foo >log &&
+ grep "^git stash: " log >log2 &&
+ test_line_count = 13 log2 &&
+ git stash clear &&
+ git stash import foo &&
+ test_cmp_rev stash@{0} t-stash0 &&
+ test_cmp_rev stash@{1} t-stash1
+'
+
+test_expect_success 'stash import appends commits' '
+ git log --format=oneline -g refs/stash >out &&
+ cat out out >out2 &&
+ git stash import refs/heads/foo &&
+ git log --format=oneline -g refs/stash >actual &&
+ test_line_count = $(wc -l <out2) actual
+'
+
+test_expect_success 'stash export can accept specified stashes' '
+ git stash clear &&
+ git stash import foo &&
+ git stash export --to-ref refs/heads/bar stash@{1} stash@{0} &&
+ git stash clear &&
+ git stash import refs/heads/bar &&
+ test_cmp_rev stash@{1} t-stash0 &&
+ test_cmp_rev stash@{0} t-stash1 &&
+ git log --format=oneline -g refs/stash >actual &&
+ test_line_count = 2 actual
+'
+
+test_expect_success 'stash export rejects invalid arguments' '
+ test_must_fail git stash export --print --to-ref refs/heads/invalid 2>err &&
+ grep "exactly one of --print and --to-ref is required" err &&
+ test_must_fail git stash export 2>err2 &&
+ grep "exactly one of --print and --to-ref is required" err2
+'
+
+test_expect_success 'stash can import and export zero stashes' '
+ git stash clear &&
+ git stash export --to-ref refs/heads/baz &&
+ test_cmp_rev "$(test_oid empty_tree)" baz: &&
+ test_cmp_rev "$(test_oid export_base)" baz &&
+ test_must_fail git rev-parse baz^1 &&
+ git stash import baz &&
+ test_must_fail git rev-parse refs/stash
+'
+
+test_expect_success 'stash rejects invalid attempts to import commits' '
+ git stash import foo &&
+ test_must_fail git stash import HEAD 2>output &&
+ oid=$(git rev-parse HEAD) &&
+ grep "$oid is not a valid exported stash commit" output &&
+ test_cmp_rev stash@{0} t-stash0 &&
+
+ git checkout --orphan orphan &&
+ git commit-tree $(test_oid empty_tree) -p "$oid" -p "$oid^" -m "" >fake-commit &&
+ git update-ref refs/heads/orphan "$(cat fake-commit)" &&
+ oid=$(git rev-parse HEAD) &&
+ test_must_fail git stash import orphan 2>output &&
+ grep "found stash commit $oid without expected prefix" output &&
+ test_cmp_rev stash@{0} t-stash0 &&
+
+ git checkout --orphan orphan2 &&
+ git commit-tree $(test_oid empty_tree) -m "" >fake-commit &&
+ git update-ref refs/heads/orphan2 "$(cat fake-commit)" &&
+ oid=$(git rev-parse HEAD) &&
+ test_must_fail git stash import orphan2 2>output &&
+ grep "found root commit $oid with invalid data" output &&
+ test_cmp_rev stash@{0} t-stash0
+'
+
test_expect_success 'stash apply should succeed with unmodified file' '
echo base >file &&
git add file &&
@@ -1549,11 +1672,9 @@ test_expect_success 'stash create reports a locked index' '
echo change >A.file &&
touch .git/index.lock &&
- cat >expect <<-EOF &&
- error: could not write index
- EOF
test_must_fail git stash create 2>err &&
- test_cmp expect err
+ test_grep "error: could not write index" err &&
+ test_grep "error: Unable to create '.*index.lock'" err
)
'
@@ -1566,11 +1687,9 @@ test_expect_success 'stash push reports a locked index' '
echo change >A.file &&
touch .git/index.lock &&
- cat >expect <<-EOF &&
- error: could not write index
- EOF
test_must_fail git stash push 2>err &&
- test_cmp expect err
+ test_grep "error: could not write index" err &&
+ test_grep "error: Unable to create '.*index.lock'" err
)
'
@@ -1584,11 +1703,41 @@ test_expect_success 'stash apply reports a locked index' '
git stash push &&
touch .git/index.lock &&
- cat >expect <<-EOF &&
- error: could not write index
- EOF
test_must_fail git stash apply 2>err &&
- test_cmp expect err
+ test_grep "error: could not write index" err &&
+ test_grep "error: Unable to create '.*index.lock'" err
+ )
+'
+
+test_expect_success 'submodules does not affect the branch recorded in stash message' '
+ git init sub_project &&
+ (
+ cd sub_project &&
+ echo "Initial content in sub_project" >sub_file.txt &&
+ git add sub_file.txt &&
+ git commit -m "Initial commit in sub_project"
+ ) &&
+
+ git init main_project &&
+ (
+ cd main_project &&
+ echo "Initial content in main_project" >main_file.txt &&
+ git add main_file.txt &&
+ git commit -m "Initial commit in main_project" &&
+
+ git -c protocol.file.allow=always submodule add ../sub_project sub &&
+ git commit -m "Added submodule sub_project" &&
+
+ git checkout -b feature_main &&
+ git -C sub checkout -b feature_sub &&
+
+ git checkout -b work_branch &&
+ echo "Important work to be stashed" >work_item.txt &&
+ git add work_item.txt &&
+ git stash push -m "custom stash for work_branch" &&
+
+ git stash list >../actual_stash_list.txt &&
+ grep "On work_branch: custom stash for work_branch" ../actual_stash_list.txt
)
'
diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh
index a51f881b1c..32b14e3a71 100755
--- a/t/t4000-diff-format.sh
+++ b/t/t4000-diff-format.sh
@@ -36,7 +36,7 @@ test_expect_success 'git diff-files -p after editing work tree.' '
# that's as far as it comes
if [ "$(git config --get core.filemode)" = false ]
then
- say 'filemode disabled on the filesystem'
+ skip_all='filemode disabled on the filesystem'
test_done
fi
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 782d97fb7d..8ebd170451 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -206,14 +206,30 @@ do
expect="$TEST_DIRECTORY/t4013/diff.$test"
actual="$pfx-diff.$test"
- test_expect_success "git $cmd # magic is ${magic:-(not used)}" '
+ case "$cmd" in
+ whatchanged | whatchanged" "*)
+ prereq=!WITH_BREAKING_CHANGES
+ ;;
+ *)
+ prereq=;;
+ esac
+
+ test_expect_success $prereq "git $cmd # magic is ${magic:-(not used)}" '
{
echo "$ git $cmd"
+
+ case "$cmd" in
+ whatchanged | whatchanged" "*)
+ run="whatchanged --i-still-use-this"
+ run="$run ${cmd#whatchanged}" ;;
+ *)
+ run=$cmd ;;
+ esac &&
case "$magic" in
"")
- GIT_PRINT_SHA1_ELLIPSIS=yes git $cmd ;;
+ GIT_PRINT_SHA1_ELLIPSIS=yes git $run ;;
noellipses)
- git $cmd ;;
+ git $run ;;
esac |
sed -e "s/^\\(-*\\)$V\\(-*\\)\$/\\1g-i-t--v-e-r-s-i-o-n\2/" \
-e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/"
@@ -460,6 +476,11 @@ diff-tree --stat --compact-summary initial mode
diff-tree -R --stat --compact-summary initial mode
EOF
+test_expect_success !WITH_BREAKING_CHANGES 'whatchanged needs --i-still-use-this' '
+ test_must_fail git whatchanged >message 2>&1 &&
+ test_grep "nominated for removal" message
+'
+
test_expect_success 'log -m matches pure log' '
git log master >result &&
process_diffs result >expected &&
diff --git a/t/t4018/r-indent b/t/t4018/r-indent
new file mode 100644
index 0000000000..9df440f2a4
--- /dev/null
+++ b/t/t4018/r-indent
@@ -0,0 +1,6 @@
+RIGHT <- function(a, b) {
+ c = mean(a, b)
+ d = c + 2
+ ChangeMe()
+ return (d)
+}
diff --git a/t/t4018/r-indent-nested b/t/t4018/r-indent-nested
new file mode 100644
index 0000000000..30412e6c79
--- /dev/null
+++ b/t/t4018/r-indent-nested
@@ -0,0 +1,10 @@
+LEFT = function(a, b) {
+ c = mean(a, b)
+ RIGHT = function(d, e) {
+ f = var(d, e)
+ g = f + 1
+ ChangeMe()
+ return (g)
+ }
+ return (RIGHT(2, 3))
+}
diff --git a/t/t4018/r-noindent b/t/t4018/r-noindent
new file mode 100644
index 0000000000..6d9b01ffe3
--- /dev/null
+++ b/t/t4018/r-noindent
@@ -0,0 +1,6 @@
+RIGHT <- function(a, b) {
+c = mean(a, b)
+d = c + 2
+ChangeMe()
+return (c)
+}
diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh
index 28f9d83d4c..4d4aa1650f 100755
--- a/t/t4041-diff-submodule-option.sh
+++ b/t/t4041-diff-submodule-option.sh
@@ -48,11 +48,12 @@ commit_file () {
git commit "$@" -m "Commit $*" >/dev/null
}
-test_create_repo sm1 &&
-add_file . foo >/dev/null
-
-head1=$(add_file sm1 foo1 foo2)
-fullhead1=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'setup submodule' '
+ git init sm1 &&
+ add_file . foo &&
+ head1=$(add_file sm1 foo1 foo2) &&
+ fullhead1=$(cd sm1 && git rev-parse --verify HEAD)
+'
test_expect_success 'added submodule' '
git add sm1 &&
@@ -235,10 +236,13 @@ test_expect_success 'typechanged submodule(submodule->blob)' '
test_cmp expected actual
'
-rm -f sm1 &&
-test_create_repo sm1 &&
-head6=$(add_file sm1 foo6 foo7)
-fullhead6=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'setup submodule anew' '
+ rm -f sm1 &&
+ git init sm1 &&
+ head6=$(add_file sm1 foo6 foo7) &&
+ fullhead6=$(cd sm1 && git rev-parse --verify HEAD)
+'
+
test_expect_success 'nonexistent commit' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
diff --git a/t/t4042-diff-textconv-caching.sh b/t/t4042-diff-textconv-caching.sh
index ff0e73531b..31018ceba2 100755
--- a/t/t4042-diff-textconv-caching.sh
+++ b/t/t4042-diff-textconv-caching.sh
@@ -120,6 +120,14 @@ test_expect_success 'log notes cache and still use cache for -p' '
'
test_expect_success 'caching is silently ignored outside repo' '
+ test_oid_cache <<-\EOM &&
+ oid1 sha1:5626abf
+ oid1 sha256:a4ed1f3
+ oid2 sha1:f719efd
+ oid2 sha256:aa9e7dc
+ EOM
+ oid1=$(test_oid --hash=builtin oid1) &&
+ oid2=$(test_oid --hash=builtin oid2) &&
mkdir -p non-repo &&
echo one >non-repo/one &&
echo two >non-repo/two &&
@@ -129,9 +137,9 @@ test_expect_success 'caching is silently ignored outside repo' '
-c diff.test.textconv="tr a-z A-Z <" \
-c diff.test.cachetextconv=true \
diff --no-index one two >actual &&
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
diff --git a/one b/two
- index 5626abf..f719efd 100644
+ index $oid1..$oid2 100644
--- a/one
+++ b/two
@@ -1 +1 @@
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
index 5e5bad61ca..01db9243ab 100755
--- a/t/t4053-diff-no-index.sh
+++ b/t/t4053-diff-no-index.sh
@@ -295,4 +295,79 @@ test_expect_success PIPE,SYMLINKS 'diff --no-index reads from pipes' '
test_cmp expect actual
'
+test_expect_success 'diff --no-index F F rejects pathspecs' '
+ test_must_fail git diff --no-index -- a/1 a/2 a 2>actual.err &&
+ test_grep "usage: git diff --no-index" actual.err
+'
+
+test_expect_success 'diff --no-index D F rejects pathspecs' '
+ test_must_fail git diff --no-index -- a a/2 a 2>actual.err &&
+ test_grep "usage: git diff --no-index" actual.err
+'
+
+test_expect_success 'diff --no-index F D rejects pathspecs' '
+ test_must_fail git diff --no-index -- a/1 b b 2>actual.err &&
+ test_grep "usage: git diff --no-index" actual.err
+'
+
+test_expect_success 'diff --no-index rejects absolute pathspec' '
+ test_must_fail git diff --no-index -- a b $(pwd)/a/1
+'
+
+test_expect_success 'diff --no-index with pathspec' '
+ test_expect_code 1 git diff --name-status --no-index a b 1 >actual &&
+ cat >expect <<-EOF &&
+ D a/1
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'diff --no-index with pathspec no matches' '
+ test_expect_code 0 git diff --name-status --no-index a b missing
+'
+
+test_expect_success 'diff --no-index with negative pathspec' '
+ test_expect_code 1 git diff --name-status --no-index a b ":!2" >actual &&
+ cat >expect <<-EOF &&
+ D a/1
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'setup nested' '
+ mkdir -p c/1/2 &&
+ mkdir -p d/1/2 &&
+ echo 1 >c/1/2/a &&
+ echo 2 >c/1/2/b
+'
+
+test_expect_success 'diff --no-index with pathspec nested negative pathspec' '
+ test_expect_code 0 git diff --no-index c d ":!1"
+'
+
+test_expect_success 'diff --no-index with pathspec nested pathspec' '
+ test_expect_code 1 git diff --name-status --no-index c d 1/2 >actual &&
+ cat >expect <<-EOF &&
+ D c/1/2/a
+ D c/1/2/b
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'diff --no-index with pathspec glob' '
+ test_expect_code 1 git diff --name-status --no-index c d ":(glob)**/a" >actual &&
+ cat >expect <<-EOF &&
+ D c/1/2/a
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'diff --no-index with pathspec glob and exclude' '
+ test_expect_code 1 git diff --name-status --no-index c d ":(glob,exclude)**/a" >actual &&
+ cat >expect <<-EOF &&
+ D c/1/2/b
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh
index 76b83101d3..dbfeb7470b 100755
--- a/t/t4060-diff-submodule-option-diff-format.sh
+++ b/t/t4060-diff-submodule-option-diff-format.sh
@@ -363,9 +363,12 @@ test_expect_success 'typechanged submodule(submodule->blob)' '
diff_cmp expected actual
'
-rm -f sm1 &&
-test_create_repo sm1 &&
-head6=$(add_file sm1 foo6 foo7)
+test_expect_success 'setup' '
+ rm -f sm1 &&
+ git init sm1 &&
+ head6=$(add_file sm1 foo6 foo7)
+'
+
test_expect_success 'nonexistent commit' '
git diff-index -p --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
diff --git a/t/t4140-apply-ita.sh b/t/t4140-apply-ita.sh
index c614eaf04c..0b11a8aef4 100755
--- a/t/t4140-apply-ita.sh
+++ b/t/t4140-apply-ita.sh
@@ -7,6 +7,10 @@ test_description='git apply of i-t-a file'
test_expect_success setup '
test_write_lines 1 2 3 4 5 >blueprint &&
+ cat blueprint >committed-file &&
+ git add committed-file &&
+ git commit -m "commit" &&
+
cat blueprint >test-file &&
git add -N test-file &&
git diff >creation-patch &&
@@ -14,7 +18,14 @@ test_expect_success setup '
rm -f test-file &&
git diff >deletion-patch &&
- grep "deleted file mode 100644" deletion-patch
+ grep "deleted file mode 100644" deletion-patch &&
+
+ git rm -f test-file &&
+ test_write_lines 6 >>committed-file &&
+ cat blueprint >test-file &&
+ git add -N test-file &&
+ git diff >complex-patch &&
+ git restore committed-file
'
test_expect_success 'apply creation patch to ita path (--cached)' '
@@ -53,4 +64,22 @@ test_expect_success 'apply deletion patch to ita path (--index)' '
git ls-files --stage --error-unmatch test-file
'
+test_expect_success 'apply creation patch to existing index with -N' '
+ git rm -f test-file &&
+ cat blueprint >index-file &&
+ git add index-file &&
+ git apply -N creation-patch &&
+
+ git ls-files --stage --error-unmatch index-file &&
+ git ls-files --stage --error-unmatch test-file
+'
+
+test_expect_success 'apply complex patch with -N' '
+ git rm -f test-file index-file &&
+ git apply -N complex-patch &&
+
+ git ls-files --stage --error-unmatch test-file &&
+ git diff | grep "a/committed-file"
+'
+
test_done
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 2ae93d3c96..699a81ab5c 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -1086,7 +1086,7 @@ test_expect_success 'am works with multi-line in-body headers' '
# bump from, date, and subject down to in-body header
awk "
/^From:/{
- print \"From: x <x\@example.com>\";
+ print \"From: x <x@example.com>\";
print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
print \"Subject: x\n\";
}; 1
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 51f7beb59f..05cee9e41b 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -134,6 +134,12 @@ test_expect_success 'diff-filter=D' '
'
+test_expect_success 'all-negative filter' '
+ git log --no-renames --format=%s --diff-filter=d HEAD >actual &&
+ printf "%s\n" fifth fourth third second initial >expect &&
+ test_cmp expect actual
+'
+
test_expect_success 'diff-filter=R' '
git log -M --pretty="format:%s" --diff-filter=R HEAD >actual &&
@@ -486,10 +492,16 @@ test_expect_success !FAIL_PREREQS 'log with various grep.patternType configurati
)
'
-for cmd in show whatchanged reflog format-patch
+cmds="show reflog format-patch"
+if test_have_prereq !WITH_BREAKING_CHANGES
+then
+ cmds="$cmds whatchanged"
+fi
+for cmd in $cmds
do
case "$cmd" in
format-patch) myarg="HEAD~.." ;;
+ whatchanged) myarg=--i-still-use-this ;;
*) myarg= ;;
esac
@@ -1201,20 +1213,27 @@ test_expect_success 'reflog is expected format' '
test_cmp expect actual
'
-test_expect_success 'whatchanged is expected format' '
+test_expect_success !WITH_BREAKING_CHANGES 'whatchanged is expected format' '
+ whatchanged="whatchanged --i-still-use-this" &&
git log --no-merges --raw >expect &&
- git whatchanged >actual &&
+ git $whatchanged >actual &&
test_cmp expect actual
'
test_expect_success 'log.abbrevCommit configuration' '
+ whatchanged="whatchanged --i-still-use-this" &&
+
git log --abbrev-commit >expect.log.abbrev &&
git log --no-abbrev-commit >expect.log.full &&
git log --pretty=raw >expect.log.raw &&
git reflog --abbrev-commit >expect.reflog.abbrev &&
git reflog --no-abbrev-commit >expect.reflog.full &&
- git whatchanged --abbrev-commit >expect.whatchanged.abbrev &&
- git whatchanged --no-abbrev-commit >expect.whatchanged.full &&
+
+ if test_have_prereq !WITH_BREAKING_CHANGES
+ then
+ git $whatchanged --abbrev-commit >expect.whatchanged.abbrev &&
+ git $whatchanged --no-abbrev-commit >expect.whatchanged.full
+ fi &&
test_config log.abbrevCommit true &&
@@ -1231,10 +1250,13 @@ test_expect_success 'log.abbrevCommit configuration' '
git reflog --no-abbrev-commit >actual &&
test_cmp expect.reflog.full actual &&
- git whatchanged >actual &&
- test_cmp expect.whatchanged.abbrev actual &&
- git whatchanged --no-abbrev-commit >actual &&
- test_cmp expect.whatchanged.full actual
+ if test_have_prereq !WITH_BREAKING_CHANGES
+ then
+ git $whatchanged >actual &&
+ test_cmp expect.whatchanged.abbrev actual &&
+ git $whatchanged --no-abbrev-commit >actual &&
+ test_cmp expect.whatchanged.full actual
+ fi
'
test_expect_success '--abbrev-commit with core.abbrev=false' '
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 4a6242ff99..74b7ddccb2 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -1133,4 +1133,37 @@ test_expect_success 'git cat-file --batch-command returns correct size with --us
test_cmp expect actual
'
+test_expect_success 'git cat-file --mailmap works with different author and committer' '
+ test_when_finished "rm .mailmap" &&
+ cat >.mailmap <<-\EOF &&
+ Mailmapped User <mailmapped-user@gitlab.com> C O Mitter <committer@example.com>
+ EOF
+ git commit --allow-empty -m "different author/committer" \
+ --author="Different Author <different@example.com>" &&
+ cat >expect <<-\EOF &&
+ author Different Author <different@example.com>
+ committer Mailmapped User <mailmapped-user@gitlab.com>
+ EOF
+ git cat-file --mailmap commit HEAD >log &&
+ sed -n -e "/^author /s/>.*/>/p" -e "/^committer /s/>.*/>/p" log >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git cat-file --mailmap maps both author and committer when both need mapping' '
+ test_when_finished "rm .mailmap" &&
+ cat >.mailmap <<-\EOF &&
+ Mapped Author <mapped-author@example.com> <different@example.com>
+ Mapped Committer <mapped-committer@example.com> C O Mitter <committer@example.com>
+ EOF
+ git commit --allow-empty -m "both author and committer mapped" \
+ --author="Different Author <different@example.com>" &&
+ cat >expect <<-\EOF &&
+ author Mapped Author <mapped-author@example.com>
+ committer Mapped Committer <mapped-committer@example.com>
+ EOF
+ git cat-file --mailmap commit HEAD >log &&
+ sed -n -e "/^author /s/>.*/>/p" -e "/^committer /s/>.*/>/p" log >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh
index 8910d53cac..639868ac56 100755
--- a/t/t4216-log-bloom.sh
+++ b/t/t4216-log-bloom.sh
@@ -66,8 +66,9 @@ sane_unset GIT_TRACE2_CONFIG_PARAMS
setup () {
rm -f "$TRASH_DIRECTORY/trace.perf" &&
- git -c core.commitGraph=false log --pretty="format:%s" $1 >log_wo_bloom &&
- GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.perf" git -c core.commitGraph=true log --pretty="format:%s" $1 >log_w_bloom
+ eval git -c core.commitGraph=false log --pretty="format:%s" "$1" >log_wo_bloom &&
+ eval "GIT_TRACE2_PERF=\"$TRASH_DIRECTORY/trace.perf\"" \
+ git -c core.commitGraph=true log --pretty="format:%s" "$1" >log_w_bloom
}
test_bloom_filters_used () {
@@ -138,10 +139,6 @@ test_expect_success 'git log with --walk-reflogs does not use Bloom filters' '
test_bloom_filters_not_used "--walk-reflogs -- A"
'
-test_expect_success 'git log -- multiple path specs does not use Bloom filters' '
- test_bloom_filters_not_used "-- file4 A/file1"
-'
-
test_expect_success 'git log -- "." pathspec at root does not use Bloom filters' '
test_bloom_filters_not_used "-- ."
'
@@ -151,9 +148,17 @@ test_expect_success 'git log with wildcard that resolves to a single path uses B
test_bloom_filters_used "-- *renamed"
'
-test_expect_success 'git log with wildcard that resolves to a multiple paths does not uses Bloom filters' '
- test_bloom_filters_not_used "-- *" &&
- test_bloom_filters_not_used "-- file*"
+test_expect_success 'git log with multiple literal paths uses Bloom filter' '
+ test_bloom_filters_used "-- file4 A/file1" &&
+ test_bloom_filters_used "-- *" &&
+ test_bloom_filters_used "-- file*"
+'
+
+test_expect_success 'git log with path contains a wildcard does not use Bloom filter' '
+ test_bloom_filters_not_used "-- file\*" &&
+ test_bloom_filters_not_used "-- A/\* file4" &&
+ test_bloom_filters_not_used "-- file4 A/\*" &&
+ test_bloom_filters_not_used "-- * A/\*"
'
test_expect_success 'setup - add commit-graph to the chain without Bloom filters' '
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
index 5174995191..027dedd976 100755
--- a/t/t5004-archive-corner-cases.sh
+++ b/t/t5004-archive-corner-cases.sh
@@ -176,10 +176,7 @@ test_expect_success EXPENSIVE,UNZIP,UNZIP_ZIP64_SUPPORT \
blob=$(echo $s | git hash-object -w --stdin) &&
# create tree containing 65500 entries of that blob
- for i in $(test_seq 1 65500)
- do
- echo "100644 blob $blob $i" || return 1
- done >tree &&
+ test_seq -f "100644 blob $blob\t%d" 1 65500 >tree &&
tree=$(git mktree <tree) &&
# zip it, creating an archive a bit bigger than 4GB
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index a5932b6a8b..73445782e7 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -525,7 +525,7 @@ test_expect_success 'index-pack --strict <pack> works in non-repo' '
test_path_is_file foo.idx
'
-test_expect_success SHA1 'show-index works OK outside a repository' '
+test_expect_success DEFAULT_HASH_ALGORITHM 'show-index works OK outside a repository' '
nongit git show-index <foo.idx
'
@@ -658,7 +658,7 @@ do
test_commit -C repo initial &&
git -C repo repack -ad &&
git -C repo verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx &&
- if test $hash = sha1
+ if test $hash = $GIT_TEST_BUILTIN_HASH
then
nongit git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx
else
@@ -676,7 +676,7 @@ do
test_commit -C repo initial &&
git -C repo repack -ad &&
git -C repo index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack &&
- if test $hash = sha1
+ if test $hash = $GIT_TEST_BUILTIN_HASH
then
nongit git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack
else
@@ -723,4 +723,23 @@ test_expect_success '--name-hash-version=2 and --write-bitmap-index are incompat
! test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err
'
+test_expect_success '--path-walk pack everything' '
+ git -C server rev-parse HEAD >in &&
+ GIT_PROGRESS_DELAY=0 git -C server pack-objects \
+ --stdout --revs --path-walk --progress <in >out.pack 2>err &&
+ grep "Compressing objects by path" err &&
+ git -C server index-pack --stdin <out.pack
+'
+
+test_expect_success '--path-walk thin pack' '
+ cat >in <<-EOF &&
+ $(git -C server rev-parse HEAD)
+ ^$(git -C server rev-parse HEAD~2)
+ EOF
+ GIT_PROGRESS_DELAY=0 git -C server pack-objects \
+ --thin --stdout --revs --path-walk --progress <in >out.pack 2>err &&
+ grep "Compressing objects by path" err &&
+ git -C server index-pack --fix-thin --stdin <out.pack
+'
+
test_done
diff --git a/t/t5306-pack-nobase.sh b/t/t5306-pack-nobase.sh
index 805d60ff31..609399d54f 100755
--- a/t/t5306-pack-nobase.sh
+++ b/t/t5306-pack-nobase.sh
@@ -59,6 +59,11 @@ test_expect_success 'indirectly clone patch_clone' '
git pull ../.git &&
test $(git rev-parse HEAD) = $B &&
+ # The --path-walk feature of "git pack-objects" is not
+ # compatible with this kind of fetch from an incomplete repo.
+ GIT_TEST_PACK_PATH_WALK=0 &&
+ export GIT_TEST_PACK_PATH_WALK &&
+
git pull ../patch_clone/.git &&
test $(git rev-parse HEAD) = $C
)
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index a62b463eaf..6718fb98c0 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -158,8 +158,9 @@ test_bitmap_cases () {
ls .git/objects/pack/ | grep bitmap >output &&
test_line_count = 1 output &&
# verify equivalent packs are generated with/without using bitmap index
- packasha1=$(git pack-objects --no-use-bitmap-index --all packa </dev/null) &&
- packbsha1=$(git pack-objects --use-bitmap-index --all packb </dev/null) &&
+ # Be careful to not use the path-walk option in either case.
+ packasha1=$(git pack-objects --no-use-bitmap-index --no-path-walk --all packa </dev/null) &&
+ packbsha1=$(git pack-objects --use-bitmap-index --no-path-walk --all packb </dev/null) &&
list_packed_objects packa-$packasha1.idx >packa.objects &&
list_packed_objects packb-$packbsha1.idx >packb.objects &&
test_cmp packa.objects packb.objects
@@ -388,6 +389,14 @@ test_bitmap_cases () {
git init --bare client.git &&
(
cd client.git &&
+
+ # This test relies on reusing a delta, but if the
+ # path-walk machinery is engaged, the base object
+ # is considered too small to use during the
+ # dynamic computation, so is not used.
+ GIT_TEST_PACK_PATH_WALK=0 &&
+ export GIT_TEST_PACK_PATH_WALK &&
+
git config transfer.unpackLimit 1 &&
git fetch .. delta-reuse-old:delta-reuse-old &&
git fetch .. delta-reuse-new:delta-reuse-new &&
@@ -486,6 +495,36 @@ test_bitmap_cases () {
grep "ignoring extra bitmap" trace2.txt
)
'
+
+ test_expect_success 'load corrupt bitmap' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+
+ test_commit base &&
+
+ git repack -adb &&
+ bitmap="$(ls .git/objects/pack/pack-*.bitmap)" &&
+ chmod +w $bitmap &&
+
+ test-tool bitmap list-commits-with-offset >offsets &&
+ xor_off=$(head -n1 offsets | awk "{print \$3}") &&
+ printf '\161' |
+ dd of=$bitmap count=1 bs=1 conv=notrunc seek=$xor_off &&
+
+ git rev-list --objects --no-object-names HEAD >expect.raw &&
+ git rev-list --objects --use-bitmap-index --no-object-names HEAD \
+ >actual.raw &&
+
+ sort expect.raw >expect &&
+ sort actual.raw >actual &&
+
+ test_cmp expect actual
+ )
+ '
}
test_bitmap_cases
diff --git a/t/t5316-pack-delta-depth.sh b/t/t5316-pack-delta-depth.sh
index defaa06d65..03dfb7a61e 100755
--- a/t/t5316-pack-delta-depth.sh
+++ b/t/t5316-pack-delta-depth.sh
@@ -89,15 +89,18 @@ max_chain() {
# adjusted (or scrapped if the heuristics have become too unreliable)
test_expect_success 'packing produces a long delta' '
# Use --window=0 to make sure we are seeing reused deltas,
- # not computing a new long chain.
- pack=$(git pack-objects --all --window=0 </dev/null pack) &&
+ # not computing a new long chain. (Also avoid the --path-walk
+ # option as it may break delta chains.)
+ pack=$(git pack-objects --all --window=0 --no-path-walk </dev/null pack) &&
echo 9 >expect &&
max_chain pack-$pack.pack >actual &&
test_cmp expect actual
'
test_expect_success '--depth limits depth' '
- pack=$(git pack-objects --all --depth=5 </dev/null pack) &&
+ # Avoid --path-walk to avoid breaking delta chains across path
+ # boundaries.
+ pack=$(git pack-objects --all --depth=5 --no-path-walk </dev/null pack) &&
echo 5 >expect &&
max_chain pack-$pack.pack >actual &&
test_cmp expect actual
diff --git a/t/t5323-pack-redundant.sh b/t/t5323-pack-redundant.sh
index bc30bc9652..2d96afd6f7 100755
--- a/t/t5323-pack-redundant.sh
+++ b/t/t5323-pack-redundant.sh
@@ -45,6 +45,11 @@ fi
main_repo=main.git
shared_repo=shared.git
+test_expect_success 'pack-redundant needs --i-still-use-this' '
+ test_must_fail git pack-redundant >message 2>&1 &&
+ test_grep "nominated for removal" message
+'
+
git_pack_redundant='git pack-redundant --i-still-use-this'
# Create commits in <repo> and assign each commit's oid to shell variables
diff --git a/t/t5331-pack-objects-stdin.sh b/t/t5331-pack-objects-stdin.sh
index b48c0cbe8f..4a8df5a389 100755
--- a/t/t5331-pack-objects-stdin.sh
+++ b/t/t5331-pack-objects-stdin.sh
@@ -64,7 +64,7 @@ test_expect_success '--stdin-packs is incompatible with --filter' '
cd stdin-packs &&
test_must_fail git pack-objects --stdin-packs --stdout \
--filter=blob:none </dev/null 2>err &&
- test_grep "cannot use --filter with --stdin-packs" err
+ test_grep "options .--stdin-packs. and .--filter. cannot be used together" err
)
'
@@ -236,4 +236,124 @@ test_expect_success 'pack-objects --stdin with packfiles from main and alternate
test_cmp expected-objects actual-objects
'
+objdir=.git/objects
+packdir=$objdir/pack
+
+objects_in_packs () {
+ for p in "$@"
+ do
+ git show-index <"$packdir/pack-$p.idx" || return 1
+ done >objects.raw &&
+
+ cut -d' ' -f2 objects.raw | sort &&
+ rm -f objects.raw
+}
+
+test_expect_success '--stdin-packs=follow walks into unknown packs' '
+ test_when_finished "rm -fr repo" &&
+
+ git init repo &&
+ (
+ cd repo &&
+
+ for c in A B C D
+ do
+ test_commit "$c" || return 1
+ done &&
+
+ A="$(echo A | git pack-objects --revs $packdir/pack)" &&
+ B="$(echo A..B | git pack-objects --revs $packdir/pack)" &&
+ C="$(echo B..C | git pack-objects --revs $packdir/pack)" &&
+ D="$(echo C..D | git pack-objects --revs $packdir/pack)" &&
+ test_commit E &&
+
+ git prune-packed &&
+
+ cat >in <<-EOF &&
+ pack-$B.pack
+ ^pack-$C.pack
+ pack-$D.pack
+ EOF
+
+ # With just --stdin-packs, pack "A" is unknown to us, so
+ # only objects from packs "B" and "D" are included in
+ # the output pack.
+ P=$(git pack-objects --stdin-packs $packdir/pack <in) &&
+ objects_in_packs $B $D >expect &&
+ objects_in_packs $P >actual &&
+ test_cmp expect actual &&
+
+ # But with --stdin-packs=follow, objects from both
+ # included packs reach objects from the unknown pack, so
+ # objects from pack "A" is included in the output pack
+ # in addition to the above.
+ P=$(git pack-objects --stdin-packs=follow $packdir/pack <in) &&
+ objects_in_packs $A $B $D >expect &&
+ objects_in_packs $P >actual &&
+ test_cmp expect actual &&
+
+ # And with --unpacked, we will pick up objects from unknown
+ # packs that are reachable from loose objects. Loose object E
+ # reaches objects in pack A, but there are three excluded packs
+ # in between.
+ #
+ # The resulting pack should include objects reachable from E
+ # that are not present in packs B, C, or D, along with those
+ # present in pack A.
+ cat >in <<-EOF &&
+ ^pack-$B.pack
+ ^pack-$C.pack
+ ^pack-$D.pack
+ EOF
+
+ P=$(git pack-objects --stdin-packs=follow --unpacked \
+ $packdir/pack <in) &&
+
+ {
+ objects_in_packs $A &&
+ git rev-list --objects --no-object-names D..E
+ }>expect.raw &&
+ sort expect.raw >expect &&
+ objects_in_packs $P >actual &&
+ test_cmp expect actual
+ )
+'
+
+stdin_packs__follow_with_only () {
+ rm -fr stdin_packs__follow_with_only &&
+ git init stdin_packs__follow_with_only &&
+ (
+ cd stdin_packs__follow_with_only &&
+
+ test_commit A &&
+ test_commit B &&
+
+ git rev-parse "$@" >B.objects &&
+
+ echo A | git pack-objects --revs $packdir/pack &&
+ B="$(git pack-objects $packdir/pack <B.objects)" &&
+
+ git cat-file --batch-check="%(objectname)" --batch-all-objects >objs &&
+ for obj in $(cat objs)
+ do
+ rm -f $objdir/$(test_oid_to_path $obj) || return 1
+ done &&
+
+ ( cd $packdir && ls pack-*.pack ) >in &&
+ git pack-objects --stdin-packs=follow --stdout >/dev/null <in
+ )
+}
+
+test_expect_success '--stdin-packs=follow tolerates missing blobs' '
+ stdin_packs__follow_with_only HEAD HEAD^{tree}
+'
+
+test_expect_success '--stdin-packs=follow tolerates missing trees' '
+ stdin_packs__follow_with_only HEAD HEAD:B.t
+'
+
+test_expect_success '--stdin-packs=follow tolerates missing commits' '
+ stdin_packs__follow_with_only HEAD HEAD^{tree}
+'
+
test_done
diff --git a/t/t5332-multi-pack-reuse.sh b/t/t5332-multi-pack-reuse.sh
index 57cad7708f..395d09444c 100755
--- a/t/t5332-multi-pack-reuse.sh
+++ b/t/t5332-multi-pack-reuse.sh
@@ -7,6 +7,13 @@ test_description='pack-objects multi-pack reuse'
GIT_TEST_MULTI_PACK_INDEX=0
GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL=0
+
+# The --path-walk option does not consider the preferred pack
+# at all for reusing deltas, so this variable changes the
+# behavior of this test, if enabled.
+GIT_TEST_PACK_PATH_WALK=0
+export GIT_TEST_PACK_PATH_WALK
+
objdir=.git/objects
packdir=$objdir/pack
diff --git a/t/t5333-pseudo-merge-bitmaps.sh b/t/t5333-pseudo-merge-bitmaps.sh
index 56674db562..1f7a5d82ee 100755
--- a/t/t5333-pseudo-merge-bitmaps.sh
+++ b/t/t5333-pseudo-merge-bitmaps.sh
@@ -234,8 +234,8 @@ test_expect_success 'pseudo-merge pattern with capture groups' '
test_commit_bulk 16 &&
git rev-list HEAD~16.. >in &&
- sed "s|\(.*\)|create refs/remotes/$r/tags/\1 \1" in |
- git update-ref --stdin || return 1
+ sed "s|\(.*\)|create refs/remotes/$r/tags/\1 \1|" in >refs &&
+ git update-ref --stdin <refs || return 1
done &&
git \
@@ -445,4 +445,21 @@ test_expect_success 'pseudo-merge closure' '
)
'
+test_expect_success 'use pseudo-merge in boundary traversal' '
+ git init pseudo-merge-boundary-traversal &&
+ (
+ cd pseudo-merge-boundary-traversal &&
+
+ git config bitmapPseudoMerge.test.pattern refs/ &&
+ git config pack.useBitmapBoundaryTraversal true &&
+
+ test_commit A &&
+ git repack -adb &&
+ test_commit B &&
+
+ nr=$(git rev-list --count --use-bitmap-index HEAD~1..HEAD) &&
+ test 1 -eq "$nr"
+ )
+'
+
test_done
diff --git a/t/t5408-send-pack-stdin.sh b/t/t5408-send-pack-stdin.sh
index 526a675045..ec339761c2 100755
--- a/t/t5408-send-pack-stdin.sh
+++ b/t/t5408-send-pack-stdin.sh
@@ -69,15 +69,24 @@ test_expect_success 'stdin mixed with cmdline' '
test_expect_success 'cmdline refs written in order' '
clear_remote &&
- test_must_fail git send-pack remote.git A:foo B:foo &&
- verify_push A foo
+ test_must_fail git send-pack remote.git A:foo B:foo 2>err &&
+ test_grep "multiple updates for ref ${SQ}refs/heads/foo${SQ} not allowed" err &&
+ test_must_fail git --git-dir=remote.git rev-parse foo
+'
+
+test_expect_success 'cmdline refs with multiple duplicates' '
+ clear_remote &&
+ test_must_fail git send-pack remote.git A:foo B:foo C:foo 2>err &&
+ test_grep "multiple updates for ref ${SQ}refs/heads/foo${SQ} not allowed" err &&
+ test_must_fail git --git-dir=remote.git rev-parse foo
'
test_expect_success '--stdin refs come after cmdline' '
clear_remote &&
echo A:foo >input &&
test_must_fail git send-pack remote.git --stdin B:foo <input &&
- verify_push B foo
+ test_grep "multiple updates for ref ${SQ}refs/heads/foo${SQ} not allowed" err &&
+ test_must_fail git --git-dir=remote.git rev-parse foo
'
test_expect_success 'refspecs and --mirror do not mix (cmdline)' '
diff --git a/t/t5410-receive-pack.sh b/t/t5410-receive-pack.sh
index f76a22943e..09d6bfd2a1 100755
--- a/t/t5410-receive-pack.sh
+++ b/t/t5410-receive-pack.sh
@@ -41,7 +41,19 @@ test_expect_success 'with core.alternateRefsPrefixes' '
test_cmp expect actual.haves
'
-test_expect_success 'receive-pack missing objects fails connectivity check' '
+# The `tee.exe` shipped in Git for Windows v2.49.0 is known to hang frequently
+# when spawned from `git.exe` and piping its output to `git.exe`. This seems
+# related to MSYS2 runtime bug fixes regarding the signal handling; Let's just
+# skip the tests that need to exercise this when the faulty MSYS2 runtime is
+# detected; The test cases are exercised enough in other matrix jobs of the CI
+# runs.
+test_lazy_prereq TEE_DOES_NOT_HANG '
+ test_have_prereq !MINGW &&
+ case "$(uname -a)" in *3.5.7-463ebcdc.x86_64*) false;; esac
+'
+
+test_expect_success TEE_DOES_NOT_HANG \
+ 'receive-pack missing objects fails connectivity check' '
test_when_finished rm -rf repo remote.git setup.git &&
git init repo &&
@@ -62,7 +74,8 @@ test_expect_success 'receive-pack missing objects fails connectivity check' '
test_must_fail git -C remote.git cat-file -e $(git -C repo rev-parse HEAD)
'
-test_expect_success 'receive-pack missing objects bypasses connectivity check' '
+test_expect_success TEE_DOES_NOT_HANG \
+ 'receive-pack missing objects bypasses connectivity check' '
test_when_finished rm -rf repo remote.git setup.git &&
git init repo &&
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index bef0250e89..2701eef85e 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -1644,4 +1644,18 @@ test_expect_success 'empty config clears remote.*.pushurl list' '
test_cmp expect actual
'
+test_expect_success 'forbid adding subset of existing remote' '
+ test_when_finished "git remote rm outer" &&
+ git remote add outer url &&
+ test_must_fail git remote add outer/inner url 2>err &&
+ test_grep ".outer/inner. is a subset of existing remote .outer." err
+'
+
+test_expect_success 'forbid adding superset of existing remote' '
+ test_when_finished "git remote rm outer/inner" &&
+ git remote add outer/inner url &&
+ test_must_fail git remote add outer url 2>err &&
+ test_grep ".outer. is a superset of existing remote .outer/inner." err
+'
+
test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index dabcc5f811..4e9c27b0f2 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -744,8 +744,8 @@ test_expect_success 'pushing valid refs triggers post-receive and post-update ho
EOF
cat >update.expect <<-EOF &&
- refs/heads/main $orgmain $newmain
refs/heads/next $orgnext $newnext
+ refs/heads/main $orgmain $newmain
EOF
cat >post-receive.expect <<-EOF &&
@@ -808,8 +808,8 @@ test_expect_success 'deletion of a non-existent ref is not fed to post-receive a
EOF
cat >update.expect <<-EOF &&
- refs/heads/main $orgmain $newmain
refs/heads/nonexistent $ZERO_OID $ZERO_OID
+ refs/heads/main $orgmain $newmain
EOF
cat >post-receive.expect <<-EOF &&
@@ -868,10 +868,10 @@ test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks w
EOF
cat >update.expect <<-EOF &&
- refs/heads/main $orgmain $newmain
refs/heads/next $orgnext $newnext
- refs/heads/seen $orgseen $newseen
refs/heads/nonexistent $ZERO_OID $ZERO_OID
+ refs/heads/main $orgmain $newmain
+ refs/heads/seen $orgseen $newseen
EOF
cat >post-receive.expect <<-EOF &&
@@ -1909,4 +1909,23 @@ test_expect_success 'push with config push.useBitmaps' '
--thin --delta-base-offset -q --no-use-bitmap-index <false
'
+test_expect_success 'push with config pack.usePathWalk=true' '
+ mk_test testrepo heads/main &&
+ git checkout main &&
+ test_config pack.usePathWalk true &&
+ GIT_TRACE2_EVENT="$(pwd)/path-walk.txt" \
+ git push --quiet testrepo main:test &&
+
+ test_region pack-objects path-walk path-walk.txt
+'
+
+test_expect_success 'push with F/D conflict with deletion and creation' '
+ test_when_finished "git branch -D branch" &&
+ git branch branch/conflict &&
+ mk_test testrepo heads/branch/conflict &&
+ git branch -D branch/conflict &&
+ git branch branch &&
+ git push testrepo :refs/heads/branch/conflict refs/heads/branch
+'
+
test_done
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 63c9a8f04b..0e0019347e 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -472,6 +472,66 @@ test_expect_success 'pull --no-autostash & merge.autostash unset' '
test_pull_autostash_fail --no-autostash --no-rebase
'
+test_expect_success 'pull succeeds with dirty working directory and pull.autostash=true' '
+ test_config pull.autostash true &&
+ test_pull_autostash 1 --rebase &&
+ test_pull_autostash 2 --no-rebase &&
+ test_pull_autostash 1 --autostash --rebase &&
+ test_pull_autostash 2 --autostash --no-rebase
+'
+
+test_expect_success 'pull fails with dirty working directory and pull.autostash=false' '
+ test_config pull.autostash false &&
+ test_pull_autostash_fail --rebase &&
+ test_pull_autostash_fail --no-rebase &&
+ test_pull_autostash_fail --no-autostash --rebase &&
+ test_pull_autostash_fail --no-autostash --no-rebase
+'
+
+test_expect_success 'pull --autostash overrides pull.autostash=false' '
+ test_config pull.autostash false &&
+ test_pull_autostash 1 --autostash --rebase &&
+ test_pull_autostash 2 --autostash --no-rebase
+'
+
+test_expect_success 'pull --no-autostash overrides pull.autostash=true' '
+ test_config pull.autostash true &&
+ test_pull_autostash_fail --no-autostash --rebase &&
+ test_pull_autostash_fail --no-autostash --no-rebase
+'
+
+test_expect_success 'pull.autostash=true overrides rebase.autostash' '
+ test_config pull.autostash true &&
+ test_config rebase.autostash true &&
+ test_pull_autostash 1 --rebase &&
+ test_config rebase.autostash false &&
+ test_pull_autostash 1 --rebase
+'
+
+test_expect_success 'pull.autostash=false overrides rebase.autostash' '
+ test_config pull.autostash false &&
+ test_config rebase.autostash true &&
+ test_pull_autostash_fail --rebase &&
+ test_config rebase.autostash false &&
+ test_pull_autostash_fail --rebase
+'
+
+test_expect_success 'pull.autostash=true overrides merge.autostash' '
+ test_config pull.autostash true &&
+ test_config merge.autostash true &&
+ test_pull_autostash 2 --no-rebase &&
+ test_config merge.autostash false &&
+ test_pull_autostash 2 --no-rebase
+'
+
+test_expect_success 'pull.autostash=false overrides merge.autostash' '
+ test_config pull.autostash false &&
+ test_config merge.autostash true &&
+ test_pull_autostash_fail --no-rebase &&
+ test_config merge.autostash false &&
+ test_pull_autostash_fail --no-rebase
+'
+
test_expect_success 'pull.rebase' '
git reset --hard before-rebase &&
test_config pull.rebase true &&
diff --git a/t/t5538-push-shallow.sh b/t/t5538-push-shallow.sh
index e91fcc173e..dc0e972943 100755
--- a/t/t5538-push-shallow.sh
+++ b/t/t5538-push-shallow.sh
@@ -123,4 +123,45 @@ EOF
git cat-file blob $(echo 1|git hash-object --stdin) >/dev/null
)
'
+
+test_expect_success 'push new commit from shallow clone has correct object count' '
+ git init origin &&
+ test_commit -C origin a &&
+ test_commit -C origin b &&
+
+ git clone --depth=1 "file://$(pwd)/origin" client &&
+ git -C client checkout -b topic &&
+ git -C client commit --allow-empty -m "empty" &&
+ GIT_PROGRESS_DELAY=0 git -C client push --progress origin topic 2>err &&
+ test_grep "Enumerating objects: 1, done." err
+'
+
+test_expect_success 'push new commit from shallow clone has good deltas' '
+ git init base &&
+ test_seq 1 999 >base/a &&
+ test_commit -C base initial &&
+ git -C base add a &&
+ git -C base commit -m "big a" &&
+
+ git clone --depth=1 "file://$(pwd)/base" deltas &&
+ git -C deltas checkout -b deltas &&
+ test_seq 1 1000 >deltas/a &&
+ git -C deltas commit -a -m "bigger a" &&
+ GIT_PROGRESS_DELAY=0 git -C deltas push --progress origin deltas 2>err &&
+
+ test_grep "Enumerating objects: 5, done" err &&
+
+ # If the delta base is found, then this message uses "bytes".
+ # If the delta base is not found, then this message uses "KiB".
+ test_grep "Writing objects: .* bytes" err &&
+
+ git -C deltas commit --amend -m "changed message" &&
+ GIT_TRACE2_EVENT="$(pwd)/config-push.txt" \
+ GIT_PROGRESS_DELAY=0 git -C deltas -c pack.usePathWalk=true \
+ push --progress -f origin deltas 2>err &&
+
+ test_grep "Enumerating objects: 1, done" err &&
+ test_region pack-objects path-walk config-push.txt
+'
+
test_done
diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh
index 9b211a626b..7a0943bd36 100755
--- a/t/t5558-clone-bundle-uri.sh
+++ b/t/t5558-clone-bundle-uri.sh
@@ -1279,6 +1279,29 @@ test_expect_success 'bundles are downloaded once during fetch --all' '
trace-mult.txt >bundle-fetches &&
test_line_count = 1 bundle-fetches
'
+
+test_expect_success 'bundles with space in URI are rejected' '
+ test_when_finished "rm -rf busted repo" &&
+ mkdir -p "$HOME/busted/ /$HOME/repo/.git/objects/bundles" &&
+ git clone --bundle-uri="$HTTPD_URL/bogus $HOME/busted/" "$HTTPD_URL/smart/fetch.git" repo 2>err &&
+ test_grep "error: bundle-uri: URI is malformed: " err &&
+ find busted -type f >files &&
+ test_must_be_empty files
+'
+
+test_expect_success 'bundles with newline in URI are rejected' '
+ test_when_finished "rm -rf busted repo" &&
+ git clone --bundle-uri="$HTTPD_URL/bogus\nget $HTTPD_URL/bogus $HOME/busted" "$HTTPD_URL/smart/fetch.git" repo 2>err &&
+ test_grep "error: bundle-uri: URI is malformed: " err &&
+ test_path_is_missing "$HOME/busted"
+'
+
+test_expect_success 'bundles with newline in target path are rejected' '
+ git clone --bundle-uri="$HTTPD_URL/bogus" "$HTTPD_URL/smart/fetch.git" "$(printf "escape\nget $HTTPD_URL/bogus .")" 2>err &&
+ test_grep "error: bundle-uri: filename is malformed: " err &&
+ test_path_is_missing escape
+'
+
# Do not add tests here unless they use the HTTP server, as they will
# not run unless the HTTP dependencies exist.
diff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh
index 9cbe7ca782..f14c0fb30e 100755
--- a/t/t6422-merge-rename-corner-cases.sh
+++ b/t/t6422-merge-rename-corner-cases.sh
@@ -1146,10 +1146,7 @@ test_conflicts_with_adds_and_renames() {
cd simple_${sideL}_${sideR} &&
# Create some related files now
- for i in $(test_seq 1 10)
- do
- echo Random base content line $i
- done >file_v1 &&
+ test_seq -f "Random base content line %d" 1 10 >file_v1 &&
cp file_v1 file_v2 &&
echo modification >>file_v2 &&
@@ -1293,10 +1290,7 @@ test_setup_nested_conflicts_from_rename_rename () {
cd nested_conflicts_from_rename_rename &&
# Create some related files now
- for i in $(test_seq 1 10)
- do
- echo Random base content line $i
- done >file_v1 &&
+ test_seq -f "Random base content line %d" 1 10 >file_v1 &&
cp file_v1 file_v2 &&
cp file_v1 file_v3 &&
diff --git a/t/t6601-path-walk.sh b/t/t6601-path-walk.sh
index 8d187f7279..56bd1e3c5b 100755
--- a/t/t6601-path-walk.sh
+++ b/t/t6601-path-walk.sh
@@ -376,6 +376,26 @@ test_expect_success 'topic, not base, boundary with pruning' '
test_cmp_sorted expect out
'
+test_expect_success 'topic, not base, --edge-aggressive with pruning' '
+ test-tool path-walk --prune --edge-aggressive -- topic --not base >out &&
+
+ cat >expect <<-EOF &&
+ 0:commit::$(git rev-parse topic)
+ 1:tree::$(git rev-parse topic^{tree})
+ 1:tree::$(git rev-parse base^{tree}):UNINTERESTING
+ 2:tree:right/:$(git rev-parse topic:right)
+ 2:tree:right/:$(git rev-parse base:right):UNINTERESTING
+ 3:blob:right/c:$(git rev-parse base:right/c):UNINTERESTING
+ 3:blob:right/c:$(git rev-parse topic:right/c)
+ blobs:2
+ commits:1
+ tags:0
+ trees:4
+ EOF
+
+ test_cmp_sorted expect out
+'
+
test_expect_success 'trees are reported exactly once' '
test_when_finished "rm -rf unique-trees" &&
test_create_repo unique-trees &&
diff --git a/t/t7007-show.sh b/t/t7007-show.sh
index d6cc69e0f2..2d322b53d1 100755
--- a/t/t7007-show.sh
+++ b/t/t7007-show.sh
@@ -167,4 +167,28 @@ test_expect_success 'show --graph is forbidden' '
test_must_fail git show --graph HEAD
'
+test_expect_success 'show unmerged index' '
+ git reset --hard &&
+
+ git switch -C base &&
+ echo "base" >conflicting &&
+ git add conflicting &&
+ git commit -m "base" &&
+
+ git branch hello &&
+ git branch goodbye &&
+
+ git switch hello &&
+ echo "hello" >conflicting &&
+ git commit -am "hello" &&
+
+ git switch goodbye &&
+ echo "goodbye" >conflicting &&
+ git commit -am "goodbye" &&
+
+ git switch hello &&
+ test_must_fail git merge goodbye &&
+ git show --merge HEAD
+'
+
test_done
diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh
index 9c3cc4cf40..66c3ec2da2 100755
--- a/t/t7401-submodule-summary.sh
+++ b/t/t7401-submodule-summary.sh
@@ -38,10 +38,11 @@ commit_file () {
git commit "$@" -m "Commit $*" >/dev/null
}
-test_create_repo sm1 &&
-add_file . foo >/dev/null
-
-head1=$(add_file sm1 foo1 foo2)
+test_expect_success 'setup submodule' '
+ git init sm1 &&
+ add_file . foo &&
+ head1=$(add_file sm1 foo1 foo2)
+'
test_expect_success 'added submodule' "
git add sm1 &&
@@ -214,9 +215,12 @@ test_expect_success 'typechanged submodule(submodule->blob)' "
test_cmp expected actual
"
-rm -f sm1 &&
-test_create_repo sm1 &&
-head6=$(add_file sm1 foo6 foo7)
+test_expect_success 'setup submodule' '
+ rm -f sm1 &&
+ git init sm1 &&
+ head6=$(add_file sm1 foo6 foo7)
+'
+
test_expect_success 'nonexistent commit' "
git submodule summary >actual &&
cat >expected <<-EOF &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index c562bad042..3adab12091 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -1095,12 +1095,15 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s
(cd super5 &&
# This test var can mess with the stderr output checked in this test.
GIT_TEST_NAME_HASH_VERSION=1 \
+ GIT_TEST_PACK_PATH_WALK=0 \
git submodule update --quiet --init --depth=1 submodule3 >out 2>err &&
test_must_be_empty out &&
test_must_be_empty err
) &&
git clone super4 super6 &&
(cd super6 &&
+ # This test variable will create a "warning" message to stderr
+ GIT_TEST_PACK_PATH_WALK=0 \
git submodule update --init --depth=1 submodule3 >out 2>err &&
test_file_not_empty out &&
test_file_not_empty err
@@ -1134,6 +1137,67 @@ test_expect_success 'setup clean recursive superproject' '
git clone --recurse-submodules top top-clean
'
+test_expect_success 'submodule update with multiple remotes' '
+ test_when_finished "rm -fr top-cloned" &&
+ cp -r top-clean top-cloned &&
+
+ # Create a commit in each repo, starting with bottom
+ test_commit -C bottom multiple_remote_commit &&
+ # Create middle commit
+ git -C middle/bottom fetch &&
+ git -C middle/bottom checkout -f FETCH_HEAD &&
+ git -C middle add bottom &&
+ git -C middle commit -m "multiple_remote_commit" &&
+ # Create top commit
+ git -C top/middle fetch &&
+ git -C top/middle checkout -f FETCH_HEAD &&
+ git -C top add middle &&
+ git -C top commit -m "multiple_remote_commit" &&
+
+ # rename the submodule remote
+ git -C top-cloned/middle remote rename origin upstream &&
+
+ # Add another remote
+ git -C top-cloned/middle remote add other bogus &&
+
+ # Make the update of "middle" a no-op, otherwise we error out
+ # because of its unmerged state
+ test_config -C top-cloned submodule.middle.update !true &&
+ git -C top-cloned submodule update --recursive 2>actual.err &&
+ cat >expect.err <<-\EOF &&
+ EOF
+ test_cmp expect.err actual.err
+'
+
+test_expect_success 'submodule update with renamed remote' '
+ test_when_finished "rm -fr top-cloned" &&
+ cp -r top-clean top-cloned &&
+
+ # Create a commit in each repo, starting with bottom
+ test_commit -C bottom rename_commit &&
+ # Create middle commit
+ git -C middle/bottom fetch &&
+ git -C middle/bottom checkout -f FETCH_HEAD &&
+ git -C middle add bottom &&
+ git -C middle commit -m "rename_commit" &&
+ # Create top commit
+ git -C top/middle fetch &&
+ git -C top/middle checkout -f FETCH_HEAD &&
+ git -C top add middle &&
+ git -C top commit -m "rename_commit" &&
+
+ # rename the submodule remote
+ git -C top-cloned/middle remote rename origin upstream &&
+
+ # Make the update of "middle" a no-op, otherwise we error out
+ # because of its unmerged state
+ test_config -C top-cloned submodule.middle.update !true &&
+ git -C top-cloned submodule update --recursive 2>actual.err &&
+ cat >expect.err <<-\EOF &&
+ EOF
+ test_cmp expect.err actual.err
+'
+
test_expect_success 'submodule update should skip unmerged submodules' '
test_when_finished "rm -fr top-cloned" &&
cp -r top-clean top-cloned &&
diff --git a/t/t7422-submodule-output.sh b/t/t7422-submodule-output.sh
index 023a5cbdc4..aea1ddf117 100755
--- a/t/t7422-submodule-output.sh
+++ b/t/t7422-submodule-output.sh
@@ -180,17 +180,14 @@ test_expect_success !MINGW 'git submodule status --recursive propagates SIGPIPE'
COMMIT=$(git rev-parse HEAD) &&
for i in $(test_seq 2000)
do
- printf "[submodule \"sm-$i\"]\npath = recursive-submodule-path-$i\n" "$i" ||
+ echo "[submodule \"sm-$i\"]" &&
+ echo "path = recursive-submodule-path-$i" ||
return 1
done >gitmodules &&
BLOB=$(git hash-object -w --stdin <gitmodules) &&
printf "100644 blob $BLOB\t.gitmodules\n" >tree &&
- for i in $(test_seq 2000)
- do
- printf "160000 commit $COMMIT\trecursive-submodule-path-%d\n" "$i" ||
- return 1
- done >>tree &&
+ test_seq -f "160000 commit $COMMIT\trecursive-submodule-path-%d" 2000 >>tree &&
TREE=$(git mktree <tree) &&
COMMIT=$(git commit-tree "$TREE") &&
diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh
index 9367794641..14b5743b96 100755
--- a/t/t7450-bad-git-dotfiles.sh
+++ b/t/t7450-bad-git-dotfiles.sh
@@ -372,4 +372,37 @@ test_expect_success 'checkout -f --recurse-submodules must not use a nested gitd
test_path_is_missing nested_checkout/thing2/.git
'
+test_expect_success SYMLINKS,!WINDOWS,!MINGW 'submodule must not checkout into different directory' '
+ test_when_finished "rm -rf sub repo bad-clone" &&
+
+ git init sub &&
+ write_script sub/post-checkout <<-\EOF &&
+ touch "$PWD/foo"
+ EOF
+ git -C sub add post-checkout &&
+ git -C sub commit -m hook &&
+
+ git init repo &&
+ git -C repo -c protocol.file.allow=always submodule add "$PWD/sub" sub &&
+ git -C repo mv sub $(printf "sub\r") &&
+
+ # Ensure config values containing CR are wrapped in quotes.
+ git config unset -f repo/.gitmodules submodule.sub.path &&
+ printf "\tpath = \"sub\r\"\n" >>repo/.gitmodules &&
+
+ git config unset -f repo/.git/modules/sub/config core.worktree &&
+ {
+ printf "[core]\n" &&
+ printf "\tworktree = \"../../../sub\r\"\n"
+ } >>repo/.git/modules/sub/config &&
+
+ ln -s .git/modules/sub/hooks repo/sub &&
+ git -C repo add -A &&
+ git -C repo commit -m submodule &&
+
+ git -c protocol.file.allow=always clone --recurse-submodules repo bad-clone &&
+ ! test -f "$PWD/foo" &&
+ test -f $(printf "bad-clone/sub\r/post-checkout")
+'
+
test_done
diff --git a/t/t7528-signed-commit-ssh.sh b/t/t7528-signed-commit-ssh.sh
index 065f780636..0f887a3ebe 100755
--- a/t/t7528-signed-commit-ssh.sh
+++ b/t/t7528-signed-commit-ssh.sh
@@ -84,18 +84,26 @@ test_expect_success GPGSSH 'sign commits using literal public keys with ssh-agen
test_config gpg.format ssh &&
eval $(ssh-agent) &&
test_when_finished "kill ${SSH_AGENT_PID}" &&
- ssh-add "${GPGSSH_KEY_PRIMARY}" &&
- echo 1 >file && git add file &&
- git commit -a -m rsa-inline -S"$(cat "${GPGSSH_KEY_PRIMARY}.pub")" &&
- echo 2 >file &&
- test_config user.signingkey "$(cat "${GPGSSH_KEY_PRIMARY}.pub")" &&
- git commit -a -m rsa-config -S &&
- ssh-add "${GPGSSH_KEY_ECDSA}" &&
- echo 3 >file &&
- git commit -a -m ecdsa-inline -S"key::$(cat "${GPGSSH_KEY_ECDSA}.pub")" &&
- echo 4 >file &&
- test_config user.signingkey "key::$(cat "${GPGSSH_KEY_ECDSA}.pub")" &&
- git commit -a -m ecdsa-config -S
+ test_when_finished "test_unconfig user.signingkey" &&
+ mkdir tmpdir &&
+ TMPDIR="$(pwd)/tmpdir" &&
+ (
+ export TMPDIR &&
+ ssh-add "${GPGSSH_KEY_PRIMARY}" &&
+ echo 1 >file && git add file &&
+ git commit -a -m rsa-inline -S"$(cat "${GPGSSH_KEY_PRIMARY}.pub")" &&
+ echo 2 >file &&
+ git config user.signingkey "$(cat "${GPGSSH_KEY_PRIMARY}.pub")" &&
+ git commit -a -m rsa-config -S &&
+ ssh-add "${GPGSSH_KEY_ECDSA}" &&
+ echo 3 >file &&
+ git commit -a -m ecdsa-inline -S"key::$(cat "${GPGSSH_KEY_ECDSA}.pub")" &&
+ echo 4 >file &&
+ git config user.signingkey "key::$(cat "${GPGSSH_KEY_ECDSA}.pub")" &&
+ git commit -a -m ecdsa-config -S
+ ) &&
+ find tmpdir -type f >tmpfiles &&
+ test_must_be_empty tmpfiles
'
test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'create signed commits with keys having defined lifetimes' '
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 2a8df29219..9838094b66 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -185,8 +185,19 @@ test_expect_success 'reject non-strategy with a git-merge-foo name' '
test_expect_success 'merge c0 with c1' '
echo "OBJID HEAD@{0}: merge c1: Fast-forward" >reflog.expected &&
+ cat >expect <<-\EOF &&
+ Updating FROM..TO
+ Fast-forward
+ file | 2 +-
+ other | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+ create mode 100644 other
+ EOF
+
git reset --hard c0 &&
- git merge c1 &&
+ git merge c1 >out &&
+ sed -e "1s/^Updating [0-9a-f.]*/Updating FROM..TO/" out >actual &&
+ test_cmp expect actual &&
verify_merge file result.1 &&
verify_head "$c1" &&
@@ -205,6 +216,67 @@ test_expect_success 'merge c0 with c1 with --ff-only' '
verify_head "$c1"
'
+test_expect_success 'the same merge with merge.stat=diffstat' '
+ cat >expect <<-\EOF &&
+ Updating FROM..TO
+ Fast-forward
+ file | 2 +-
+ other | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+ create mode 100644 other
+ EOF
+
+ git reset --hard c0 &&
+ git -c merge.stat=diffstat merge c1 >out &&
+ sed -e "1s/^Updating [0-9a-f.]*/Updating FROM..TO/" out >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'the same merge with compact summary' '
+ cat >expect <<-\EOF &&
+ Updating FROM..TO
+ Fast-forward
+ file | 2 +-
+ other (new) | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+ EOF
+
+ git reset --hard c0 &&
+ git merge --compact-summary c1 >out &&
+ sed -e "1s/^Updating [0-9a-f.]*/Updating FROM..TO/" out >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'the same merge with compact summary' '
+ cat >expect <<-\EOF &&
+ Updating FROM..TO
+ Fast-forward
+ file | 2 +-
+ other (new) | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+ EOF
+
+ git reset --hard c0 &&
+ git merge --compact-summary c1 >out &&
+ sed -e "1s/^Updating [0-9a-f.]*/Updating FROM..TO/" out >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'the same merge with merge.stat=compact' '
+ cat >expect <<-\EOF &&
+ Updating FROM..TO
+ Fast-forward
+ file | 2 +-
+ other (new) | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+ EOF
+
+ git reset --hard c0 &&
+ git -c merge.stat=compact merge c1 >out &&
+ sed -e "1s/^Updating [0-9a-f.]*/Updating FROM..TO/" out >actual &&
+ test_cmp expect actual
+'
+
test_debug 'git log --graph --decorate --oneline --all'
test_expect_success 'merge from unborn branch' '
diff --git a/t/t7704-repack-cruft.sh b/t/t7704-repack-cruft.sh
index 8aebfb45f5..aa2e2e6ad8 100755
--- a/t/t7704-repack-cruft.sh
+++ b/t/t7704-repack-cruft.sh
@@ -724,4 +724,149 @@ test_expect_success 'cruft repack respects --quiet' '
)
'
+setup_cruft_exclude_tests() {
+ git init "$1" &&
+ (
+ cd "$1" &&
+
+ git config repack.midxMustContainCruft false &&
+
+ test_commit one &&
+
+ test_commit --no-tag two &&
+ two="$(git rev-parse HEAD)" &&
+ test_commit --no-tag three &&
+ three="$(git rev-parse HEAD)" &&
+ git reset --hard one &&
+ git reflog expire --all --expire=all &&
+
+ GIT_TEST_MULTI_PACK_INDEX=0 git repack --cruft -d &&
+
+ git merge $two &&
+ test_commit four
+ )
+}
+
+test_expect_success 'repack --write-midx excludes cruft where possible' '
+ setup_cruft_exclude_tests exclude-cruft-when-possible &&
+ (
+ cd exclude-cruft-when-possible &&
+
+ GIT_TEST_MULTI_PACK_INDEX=0 \
+ git repack -d --geometric=2 --write-midx --write-bitmap-index &&
+
+ test-tool read-midx --show-objects $objdir >midx &&
+ cruft="$(ls $packdir/*.mtimes)" &&
+ test_grep ! "$(basename "$cruft" .mtimes).idx" midx &&
+
+ git rev-list --all --objects --no-object-names >reachable.raw &&
+ sort reachable.raw >reachable.objects &&
+ awk "/\.pack$/ { print \$1 }" <midx | sort >midx.objects &&
+
+ test_cmp reachable.objects midx.objects
+ )
+'
+
+test_expect_success 'repack --write-midx includes cruft when instructed' '
+ setup_cruft_exclude_tests exclude-cruft-when-instructed &&
+ (
+ cd exclude-cruft-when-instructed &&
+
+ GIT_TEST_MULTI_PACK_INDEX=0 \
+ git -c repack.midxMustContainCruft=true repack \
+ -d --geometric=2 --write-midx --write-bitmap-index &&
+
+ test-tool read-midx --show-objects $objdir >midx &&
+ cruft="$(ls $packdir/*.mtimes)" &&
+ test_grep "$(basename "$cruft" .mtimes).idx" midx &&
+
+ git cat-file --batch-check="%(objectname)" --batch-all-objects \
+ >all.objects &&
+ awk "/\.pack$/ { print \$1 }" <midx | sort >midx.objects &&
+
+ test_cmp all.objects midx.objects
+ )
+'
+
+test_expect_success 'repack --write-midx includes cruft when necessary' '
+ setup_cruft_exclude_tests exclude-cruft-when-necessary &&
+ (
+ cd exclude-cruft-when-necessary &&
+
+ test_path_is_file $(ls $packdir/pack-*.mtimes) &&
+ ( cd $packdir && ls pack-*.idx ) | sort >packs.all &&
+ git multi-pack-index write --stdin-packs --bitmap <packs.all &&
+
+ test_commit five &&
+ GIT_TEST_MULTI_PACK_INDEX=0 \
+ git repack -d --geometric=2 --write-midx --write-bitmap-index &&
+
+ test-tool read-midx --show-objects $objdir >midx &&
+ awk "/\.pack$/ { print \$1 }" <midx | sort >midx.objects &&
+ git cat-file --batch-all-objects --batch-check="%(objectname)" \
+ >expect.objects &&
+ test_cmp expect.objects midx.objects &&
+
+ grep "^pack-" midx >midx.packs &&
+ test_line_count = "$(($(wc -l <packs.all) + 1))" midx.packs
+ )
+'
+
+test_expect_success 'repack --write-midx includes cruft when already geometric' '
+ git init repack--write-midx-geometric-noop &&
+ (
+ cd repack--write-midx-geometric-noop &&
+
+ git branch -M main &&
+ test_commit A &&
+ test_commit B &&
+
+ git checkout -B side &&
+ test_commit --no-tag C &&
+ C="$(git rev-parse HEAD)" &&
+
+ git checkout main &&
+ git branch -D side &&
+ git reflog expire --all --expire=all &&
+
+ # At this point we have two packs: one containing the
+ # objects belonging to commits A and B, and another
+ # (cruft) pack containing the objects belonging to
+ # commit C.
+ git repack --cruft -d &&
+
+ # Create a third pack which contains a merge commit
+ # making commit C reachable again.
+ #
+ # --no-ff is important here, as it ensures that we
+ # actually write a new object and subsequently a new
+ # pack to contain it.
+ git merge --no-ff $C &&
+ git repack -d &&
+
+ ls $packdir/pack-*.idx | sort >packs.all &&
+ cruft="$(ls $packdir/pack-*.mtimes)" &&
+ cruft="${cruft%.mtimes}.idx" &&
+
+ for idx in $(grep -v $cruft <packs.all)
+ do
+ git show-index <$idx >out &&
+ wc -l <out || return 1
+ done >sizes.raw &&
+
+ # Make sure that there are two non-cruft packs, and
+ # that one of them contains at least twice as many
+ # objects as the other, ensuring that they are already
+ # in a geometric progression.
+ sort -n sizes.raw >sizes &&
+ test_line_count = 2 sizes &&
+ s1=$(head -n 1 sizes) &&
+ s2=$(tail -n 1 sizes) &&
+ test "$s2" -gt "$((2 * $s1))" &&
+
+ git -c repack.midxMustContainCruft=false repack --geometric=2 \
+ --write-midx --write-bitmap-index
+ )
+'
+
test_done
diff --git a/t/t7815-grep-binary.sh b/t/t7815-grep-binary.sh
index b7d83f9a5d..55d5e6de17 100755
--- a/t/t7815-grep-binary.sh
+++ b/t/t7815-grep-binary.sh
@@ -63,7 +63,7 @@ test_expect_success 'git grep ile a' '
git grep ile a
'
-test_expect_failure !CYGWIN 'git grep .fi a' '
+test_expect_failure !CYGWIN,!MACOS 'git grep .fi a' '
git grep .fi a
'
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index 8cf89e285f..ddd273d8dc 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -49,9 +49,9 @@ test_expect_success 'run [--auto|--quiet]' '
git maintenance run --auto 2>/dev/null &&
GIT_TRACE2_EVENT="$(pwd)/run-no-quiet.txt" \
git maintenance run --no-quiet 2>/dev/null &&
- test_subcommand git gc --quiet --no-detach <run-no-auto.txt &&
- test_subcommand ! git gc --auto --quiet --no-detach <run-auto.txt &&
- test_subcommand git gc --no-quiet --no-detach <run-no-quiet.txt
+ test_subcommand git gc --quiet --no-detach --skip-foreground-tasks <run-no-auto.txt &&
+ test_subcommand ! git gc --auto --quiet --no-detach --skip-foreground-tasks <run-auto.txt &&
+ test_subcommand git gc --no-quiet --no-detach --skip-foreground-tasks <run-no-quiet.txt
'
test_expect_success 'maintenance.auto config option' '
@@ -154,9 +154,9 @@ test_expect_success 'run --task=<task>' '
git maintenance run --task=commit-graph 2>/dev/null &&
GIT_TRACE2_EVENT="$(pwd)/run-both.txt" \
git maintenance run --task=commit-graph --task=gc 2>/dev/null &&
- test_subcommand ! git gc --quiet --no-detach <run-commit-graph.txt &&
- test_subcommand git gc --quiet --no-detach <run-gc.txt &&
- test_subcommand git gc --quiet --no-detach <run-both.txt &&
+ test_subcommand ! git gc --quiet --no-detach --skip-foreground-tasks <run-commit-graph.txt &&
+ test_subcommand git gc --quiet --no-detach --skip-foreground-tasks <run-gc.txt &&
+ test_subcommand git gc --quiet --no-detach --skip-foreground-tasks <run-both.txt &&
test_subcommand git commit-graph write --split --reachable --no-progress <run-commit-graph.txt &&
test_subcommand ! git commit-graph write --split --reachable --no-progress <run-gc.txt &&
test_subcommand git commit-graph write --split --reachable --no-progress <run-both.txt
@@ -610,7 +610,12 @@ test_expect_success 'rerere-gc task with --auto honors maintenance.rerere-gc.aut
test_expect_success '--auto and --schedule incompatible' '
test_must_fail git maintenance run --auto --schedule=daily 2>err &&
- test_grep "at most one" err
+ test_grep "cannot be used together" err
+'
+
+test_expect_success '--task and --schedule incompatible' '
+ test_must_fail git maintenance run --task=pack-refs --schedule=daily 2>err &&
+ test_grep "cannot be used together" err
'
test_expect_success 'invalid --schedule value' '
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 0c1af43f6f..e56e0c8d77 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -201,6 +201,13 @@ test_expect_success $PREREQ 'cc trailer with get_maintainer.pl output' '
test_cmp expected-cc commandline1
'
+test_expect_failure $PREREQ 'invalid smtp server port value' '
+ clean_fake_sendmail &&
+ git send-email -1 --to=recipient@example.com \
+ --smtp-server-port=bogus-symbolic-name \
+ --smtp-server="$(pwd)/fake.sendmail"
+'
+
test_expect_success $PREREQ 'setup expect' "
cat >expected-show-all-headers <<\EOF
0001-Second.patch
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index b258dbf1df..4dc3d645bf 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -120,7 +120,7 @@ test_expect_success 'A: create pack from stdin' '
INPUT_END
git fast-import --export-marks=marks.out <input &&
- git whatchanged main
+ git log --raw main
'
test_expect_success 'A: verify pack' '
@@ -279,7 +279,7 @@ test_expect_success 'A: verify marks import does not crash' '
INPUT_END
git fast-import --import-marks=marks.out <input &&
- git whatchanged verify--import-marks
+ git log --raw verify--import-marks
'
test_expect_success 'A: verify pack' '
@@ -652,7 +652,7 @@ test_expect_success 'C: incremental import create pack from stdin' '
INPUT_END
git fast-import <input &&
- git whatchanged branch
+ git log --raw branch
'
test_expect_success 'C: verify pack' '
@@ -715,7 +715,7 @@ test_expect_success 'D: inline data in commit' '
INPUT_END
git fast-import <input &&
- git whatchanged branch
+ git log --raw branch
'
test_expect_success 'D: verify pack' '
@@ -882,7 +882,7 @@ test_expect_success 'H: deletall, add 1' '
INPUT_END
git fast-import <input &&
- git whatchanged H
+ git log --raw H
'
test_expect_success 'H: verify pack' '
@@ -2066,7 +2066,7 @@ test_expect_success 'Q: commit notes' '
INPUT_END
git fast-import <input &&
- git whatchanged notes-test
+ git log --raw notes-test
'
test_expect_success 'Q: verify pack' '
diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh
index 1ae4d7c0d3..e62173cf1f 100755
--- a/t/t9301-fast-import-notes.sh
+++ b/t/t9301-fast-import-notes.sh
@@ -76,7 +76,7 @@ INPUT_END
test_expect_success 'set up main branch' '
git fast-import <input &&
- git whatchanged main
+ git log --raw main
'
commit4=$(git rev-parse refs/heads/main)
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index dda9e7c3e7..46700dbc40 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -299,22 +299,10 @@ test_expect_success GPG 'set up signed commit' '
'
-test_expect_success GPG 'signed-commits default' '
-
- sane_unset FAST_EXPORT_SIGNED_COMMITS_NOABORT &&
- test_must_fail git fast-export --reencode=no commit-signing &&
-
- FAST_EXPORT_SIGNED_COMMITS_NOABORT=1 git fast-export --reencode=no commit-signing >output 2>err &&
- ! grep ^gpgsig output &&
- grep "^encoding ISO-8859-1" output &&
- test -s err &&
- sed "s/commit-signing/commit-strip-signing/" output | (
- cd new &&
- git fast-import &&
- STRIPPED=$(git rev-parse --verify refs/heads/commit-strip-signing) &&
- test $COMMIT_SIGNING != $STRIPPED
- )
-
+test_expect_success GPG 'signed-commits default is same as strip' '
+ git fast-export --reencode=no commit-signing >out1 2>err &&
+ git fast-export --reencode=no --signed-commits=strip commit-signing >out2 &&
+ test_cmp out1 out2
'
test_expect_success GPG 'signed-commits=abort' '
@@ -326,7 +314,7 @@ test_expect_success GPG 'signed-commits=abort' '
test_expect_success GPG 'signed-commits=verbatim' '
git fast-export --signed-commits=verbatim --reencode=no commit-signing >output &&
- grep "^gpgsig sha" output &&
+ test_grep -E "^gpgsig $GIT_DEFAULT_HASH openpgp" output &&
grep "encoding ISO-8859-1" output &&
(
cd new &&
@@ -340,7 +328,7 @@ test_expect_success GPG 'signed-commits=verbatim' '
test_expect_success GPG 'signed-commits=warn-verbatim' '
git fast-export --signed-commits=warn-verbatim --reencode=no commit-signing >output 2>err &&
- grep "^gpgsig sha" output &&
+ test_grep -E "^gpgsig $GIT_DEFAULT_HASH openpgp" output &&
grep "encoding ISO-8859-1" output &&
test -s err &&
(
@@ -381,6 +369,62 @@ test_expect_success GPG 'signed-commits=warn-strip' '
'
+test_expect_success GPGSM 'setup X.509 signed commit' '
+
+ git checkout -b x509-signing main &&
+ test_config gpg.format x509 &&
+ test_config user.signingkey $GIT_COMMITTER_EMAIL &&
+ echo "X.509 content" >file &&
+ git add file &&
+ git commit -S -m "X.509 signed commit" &&
+ X509_COMMIT=$(git rev-parse HEAD) &&
+ git checkout main
+
+'
+
+test_expect_success GPGSM 'round-trip X.509 signed commit' '
+
+ git fast-export --signed-commits=verbatim x509-signing >output &&
+ test_grep -E "^gpgsig $GIT_DEFAULT_HASH x509" output &&
+ (
+ cd new &&
+ git fast-import &&
+ git cat-file commit refs/heads/x509-signing >actual &&
+ grep "^gpgsig" actual &&
+ IMPORTED=$(git rev-parse refs/heads/x509-signing) &&
+ test $X509_COMMIT = $IMPORTED
+ ) <output
+
+'
+
+test_expect_success GPGSSH 'setup SSH signed commit' '
+
+ git checkout -b ssh-signing main &&
+ test_config gpg.format ssh &&
+ test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" &&
+ echo "SSH content" >file &&
+ git add file &&
+ git commit -S -m "SSH signed commit" &&
+ SSH_COMMIT=$(git rev-parse HEAD) &&
+ git checkout main
+
+'
+
+test_expect_success GPGSSH 'round-trip SSH signed commit' '
+
+ git fast-export --signed-commits=verbatim ssh-signing >output &&
+ test_grep -E "^gpgsig $GIT_DEFAULT_HASH ssh" output &&
+ (
+ cd new &&
+ git fast-import &&
+ git cat-file commit refs/heads/ssh-signing >actual &&
+ grep "^gpgsig" actual &&
+ IMPORTED=$(git rev-parse refs/heads/ssh-signing) &&
+ test $SSH_COMMIT = $IMPORTED
+ ) <output
+
+'
+
test_expect_success 'setup submodule' '
test_config_global protocol.file.allow always &&
@@ -917,4 +961,46 @@ test_expect_success 'fast-export handles --end-of-options' '
test_cmp expect actual
'
+test_expect_success GPG 'setup a commit with dual signatures on its SHA-1 and SHA-256 formats' '
+ # Create a signed SHA-256 commit
+ git init --object-format=sha256 explicit-sha256 &&
+ git -C explicit-sha256 config extensions.compatObjectFormat sha1 &&
+ git -C explicit-sha256 checkout -b dual-signed &&
+ test_commit -C explicit-sha256 A &&
+ echo B >explicit-sha256/B &&
+ git -C explicit-sha256 add B &&
+ test_tick &&
+ git -C explicit-sha256 commit -S -m "signed" B &&
+ SHA256_B=$(git -C explicit-sha256 rev-parse dual-signed) &&
+
+ # Create the corresponding SHA-1 commit
+ SHA1_B=$(git -C explicit-sha256 rev-parse --output-object-format=sha1 dual-signed) &&
+
+ # Check that the resulting SHA-1 commit has both signatures
+ echo $SHA1_B | git -C explicit-sha256 cat-file --batch >out &&
+ test_grep -E "^gpgsig " out &&
+ test_grep -E "^gpgsig-sha256 " out
+'
+
+test_expect_success GPG 'export and import of doubly signed commit' '
+ git -C explicit-sha256 fast-export --signed-commits=verbatim dual-signed >output &&
+ test_grep -E "^gpgsig sha1 openpgp" output &&
+ test_grep -E "^gpgsig sha256 openpgp" output &&
+
+ (
+ cd new &&
+ git fast-import &&
+ git cat-file commit refs/heads/dual-signed >actual &&
+ test_grep -E "^gpgsig " actual &&
+ test_grep -E "^gpgsig-sha256 " actual &&
+ IMPORTED=$(git rev-parse refs/heads/dual-signed) &&
+ if test "$GIT_DEFAULT_HASH" = "sha1"
+ then
+ test $SHA1_B = $IMPORTED
+ else
+ test $SHA256_B = $IMPORTED
+ fi
+ ) <output
+'
+
test_done
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 7679780fb8..578d6c8b32 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -700,19 +700,17 @@ test_expect_success \
# ----------------------------------------------------------------------
# syntax highlighting
+test_lazy_prereq HIGHLIGHT '
+ highlight_version=$(highlight --version </dev/null 2>/dev/null) &&
+ test -n "$highlight_version"
+'
-highlight_version=$(highlight --version </dev/null 2>/dev/null)
-if [ $? -eq 127 ]; then
- say "Skipping syntax highlighting tests: 'highlight' not found"
-elif test -z "$highlight_version"; then
- say "Skipping syntax highlighting tests: incorrect 'highlight' found"
-else
- test_set_prereq HIGHLIGHT
+test_expect_success HIGHLIGHT '
cat >>gitweb_config.perl <<-\EOF
our $highlight_bin = "highlight";
- $feature{'highlight'}{'override'} = 1;
+ $feature{"highlight"}{"override"} = 1;
EOF
-fi
+'
test_expect_success HIGHLIGHT \
'syntax highlighting (no highlight, unknown syntax)' \
diff --git a/t/t9822-git-p4-path-encoding.sh b/t/t9822-git-p4-path-encoding.sh
index 572d395498..e6e07facd4 100755
--- a/t/t9822-git-p4-path-encoding.sh
+++ b/t/t9822-git-p4-path-encoding.sh
@@ -7,12 +7,17 @@ test_description='Clone repositories with non ASCII paths'
UTF8_ESCAPED="a-\303\244_o-\303\266_u-\303\274.txt"
ISO8859_ESCAPED="a-\344_o-\366_u-\374.txt"
-ISO8859="$(printf "$ISO8859_ESCAPED")" &&
-echo content123 >"$ISO8859" &&
-rm "$ISO8859" || {
+test_lazy_prereq FS_ACCEPTS_ISO_8859_1 '
+ ISO8859="$(printf "$ISO8859_ESCAPED")" &&
+ echo content123 >"$ISO8859" &&
+ rm "$ISO8859"
+'
+
+if ! test_have_prereq FS_ACCEPTS_ISO_8859_1
+then
skip_all="fs does not accept ISO-8859-1 filenames"
test_done
-}
+fi
test_expect_success 'start p4d' '
start_p4d
diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh
index 6116f806f6..b969c7e0d5 100755
--- a/t/t9835-git-p4-metadata-encoding-python2.sh
+++ b/t/t9835-git-p4-metadata-encoding-python2.sh
@@ -12,23 +12,25 @@ failing, and produces maximally sane output in git.'
## SECTION REPEATED IN t9836 ##
###############################
+EXTRA_PATH="$(pwd)/temp_python"
+mkdir "$EXTRA_PATH"
+PATH="$EXTRA_PATH:$PATH"
+export PATH
+
# These tests are specific to Python 2. Write a custom script that executes
# git-p4 directly with the Python 2 interpreter to ensure that we use that
# version even if Git was compiled with Python 3.
-python_target_binary=$(which python2)
-if test -n "$python_target_binary"
-then
- mkdir temp_python
- PATH="$(pwd)/temp_python:$PATH"
- export PATH
-
- write_script temp_python/git-p4-python2 <<-EOF
+test_lazy_prereq P4_PYTHON2 '
+ python_target_binary=$(which python2) &&
+ test -n "$python_target_binary" &&
+ write_script "$EXTRA_PATH"/git-p4-python2 <<-EOF &&
exec "$python_target_binary" "$(git --exec-path)/git-p4" "\$@"
EOF
-fi
+ ( git p4-python2 || true ) >err &&
+ test_grep "valid commands" err
+'
-git p4-python2 >err
-if ! grep 'valid commands' err
+if ! test_have_prereq P4_PYTHON2
then
skip_all="skipping python2 git p4 tests; python2 not available"
test_done
diff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh
index 5e5217a66b..da6669bf71 100755
--- a/t/t9836-git-p4-metadata-encoding-python3.sh
+++ b/t/t9836-git-p4-metadata-encoding-python3.sh
@@ -12,23 +12,25 @@ failing, and produces maximally sane output in git.'
## SECTION REPEATED IN t9835 ##
###############################
+EXTRA_PATH="$(pwd)/temp_python"
+mkdir "$EXTRA_PATH"
+PATH="$EXTRA_PATH:$PATH"
+export PATH
+
# These tests are specific to Python 3. Write a custom script that executes
# git-p4 directly with the Python 3 interpreter to ensure that we use that
# version even if Git was compiled with Python 2.
-python_target_binary=$(which python3)
-if test -n "$python_target_binary"
-then
- mkdir temp_python
- PATH="$(pwd)/temp_python:$PATH"
- export PATH
-
- write_script temp_python/git-p4-python3 <<-EOF
+test_lazy_prereq P4_PYTHON3 '
+ python_target_binary=$(which python3) &&
+ test -n "$python_target_binary" &&
+ write_script "$EXTRA_PATH"/git-p4-python3 <<-EOF &&
exec "$python_target_binary" "$(git --exec-path)/git-p4" "\$@"
EOF
-fi
+ ( git p4-python3 || true ) >err &&
+ test_grep "valid commands" err
+'
-git p4-python3 >err
-if ! grep 'valid commands' err
+if ! test_have_prereq P4_PYTHON3
then
skip_all="skipping python3 git p4 tests; python3 not available"
test_done
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index d667dda654..637a6f13a6 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -66,10 +66,6 @@ test_expect_success 'prompt - unborn branch' '
test_cmp expected "$actual"
'
-if test_have_prereq !FUNNYNAMES; then
- say 'Your filesystem does not allow newlines in filenames.'
-fi
-
test_expect_success FUNNYNAMES 'prompt - with newline in path' '
repo_with_newline="repo
with
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index bee4a2ca34..a28de7b19b 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1451,9 +1451,21 @@ test_cmp_fspath () {
# test_seq 1 5 -- outputs 1 2 3 4 5 one line at a time
#
# or with one argument (end), in which case it starts counting
-# from 1.
+# from 1. In addition to the start/end arguments, you can pass an optional
+# printf format. For example:
+#
+# test_seq -f "line %d" 1 5
+#
+# would print 5 lines, "line 1" through "line 5".
test_seq () {
+ local fmt="%d"
+ case "$1" in
+ -f)
+ fmt="$2"
+ shift 2
+ ;;
+ esac
case $# in
1) set 1 "$@" ;;
2) ;;
@@ -1462,7 +1474,7 @@ test_seq () {
test_seq_counter__=$1
while test "$test_seq_counter__" -le "$2"
do
- echo "$test_seq_counter__"
+ printf "$fmt\n" "$test_seq_counter__"
test_seq_counter__=$(( $test_seq_counter__ + 1 ))
done
}
@@ -1695,7 +1707,7 @@ test_set_hash () {
# Detect the hash algorithm in use.
test_detect_hash () {
- case "$GIT_TEST_DEFAULT_HASH" in
+ case "${GIT_TEST_DEFAULT_HASH:-$GIT_TEST_BUILTIN_HASH}" in
"sha256")
test_hash_algo=sha256
test_compat_hash_algo=sha1
@@ -1767,6 +1779,9 @@ test_oid () {
--hash=compat)
algo="$test_compat_hash_algo" &&
shift;;
+ --hash=builtin)
+ algo="$GIT_TEST_BUILTIN_HASH" &&
+ shift;;
--hash=*)
algo="${1#--hash=}" &&
shift;;
diff --git a/t/test-lib.sh b/t/test-lib.sh
index af722d383d..621cd31ae1 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -134,7 +134,8 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
################################################################
# It appears that people try to run tests without building...
-"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null
+GIT_BINARY="${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X"
+"$GIT_BINARY" >/dev/null
if test $? != 1
then
if test -n "$GIT_TEST_INSTALLED"
@@ -470,7 +471,7 @@ then
then
: Executed by a Bash version supporting BASH_XTRACEFD. Good.
else
- echo >&2 "warning: ignoring -x; '$0' is untraceable without BASH_XTRACEFD"
+ echo >&2 "# warning: ignoring -x; '$0' is untraceable without BASH_XTRACEFD"
trace=
fi
fi
@@ -536,7 +537,8 @@ export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
export EDITOR
-GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-sha1}"
+GIT_TEST_BUILTIN_HASH=$("$GIT_BINARY" version --build-options | sed -ne 's/^default-hash: //p')
+GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-$GIT_TEST_BUILTIN_HASH}"
export GIT_DEFAULT_HASH
GIT_DEFAULT_REF_FORMAT="${GIT_TEST_DEFAULT_REF_FORMAT:-files}"
export GIT_DEFAULT_REF_FORMAT
@@ -707,7 +709,7 @@ then
exec 3>>"$GIT_TEST_TEE_OUTPUT_FILE" 4>&3
elif test "$verbose" = "t"
then
- exec 4>&2 3>&1
+ exec 4>&2 3>&2
else
exec 4>/dev/null 3>/dev/null
fi
@@ -949,7 +951,7 @@ maybe_setup_verbose () {
test -z "$verbose_only" && return
if match_pattern_list $test_count "$verbose_only"
then
- exec 4>&2 3>&1
+ exec 4>&2 3>&2
# Emit a delimiting blank line when going from
# non-verbose to verbose. Within verbose mode the
# delimiter is printed by test_expect_*. The choice
@@ -1272,7 +1274,14 @@ test_done () {
check_test_results_san_file_ "$test_failure"
- if test -z "$skip_all" && test -n "$invert_exit_code"
+ if test "$test_fixed" != 0
+ then
+ if test -z "$invert_exit_code"
+ then
+ GIT_EXIT_OK=t
+ exit 1
+ fi
+ elif test -z "$skip_all" && test -n "$invert_exit_code"
then
say_color warn "# faking up non-zero exit with --invert-exit-code"
GIT_EXIT_OK=t
@@ -1577,6 +1586,8 @@ fi
# Use -P to resolve symlinks in our working directory so that the cwd
# in subprocesses like git equals our $PWD (for pathname comparisons).
cd -P "$TRASH_DIRECTORY" || BAIL_OUT "cannot cd -P to \"$TRASH_DIRECTORY\""
+TRASH_DIRECTORY=$(pwd)
+HOME="$TRASH_DIRECTORY"
start_test_output "$0"
@@ -1636,6 +1647,12 @@ fi
# Fix some commands on Windows, and other OS-specific things
uname_s=$(uname -s)
case $uname_s in
+Darwin)
+ test_set_prereq MACOS
+ test_set_prereq POSIXPERM
+ test_set_prereq BSLASHPSPEC
+ test_set_prereq EXECKEEPSPID
+ ;;
*MINGW*)
# Windows has its own (incompatible) sort and find
sort () {
@@ -1893,6 +1910,10 @@ test_lazy_prereq SHA1 '
esac
'
+test_lazy_prereq DEFAULT_HASH_ALGORITHM '
+ test "$GIT_TEST_BUILTIN_HASH" = "$GIT_DEFAULT_HASH"
+'
+
test_lazy_prereq DEFAULT_REPO_FORMAT '
test_have_prereq SHA1,REFFILES
'
diff --git a/t/unit-tests/u-prio-queue.c b/t/unit-tests/u-prio-queue.c
index 145e689c9c..63e58114ae 100644
--- a/t/unit-tests/u-prio-queue.c
+++ b/t/unit-tests/u-prio-queue.c
@@ -13,6 +13,7 @@ static int intcmp(const void *va, const void *vb, void *data UNUSED)
#define STACK -3
#define GET -4
#define REVERSE -5
+#define REPLACE -6
static int show(int *v)
{
@@ -51,6 +52,15 @@ static void test_prio_queue(int *input, size_t input_size,
case REVERSE:
prio_queue_reverse(&pq);
break;
+ case REPLACE:
+ peek = prio_queue_peek(&pq);
+ cl_assert(i + 1 < input_size);
+ cl_assert(input[i + 1] >= 0);
+ cl_assert(j < result_size);
+ cl_assert_equal_i(result[j], show(peek));
+ j++;
+ prio_queue_replace(&pq, &input[++i]);
+ break;
default:
prio_queue_put(&pq, &input[i]);
break;
@@ -81,6 +91,13 @@ void test_prio_queue__empty(void)
((int []){ 1, 2, MISSING, 1, 2, MISSING }));
}
+void test_prio_queue__replace(void)
+{
+ TEST_INPUT(((int []){ REPLACE, 6, 2, 4, REPLACE, 5, 7, GET,
+ REPLACE, 1, DUMP }),
+ ((int []){ MISSING, 2, 4, 5, 1, 6, 7 }));
+}
+
void test_prio_queue__stack(void)
{
TEST_INPUT(((int []){ STACK, 8, 1, 5, 4, 6, 2, 3, DUMP }),
@@ -92,3 +109,9 @@ void test_prio_queue__reverse_stack(void)
TEST_INPUT(((int []){ STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP }),
((int []){ 1, 2, 3, 4, 5, 6 }));
}
+
+void test_prio_queue__replace_stack(void)
+{
+ TEST_INPUT(((int []){ STACK, 8, 1, 5, REPLACE, 4, 6, 2, 3, DUMP }),
+ ((int []){ 5, 3, 2, 6, 4, 1, 8 }));
+}
diff --git a/t/unit-tests/u-string-list.c b/t/unit-tests/u-string-list.c
new file mode 100644
index 0000000000..d4ba5f9fa5
--- /dev/null
+++ b/t/unit-tests/u-string-list.c
@@ -0,0 +1,227 @@
+#include "unit-test.h"
+#include "string-list.h"
+
+static void t_vcreate_string_list_dup(struct string_list *list,
+ int free_util, va_list ap)
+{
+ const char *arg;
+
+ cl_assert(list->strdup_strings);
+
+ string_list_clear(list, free_util);
+ while ((arg = va_arg(ap, const char *)))
+ string_list_append(list, arg);
+}
+
+static void t_create_string_list_dup(struct string_list *list, int free_util, ...)
+{
+ va_list ap;
+
+ cl_assert(list->strdup_strings);
+
+ string_list_clear(list, free_util);
+ va_start(ap, free_util);
+ t_vcreate_string_list_dup(list, free_util, ap);
+ va_end(ap);
+}
+
+static void t_string_list_clear(struct string_list *list, int free_util)
+{
+ string_list_clear(list, free_util);
+ cl_assert_equal_p(list->items, NULL);
+ cl_assert_equal_i(list->nr, 0);
+ cl_assert_equal_i(list->alloc, 0);
+}
+
+static void t_string_list_equal(struct string_list *list,
+ struct string_list *expected_strings)
+{
+ cl_assert_equal_i(list->nr, expected_strings->nr);
+ cl_assert(list->nr <= list->alloc);
+ for (size_t i = 0; i < expected_strings->nr; i++)
+ cl_assert_equal_s(list->items[i].string,
+ expected_strings->items[i].string);
+}
+
+static void t_string_list_split(const char *data, int delim, int maxsplit, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_DUP;
+ va_list ap;
+ int len;
+
+ va_start(ap, maxsplit);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split(&list, data, delim, maxsplit);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+void test_string_list__split(void)
+{
+ t_string_list_split("foo:bar:baz", ':', -1, "foo", "bar", "baz", NULL);
+ t_string_list_split("foo:bar:baz", ':', 0, "foo:bar:baz", NULL);
+ t_string_list_split("foo:bar:baz", ':', 1, "foo", "bar:baz", NULL);
+ t_string_list_split("foo:bar:baz", ':', 2, "foo", "bar", "baz", NULL);
+ t_string_list_split("foo:bar:", ':', -1, "foo", "bar", "", NULL);
+ t_string_list_split("", ':', -1, "", NULL);
+ t_string_list_split(":", ':', -1, "", "", NULL);
+}
+
+static void t_string_list_split_in_place(const char *data, const char *delim,
+ int maxsplit, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_NODUP;
+ char *string = xstrdup(data);
+ va_list ap;
+ int len;
+
+ va_start(ap, maxsplit);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split_in_place(&list, string, delim, maxsplit);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ free(string);
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+void test_string_list__split_in_place(void)
+{
+ t_string_list_split_in_place("foo:;:bar:;:baz:;:", ":;", -1,
+ "foo", "", "", "bar", "", "", "baz", "", "", "", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 0,
+ "foo:;:bar:;:baz", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 1,
+ "foo", ";:bar:;:baz", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 2,
+ "foo", "", ":bar:;:baz", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:", ":;", -1,
+ "foo", "", "", "bar", "", "", "", NULL);
+}
+
+static int prefix_cb(struct string_list_item *item, void *cb_data)
+{
+ const char *prefix = (const char *)cb_data;
+ return starts_with(item->string, prefix);
+}
+
+static void t_string_list_filter(struct string_list *list, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ const char *prefix = "y";
+ va_list ap;
+
+ va_start(ap, list);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ filter_string_list(list, 0, prefix_cb, (void *)prefix);
+ t_string_list_equal(list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+}
+
+void test_string_list__filter(void)
+{
+ struct string_list list = STRING_LIST_INIT_DUP;
+
+ t_create_string_list_dup(&list, 0, NULL);
+ t_string_list_filter(&list, NULL);
+
+ t_create_string_list_dup(&list, 0, "no", NULL);
+ t_string_list_filter(&list, NULL);
+
+ t_create_string_list_dup(&list, 0, "yes", NULL);
+ t_string_list_filter(&list, "yes", NULL);
+
+ t_create_string_list_dup(&list, 0, "no", "yes", NULL);
+ t_string_list_filter(&list, "yes", NULL);
+
+ t_create_string_list_dup(&list, 0, "yes", "no", NULL);
+ t_string_list_filter(&list, "yes", NULL);
+
+ t_create_string_list_dup(&list, 0, "y1", "y2", NULL);
+ t_string_list_filter(&list, "y1", "y2", NULL);
+
+ t_create_string_list_dup(&list, 0, "y2", "y1", NULL);
+ t_string_list_filter(&list, "y2", "y1", NULL);
+
+ t_create_string_list_dup(&list, 0, "x1", "x2", NULL);
+ t_string_list_filter(&list, NULL);
+
+ t_string_list_clear(&list, 0);
+}
+
+static void t_string_list_remove_duplicates(struct string_list *list, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ va_list ap;
+
+ va_start(ap, list);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_remove_duplicates(list, 0);
+ t_string_list_equal(list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+}
+
+void test_string_list__remove_duplicates(void)
+{
+ struct string_list list = STRING_LIST_INIT_DUP;
+
+ t_create_string_list_dup(&list, 0, NULL);
+ t_string_list_remove_duplicates(&list, NULL);
+
+ t_create_string_list_dup(&list, 0, "", NULL);
+ t_string_list_remove_duplicates(&list, "", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", NULL);
+ t_string_list_remove_duplicates(&list, "a", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", NULL);
+ t_string_list_remove_duplicates(&list, "a", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "a", NULL);
+ t_string_list_remove_duplicates(&list, "a", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "b", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "b", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "b", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "b", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "c", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "b", "b", "c", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "a", "b", "b", "b",
+ "c", "c", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_string_list_clear(&list, 0);
+}