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. 74866d75793 (git: make super-prefix option, 2016-10-07)
2. e77aa336f11 (ls-files: optionally recurse into submodules, 2016-10-07)
3. 89c86265576 (submodule helper: support super prefix, 2016-12-08)
4. 0281e487fd9 (grep: optionally recurse into submodules, 2016-12-16)
5. 3d415425c7b (unpack-trees: support super-prefix option, 2017-01-17)
6. 188dce131fa (ls-files: use repository object, 2017-06-22)
7. f9ee2fcdfa0 (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>
Ævar Arnfjörð Bjarmason committedDec 20, 2022 at 13:39 UTC4002ec3dcf0f89db46fbdf56549218c573a9c0f2
15 files changed+48-99
Documentation/git.txt
+1-6
index 1d33e083ab..f9a7a4554c 100644--- a/Documentation/git.txt+++ b/Documentation/git.txt@@ -13,8 +13,7 @@ SYNOPSIS [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]- [--super-prefix=<path>] [--config-env=<name>=<envvar>]- <command> [<args>]+ [--config-env=<name>=<envvar>] <command> [<args>] 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 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
builtin.h
-4
index aa955466b4..46cc789789 100644--- a/builtin.h+++ b/builtin.h@@ -51,10 +51,6 @@ * on bare repositories. * This only makes sense when `RUN_SETUP` is also set. *- * `SUPPORT_SUPER_PREFIX`:- *- * The built-in supports `--super-prefix`.- * * `DELAY_PAGER_CONFIG`: * * If RUN_SETUP or RUN_SETUP_GENTLY is set, git.c normally handles
builtin/checkout.c
+1-1
index a0142c815f..cd04f0bf57 100644--- a/builtin/checkout.c+++ b/builtin/checkout.c@@ -232,7 +232,7 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos, pos++; } if (!overlay_mode) {- unlink_entry(ce);+ unlink_entry(ce, NULL); return 0; } if (stage == 2)
builtin/read-tree.c
+1
index f702f9d47b..3ce7541783 100644--- a/builtin/read-tree.c+++ b/builtin/read-tree.c@@ -114,6 +114,7 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) int prefix_set = 0; struct lock_file lock_file = LOCK_INIT; const struct option read_tree_options[] = {+ OPT__SUPER_PREFIX(&opts.super_prefix), OPT_CALLBACK_F(0, "index-output", NULL, N_("file"), N_("write resulting index to <file>"), PARSE_OPT_NONEG, index_output_cb),
index 616e4f073c..971ab26871 100644--- a/entry.c+++ b/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); sub = submodule_from_ce(ce); if (sub)- return submodule_move_head(ce->name,+ return submodule_move_head(ce->name, state->super_prefix, NULL, oid_to_hex(&ce->oid), state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0); break;@@ -476,7 +476,7 @@ int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca, * no pathname to return. */ BUG("Can't remove entry to a path");- unlink_entry(ce);+ unlink_entry(ce, state->super_prefix); return 0; }@@ -510,10 +510,10 @@ int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca, if (!(st.st_mode & S_IFDIR)) 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); } else- return submodule_move_head(ce->name,+ return submodule_move_head(ce->name, state->super_prefix, "HEAD", oid_to_hex(&ce->oid), 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); }-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); if (sub) { /* 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); } if (check_leading_path(ce->name, ce_namelen(ce), 1) >= 0)
entry.h
+5-1
index 9be4659881..2d4fbb88c8 100644--- a/entry.h+++ b/entry.h@@ -8,6 +8,7 @@ struct checkout { struct index_state *istate; const char *base_dir; int base_dir_len;+ const char *super_prefix; struct delayed_checkout *delayed_checkout; struct checkout_metadata meta; 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 * 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); int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st);