rev-parse: add --show-superproject-working-tree
In some situations it is useful to know if the given repository is a submodule of another repository. Add the flag --show-superproject-working-tree to git-rev-parse to make it easy to find out if there is a superproject. When no superproject exists, the output will be empty. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
e0688e9b28
commit
bf0231c661
82
submodule.c
82
submodule.c
@ -1514,3 +1514,85 @@ void absorb_git_dir_into_superproject(const char *prefix,
|
||||
strbuf_release(&sb);
|
||||
}
|
||||
}
|
||||
|
||||
const char *get_superproject_working_tree(void)
|
||||
{
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
const char *one_up = real_path_if_valid("../");
|
||||
const char *cwd = xgetcwd();
|
||||
const char *ret = NULL;
|
||||
const char *subpath;
|
||||
int code;
|
||||
ssize_t len;
|
||||
|
||||
if (!is_inside_work_tree())
|
||||
/*
|
||||
* FIXME:
|
||||
* We might have a superproject, but it is harder
|
||||
* to determine.
|
||||
*/
|
||||
return NULL;
|
||||
|
||||
if (!one_up)
|
||||
return NULL;
|
||||
|
||||
subpath = relative_path(cwd, one_up, &sb);
|
||||
|
||||
prepare_submodule_repo_env(&cp.env_array);
|
||||
argv_array_pop(&cp.env_array);
|
||||
|
||||
argv_array_pushl(&cp.args, "--literal-pathspecs", "-C", "..",
|
||||
"ls-files", "-z", "--stage", "--full-name", "--",
|
||||
subpath, NULL);
|
||||
strbuf_reset(&sb);
|
||||
|
||||
cp.no_stdin = 1;
|
||||
cp.no_stderr = 1;
|
||||
cp.out = -1;
|
||||
cp.git_cmd = 1;
|
||||
|
||||
if (start_command(&cp))
|
||||
die(_("could not start ls-files in .."));
|
||||
|
||||
len = strbuf_read(&sb, cp.out, PATH_MAX);
|
||||
close(cp.out);
|
||||
|
||||
if (starts_with(sb.buf, "160000")) {
|
||||
int super_sub_len;
|
||||
int cwd_len = strlen(cwd);
|
||||
char *super_sub, *super_wt;
|
||||
|
||||
/*
|
||||
* There is a superproject having this repo as a submodule.
|
||||
* The format is <mode> SP <hash> SP <stage> TAB <full name> \0,
|
||||
* We're only interested in the name after the tab.
|
||||
*/
|
||||
super_sub = strchr(sb.buf, '\t') + 1;
|
||||
super_sub_len = sb.buf + sb.len - super_sub - 1;
|
||||
|
||||
if (super_sub_len > cwd_len ||
|
||||
strcmp(&cwd[cwd_len - super_sub_len], super_sub))
|
||||
die (_("BUG: returned path string doesn't match cwd?"));
|
||||
|
||||
super_wt = xstrdup(cwd);
|
||||
super_wt[cwd_len - super_sub_len] = '\0';
|
||||
|
||||
ret = real_path(super_wt);
|
||||
free(super_wt);
|
||||
}
|
||||
strbuf_release(&sb);
|
||||
|
||||
code = finish_command(&cp);
|
||||
|
||||
if (code == 128)
|
||||
/* '../' is not a git repository */
|
||||
return NULL;
|
||||
if (code == 0 && len == 0)
|
||||
/* There is an unrelated git repository at '../' */
|
||||
return NULL;
|
||||
if (code)
|
||||
die(_("ls-tree returned unexpected return code %d"), code);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user