Skip to content

Commit

Permalink
git: make super-prefix option
Browse files Browse the repository at this point in the history
Add a super-prefix environment variable 'GIT_INTERNAL_SUPER_PREFIX'
which can be used to specify a path from above a repository down to its
root.  When such a super-prefix is specified, the paths reported by Git
are prefixed with it to make them relative to that directory "above".
The paths given by the user on the command line
(e.g. "git subcmd --output-file=path/to/a/file" and pathspecs) are taken
relative to the directory "above" to match.

The immediate use of this option is by commands which have a
--recurse-submodule option in order to give context to submodules about
how they were invoked.  This option is currently only allowed for
builtins which support a super-prefix.

Signed-off-by: Brandon Williams <bmwill@google.com>
Reviewed-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
bmwill authored and gitster committed Oct 10, 2016
1 parent 35f6318 commit 74866d7
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Documentation/git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SYNOPSIS
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[--super-prefix=<path>]
<command> [<args>]

DESCRIPTION
Expand Down Expand Up @@ -601,6 +602,11 @@ foo.bar= ...`) sets `foo.bar` to the empty string.
details. Equivalent to setting the `GIT_NAMESPACE` environment
variable.

--super-prefix=<path>::
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
Expand Down
2 changes: 2 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

/*
Expand Down
13 changes: 13 additions & 0 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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;

/*
Expand Down
25 changes: 25 additions & 0 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 74866d7

Please sign in to comment.