diff --git a/Documentation/git.txt b/Documentation/git.txt index 7913fc2513234d..2188ae60566849 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -13,6 +13,7 @@ SYNOPSIS [--exec-path[=]] [--html-path] [--man-path] [--info-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=] [--work-tree=] [--namespace=] + [--super-prefix=] [] DESCRIPTION @@ -601,6 +602,11 @@ foo.bar= ...`) sets `foo.bar` to the empty string. details. Equivalent to setting the `GIT_NAMESPACE` environment variable. +--super-prefix=:: + Currently for internal use only. Set a prefix which gives a path from + above a repository down to its root. One use is to give submodules + context about the superproject that invoked it. + --bare:: Treat the repository as a bare repository. If GIT_DIR environment is not set, it is set to the current working diff --git a/cache.h b/cache.h index 35563266bf54c4..8cf495db75914f 100644 --- a/cache.h +++ b/cache.h @@ -408,6 +408,7 @@ static inline enum object_type object_type(unsigned int mode) #define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE" #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE" #define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX" +#define GIT_SUPER_PREFIX_ENVIRONMENT "GIT_INTERNAL_SUPER_PREFIX" #define DEFAULT_GIT_DIR_ENVIRONMENT ".git" #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY" #define INDEX_ENVIRONMENT "GIT_INDEX_FILE" @@ -468,6 +469,7 @@ extern int get_common_dir_noenv(struct strbuf *sb, const char *gitdir); extern int get_common_dir(struct strbuf *sb, const char *gitdir); extern const char *get_git_namespace(void); extern const char *strip_namespace(const char *namespaced_ref); +extern const char *get_super_prefix(void); extern const char *get_git_work_tree(void); /* diff --git a/environment.c b/environment.c index ca72464a985021..d12d7db20a5552 100644 --- a/environment.c +++ b/environment.c @@ -100,6 +100,8 @@ static char *work_tree; static const char *namespace; static size_t namespace_len; +static const char *super_prefix; + static const char *git_dir, *git_common_dir; static char *git_object_dir, *git_index_file, *git_graft_file; int git_db_env, git_index_env, git_graft_env, git_common_dir_env; @@ -120,6 +122,7 @@ const char * const local_repo_env[] = { NO_REPLACE_OBJECTS_ENVIRONMENT, GIT_REPLACE_REF_BASE_ENVIRONMENT, GIT_PREFIX_ENVIRONMENT, + GIT_SUPER_PREFIX_ENVIRONMENT, GIT_SHALLOW_FILE_ENVIRONMENT, GIT_COMMON_DIR_ENVIRONMENT, NULL @@ -222,6 +225,16 @@ const char *strip_namespace(const char *namespaced_ref) return namespaced_ref + namespace_len; } +const char *get_super_prefix(void) +{ + static int initialized; + if (!initialized) { + super_prefix = getenv(GIT_SUPER_PREFIX_ENVIRONMENT); + initialized = 1; + } + return super_prefix; +} + static int git_work_tree_initialized; /* diff --git a/git.c b/git.c index 1c611517585318..469a83f2b42ce7 100644 --- a/git.c +++ b/git.c @@ -164,6 +164,20 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) setenv(GIT_WORK_TREE_ENVIRONMENT, cmd, 1); if (envchanged) *envchanged = 1; + } else if (!strcmp(cmd, "--super-prefix")) { + if (*argc < 2) { + fprintf(stderr, "No prefix given for --super-prefix.\n" ); + usage(git_usage_string); + } + setenv(GIT_SUPER_PREFIX_ENVIRONMENT, (*argv)[1], 1); + if (envchanged) + *envchanged = 1; + (*argv)++; + (*argc)--; + } else if (skip_prefix(cmd, "--super-prefix=", &cmd)) { + setenv(GIT_SUPER_PREFIX_ENVIRONMENT, cmd, 1); + if (envchanged) + *envchanged = 1; } else if (!strcmp(cmd, "--bare")) { char *cwd = xgetcwd(); is_bare_repository_cfg = 1; @@ -310,6 +324,7 @@ static int handle_alias(int *argcp, const char ***argv) * RUN_SETUP for reading from the configuration file. */ #define NEED_WORK_TREE (1<<3) +#define SUPPORT_SUPER_PREFIX (1<<4) struct cmd_struct { const char *cmd; @@ -344,6 +359,13 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) } commit_pager_choice(); + if (!help && get_super_prefix()) { + if (!(p->option & SUPPORT_SUPER_PREFIX)) + die("%s doesn't support --super-prefix", p->cmd); + if (prefix) + die("can't use --super-prefix from a subdirectory"); + } + if (!help && p->option & NEED_WORK_TREE) setup_work_tree(); @@ -558,6 +580,9 @@ static void execv_dashed_external(const char **argv) const char *tmp; int status; + if (get_super_prefix()) + die("%s doesn't support --super-prefix", argv[0]); + if (use_pager == -1) use_pager = check_pager_config(argv[0]); commit_pager_choice();