read-tree: add "--super-prefix" option, eliminate global
The "--super-prefix" option to "git" was initially added in [1] for use with "ls-files"[2], and shortly thereafter "submodule--helper"[3] and "grep"[4]. It wasn't until [5] that "read-tree" made use of it. At the time [5] made sense, but since then we've made "ls-files" recurse in-process in [6], "grep" in [7], and finally "submodule--helper" in the preceding commits. Let's also remove it from "read-tree", which allows us to remove the option to "git" itself. We can do this because the only remaining user of it is the submodule API, which will now invoke "read-tree" with its new "--super-prefix" option. It will only do so when the "submodule_move_head()" function is called. That "submodule_move_head()" function was then only invoked by "read-tree" itself, but now rather than setting an environment variable to pass "--super-prefix" between cmd_read_tree() we: - Set a new "super_prefix" in "struct unpack_trees_options". The "super_prefixed()" function in "unpack-trees.c" added in [5] will now use this, rather than get_super_prefix() looking up the environment variable we set earlier in the same process. - Add the same field to the "struct checkout", which is only needed to ferry the "super_prefix" in the "struct unpack_trees_options" all the way down to the "entry.c" callers of "submodule_move_head()". Those calls which used the super prefix all originated in "cmd_read_tree()". The only other caller is the "unlink_entry()" caller in "builtin/checkout.c", which now passes a "NULL". 1.74866d7579
(git: make super-prefix option, 2016-10-07) 2.e77aa336f1
(ls-files: optionally recurse into submodules, 2016-10-07) 3.89c8626557
(submodule helper: support super prefix, 2016-12-08) 4.0281e487fd
(grep: optionally recurse into submodules, 2016-12-16) 5.3d415425c7
(unpack-trees: support super-prefix option, 2017-01-17) 6.188dce131f
(ls-files: use repository object, 2017-06-22) 7.f9ee2fcdfa
(grep: recurse in-process using 'struct repository', 2017-08-02) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
f5a6be9d54
commit
4002ec3dcf
@ -13,8 +13,7 @@ SYNOPSIS
|
|||||||
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
|
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
|
||||||
[-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]
|
[-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]
|
||||||
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
|
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
|
||||||
[--super-prefix=<path>] [--config-env=<name>=<envvar>]
|
[--config-env=<name>=<envvar>] <command> [<args>]
|
||||||
<command> [<args>]
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -169,11 +168,6 @@ If you just want to run git as if it was started in `<path>` then use
|
|||||||
details. Equivalent to setting the `GIT_NAMESPACE` environment
|
details. Equivalent to setting the `GIT_NAMESPACE` environment
|
||||||
variable.
|
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::
|
--bare::
|
||||||
Treat the repository as a bare repository. If GIT_DIR
|
Treat the repository as a bare repository. If GIT_DIR
|
||||||
environment is not set, it is set to the current working
|
environment is not set, it is set to the current working
|
||||||
|
@ -51,10 +51,6 @@
|
|||||||
* on bare repositories.
|
* on bare repositories.
|
||||||
* This only makes sense when `RUN_SETUP` is also set.
|
* This only makes sense when `RUN_SETUP` is also set.
|
||||||
*
|
*
|
||||||
* `SUPPORT_SUPER_PREFIX`:
|
|
||||||
*
|
|
||||||
* The built-in supports `--super-prefix`.
|
|
||||||
*
|
|
||||||
* `DELAY_PAGER_CONFIG`:
|
* `DELAY_PAGER_CONFIG`:
|
||||||
*
|
*
|
||||||
* If RUN_SETUP or RUN_SETUP_GENTLY is set, git.c normally handles
|
* If RUN_SETUP or RUN_SETUP_GENTLY is set, git.c normally handles
|
||||||
|
@ -232,7 +232,7 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
|
|||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
if (!overlay_mode) {
|
if (!overlay_mode) {
|
||||||
unlink_entry(ce);
|
unlink_entry(ce, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (stage == 2)
|
if (stage == 2)
|
||||||
|
@ -114,6 +114,7 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
|
|||||||
int prefix_set = 0;
|
int prefix_set = 0;
|
||||||
struct lock_file lock_file = LOCK_INIT;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
const struct option read_tree_options[] = {
|
const struct option read_tree_options[] = {
|
||||||
|
OPT__SUPER_PREFIX(&opts.super_prefix),
|
||||||
OPT_CALLBACK_F(0, "index-output", NULL, N_("file"),
|
OPT_CALLBACK_F(0, "index-output", NULL, N_("file"),
|
||||||
N_("write resulting index to <file>"),
|
N_("write resulting index to <file>"),
|
||||||
PARSE_OPT_NONEG, index_output_cb),
|
PARSE_OPT_NONEG, index_output_cb),
|
||||||
|
2
cache.h
2
cache.h
@ -480,7 +480,6 @@ static inline enum object_type object_type(unsigned int mode)
|
|||||||
#define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE"
|
#define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE"
|
||||||
#define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
|
#define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
|
||||||
#define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX"
|
#define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX"
|
||||||
#define GIT_SUPER_PREFIX_ENVIRONMENT "GIT_INTERNAL_SUPER_PREFIX"
|
|
||||||
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
|
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
|
||||||
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
|
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
|
||||||
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
|
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
|
||||||
@ -566,7 +565,6 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
|
|||||||
int get_common_dir(struct strbuf *sb, const char *gitdir);
|
int get_common_dir(struct strbuf *sb, const char *gitdir);
|
||||||
const char *get_git_namespace(void);
|
const char *get_git_namespace(void);
|
||||||
const char *strip_namespace(const char *namespaced_ref);
|
const char *strip_namespace(const char *namespaced_ref);
|
||||||
const char *get_super_prefix(void);
|
|
||||||
const char *get_git_work_tree(void);
|
const char *get_git_work_tree(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
12
entry.c
12
entry.c
@ -383,7 +383,7 @@ static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca
|
|||||||
return error("cannot create submodule directory %s", path);
|
return error("cannot create submodule directory %s", path);
|
||||||
sub = submodule_from_ce(ce);
|
sub = submodule_from_ce(ce);
|
||||||
if (sub)
|
if (sub)
|
||||||
return submodule_move_head(ce->name,
|
return submodule_move_head(ce->name, state->super_prefix,
|
||||||
NULL, oid_to_hex(&ce->oid),
|
NULL, oid_to_hex(&ce->oid),
|
||||||
state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
|
state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
|
||||||
break;
|
break;
|
||||||
@ -476,7 +476,7 @@ int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca,
|
|||||||
* no pathname to return.
|
* no pathname to return.
|
||||||
*/
|
*/
|
||||||
BUG("Can't remove entry to a path");
|
BUG("Can't remove entry to a path");
|
||||||
unlink_entry(ce);
|
unlink_entry(ce, state->super_prefix);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,10 +510,10 @@ int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca,
|
|||||||
if (!(st.st_mode & S_IFDIR))
|
if (!(st.st_mode & S_IFDIR))
|
||||||
unlink_or_warn(ce->name);
|
unlink_or_warn(ce->name);
|
||||||
|
|
||||||
return submodule_move_head(ce->name,
|
return submodule_move_head(ce->name, state->super_prefix,
|
||||||
NULL, oid_to_hex(&ce->oid), 0);
|
NULL, oid_to_hex(&ce->oid), 0);
|
||||||
} else
|
} else
|
||||||
return submodule_move_head(ce->name,
|
return submodule_move_head(ce->name, state->super_prefix,
|
||||||
"HEAD", oid_to_hex(&ce->oid),
|
"HEAD", oid_to_hex(&ce->oid),
|
||||||
state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
|
state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
|
||||||
}
|
}
|
||||||
@ -560,12 +560,12 @@ int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca,
|
|||||||
return write_entry(ce, path.buf, ca, state, 0, nr_checkouts);
|
return write_entry(ce, path.buf, ca, state, 0, nr_checkouts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlink_entry(const struct cache_entry *ce)
|
void unlink_entry(const struct cache_entry *ce, const char *super_prefix)
|
||||||
{
|
{
|
||||||
const struct submodule *sub = submodule_from_ce(ce);
|
const struct submodule *sub = submodule_from_ce(ce);
|
||||||
if (sub) {
|
if (sub) {
|
||||||
/* state.force is set at the caller. */
|
/* state.force is set at the caller. */
|
||||||
submodule_move_head(ce->name, "HEAD", NULL,
|
submodule_move_head(ce->name, super_prefix, "HEAD", NULL,
|
||||||
SUBMODULE_MOVE_HEAD_FORCE);
|
SUBMODULE_MOVE_HEAD_FORCE);
|
||||||
}
|
}
|
||||||
if (check_leading_path(ce->name, ce_namelen(ce), 1) >= 0)
|
if (check_leading_path(ce->name, ce_namelen(ce), 1) >= 0)
|
||||||
|
6
entry.h
6
entry.h
@ -8,6 +8,7 @@ struct checkout {
|
|||||||
struct index_state *istate;
|
struct index_state *istate;
|
||||||
const char *base_dir;
|
const char *base_dir;
|
||||||
int base_dir_len;
|
int base_dir_len;
|
||||||
|
const char *super_prefix;
|
||||||
struct delayed_checkout *delayed_checkout;
|
struct delayed_checkout *delayed_checkout;
|
||||||
struct checkout_metadata meta;
|
struct checkout_metadata meta;
|
||||||
unsigned force:1,
|
unsigned force:1,
|
||||||
@ -48,8 +49,11 @@ int finish_delayed_checkout(struct checkout *state, int show_progress);
|
|||||||
/*
|
/*
|
||||||
* Unlink the last component and schedule the leading directories for
|
* Unlink the last component and schedule the leading directories for
|
||||||
* removal, such that empty directories get removed.
|
* removal, such that empty directories get removed.
|
||||||
|
*
|
||||||
|
* The "super_prefix" is either NULL, or the "--super-prefix" passed
|
||||||
|
* down from "read-tree" et al.
|
||||||
*/
|
*/
|
||||||
void unlink_entry(const struct cache_entry *ce);
|
void unlink_entry(const struct cache_entry *ce, const char *super_prefix);
|
||||||
|
|
||||||
void *read_blob_entry(const struct cache_entry *ce, size_t *size);
|
void *read_blob_entry(const struct cache_entry *ce, size_t *size);
|
||||||
int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st);
|
int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st);
|
||||||
|
@ -102,8 +102,6 @@ char *git_work_tree_cfg;
|
|||||||
|
|
||||||
static char *git_namespace;
|
static char *git_namespace;
|
||||||
|
|
||||||
static char *super_prefix;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Repository-local GIT_* environment variables; see cache.h for details.
|
* Repository-local GIT_* environment variables; see cache.h for details.
|
||||||
*/
|
*/
|
||||||
@ -121,7 +119,6 @@ const char * const local_repo_env[] = {
|
|||||||
NO_REPLACE_OBJECTS_ENVIRONMENT,
|
NO_REPLACE_OBJECTS_ENVIRONMENT,
|
||||||
GIT_REPLACE_REF_BASE_ENVIRONMENT,
|
GIT_REPLACE_REF_BASE_ENVIRONMENT,
|
||||||
GIT_PREFIX_ENVIRONMENT,
|
GIT_PREFIX_ENVIRONMENT,
|
||||||
GIT_SUPER_PREFIX_ENVIRONMENT,
|
|
||||||
GIT_SHALLOW_FILE_ENVIRONMENT,
|
GIT_SHALLOW_FILE_ENVIRONMENT,
|
||||||
GIT_COMMON_DIR_ENVIRONMENT,
|
GIT_COMMON_DIR_ENVIRONMENT,
|
||||||
NULL
|
NULL
|
||||||
@ -234,16 +231,6 @@ const char *strip_namespace(const char *namespaced_ref)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_super_prefix(void)
|
|
||||||
{
|
|
||||||
static int initialized;
|
|
||||||
if (!initialized) {
|
|
||||||
super_prefix = xstrdup_or_null(getenv(GIT_SUPER_PREFIX_ENVIRONMENT));
|
|
||||||
initialized = 1;
|
|
||||||
}
|
|
||||||
return super_prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int git_work_tree_initialized;
|
static int git_work_tree_initialized;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
37
git.c
37
git.c
@ -14,9 +14,8 @@
|
|||||||
* RUN_SETUP for reading from the configuration file.
|
* RUN_SETUP for reading from the configuration file.
|
||||||
*/
|
*/
|
||||||
#define NEED_WORK_TREE (1<<3)
|
#define NEED_WORK_TREE (1<<3)
|
||||||
#define SUPPORT_SUPER_PREFIX (1<<4)
|
#define DELAY_PAGER_CONFIG (1<<4)
|
||||||
#define DELAY_PAGER_CONFIG (1<<5)
|
#define NO_PARSEOPT (1<<5) /* parse-options is not used */
|
||||||
#define NO_PARSEOPT (1<<6) /* parse-options is not used */
|
|
||||||
|
|
||||||
struct cmd_struct {
|
struct cmd_struct {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
@ -29,8 +28,7 @@ const char git_usage_string[] =
|
|||||||
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
|
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
|
||||||
" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
|
" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
|
||||||
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
|
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
|
||||||
" [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
|
" [--config-env=<name>=<envvar>] <command> [<args>]");
|
||||||
" <command> [<args>]");
|
|
||||||
|
|
||||||
const char git_more_info_string[] =
|
const char git_more_info_string[] =
|
||||||
N_("'git help -a' and 'git help -g' list available subcommands and some\n"
|
N_("'git help -a' and 'git help -g' list available subcommands and some\n"
|
||||||
@ -226,20 +224,6 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
|
|||||||
setenv(GIT_WORK_TREE_ENVIRONMENT, cmd, 1);
|
setenv(GIT_WORK_TREE_ENVIRONMENT, cmd, 1);
|
||||||
if (envchanged)
|
if (envchanged)
|
||||||
*envchanged = 1;
|
*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")) {
|
} else if (!strcmp(cmd, "--bare")) {
|
||||||
char *cwd = xgetcwd();
|
char *cwd = xgetcwd();
|
||||||
is_bare_repository_cfg = 1;
|
is_bare_repository_cfg = 1;
|
||||||
@ -449,11 +433,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
|
|||||||
trace_repo_setup(prefix);
|
trace_repo_setup(prefix);
|
||||||
commit_pager_choice();
|
commit_pager_choice();
|
||||||
|
|
||||||
if (!help && get_super_prefix()) {
|
|
||||||
if (!(p->option & SUPPORT_SUPER_PREFIX))
|
|
||||||
die(_("%s doesn't support --super-prefix"), p->cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!help && p->option & NEED_WORK_TREE)
|
if (!help && p->option & NEED_WORK_TREE)
|
||||||
setup_work_tree();
|
setup_work_tree();
|
||||||
|
|
||||||
@ -504,7 +483,7 @@ static struct cmd_struct commands[] = {
|
|||||||
{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
|
{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
|
||||||
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
|
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
|
||||||
{ "checkout--worker", cmd_checkout__worker,
|
{ "checkout--worker", cmd_checkout__worker,
|
||||||
RUN_SETUP | NEED_WORK_TREE | SUPPORT_SUPER_PREFIX },
|
RUN_SETUP | NEED_WORK_TREE },
|
||||||
{ "checkout-index", cmd_checkout_index,
|
{ "checkout-index", cmd_checkout_index,
|
||||||
RUN_SETUP | NEED_WORK_TREE},
|
RUN_SETUP | NEED_WORK_TREE},
|
||||||
{ "cherry", cmd_cherry, RUN_SETUP },
|
{ "cherry", cmd_cherry, RUN_SETUP },
|
||||||
@ -583,7 +562,7 @@ static struct cmd_struct commands[] = {
|
|||||||
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
|
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
|
||||||
{ "push", cmd_push, RUN_SETUP },
|
{ "push", cmd_push, RUN_SETUP },
|
||||||
{ "range-diff", cmd_range_diff, RUN_SETUP | USE_PAGER },
|
{ "range-diff", cmd_range_diff, RUN_SETUP | USE_PAGER },
|
||||||
{ "read-tree", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},
|
{ "read-tree", cmd_read_tree, RUN_SETUP },
|
||||||
{ "rebase", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },
|
{ "rebase", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },
|
||||||
{ "receive-pack", cmd_receive_pack },
|
{ "receive-pack", cmd_receive_pack },
|
||||||
{ "reflog", cmd_reflog, RUN_SETUP },
|
{ "reflog", cmd_reflog, RUN_SETUP },
|
||||||
@ -727,9 +706,6 @@ static void execv_dashed_external(const char **argv)
|
|||||||
struct child_process cmd = CHILD_PROCESS_INIT;
|
struct child_process cmd = CHILD_PROCESS_INIT;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (get_super_prefix())
|
|
||||||
die(_("%s doesn't support --super-prefix"), argv[0]);
|
|
||||||
|
|
||||||
if (use_pager == -1 && !is_builtin(argv[0]))
|
if (use_pager == -1 && !is_builtin(argv[0]))
|
||||||
use_pager = check_pager_config(argv[0]);
|
use_pager = check_pager_config(argv[0]);
|
||||||
commit_pager_choice();
|
commit_pager_choice();
|
||||||
@ -799,9 +775,6 @@ static int run_argv(int *argcp, const char ***argv)
|
|||||||
*/
|
*/
|
||||||
trace2_cmd_name("_run_git_alias_");
|
trace2_cmd_name("_run_git_alias_");
|
||||||
|
|
||||||
if (get_super_prefix())
|
|
||||||
die("%s doesn't support --super-prefix", **argv);
|
|
||||||
|
|
||||||
commit_pager_choice();
|
commit_pager_choice();
|
||||||
|
|
||||||
strvec_push(&cmd.args, "git");
|
strvec_push(&cmd.args, "git");
|
||||||
|
27
submodule.c
27
submodule.c
@ -2054,14 +2054,6 @@ void submodule_unset_core_worktree(const struct submodule *sub)
|
|||||||
strbuf_release(&config_path);
|
strbuf_release(&config_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *get_super_prefix_or_empty(void)
|
|
||||||
{
|
|
||||||
const char *s = get_super_prefix();
|
|
||||||
if (!s)
|
|
||||||
s = "";
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int submodule_has_dirty_index(const struct submodule *sub)
|
static int submodule_has_dirty_index(const struct submodule *sub)
|
||||||
{
|
{
|
||||||
struct child_process cp = CHILD_PROCESS_INIT;
|
struct child_process cp = CHILD_PROCESS_INIT;
|
||||||
@ -2080,7 +2072,7 @@ static int submodule_has_dirty_index(const struct submodule *sub)
|
|||||||
return finish_command(&cp);
|
return finish_command(&cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void submodule_reset_index(const char *path)
|
static void submodule_reset_index(const char *path, const char *super_prefix)
|
||||||
{
|
{
|
||||||
struct child_process cp = CHILD_PROCESS_INIT;
|
struct child_process cp = CHILD_PROCESS_INIT;
|
||||||
prepare_submodule_repo_env(&cp.env);
|
prepare_submodule_repo_env(&cp.env);
|
||||||
@ -2089,10 +2081,10 @@ static void submodule_reset_index(const char *path)
|
|||||||
cp.no_stdin = 1;
|
cp.no_stdin = 1;
|
||||||
cp.dir = path;
|
cp.dir = path;
|
||||||
|
|
||||||
strvec_pushf(&cp.args, "--super-prefix=%s%s/",
|
|
||||||
get_super_prefix_or_empty(), path);
|
|
||||||
/* TODO: determine if this might overwright untracked files */
|
/* TODO: determine if this might overwright untracked files */
|
||||||
strvec_pushl(&cp.args, "read-tree", "-u", "--reset", NULL);
|
strvec_pushl(&cp.args, "read-tree", "-u", "--reset", NULL);
|
||||||
|
strvec_pushf(&cp.args, "--super-prefix=%s%s/",
|
||||||
|
(super_prefix ? super_prefix : ""), path);
|
||||||
|
|
||||||
strvec_push(&cp.args, empty_tree_oid_hex());
|
strvec_push(&cp.args, empty_tree_oid_hex());
|
||||||
|
|
||||||
@ -2105,9 +2097,8 @@ static void submodule_reset_index(const char *path)
|
|||||||
* For edge cases (a submodule coming into existence or removing a submodule)
|
* For edge cases (a submodule coming into existence or removing a submodule)
|
||||||
* pass NULL for old or new respectively.
|
* pass NULL for old or new respectively.
|
||||||
*/
|
*/
|
||||||
int submodule_move_head(const char *path,
|
int submodule_move_head(const char *path, const char *super_prefix,
|
||||||
const char *old_head,
|
const char *old_head, const char *new_head,
|
||||||
const char *new_head,
|
|
||||||
unsigned flags)
|
unsigned flags)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -2146,7 +2137,7 @@ int submodule_move_head(const char *path,
|
|||||||
if (old_head) {
|
if (old_head) {
|
||||||
if (!submodule_uses_gitfile(path))
|
if (!submodule_uses_gitfile(path))
|
||||||
absorb_git_dir_into_superproject(path,
|
absorb_git_dir_into_superproject(path,
|
||||||
get_super_prefix());
|
super_prefix);
|
||||||
} else {
|
} else {
|
||||||
struct strbuf gitdir = STRBUF_INIT;
|
struct strbuf gitdir = STRBUF_INIT;
|
||||||
submodule_name_to_gitdir(&gitdir, the_repository,
|
submodule_name_to_gitdir(&gitdir, the_repository,
|
||||||
@ -2155,7 +2146,7 @@ int submodule_move_head(const char *path,
|
|||||||
strbuf_release(&gitdir);
|
strbuf_release(&gitdir);
|
||||||
|
|
||||||
/* make sure the index is clean as well */
|
/* make sure the index is clean as well */
|
||||||
submodule_reset_index(path);
|
submodule_reset_index(path, super_prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
|
if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
|
||||||
@ -2173,9 +2164,9 @@ int submodule_move_head(const char *path,
|
|||||||
cp.no_stdin = 1;
|
cp.no_stdin = 1;
|
||||||
cp.dir = path;
|
cp.dir = path;
|
||||||
|
|
||||||
strvec_pushf(&cp.args, "--super-prefix=%s%s/",
|
|
||||||
get_super_prefix_or_empty(), path);
|
|
||||||
strvec_pushl(&cp.args, "read-tree", "--recurse-submodules", NULL);
|
strvec_pushl(&cp.args, "read-tree", "--recurse-submodules", NULL);
|
||||||
|
strvec_pushf(&cp.args, "--super-prefix=%s%s/",
|
||||||
|
(super_prefix ? super_prefix : ""), path);
|
||||||
|
|
||||||
if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN)
|
if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN)
|
||||||
strvec_push(&cp.args, "-n");
|
strvec_push(&cp.args, "-n");
|
||||||
|
@ -150,9 +150,8 @@ int validate_submodule_git_dir(char *git_dir, const char *submodule_name);
|
|||||||
|
|
||||||
#define SUBMODULE_MOVE_HEAD_DRY_RUN (1<<0)
|
#define SUBMODULE_MOVE_HEAD_DRY_RUN (1<<0)
|
||||||
#define SUBMODULE_MOVE_HEAD_FORCE (1<<1)
|
#define SUBMODULE_MOVE_HEAD_FORCE (1<<1)
|
||||||
int submodule_move_head(const char *path,
|
int submodule_move_head(const char *path, const char *super_prefix,
|
||||||
const char *old,
|
const char *old_head, const char *new_head,
|
||||||
const char *new_head,
|
|
||||||
unsigned flags);
|
unsigned flags);
|
||||||
|
|
||||||
void submodule_unset_core_worktree(const struct submodule *sub);
|
void submodule_unset_core_worktree(const struct submodule *sub);
|
||||||
|
@ -370,7 +370,7 @@ test_expect_success 'read-tree supports the super-prefix' '
|
|||||||
cat <<-EOF >expect &&
|
cat <<-EOF >expect &&
|
||||||
error: Updating '\''fictional/a'\'' would lose untracked files in it
|
error: Updating '\''fictional/a'\'' would lose untracked files in it
|
||||||
EOF
|
EOF
|
||||||
test_must_fail git --super-prefix fictional/ read-tree -u -m "$treeH" "$treeM" 2>actual &&
|
test_must_fail git read-tree --super-prefix fictional/ -u -m "$treeH" "$treeM" 2>actual &&
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -644,7 +644,7 @@ test_expect_success 'repack does not loosen promisor objects' '
|
|||||||
grep "loosen_unused_packed_objects/loosened:0" trace
|
grep "loosen_unused_packed_objects/loosened:0" trace
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_failure 'lazy-fetch in submodule succeeds' '
|
test_expect_success 'lazy-fetch in submodule succeeds' '
|
||||||
# setup
|
# setup
|
||||||
test_config_global protocol.file.allow always &&
|
test_config_global protocol.file.allow always &&
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ static const char *unpack_plumbing_errors[NB_UNPACK_TREES_WARNING_TYPES] = {
|
|||||||
? ((o)->msgs[(type)]) \
|
? ((o)->msgs[(type)]) \
|
||||||
: (unpack_plumbing_errors[(type)]) )
|
: (unpack_plumbing_errors[(type)]) )
|
||||||
|
|
||||||
static const char *super_prefixed(const char *path)
|
static const char *super_prefixed(const char *path, const char *super_prefix)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* It is necessary and sufficient to have two static buffers
|
* It is necessary and sufficient to have two static buffers
|
||||||
@ -83,7 +83,6 @@ static const char *super_prefixed(const char *path)
|
|||||||
static unsigned idx = ARRAY_SIZE(buf) - 1;
|
static unsigned idx = ARRAY_SIZE(buf) - 1;
|
||||||
|
|
||||||
if (super_prefix_len < 0) {
|
if (super_prefix_len < 0) {
|
||||||
const char *super_prefix = get_super_prefix();
|
|
||||||
if (!super_prefix) {
|
if (!super_prefix) {
|
||||||
super_prefix_len = 0;
|
super_prefix_len = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -236,7 +235,8 @@ static int add_rejected_path(struct unpack_trees_options *o,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!o->show_all_errors)
|
if (!o->show_all_errors)
|
||||||
return error(ERRORMSG(o, e), super_prefixed(path));
|
return error(ERRORMSG(o, e), super_prefixed(path,
|
||||||
|
o->super_prefix));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Otherwise, insert in a list for future display by
|
* Otherwise, insert in a list for future display by
|
||||||
@ -263,7 +263,8 @@ static void display_error_msgs(struct unpack_trees_options *o)
|
|||||||
error_displayed = 1;
|
error_displayed = 1;
|
||||||
for (i = 0; i < rejects->nr; i++)
|
for (i = 0; i < rejects->nr; i++)
|
||||||
strbuf_addf(&path, "\t%s\n", rejects->items[i].string);
|
strbuf_addf(&path, "\t%s\n", rejects->items[i].string);
|
||||||
error(ERRORMSG(o, e), super_prefixed(path.buf));
|
error(ERRORMSG(o, e), super_prefixed(path.buf,
|
||||||
|
o->super_prefix));
|
||||||
strbuf_release(&path);
|
strbuf_release(&path);
|
||||||
}
|
}
|
||||||
string_list_clear(rejects, 0);
|
string_list_clear(rejects, 0);
|
||||||
@ -290,7 +291,8 @@ static void display_warning_msgs(struct unpack_trees_options *o)
|
|||||||
warning_displayed = 1;
|
warning_displayed = 1;
|
||||||
for (i = 0; i < rejects->nr; i++)
|
for (i = 0; i < rejects->nr; i++)
|
||||||
strbuf_addf(&path, "\t%s\n", rejects->items[i].string);
|
strbuf_addf(&path, "\t%s\n", rejects->items[i].string);
|
||||||
warning(ERRORMSG(o, e), super_prefixed(path.buf));
|
warning(ERRORMSG(o, e), super_prefixed(path.buf,
|
||||||
|
o->super_prefix));
|
||||||
strbuf_release(&path);
|
strbuf_release(&path);
|
||||||
}
|
}
|
||||||
string_list_clear(rejects, 0);
|
string_list_clear(rejects, 0);
|
||||||
@ -312,7 +314,8 @@ static int check_submodule_move_head(const struct cache_entry *ce,
|
|||||||
if (o->reset)
|
if (o->reset)
|
||||||
flags |= SUBMODULE_MOVE_HEAD_FORCE;
|
flags |= SUBMODULE_MOVE_HEAD_FORCE;
|
||||||
|
|
||||||
if (submodule_move_head(ce->name, old_id, new_id, flags))
|
if (submodule_move_head(ce->name, o->super_prefix, old_id, new_id,
|
||||||
|
flags))
|
||||||
return add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
|
return add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -415,6 +418,7 @@ static int check_updates(struct unpack_trees_options *o,
|
|||||||
int i, pc_workers, pc_threshold;
|
int i, pc_workers, pc_threshold;
|
||||||
|
|
||||||
trace_performance_enter();
|
trace_performance_enter();
|
||||||
|
state.super_prefix = o->super_prefix;
|
||||||
state.force = 1;
|
state.force = 1;
|
||||||
state.quiet = 1;
|
state.quiet = 1;
|
||||||
state.refresh_cache = 1;
|
state.refresh_cache = 1;
|
||||||
@ -445,7 +449,7 @@ static int check_updates(struct unpack_trees_options *o,
|
|||||||
|
|
||||||
if (ce->ce_flags & CE_WT_REMOVE) {
|
if (ce->ce_flags & CE_WT_REMOVE) {
|
||||||
display_progress(progress, ++cnt);
|
display_progress(progress, ++cnt);
|
||||||
unlink_entry(ce);
|
unlink_entry(ce, o->super_prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2959,8 +2963,8 @@ int bind_merge(const struct cache_entry * const *src,
|
|||||||
if (a && old)
|
if (a && old)
|
||||||
return o->quiet ? -1 :
|
return o->quiet ? -1 :
|
||||||
error(ERRORMSG(o, ERROR_BIND_OVERLAP),
|
error(ERRORMSG(o, ERROR_BIND_OVERLAP),
|
||||||
super_prefixed(a->name),
|
super_prefixed(a->name, o->super_prefix),
|
||||||
super_prefixed(old->name));
|
super_prefixed(old->name, o->super_prefix));
|
||||||
if (!a)
|
if (!a)
|
||||||
return keep_entry(old, o);
|
return keep_entry(old, o);
|
||||||
else
|
else
|
||||||
@ -3021,7 +3025,7 @@ int stash_worktree_untracked_merge(const struct cache_entry * const *src,
|
|||||||
|
|
||||||
if (worktree && untracked)
|
if (worktree && untracked)
|
||||||
return error(_("worktree and untracked commit have duplicate entries: %s"),
|
return error(_("worktree and untracked commit have duplicate entries: %s"),
|
||||||
super_prefixed(worktree->name));
|
super_prefixed(worktree->name, o->super_prefix));
|
||||||
|
|
||||||
return merged_entry(worktree ? worktree : untracked, NULL, o);
|
return merged_entry(worktree ? worktree : untracked, NULL, o);
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ struct unpack_trees_options {
|
|||||||
skip_cache_tree_update;
|
skip_cache_tree_update;
|
||||||
enum unpack_trees_reset_type reset;
|
enum unpack_trees_reset_type reset;
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
|
const char *super_prefix;
|
||||||
int cache_bottom;
|
int cache_bottom;
|
||||||
struct pathspec *pathspec;
|
struct pathspec *pathspec;
|
||||||
merge_fn_t fn;
|
merge_fn_t fn;
|
||||||
|
Loading…
Reference in New Issue
Block a user