diff options
Diffstat (limited to 't')
259 files changed, 7053 insertions, 2662 deletions
@@ -421,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is the default when running tests), errors out when an abbreviated option is used. +GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to +use in the test scripts. Recognized values for <hash-algo> are "sha1" +and "sha256". + Naming Tests ------------ diff --git a/t/chainlint.sed b/t/chainlint.sed index 70df40e34b..8a25c5b855 100644 --- a/t/chainlint.sed +++ b/t/chainlint.sed @@ -117,7 +117,7 @@ /^[ ]*!*[ ]*(..*)[ ]*[0-9]*[<>|&]/boneline # multi-line "(...\n...)" -/^[ ]*(/bsubshell +/^[ ]*(/bsubsh # innocuous line -- print it and advance to next line b @@ -130,11 +130,11 @@ b } b -:subshell +:subsh # bare "(" line? -- stash for later printing /^[ ]*([ ]*$/ { h - bnextline + bnextln } # "(..." line -- split off and stash "(", then process "..." as its own line x @@ -143,7 +143,7 @@ x s/(// bslurp -:nextline +:nextln N s/.*\n// @@ -151,10 +151,10 @@ s/.*\n// # incomplete line "...\" /\\$/bicmplte # multi-line quoted string "...\n..."? -/"/bdqstring +/"/bdqstr # multi-line quoted string '...\n...'? (but not contraction in string "it's") /'/{ - /"[^'"]*'[^'"]*"/!bsqstring + /"[^'"]*'[^'"]*"/!bsqstr } :folded # here-doc -- swallow it @@ -163,8 +163,8 @@ s/.*\n// # before closing ")", "done", "elsif", "else", or "fi" will need to be # re-visited to drop "suspect" marking since final line of those constructs # legitimately lacks "&&", so "suspect" mark must be removed -/^[ ]*#/bnextline -/^[ ]*$/bnextline +/^[ ]*#/bnextln +/^[ ]*$/bnextln # in-line comment -- strip it (but not "#" in a string, Bash ${#...} array # length, or Perforce "//depot/path#42" revision in filespec) /[ ]#/{ @@ -175,22 +175,22 @@ s/.*\n// # multi-line "case ... esac" /^[ ]*case[ ]..*[ ]in/bcase # multi-line "for ... done" or "while ... done" -/^[ ]*for[ ]..*[ ]in/bcontinue -/^[ ]*while[ ]/bcontinue -/^[ ]*do[ ]/bcontinue -/^[ ]*do[ ]*$/bcontinue -/;[ ]*do/bcontinue +/^[ ]*for[ ]..*[ ]in/bcont +/^[ ]*while[ ]/bcont +/^[ ]*do[ ]/bcont +/^[ ]*do[ ]*$/bcont +/;[ ]*do/bcont /^[ ]*done[ ]*&&[ ]*$/bdone /^[ ]*done[ ]*$/bdone /^[ ]*done[ ]*[<>|]/bdone /^[ ]*done[ ]*)/bdone -/||[ ]*exit[ ]/bcontinue -/||[ ]*exit[ ]*$/bcontinue +/||[ ]*exit[ ]/bcont +/||[ ]*exit[ ]*$/bcont # multi-line "if...elsif...else...fi" -/^[ ]*if[ ]/bcontinue -/^[ ]*then[ ]/bcontinue -/^[ ]*then[ ]*$/bcontinue -/;[ ]*then/bcontinue +/^[ ]*if[ ]/bcont +/^[ ]*then[ ]/bcont +/^[ ]*then[ ]*$/bcont +/;[ ]*then/bcont /^[ ]*elif[ ]/belse /^[ ]*elif[ ]*$/belse /^[ ]*else[ ]/belse @@ -234,10 +234,10 @@ s/.*\n// } } # line ends with pipe "...|" -- valid; not missing "&&" -/|[ ]*$/bcontinue +/|[ ]*$/bcont # missing end-of-line "&&" -- mark suspect /&&[ ]*$/!s/^/?!AMP?!/ -:continue +:cont # retrieve and print previous line x n @@ -250,7 +250,7 @@ s/\\\n// bslurp # check for multi-line double-quoted string "...\n..." -- fold to one line -:dqstring +:dqstr # remove all quote pairs s/"\([^"]*\)"/@!\1@!/g # done if no dangling quote @@ -258,13 +258,13 @@ s/"\([^"]*\)"/@!\1@!/g # otherwise, slurp next line and try again N s/\n// -bdqstring +bdqstr :dqdone s/@!/"/g bfolded # check for multi-line single-quoted string '...\n...' -- fold to one line -:sqstring +:sqstr # remove all quote pairs s/'\([^']*\)'/@!\1@!/g # done if no dangling quote @@ -272,7 +272,7 @@ s/'\([^']*\)'/@!\1@!/g # otherwise, slurp next line and try again N s/\n// -bsqstring +bsqstr :sqdone s/@!/'/g bfolded @@ -282,11 +282,11 @@ bfolded :heredoc s/^\(.*\)<<[ ]*[-\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1<</ s/[ ]*<<// -:heredsub +:hdocsub N /^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{ s/\n.*$// - bheredsub + bhdocsub } s/^<[^>]*>// s/\n.*$// @@ -305,7 +305,7 @@ bcase x s/?!AMP?!// x -bcontinue +bcont # found "done" closing for-loop or while-loop, or "fi" closing if-then -- drop # "suspect" from final contained line since that line legitimately lacks "&&" @@ -321,10 +321,10 @@ bchkchn # found nested multi-line "(...\n...)" -- pass through untouched :nest x -:nstslurp +:nstslrp n # closing ")" on own line -- stop nested slurp -/^[ ]*)/bnstclose +/^[ ]*)/bnstcl # comment -- not closing ")" if in comment /^[ ]*#/bnstcnt # "$((...))" -- arithmetic expansion; not closing ")" @@ -332,11 +332,11 @@ n # "$(...)" -- command substitution; not closing ")" /\$([^)][^)]*)[^)]*$/bnstcnt # closing "...)" -- stop nested slurp -/)/bnstclose +/)/bnstcl :nstcnt x -bnstslurp -:nstclose +bnstslrp +:nstcl s/^/>>/ # is it "))" which closes nested and parent subshells? /)[ ]*)/bslurp diff --git a/t/helper/.gitignore b/t/helper/.gitignore index 48c7bb0bbb..8c2ddcce95 100644 --- a/t/helper/.gitignore +++ b/t/helper/.gitignore @@ -1,4 +1,2 @@ /test-tool /test-fake-ssh -/test-line-buffer -/test-svn-fe diff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c index f0aa80b98e..46e97b04eb 100644 --- a/t/helper/test-bloom.c +++ b/t/helper/test-bloom.c @@ -39,7 +39,9 @@ static void get_bloom_filter_for_commit(const struct object_id *commit_oid) struct bloom_filter *filter; setup_git_directory(); c = lookup_commit(the_repository, commit_oid); - filter = get_bloom_filter(the_repository, c, 1); + filter = get_or_compute_bloom_filter(the_repository, c, 1, + &settings, + NULL); print_bloom_filter(filter); } @@ -50,6 +52,8 @@ static const char *bloom_usage = "\n" int cmd__bloom(int argc, const char **argv) { + setup_git_directory(); + if (argc < 2) usage(bloom_usage); diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 234c722b48..a6e936721f 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -126,7 +126,7 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (argc == 3 && !strcmp(argv[1], "get_string")) { - if (!git_config_get_string_const(argv[2], &v)) { + if (!git_config_get_string_tmp(argv[2], &v)) { printf("%s\n", v); goto exit0; } else { diff --git a/t/helper/test-line-buffer.c b/t/helper/test-line-buffer.c deleted file mode 100644 index 078dd7e29d..0000000000 --- a/t/helper/test-line-buffer.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * test-line-buffer.c: code to exercise the svn importer's input helper - */ - -#include "git-compat-util.h" -#include "strbuf.h" -#include "vcs-svn/line_buffer.h" - -static uint32_t strtouint32(const char *s) -{ - char *end; - uintmax_t n = strtoumax(s, &end, 10); - if (*s == '\0' || *end != '\0') - die("invalid count: %s", s); - return (uint32_t) n; -} - -static void handle_command(const char *command, const char *arg, struct line_buffer *buf) -{ - if (starts_with(command, "binary ")) { - struct strbuf sb = STRBUF_INIT; - strbuf_addch(&sb, '>'); - buffer_read_binary(buf, &sb, strtouint32(arg)); - fwrite(sb.buf, 1, sb.len, stdout); - strbuf_release(&sb); - } else if (starts_with(command, "copy ")) { - buffer_copy_bytes(buf, strtouint32(arg)); - } else if (starts_with(command, "skip ")) { - buffer_skip_bytes(buf, strtouint32(arg)); - } else { - die("unrecognized command: %s", command); - } -} - -static void handle_line(const char *line, struct line_buffer *stdin_buf) -{ - const char *arg = strchr(line, ' '); - if (!arg) - die("no argument in line: %s", line); - handle_command(line, arg + 1, stdin_buf); -} - -int cmd_main(int argc, const char **argv) -{ - struct line_buffer stdin_buf = LINE_BUFFER_INIT; - struct line_buffer file_buf = LINE_BUFFER_INIT; - struct line_buffer *input = &stdin_buf; - const char *filename; - char *s; - - if (argc == 1) - filename = NULL; - else if (argc == 2) - filename = argv[1]; - else - usage("test-line-buffer [file | &fd] < script"); - - if (buffer_init(&stdin_buf, NULL)) - die_errno("open error"); - if (filename) { - if (*filename == '&') { - if (buffer_fdinit(&file_buf, strtouint32(filename + 1))) - die_errno("error opening fd %s", filename + 1); - } else { - if (buffer_init(&file_buf, filename)) - die_errno("error opening %s", filename); - } - input = &file_buf; - } - - while ((s = buffer_read_line(&stdin_buf))) - handle_line(s, input); - - if (filename && buffer_deinit(&file_buf)) - die("error reading from %s", filename); - if (buffer_deinit(&stdin_buf)) - die("input error"); - if (ferror(stdout)) - die("output error"); - return 0; -} diff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c new file mode 100644 index 0000000000..42164d9898 --- /dev/null +++ b/t/helper/test-proc-receive.c @@ -0,0 +1,176 @@ +#include "cache.h" +#include "connect.h" +#include "parse-options.h" +#include "pkt-line.h" +#include "sigchain.h" +#include "test-tool.h" + +static const char *proc_receive_usage[] = { + "test-tool proc-receive [<options>...]", + NULL +}; + +static int die_version; +static int die_readline; +static int no_push_options; +static int use_atomic; +static int use_push_options; +static int verbose; +static int version = 1; +static struct string_list returns = STRING_LIST_INIT_NODUP; + +struct command { + struct command *next; + const char *error_string; + unsigned int skip_update:1, + did_not_exist:1; + int index; + struct object_id old_oid; + struct object_id new_oid; + char ref_name[FLEX_ARRAY]; /* more */ +}; + +static void proc_receive_verison(struct packet_reader *reader) { + int server_version = 0; + + for (;;) { + int linelen; + + if (packet_reader_read(reader) != PACKET_READ_NORMAL) + break; + + if (reader->pktlen > 8 && starts_with(reader->line, "version=")) { + server_version = atoi(reader->line+8); + linelen = strlen(reader->line); + if (linelen < reader->pktlen) { + const char *feature_list = reader->line + linelen + 1; + if (parse_feature_request(feature_list, "atomic")) + use_atomic= 1; + if (parse_feature_request(feature_list, "push-options")) + use_push_options = 1; + } + } + } + + if (server_version != 1 || die_version) + die("bad protocol version: %d", server_version); + + packet_write_fmt(1, "version=%d%c%s\n", + version, '\0', + use_push_options && !no_push_options ? "push-options": ""); + packet_flush(1); +} + +static void proc_receive_read_commands(struct packet_reader *reader, + struct command **commands) +{ + struct command **tail = commands; + + for (;;) { + struct object_id old_oid, new_oid; + struct command *cmd; + const char *refname; + const char *p; + + if (packet_reader_read(reader) != PACKET_READ_NORMAL) + break; + + if (parse_oid_hex(reader->line, &old_oid, &p) || + *p++ != ' ' || + parse_oid_hex(p, &new_oid, &p) || + *p++ != ' ' || + die_readline) + die("protocol error: expected 'old new ref', got '%s'", + reader->line); + refname = p; + FLEX_ALLOC_STR(cmd, ref_name, refname); + oidcpy(&cmd->old_oid, &old_oid); + oidcpy(&cmd->new_oid, &new_oid); + + *tail = cmd; + tail = &cmd->next; + } +} + +static void proc_receive_read_push_options(struct packet_reader *reader, + struct string_list *options) +{ + + if (no_push_options || !use_push_options) + return; + + while (1) { + if (packet_reader_read(reader) != PACKET_READ_NORMAL) + break; + + string_list_append(options, reader->line); + } +} + +int cmd__proc_receive(int argc, const char **argv) +{ + int nongit_ok = 0; + struct packet_reader reader; + struct command *commands = NULL; + struct string_list push_options = STRING_LIST_INIT_DUP; + struct string_list_item *item; + struct option options[] = { + OPT_BOOL(0, "no-push-options", &no_push_options, + "disable push options"), + OPT_BOOL(0, "die-version", &die_version, + "die during version negotiation"), + OPT_BOOL(0, "die-readline", &die_readline, + "die when readline"), + OPT_STRING_LIST('r', "return", &returns, "old/new/ref/status/msg", + "return of results"), + OPT__VERBOSE(&verbose, "be verbose"), + OPT_INTEGER('V', "version", &version, + "use this protocol version number"), + OPT_END() + }; + + setup_git_directory_gently(&nongit_ok); + + argc = parse_options(argc, argv, "test-tools", options, proc_receive_usage, 0); + if (argc > 0) + usage_msg_opt("Too many arguments.", proc_receive_usage, options); + packet_reader_init(&reader, 0, NULL, 0, + PACKET_READ_CHOMP_NEWLINE | + PACKET_READ_DIE_ON_ERR_PACKET); + + sigchain_push(SIGPIPE, SIG_IGN); + proc_receive_verison(&reader); + proc_receive_read_commands(&reader, &commands); + proc_receive_read_push_options(&reader, &push_options); + + if (verbose) { + struct command *cmd; + + if (use_push_options || use_atomic) + fprintf(stderr, "proc-receive:%s%s\n", + use_atomic? " atomic": "", + use_push_options ? " push_options": ""); + + for (cmd = commands; cmd; cmd = cmd->next) + fprintf(stderr, "proc-receive< %s %s %s\n", + oid_to_hex(&cmd->old_oid), + oid_to_hex(&cmd->new_oid), + cmd->ref_name); + + if (push_options.nr > 0) + for_each_string_list_item(item, &push_options) + fprintf(stderr, "proc-receive< %s\n", item->string); + + if (returns.nr) + for_each_string_list_item(item, &returns) + fprintf(stderr, "proc-receive> %s\n", item->string); + } + + if (returns.nr) + for_each_string_list_item(item, &returns) + packet_write_fmt(1, "%s\n", item->string); + packet_flush(1); + sigchain_pop(SIGPIPE); + + return 0; +} diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c index 6d0c962438..5f585a1725 100644 --- a/t/helper/test-read-graph.c +++ b/t/helper/test-read-graph.c @@ -12,11 +12,12 @@ int cmd__read_graph(int argc, const char **argv) setup_git_directory(); odb = the_repository->objects->odb; + prepare_repo_settings(the_repository); + graph = read_commit_graph_one(the_repository, odb); if (!graph) return 1; - printf("header: %08x %d %d %d %d\n", ntohl(*(uint32_t*)graph->data), *(unsigned char*)(graph->data + 4), diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index 831b586d02..2430880f78 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -7,14 +7,18 @@ static int read_midx_file(const char *object_dir) { uint32_t i; - struct multi_pack_index *m = load_multi_pack_index(object_dir, 1); + struct multi_pack_index *m; + + setup_git_directory(); + m = load_multi_pack_index(object_dir, 1); if (!m) return 1; - printf("header: %08x %d %d %d\n", + printf("header: %08x %d %d %d %d\n", m->signature, m->version, + m->hash_len, m->num_chunks, m->num_packs); diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index 1646aa25d8..7ae03dc712 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -12,7 +12,7 @@ #include "git-compat-util.h" #include "cache.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "strbuf.h" #include "parse-options.h" #include "string-list.h" @@ -31,7 +31,7 @@ static int parallel_next(struct child_process *cp, if (number_callbacks >= 4) return 0; - argv_array_pushv(&cp->args, d->argv); + strvec_pushv(&cp->args, d->argv); strbuf_addstr(err, "preloaded output of a child\n"); number_callbacks++; return 1; @@ -72,19 +72,19 @@ static int next_test(struct child_process *cp, struct strbuf *err, void *cb, return 0; test = suite->tests.items[suite->next++].string; - argv_array_pushl(&cp->args, "sh", test, NULL); + strvec_pushl(&cp->args, "sh", test, NULL); if (suite->quiet) - argv_array_push(&cp->args, "--quiet"); + strvec_push(&cp->args, "--quiet"); if (suite->immediate) - argv_array_push(&cp->args, "-i"); + strvec_push(&cp->args, "-i"); if (suite->verbose) - argv_array_push(&cp->args, "-v"); + strvec_push(&cp->args, "-v"); if (suite->verbose_log) - argv_array_push(&cp->args, "-V"); + strvec_push(&cp->args, "-V"); if (suite->trace) - argv_array_push(&cp->args, "-x"); + strvec_push(&cp->args, "-x"); if (suite->write_junit_xml) - argv_array_push(&cp->args, "--write-junit-xml"); + strvec_push(&cp->args, "--write-junit-xml"); strbuf_addf(err, "Output of '%s':\n", test); *task_cb = (void *)test; @@ -220,7 +220,7 @@ static int quote_stress_test(int argc, const char **argv) char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a"; int i, j, k, trials = 100, skip = 0, msys2 = 0; struct strbuf out = STRBUF_INIT; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; struct option options[] = { OPT_INTEGER('n', "trials", &trials, "Number of trials"), OPT_INTEGER('s', "skip", &skip, "Skip <n> trials"), @@ -241,20 +241,20 @@ static int quote_stress_test(int argc, const char **argv) size_t arg_count, arg_offset; int ret = 0; - argv_array_clear(&args); + strvec_clear(&args); if (msys2) - argv_array_pushl(&args, "sh", "-c", - "printf %s\\\\0 \"$@\"", "skip", NULL); + strvec_pushl(&args, "sh", "-c", + "printf %s\\\\0 \"$@\"", "skip", NULL); else - argv_array_pushl(&args, "test-tool", "run-command", - "quote-echo", NULL); - arg_offset = args.argc; + strvec_pushl(&args, "test-tool", "run-command", + "quote-echo", NULL); + arg_offset = args.nr; if (argc > 0) { trials = 1; arg_count = argc; for (j = 0; j < arg_count; j++) - argv_array_push(&args, argv[j]); + strvec_push(&args, argv[j]); } else { arg_count = 1 + (my_random() % 5); for (j = 0; j < arg_count; j++) { @@ -268,20 +268,20 @@ static int quote_stress_test(int argc, const char **argv) ARRAY_SIZE(special)]; buf[arg_len] = '\0'; - argv_array_push(&args, buf); + strvec_push(&args, buf); } } if (i < skip) continue; - cp.argv = args.argv; + cp.argv = args.v; strbuf_reset(&out); if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0) return error("Failed to spawn child process"); for (j = 0, k = 0; j < arg_count; j++) { - const char *arg = args.argv[j + arg_offset]; + const char *arg = args.v[j + arg_offset]; if (strcmp(arg, out.buf + k)) ret = error("incorrectly quoted arg: '%s', " @@ -298,10 +298,10 @@ static int quote_stress_test(int argc, const char **argv) fprintf(stderr, "Trial #%d failed. Arguments:\n", i); for (j = 0; j < arg_count; j++) fprintf(stderr, "arg #%d: '%s'\n", - (int)j, args.argv[j + arg_offset]); + (int)j, args.v[j + arg_offset]); strbuf_release(&out); - argv_array_clear(&args); + strvec_clear(&args); return ret; } @@ -311,7 +311,7 @@ static int quote_stress_test(int argc, const char **argv) } strbuf_release(&out); - argv_array_clear(&args); + strvec_clear(&args); return 0; } @@ -338,8 +338,8 @@ static int inherit_handle(const char *argv0) xsnprintf(path, sizeof(path), "out-XXXXXX"); tmp = xmkstemp(path); - argv_array_pushl(&cp.args, - "test-tool", argv0, "inherited-handle-child", NULL); + strvec_pushl(&cp.args, + "test-tool", argv0, "inherited-handle-child", NULL); cp.in = -1; cp.no_stdout = cp.no_stderr = 1; if (start_command(&cp) < 0) @@ -391,7 +391,7 @@ int cmd__run_command(int argc, const char **argv) while (!strcmp(argv[1], "env")) { if (!argv[2]) die("env specifier without a value"); - argv_array_push(&proc.env_array, argv[2]); + strvec_push(&proc.env_array, argv[2]); argv += 2; argc -= 2; } diff --git a/t/helper/test-svn-fe.c b/t/helper/test-svn-fe.c deleted file mode 100644 index 7667c0803f..0000000000 --- a/t/helper/test-svn-fe.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * test-svn-fe: Code to exercise the svn import lib - */ - -#include "git-compat-util.h" -#include "vcs-svn/svndump.h" -#include "vcs-svn/svndiff.h" -#include "vcs-svn/sliding_window.h" -#include "vcs-svn/line_buffer.h" - -static const char test_svnfe_usage[] = - "test-svn-fe (<dumpfile> | [-d] <preimage> <delta> <len>)"; - -static int apply_delta(int argc, const char **argv) -{ - struct line_buffer preimage = LINE_BUFFER_INIT; - struct line_buffer delta = LINE_BUFFER_INIT; - struct sliding_view preimage_view = SLIDING_VIEW_INIT(&preimage, -1); - - if (argc != 5) - usage(test_svnfe_usage); - - if (buffer_init(&preimage, argv[2])) - die_errno("cannot open preimage"); - if (buffer_init(&delta, argv[3])) - die_errno("cannot open delta"); - if (svndiff0_apply(&delta, (off_t) strtoumax(argv[4], NULL, 0), - &preimage_view, stdout)) - return 1; - if (buffer_deinit(&preimage)) - die_errno("cannot close preimage"); - if (buffer_deinit(&delta)) - die_errno("cannot close delta"); - strbuf_release(&preimage_view.buf); - return 0; -} - -int cmd_main(int argc, const char **argv) -{ - if (argc == 2) { - if (svndump_init(argv[1])) - return 1; - svndump_read(NULL, "refs/heads/master", "refs/notes/svn/revs"); - svndump_deinit(); - svndump_reset(); - return 0; - } - - if (argc >= 2 && !strcmp(argv[1], "-d")) - return apply_delta(argc, argv); - usage(test_svnfe_usage); -} diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 590b2efca7..a0d3966b29 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -46,6 +46,7 @@ static struct test_cmd cmds[] = { { "path-utils", cmd__path_utils }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, + { "proc-receive", cmd__proc_receive}, { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index ddc8e990e9..07034d3f38 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -35,6 +35,7 @@ int cmd__parse_pathspec_file(int argc, const char** argv); int cmd__path_utils(int argc, const char **argv); int cmd__pkt_line(int argc, const char **argv); int cmd__prio_queue(int argc, const char **argv); +int cmd__proc_receive(int argc, const char **argv); int cmd__progress(int argc, const char **argv); int cmd__reach(int argc, const char **argv); int cmd__read_cache(int argc, const char **argv); diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c index 197819c872..823f33ceff 100644 --- a/t/helper/test-trace2.c +++ b/t/helper/test-trace2.c @@ -1,6 +1,6 @@ #include "test-tool.h" #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "exec-cmd.h" #include "config.h" diff --git a/t/lib-pack.sh b/t/lib-pack.sh index f3463170b3..bb8938ccbe 100644 --- a/t/lib-pack.sh +++ b/t/lib-pack.sh @@ -35,8 +35,6 @@ pack_header () { # have hardcoded some well-known objects. See the case statements below for the # complete list. pack_obj () { - test_oid_init - case "$1" in # empty blob $EMPTY_BLOB) @@ -93,6 +91,14 @@ pack_obj () { ;; esac ;; + # blob containing "\3\326" + 471819e8c52bf11513f100b2810a8aa0622d5cd3d1c913758a071dd4b3bad8fe) + case "$2" in + '') + printf '\062\170\234\143\276\006\000\000\336\000\332' + return + ;; + esac esac # If it's not a delta, we can convince pack-objects to generate a pack @@ -113,7 +119,6 @@ pack_obj () { # Compute and append pack trailer to "$1" pack_trailer () { - test_oid_init && test-tool $(test_oid algo) -b <"$1" >trailer.tmp && cat trailer.tmp >>"$1" && rm -f trailer.tmp diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh index 07c822c8ff..87a759149f 100644 --- a/t/lib-submodule-update.sh +++ b/t/lib-submodule-update.sh @@ -196,7 +196,6 @@ test_git_directory_exists () { # the submodule repo if it doesn't exist and configures the most problematic # settings for diff.ignoreSubmodules. prolog () { - test_oid_init && (test -d submodule_update_repo || create_lib_submodule_repo) && test_config_global diff.ignoreSubmodules all && test_config diff.ignoreSubmodules all diff --git a/t/lib-t6000.sh b/t/lib-t6000.sh index b0ed4767e3..fba6778ca3 100644 --- a/t/lib-t6000.sh +++ b/t/lib-t6000.sh @@ -1,7 +1,5 @@ : included from 6002 and others -mkdir -p .git/refs/tags - >sed.script # Answer the sha1 has associated with the tag. The tag must exist under refs/tags @@ -26,7 +24,8 @@ save_tag () { _tag=$1 test -n "$_tag" || error "usage: save_tag tag commit-args ..." shift 1 - "$@" >".git/refs/tags/$_tag" + + git update-ref "refs/tags/$_tag" $("$@") echo "s/$(tag $_tag)/$_tag/g" >sed.script.tmp cat sed.script >>sed.script.tmp diff --git a/t/perf/README b/t/perf/README index c7b70e2d28..bd649afa97 100644 --- a/t/perf/README +++ b/t/perf/README @@ -84,6 +84,15 @@ You can set the following variables (also in your config.mak): probably be about linux.git size for optimal results. Both default to the git.git you are running from. + GIT_PERF_EXTRA + Boolean to enable additional tests. Most test scripts are + written to detect regressions between two versions of Git, and + the output will compare timings for individual tests between + those versions. Some scripts have additional tests which are not + run by default, that show patterns within a single version of + Git (e.g., performance of index-pack as the number of threads + changes). These can be enabled with GIT_PERF_EXTRA. + You can also pass the options taken by ordinary git tests; the most useful one is: diff --git a/t/perf/p1400-update-ref.sh b/t/perf/p1400-update-ref.sh index d275a81248..ce5ac3ed85 100755 --- a/t/perf/p1400-update-ref.sh +++ b/t/perf/p1400-update-ref.sh @@ -7,11 +7,13 @@ test_description="Tests performance of update-ref" test_perf_fresh_repo test_expect_success "setup" ' + git init --bare target-repo.git && test_commit PRE && test_commit POST && printf "create refs/heads/%d PRE\n" $(test_seq 1000) >create && printf "update refs/heads/%d POST PRE\n" $(test_seq 1000) >update && - printf "delete refs/heads/%d POST\n" $(test_seq 1000) >delete + printf "delete refs/heads/%d POST\n" $(test_seq 1000) >delete && + git update-ref --stdin <create ' test_perf "update-ref" ' @@ -24,9 +26,14 @@ test_perf "update-ref" ' ' test_perf "update-ref --stdin" ' - git update-ref --stdin <create && git update-ref --stdin <update && - git update-ref --stdin <delete + git update-ref --stdin <delete && + git update-ref --stdin <create +' + +test_perf "nonatomic push" ' + git push ./target-repo.git $(test_seq 1000) && + git push --delete ./target-repo.git $(test_seq 1000) ' test_done diff --git a/t/perf/p5302-pack-index.sh b/t/perf/p5302-pack-index.sh index a9b3e112d9..228593d9ad 100755 --- a/t/perf/p5302-pack-index.sh +++ b/t/perf/p5302-pack-index.sh @@ -13,35 +13,36 @@ test_expect_success 'repack' ' export PACK ' -test_perf 'index-pack 0 threads' ' - rm -rf repo.git && - git init --bare repo.git && - GIT_DIR=repo.git git index-pack --threads=1 --stdin < $PACK -' - -test_perf 'index-pack 1 thread ' ' - rm -rf repo.git && - git init --bare repo.git && - GIT_DIR=repo.git GIT_FORCE_THREADS=1 git index-pack --threads=1 --stdin < $PACK +# Rather than counting up and doubling each time, count down from the endpoint, +# halving each time. That ensures that our final test uses as many threads as +# CPUs, even if it isn't a power of 2. +test_expect_success 'set up thread-counting tests' ' + t=$(test-tool online-cpus) && + threads= && + while test $t -gt 0 + do + threads="$t $threads" + t=$((t / 2)) + done ' -test_perf 'index-pack 2 threads' ' +test_perf PERF_EXTRA 'index-pack 0 threads' ' rm -rf repo.git && git init --bare repo.git && - GIT_DIR=repo.git git index-pack --threads=2 --stdin < $PACK -' - -test_perf 'index-pack 4 threads' ' - rm -rf repo.git && - git init --bare repo.git && - GIT_DIR=repo.git git index-pack --threads=4 --stdin < $PACK + GIT_DIR=repo.git git index-pack --threads=1 --stdin < $PACK ' -test_perf 'index-pack 8 threads' ' - rm -rf repo.git && - git init --bare repo.git && - GIT_DIR=repo.git git index-pack --threads=8 --stdin < $PACK -' +for t in $threads +do + THREADS=$t + export THREADS + test_perf PERF_EXTRA "index-pack $t threads" ' + rm -rf repo.git && + git init --bare repo.git && + GIT_DIR=repo.git GIT_FORCE_THREADS=1 \ + git index-pack --threads=$THREADS --stdin <$PACK + ' +done test_perf 'index-pack default number of threads' ' rm -rf repo.git && diff --git a/t/perf/p5303-many-packs.sh b/t/perf/p5303-many-packs.sh index 7ee791669a..f4c2ab0584 100755 --- a/t/perf/p5303-many-packs.sh +++ b/t/perf/p5303-many-packs.sh @@ -73,6 +73,10 @@ do git rev-list --objects --all >/dev/null ' + test_perf "abbrev-commit ($nr_packs)" ' + git rev-list --abbrev-commit HEAD >/dev/null + ' + # This simulates the interesting part of the repack, which is the # actual pack generation, without smudging the on-disk setup # between trials. diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 13e389367a..821581a885 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -245,3 +245,5 @@ test_at_end_hook_ () { test_export () { export "$@" } + +test_lazy_prereq PERF_EXTRA 'test_bool_env GIT_PERF_EXTRA false' diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 2ff176cd5d..923281af93 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -891,10 +891,6 @@ test_expect_success 'test_atexit is run' " test_path_is_missing also-clean-atexit " -test_expect_success 'test_oid setup' ' - test_oid_init -' - test_expect_success 'test_oid provides sane info by default' ' test_oid zero >actual && grep "^00*\$" actual && @@ -928,6 +924,17 @@ test_expect_success 'test_oid can look up data for SHA-256' ' test "$hexsz" -eq 64 ' +test_expect_success 'test_oid can look up data for a specified algorithm' ' + rawsz="$(test_oid --hash=sha1 rawsz)" && + hexsz="$(test_oid --hash=sha1 hexsz)" && + test "$rawsz" -eq 20 && + test "$hexsz" -eq 40 && + rawsz="$(test_oid --hash=sha256 rawsz)" && + hexsz="$(test_oid --hash=sha256 hexsz)" && + test "$rawsz" -eq 32 && + test "$hexsz" -eq 64 +' + test_expect_success 'test_bool_env' ' ( sane_unset envvar && @@ -1271,4 +1278,22 @@ test_expect_success 'very long name in the index handled sanely' ' test $len = 4098 ' +test_expect_success 'test_must_fail on a failing git command' ' + test_must_fail git notacommand +' + +test_expect_success 'test_must_fail on a failing git command with env' ' + test_must_fail env var1=a var2=b git notacommand +' + +test_expect_success 'test_must_fail rejects a non-git command' ' + ! test_must_fail grep ^$ notafile 2>err && + grep -F "test_must_fail: only '"'"'git'"'"' is allowed" err +' + +test_expect_success 'test_must_fail rejects a non-git command with env' ' + ! test_must_fail env var1=a var2=b grep ^$ notafile 2>err && + grep -F "test_must_fail: only '"'"'git'"'"' is allowed" err +' + test_done diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 6d2467995e..2f7c3dcd0f 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -316,6 +316,28 @@ test_expect_success 'init with separate gitdir' ' test_path_is_dir realgitdir/refs ' +test_expect_success 'explicit bare & --separate-git-dir incompatible' ' + test_must_fail git init --bare --separate-git-dir goop.git bare.git 2>err && + test_i18ngrep "mutually exclusive" err +' + +test_expect_success 'implicit bare & --separate-git-dir incompatible' ' + test_when_finished "rm -rf bare.git" && + mkdir -p bare.git && + test_must_fail env GIT_DIR=. \ + git -C bare.git init --separate-git-dir goop.git 2>err && + test_i18ngrep "incompatible" err +' + +test_expect_success 'bare & --separate-git-dir incompatible within worktree' ' + test_when_finished "rm -rf bare.git linkwt seprepo" && + test_commit gumby && + git clone --bare . bare.git && + git -C bare.git worktree add --detach ../linkwt && + test_must_fail git -C linkwt init --separate-git-dir seprepo 2>err && + test_i18ngrep "incompatible" err +' + test_lazy_prereq GETCWD_IGNORES_PERMS ' base=GETCWD_TEST_BASE_DIR && mkdir -p $base/dir && @@ -392,6 +414,25 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' ' test_path_is_dir realgitdir/refs ' +sep_git_dir_worktree () { + test_when_finished "rm -rf mainwt linkwt seprepo" && + git init mainwt && + test_commit -C mainwt gumby && + git -C mainwt worktree add --detach ../linkwt && + git -C "$1" init --separate-git-dir ../seprepo && + git -C mainwt rev-parse --git-common-dir >expect && + git -C linkwt rev-parse --git-common-dir >actual && + test_cmp expect actual +} + +test_expect_success 're-init to move gitdir with linked worktrees' ' + sep_git_dir_worktree mainwt +' + +test_expect_success 're-init to move gitdir within linked worktree' ' + sep_git_dir_worktree linkwt +' + test_expect_success MINGW '.git hidden' ' rm -rf newdir && ( @@ -441,6 +482,39 @@ test_expect_success 're-init from a linked worktree' ' ) ' +test_expect_success 'init honors GIT_DEFAULT_HASH' ' + GIT_DEFAULT_HASH=sha1 git init sha1 && + git -C sha1 rev-parse --show-object-format >actual && + echo sha1 >expected && + test_cmp expected actual && + GIT_DEFAULT_HASH=sha256 git init sha256 && + git -C sha256 rev-parse --show-object-format >actual && + echo sha256 >expected && + test_cmp expected actual +' + +test_expect_success 'init honors --object-format' ' + git init --object-format=sha1 explicit-sha1 && + git -C explicit-sha1 rev-parse --show-object-format >actual && + echo sha1 >expected && + test_cmp expected actual && + git init --object-format=sha256 explicit-sha256 && + git -C explicit-sha256 rev-parse --show-object-format >actual && + echo sha256 >expected && + test_cmp expected actual +' + +test_expect_success 'extensions.objectFormat is not allowed with repo version 0' ' + git init --object-format=sha256 explicit-v0 && + git -C explicit-v0 config core.repositoryformatversion 0 && + test_must_fail git -C explicit-v0 rev-parse --show-object-format +' + +test_expect_success 'init rejects attempts to initialize with different hash' ' + test_must_fail git -C sha1 init --object-format=sha256 && + test_must_fail git -C sha256 init --object-format=sha1 +' + test_expect_success MINGW 'core.hidedotfiles = false' ' git config --global core.hidedotfiles false && rm -rf newdir && diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index f8178ee4e3..14cafc138b 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -44,7 +44,7 @@ Magic arguments --no-ambiguous negative ambiguity Standard options - --abbrev[=<n>] use <n> digits to display SHA-1s + --abbrev[=<n>] use <n> digits to display object names -v, --verbose be verbose -n, --dry-run dry run -q, --quiet be quiet diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh deleted file mode 100755 index ce92e6acad..0000000000 --- a/t/t0081-line-buffer.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh - -test_description="Test the svn importer's input handling routines. - -These tests provide some simple checks that the line_buffer API -behaves as advertised. - -While at it, check that input of newlines and null bytes are handled -correctly. -" -. ./test-lib.sh - -test_expect_success 'hello world' ' - echo ">HELLO" >expect && - test-line-buffer <<-\EOF >actual && - binary 6 - HELLO - EOF - test_cmp expect actual -' - -test_expect_success '0-length read, send along greeting' ' - echo ">HELLO" >expect && - test-line-buffer <<-\EOF >actual && - binary 0 - copy 6 - HELLO - EOF - test_cmp expect actual -' - -test_expect_success !MINGW 'read from file descriptor' ' - rm -f input && - echo hello >expect && - echo hello >input && - echo copy 6 | - test-line-buffer "&4" 4<input >actual && - test_cmp expect actual -' - -test_expect_success 'skip, copy null byte' ' - echo Q | q_to_nul >expect && - q_to_nul <<-\EOF | test-line-buffer >actual && - skip 2 - Q - copy 2 - Q - EOF - test_cmp expect actual -' - -test_expect_success 'read null byte' ' - echo ">QhelloQ" | q_to_nul >expect && - q_to_nul <<-\EOF | test-line-buffer >actual && - binary 8 - QhelloQ - EOF - test_cmp expect actual -' - -test_expect_success 'long reads are truncated' ' - echo ">foo" >expect && - test-line-buffer <<-\EOF >actual && - binary 5 - foo - EOF - test_cmp expect actual -' - -test_expect_success 'long copies are truncated' ' - printf "%s\n" ">" foo >expect && - test-line-buffer <<-\EOF >actual && - binary 1 - - copy 5 - foo - EOF - test_cmp expect actual -' - -test_expect_success 'long binary reads are truncated' ' - echo ">foo" >expect && - test-line-buffer <<-\EOF >actual && - binary 5 - foo - EOF - test_cmp expect actual -' - -test_done diff --git a/t/t0095-bloom.sh b/t/t0095-bloom.sh index 232ba2c485..7e4ab1795f 100755 --- a/t/t0095-bloom.sh +++ b/t/t0095-bloom.sh @@ -71,8 +71,8 @@ test_expect_success 'get bloom filters for commit with no changes' ' git init && git commit --allow-empty -m "c0" && cat >expect <<-\EOF && - Filter_Length:0 - Filter_Data: + Filter_Length:1 + Filter_Data:00| EOF test-tool bloom get_filter_for_commit "$(git rev-parse HEAD)" >actual && test_cmp expect actual @@ -107,8 +107,8 @@ test_expect_success EXPENSIVE 'get bloom filter for commit with 513 changes' ' git add bigDir && git commit -m "commit with 513 changes" && cat >expect <<-\EOF && - Filter_Length:0 - Filter_Data: + Filter_Length:1 + Filter_Data:ff| EOF test-tool bloom get_filter_for_commit "$(git rev-parse HEAD)" >actual && test_cmp expect actual diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index 6aa0f313bd..584a039b85 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -42,7 +42,7 @@ test_expect_success 'convert shallow clone to partial clone' ' test_cmp_config -C client 1 core.repositoryformatversion ' -test_expect_success 'convert to partial clone with noop extension' ' +test_expect_success SHA1 'convert to partial clone with noop extension' ' rm -fr server client && test_create_repo server && test_commit -C server my_commit 1 && @@ -53,7 +53,7 @@ test_expect_success 'convert to partial clone with noop extension' ' git -C client fetch --unshallow --filter="blob:none" ' -test_expect_success 'converting to partial clone fails with unrecognized extension' ' +test_expect_success SHA1 'converting to partial clone fails with unrecognized extension' ' rm -fr server client && test_create_repo server && test_commit -C server my_commit 1 && @@ -183,7 +183,7 @@ test_expect_success 'missing CLI object, but promised, passes fsck' ' ' test_expect_success 'fetching of missing objects' ' - rm -rf repo && + rm -rf repo err && test_create_repo server && test_commit -C server foo && git -C server repack -a -d --write-bitmap-index && @@ -194,7 +194,10 @@ test_expect_success 'fetching of missing objects' ' git -C repo config core.repositoryformatversion 1 && git -C repo config extensions.partialclone "origin" && - git -C repo cat-file -p "$HASH" && + git -C repo cat-file -p "$HASH" 2>err && + + # Ensure that no spurious FETCH_HEAD messages are written + ! grep FETCH_HEAD err && # Ensure that the .promisor file is written, and check that its # associated packfile contains the object @@ -214,7 +217,7 @@ test_expect_success 'fetching of missing objects works with ref-in-want enabled' rm -rf repo/.git/objects/* && rm -f trace && GIT_TRACE_PACKET="$(pwd)/trace" git -C repo cat-file -p "$HASH" && - grep "git< fetch=.*ref-in-want" trace + grep "fetch< fetch=.*ref-in-want" trace ' test_expect_success 'fetching of missing objects from another promisor remote' ' diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index 43c4be1e5e..2f501d2dc9 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -140,8 +140,6 @@ test_expect_success '--batch-check without %(rest) considers whole line' ' test_cmp expect actual ' -test_oid_init - tree_sha1=$(git write-tree) tree_size=$(($(test_oid rawsz) + 13)) tree_pretty_content="100644 blob $hello_sha1 hello" diff --git a/t/t1050-large.sh b/t/t1050-large.sh index 6a56d1ca24..61e89a8071 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -12,7 +12,6 @@ file_size () { } test_expect_success setup ' - test_oid_init && # clone does not allow us to pass core.bigfilethreshold to # new repos, so set core.bigfilethreshold globally git config --global core.bigfilethreshold 200k && diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 7cd45fc139..84acfc48b6 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -369,7 +369,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat git clone repo unmerged && cat >input <<-EOF && - 0 0000000000000000000000000000000000000000 folder1/a + 0 $ZERO_OID folder1/a 100644 $(git -C unmerged rev-parse HEAD:folder1/a) 1 folder1/a EOF git -C unmerged update-index --index-info <input && @@ -396,7 +396,7 @@ test_expect_success 'sparse-checkout reapply' ' echo dirty >tweak/deep/deeper2/a && cat >input <<-EOF && - 0 0000000000000000000000000000000000000000 folder1/a + 0 $ZERO_OID folder1/a 100644 $(git -C tweak rev-parse HEAD:folder1/a) 1 folder1/a EOF git -C tweak update-index --index-info <input && diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 97ebfe1f9d..825d9a184f 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1836,11 +1836,14 @@ test_expect_success '--show-scope with --show-origin' ' test_cmp expect output ' -test_expect_success '--local requires a repo' ' - # we expect 128 to ensure that we do not simply - # fail to find anything and return code "1" - test_expect_code 128 nongit git config --local foo.bar -' +for opt in --local --worktree +do + test_expect_success "$opt requires a repo" ' + # we expect 128 to ensure that we do not simply + # fail to find anything and return code "1" + test_expect_code 128 nongit git config $opt foo.bar + ' +done cat >.git/config <<-\EOF && [core] diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh index d60c042ce8..0acabb6d11 100755 --- a/t/t1302-repo-version.sh +++ b/t/t1302-repo-version.sh @@ -87,6 +87,9 @@ allow 1 allow 1 noop abort 1 no-such-extension allow 0 no-such-extension +allow 0 noop +abort 0 noop-v1 +allow 1 noop-v1 EOF test_expect_success 'precious-objects allowed' ' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 27171f8261..770e7be363 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -160,10 +160,10 @@ test_expect_success 'core.logAllRefUpdates=always creates reflog by default' ' git reflog exists $outside ' -test_expect_success 'core.logAllRefUpdates=always creates no reflog for ORIG_HEAD' ' +test_expect_success 'core.logAllRefUpdates=always creates reflog for ORIG_HEAD' ' test_config core.logAllRefUpdates always && git update-ref ORIG_HEAD $A && - test_must_fail git reflog exists ORIG_HEAD + git reflog exists ORIG_HEAD ' test_expect_success '--no-create-reflog overrides core.logAllRefUpdates=always' ' @@ -324,7 +324,7 @@ test_expect_success "create $m (logged by config)" ' test_expect_success "update $m (logged by config)" ' test_config core.logAllRefUpdates true && GIT_COMMITTER_DATE="2005-05-26 23:33" \ - git update-ref HEAD'" $B $A "'-m "Switch" && + git update-ref HEAD $B $A -m "Switch" && test $B = $(git show-ref -s --verify $m) ' test_expect_success "set $m (logged by config)" ' @@ -475,57 +475,57 @@ test_expect_success 'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER test_expect_success 'given old value for missing pseudoref, do not create' ' test_must_fail git update-ref PSEUDOREF $A $B 2>err && - test_path_is_missing .git/PSEUDOREF && - test_i18ngrep "could not read ref" err + test_must_fail git rev-parse PSEUDOREF && + test_i18ngrep "unable to resolve reference" err ' test_expect_success 'create pseudoref' ' git update-ref PSEUDOREF $A && - test $A = $(cat .git/PSEUDOREF) + test $A = $(git rev-parse PSEUDOREF) ' test_expect_success 'overwrite pseudoref with no old value given' ' git update-ref PSEUDOREF $B && - test $B = $(cat .git/PSEUDOREF) + test $B = $(git rev-parse PSEUDOREF) ' test_expect_success 'overwrite pseudoref with correct old value' ' git update-ref PSEUDOREF $C $B && - test $C = $(cat .git/PSEUDOREF) + test $C = $(git rev-parse PSEUDOREF) ' test_expect_success 'do not overwrite pseudoref with wrong old value' ' test_must_fail git update-ref PSEUDOREF $D $E 2>err && - test $C = $(cat .git/PSEUDOREF) && - test_i18ngrep "unexpected object ID" err + test $C = $(git rev-parse PSEUDOREF) && + test_i18ngrep "cannot lock ref.*expected" err ' test_expect_success 'delete pseudoref' ' git update-ref -d PSEUDOREF && - test_path_is_missing .git/PSEUDOREF + test_must_fail git rev-parse PSEUDOREF ' test_expect_success 'do not delete pseudoref with wrong old value' ' git update-ref PSEUDOREF $A && test_must_fail git update-ref -d PSEUDOREF $B 2>err && - test $A = $(cat .git/PSEUDOREF) && - test_i18ngrep "unexpected object ID" err + test $A = $(git rev-parse PSEUDOREF) && + test_i18ngrep "cannot lock ref.*expected" err ' test_expect_success 'delete pseudoref with correct old value' ' git update-ref -d PSEUDOREF $A && - test_path_is_missing .git/PSEUDOREF + test_must_fail git rev-parse PSEUDOREF ' test_expect_success 'create pseudoref with old OID zero' ' git update-ref PSEUDOREF $A $Z && - test $A = $(cat .git/PSEUDOREF) + test $A = $(git rev-parse PSEUDOREF) ' test_expect_success 'do not overwrite pseudoref with old OID zero' ' test_when_finished git update-ref -d PSEUDOREF && test_must_fail git update-ref PSEUDOREF $B $Z 2>err && - test $A = $(cat .git/PSEUDOREF) && + test $A = $(git rev-parse PSEUDOREF) && test_i18ngrep "already exists" err ' diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index 331899ddc4..74af927fba 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -31,7 +31,10 @@ test_expect_success 'create_symref(FOO, refs/heads/master)' ' test_expect_success 'delete_refs(FOO, refs/tags/new-tag)' ' git rev-parse FOO -- && git rev-parse refs/tags/new-tag -- && - $RUN delete-refs 0 nothing FOO refs/tags/new-tag && + m=$(git rev-parse master) && + REF_NO_DEREF=1 && + $RUN delete-refs $REF_NO_DEREF nothing FOO refs/tags/new-tag && + test_must_fail git rev-parse --symbolic-full-name FOO && test_must_fail git rev-parse FOO -- && test_must_fail git rev-parse refs/tags/new-tag -- ' diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 76d9b744a6..730a43d9dd 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -54,7 +54,6 @@ check_dont_have () { } test_expect_success setup ' - test_oid_init && mkdir -p A/B && echo rat >C && echo ox >A/D && diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh index da58d867a5..f6e741c6c0 100755 --- a/t/t1416-ref-transaction-hooks.sh +++ b/t/t1416-ref-transaction-hooks.sh @@ -7,6 +7,7 @@ test_description='reference transaction hooks' test_expect_success setup ' mkdir -p .git/hooks && test_commit PRE && + PRE_OID=$(git rev-parse PRE) && test_commit POST && POST_OID=$(git rev-parse POST) ' @@ -106,4 +107,30 @@ test_expect_success 'hook gets all queued updates in aborted state' ' test_cmp expect actual ' +test_expect_success 'interleaving hook calls succeed' ' + test_when_finished "rm -r target-repo.git" && + + git init --bare target-repo.git && + + write_script target-repo.git/hooks/reference-transaction <<-\EOF && + echo $0 "$@" >>actual + EOF + + write_script target-repo.git/hooks/update <<-\EOF && + echo $0 "$@" >>actual + EOF + + 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 + EOF + + git push ./target-repo.git PRE POST && + test_cmp expect target-repo.git/actual +' + test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 344a2aad82..b17f5c21fb 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -9,7 +9,6 @@ test_description='git fsck random collection of tests . ./test-lib.sh test_expect_success setup ' - test_oid_init && git config gc.auto 0 && git config i18n.commitencoding ISO-8859-1 && test_commit A fileA one && @@ -714,7 +713,7 @@ test_expect_success 'fsck fails on corrupt packfile' ' # at least one of which is not zero, so setting the first byte to 0 is # sufficient.) chmod a+w .git/objects/pack/pack-$pack.pack && - printf '\0' | dd of=.git/objects/pack/pack-$pack.pack bs=1 conv=notrunc seek=12 && + printf "\0" | dd of=.git/objects/pack/pack-$pack.pack bs=1 conv=notrunc seek=12 && test_when_finished "rm -f .git/objects/pack/pack-$pack.*" && remove_object $hsh && diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 603019b541..408b97d5af 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -59,7 +59,6 @@ test_rev_parse () { ROOT=$(pwd) test_expect_success 'setup' ' - test_oid_init && mkdir -p sub/dir work && cp -R .git repo.git ' diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index dbf690b9c1..3e657e693b 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -190,6 +190,24 @@ test_expect_success 'dotdot is not an empty set' ' test_cmp expect actual ' +test_expect_success 'dotdot does not peel endpoints' ' + git tag -a -m "annote" annotated HEAD && + A=$(git rev-parse annotated) && + H=$(git rev-parse annotated^0) && + { + echo $A && echo ^$A + } >expect-with-two-dots && + { + echo $A && echo $A && echo ^$H + } >expect-with-merge-base && + + git rev-parse annotated..annotated >actual-with-two-dots && + test_cmp expect-with-two-dots actual-with-two-dots && + + git rev-parse annotated...annotated >actual-with-merge-base && + test_cmp expect-with-merge-base actual-with-merge-base +' + test_expect_success 'arg before dashdash must be a revision (missing)' ' test_must_fail git rev-parse foobar -- 2>stderr && test_i18ngrep "bad revision" stderr diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index f213aa8053..dfc0d96d8a 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -137,7 +137,7 @@ test_expect_success 'merge my-side@{u} records the correct name' ' git branch -t new my-side@{u} && git merge -s ours new@{u} && git show -s --pretty=tformat:%s >actual && - echo "Merge remote-tracking branch ${SQ}origin/side${SQ} into master" >expect && + echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect && test_cmp expect actual ) ' diff --git a/t/t2025-checkout-no-overlay.sh b/t/t2025-checkout-no-overlay.sh index 76330cb5ab..fa9e098706 100755 --- a/t/t2025-checkout-no-overlay.sh +++ b/t/t2025-checkout-no-overlay.sh @@ -44,4 +44,16 @@ test_expect_success '--no-overlay --theirs with D/F conflict deletes file' ' test_path_is_missing file1 ' +test_expect_success 'wildcard pathspec matches file in subdirectory' ' + git reset --hard && + mkdir subdir && + test_commit file3-1 subdir/file3 && + test_commit file3-2 subdir/file3 && + + git checkout --no-overlay file3-1 "*file3" && + echo file3-1 >expect && + test_path_is_file subdir/file3 && + test_cmp expect subdir/file3 +' + test_done diff --git a/t/t2072-restore-pathspec-file.sh b/t/t2072-restore-pathspec-file.sh index 0d47946e8a..b48345bf95 100755 --- a/t/t2072-restore-pathspec-file.sh +++ b/t/t2072-restore-pathspec-file.sh @@ -9,18 +9,21 @@ test_tick test_expect_success setup ' test_commit file0 && + mkdir dir1 && + echo 1 >dir1/file && echo 1 >fileA.t && echo 1 >fileB.t && echo 1 >fileC.t && echo 1 >fileD.t && - git add fileA.t fileB.t fileC.t fileD.t && + git add dir1 fileA.t fileB.t fileC.t fileD.t && git commit -m "files 1" && + echo 2 >dir1/file && echo 2 >fileA.t && echo 2 >fileB.t && echo 2 >fileC.t && echo 2 >fileD.t && - git add fileA.t fileB.t fileC.t fileD.t && + git add dir1 fileA.t fileB.t fileC.t fileD.t && git commit -m "files 2" && git tag checkpoint @@ -31,7 +34,7 @@ restore_checkpoint () { } verify_expect () { - git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual && + git status --porcelain --untracked-files=no -- dir1 fileA.t fileB.t fileC.t fileD.t >actual && test_cmp expect actual } @@ -161,4 +164,14 @@ test_expect_success 'error conditions' ' test_i18ngrep -e "you must specify path(s) to restore" err ' +test_expect_success 'wildcard pathspec matches file in subdirectory' ' + restore_checkpoint && + + echo "*file" | git restore --pathspec-from-file=- --source=HEAD^1 && + cat >expect <<-\EOF && + M dir1/file + EOF + verify_expect +' + test_done diff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh new file mode 100755 index 0000000000..1fe468bfe8 --- /dev/null +++ b/t/t2406-worktree-repair.sh @@ -0,0 +1,179 @@ +#!/bin/sh + +test_description='test git worktree repair' + +. ./test-lib.sh + +test_expect_success setup ' + test_commit init +' + +test_expect_success 'skip missing worktree' ' + test_when_finished "git worktree prune" && + git worktree add --detach missing && + rm -rf missing && + git worktree repair >out 2>err && + test_must_be_empty out && + test_must_be_empty err +' + +test_expect_success 'worktree path not directory' ' + test_when_finished "git worktree prune" && + git worktree add --detach notdir && + rm -rf notdir && + >notdir && + test_must_fail git worktree repair >out 2>err && + test_must_be_empty out && + test_i18ngrep "not a directory" err +' + +test_expect_success "don't clobber .git repo" ' + test_when_finished "rm -rf repo && git worktree prune" && + git worktree add --detach repo && + rm -rf repo && + test_create_repo repo && + test_must_fail git worktree repair >out 2>err && + test_must_be_empty out && + test_i18ngrep ".git is not a file" err +' + +test_corrupt_gitfile () { + butcher=$1 && + problem=$2 && + repairdir=${3:-.} && + test_when_finished 'rm -rf corrupt && git worktree prune' && + git worktree add --detach corrupt && + git -C corrupt rev-parse --absolute-git-dir >expect && + eval "$butcher" && + git -C "$repairdir" worktree repair >out 2>err && + test_i18ngrep "$problem" out && + test_must_be_empty err && + git -C corrupt rev-parse --absolute-git-dir >actual && + test_cmp expect actual +} + +test_expect_success 'repair missing .git file' ' + test_corrupt_gitfile "rm -f corrupt/.git" ".git file broken" +' + +test_expect_success 'repair bogus .git file' ' + test_corrupt_gitfile "echo \"gitdir: /nowhere\" >corrupt/.git" \ + ".git file broken" +' + +test_expect_success 'repair incorrect .git file' ' + test_when_finished "rm -rf other && git worktree prune" && + test_create_repo other && + other=$(git -C other rev-parse --absolute-git-dir) && + test_corrupt_gitfile "echo \"gitdir: $other\" >corrupt/.git" \ + ".git file incorrect" +' + +test_expect_success 'repair .git file from main/.git' ' + test_corrupt_gitfile "rm -f corrupt/.git" ".git file broken" .git +' + +test_expect_success 'repair .git file from linked worktree' ' + test_when_finished "rm -rf other && git worktree prune" && + git worktree add --detach other && + test_corrupt_gitfile "rm -f corrupt/.git" ".git file broken" other +' + +test_expect_success 'repair .git file from bare.git' ' + test_when_finished "rm -rf bare.git corrupt && git worktree prune" && + git clone --bare . bare.git && + git -C bare.git worktree add --detach ../corrupt && + git -C corrupt rev-parse --absolute-git-dir >expect && + rm -f corrupt/.git && + git -C bare.git worktree repair && + git -C corrupt rev-parse --absolute-git-dir >actual && + test_cmp expect actual +' + +test_expect_success 'invalid worktree path' ' + test_must_fail git worktree repair /notvalid >out 2>err && + test_must_be_empty out && + test_i18ngrep "not a valid path" err +' + +test_expect_success 'repo not found; .git not file' ' + test_when_finished "rm -rf not-a-worktree" && + test_create_repo not-a-worktree && + test_must_fail git worktree repair not-a-worktree >out 2>err && + test_must_be_empty out && + test_i18ngrep ".git is not a file" err +' + +test_expect_success 'repo not found; .git file broken' ' + test_when_finished "rm -rf orig moved && git worktree prune" && + git worktree add --detach orig && + echo /invalid >orig/.git && + mv orig moved && + test_must_fail git worktree repair moved >out 2>err && + test_must_be_empty out && + test_i18ngrep ".git file broken" err +' + +test_expect_success 'repair broken gitdir' ' + test_when_finished "rm -rf orig moved && git worktree prune" && + git worktree add --detach orig && + sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect && + rm .git/worktrees/orig/gitdir && + mv orig moved && + git worktree repair moved >out 2>err && + test_cmp expect .git/worktrees/orig/gitdir && + test_i18ngrep "gitdir unreadable" out && + test_must_be_empty err +' + +test_expect_success 'repair incorrect gitdir' ' + test_when_finished "rm -rf orig moved && git worktree prune" && + git worktree add --detach orig && + sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect && + mv orig moved && + git worktree repair moved >out 2>err && + test_cmp expect .git/worktrees/orig/gitdir && + test_i18ngrep "gitdir incorrect" out && + test_must_be_empty err +' + +test_expect_success 'repair gitdir (implicit) from linked worktree' ' + test_when_finished "rm -rf orig moved && git worktree prune" && + git worktree add --detach orig && + sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect && + mv orig moved && + git -C moved worktree repair >out 2>err && + test_cmp expect .git/worktrees/orig/gitdir && + test_i18ngrep "gitdir incorrect" out && + test_must_be_empty err +' + +test_expect_success 'unable to repair gitdir (implicit) from main worktree' ' + test_when_finished "rm -rf orig moved && git worktree prune" && + git worktree add --detach orig && + cat .git/worktrees/orig/gitdir >expect && + mv orig moved && + git worktree repair >out 2>err && + test_cmp expect .git/worktrees/orig/gitdir && + test_must_be_empty out && + test_must_be_empty err +' + +test_expect_success 'repair multiple gitdir files' ' + test_when_finished "rm -rf orig1 orig2 moved1 moved2 && + git worktree prune" && + git worktree add --detach orig1 && + git worktree add --detach orig2 && + sed s,orig1/\.git$,moved1/.git, .git/worktrees/orig1/gitdir >expect1 && + sed s,orig2/\.git$,moved2/.git, .git/worktrees/orig2/gitdir >expect2 && + mv orig1 moved1 && + mv orig2 moved2 && + git worktree repair moved1 moved2 >out 2>err && + test_cmp expect1 .git/worktrees/orig1/gitdir && + test_cmp expect2 .git/worktrees/orig2/gitdir && + test_i18ngrep "gitdir incorrect:.*orig1/gitdir$" out && + test_i18ngrep "gitdir incorrect:.*orig2/gitdir$" out && + test_must_be_empty err +' + +test_done diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh index ffdfb16f58..740ce56eab 100755 --- a/t/t3000-ls-files-others.sh +++ b/t/t3000-ls-files-others.sh @@ -152,7 +152,7 @@ test_expect_success 'ls-files -o --directory with mix dir/file pathspecs' ' ) ' -test_expect_success 'ls-files --o --directory with glob filetype match' ' +test_expect_success 'ls-files -o --directory with glob filetype match' ' ( cd nested && @@ -168,7 +168,7 @@ test_expect_success 'ls-files --o --directory with glob filetype match' ' ) ' -test_expect_success 'ls-files --o --directory with mix of tracked states' ' +test_expect_success 'ls-files -o --directory with mix of tracked states' ' ( cd nested && @@ -184,7 +184,7 @@ test_expect_success 'ls-files --o --directory with mix of tracked states' ' ) ' -test_expect_success 'ls-files --o --directory with glob filetype match only' ' +test_expect_success 'ls-files -o --directory with glob filetype match only' ' ( cd nested && @@ -198,7 +198,7 @@ test_expect_success 'ls-files --o --directory with glob filetype match only' ' ) ' -test_expect_success 'ls-files --o --directory to get immediate paths under one dir only' ' +test_expect_success 'ls-files -o --directory to get immediate paths under one dir only' ' ( cd nested && @@ -212,4 +212,20 @@ test_expect_success 'ls-files --o --directory to get immediate paths under one d ) ' +test_expect_success 'ls-files -o avoids listing untracked non-matching gitdir' ' + test_when_finished "rm -rf nested/untracked/deep/empty" && + ( + cd nested && + + git init untracked/deep/empty && + git ls-files --others "untracked/*.c" >actual && + + cat <<-EOF >expect && + untracked/deep/foo.c + EOF + + test_cmp expect actual + ) +' + test_done diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 4c0734157b..c24c6632ee 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1287,6 +1287,7 @@ test_expect_success 'detect typo in branch name when using --edit-description' ' ' test_expect_success 'refuse --edit-description on unborn branch for now' ' + test_when_finished "git checkout master" && write_script editor <<-\EOF && echo "New contents" >"$1" EOF @@ -1298,10 +1299,6 @@ test_expect_success '--merged catches invalid object names' ' test_must_fail git branch --merged 0000000000000000000000000000000000000000 ' -test_expect_success '--merged is incompatible with --no-merged' ' - test_must_fail git branch --merged HEAD --no-merged HEAD -' - test_expect_success '--list during rebase' ' test_when_finished "reset_rebase" && git checkout master && diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh index 40251c9f8f..efea5c4971 100755 --- a/t/t3201-branch-contains.sh +++ b/t/t3201-branch-contains.sh @@ -171,6 +171,69 @@ test_expect_success 'Assert that --contains only works on commits, not trees & b test_must_fail git branch --no-contains $blob ' +test_expect_success 'multiple branch --contains' ' + git checkout -b side2 master && + >feature && + git add feature && + git commit -m "add feature" && + git checkout -b next master && + git merge side && + git branch --contains side --contains side2 >actual && + cat >expect <<-\EOF && + * next + side + side2 + EOF + test_cmp expect actual +' + +test_expect_success 'multiple branch --merged' ' + git branch --merged next --merged master >actual && + cat >expect <<-\EOF && + master + * next + side + EOF + test_cmp expect actual +' + +test_expect_success 'multiple branch --no-contains' ' + git branch --no-contains side --no-contains side2 >actual && + cat >expect <<-\EOF && + master + EOF + test_cmp expect actual +' + +test_expect_success 'multiple branch --no-merged' ' + git branch --no-merged next --no-merged master >actual && + cat >expect <<-\EOF && + side2 + EOF + test_cmp expect actual +' + +test_expect_success 'branch --contains combined with --no-contains' ' + git checkout -b seen master && + git merge side && + git merge side2 && + git branch --contains side --no-contains side2 >actual && + cat >expect <<-\EOF && + next + side + EOF + test_cmp expect actual +' + +test_expect_success 'branch --merged combined with --no-merged' ' + git branch --merged seen --no-merged next >actual && + cat >expect <<-\EOF && + * seen + side2 + EOF + test_cmp expect actual +' + # We want to set up a case where the walk for the tracking info # of one branch crosses the tip of another branch (and make sure # that the latter walk does not mess up our flag to see if it was @@ -200,15 +263,4 @@ test_expect_success 'branch --merged with --verbose' ' test_i18ncmp expect actual ' -test_expect_success 'branch --contains combined with --no-contains' ' - git branch --contains zzz --no-contains topic >actual && - cat >expect <<-\EOF && - master - side - zzz - EOF - test_cmp expect actual - -' - test_done diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index e024cff65c..6eb344be03 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -252,17 +252,13 @@ test_expect_success 'changed commit with --stat diff option' ' git range-diff --no-color --stat topic...changed >actual && cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) + a => b | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) + a => b | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) EOF test_cmp expect actual ' diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh index 3b4753e1b4..94c1b02251 100755 --- a/t/t3305-notes-fanout.sh +++ b/t/t3305-notes-fanout.sh @@ -7,7 +7,7 @@ test_description='Test that adding/removing many notes triggers automatic fanout path_has_fanout() { path=$1 && fanout=$2 && - after_last_slash=$((40 - $fanout * 2)) && + after_last_slash=$(($(test_oid hexsz) - $fanout * 2)) && echo $path | grep -q "^\([0-9a-f]\{2\}/\)\{$fanout\}[0-9a-f]\{$after_last_slash\}$" } diff --git a/t/t3308-notes-merge.sh b/t/t3308-notes-merge.sh index 790e292966..d69c84c640 100755 --- a/t/t3308-notes-merge.sh +++ b/t/t3308-notes-merge.sh @@ -22,7 +22,6 @@ test_expect_success setup ' # Copy notes to remote-notes git fetch . refs/notes/*:refs/remote-notes/origin/* && - test_oid_init && test_oid_cache <<-EOF hash4a sha1:5e93d24084d32e1cb61f7070505b9d2530cca987 hash3a sha1:8366731eeee53787d2bdf8fc1eff7d94757e8da0 diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 4a7d21f898..07a1617351 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -256,7 +256,7 @@ test_expect_success 'stop on conflicting pick' ' D ======= G - >>>>>>> $commit... G + >>>>>>> $commit (G) EOF git tag new-branch1 && test_must_fail git rebase -i master && @@ -1250,7 +1250,7 @@ test_expect_success 'rebase -i error on commits with \ in message' ' test_expect_code 1 grep " emp" error ' -test_expect_success SHA1 'short SHA-1 setup' ' +test_expect_success 'short commit ID setup' ' test_when_finished "git checkout master" && git checkout --orphan collide && git rm -rf . && @@ -1262,23 +1262,54 @@ test_expect_success SHA1 'short SHA-1 setup' ' ) ' -test_expect_success SHA1 'short SHA-1 collide' ' +if test -n "$GIT_TEST_FIND_COLLIDER" +then + author="$(unset test_tick; test_tick; git var GIT_AUTHOR_IDENT)" + committer="$(unset test_tick; test_tick; git var GIT_COMMITTER_IDENT)" + blob="$(git rev-parse collide2:collide)" + from="$(git rev-parse collide1^0)" + repl="commit refs/heads/collider-&\\n" + repl="${repl}author $author\\ncommitter $committer\\n" + repl="${repl}data <<EOF\\ncollide2 &\\nEOF\\n" + repl="${repl}from $from\\nM 100644 $blob collide\\n" + test_seq 1 32768 | sed "s|.*|$repl|" >script && + git fast-import <script && + git pack-refs && + git for-each-ref >refs && + grep "^$(test_oid t3404_collision)" <refs >matches && + cat matches && + test_line_count -gt 2 matches || { + echo "Could not find a collider" >&2 + exit 1 + } +fi + +test_expect_success 'short commit ID collide' ' + test_oid_cache <<-EOF && + # collision-related constants + t3404_collision sha1:6bcd + t3404_collision sha256:0161 + t3404_collider sha1:ac4f2ee + t3404_collider sha256:16697 + EOF test_when_finished "reset_rebase && git checkout master" && git checkout collide && - colliding_sha1=6bcda37 && - test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && + colliding_id=$(test_oid t3404_collision) && + hexsz=$(test_oid hexsz) && + test $colliding_id = "$(git rev-parse HEAD | cut -c 1-4)" && + test_config core.abbrev 4 && ( unset test_tick && test_tick && set_fake_editor && - FAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \ + FAKE_COMMIT_MESSAGE="collide2 $(test_oid t3404_collider)" \ FAKE_LINES="reword 1 break 2" git rebase -i HEAD~2 && - test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && - grep "^pick $colliding_sha1 " \ + test $colliding_id = "$(git rev-parse HEAD | cut -c 1-4)" && + grep "^pick $colliding_id " \ .git/rebase-merge/git-rebase-todo.tmp && - grep "^pick [0-9a-f]\{40\}" \ + grep "^pick [0-9a-f]\{$hexsz\}" \ .git/rebase-merge/git-rebase-todo && - grep "^pick [0-9a-f]\{40\}" \ + grep "^pick [0-9a-f]\{$hexsz\}" \ .git/rebase-merge/git-rebase-todo.backup && git rebase --continue ) && @@ -1760,6 +1791,12 @@ test_expect_success 'correct error message for commit --amend after empty pick' test_i18ngrep "middle of a rebase -- cannot amend." err ' +test_expect_success 'todo has correct onto hash' ' + GIT_SEQUENCE_EDITOR=cat git rebase -i no-conflict-branch~4 no-conflict-branch >actual && + onto=$(git rev-parse --short HEAD~4) && + test_i18ngrep "^# Rebase ..* onto $onto" actual +' + # This must be the last test in this file test_expect_success '$EDITOR and friends are unchanged' ' test_editor_unchanged diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh index 50e7960702..c8234062c6 100755 --- a/t/t3422-rebase-incompatible-options.sh +++ b/t/t3422-rebase-incompatible-options.sh @@ -61,8 +61,6 @@ test_rebase_am_only () { } test_rebase_am_only --whitespace=fix -test_rebase_am_only --ignore-whitespace -test_rebase_am_only --committer-date-is-author-date test_rebase_am_only -C4 test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' ' diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh index 6f0452c0ea..a29eda87e9 100755 --- a/t/t3432-rebase-fast-forward.sh +++ b/t/t3432-rebase-fast-forward.sh @@ -60,15 +60,16 @@ test_rebase_same_head_ () { fi && oldhead=\$(git rev-parse HEAD) && test_when_finished 'git reset --hard \$oldhead' && - cp .git/logs/HEAD expect && + git reflog HEAD >expect && git rebase$flag $* >stdout && + git reflog HEAD >actual && if test $what = work then old=\$(wc -l <expect) && - test_line_count '-gt' \$old .git/logs/HEAD + test_line_count '-gt' \$old actual elif test $what = noop then - test_cmp expect .git/logs/HEAD + test_cmp expect actual fi && newhead=\$(git rev-parse HEAD) && if test $cmp = same diff --git a/t/t3436-rebase-more-options.sh b/t/t3436-rebase-more-options.sh new file mode 100755 index 0000000000..996e82787e --- /dev/null +++ b/t/t3436-rebase-more-options.sh @@ -0,0 +1,180 @@ +#!/bin/sh +# +# Copyright (c) 2019 Rohit Ashiwal +# + +test_description='tests to ensure compatibility between am and interactive backends' + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/lib-rebase.sh + +GIT_AUTHOR_DATE="1999-04-02T08:03:20+05:30" +export GIT_AUTHOR_DATE + +# This is a special case in which both am and interactive backends +# provide the same output. It was done intentionally because +# both the backends fall short of optimal behaviour. +test_expect_success 'setup' ' + git checkout -b topic && + test_write_lines "line 1" " line 2" "line 3" >file && + git add file && + git commit -m "add file" && + + test_write_lines "line 1" "new line 2" "line 3" >file && + git commit -am "update file" && + git tag side && + test_commit commit1 foo foo1 && + test_commit commit2 foo foo2 && + test_commit commit3 foo foo3 && + + git checkout --orphan master && + rm foo && + test_write_lines "line 1" " line 2" "line 3" >file && + git commit -am "add file" && + git tag main && + + mkdir test-bin && + write_script test-bin/git-merge-test <<-\EOF + exec git merge-recursive "$@" + EOF +' + +test_expect_success '--ignore-whitespace works with apply backend' ' + test_must_fail git rebase --apply main side && + git rebase --abort && + git rebase --apply --ignore-whitespace main side && + git diff --exit-code side +' + +test_expect_success '--ignore-whitespace works with merge backend' ' + test_must_fail git rebase --merge main side && + git rebase --abort && + git rebase --merge --ignore-whitespace main side && + git diff --exit-code side +' + +test_expect_success '--ignore-whitespace is remembered when continuing' ' + ( + set_fake_editor && + FAKE_LINES="break 1" git rebase -i --ignore-whitespace \ + main side && + git rebase --continue + ) && + git diff --exit-code side +' + +test_ctime_is_atime () { + git log $1 --format=%ai >authortime && + git log $1 --format=%ci >committertime && + test_cmp authortime committertime +} + +test_expect_success '--committer-date-is-author-date works with apply backend' ' + GIT_AUTHOR_DATE="@1234 +0300" git commit --amend --reset-author && + git rebase --apply --committer-date-is-author-date HEAD^ && + test_ctime_is_atime -1 +' + +test_expect_success '--committer-date-is-author-date works with merge backend' ' + GIT_AUTHOR_DATE="@1234 +0300" git commit --amend --reset-author && + git rebase -m --committer-date-is-author-date HEAD^ && + test_ctime_is_atime -1 +' + +test_expect_success '--committer-date-is-author-date works with rebase -r' ' + git checkout side && + GIT_AUTHOR_DATE="@1234 +0300" git merge --no-ff commit3 && + git rebase -r --root --committer-date-is-author-date && + test_ctime_is_atime +' + +test_expect_success '--committer-date-is-author-date works when forking merge' ' + git checkout side && + GIT_AUTHOR_DATE="@1234 +0300" git merge --no-ff commit3 && + PATH="./test-bin:$PATH" git rebase -r --root --strategy=test \ + --committer-date-is-author-date && + test_ctime_is_atime +' + +test_expect_success '--committer-date-is-author-date works when committing conflict resolution' ' + git checkout commit2 && + GIT_AUTHOR_DATE="@1980 +0000" git commit --amend --only --reset-author && + test_must_fail git rebase -m --committer-date-is-author-date \ + --onto HEAD^^ HEAD^ && + echo resolved > foo && + git add foo && + git rebase --continue && + test_ctime_is_atime -1 +' + +# Checking for +0000 in the author date is sufficient since the +# default timezone is UTC but the timezone used while committing is +# +0530. The inverted logic in the grep is necessary to check all the +# author dates in the file. +test_atime_is_ignored () { + git log $1 --format=%ai >authortime && + ! grep -v +0000 authortime +} + +test_expect_success '--reset-author-date works with apply backend' ' + git commit --amend --date="$GIT_AUTHOR_DATE" && + git rebase --apply --reset-author-date HEAD^ && + test_atime_is_ignored -1 +' + +test_expect_success '--reset-author-date works with merge backend' ' + git commit --amend --date="$GIT_AUTHOR_DATE" && + git rebase --reset-author-date -m HEAD^ && + test_atime_is_ignored -1 +' + +test_expect_success '--reset-author-date works after conflict resolution' ' + test_must_fail git rebase --reset-author-date -m \ + --onto commit2^^ commit2^ commit2 && + echo resolved >foo && + git add foo && + git rebase --continue && + test_atime_is_ignored -1 +' + +test_expect_success '--reset-author-date works with rebase -r' ' + git checkout side && + git merge --no-ff commit3 && + git rebase -r --root --reset-author-date && + test_atime_is_ignored +' + +test_expect_success '--reset-author-date with --committer-date-is-author-date works' ' + test_must_fail git rebase -m --committer-date-is-author-date \ + --reset-author-date --onto commit2^^ commit2^ commit3 && + git checkout --theirs foo && + git add foo && + git rebase --continue && + test_ctime_is_atime -2 && + test_atime_is_ignored -2 +' + +test_expect_success '--reset-author-date --committer-date-is-author-date works when forking merge' ' + GIT_SEQUENCE_EDITOR="echo \"merge -C $(git rev-parse HEAD) commit3\">" \ + PATH="./test-bin:$PATH" git rebase -i --strategy=test \ + --reset-author-date \ + --committer-date-is-author-date side side && + test_ctime_is_atime -1 && + test_atime_is_ignored -1 + ' + +test_expect_success '--ignore-date is an alias for --reset-author-date' ' + git commit --amend --date="$GIT_AUTHOR_DATE" && + git rebase --apply --ignore-date HEAD^ && + git commit --allow-empty -m empty --date="$GIT_AUTHOR_DATE" && + git rebase -m --ignore-date HEAD^ && + test_atime_is_ignored -2 +' + +# This must be the last test in this file +test_expect_success '$EDITOR and friends are unchanged' ' + test_editor_unchanged +' + +test_done diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh index f038f34b7c..2b8d9cb38e 100755 --- a/t/t3500-cherry.sh +++ b/t/t3500-cherry.sh @@ -55,4 +55,27 @@ test_expect_success \ expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* - .*" ' +test_expect_success 'cherry ignores whitespace' ' + git switch --orphan=upstream-with-space && + test_commit initial file && + >expect && + git switch --create=feature-without-space && + + # A spaceless file on the feature branch. Expect a match upstream. + printf space >file && + git add file && + git commit -m"file without space" && + git log --format="- %H" -1 >>expect && + + # A further change. Should not match upstream. + test_commit change file && + git log --format="+ %H" -1 >>expect && + + git switch upstream-with-space && + # Same as the spaceless file, just with spaces and on upstream. + test_commit "file with space" file "s p a c e" file-with-space && + git cherry upstream-with-space feature-without-space >actual && + test_cmp expect actual +' + test_done diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index 7c1da21df1..3669dfb1be 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -47,7 +47,7 @@ test_expect_success 'cherry-pick --nonsense' ' git diff --exit-code HEAD && test_must_fail git cherry-pick --nonsense 2>msg && git diff --exit-code HEAD "$pos" && - test_i18ngrep '[Uu]sage:' msg + test_i18ngrep "[Uu]sage:" msg ' test_expect_success 'revert --nonsense' ' @@ -56,7 +56,7 @@ test_expect_success 'revert --nonsense' ' git diff --exit-code HEAD && test_must_fail git revert --nonsense 2>msg && git diff --exit-code HEAD "$pos" && - test_i18ngrep '[Uu]sage:' msg + test_i18ngrep "[Uu]sage:" msg ' test_expect_success 'cherry-pick after renaming branch' ' diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 752bc43487..a21adcf0e4 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -283,12 +283,12 @@ test_expect_success 'failed cherry-pick describes conflict in work tree' ' a ======= c - >>>>>>> objid picked + >>>>>>> objid (picked) EOF test_must_fail git cherry-pick picked && - sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && + sed "s/[a-f0-9]* (/objid (/" foo >actual && test_cmp expected actual ' @@ -298,16 +298,16 @@ test_expect_success 'diff3 -m style' ' cat <<-EOF >expected && <<<<<<< HEAD a - ||||||| parent of objid picked + ||||||| parent of objid (picked) b ======= c - >>>>>>> objid picked + >>>>>>> objid (picked) EOF test_must_fail git cherry-pick picked && - sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && + sed "s/[a-f0-9]* (/objid (/" foo >actual && test_cmp expected actual ' @@ -319,7 +319,7 @@ test_expect_success 'revert also handles conflicts sanely' ' a ======= b - >>>>>>> parent of objid picked + >>>>>>> parent of objid (picked) EOF { git checkout picked -- foo && @@ -345,7 +345,7 @@ test_expect_success 'revert also handles conflicts sanely' ' test_must_fail git update-index --refresh -q && test_must_fail git diff-index --exit-code HEAD && test_cmp expected-stages actual-stages && - sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && + sed "s/[a-f0-9]* (/objid (/" foo >actual && test_cmp expected actual ' @@ -429,16 +429,16 @@ test_expect_success 'revert conflict, diff3 -m style' ' cat <<-EOF >expected && <<<<<<< HEAD a - ||||||| objid picked + ||||||| objid (picked) c ======= b - >>>>>>> parent of objid picked + >>>>>>> parent of objid (picked) EOF test_must_fail git revert picked && - sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && + sed "s/[a-f0-9]* (/objid (/" foo >actual && test_cmp expected actual ' @@ -512,7 +512,7 @@ test_expect_success 'commit after failed cherry-pick adds -s at the right place' Signed-off-by: C O Mitter <committer@example.com> # Conflicts: EOF - grep -e "^# Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual && + grep -e "^# Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual && test_cmp expect actual && cat <<-\EOF >expected && @@ -541,7 +541,7 @@ test_expect_success 'commit --amend -s places the sign-off at the right place' ' Signed-off-by: C O Mitter <committer@example.com> Conflicts: EOF - grep -e "^Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual && + grep -e "^Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual && test_cmp expect actual ' diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index f2c0168941..efec8d13b6 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -241,7 +241,6 @@ test_expect_success 'refresh index before checking if it is up-to-date' ' ' test_expect_success 'choking "git rm" should not let it die with cruft' ' - test_oid_init && git reset -q --hard && test_when_finished "rm -f .git/index.lock && git reset -q --hard" && i=0 && diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 49decbac71..ca04fac417 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -31,7 +31,16 @@ diff_cmp () { # indicates a dumb terminal, so we set that variable, too. force_color () { - env GIT_PAGER_IN_USE=true TERM=vt100 "$@" + # The first element of $@ may be a shell function, as a result POSIX + # does not guarantee that "one-shot assignment" will not persist after + # the function call. Thus, we prevent these variables from escaping + # this function's context with this subshell. + ( + GIT_PAGER_IN_USE=true && + TERM=vt100 && + export GIT_PAGER_IN_USE TERM && + "$@" + ) } test_expect_success 'setup (initial)' ' @@ -560,12 +569,20 @@ test_expect_success 'patch mode ignores unmerged entries' ' diff_cmp expected diff ' +test_expect_success 'index is refreshed after applying patch' ' + git reset --hard && + echo content >test && + printf y | git add -p && + git diff-files --exit-code +' + test_expect_success 'diffs can be colorized' ' git reset --hard && echo content >test && printf y >y && force_color git add -p >output 2>&1 <y && + git diff-files --exit-code && # We do not want to depend on the exact coloring scheme # git uses for diffs, so just check that we saw some kind of color. @@ -604,7 +621,7 @@ test_expect_success 'detect bogus diffFilter output' ' echo content >test && test_config interactive.diffFilter "sed 1d" && printf y >y && - test_must_fail force_color git add -p <y + force_color test_must_fail git add -p <y ' test_expect_success 'diff.algorithm is passed to `git diff-files`' ' @@ -805,6 +822,44 @@ test_expect_success 'checkout -p works with pathological context lines' ' test_cmp expect a ' +# This should be called from a subshell as it sets a temporary editor +setup_new_file() { + write_script new-file-editor.sh <<-\EOF && + sed /^#/d "$1" >patch && + sed /^+c/d patch >"$1" + EOF + test_set_editor "$(pwd)/new-file-editor.sh" && + test_write_lines a b c d e f >new-file && + test_write_lines a b d e f >new-file-expect && + test_write_lines "@@ -0,0 +1,6 @@" +a +b +c +d +e +f >patch-expect +} + +test_expect_success 'add -N followed by add -p patch editing' ' + git reset --hard && + ( + setup_new_file && + git add -N new-file && + test_write_lines e n q | git add -p && + git cat-file blob :new-file >actual && + test_cmp new-file-expect actual && + test_cmp patch-expect patch + ) +' + +test_expect_success 'checkout -p patch editing of added file' ' + git reset --hard && + ( + setup_new_file && + git add new-file && + git commit -m "add new file" && + git rm new-file && + git commit -m "remove new file" && + test_write_lines e n q | git checkout -p HEAD^ && + test_cmp new-file-expect new-file && + test_cmp patch-expect patch + ) +' + test_expect_success 'show help from add--helper' ' git reset --hard && cat >expect <<-EOF && diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index 64dcc5ec28..d696aa4e52 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -23,7 +23,6 @@ check_verify_failure () { # first create a commit, so we have a valid object/type # for the tag. test_expect_success 'setup' ' - test_oid_init && echo Hello >A && git update-index --add A && git commit -m "Initial commit" && diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index cbcdd10464..6a9f010197 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -10,8 +10,6 @@ test_description='Test diff raw-output. . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh -test_oid_init - test_oid_cache <<\EOF aa_1 sha1:ccba72ad3888a3520b39efcf780b9ee64167535d aa_1 sha256:9febfbf18197819b2735c45291f138525d2476d59470f98239647544586ba403 diff --git a/t/t4005-diff-rename-2.sh b/t/t4005-diff-rename-2.sh index f542d2929d..d18a80493c 100755 --- a/t/t4005-diff-rename-2.sh +++ b/t/t4005-diff-rename-2.sh @@ -14,8 +14,8 @@ test_expect_success 'setup reference tree' ' git update-index --add COPYING rezrov && tree=$(git write-tree) && echo $tree && - sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 && - sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 && + sed -e "s/HOWEVER/However/" <COPYING >COPYING.1 && + sed -e "s/GPL/G.P.L/g" <COPYING >COPYING.2 && origoid=$(git hash-object COPYING) && oid1=$(git hash-object COPYING.1) && oid2=$(git hash-object COPYING.2) diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index e5ca359edf..65cc703c65 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -125,7 +125,9 @@ test_expect_success 'setup submodules' ' test_expect_success 'diff-tree ignores trailing slash on submodule path' ' git diff --name-only HEAD^ HEAD submod >expect && git diff --name-only HEAD^ HEAD submod/ >actual && - test_cmp expect actual + test_cmp expect actual && + git diff --name-only HEAD^ HEAD -- submod/whatever >actual && + test_must_be_empty actual ' test_expect_success 'diff multiple wildcard pathspecs' ' diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 43267d6024..5c7b0122b4 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -117,12 +117,12 @@ test_expect_success setup ' : <<\EOF ! [initial] Initial - * [master] Merge branch 'side' into master + * [master] Merge branch 'side' ! [rearrange] Rearranged lines in dir/sub ! [side] Side ---- + [rearrange] Rearranged lines in dir/sub - - [master] Merge branch 'side' into master + - [master] Merge branch 'side' * + [side] Side * [master^] Third * [master~2] Second @@ -130,27 +130,45 @@ test_expect_success setup ' EOF process_diffs () { - _x04="[0-9a-f][0-9a-f][0-9a-f][0-9a-f]" && - _x07="$_x05[0-9a-f][0-9a-f]" && - sed -e "s/$OID_REGEX/$ZERO_OID/g" \ - -e "s/From $_x40 /From $ZERO_OID /" \ - -e "s/from $_x40)/from $ZERO_OID)/" \ - -e "s/commit $_x40\$/commit $ZERO_OID/" \ - -e "s/commit $_x40 (/commit $ZERO_OID (/" \ - -e "s/$_x40 $_x40 $_x40/$ZERO_OID $ZERO_OID $ZERO_OID/" \ - -e "s/$_x40 $_x40 /$ZERO_OID $ZERO_OID /" \ - -e "s/^$_x40 $_x40$/$ZERO_OID $ZERO_OID/" \ - -e "s/^$_x40 /$ZERO_OID /" \ - -e "s/^$_x40$/$ZERO_OID/" \ - -e "s/$_x07\.\.$_x07/fffffff..fffffff/g" \ - -e "s/$_x07,$_x07\.\.$_x07/fffffff,fffffff..fffffff/g" \ - -e "s/$_x07 $_x07 $_x07/fffffff fffffff fffffff/g" \ - -e "s/$_x07 $_x07 /fffffff fffffff /g" \ - -e "s/Merge: $_x07 $_x07/Merge: fffffff fffffff/g" \ - -e "s/$_x07\.\.\./fffffff.../g" \ - -e "s/ $_x04\.\.\./ ffff.../g" \ - -e "s/ $_x04/ ffff/g" \ - "$1" + perl -e ' + my $oid_length = length($ARGV[0]); + my $x40 = "[0-9a-f]{40}"; + my $xab = "[0-9a-f]{4,16}"; + my $orx = "[0-9a-f]" x $oid_length; + + sub munge_oid { + my ($oid) = @_; + my $x; + + return "" unless length $oid; + + if ($oid =~ /^(100644|100755|120000)$/) { + return $oid; + } + + if ($oid =~ /^0*$/) { + $x = "0"; + } else { + $x = "f"; + } + + if (length($oid) == 40) { + return $x x $oid_length; + } else { + return $x x length($oid); + } + } + + while (<STDIN>) { + s/($orx)/munge_oid($1)/ge; + s/From ($x40)( |\))/"From " . munge_oid($1) . $2/ge; + s/commit ($x40)($| \(from )($x40?)/"commit " . munge_oid($1) . $2 . munge_oid($3)/ge; + s/\b($x40)( |\.\.|$)/munge_oid($1) . $2/ge; + s/^($x40)($| )/munge_oid($1) . $2/e; + s/($xab)(\.\.|,| |\.\.\.|$)/munge_oid($1) . $2/ge; + print; + } + ' "$ZERO_OID" <"$1" } V=$(git version | sed -e 's/^git version //' -e 's/\./\\./g') @@ -221,6 +239,9 @@ diff-tree --root -r --abbrev=4 initial :noellipses diff-tree --root -r --abbrev=4 initial diff-tree -p initial diff-tree --root -p initial +diff-tree --root -p --abbrev=10 initial +diff-tree --root -p --full-index initial +diff-tree --root -p --full-index --abbrev=10 initial diff-tree --patch-with-stat initial diff-tree --root --patch-with-stat initial diff-tree --patch-with-raw initial @@ -297,6 +318,9 @@ log --root --patch-with-stat --summary master log --root -c --patch-with-stat --summary master # improved by Timo's patch log --root --cc --patch-with-stat --summary master +log --no-diff-merges -p --first-parent master +log --diff-merges=off -p --first-parent master +log --first-parent --diff-merges=off -p master log -p --first-parent master log -m -p --first-parent master log -m -p master diff --git a/t/t4013/diff.diff-tree_--root_-p_--abbrev=10_initial b/t/t4013/diff.diff-tree_--root_-p_--abbrev=10_initial new file mode 100644 index 0000000000..7518a9044e --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_-p_--abbrev=10_initial @@ -0,0 +1,29 @@ +$ git diff-tree --root -p --abbrev=10 initial +444ac553ac7612cc88969031b02b3767fb8a353a +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000000..35d242ba79 +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000000..01e79c32a8 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000000..01e79c32a8 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--root_-p_--full-index_--abbrev=10_initial b/t/t4013/diff.diff-tree_--root_-p_--full-index_--abbrev=10_initial new file mode 100644 index 0000000000..69f913fbe5 --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_-p_--full-index_--abbrev=10_initial @@ -0,0 +1,29 @@ +$ git diff-tree --root -p --full-index --abbrev=10 initial +444ac553ac7612cc88969031b02b3767fb8a353a +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000000000000000000000000000000000000..35d242ba79ae89ac695e26b3d4c27a8e6f028f9e +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000000000000000000000000000000000000..01e79c32a8c99c557f0757da7cb6d65b3414466d +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000000000000000000000000000000000000..01e79c32a8c99c557f0757da7cb6d65b3414466d +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--root_-p_--full-index_initial b/t/t4013/diff.diff-tree_--root_-p_--full-index_initial new file mode 100644 index 0000000000..1b0b6717fa --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_-p_--full-index_initial @@ -0,0 +1,29 @@ +$ git diff-tree --root -p --full-index initial +444ac553ac7612cc88969031b02b3767fb8a353a +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000000000000000000000000000000000000..35d242ba79ae89ac695e26b3d4c27a8e6f028f9e +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000000000000000000000000000000000000..01e79c32a8c99c557f0757da7cb6d65b3414466d +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000000000000000000000000000000000000..01e79c32a8c99c557f0757da7cb6d65b3414466d +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all index c56783b985..3f9b872ece 100644 --- a/t/t4013/diff.log_--decorate=full_--all +++ b/t/t4013/diff.log_--decorate=full_--all @@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side) Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all index 1cbdc038f4..f5e20e1e14 100644 --- a/t/t4013/diff.log_--decorate_--all +++ b/t/t4013/diff.log_--decorate_--all @@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (side) Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--diff-merges=off_-p_--first-parent_master b/t/t4013/diff.log_--diff-merges=off_-p_--first-parent_master new file mode 100644 index 0000000000..194e893c94 --- /dev/null +++ b/t/t4013/diff.log_--diff-merges=off_-p_--first-parent_master @@ -0,0 +1,78 @@ +$ git log --diff-merges=off -p --first-parent master +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 +Merge: 9a6d494 c7a2ab9 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +diff --git a/dir/sub b/dir/sub +index 35d242b..8422d40 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++C ++D +diff --git a/file0 b/file0 +index 01e79c3..b414108 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++4 ++5 ++6 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ diff --git a/t/t4013/diff.log_--first-parent_--diff-merges=off_-p_master b/t/t4013/diff.log_--first-parent_--diff-merges=off_-p_master new file mode 100644 index 0000000000..5d7461a167 --- /dev/null +++ b/t/t4013/diff.log_--first-parent_--diff-merges=off_-p_master @@ -0,0 +1,78 @@ +$ git log --first-parent --diff-merges=off -p master +commit 80e25ffa65bcdbe82ef654b4d06dbbde7945c37f +Merge: 9a6d494 c7a2ab9 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +diff --git a/dir/sub b/dir/sub +index 35d242b..8422d40 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++C ++D +diff --git a/file0 b/file0 +index 01e79c3..b414108 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++4 ++5 ++6 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ diff --git a/t/t4013/diff.log_--no-diff-merges_-p_--first-parent_master b/t/t4013/diff.log_--no-diff-merges_-p_--first-parent_master new file mode 100644 index 0000000000..597002232e --- /dev/null +++ b/t/t4013/diff.log_--no-diff-merges_-p_--first-parent_master @@ -0,0 +1,78 @@ +$ git log --no-diff-merges -p --first-parent master +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 +Merge: 9a6d494 c7a2ab9 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +diff --git a/dir/sub b/dir/sub +index 35d242b..8422d40 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++C ++D +diff --git a/file0 b/file0 +index 01e79c3..b414108 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++4 ++5 ++6 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ index f5b1b6516b..a18f1472a9 100644 --- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ +++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master index af23803cdc..ae425c4672 100644 --- a/t/t4013/diff.log_--patch-with-stat_master +++ b/t/t4013/diff.log_--patch-with-stat_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_ index 814098fbf8..d5207cadf4 100644 --- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ +++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_ @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master index b927fe4a98..0fc1e8cd71 100644 --- a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master +++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master index 6db3cea329..dffc09dde9 100644 --- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master +++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master index 98e9c320c3..55aa98012d 100644 --- a/t/t4013/diff.log_--root_--patch-with-stat_master +++ b/t/t4013/diff.log_--root_--patch-with-stat_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master index b61b1117ae..019d85f7de 100644 --- a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master +++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4013/diff.log_--root_-p_master b/t/t4013/diff.log_--root_-p_master index 345bd9e8a9..b42c334439 100644 --- a/t/t4013/diff.log_--root_-p_master +++ b/t/t4013/diff.log_--root_-p_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_master b/t/t4013/diff.log_--root_master index db56b1fe6b..e8f46159da 100644 --- a/t/t4013/diff.log_--root_master +++ b/t/t4013/diff.log_--root_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_-m_-p_--first-parent_master b/t/t4013/diff.log_-m_-p_--first-parent_master index bcadb50e26..7a0073f529 100644 --- a/t/t4013/diff.log_-m_-p_--first-parent_master +++ b/t/t4013/diff.log_-m_-p_--first-parent_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 diff --git a/t/t4013/diff.log_-m_-p_master b/t/t4013/diff.log_-m_-p_master index 2acf43a9fb..9ca62a01ed 100644 --- a/t/t4013/diff.log_-m_-p_master +++ b/t/t4013/diff.log_-m_-p_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 @@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644 diff --git a/t/t4013/diff.log_-p_--first-parent_master b/t/t4013/diff.log_-p_--first-parent_master index c6a5876d80..28840ebea1 100644 --- a/t/t4013/diff.log_-p_--first-parent_master +++ b/t/t4013/diff.log_-p_--first-parent_master @@ -4,7 +4,29 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' + +diff --git a/dir/sub b/dir/sub +index cead32e..992913c 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -4,3 +4,5 @@ C + D + E + F ++1 ++2 +diff --git a/file0 b/file0 +index b414108..10a8a9f 100644 +--- a/file0 ++++ b/file0 +@@ -4,3 +4,6 @@ + 4 + 5 + 6 ++A ++B ++C commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_-p_master b/t/t4013/diff.log_-p_master index 1841cded94..bf1326dc36 100644 --- a/t/t4013/diff.log_-p_master +++ b/t/t4013/diff.log_-p_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_master b/t/t4013/diff.log_master index f8ec445eb3..a8f6ce5abd 100644 --- a/t/t4013/diff.log_master +++ b/t/t4013/diff.log_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.show_--first-parent_master b/t/t4013/diff.show_--first-parent_master index 94548f4598..3dcbe473a0 100644 --- a/t/t4013/diff.show_--first-parent_master +++ b/t/t4013/diff.show_--first-parent_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 diff --git a/t/t4013/diff.show_-c_master b/t/t4013/diff.show_-c_master index 1c46ed64fd..81aba8da96 100644 --- a/t/t4013/diff.show_-c_master +++ b/t/t4013/diff.show_-c_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --combined dir/sub index cead32e,7289e35..992913c diff --git a/t/t4013/diff.show_-m_master b/t/t4013/diff.show_-m_master index 7559fc22f8..4ea2ee453d 100644 --- a/t/t4013/diff.show_-m_master +++ b/t/t4013/diff.show_-m_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 @@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644 diff --git a/t/t4013/diff.show_master b/t/t4013/diff.show_master index 57091c5d90..fb08ce0e46 100644 --- a/t/t4013/diff.show_master +++ b/t/t4013/diff.show_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --cc dir/sub index cead32e,7289e35..992913c diff --git a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master index 5f13a71bb5..30aae7817b 100644 --- a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master +++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master index 8acb88267b..d1d32bd34c 100644 --- a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master +++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 88d3026894..8bdaa0a693 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -789,7 +789,7 @@ test_expect_success 'checkdiff allows new blank lines' ' git diff --check ' -test_expect_success 'whitespace-only changes not reported' ' +test_expect_success 'whitespace-only changes not reported (diff)' ' git reset --hard && echo >x "hello world" && git add x && @@ -799,10 +799,44 @@ test_expect_success 'whitespace-only changes not reported' ' test_must_be_empty actual ' -test_expect_success 'whitespace-only changes reported across renames' ' +test_expect_success 'whitespace-only changes not reported (diffstat)' ' + # reuse state from previous test + git diff --stat -b >actual && + test_must_be_empty actual +' + +test_expect_success 'whitespace changes with modification reported (diffstat)' ' + git reset --hard && + echo >x "hello world" && + git update-index --chmod=+x x && + git diff --stat --cached -b >actual && + cat <<-EOF >expect && + x | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + EOF + test_cmp expect actual +' + +test_expect_success 'whitespace-only changes reported across renames (diffstat)' ' git reset --hard && for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x && git add x && + git commit -m "base" && + sed -e "5s/^/ /" x >z && + git rm x && + git add z && + git diff -w -M --cached --stat >actual && + cat <<-EOF >expect && + x => z | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + EOF + test_cmp expect actual +' + +test_expect_success 'whitespace-only changes reported across renames' ' + git reset --hard HEAD~1 && + for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x && + git add x && hash_x=$(git hash-object x) && before=$(git rev-parse --short "$hash_x") && git commit -m "base" && diff --git a/t/t4018/fortran-block-data b/t/t4018/fortran-block-data new file mode 100644 index 0000000000..63d4e21d0a --- /dev/null +++ b/t/t4018/fortran-block-data @@ -0,0 +1,5 @@ + BLOCK DATA RIGHT + + COMMON /B/ C, ChangeMe + DATA C, ChangeMe / 2.0, 6.0 / + END diff --git a/t/t4018/fortran-comment b/t/t4018/fortran-comment new file mode 100644 index 0000000000..7b10d17658 --- /dev/null +++ b/t/t4018/fortran-comment @@ -0,0 +1,13 @@ + module a + + contains + + ! subroutine wrong + subroutine RIGHT + ! subroutine wrong + + real ChangeMe + + end subroutine RIGHT + + end module a diff --git a/t/t4018/fortran-comment-keyword b/t/t4018/fortran-comment-keyword new file mode 100644 index 0000000000..e9206a5379 --- /dev/null +++ b/t/t4018/fortran-comment-keyword @@ -0,0 +1,14 @@ + module a + + contains + + subroutine RIGHT (funcA, funcB) + + real funcA ! grid function a + real funcB ! grid function b + + real ChangeMe + + end subroutine RIGHT + + end module a diff --git a/t/t4018/fortran-comment-legacy b/t/t4018/fortran-comment-legacy new file mode 100644 index 0000000000..53cd062c1e --- /dev/null +++ b/t/t4018/fortran-comment-legacy @@ -0,0 +1,13 @@ + module a + + contains + +C subroutine wrong + subroutine RIGHT +C subroutine wrong + + real ChangeMe + + end subroutine RIGHT + + end module a diff --git a/t/t4018/fortran-comment-legacy-star b/t/t4018/fortran-comment-legacy-star new file mode 100644 index 0000000000..2cbcdc3d8a --- /dev/null +++ b/t/t4018/fortran-comment-legacy-star @@ -0,0 +1,13 @@ + module a + + contains + +* subroutine wrong + subroutine RIGHT +* subroutine wrong + + real ChangeMe + + end subroutine RIGHT + + end module a diff --git a/t/t4018/fortran-external-function b/t/t4018/fortran-external-function new file mode 100644 index 0000000000..5a2d85d3aa --- /dev/null +++ b/t/t4018/fortran-external-function @@ -0,0 +1,9 @@ +function RIGHT(a, b) result(c) + +integer, intent(in) :: ChangeMe +integer, intent(in) :: b +integer, intent(out) :: c + +c = a+b + +end function RIGHT diff --git a/t/t4018/fortran-external-subroutine b/t/t4018/fortran-external-subroutine new file mode 100644 index 0000000000..4ce85fea13 --- /dev/null +++ b/t/t4018/fortran-external-subroutine @@ -0,0 +1,5 @@ +subroutine RIGHT + +real ChangeMe + +end subroutine RIGHT diff --git a/t/t4018/fortran-module b/t/t4018/fortran-module new file mode 100644 index 0000000000..c4b737dac3 --- /dev/null +++ b/t/t4018/fortran-module @@ -0,0 +1,5 @@ +module RIGHT + +use ChangeMe + +end module RIGHT diff --git a/t/t4018/fortran-module-procedure b/t/t4018/fortran-module-procedure new file mode 100644 index 0000000000..1ce6d854c2 --- /dev/null +++ b/t/t4018/fortran-module-procedure @@ -0,0 +1,13 @@ + module RIGHT + + implicit none + private + + interface letters ! generic interface + module procedure aaaa, & + bbbb, & + ChangeMe, & + dddd + end interface + +end module RIGHT diff --git a/t/t4018/fortran-program b/t/t4018/fortran-program new file mode 100644 index 0000000000..4616895e4b --- /dev/null +++ b/t/t4018/fortran-program @@ -0,0 +1,5 @@ +program RIGHT + +call ChangeMe + +end program RIGHT diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index e29deaf4a5..d7145ccca4 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -6,7 +6,6 @@ test_description='difference in submodules' . "$TEST_DIRECTORY"/diff-lib.sh test_expect_success setup ' - test_oid_init && test_tick && test_create_repo sub && ( diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index fb145aa173..0c8fb39ced 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -102,7 +102,7 @@ test_expect_success 'word diff with runs of whitespace' ' ' test_expect_success '--word-diff=porcelain' ' - sed 's/#.*$//' >expect <<-EOF && + sed "s/#.*$//" >expect <<-EOF && diff --git a/pre b/post index $pre..$post 100644 --- a/pre diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh index ef8e0e9cb0..804f2a82e8 100755 --- a/t/t4067-diff-partial-clone.sh +++ b/t/t4067-diff-partial-clone.sh @@ -20,7 +20,7 @@ test_expect_success 'git show batches blobs' ' # Ensure that there is exactly 1 negotiation by checking that there is # only 1 "done" line sent. ("done" marks the end of negotiation.) GIT_TRACE_PACKET="$(pwd)/trace" git -C client show HEAD && - grep "git> done" trace >done_lines && + grep "fetch> done" trace >done_lines && test_line_count = 1 done_lines ' @@ -44,7 +44,7 @@ test_expect_success 'diff batches blobs' ' # Ensure that there is exactly 1 negotiation by checking that there is # only 1 "done" line sent. ("done" marks the end of negotiation.) GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD && - grep "git> done" trace >done_lines && + grep "fetch> done" trace >done_lines && test_line_count = 1 done_lines ' @@ -127,7 +127,7 @@ test_expect_success 'diff with rename detection batches blobs' ' # only 1 "done" line sent. ("done" marks the end of negotiation.) GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD >out && grep ":100644 100644.*R[0-9][0-9][0-9].*b.*c" out && - grep "git> done" trace >done_lines && + grep "fetch> done" trace >done_lines && test_line_count = 1 done_lines ' @@ -175,7 +175,7 @@ test_expect_success 'diff --break-rewrites fetches only if necessary, and batche # by checking that there is only 1 "done" line sent. ("done" marks the # end of negotiation.) GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --break-rewrites --raw -M HEAD^ HEAD && - grep "git> done" trace >done_lines && + grep "fetch> done" trace >done_lines && test_line_count = 1 done_lines ' diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh index 32e3b0ee0b..71ef4132d1 100755 --- a/t/t4104-apply-boundary.sh +++ b/t/t4104-apply-boundary.sh @@ -3,80 +3,55 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git apply boundary tests +test_description='git apply boundary tests' -' . ./test-lib.sh L="c d e f g h i j k l m n o p q r s t u v w x" test_expect_success setup ' - for i in b '"$L"' y - do - echo $i - done >victim && + test_write_lines b $L y >victim && cat victim >original && git update-index --add victim && # add to the head - for i in a b '"$L"' y - do - echo $i - done >victim && + test_write_lines a b $L y >victim && cat victim >add-a-expect && git diff victim >add-a-patch.with && git diff --unified=0 >add-a-patch.without && # insert at line two - for i in b a '"$L"' y - do - echo $i - done >victim && + test_write_lines b a $L y >victim && cat victim >insert-a-expect && git diff victim >insert-a-patch.with && git diff --unified=0 >insert-a-patch.without && # modify at the head - for i in a '"$L"' y - do - echo $i - done >victim && + test_write_lines a $L y >victim && cat victim >mod-a-expect && git diff victim >mod-a-patch.with && git diff --unified=0 >mod-a-patch.without && # remove from the head - for i in '"$L"' y - do - echo $i - done >victim && + test_write_lines $L y >victim && cat victim >del-a-expect && git diff victim >del-a-patch.with && git diff --unified=0 >del-a-patch.without && # add to the tail - for i in b '"$L"' y z - do - echo $i - done >victim && + test_write_lines b $L y z >victim && cat victim >add-z-expect && git diff victim >add-z-patch.with && git diff --unified=0 >add-z-patch.without && # modify at the tail - for i in b '"$L"' z - do - echo $i - done >victim && + test_write_lines b $L z >victim && cat victim >mod-z-expect && git diff victim >mod-z-patch.with && git diff --unified=0 >mod-z-patch.without && # remove from the tail - for i in b '"$L"' - do - echo $i - done >victim && + test_write_lines b $L >victim && cat victim >del-z-expect && git diff victim >del-z-patch.with && git diff --unified=0 >del-z-patch.without @@ -88,15 +63,15 @@ for with in with without do case "$with" in with) u= ;; - without) u='--unidiff-zero ' ;; + without) u=--unidiff-zero ;; esac for kind in add-a add-z insert-a mod-a mod-z del-a del-z do test_expect_success "apply $kind-patch $with context" ' cat original >victim && git update-index victim && - git apply --index '"$u$kind-patch.$with"' && - test_cmp '"$kind"'-expect victim + git apply --index $u "$kind-patch.$with" && + test_cmp "$kind-expect" victim ' done done @@ -110,13 +85,12 @@ do test_expect_success "apply non-git $kind-patch without context" ' cat original >victim && git update-index victim && - git apply --unidiff-zero --index '"$kind-ng.without"' && - test_cmp '"$kind"'-expect victim + git apply --unidiff-zero --index "$kind-ng.without" && + test_cmp "$kind-expect" victim ' done test_expect_success 'two lines' ' - >file && git add file && echo aaa >file && @@ -125,11 +99,10 @@ test_expect_success 'two lines' ' echo bbb >file && git add file && test_must_fail git apply --check patch - ' test_expect_success 'apply patch with 3 context lines matching at end' ' - { echo a; echo b; echo c; echo d; } >file && + test_write_lines a b c d >file && git add file && echo e >>file && git diff >patch && diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh index 99ed4cc546..d1c16ba33c 100755 --- a/t/t4134-apply-submodule.sh +++ b/t/t4134-apply-submodule.sh @@ -8,7 +8,6 @@ test_description='git apply submodule tests' . ./test-lib.sh test_expect_success setup ' - test_oid_init && cat > create-sm.patch <<EOF && diff --git a/dir/sm b/dir/sm new file mode 160000 diff --git a/t/t4140-apply-ita.sh b/t/t4140-apply-ita.sh new file mode 100755 index 0000000000..c614eaf04c --- /dev/null +++ b/t/t4140-apply-ita.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +test_description='git apply of i-t-a file' + +. ./test-lib.sh + +test_expect_success setup ' + test_write_lines 1 2 3 4 5 >blueprint && + + cat blueprint >test-file && + git add -N test-file && + git diff >creation-patch && + grep "new file mode 100644" creation-patch && + + rm -f test-file && + git diff >deletion-patch && + grep "deleted file mode 100644" deletion-patch +' + +test_expect_success 'apply creation patch to ita path (--cached)' ' + git rm -f test-file && + cat blueprint >test-file && + git add -N test-file && + + git apply --cached creation-patch && + git cat-file blob :test-file >actual && + test_cmp blueprint actual +' + +test_expect_success 'apply creation patch to ita path (--index)' ' + git rm -f test-file && + cat blueprint >test-file && + git add -N test-file && + rm -f test-file && + + test_must_fail git apply --index creation-patch +' + +test_expect_success 'apply deletion patch to ita path (--cached)' ' + git rm -f test-file && + cat blueprint >test-file && + git add -N test-file && + + git apply --cached deletion-patch && + test_must_fail git ls-files --stage --error-unmatch test-file +' + +test_expect_success 'apply deletion patch to ita path (--index)' ' + cat blueprint >test-file && + git add -N test-file && + + test_must_fail git apply --index deletion-patch && + git ls-files --stage --error-unmatch test-file +' + +test_done diff --git a/t/t4150-am.sh b/t/t4150-am.sh index bda4586a79..1da8ab120b 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -989,7 +989,7 @@ test_expect_success 'am -s unexpected trailer block' ' Signed-off-by: J C H <j@c.h> EOF git commit -F msg && - git cat-file commit HEAD | sed -e '1,/^$/d' >original && + git cat-file commit HEAD | sed -e "1,/^$/d" >original && git format-patch --stdout -1 >patch && git reset --hard HEAD^ && @@ -998,7 +998,7 @@ test_expect_success 'am -s unexpected trailer block' ' cat original && echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" ) >expect && - git cat-file commit HEAD | sed -e '1,/^$/d' >actual && + git cat-file commit HEAD | sed -e "1,/^$/d" >actual && test_cmp expect actual && cat >msg <<-\EOF && @@ -1009,7 +1009,7 @@ test_expect_success 'am -s unexpected trailer block' ' EOF git reset HEAD^ && git commit -F msg file && - git cat-file commit HEAD | sed -e '1,/^$/d' >original && + git cat-file commit HEAD | sed -e "1,/^$/d" >original && git format-patch --stdout -1 >patch && git reset --hard HEAD^ && @@ -1020,7 +1020,7 @@ test_expect_success 'am -s unexpected trailer block' ' echo && echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" ) >expect && - git cat-file commit HEAD | sed -e '1,/^$/d' >actual && + git cat-file commit HEAD | sed -e "1,/^$/d" >actual && test_cmp expect actual ' @@ -1133,4 +1133,20 @@ test_expect_success 'am and .gitattibutes' ' ) ' +test_expect_success 'apply binary blob in partial clone' ' + printf "\\000" >binary && + git add binary && + git commit -m "binary blob" && + git format-patch --stdout -m HEAD^ >patch && + + test_create_repo server && + test_config -C server uploadpack.allowfilter 1 && + test_config -C server uploadpack.allowanysha1inwant 1 && + git clone --filter=blob:none "file://$(pwd)/server" client && + test_when_finished "rm -rf client" && + + # Exercise to make sure that it works + git -C client am ../patch +' + test_done diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 831d424c47..b12b43e9e9 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -25,7 +25,6 @@ test_description='git rerere . ./test-lib.sh test_expect_success 'setup' ' - test_oid_init && cat >a1 <<-\EOF && Some title ========== @@ -364,7 +363,7 @@ test_expect_success 'set up an unresolved merge' ' git reset --hard && git checkout version2 && fifth=$(git rev-parse fifth) && - echo "$fifth branch 'fifth' of ." | + echo "$fifth branch fifth of ." | git fmt-merge-msg >msg && ancestor=$(git merge-base version2 fifth) && test_must_fail git merge-recursive "$ancestor" -- HEAD fifth && diff --git a/t/t4202-log.sh b/t/t4202-log.sh index fd9af658af..56d34ed465 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -483,7 +483,7 @@ test_expect_success 'set up merge history' ' ' cat > expect <<\EOF -* Merge branch 'side' into master +* Merge branch 'side' |\ | * side-2 | * side-1 @@ -502,7 +502,7 @@ test_expect_success 'log --graph with merge' ' ' cat > expect <<\EOF -| | | * Merge branch 'side' into master +| | | * Merge branch 'side' | | | |\ | | | | * side-2 | | | | * side-1 @@ -521,7 +521,7 @@ test_expect_success 'log --graph --line-prefix="| | | " with merge' ' ' cat > expect.colors <<\EOF -* Merge branch 'side' into master +* Merge branch 'side' <BLUE>|<RESET><CYAN>\<RESET> <BLUE>|<RESET> * side-2 <BLUE>|<RESET> * side-1 @@ -555,7 +555,7 @@ cat > expect <<\EOF |\ Merge: A B | | Author: A U Thor <author@example.com> | | -| | Merge branch 'side' into master +| | Merge branch 'side' | | | * commit tags/side-2 | | Author: A U Thor <author@example.com> @@ -632,11 +632,11 @@ test_expect_success 'set up more tangled history' ' ' cat > expect <<\EOF -* Merge tag 'reach' into master +* Merge tag 'reach' |\ | \ | \ -*-. \ Merge tags 'octopus-a' and 'octopus-b' into master +*-. \ Merge tags 'octopus-a' and 'octopus-b' |\ \ \ * | | | seventh | | * | octopus-b @@ -646,14 +646,14 @@ cat > expect <<\EOF |/ / | * reach |/ -* Merge branch 'tangle' into master +* Merge branch 'tangle' |\ | * Merge branch 'side' (early part) into tangle | |\ | * \ Merge branch 'master' (early part) into tangle | |\ \ | * | | tangle-a -* | | | Merge branch 'side' into master +* | | | Merge branch 'side' |\ \ \ \ | * | | | side-2 | | |_|/ @@ -735,16 +735,16 @@ test_expect_success 'log.decorate configuration' ' test_expect_success 'decorate-refs with glob' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b (octopus-b) octopus-a (octopus-a) reach EOF cat >expect.no-decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b octopus-a @@ -765,8 +765,8 @@ test_expect_success 'decorate-refs with glob' ' test_expect_success 'decorate-refs without globs' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b octopus-a @@ -779,8 +779,8 @@ test_expect_success 'decorate-refs without globs' ' test_expect_success 'multiple decorate-refs' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b (octopus-b) octopus-a (octopus-a) @@ -794,8 +794,8 @@ test_expect_success 'multiple decorate-refs' ' test_expect_success 'decorate-refs-exclude with glob' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (HEAD -> master) + Merge-tags-octopus-a-and-octopus-b seventh (tag: seventh) octopus-b (tag: octopus-b) octopus-a (tag: octopus-a) @@ -811,8 +811,8 @@ test_expect_success 'decorate-refs-exclude with glob' ' test_expect_success 'decorate-refs-exclude without globs' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (HEAD -> master) + Merge-tags-octopus-a-and-octopus-b seventh (tag: seventh) octopus-b (tag: octopus-b, octopus-b) octopus-a (tag: octopus-a, octopus-a) @@ -828,8 +828,8 @@ test_expect_success 'decorate-refs-exclude without globs' ' test_expect_success 'multiple decorate-refs-exclude' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (HEAD -> master) + Merge-tags-octopus-a-and-octopus-b seventh (tag: seventh) octopus-b (tag: octopus-b) octopus-a (tag: octopus-a) @@ -851,8 +851,8 @@ test_expect_success 'multiple decorate-refs-exclude' ' test_expect_success 'decorate-refs and decorate-refs-exclude' ' cat >expect.no-decorate <<-\EOF && - Merge-tag-reach-into-master (master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (master) + Merge-tags-octopus-a-and-octopus-b seventh octopus-b octopus-a @@ -866,8 +866,8 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' ' test_expect_success 'deocrate-refs and log.excludeDecoration' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (master) + Merge-tags-octopus-a-and-octopus-b seventh octopus-b (octopus-b) octopus-a (octopus-a) @@ -881,10 +881,10 @@ test_expect_success 'deocrate-refs and log.excludeDecoration' ' test_expect_success 'decorate-refs-exclude and simplify-by-decoration' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) + Merge-tag-reach (HEAD -> master) reach (tag: reach, reach) seventh (tag: seventh) - Merge-branch-tangle-into-master + Merge-branch-tangle Merge-branch-side-early-part-into-tangle (tangle) tangle-a (tag: tangle-a) EOF @@ -1068,7 +1068,7 @@ cat >expect <<\EOF |\ Merge: MERGE_PARENTS | | Author: A U Thor <author@example.com> | | -| | Merge branch 'tangle' into master +| | Merge branch 'tangle' | | | * commit COMMIT_OBJECT_NAME | |\ Merge: MERGE_PARENTS @@ -1102,7 +1102,7 @@ cat >expect <<\EOF |\ \ \ \ Merge: MERGE_PARENTS | | | | | Author: A U Thor <author@example.com> | | | | | -| | | | | Merge branch 'side' into master +| | | | | Merge branch 'side' | | | | | | * | | | commit COMMIT_OBJECT_NAME | | |_|/ Author: A U Thor <author@example.com> @@ -1343,7 +1343,7 @@ cat >expect <<\EOF *** |\ Merge: MERGE_PARENTS *** | | Author: A U Thor <author@example.com> *** | | -*** | | Merge branch 'tangle' into master +*** | | Merge branch 'tangle' *** | | *** | * commit COMMIT_OBJECT_NAME *** | |\ Merge: MERGE_PARENTS @@ -1377,7 +1377,7 @@ cat >expect <<\EOF *** |\ \ \ \ Merge: MERGE_PARENTS *** | | | | | Author: A U Thor <author@example.com> *** | | | | | -*** | | | | | Merge branch 'side' into master +*** | | | | | Merge branch 'side' *** | | | | | *** | * | | | commit COMMIT_OBJECT_NAME *** | | |_|/ Author: A U Thor <author@example.com> @@ -1540,8 +1540,8 @@ cat >expect <<-\EOF * reach | | A reach.t -* Merge branch 'tangle' into master -* Merge branch 'side' into master +* Merge branch 'tangle' +* Merge branch 'side' |\ | * side-2 | @@ -1562,8 +1562,8 @@ cat >expect <<-\EOF * reach | | reach.t -* Merge branch 'tangle' into master -* Merge branch 'side' into master +* Merge branch 'tangle' +* Merge branch 'side' |\ | * side-2 | @@ -1850,6 +1850,16 @@ test_expect_success 'log does not default to HEAD when rev input is given' ' test_must_be_empty actual ' +test_expect_success 'do not default to HEAD with ignored object on cmdline' ' + git log --ignore-missing $ZERO_OID >actual && + test_must_be_empty actual +' + +test_expect_success 'do not default to HEAD with ignored object on stdin' ' + echo $ZERO_OID | git log --ignore-missing --stdin >actual && + test_must_be_empty actual +' + test_expect_success 'set up --source tests' ' git checkout --orphan source-a && test_commit one && diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index e186c83250..2d1d7b5d19 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -4,7 +4,6 @@ test_description='test log -L' . ./test-lib.sh test_expect_success 'setup (import history)' ' - test_oid_init && git fast-import < "$TEST_DIRECTORY"/t4211/history.export && git reset --hard ' diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh index c855bcd3e7..d11040ce41 100755 --- a/t/t4216-log-bloom.sh +++ b/t/t4216-log-bloom.sh @@ -30,12 +30,19 @@ test_expect_success 'setup test - repo, commits, commit graph, log outputs' ' rm file_to_be_deleted && git add . && git commit -m "file removed" && - git commit-graph write --reachable --changed-paths + git commit --allow-empty -m "empty" && + git commit-graph write --reachable --changed-paths && + + test_oid_cache <<-EOF + oid_version sha1:1 + oid_version sha256:2 + EOF ' + graph_read_expect () { NUM_CHUNKS=5 cat >expect <<- EOF - header: 43475048 1 1 $NUM_CHUNKS 0 + header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0 num_commits: $1 chunks: oid_fanout oid_lookup commit_metadata bloom_indexes bloom_data EOF @@ -44,7 +51,7 @@ graph_read_expect () { } test_expect_success 'commit-graph write wrote out the bloom chunks' ' - graph_read_expect 15 + graph_read_expect 16 ' # Turn off any inherited trace2 settings for this test. @@ -53,14 +60,14 @@ sane_unset GIT_TRACE2_PERF_BRIEF sane_unset GIT_TRACE2_CONFIG_PARAMS setup () { - rm "$TRASH_DIRECTORY/trace.perf" + 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 } test_bloom_filters_used () { log_args=$1 - bloom_trace_prefix="statistics:{\"filter_not_present\":0,\"zero_length_filter\":0,\"maybe\"" + bloom_trace_prefix="statistics:{\"filter_not_present\":${2:-0},\"maybe\"" setup "$log_args" && grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" && test_cmp log_wo_bloom log_w_bloom && @@ -90,7 +97,9 @@ do "--ancestry-path side..master" do test_expect_success "git log option: $option for path: $path" ' - test_bloom_filters_used "$option -- $path" + test_bloom_filters_used "$option -- $path" && + test_config commitgraph.readChangedPaths false && + test_bloom_filters_not_used "$option -- $path" ' done done @@ -112,6 +121,10 @@ 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 "-- ." +' + test_expect_success 'git log with wildcard that resolves to a single path uses Bloom filters' ' test_bloom_filters_used "-- *4" && test_bloom_filters_used "-- *renamed" @@ -126,12 +139,15 @@ test_expect_success 'setup - add commit-graph to the chain without Bloom filters test_commit c14 A/anotherFile2 && test_commit c15 A/B/anotherFile2 && test_commit c16 A/B/C/anotherFile2 && - GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0 git commit-graph write --reachable --split && + git commit-graph write --reachable --split --no-changed-paths && test_line_count = 2 .git/objects/info/commit-graphs/commit-graph-chain ' -test_expect_success 'Do not use Bloom filters if the latest graph does not have Bloom filters.' ' - test_bloom_filters_not_used "-- A/B" +test_expect_success 'use Bloom filters even if the latest graph does not have Bloom filters' ' + # Ensure that the number of empty filters is equal to the number of + # filters in the latest graph layer to prove that they are loaded (and + # ignored). + test_bloom_filters_used "-- A/B" 3 ' test_expect_success 'setup - add commit-graph to the chain with Bloom filters' ' @@ -142,7 +158,7 @@ test_expect_success 'setup - add commit-graph to the chain with Bloom filters' ' test_bloom_filters_used_when_some_filters_are_missing () { log_args=$1 - bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"zero_length_filter\":0,\"maybe\":8,\"definitely_not\":6" + bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"maybe\":6,\"definitely_not\":9" setup "$log_args" && grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" && test_cmp log_wo_bloom log_w_bloom @@ -152,4 +168,238 @@ test_expect_success 'Use Bloom filters if they exist in the latest but not all c test_bloom_filters_used_when_some_filters_are_missing "-- A/B" ' +test_expect_success 'persist filter settings' ' + test_when_finished rm -rf .git/objects/info/commit-graph* && + rm -rf .git/objects/info/commit-graph* && + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ + GIT_TRACE2_EVENT_NESTING=5 \ + GIT_TEST_BLOOM_SETTINGS_NUM_HASHES=9 \ + GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY=15 \ + git commit-graph write --reachable --changed-paths && + grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2.txt && + GIT_TRACE2_EVENT="$(pwd)/trace2-auto.txt" \ + GIT_TRACE2_EVENT_NESTING=5 \ + git commit-graph write --reachable --changed-paths && + grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2-auto.txt +' + +test_max_changed_paths () { + grep "\"max_changed_paths\":$1" $2 +} + +test_filter_not_computed () { + grep "\"key\":\"filter-not-computed\",\"value\":\"$1\"" $2 +} + +test_filter_computed () { + grep "\"key\":\"filter-computed\",\"value\":\"$1\"" $2 +} + +test_filter_trunc_empty () { + grep "\"key\":\"filter-trunc-empty\",\"value\":\"$1\"" $2 +} + +test_filter_trunc_large () { + grep "\"key\":\"filter-trunc-large\",\"value\":\"$1\"" $2 +} + +test_expect_success 'correctly report changes over limit' ' + git init limits && + ( + cd limits && + mkdir d && + mkdir d/e && + + for i in $(test_seq 1 2) + do + printf $i >d/file$i.txt && + printf $i >d/e/file$i.txt || return 1 + done && + + mkdir mode && + printf bash >mode/script.sh && + + mkdir foo && + touch foo/bar && + touch foo.txt && + + git add d foo foo.txt mode && + git commit -m "files" && + + # Commit has 7 file and 4 directory adds + GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=10 \ + GIT_TRACE2_EVENT="$(pwd)/trace" \ + git commit-graph write --reachable --changed-paths && + test_max_changed_paths 10 trace && + test_filter_computed 1 trace && + test_filter_trunc_large 1 trace && + + for path in $(git ls-tree -r --name-only HEAD) + do + git -c commitGraph.readChangedPaths=false log \ + -- $path >expect && + git log -- $path >actual && + test_cmp expect actual || return 1 + done && + + # Make a variety of path changes + printf new1 >d/e/file1.txt && + printf new2 >d/file2.txt && + rm d/e/file2.txt && + rm -r foo && + printf text >foo && + mkdir f && + printf new1 >f/file1.txt && + + # including a mode-only change (counts as modified) + git update-index --chmod=+x mode/script.sh && + + git add foo d f && + git commit -m "complicated" && + + # start from scratch and rebuild + rm -f .git/objects/info/commit-graph && + GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=10 \ + GIT_TRACE2_EVENT="$(pwd)/trace-edit" \ + git commit-graph write --reachable --changed-paths && + test_max_changed_paths 10 trace-edit && + test_filter_computed 2 trace-edit && + test_filter_trunc_large 2 trace-edit && + + for path in $(git ls-tree -r --name-only HEAD) + do + git -c commitGraph.readChangedPaths=false log \ + -- $path >expect && + git log -- $path >actual && + test_cmp expect actual || return 1 + done && + + # start from scratch and rebuild + rm -f .git/objects/info/commit-graph && + GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=11 \ + GIT_TRACE2_EVENT="$(pwd)/trace-update" \ + git commit-graph write --reachable --changed-paths && + test_max_changed_paths 11 trace-update && + test_filter_computed 2 trace-update && + test_filter_trunc_large 0 trace-update && + + for path in $(git ls-tree -r --name-only HEAD) + do + git -c commitGraph.readChangedPaths=false log \ + -- $path >expect && + git log -- $path >actual && + test_cmp expect actual || return 1 + done + ) +' + +test_expect_success 'correctly report commits with no changed paths' ' + git init empty && + test_when_finished "rm -fr empty" && + ( + cd empty && + + git commit --allow-empty -m "initial commit" && + + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + git commit-graph write --reachable --changed-paths && + test_filter_computed 1 trace.event && + test_filter_not_computed 0 trace.event && + test_filter_trunc_empty 1 trace.event && + test_filter_trunc_large 0 trace.event + ) +' + +test_expect_success 'Bloom generation is limited by --max-new-filters' ' + ( + cd limits && + test_commit c2 filter && + test_commit c3 filter && + test_commit c4 no-filter && + + rm -f trace.event && + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + git commit-graph write --reachable --split=replace \ + --changed-paths --max-new-filters=2 && + + test_filter_computed 2 trace.event && + test_filter_not_computed 3 trace.event && + test_filter_trunc_empty 0 trace.event && + test_filter_trunc_large 0 trace.event + ) +' + +test_expect_success 'Bloom generation backfills previously-skipped filters' ' + # Check specifying commitGraph.maxNewFilters over "git config" works. + test_config -C limits commitGraph.maxNewFilters 1 && + ( + cd limits && + + rm -f trace.event && + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + git commit-graph write --reachable --changed-paths \ + --split=replace && + test_filter_computed 1 trace.event && + test_filter_not_computed 4 trace.event && + test_filter_trunc_empty 0 trace.event && + test_filter_trunc_large 0 trace.event + ) +' + +test_expect_success '--max-new-filters overrides configuration' ' + git init override && + test_when_finished "rm -fr override" && + test_config -C override commitGraph.maxNewFilters 2 && + ( + cd override && + test_commit one && + test_commit two && + + rm -f trace.event && + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + git commit-graph write --reachable --changed-paths \ + --max-new-filters=1 && + test_filter_computed 1 trace.event && + test_filter_not_computed 1 trace.event && + test_filter_trunc_empty 0 trace.event && + test_filter_trunc_large 0 trace.event + ) +' + +test_expect_success 'Bloom generation backfills empty commits' ' + git init empty && + test_when_finished "rm -fr empty" && + ( + cd empty && + for i in $(test_seq 1 6) + do + git commit --allow-empty -m "$i" + done && + + # Generate Bloom filters for empty commits 1-6, two at a time. + for i in $(test_seq 1 3) + do + rm -f trace.event && + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + git commit-graph write --reachable \ + --changed-paths --max-new-filters=2 && + test_filter_computed 2 trace.event && + test_filter_not_computed 4 trace.event && + test_filter_trunc_empty 2 trace.event && + test_filter_trunc_large 0 trace.event + done && + + # Finally, make sure that once all commits have filters, that + # none are subsequently recomputed. + rm -f trace.event && + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + git commit-graph write --reachable \ + --changed-paths --max-new-filters=2 && + test_filter_computed 0 trace.event && + test_filter_not_computed 6 trace.event && + test_filter_trunc_empty 0 trace.event && + test_filter_trunc_large 0 trace.event + ) +' + test_done diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 746cdb626e..392201cabd 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -12,8 +12,7 @@ TRASH=$(pwd) test_expect_success \ 'setup' \ - 'test_oid_init && - rm -f .git/index* && + 'rm -f .git/index* && perl -e "print \"a\" x 4096;" > a && perl -e "print \"b\" x 4096;" > b && perl -e "print \"c\" x 4096;" > c && @@ -497,4 +496,40 @@ test_expect_success 'make sure index-pack detects the SHA1 collision (large blob ) ' +test_expect_success 'prefetch objects' ' + rm -rf server client && + + git init server && + test_config -C server uploadpack.allowanysha1inwant 1 && + test_config -C server uploadpack.allowfilter 1 && + test_config -C server protocol.version 2 && + + echo one >server/one && + git -C server add one && + git -C server commit -m one && + git -C server branch one_branch && + + echo two_a >server/two_a && + echo two_b >server/two_b && + git -C server add two_a two_b && + git -C server commit -m two && + + echo three >server/three && + git -C server add three && + git -C server commit -m three && + git -C server branch three_branch && + + # Clone, fetch "two" with blobs excluded, and re-push it. This requires + # the client to have the blobs of "two" - verify that these are + # prefetched in one batch. + git clone --filter=blob:none --single-branch -b one_branch \ + "file://$(pwd)/server" client && + test_config -C client protocol.version 2 && + TWO=$(git -C server rev-parse three_branch^) && + git -C client fetch --filter=blob:none origin "$TWO" && + GIT_TRACE_PACKET=$(pwd)/trace git -C client push origin "$TWO":refs/heads/two_branch && + grep "fetch> done" trace >donelines && + test_line_count = 1 donelines +' + test_done diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 8981c9b90e..c92e553a2f 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -7,7 +7,6 @@ test_description='pack index with 64-bit offsets and object CRC' . ./test-lib.sh test_expect_success 'setup' ' - test_oid_init && rawsz=$(test_oid rawsz) && rm -rf .git && git init && @@ -15,7 +14,7 @@ test_expect_success 'setup' ' i=1 && while test $i -le 100 do - iii=$(printf '%03i' $i) + iii=$(printf "%03i" $i) test-tool genrandom "bar" 200 > wide_delta_$iii && test-tool genrandom "baz $iii" 50 >> wide_delta_$iii && test-tool genrandom "foo"$i 100 > deep_delta_$iii && diff --git a/t/t5308-pack-detect-duplicates.sh b/t/t5308-pack-detect-duplicates.sh index 6845c1f3c3..693b2411c8 100755 --- a/t/t5308-pack-detect-duplicates.sh +++ b/t/t5308-pack-detect-duplicates.sh @@ -4,23 +4,27 @@ test_description='handling of duplicate objects in incoming packfiles' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pack.sh -if ! test_have_prereq SHA1 -then - skip_all='not using SHA-1 for objects' - test_done -fi +test_expect_success 'setup' ' + test_oid_cache <<-EOF + lo_oid sha1:e68fe8129b546b101aee9510c5328e7f21ca1d18 + lo_oid sha256:471819e8c52bf11513f100b2810a8aa0622d5cd3d1c913758a071dd4b3bad8fe + + missing_oid sha1:e69d000000000000000000000000000000000000 + missing_oid sha256:4720000000000000000000000000000000000000000000000000000000000000 + EOF +' # The sha1s we have in our pack. It's important that these have the same # starting byte, so that they end up in the same fanout section of the index. # That lets us make sure we are exercising the binary search with both sets. -LO_SHA1=e68fe8129b546b101aee9510c5328e7f21ca1d18 -HI_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 +LO_SHA1=$(test_oid lo_oid) +HI_SHA1=$EMPTY_BLOB # And here's a "missing sha1" which will produce failed lookups. It must also # be in the same fanout section, and should be between the two (so that during # our binary search, we are sure to end up looking at one or the other of the # duplicate runs). -MISSING_SHA1='e69d000000000000000000000000000000000000' +MISSING_SHA1=$(test_oid missing_oid) # git will never intentionally create packfiles with # duplicate objects, so we have to construct them by hand. diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh index 2a4557efc2..535313e4dc 100755 --- a/t/t5313-pack-bounds-checks.sh +++ b/t/t5313-pack-bounds-checks.sh @@ -45,7 +45,6 @@ extended_table () { } test_expect_success 'setup' ' - test_oid_init && test_oid_cache <<-EOF oid000 sha1:1485 oid000 sha256:4222 diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 26f332d6a3..2ed0c1544d 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -11,7 +11,11 @@ test_expect_success 'setup full repo' ' git init && git config core.commitGraph true && objdir=".git/objects" && - test_oid_init + + test_oid_cache <<-EOF + oid_version sha1:1 + oid_version sha256:2 + EOF ' test_expect_success POSIXPERM 'tweak umask for modebit tests' ' @@ -78,7 +82,7 @@ graph_read_expect() { NUM_CHUNKS=$((3 + $(echo "$2" | wc -w))) fi cat >expect <<- EOF - header: 43475048 1 1 $NUM_CHUNKS 0 + header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0 num_commits: $1 chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL EOF @@ -413,6 +417,35 @@ test_expect_success 'replace-objects invalidates commit-graph' ' ) ' +test_expect_success 'warn on improper hash version' ' + git init --object-format=sha1 sha1 && + ( + cd sha1 && + test_commit 1 && + git commit-graph write --reachable && + mv .git/objects/info/commit-graph ../cg-sha1 + ) && + git init --object-format=sha256 sha256 && + ( + cd sha256 && + test_commit 1 && + git commit-graph write --reachable && + mv .git/objects/info/commit-graph ../cg-sha256 + ) && + ( + cd sha1 && + mv ../cg-sha256 .git/objects/info/commit-graph && + git log -1 2>err && + test_i18ngrep "commit-graph hash version 2 does not match version 1" err + ) && + ( + cd sha256 && + mv ../cg-sha1 .git/objects/info/commit-graph && + git log -1 2>err && + test_i18ngrep "commit-graph hash version 1 does not match version 2" err + ) +' + # the verify tests below expect the commit-graph to contain # exactly the commits reachable from the commits/8 branch. # If the file changes the set of commits in the list, then the @@ -476,7 +509,7 @@ corrupt_graph_verify() { cp $objdir/info/commit-graph commit-graph-pre-write-test fi && git status --short && - GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD=true git commit-graph write && + GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE=true git commit-graph write && chmod u+w $objdir/info/commit-graph && git commit-graph verify } @@ -529,7 +562,7 @@ test_expect_success 'detect bad hash version' ' ' test_expect_success 'detect low chunk count' ' - corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\02" \ + corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\01" \ "missing the .* chunk" ' @@ -615,7 +648,8 @@ test_expect_success 'detect invalid checksum hash' ' test_expect_success 'detect incorrect chunk count' ' corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\377" \ - "chunk lookup table entry missing" $GRAPH_CHUNK_LOOKUP_OFFSET + "commit-graph file is too small to hold [0-9]* chunks" \ + $GRAPH_CHUNK_LOOKUP_OFFSET ' test_expect_success 'git fsck (checks commit-graph)' ' diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index 7214cab36c..f340b376bc 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -5,6 +5,8 @@ test_description='multi-pack-indexes' objdir=.git/objects +HASH_LEN=$(test_oid rawsz) + midx_read_expect () { NUM_PACKS=$1 NUM_OBJECTS=$2 @@ -13,7 +15,7 @@ midx_read_expect () { EXTRA_CHUNKS="$5" { cat <<-EOF && - header: 4d494458 1 $NUM_CHUNKS $NUM_PACKS + header: 4d494458 1 $HASH_LEN $NUM_CHUNKS $NUM_PACKS chunks: pack-names oid-fanout oid-lookup object-offsets$EXTRA_CHUNKS num_objects: $NUM_OBJECTS packs: @@ -29,7 +31,6 @@ midx_read_expect () { } test_expect_success 'setup' ' - test_oid_init && test_oid_cache <<-EOF idxoff sha1:2999 idxoff sha256:3739 @@ -47,7 +48,7 @@ test_expect_success "don't write midx with no packs" ' test_path_is_missing pack/multi-pack-index ' -test_expect_success "Warn if a midx contains no oid" ' +test_expect_success SHA1 'warn if a midx contains no oid' ' cp "$TEST_DIRECTORY"/t5319/no-objects.midx $objdir/pack/multi-pack-index && test_must_fail git multi-pack-index verify && rm $objdir/pack/multi-pack-index @@ -199,6 +200,40 @@ test_expect_success 'write midx with twelve packs' ' compare_results_with_midx "twelve packs" +test_expect_success 'warn on improper hash version' ' + git init --object-format=sha1 sha1 && + ( + cd sha1 && + git config core.multiPackIndex true && + test_commit 1 && + git repack -a && + git multi-pack-index write && + mv .git/objects/pack/multi-pack-index ../mpi-sha1 + ) && + git init --object-format=sha256 sha256 && + ( + cd sha256 && + git config core.multiPackIndex true && + test_commit 1 && + git repack -a && + git multi-pack-index write && + mv .git/objects/pack/multi-pack-index ../mpi-sha256 + ) && + ( + cd sha1 && + mv ../mpi-sha256 .git/objects/pack/multi-pack-index && + git log -1 2>err && + test_i18ngrep "multi-pack-index hash version 2 does not match version 1" err + ) && + ( + cd sha256 && + mv ../mpi-sha1 .git/objects/pack/multi-pack-index && + git log -1 2>err && + test_i18ngrep "multi-pack-index hash version 1 does not match version 2" err + ) +' + + test_expect_success 'verify multi-pack-index success' ' git multi-pack-index verify --object-dir=$objdir ' @@ -244,7 +279,6 @@ test_expect_success 'verify bad signature' ' "multi-pack-index signature" ' -HASH_LEN=$(test_oid rawsz) NUM_OBJECTS=74 MIDX_BYTE_VERSION=4 MIDX_BYTE_OID_VERSION=5 @@ -273,7 +307,7 @@ test_expect_success 'verify bad version' ' ' test_expect_success 'verify bad OID version' ' - corrupt_midx_and_verify $MIDX_BYTE_OID_VERSION "\02" $objdir \ + corrupt_midx_and_verify $MIDX_BYTE_OID_VERSION "\03" $objdir \ "hash version" ' @@ -348,12 +382,52 @@ test_expect_success 'repack with the --no-progress option' ' test_line_count = 0 err ' -test_expect_success 'repack removes multi-pack-index' ' +test_expect_success 'repack removes multi-pack-index when deleting packs' ' test_path_is_file $objdir/pack/multi-pack-index && - GIT_TEST_MULTI_PACK_INDEX=0 git repack -adf && + # Set GIT_TEST_MULTI_PACK_INDEX to 0 to avoid writing a new + # multi-pack-index after repacking, but set "core.multiPackIndex" to + # true so that "git repack" can read the existing MIDX. + GIT_TEST_MULTI_PACK_INDEX=0 git -c core.multiPackIndex repack -adf && test_path_is_missing $objdir/pack/multi-pack-index ' +test_expect_success 'repack preserves multi-pack-index when creating packs' ' + git init preserve && + test_when_finished "rm -fr preserve" && + ( + cd preserve && + packdir=.git/objects/pack && + midx=$packdir/multi-pack-index && + + test_commit 1 && + pack1=$(git pack-objects --all $packdir/pack) && + touch $packdir/pack-$pack1.keep && + test_commit 2 && + pack2=$(git pack-objects --revs $packdir/pack) && + touch $packdir/pack-$pack2.keep && + + git multi-pack-index write && + cp $midx $midx.bak && + + cat >pack-input <<-EOF && + HEAD + ^HEAD~1 + EOF + test_commit 3 && + pack3=$(git pack-objects --revs $packdir/pack <pack-input) && + test_commit 4 && + pack4=$(git pack-objects --revs $packdir/pack <pack-input) && + + GIT_TEST_MULTI_PACK_INDEX=0 git -c core.multiPackIndex repack -ad && + ls -la $packdir && + test_path_is_file $packdir/pack-$pack1.pack && + test_path_is_file $packdir/pack-$pack2.pack && + test_path_is_missing $packdir/pack-$pack3.pack && + test_path_is_missing $packdir/pack-$pack4.pack && + test_cmp_bin $midx.bak $midx + ) +' + compare_results_with_midx "after repack" test_expect_success 'multi-pack-index and pack-bitmap' ' @@ -643,6 +717,7 @@ test_expect_success 'expire respects .keep files' ' ' test_expect_success 'repack --batch-size=0 repacks everything' ' + cp -r dup dup2 && ( cd dup && rm .git/objects/pack/*.keep && @@ -662,4 +737,21 @@ test_expect_success 'repack --batch-size=0 repacks everything' ' ) ' +test_expect_success 'repack --batch-size=<large> repacks everything' ' + ( + cd dup2 && + rm .git/objects/pack/*.keep && + ls .git/objects/pack/*idx >idx-list && + test_line_count = 2 idx-list && + git multi-pack-index repack --batch-size=2000000 && + ls .git/objects/pack/*idx >idx-list && + test_line_count = 3 idx-list && + test-tool read-midx .git/objects | grep idx >midx-list && + test_line_count = 3 midx-list && + git multi-pack-index expire && + ls -al .git/objects/pack/*idx >idx-list && + test_line_count = 1 idx-list + ) +' + test_done diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index 269d0964a3..c334ee9155 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -12,13 +12,15 @@ test_expect_success 'setup repo' ' git config gc.writeCommitGraph false && infodir=".git/objects/info" && graphdir="$infodir/commit-graphs" && - test_oid_init && test_oid_cache <<-EOM shallow sha1:1760 shallow sha256:2064 base sha1:1376 base sha256:1496 + + oid_version sha1:1 + oid_version sha256:2 EOM ' @@ -29,7 +31,7 @@ graph_read_expect() { NUM_BASE=$2 fi cat >expect <<- EOF - header: 43475048 1 1 3 $NUM_BASE + header: 43475048 1 $(test_oid oid_version) 3 $NUM_BASE num_commits: $1 chunks: oid_fanout oid_lookup commit_metadata EOF @@ -399,7 +401,7 @@ test_expect_success ULIMIT_FILE_DESCRIPTORS 'handles file descriptor exhaustion' for i in $(test_seq 64) do test_commit $i && - test_might_fail run_with_limited_open_files git commit-graph write \ + run_with_limited_open_files test_might_fail git commit-graph write \ --split=no-merge --reachable || return 1 done ) @@ -425,4 +427,17 @@ done <<\EOF 0600 -r-------- EOF +test_expect_success '--split=replace with partial Bloom data' ' + rm -rf $graphdir $infodir/commit-graph && + git reset --hard commits/3 && + git rev-list -1 HEAD~2 >a && + git rev-list -1 HEAD~1 >b && + git commit-graph write --split=no-merge --stdin-commits --changed-paths <a && + git commit-graph write --split=no-merge --stdin-commits <b && + git commit-graph write --split=replace --stdin-commits --changed-paths <c && + ls $graphdir/graph-*.graph >graph-files && + test_line_count = 1 graph-files && + verify_chain_files_exist $graphdir +' + test_done diff --git a/t/t5411-proc-receive-hook.sh b/t/t5411-proc-receive-hook.sh new file mode 100755 index 0000000000..746487286f --- /dev/null +++ b/t/t5411-proc-receive-hook.sh @@ -0,0 +1,117 @@ +#!/bin/sh +# +# Copyright (c) 2020 Jiang Xin +# + +test_description='Test proc-receive hook' + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/t5411/common-functions.sh + +setup_upstream_and_workbench () { + # Refs of upstream : master(A) + # Refs of workbench: master(A) tags/v123 + test_expect_success "setup upstream and workbench" ' + rm -rf upstream.git && + rm -rf workbench && + git init --bare upstream.git && + git init workbench && + create_commits_in workbench A B && + ( + cd workbench && + # Try to make a stable fixed width for abbreviated commit ID, + # this fixed-width oid will be replaced with "<OID>". + git config core.abbrev 7 && + git tag -m "v123" v123 $A && + git remote add origin ../upstream.git && + git push origin master && + git update-ref refs/heads/master $A $B && + git -C ../upstream.git update-ref \ + refs/heads/master $A $B + ) && + TAG=$(git -C workbench rev-parse v123) && + + # setup pre-receive hook + write_script upstream.git/hooks/pre-receive <<-\EOF && + exec >&2 + echo "# pre-receive hook" + while read old new ref + do + echo "pre-receive< $old $new $ref" + done + EOF + + # setup post-receive hook + write_script upstream.git/hooks/post-receive <<-\EOF && + exec >&2 + echo "# post-receive hook" + while read old new ref + do + echo "post-receive< $old $new $ref" + done + EOF + + upstream=upstream.git + ' +} + +run_proc_receive_hook_test() { + case $1 in + http) + PROTOCOL="HTTP protocol" + URL_PREFIX="http://.*" + ;; + local) + PROTOCOL="builtin protocol" + URL_PREFIX="\.\." + ;; + esac + + # Include test cases for both file and HTTP protocol + for t in "$TEST_DIRECTORY"/t5411/test-*.sh + do + . "$t" + done +} + +# Initialize the upstream repository and local workbench. +setup_upstream_and_workbench + +# Load test cases that only need to be executed once. +for t in "$TEST_DIRECTORY"/t5411/once-*.sh +do + . "$t" +done + +# Initialize the upstream repository and local workbench. +setup_upstream_and_workbench + +# Run test cases for 'proc-receive' hook on local file protocol. +run_proc_receive_hook_test local + +ROOT_PATH="$PWD" +. "$TEST_DIRECTORY"/lib-gpg.sh +. "$TEST_DIRECTORY"/lib-httpd.sh +. "$TEST_DIRECTORY"/lib-terminal.sh +start_httpd + +# Re-initialize the upstream repository and local workbench. +setup_upstream_and_workbench + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "setup for HTTP protocol" ' + git -C upstream.git config http.receivepack true && + upstream="$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" && + mv upstream.git "$upstream" && + git -C workbench remote set-url origin "$HTTPD_URL/auth-push/smart/upstream.git" && + set_askpass user@host pass@host +' + +setup_askpass_helper + +# Run test cases for 'proc-receive' hook on HTTP protocol. +run_proc_receive_hook_test http + +test_done diff --git a/t/t5411/common-functions.sh b/t/t5411/common-functions.sh new file mode 100644 index 0000000000..6580bebd8e --- /dev/null +++ b/t/t5411/common-functions.sh @@ -0,0 +1,56 @@ +# Create commits in <repo> and assign each commit's oid to shell variables +# given in the arguments (A, B, and C). E.g.: +# +# create_commits_in <repo> A B C +# +# NOTE: Never calling this function from a subshell since variable +# assignments will disappear when subshell exits. +create_commits_in () { + repo="$1" && + if ! parent=$(git -C "$repo" rev-parse HEAD^{} --) + then + parent= + fi && + T=$(git -C "$repo" write-tree) && + shift && + while test $# -gt 0 + do + name=$1 && + test_tick && + if test -z "$parent" + then + oid=$(echo $name | git -C "$repo" commit-tree $T) + else + oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T) + fi && + eval $name=$oid && + parent=$oid && + shift || + return 1 + done && + git -C "$repo" update-ref refs/heads/master $oid +} + +# Format the output of git-push, git-show-ref and other commands to make a +# user-friendly and stable text. We can easily prepare the expect text +# without having to worry about future changes of the commit ID and spaces +# of the output. Single quotes are replaced with double quotes, because +# it is boring to prepare unquoted single quotes in expect text. We also +# remove some locale error messages, which break test if we turn on +# `GIT_TEST_GETTEXT_POISON=true` in order to test unintentional translations +# on plumbing commands. +make_user_friendly_and_stable_output () { + sed \ + -e "s/ *\$//" \ + -e "s/ */ /g" \ + -e "s/'/\"/g" \ + -e "s/ / /g" \ + -e "s/$A/<COMMIT-A>/g" \ + -e "s/$B/<COMMIT-B>/g" \ + -e "s/$TAG/<TAG-v123>/g" \ + -e "s/$ZERO_OID/<ZERO-OID>/g" \ + -e "s/$(echo $A | cut -c1-7)[0-9a-f]*/<OID-A>/g" \ + -e "s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g" \ + -e "s#To $URL_PREFIX/upstream.git#To <URL/of/upstream.git>#" \ + -e "/^error: / d" +} diff --git a/t/t5411/once-0010-report-status-v1.sh b/t/t5411/once-0010-report-status-v1.sh new file mode 100644 index 0000000000..dc2cf4a522 --- /dev/null +++ b/t/t5411/once-0010-report-status-v1.sh @@ -0,0 +1,94 @@ +test_expect_success "setup receive.procReceiveRefs" ' + git -C "$upstream" config --add receive.procReceiveRefs refs/for +' + +test_expect_success "setup proc-receive hook" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic1" \ + -r "option fall-through" \ + -r "ok refs/for/master/topic2" \ + -r "option refname refs/for/changes/23/123/1" \ + -r "option new-oid $A" \ + -r "ok refs/for/master/topic2" \ + -r "option refname refs/for/changes/24/124/2" \ + -r "option old-oid $B" \ + -r "option new-oid $A" \ + -r "option forced-update" \ + -r "ng refs/for/next/topic target branch not exist" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : (B) refs/for/master/topic1(A) foo(A) refs/for/next/topic(A) refs/for/master/topic2(A) +test_expect_success "proc-receive: report status v1" ' + { + if test -z "$GIT_DEFAULT_HASH" || test "$GIT_DEFAULT_HASH" = "sha1" + then + printf "%s %s refs/heads/master\0report-status\n" \ + $A $B | packetize + else + printf "%s %s refs/heads/master\0report-status object-format=$GIT_DEFAULT_HASH\n" \ + $A $B | packetize + fi && + printf "%s %s refs/for/master/topic1\n" \ + $ZERO_OID $A | packetize && + printf "%s %s refs/heads/foo\n" \ + $ZERO_OID $A | packetize && + printf "%s %s refs/for/next/topic\n" \ + $ZERO_OID $A | packetize && + printf "%s %s refs/for/master/topic2\n" \ + $ZERO_OID $A | packetize && + printf 0000 && + printf "" | git -C "$upstream" pack-objects --stdout + } | git receive-pack "$upstream" --stateless-rpc \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + # pre-receive hook + pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1 + pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo + pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic2 + # proc-receive hook + proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1 + proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic2 + proc-receive> ok refs/for/master/topic1 + proc-receive> option fall-through + proc-receive> ok refs/for/master/topic2 + proc-receive> option refname refs/for/changes/23/123/1 + proc-receive> option new-oid <COMMIT-A> + proc-receive> ok refs/for/master/topic2 + proc-receive> option refname refs/for/changes/24/124/2 + proc-receive> option old-oid <COMMIT-B> + proc-receive> option new-oid <COMMIT-A> + proc-receive> option forced-update + proc-receive> ng refs/for/next/topic target branch not exist + 000eunpack ok + 0019ok refs/heads/master + 001eok refs/for/master/topic1 + 0016ok refs/heads/foo + 0033ng refs/for/next/topic target branch not exist + 001eok refs/for/master/topic2 + 0000# post-receive hook + post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1 + post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo + post-receive< <ZERO-OID> <COMMIT-A> refs/for/changes/23/123/1 + post-receive< <COMMIT-B> <COMMIT-A> refs/for/changes/24/124/2 + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/for/master/topic1 + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0000-standard-git-push.sh b/t/t5411/test-0000-standard-git-push.sh new file mode 100644 index 0000000000..e206587348 --- /dev/null +++ b/t/t5411/test-0000-standard-git-push.sh @@ -0,0 +1,143 @@ +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git-push : master(B) next(A) +test_expect_success "git-push ($PROTOCOL)" ' + git -C workbench push origin \ + $B:refs/heads/master \ + HEAD:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + To <URL/of/upstream.git> + <OID-A>..<OID-B> <COMMIT-B> -> master + * [new branch] HEAD -> next + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) next(A) +# Refs of workbench: master(A) tags/v123 +# git-push --atomic: master(A) next(B) +test_expect_success "git-push --atomic ($PROTOCOL)" ' + test_must_fail git -C workbench push --atomic origin \ + master \ + $B:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out | + sed -n \ + -e "/^To / { s/ */ /g; p; }" \ + -e "/^ ! / { s/ */ /g; p; }" \ + >actual && + cat >expect <<-EOF && + To <URL/of/upstream.git> + ! [rejected] master -> master (non-fast-forward) + ! [rejected] <COMMIT-B> -> next (atomic push failed) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) next(A) +# Refs of workbench: master(A) tags/v123 +# git-push : master(A) next(B) +test_expect_success "non-fast-forward git-push ($PROTOCOL)" ' + test_must_fail git \ + -C workbench \ + -c advice.pushUpdateRejected=false \ + push origin \ + master \ + $B:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next + To <URL/of/upstream.git> + <OID-A>..<OID-B> <COMMIT-B> -> next + ! [rejected] master -> master (non-fast-forward) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + <COMMIT-B> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) next(B) +# Refs of workbench: master(A) tags/v123 +# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A) +test_expect_success "git-push -f ($PROTOCOL)" ' + git -C workbench push -f origin \ + refs/tags/v123 \ + :refs/heads/next \ + master \ + master:refs/review/master/topic \ + HEAD:refs/heads/a/b/c \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next + remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c + remote: # post-receive hook + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next + remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c + To <URL/of/upstream.git> + + <OID-B>...<OID-A> master -> master (forced update) + - [deleted] next + * [new tag] v123 -> v123 + * [new reference] master -> refs/review/master/topic + * [new branch] HEAD -> a/b/c + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/a/b/c + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/review/master/topic + <TAG-v123> refs/tags/v123 + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) tags/v123 refs/review/master/topic(A) a/b/c(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + ( + cd "$upstream" && + git update-ref -d refs/review/master/topic && + git update-ref -d refs/tags/v123 && + git update-ref -d refs/heads/a/b/c + ) +' diff --git a/t/t5411/test-0001-standard-git-push--porcelain.sh b/t/t5411/test-0001-standard-git-push--porcelain.sh new file mode 100644 index 0000000000..48f6fcc846 --- /dev/null +++ b/t/t5411/test-0001-standard-git-push--porcelain.sh @@ -0,0 +1,147 @@ +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git-push : master(B) next(A) +test_expect_success "git-push ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + $B:refs/heads/master \ + HEAD:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + To <URL/of/upstream.git> + <COMMIT-B>:refs/heads/master <OID-A>..<OID-B> + * HEAD:refs/heads/next [new branch] + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) next(A) +# Refs of workbench: master(A) tags/v123 +# git-push --atomic: master(A) next(B) +test_expect_success "git-push --atomic ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --atomic --porcelain origin \ + master \ + $B:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out | + sed -n \ + -e "s/^# GETTEXT POISON #//" \ + -e "/^To / { s/ */ /g; p; }" \ + -e "/^! / { s/ */ /g; p; }" \ + >actual && + cat >expect <<-EOF && + To <URL/of/upstream.git> + ! refs/heads/master:refs/heads/master [rejected] (non-fast-forward) + ! <COMMIT-B>:refs/heads/next [rejected] (atomic push failed) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) next(A) +# Refs of workbench: master(A) tags/v123 +# git-push : master(A) next(B) +test_expect_success "non-fast-forward git-push ($PROTOCOL/porcelain)" ' + test_must_fail git \ + -C workbench \ + -c advice.pushUpdateRejected=false \ + push --porcelain origin \ + master \ + $B:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next + To <URL/of/upstream.git> + <COMMIT-B>:refs/heads/next <OID-A>..<OID-B> + ! refs/heads/master:refs/heads/master [rejected] (non-fast-forward) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + <COMMIT-B> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) next(B) +# Refs of workbench: master(A) tags/v123 +# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A) +test_expect_success "git-push -f ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain -f origin \ + refs/tags/v123 \ + :refs/heads/next \ + master \ + master:refs/review/master/topic \ + HEAD:refs/heads/a/b/c \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next + remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c + remote: # post-receive hook + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next + remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c + To <URL/of/upstream.git> + + refs/heads/master:refs/heads/master <OID-B>...<OID-A> (forced update) + - :refs/heads/next [deleted] + * refs/tags/v123:refs/tags/v123 [new tag] + * refs/heads/master:refs/review/master/topic [new reference] + * HEAD:refs/heads/a/b/c [new branch] + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/a/b/c + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/review/master/topic + <TAG-v123> refs/tags/v123 + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) tags/v123 refs/review/master/topic(A) a/b/c(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + ( + cd "$upstream" && + git update-ref -d refs/review/master/topic && + git update-ref -d refs/tags/v123 && + git update-ref -d refs/heads/a/b/c + ) +' diff --git a/t/t5411/test-0002-pre-receive-declined.sh b/t/t5411/test-0002-pre-receive-declined.sh new file mode 100644 index 0000000000..c246f7e68e --- /dev/null +++ b/t/t5411/test-0002-pre-receive-declined.sh @@ -0,0 +1,33 @@ +test_expect_success "setup pre-receive hook ($PROTOCOL)" ' + mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" && + write_script "$upstream/hooks/pre-receive" <<-EOF + exit 1 + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git-push : master(B) next(A) +test_expect_success "git-push is declined ($PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + $B:refs/heads/master \ + HEAD:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + To <URL/of/upstream.git> + ! [remote rejected] <COMMIT-B> -> master (pre-receive hook declined) + ! [remote rejected] HEAD -> next (pre-receive hook declined) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "cleanup ($PROTOCOL)" ' + mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive" +' diff --git a/t/t5411/test-0003-pre-receive-declined--porcelain.sh b/t/t5411/test-0003-pre-receive-declined--porcelain.sh new file mode 100644 index 0000000000..b14894de81 --- /dev/null +++ b/t/t5411/test-0003-pre-receive-declined--porcelain.sh @@ -0,0 +1,34 @@ +test_expect_success "setup pre-receive hook ($PROTOCOL/porcelain)" ' + mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" && + write_script "$upstream/hooks/pre-receive" <<-EOF + exit 1 + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git-push : master(B) next(A) +test_expect_success "git-push is declined ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + $B:refs/heads/master \ + HEAD:refs/heads/next \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + To <URL/of/upstream.git> + ! <COMMIT-B>:refs/heads/master [remote rejected] (pre-receive hook declined) + ! HEAD:refs/heads/next [remote rejected] (pre-receive hook declined) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive" +' diff --git a/t/t5411/test-0010-proc-receive-settings.sh b/t/t5411/test-0010-proc-receive-settings.sh new file mode 100644 index 0000000000..a36809927b --- /dev/null +++ b/t/t5411/test-0010-proc-receive-settings.sh @@ -0,0 +1,7 @@ +test_expect_success "add two receive.procReceiveRefs settings" ' + ( + cd "$upstream" && + git config --add receive.procReceiveRefs refs/for && + git config --add receive.procReceiveRefs refs/review/ + ) +' diff --git a/t/t5411/test-0011-no-hook-error.sh b/t/t5411/test-0011-no-hook-error.sh new file mode 100644 index 0000000000..bb6ec92a92 --- /dev/null +++ b/t/t5411/test-0011-no-hook-error.sh @@ -0,0 +1,64 @@ +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : next(A) refs/for/master/topic(A) +test_expect_success "proc-receive: no hook, fail to push special ref ($PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:next \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: error: cannot find hook "proc-receive" + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + To <URL/of/upstream.git> + * [new branch] HEAD -> next + ! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) next(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + git -C "$upstream" update-ref -d refs/heads/next +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push --atomic: (B) next(A) refs/for/master/topic(A) +test_expect_success "proc-receive: no hook, all failed for atomic push ($PROTOCOL)" ' + test_must_fail git -C workbench push --atomic origin \ + $B:master \ + HEAD:next \ + HEAD:refs/for/master/topic >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: error: cannot find hook "proc-receive" + To <URL/of/upstream.git> + ! [remote rejected] <COMMIT-B> -> master (fail to run proc-receive hook) + ! [remote rejected] HEAD -> next (fail to run proc-receive hook) + ! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0012-no-hook-error--porcelain.sh b/t/t5411/test-0012-no-hook-error--porcelain.sh new file mode 100644 index 0000000000..4814f74dc2 --- /dev/null +++ b/t/t5411/test-0012-no-hook-error--porcelain.sh @@ -0,0 +1,66 @@ +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : next(A) refs/for/master/topic(A) +test_expect_success "proc-receive: no hook, fail to push special ref ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:next \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: error: cannot find hook "proc-receive" + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + To <URL/of/upstream.git> + * HEAD:refs/heads/next [new branch] + ! HEAD:refs/for/master/topic [remote rejected] (fail to run proc-receive hook) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) next(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + git -C "$upstream" update-ref -d refs/heads/next +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push --atomic: (B) next(A) refs/for/master/topic(A) +test_expect_success "proc-receive: no hook, all failed for atomic push ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain --atomic origin \ + $B:master \ + HEAD:next \ + HEAD:refs/for/master/topic >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: error: cannot find hook "proc-receive" + To <URL/of/upstream.git> + ! <COMMIT-B>:refs/heads/master [remote rejected] (fail to run proc-receive hook) + ! HEAD:refs/heads/next [remote rejected] (fail to run proc-receive hook) + ! HEAD:refs/for/master/topic [remote rejected] (fail to run proc-receive hook) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0013-bad-protocol.sh b/t/t5411/test-0013-bad-protocol.sh new file mode 100644 index 0000000000..c5fe4cb37b --- /dev/null +++ b/t/t5411/test-0013-bad-protocol.sh @@ -0,0 +1,217 @@ +test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v --version 2 + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + + # Check status report for git-push + sed -n \ + -e "/^To / { p; n; p; }" \ + <actual >actual-report && + cat >expect <<-EOF && + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook) + EOF + test_cmp expect actual-report && + + # Check error message from "receive-pack", but ignore unstable fatal error + # message ("remote: fatal: the remote end hung up unexpectedly") which + # is different from the remote HTTP server with different locale settings. + grep "^remote: error:" <actual >actual-error && + cat >expect <<-EOF && + remote: error: proc-receive version "2" is not supported + EOF + test_cmp expect actual-error && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (hook --die-version, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v --die-version + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: bad protocol (hook --die-version, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: fatal: bad protocol version: 1 + remote: error: proc-receive version "0" is not supported + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook) + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (hook --die-readline, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v --die-readline + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: bad protocol (hook --die-readline, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + + grep "remote: fatal: protocol error: expected \"old new ref\", got \"<ZERO-OID> <COMMIT-A> refs/for/master/topic\"" actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (no report, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : next(A) refs/for/master/topic(A) +test_expect_success "proc-receive: bad protocol (no report, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/heads/next \ + HEAD:refs/for/master/topic >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + To <URL/of/upstream.git> + * [new branch] HEAD -> next + ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) next(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + git -C "$upstream" update-ref -d refs/heads/next + +' + +test_expect_success "setup proc-receive hook (no ref, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: bad protocol (no ref, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic\ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok + remote: error: proc-receive reported incomplete status line: "ok" + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "xx refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: bad protocol (unknown status, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> xx refs/for/master/topic + remote: error: proc-receive reported bad status "xx" on ref "refs/for/master/topic" + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0014-bad-protocol--porcelain.sh b/t/t5411/test-0014-bad-protocol--porcelain.sh new file mode 100644 index 0000000000..53b47b0185 --- /dev/null +++ b/t/t5411/test-0014-bad-protocol--porcelain.sh @@ -0,0 +1,160 @@ +test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v --version 2 + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + + # Check status report for git-push + sed -n \ + -e "/^To / { p; n; p; n; p; }" \ + <actual >actual-report && + cat >expect <<-EOF && + To <URL/of/upstream.git> + ! HEAD:refs/for/master/topic [remote rejected] (fail to run proc-receive hook) + Done + EOF + test_cmp expect actual-report && + + # Check error message from "receive-pack", but ignore unstable fatal error + # message ("remote: fatal: the remote end hung up unexpectedly") which + # is different from the remote HTTP server with different locale settings. + grep "^remote: error:" <actual >actual-error && + cat >expect <<-EOF && + remote: error: proc-receive version "2" is not supported + EOF + test_cmp expect actual-error && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (no report, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : next(A) refs/for/master/topic(A) +test_expect_success "proc-receive: bad protocol (no report, $PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/heads/next \ + HEAD:refs/for/master/topic >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + To <URL/of/upstream.git> + * HEAD:refs/heads/next [new branch] + ! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) next(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + git -C "$upstream" update-ref -d refs/heads/next + +' + +test_expect_success "setup proc-receive hook (no ref, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: bad protocol (no ref, $PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic\ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok + remote: error: proc-receive reported incomplete status line: "ok" + To <URL/of/upstream.git> + ! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "xx refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: bad protocol (unknown status, $PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> xx refs/for/master/topic + remote: error: proc-receive reported bad status "xx" on ref "refs/for/master/topic" + To <URL/of/upstream.git> + ! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0020-report-ng.sh b/t/t5411/test-0020-report-ng.sh new file mode 100644 index 0000000000..f726b7ca9c --- /dev/null +++ b/t/t5411/test-0020-report-ng.sh @@ -0,0 +1,67 @@ +test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ng refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: fail to update (ng, no message, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ng refs/for/master/topic + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/master/topic (failed) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (ng message, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ng refs/for/master/topic error msg" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: fail to update (ng, with message, $PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ng refs/for/master/topic error msg + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/master/topic (error msg) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0021-report-ng--porcelain.sh b/t/t5411/test-0021-report-ng--porcelain.sh new file mode 100644 index 0000000000..fbf5569103 --- /dev/null +++ b/t/t5411/test-0021-report-ng--porcelain.sh @@ -0,0 +1,69 @@ +test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ng refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: fail to update (ng, no message, $PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ng refs/for/master/topic + To <URL/of/upstream.git> + ! HEAD:refs/for/master/topic [remote rejected] (failed) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (ng message, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ng refs/for/master/topic error msg" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: fail to update (ng, with message, $PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ng refs/for/master/topic error msg + To <URL/of/upstream.git> + ! HEAD:refs/for/master/topic [remote rejected] (error msg) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0022-report-unexpect-ref.sh b/t/t5411/test-0022-report-unexpect-ref.sh new file mode 100644 index 0000000000..92a415b929 --- /dev/null +++ b/t/t5411/test-0022-report-unexpect-ref.sh @@ -0,0 +1,45 @@ +test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/heads/master" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : (B) refs/for/master/topic +test_expect_success "proc-receive: report unexpected ref ($PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + $B:refs/heads/master \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/heads/master + remote: error: proc-receive reported status on unexpected ref: refs/heads/master + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + To <URL/of/upstream.git> + <OID-A>..<OID-B> <COMMIT-B> -> master + ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + git -C "$upstream" update-ref refs/heads/master $A +' diff --git a/t/t5411/test-0023-report-unexpect-ref--porcelain.sh b/t/t5411/test-0023-report-unexpect-ref--porcelain.sh new file mode 100644 index 0000000000..acbf93e40a --- /dev/null +++ b/t/t5411/test-0023-report-unexpect-ref--porcelain.sh @@ -0,0 +1,46 @@ +test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/heads/master" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : (B) refs/for/master/topic +test_expect_success "proc-receive: report unexpected ref ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + $B:refs/heads/master \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/heads/master + remote: error: proc-receive reported status on unexpected ref: refs/heads/master + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + To <URL/of/upstream.git> + <COMMIT-B>:refs/heads/master <OID-A>..<OID-B> + ! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + git -C "$upstream" update-ref refs/heads/master $A +' diff --git a/t/t5411/test-0024-report-unknown-ref.sh b/t/t5411/test-0024-report-unknown-ref.sh new file mode 100644 index 0000000000..c3946f329a --- /dev/null +++ b/t/t5411/test-0024-report-unknown-ref.sh @@ -0,0 +1,34 @@ +test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/a/b/c/my/topic +test_expect_success "proc-receive: report unknown reference ($PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/a/b/c/my/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic + remote: proc-receive> ok refs/for/master/topic + remote: error: proc-receive reported status on unknown ref: refs/for/master/topic + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/a/b/c/my/topic (proc-receive failed to report status) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0025-report-unknown-ref--porcelain.sh b/t/t5411/test-0025-report-unknown-ref--porcelain.sh new file mode 100644 index 0000000000..d093b1a579 --- /dev/null +++ b/t/t5411/test-0025-report-unknown-ref--porcelain.sh @@ -0,0 +1,35 @@ +test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/a/b/c/my/topic +test_expect_success "proc-receive: report unknown reference ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/for/a/b/c/my/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic + remote: proc-receive> ok refs/for/master/topic + remote: error: proc-receive reported status on unknown ref: refs/for/master/topic + To <URL/of/upstream.git> + ! HEAD:refs/for/a/b/c/my/topic [remote rejected] (proc-receive failed to report status) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0026-push-options.sh b/t/t5411/test-0026-push-options.sh new file mode 100644 index 0000000000..d0c4da8b23 --- /dev/null +++ b/t/t5411/test-0026-push-options.sh @@ -0,0 +1,79 @@ +test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL)" ' + git -C "$upstream" config receive.advertisePushOptions false && + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push -o ... : refs/for/master/topic +test_expect_success "proc-receive: not support push options ($PROTOCOL)" ' + test_must_fail git -C workbench push \ + -o issue=123 \ + -o reviewer=user1 \ + origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + test_i18ngrep "fatal: the receiving end does not support push options" \ + actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "enable push options ($PROTOCOL)" ' + git -C "$upstream" config receive.advertisePushOptions true +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push -o ... : next(A) refs/for/master/topic +test_expect_success "proc-receive: push with options ($PROTOCOL)" ' + git -C workbench push \ + --atomic \ + -o issue=123 \ + -o reviewer=user1 \ + origin \ + HEAD:refs/heads/next \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive: atomic push_options + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive< issue=123 + remote: proc-receive< reviewer=user1 + remote: proc-receive> ok refs/for/master/topic + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + To <URL/of/upstream.git> + * [new branch] HEAD -> next + * [new reference] HEAD -> refs/for/master/topic + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) next(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + git -C "$upstream" update-ref -d refs/heads/next +' diff --git a/t/t5411/test-0027-push-options--porcelain.sh b/t/t5411/test-0027-push-options--porcelain.sh new file mode 100644 index 0000000000..c89a1e7c57 --- /dev/null +++ b/t/t5411/test-0027-push-options--porcelain.sh @@ -0,0 +1,82 @@ +test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL/porcelain)" ' + git -C "$upstream" config receive.advertisePushOptions false && + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push -o ... : refs/for/master/topic +test_expect_success "proc-receive: not support push options ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push \ + --porcelain \ + -o issue=123 \ + -o reviewer=user1 \ + origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + test_i18ngrep "fatal: the receiving end does not support push options" \ + actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "enable push options ($PROTOCOL/porcelain)" ' + git -C "$upstream" config receive.advertisePushOptions true +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push -o ... : next(A) refs/for/master/topic +test_expect_success "proc-receive: push with options ($PROTOCOL/porcelain)" ' + git -C workbench push \ + --porcelain \ + --atomic \ + -o issue=123 \ + -o reviewer=user1 \ + origin \ + HEAD:refs/heads/next \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive: atomic push_options + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive< issue=123 + remote: proc-receive< reviewer=user1 + remote: proc-receive> ok refs/for/master/topic + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + To <URL/of/upstream.git> + * HEAD:refs/heads/next [new branch] + * HEAD:refs/for/master/topic [new reference] + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) next(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + git -C "$upstream" update-ref -d refs/heads/next +' diff --git a/t/t5411/test-0030-report-ok.sh b/t/t5411/test-0030-report-ok.sh new file mode 100644 index 0000000000..44c99d3831 --- /dev/null +++ b/t/t5411/test-0030-report-ok.sh @@ -0,0 +1,35 @@ +test_expect_success "setup proc-receive hook (ok, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: ok ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + To <URL/of/upstream.git> + * [new reference] HEAD -> refs/for/master/topic + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0031-report-ok--porcelain.sh b/t/t5411/test-0031-report-ok--porcelain.sh new file mode 100644 index 0000000000..3223b26184 --- /dev/null +++ b/t/t5411/test-0031-report-ok--porcelain.sh @@ -0,0 +1,36 @@ +test_expect_success "setup proc-receive hook (ok, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic +test_expect_success "proc-receive: ok ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + To <URL/of/upstream.git> + * HEAD:refs/for/master/topic [new reference] + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0032-report-with-options.sh b/t/t5411/test-0032-report-with-options.sh new file mode 100644 index 0000000000..b77b78c49f --- /dev/null +++ b/t/t5411/test-0032-report-with-options.sh @@ -0,0 +1,256 @@ +test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option without matching ok ($PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: error: proc-receive reported "option" without a matching "ok/ng" directive + To <URL/of/upstream.git> + ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status) + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option refname, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option refname ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head + To <URL/of/upstream.git> + * [new reference] HEAD -> refs/pull/123/head + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option refname and forced-update, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" \ + -r "option forced-update" + EOF +' +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option refname and forced-update ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option forced-update + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head + To <URL/of/upstream.git> + * [new reference] HEAD -> refs/pull/123/head + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option refname and old-oid, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option refname and old-oid ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/123/head + To <URL/of/upstream.git> + <OID-B>..<OID-A> HEAD -> refs/pull/123/head + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option old-oid, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option old-oid ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/for/master/topic + To <URL/of/upstream.git> + <OID-B>..<OID-A> HEAD -> refs/for/master/topic + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option old-oid and new-oid, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option old-oid and new-oid ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + To <URL/of/upstream.git> + <OID-A>..<OID-B> HEAD -> refs/for/master/topic + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (report with multiple rewrites, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/a/b/c/topic" \ + -r "ok refs/for/next/topic" \ + -r "option refname refs/pull/123/head" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/124/head" \ + -r "option old-oid $B" \ + -r "option forced-update" \ + -r "option new-oid $A" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report with multiple rewrites ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/next/topic \ + HEAD:refs/for/a/b/c/topic \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/a/b/c/topic + remote: proc-receive> ok refs/for/next/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/124/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: proc-receive> option forced-update + remote: proc-receive> option new-oid <COMMIT-A> + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head + To <URL/of/upstream.git> + * [new reference] HEAD -> refs/pull/123/head + * [new reference] HEAD -> refs/for/a/b/c/topic + + <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update) + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0033-report-with-options--porcelain.sh b/t/t5411/test-0033-report-with-options--porcelain.sh new file mode 100644 index 0000000000..1fe352b686 --- /dev/null +++ b/t/t5411/test-0033-report-with-options--porcelain.sh @@ -0,0 +1,265 @@ +test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option without matching ok ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: error: proc-receive reported "option" without a matching "ok/ng" directive + To <URL/of/upstream.git> + ! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status) + Done + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option refname, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option refname ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head + To <URL/of/upstream.git> + * HEAD:refs/pull/123/head [new reference] + Done + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option refname and forced-update, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" \ + -r "option forced-update" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option refname and forced-update ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option forced-update + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head + To <URL/of/upstream.git> + * HEAD:refs/pull/123/head [new reference] + Done + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option refname and old-oid, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option refname and old-oid ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/123/head + To <URL/of/upstream.git> + HEAD:refs/pull/123/head <OID-B>..<OID-A> + Done + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option old-oid, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option old-oid ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/for/master/topic + To <URL/of/upstream.git> + HEAD:refs/for/master/topic <OID-B>..<OID-A> + Done + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (option old-oid and new-oid, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report option old-oid and new-oid ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + To <URL/of/upstream.git> + HEAD:refs/for/master/topic <OID-A>..<OID-B> + Done + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (report with multiple rewrites, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/a/b/c/topic" \ + -r "ok refs/for/next/topic" \ + -r "option refname refs/pull/123/head" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/124/head" \ + -r "option old-oid $B" \ + -r "option forced-update" \ + -r "option new-oid $A" + + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report with multiple rewrites ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/next/topic \ + HEAD:refs/for/a/b/c/topic \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/a/b/c/topic + remote: proc-receive> ok refs/for/next/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/124/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: proc-receive> option forced-update + remote: proc-receive> option new-oid <COMMIT-A> + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head + To <URL/of/upstream.git> + * HEAD:refs/pull/123/head [new reference] + * HEAD:refs/for/a/b/c/topic [new reference] + + HEAD:refs/pull/124/head <OID-B>...<OID-A> (forced update) + Done + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0034-report-ft.sh b/t/t5411/test-0034-report-ft.sh new file mode 100644 index 0000000000..aca2b0676c --- /dev/null +++ b/t/t5411/test-0034-report-ft.sh @@ -0,0 +1,44 @@ +test_expect_success "setup proc-receive hook (ft, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option fall-through" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(B) +test_expect_success "proc-receive: fall throught, let receive-pack to execute ($PROTOCOL)" ' + git -C workbench push origin \ + $B:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option fall-through + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic + To <URL/of/upstream.git> + * [new reference] <COMMIT-B> -> refs/for/master/topic + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/for/master/topic + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) refs/for/master/topic(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + git -C "$upstream" update-ref -d refs/for/master/topic +' diff --git a/t/t5411/test-0035-report-ft--porcelain.sh b/t/t5411/test-0035-report-ft--porcelain.sh new file mode 100644 index 0000000000..30ffffb352 --- /dev/null +++ b/t/t5411/test-0035-report-ft--porcelain.sh @@ -0,0 +1,45 @@ +test_expect_success "setup proc-receive hook (fall-through, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option fall-through" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(B) +test_expect_success "proc-receive: fall throught, let receive-pack to execute ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + $B:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option fall-through + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic + To <URL/of/upstream.git> + * <COMMIT-B>:refs/for/master/topic [new reference] + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/for/master/topic + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) refs/for/master/topic(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + git -C "$upstream" update-ref -d refs/for/master/topic +' diff --git a/t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh b/t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh new file mode 100644 index 0000000000..73283d81e8 --- /dev/null +++ b/t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh @@ -0,0 +1,227 @@ +test_expect_success "setup git config for remote-tracking of special refs" ' + ( + cd workbench && + if ! git config --get-all remote.origin.fetch | grep refs/for/ + then + git config --add remote.origin.fetch \ + "+refs/for/*:refs/t/for/*" && + git config --add remote.origin.fetch \ + "+refs/pull/*:refs/t/pull/*" && + git config --add remote.origin.fetch \ + "+refs/changes/*:refs/t/changes/*" + fi + ) +' + +test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/24/124/1" \ + -r "option old-oid $ZERO_OID" \ + -r "option new-oid $A" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/25/125/1" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: multiple rewrite for one ref, no refname for the 1st rewrite ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/24/124/1 + remote: proc-receive> option old-oid <ZERO-OID> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/25/125/1 + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/25/125/1 + To <URL/of/upstream.git> + <OID-A>..<OID-B> HEAD -> refs/for/master/topic + * [new reference] HEAD -> refs/changes/24/124/1 + <OID-A>..<OID-B> HEAD -> refs/changes/25/125/1 + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "proc-receive: check remote-tracking #1 ($PROTOCOL)" ' + git -C workbench show-ref | + grep -v -e refs/remotes -e refs/heads -e refs/tags >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/t/changes/24/124/1 + <COMMIT-B> refs/t/changes/25/125/1 + <COMMIT-B> refs/t/for/master/topic + EOF + test_cmp expect actual && + git -C workbench update-ref -d refs/t/for/master/topic && + git -C workbench update-ref -d refs/t/changes/24/124/1 && + git -C workbench update-ref -d refs/t/changes/25/125/1 +' + +test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/24/124/1" \ + -r "option old-oid $ZERO_OID" \ + -r "option new-oid $A" \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/25/125/1" \ + -r "option old-oid $B" \ + -r "option new-oid $A" \ + -r "option forced-update" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: multiple rewrites for one ref, no refname for the 2nd rewrite ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/24/124/1 + remote: proc-receive> option old-oid <ZERO-OID> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/25/125/1 + remote: proc-receive> option old-oid <COMMIT-B> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> option forced-update + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/changes/25/125/1 + To <URL/of/upstream.git> + * [new reference] HEAD -> refs/changes/24/124/1 + <OID-A>..<OID-B> HEAD -> refs/for/master/topic + + <OID-B>...<OID-A> HEAD -> refs/changes/25/125/1 (forced update) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "proc-receive: check remote-tracking #2 ($PROTOCOL)" ' + git -C workbench show-ref | + grep -v -e refs/remotes -e refs/heads -e refs/tags >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/t/changes/24/124/1 + <COMMIT-A> refs/t/changes/25/125/1 + <COMMIT-B> refs/t/for/master/topic + EOF + test_cmp expect actual && + git -C workbench update-ref -d refs/t/for/master/topic && + git -C workbench update-ref -d refs/t/changes/24/124/1 && + git -C workbench update-ref -d refs/t/changes/25/125/1 +' + +test_expect_success "setup proc-receive hook (multiple rewrites for one ref, $PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/23/123/1" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/24/124/2" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: multiple rewrites for one ref ($PROTOCOL)" ' + git -C workbench push origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/23/123/1 + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/24/124/2 + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/23/123/1 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/24/124/2 + To <URL/of/upstream.git> + * [new reference] HEAD -> refs/changes/23/123/1 + <OID-A>..<OID-B> HEAD -> refs/changes/24/124/2 + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "proc-receive: check remote-tracking #3 ($PROTOCOL)" ' + git -C workbench show-ref | + grep -v -e refs/remotes -e refs/heads -e refs/tags >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/t/changes/23/123/1 + <COMMIT-B> refs/t/changes/24/124/2 + EOF + test_cmp expect actual && + git -C workbench update-ref -d refs/t/changes/24/124/1 && + git -C workbench update-ref -d refs/t/changes/25/125/2 +' diff --git a/t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh b/t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh new file mode 100644 index 0000000000..77b5b22ed4 --- /dev/null +++ b/t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh @@ -0,0 +1,172 @@ +test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/24/124/1" \ + -r "option old-oid $ZERO_OID" \ + -r "option new-oid $A" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/25/125/1" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: multiple rewrite for one ref, no refname for the 1st rewrite ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/24/124/1 + remote: proc-receive> option old-oid <ZERO-OID> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/25/125/1 + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/25/125/1 + To <URL/of/upstream.git> + HEAD:refs/for/master/topic <OID-A>..<OID-B> + * HEAD:refs/changes/24/124/1 [new reference] + HEAD:refs/changes/25/125/1 <OID-A>..<OID-B> + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/24/124/1" \ + -r "option old-oid $ZERO_OID" \ + -r "option new-oid $A" \ + -r "ok refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/25/125/1" \ + -r "option old-oid $B" \ + -r "option new-oid $A" \ + -r "option forced-update" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: multiple rewrites for one ref, no refname for the 2nd rewrite ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/24/124/1 + remote: proc-receive> option old-oid <ZERO-OID> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/25/125/1 + remote: proc-receive> option old-oid <COMMIT-B> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> option forced-update + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/changes/25/125/1 + To <URL/of/upstream.git> + * HEAD:refs/changes/24/124/1 [new reference] + HEAD:refs/for/master/topic <OID-A>..<OID-B> + + HEAD:refs/changes/25/125/1 <OID-B>...<OID-A> (forced update) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook (multiple rewrites for one ref, $PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/23/123/1" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/changes/24/124/2" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : refs/for/master/topic(A) +test_expect_success "proc-receive: multiple rewrites for one ref ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain origin \ + HEAD:refs/for/master/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/23/123/1 + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/changes/24/124/2 + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/23/123/1 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/24/124/2 + To <URL/of/upstream.git> + * HEAD:refs/changes/23/123/1 [new reference] + HEAD:refs/changes/24/124/2 <OID-A>..<OID-B> + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' diff --git a/t/t5411/test-0038-report-mixed-refs.sh b/t/t5411/test-0038-report-mixed-refs.sh new file mode 100644 index 0000000000..a74a2cb449 --- /dev/null +++ b/t/t5411/test-0038-report-mixed-refs.sh @@ -0,0 +1,89 @@ +test_expect_success "setup proc-receive hook ($PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/next/topic2" \ + -r "ng refs/for/next/topic1 fail to call Web API" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : (B) bar(A) baz(A) refs/for/next/topic(A) foo(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report update of mixed refs ($PROTOCOL)" ' + test_must_fail git -C workbench push origin \ + $B:refs/heads/master \ + HEAD:refs/heads/bar \ + HEAD:refs/heads/baz \ + HEAD:refs/for/next/topic2 \ + HEAD:refs/for/next/topic1 \ + HEAD:refs/heads/foo \ + HEAD:refs/for/master/topic \ + HEAD:refs/for/next/topic3 \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3 + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2 + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1 + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3 + remote: proc-receive> ok refs/for/next/topic2 + remote: proc-receive> ng refs/for/next/topic1 fail to call Web API + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + To <URL/of/upstream.git> + <OID-A>..<OID-B> <COMMIT-B> -> master + * [new branch] HEAD -> bar + * [new branch] HEAD -> baz + * [new reference] HEAD -> refs/for/next/topic2 + * [new branch] HEAD -> foo + <OID-A>..<OID-B> HEAD -> refs/for/master/topic + ! [remote rejected] HEAD -> refs/for/next/topic1 (fail to call Web API) + ! [remote rejected] HEAD -> refs/for/next/topic3 (proc-receive failed to report status) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) foo(A) bar(A)) baz(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + ( + cd "$upstream" && + git update-ref refs/heads/master $A && + git update-ref -d refs/heads/foo && + git update-ref -d refs/heads/bar && + git update-ref -d refs/heads/baz + ) +' diff --git a/t/t5411/test-0039-report-mixed-refs--porcelain.sh b/t/t5411/test-0039-report-mixed-refs--porcelain.sh new file mode 100644 index 0000000000..e4baa13ea3 --- /dev/null +++ b/t/t5411/test-0039-report-mixed-refs--porcelain.sh @@ -0,0 +1,91 @@ +test_expect_success "setup proc-receive hook ($PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/for/next/topic2" \ + -r "ng refs/for/next/topic1 fail to call Web API" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/for/master/topic" \ + -r "option old-oid $A" \ + -r "option new-oid $B" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : (B) bar(A) baz(A) refs/for/next/topic(A) foo(A) refs/for/master/topic(A) +test_expect_success "proc-receive: report update of mixed refs ($PROTOCOL/porcelain)" ' + test_must_fail git -C workbench push --porcelain origin \ + $B:refs/heads/master \ + HEAD:refs/heads/bar \ + HEAD:refs/heads/baz \ + HEAD:refs/for/next/topic2 \ + HEAD:refs/for/next/topic1 \ + HEAD:refs/heads/foo \ + HEAD:refs/for/master/topic \ + HEAD:refs/for/next/topic3 \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3 + remote: # proc-receive hook + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2 + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1 + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3 + remote: proc-receive> ok refs/for/next/topic2 + remote: proc-receive> ng refs/for/next/topic1 fail to call Web API + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/for/master/topic + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic + To <URL/of/upstream.git> + <COMMIT-B>:refs/heads/master <OID-A>..<OID-B> + * HEAD:refs/heads/bar [new branch] + * HEAD:refs/heads/baz [new branch] + * HEAD:refs/for/next/topic2 [new reference] + * HEAD:refs/heads/foo [new branch] + HEAD:refs/for/master/topic <OID-A>..<OID-B> + ! HEAD:refs/for/next/topic1 [remote rejected] (fail to call Web API) + ! HEAD:refs/for/next/topic3 [remote rejected] (proc-receive failed to report status) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(B) foo(A) bar(A)) baz(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + ( + cd "$upstream" && + git update-ref refs/heads/master $A && + git update-ref -d refs/heads/foo && + git update-ref -d refs/heads/bar && + git update-ref -d refs/heads/baz + ) + +' diff --git a/t/t5411/test-0040-process-all-refs.sh b/t/t5411/test-0040-process-all-refs.sh new file mode 100644 index 0000000000..b07c999f53 --- /dev/null +++ b/t/t5411/test-0040-process-all-refs.sh @@ -0,0 +1,113 @@ +test_expect_success "config receive.procReceiveRefs = refs ($PROTOCOL)" ' + git -C "$upstream" config --unset-all receive.procReceiveRefs && + git -C "$upstream" config --add receive.procReceiveRefs refs +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "setup upstream branches ($PROTOCOL)" ' + ( + cd "$upstream" && + git update-ref refs/heads/master $B && + git update-ref refs/heads/foo $A && + git update-ref refs/heads/bar $A && + git update-ref refs/heads/baz $A + ) + +' + +test_expect_success "setup proc-receive hook ($PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/heads/master" \ + -r "option fall-through" \ + -r "ok refs/heads/foo" \ + -r "option fall-through" \ + -r "ok refs/heads/bar" \ + -r "option fall-through" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $A" \ + -r "option new-oid $B" \ + -r "ok refs/for/next/topic" \ + -r "option refname refs/pull/124/head" \ + -r "option old-oid $B" \ + -r "option new-oid $A" \ + -r "option forced-update" + EOF +' + +# Refs of upstream : master(B) foo(A) bar(A)) baz(A) +# Refs of workbench: master(A) tags/v123 +# git push -f : master(A) (NULL) (B) refs/for/master/topic(A) refs/for/next/topic(A) +test_expect_success "proc-receive: process all refs ($PROTOCOL)" ' + git -C workbench push -f origin \ + HEAD:refs/heads/master \ + :refs/heads/foo \ + $B:refs/heads/bar \ + HEAD:refs/for/master/topic \ + HEAD:refs/for/next/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar + remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo + remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: # proc-receive hook + remote: proc-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar + remote: proc-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo + remote: proc-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: proc-receive> ok refs/heads/master + remote: proc-receive> option fall-through + remote: proc-receive> ok refs/heads/foo + remote: proc-receive> option fall-through + remote: proc-receive> ok refs/heads/bar + remote: proc-receive> option fall-through + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: proc-receive> ok refs/for/next/topic + remote: proc-receive> option refname refs/pull/124/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> option forced-update + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar + remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head + To <URL/of/upstream.git> + <OID-A>..<OID-B> <COMMIT-B> -> bar + - [deleted] foo + + <OID-B>...<OID-A> HEAD -> master (forced update) + <OID-A>..<OID-B> HEAD -> refs/pull/123/head + + <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update) + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) bar(A) baz(B) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL)" ' + ( + cd "$upstream" && + git update-ref -d refs/heads/bar && + git update-ref -d refs/heads/baz + ) +' diff --git a/t/t5411/test-0041-process-all-refs--porcelain.sh b/t/t5411/test-0041-process-all-refs--porcelain.sh new file mode 100644 index 0000000000..0dd9824616 --- /dev/null +++ b/t/t5411/test-0041-process-all-refs--porcelain.sh @@ -0,0 +1,114 @@ +test_expect_success "config receive.procReceiveRefs = refs ($PROTOCOL/porcelain)" ' + git -C "$upstream" config --unset-all receive.procReceiveRefs && + git -C "$upstream" config --add receive.procReceiveRefs refs +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "setup upstream branches ($PROTOCOL/porcelain)" ' + ( + cd "$upstream" && + git update-ref refs/heads/master $B && + git update-ref refs/heads/foo $A && + git update-ref refs/heads/bar $A && + git update-ref refs/heads/baz $A + ) + +' + +test_expect_success "setup proc-receive hook ($PROTOCOL/porcelain)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/heads/master" \ + -r "option fall-through" \ + -r "ok refs/heads/foo" \ + -r "option fall-through" \ + -r "ok refs/heads/bar" \ + -r "option fall-through" \ + -r "ok refs/for/master/topic" \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $A" \ + -r "option new-oid $B" \ + -r "ok refs/for/next/topic" \ + -r "option refname refs/pull/124/head" \ + -r "option old-oid $B" \ + -r "option new-oid $A" \ + -r "option forced-update" + EOF +' + +# Refs of upstream : master(B) foo(A) bar(A)) baz(A) +# Refs of workbench: master(A) tags/v123 +# git push -f : master(A) (NULL) (B) refs/for/master/topic(A) refs/for/next/topic(A) +test_expect_success "proc-receive: process all refs ($PROTOCOL/porcelain)" ' + git -C workbench push --porcelain -f origin \ + HEAD:refs/heads/master \ + :refs/heads/foo \ + $B:refs/heads/bar \ + HEAD:refs/for/master/topic \ + HEAD:refs/for/next/topic \ + >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar + remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo + remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: # proc-receive hook + remote: proc-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar + remote: proc-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo + remote: proc-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic + remote: proc-receive> ok refs/heads/master + remote: proc-receive> option fall-through + remote: proc-receive> ok refs/heads/foo + remote: proc-receive> option fall-through + remote: proc-receive> ok refs/heads/bar + remote: proc-receive> option fall-through + remote: proc-receive> ok refs/for/master/topic + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: proc-receive> ok refs/for/next/topic + remote: proc-receive> option refname refs/pull/124/head + remote: proc-receive> option old-oid <COMMIT-B> + remote: proc-receive> option new-oid <COMMIT-A> + remote: proc-receive> option forced-update + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar + remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head + To <URL/of/upstream.git> + <COMMIT-B>:refs/heads/bar <OID-A>..<OID-B> + - :refs/heads/foo [deleted] + + HEAD:refs/heads/master <OID-B>...<OID-A> (forced update) + HEAD:refs/pull/123/head <OID-A>..<OID-B> + + HEAD:refs/pull/124/head <OID-B>...<OID-A> (forced update) + Done + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-B> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) bar(A) baz(B) +# Refs of workbench: master(A) tags/v123 +test_expect_success "cleanup ($PROTOCOL/porcelain)" ' + ( + cd "$upstream" && + git update-ref -d refs/heads/bar && + git update-ref -d refs/heads/baz + ) +' diff --git a/t/t5411/test-0050-proc-receive-refs-with-modifiers.sh b/t/t5411/test-0050-proc-receive-refs-with-modifiers.sh new file mode 100644 index 0000000000..c22849cbe2 --- /dev/null +++ b/t/t5411/test-0050-proc-receive-refs-with-modifiers.sh @@ -0,0 +1,135 @@ +test_expect_success "config receive.procReceiveRefs with modifiers ($PROTOCOL)" ' + ( + cd "$upstream" && + git config --unset-all receive.procReceiveRefs && + git config --add receive.procReceiveRefs m:refs/heads/master && + git config --add receive.procReceiveRefs ad:refs/heads && + git config --add receive.procReceiveRefs "a!:refs/heads" + ) +' + +test_expect_success "setup proc-receive hook ($PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/heads/master" \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $A" \ + -r "option new-oid $B" \ + -r "ok refs/tags/v123 " \ + -r "option refname refs/pull/124/head" + EOF +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +# git push : master(B) tags/v123 +test_expect_success "proc-receive: update branch and new tag ($PROTOCOL)" ' + git -C workbench push origin \ + $B:refs/heads/master \ + v123 >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123 + remote: # proc-receive hook + remote: proc-receive< <COMMIT-A> <COMMIT-B> refs/heads/master + remote: proc-receive< <ZERO-OID> <TAG-v123> refs/tags/v123 + remote: proc-receive> ok refs/heads/master + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <COMMIT-B> + remote: proc-receive> ok refs/tags/v123 + remote: proc-receive> option refname refs/pull/124/head + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head + remote: post-receive< <ZERO-OID> <TAG-v123> refs/pull/124/head + To <URL/of/upstream.git> + <OID-A>..<OID-B> <COMMIT-B> -> refs/pull/123/head + * [new reference] v123 -> refs/pull/124/head + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + EOF + test_cmp expect actual +' + +# Refs of upstream : master(A) +# Refs of workbench: master(A) tags/v123 +test_expect_success "setup upstream: create tags/v123 ($PROTOCOL)" ' + git -C "$upstream" update-ref refs/heads/topic $A && + git -C "$upstream" update-ref refs/tags/v123 $TAG && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-A> refs/heads/topic + <TAG-v123> refs/tags/v123 + EOF + test_cmp expect actual +' + +test_expect_success "setup proc-receive hook ($PROTOCOL)" ' + write_script "$upstream/hooks/proc-receive" <<-EOF + printf >&2 "# proc-receive hook\n" + test-tool proc-receive -v \ + -r "ok refs/heads/master" \ + -r "option refname refs/pull/123/head" \ + -r "option old-oid $A" \ + -r "option new-oid $ZERO_OID" \ + -r "ok refs/heads/next" \ + -r "option refname refs/pull/124/head" \ + -r "option new-oid $A" + EOF +' + +# Refs of upstream : master(A) topic(A) tags/v123 +# Refs of workbench: master(A) tags/v123 +# git push : NULL topic(B) NULL next(A) +test_expect_success "proc-receive: create/delete branch, and delete tag ($PROTOCOL)" ' + git -C workbench push origin \ + :refs/heads/master \ + $B:refs/heads/topic \ + $A:refs/heads/next \ + :refs/tags/v123 >out 2>&1 && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + remote: # pre-receive hook + remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/master + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/topic + remote: pre-receive< <TAG-v123> <ZERO-OID> refs/tags/v123 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: # proc-receive hook + remote: proc-receive< <COMMIT-A> <ZERO-OID> refs/heads/master + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/heads/next + remote: proc-receive> ok refs/heads/master + remote: proc-receive> option refname refs/pull/123/head + remote: proc-receive> option old-oid <COMMIT-A> + remote: proc-receive> option new-oid <ZERO-OID> + remote: proc-receive> ok refs/heads/next + remote: proc-receive> option refname refs/pull/124/head + remote: proc-receive> option new-oid <COMMIT-A> + remote: # post-receive hook + remote: post-receive< <COMMIT-A> <ZERO-OID> refs/pull/123/head + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/topic + remote: post-receive< <TAG-v123> <ZERO-OID> refs/tags/v123 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/124/head + To <URL/of/upstream.git> + - [deleted] refs/pull/123/head + <OID-A>..<OID-B> <COMMIT-B> -> topic + - [deleted] v123 + * [new reference] <COMMIT-A> -> refs/pull/124/head + EOF + test_cmp expect actual && + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/master + <COMMIT-B> refs/heads/topic + EOF + test_cmp expect actual +' diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index a32efe2b6c..1a16ac4c0d 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -4,7 +4,6 @@ test_description='fetch/receive strict mode' . ./test-lib.sh test_expect_success 'setup and inject "corrupt or missing" object' ' - test_oid_init && echo hello >greetings && git add greetings && git commit -m greetings && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index a66dbe0bde..dbc724e4c0 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -213,7 +213,7 @@ test_expect_success 'fetch tags when there is no tags' ' test_expect_success 'fetch following tags' ' cd "$D" && - git tag -a -m 'annotated' anno HEAD && + git tag -a -m "annotated" anno HEAD && git tag light HEAD && mkdir four && @@ -281,15 +281,19 @@ test_expect_success 'create bundle 1' ' cd "$D" && echo >file updated again by origin && git commit -a -m "tip" && - git bundle create bundle1 master^..master + git bundle create --version=3 bundle1 master^..master ' test_expect_success 'header of bundle looks right' ' - head -n 4 "$D"/bundle1 && - head -n 1 "$D"/bundle1 | grep "^#" && - head -n 2 "$D"/bundle1 | grep "^-$OID_REGEX " && - head -n 3 "$D"/bundle1 | grep "^$OID_REGEX " && - head -n 4 "$D"/bundle1 | grep "^$" + cat >expect <<-EOF && + # v3 git bundle + @object-format=$(test_oid algo) + -OID updated by origin + OID refs/heads/master + + EOF + sed -e "s/$OID_REGEX/OID/g" -e "5q" "$D"/bundle1 >actual && + test_cmp expect actual ' test_expect_success 'create bundle 2' ' @@ -331,7 +335,7 @@ test_expect_success 'bundle does not prerequisite objects' ' test_expect_success 'bundle should be able to create a full history' ' cd "$D" && - git tag -a -m '1.0' v1.0 master && + git tag -a -m "1.0" v1.0 master && git bundle create bundle4 v1.0 ' @@ -539,10 +543,23 @@ test_expect_success 'fetch into the current branch with --update-head-ok' ' ' -test_expect_success 'fetch --dry-run' ' +test_expect_success 'fetch --dry-run does not touch FETCH_HEAD, but still prints what would be written' ' + rm -f .git/FETCH_HEAD err && + git fetch --dry-run . 2>err && + ! test -f .git/FETCH_HEAD && + grep FETCH_HEAD err +' + +test_expect_success '--no-write-fetch-head does not touch FETCH_HEAD, and does not print what would be written' ' + rm -f .git/FETCH_HEAD err && + git fetch --no-write-fetch-head . 2>err && + ! test -f .git/FETCH_HEAD && + ! grep FETCH_HEAD err +' +test_expect_success '--write-fetch-head gets defeated by --dry-run' ' rm -f .git/FETCH_HEAD && - git fetch --dry-run . && + git fetch --dry-run --write-fetch-head . && ! test -f .git/FETCH_HEAD ' @@ -797,7 +814,7 @@ test_configured_prune true true unset unset pruned pruned \ "--prune origin refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/*" # --prune-tags on its own does nothing, needs --prune as well, same -# for for fetch.pruneTags without fetch.prune +# for fetch.pruneTags without fetch.prune test_configured_prune unset unset unset unset kept kept "--prune-tags" test_configured_prune unset unset true unset kept kept "" test_configured_prune unset unset unset true kept kept "" @@ -919,7 +936,7 @@ test_expect_success 'fetching with auto-gc does not lock up' ' git config fetch.unpackLimit 1 && git config gc.autoPackLimit 1 && git config gc.autoDetach false && - GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 && + GIT_ASK_YESNO="$D/askyesno" git fetch --verbose >fetch.out 2>&1 && test_i18ngrep "Auto packing the repository" fetch.out && ! grep "Should I try again" fetch.out ) diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh index de8e2f1531..bd202ec6f3 100755 --- a/t/t5514-fetch-multiple.sh +++ b/t/t5514-fetch-multiple.sh @@ -108,7 +108,7 @@ test_expect_success 'git fetch --multiple (two remotes)' ' GIT_TRACE=1 git fetch --multiple one two 2>trace && git branch -r > output && test_cmp ../expect output && - grep "built-in: git gc" trace >gc && + grep "built-in: git maintenance" trace >gc && test_line_count = 1 gc ) ' diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 36ad20a849..d11382f769 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1039,7 +1039,7 @@ test_force_fetch_tag "annotated tag" "-f -a -m'tag message'" test_expect_success 'push --porcelain' ' mk_empty testrepo && echo >.git/foo "To testrepo" && - echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new branch]" && + echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new reference]" && echo >>.git/foo "Done" && git push >.git/bar --porcelain testrepo refs/heads/master:refs/remotes/origin/master && ( diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 159afa7ac8..db1a381cd9 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -85,6 +85,13 @@ test_expect_success 'git pull --cleanup errors early on invalid argument' ' test -s err) ' +test_expect_success 'git pull --no-write-fetch-head fails' ' + mkdir clonedwfh && + (cd clonedwfh && git init && + test_expect_code 129 git pull --no-write-fetch-head "../parent" >out 2>err && + test_must_be_empty out && + test_i18ngrep "no-write-fetch-head" err) +' test_expect_success 'git pull --force' ' mkdir clonedoldstyle && diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index 4ce9a9f704..205a2631e7 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -14,7 +14,6 @@ corrupt_repo () { } test_expect_success 'setup and corrupt repository' ' - test_oid_init && echo file >file && git add file && git rev-parse :file && diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh index 030331f1c5..7e928aff66 100755 --- a/t/t5534-push-signed.sh +++ b/t/t5534-push-signed.sh @@ -273,4 +273,27 @@ test_expect_success GPGSM 'fail without key and heed user.signingkey x509' ' test_cmp expect dst/push-cert-status ' +test_expect_success GPG 'failed atomic push does not execute GPG' ' + prepare_dst && + git -C dst config receive.certnonceseed sekrit && + write_script gpg <<-EOF && + # should check atomic push locally before running GPG. + exit 1 + EOF + test_must_fail env PATH="$TRASH_DIRECTORY:$PATH" git push \ + --signed --atomic --porcelain \ + dst noop ff noff >out 2>&1 && + + test_i18ngrep ! "gpg failed to sign" out && + sed -n -e "/^To dst/,$ p" out >actual && + cat >expect <<-EOF && + To dst + = refs/heads/noop:refs/heads/noop [up to date] + ! refs/heads/ff:refs/heads/ff [rejected] (atomic push failed) + ! refs/heads/noff:refs/heads/noff [rejected] (non-fast-forward) + Done + EOF + test_i18ncmp expect actual +' + test_done diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh index c0d02dee89..82aa99ae87 100755 --- a/t/t5539-fetch-http-shallow.sh +++ b/t/t5539-fetch-http-shallow.sh @@ -9,10 +9,12 @@ start_httpd commit() { echo "$1" >tracked && git add tracked && + test_tick && git commit -m "$1" } test_expect_success 'setup shallow clone' ' + test_tick=1500000000 && commit 1 && commit 2 && commit 3 && @@ -48,7 +50,6 @@ EOF test_expect_success 'no shallow lines after receiving ACK ready' ' ( cd shallow && - test_tick && for i in $(test_seq 15) do git checkout --orphan unrelated$i && @@ -66,6 +67,7 @@ test_expect_success 'no shallow lines after receiving ACK ready' ' ( cd clone && git checkout --orphan newnew && + test_tick=1400000000 && test_commit new-too && # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 463d0f12e5..187454f5dd 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -479,6 +479,21 @@ test_expect_success 'clone/fetch scrubs password from reflogs' ' ! grep "$HTTPD_URL_USER_PASS" reflog ' +test_expect_success 'Non-ASCII branch name can be used with --force-with-lease' ' + cd "$ROOT_PATH" && + git clone "$HTTPD_URL_USER_PASS/smart/test_repo.git" non-ascii && + cd non-ascii && + git checkout -b rama-de-árbol && + test_commit F && + git push --force-with-lease origin rama-de-árbol && + git ls-remote origin refs/heads/rama-de-árbol >actual && + git ls-remote . refs/heads/rama-de-árbol >expect && + test_cmp expect actual && + git push --delete --force-with-lease origin rama-de-árbol && + git ls-remote origin refs/heads/rama-de-árbol >actual && + test_must_be_empty actual +' + test_expect_success 'colorize errors/hints' ' cd "$ROOT_PATH"/test_repo_clone && test_must_fail git -c color.transport=always -c color.advice=always \ diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh index 81975ad8f9..7622981cbf 100755 --- a/t/t5553-set-upstream.sh +++ b/t/t5553-set-upstream.sh @@ -81,7 +81,7 @@ test_expect_success 'fetch --set-upstream http://nosuchdomain.example.com fails test_expect_success 'fetch --set-upstream with valid URL sets upstream to URL' ' clear_config other other2 && - url="file://'"$PWD"'" && + url="file://$PWD" && git fetch --set-upstream "$url" && check_config master "$url" HEAD && check_config_missing other && @@ -158,7 +158,7 @@ test_expect_success 'pull --set-upstream upstream with more than one branch does test_expect_success 'pull --set-upstream with valid URL sets upstream to URL' ' clear_config master other other2 && git checkout master && - url="file://'"$PWD"'" && + url="file://$PWD" && git pull --set-upstream "$url" && check_config master "$url" HEAD && check_config_missing other && @@ -168,7 +168,7 @@ test_expect_success 'pull --set-upstream with valid URL sets upstream to URL' ' test_expect_success 'pull --set-upstream with valid URL and branch sets branch' ' clear_config master other other2 && git checkout master && - url="file://'"$PWD"'" && + url="file://$PWD" && git pull --set-upstream "$url" master && check_config master "$url" refs/heads/master && check_config_missing other && diff --git a/t/t5554-noop-fetch-negotiator.sh b/t/t5554-noop-fetch-negotiator.sh new file mode 100755 index 0000000000..2ac7b5859e --- /dev/null +++ b/t/t5554-noop-fetch-negotiator.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +test_description='test noop fetch negotiator' +. ./test-lib.sh + +test_expect_success 'noop negotiator does not emit any "have"' ' + rm -f trace && + + test_create_repo server && + test_commit -C server to_fetch && + + test_create_repo client && + test_commit -C client we_have && + + test_config -C client fetch.negotiationalgorithm noop && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "$(pwd)/server" && + + ! grep "fetch> have" trace && + grep "fetch> done" trace +' + +test_done diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh index c6ec625497..e5d3d15ba8 100755 --- a/t/t5562-http-backend-content-length.sh +++ b/t/t5562-http-backend-content-length.sh @@ -46,7 +46,6 @@ ssize_b100dots() { } test_expect_success 'setup' ' - test_oid_init && HTTP_CONTENT_ENCODING="identity" && export HTTP_CONTENT_ENCODING && git config http.receivepack true && diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 84ea2a3eb7..b6c8312da1 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -271,7 +271,9 @@ test_expect_success 'fetch from gitfile parent' ' test_expect_success 'clone separate gitdir where target already exists' ' rm -rf dst && - test_must_fail git clone --separate-git-dir realgitdir src dst + echo foo=bar >>realgitdir/config && + test_must_fail git clone --separate-git-dir realgitdir src dst && + grep foo=bar realgitdir/config ' test_expect_success 'clone --reference from original' ' @@ -629,6 +631,20 @@ test_expect_success CASE_INSENSITIVE_FS 'colliding file detection' ' test_i18ngrep "the following paths have collided" icasefs/warning ' +test_expect_success 'clone with GIT_DEFAULT_HASH' ' + ( + sane_unset GIT_DEFAULT_HASH && + git init --object-format=sha1 test-sha1 && + git init --object-format=sha256 test-sha256 + ) && + test_commit -C test-sha1 foo && + test_commit -C test-sha256 foo && + GIT_DEFAULT_HASH=sha1 git clone test-sha256 test-clone-sha256 && + GIT_DEFAULT_HASH=sha256 git clone test-sha1 test-clone-sha1 && + git -C test-clone-sha1 status && + git -C test-clone-sha256 status +' + partial_clone_server () { SERVER="$1" && @@ -702,7 +718,7 @@ test_expect_success 'batch missing blob request during checkout' ' # Ensure that there is only one negotiation by checking that there is # only "done" line sent. ("done" marks the end of negotiation.) GIT_TRACE_PACKET="$(pwd)/trace" git -C client checkout HEAD^ && - grep "git> done" trace >done_lines && + grep "fetch> done" trace >done_lines && test_line_count = 1 done_lines ' diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index 6d5a977fcb..26985f4b44 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -4,6 +4,10 @@ test_description='some bundle related tests' . ./test-lib.sh test_expect_success 'setup' ' + test_oid_cache <<-EOF && + version sha1:2 + version sha256:3 + EOF test_commit initial && test_tick && git tag -m tag tag && @@ -94,4 +98,31 @@ test_expect_success 'fetch SHA-1 from bundle' ' git fetch --no-tags foo/tip.bundle "$(cat hash)" ' +test_expect_success 'git bundle uses expected default format' ' + git bundle create bundle HEAD^.. && + head -n1 bundle | grep "^# v$(test_oid version) git bundle$" +' + +test_expect_success 'git bundle v3 has expected contents' ' + git branch side HEAD && + git bundle create --version=3 bundle HEAD^..side && + head -n2 bundle >actual && + cat >expect <<-EOF && + # v3 git bundle + @object-format=$(test_oid algo) + EOF + test_cmp expect actual && + git bundle verify bundle +' + +test_expect_success 'git bundle v3 rejects unknown capabilities' ' + cat >new <<-EOF && + # v3 git bundle + @object-format=$(test_oid algo) + @unknown=silly + EOF + test_must_fail git bundle verify new 2>output && + test_i18ngrep "unknown capability .unknown=silly." output +' + test_done diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 8a27452a51..f4d49d8335 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -163,6 +163,22 @@ test_expect_success 'manual prefetch of missing objects' ' test_line_count = 0 observed.oids ' +test_expect_success 'partial clone with transfer.fsckobjects=1 works with submodules' ' + test_create_repo submodule && + test_commit -C submodule mycommit && + + test_create_repo src_with_sub && + test_config -C src_with_sub uploadpack.allowfilter 1 && + test_config -C src_with_sub uploadpack.allowanysha1inwant 1 && + + git -C src_with_sub submodule add "file://$(pwd)/submodule" mysub && + git -C src_with_sub commit -m "commit with submodule" && + + git -c transfer.fsckobjects=1 \ + clone --filter="blob:none" "file://$(pwd)/src_with_sub" dst && + test_when_finished rm -rf dst +' + test_expect_success 'partial clone with transfer.fsckobjects=1 uses index-pack --fsck-objects' ' git init src && test_commit -C src x && @@ -235,6 +251,39 @@ test_expect_success 'implicitly construct combine: filter with repeated flags' ' test_cmp unique_types.expected unique_types.actual ' +test_expect_success 'upload-pack fails banned object filters' ' + test_config -C srv.bare uploadpackfilter.blob:none.allow false && + test_must_fail ok=sigpipe git clone --no-checkout --filter=blob:none \ + "file://$(pwd)/srv.bare" pc3 2>err && + test_i18ngrep "filter '\''blob:none'\'' not supported" err +' + +test_expect_success 'upload-pack fails banned combine object filters' ' + test_config -C srv.bare uploadpackfilter.allow false && + test_config -C srv.bare uploadpackfilter.combine.allow true && + test_config -C srv.bare uploadpackfilter.tree.allow true && + test_config -C srv.bare uploadpackfilter.blob:none.allow false && + test_must_fail ok=sigpipe git clone --no-checkout --filter=tree:1 \ + --filter=blob:none "file://$(pwd)/srv.bare" pc3 2>err && + test_i18ngrep "filter '\''blob:none'\'' not supported" err +' + +test_expect_success 'upload-pack fails banned object filters with fallback' ' + test_config -C srv.bare uploadpackfilter.allow false && + test_must_fail ok=sigpipe git clone --no-checkout --filter=blob:none \ + "file://$(pwd)/srv.bare" pc3 2>err && + test_i18ngrep "filter '\''blob:none'\'' not supported" err +' + +test_expect_success 'upload-pack limits tree depth filters' ' + test_config -C srv.bare uploadpackfilter.allow false && + test_config -C srv.bare uploadpackfilter.tree.allow true && + test_config -C srv.bare uploadpackfilter.tree.maxDepth 0 && + test_must_fail ok=sigpipe git clone --no-checkout --filter=tree:1 \ + "file://$(pwd)/srv.bare" pc3 2>err && + test_i18ngrep "tree filter allows max depth 0, but got 1" err +' + test_expect_success 'partial clone fetches blobs pointed to by refs even if normally filtered out' ' rm -rf src dst && git init src && @@ -384,6 +433,26 @@ test_expect_success 'fetch lazy-fetches only to resolve deltas, protocol v2' ' grep "want $(cat hash)" trace ' +test_expect_success 'fetch does not lazy-fetch missing targets of its refs' ' + rm -rf server client trace && + + test_create_repo server && + test_config -C server uploadpack.allowfilter 1 && + test_config -C server uploadpack.allowanysha1inwant 1 && + test_commit -C server foo && + + git clone --filter=blob:none "file://$(pwd)/server" client && + # Make all refs point to nothing by deleting all objects. + rm client/.git/objects/pack/* && + + test_commit -C server bar && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \ + --no-tags --recurse-submodules=no \ + origin refs/tags/bar && + FOO_HASH=$(git -C server rev-parse foo) && + ! grep "want $FOO_HASH" trace +' + # The following two tests must be in this order. It is important that # the srv.bare repository did not have tags during clone, but has tags # in the fetch. @@ -422,6 +491,44 @@ test_expect_success 'single-branch tag following respects partial clone' ' test_must_fail git -C single rev-parse --verify refs/tags/C ' +test_expect_success 'fetch from a partial clone, protocol v0' ' + rm -rf server client trace && + + # Pretend that the server is a partial clone + git init server && + git -C server remote add a_remote "file://$(pwd)/" && + test_config -C server core.repositoryformatversion 1 && + test_config -C server extensions.partialclone a_remote && + test_config -C server protocol.version 0 && + test_commit -C server foo && + + # Fetch from the server + git init client && + test_config -C client protocol.version 0 && + test_commit -C client bar && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "file://$(pwd)/server" && + ! grep "version 2" trace +' + +test_expect_success 'fetch from a partial clone, protocol v2' ' + rm -rf server client trace && + + # Pretend that the server is a partial clone + git init server && + git -C server remote add a_remote "file://$(pwd)/" && + test_config -C server core.repositoryformatversion 1 && + test_config -C server extensions.partialclone a_remote && + test_config -C server protocol.version 2 && + test_commit -C server foo && + + # Fetch from the server + git init client && + test_config -C client protocol.version 2 && + test_commit -C client bar && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "file://$(pwd)/server" && + grep "version 2" trace +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 1b54c35b01..7d5b17909b 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -13,7 +13,6 @@ start_git_daemon --export-all --enable=receive-pack daemon_parent=$GIT_DAEMON_DOCUMENT_ROOT_PATH/parent test_expect_success 'create repo to be served by git-daemon' ' - test_oid_init && git init "$daemon_parent" && test_commit -C "$daemon_parent" one ' @@ -829,7 +828,7 @@ test_expect_success 'part of packfile response provided as URI' ' # Ensure that my-blob and other-blob are in separate packfiles. for idx in http_child/.git/objects/pack/*.idx do - git verify-pack --verbose $idx >out && + git verify-pack --object-format=$(test_oid algo) --verbose $idx >out && { grep "^[0-9a-f]\{16,\} " out || : } >out.objectlist && @@ -884,6 +883,59 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' test_i18ngrep "pack downloaded from.*does not match expected hash" err ' +test_expect_success 'packfile-uri with transfer.fsckobjects' ' + P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && + rm -rf "$P" http_child log && + + git init "$P" && + git -C "$P" config "uploadpack.allowsidebandall" "true" && + + echo my-blob >"$P/my-blob" && + git -C "$P" add my-blob && + git -C "$P" commit -m x && + + configure_exclusion "$P" my-blob >h && + + sane_unset GIT_TEST_SIDEBAND_ALL && + git -c protocol.version=2 -c transfer.fsckobjects=1 \ + -c fetch.uriprotocols=http,https \ + clone "$HTTPD_URL/smart/http_parent" http_child && + + # Ensure that there are exactly 4 files (2 .pack and 2 .idx). + ls http_child/.git/objects/pack/* >filelist && + test_line_count = 4 filelist +' + +test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object' ' + P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && + rm -rf "$P" http_child log && + + git init "$P" && + git -C "$P" config "uploadpack.allowsidebandall" "true" && + + cat >bogus-commit <<-EOF && + tree $EMPTY_TREE + author Bugs Bunny 1234567890 +0000 + committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000 + + This commit object intentionally broken + EOF + BOGUS=$(git -C "$P" hash-object -t commit -w --stdin <bogus-commit) && + git -C "$P" branch bogus-branch "$BOGUS" && + + echo my-blob >"$P/my-blob" && + git -C "$P" add my-blob && + git -C "$P" commit -m x && + + configure_exclusion "$P" my-blob >h && + + sane_unset GIT_TEST_SIDEBAND_ALL && + test_must_fail git -c protocol.version=2 -c transfer.fsckobjects=1 \ + -c fetch.uriprotocols=http,https \ + clone "$HTTPD_URL/smart/http_parent" http_child 2>error && + test_i18ngrep "invalid author/committer line - missing email" error +' + # DO NOT add non-httpd-specific tests here, because the last part of this # test script is only executed when httpd is available and enabled. diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index 748282f058..d9ecf0f4a9 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -43,7 +43,6 @@ write_command () { # \ | / # a test_expect_success 'setup repository' ' - test_oid_init && test_commit a && git checkout -b o/foo && test_commit b && diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index 3dc1ad8f71..fc4d55dcb2 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -8,6 +8,7 @@ test_expect_success setup ' echo content1 >wanted_file && echo content2 >unwanted_file && git add wanted_file unwanted_file && + test_tick && git commit -m one ' @@ -21,6 +22,7 @@ test_expect_success 'rev-list --objects with pathspecs and deeper paths' ' mkdir foo && >foo/file && git add foo/file && + test_tick && git commit -m two && git rev-list --objects HEAD -- foo >output && @@ -69,6 +71,7 @@ test_expect_success '--no-object-names and --object-names are last-one-wins' ' ' test_expect_success 'rev-list A..B and rev-list ^A B are the same' ' + test_tick && git commit --allow-empty -m another && git tag -a -m "annotated" v1.0 && git rev-list --objects ^v1.0^ v1.0 >expect && @@ -84,10 +87,10 @@ test_expect_success 'propagate uninteresting flag down correctly' ' test_expect_success 'symleft flag bit is propagated down from tag' ' git log --format="%m %s" --left-right v1.0...master >actual && cat >expect <<-\EOF && - > two - > one < another < that + > two + > one EOF test_cmp expect actual ' @@ -125,8 +128,8 @@ test_expect_success 'rev-list can negate index objects' ' test_cmp expect actual ' -test_expect_success '--bisect and --first-parent can not be combined' ' - test_must_fail git rev-list --bisect --first-parent HEAD +test_expect_success '--bisect and --first-parent can be combined' ' + git rev-list --bisect --first-parent HEAD ' test_expect_success '--header shows a NUL after each commit' ' diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index a661408038..b95a0212ad 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -263,4 +263,49 @@ test_expect_success 'rev-parse --bisect can default to good/bad refs' ' test_cmp expect.sorted actual.sorted ' +test_output_expect_success '--bisect --first-parent' 'git rev-list --bisect --first-parent E ^F' <<EOF +e4 +EOF + +test_output_expect_success '--first-parent' 'git rev-list --first-parent E ^F' <<EOF +E +e1 +e2 +e3 +e4 +e5 +e6 +e7 +e8 +EOF + +test_output_expect_success '--bisect-vars --first-parent' 'git rev-list --bisect-vars --first-parent E ^F' <<EOF +bisect_rev='e5' +bisect_nr=4 +bisect_good=4 +bisect_bad=3 +bisect_all=9 +bisect_steps=2 +EOF + +test_expect_success '--bisect-all --first-parent' ' + cat >expect.unsorted <<-EOF && + $(git rev-parse E) (tag: E, dist=0) + $(git rev-parse e1) (tag: e1, dist=1) + $(git rev-parse e2) (tag: e2, dist=2) + $(git rev-parse e3) (tag: e3, dist=3) + $(git rev-parse e4) (tag: e4, dist=4) + $(git rev-parse e5) (tag: e5, dist=4) + $(git rev-parse e6) (tag: e6, dist=3) + $(git rev-parse e7) (tag: e7, dist=2) + $(git rev-parse e8) (tag: e8, dist=1) + EOF + + # expect results to be ordered by distance (descending), + # commit hash (ascending) + sort -k4,4r -k1,1 expect.unsorted >expect && + git rev-list --bisect-all --first-parent E ^F >actual && + test_cmp expect actual +' + test_done diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 7e82e43a63..bc95da8a5f 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -32,7 +32,6 @@ changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding) truncate_count=20 test_expect_success 'setup' ' - test_oid_init && : >foo && git add foo && git config i18n.commitEncoding $test_encoding && diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index bb5aeac07f..b31ff7eeec 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -345,6 +345,11 @@ test_expect_success 'rev-list should succeed with empty output with empty glob' test_must_be_empty actual ' +test_expect_success 'rev-list should succeed with empty output when ignoring missing' ' + git rev-list --ignore-missing $ZERO_OID >actual && + test_must_be_empty actual +' + test_expect_success 'shortlog accepts --glob/--tags/--remotes' ' compare shortlog "subspace/one subspace/two" --branches=subspace && diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 36d9b2b2e4..aa226381be 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -82,6 +82,13 @@ test_expect_success 'bisect fails if given any junk instead of revs' ' git bisect bad $HASH4 ' +test_expect_success 'bisect start without -- takes unknown arg as pathspec' ' + git bisect reset && + git bisect start foo bar && + grep foo ".git/BISECT_NAMES" && + grep bar ".git/BISECT_NAMES" +' + test_expect_success 'bisect reset: back in the master branch' ' git bisect reset && echo "* master" > branch.expect && @@ -243,32 +250,30 @@ test_expect_success 'bisect skip: with commit both bad and skipped' ' ' # We want to automatically find the commit that -# introduced "Another" into hello. -test_expect_success \ - '"git bisect run" simple case' \ - 'echo "#"\!"/bin/sh" > test_script.sh && - echo "grep Another hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && - git bisect start && - git bisect good $HASH1 && - git bisect bad $HASH4 && - git bisect run ./test_script.sh > my_bisect_log.txt && - grep "$HASH3 is the first bad commit" my_bisect_log.txt && - git bisect reset' +# added "Another" into hello. +test_expect_success '"git bisect run" simple case' ' + write_script test_script.sh <<-\EOF && + ! grep Another hello >/dev/null + EOF + git bisect start && + git bisect good $HASH1 && + git bisect bad $HASH4 && + git bisect run ./test_script.sh >my_bisect_log.txt && + grep "$HASH3 is the first bad commit" my_bisect_log.txt && + git bisect reset +' # We want to automatically find the commit that -# introduced "Ciao" into hello. -test_expect_success \ - '"git bisect run" with more complex "git bisect start"' \ - 'echo "#"\!"/bin/sh" > test_script.sh && - echo "grep Ciao hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && - git bisect start $HASH4 $HASH1 && - git bisect run ./test_script.sh > my_bisect_log.txt && - grep "$HASH4 is the first bad commit" my_bisect_log.txt && - git bisect reset' +# added "Ciao" into hello. +test_expect_success '"git bisect run" with more complex "git bisect start"' ' + write_script test_script.sh <<-\EOF && + ! grep Ciao hello >/dev/null + EOF + git bisect start $HASH4 $HASH1 && + git bisect run ./test_script.sh >my_bisect_log.txt && + grep "$HASH4 is the first bad commit" my_bisect_log.txt && + git bisect reset +' # $HASH1 is good, $HASH5 is bad, we skip $HASH3 # but $HASH4 is good, @@ -295,24 +300,17 @@ HASH6= test_expect_success 'bisect run & skip: cannot tell between 2' ' add_line_into_file "6: Yet a line." hello && HASH6=$(git rev-parse --verify HEAD) && - echo "#"\!"/bin/sh" > test_script.sh && - echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh && - echo "grep line hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && + write_script test_script.sh <<-\EOF && + sed -ne \$p hello | grep Ciao >/dev/null && exit 125 + ! grep line hello >/dev/null + EOF git bisect start $HASH6 $HASH1 && - if git bisect run ./test_script.sh > my_bisect_log.txt - then - echo Oops, should have failed. - false - else - test $? -eq 2 && - grep "first bad commit could be any of" my_bisect_log.txt && - ! grep $HASH3 my_bisect_log.txt && - ! grep $HASH6 my_bisect_log.txt && - grep $HASH4 my_bisect_log.txt && - grep $HASH5 my_bisect_log.txt - fi + test_expect_code 2 git bisect run ./test_script.sh >my_bisect_log.txt && + grep "first bad commit could be any of" my_bisect_log.txt && + ! grep $HASH3 my_bisect_log.txt && + ! grep $HASH6 my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + grep $HASH5 my_bisect_log.txt ' HASH7= @@ -320,14 +318,13 @@ test_expect_success 'bisect run & skip: find first bad' ' git bisect reset && add_line_into_file "7: Should be the last line." hello && HASH7=$(git rev-parse --verify HEAD) && - echo "#"\!"/bin/sh" > test_script.sh && - echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh && - echo "sed -ne \\\$p hello | grep day > /dev/null && exit 125" >> test_script.sh && - echo "grep Yet hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && + write_script test_script.sh <<-\EOF && + sed -ne \$p hello | grep Ciao >/dev/null && exit 125 + sed -ne \$p hello | grep day >/dev/null && exit 125 + ! grep Yet hello >/dev/null + EOF git bisect start $HASH7 $HASH1 && - git bisect run ./test_script.sh > my_bisect_log.txt && + git bisect run ./test_script.sh >my_bisect_log.txt && grep "$HASH6 is the first bad commit" my_bisect_log.txt ' @@ -458,6 +455,24 @@ test_expect_success 'many merge bases creation' ' grep "$SIDE_HASH5" merge_bases.txt ' +# We want to automatically find the merge that +# added "line" into hello. +test_expect_success '"git bisect run --first-parent" simple case' ' + git rev-list --first-parent $B_HASH ^$HASH4 >first_parent_chain.txt && + write_script test_script.sh <<-\EOF && + grep $(git rev-parse HEAD) first_parent_chain.txt || exit -1 + ! grep line hello >/dev/null + EOF + git bisect start --first-parent && + test_path_is_file ".git/BISECT_FIRST_PARENT" && + git bisect good $HASH4 && + git bisect bad $B_HASH && + git bisect run ./test_script.sh >my_bisect_log.txt && + grep "$B_HASH is the first bad commit" my_bisect_log.txt && + git bisect reset && + test_path_is_missing .git/BISECT_FIRST_PARENT +' + test_expect_success 'good merge bases when good and bad are siblings' ' git bisect start "$B_HASH" "$A_HASH" > my_bisect_log.txt && test_i18ngrep "merge base must be tested" my_bisect_log.txt && diff --git a/t/t6100-rev-list-in-order.sh b/t/t6100-rev-list-in-order.sh index b2bb0a7f61..e934bc239c 100755 --- a/t/t6100-rev-list-in-order.sh +++ b/t/t6100-rev-list-in-order.sh @@ -22,7 +22,7 @@ test_expect_success 'setup a commit history with trees, blobs' ' test_expect_success 'rev-list --in-commit-order' ' git rev-list --in-commit-order --objects HEAD >actual.raw && - cut -c 1-40 >actual <actual.raw && + cut -d" " -f1 >actual <actual.raw && git cat-file --batch-check="%(objectname)" >expect.raw <<-\EOF && HEAD^{commit} @@ -49,7 +49,7 @@ test_expect_success 'rev-list --in-commit-order' ' test_expect_success 'rev-list lists blobs and trees after commits' ' git rev-list --objects HEAD >actual.raw && - cut -c 1-40 >actual <actual.raw && + cut -d" " -f1 >actual <actual.raw && git cat-file --batch-check="%(objectname)" >expect.raw <<-\EOF && HEAD^{commit} diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index 7683e4a114..7531262a5e 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -34,7 +34,7 @@ test_expect_success 'setup' ' ' test_expect_success 'start is valid' ' - git rev-parse start | grep "^[0-9a-f]\{40\}$" + git rev-parse start | grep "^$OID_REGEX$" ' test_expect_success 'start^0' ' diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index 2b3fd498d0..7d549748ef 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -79,7 +79,7 @@ test_expect_success GPG 'set up a signed tag' ' ' test_expect_success 'message for merging local branch' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git checkout master && git fetch . left && @@ -107,7 +107,7 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' ' ' test_expect_success 'message for merging external branch' ' - echo "Merge branch ${apos}left${apos} of $(pwd) into master" >expected && + echo "Merge branch ${apos}left${apos} of $(pwd)" >expected && git checkout master && git fetch "$(pwd)" left && @@ -118,7 +118,7 @@ test_expect_success 'message for merging external branch' ' test_expect_success '[merge] summary/log configuration' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -160,7 +160,7 @@ test_expect_success 'setup FETCH_HEAD' ' test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -177,7 +177,7 @@ test_expect_success 'merge.log=3 limits shortlog length' ' test_expect_success 'merge.log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -195,7 +195,7 @@ test_expect_success 'merge.log=5 shows all 5 commits' ' test_expect_success '--log=5 with custom comment character' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} x By Another Author (3) and A U Thor (2) x Via Another Committer @@ -212,14 +212,14 @@ test_expect_success '--log=5 with custom comment character' ' ' test_expect_success 'merge.log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -236,7 +236,7 @@ test_expect_success '--log=3 limits shortlog length' ' test_expect_success '--log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -253,13 +253,13 @@ test_expect_success '--log=5 shows all 5 commits' ' ' test_expect_success '--no-log disables shortlog' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual ' @@ -300,7 +300,7 @@ test_expect_success 'fmt-merge-msg -m' ' test_expect_success 'setup: expected shortlog for two branches' ' cat >expected <<-EOF - Merge branches ${apos}left${apos} and ${apos}right${apos} into master + Merge branches ${apos}left${apos} and ${apos}right${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -397,7 +397,7 @@ test_expect_success 'merge-msg with nothing to merge' ' test_expect_success 'merge-msg tag' ' cat >expected <<-EOF && - Merge tag ${apos}tag-r3${apos} into master + Merge tag ${apos}tag-r3${apos} * tag ${apos}tag-r3${apos}: Right #3 @@ -418,7 +418,7 @@ test_expect_success 'merge-msg tag' ' test_expect_success 'merge-msg two tags' ' cat >expected <<-EOF && - Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} into master + Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} * tag ${apos}tag-r3${apos}: Right #3 @@ -448,7 +448,7 @@ test_expect_success 'merge-msg two tags' ' test_expect_success 'merge-msg tag and branch' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} into master + Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} * tag ${apos}tag-r3${apos}: Right #3 @@ -479,7 +479,7 @@ test_expect_success 'merge-msg tag and branch' ' test_expect_success 'merge-msg lots of commits' ' { cat <<-EOF && - Merge branch ${apos}long${apos} into master + Merge branch ${apos}long${apos} * long: (35 commits) EOF @@ -516,7 +516,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git fmt-merge-msg <.git/FETCH_HEAD >actual && { cat <<-\EOF - Merge tag '\''annote'\'' into master + Merge tag '\''annote'\'' An annotated one @@ -531,7 +531,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git merge --no-commit --no-ff $annote && { cat <<-EOF - Merge tag '\''$annote'\'' into master + Merge tag '\''$annote'\'' An annotated one @@ -542,4 +542,24 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' test_cmp expected .git/MERGE_MSG ' +test_expect_success 'merge.suppressDest configuration' ' + git checkout -B side master && + git commit --allow-empty -m "One step ahead" && + git checkout master && + git fetch . side && + + git -c merge.suppressDest="" fmt-merge-msg <.git/FETCH_HEAD >full.1 && + head -n1 full.1 >actual && + grep -e "Merge branch .side. into master" actual && + + git -c merge.suppressDest="mast" fmt-merge-msg <.git/FETCH_HEAD >full.2 && + head -n1 full.2 >actual && + grep -e "Merge branch .side. into master$" actual && + + git -c merge.suppressDest="ma??er" fmt-merge-msg <.git/FETCH_HEAD >full.3 && + head -n1 full.3 >actual && + grep -e "Merge branch .side." actual && + ! grep -e " into master$" actual +' + test_done diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index da59fadc5d..b359023189 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -52,6 +52,25 @@ test_atom() { sanitize_pgp <actual >actual.clean && test_cmp expected actual.clean " + # Automatically test "contents:size" atom after testing "contents" + if test "$2" = "contents" + then + case $(git cat-file -t "$ref") in + tag) + # We cannot use $3 as it expects sanitize_pgp to run + expect=$(git cat-file tag $ref | tail -n +6 | wc -c) ;; + tree | blob) + expect='' ;; + commit) + expect=$(printf '%s' "$3" | wc -c) ;; + esac + # Leave $expect unquoted to lose possible leading whitespaces + echo $expect >expected + test_expect_${4:-success} $PREREQ "basic atom: $1 contents:size" ' + git for-each-ref --format="%(contents:size)" "$ref" >actual && + test_cmp expected actual + ' + fi } hexlen=$(test_oid hexsz) @@ -97,7 +116,13 @@ test_atom head objectname:short $(git rev-parse --short refs/heads/master) test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master) test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/master) test_atom head tree $(git rev-parse refs/heads/master^{tree}) +test_atom head tree:short $(git rev-parse --short refs/heads/master^{tree}) +test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/master^{tree}) +test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/master^{tree}) test_atom head parent '' +test_atom head parent:short '' +test_atom head parent:short=1 '' +test_atom head parent:short=10 '' test_atom head numparent 0 test_atom head object '' test_atom head type '' @@ -106,19 +131,26 @@ test_atom head '*objecttype' '' test_atom head author 'A U Thor <author@example.com> 1151968724 +0200' test_atom head authorname 'A U Thor' test_atom head authoremail '<author@example.com>' +test_atom head authoremail:trim 'author@example.com' +test_atom head authoremail:localpart 'author' test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200' test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200' test_atom head committername 'C O Mitter' test_atom head committeremail '<committer@example.com>' +test_atom head committeremail:trim 'committer@example.com' +test_atom head committeremail:localpart 'committer' test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200' test_atom head tag '' test_atom head tagger '' test_atom head taggername '' test_atom head taggeremail '' +test_atom head taggeremail:trim '' +test_atom head taggeremail:localpart '' test_atom head taggerdate '' test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200' test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200' test_atom head subject 'Initial' +test_atom head subject:sanitize 'Initial' test_atom head contents:subject 'Initial' test_atom head body '' test_atom head contents:body '' @@ -142,7 +174,13 @@ test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag) test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master) test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/master) test_atom tag tree '' +test_atom tag tree:short '' +test_atom tag tree:short=1 '' +test_atom tag tree:short=10 '' test_atom tag parent '' +test_atom tag parent:short '' +test_atom tag parent:short=1 '' +test_atom tag parent:short=10 '' test_atom tag numparent '' test_atom tag object $(git rev-parse refs/tags/testtag^0) test_atom tag type 'commit' @@ -151,19 +189,26 @@ test_atom tag '*objecttype' 'commit' test_atom tag author '' test_atom tag authorname '' test_atom tag authoremail '' +test_atom tag authoremail:trim '' +test_atom tag authoremail:localpart '' test_atom tag authordate '' test_atom tag committer '' test_atom tag committername '' test_atom tag committeremail '' +test_atom tag committeremail:trim '' +test_atom tag committeremail:localpart '' test_atom tag committerdate '' test_atom tag tag 'testtag' test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200' test_atom tag taggername 'C O Mitter' test_atom tag taggeremail '<committer@example.com>' +test_atom tag taggeremail:trim 'committer@example.com' +test_atom tag taggeremail:localpart 'committer' test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200' test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200' test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200' test_atom tag subject 'Tagging at 1151968727' +test_atom tag subject:sanitize 'Tagging-at-1151968727' test_atom tag contents:subject 'Tagging at 1151968727' test_atom tag body '' test_atom tag contents:body '' @@ -545,10 +590,14 @@ test_atom refs/tags/taggerless tag 'taggerless' test_atom refs/tags/taggerless tagger '' test_atom refs/tags/taggerless taggername '' test_atom refs/tags/taggerless taggeremail '' +test_atom refs/tags/taggerless taggeremail:trim '' +test_atom refs/tags/taggerless taggeremail:localpart '' test_atom refs/tags/taggerless taggerdate '' test_atom refs/tags/taggerless committer '' test_atom refs/tags/taggerless committername '' test_atom refs/tags/taggerless committeremail '' +test_atom refs/tags/taggerless committeremail:trim '' +test_atom refs/tags/taggerless committeremail:localpart '' test_atom refs/tags/taggerless committerdate '' test_atom refs/tags/taggerless subject 'Broken tag' @@ -572,6 +621,7 @@ test_expect_success 'create tag with subject and body content' ' git tag -F msg subject-body ' test_atom refs/tags/subject-body subject 'the subject line' +test_atom refs/tags/subject-body subject:sanitize 'the-subject-line' test_atom refs/tags/subject-body body 'first body line second body line ' @@ -592,6 +642,7 @@ test_expect_success 'create tag with multiline subject' ' git tag -F msg multiline ' test_atom refs/tags/multiline subject 'first subject line second subject line' +test_atom refs/tags/multiline subject:sanitize 'first-subject-line-second-subject-line' test_atom refs/tags/multiline contents:subject 'first subject line second subject line' test_atom refs/tags/multiline body 'first body line second body line @@ -624,6 +675,7 @@ sig='-----BEGIN PGP SIGNATURE----- PREREQ=GPG test_atom refs/tags/signed-empty subject '' +test_atom refs/tags/signed-empty subject:sanitize '' test_atom refs/tags/signed-empty contents:subject '' test_atom refs/tags/signed-empty body "$sig" test_atom refs/tags/signed-empty contents:body '' @@ -631,6 +683,7 @@ test_atom refs/tags/signed-empty contents:signature "$sig" test_atom refs/tags/signed-empty contents "$sig" test_atom refs/tags/signed-short subject 'subject line' +test_atom refs/tags/signed-short subject:sanitize 'subject-line' test_atom refs/tags/signed-short contents:subject 'subject line' test_atom refs/tags/signed-short body "$sig" test_atom refs/tags/signed-short contents:body '' @@ -639,6 +692,7 @@ test_atom refs/tags/signed-short contents "subject line $sig" test_atom refs/tags/signed-long subject 'subject line' +test_atom refs/tags/signed-long subject:sanitize 'subject-line' test_atom refs/tags/signed-long contents:subject 'subject line' test_atom refs/tags/signed-long body "body contents $sig" @@ -650,6 +704,25 @@ test_atom refs/tags/signed-long contents "subject line body contents $sig" +test_expect_success 'set up refs pointing to tree and blob' ' + git update-ref refs/mytrees/first refs/heads/master^{tree} && + git update-ref refs/myblobs/first refs/heads/master:one +' + +test_atom refs/mytrees/first subject "" +test_atom refs/mytrees/first contents:subject "" +test_atom refs/mytrees/first body "" +test_atom refs/mytrees/first contents:body "" +test_atom refs/mytrees/first contents:signature "" +test_atom refs/mytrees/first contents "" + +test_atom refs/myblobs/first subject "" +test_atom refs/myblobs/first contents:subject "" +test_atom refs/myblobs/first body "" +test_atom refs/myblobs/first contents:body "" +test_atom refs/myblobs/first contents:signature "" +test_atom refs/myblobs/first contents "" + test_expect_success 'set up multiple-sort tags' ' for when in 100000 200000 do @@ -738,61 +811,40 @@ test_expect_success 'set up trailers for next test' ' ' test_expect_success '%(trailers:unfold) unfolds trailers' ' - git for-each-ref --format="%(trailers:unfold)" refs/heads/master >actual && { unfold <trailers echo } >expect && + git for-each-ref --format="%(trailers:unfold)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/master >actual && test_cmp expect actual ' test_expect_success '%(trailers:only) shows only "key: value" trailers' ' - git for-each-ref --format="%(trailers:only)" refs/heads/master >actual && { grep -v patch.description <trailers && echo } >expect && + git for-each-ref --format="%(trailers:only)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:only)" refs/heads/master >actual && test_cmp expect actual ' test_expect_success '%(trailers:only) and %(trailers:unfold) work together' ' - git for-each-ref --format="%(trailers:only,unfold)" refs/heads/master >actual && - git for-each-ref --format="%(trailers:unfold,only)" refs/heads/master >reverse && - test_cmp actual reverse && { grep -v patch.description <trailers | unfold && echo } >expect && - test_cmp expect actual -' - -test_expect_success '%(contents:trailers:unfold) unfolds trailers' ' - git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/master >actual && - { - unfold <trailers - echo - } >expect && - test_cmp expect actual -' - -test_expect_success '%(contents:trailers:only) shows only "key: value" trailers' ' - git for-each-ref --format="%(contents:trailers:only)" refs/heads/master >actual && - { - grep -v patch.description <trailers && - echo - } >expect && - test_cmp expect actual -' - -test_expect_success '%(contents:trailers:only) and %(contents:trailers:unfold) work together' ' + git for-each-ref --format="%(trailers:only,unfold)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(trailers:unfold,only)" refs/heads/master >actual && + test_cmp actual actual && git for-each-ref --format="%(contents:trailers:only,unfold)" refs/heads/master >actual && - git for-each-ref --format="%(contents:trailers:unfold,only)" refs/heads/master >reverse && - test_cmp actual reverse && - { - grep -v patch.description <trailers | unfold && - echo - } >expect && - test_cmp expect actual + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:unfold,only)" refs/heads/master >actual && + test_cmp actual actual ' test_expect_success '%(trailers) rejects unknown trailers arguments' ' @@ -801,15 +853,16 @@ test_expect_success '%(trailers) rejects unknown trailers arguments' ' fatal: unknown %(trailers) argument: unsupported EOF test_must_fail git for-each-ref --format="%(trailers:unsupported)" 2>actual && + test_i18ncmp expect actual && + test_must_fail git for-each-ref --format="%(contents:trailers:unsupported)" 2>actual && test_i18ncmp expect actual ' -test_expect_success '%(contents:trailers) rejects unknown trailers arguments' ' - # error message cannot be checked under i18n +test_expect_success 'if arguments, %(contents:trailers) shows error if colon is missing' ' cat >expect <<-EOF && - fatal: unknown %(trailers) argument: unsupported + fatal: unrecognized %(contents) argument: trailersonly EOF - test_must_fail git for-each-ref --format="%(contents:trailers:unsupported)" 2>actual && + test_must_fail git for-each-ref --format="%(contents:trailersonly)" 2>actual && test_i18ncmp expect actual ' diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh index 49cc65bb58..809854fc0c 100755 --- a/t/t6301-for-each-ref-errors.sh +++ b/t/t6301-for-each-ref-errors.sh @@ -5,9 +5,9 @@ test_description='for-each-ref errors for broken refs' . ./test-lib.sh ZEROS=$ZERO_OID -MISSING=abababababababababababababababababababab test_expect_success setup ' + MISSING=$(test_oid deadbeef) && git commit --allow-empty -m "Initial" && git tag testtag && git for-each-ref >full-list && diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index 35408d53fd..781e470aea 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -437,8 +437,8 @@ test_expect_success 'check %(if:notequals=<string>)' ' test_cmp expect actual ' -test_expect_success '--merged is incompatible with --no-merged' ' - test_must_fail git for-each-ref --merged HEAD --no-merged HEAD +test_expect_success '--merged is compatible with --no-merged' ' + git for-each-ref --merged HEAD --no-merged HEAD ' test_expect_success 'validate worktree atom' ' diff --git a/t/t6020-merge-df.sh b/t/t6400-merge-df.sh index 400a4cd139..400a4cd139 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6400-merge-df.sh diff --git a/t/t6021-merge-criss-cross.sh b/t/t6401-merge-criss-cross.sh index 9d5e992878..9d5e992878 100755 --- a/t/t6021-merge-criss-cross.sh +++ b/t/t6401-merge-criss-cross.sh diff --git a/t/t6022-merge-rename.sh b/t/t6402-merge-rename.sh index bbbba3dcbf..bbbba3dcbf 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6402-merge-rename.sh diff --git a/t/t6023-merge-file.sh b/t/t6403-merge-file.sh index 2f421d967a..2f421d967a 100755 --- a/t/t6023-merge-file.sh +++ b/t/t6403-merge-file.sh diff --git a/t/t6024-recursive-merge.sh b/t/t6404-recursive-merge.sh index 332cfc53fd..332cfc53fd 100755 --- a/t/t6024-recursive-merge.sh +++ b/t/t6404-recursive-merge.sh diff --git a/t/t6025-merge-symlinks.sh b/t/t6405-merge-symlinks.sh index 6c0a90d044..6c0a90d044 100755 --- a/t/t6025-merge-symlinks.sh +++ b/t/t6405-merge-symlinks.sh diff --git a/t/t6026-merge-attr.sh b/t/t6406-merge-attr.sh index 5900358ce9..76a55f838c 100755 --- a/t/t6026-merge-attr.sh +++ b/t/t6406-merge-attr.sh @@ -122,7 +122,7 @@ test_expect_success 'custom merge backend' ' o=$(git unpack-file master^:text) && a=$(git unpack-file side^:text) && b=$(git unpack-file master:text) && - sh -c "./custom-merge $o $a $b 0 'text'" && + sh -c "./custom-merge $o $a $b 0 text" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && rm -f $o $a $b @@ -149,7 +149,7 @@ test_expect_success 'custom merge backend' ' o=$(git unpack-file master^:text) && a=$(git unpack-file anchor:text) && b=$(git unpack-file master:text) && - sh -c "./custom-merge $o $a $b 0 'text'" && + sh -c "./custom-merge $o $a $b 0 text" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && sed -e 1,3d -e 4q $a >check-3 && diff --git a/t/t6027-merge-binary.sh b/t/t6407-merge-binary.sh index 4e6c7cb77e..4e6c7cb77e 100755 --- a/t/t6027-merge-binary.sh +++ b/t/t6407-merge-binary.sh diff --git a/t/t6028-merge-up-to-date.sh b/t/t6408-merge-up-to-date.sh index 7763c1ba98..7763c1ba98 100755 --- a/t/t6028-merge-up-to-date.sh +++ b/t/t6408-merge-up-to-date.sh diff --git a/t/t6029-merge-subtree.sh b/t/t6409-merge-subtree.sh index 793f0c8bf3..793f0c8bf3 100755 --- a/t/t6029-merge-subtree.sh +++ b/t/t6409-merge-subtree.sh diff --git a/t/t6031-merge-filemode.sh b/t/t6411-merge-filemode.sh index 87741efad3..87741efad3 100755 --- a/t/t6031-merge-filemode.sh +++ b/t/t6411-merge-filemode.sh diff --git a/t/t6032-merge-large-rename.sh b/t/t6412-merge-large-rename.sh index 80777386dc..80777386dc 100755 --- a/t/t6032-merge-large-rename.sh +++ b/t/t6412-merge-large-rename.sh diff --git a/t/t6033-merge-crlf.sh b/t/t6413-merge-crlf.sh index e8d65eefb5..e8d65eefb5 100755 --- a/t/t6033-merge-crlf.sh +++ b/t/t6413-merge-crlf.sh diff --git a/t/t6034-merge-rename-nocruft.sh b/t/t6414-merge-rename-nocruft.sh index a25e730460..a25e730460 100755 --- a/t/t6034-merge-rename-nocruft.sh +++ b/t/t6414-merge-rename-nocruft.sh diff --git a/t/t6035-merge-dir-to-symlink.sh b/t/t6415-merge-dir-to-symlink.sh index 2eddcc7664..2eddcc7664 100755 --- a/t/t6035-merge-dir-to-symlink.sh +++ b/t/t6415-merge-dir-to-symlink.sh diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh index b3bf462617..fd98989b14 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6416-recursive-corner-cases.sh @@ -452,7 +452,7 @@ test_expect_success 'git detects conflict merging criss-cross+modify/delete, rev # # So choice 5 at least provides some kind of conflict for the original case, # and can merge cleanly as expected with D1 and E3. It also made things just -# slightly funny for merging D1 and e$, where E4 is defined as: +# slightly funny for merging D1 and E4, where E4 is defined as: # Commit E4: Merge B & C, modifying 'a' and renaming to 'a2', and deleting 'a/' # in this case, we'll get a rename/rename(1to2) conflict because a~$UNIQUE # gets renamed to 'a' in D1 and to 'a2' in E4. But that's better than having @@ -1144,7 +1144,7 @@ test_expect_failure 'check symlink add/add' ' test_must_fail git merge -s recursive E^0 && git ls-files -s >out && - test_line_count = 2 out && + test_line_count = 3 out && git ls-files -u >out && test_line_count = 2 out && git ls-files -o >out && diff --git a/t/t6037-merge-ours-theirs.sh b/t/t6417-merge-ours-theirs.sh index 0aebc6c028..0aebc6c028 100755 --- a/t/t6037-merge-ours-theirs.sh +++ b/t/t6417-merge-ours-theirs.sh diff --git a/t/t6038-merge-text-auto.sh b/t/t6418-merge-text-auto.sh index 5e8d5fa50c..30983d18b1 100755 --- a/t/t6038-merge-text-auto.sh +++ b/t/t6418-merge-text-auto.sh @@ -158,7 +158,7 @@ test_expect_success 'Detect LF/CRLF conflict from addition of text=auto' ' compare_files expected file.fuzzy ' -test_expect_failure 'checkout -m after setting text=auto' ' +test_expect_success 'checkout -m after setting text=auto' ' cat <<-\EOF >expected && first line same line @@ -168,12 +168,12 @@ test_expect_failure 'checkout -m after setting text=auto' ' git rm -fr . && rm -f .gitattributes && git reset --hard initial && - git checkout a -- . && + git restore --source=a -- . && git checkout -m b && - compare_files expected file + git diff --no-index --ignore-cr-at-eol expected file ' -test_expect_failure 'checkout -m addition of text=auto' ' +test_expect_success 'checkout -m addition of text=auto' ' cat <<-\EOF >expected && first line same line @@ -183,23 +183,9 @@ test_expect_failure 'checkout -m addition of text=auto' ' git rm -fr . && rm -f .gitattributes file && git reset --hard initial && - git checkout b -- . && + git restore --source=b -- . && git checkout -m a && - compare_files expected file -' - -test_expect_failure 'cherry-pick patch from after text=auto was added' ' - append_cr <<-\EOF >expected && - first line - same line - EOF - - git config merge.renormalize true && - git rm -fr . && - git reset --hard b && - test_must_fail git cherry-pick a >err 2>&1 && - grep "[Nn]othing added" err && - compare_files expected file + git diff --no-index --ignore-cr-at-eol expected file ' test_expect_success 'Test delete/normalize conflict' ' @@ -211,7 +197,8 @@ test_expect_success 'Test delete/normalize conflict' ' git commit -m "remove file" && git checkout master && git reset --hard a^ && - git merge side + git merge side && + test_path_is_missing file ' test_done diff --git a/t/t6039-merge-ignorecase.sh b/t/t6419-merge-ignorecase.sh index 531850d834..531850d834 100755 --- a/t/t6039-merge-ignorecase.sh +++ b/t/t6419-merge-ignorecase.sh diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh index f163893ff9..3375eaf4e7 100755 --- a/t/t6042-merge-rename-corner-cases.sh +++ b/t/t6422-merge-rename-corner-cases.sh @@ -457,7 +457,7 @@ test_expect_success 'handle rename-with-content-merge vs. add' ' git checkout A^0 && test_must_fail git merge -s recursive B^0 >out && - test_i18ngrep "CONFLICT (rename/add)" out && + test_i18ngrep "CONFLICT (.*/add)" out && git ls-files -s >out && test_line_count = 2 out && @@ -503,7 +503,7 @@ test_expect_success 'handle rename-with-content-merge vs. add, merge other way' git checkout B^0 && test_must_fail git merge -s recursive A^0 >out && - test_i18ngrep "CONFLICT (rename/add)" out && + test_i18ngrep "CONFLICT (.*/add)" out && git ls-files -s >out && test_line_count = 2 out && @@ -583,7 +583,7 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' ' git checkout B^0 && test_must_fail git merge -s recursive C^0 >out && - test_i18ngrep "CONFLICT (rename/rename)" out && + test_i18ngrep "CONFLICT (\(.*\)/\1)" out && git ls-files -s >out && test_line_count = 2 out && @@ -886,12 +886,17 @@ test_expect_failure 'rad-check: rename/add/delete conflict' ' git checkout B^0 && test_must_fail git merge -s recursive A^0 >out 2>err && - # Not sure whether the output should contain just one - # "CONFLICT (rename/add/delete)" line, or if it should break - # it into a pair of "CONFLICT (rename/delete)" and - # "CONFLICT (rename/add)"; allow for either. - test_i18ngrep "CONFLICT (rename.*add)" out && - test_i18ngrep "CONFLICT (rename.*delete)" out && + # Instead of requiring the output to contain one combined line + # CONFLICT (rename/add/delete) + # or perhaps two lines: + # CONFLICT (rename/add): new file collides with rename target + # CONFLICT (rename/delete): rename source removed on other side + # and instead of requiring "rename/add" instead of "add/add", + # be flexible in the type of console output message(s) reported + # for this particular case; we will be more stringent about the + # contents of the index and working directory. + test_i18ngrep "CONFLICT (.*/add)" out && + test_i18ngrep "CONFLICT (rename.*/delete)" out && test_must_be_empty err && git ls-files -s >file_count && @@ -899,14 +904,14 @@ test_expect_failure 'rad-check: rename/add/delete conflict' ' git ls-files -u >file_count && test_line_count = 2 file_count && git ls-files -o >file_count && - test_line_count = 2 file_count && + test_line_count = 3 file_count && git rev-parse >actual \ :2:bar :3:bar && git rev-parse >expect \ B:bar A:bar && - test_cmp file_is_missing foo && + test_path_is_missing foo && # bar should have two-way merged contents of the different # versions of bar; check that content from both sides is # present. @@ -954,11 +959,17 @@ test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' ' git checkout A^0 && test_must_fail git merge -s recursive B^0 >out 2>err && - # Not sure whether the output should contain just one - # "CONFLICT (rename/rename/delete/delete)" line, or if it - # should break it into three: "CONFLICT (rename/rename)" and - # two "CONFLICT (rename/delete)" lines; allow for either. - test_i18ngrep "CONFLICT (rename/rename)" out && + # Instead of requiring the output to contain one combined line + # CONFLICT (rename/rename/delete/delete) + # or perhaps two lines: + # CONFLICT (rename/rename): ... + # CONFLICT (rename/delete): info about pair 1 + # CONFLICT (rename/delete): info about pair 2 + # and instead of requiring "rename/rename" instead of "add/add", + # be flexible in the type of console output message(s) reported + # for this particular case; we will be more stringent about the + # contents of the index and working directory. + test_i18ngrep "CONFLICT (\(.*\)/\1)" out && test_i18ngrep "CONFLICT (rename.*delete)" out && test_must_be_empty err && @@ -967,15 +978,15 @@ test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' ' git ls-files -u >file_count && test_line_count = 2 file_count && git ls-files -o >file_count && - test_line_count = 2 file_count && + test_line_count = 3 file_count && git rev-parse >actual \ :2:baz :3:baz && git rev-parse >expect \ O:foo O:bar && - test_cmp file_is_missing foo && - test_cmp file_is_missing bar && + test_path_is_missing foo && + test_path_is_missing bar && # baz should have two-way merged contents of the original # contents of foo and bar; check that content from both sides # is present. @@ -1042,25 +1053,25 @@ test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename test_must_be_empty err && git ls-files -s >file_count && - test_line_count = 6 file_count && + test_line_count = 9 file_count && git ls-files -u >file_count && - test_line_count = 6 file_count && + test_line_count = 9 file_count && git ls-files -o >file_count && test_line_count = 3 file_count && test_seq 10 20 >merged-one && test_seq 51 60 >merged-five && # Determine what the merge of three would give us. - test_seq 30 40 >three-side-A && + test_seq 31 39 >three-base && + test_seq 31 40 >three-side-A && test_seq 31 39 >three-side-B && - echo forty >three-side-B && - >empty && + echo forty >>three-side-B && test_must_fail git merge-file \ - -L "HEAD" \ + -L "HEAD:four" \ -L "" \ - -L "B^0" \ - three-side-A empty three-side-B && - sed -e "s/^\([<=>]\)/\1\1\1/" three-side-A >merged-three && + -L "B^0:two" \ + three-side-A three-base three-side-B && + sed -e "s/^\([<=>]\)/\1\1/" three-side-A >merged-three && # Verify the index is as expected git rev-parse >actual \ @@ -1075,6 +1086,7 @@ test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename git cat-file -p :2:two >expect && git cat-file -p :3:two >other && + >empty && test_must_fail git merge-file \ -L "HEAD" -L "" -L "B^0" \ expect empty other && diff --git a/t/t6043-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh index 83792c5ef1..f7ecbb886d 100755 --- a/t/t6043-merge-rename-directories.sh +++ b/t/t6423-merge-rename-directories.sh @@ -275,7 +275,7 @@ test_expect_success '1d: Directory renames cause a rename/rename(2to1) conflict' git checkout A^0 && test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && - test_i18ngrep "CONFLICT (rename/rename)" out && + test_i18ngrep "CONFLICT (\(.*\)/\1)" out && git ls-files -s >out && test_line_count = 8 out && @@ -1686,7 +1686,7 @@ test_expect_success '7b: rename/rename(2to1), but only due to transitive rename' git checkout A^0 && test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && - test_i18ngrep "CONFLICT (rename/rename)" out && + test_i18ngrep "CONFLICT (\(.*\)/\1)" out && git ls-files -s >out && test_line_count = 4 out && @@ -2260,24 +2260,23 @@ test_expect_success '8d: rename/delete...or not?' ' # Commit B: w/{b,c}, z/d # # Possible Resolutions: -# w/o dir-rename detection: z/d, CONFLICT(z/b -> y/b vs. w/b), -# CONFLICT(z/c -> y/c vs. w/c) -# Currently expected: y/d, CONFLICT(z/b -> y/b vs. w/b), -# CONFLICT(z/c -> y/c vs. w/c) -# Optimal: ?? +# if z not considered renamed: z/d, CONFLICT(z/b -> y/b vs. w/b), +# CONFLICT(z/c -> y/c vs. w/c) +# if z->y rename considered: y/d, CONFLICT(z/b -> y/b vs. w/b), +# CONFLICT(z/c -> y/c vs. w/c) +# Optimal: ?? # # Notes: In commit A, directory z got renamed to y. In commit B, directory z # did NOT get renamed; the directory is still present; instead it is # considered to have just renamed a subset of paths in directory z -# elsewhere. Therefore, the directory rename done in commit A to z/ -# applies to z/d and maps it to y/d. +# elsewhere. However, this is much like testcase 6b (where commit B +# moves all the original paths out of z/ but opted to keep d +# within z/). This makes it hard to judge where d should end up. # # It's possible that users would get confused about this, but what -# should we do instead? Silently leaving at z/d seems just as bad or -# maybe even worse. Perhaps we could print a big warning about z/d -# and how we're moving to y/d in this case, but when I started thinking -# about the ramifications of doing that, I didn't know how to rule out -# that opening other weird edge and corner cases so I just punted. +# should we do instead? It's not at all clear to me whether z/d or +# y/d or something else is a better resolution here, and other cases +# start getting really tricky, so I just picked one. test_setup_8e () { test_create_repo 8e && @@ -2844,6 +2843,14 @@ test_expect_success '9f: Renamed directory that only contained immediate subdirs # Commit A: priority/{alpha,bravo}/$more_files # Commit B: goal/{a,b}/$more_files, goal/c # Expected: priority/{alpha,bravo}/$more_files, priority/c +# We currently fail this test because the directory renames we detect are +# goal/a/ -> priority/alpha/ +# goal/b/ -> priority/bravo/ +# We do not detect +# goal/ -> priority/ +# because of no files found within goal/, and the fact that "a" != "alpha" +# and "b" != "bravo". But I'm not sure it's really a failure given that +# viewpoint... test_setup_9g () { test_create_repo 9g && @@ -2880,6 +2887,7 @@ test_setup_9g () { } test_expect_failure '9g: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' ' + test_setup_9g && ( cd 9g && @@ -3362,6 +3370,7 @@ test_setup_10e () { } test_expect_failure '10e: Does git complain about untracked file that is not really in the way?' ' + test_setup_10e && ( cd 10e && @@ -4403,7 +4412,7 @@ test_expect_success '13b(info): messages for transitive rename with conflicted c # Commit O: z/{b,c}, x/{d,e} # Commit A: y/{b,c,d}, x/e # Commit B: z/{b,c,d}, x/e -# Expected: y/{b,c,d}, with info or conflict messages for d ( +# Expected: y/{b,c,d}, x/e, with info or conflict messages for d # A: renamed x/d -> z/d; B: renamed z/ -> y/ AND renamed x/d to y/d # One could argue A had partial knowledge of what was done with # d and B had full knowledge, but that's a slippery slope as diff --git a/t/t6044-merge-unrelated-index-changes.sh b/t/t6424-merge-unrelated-index-changes.sh index 5e3779ebc9..5e3779ebc9 100755 --- a/t/t6044-merge-unrelated-index-changes.sh +++ b/t/t6424-merge-unrelated-index-changes.sh diff --git a/t/t6045-merge-rename-delete.sh b/t/t6425-merge-rename-delete.sh index 5d33577d2f..f79d021590 100755 --- a/t/t6045-merge-rename-delete.sh +++ b/t/t6425-merge-rename-delete.sh @@ -17,7 +17,8 @@ test_expect_success 'rename/delete' ' git commit -m "delete" && test_must_fail git merge --strategy=recursive rename >output && - test_i18ngrep "CONFLICT (rename/delete): A deleted in HEAD and renamed to B in rename. Version rename of B left in tree." output + test_i18ngrep "CONFLICT (rename/delete): A.* renamed .*to B.* in rename" output && + test_i18ngrep "CONFLICT (rename/delete): A.*deleted in HEAD." output ' test_done diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh index 1ddc9e6626..699813671c 100755 --- a/t/t6046-merge-skip-unneeded-updates.sh +++ b/t/t6426-merge-skip-unneeded-updates.sh @@ -374,7 +374,7 @@ test_expect_success '2c: Modify b & add c VS rename b->c' ' export GIT_MERGE_VERBOSITY && test_must_fail git merge -s recursive B^0 >out 2>err && - test_i18ngrep "CONFLICT (rename/add): Rename b->c" out && + test_i18ngrep "CONFLICT (.*/add):" out && test_must_be_empty err && # Make sure c WAS updated @@ -661,7 +661,7 @@ test_setup_4a () { } # NOTE: For as long as we continue using unpack_trees() without index_only -# set to true, it will error out on a case like this claiming the the locally +# set to true, it will error out on a case like this claiming that the locally # modified file would be overwritten by the merge. Getting this testcase # correct requires doing the merge in-memory first, then realizing that no # updates to the file are necessary, and thus that we can just leave the path diff --git a/t/t6047-diff3-conflict-markers.sh b/t/t6427-diff3-conflict-markers.sh index f4655bb358..f4655bb358 100755 --- a/t/t6047-diff3-conflict-markers.sh +++ b/t/t6427-diff3-conflict-markers.sh diff --git a/t/t3030-merge-recursive.sh b/t/t6430-merge-recursive.sh index d48d211a95..d48d211a95 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t6430-merge-recursive.sh diff --git a/t/t3031-merge-criscross.sh b/t/t6431-merge-criscross.sh index 3824756a02..3824756a02 100755 --- a/t/t3031-merge-criscross.sh +++ b/t/t6431-merge-criscross.sh diff --git a/t/t3032-merge-recursive-space-options.sh b/t/t6432-merge-recursive-space-options.sh index b56180ee4a..b56180ee4a 100755 --- a/t/t3032-merge-recursive-space-options.sh +++ b/t/t6432-merge-recursive-space-options.sh diff --git a/t/t3033-merge-toplevel.sh b/t/t6433-merge-toplevel.sh index e29c284b9b..e29c284b9b 100755 --- a/t/t3033-merge-toplevel.sh +++ b/t/t6433-merge-toplevel.sh diff --git a/t/t3034-merge-recursive-rename-options.sh b/t/t6434-merge-recursive-rename-options.sh index 3d9fae68c4..3d9fae68c4 100755 --- a/t/t3034-merge-recursive-rename-options.sh +++ b/t/t6434-merge-recursive-rename-options.sh diff --git a/t/t3035-merge-sparse.sh b/t/t6435-merge-sparse.sh index 74562e1235..74562e1235 100755 --- a/t/t3035-merge-sparse.sh +++ b/t/t6435-merge-sparse.sh diff --git a/t/t7607-merge-overwrite.sh b/t/t6436-merge-overwrite.sh index dd8ab7ede1..dd8ab7ede1 100755 --- a/t/t7607-merge-overwrite.sh +++ b/t/t6436-merge-overwrite.sh diff --git a/t/t7405-submodule-merge.sh b/t/t6437-submodule-merge.sh index aa33978ed2..6a1e5f8232 100755 --- a/t/t7405-submodule-merge.sh +++ b/t/t6437-submodule-merge.sh @@ -195,7 +195,7 @@ test_expect_success 'git submodule status should display the merge conflict prop url = $TRASH_DIRECTORY/sub EOF cat >expect <<EOF && -U0000000000000000000000000000000000000000 sub +U$ZERO_OID sub EOF git submodule status > actual && test_cmp expect actual && @@ -214,7 +214,7 @@ test_expect_success 'git submodule status should display the merge conflict prop url = $TRASH_DIRECTORY/sub EOF cat >expect <<EOF && -U0000000000000000000000000000000000000000 sub +U$ZERO_OID sub EOF git submodule status > actual && test_cmp expect actual && diff --git a/t/t7613-merge-submodule.sh b/t/t6438-submodule-directory-file-conflicts.sh index 04bf4be7d7..04bf4be7d7 100755 --- a/t/t7613-merge-submodule.sh +++ b/t/t6438-submodule-directory-file-conflicts.sh diff --git a/t/t7609-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh index 5c8894d94f..5c8894d94f 100755 --- a/t/t7609-merge-co-error-msgs.sh +++ b/t/t6439-merge-co-error-msgs.sh diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 0a69a67117..4a3b8f48ac 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -10,7 +10,24 @@ test_expect_success 'setup' ' # do not let the amount of physical memory affects gc # behavior, make sure we always pack everything to one pack by # default - git config gc.bigPackThreshold 2g + git config gc.bigPackThreshold 2g && + + # These are simply values which, when hashed as a blob with a newline, + # produce a hash where the first byte is 0x17 in their respective + # algorithms. + test_oid_cache <<-EOF + obj1 sha1:263 + obj1 sha256:34 + + obj2 sha1:410 + obj2 sha256:174 + + obj3 sha1:523 + obj3 sha256:313 + + obj4 sha1:790 + obj4 sha256:481 + EOF ' test_expect_success 'gc empty repository' ' @@ -85,13 +102,13 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre # We need to create two object whose sha1s start with 17 # since this is what git gc counts. As it happens, these # two blobs will do so. - test_commit 263 && - test_commit 410 && + test_commit "$(test_oid obj1)" && + test_commit "$(test_oid obj2)" && # Our first gc will create a pack; our second will create a second pack git gc --auto && ls .git/objects/pack | sort >existing_packs && - test_commit 523 && - test_commit 790 && + test_commit "$(test_oid obj3)" && + test_commit "$(test_oid obj4)" && git gc --auto 2>err && test_i18ngrep ! "^warning:" err && diff --git a/t/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh index f30b4849b6..8a3bb4105b 100755 --- a/t/t6501-freshen-objects.sh +++ b/t/t6501-freshen-objects.sh @@ -128,9 +128,9 @@ for repack in '' true; do done test_expect_success 'do not complain about existing broken links (commit)' ' - cat >broken-commit <<-\EOF && - tree 0000000000000000000000000000000000000001 - parent 0000000000000000000000000000000000000002 + cat >broken-commit <<-EOF && + tree $(test_oid 001) + parent $(test_oid 002) author whatever <whatever@example.com> 1234 -0000 committer whatever <whatever@example.com> 1234 -0000 @@ -143,8 +143,8 @@ test_expect_success 'do not complain about existing broken links (commit)' ' ' test_expect_success 'do not complain about existing broken links (tree)' ' - cat >broken-tree <<-\EOF && - 100644 blob 0000000000000000000000000000000000000003 foo + cat >broken-tree <<-EOF && + 100644 blob $(test_oid 003) foo EOF tree=$(git mktree --missing <broken-tree) && git gc -q 2>stderr && @@ -153,8 +153,8 @@ test_expect_success 'do not complain about existing broken links (tree)' ' ' test_expect_success 'do not complain about existing broken links (tag)' ' - cat >broken-tag <<-\EOF && - object 0000000000000000000000000000000000000004 + cat >broken-tag <<-EOF && + object $(test_oid 004) type commit tag broken tagger whatever <whatever@example.com> 1234 -0000 diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 36b50d0b4c..63d5f41a12 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -177,7 +177,7 @@ test_expect_success "Sergey Vlasov's test case" ' date >ab.c && date >ab/d && git add ab.c ab && - git commit -m 'initial' && + git commit -m "initial" && git mv ab a ' @@ -248,6 +248,23 @@ test_expect_success 'git mv should not change sha1 of moved cache entry' ' rm -f dirty dirty2 +# NB: This test is about the error message +# as well as the failure. +test_expect_success 'git mv error on conflicted file' ' + rm -fr .git && + git init && + >conflict && + test_when_finished "rm -f conflict" && + cfhash=$(git hash-object -w conflict) && + q_to_tab <<-EOF | git update-index --index-info && + 0 $cfhash 0Qconflict + 100644 $cfhash 1Qconflict + EOF + + test_must_fail git mv conflict newname 2>actual && + test_i18ngrep "conflicted" actual +' + test_expect_success 'git mv should overwrite symlink to a file' ' rm -fr .git && diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index e23de7d0b5..36477cb1f4 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -463,10 +463,11 @@ test_expect_success 'rewrite submodule with another content' ' ' test_expect_success 'replace submodule revision' ' + invalid=$(test_oid numeric) && git reset --hard original && git filter-branch -f --tree-filter \ "if git ls-files --error-unmatch -- submod > /dev/null 2>&1 - then git update-index --cacheinfo 160000 0123456789012345678901234567890123456789 submod + then git update-index --cacheinfo 160000 $invalid submod fi" HEAD && test $orig_head != $(git show-ref --hash --head HEAD) ' diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 74b637deb2..05f411c821 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -2015,8 +2015,8 @@ test_expect_success '--merged can be used in non-list mode' ' test_cmp expect actual ' -test_expect_success '--merged is incompatible with --no-merged' ' - test_must_fail git tag --merged HEAD --no-merged HEAD +test_expect_success '--merged is compatible with --no-merged' ' + git tag --merged HEAD --no-merged HEAD ' test_expect_success '--merged shows merged tags' ' diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index e4cf5484f9..2f9bea9793 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -30,6 +30,31 @@ test_expect_success 'same with gitignore starting with BOM' ' test_cmp expected actual ' +test_expect_success 'status untracked files --ignored with pathspec (no match)' ' + git status --porcelain --ignored -- untracked/i >actual && + test_must_be_empty actual && + git status --porcelain --ignored -- untracked/u >actual && + test_must_be_empty actual +' + +test_expect_success 'status untracked files --ignored with pathspec (literal match)' ' + git status --porcelain --ignored -- untracked/ignored >actual && + echo "!! untracked/ignored" >expected && + test_cmp expected actual && + git status --porcelain --ignored -- untracked/uncommitted >actual && + echo "?? untracked/uncommitted" >expected && + test_cmp expected actual +' + +test_expect_success 'status untracked files --ignored with pathspec (glob match)' ' + git status --porcelain --ignored -- untracked/i\* >actual && + echo "!! untracked/ignored" >expected && + test_cmp expected actual && + git status --porcelain --ignored -- untracked/u\* >actual && + echo "?? untracked/uncommitted" >expected && + test_cmp expected actual +' + cat >expected <<\EOF ?? .gitignore ?? actual diff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh index 428cff9cf3..a682a3d826 100755 --- a/t/t7063-status-untracked-cache.sh +++ b/t/t7063-status-untracked-cache.sh @@ -75,14 +75,24 @@ test_expect_success 'setup' ' touch one two three done/one dtwo/two dthree/three && git add one two done/one && : >.git/info/exclude && - git update-index --untracked-cache + git update-index --untracked-cache && + test_oid_cache <<-EOF + root sha1:e6fcc8f2ee31bae321d66afd183fcb7237afae6e + root sha256:b90c672088c015b9c83876e919da311bad4cd39639fb139f988af6a11493b974 + + exclude sha1:13263c0978fb9fad16b2d580fb800b6d811c3ff0 + exclude sha256:fe4aaa1bbbbce4cb8f73426748a14c5ad6026b26f90505a0bf2494b165a5b76c + + done sha1:1946f0437f90c5005533cbe1736a6451ca301714 + done sha256:7f079501d79f665b3acc50f5e0e9e94509084d5032ac20113a37dd5029b757cc + EOF ' test_expect_success 'untracked cache is empty' ' test-tool dump-untracked-cache >../actual && cat >../expect-empty <<EOF && -info/exclude 0000000000000000000000000000000000000000 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $ZERO_OID +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 EOF @@ -100,17 +110,17 @@ EOF cat >../dump.expect <<EOF && info/exclude $EMPTY_BLOB -core.excludesfile 0000000000000000000000000000000000000000 +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ 0000000000000000000000000000000000000000 recurse valid +/ $ZERO_OID recurse valid dthree/ dtwo/ three -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid three -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF @@ -190,18 +200,18 @@ test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && info/exclude $EMPTY_BLOB -core.excludesfile 0000000000000000000000000000000000000000 +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ 0000000000000000000000000000000000000000 recurse valid +/ $ZERO_OID recurse valid dthree/ dtwo/ four three -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid three -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -239,18 +249,18 @@ test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && info/exclude $EMPTY_BLOB -core.excludesfile 0000000000000000000000000000000000000000 +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dthree/ dtwo/ three -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid three -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -284,16 +294,16 @@ EOF test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -303,14 +313,14 @@ test_expect_success 'move two from tracked to untracked' ' git rm --cached two && test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/ $(test_oid root) recurse +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -342,17 +352,17 @@ EOF test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ two -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -362,14 +372,14 @@ test_expect_success 'move two from untracked to tracked' ' git add two && test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/ $(test_oid root) recurse +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -401,16 +411,16 @@ EOF test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -447,16 +457,16 @@ EOF test_expect_success 'untracked cache correct after commit' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -508,17 +518,17 @@ EOF test_expect_success 'untracked cache correct after status' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid +/done/ $(test_oid done) recurse valid five -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -580,22 +590,22 @@ EOF test_expect_success 'verify untracked cache dump (sparse/subdirs)' ' test-tool dump-untracked-cache >../actual && cat >../expect-from-test-dump <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid +/done/ $(test_oid done) recurse valid five sub/ -/done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/sub/ $ZERO_OID recurse check_only valid sub/ -/done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/sub/sub/ $ZERO_OID recurse check_only valid file -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect-from-test-dump ../actual @@ -806,8 +816,8 @@ test_expect_success '"status" after file replacement should be clean with UC=tru test-tool dump-untracked-cache >../actual && grep -F "recurse valid" ../actual >../actual.grep && cat >../expect.grep <<EOF && -/ 0000000000000000000000000000000000000000 recurse valid -/two/ 0000000000000000000000000000000000000000 recurse valid +/ $ZERO_OID recurse valid +/two/ $ZERO_OID recurse valid EOF status_is_clean && test_cmp ../expect.grep ../actual.grep diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 97be0d968d..22161b3b2d 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -37,17 +37,23 @@ test_expect_success 'creating initial files and commits' ' echo "2nd line 1st file" >>first && git commit -a -m "modify 1st file" && + head5p2=$(git rev-parse --verify HEAD) && + head5p2f=$(git rev-parse --short HEAD:first) && git rm first && git mv second secondfile && git commit -a -m "remove 1st and rename 2nd" && + head5p1=$(git rev-parse --verify HEAD) && + head5p1s=$(git rev-parse --short HEAD:secondfile) && echo "1st line 2nd file" >secondfile && echo "2nd line 2nd file" >>secondfile && # "git commit -m" would break MinGW, as Windows refuse to pass # $test_encoding encoded parameter to git. commit_msg $test_encoding | git -c "i18n.commitEncoding=$test_encoding" commit -a -F - && - head5=$(git rev-parse --verify HEAD) + head5=$(git rev-parse --verify HEAD) && + head5s=$(git rev-parse --short HEAD:secondfile) && + head5sl=$(git rev-parse HEAD:secondfile) ' # git log --pretty=oneline # to see those SHA1 involved @@ -94,7 +100,7 @@ test_expect_success 'giving a non existing revision should fail' ' test_expect_success 'reset --soft with unmerged index should fail' ' touch .git/MERGE_HEAD && - echo "100644 44c5b5884550c17758737edcced463447b91d42b 1 un" | + echo "100644 $head5sl 1 un" | git update-index --index-info && test_must_fail git reset --soft HEAD && rm .git/MERGE_HEAD && @@ -192,7 +198,7 @@ test_expect_success \ >.diff_expect cat >.cached_expect <<EOF diff --git a/secondfile b/secondfile -index 1bbba79..44c5b58 100644 +index $head5p1s..$head5s 100644 --- a/secondfile +++ b/secondfile @@ -1 +1,2 @@ @@ -207,7 +213,7 @@ secondfile: EOF test_expect_success '--soft reset only should show changes in diff --cached' ' git reset --soft HEAD^ && - check_changes d1a4bc3abce4829628ae2dcb0d60ef3d1a78b1c4 && + check_changes $head5p1 && test "$(git rev-parse ORIG_HEAD)" = \ $head5 ' @@ -242,7 +248,7 @@ EOF test_expect_success \ '--hard reset should change the files and undo commits permanently' ' git reset --hard HEAD~2 && - check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && + check_changes $head5p2 && test "$(git rev-parse ORIG_HEAD)" = \ $head4 ' @@ -251,7 +257,7 @@ test_expect_success \ cat >.cached_expect <<EOF diff --git a/first b/first deleted file mode 100644 -index 8206c22..0000000 +index $head5p2f..0000000 --- a/first +++ /dev/null @@ -1,2 +0,0 @@ @@ -259,14 +265,14 @@ index 8206c22..0000000 -2nd line 1st file diff --git a/second b/second deleted file mode 100644 -index 1bbba79..0000000 +index $head5p1s..0000000 --- a/second +++ /dev/null @@ -1 +0,0 @@ -2nd file diff --git a/secondfile b/secondfile new file mode 100644 -index 0000000..44c5b58 +index 0000000..$head5s --- /dev/null +++ b/secondfile @@ -0,0 +1,2 @@ @@ -286,13 +292,13 @@ test_expect_success \ echo "1st line 2nd file" >secondfile && echo "2nd line 2nd file" >>secondfile && git add secondfile && - check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e + check_changes $head5p2 ' cat >.diff_expect <<EOF diff --git a/first b/first deleted file mode 100644 -index 8206c22..0000000 +index $head5p2f..0000000 --- a/first +++ /dev/null @@ -1,2 +0,0 @@ @@ -300,7 +306,7 @@ index 8206c22..0000000 -2nd line 1st file diff --git a/second b/second deleted file mode 100644 -index 1bbba79..0000000 +index $head5p1s..0000000 --- a/second +++ /dev/null @@ -1 +0,0 @@ @@ -314,9 +320,8 @@ secondfile: EOF test_expect_success '--mixed reset to HEAD should unadd the files' ' git reset && - check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && - test "$(git rev-parse ORIG_HEAD)" = \ - ddaefe00f1da16864591c61fdc7adb5d7cd6b74e + check_changes $head5p2 && + test "$(git rev-parse ORIG_HEAD)" = $head5p2 ' >.diff_expect @@ -328,7 +333,7 @@ secondfile: EOF test_expect_success 'redoing the last two commits should succeed' ' git add secondfile && - git reset --hard ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && + git reset --hard $head5p2 && git rm first && git mv second secondfile && @@ -389,47 +394,55 @@ test_expect_success \ check_changes $head5 ' -cat > expect << EOF -diff --git a/file1 b/file1 -index d00491f..7ed6ff8 100644 ---- a/file1 -+++ b/file1 -@@ -1 +1 @@ --1 -+5 -diff --git a/file2 b/file2 -deleted file mode 100644 -index 0cfbf08..0000000 ---- a/file2 -+++ /dev/null -@@ -1 +0,0 @@ --2 -EOF -cat > cached_expect << EOF -diff --git a/file4 b/file4 -new file mode 100644 -index 0000000..b8626c4 ---- /dev/null -+++ b/file4 -@@ -0,0 +1 @@ -+4 -EOF test_expect_success 'test --mixed <paths>' ' echo 1 > file1 && echo 2 > file2 && git add file1 file2 && test_tick && git commit -m files && + before1=$(git rev-parse --short HEAD:file1) && + before2=$(git rev-parse --short HEAD:file2) && git rm file2 && echo 3 > file3 && echo 4 > file4 && echo 5 > file1 && + after1=$(git rev-parse --short $(git hash-object file1)) && + after4=$(git rev-parse --short $(git hash-object file4)) && git add file1 file3 file4 && git reset HEAD -- file1 file2 file3 && test_must_fail git diff --quiet && git diff > output && + + cat > expect <<-EOF && + diff --git a/file1 b/file1 + index $before1..$after1 100644 + --- a/file1 + +++ b/file1 + @@ -1 +1 @@ + -1 + +5 + diff --git a/file2 b/file2 + deleted file mode 100644 + index $before2..0000000 + --- a/file2 + +++ /dev/null + @@ -1 +0,0 @@ + -2 + EOF + test_cmp expect output && git diff --cached > output && + + cat > cached_expect <<-EOF && + diff --git a/file4 b/file4 + new file mode 100644 + index 0000000..$after4 + --- /dev/null + +++ b/file4 + @@ -0,0 +1 @@ + +4 + EOF + test_cmp cached_expect output ' diff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh index cad3a9de9e..15ccb14f7e 100755 --- a/t/t7107-reset-pathspec-file.sh +++ b/t/t7107-reset-pathspec-file.sh @@ -22,7 +22,12 @@ restore_checkpoint () { verify_expect () { git status --porcelain -- fileA.t fileB.t fileC.t fileD.t >actual && - test_cmp expect actual + if test "x$1" = 'x!' + then + ! test_cmp expect actual + else + test_cmp expect actual + fi } test_expect_success '--pathspec-from-file from stdin' ' @@ -131,7 +136,7 @@ test_expect_success 'quotes not compatible with --pathspec-file-nul' ' cat >expect <<-\EOF && D fileA.t EOF - test_must_fail verify_expect + verify_expect ! ' test_expect_success 'only touches what was listed' ' diff --git a/t/t7201-co.sh b/t/t7201-co.sh index b696bae5f5..4d62b9b00f 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -230,9 +230,10 @@ test_expect_success 'switch to another branch while carrying a deletion' ' test_expect_success 'checkout to detach HEAD (with advice declined)' ' git config advice.detachedHead false && + rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && git checkout renamer^ 2>messages && - test_i18ngrep "HEAD is now at 7329388" messages && + test_i18ngrep "HEAD is now at $rev" messages && test_line_count = 1 messages && H=$(git rev-parse --verify HEAD) && M=$(git show-ref -s --verify refs/heads/master) && @@ -248,9 +249,10 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' ' test_expect_success 'checkout to detach HEAD' ' git config advice.detachedHead true && + rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && GIT_TEST_GETTEXT_POISON=false git checkout renamer^ 2>messages && - grep "HEAD is now at 7329388" messages && + grep "HEAD is now at $rev" messages && test_line_count -gt 1 messages && H=$(git rev-parse --verify HEAD) && M=$(git show-ref -s --verify refs/heads/master) && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 956e17abb3..fec7e0299d 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1231,7 +1231,7 @@ test_expect_success 'submodule helper list is not confused by common prefixes' ' git submodule add /dir1/b dir1/b && git submodule add /dir2/b dir2/b && git commit -m "first submodule commit" && - git submodule--helper list dir1/b |cut -c51- >actual && + git submodule--helper list dir1/b | cut -f 2 >actual && echo "dir1/b" >expect && test_cmp expect actual ' @@ -1260,7 +1260,7 @@ test_expect_success 'submodule update --init with a specification' ' pwd=$(pwd) && git clone file://"$pwd"/multisuper multisuper_clone && git -C multisuper_clone submodule update --init . ":(exclude)sub0" && - git -C multisuper_clone submodule status |cut -c 1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1271,7 +1271,7 @@ test_expect_success 'submodule update --init with submodule.active set' ' git -C multisuper_clone config submodule.active "." && git -C multisuper_clone config --add submodule.active ":(exclude)sub0" && git -C multisuper_clone submodule update --init && - git -C multisuper_clone submodule status |cut -c 1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1290,7 +1290,7 @@ test_expect_success 'submodule update and setting submodule.<name>.active' ' -sub3 EOF git -C multisuper_clone submodule update && - git -C multisuper_clone submodule status |cut -c 1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1307,12 +1307,12 @@ test_expect_success 'clone active submodule without submodule url set' ' git submodule update && git submodule status >actual_raw && - cut -c 1,43- actual_raw >actual && + cut -d" " -f3- actual_raw >actual && cat >expect <<-\EOF && - sub0 (test2) - sub1 (test2) - sub2 (test2) - sub3 (test2) + sub0 (test2) + sub1 (test2) + sub2 (test2) + sub3 (test2) EOF test_cmp expect actual ) @@ -1328,7 +1328,7 @@ test_expect_success 'clone --recurse-submodules with a pathspec works' ' EOF git clone --recurse-submodules="sub0" multisuper multisuper_clone && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expected actual ' @@ -1345,7 +1345,7 @@ test_expect_success 'clone with multiple --recurse-submodules options' ' --recurse-submodules=":(exclude)sub0" \ --recurse-submodules=":(exclude)sub2" \ multisuper multisuper_clone && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1373,7 +1373,7 @@ test_expect_success 'clone and subsequent updates correctly auto-initialize subm --recurse-submodules=":(exclude)sub4" \ multisuper multisuper_clone && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual && git -C multisuper submodule add ../sub1 sub4 && @@ -1382,7 +1382,7 @@ test_expect_success 'clone and subsequent updates correctly auto-initialize subm # obtain the new superproject git -C multisuper_clone pull && git -C multisuper_clone submodule update --init && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect2 actual ' diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 9bc841d085..7608814708 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -5,9 +5,18 @@ test_description='Summary support for submodules -This test tries to verify the sanity of summary subcommand of git submodule. +This test script tries to verify the sanity of summary subcommand of git submodule. ' +# NOTE: This test script uses 'git add' instead of 'git submodule add' to add +# submodules to the superproject. Some submodule subcommands such as init and +# deinit might not work as expected in this script. t7421 does not have this +# caveat. +# +# NEEDSWORK: This test script is old fashioned and may need a big cleanup due to +# various reasons, one of them being that there are lots of commands taking place +# outside of 'test_expect_success' block, which is no longer in good-style. + . ./test-lib.sh add_file () { @@ -16,12 +25,12 @@ add_file () { owd=$(pwd) cd "$sm" for name; do - echo "$name" > "$name" && + echo "$name" >"$name" && git add "$name" && test_tick && git commit -m "Add $name" done >/dev/null - git rev-parse --verify HEAD | cut -c1-7 + git rev-parse --short HEAD cd "$owd" } commit_file () { @@ -38,10 +47,10 @@ test_expect_success 'added submodule' " git add sm1 && git submodule summary >actual && cat >expected <<-EOF && -* sm1 0000000...$head1 (2): - > Add foo2 + * sm1 0000000...$head1 (2): + > Add foo2 -EOF + EOF test_cmp expected actual " @@ -52,10 +61,10 @@ test_expect_success 'added submodule (subdirectory)' " git submodule summary >../actual ) && cat >expected <<-EOF && -* ../sm1 0000000...$head1 (2): - > Add foo2 + * ../sm1 0000000...$head1 (2): + > Add foo2 -EOF + EOF test_cmp expected actual " @@ -73,10 +82,10 @@ test_expect_success 'added submodule (subdirectory with explicit path)' " git submodule summary ../sm1 >../actual ) && cat >expected <<-EOF && -* ../sm1 0000000...$head1 (2): - > Add foo2 + * ../sm1 0000000...$head1 (2): + > Add foo2 -EOF + EOF test_cmp expected actual " @@ -86,20 +95,20 @@ head2=$(add_file sm1 foo3) test_expect_success 'modified submodule(forward)' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head1...$head2 (1): - > Add foo3 + * sm1 $head1...$head2 (1): + > Add foo3 -EOF + EOF test_cmp expected actual " test_expect_success 'modified submodule(forward), --files' " git submodule summary --files >actual && cat >expected <<-EOF && -* sm1 $head1...$head2 (1): - > Add foo3 + * sm1 $head1...$head2 (1): + > Add foo3 -EOF + EOF test_cmp expected actual " @@ -110,10 +119,10 @@ test_expect_success 'no ignore=all setting has any effect' " git config diff.ignoreSubmodules all && git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head1...$head2 (1): - > Add foo3 + * sm1 $head1...$head2 (1): + > Add foo3 -EOF + EOF test_cmp expected actual && git config --unset diff.ignoreSubmodules && git config --remove-section submodule.sm1 && @@ -125,17 +134,17 @@ commit_file sm1 && head3=$( cd sm1 && git reset --hard HEAD~2 >/dev/null && - git rev-parse --verify HEAD | cut -c1-7 + git rev-parse --short HEAD ) test_expect_success 'modified submodule(backward)' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head2...$head3 (2): - < Add foo3 - < Add foo2 + * sm1 $head2...$head3 (2): + < Add foo3 + < Add foo2 -EOF + EOF test_cmp expected actual " @@ -144,25 +153,25 @@ head4_full=$(GIT_DIR=sm1/.git git rev-parse --verify HEAD) test_expect_success 'modified submodule(backward and forward)' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head2...$head4 (4): - > Add foo5 - > Add foo4 - < Add foo3 - < Add foo2 + * sm1 $head2...$head4 (4): + > Add foo5 + > Add foo4 + < Add foo3 + < Add foo2 -EOF + EOF test_cmp expected actual " test_expect_success '--summary-limit' " git submodule summary -n 3 >actual && cat >expected <<-EOF && -* sm1 $head2...$head4 (4): - > Add foo5 - > Add foo4 - < Add foo3 + * sm1 $head2...$head4 (4): + > Add foo5 + > Add foo4 + < Add foo3 -EOF + EOF test_cmp expected actual " @@ -177,21 +186,21 @@ mv sm1-bak sm1 test_expect_success 'typechanged submodule(submodule->blob), --cached' " git submodule summary --cached >actual && cat >expected <<-EOF && -* sm1 $head4(submodule)->$head5(blob) (3): - < Add foo5 + * sm1 $head4(submodule)->$head5(blob) (3): + < Add foo5 -EOF - test_i18ncmp actual expected + EOF + test_i18ncmp expected actual " test_expect_success 'typechanged submodule(submodule->blob), --files' " git submodule summary --files >actual && cat >expected <<-EOF && -* sm1 $head5(blob)->$head4(submodule) (3): - > Add foo5 + * sm1 $head5(blob)->$head4(submodule) (3): + > Add foo5 -EOF - test_i18ncmp actual expected + EOF + test_i18ncmp expected actual " rm -rf sm1 && @@ -199,10 +208,10 @@ git checkout-index sm1 test_expect_success 'typechanged submodule(submodule->blob)' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head4(submodule)->$head5(blob): + * sm1 $head4(submodule)->$head5(blob): -EOF - test_i18ncmp actual expected + EOF + test_i18ncmp expected actual " rm -f sm1 && @@ -211,21 +220,21 @@ head6=$(add_file sm1 foo6 foo7) test_expect_success 'nonexistent commit' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head4...$head6: - Warn: sm1 doesn't contain commit $head4_full + * sm1 $head4...$head6: + Warn: sm1 doesn't contain commit $head4_full -EOF - test_i18ncmp actual expected + EOF + test_i18ncmp expected actual " commit_file test_expect_success 'typechanged submodule(blob->submodule)' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head5(blob)->$head6(submodule) (2): - > Add foo7 + * sm1 $head5(blob)->$head6(submodule) (2): + > Add foo7 -EOF + EOF test_i18ncmp expected actual " @@ -234,9 +243,9 @@ rm -rf sm1 test_expect_success 'deleted submodule' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head6...0000000: + * sm1 $head6...0000000: -EOF + EOF test_cmp expected actual " @@ -249,22 +258,22 @@ test_expect_success 'create second submodule' ' test_expect_success 'multiple submodules' " git submodule summary >actual && cat >expected <<-EOF && -* sm1 $head6...0000000: + * sm1 $head6...0000000: -* sm2 0000000...$head7 (2): - > Add foo9 + * sm2 0000000...$head7 (2): + > Add foo9 -EOF + EOF test_cmp expected actual " test_expect_success 'path filter' " git submodule summary sm2 >actual && cat >expected <<-EOF && -* sm2 0000000...$head7 (2): - > Add foo9 + * sm2 0000000...$head7 (2): + > Add foo9 -EOF + EOF test_cmp expected actual " @@ -272,24 +281,24 @@ commit_file sm2 test_expect_success 'given commit' " git submodule summary HEAD^ >actual && cat >expected <<-EOF && -* sm1 $head6...0000000: + * sm1 $head6...0000000: -* sm2 0000000...$head7 (2): - > Add foo9 + * sm2 0000000...$head7 (2): + > Add foo9 -EOF + EOF test_cmp expected actual " test_expect_success '--for-status' " git submodule summary --for-status HEAD^ >actual && - test_i18ncmp actual - <<EOF -* sm1 $head6...0000000: + test_i18ncmp - actual <<-EOF + * sm1 $head6...0000000: -* sm2 0000000...$head7 (2): - > Add foo9 + * sm2 0000000...$head7 (2): + > Add foo9 -EOF + EOF " test_expect_success 'fail when using --files together with --cached' " diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh new file mode 100755 index 0000000000..b070f13714 --- /dev/null +++ b/t/t7421-submodule-summary-add.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Copyright (C) 2020 Shourya Shukla +# + +test_description='Summary support for submodules, adding them using git submodule add + +This test script tries to verify the sanity of summary subcommand of git submodule +while making sure to add submodules using `git submodule add` instead of +`git add` as done in t7401. +' + +. ./test-lib.sh + +test_expect_success 'summary test environment setup' ' + git init sm && + test_commit -C sm "add file" file file-content file-tag && + + git submodule add ./sm my-subm && + test_tick && + git commit -m "add submodule" +' + +test_expect_success 'submodule summary output for initialized submodule' ' + test_commit -C sm "add file2" file2 file2-content file2-tag && + git submodule update --remote && + test_tick && + git commit -m "update submodule" my-subm && + git submodule summary HEAD^ >actual && + rev1=$(git -C sm rev-parse --short HEAD^) && + rev2=$(git -C sm rev-parse --short HEAD) && + cat >expected <<-EOF && + * my-subm ${rev1}...${rev2} (1): + > add file2 + + EOF + test_cmp expected actual +' + +test_expect_success 'submodule summary output for deinitialized submodule' ' + git submodule deinit my-subm && + git submodule summary HEAD^ >actual && + test_must_be_empty actual && + git submodule update --init my-subm && + git submodule summary HEAD^ >actual && + rev1=$(git -C sm rev-parse --short HEAD^) && + rev2=$(git -C sm rev-parse --short HEAD) && + cat >expected <<-EOF && + * my-subm ${rev1}...${rev2} (1): + > add file2 + + EOF + test_cmp expected actual +' + +test_expect_success 'submodule summary output for submodules with changed paths' ' + git mv my-subm subm && + git commit -m "change submodule path" && + rev=$(git -C sm rev-parse --short HEAD^) && + git submodule summary HEAD^^ -- my-subm >actual 2>err && + test_must_be_empty err && + cat >expected <<-EOF && + * my-subm ${rev}...0000000: + + EOF + test_cmp expected actual +' + +test_done diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index 08629a6e70..3fcb44767f 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -22,6 +22,10 @@ sanitize_output () { mv output2 output } +sanitize_diff () { + sed -e "/^index [0-9a-f,]*\.\.[0-9a-f]*/d" "$1" +} + test_expect_success 'setup' ' test_create_repo_with_commit sub && @@ -269,7 +273,6 @@ short_sha1_merge_sub1=$(cd sub1 && git rev-parse --short HEAD) short_sha1_merge_sub2=$(cd sub2 && git rev-parse --short HEAD) cat >diff_expect <<\EOF diff --cc .gitmodules -index badaa4c,44f999a..0000000 --- a/.gitmodules +++ b/.gitmodules @@@ -1,3 -1,3 +1,9 @@@ @@ -286,7 +289,6 @@ EOF cat >diff_submodule_expect <<\EOF diff --cc .gitmodules -index badaa4c,44f999a..0000000 --- a/.gitmodules +++ b/.gitmodules @@@ -1,3 -1,3 +1,9 @@@ @@ -306,7 +308,8 @@ test_expect_success 'diff with merge conflict in .gitmodules' ' cd super && git diff >../diff_actual 2>&1 ) && - test_cmp diff_expect diff_actual + sanitize_diff diff_actual >diff_sanitized && + test_cmp diff_expect diff_sanitized ' test_expect_success 'diff --submodule with merge conflict in .gitmodules' ' @@ -314,7 +317,8 @@ test_expect_success 'diff --submodule with merge conflict in .gitmodules' ' cd super && git diff --submodule >../diff_submodule_actual 2>&1 ) && - test_cmp diff_submodule_expect diff_submodule_actual + sanitize_diff diff_submodule_actual >diff_sanitized && + test_cmp diff_submodule_expect diff_sanitized ' # We'll setup different cases for further testing: diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 8e969f3e36..963fed6821 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -814,6 +814,33 @@ test_expect_success 'status -s without relative paths' ' ' +cat >expect <<\EOF + M dir1/modified +A dir2/added +A "file with spaces" +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? "file with spaces 2" +?? untracked +EOF + +test_expect_success 'status -s without relative paths' ' + test_when_finished "git rm --cached \"file with spaces\"; rm -f file*" && + >"file with spaces" && + >"file with spaces 2" && + >"expect with spaces" && + git add "file with spaces" && + + git status -s >output && + test_cmp expect output && + + git status -s --ignored >output && + grep "^!! \"expect with spaces\"$" output && + grep -v "^!! " output >output-wo-ignored && + test_cmp expect output-wo-ignored +' + test_expect_success 'dry-run of partial commit excluding new file in index' ' cat >expect <<EOF && On branch master @@ -837,7 +864,7 @@ EOF ' cat >expect <<EOF -:100644 100644 $EMPTY_BLOB 0000000000000000000000000000000000000000 M dir1/modified +:100644 100644 $EMPTY_BLOB $ZERO_OID M dir1/modified EOF test_expect_success 'status refreshes the index' ' touch dir2/added && @@ -846,6 +873,18 @@ test_expect_success 'status refreshes the index' ' test_cmp expect output ' +test_expect_success 'status shows detached HEAD properly after checking out non-local upstream branch' ' + test_when_finished rm -rf upstream downstream actual && + + test_create_repo upstream && + test_commit -C upstream foo && + + git clone upstream downstream && + git -C downstream checkout @{u} && + git -C downstream status >actual && + test_i18ngrep "HEAD detached at [0-9a-f]\\+" actual +' + test_expect_success 'setup status submodule summary' ' test_create_repo sm && ( cd sm && diff --git a/t/t7518-ident-corner-cases.sh b/t/t7518-ident-corner-cases.sh index b22f631261..dc3e9c8c88 100755 --- a/t/t7518-ident-corner-cases.sh +++ b/t/t7518-ident-corner-cases.sh @@ -29,7 +29,18 @@ test_expect_success 'empty configured name does not auto-detect' ' sane_unset GIT_AUTHOR_NAME && test_must_fail \ git -c user.name= commit --allow-empty -m foo 2>err && - test_i18ngrep "empty ident name" err + test_i18ngrep "empty ident name" err && + test_i18ngrep "Author identity unknown" err + ) +' + +test_expect_success 'empty configured name does not auto-detect for committer' ' + ( + sane_unset GIT_COMMITTER_NAME && + test_must_fail \ + git -c user.name= commit --allow-empty -m foo 2>err && + test_i18ngrep "empty ident name" err && + test_i18ngrep "Committer identity unknown" err ) ' diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 1d45f9a4ed..1c85f75555 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -14,9 +14,9 @@ Testing basic merge operations/option parsing. ! [c4] c4 ! [c5] c5 ! [c6] c6 - * [master] Merge commit 'c1' into master + * [master] Merge commit 'c1' -------- - - [master] Merge commit 'c1' into master + - [master] Merge commit 'c1' + * [c1] commit 1 + [c6] c6 + [c5] c5 @@ -44,8 +44,8 @@ test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9 test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z create_merge_msgs () { - echo "Merge tag 'c2' into master" >msg.1-5 && - echo "Merge tags 'c2' and 'c3' into master" >msg.1-5-9 && + echo "Merge tag 'c2'" >msg.1-5 && + echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 && { echo "Squashed commit of the following:" && echo && @@ -246,7 +246,7 @@ test_expect_success 'merge --squash c3 with c7' ' # file EOF git cat-file commit HEAD >raw && - sed -e '1,/^$/d' raw >actual && + sed -e "1,/^$/d" raw >actual && test_cmp expect actual ' @@ -258,7 +258,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' ' git commit --no-edit -a && cat >expect <<-\EOF && - Merge tag '"'"'c7'"'"' into master + Merge tag '"'"'c7'"'"' # ------------------------ >8 ------------------------ # Do not modify or remove the line above. @@ -268,7 +268,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' ' # file EOF git cat-file commit HEAD >raw && - sed -e '1,/^$/d' raw >actual && + sed -e "1,/^$/d" raw >actual && test_i18ncmp expect actual ' @@ -292,7 +292,7 @@ test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' ' # file EOF git cat-file commit HEAD >raw && - sed -e '1,/^$/d' raw >actual && + sed -e "1,/^$/d" raw >actual && test_i18ncmp expect actual ' @@ -808,10 +808,10 @@ test_expect_success 'merge with conflicted --autostash changes' ' ' cat >expected.branch <<\EOF -Merge branch 'c5-branch' (early part) into master +Merge branch 'c5-branch' (early part) EOF cat >expected.tag <<\EOF -Merge commit 'c5~1' into master +Merge commit 'c5~1' EOF test_expect_success 'merge early part of c2' ' diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 0f97828cd0..c5c4ea5fc0 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -33,11 +33,18 @@ test_expect_success 'pull.rebase not set' ' test_i18ngrep "Pulling without specifying how to reconcile" err ' +test_expect_success 'pull.rebase not set and pull.ff=true' ' + git reset --hard c0 && + test_config pull.ff true && + git pull . c1 2>err && + test_i18ngrep ! "Pulling without specifying how to reconcile" err +' + test_expect_success 'pull.rebase not set and pull.ff=false' ' git reset --hard c0 && test_config pull.ff false && git pull . c1 2>err && - test_i18ngrep "Pulling without specifying how to reconcile" err + test_i18ngrep ! "Pulling without specifying how to reconcile" err ' test_expect_success 'pull.rebase not set and pull.ff=only' ' @@ -59,6 +66,18 @@ test_expect_success 'pull.rebase not set and --no-rebase given' ' test_i18ngrep ! "Pulling without specifying how to reconcile" err ' +test_expect_success 'pull.rebase not set and --ff given' ' + git reset --hard c0 && + git pull --ff . c1 2>err && + test_i18ngrep ! "Pulling without specifying how to reconcile" err +' + +test_expect_success 'pull.rebase not set and --no-ff given' ' + git reset --hard c0 && + git pull --no-ff . c1 2>err && + test_i18ngrep ! "Pulling without specifying how to reconcile" err +' + test_expect_success 'pull.rebase not set and --ff-only given' ' git reset --hard c0 && git pull --ff-only . c1 2>err && diff --git a/t/t7608-merge-messages.sh b/t/t7608-merge-messages.sh index 2af33f195b..8e7e0a5865 100755 --- a/t/t7608-merge-messages.sh +++ b/t/t7608-merge-messages.sh @@ -16,7 +16,7 @@ test_expect_success 'merge local branch' ' git checkout master && test_commit master-2 && git merge local-branch && - check_oneline "Merge branch Qlocal-branchQ into master" + check_oneline "Merge branch Qlocal-branchQ" ' test_expect_success 'merge octopus branches' ' @@ -26,7 +26,7 @@ test_expect_success 'merge octopus branches' ' test_commit octopus-2 && git checkout master && git merge octopus-a octopus-b && - check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ into master" + check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ" ' test_expect_success 'merge tag' ' @@ -35,7 +35,7 @@ test_expect_success 'merge tag' ' git checkout master && test_commit master-3 && git merge tag-1 && - check_oneline "Merge tag Qtag-1Q into master" + check_oneline "Merge tag Qtag-1Q" ' test_expect_success 'ambiguous tag' ' @@ -44,7 +44,7 @@ test_expect_success 'ambiguous tag' ' git checkout master && test_commit master-4 && git merge ambiguous && - check_oneline "Merge tag QambiguousQ into master" + check_oneline "Merge tag QambiguousQ" ' test_expect_success 'remote-tracking branch' ' @@ -54,7 +54,7 @@ test_expect_success 'remote-tracking branch' ' git checkout master && test_commit master-5 && git merge origin/master && - check_oneline "Merge remote-tracking branch Qorigin/masterQ into master" + check_oneline "Merge remote-tracking branch Qorigin/masterQ" ' test_done diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh new file mode 100755 index 0000000000..53c883531e --- /dev/null +++ b/t/t7900-maintenance.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +test_description='git maintenance builtin' + +. ./test-lib.sh + +GIT_TEST_COMMIT_GRAPH=0 + +test_expect_success 'help text' ' + test_expect_code 129 git maintenance -h 2>err && + test_i18ngrep "usage: git maintenance run" err && + test_expect_code 128 git maintenance barf 2>err && + test_i18ngrep "invalid subcommand: barf" err && + test_expect_code 129 git maintenance 2>err && + test_i18ngrep "usage: git maintenance" err +' + +test_expect_success 'run [--auto|--quiet]' ' + GIT_TRACE2_EVENT="$(pwd)/run-no-auto.txt" \ + git maintenance run 2>/dev/null && + GIT_TRACE2_EVENT="$(pwd)/run-auto.txt" \ + 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 <run-no-auto.txt && + test_subcommand ! git gc --auto --quiet <run-auto.txt && + test_subcommand git gc --no-quiet <run-no-quiet.txt +' + +test_expect_success 'maintenance.<task>.enabled' ' + git config maintenance.gc.enabled false && + git config maintenance.commit-graph.enabled true && + GIT_TRACE2_EVENT="$(pwd)/run-config.txt" git maintenance run 2>err && + test_subcommand ! git gc --quiet <run-config.txt && + test_subcommand git commit-graph write --split --reachable --no-progress <run-config.txt +' + +test_expect_success 'run --task=<task>' ' + GIT_TRACE2_EVENT="$(pwd)/run-commit-graph.txt" \ + git maintenance run --task=commit-graph 2>/dev/null && + GIT_TRACE2_EVENT="$(pwd)/run-gc.txt" \ + git maintenance run --task=gc 2>/dev/null && + GIT_TRACE2_EVENT="$(pwd)/run-commit-graph.txt" \ + 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 <run-commit-graph.txt && + test_subcommand git gc --quiet <run-gc.txt && + test_subcommand git gc --quiet <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 +' + +test_expect_success 'run --task=bogus' ' + test_must_fail git maintenance run --task=bogus 2>err && + test_i18ngrep "is not a valid task" err +' + +test_expect_success 'run --task duplicate' ' + test_must_fail git maintenance run --task=gc --task=gc 2>err && + test_i18ngrep "cannot be selected multiple times" err +' + +test_done diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh index eea048e52c..015973e8fe 100755 --- a/t/t8002-blame.sh +++ b/t/t8002-blame.sh @@ -6,6 +6,10 @@ test_description='git blame' PROG='git blame -c' . "$TEST_DIRECTORY"/annotate-tests.sh +test_expect_success 'setup' ' + hexsz=$(test_oid hexsz) +' + test_expect_success 'blame untracked file in empty repo' ' >untracked && test_must_fail git blame untracked @@ -105,21 +109,32 @@ test_expect_success 'blame --abbrev=<n> works' ' ' test_expect_success 'blame -l aligns regular and boundary commits' ' - check_abbrev 40 -l HEAD && - check_abbrev 39 -l ^HEAD + check_abbrev $hexsz -l HEAD && + check_abbrev $((hexsz - 1)) -l ^HEAD ' -test_expect_success 'blame --abbrev=40 behaves like -l' ' - check_abbrev 40 --abbrev=40 HEAD && - check_abbrev 39 --abbrev=40 ^HEAD +test_expect_success 'blame --abbrev with full length behaves like -l' ' + check_abbrev $hexsz --abbrev=$hexsz HEAD && + check_abbrev $((hexsz - 1)) --abbrev=$hexsz ^HEAD ' -test_expect_success '--no-abbrev works like --abbrev=40' ' - check_abbrev 40 --no-abbrev +test_expect_success '--no-abbrev works like --abbrev with full length' ' + check_abbrev $hexsz --no-abbrev ' test_expect_success '--exclude-promisor-objects does not BUG-crash' ' test_must_fail git blame --exclude-promisor-objects one ' +test_expect_success 'blame with uncommitted edits in partial clone does not crash' ' + git init server && + echo foo >server/file.txt && + git -C server add file.txt && + git -C server commit -m file && + + git clone --filter=blob:none "file://$(pwd)/server" client && + echo bar >>client/file.txt && + git -C client blame file.txt +' + test_done diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh index 9130b887d2..ba8013b002 100755 --- a/t/t8003-blame-corner-cases.sh +++ b/t/t8003-blame-corner-cases.sh @@ -6,7 +6,6 @@ test_description='git blame corner cases' pick_fc='s/^[0-9a-f^]* *\([^ ]*\) *(\([^ ]*\) .*/\1-\2/' test_expect_success setup ' - echo A A A A A >one && echo B B B B B >two && echo C C C C C >tres && @@ -274,18 +273,14 @@ test_expect_success 'blame file with CRLF core.autocrlf=true' ' grep "A U Thor" actual ' -# Tests the splitting and merging of blame entries in blame_coalesce(). -# The output of blame is the same, regardless of whether blame_coalesce() runs -# or not, so we'd likely only notice a problem if blame crashes or assigned -# blame to the "splitting" commit ('SPLIT' below). -test_expect_success 'blame coalesce' ' +test_expect_success 'setup coalesce tests' ' cat >giraffe <<-\EOF && ABC DEF EOF git add giraffe && git commit -m "original file" && - oid=$(git rev-parse HEAD) && + orig=$(git rev-parse HEAD) && cat >giraffe <<-\EOF && ABC @@ -294,6 +289,7 @@ test_expect_success 'blame coalesce' ' EOF git add giraffe && git commit -m "interior SPLIT line" && + split=$(git rev-parse HEAD) && cat >giraffe <<-\EOF && ABC @@ -301,12 +297,25 @@ test_expect_success 'blame coalesce' ' EOF git add giraffe && git commit -m "same contents as original" && + final=$(git rev-parse HEAD) +' + +test_expect_success 'blame coalesce' ' + cat >expect <<-EOF && + $orig 1 1 2 + $orig 2 2 + EOF + git blame --porcelain $final giraffe >actual.raw && + grep "^$orig" actual.raw >actual && + test_cmp expect actual +' +test_expect_success 'blame does not coalesce non-adjacent result lines' ' cat >expect <<-EOF && - $oid 1) ABC - $oid 2) DEF + $orig 1) ABC + $orig 3) DEF EOF - git -c core.abbrev=40 blame -s giraffe >actual && + git blame --no-abbrev -s -L1,1 -L3,3 $split giraffe >actual && test_cmp expect actual ' diff --git a/t/t8011-blame-split-file.sh b/t/t8011-blame-split-file.sh index 831125047b..bdda0c03fe 100755 --- a/t/t8011-blame-split-file.sh +++ b/t/t8011-blame-split-file.sh @@ -54,7 +54,7 @@ test_expect_success 'setup simulated porcelain' ' cat >read-porcelain.pl <<-\EOF my $field = shift; while (<>) { - if (/^[0-9a-f]{40} /) { + if (/^[0-9a-f]{40,} /) { flush(); $hash = $&; } elsif (/^$field (.*)/) { diff --git a/t/t8013-blame-ignore-revs.sh b/t/t8013-blame-ignore-revs.sh index 36dc31eb39..24ae5018e8 100755 --- a/t/t8013-blame-ignore-revs.sh +++ b/t/t8013-blame-ignore-revs.sh @@ -21,6 +21,7 @@ test_expect_success setup ' test_tick && git commit -m X && git tag X && + git tag -a -m "X (annotated)" XT && git blame --line-porcelain file >blame_raw && @@ -31,20 +32,36 @@ test_expect_success setup ' grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual && git rev-parse X >expect && test_cmp expect actual +' + +# Ensure bogus --ignore-rev requests are caught +test_expect_success 'validate --ignore-rev' ' + test_must_fail git blame --ignore-rev X^{tree} file +' + +# Ensure bogus --ignore-revs-file requests are caught +test_expect_success 'validate --ignore-revs-file' ' + git rev-parse X^{tree} >ignore_x && + test_must_fail git blame --ignore-revs-file ignore_x file +' + +for I in X XT +do + # Ignore X (or XT), make sure A is blamed for line 1 and B for line 2. + # Giving X (i.e. commit) and XT (i.e. annotated tag to commit) should + # produce the same result. + test_expect_success "ignore_rev_changing_lines ($I)" ' + git blame --line-porcelain --ignore-rev $I file >blame_raw && + + grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual && + git rev-parse A >expect && + test_cmp expect actual && + + grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual && + git rev-parse B >expect && + test_cmp expect actual ' - -# Ignore X, make sure A is blamed for line 1 and B for line 2. -test_expect_success ignore_rev_changing_lines ' - git blame --line-porcelain --ignore-rev X file >blame_raw && - - grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual && - git rev-parse A >expect && - test_cmp expect actual && - - grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual && - git rev-parse B >expect && - test_cmp expect actual - ' +done # For ignored revs that have added 'unblamable' lines, attribute those to the # ignored commit. @@ -67,7 +84,7 @@ test_expect_success ignore_rev_adding_unblamable_lines ' grep -E "^[0-9a-f]+ [0-9]+ 4" blame_raw | sed -e "s/ .*//" >actual && test_cmp expect actual - ' +' # Ignore X and Y, both in separate files. Lines 1 == A, 2 == B. test_expect_success ignore_revs_from_files ' @@ -82,7 +99,7 @@ test_expect_success ignore_revs_from_files ' grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual && git rev-parse B >expect && test_cmp expect actual - ' +' # Ignore X from the config option, Y from a file. test_expect_success ignore_revs_from_configs_and_files ' @@ -96,7 +113,7 @@ test_expect_success ignore_revs_from_configs_and_files ' grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual && git rev-parse B >expect && test_cmp expect actual - ' +' # Override blame.ignoreRevsFile (ignore_x) with an empty string. X should be # blamed now for lines 1 and 2, since we are no longer ignoring X. @@ -120,7 +137,7 @@ test_expect_success bad_files_and_revs ' echo NOREV >ignore_norev && test_must_fail git blame file --ignore-revs-file ignore_norev 2>err && test_i18ngrep "invalid object name: NOREV" err - ' +' # For ignored revs that have added 'unblamable' lines, mark those lines with a # '*' @@ -138,7 +155,7 @@ test_expect_success mark_unblamable_lines ' sed -n "4p" blame_raw | cut -c1 >actual && test_cmp expect actual - ' +' # Commit Z will touch the first two lines. Y touched all four. # A--B--X--Y--Z @@ -171,7 +188,7 @@ test_expect_success mark_ignored_lines ' sed -n "4p" blame_raw | cut -c1 >actual && ! test_cmp expect actual - ' +' # For ignored revs that added 'unblamable' lines and more recent commits changed # the blamable lines, mark the unblamable lines with a @@ -190,7 +207,7 @@ test_expect_success mark_unblamable_lines_intermediate ' sed -n "4p" blame_raw | cut -c1 >actual && test_cmp expect actual - ' +' # The heuristic called by guess_line_blames() tries to find the size of a # blame_entry 'e' in the parent's address space. Those calculations need to @@ -227,7 +244,7 @@ test_expect_success ignored_chunk_negative_parent_size ' git tag C && git blame file --ignore-rev B >blame_raw - ' +' # Resetting the repo and creating: # @@ -269,6 +286,6 @@ test_expect_success ignore_merge ' grep -E "^[0-9a-f]+ [0-9]+ 9" blame_raw | sed -e "s/ .*//" >actual && git rev-parse C >expect && test_cmp expect actual - ' +' test_done diff --git a/t/t8014-blame-ignore-fuzzy.sh b/t/t8014-blame-ignore-fuzzy.sh index 6e61882b6f..e68e6115a6 100755 --- a/t/t8014-blame-ignore-fuzzy.sh +++ b/t/t8014-blame-ignore-fuzzy.sh @@ -248,7 +248,7 @@ Final EOF # The first line of b matches best with the last line of a, but the overall -# match is better if we match it with the the first line of a. +# match is better if we match it with the first line of a. title11="Piggy in the middle" cat <<EOF >a11 abcdefg diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index ec261085ec..a08f72596a 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1551,7 +1551,7 @@ test_expect_success $PREREQ '8-bit and sendemail.transferencoding=quoted-printab --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && + sed "1,/^$/d" msgtxt1 >actual && test_cmp expected actual ' @@ -1568,7 +1568,7 @@ test_expect_success $PREREQ '8-bit and sendemail.transferencoding=base64' ' --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && + sed "1,/^$/d" msgtxt1 >actual && test_cmp expected actual ' @@ -1594,7 +1594,7 @@ test_expect_success $PREREQ 'convert from quoted-printable to base64' ' --smtp-server="$(pwd)/fake.sendmail" \ email-using-qp \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && + sed "1,/^$/d" msgtxt1 >actual && test_cmp expected actual ' @@ -1624,7 +1624,7 @@ test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=quoted-printabl --smtp-server="$(pwd)/fake.sendmail" \ email-using-crlf \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && + sed "1,/^$/d" msgtxt1 >actual && test_cmp expected actual ' @@ -1641,7 +1641,7 @@ test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=base64' ' --smtp-server="$(pwd)/fake.sendmail" \ email-using-crlf \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && + sed "1,/^$/d" msgtxt1 >actual && test_cmp expected actual ' @@ -2142,4 +2142,33 @@ test_expect_success $PREREQ 'test that send-email works outside a repo' ' "$(pwd)/0001-add-master.patch" ' +test_expect_success $PREREQ 'test that sendmail config is rejected' ' + test_config sendmail.program sendmail && + test_must_fail git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + HEAD^ 2>err && + test_i18ngrep "found configuration options for '"'"sendmail"'"'" err +' + +test_expect_success $PREREQ 'test that sendmail config rejection is specific' ' + test_config resendmail.program sendmail && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + HEAD^ +' + +test_expect_success $PREREQ 'test forbidSendmailVariables behavior override' ' + test_config sendmail.program sendmail && + test_config sendemail.forbidSendmailVariables false && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + HEAD^ +' + test_done diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh deleted file mode 100755 index 83f8f5cacb..0000000000 --- a/t/t9010-svn-fe.sh +++ /dev/null @@ -1,1105 +0,0 @@ -#!/bin/sh - -test_description='check svn dumpfile importer' - -. ./test-lib.sh - -if test_have_prereq !PIPE -then - skip_all="svn dumpfile importer testing requires the PIPE prerequisite" - test_done -fi - -reinit_git () { - rm -fr .git && - rm -f stream backflow && - git init && - mkfifo stream backflow -} - -try_dump () { - input=$1 && - maybe_fail_svnfe=${2:+test_$2} && - maybe_fail_fi=${3:+test_$3} && - - { - $maybe_fail_svnfe test-svn-fe "$input" >stream 3<backflow & - } && - $maybe_fail_fi git fast-import --cat-blob-fd=3 <stream 3>backflow && - wait $! -} - -properties () { - while test "$#" -ne 0 - do - property="$1" && - value="$2" && - printf "%s\n" "K ${#property}" && - printf "%s\n" "$property" && - printf "%s\n" "V ${#value}" && - printf "%s\n" "$value" && - shift 2 || - return 1 - done -} - -text_no_props () { - text="$1 -" && - printf "%s\n" "Prop-content-length: 10" && - printf "%s\n" "Text-content-length: ${#text}" && - printf "%s\n" "Content-length: $((${#text} + 10))" && - printf "%s\n" "" "PROPS-END" && - printf "%s\n" "$text" -} - -test_expect_success 'empty dump' ' - reinit_git && - echo "SVN-fs-dump-format-version: 2" >input && - try_dump input -' - -test_expect_success 'v4 dumps not supported' ' - reinit_git && - echo "SVN-fs-dump-format-version: 4" >v4.dump && - try_dump v4.dump must_fail -' - -test_expect_failure 'empty revision' ' - reinit_git && - printf "rev <nobody, nobody@local>: %s\n" "" "" >expect && - cat >emptyrev.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 0 - Content-length: 0 - - Revision-number: 2 - Prop-content-length: 0 - Content-length: 0 - - EOF - try_dump emptyrev.dump && - git log -p --format="rev <%an, %ae>: %s" HEAD >actual && - test_cmp expect actual -' - -test_expect_success 'empty properties' ' - reinit_git && - printf "rev <nobody, nobody@local>: %s\n" "" "" >expect && - cat >emptyprop.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Revision-number: 2 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - EOF - try_dump emptyprop.dump && - git log -p --format="rev <%an, %ae>: %s" HEAD >actual && - test_cmp expect actual -' - -test_expect_success 'author name and commit message' ' - reinit_git && - echo "<author@example.com, author@example.com@local>" >expect.author && - cat >message <<-\EOF && - A concise summary of the change - - A detailed description of the change, why it is needed, what - was broken and why applying this is the best course of action. - - * file.c - Details pertaining to an individual file. - EOF - { - properties \ - svn:author author@example.com \ - svn:log "$(cat message)" && - echo PROPS-END - } >props && - { - echo "SVN-fs-dump-format-version: 3" && - echo && - echo "Revision-number: 1" && - echo Prop-content-length: $(wc -c <props) && - echo Content-length: $(wc -c <props) && - echo && - cat props - } >log.dump && - try_dump log.dump && - git log -p --format="%B" HEAD >actual.log && - git log --format="<%an, %ae>" >actual.author && - test_cmp message actual.log && - test_cmp expect.author actual.author -' - -test_expect_success 'unsupported properties are ignored' ' - reinit_git && - echo author >expect && - cat >extraprop.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 56 - Content-length: 56 - - K 8 - nonsense - V 1 - y - K 10 - svn:author - V 6 - author - PROPS-END - EOF - try_dump extraprop.dump && - git log -p --format=%an HEAD >actual && - test_cmp expect actual -' - -test_expect_failure 'timestamp and empty file' ' - echo author@example.com >expect.author && - echo 1999-01-01 >expect.date && - echo file >expect.files && - reinit_git && - { - properties \ - svn:author author@example.com \ - svn:date "1999-01-01T00:01:002.000000Z" \ - svn:log "add empty file" && - echo PROPS-END - } >props && - { - cat <<-EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - EOF - echo Prop-content-length: $(wc -c <props) && - echo Content-length: $(wc -c <props) && - echo && - cat props && - cat <<-\EOF - - Node-path: empty-file - Node-kind: file - Node-action: add - Content-length: 0 - - EOF - } >emptyfile.dump && - try_dump emptyfile.dump && - git log --format=%an HEAD >actual.author && - git log --date=short --format=%ad HEAD >actual.date && - git ls-tree -r --name-only HEAD >actual.files && - test_cmp expect.author actual.author && - test_cmp expect.date actual.date && - test_cmp expect.files actual.files && - git checkout HEAD empty-file && - test_must_be_empty file -' - -test_expect_success 'directory with files' ' - reinit_git && - printf "%s\n" directory/file1 directory/file2 >expect.files && - echo hi >hi && - echo hello >hello && - { - properties \ - svn:author author@example.com \ - svn:date "1999-02-01T00:01:002.000000Z" \ - svn:log "add directory with some files in it" && - echo PROPS-END - } >props && - { - cat <<-EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - EOF - echo Prop-content-length: $(wc -c <props) && - echo Content-length: $(wc -c <props) && - echo && - cat props && - cat <<-\EOF && - - Node-path: directory - Node-kind: dir - Node-action: add - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: directory/file1 - Node-kind: file - Node-action: add - EOF - text_no_props hello && - cat <<-\EOF && - Node-path: directory/file2 - Node-kind: file - Node-action: add - EOF - text_no_props hi - } >directory.dump && - try_dump directory.dump && - - git ls-tree -r --name-only HEAD >actual.files && - git checkout HEAD directory && - test_cmp expect.files actual.files && - test_cmp hello directory/file1 && - test_cmp hi directory/file2 -' - -test_expect_success 'branch name with backslash' ' - reinit_git && - sort <<-\EOF >expect.branch-files && - trunk/file1 - trunk/file2 - "branches/UpdateFOPto094\\/file1" - "branches/UpdateFOPto094\\/file2" - EOF - - echo hi >hi && - echo hello >hello && - { - properties \ - svn:author author@example.com \ - svn:date "1999-02-02T00:01:02.000000Z" \ - svn:log "add directory with some files in it" && - echo PROPS-END - } >props.setup && - { - properties \ - svn:author brancher@example.com \ - svn:date "2007-12-06T21:38:34.000000Z" \ - svn:log "Updating fop to .94 and adjust fo-stylesheets" && - echo PROPS-END - } >props.branch && - { - cat <<-EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - EOF - echo Prop-content-length: $(wc -c <props.setup) && - echo Content-length: $(wc -c <props.setup) && - echo && - cat props.setup && - cat <<-\EOF && - - Node-path: trunk - Node-kind: dir - Node-action: add - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: branches - Node-kind: dir - Node-action: add - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: trunk/file1 - Node-kind: file - Node-action: add - EOF - text_no_props hello && - cat <<-\EOF && - Node-path: trunk/file2 - Node-kind: file - Node-action: add - EOF - text_no_props hi && - cat <<-\EOF && - - Revision-number: 2 - EOF - echo Prop-content-length: $(wc -c <props.branch) && - echo Content-length: $(wc -c <props.branch) && - echo && - cat props.branch && - cat <<-\EOF - - Node-path: branches/UpdateFOPto094\ - Node-kind: dir - Node-action: add - Node-copyfrom-rev: 1 - Node-copyfrom-path: trunk - - Node-kind: dir - Node-action: add - Prop-content-length: 34 - Content-length: 34 - - K 13 - svn:mergeinfo - V 0 - - PROPS-END - EOF - } >branch.dump && - try_dump branch.dump && - - git ls-tree -r --name-only HEAD | - sort >actual.branch-files && - test_cmp expect.branch-files actual.branch-files -' - -test_expect_success 'node without action' ' - reinit_git && - cat >inaction.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: directory - Node-kind: dir - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - EOF - try_dump inaction.dump must_fail -' - -test_expect_success 'action: add node without text' ' - reinit_git && - cat >textless.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: textless - Node-kind: file - Node-action: add - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - EOF - try_dump textless.dump must_fail -' - -test_expect_failure 'change file mode but keep old content' ' - reinit_git && - cat >expect <<-\EOF && - OBJID - :120000 100644 OBJID OBJID T greeting - OBJID - :100644 120000 OBJID OBJID T greeting - OBJID - :000000 100644 OBJID OBJID A greeting - EOF - echo "link hello" >expect.blob && - echo hello >hello && - cat >filemode.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: add - Prop-content-length: 10 - Text-content-length: 11 - Content-length: 21 - - PROPS-END - link hello - - Revision-number: 2 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: change - Prop-content-length: 33 - Content-length: 33 - - K 11 - svn:special - V 1 - * - PROPS-END - - Revision-number: 3 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: change - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - EOF - try_dump filemode.dump && - { - git rev-list HEAD | - git diff-tree --root --stdin | - sed "s/$OID_REGEX/OBJID/g" - } >actual && - git show HEAD:greeting >actual.blob && - git show HEAD^:greeting >actual.target && - test_cmp expect actual && - test_cmp expect.blob actual.blob && - test_cmp hello actual.target -' - -test_expect_success 'NUL in property value' ' - reinit_git && - echo "commit message" >expect.message && - { - properties \ - unimportant "something with a NUL (Q)" \ - svn:log "commit message" && - echo PROPS-END - } | - q_to_nul >props && - { - cat <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - EOF - echo Prop-content-length: $(wc -c <props) && - echo Content-length: $(wc -c <props) && - echo && - cat props - } >nulprop.dump && - try_dump nulprop.dump && - git diff-tree --always -s --format=%s HEAD >actual.message && - test_cmp expect.message actual.message -' - -test_expect_success 'NUL in log message, file content, and property name' ' - # Caveat: svnadmin 1.6.16 (r1073529) truncates at \0 in the - # svn:specialQnotreally example. - reinit_git && - cat >expect <<-\EOF && - OBJID - :100644 100644 OBJID OBJID M greeting - OBJID - :000000 100644 OBJID OBJID A greeting - EOF - printf "\n%s\n" "something with an ASCII NUL (Q)" >expect.message && - printf "%s\n" "helQo" >expect.hello1 && - printf "%s\n" "link hello" >expect.hello2 && - { - properties svn:log "something with an ASCII NUL (Q)" && - echo PROPS-END - } | - q_to_nul >props && - { - q_to_nul <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: add - Prop-content-length: 10 - Text-content-length: 6 - Content-length: 16 - - PROPS-END - helQo - - Revision-number: 2 - EOF - echo Prop-content-length: $(wc -c <props) && - echo Content-length: $(wc -c <props) && - echo && - cat props && - q_to_nul <<-\EOF - - Node-path: greeting - Node-kind: file - Node-action: change - Prop-content-length: 43 - Text-content-length: 11 - Content-length: 54 - - K 21 - svn:specialQnotreally - V 1 - * - PROPS-END - link hello - EOF - } >8bitclean.dump && - try_dump 8bitclean.dump && - { - git rev-list HEAD | - git diff-tree --root --stdin | - sed "s/$OID_REGEX/OBJID/g" - } >actual && - { - git cat-file commit HEAD | nul_to_q && - echo - } | - sed -ne "/^\$/,\$ p" >actual.message && - git cat-file blob HEAD^:greeting | nul_to_q >actual.hello1 && - git cat-file blob HEAD:greeting | nul_to_q >actual.hello2 && - test_cmp expect actual && - test_cmp expect.message actual.message && - test_cmp expect.hello1 actual.hello1 && - test_cmp expect.hello2 actual.hello2 -' - -test_expect_success 'change file mode and reiterate content' ' - reinit_git && - cat >expect <<-\EOF && - OBJID - :120000 100644 OBJID OBJID T greeting - OBJID - :100644 120000 OBJID OBJID T greeting - OBJID - :000000 100644 OBJID OBJID A greeting - EOF - echo "link hello" >expect.blob && - echo hello >hello && - cat >filemode2.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: add - Prop-content-length: 10 - Text-content-length: 11 - Content-length: 21 - - PROPS-END - link hello - - Revision-number: 2 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: change - Prop-content-length: 33 - Text-content-length: 11 - Content-length: 44 - - K 11 - svn:special - V 1 - * - PROPS-END - link hello - - Revision-number: 3 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: change - Prop-content-length: 10 - Text-content-length: 11 - Content-length: 21 - - PROPS-END - link hello - EOF - try_dump filemode2.dump && - { - git rev-list HEAD | - git diff-tree --root --stdin | - sed "s/$OID_REGEX/OBJID/g" - } >actual && - git show HEAD:greeting >actual.blob && - git show HEAD^:greeting >actual.target && - test_cmp expect actual && - test_cmp expect.blob actual.blob && - test_cmp hello actual.target -' - -test_expect_success 'deltas supported' ' - reinit_git && - { - # (old) h + (inline) ello + (old) \n - printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" | - q_to_nul - } >delta && - { - properties \ - svn:author author@example.com \ - svn:date "1999-01-05T00:01:002.000000Z" \ - svn:log "add greeting" && - echo PROPS-END - } >props && - { - properties \ - svn:author author@example.com \ - svn:date "1999-01-06T00:01:002.000000Z" \ - svn:log "change it" && - echo PROPS-END - } >props2 && - { - echo SVN-fs-dump-format-version: 3 && - echo && - echo Revision-number: 1 && - echo Prop-content-length: $(wc -c <props) && - echo Content-length: $(wc -c <props) && - echo && - cat props && - cat <<-\EOF && - - Node-path: hello - Node-kind: file - Node-action: add - Prop-content-length: 10 - Text-content-length: 3 - Content-length: 13 - - PROPS-END - hi - - EOF - echo Revision-number: 2 && - echo Prop-content-length: $(wc -c <props2) && - echo Content-length: $(wc -c <props2) && - echo && - cat props2 && - cat <<-\EOF && - - Node-path: hello - Node-kind: file - Node-action: change - Text-delta: true - Prop-content-length: 10 - EOF - echo Text-content-length: $(wc -c <delta) && - echo Content-length: $((10 + $(wc -c <delta))) && - echo && - echo PROPS-END && - cat delta - } >delta.dump && - try_dump delta.dump -' - -test_expect_success 'property deltas supported' ' - reinit_git && - cat >expect <<-\EOF && - OBJID - :100755 100644 OBJID OBJID M script.sh - EOF - { - properties \ - svn:author author@example.com \ - svn:date "1999-03-06T00:01:002.000000Z" \ - svn:log "make an executable, or chmod -x it" && - echo PROPS-END - } >revprops && - { - echo SVN-fs-dump-format-version: 3 && - echo && - echo Revision-number: 1 && - echo Prop-content-length: $(wc -c <revprops) && - echo Content-length: $(wc -c <revprops) && - echo && - cat revprops && - echo && - cat <<-\EOF && - Node-path: script.sh - Node-kind: file - Node-action: add - Text-content-length: 0 - Prop-content-length: 39 - Content-length: 39 - - K 14 - svn:executable - V 4 - true - PROPS-END - - EOF - echo Revision-number: 2 && - echo Prop-content-length: $(wc -c <revprops) && - echo Content-length: $(wc -c <revprops) && - echo && - cat revprops && - echo && - cat <<-\EOF - Node-path: script.sh - Node-kind: file - Node-action: change - Prop-delta: true - Prop-content-length: 30 - Content-length: 30 - - D 14 - svn:executable - PROPS-END - EOF - } >propdelta.dump && - try_dump propdelta.dump && - { - git rev-list HEAD | - git diff-tree --stdin | - sed "s/$OID_REGEX/OBJID/g" - } >actual && - test_cmp expect actual -' - -test_expect_success 'properties on /' ' - reinit_git && - cat <<-\EOF >expect && - OBJID - OBJID - :000000 100644 OBJID OBJID A greeting - EOF - sed -e "s/X$//" <<-\EOF >changeroot.dump && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: greeting - Node-kind: file - Node-action: add - Text-content-length: 0 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Revision-number: 2 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: X - Node-kind: dir - Node-action: change - Prop-delta: true - Prop-content-length: 43 - Content-length: 43 - - K 10 - svn:ignore - V 11 - build-area - - PROPS-END - EOF - try_dump changeroot.dump && - { - git rev-list HEAD | - git diff-tree --root --always --stdin | - sed "s/$OID_REGEX/OBJID/g" - } >actual && - test_cmp expect actual -' - -test_expect_success 'deltas for typechange' ' - reinit_git && - cat >expect <<-\EOF && - OBJID - :120000 100644 OBJID OBJID T test-file - OBJID - :100755 120000 OBJID OBJID T test-file - OBJID - :000000 100755 OBJID OBJID A test-file - EOF - cat >deleteprop.dump <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: test-file - Node-kind: file - Node-action: add - Prop-delta: true - Prop-content-length: 35 - Text-content-length: 17 - Content-length: 52 - - K 14 - svn:executable - V 0 - - PROPS-END - link testing 123 - - Revision-number: 2 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: test-file - Node-kind: file - Node-action: change - Prop-delta: true - Prop-content-length: 53 - Text-content-length: 17 - Content-length: 70 - - K 11 - svn:special - V 1 - * - D 14 - svn:executable - PROPS-END - link testing 231 - - Revision-number: 3 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: test-file - Node-kind: file - Node-action: change - Prop-delta: true - Prop-content-length: 27 - Text-content-length: 17 - Content-length: 44 - - D 11 - svn:special - PROPS-END - link testing 321 - EOF - try_dump deleteprop.dump && - { - git rev-list HEAD | - git diff-tree --root --stdin | - sed "s/$OID_REGEX/OBJID/g" - } >actual && - test_cmp expect actual -' - -test_expect_success 'deltas need not consume the whole preimage' ' - reinit_git && - cat >expect <<-\EOF && - OBJID - :120000 100644 OBJID OBJID T postimage - OBJID - :100644 120000 OBJID OBJID T postimage - OBJID - :000000 100644 OBJID OBJID A postimage - EOF - echo "first preimage" >expect.1 && - printf target >expect.2 && - printf lnk >expect.3 && - { - printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" | - q_to_nul - } >delta.1 && - { - properties svn:special "*" && - echo PROPS-END - } >symlink.props && - { - printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" | - q_to_nul - } >delta.2 && - { - printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" | - q_to_nul - } >delta.3 && - { - cat <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: postimage - Node-kind: file - Node-action: add - Text-delta: true - Prop-content-length: 10 - EOF - echo Text-content-length: $(wc -c <delta.1) && - echo Content-length: $((10 + $(wc -c <delta.1))) && - echo && - echo PROPS-END && - cat delta.1 && - cat <<-\EOF && - - Revision-number: 2 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: postimage - Node-kind: file - Node-action: change - Text-delta: true - EOF - echo Prop-content-length: $(wc -c <symlink.props) && - echo Text-content-length: $(wc -c <delta.2) && - echo Content-length: $(($(wc -c <symlink.props) + $(wc -c <delta.2))) && - echo && - cat symlink.props && - cat delta.2 && - cat <<-\EOF && - - Revision-number: 3 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: postimage - Node-kind: file - Node-action: change - Text-delta: true - Prop-content-length: 10 - EOF - echo Text-content-length: $(wc -c <delta.3) && - echo Content-length: $((10 + $(wc -c <delta.3))) && - echo && - echo PROPS-END && - cat delta.3 && - echo - } >deltapartial.dump && - try_dump deltapartial.dump && - { - git rev-list HEAD | - git diff-tree --root --stdin | - sed "s/$OID_REGEX/OBJID/g" - } >actual && - test_cmp expect actual && - git show HEAD:postimage >actual.3 && - git show HEAD^:postimage >actual.2 && - git show HEAD^^:postimage >actual.1 && - test_cmp expect.1 actual.1 && - test_cmp expect.2 actual.2 && - test_cmp expect.3 actual.3 -' - -test_expect_success 'no hang for delta trying to read past end of preimage' ' - reinit_git && - { - # COPY 1 - printf "SVNQ%b%b" "Q\001\001\002Q" "\001Q" | - q_to_nul - } >greedy.delta && - { - cat <<-\EOF && - SVN-fs-dump-format-version: 3 - - Revision-number: 1 - Prop-content-length: 10 - Content-length: 10 - - PROPS-END - - Node-path: bootstrap - Node-kind: file - Node-action: add - Text-delta: true - Prop-content-length: 10 - EOF - echo Text-content-length: $(wc -c <greedy.delta) && - echo Content-length: $((10 + $(wc -c <greedy.delta))) && - echo && - echo PROPS-END && - cat greedy.delta && - echo - } >greedydelta.dump && - try_dump greedydelta.dump must_fail might_fail -' - -test_expect_success 'set up svn repo' ' - svnconf=$PWD/svnconf && - mkdir -p "$svnconf" && - - if - svnadmin -h >/dev/null 2>&1 && - svnadmin create simple-svn && - svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" && - svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco - then - test_set_prereq SVNREPO - fi -' - -test_expect_success SVNREPO 't9135/svn.dump' ' - mkdir -p simple-git && - ( - cd simple-git && - reinit_git && - try_dump "$TEST_DIRECTORY/t9135/svn.dump" - ) && - ( - cd simple-svnco && - git init && - git add . && - git fetch ../simple-git master && - git diff --exit-code FETCH_HEAD - ) -' - -test_done diff --git a/t/t9011-svn-da.sh b/t/t9011-svn-da.sh deleted file mode 100755 index ab1ef28fd9..0000000000 --- a/t/t9011-svn-da.sh +++ /dev/null @@ -1,248 +0,0 @@ -#!/bin/sh - -test_description='test parsing of svndiff0 files - -Using the "test-svn-fe -d" helper, check that svn-fe correctly -interprets deltas using various facilities (some from the spec, -some only learned from practice). -' -. ./test-lib.sh - ->empty -printf foo >preimage - -test_expect_success 'reject empty delta' ' - test_must_fail test-svn-fe -d preimage empty 0 -' - -test_expect_success 'delta can empty file' ' - printf "SVNQ" | q_to_nul >clear.delta && - test-svn-fe -d preimage clear.delta 4 >actual && - test_must_be_empty actual -' - -test_expect_success 'reject svndiff2' ' - printf "SVN\002" >bad.filetype && - test_must_fail test-svn-fe -d preimage bad.filetype 4 -' - -test_expect_success 'one-window empty delta' ' - printf "SVNQ%s" "QQQQQ" | q_to_nul >clear.onewindow && - test-svn-fe -d preimage clear.onewindow 9 >actual && - test_must_be_empty actual -' - -test_expect_success 'reject incomplete window header' ' - printf "SVNQ%s" "QQQQQ" | q_to_nul >clear.onewindow && - printf "SVNQ%s" "QQ" | q_to_nul >clear.partialwindow && - test_must_fail test-svn-fe -d preimage clear.onewindow 6 && - test_must_fail test-svn-fe -d preimage clear.partialwindow 6 -' - -test_expect_success 'reject declared delta longer than actual delta' ' - printf "SVNQ%s" "QQQQQ" | q_to_nul >clear.onewindow && - printf "SVNQ%s" "QQ" | q_to_nul >clear.partialwindow && - test_must_fail test-svn-fe -d preimage clear.onewindow 14 && - test_must_fail test-svn-fe -d preimage clear.partialwindow 9 -' - -test_expect_success 'two-window empty delta' ' - printf "SVNQ%s%s" "QQQQQ" "QQQQQ" | q_to_nul >clear.twowindow && - test-svn-fe -d preimage clear.twowindow 14 >actual && - test_must_fail test-svn-fe -d preimage clear.twowindow 13 && - test_must_be_empty actual -' - -test_expect_success 'noisy zeroes' ' - printf "SVNQ%s" \ - "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRQQQQQ" | - tr R "\200" | - q_to_nul >clear.noisy && - len=$(wc -c <clear.noisy) && - test-svn-fe -d preimage clear.noisy $len && - test_must_be_empty actual -' - -test_expect_success 'reject variable-length int in magic' ' - printf "SVNRQ" | tr R "\200" | q_to_nul >clear.badmagic && - test_must_fail test-svn-fe -d preimage clear.badmagic 5 -' - -test_expect_success 'reject truncated integer' ' - printf "SVNQ%s%s" "QQQQQ" "QQQQRRQ" | - tr R "\200" | - q_to_nul >clear.fullint && - printf "SVNQ%s%s" "QQQQQ" "QQQQRR" | - tr RT "\201" | - q_to_nul >clear.partialint && - test_must_fail test-svn-fe -d preimage clear.fullint 15 && - test-svn-fe -d preimage clear.fullint 16 && - test_must_fail test-svn-fe -d preimage clear.partialint 15 -' - -test_expect_success 'nonempty (but unused) preimage view' ' - printf "SVNQ%b" "Q\003QQQ" | q_to_nul >clear.readpreimage && - test-svn-fe -d preimage clear.readpreimage 9 >actual && - test_must_be_empty actual -' - -test_expect_success 'preimage view: right endpoint cannot backtrack' ' - printf "SVNQ%b%b" "Q\003QQQ" "Q\002QQQ" | - q_to_nul >clear.backtrack && - test_must_fail test-svn-fe -d preimage clear.backtrack 14 -' - -test_expect_success 'preimage view: left endpoint can advance' ' - printf "SVNQ%b%b" "Q\003QQQ" "\001\002QQQ" | - q_to_nul >clear.preshrink && - printf "SVNQ%b%b" "Q\003QQQ" "\001\001QQQ" | - q_to_nul >clear.shrinkbacktrack && - test-svn-fe -d preimage clear.preshrink 14 >actual && - test_must_fail test-svn-fe -d preimage clear.shrinkbacktrack 14 && - test_must_be_empty actual -' - -test_expect_success 'preimage view: offsets compared by value' ' - printf "SVNQ%b%b" "\001\001QQQ" "\0200Q\003QQQ" | - q_to_nul >clear.noisybacktrack && - printf "SVNQ%b%b" "\001\001QQQ" "\0200\001\002QQQ" | - q_to_nul >clear.noisyadvance && - test_must_fail test-svn-fe -d preimage clear.noisybacktrack 15 && - test-svn-fe -d preimage clear.noisyadvance 15 && - test_must_be_empty actual -' - -test_expect_success 'preimage view: reject truncated preimage' ' - printf "SVNQ%b" "\010QQQQ" | q_to_nul >clear.lateemptyread && - printf "SVNQ%b" "\010\001QQQ" | q_to_nul >clear.latenonemptyread && - printf "SVNQ%b" "\001\010QQQ" | q_to_nul >clear.longread && - test_must_fail test-svn-fe -d preimage clear.lateemptyread 9 && - test_must_fail test-svn-fe -d preimage clear.latenonemptyread 9 && - test_must_fail test-svn-fe -d preimage clear.longread 9 -' - -test_expect_success 'forbid unconsumed inline data' ' - printf "SVNQ%b%s%b%s" "QQQQ\003" "bar" "QQQQ\001" "x" | - q_to_nul >inline.clear && - test_must_fail test-svn-fe -d preimage inline.clear 18 >actual -' - -test_expect_success 'reject truncated inline data' ' - printf "SVNQ%b%s" "QQQQ\003" "b" | q_to_nul >inline.trunc && - test_must_fail test-svn-fe -d preimage inline.trunc 10 -' - -test_expect_success 'reject truncated inline data (after instruction section)' ' - printf "SVNQ%b%b%s" "QQ\001\001\003" "\0201" "b" | q_to_nul >insn.trunc && - test_must_fail test-svn-fe -d preimage insn.trunc 11 -' - -test_expect_success 'copyfrom_data' ' - echo hi >expect && - printf "SVNQ%b%b%b" "QQ\003\001\003" "\0203" "hi\n" | q_to_nul >copydat && - test-svn-fe -d preimage copydat 13 >actual && - test_cmp expect actual -' - -test_expect_success 'multiple copyfrom_data' ' - echo hi >expect && - printf "SVNQ%b%b%b%b%b" "QQ\003\002\003" "\0201\0202" "hi\n" \ - "QQQ\002Q" "\0200Q" | q_to_nul >copy.multi && - len=$(wc -c <copy.multi) && - test-svn-fe -d preimage copy.multi $len >actual && - test_cmp expect actual -' - -test_expect_success 'incomplete multiple insn' ' - printf "SVNQ%b%b%b" "QQ\003\002\003" "\0203\0200" "hi\n" | - q_to_nul >copy.partial && - len=$(wc -c <copy.partial) && - test_must_fail test-svn-fe -d preimage copy.partial $len -' - -test_expect_success 'catch attempt to copy missing data' ' - printf "SVNQ%b%b%s%b%s" "QQ\002\002\001" "\0201\0201" "X" \ - "QQQQ\002" "YZ" | - q_to_nul >copy.incomplete && - len=$(wc -c <copy.incomplete) && - test_must_fail test-svn-fe -d preimage copy.incomplete $len -' - -test_expect_success 'copyfrom target to repeat data' ' - printf foofoo >expect && - printf "SVNQ%b%b%s" "QQ\006\004\003" "\0203\0100\003Q" "foo" | - q_to_nul >copytarget.repeat && - len=$(wc -c <copytarget.repeat) && - test-svn-fe -d preimage copytarget.repeat $len >actual && - test_cmp expect actual -' - -test_expect_success 'copyfrom target out of order' ' - printf foooof >expect && - printf "SVNQ%b%b%s" \ - "QQ\006\007\003" "\0203\0101\002\0101\001\0101Q" "foo" | - q_to_nul >copytarget.reverse && - len=$(wc -c <copytarget.reverse) && - test-svn-fe -d preimage copytarget.reverse $len >actual && - test_cmp expect actual -' - -test_expect_success 'catch copyfrom future' ' - printf "SVNQ%b%b%s" "QQ\004\004\003" "\0202\0101\002\0201" "XYZ" | - q_to_nul >copytarget.infuture && - len=$(wc -c <copytarget.infuture) && - test_must_fail test-svn-fe -d preimage copytarget.infuture $len -' - -test_expect_success 'copy to sustain' ' - printf XYXYXYXYXYXZ >expect && - printf "SVNQ%b%b%s" "QQ\014\004\003" "\0202\0111Q\0201" "XYZ" | - q_to_nul >copytarget.sustain && - len=$(wc -c <copytarget.sustain) && - test-svn-fe -d preimage copytarget.sustain $len >actual && - test_cmp expect actual -' - -test_expect_success 'catch copy that overflows' ' - printf "SVNQ%b%b%s" "QQ\003\003\001" "\0201\0177Q" X | - q_to_nul >copytarget.overflow && - len=$(wc -c <copytarget.overflow) && - test_must_fail test-svn-fe -d preimage copytarget.overflow $len -' - -test_expect_success 'copyfrom source' ' - printf foo >expect && - printf "SVNQ%b%b" "Q\003\003\002Q" "\003Q" | q_to_nul >copysource.all && - test-svn-fe -d preimage copysource.all 11 >actual && - test_cmp expect actual -' - -test_expect_success 'copy backwards' ' - printf oof >expect && - printf "SVNQ%b%b" "Q\003\003\006Q" "\001\002\001\001\001Q" | - q_to_nul >copysource.rev && - test-svn-fe -d preimage copysource.rev 15 >actual && - test_cmp expect actual -' - -test_expect_success 'offsets are relative to window' ' - printf fo >expect && - printf "SVNQ%b%b%b%b" "Q\003\001\002Q" "\001Q" \ - "\002\001\001\002Q" "\001Q" | - q_to_nul >copysource.two && - test-svn-fe -d preimage copysource.two 18 >actual && - test_cmp expect actual -' - -test_expect_success 'example from notes/svndiff' ' - printf aaaaccccdddddddd >expect && - printf aaaabbbbcccc >source && - printf "SVNQ%b%b%s" "Q\014\020\007\001" \ - "\004Q\004\010\0201\0107\010" d | - q_to_nul >delta.example && - len=$(wc -c <delta.example) && - test-svn-fe -d source delta.example $len >actual && - test_cmp expect actual -' - -test_done diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh deleted file mode 100755 index 754c4a3284..0000000000 --- a/t/t9020-remote-svn.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/sh - -test_description='tests remote-svn' - -. ./test-lib.sh - -MARKSPATH=.git/info/fast-import/remote-svn - -if ! test_have_prereq PYTHON -then - skip_all='skipping remote-svn tests, python not available' - test_done -fi - -# Override svnrdump with our simulator -PATH="$HOME:$PATH" -export PATH PYTHON_PATH GIT_BUILD_DIR - -write_script "$HOME/svnrdump" <<\EOF -exec "$PYTHON_PATH" "$GIT_BUILD_DIR/contrib/svn-fe/svnrdump_sim.py" "$@" -EOF - -init_git () { - rm -fr .git && - git init && - #git remote add svnsim testsvn::sim:///$TEST_DIRECTORY/t9020/example.svnrdump - # let's reuse an existing dump file!? - git remote add svnsim "testsvn::sim://$TEST_DIRECTORY/t9154/svn.dump" - git remote add svnfile "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" -} - -if test -e "$GIT_BUILD_DIR/git-remote-testsvn" -then - test_set_prereq REMOTE_SVN -fi - -test_debug ' - git --version - type git - type svnrdump -' - -test_expect_success REMOTE_SVN 'simple fetch' ' - init_git && - git fetch svnsim && - test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master && - cp .git/refs/remotes/svnsim/master master.good -' - -test_debug ' - git show-ref -s refs/svn/svnsim/master - git show-ref -s refs/remotes/svnsim/master -' - -test_expect_success REMOTE_SVN 'repeated fetch, nothing shall change' ' - git fetch svnsim && - test_cmp master.good .git/refs/remotes/svnsim/master -' - -test_expect_success REMOTE_SVN 'fetch from a file:// url gives the same result' ' - git fetch svnfile -' - -test_expect_failure REMOTE_SVN 'the sha1 differ because the git-svn-id line in the commit msg contains the url' ' - test_cmp .git/refs/remotes/svnfile/master .git/refs/remotes/svnsim/master -' - -test_expect_success REMOTE_SVN 'mark-file regeneration' ' - # filter out any other marks, that can not be regenerated. Only up to 3 digit revisions are allowed here - grep ":[0-9]\{1,3\} " $MARKSPATH/svnsim.marks > $MARKSPATH/svnsim.marks.old && - rm $MARKSPATH/svnsim.marks && - git fetch svnsim && - test_cmp $MARKSPATH/svnsim.marks.old $MARKSPATH/svnsim.marks -' - -test_expect_success REMOTE_SVN 'incremental imports must lead to the same head' ' - SVNRMAX=3 && - export SVNRMAX && - init_git && - git fetch svnsim && - test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master && - unset SVNRMAX && - git fetch svnsim && - test_cmp master.good .git/refs/remotes/svnsim/master -' - -test_expect_success REMOTE_SVN 'respects configured default initial branch' ' - git -c init.defaultBranch=trunk remote add -f trunk \ - "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" && - git rev-parse --verify refs/remotes/trunk/trunk -' - -test_debug 'git branch -a' - -test_done diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 9f2d19ecc4..e4bb22034e 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -63,16 +63,16 @@ test_expect_success "$name" ' name='detect node change from file to directory #1' -test_expect_success "$name" " +test_expect_success "$name" ' mkdir dir/new_file && mv dir/file dir/new_file/file && mv dir/new_file dir/file && git update-index --remove dir/file && git update-index --add dir/file/file && - git commit -m '$name' && + git commit -m "$name" && test_must_fail git svn set-tree --find-copies-harder --rmdir \ remotes/git-svn..mybranch -" +' name='detect node change from directory to file #1' @@ -200,8 +200,9 @@ GIT_SVN_ID=alt export GIT_SVN_ID test_expect_success "$name" \ 'git svn init "$svnrepo" && git svn fetch && - git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && - git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && + git log --format="tree %T %s" remotes/git-svn | + awk "!seen[\$0]++ { print \$1, \$2 }" >a && + git log --format="tree %T" alt >b && test_cmp a b' name='check imported tree checksums expected tree checksums' diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index e151df81c0..308c1ef42c 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -92,7 +92,7 @@ test_expect_success 'A: create pack from stdin' ' EOF reset refs/tags/to-be-deleted - from 0000000000000000000000000000000000000000 + from $ZERO_OID tag nested mark :6 @@ -102,7 +102,7 @@ test_expect_success 'A: create pack from stdin' ' EOF reset refs/tags/nested - from 0000000000000000000000000000000000000000 + from $ZERO_OID tag nested mark :7 @@ -284,8 +284,9 @@ test_expect_success 'A: verify pack' ' ' test_expect_success 'A: verify diff' ' + copy=$(git rev-parse --verify master:file2) && cat >expect <<-EOF && - :000000 100755 0000000000000000000000000000000000000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 A copy-of-file2 + :000000 100755 $ZERO_OID $copy A copy-of-file2 EOF git diff-tree -M -r master verify--import-marks >actual && compare_diff_raw expect actual && @@ -364,7 +365,7 @@ test_expect_success 'B: fail on invalid blob sha1' ' COMMIT from refs/heads/master - M 755 0000000000000000000000000000000000000001 zero1 + M 755 $(echo $ZERO_OID | sed -e "s/0$/1/") zero1 INPUT_END @@ -528,6 +529,7 @@ test_expect_success 'B: fail on invalid committer (5)' ' test_expect_success 'C: incremental import create pack from stdin' ' newf=$(echo hi newf | git hash-object -w --stdin) && oldf=$(git rev-parse --verify master:file2) && + thrf=$(git rev-parse --verify master:file3) && test_tick && cat >input <<-INPUT_END && commit refs/heads/branch @@ -570,10 +572,11 @@ test_expect_success 'C: verify commit' ' ' test_expect_success 'C: validate rename result' ' + zero=$ZERO_OID && cat >expect <<-EOF && - :000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A file2/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2 file2/oldf - :100644 000000 0d92e9f3374ae2947c23aa477cbc68ce598135f1 0000000000000000000000000000000000000000 D file3 + :000000 100755 $zero $newf A file2/newf + :100644 100644 $oldf $oldf R100 file2 file2/oldf + :100644 000000 $thrf $zero D file3 EOF git diff-tree -M -r master branch >actual && compare_diff_raw expect actual @@ -614,9 +617,11 @@ test_expect_success 'D: verify pack' ' ' test_expect_success 'D: validate new files added' ' + f5id=$(echo "$file5_data" | git hash-object --stdin) && + f6id=$(echo "$file6_data" | git hash-object --stdin) && cat >expect <<-EOF && - :000000 100755 0000000000000000000000000000000000000000 e74b7d465e52746be2b4bae983670711e6e66657 A newdir/exec.sh - :000000 100644 0000000000000000000000000000000000000000 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 A newdir/interesting + :000000 100755 $ZERO_OID $f6id A newdir/exec.sh + :000000 100644 $ZERO_OID $f5id A newdir/interesting EOF git diff-tree -M -r branch^ branch >actual && compare_diff_raw expect actual @@ -779,12 +784,13 @@ test_expect_success 'H: verify pack' ' ' test_expect_success 'H: validate old files removed, new files added' ' + f4id=$(git rev-parse HEAD:file4) && cat >expect <<-EOF && - :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file2/newf - :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file2/oldf - :100755 000000 85df50785d62d3b05ab03d9cbf7e4a0b49449730 0000000000000000000000000000000000000000 D file4 - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting h/e/l/lo - :100755 000000 e74b7d465e52746be2b4bae983670711e6e66657 0000000000000000000000000000000000000000 D newdir/exec.sh + :100755 000000 $newf $zero D file2/newf + :100644 000000 $oldf $zero D file2/oldf + :100755 000000 $f4id $zero D file4 + :100644 100644 $f5id $f5id R100 newdir/interesting h/e/l/lo + :100755 000000 $f6id $zero D newdir/exec.sh EOF git diff-tree -M -r H^ H >actual && compare_diff_raw expect actual @@ -935,14 +941,15 @@ test_expect_success 'L: verify internal tree sorting' ' INPUT_END cat >expect <<-EXPECT_END && - :100644 100644 4268632... 55d3a52... M b. - :040000 040000 0ae5cac... 443c768... M b - :100644 100644 4268632... 55d3a52... M ba + :100644 100644 M b. + :040000 040000 M b + :100644 100644 M ba EXPECT_END git fast-import <input && GIT_PRINT_SHA1_ELLIPSIS="yes" git diff-tree --abbrev --raw L^ L >output && - test_cmp expect output + cut -d" " -f1,2,5 output >actual && + test_cmp expect actual ' test_expect_success 'L: nested tree copy does not corrupt deltas' ' @@ -1004,7 +1011,7 @@ test_expect_success 'M: rename file in same subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf file2/n.e.w.f + :100755 100755 $newf $newf R100 file2/newf file2/n.e.w.f EOF git fast-import <input && git diff-tree -M -r M1^ M1 >actual && @@ -1025,7 +1032,7 @@ test_expect_success 'M: rename file to new subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf i/am/new/to/you + :100755 100755 $newf $newf R100 file2/newf i/am/new/to/you EOF git fast-import <input && git diff-tree -M -r M2^ M2 >actual && @@ -1046,7 +1053,7 @@ test_expect_success 'M: rename subdirectory to new subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you other/sub/am/new/to/you + :100755 100755 $newf $newf R100 i/am/new/to/you other/sub/am/new/to/you EOF git fast-import <input && git diff-tree -M -r M3^ M3 >actual && @@ -1067,11 +1074,11 @@ test_expect_success 'M: rename root to subdirectory' ' INPUT_END cat >expect <<-EOF && - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2/oldf sub/file2/oldf - :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 R100 file4 sub/file4 - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you sub/i/am/new/to/you - :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100 newdir/exec.sh sub/newdir/exec.sh - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting sub/newdir/interesting + :100644 100644 $oldf $oldf R100 file2/oldf sub/file2/oldf + :100755 100755 $f4id $f4id R100 file4 sub/file4 + :100755 100755 $newf $newf R100 i/am/new/to/you sub/i/am/new/to/you + :100755 100755 $f6id $f6id R100 newdir/exec.sh sub/newdir/exec.sh + :100644 100644 $f5id $f5id R100 newdir/interesting sub/newdir/interesting EOF git fast-import <input && git diff-tree -M -r M4^ M4 >actual && @@ -1097,7 +1104,7 @@ test_expect_success 'N: copy file in same subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file2/n.e.w.f + :100755 100755 $newf $newf C100 file2/newf file2/n.e.w.f EOF git fast-import <input && git diff-tree -C --find-copies-harder -r N1^ N1 >actual && @@ -1129,9 +1136,9 @@ test_expect_success 'N: copy then modify subdirectory' ' INPUT_END cat >expect <<-EOF && - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + :100644 100644 $f5id $f5id C100 newdir/interesting file3/file5 + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF git fast-import <input && git diff-tree -C --find-copies-harder -r N2^^ N2 >actual && @@ -1162,9 +1169,9 @@ test_expect_success 'N: copy dirty subdirectory' ' ' test_expect_success 'N: copy directory by id' ' - cat >expect <<-\EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + cat >expect <<-EOF && + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF subdir=$(git rev-parse refs/heads/branch^0:file2) && cat >input <<-INPUT_END && @@ -1183,9 +1190,9 @@ test_expect_success 'N: copy directory by id' ' ' test_expect_success PIPE 'N: read and copy directory' ' - cat >expect <<-\EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + cat >expect <<-EOF && + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF git update-ref -d refs/heads/N4 && rm -f backflow && @@ -1254,9 +1261,9 @@ test_expect_success PIPE 'N: empty directory reads as missing' ' ' test_expect_success 'N: copy root directory by tree hash' ' - cat >expect <<-\EOF && - :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file3/newf - :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file3/oldf + cat >expect <<-EOF && + :100755 000000 $newf $zero D file3/newf + :100644 000000 $oldf $zero D file3/oldf EOF root=$(git rev-parse refs/heads/branch^0^{tree}) && cat >input <<-INPUT_END && @@ -1275,12 +1282,12 @@ test_expect_success 'N: copy root directory by tree hash' ' ' test_expect_success 'N: copy root by path' ' - cat >expect <<-\EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf oldroot/file2/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf oldroot/file2/oldf - :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 C100 file4 oldroot/file4 - :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 C100 newdir/exec.sh oldroot/newdir/exec.sh - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting oldroot/newdir/interesting + cat >expect <<-EOF && + :100755 100755 $newf $newf C100 file2/newf oldroot/file2/newf + :100644 100644 $oldf $oldf C100 file2/oldf oldroot/file2/oldf + :100755 100755 $f4id $f4id C100 file4 oldroot/file4 + :100755 100755 $f6id $f6id C100 newdir/exec.sh oldroot/newdir/exec.sh + :100644 100644 $f5id $f5id C100 newdir/interesting oldroot/newdir/interesting EOF cat >input <<-INPUT_END && commit refs/heads/N-copy-root-path @@ -1340,10 +1347,10 @@ test_expect_success 'N: delete directory by copying' ' ' test_expect_success 'N: modify copied tree' ' - cat >expect <<-\EOF && - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + cat >expect <<-EOF && + :100644 100644 $f5id $f5id C100 newdir/interesting file3/file5 + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF subdir=$(git rev-parse refs/heads/branch^0:file2) && cat >input <<-INPUT_END && @@ -2726,7 +2733,7 @@ test_expect_success 'R: corrupt lines do not mess marks file' ' rm -f io.marks && blob=$(echo hi | git hash-object --stdin) && cat >expect <<-EOF && - :3 0000000000000000000000000000000000000000 + :3 $ZERO_OID :1 $blob :2 $blob EOF @@ -3077,7 +3084,7 @@ test_expect_success 'T: delete branch' ' git branch to-delete && git fast-import <<-EOF && reset refs/heads/to-delete - from 0000000000000000000000000000000000000000 + from $ZERO_OID EOF test_must_fail git rev-parse --verify refs/heads/to-delete ' @@ -3117,6 +3124,9 @@ test_expect_success 'U: initialize for U tests' ' INPUT_END + f7id=$(echo "blob 1" | git hash-object --stdin) && + f8id=$(echo "sleep well" | git hash-object --stdin) && + f9id=$(echo "au revoir" | git hash-object --stdin) && git fast-import <input ' @@ -3137,7 +3147,7 @@ test_expect_success 'U: filedelete file succeeds' ' test_expect_success 'U: validate file delete result' ' cat >expect <<-EOF && - :100644 000000 2907ebb4bf85d91bf0716bb3bd8a68ef48d6da76 0000000000000000000000000000000000000000 D good/night.txt + :100644 000000 $f8id $ZERO_OID D good/night.txt EOF git diff-tree -M -r U^1 U >actual && @@ -3162,7 +3172,7 @@ test_expect_success 'U: filedelete directory succeeds' ' test_expect_success 'U: validate directory delete result' ' cat >expect <<-EOF && - :100644 000000 69cb75792f55123d8389c156b0b41c2ff00ed507 0000000000000000000000000000000000000000 D good/bye.txt + :100644 000000 $f9id $ZERO_OID D good/bye.txt EOF git diff-tree -M -r U^1 U >actual && @@ -3187,7 +3197,7 @@ test_expect_success 'U: filedelete root succeeds' ' test_expect_success 'U: validate root delete result' ' cat >expect <<-EOF && - :100644 000000 c18147dc648481eeb65dc5e66628429a64843327 0000000000000000000000000000000000000000 D hello.c + :100644 000000 $f7id $ZERO_OID D hello.c EOF git diff-tree -M -r U^1 U >actual && diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh index ca223dca98..14c1baa739 100755 --- a/t/t9301-fast-import-notes.sh +++ b/t/t9301-fast-import-notes.sh @@ -470,12 +470,13 @@ test_expect_success 'add lots of commits and notes' ' ' test_expect_success 'verify that lots of notes trigger a fanout scheme' ' + hexsz=$(test_oid hexsz) && # None of the entries in the top-level notes tree should be a full SHA1 git ls-tree --name-only refs/notes/many_notes | while read path do - if test $(expr length "$path") -ge 40 + if test $(expr length "$path") -ge $hexsz then return 1 fi @@ -518,7 +519,7 @@ test_expect_success 'verify that importing a notes tree respects the fanout sche git ls-tree --name-only refs/notes/other_notes | while read path do - if test $(expr length "$path") -ge 40 + if test $(expr length "$path") -ge $hexsz then return 1 fi @@ -593,7 +594,7 @@ test_expect_success 'verify that changing notes respect existing fanout' ' git ls-tree --name-only refs/notes/many_notes | while read path do - if test $(expr length "$path") -ge 40 + if test $(expr length "$path") -ge $hexsz then return 1 fi @@ -616,7 +617,7 @@ i=$(($num_commits - $remaining_notes)) for sha1 in $(git rev-list -n $i refs/heads/many_commits) do cat >>input <<INPUT_END -N 0000000000000000000000000000000000000000 $sha1 +N $ZERO_OID $sha1 INPUT_END done @@ -646,7 +647,6 @@ test_expect_success 'remove lots of notes' ' ' test_expect_success 'verify that removing notes trigger fanout consolidation' ' - # All entries in the top-level notes tree should be a full SHA1 git ls-tree --name-only -r refs/notes/many_notes | while read path @@ -656,7 +656,7 @@ test_expect_success 'verify that removing notes trigger fanout consolidation' ' test "$path" = "deadbeef" && continue test "$path" = "de/adbeef" && continue - if test $(expr length "$path") -ne 40 + if test $(expr length "$path") -ne $hexsz then return 1 fi diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 690c90fb82..1372842559 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -132,12 +132,12 @@ test_expect_success 'reencoding iso-8859-7' ' sed "s/wer/i18n/" iso-8859-7.fi | (cd new && git fast-import && - # The commit object, if not re-encoded, would be 240 bytes. + # The commit object, if not re-encoded, would be 200 bytes plus hash. # Removing the "encoding iso-8859-7\n" header drops 20 bytes. # Re-encoding the Pi character from \xF0 (\360) in iso-8859-7 # to \xCF\x80 (\317\200) in UTF-8 adds a byte. Check for # the expected size. - test 221 -eq "$(git cat-file -s i18n)" && + test $(($(test_oid hexsz) + 181)) -eq "$(git cat-file -s i18n)" && # ...and for the expected translation of bytes. git cat-file commit i18n >actual && grep $(printf "\317\200") actual && @@ -164,12 +164,12 @@ test_expect_success 'preserving iso-8859-7' ' sed "s/wer/i18n-no-recoding/" iso-8859-7.fi | (cd new && git fast-import && - # The commit object, if not re-encoded, is 240 bytes. + # The commit object, if not re-encoded, is 200 bytes plus hash. # Removing the "encoding iso-8859-7\n" header would drops 20 # bytes. Re-encoding the Pi character from \xF0 (\360) in # iso-8859-7 to \xCF\x80 (\317\200) in UTF-8 adds a byte. # Check for the expected size... - test 240 -eq "$(git cat-file -s i18n-no-recoding)" && + test $(($(test_oid hexsz) + 200)) -eq "$(git cat-file -s i18n-no-recoding)" && # ...as well as the expected byte. git cat-file commit i18n-no-recoding >actual && grep $(printf "\360") actual && @@ -192,7 +192,7 @@ test_expect_success 'encoding preserved if reencoding fails' ' grep ^encoding actual && # Verify that the commit has the expected size; i.e. # that no bytes were re-encoded to a different encoding. - test 252 -eq "$(git cat-file -s i18n-invalid)" && + test $(($(test_oid hexsz) + 212)) -eq "$(git cat-file -s i18n-invalid)" && # ...and check for the original special bytes grep $(printf "\360") actual && grep $(printf "\377") actual) @@ -694,7 +694,7 @@ test_expect_success 'delete ref because entire history excluded' ' git fast-export to-delete ^to-delete >actual && cat >expected <<-EOF && reset refs/heads/to-delete - from 0000000000000000000000000000000000000000 + from $ZERO_OID EOF test_cmp expected actual @@ -704,7 +704,7 @@ test_expect_success 'delete refspec' ' git fast-export --refspec :refs/heads/to-delete >actual && cat >expected <<-EOF && reset refs/heads/to-delete - from 0000000000000000000000000000000000000000 + from $ZERO_OID EOF test_cmp expected actual diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index a5e5dca753..4a46f31c41 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -603,7 +603,7 @@ test_expect_success 'cvs server does not run with vanilla git-shell' ' cd cvswork && CVS_SERVER=$WORKDIR/remote-cvs && export CVS_SERVER && - test_must_fail cvs log merge + ! cvs log merge ) ' diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index 84787eee9a..c7a0dd84a4 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -167,10 +167,10 @@ test_expect_success 'adding files' ' test_expect_success 'updating' ' git pull gitcvs.git && - echo 'hi' > subdir/newfile.bin && - echo 'junk' > subdir/file.h && - echo 'hi' > subdir/newfile.c && - echo 'hello' >> binfile.bin && + echo "hi" >subdir/newfile.bin && + echo "junk" >subdir/file.h && + echo "hi" >subdir/newfile.c && + echo "hello" >>binfile.bin && git add subdir/newfile.bin subdir/file.h subdir/newfile.c binfile.bin && git commit -q -m "Add and change some files" && git push gitcvs.git >/dev/null && diff --git a/t/t9402-git-cvsserver-refs.sh b/t/t9402-git-cvsserver-refs.sh index cf31ace667..6436c91a3c 100755 --- a/t/t9402-git-cvsserver-refs.sh +++ b/t/t9402-git-cvsserver-refs.sh @@ -178,7 +178,7 @@ test_expect_success 'setup v1.2 on b1' ' mkdir cdir && echo "cdir/cfile" >cdir/cfile && git add -A cdir adir t3 t2 && - git commit -q -m 'v1.2' && + git commit -q -m "v1.2" && git tag v1.2 && git push --tags gitcvs.git b1:b1 ' diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 267ddc997d..b484e3e250 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -621,12 +621,22 @@ test_expect_success \ git config gitweb.snapshot "zip,tgz, tbz2" && gitweb_run "p=.git;a=tree"' -cat >.git/config <<\EOF -# testing noval and alternate separator -[gitweb] - blame - snapshot = zip tgz -EOF +test_expect_success 'setup' ' + version=$(git config core.repositoryformatversion) && + algo=$(test_might_fail git config extensions.objectformat) && + cat >.git/config <<-\EOF && + # testing noval and alternate separator + [gitweb] + blame + snapshot = zip tgz + EOF + git config core.repositoryformatversion "$version" && + if test -n "$algo" + then + git config extensions.objectformat "$algo" + fi +' + test_expect_success \ 'config override: tree view, features enabled in repo config (2)' \ 'gitweb_run "p=.git;a=tree"' diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 34cd01366f..e046f7db76 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -23,6 +23,8 @@ sub adjust_dirsep { return $path; } +my $oid_re = qr/^[0-9a-fA-F]{40}(?:[0-9a-fA-F]{24})?$/; + BEGIN { use_ok('Git') } # set up @@ -59,15 +61,15 @@ ok($@, "config_bool: non-boolean values fail"); open STDERR, ">&", $tmpstderr or die "cannot restore STDERR"; # ident -like($r->ident("aUthor"), qr/^A U Thor <author\@example.com> [0-9]+ \+0000$/, +like($r->ident("aUthor"), qr/^A U Thor <author\@example.com> [0-9]+ [+-]\d{4}$/, "ident scalar: author (type)"); -like($r->ident("cOmmitter"), qr/^C O Mitter <committer\@example.com> [0-9]+ \+0000$/, +like($r->ident("cOmmitter"), qr/^C O Mitter <committer\@example.com> [0-9]+ [+-]\d{4}$/, "ident scalar: committer (type)"); is($r->ident("invalid"), "invalid", "ident scalar: invalid ident string (no parsing)"); my ($name, $email, $time_tz) = $r->ident('author'); is_deeply([$name, $email], ["A U Thor", "author\@example.com"], "ident array: author"); -like($time_tz, qr/[0-9]+ \+0000/, "ident array: author"); +like($time_tz, qr/[0-9]+ [+-]\d{4}/, "ident array: author"); is_deeply([$r->ident("Name <email> 123 +0000")], ["Name", "email", "123 +0000"], "ident array: ident string"); is_deeply([$r->ident("invalid")], [], "ident array: invalid ident string"); @@ -93,7 +95,7 @@ is(Git::hash_object("blob", $tmpfile), $file1hash, "hash_object: roundtrip"); open TEMPFILE, ">$tmpfile" or die "Can't open $tmpfile: $!"; print TEMPFILE my $test_text = "test blob, to be inserted\n"; close TEMPFILE or die "Failed writing to $tmpfile: $!"; -like(our $newhash = $r->hash_and_insert_object($tmpfile), qr/[0-9a-fA-F]{40}/, +like(our $newhash = $r->hash_and_insert_object($tmpfile), $oid_re, "hash_and_insert_object: returns hash"); open TEMPFILE, "+>$tmpfile" or die "Can't open $tmpfile: $!"; is($r->cat_blob($newhash, \*TEMPFILE), length $test_text, "cat_blob: roundtrip size"); @@ -119,7 +121,7 @@ is($r2->wc_subdir, "directory2/", "wc_subdir initial (2)"); # commands in sub directory my $last_commit = $r2->command_oneline(qw(rev-parse --verify HEAD)); -like($last_commit, qr/^[0-9a-fA-F]{40}$/, 'rev-parse returned hash'); +like($last_commit, $oid_re, 'rev-parse returned hash'); my $dir_commit = $r2->command_oneline('log', '-n1', '--pretty=format:%H', '.'); isnt($last_commit, $dir_commit, 'log . does not show last commit'); diff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh index e9276c48f4..7194fb2855 100755 --- a/t/t9832-unshelve.sh +++ b/t/t9832-unshelve.sh @@ -29,8 +29,11 @@ test_expect_success 'init depot' ' ) ' +# Create an initial clone, with a commit unrelated to the P4 change +# on HEAD test_expect_success 'initial clone' ' - git p4 clone --dest="$git" //depot/@all + git p4 clone --dest="$git" //depot/@all && + test_commit -C "$git" "unrelated" ' test_expect_success 'create shelved changelist' ' diff --git a/t/t9834-git-p4-file-dir-bug.sh b/t/t9834-git-p4-file-dir-bug.sh index 031e1f8668..dac67e89d7 100755 --- a/t/t9834-git-p4-file-dir-bug.sh +++ b/t/t9834-git-p4-file-dir-bug.sh @@ -10,7 +10,7 @@ repository.' test_expect_success 'start p4d' ' start_p4d && - test_might_fail p4 configure set submit.collision.check=0 + { p4 configure set submit.collision.check=0 || :; } ' test_expect_success 'init depot' ' diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 3103be8a32..8d59b90348 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -798,6 +798,37 @@ list_contains () { return 1 } +# Returns success if the arguments indicate that a command should be +# accepted by test_must_fail(). If the command is run with env, the env +# and its corresponding variable settings will be stripped before we +# test the command being run. +test_must_fail_acceptable () { + if test "$1" = "env" + then + shift + while test $# -gt 0 + do + case "$1" in + *?=*) + shift + ;; + *) + break + ;; + esac + done + fi + + case "$1" in + git|__git*|test-tool|test_terminal) + return 0 + ;; + *) + return 1 + ;; + esac +} + # This is not among top-level (test_expect_success | test_expect_failure) # but is a prefix that can be used in the test script, like: # @@ -817,6 +848,17 @@ list_contains () { # Multiple signals can be specified as a comma separated list. # Currently recognized signal names are: sigpipe, success. # (Don't use 'success', use 'test_might_fail' instead.) +# +# Do not use this to run anything but "git" and other specific testable +# commands (see test_must_fail_acceptable()). We are not in the +# business of vetting system supplied commands -- in other words, this +# is wrong: +# +# test_must_fail grep pattern output +# +# Instead use '!': +# +# ! grep pattern output test_must_fail () { case "$1" in @@ -828,6 +870,11 @@ test_must_fail () { _test_ok= ;; esac + if ! test_must_fail_acceptable "$@" + then + echo >&7 "test_must_fail: only 'git' is allowed: $*" + return 1 + fi "$@" 2>&7 exit_code=$? if test $exit_code -eq 0 && ! list_contains "$_test_ok" success @@ -905,7 +952,13 @@ test_expect_code () { # - not all diff versions understand "-u" test_cmp() { - eval "$GIT_TEST_CMP" '"$@"' + test $# -eq 2 || BUG "test_cmp requires two arguments" + if ! eval "$GIT_TEST_CMP" '"$@"' + then + test "x$1" = x- || test -e "$1" || BUG "test_cmp '$1' missing" + test "x$2" = x- || test -e "$2" || BUG "test_cmp '$2' missing" + return 1 + fi } # Check that the given config key has the expected value. @@ -934,7 +987,13 @@ test_cmp_config() { # test_cmp_bin - helper to compare binary files test_cmp_bin() { - cmp "$@" + test $# -eq 2 || BUG "test_cmp_bin requires two arguments" + if ! cmp "$@" + then + test "x$1" = x- || test -e "$1" || BUG "test_cmp_bin '$1' missing" + test "x$2" = x- || test -e "$2" || BUG "test_cmp_bin '$2' missing" + return 1 + fi } # Use this instead of test_cmp to compare files that contain expected and @@ -1417,9 +1476,7 @@ test_set_hash () { # Detect the hash algorithm in use. test_detect_hash () { - # Currently we only support SHA-1, but in the future this function will - # actually detect the algorithm in use. - test_hash_algo='sha1' + test_hash_algo="${GIT_TEST_DEFAULT_HASH:-sha1}" } # Load common hash metadata and common placeholder object IDs for use with @@ -1468,7 +1525,17 @@ test_oid_cache () { # Look up a per-hash value based on a key ($1). The value must have been loaded # by test_oid_init or test_oid_cache. test_oid () { - local var="test_oid_${test_hash_algo}_$1" && + local algo="${test_hash_algo}" && + + case "$1" in + --hash=*) + algo="${1#--hash=}" && + shift;; + *) + ;; + esac && + + local var="test_oid_${algo}_$1" && # If the variable is unset, we must be missing an entry for this # key-hash pair, so exit with an error. @@ -1561,3 +1628,36 @@ test_path_is_hidden () { case "$("$SYSTEMROOT"/system32/attrib "$1")" in *H*?:*) return 0;; esac return 1 } + +# Check that the given command was invoked as part of the +# trace2-format trace on stdin. +# +# test_subcommand [!] <command> <args>... < <trace> +# +# For example, to look for an invocation of "git upload-pack +# /path/to/repo" +# +# GIT_TRACE2_EVENT=event.log git fetch ... && +# test_subcommand git upload-pack "$PATH" <event.log +# +# If the first parameter passed is !, this instead checks that +# the given command was not called. +# +test_subcommand () { + local negate= + if test "$1" = "!" + then + negate=t + shift + fi + + local expr=$(printf '"%s",' "$@") + expr="${expr%,}" + + if test -n "$negate" + then + ! grep "\[$expr\]" + else + grep "\[$expr\]" + fi +} diff --git a/t/test-lib.sh b/t/test-lib.sh index 618a7c8d5b..ef31f40037 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -441,17 +441,23 @@ TEST_AUTHOR_LOCALNAME=author TEST_AUTHOR_DOMAIN=example.com GIT_AUTHOR_EMAIL=${TEST_AUTHOR_LOCALNAME}@${TEST_AUTHOR_DOMAIN} GIT_AUTHOR_NAME='A U Thor' +GIT_AUTHOR_DATE='1112354055 +0200' TEST_COMMITTER_LOCALNAME=committer TEST_COMMITTER_DOMAIN=example.com GIT_COMMITTER_EMAIL=${TEST_COMMITTER_LOCALNAME}@${TEST_COMMITTER_DOMAIN} GIT_COMMITTER_NAME='C O Mitter' +GIT_COMMITTER_DATE='1112354055 +0200' GIT_MERGE_VERBOSITY=5 GIT_MERGE_AUTOEDIT=no export GIT_MERGE_VERBOSITY GIT_MERGE_AUTOEDIT export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME +export GIT_COMMITTER_DATE GIT_AUTHOR_DATE export EDITOR +GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-sha1}" +export GIT_DEFAULT_HASH + # Tests using GIT_TRACE typically don't want <timestamp> <file>:<line> output GIT_TRACE_BARE=1 export GIT_TRACE_BARE @@ -1686,7 +1692,11 @@ test_lazy_prereq CURL ' # which will not work with other hash algorithms and tests that work but don't # test anything meaningful (e.g. special values which cause short collisions). test_lazy_prereq SHA1 ' - test $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 + case "$GIT_DEFAULT_HASH" in + sha1) true ;; + "") test $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 ;; + *) false ;; + esac ' test_lazy_prereq REBASE_P ' |