Re: [RFC PATCH 1/8] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
- From
Glen Choo <chooglen@google.com>
- Date
- Nov 11, 2022, 00:12 UTC
- Message-ID
- <kl6ledua2vtw.fsf@chooglen-macbookpro.roam.corp.google.com>
- In-Reply-To
- <RFC-patch-1.8-ad0356b596f-20221109T192315Z-avarab@gmail.com>
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
Show 5 quoted lines
> But in the case of "absorbgitdirs" it only needed "--super-prefix" to > invoke itself recursively, and we'd never have another "in-between" > process in the chain. So we didn't need the bigger hammer of "git > --super-prefix", and the "setenv(GIT_SUPER_PREFIX_ENVIRONMENT, ...)" > that it entails.
I also thought this was the case, but in the proces of reviewing this, I I'm not sure any more. More below..
Show 6 quoted lines
> Eventually (as with all other "--super-prefix" users) we'll want to > clean this code up so that this all happens in-process. I.e. needing > any variant of "--super-prefix" is itself a hack around our various > global state, and implicit reliance on "the_repository". This stepping > stone makes such an eventual change easier, as we'll need to deal with > less global state at that point.
Yes, I 100% agree. I am not optimistic that we can clean all of these up any time soon, but I can buy the argument that we will have to remove the extra global state at some point, so we should just bite the bullet now.
Show 38 quoted lines
> diff --git a/parse-options.h b/parse-options.h
> index b6ef86e0d15..50d852f2991 100644
> --- a/parse-options.h
> +++ b/parse-options.h
> @@ -369,6 +369,10 @@ int parse_opt_tracking_mode(const struct option *, const char *, int);
> { OPTION_CALLBACK, 0, "abbrev", (var), N_("n"), \
> N_("use <n> digits to display object names"), \
> PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
> +#define OPT__SUPER_PREFIX(var) \
> + OPT_STRING_F(0, "super-prefix", (var), N_("prefix"), \
> + N_("prefixed path to initial superproject"), PARSE_OPT_HIDDEN)
> +
> #define OPT__COLOR(var, h) \
> OPT_COLOR_FLAG(0, "color", (var), (h))
> #define OPT_COLUMN(s, l, v, h) \
> diff --git a/submodule.c b/submodule.c
> index c47358097fd..d9fd0af81b6 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -2268,7 +2268,8 @@ int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
> * Embeds a single submodules git directory into the superprojects git dir,
> * non recursively.
> */
> -static void relocate_single_git_dir_into_superproject(const char *path)
> +static void relocate_single_git_dir_into_superproject(const char *path,
> + const char *super_prefix)
> {
> char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL;
> struct strbuf new_gitdir = STRBUF_INIT;
> @@ -2302,7 +2303,7 @@ static void relocate_single_git_dir_into_superproject(const char *path)
> real_old_git_dir[off] == real_new_git_dir[off])
> off++;
> fprintf(stderr, _("Migrating git directory of '%s%s' from '%s' to '%s'\n"),
> - get_super_prefix_or_empty(), path,
> + (super_prefix ? super_prefix : ""), path,
> real_old_git_dir + off, real_new_git_dir + off);
>
> relocate_gitdir(path, real_old_git_dir, real_new_git_dir);When this gets cleaned up post-RFC, I think we should have OPT__SUPER_PREFIX handle this "default to empty" behavior for us.
Show 15 quoted lines
> diff --git a/submodule.h b/submodule.h
> index b52a4ff1e73..e5ee13fb06a 100644
> --- a/submodule.h
> +++ b/submodule.h
> @@ -164,7 +164,12 @@ void submodule_unset_core_worktree(const struct submodule *sub);
> */
> void prepare_submodule_repo_env(struct strvec *env);
>
> -void absorb_git_dir_into_superproject(const char *path);
> +void absorb_git_dir_into_superproject_sp(const char *path,
> + const char *super_prefix);
> +static inline void absorb_git_dir_into_superproject(const char *path)
> +{
> + absorb_git_dir_into_superproject_sp(path, NULL);
> +}Since absorb_git_dir_into_superproject() is called by submodule_move_head() (the function that handles submodule changes in unpack_trees()), it can be called from "git read-tree".
So we really do end up mixing the different values of --super-prefix; invoking "absorbgitdirs" directly would print the relative path from cwd, but invoking it indirectly via "read-tree" would print the path from the root of the superproject tree. I guess that result makes sense, since "read-tree" and friends print paths from the root of the tree, but it feels a bit odd.
I'll propose a test for this after I finish reading through the series. To avoid masking this behavior, I think we'll have to avoid going down the *_sp() path and just plumb super_prefix everywhere.
Show 5 quoted lines
> > /* > * Return the absolute path of the working tree of the superproject, which this > -- > 2.38.0.1467.g709fbdff1a9