From: Junio C Hamano Date: Thu, 10 Mar 2016 19:13:38 +0000 (-0800) Subject: Merge branch 'jk/epipe-in-async' into maint X-Git-Tag: v2.7.3~17 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/fbef03d6ab6b9ee23ba1cf895f47314fe4308d2c?hp=43f3afc6bc6b79715ea46aaf341683cbba6ee965 Merge branch 'jk/epipe-in-async' into maint Handling of errors while writing into our internal asynchronous process has been made more robust, which reduces flakiness in our tests. * jk/epipe-in-async: t5504: handle expected output from SIGPIPE death test_must_fail: report number of unexpected signal fetch-pack: ignore SIGPIPE in sideband demuxer write_or_die: handle EPIPE in async threads --- diff --git a/branch.c b/branch.c index 7ff3f20496..c50ea42172 100644 --- a/branch.c +++ b/branch.c @@ -49,7 +49,13 @@ static int should_setup_rebase(const char *origin) return 0; } -void install_branch_config(int flag, const char *local, const char *origin, const char *remote) +static const char tracking_advice[] = +N_("\n" +"After fixing the error cause you may try to fix up\n" +"the remote tracking information by invoking\n" +"\"git branch --set-upstream-to=%s%s%s\"."); + +int install_branch_config(int flag, const char *local, const char *origin, const char *remote) { const char *shortname = NULL; struct strbuf key = STRBUF_INIT; @@ -60,20 +66,23 @@ void install_branch_config(int flag, const char *local, const char *origin, cons && !origin) { warning(_("Not setting branch %s as its own upstream."), local); - return; + return 0; } strbuf_addf(&key, "branch.%s.remote", local); - git_config_set(key.buf, origin ? origin : "."); + if (git_config_set_gently(key.buf, origin ? origin : ".") < 0) + goto out_err; strbuf_reset(&key); strbuf_addf(&key, "branch.%s.merge", local); - git_config_set(key.buf, remote); + if (git_config_set_gently(key.buf, remote) < 0) + goto out_err; if (rebasing) { strbuf_reset(&key); strbuf_addf(&key, "branch.%s.rebase", local); - git_config_set(key.buf, "true"); + if (git_config_set_gently(key.buf, "true") < 0) + goto out_err; } strbuf_release(&key); @@ -102,6 +111,19 @@ void install_branch_config(int flag, const char *local, const char *origin, cons local, remote); } } + + return 0; + +out_err: + strbuf_release(&key); + error(_("Unable to write upstream branch configuration")); + + advise(_(tracking_advice), + origin ? origin : "", + origin ? "/" : "", + shortname ? shortname : remote); + + return -1; } /* @@ -109,8 +131,8 @@ void install_branch_config(int flag, const char *local, const char *origin, cons * to infer the settings for branch..{remote,merge} from the * config. */ -static int setup_tracking(const char *new_ref, const char *orig_ref, - enum branch_track track, int quiet) +static void setup_tracking(const char *new_ref, const char *orig_ref, + enum branch_track track, int quiet) { struct tracking tracking; int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE; @@ -118,7 +140,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref, memset(&tracking, 0, sizeof(tracking)); tracking.spec.dst = (char *)orig_ref; if (for_each_remote(find_tracked_branch, &tracking)) - return 1; + return; if (!tracking.matches) switch (track) { @@ -127,18 +149,18 @@ static int setup_tracking(const char *new_ref, const char *orig_ref, case BRANCH_TRACK_OVERRIDE: break; default: - return 1; + return; } if (tracking.matches > 1) - return error(_("Not tracking: ambiguous information for ref %s"), - orig_ref); + die(_("Not tracking: ambiguous information for ref %s"), + orig_ref); - install_branch_config(config_flags, new_ref, tracking.remote, - tracking.src ? tracking.src : orig_ref); + if (install_branch_config(config_flags, new_ref, tracking.remote, + tracking.src ? tracking.src : orig_ref) < 0) + exit(-1); free(tracking.src); - return 0; } int read_branch_desc(struct strbuf *buf, const char *branch_name) diff --git a/branch.h b/branch.h index 58aa45fe72..78ad4387cd 100644 --- a/branch.h +++ b/branch.h @@ -43,9 +43,10 @@ void remove_branch_state(void); /* * Configure local branch "local" as downstream to branch "remote" * from remote "origin". Used by git branch --set-upstream. + * Returns 0 on success. */ #define BRANCH_CONFIG_VERBOSE 01 -extern void install_branch_config(int flag, const char *local, const char *origin, const char *remote); +extern int install_branch_config(int flag, const char *local, const char *origin, const char *remote); /* * Read branch description diff --git a/builtin/branch.c b/builtin/branch.c index 3f6c825db1..7b45b6bd6b 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -570,7 +570,6 @@ static const char edit_description[] = "BRANCH_DESCRIPTION"; static int edit_branch_description(const char *branch_name) { - int status; struct strbuf buf = STRBUF_INIT; struct strbuf name = STRBUF_INIT; @@ -595,11 +594,11 @@ static int edit_branch_description(const char *branch_name) strbuf_stripspace(&buf, 1); strbuf_addf(&name, "branch.%s.description", branch_name); - status = git_config_set(name.buf, buf.len ? buf.buf : NULL); + git_config_set(name.buf, buf.len ? buf.buf : NULL); strbuf_release(&name); strbuf_release(&buf); - return status; + return 0; } int cmd_branch(int argc, const char **argv, const char *prefix) diff --git a/builtin/clone.c b/builtin/clone.c index a0b3cd9e56..8a90cad5b5 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -732,7 +732,7 @@ static int checkout(void) static int write_one_config(const char *key, const char *value, void *data) { - return git_config_set_multivar(key, value ? value : "true", "^$", 0); + return git_config_set_multivar_gently(key, value ? value : "true", "^$", 0); } static void write_config(struct string_list *config) diff --git a/builtin/config.c b/builtin/config.c index adc772786a..c26d6e7fdd 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -582,7 +582,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_write(); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1]); - ret = git_config_set_in_file(given_config_source.file, argv[0], value); + ret = git_config_set_in_file_gently(given_config_source.file, argv[0], value); if (ret == CONFIG_NOTHING_SET) error("cannot overwrite multiple values with a single value\n" " Use a regexp, --add or --replace-all to change %s.", argv[0]); @@ -592,23 +592,23 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_write(); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1]); - return git_config_set_multivar_in_file(given_config_source.file, - argv[0], value, argv[2], 0); + return git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, argv[2], 0); } else if (actions == ACTION_ADD) { check_write(); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1]); - return git_config_set_multivar_in_file(given_config_source.file, - argv[0], value, - CONFIG_REGEX_NONE, 0); + return git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, + CONFIG_REGEX_NONE, 0); } else if (actions == ACTION_REPLACE_ALL) { check_write(); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1]); - return git_config_set_multivar_in_file(given_config_source.file, - argv[0], value, argv[2], 1); + return git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, argv[2], 1); } else if (actions == ACTION_GET) { check_argc(argc, 1, 2); @@ -634,17 +634,17 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_write(); check_argc(argc, 1, 2); if (argc == 2) - return git_config_set_multivar_in_file(given_config_source.file, - argv[0], NULL, argv[1], 0); + return git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], NULL, argv[1], 0); else - return git_config_set_in_file(given_config_source.file, - argv[0], NULL); + return git_config_set_in_file_gently(given_config_source.file, + argv[0], NULL); } else if (actions == ACTION_UNSET_ALL) { check_write(); check_argc(argc, 1, 2); - return git_config_set_multivar_in_file(given_config_source.file, - argv[0], NULL, argv[1], 1); + return git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], NULL, argv[1], 1); } else if (actions == ACTION_RENAME_SECTION) { int ret; diff --git a/builtin/init-db.c b/builtin/init-db.c index 07229d60f1..6223b7d46a 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -250,7 +250,7 @@ static int create_default_files(const char *template_path) git_config_set("core.bare", "false"); /* allow template config file to override the default */ if (log_all_ref_updates == -1) - git_config_set("core.logallrefupdates", "true"); + git_config_set("core.logallrefupdates", "true"); if (needs_work_tree_config(get_git_dir(), work_tree)) git_config_set("core.worktree", work_tree); } diff --git a/builtin/remote.c b/builtin/remote.c index 6694cf20ef..43136951b5 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -108,8 +108,8 @@ enum { #define MIRROR_PUSH 2 #define MIRROR_BOTH (MIRROR_FETCH|MIRROR_PUSH) -static int add_branch(const char *key, const char *branchname, - const char *remotename, int mirror, struct strbuf *tmp) +static void add_branch(const char *key, const char *branchname, + const char *remotename, int mirror, struct strbuf *tmp) { strbuf_reset(tmp); strbuf_addch(tmp, '+'); @@ -119,7 +119,7 @@ static int add_branch(const char *key, const char *branchname, else strbuf_addf(tmp, "refs/heads/%s:refs/remotes/%s/%s", branchname, remotename, branchname); - return git_config_set_multivar(key, tmp->buf, "^$", 0); + git_config_set_multivar(key, tmp->buf, "^$", 0); } static const char mirror_advice[] = @@ -197,8 +197,7 @@ static int add(int argc, const char **argv) die(_("'%s' is not a valid remote name"), name); strbuf_addf(&buf, "remote.%s.url", name); - if (git_config_set(buf.buf, url)) - return 1; + git_config_set(buf.buf, url); if (!mirror || mirror & MIRROR_FETCH) { strbuf_reset(&buf); @@ -206,25 +205,22 @@ static int add(int argc, const char **argv) if (track.nr == 0) string_list_append(&track, "*"); for (i = 0; i < track.nr; i++) { - if (add_branch(buf.buf, track.items[i].string, - name, mirror, &buf2)) - return 1; + add_branch(buf.buf, track.items[i].string, + name, mirror, &buf2); } } if (mirror & MIRROR_PUSH) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.mirror", name); - if (git_config_set(buf.buf, "true")) - return 1; + git_config_set(buf.buf, "true"); } if (fetch_tags != TAGS_DEFAULT) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.tagopt", name); - if (git_config_set(buf.buf, - fetch_tags == TAGS_SET ? "--tags" : "--no-tags")) - return 1; + git_config_set(buf.buf, + fetch_tags == TAGS_SET ? "--tags" : "--no-tags"); } if (fetch && fetch_remote(name)) @@ -590,25 +586,20 @@ static int migrate_file(struct remote *remote) strbuf_addf(&buf, "remote.%s.url", remote->name); for (i = 0; i < remote->url_nr; i++) - if (git_config_set_multivar(buf.buf, remote->url[i], "^$", 0)) - return error(_("Could not append '%s' to '%s'"), - remote->url[i], buf.buf); + git_config_set_multivar(buf.buf, remote->url[i], "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.push", remote->name); for (i = 0; i < remote->push_refspec_nr; i++) - if (git_config_set_multivar(buf.buf, remote->push_refspec[i], "^$", 0)) - return error(_("Could not append '%s' to '%s'"), - remote->push_refspec[i], buf.buf); + git_config_set_multivar(buf.buf, remote->push_refspec[i], "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", remote->name); for (i = 0; i < remote->fetch_refspec_nr; i++) - if (git_config_set_multivar(buf.buf, remote->fetch_refspec[i], "^$", 0)) - return error(_("Could not append '%s' to '%s'"), - remote->fetch_refspec[i], buf.buf); + git_config_set_multivar(buf.buf, remote->fetch_refspec[i], "^$", 0); if (remote->origin == REMOTE_REMOTES) unlink_or_warn(git_path("remotes/%s", remote->name)); else if (remote->origin == REMOTE_BRANCHES) unlink_or_warn(git_path("branches/%s", remote->name)); + return 0; } @@ -655,8 +646,7 @@ static int mv(int argc, const char **argv) strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", rename.new); - if (git_config_set_multivar(buf.buf, NULL, NULL, 1)) - return error(_("Could not remove config section '%s'"), buf.buf); + git_config_set_multivar(buf.buf, NULL, NULL, 1); strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old); for (i = 0; i < oldremote->fetch_refspec_nr; i++) { char *ptr; @@ -676,8 +666,7 @@ static int mv(int argc, const char **argv) "\tPlease update the configuration manually if necessary."), buf2.buf); - if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0)) - return error(_("Could not append '%s'"), buf.buf); + git_config_set_multivar(buf.buf, buf2.buf, "^$", 0); } read_branches(); @@ -687,9 +676,7 @@ static int mv(int argc, const char **argv) if (info->remote_name && !strcmp(info->remote_name, rename.old)) { strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.remote", item->string); - if (git_config_set(buf.buf, rename.new)) { - return error(_("Could not set '%s'"), buf.buf); - } + git_config_set(buf.buf, rename.new); } } @@ -787,10 +774,7 @@ static int rm(int argc, const char **argv) strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.%s", item->string, *k); - if (git_config_set(buf.buf, NULL)) { - strbuf_release(&buf); - return -1; - } + git_config_set(buf.buf, NULL); } } } @@ -1409,24 +1393,20 @@ static int update(int argc, const char **argv) static int remove_all_fetch_refspecs(const char *remote, const char *key) { - return git_config_set_multivar(key, NULL, NULL, 1); + return git_config_set_multivar_gently(key, NULL, NULL, 1); } -static int add_branches(struct remote *remote, const char **branches, - const char *key) +static void add_branches(struct remote *remote, const char **branches, + const char *key) { const char *remotename = remote->name; int mirror = remote->mirror; struct strbuf refspec = STRBUF_INIT; for (; *branches; branches++) - if (add_branch(key, *branches, remotename, mirror, &refspec)) { - strbuf_release(&refspec); - return 1; - } + add_branch(key, *branches, remotename, mirror, &refspec); strbuf_release(&refspec); - return 0; } static int set_remote_branches(const char *remotename, const char **branches, @@ -1445,10 +1425,7 @@ static int set_remote_branches(const char *remotename, const char **branches, strbuf_release(&key); return 1; } - if (add_branches(remote, branches, key.buf)) { - strbuf_release(&key); - return 1; - } + add_branches(remote, branches, key.buf); strbuf_release(&key); return 0; @@ -1580,10 +1557,11 @@ static int set_url(int argc, const char **argv) if ((!oldurl && !delete_mode) || add_mode) { if (add_mode) git_config_set_multivar(name_buf.buf, newurl, - "^$", 0); + "^$", 0); else git_config_set(name_buf.buf, newurl); strbuf_release(&name_buf); + return 0; } diff --git a/cache.h b/cache.h index 015d53bdff..e2e64d188e 100644 --- a/cache.h +++ b/cache.h @@ -1485,7 +1485,7 @@ extern int update_server_info(int); /* git_config_parse_key() returns these negated: */ #define CONFIG_INVALID_KEY 1 #define CONFIG_NO_SECTION_OR_NAME 2 -/* git_config_set(), git_config_set_multivar() return the above or these: */ +/* git_config_set_gently(), git_config_set_multivar_gently() return the above or these: */ #define CONFIG_NO_LOCK -1 #define CONFIG_INVALID_FILE 3 #define CONFIG_NO_WRITE 4 @@ -1523,12 +1523,16 @@ extern int git_config_bool(const char *, const char *); extern int git_config_maybe_bool(const char *, const char *); extern int git_config_string(const char **, const char *, const char *); extern int git_config_pathname(const char **, const char *, const char *); -extern int git_config_set_in_file(const char *, const char *, const char *); -extern int git_config_set(const char *, const char *); +extern int git_config_set_in_file_gently(const char *, const char *, const char *); +extern void git_config_set_in_file(const char *, const char *, const char *); +extern int git_config_set_gently(const char *, const char *); +extern void git_config_set(const char *, const char *); extern int git_config_parse_key(const char *, char **, int *); extern int git_config_key_is_valid(const char *key); -extern int git_config_set_multivar(const char *, const char *, const char *, int); -extern int git_config_set_multivar_in_file(const char *, const char *, const char *, const char *, int); +extern int git_config_set_multivar_gently(const char *, const char *, const char *, int); +extern void git_config_set_multivar(const char *, const char *, const char *, int); +extern int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, int); +extern void git_config_set_multivar_in_file(const char *, const char *, const char *, const char *, int); extern int git_config_rename_section(const char *, const char *); extern int git_config_rename_section_in_file(const char *, const char *, const char *); extern const char *git_etc_gitconfig(void); diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 079070ff1d..dfbe6d8408 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -50,7 +50,8 @@ void probe_utf8_pathname_composition(void) close(output_fd); git_path_buf(&path, "%s", auml_nfd); precomposed_unicode = access(path.buf, R_OK) ? 0 : 1; - git_config_set("core.precomposeunicode", precomposed_unicode ? "true" : "false"); + git_config_set("core.precomposeunicode", + precomposed_unicode ? "true" : "false"); git_path_buf(&path, "%s", auml_nfc); if (unlink(path.buf)) die_errno(_("failed to unlink '%s'"), path.buf); diff --git a/config.c b/config.c index 86a5eb2571..325c3eaf9d 100644 --- a/config.c +++ b/config.c @@ -1825,15 +1825,26 @@ static ssize_t find_beginning_of_line(const char *contents, size_t size, return offset; } -int git_config_set_in_file(const char *config_filename, - const char *key, const char *value) +int git_config_set_in_file_gently(const char *config_filename, + const char *key, const char *value) { - return git_config_set_multivar_in_file(config_filename, key, value, NULL, 0); + return git_config_set_multivar_in_file_gently(config_filename, key, value, NULL, 0); } -int git_config_set(const char *key, const char *value) +void git_config_set_in_file(const char *config_filename, + const char *key, const char *value) { - return git_config_set_multivar(key, value, NULL, 0); + git_config_set_multivar_in_file(config_filename, key, value, NULL, 0); +} + +int git_config_set_gently(const char *key, const char *value) +{ + return git_config_set_multivar_gently(key, value, NULL, 0); +} + +void git_config_set(const char *key, const char *value) +{ + git_config_set_multivar(key, value, NULL, 0); } /* @@ -1950,9 +1961,10 @@ int git_config_key_is_valid(const char *key) * - the config file is removed and the lock file rename()d to it. * */ -int git_config_set_multivar_in_file(const char *config_filename, - const char *key, const char *value, - const char *value_regex, int multi_replace) +int git_config_set_multivar_in_file_gently(const char *config_filename, + const char *key, const char *value, + const char *value_regex, + int multi_replace) { int fd = -1, in_fd = -1; int ret; @@ -2179,11 +2191,27 @@ int git_config_set_multivar_in_file(const char *config_filename, } -int git_config_set_multivar(const char *key, const char *value, - const char *value_regex, int multi_replace) +void git_config_set_multivar_in_file(const char *config_filename, + const char *key, const char *value, + const char *value_regex, int multi_replace) +{ + if (git_config_set_multivar_in_file_gently(config_filename, key, value, + value_regex, multi_replace) < 0) + die(_("Could not set '%s' to '%s'"), key, value); +} + +int git_config_set_multivar_gently(const char *key, const char *value, + const char *value_regex, int multi_replace) +{ + return git_config_set_multivar_in_file_gently(NULL, key, value, value_regex, + multi_replace); +} + +void git_config_set_multivar(const char *key, const char *value, + const char *value_regex, int multi_replace) { - return git_config_set_multivar_in_file(NULL, key, value, value_regex, - multi_replace); + git_config_set_multivar_in_file(NULL, key, value, value_regex, + multi_replace); } static int section_name_match (const char *buf, const char *name) diff --git a/remote-curl.c b/remote-curl.c index f404faf0f4..e114f24448 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -439,8 +439,20 @@ static int run_slot(struct active_request_slot *slot, err = run_one_slot(slot, results); if (err != HTTP_OK && err != HTTP_REAUTH) { - error("RPC failed; result=%d, HTTP code = %ld", - results->curl_result, results->http_code); + struct strbuf msg = STRBUF_INIT; + if (results->http_code && results->http_code != 200) + strbuf_addf(&msg, "HTTP %ld", results->http_code); + if (results->curl_result != CURLE_OK) { + if (msg.len) + strbuf_addch(&msg, ' '); + strbuf_addf(&msg, "curl %d", results->curl_result); + if (curl_errorstr[0]) { + strbuf_addch(&msg, ' '); + strbuf_addstr(&msg, curl_errorstr); + } + } + error("RPC failed; %s", msg.buf); + strbuf_release(&msg); } return err; diff --git a/submodule.c b/submodule.c index 14e76247bf..b58d4ee945 100644 --- a/submodule.c +++ b/submodule.c @@ -68,7 +68,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath) strbuf_addstr(&entry, "submodule."); strbuf_addstr(&entry, submodule->name); strbuf_addstr(&entry, ".path"); - if (git_config_set_in_file(".gitmodules", entry.buf, newpath) < 0) { + if (git_config_set_in_file_gently(".gitmodules", entry.buf, newpath) < 0) { /* Maybe the user already did that, don't error out here */ warning(_("Could not update .gitmodules entry %s"), entry.buf); strbuf_release(&entry); @@ -1034,11 +1034,9 @@ void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir) /* Update core.worktree setting */ strbuf_reset(&file_name); strbuf_addf(&file_name, "%s/config", git_dir); - if (git_config_set_in_file(file_name.buf, "core.worktree", - relative_path(real_work_tree, git_dir, - &rel_path))) - die(_("Could not set core.worktree in %s"), - file_name.buf); + git_config_set_in_file(file_name.buf, "core.worktree", + relative_path(real_work_tree, git_dir, + &rel_path)); strbuf_release(&file_name); strbuf_release(&rel_path); diff --git a/t/t1501-work-tree.sh b/t/t1501-work-tree.sh new file mode 100755 index 0000000000..cc5b870e58 --- /dev/null +++ b/t/t1501-work-tree.sh @@ -0,0 +1,426 @@ +#!/bin/sh + +test_description='test separate work tree' +. ./test-lib.sh + +test_expect_success 'setup' ' + EMPTY_TREE=$(git write-tree) && + EMPTY_BLOB=$(git hash-object -t blob --stdin expected.bare && + echo $2 >expected.inside-git && + echo $3 >expected.inside-worktree && + if test $# -ge 4 + then + echo $4 >expected.prefix + fi && + + git rev-parse --is-bare-repository >actual.bare && + git rev-parse --is-inside-git-dir >actual.inside-git && + git rev-parse --is-inside-work-tree >actual.inside-worktree && + if test $# -ge 4 + then + git rev-parse --show-prefix >actual.prefix + fi && + + test_cmp expected.bare actual.bare && + test_cmp expected.inside-git actual.inside-git && + test_cmp expected.inside-worktree actual.inside-worktree && + if test $# -ge 4 + then + # rev-parse --show-prefix should output + # a single newline when at the top of the work tree, + # but we test for that separately. + test -z "$4" && ! test -s actual.prefix || + test_cmp expected.prefix actual.prefix + fi + } +' + +test_expect_success 'setup: core.worktree = relative path' ' + sane_unset GIT_WORK_TREE && + GIT_DIR=repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + export GIT_DIR GIT_CONFIG && + git config core.worktree ../work +' + +test_expect_success 'outside' ' + test_rev_parse false false false +' + +test_expect_success 'inside work tree' ' + ( + cd work && + GIT_DIR=../repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + test_rev_parse false false true "" + ) +' + +test_expect_success 'empty prefix is actually written out' ' + echo >expected && + ( + cd work && + GIT_DIR=../repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + git rev-parse --show-prefix >../actual + ) && + test_cmp expected actual +' + +test_expect_success 'subdir of work tree' ' + ( + cd work/sub/dir && + GIT_DIR=../../../repo.git && + GIT_CONFIG="$(pwd)"/$GIT_DIR/config && + test_rev_parse false false true sub/dir/ + ) +' + +test_expect_success 'setup: core.worktree = absolute path' ' + sane_unset GIT_WORK_TREE && + GIT_DIR=$(pwd)/repo.git && + GIT_CONFIG=$GIT_DIR/config && + export GIT_DIR GIT_CONFIG && + git config core.worktree "$(pwd)/work" +' + +test_expect_success 'outside' ' + test_rev_parse false false false && + ( + cd work2 && + test_rev_parse false false false + ) +' + +test_expect_success 'inside work tree' ' + ( + cd work && + test_rev_parse false false true "" + ) +' + +test_expect_success 'subdir of work tree' ' + ( + cd work/sub/dir && + test_rev_parse false false true sub/dir/ + ) +' + +test_expect_success 'setup: GIT_WORK_TREE=relative (override core.worktree)' ' + GIT_DIR=$(pwd)/repo.git && + GIT_CONFIG=$GIT_DIR/config && + git config core.worktree non-existent && + GIT_WORK_TREE=work && + export GIT_DIR GIT_CONFIG GIT_WORK_TREE +' + +test_expect_success 'outside' ' + test_rev_parse false false false && + ( + cd work2 && + test_rev_parse false false false + ) +' + +test_expect_success 'inside work tree' ' + ( + cd work && + GIT_WORK_TREE=. && + test_rev_parse false false true "" + ) +' + +test_expect_success 'subdir of work tree' ' + ( + cd work/sub/dir && + GIT_WORK_TREE=../.. && + test_rev_parse false false true sub/dir/ + ) +' + +test_expect_success 'setup: GIT_WORK_TREE=absolute, below git dir' ' + mv work repo.git/work && + mv work2 repo.git/work2 && + GIT_DIR=$(pwd)/repo.git && + GIT_CONFIG=$GIT_DIR/config && + GIT_WORK_TREE=$(pwd)/repo.git/work && + export GIT_DIR GIT_CONFIG GIT_WORK_TREE +' + +test_expect_success 'outside' ' + echo outside && + test_rev_parse false false false +' + +test_expect_success 'in repo.git' ' + ( + cd repo.git && + test_rev_parse false true false + ) && + ( + cd repo.git/objects && + test_rev_parse false true false + ) && + ( + cd repo.git/work2 && + test_rev_parse false true false + ) +' + +test_expect_success 'inside work tree' ' + ( + cd repo.git/work && + test_rev_parse false true true "" + ) +' + +test_expect_success 'subdir of work tree' ' + ( + cd repo.git/work/sub/dir && + test_rev_parse false true true sub/dir/ + ) +' + +test_expect_success 'find work tree from repo' ' + echo sub/dir/untracked >expected && + cat <<-\EOF >repo.git/work/.gitignore && + expected.* + actual.* + .gitignore + EOF + >repo.git/work/sub/dir/untracked && + ( + cd repo.git && + git ls-files --others --exclude-standard >../actual + ) && + test_cmp expected actual +' + +test_expect_success 'find work tree from work tree' ' + echo sub/dir/tracked >expected && + >repo.git/work/sub/dir/tracked && + ( + cd repo.git/work/sub/dir && + git --git-dir=../../.. add tracked + ) && + ( + cd repo.git && + git ls-files >../actual + ) && + test_cmp expected actual +' + +test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' ' + ( + cd repo.git/work/sub/dir && + GIT_DIR=../../.. && + GIT_WORK_TREE=../.. && + GIT_PAGER= && + export GIT_DIR GIT_WORK_TREE GIT_PAGER && + + git diff --exit-code tracked && + echo changed >tracked && + test_must_fail git diff --exit-code tracked + ) +' + +test_expect_success 'diff-index respects work tree under .git dir' ' + cat >diff-index-cached.expected <<-EOF && + :000000 100644 $_z40 $EMPTY_BLOB A sub/dir/tracked + EOF + cat >diff-index.expected <<-EOF && + :000000 100644 $_z40 $_z40 A sub/dir/tracked + EOF + + ( + GIT_DIR=repo.git && + GIT_WORK_TREE=repo.git/work && + export GIT_DIR GIT_WORK_TREE && + git diff-index $EMPTY_TREE >diff-index.actual && + git diff-index --cached $EMPTY_TREE >diff-index-cached.actual + ) && + test_cmp diff-index.expected diff-index.actual && + test_cmp diff-index-cached.expected diff-index-cached.actual +' + +test_expect_success 'diff-files respects work tree under .git dir' ' + cat >diff-files.expected <<-EOF && + :100644 100644 $EMPTY_BLOB $_z40 M sub/dir/tracked + EOF + + ( + GIT_DIR=repo.git && + GIT_WORK_TREE=repo.git/work && + export GIT_DIR GIT_WORK_TREE && + git diff-files >diff-files.actual + ) && + test_cmp diff-files.expected diff-files.actual +' + +test_expect_success 'git diff respects work tree under .git dir' ' + cat >diff-TREE.expected <<-EOF && + diff --git a/sub/dir/tracked b/sub/dir/tracked + new file mode 100644 + index 0000000..$CHANGED_BLOB7 + --- /dev/null + +++ b/sub/dir/tracked + @@ -0,0 +1 @@ + +changed + EOF + cat >diff-TREE-cached.expected <<-EOF && + diff --git a/sub/dir/tracked b/sub/dir/tracked + new file mode 100644 + index 0000000..$EMPTY_BLOB7 + EOF + cat >diff-FILES.expected <<-EOF && + diff --git a/sub/dir/tracked b/sub/dir/tracked + index $EMPTY_BLOB7..$CHANGED_BLOB7 100644 + --- a/sub/dir/tracked + +++ b/sub/dir/tracked + @@ -0,0 +1 @@ + +changed + EOF + + ( + GIT_DIR=repo.git && + GIT_WORK_TREE=repo.git/work && + export GIT_DIR GIT_WORK_TREE && + git diff $EMPTY_TREE >diff-TREE.actual && + git diff --cached $EMPTY_TREE >diff-TREE-cached.actual && + git diff >diff-FILES.actual + ) && + test_cmp diff-TREE.expected diff-TREE.actual && + test_cmp diff-TREE-cached.expected diff-TREE-cached.actual && + test_cmp diff-FILES.expected diff-FILES.actual +' + +test_expect_success 'git grep' ' + echo dir/tracked >expected.grep && + ( + cd repo.git/work/sub && + GIT_DIR=../.. && + GIT_WORK_TREE=.. && + export GIT_DIR GIT_WORK_TREE && + git grep -l changed >../../../actual.grep + ) && + test_cmp expected.grep actual.grep +' + +test_expect_success 'git commit' ' + ( + cd repo.git && + GIT_DIR=. GIT_WORK_TREE=work git commit -a -m done + ) +' + +test_expect_success 'absolute pathspec should fail gracefully' ' + ( + cd repo.git && + test_might_fail git config --unset core.worktree && + test_must_fail git log HEAD -- /home + ) +' + +test_expect_success 'make_relative_path handles double slashes in GIT_DIR' ' + >dummy_file && + echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file && + git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file +' + +test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' ' + GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \ + test-subprocess --setup-work-tree rev-parse --show-toplevel >actual && + echo "$(pwd)/repo.git/work" >expected && + test_cmp expected actual +' + +test_expect_success 'Multi-worktree setup' ' + mkdir work && + mkdir -p repo.git/repos/foo && + cp repo.git/HEAD repo.git/index repo.git/repos/foo && + test_might_fail cp repo.git/sharedindex.* repo.git/repos/foo && + sane_unset GIT_DIR GIT_CONFIG GIT_WORK_TREE +' + +test_expect_success 'GIT_DIR set (1)' ' + echo "gitdir: repo.git/repos/foo" >gitfile && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + GIT_DIR=../gitfile git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual + ) +' + +test_expect_success 'GIT_DIR set (2)' ' + echo "gitdir: repo.git/repos/foo" >gitfile && + echo "$(pwd)/repo.git" >repo.git/repos/foo/commondir && + ( + cd work && + GIT_DIR=../gitfile git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual + ) +' + +test_expect_success 'Auto discovery' ' + echo "gitdir: repo.git/repos/foo" >.git && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual && + echo haha >data1 && + git add data1 && + git ls-files --full-name :/ | grep data1 >actual && + echo work/data1 >expect && + test_cmp expect actual + ) +' + +test_expect_success '$GIT_DIR/common overrides core.worktree' ' + mkdir elsewhere && + git --git-dir=repo.git config core.worktree "$TRASH_DIRECTORY/elsewhere" && + echo "gitdir: repo.git/repos/foo" >.git && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual && + echo haha >data2 && + git add data2 && + git ls-files --full-name :/ | grep data2 >actual && + echo work/data2 >expect && + test_cmp expect actual + ) +' + +test_expect_success '$GIT_WORK_TREE overrides $GIT_DIR/common' ' + echo "gitdir: repo.git/repos/foo" >.git && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + echo haha >data3 && + git --git-dir=../.git --work-tree=. add data3 && + git ls-files --full-name -- :/ | grep data3 >actual && + echo data3 >expect && + test_cmp expect actual + ) +' + +test_done diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh deleted file mode 100755 index cc5b870e58..0000000000 --- a/t/t1501-worktree.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/bin/sh - -test_description='test separate work tree' -. ./test-lib.sh - -test_expect_success 'setup' ' - EMPTY_TREE=$(git write-tree) && - EMPTY_BLOB=$(git hash-object -t blob --stdin expected.bare && - echo $2 >expected.inside-git && - echo $3 >expected.inside-worktree && - if test $# -ge 4 - then - echo $4 >expected.prefix - fi && - - git rev-parse --is-bare-repository >actual.bare && - git rev-parse --is-inside-git-dir >actual.inside-git && - git rev-parse --is-inside-work-tree >actual.inside-worktree && - if test $# -ge 4 - then - git rev-parse --show-prefix >actual.prefix - fi && - - test_cmp expected.bare actual.bare && - test_cmp expected.inside-git actual.inside-git && - test_cmp expected.inside-worktree actual.inside-worktree && - if test $# -ge 4 - then - # rev-parse --show-prefix should output - # a single newline when at the top of the work tree, - # but we test for that separately. - test -z "$4" && ! test -s actual.prefix || - test_cmp expected.prefix actual.prefix - fi - } -' - -test_expect_success 'setup: core.worktree = relative path' ' - sane_unset GIT_WORK_TREE && - GIT_DIR=repo.git && - GIT_CONFIG="$(pwd)"/$GIT_DIR/config && - export GIT_DIR GIT_CONFIG && - git config core.worktree ../work -' - -test_expect_success 'outside' ' - test_rev_parse false false false -' - -test_expect_success 'inside work tree' ' - ( - cd work && - GIT_DIR=../repo.git && - GIT_CONFIG="$(pwd)"/$GIT_DIR/config && - test_rev_parse false false true "" - ) -' - -test_expect_success 'empty prefix is actually written out' ' - echo >expected && - ( - cd work && - GIT_DIR=../repo.git && - GIT_CONFIG="$(pwd)"/$GIT_DIR/config && - git rev-parse --show-prefix >../actual - ) && - test_cmp expected actual -' - -test_expect_success 'subdir of work tree' ' - ( - cd work/sub/dir && - GIT_DIR=../../../repo.git && - GIT_CONFIG="$(pwd)"/$GIT_DIR/config && - test_rev_parse false false true sub/dir/ - ) -' - -test_expect_success 'setup: core.worktree = absolute path' ' - sane_unset GIT_WORK_TREE && - GIT_DIR=$(pwd)/repo.git && - GIT_CONFIG=$GIT_DIR/config && - export GIT_DIR GIT_CONFIG && - git config core.worktree "$(pwd)/work" -' - -test_expect_success 'outside' ' - test_rev_parse false false false && - ( - cd work2 && - test_rev_parse false false false - ) -' - -test_expect_success 'inside work tree' ' - ( - cd work && - test_rev_parse false false true "" - ) -' - -test_expect_success 'subdir of work tree' ' - ( - cd work/sub/dir && - test_rev_parse false false true sub/dir/ - ) -' - -test_expect_success 'setup: GIT_WORK_TREE=relative (override core.worktree)' ' - GIT_DIR=$(pwd)/repo.git && - GIT_CONFIG=$GIT_DIR/config && - git config core.worktree non-existent && - GIT_WORK_TREE=work && - export GIT_DIR GIT_CONFIG GIT_WORK_TREE -' - -test_expect_success 'outside' ' - test_rev_parse false false false && - ( - cd work2 && - test_rev_parse false false false - ) -' - -test_expect_success 'inside work tree' ' - ( - cd work && - GIT_WORK_TREE=. && - test_rev_parse false false true "" - ) -' - -test_expect_success 'subdir of work tree' ' - ( - cd work/sub/dir && - GIT_WORK_TREE=../.. && - test_rev_parse false false true sub/dir/ - ) -' - -test_expect_success 'setup: GIT_WORK_TREE=absolute, below git dir' ' - mv work repo.git/work && - mv work2 repo.git/work2 && - GIT_DIR=$(pwd)/repo.git && - GIT_CONFIG=$GIT_DIR/config && - GIT_WORK_TREE=$(pwd)/repo.git/work && - export GIT_DIR GIT_CONFIG GIT_WORK_TREE -' - -test_expect_success 'outside' ' - echo outside && - test_rev_parse false false false -' - -test_expect_success 'in repo.git' ' - ( - cd repo.git && - test_rev_parse false true false - ) && - ( - cd repo.git/objects && - test_rev_parse false true false - ) && - ( - cd repo.git/work2 && - test_rev_parse false true false - ) -' - -test_expect_success 'inside work tree' ' - ( - cd repo.git/work && - test_rev_parse false true true "" - ) -' - -test_expect_success 'subdir of work tree' ' - ( - cd repo.git/work/sub/dir && - test_rev_parse false true true sub/dir/ - ) -' - -test_expect_success 'find work tree from repo' ' - echo sub/dir/untracked >expected && - cat <<-\EOF >repo.git/work/.gitignore && - expected.* - actual.* - .gitignore - EOF - >repo.git/work/sub/dir/untracked && - ( - cd repo.git && - git ls-files --others --exclude-standard >../actual - ) && - test_cmp expected actual -' - -test_expect_success 'find work tree from work tree' ' - echo sub/dir/tracked >expected && - >repo.git/work/sub/dir/tracked && - ( - cd repo.git/work/sub/dir && - git --git-dir=../../.. add tracked - ) && - ( - cd repo.git && - git ls-files >../actual - ) && - test_cmp expected actual -' - -test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' ' - ( - cd repo.git/work/sub/dir && - GIT_DIR=../../.. && - GIT_WORK_TREE=../.. && - GIT_PAGER= && - export GIT_DIR GIT_WORK_TREE GIT_PAGER && - - git diff --exit-code tracked && - echo changed >tracked && - test_must_fail git diff --exit-code tracked - ) -' - -test_expect_success 'diff-index respects work tree under .git dir' ' - cat >diff-index-cached.expected <<-EOF && - :000000 100644 $_z40 $EMPTY_BLOB A sub/dir/tracked - EOF - cat >diff-index.expected <<-EOF && - :000000 100644 $_z40 $_z40 A sub/dir/tracked - EOF - - ( - GIT_DIR=repo.git && - GIT_WORK_TREE=repo.git/work && - export GIT_DIR GIT_WORK_TREE && - git diff-index $EMPTY_TREE >diff-index.actual && - git diff-index --cached $EMPTY_TREE >diff-index-cached.actual - ) && - test_cmp diff-index.expected diff-index.actual && - test_cmp diff-index-cached.expected diff-index-cached.actual -' - -test_expect_success 'diff-files respects work tree under .git dir' ' - cat >diff-files.expected <<-EOF && - :100644 100644 $EMPTY_BLOB $_z40 M sub/dir/tracked - EOF - - ( - GIT_DIR=repo.git && - GIT_WORK_TREE=repo.git/work && - export GIT_DIR GIT_WORK_TREE && - git diff-files >diff-files.actual - ) && - test_cmp diff-files.expected diff-files.actual -' - -test_expect_success 'git diff respects work tree under .git dir' ' - cat >diff-TREE.expected <<-EOF && - diff --git a/sub/dir/tracked b/sub/dir/tracked - new file mode 100644 - index 0000000..$CHANGED_BLOB7 - --- /dev/null - +++ b/sub/dir/tracked - @@ -0,0 +1 @@ - +changed - EOF - cat >diff-TREE-cached.expected <<-EOF && - diff --git a/sub/dir/tracked b/sub/dir/tracked - new file mode 100644 - index 0000000..$EMPTY_BLOB7 - EOF - cat >diff-FILES.expected <<-EOF && - diff --git a/sub/dir/tracked b/sub/dir/tracked - index $EMPTY_BLOB7..$CHANGED_BLOB7 100644 - --- a/sub/dir/tracked - +++ b/sub/dir/tracked - @@ -0,0 +1 @@ - +changed - EOF - - ( - GIT_DIR=repo.git && - GIT_WORK_TREE=repo.git/work && - export GIT_DIR GIT_WORK_TREE && - git diff $EMPTY_TREE >diff-TREE.actual && - git diff --cached $EMPTY_TREE >diff-TREE-cached.actual && - git diff >diff-FILES.actual - ) && - test_cmp diff-TREE.expected diff-TREE.actual && - test_cmp diff-TREE-cached.expected diff-TREE-cached.actual && - test_cmp diff-FILES.expected diff-FILES.actual -' - -test_expect_success 'git grep' ' - echo dir/tracked >expected.grep && - ( - cd repo.git/work/sub && - GIT_DIR=../.. && - GIT_WORK_TREE=.. && - export GIT_DIR GIT_WORK_TREE && - git grep -l changed >../../../actual.grep - ) && - test_cmp expected.grep actual.grep -' - -test_expect_success 'git commit' ' - ( - cd repo.git && - GIT_DIR=. GIT_WORK_TREE=work git commit -a -m done - ) -' - -test_expect_success 'absolute pathspec should fail gracefully' ' - ( - cd repo.git && - test_might_fail git config --unset core.worktree && - test_must_fail git log HEAD -- /home - ) -' - -test_expect_success 'make_relative_path handles double slashes in GIT_DIR' ' - >dummy_file && - echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file && - git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file -' - -test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' ' - GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \ - test-subprocess --setup-work-tree rev-parse --show-toplevel >actual && - echo "$(pwd)/repo.git/work" >expected && - test_cmp expected actual -' - -test_expect_success 'Multi-worktree setup' ' - mkdir work && - mkdir -p repo.git/repos/foo && - cp repo.git/HEAD repo.git/index repo.git/repos/foo && - test_might_fail cp repo.git/sharedindex.* repo.git/repos/foo && - sane_unset GIT_DIR GIT_CONFIG GIT_WORK_TREE -' - -test_expect_success 'GIT_DIR set (1)' ' - echo "gitdir: repo.git/repos/foo" >gitfile && - echo ../.. >repo.git/repos/foo/commondir && - ( - cd work && - GIT_DIR=../gitfile git rev-parse --git-common-dir >actual && - test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && - test_cmp expect actual - ) -' - -test_expect_success 'GIT_DIR set (2)' ' - echo "gitdir: repo.git/repos/foo" >gitfile && - echo "$(pwd)/repo.git" >repo.git/repos/foo/commondir && - ( - cd work && - GIT_DIR=../gitfile git rev-parse --git-common-dir >actual && - test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && - test_cmp expect actual - ) -' - -test_expect_success 'Auto discovery' ' - echo "gitdir: repo.git/repos/foo" >.git && - echo ../.. >repo.git/repos/foo/commondir && - ( - cd work && - git rev-parse --git-common-dir >actual && - test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && - test_cmp expect actual && - echo haha >data1 && - git add data1 && - git ls-files --full-name :/ | grep data1 >actual && - echo work/data1 >expect && - test_cmp expect actual - ) -' - -test_expect_success '$GIT_DIR/common overrides core.worktree' ' - mkdir elsewhere && - git --git-dir=repo.git config core.worktree "$TRASH_DIRECTORY/elsewhere" && - echo "gitdir: repo.git/repos/foo" >.git && - echo ../.. >repo.git/repos/foo/commondir && - ( - cd work && - git rev-parse --git-common-dir >actual && - test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && - test_cmp expect actual && - echo haha >data2 && - git add data2 && - git ls-files --full-name :/ | grep data2 >actual && - echo work/data2 >expect && - test_cmp expect actual - ) -' - -test_expect_success '$GIT_WORK_TREE overrides $GIT_DIR/common' ' - echo "gitdir: repo.git/repos/foo" >.git && - echo ../.. >repo.git/repos/foo/commondir && - ( - cd work && - echo haha >data3 && - git --git-dir=../.git --work-tree=. add data3 && - git ls-files --full-name -- :/ | grep data3 >actual && - echo data3 >expect && - test_cmp expect actual - ) -' - -test_done diff --git a/t/t1509-root-work-tree.sh b/t/t1509-root-work-tree.sh new file mode 100755 index 0000000000..553a3f601b --- /dev/null +++ b/t/t1509-root-work-tree.sh @@ -0,0 +1,258 @@ +#!/bin/sh + +test_description='Test Git when git repository is located at root + +This test requires write access in root. Do not bother if you do not +have a throwaway chroot or VM. + +Script t1509/prepare-chroot.sh may help you setup chroot, then you +can chroot in and execute this test from there. +' + +. ./test-lib.sh + +test_cmp_val() { + echo "$1" > expected + echo "$2" > result + test_cmp expected result +} + +test_vars() { + test_expect_success "$1: gitdir" ' + test_cmp_val "'"$2"'" "$(git rev-parse --git-dir)" + ' + + test_expect_success "$1: worktree" ' + test_cmp_val "'"$3"'" "$(git rev-parse --show-toplevel)" + ' + + test_expect_success "$1: prefix" ' + test_cmp_val "'"$4"'" "$(git rev-parse --show-prefix)" + ' +} + +test_foobar_root() { + test_expect_success 'add relative' ' + test -z "$(cd / && git ls-files)" && + git add foo/foome && + git add foo/bar/barme && + git add me && + ( cd / && git ls-files --stage ) > result && + test_cmp /ls.expected result && + rm "$(git rev-parse --git-dir)/index" + ' + + test_expect_success 'add absolute' ' + test -z "$(cd / && git ls-files)" && + git add /foo/foome && + git add /foo/bar/barme && + git add /me && + ( cd / && git ls-files --stage ) > result && + test_cmp /ls.expected result && + rm "$(git rev-parse --git-dir)/index" + ' + +} + +test_foobar_foo() { + test_expect_success 'add relative' ' + test -z "$(cd / && git ls-files)" && + git add foome && + git add bar/barme && + git add ../me && + ( cd / && git ls-files --stage ) > result && + test_cmp /ls.expected result && + rm "$(git rev-parse --git-dir)/index" + ' + + test_expect_success 'add absolute' ' + test -z "$(cd / && git ls-files)" && + git add /foo/foome && + git add /foo/bar/barme && + git add /me && + ( cd / && git ls-files --stage ) > result && + test_cmp /ls.expected result && + rm "$(git rev-parse --git-dir)/index" + ' +} + +test_foobar_foobar() { + test_expect_success 'add relative' ' + test -z "$(cd / && git ls-files)" && + git add ../foome && + git add barme && + git add ../../me && + ( cd / && git ls-files --stage ) > result && + test_cmp /ls.expected result && + rm "$(git rev-parse --git-dir)/index" + ' + + test_expect_success 'add absolute' ' + test -z "$(cd / && git ls-files)" && + git add /foo/foome && + git add /foo/bar/barme && + git add /me && + ( cd / && git ls-files --stage ) > result && + test_cmp /ls.expected result && + rm "$(git rev-parse --git-dir)/index" + ' +} + +if ! test -w / +then + skip_all="Test requiring writable / skipped. Read this test if you want to run it" + test_done +fi + +if test -e /refs || test -e /objects || test -e /info || test -e /hooks || + test -e /.git || test -e /foo || test -e /me +then + skip_all="Skip test that clobbers existing files in /" + test_done +fi + +if [ "$IKNOWWHATIAMDOING" != "YES" ]; then + skip_all="You must set env var IKNOWWHATIAMDOING=YES in order to run this test" + test_done +fi + +if ! test_have_prereq NOT_ROOT +then + skip_all="No you can't run this as root" + test_done +fi + +ONE_SHA1=d00491fd7e5bb6fa28c517a0bb32b8b506539d4d + +test_expect_success 'setup' ' + rm -rf /foo && + mkdir /foo && + mkdir /foo/bar && + echo 1 > /foo/foome && + echo 1 > /foo/bar/barme && + echo 1 > /me +' + +say "GIT_DIR absolute, GIT_WORK_TREE set" + +test_expect_success 'go to /' 'cd /' + +cat >ls.expected < expected && + git init > result && + test_cmp expected result +' + +test_vars 'auto gitdir, root' ".git" "/" "" +test_foobar_root + +test_expect_success 'go to /foo' 'cd /foo' +test_vars 'auto gitdir, foo' "/.git" "/" "foo/" +test_foobar_foo + +test_expect_success 'go to /foo/bar' 'cd /foo/bar' +test_vars 'auto gitdir, foo/bar' "/.git" "/" "foo/bar/" +test_foobar_foobar + +test_expect_success 'cleanup' 'rm -rf /.git' + +say "auto bare gitdir" + +# DESTROYYYYY!!!!! +test_expect_success 'setup' ' + rm -rf /refs /objects /info /hooks && + rm -f /expected /ls.expected /me /result && + cd / && + echo "Initialized empty Git repository in /" > expected && + git init --bare > result && + test_cmp expected result +' + +test_vars 'auto gitdir, root' "." "" "" + +test_expect_success 'go to /foo' 'cd /foo' + +test_vars 'auto gitdir, root' "/" "" "" + +test_done diff --git a/t/t1509-root-worktree.sh b/t/t1509-root-worktree.sh deleted file mode 100755 index 553a3f601b..0000000000 --- a/t/t1509-root-worktree.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/bin/sh - -test_description='Test Git when git repository is located at root - -This test requires write access in root. Do not bother if you do not -have a throwaway chroot or VM. - -Script t1509/prepare-chroot.sh may help you setup chroot, then you -can chroot in and execute this test from there. -' - -. ./test-lib.sh - -test_cmp_val() { - echo "$1" > expected - echo "$2" > result - test_cmp expected result -} - -test_vars() { - test_expect_success "$1: gitdir" ' - test_cmp_val "'"$2"'" "$(git rev-parse --git-dir)" - ' - - test_expect_success "$1: worktree" ' - test_cmp_val "'"$3"'" "$(git rev-parse --show-toplevel)" - ' - - test_expect_success "$1: prefix" ' - test_cmp_val "'"$4"'" "$(git rev-parse --show-prefix)" - ' -} - -test_foobar_root() { - test_expect_success 'add relative' ' - test -z "$(cd / && git ls-files)" && - git add foo/foome && - git add foo/bar/barme && - git add me && - ( cd / && git ls-files --stage ) > result && - test_cmp /ls.expected result && - rm "$(git rev-parse --git-dir)/index" - ' - - test_expect_success 'add absolute' ' - test -z "$(cd / && git ls-files)" && - git add /foo/foome && - git add /foo/bar/barme && - git add /me && - ( cd / && git ls-files --stage ) > result && - test_cmp /ls.expected result && - rm "$(git rev-parse --git-dir)/index" - ' - -} - -test_foobar_foo() { - test_expect_success 'add relative' ' - test -z "$(cd / && git ls-files)" && - git add foome && - git add bar/barme && - git add ../me && - ( cd / && git ls-files --stage ) > result && - test_cmp /ls.expected result && - rm "$(git rev-parse --git-dir)/index" - ' - - test_expect_success 'add absolute' ' - test -z "$(cd / && git ls-files)" && - git add /foo/foome && - git add /foo/bar/barme && - git add /me && - ( cd / && git ls-files --stage ) > result && - test_cmp /ls.expected result && - rm "$(git rev-parse --git-dir)/index" - ' -} - -test_foobar_foobar() { - test_expect_success 'add relative' ' - test -z "$(cd / && git ls-files)" && - git add ../foome && - git add barme && - git add ../../me && - ( cd / && git ls-files --stage ) > result && - test_cmp /ls.expected result && - rm "$(git rev-parse --git-dir)/index" - ' - - test_expect_success 'add absolute' ' - test -z "$(cd / && git ls-files)" && - git add /foo/foome && - git add /foo/bar/barme && - git add /me && - ( cd / && git ls-files --stage ) > result && - test_cmp /ls.expected result && - rm "$(git rev-parse --git-dir)/index" - ' -} - -if ! test -w / -then - skip_all="Test requiring writable / skipped. Read this test if you want to run it" - test_done -fi - -if test -e /refs || test -e /objects || test -e /info || test -e /hooks || - test -e /.git || test -e /foo || test -e /me -then - skip_all="Skip test that clobbers existing files in /" - test_done -fi - -if [ "$IKNOWWHATIAMDOING" != "YES" ]; then - skip_all="You must set env var IKNOWWHATIAMDOING=YES in order to run this test" - test_done -fi - -if ! test_have_prereq NOT_ROOT -then - skip_all="No you can't run this as root" - test_done -fi - -ONE_SHA1=d00491fd7e5bb6fa28c517a0bb32b8b506539d4d - -test_expect_success 'setup' ' - rm -rf /foo && - mkdir /foo && - mkdir /foo/bar && - echo 1 > /foo/foome && - echo 1 > /foo/bar/barme && - echo 1 > /me -' - -say "GIT_DIR absolute, GIT_WORK_TREE set" - -test_expect_success 'go to /' 'cd /' - -cat >ls.expected < expected && - git init > result && - test_cmp expected result -' - -test_vars 'auto gitdir, root' ".git" "/" "" -test_foobar_root - -test_expect_success 'go to /foo' 'cd /foo' -test_vars 'auto gitdir, foo' "/.git" "/" "foo/" -test_foobar_foo - -test_expect_success 'go to /foo/bar' 'cd /foo/bar' -test_vars 'auto gitdir, foo/bar' "/.git" "/" "foo/bar/" -test_foobar_foobar - -test_expect_success 'cleanup' 'rm -rf /.git' - -say "auto bare gitdir" - -# DESTROYYYYY!!!!! -test_expect_success 'setup' ' - rm -rf /refs /objects /info /hooks && - rm -f /expected /ls.expected /me /result && - cd / && - echo "Initialized empty Git repository in /" > expected && - git init --bare > result && - test_cmp expected result -' - -test_vars 'auto gitdir, root' "." "" "" - -test_expect_success 'go to /foo' 'cd /foo' - -test_vars 'auto gitdir, root' "/" "" "" - -test_done diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index cdaf6f64ec..a897248490 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -446,6 +446,13 @@ test_expect_success '--set-upstream-to fails on a non-ref' ' test_must_fail git branch --set-upstream-to HEAD^{} ' +test_expect_success '--set-upstream-to fails on locked config' ' + test_when_finished "rm -f .git/config.lock" && + >.git/config.lock && + git branch locked && + test_must_fail git branch --set-upstream-to locked +' + test_expect_success 'use --set-upstream-to modify HEAD' ' test_config branch.master.remote foo && test_config branch.master.merge foo && @@ -466,6 +473,13 @@ test_expect_success '--unset-upstream should fail if given a non-existent branch test_must_fail git branch --unset-upstream i-dont-exist ' +test_expect_success '--unset-upstream should fail if config is locked' ' + test_when_finished "rm -f .git/config.lock" && + git branch --set-upstream-to locked && + >.git/config.lock && + test_must_fail git branch --unset-upstream +' + test_expect_success 'test --unset-upstream on HEAD' ' git branch my14 && test_config branch.master.remote foo && @@ -579,7 +593,7 @@ test_expect_success 'avoid ambiguous track' ' git config remote.ambi1.fetch refs/heads/lalala:refs/heads/master && git config remote.ambi2.url lilili && git config remote.ambi2.fetch refs/heads/lilili:refs/heads/master && - git branch all1 master && + test_must_fail git branch all1 master && test -z "$(git config branch.all1.merge)" ' diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index dfaf9d9f68..013e03dee2 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -932,6 +932,15 @@ test_expect_success 'get-url on new remote' ' echo foo | get_url_test --push --all someremote ' +test_expect_success 'remote set-url with locked config' ' + test_when_finished "rm -f .git/config.lock" && + git config --get-all remote.someremote.url >expect && + >.git/config.lock && + test_must_fail git remote set-url someremote baz && + git config --get-all remote.someremote.url >actual && + cmp expect actual +' + test_expect_success 'remote set-url bar' ' git remote set-url someremote bar && echo bar >expect && diff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh new file mode 100755 index 0000000000..c20717181e --- /dev/null +++ b/t/t7409-submodule-detached-work-tree.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Copyright (c) 2012 Daniel Graña +# + +test_description='Test submodules on detached working tree + +This test verifies that "git submodule" initialization, update and addition works +on detahced working trees +' + +TEST_NO_CREATE_REPO=1 +. ./test-lib.sh + +test_expect_success 'submodule on detached working tree' ' + git init --bare remote && + test_create_repo bundle1 && + ( + cd bundle1 && + test_commit "shoot" && + git rev-parse --verify HEAD >../expect + ) && + mkdir home && + ( + cd home && + GIT_WORK_TREE="$(pwd)" && + GIT_DIR="$(pwd)/.dotfiles" && + export GIT_WORK_TREE GIT_DIR && + git clone --bare ../remote .dotfiles && + git submodule add ../bundle1 .vim/bundle/sogood && + test_commit "sogood" && + ( + unset GIT_WORK_TREE GIT_DIR && + cd .vim/bundle/sogood && + git rev-parse --verify HEAD >actual && + test_cmp ../../../../expect actual + ) && + git push origin master + ) && + mkdir home2 && + ( + cd home2 && + git clone --bare ../remote .dotfiles && + GIT_WORK_TREE="$(pwd)" && + GIT_DIR="$(pwd)/.dotfiles" && + export GIT_WORK_TREE GIT_DIR && + git checkout master && + git submodule update --init && + ( + unset GIT_WORK_TREE GIT_DIR && + cd .vim/bundle/sogood && + git rev-parse --verify HEAD >actual && + test_cmp ../../../../expect actual + ) + ) +' + +test_expect_success 'submodule on detached working pointed by core.worktree' ' + mkdir home3 && + ( + cd home3 && + GIT_DIR="$(pwd)/.dotfiles" && + export GIT_DIR && + git clone --bare ../remote "$GIT_DIR" && + git config core.bare false && + git config core.worktree .. && + git checkout master && + git submodule add ../bundle1 .vim/bundle/dupe && + test_commit "dupe" && + git push origin master + ) && + ( + cd home && + GIT_DIR="$(pwd)/.dotfiles" && + export GIT_DIR && + git config core.bare false && + git config core.worktree .. && + git pull && + git submodule update --init && + test -f .vim/bundle/dupe/shoot.t + ) +' + +test_done diff --git a/t/t7409-submodule-detached-worktree.sh b/t/t7409-submodule-detached-worktree.sh deleted file mode 100755 index c20717181e..0000000000 --- a/t/t7409-submodule-detached-worktree.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2012 Daniel Graña -# - -test_description='Test submodules on detached working tree - -This test verifies that "git submodule" initialization, update and addition works -on detahced working trees -' - -TEST_NO_CREATE_REPO=1 -. ./test-lib.sh - -test_expect_success 'submodule on detached working tree' ' - git init --bare remote && - test_create_repo bundle1 && - ( - cd bundle1 && - test_commit "shoot" && - git rev-parse --verify HEAD >../expect - ) && - mkdir home && - ( - cd home && - GIT_WORK_TREE="$(pwd)" && - GIT_DIR="$(pwd)/.dotfiles" && - export GIT_WORK_TREE GIT_DIR && - git clone --bare ../remote .dotfiles && - git submodule add ../bundle1 .vim/bundle/sogood && - test_commit "sogood" && - ( - unset GIT_WORK_TREE GIT_DIR && - cd .vim/bundle/sogood && - git rev-parse --verify HEAD >actual && - test_cmp ../../../../expect actual - ) && - git push origin master - ) && - mkdir home2 && - ( - cd home2 && - git clone --bare ../remote .dotfiles && - GIT_WORK_TREE="$(pwd)" && - GIT_DIR="$(pwd)/.dotfiles" && - export GIT_WORK_TREE GIT_DIR && - git checkout master && - git submodule update --init && - ( - unset GIT_WORK_TREE GIT_DIR && - cd .vim/bundle/sogood && - git rev-parse --verify HEAD >actual && - test_cmp ../../../../expect actual - ) - ) -' - -test_expect_success 'submodule on detached working pointed by core.worktree' ' - mkdir home3 && - ( - cd home3 && - GIT_DIR="$(pwd)/.dotfiles" && - export GIT_DIR && - git clone --bare ../remote "$GIT_DIR" && - git config core.bare false && - git config core.worktree .. && - git checkout master && - git submodule add ../bundle1 .vim/bundle/dupe && - test_commit "dupe" && - git push origin master - ) && - ( - cd home && - GIT_DIR="$(pwd)/.dotfiles" && - export GIT_DIR && - git config core.bare false && - git config core.worktree .. && - git pull && - git submodule update --init && - test -f .vim/bundle/dupe/shoot.t - ) -' - -test_done