This was impossible earlier because git_dir can be relative. Now that git_dir is absolute, I see no reason for worktree setup inside setup_git_directory_gently(). The semantic is now clearer: if you need worktree, call setup_work_tree yourself (well, I will clean up setup_git_directory() part later) This patch will free some commands from prefix handling if they don't ever need worktree. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- builtin-apply.c | 7 +++++-- builtin-bundle.c | 9 ++------- builtin-config.c | 15 +++++---------- builtin-diff-files.c | 10 +++++----- builtin-diff.c | 11 ++++++----- builtin-upload-archive.c | 4 ++-- cache.h | 2 +- git.c | 6 +----- hash-object.c | 8 +------- setup.c | 34 +++++++++++++++++----------------- 10 files changed, 45 insertions(+), 61 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index 12e85a4..c50ae32 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -3103,8 +3103,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) const char *whitespace_option = NULL; - prefix = setup_git_directory_gently(&is_not_gitdir); - prefix_length = prefix ? strlen(prefix) : 0; + setup_git_directory_gently(&is_not_gitdir); + if (!is_not_gitdir && is_inside_work_tree()) { + prefix = setup_work_tree(NULL); + prefix_length = prefix ? strlen(prefix) : 0; + } git_config(git_apply_config); if (apply_default_whitespace) parse_whitespace_option(apply_default_whitespace); diff --git a/builtin-bundle.c b/builtin-bundle.c index 9f38e21..2a7687e 100644 --- a/builtin-bundle.c +++ b/builtin-bundle.c @@ -11,7 +11,7 @@ static const char *bundle_usage="git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )"; -int cmd_bundle(int argc, const char **argv, const char *prefix) +int cmd_bundle(int argc, const char **argv, const char *unused_prefix) { struct bundle_header header; int nongit = 0; @@ -27,12 +27,7 @@ int cmd_bundle(int argc, const char **argv, const char *prefix) argc -= 2; argv += 2; - prefix = setup_git_directory_gently(&nongit); - if (prefix && bundle_file[0] != '/') { - snprintf(buffer, sizeof(buffer), "%s/%s", prefix, bundle_file); - bundle_file = buffer; - } - + setup_git_directory_gently(&nongit); memset(&header, 0, sizeof(header)); if (strcmp(cmd, "create") && (bundle_fd = read_bundle_header(bundle_file, &header)) < 0) diff --git a/builtin-config.c b/builtin-config.c index 2b9a426..ae6be9b 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -262,11 +262,11 @@ static int get_colorbool(int argc, const char **argv) } } -int cmd_config(int argc, const char **argv, const char *prefix) +int cmd_config(int argc, const char **argv, const char *unused_prefix) { int nongit = 0; char* value; - const char *file = setup_git_directory_gently(&nongit); + setup_git_directory_gently(&nongit); while (1 < argc) { if (!strcmp(argv[1], "--int")) @@ -276,8 +276,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) { if (argc != 2) usage(git_config_set_usage); - if (git_config(show_all_config) < 0 && file && errno) - die("unable to read config file %s: %s", file, + if (git_config(show_all_config) < 0 && errno) + die("unable to read config file: %s", strerror(errno)); return 0; } @@ -296,12 +296,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) else if (!strcmp(argv[1], "--file") || !strcmp(argv[1], "-f")) { if (argc < 3) usage(git_config_set_usage); - if (!is_absolute_path(argv[2]) && file) - file = prefix_filename(file, strlen(file), - argv[2]); - else - file = argv[2]; - setenv(CONFIG_ENVIRONMENT, file, 1); + setenv(CONFIG_ENVIRONMENT, argv[2], 1); argc--; argv++; } diff --git a/builtin-diff-files.c b/builtin-diff-files.c index 11671a8..2529900 100644 --- a/builtin-diff-files.c +++ b/builtin-diff-files.c @@ -13,21 +13,21 @@ static const char diff_files_usage[] = "git-diff-files [-q] [-0/-1/2/3 |-c|--cc|--no-index] [<common diff options>] [<path>...]" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_files(int argc, const char **argv, const char *prefix) +int cmd_diff_files(int argc, const char **argv, const char *unused_prefix) { struct rev_info rev; int nongit = 0; int result; - prefix = setup_git_directory_gently(&nongit); - init_revisions(&rev, prefix); + setup_git_directory_gently(&nongit); + init_revisions(&rev, NULL); git_config(git_diff_basic_config); /* no "diff" UI options */ rev.abbrev = 0; - if (!setup_diff_no_index(&rev, argc, argv, nongit, prefix)) + if (!setup_diff_no_index(&rev, argc, argv, nongit, NULL)) argc = 0; else { - rev.prefix = setup_work_tree(prefix); + rev.prefix = setup_work_tree(NULL); argc = setup_revisions(argc, argv, &rev, NULL); } if (!rev.diffopt.output_format) diff --git a/builtin-diff.c b/builtin-diff.c index 254e5a0..61b30e6 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -202,7 +202,7 @@ static void refresh_index_quietly(void) rollback_lock_file(lock_file); } -int cmd_diff(int argc, const char **argv, const char *prefix) +int cmd_diff(int argc, const char **argv, const char *unused_prefix) { int i; struct rev_info rev; @@ -233,19 +233,20 @@ int cmd_diff(int argc, const char **argv, const char *prefix) * Other cases are errors. */ - prefix = setup_git_directory_gently(&nongit); + setup_git_directory_gently(&nongit); git_config(git_diff_ui_config); if (diff_use_color_default == -1) diff_use_color_default = git_use_color_default; - init_revisions(&rev, prefix); + init_revisions(&rev, NULL); rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; - if (!setup_diff_no_index(&rev, argc, argv, nongit, prefix)) + if (!setup_diff_no_index(&rev, argc, argv, nongit, NULL)) argc = 0; else { - rev.prefix = setup_work_tree(prefix); + rev.prefix = setup_work_tree(NULL); + rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; argc = setup_revisions(argc, argv, &rev, NULL); } if (!rev.diffopt.output_format) { diff --git a/builtin-upload-archive.c b/builtin-upload-archive.c index 48ae09e..4f7fa35 100644 --- a/builtin-upload-archive.c +++ b/builtin-upload-archive.c @@ -17,7 +17,7 @@ static const char lostchild[] = "git-upload-archive: archiver process was lost"; -static int run_upload_archive(int argc, const char **argv, const char *prefix) +static int run_upload_archive(int argc, const char **argv, const char *unused_prefix) { struct archiver ar; const char *sent_argv[MAX_ARGS]; @@ -67,7 +67,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix) /* parse all options sent by the client */ treeish_idx = parse_archive_args(sent_argc, sent_argv, &ar); - parse_treeish_arg(sent_argv + treeish_idx, &ar.args, prefix); + parse_treeish_arg(sent_argv + treeish_idx, &ar.args, NULL); parse_pathspec_arg(sent_argv + treeish_idx + 1, &ar.args); return ar.write_archive(&ar.args); diff --git a/cache.h b/cache.h index dc768db..a5952db 100644 --- a/cache.h +++ b/cache.h @@ -283,7 +283,7 @@ extern const char *get_git_work_tree(void); extern const char **get_pathspec(const char *prefix, const char **pathspec); extern const char *setup_work_tree(const char *prefix); -extern const char *setup_git_directory_gently(int *); +extern void setup_git_directory_gently(int *); extern const char *setup_git_directory(void); extern const char *prefix_path(const char *prefix, int len, const char *path); extern const char *prefix_filename(const char *prefix, int len, const char *path); diff --git a/git.c b/git.c index 90451ee..ffdf6b9 100644 --- a/git.c +++ b/git.c @@ -156,11 +156,10 @@ static int split_cmdline(char *cmdline, const char ***argv) static int handle_alias(int *argcp, const char ***argv) { int nongit = 0, envchanged = 0, ret = 0, saved_errno = errno; - const char *subdir; int count, option_count; const char** new_argv; - subdir = setup_git_directory_gently(&nongit); + setup_git_directory_gently(&nongit); alias_command = (*argv)[0]; git_config(git_alias_config); @@ -216,9 +215,6 @@ static int handle_alias(int *argcp, const char ***argv) ret = 1; } - if (subdir) - chdir(subdir); - errno = saved_errno; return ret; diff --git a/hash-object.c b/hash-object.c index 46d57ad..5986701 100644 --- a/hash-object.c +++ b/hash-object.c @@ -38,14 +38,11 @@ int main(int argc, char **argv) int i; const char *type = blob_type; int write_object = 0; - const char *prefix = NULL; - int prefix_length = -1; int no_more_flags = 0; int hashstdin = 0; int nongit = 0; - prefix = setup_git_directory_gently(&nongit); - prefix_length = prefix ? strlen(prefix) : 0; + setup_git_directory_gently(&nongit); git_config(git_default_config); for (i = 1 ; i < argc; i++) { @@ -80,9 +77,6 @@ int main(int argc, char **argv) hash_stdin(type, write_object); hashstdin = 0; } - if (0 <= prefix_length) - arg = prefix_filename(prefix, prefix_length, - arg); hash_object(arg, type_from_string(type), write_object); no_more_flags = 1; } diff --git a/setup.c b/setup.c index 6c908a5..78ae2f9 100644 --- a/setup.c +++ b/setup.c @@ -301,7 +301,7 @@ static int check_repository_format_gently(int *nongit_ok) * We cannot decide in this function whether we are in the work tree or * not, since the config can only be read _after_ this function was called. */ -const char *setup_git_directory_gently(int *nongit_ok) +void setup_git_directory_gently(int *nongit_ok) { const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); static char cwd[PATH_MAX+1]; @@ -335,11 +335,11 @@ const char *setup_git_directory_gently(int *nongit_ok) inside_work_tree = 1; } check_repository_format_gently(nongit_ok); - return NULL; + return; } if (nongit_ok) { *nongit_ok = 1; - return NULL; + return; } die("Not a git repository: '%s'", gitdirenv); } @@ -364,9 +364,12 @@ const char *setup_git_directory_gently(int *nongit_ok) inside_git_dir = 1; if (!work_tree_env) inside_work_tree = 0; - setenv(GIT_DIR_ENVIRONMENT, ".", 1); + if (chdir(cwd)) + die("Cannot come back to cwd"); + cwd[offset] = '\0'; + setenv(GIT_DIR_ENVIRONMENT, cwd, 1); check_repository_format_gently(nongit_ok); - return NULL; + return; } chdir(".."); do { @@ -375,27 +378,23 @@ const char *setup_git_directory_gently(int *nongit_ok) if (chdir(cwd)) die("Cannot come back to cwd"); *nongit_ok = 1; - return NULL; + return; } die("Not a git repository"); } } while (cwd[--offset] != '/'); } + if (chdir(cwd)) + die("Cannot come back to cwd"); inside_git_dir = 0; if (!work_tree_env) inside_work_tree = 1; git_work_tree_cfg = xstrndup(cwd, offset); - if (check_repository_format_gently(nongit_ok)) - return NULL; - if (offset == len) - return NULL; - - /* Make "offset" point to past the '/', and add a '/' at the end */ - offset++; - cwd[len++] = '/'; - cwd[len] = 0; - return cwd + offset; + cwd[offset] = '/'; + strcpy(cwd+offset+1, DEFAULT_GIT_DIR_ENVIRONMENT); + setenv(GIT_DIR_ENVIRONMENT, cwd, 1); + check_repository_format_gently(nongit_ok); } int git_config_perm(const char *var, const char *value) @@ -444,5 +443,6 @@ int check_repository_format(void) const char *setup_git_directory(void) { - return setup_git_directory_gently(NULL); + setup_git_directory_gently(NULL); + return is_inside_work_tree() ? setup_work_tree(NULL) : NULL; } -- 1.5.4.2.281.g28d0e - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html