* [PATCH v2 01/10] read-tree + fetch tests: test failing "--super-prefix" interaction
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 19:00 ` Glen Choo
2022-11-14 10:08 ` [PATCH v2 02/10] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
` (12 subsequent siblings)
13 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
From: Glen Choo <chooglen@google.com>
Ever since "git fetch --refetch" was introduced in 0f5e8851737 (Merge
branch 'rc/fetch-refetch', 2022-04-04) the test being added here would
fail. This is because "restore" will "read-tree .. --reset <hash>",
which will in turn invoke "fetch". The "fetch" will then die with:
fatal: fetch doesn't support --super-prefix
This edge case and other "--super-prefix" bugs will be fixed in
subsequent commits, but let's first add a "test_expect_failure" test
for it. It passes until the very last command in the test.
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 037941b95d2..e56466580cf 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
grep "loosen_unused_packed_objects/loosened:0" trace
'
+test_expect_failure 'lazy-fetch in submodule succeeds' '
+ # setup
+ test_config_global protocol.file.allow always &&
+
+ git init src-sub &&
+ git -C src-sub config uploadpack.allowfilter 1 &&
+ git -C src-sub config uploadpack.allowanysha1inwant 1 &&
+
+ # This blob must be missing in the subsequent commit.
+ echo foo >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule one" &&
+ SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
+
+ echo bar >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule two" &&
+ SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
+
+ git init src-super &&
+ git -C src-super config uploadpack.allowfilter 1 &&
+ git -C src-super config uploadpack.allowanysha1inwant 1 &&
+ git -C src-super submodule add ../src-sub src-sub &&
+
+ git -C src-super/src-sub checkout $SUB_ONE &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject one" &&
+
+ git -C src-super/src-sub checkout $SUB_TWO &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject two" &&
+
+ # the fetch
+ test_when_finished "rm -rf src-super src-sub client" &&
+
+ test_config_global protocol.file.allow always &&
+ git clone --filter=blob:none --also-filter-submodules \
+ --recurse-submodules "file://$(pwd)/src-super" client &&
+
+ # Trigger lazy-fetch from the superproject
+ git -C client restore --recurse-submodules --source=HEAD^ :/
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v2 01/10] read-tree + fetch tests: test failing "--super-prefix" interaction
2022-11-14 10:08 ` [PATCH v2 01/10] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
@ 2022-11-14 19:00 ` Glen Choo
2022-11-14 19:14 ` Ævar Arnfjörð Bjarmason
0 siblings, 1 reply; 105+ messages in thread
From: Glen Choo @ 2022-11-14 19:00 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> From: Glen Choo <chooglen@google.com>
>
> Ever since "git fetch --refetch" was introduced in 0f5e8851737 (Merge
> branch 'rc/fetch-refetch', 2022-04-04) the test being added here would
> fail. This is because "restore" will "read-tree .. --reset <hash>",
> which will in turn invoke "fetch". The "fetch" will then die with:
>
> fatal: fetch doesn't support --super-prefix
>
> This edge case and other "--super-prefix" bugs will be fixed in
> subsequent commits, but let's first add a "test_expect_failure" test
> for it. It passes until the very last command in the test.
>
> Signed-off-by: Glen Choo <chooglen@google.com>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 43 insertions(+)
>
> diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
> index 037941b95d2..e56466580cf 100755
> --- a/t/t5616-partial-clone.sh
> +++ b/t/t5616-partial-clone.sh
> @@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
> grep "loosen_unused_packed_objects/loosened:0" trace
> '
>
> +test_expect_failure 'lazy-fetch in submodule succeeds' '
> + # setup
> + test_config_global protocol.file.allow always &&
> +
> + git init src-sub &&
> + git -C src-sub config uploadpack.allowfilter 1 &&
> + git -C src-sub config uploadpack.allowanysha1inwant 1 &&
> +
> + # This blob must be missing in the subsequent commit.
> + echo foo >src-sub/file &&
> + git -C src-sub add file &&
> + git -C src-sub commit -m "submodule one" &&
> + SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
> +
> + echo bar >src-sub/file &&
> + git -C src-sub add file &&
> + git -C src-sub commit -m "submodule two" &&
> + SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
> +
> + git init src-super &&
> + git -C src-super config uploadpack.allowfilter 1 &&
> + git -C src-super config uploadpack.allowanysha1inwant 1 &&
> + git -C src-super submodule add ../src-sub src-sub &&
> +
> + git -C src-super/src-sub checkout $SUB_ONE &&
> + git -C src-super add src-sub &&
> + git -C src-super commit -m "superproject one" &&
> +
> + git -C src-super/src-sub checkout $SUB_TWO &&
> + git -C src-super add src-sub &&
> + git -C src-super commit -m "superproject two" &&
> +
> + # the fetch
> + test_when_finished "rm -rf src-super src-sub client" &&
(Genuinely curious) are we okay with test_when_finished in the middle of
the test body instead of at the top?
> +
> + test_config_global protocol.file.allow always &&
We have this exact same test_config_global line at the top of this test,
so we can drop this one.
> + git clone --filter=blob:none --also-filter-submodules \
> + --recurse-submodules "file://$(pwd)/src-super" client &&
> +
> + # Trigger lazy-fetch from the superproject
> + git -C client restore --recurse-submodules --source=HEAD^ :/
> +'
> +
> . "$TEST_DIRECTORY"/lib-httpd.sh
> start_httpd
>
> --
> 2.38.0.1471.ge4d8947e7aa
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 01/10] read-tree + fetch tests: test failing "--super-prefix" interaction
2022-11-14 19:00 ` Glen Choo
@ 2022-11-14 19:14 ` Ævar Arnfjörð Bjarmason
2022-11-14 19:49 ` Glen Choo
0 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 19:14 UTC (permalink / raw)
To: Glen Choo; +Cc: git, Taylor Blau, Robert Coup
On Mon, Nov 14 2022, Glen Choo wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> From: Glen Choo <chooglen@google.com>
>>
>> Ever since "git fetch --refetch" was introduced in 0f5e8851737 (Merge
>> branch 'rc/fetch-refetch', 2022-04-04) the test being added here would
>> fail. This is because "restore" will "read-tree .. --reset <hash>",
>> which will in turn invoke "fetch". The "fetch" will then die with:
>>
>> fatal: fetch doesn't support --super-prefix
>>
>> This edge case and other "--super-prefix" bugs will be fixed in
>> subsequent commits, but let's first add a "test_expect_failure" test
>> for it. It passes until the very last command in the test.
>>
>> Signed-off-by: Glen Choo <chooglen@google.com>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>> t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 43 insertions(+)
>>
>> diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
>> index 037941b95d2..e56466580cf 100755
>> --- a/t/t5616-partial-clone.sh
>> +++ b/t/t5616-partial-clone.sh
>> @@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
>> grep "loosen_unused_packed_objects/loosened:0" trace
>> '
>>
>> +test_expect_failure 'lazy-fetch in submodule succeeds' '
>> + # setup
>> + test_config_global protocol.file.allow always &&
>> +
>> + git init src-sub &&
>> + git -C src-sub config uploadpack.allowfilter 1 &&
>> + git -C src-sub config uploadpack.allowanysha1inwant 1 &&
>> +
>> + # This blob must be missing in the subsequent commit.
>> + echo foo >src-sub/file &&
>> + git -C src-sub add file &&
>> + git -C src-sub commit -m "submodule one" &&
>> + SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
>> +
>> + echo bar >src-sub/file &&
>> + git -C src-sub add file &&
>> + git -C src-sub commit -m "submodule two" &&
>> + SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
>> +
>> + git init src-super &&
>> + git -C src-super config uploadpack.allowfilter 1 &&
>> + git -C src-super config uploadpack.allowanysha1inwant 1 &&
>> + git -C src-super submodule add ../src-sub src-sub &&
>> +
>> + git -C src-super/src-sub checkout $SUB_ONE &&
>> + git -C src-super add src-sub &&
>> + git -C src-super commit -m "superproject one" &&
>> +
>> + git -C src-super/src-sub checkout $SUB_TWO &&
>> + git -C src-super add src-sub &&
>> + git -C src-super commit -m "superproject two" &&
>> +
>> + # the fetch
>> + test_when_finished "rm -rf src-super src-sub client" &&
>
> (Genuinely curious) are we okay with test_when_finished in the middle of
> the test body instead of at the top?
Yeah, and it's not just supported, but preferred, usually we do:
test_when_finished "rm -rf repo" &&
git init repo &&
So at the top makes sense, but if there's a bunch of stuff we might fail
on first it makes sense not to attempt the cleanup.
But I see in this case the "src-super" part of it should be earlier, and
"src-sub", but the "client" should be just before the clone below, don't
know how I missed that. Will fix.
>> +
>> + test_config_global protocol.file.allow always &&
>
> We have this exact same test_config_global line at the top of this test,
> so we can drop this one.
Ditto, thanks, I'll fix that. A mistake when combining the tests.
You had these as two tests, but one was mandatory setup for the other,
and when making it test_expect_failure I wanted to have it atomic..
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 01/10] read-tree + fetch tests: test failing "--super-prefix" interaction
2022-11-14 19:14 ` Ævar Arnfjörð Bjarmason
@ 2022-11-14 19:49 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-14 19:49 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git, Taylor Blau, Robert Coup
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> On Mon, Nov 14 2022, Glen Choo wrote:
>
>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>>
>>> From: Glen Choo <chooglen@google.com>
>>>
>>> Ever since "git fetch --refetch" was introduced in 0f5e8851737 (Merge
>>> branch 'rc/fetch-refetch', 2022-04-04) the test being added here would
>>> fail. This is because "restore" will "read-tree .. --reset <hash>",
>>> which will in turn invoke "fetch". The "fetch" will then die with:
>>>
>>> fatal: fetch doesn't support --super-prefix
>>>
>>> This edge case and other "--super-prefix" bugs will be fixed in
>>> subsequent commits, but let's first add a "test_expect_failure" test
>>> for it. It passes until the very last command in the test.
>>>
>>> Signed-off-by: Glen Choo <chooglen@google.com>
>>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>>> ---
>>> t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 43 insertions(+)
>>>
>>> diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
>>> index 037941b95d2..e56466580cf 100755
>>> --- a/t/t5616-partial-clone.sh
>>> +++ b/t/t5616-partial-clone.sh
>>> @@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
>>> grep "loosen_unused_packed_objects/loosened:0" trace
>>> '
>>>
>>> +test_expect_failure 'lazy-fetch in submodule succeeds' '
>>> + # setup
>>> + test_config_global protocol.file.allow always &&
>>> +
>>> + git init src-sub &&
>>> + git -C src-sub config uploadpack.allowfilter 1 &&
>>> + git -C src-sub config uploadpack.allowanysha1inwant 1 &&
>>> +
>>> + # This blob must be missing in the subsequent commit.
>>> + echo foo >src-sub/file &&
>>> + git -C src-sub add file &&
>>> + git -C src-sub commit -m "submodule one" &&
>>> + SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
>>> +
>>> + echo bar >src-sub/file &&
>>> + git -C src-sub add file &&
>>> + git -C src-sub commit -m "submodule two" &&
>>> + SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
>>> +
>>> + git init src-super &&
>>> + git -C src-super config uploadpack.allowfilter 1 &&
>>> + git -C src-super config uploadpack.allowanysha1inwant 1 &&
>>> + git -C src-super submodule add ../src-sub src-sub &&
>>> +
>>> + git -C src-super/src-sub checkout $SUB_ONE &&
>>> + git -C src-super add src-sub &&
>>> + git -C src-super commit -m "superproject one" &&
>>> +
>>> + git -C src-super/src-sub checkout $SUB_TWO &&
>>> + git -C src-super add src-sub &&
>>> + git -C src-super commit -m "superproject two" &&
>>> +
>>> + # the fetch
>>> + test_when_finished "rm -rf src-super src-sub client" &&
>>
>> (Genuinely curious) are we okay with test_when_finished in the middle of
>> the test body instead of at the top?
>
> Yeah, and it's not just supported, but preferred, usually we do:
>
> test_when_finished "rm -rf repo" &&
> git init repo &&
>
> So at the top makes sense, but if there's a bunch of stuff we might fail
> on first it makes sense not to attempt the cleanup.
>
> But I see in this case the "src-super" part of it should be earlier, and
> "src-sub", but the "client" should be just before the clone below, don't
> know how I missed that. Will fix.
Ah, I see. Yeah that makes sense.
>
>>> +
>>> + test_config_global protocol.file.allow always &&
>>
>> We have this exact same test_config_global line at the top of this test,
>> so we can drop this one.
>
> Ditto, thanks, I'll fix that. A mistake when combining the tests.
>
> You had these as two tests, but one was mandatory setup for the other,
> and when making it test_expect_failure I wanted to have it atomic..
Makes sense too. I initially had them separate for readability purposes,
but the inline comments work too.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v2 02/10] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
2022-11-14 10:08 ` [PATCH v2 01/10] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 21:22 ` Glen Choo
2022-11-14 10:08 ` [PATCH v2 03/10] submodule--helper: "deinit" has never used "--super-prefix" Ævar Arnfjörð Bjarmason
` (11 subsequent siblings)
13 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
The "--super-prefix" facility was introduced in [1] has always been a
transitory hack, which is why we've made it an error to supply it as
an option to "git" to commands that don't know about it.
That's been a good goal, as it has a global effect we haven't wanted
calls to get_super_prefix() from built-ins we didn't expect.
But it has meant that when we've had chains of different built-ins
using it all of the processes in that "chain" have needed to support
it, and worse processes that don't need it have needed to ask for
"SUPPORT_SUPER_PREFIX" because their parent process needs it.
That's how "fsmonitor--daemon" ended up with it, per [2] it's called
from (among other things) "submodule--helper absorbgitdirs", but as we
declared "submodule--helper" as "SUPPORT_SUPER_PREFIX" we needed to
declare "fsmonitor--daemon" as accepting it too, even though it
doesn't care about it.
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.
Let's instead accept a hidden "--super-prefix" option to
"submodule--helper absorbgitdirs" itself.
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.
The "fsmonitor--daemon" test adjusted here was added in [3]. The
comment added in that commit has been out-of-date from the beginning,
and the "have_t2_error_event()" was being overly specific in testing
for a bug that we *don't* have. Let's instead test for the stdout and
stderr that we *do have*.
1. 74866d75793 (git: make super-prefix option, 2016-10-07)
2. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 8 +++++---
git.c | 2 +-
parse-options.h | 4 ++++
submodule.c | 20 ++++++++++++--------
submodule.h | 7 ++++++-
t/t7527-builtin-fsmonitor.sh | 33 ++++++++-------------------------
6 files changed, 36 insertions(+), 38 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index c75e9e86b06..427e793e204 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2828,7 +2828,9 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
+ const char *super_prefix = NULL;
struct option embed_gitdir_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT_END()
};
const char *const git_submodule_helper_usage[] = {
@@ -2844,7 +2846,8 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
goto cleanup;
for (i = 0; i < list.nr; i++)
- absorb_git_dir_into_superproject(list.entries[i]->name);
+ absorb_git_dir_into_superproject_sp(list.entries[i]->name,
+ super_prefix);
ret = 0;
cleanup:
@@ -3382,8 +3385,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
- get_super_prefix())
+ strcmp(subcmd, "sync") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
diff --git a/git.c b/git.c
index 10202a7f126..b1b7e1a837e 100644
--- a/git.c
+++ b/git.c
@@ -539,7 +539,7 @@ static struct cmd_struct commands[] = {
{ "format-patch", cmd_format_patch, RUN_SETUP },
{ "fsck", cmd_fsck, RUN_SETUP },
{ "fsck-objects", cmd_fsck, RUN_SETUP },
- { "fsmonitor--daemon", cmd_fsmonitor__daemon, SUPPORT_SUPER_PREFIX | RUN_SETUP },
+ { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP },
{ "gc", cmd_gc, RUN_SETUP },
{ "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
{ "grep", cmd_grep, RUN_SETUP_GENTLY },
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);
@@ -2313,7 +2314,8 @@ static void relocate_single_git_dir_into_superproject(const char *path)
strbuf_release(&new_gitdir);
}
-static void absorb_git_dir_into_superproject_recurse(const char *path)
+static void absorb_git_dir_into_superproject_recurse(const char *path,
+ const char *super_prefix)
{
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2321,10 +2323,11 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/",
- get_super_prefix_or_empty(), path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+ super_prefix : "", path);
+
prepare_submodule_repo_env(&cp.env);
if (run_command(&cp))
die(_("could not recurse into submodule '%s'"), path);
@@ -2335,7 +2338,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
* having its git directory within the working tree to the git dir nested
* in its superprojects git dir under modules/.
*/
-void absorb_git_dir_into_superproject(const char *path)
+void absorb_git_dir_into_superproject_sp(const char *path,
+ const char *super_prefix)
{
int err_code;
const char *sub_git_dir;
@@ -2377,14 +2381,14 @@ void absorb_git_dir_into_superproject(const char *path)
char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
if (!starts_with(real_sub_git_dir, real_common_git_dir))
- relocate_single_git_dir_into_superproject(path);
+ relocate_single_git_dir_into_superproject(path, super_prefix);
free(real_sub_git_dir);
free(real_common_git_dir);
}
strbuf_release(&gitdir);
- absorb_git_dir_into_superproject_recurse(path);
+ absorb_git_dir_into_superproject_recurse(path, super_prefix);
}
int get_superproject_working_tree(struct strbuf *buf)
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);
+}
/*
* Return the absolute path of the working tree of the superproject, which this
diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
index 4abc74db2bb..31526937d95 100755
--- a/t/t7527-builtin-fsmonitor.sh
+++ b/t/t7527-builtin-fsmonitor.sh
@@ -866,30 +866,11 @@ test_expect_success 'submodule always visited' '
# the submodule, and someone does a `git submodule absorbgitdirs`
# in the super, Git will recursively invoke `git submodule--helper`
# to do the work and this may try to read the index. This will
-# try to start the daemon in the submodule *and* pass (either
-# directly or via inheritance) the `--super-prefix` arg to the
-# `git fsmonitor--daemon start` command inside the submodule.
-# This causes a warning because fsmonitor--daemon does take that
-# global arg (see the table in git.c)
-#
-# This causes a warning when trying to start the daemon that is
-# somewhat confusing. It does not seem to hurt anything because
-# the fsmonitor code maps the query failure into a trivial response
-# and does the work anyway.
-#
-# It would be nice to silence the warning, however.
-
-have_t2_error_event () {
- log=$1
- msg="fsmonitor--daemon doesnQt support --super-prefix" &&
-
- tr '\047' Q <$1 | grep -e "$msg"
-}
+# try to start the daemon in the submodule.
test_expect_success "stray submodule super-prefix warning" '
test_when_finished "rm -rf super; \
- rm -rf sub; \
- rm super-sub.trace" &&
+ rm -rf sub" &&
create_super super &&
create_sub sub &&
@@ -904,10 +885,12 @@ test_expect_success "stray submodule super-prefix warning" '
test_path_is_dir super/dir_1/dir_2/sub/.git &&
- GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
- git -C super submodule absorbgitdirs &&
-
- ! have_t2_error_event super-sub.trace
+ cat >expect <<-\EOF &&
+ Migrating git directory of '\''dir_1/dir_2/sub'\'' from '\''dir_1/dir_2/sub/.git'\'' to '\''.git/modules/dir_1/dir_2/sub'\''
+ EOF
+ git -C super submodule absorbgitdirs >out 2>actual &&
+ test_cmp expect actual &&
+ test_must_be_empty out
'
# On a case-insensitive file system, confirm that the daemon
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v2 02/10] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-11-14 10:08 ` [PATCH v2 02/10] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
@ 2022-11-14 21:22 ` Glen Choo
2022-11-17 18:10 ` Ævar Arnfjörð Bjarmason
0 siblings, 1 reply; 105+ messages in thread
From: Glen Choo @ 2022-11-14 21:22 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> The "--super-prefix" facility was introduced in [1] has always been a
> transitory hack, which is why we've made it an error to supply it as
> an option to "git" to commands that don't know about it.
>
> That's been a good goal, as it has a global effect we haven't wanted
> calls to get_super_prefix() from built-ins we didn't expect.
>
> But it has meant that when we've had chains of different built-ins
> using it all of the processes in that "chain" have needed to support
> it, and worse processes that don't need it have needed to ask for
> "SUPPORT_SUPER_PREFIX" because their parent process needs it.
>
> That's how "fsmonitor--daemon" ended up with it, per [2] it's called
> from (among other things) "submodule--helper absorbgitdirs", but as we
> declared "submodule--helper" as "SUPPORT_SUPER_PREFIX" we needed to
> declare "fsmonitor--daemon" as accepting it too, even though it
> doesn't care about it.
>
> 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.
>
> Let's instead accept a hidden "--super-prefix" option to
> "submodule--helper absorbgitdirs" itself.
>
> 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.
>
> The "fsmonitor--daemon" test adjusted here was added in [3]. The
> comment added in that commit has been out-of-date from the beginning,
> and the "have_t2_error_event()" was being overly specific in testing
> for a bug that we *don't* have. Let's instead test for the stdout and
> stderr that we *do have*.
I didn't understand this bit initially, because I read this as
"have_t2_error_event() isn't catching bugs", which isn't true. But I see
what you mean after inspecting the test_cmp output:
@@ -1 +1,2 @@
Migrating git directory of 'dir_1/dir_2/sub' from 'dir_1/dir_2/sub/.git' to '.git/modules/dir_1/dir_2/sub'
+fatal: fsmonitor--daemon doesn't support --super-prefix
IOW, it doesn't make sense to inspecting the tr2 output for stray
warnings when our stderr is so obviously broken. But at the end of the
series, I don't think we even need this test at all because if we don't
have a global "--super-prefix", there's literally no reason for
fsmonitor--daemon to worry about absorbgitdirs or "supporting" the super
prefix. That's why I removed it in [1].
Wondering aloud, that stderr suggests that the "git submodule absorbgitdirs"
invocation failed. I wonder why the test didn't catch a bad exit code
(and resulting in us inspecting stderr unnecessarily). I think it's not
worth looking too closely at right now, but we could revisit this after
we get builtin/submodule.c.
[1] https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com
>
> 1. 74866d75793 (git: make super-prefix option, 2016-10-07)
> 2. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
> 2022-05-26)
> 3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
> 2022-05-26)
>
> Signed-off-by: Glen Choo <chooglen@google.com>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> builtin/submodule--helper.c | 8 +++++---
> git.c | 2 +-
> parse-options.h | 4 ++++
> submodule.c | 20 ++++++++++++--------
> submodule.h | 7 ++++++-
> t/t7527-builtin-fsmonitor.sh | 33 ++++++++-------------------------
> 6 files changed, 36 insertions(+), 38 deletions(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index c75e9e86b06..427e793e204 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -2828,7 +2828,9 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
> int i;
> struct pathspec pathspec = { 0 };
> struct module_list list = MODULE_LIST_INIT;
> + const char *super_prefix = NULL;
> struct option embed_gitdir_options[] = {
> + OPT__SUPER_PREFIX(&super_prefix),
> OPT_END()
> };
> const char *const git_submodule_helper_usage[] = {
> @@ -2844,7 +2846,8 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
> goto cleanup;
>
> for (i = 0; i < list.nr; i++)
> - absorb_git_dir_into_superproject(list.entries[i]->name);
> + absorb_git_dir_into_superproject_sp(list.entries[i]->name,
> + super_prefix);
>
> ret = 0;
> cleanup:
> @@ -3382,8 +3385,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
>
> if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
> strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
> - strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
> - get_super_prefix())
> + strcmp(subcmd, "sync") && get_super_prefix())
> /*
> * xstrfmt() rather than "%s %s" to keep the translated
> * string identical to git.c's.
> diff --git a/git.c b/git.c
> index 10202a7f126..b1b7e1a837e 100644
> --- a/git.c
> +++ b/git.c
> @@ -539,7 +539,7 @@ static struct cmd_struct commands[] = {
> { "format-patch", cmd_format_patch, RUN_SETUP },
> { "fsck", cmd_fsck, RUN_SETUP },
> { "fsck-objects", cmd_fsck, RUN_SETUP },
> - { "fsmonitor--daemon", cmd_fsmonitor__daemon, SUPPORT_SUPER_PREFIX | RUN_SETUP },
> + { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP },
> { "gc", cmd_gc, RUN_SETUP },
> { "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
> { "grep", cmd_grep, RUN_SETUP_GENTLY },
> 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)
> +
Could we default to "" instead of NULL? (possibly via a callback). I
think there's never any good reason to have NULL instead of "", e.g.
since this is internal, we don't care to distinguish between
"--super-prefix=''" and not passing "--super-prefix" at all...
> #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);
Which would make sites like these a bit cleaner.
Tangentially, 'default to "" if NULL' sounds like a common pattern. Is
there a good reason not to have a macro or inline function to do that?
e.g. we think the ternary expression is good enough?)
>
> relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
> @@ -2313,7 +2314,8 @@ static void relocate_single_git_dir_into_superproject(const char *path)
> strbuf_release(&new_gitdir);
> }
>
> -static void absorb_git_dir_into_superproject_recurse(const char *path)
> +static void absorb_git_dir_into_superproject_recurse(const char *path,
> + const char *super_prefix)
> {
>
> struct child_process cp = CHILD_PROCESS_INIT;
> @@ -2321,10 +2323,11 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
> cp.dir = path;
> cp.git_cmd = 1;
> cp.no_stdin = 1;
> - strvec_pushf(&cp.args, "--super-prefix=%s%s/",
> - get_super_prefix_or_empty(), path);
> strvec_pushl(&cp.args, "submodule--helper",
> "absorbgitdirs", NULL);
> + strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
> + super_prefix : "", path);
> +
> prepare_submodule_repo_env(&cp.env);
> if (run_command(&cp))
> die(_("could not recurse into submodule '%s'"), path);
> @@ -2335,7 +2338,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
> * having its git directory within the working tree to the git dir nested
> * in its superprojects git dir under modules/.
> */
> -void absorb_git_dir_into_superproject(const char *path)
> +void absorb_git_dir_into_superproject_sp(const char *path,
> + const char *super_prefix)
> {
> int err_code;
> const char *sub_git_dir;
> @@ -2377,14 +2381,14 @@ void absorb_git_dir_into_superproject(const char *path)
> char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
>
> if (!starts_with(real_sub_git_dir, real_common_git_dir))
> - relocate_single_git_dir_into_superproject(path);
> + relocate_single_git_dir_into_superproject(path, super_prefix);
>
> free(real_sub_git_dir);
> free(real_common_git_dir);
> }
> strbuf_release(&gitdir);
>
> - absorb_git_dir_into_superproject_recurse(path);
> + absorb_git_dir_into_superproject_recurse(path, super_prefix);
> }
>
> int get_superproject_working_tree(struct strbuf *buf)
> 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);
> +}
Is there a reason you chose to go with _sp() instead of changing the
original function signature? I tested out that change, and it seems
rather small (absorb_git_dir_into_superproject() only has 4 call sites).
Crucially, changing the signature catches a "git read-tree" call site:
diff --git a/submodule.c b/submodule.c
index d9fd0af81b..e79a04d3e3 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2139,7 +2139,9 @@ int submodule_move_head(const char *path,
if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
if (old_head) {
if (!submodule_uses_gitfile(path))
- absorb_git_dir_into_superproject(path);
+ /* Pass super_prefix properly later. */
+ absorb_git_dir_into_superproject(path,
+ get_super_prefix());
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
which would otherwise be broken since we used to read the global super
prefix, but we don't do that in this patch. This has no test coverage
(bleh), but it shouldn't be too hard, something like:
git init super &&
cd super &&
# Create an unabsorbed submodule right in the worktree
git init sub &&
test_commit -C sub "foo" &&
git add sub &&
git commit -m "Add submodule" &&
test_commit "bar" &&
# This should invoke "git read-tree" and absorb the git dir.
# Or maybe we should invoke "git read-tree" directly?
git checkout --recurse-submodules HEAD^ 2>err &&
# Search for the shortened message
grep "Migrating submodule sub from sub to .git/modules/...." err
> /*
> * Return the absolute path of the working tree of the superproject, which this
> diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
> index 4abc74db2bb..31526937d95 100755
> --- a/t/t7527-builtin-fsmonitor.sh
> +++ b/t/t7527-builtin-fsmonitor.sh
> @@ -866,30 +866,11 @@ test_expect_success 'submodule always visited' '
> # the submodule, and someone does a `git submodule absorbgitdirs`
> # in the super, Git will recursively invoke `git submodule--helper`
> # to do the work and this may try to read the index. This will
> -# try to start the daemon in the submodule *and* pass (either
> -# directly or via inheritance) the `--super-prefix` arg to the
> -# `git fsmonitor--daemon start` command inside the submodule.
> -# This causes a warning because fsmonitor--daemon does take that
> -# global arg (see the table in git.c)
> -#
> -# This causes a warning when trying to start the daemon that is
> -# somewhat confusing. It does not seem to hurt anything because
> -# the fsmonitor code maps the query failure into a trivial response
> -# and does the work anyway.
> -#
> -# It would be nice to silence the warning, however.
> -
> -have_t2_error_event () {
> - log=$1
> - msg="fsmonitor--daemon doesnQt support --super-prefix" &&
> -
> - tr '\047' Q <$1 | grep -e "$msg"
> -}
> +# try to start the daemon in the submodule.
>
> test_expect_success "stray submodule super-prefix warning" '
> test_when_finished "rm -rf super; \
> - rm -rf sub; \
> - rm super-sub.trace" &&
> + rm -rf sub" &&
>
> create_super super &&
> create_sub sub &&
> @@ -904,10 +885,12 @@ test_expect_success "stray submodule super-prefix warning" '
>
> test_path_is_dir super/dir_1/dir_2/sub/.git &&
>
> - GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
> - git -C super submodule absorbgitdirs &&
> -
> - ! have_t2_error_event super-sub.trace
> + cat >expect <<-\EOF &&
> + Migrating git directory of '\''dir_1/dir_2/sub'\'' from '\''dir_1/dir_2/sub/.git'\'' to '\''.git/modules/dir_1/dir_2/sub'\''
> + EOF
> + git -C super submodule absorbgitdirs >out 2>actual &&
> + test_cmp expect actual &&
> + test_must_be_empty out
> '
>
> # On a case-insensitive file system, confirm that the daemon
> --
> 2.38.0.1471.ge4d8947e7aa
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 02/10] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-11-14 21:22 ` Glen Choo
@ 2022-11-17 18:10 ` Ævar Arnfjörð Bjarmason
0 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-17 18:10 UTC (permalink / raw)
To: Glen Choo; +Cc: git, Taylor Blau, Robert Coup
On Mon, Nov 14 2022, Glen Choo wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> The "--super-prefix" facility was introduced in [1] has always been a
>> transitory hack, which is why we've made it an error to supply it as
>> an option to "git" to commands that don't know about it.
>>
>> That's been a good goal, as it has a global effect we haven't wanted
>> calls to get_super_prefix() from built-ins we didn't expect.
>>
>> But it has meant that when we've had chains of different built-ins
>> using it all of the processes in that "chain" have needed to support
>> it, and worse processes that don't need it have needed to ask for
>> "SUPPORT_SUPER_PREFIX" because their parent process needs it.
>>
>> That's how "fsmonitor--daemon" ended up with it, per [2] it's called
>> from (among other things) "submodule--helper absorbgitdirs", but as we
>> declared "submodule--helper" as "SUPPORT_SUPER_PREFIX" we needed to
>> declare "fsmonitor--daemon" as accepting it too, even though it
>> doesn't care about it.
>>
>> 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.
>>
>> Let's instead accept a hidden "--super-prefix" option to
>> "submodule--helper absorbgitdirs" itself.
>>
>> 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.
>>
>> The "fsmonitor--daemon" test adjusted here was added in [3]. The
>> comment added in that commit has been out-of-date from the beginning,
>> and the "have_t2_error_event()" was being overly specific in testing
>> for a bug that we *don't* have. Let's instead test for the stdout and
>> stderr that we *do have*.
>
> I didn't understand this bit initially, because I read this as
> "have_t2_error_event() isn't catching bugs", which isn't true. But I see
> what you mean after inspecting the test_cmp output:
>
> @@ -1 +1,2 @@
> Migrating git directory of 'dir_1/dir_2/sub' from 'dir_1/dir_2/sub/.git' to '.git/modules/dir_1/dir_2/sub'
> +fatal: fsmonitor--daemon doesn't support --super-prefix
>
> IOW, it doesn't make sense to inspecting the tr2 output for stray
> warnings when our stderr is so obviously broken. But at the end of the
> series, I don't think we even need this test at all because if we don't
> have a global "--super-prefix", there's literally no reason for
> fsmonitor--daemon to worry about absorbgitdirs or "supporting" the super
> prefix. That's why I removed it in [1].
>
> Wondering aloud, that stderr suggests that the "git submodule absorbgitdirs"
> invocation failed. I wonder why the test didn't catch a bad exit code
> (and resulting in us inspecting stderr unnecessarily). I think it's not
> worth looking too closely at right now, but we could revisit this after
> we get builtin/submodule.c.
>
> [1] https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com
I'm prepping a re-roll where I'll keep some of this test, as testing
fsmonitor+absorbgitdirs is worthhwile, but the commit message etc. is
rephrased.
>> diff --git a/git.c b/git.c
>> index 10202a7f126..b1b7e1a837e 100644
>> --- a/git.c
>> +++ b/git.c
>> @@ -539,7 +539,7 @@ static struct cmd_struct commands[] = {
>> { "format-patch", cmd_format_patch, RUN_SETUP },
>> { "fsck", cmd_fsck, RUN_SETUP },
>> { "fsck-objects", cmd_fsck, RUN_SETUP },
>> - { "fsmonitor--daemon", cmd_fsmonitor__daemon, SUPPORT_SUPER_PREFIX | RUN_SETUP },
>> + { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP },
>> { "gc", cmd_gc, RUN_SETUP },
>> { "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
>> { "grep", cmd_grep, RUN_SETUP_GENTLY },
>> 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)
>> +
>
> Could we default to "" instead of NULL? (possibly via a callback). I
> think there's never any good reason to have NULL instead of "", e.g.
> since this is internal, we don't care to distinguish between
> "--super-prefix=''" and not passing "--super-prefix" at all...
I saw this comment on another patch, I think I'll keep it for now, but I
updated the reason: It's because the "prefix" is either NULL or a
non-zero length string, so we're doing the same here to be consistent
with it.
I think that makes sense, but ultimately it's an arbitrary choice, but
as they're sibling variables in the cases they're used doing the same
seems worthwhile...
>> #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);
>
>
> Which would make sites like these a bit cleaner.
>
> Tangentially, 'default to "" if NULL' sounds like a common pattern. Is
> there a good reason not to have a macro or inline function to do that?
> e.g. we think the ternary expression is good enough?)
See above.
>>
>> relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
>> @@ -2313,7 +2314,8 @@ static void relocate_single_git_dir_into_superproject(const char *path)
>> strbuf_release(&new_gitdir);
>> }
>>
>> -static void absorb_git_dir_into_superproject_recurse(const char *path)
>> +static void absorb_git_dir_into_superproject_recurse(const char *path,
>> + const char *super_prefix)
>> {
>>
>> struct child_process cp = CHILD_PROCESS_INIT;
>> @@ -2321,10 +2323,11 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
>> cp.dir = path;
>> cp.git_cmd = 1;
>> cp.no_stdin = 1;
>> - strvec_pushf(&cp.args, "--super-prefix=%s%s/",
>> - get_super_prefix_or_empty(), path);
>> strvec_pushl(&cp.args, "submodule--helper",
>> "absorbgitdirs", NULL);
>> + strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
>> + super_prefix : "", path);
>> +
>> prepare_submodule_repo_env(&cp.env);
>> if (run_command(&cp))
>> die(_("could not recurse into submodule '%s'"), path);
>> @@ -2335,7 +2338,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
>> * having its git directory within the working tree to the git dir nested
>> * in its superprojects git dir under modules/.
>> */
>> -void absorb_git_dir_into_superproject(const char *path)
>> +void absorb_git_dir_into_superproject_sp(const char *path,
>> + const char *super_prefix)
>> {
>> int err_code;
>> const char *sub_git_dir;
>> @@ -2377,14 +2381,14 @@ void absorb_git_dir_into_superproject(const char *path)
>> char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
>>
>> if (!starts_with(real_sub_git_dir, real_common_git_dir))
>> - relocate_single_git_dir_into_superproject(path);
>> + relocate_single_git_dir_into_superproject(path, super_prefix);
>>
>> free(real_sub_git_dir);
>> free(real_common_git_dir);
>> }
>> strbuf_release(&gitdir);
>>
>> - absorb_git_dir_into_superproject_recurse(path);
>> + absorb_git_dir_into_superproject_recurse(path, super_prefix);
>> }
>>
>> int get_superproject_working_tree(struct strbuf *buf)
>> 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);
>> +}
>
> Is there a reason you chose to go with _sp() instead of changing the
> original function signature? I tested out that change, and it seems
> rather small (absorb_git_dir_into_superproject() only has 4 call sites).
I've just changed that, so no more *_sp()...
> Crucially, changing the signature catches a "git read-tree" call site:
>
> diff --git a/submodule.c b/submodule.c
> index d9fd0af81b..e79a04d3e3 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -2139,7 +2139,9 @@ int submodule_move_head(const char *path,
> if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
> if (old_head) {
> if (!submodule_uses_gitfile(path))
> - absorb_git_dir_into_superproject(path);
> + /* Pass super_prefix properly later. */
> + absorb_git_dir_into_superproject(path,
> + get_super_prefix());
> } else {
> struct strbuf gitdir = STRBUF_INIT;
> submodule_name_to_gitdir(&gitdir, the_repository,
>
> which would otherwise be broken since we used to read the global super
> prefix, but we don't do that in this patch. This has no test coverage
> (bleh), but it shouldn't be too hard, something like:
>
> git init super &&
> cd super &&
> # Create an unabsorbed submodule right in the worktree
> git init sub &&
> test_commit -C sub "foo" &&
> git add sub &&
> git commit -m "Add submodule" &&
> test_commit "bar" &&
> # This should invoke "git read-tree" and absorb the git dir.
> # Or maybe we should invoke "git read-tree" directly?
> git checkout --recurse-submodules HEAD^ 2>err &&
> # Search for the shortened message
> grep "Migrating submodule sub from sub to .git/modules/...." err
Ah! Yeah that is a good catch, and a great reason to do it this way.
I tried to come up with a test case that actually tested this. I.e. I
set a "here = 1" at that absorb_git_dir_into_superproject() in the diff
above, and then if BUG()'d out in that function, but the part where
we're about to recurse.
I couldn't get it to trigger, but I didn't look at it very
long. I.e. doesn't this require not this sort of test, but something
where it's being absorbed, *and* we'd walk and absorb it recursiveyl?
At least with checkout we then run into an error (can't remember the
message, sorry, this was earlier), and I haven't found a way to trigger
it.
But I'll poke it some more, but if you happen to have a test case for it
that would really help...
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v2 03/10] submodule--helper: "deinit" has never used "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
2022-11-14 10:08 ` [PATCH v2 01/10] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
2022-11-14 10:08 ` [PATCH v2 02/10] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 10:08 ` [PATCH v2 04/10] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
` (10 subsequent siblings)
13 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
The "deinit_submodule()" function has never been able to use the "git
--super-prefix". It will call "absorb_git_dir_into_superproject()",
but it will only do so from the top-level project.
If "absorbgitdirs" recurses it will use the "path" passed to
"absorb_git_dir_into_superproject()" in "deinit_submodule()" as its
starting "--super-prefix".
So, let's introduce a "get_submodule_displaypath_sp()" helper, and
make our existing "get_submodule_displaypath()" a wrapper for it. In a
subsequent commit the wrapper will be going away, as the rest of the
commands here will stop using the global "get_super_prefix()".
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 427e793e204..c4d5e029b37 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -113,10 +113,9 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int
}
/* the result should be freed by the caller. */
-static char *get_submodule_displaypath(const char *path, const char *prefix)
+static char *get_submodule_displaypath_sp(const char *path, const char *prefix,
+ const char *super_prefix)
{
- const char *super_prefix = get_super_prefix();
-
if (prefix && super_prefix) {
BUG("cannot have prefix '%s' and superprefix '%s'",
prefix, super_prefix);
@@ -132,6 +131,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix)
}
}
+static char *get_submodule_displaypath(const char *path, const char *prefix)
+{
+ const char *super_prefix = get_super_prefix();
+
+ return get_submodule_displaypath_sp(path, prefix, super_prefix);
+}
+
static char *compute_rev_name(const char *sub_path, const char* object_id)
{
struct strbuf sb = STRBUF_INIT;
@@ -1365,7 +1371,7 @@ static void deinit_submodule(const char *path, const char *prefix,
if (!sub || !sub->name)
goto cleanup;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath_sp(path, prefix, NULL);
/* remove the submodule work tree (unless the user already did it) */
if (is_directory(path)) {
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v2 04/10] submodule--helper: convert "foreach" to its own "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (2 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 03/10] submodule--helper: "deinit" has never used "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 21:56 ` Glen Choo
2022-11-14 10:08 ` [PATCH v2 05/10] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
` (9 subsequent siblings)
13 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper foreach" to use its own "--super-prefix", instead
of relying on the global "--super-prefix" argument to "git"
itself. See that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index c4d5e029b37..989c75280af 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -285,6 +285,7 @@ struct foreach_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
int quiet;
int recursive;
};
@@ -300,7 +301,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
struct child_process cp = CHILD_PROCESS_INIT;
char *displaypath;
- displaypath = get_submodule_displaypath(path, info->prefix);
+ displaypath = get_submodule_displaypath_sp(path, info->prefix,
+ info->super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -370,10 +372,10 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_pushl(&cpr.args, "--super-prefix", NULL);
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive",
NULL);
+ strvec_pushl(&cpr.args, "--super-prefix", NULL);
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (info->quiet)
strvec_push(&cpr.args, "--quiet");
@@ -396,7 +398,9 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
struct foreach_cb info = FOREACH_CB_INIT;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
+ const char *super_prefix = NULL;
struct option module_foreach_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
OPT_BOOL(0, "recursive", &info.recursive,
N_("recurse into nested submodules")),
@@ -417,6 +421,7 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
info.argc = argc;
info.argv = argv;
info.prefix = prefix;
+ info.super_prefix = super_prefix;
for_each_listed_submodule(&list, runcommand_in_submodule_cb, &info);
@@ -3390,8 +3395,8 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && get_super_prefix())
+ strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v2 04/10] submodule--helper: convert "foreach" to its own "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 04/10] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-11-14 21:56 ` Glen Choo
2022-11-17 18:14 ` Ævar Arnfjörð Bjarmason
0 siblings, 1 reply; 105+ messages in thread
From: Glen Choo @ 2022-11-14 21:56 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> As with a preceding commit to convert "absorbgitdirs", we can convert
> "submodule--helper foreach" to use its own "--super-prefix", instead
> of relying on the global "--super-prefix" argument to "git"
> itself. See that earlier commit for the rationale and background.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> builtin/submodule--helper.c | 15 ++++++++++-----
> 1 file changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index c4d5e029b37..989c75280af 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -396,7 +398,9 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
> struct foreach_cb info = FOREACH_CB_INIT;
> struct pathspec pathspec = { 0 };
> struct module_list list = MODULE_LIST_INIT;
> + const char *super_prefix = NULL;
> struct option module_foreach_options[] = {
> + OPT__SUPER_PREFIX(&super_prefix),
> OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
> OPT_BOOL(0, "recursive", &info.recursive,
> N_("recurse into nested submodules")),
> @@ -417,6 +421,7 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
> info.argc = argc;
> info.argv = argv;
> info.prefix = prefix;
> + info.super_prefix = super_prefix;
(Also applies to subsequent patches) Why don't we assign the super
prefix directly to the struct's field? e.g.
OPT__SUPER_PREFIX(&info.super_prefix),
>
> for_each_listed_submodule(&list, runcommand_in_submodule_cb, &info);
>
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 04/10] submodule--helper: convert "foreach" to its own "--super-prefix"
2022-11-14 21:56 ` Glen Choo
@ 2022-11-17 18:14 ` Ævar Arnfjörð Bjarmason
0 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-17 18:14 UTC (permalink / raw)
To: Glen Choo; +Cc: git, Taylor Blau, Robert Coup
On Mon, Nov 14 2022, Glen Choo wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> As with a preceding commit to convert "absorbgitdirs", we can convert
>> "submodule--helper foreach" to use its own "--super-prefix", instead
>> of relying on the global "--super-prefix" argument to "git"
>> itself. See that earlier commit for the rationale and background.
>>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>> builtin/submodule--helper.c | 15 ++++++++++-----
>> 1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
>> index c4d5e029b37..989c75280af 100644
>> --- a/builtin/submodule--helper.c
>> +++ b/builtin/submodule--helper.c
>> @@ -396,7 +398,9 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
>> struct foreach_cb info = FOREACH_CB_INIT;
>> struct pathspec pathspec = { 0 };
>> struct module_list list = MODULE_LIST_INIT;
>> + const char *super_prefix = NULL;
>> struct option module_foreach_options[] = {
>> + OPT__SUPER_PREFIX(&super_prefix),
>> OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
>> OPT_BOOL(0, "recursive", &info.recursive,
>> N_("recurse into nested submodules")),
>> @@ -417,6 +421,7 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
>> info.argc = argc;
>> info.argv = argv;
>> info.prefix = prefix;
>> + info.super_prefix = super_prefix;
>
> (Also applies to subsequent patches) Why don't we assign the super
> prefix directly to the struct's field? e.g.
>
> OPT__SUPER_PREFIX(&info.super_prefix),
Good point! I've done that consistently in my WIP re-roll.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v2 05/10] submodule--helper: convert "sync" to its own "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (3 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 04/10] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 10:08 ` [PATCH v2 06/10] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
` (8 subsequent siblings)
13 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper sync" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 989c75280af..db58fd5b2c4 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1214,12 +1214,13 @@ static int module_summary(int argc, const char **argv, const char *prefix)
struct sync_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define SYNC_CB_INIT { 0 }
static void sync_submodule(const char *path, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
const struct submodule *sub;
char *remote_key = NULL;
@@ -1250,7 +1251,7 @@ static void sync_submodule(const char *path, const char *prefix,
super_config_url = xstrdup("");
}
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath_sp(path, prefix, super_prefix);
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ -1287,10 +1288,11 @@ static void sync_submodule(const char *path, const char *prefix,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "sync",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
+
if (flags & OPT_QUIET)
strvec_push(&cpr.args, "--quiet");
@@ -1313,7 +1315,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct sync_cb *info = cb_data;
- sync_submodule(list_item->name, info->prefix, info->flags);
+ sync_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_sync(int argc, const char **argv, const char *prefix)
@@ -1323,7 +1326,9 @@ static int module_sync(int argc, const char **argv, const char *prefix)
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
int recursive = 0;
+ const char *super_prefix = NULL;
struct option module_sync_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
OPT_BOOL(0, "recursive", &recursive,
N_("recurse into nested submodules")),
@@ -1342,6 +1347,7 @@ static int module_sync(int argc, const char **argv, const char *prefix)
goto cleanup;
info.prefix = prefix;
+ info.super_prefix = super_prefix;
if (quiet)
info.flags |= OPT_QUIET;
if (recursive)
@@ -2890,7 +2896,7 @@ static int module_set_url(int argc, const char **argv, const char *prefix)
config_name = xstrfmt("submodule.%s.url", path);
config_set_in_gitmodules_file_gently(config_name, newurl);
- sync_submodule(path, prefix, quiet ? OPT_QUIET : 0);
+ sync_submodule(path, prefix, NULL, quiet ? OPT_QUIET : 0);
free(config_name);
@@ -3395,8 +3401,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
- get_super_prefix())
+ strcmp(subcmd, "status") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v2 06/10] submodule--helper: convert "status" to its own "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (4 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 05/10] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 10:08 ` [PATCH v2 07/10] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
` (7 subsequent siblings)
13 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index db58fd5b2c4..40939b0b18e 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -581,6 +581,7 @@ static int module_init(int argc, const char **argv, const char *prefix)
struct status_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define STATUS_CB_INIT { 0 }
@@ -619,7 +620,7 @@ static int handle_submodule_head_ref(const char *refname UNUSED,
static void status_submodule(const char *path, const struct object_id *ce_oid,
unsigned int ce_flags, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
char *displaypath;
struct strvec diff_files_args = STRVEC_INIT;
@@ -635,7 +636,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath_sp(path, prefix, super_prefix);
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ -693,10 +694,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "status",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (flags & OPT_CACHED)
strvec_push(&cpr.args, "--cached");
@@ -720,7 +721,7 @@ static void status_submodule_cb(const struct cache_entry *list_item,
struct status_cb *info = cb_data;
status_submodule(list_item->name, &list_item->oid, list_item->ce_flags,
- info->prefix, info->flags);
+ info->prefix, info->super_prefix, info->flags);
}
static int module_status(int argc, const char **argv, const char *prefix)
@@ -729,7 +730,9 @@ static int module_status(int argc, const char **argv, const char *prefix)
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
+ const char *super_prefix = NULL;
struct option module_status_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT__QUIET(&quiet, N_("suppress submodule status output")),
OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
@@ -748,6 +751,7 @@ static int module_status(int argc, const char **argv, const char *prefix)
goto cleanup;
info.prefix = prefix;
+ info.super_prefix = super_prefix;
if (quiet)
info.flags |= OPT_QUIET;
@@ -3401,7 +3405,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && get_super_prefix())
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v2 07/10] submodule--helper: convert "{update,clone}" to their own "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (5 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 06/10] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 22:04 ` Glen Choo
2022-11-14 10:08 ` [PATCH v2 08/10] submodule tests: test "git branch -t" output and stderr Ævar Arnfjörð Bjarmason
` (6 subsequent siblings)
13 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git".
We need to convert both of these away from the global "--super-prefix"
at the same time, because "update" will call "clone", but "clone"
itself didn't make use of the global "--super-prefix" for displaying
paths. It was only on the list of sub-commands that accepted it
because "update"'s use of it would set it in its environment.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 45 ++++++++++++++++---------------------
git.c | 2 +-
2 files changed, 20 insertions(+), 27 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 40939b0b18e..e13615eb939 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -131,13 +131,6 @@ static char *get_submodule_displaypath_sp(const char *path, const char *prefix,
}
}
-static char *get_submodule_displaypath(const char *path, const char *prefix)
-{
- const char *super_prefix = get_super_prefix();
-
- return get_submodule_displaypath_sp(path, prefix, super_prefix);
-}
-
static char *compute_rev_name(const char *sub_path, const char* object_id)
{
struct strbuf sb = STRBUF_INIT;
@@ -446,11 +439,13 @@ static int starts_with_dot_dot_slash(const char *const path)
struct init_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define INIT_CB_INIT { 0 }
static void init_submodule(const char *path, const char *prefix,
+ const char *super_prefix,
unsigned int flags)
{
const struct submodule *sub;
@@ -458,7 +453,7 @@ static void init_submodule(const char *path, const char *prefix,
const char *upd;
char *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath_sp(path, prefix, super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -534,7 +529,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct init_cb *info = cb_data;
- init_submodule(list_item->name, info->prefix, info->flags);
+ init_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_init(int argc, const char **argv, const char *prefix)
@@ -802,6 +798,7 @@ struct summary_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
unsigned int cached: 1;
unsigned int for_status: 1;
unsigned int files: 1;
@@ -963,7 +960,8 @@ static void generate_submodule_summary(struct summary_cb *info,
dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
}
- displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
+ displaypath = get_submodule_displaypath_sp(p->sm_path, info->prefix,
+ info->super_prefix);
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ -1904,6 +1902,7 @@ static void submodule_update_clone_release(struct submodule_update_clone *suc)
struct update_data {
const char *prefix;
+ const char *super_prefix;
char *displaypath;
enum submodule_update_type update_default;
struct object_id suboid;
@@ -1979,7 +1978,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
enum submodule_update_type update_type;
char *key;
const struct update_data *ud = suc->update_data;
- char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
+ char *displaypath = get_submodule_displaypath_sp(ce->name, ud->prefix,
+ ud->super_prefix);
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ -2459,11 +2459,11 @@ static void update_data_to_args(const struct update_data *update_data,
{
enum submodule_update_type update_type = update_data->update_default;
+ strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
if (update_data->displaypath) {
strvec_push(args, "--super-prefix");
strvec_pushf(args, "%s/", update_data->displaypath);
}
- strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
if (update_data->quiet)
strvec_push(args, "--quiet");
@@ -2628,8 +2628,9 @@ static int update_submodules(struct update_data *update_data)
if (code)
goto fail;
- update_data->displaypath = get_submodule_displaypath(
- update_data->sm_path, update_data->prefix);
+ update_data->displaypath = get_submodule_displaypath_sp(
+ update_data->sm_path, update_data->prefix,
+ update_data->super_prefix);
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ -2654,7 +2655,9 @@ static int module_update(int argc, const char **argv, const char *prefix)
struct list_objects_filter_options filter_options =
LIST_OBJECTS_FILTER_INIT;
int ret;
+ const char *super_prefix = NULL;
struct option module_update_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
OPT_BOOL(0, "init", &opt.init,
N_("initialize uninitialized submodules before update")),
@@ -2720,6 +2723,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
opt.filter_options = &filter_options;
opt.prefix = prefix;
+ opt.super_prefix = super_prefix;
if (opt.update_default)
opt.update_strategy.type = opt.update_default;
@@ -2751,6 +2755,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
module_list_active(&list);
info.prefix = opt.prefix;
+ info.super_prefix = super_prefix;
if (opt.quiet)
info.flags |= OPT_QUIET;
@@ -3377,8 +3382,6 @@ static int module_add(int argc, const char **argv, const char *prefix)
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
{
- const char *cmd = argv[0];
- const char *subcmd;
parse_opt_subcommand_fn *fn = NULL;
const char *const usage[] = {
N_("git submodule--helper <command>"),
@@ -3402,16 +3405,6 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
OPT_END()
};
argc = parse_options(argc, argv, prefix, options, usage, 0);
- subcmd = argv[0];
-
- if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- get_super_prefix())
- /*
- * xstrfmt() rather than "%s %s" to keep the translated
- * string identical to git.c's.
- */
- die(_("%s doesn't support --super-prefix"),
- xstrfmt("'%s %s'", cmd, subcmd));
return fn(argc, argv, prefix);
}
diff --git a/git.c b/git.c
index b1b7e1a837e..2bca22cfd9a 100644
--- a/git.c
+++ b/git.c
@@ -610,7 +610,7 @@ static struct cmd_struct commands[] = {
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
- { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX },
+ { "submodule--helper", cmd_submodule__helper, RUN_SETUP },
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v2 07/10] submodule--helper: convert "{update,clone}" to their own "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 07/10] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
@ 2022-11-14 22:04 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-14 22:04 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index 40939b0b18e..e13615eb939 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -131,13 +131,6 @@ static char *get_submodule_displaypath_sp(const char *path, const char *prefix,
> }
> }
>
> -static char *get_submodule_displaypath(const char *path, const char *prefix)
> -{
> - const char *super_prefix = get_super_prefix();
> -
> - return get_submodule_displaypath_sp(path, prefix, super_prefix);
> -}
> -
It feels a bit odd that the function we keep is the one with _sp,
especially since the "original" is gone. FWIW, I wouldn't mind if we
just changed the signature of get_submodule_displaypath() instead of
introducing the _sp helper.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v2 08/10] submodule tests: test "git branch -t" output and stderr
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (6 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 07/10] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 22:20 ` Glen Choo
2022-11-14 10:08 ` [PATCH v2 09/10] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
` (5 subsequent siblings)
13 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
The "git branch" command will currently make use of the
"--super-prefix", as it will indirectly call submodule_move_head(),
which will have access to the "--super-prefix".
The output could thus be affected by the "--super-prefix". Right now
it isn't in this case, but let's exhaustively assert that that's the
case by testing the output of all of these "git branch -t" commands.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/lib-submodule-update.sh | 98 ++++++++++++++++++++++-----------------
1 file changed, 55 insertions(+), 43 deletions(-)
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 2d31fcfda1f..302d095ad9b 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -245,6 +245,17 @@ reset_work_tree_to_interested () {
git -C submodule_update/.git/modules/sub1 config submodule.sub2.url "bogus"
}
+test_branch_t_output () {
+ local branchname="$1" &&
+ local start_point="$2" &&
+ cat >expect <<-EOF &&
+ branch '$branchname' set up to track '$start_point'.
+ EOF
+ git branch -t "$branchname" "$start_point" >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp expect actual
+}
+
# Test that the superproject contains the content according to commit "$1"
# (the work tree must match the index for everything but submodules but the
# index must exactly match the given commit including any submodule SHA-1s).
@@ -323,7 +334,7 @@ test_submodule_switch_common () {
reset_work_tree_to no_submodule &&
(
cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
$command add_sub1 &&
test_superproject_content origin/add_sub1 &&
test_dir_is_empty sub1 &&
@@ -345,7 +356,7 @@ test_submodule_switch_common () {
(
cd submodule_update &&
mkdir sub1 &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
$command add_sub1 &&
test_superproject_content origin/add_sub1 &&
test_dir_is_empty sub1 &&
@@ -360,7 +371,7 @@ test_submodule_switch_common () {
reset_work_tree_to replace_sub1_with_file &&
(
cd submodule_update &&
- git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
+ test_branch_t_output replace_file_with_sub1 origin/replace_file_with_sub1 &&
$command replace_file_with_sub1 &&
test_superproject_content origin/replace_file_with_sub1 &&
test_dir_is_empty sub1 &&
@@ -384,7 +395,7 @@ test_submodule_switch_common () {
reset_work_tree_to replace_sub1_with_directory &&
(
cd submodule_update &&
- git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
+ test_branch_t_output replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
$command replace_directory_with_sub1 &&
test_superproject_content origin/replace_directory_with_sub1 &&
test_dir_is_empty sub1 &&
@@ -406,7 +417,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t remove_sub1 origin/remove_sub1 &&
+ test_branch_t_output remove_sub1 origin/remove_sub1 &&
$command remove_sub1 &&
test_superproject_content origin/remove_sub1 &&
test_submodule_content sub1 origin/add_sub1
@@ -418,7 +429,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t remove_sub1 origin/remove_sub1 &&
+ test_branch_t_output remove_sub1 origin/remove_sub1 &&
replace_gitfile_with_git_dir sub1 &&
$command remove_sub1 &&
test_superproject_content origin/remove_sub1 &&
@@ -447,7 +458,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
+ test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
$command replace_sub1_with_directory test_must_fail &&
test_superproject_content origin/add_sub1 &&
test_submodule_content sub1 origin/add_sub1
@@ -459,7 +470,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
+ test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
replace_gitfile_with_git_dir sub1 &&
$command replace_sub1_with_directory test_must_fail &&
test_superproject_content origin/add_sub1 &&
@@ -474,7 +485,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
+ test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
$command replace_sub1_with_file test_must_fail &&
test_superproject_content origin/add_sub1 &&
test_submodule_content sub1 origin/add_sub1
@@ -487,7 +498,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
+ test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
replace_gitfile_with_git_dir sub1 &&
$command replace_sub1_with_file test_must_fail &&
test_superproject_content origin/add_sub1 &&
@@ -512,7 +523,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t modify_sub1 origin/modify_sub1 &&
+ test_branch_t_output modify_sub1 origin/modify_sub1 &&
$command modify_sub1 &&
test_superproject_content origin/modify_sub1 &&
test_submodule_content sub1 origin/add_sub1 &&
@@ -527,7 +538,7 @@ test_submodule_switch_common () {
reset_work_tree_to add_sub1 &&
(
cd submodule_update &&
- git branch -t invalid_sub1 origin/invalid_sub1 &&
+ test_branch_t_output invalid_sub1 origin/invalid_sub1 &&
$command invalid_sub1 &&
test_superproject_content origin/invalid_sub1 &&
test_submodule_content sub1 origin/add_sub1 &&
@@ -542,7 +553,7 @@ test_submodule_switch_common () {
reset_work_tree_to invalid_sub1 &&
(
cd submodule_update &&
- git branch -t valid_sub1 origin/valid_sub1 &&
+ test_branch_t_output valid_sub1 origin/valid_sub1 &&
$command valid_sub1 &&
test_superproject_content origin/valid_sub1 &&
test_dir_is_empty sub1 &&
@@ -596,7 +607,7 @@ test_submodule_switch_func () {
reset_work_tree_to no_submodule &&
(
cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
>sub1 &&
$command add_sub1 test_must_fail &&
test_superproject_content origin/no_submodule &&
@@ -635,7 +646,7 @@ test_submodule_forced_switch () {
reset_work_tree_to no_submodule &&
(
cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
>sub1 &&
$command add_sub1 &&
test_superproject_content origin/add_sub1 &&
@@ -675,7 +686,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested no_submodule &&
(
cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
$command add_sub1 &&
test_superproject_content origin/add_sub1 &&
test_submodule_content sub1 origin/add_sub1
@@ -688,7 +699,7 @@ test_submodule_recursing_with_args_common () {
(
cd submodule_update &&
mkdir sub1 &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
$command add_sub1 &&
test_superproject_content origin/add_sub1 &&
test_submodule_content sub1 origin/add_sub1
@@ -701,7 +712,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested replace_sub1_with_file &&
(
cd submodule_update &&
- git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
+ test_branch_t_output replace_file_with_sub1 origin/replace_file_with_sub1 &&
$command replace_file_with_sub1 &&
test_superproject_content origin/replace_file_with_sub1 &&
test_submodule_content sub1 origin/replace_file_with_sub1
@@ -713,19 +724,20 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested replace_sub1_with_directory &&
(
cd submodule_update &&
- git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
+ test_branch_t_output replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
$command replace_directory_with_sub1 &&
test_superproject_content origin/replace_directory_with_sub1 &&
test_submodule_content sub1 origin/replace_directory_with_sub1
)
'
+
# Switching to a commit with nested submodules recursively checks them out
test_expect_success "$command: nested submodules are checked out" '
prolog &&
reset_work_tree_to_interested no_submodule &&
(
cd submodule_update &&
- git branch -t modify_sub1_recursively origin/modify_sub1_recursively &&
+ test_branch_t_output modify_sub1_recursively origin/modify_sub1_recursively &&
$command modify_sub1_recursively &&
test_superproject_content origin/modify_sub1_recursively &&
test_submodule_content sub1 origin/modify_sub1_recursively &&
@@ -740,7 +752,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t remove_sub1 origin/remove_sub1 &&
+ test_branch_t_output remove_sub1 origin/remove_sub1 &&
$command remove_sub1 &&
test_superproject_content origin/remove_sub1 &&
! test -e sub1 &&
@@ -753,7 +765,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t remove_sub1 origin/remove_sub1 &&
+ test_branch_t_output remove_sub1 origin/remove_sub1 &&
replace_gitfile_with_git_dir sub1 &&
rm -rf .git/modules &&
$command remove_sub1 &&
@@ -769,7 +781,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
+ test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
$command replace_sub1_with_file &&
test_superproject_content origin/replace_sub1_with_file &&
test -f sub1
@@ -786,7 +798,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
+ test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
: >sub1/untrackedfile &&
test_must_fail $command replace_sub1_with_file &&
test_superproject_content origin/add_sub1 &&
@@ -801,7 +813,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested add_nested_sub &&
(
cd submodule_update &&
- git branch -t no_submodule origin/no_submodule &&
+ test_branch_t_output no_submodule origin/no_submodule &&
$command no_submodule &&
test_superproject_content origin/no_submodule &&
! test_path_is_dir sub1 &&
@@ -817,7 +829,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t modify_sub1 origin/modify_sub1 &&
+ test_branch_t_output modify_sub1 origin/modify_sub1 &&
$command modify_sub1 &&
test_superproject_content origin/modify_sub1 &&
test_submodule_content sub1 origin/modify_sub1
@@ -830,7 +842,7 @@ test_submodule_recursing_with_args_common () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t invalid_sub1 origin/invalid_sub1 &&
+ test_branch_t_output invalid_sub1 origin/invalid_sub1 &&
test_must_fail $command invalid_sub1 2>err &&
test_i18ngrep sub1 err &&
test_superproject_content origin/add_sub1 &&
@@ -844,13 +856,13 @@ test_submodule_recursing_with_args_common () {
(
cd submodule_update &&
git -C sub1 checkout -b keep_branch &&
- git -C sub1 rev-parse HEAD >expect &&
- git branch -t modify_sub1 origin/modify_sub1 &&
+ git -C sub1 rev-parse HEAD >expect.rev-parse &&
+ test_branch_t_output modify_sub1 origin/modify_sub1 &&
$command modify_sub1 &&
test_superproject_content origin/modify_sub1 &&
test_submodule_content sub1 origin/modify_sub1 &&
git -C sub1 rev-parse keep_branch >actual &&
- test_cmp expect actual &&
+ test_cmp expect.rev-parse actual &&
test_must_fail git -C sub1 symbolic-ref HEAD
)
'
@@ -894,7 +906,7 @@ test_submodule_switch_recursing_with_args () {
reset_work_tree_to_interested no_submodule &&
(
cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
: >sub1 &&
test_must_fail $command add_sub1 &&
test_superproject_content origin/no_submodule &&
@@ -908,7 +920,7 @@ test_submodule_switch_recursing_with_args () {
reset_work_tree_to_interested no_submodule &&
(
cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
: >sub1 &&
mkdir .git/info &&
echo sub1 >.git/info/exclude &&
@@ -925,7 +937,7 @@ test_submodule_switch_recursing_with_args () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
+ test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
$command replace_sub1_with_directory &&
test_superproject_content origin/replace_sub1_with_directory &&
test_submodule_content sub1 origin/replace_sub1_with_directory
@@ -937,7 +949,7 @@ test_submodule_switch_recursing_with_args () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
+ test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
replace_gitfile_with_git_dir sub1 &&
rm -rf .git/modules &&
$command replace_sub1_with_directory &&
@@ -954,7 +966,7 @@ test_submodule_switch_recursing_with_args () {
(
cd submodule_update &&
rm -rf .git/modules/sub1/info &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
+ test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
mkdir .git/modules/sub1/info &&
echo ignored >.git/modules/sub1/info/exclude &&
: >sub1/ignored &&
@@ -969,7 +981,7 @@ test_submodule_switch_recursing_with_args () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t modify_sub1 origin/modify_sub1 &&
+ test_branch_t_output modify_sub1 origin/modify_sub1 &&
git -c submodule.recurse=true $cmd_args modify_sub1 &&
test_superproject_content origin/modify_sub1 &&
test_submodule_content sub1 origin/modify_sub1
@@ -981,7 +993,7 @@ test_submodule_switch_recursing_with_args () {
reset_work_tree_to_interested add_nested_sub &&
(
cd submodule_update &&
- git branch -t modify_sub1_recursively origin/modify_sub1_recursively &&
+ test_branch_t_output modify_sub1_recursively origin/modify_sub1_recursively &&
$command modify_sub1_recursively &&
test_superproject_content origin/modify_sub1_recursively &&
test_submodule_content sub1 origin/modify_sub1_recursively &&
@@ -1009,7 +1021,7 @@ test_submodule_forced_switch_recursing_with_args () {
reset_work_tree_to_interested no_submodule &&
(
cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
+ test_branch_t_output add_sub1 origin/add_sub1 &&
>sub1 &&
$command add_sub1 &&
test_superproject_content origin/add_sub1 &&
@@ -1023,7 +1035,7 @@ test_submodule_forced_switch_recursing_with_args () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
+ test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
$command replace_sub1_with_directory &&
test_superproject_content origin/replace_sub1_with_directory
)
@@ -1034,7 +1046,7 @@ test_submodule_forced_switch_recursing_with_args () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
+ test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
replace_gitfile_with_git_dir sub1 &&
rm -rf .git/modules/sub1 &&
$command replace_sub1_with_directory &&
@@ -1049,7 +1061,7 @@ test_submodule_forced_switch_recursing_with_args () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
+ test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
: >sub1/expect &&
$command replace_sub1_with_file &&
test_superproject_content origin/replace_sub1_with_file
@@ -1062,7 +1074,7 @@ test_submodule_forced_switch_recursing_with_args () {
reset_work_tree_to_interested invalid_sub1 &&
(
cd submodule_update &&
- git branch -t valid_sub1 origin/valid_sub1 &&
+ test_branch_t_output valid_sub1 origin/valid_sub1 &&
$command valid_sub1 &&
test_superproject_content origin/valid_sub1 &&
test_submodule_content sub1 origin/valid_sub1
@@ -1077,7 +1089,7 @@ test_submodule_forced_switch_recursing_with_args () {
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
- git branch -t modify_sub1 origin/modify_sub1 &&
+ test_branch_t_output modify_sub1 origin/modify_sub1 &&
echo "gitdir: bogus/path" >sub1/.git &&
$command modify_sub1 &&
test_superproject_content origin/modify_sub1 &&
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v2 08/10] submodule tests: test "git branch -t" output and stderr
2022-11-14 10:08 ` [PATCH v2 08/10] submodule tests: test "git branch -t" output and stderr Ævar Arnfjörð Bjarmason
@ 2022-11-14 22:20 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-14 22:20 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> The "git branch" command will currently make use of the
> "--super-prefix", as it will indirectly call submodule_move_head(),
> which will have access to the "--super-prefix".
I couldn't figure out how "git branch" ends up calling
submodule_move_head(), could you include the call chain?
I find it very odd because AFAICT we only call submodule_move_head()
when we are modifying the working tree (or checking if it is safe to
modify), and "git branch" shouldn't touch the working tree.
> The output could thus be affected by the "--super-prefix". Right now
> it isn't in this case, but let's exhaustively assert that that's the
> case by testing the output of all of these "git branch -t" commands.
It's reasonable to be worried if the output contained paths to the
working tree, but...
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> t/lib-submodule-update.sh | 98 ++++++++++++++++++++++-----------------
> 1 file changed, 55 insertions(+), 43 deletions(-)
>
> diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
> index 2d31fcfda1f..302d095ad9b 100644
> --- a/t/lib-submodule-update.sh
> +++ b/t/lib-submodule-update.sh
> @@ -245,6 +245,17 @@ reset_work_tree_to_interested () {
> git -C submodule_update/.git/modules/sub1 config submodule.sub2.url "bogus"
> }
>
> +test_branch_t_output () {
> + local branchname="$1" &&
> + local start_point="$2" &&
> + cat >expect <<-EOF &&
> + branch '$branchname' set up to track '$start_point'.
> + EOF
> + git branch -t "$branchname" "$start_point" >actual 2>err &&
> + test_must_be_empty err &&
> + test_cmp expect actual
> +}
> +
it looks like the output is based entirely on the ref store, which has
no reason to use the super prefix. Based on the commit message in
74866d7579 (git: make super-prefix option, 2016-10-07):
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.
and the fact that the super prefix has never been used for anything
other than the working tree, I don't think this level of paranoia is
necessary.
> # Test that the superproject contains the content according to commit "$1"
> # (the work tree must match the index for everything but submodules but the
> # index must exactly match the given commit including any submodule SHA-1s).
> @@ -323,7 +334,7 @@ test_submodule_switch_common () {
> reset_work_tree_to no_submodule &&
> (
> cd submodule_update &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> $command add_sub1 &&
> test_superproject_content origin/add_sub1 &&
> test_dir_is_empty sub1 &&
> @@ -345,7 +356,7 @@ test_submodule_switch_common () {
> (
> cd submodule_update &&
> mkdir sub1 &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> $command add_sub1 &&
> test_superproject_content origin/add_sub1 &&
> test_dir_is_empty sub1 &&
> @@ -360,7 +371,7 @@ test_submodule_switch_common () {
> reset_work_tree_to replace_sub1_with_file &&
> (
> cd submodule_update &&
> - git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
> + test_branch_t_output replace_file_with_sub1 origin/replace_file_with_sub1 &&
> $command replace_file_with_sub1 &&
> test_superproject_content origin/replace_file_with_sub1 &&
> test_dir_is_empty sub1 &&
> @@ -384,7 +395,7 @@ test_submodule_switch_common () {
> reset_work_tree_to replace_sub1_with_directory &&
> (
> cd submodule_update &&
> - git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
> + test_branch_t_output replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
> $command replace_directory_with_sub1 &&
> test_superproject_content origin/replace_directory_with_sub1 &&
> test_dir_is_empty sub1 &&
> @@ -406,7 +417,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t remove_sub1 origin/remove_sub1 &&
> + test_branch_t_output remove_sub1 origin/remove_sub1 &&
> $command remove_sub1 &&
> test_superproject_content origin/remove_sub1 &&
> test_submodule_content sub1 origin/add_sub1
> @@ -418,7 +429,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t remove_sub1 origin/remove_sub1 &&
> + test_branch_t_output remove_sub1 origin/remove_sub1 &&
> replace_gitfile_with_git_dir sub1 &&
> $command remove_sub1 &&
> test_superproject_content origin/remove_sub1 &&
> @@ -447,7 +458,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
> + test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
> $command replace_sub1_with_directory test_must_fail &&
> test_superproject_content origin/add_sub1 &&
> test_submodule_content sub1 origin/add_sub1
> @@ -459,7 +470,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
> + test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
> replace_gitfile_with_git_dir sub1 &&
> $command replace_sub1_with_directory test_must_fail &&
> test_superproject_content origin/add_sub1 &&
> @@ -474,7 +485,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
> + test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
> $command replace_sub1_with_file test_must_fail &&
> test_superproject_content origin/add_sub1 &&
> test_submodule_content sub1 origin/add_sub1
> @@ -487,7 +498,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
> + test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
> replace_gitfile_with_git_dir sub1 &&
> $command replace_sub1_with_file test_must_fail &&
> test_superproject_content origin/add_sub1 &&
> @@ -512,7 +523,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t modify_sub1 origin/modify_sub1 &&
> + test_branch_t_output modify_sub1 origin/modify_sub1 &&
> $command modify_sub1 &&
> test_superproject_content origin/modify_sub1 &&
> test_submodule_content sub1 origin/add_sub1 &&
> @@ -527,7 +538,7 @@ test_submodule_switch_common () {
> reset_work_tree_to add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t invalid_sub1 origin/invalid_sub1 &&
> + test_branch_t_output invalid_sub1 origin/invalid_sub1 &&
> $command invalid_sub1 &&
> test_superproject_content origin/invalid_sub1 &&
> test_submodule_content sub1 origin/add_sub1 &&
> @@ -542,7 +553,7 @@ test_submodule_switch_common () {
> reset_work_tree_to invalid_sub1 &&
> (
> cd submodule_update &&
> - git branch -t valid_sub1 origin/valid_sub1 &&
> + test_branch_t_output valid_sub1 origin/valid_sub1 &&
> $command valid_sub1 &&
> test_superproject_content origin/valid_sub1 &&
> test_dir_is_empty sub1 &&
> @@ -596,7 +607,7 @@ test_submodule_switch_func () {
> reset_work_tree_to no_submodule &&
> (
> cd submodule_update &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> >sub1 &&
> $command add_sub1 test_must_fail &&
> test_superproject_content origin/no_submodule &&
> @@ -635,7 +646,7 @@ test_submodule_forced_switch () {
> reset_work_tree_to no_submodule &&
> (
> cd submodule_update &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> >sub1 &&
> $command add_sub1 &&
> test_superproject_content origin/add_sub1 &&
> @@ -675,7 +686,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested no_submodule &&
> (
> cd submodule_update &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> $command add_sub1 &&
> test_superproject_content origin/add_sub1 &&
> test_submodule_content sub1 origin/add_sub1
> @@ -688,7 +699,7 @@ test_submodule_recursing_with_args_common () {
> (
> cd submodule_update &&
> mkdir sub1 &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> $command add_sub1 &&
> test_superproject_content origin/add_sub1 &&
> test_submodule_content sub1 origin/add_sub1
> @@ -701,7 +712,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested replace_sub1_with_file &&
> (
> cd submodule_update &&
> - git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
> + test_branch_t_output replace_file_with_sub1 origin/replace_file_with_sub1 &&
> $command replace_file_with_sub1 &&
> test_superproject_content origin/replace_file_with_sub1 &&
> test_submodule_content sub1 origin/replace_file_with_sub1
> @@ -713,19 +724,20 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested replace_sub1_with_directory &&
> (
> cd submodule_update &&
> - git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
> + test_branch_t_output replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
> $command replace_directory_with_sub1 &&
> test_superproject_content origin/replace_directory_with_sub1 &&
> test_submodule_content sub1 origin/replace_directory_with_sub1
> )
> '
> +
> # Switching to a commit with nested submodules recursively checks them out
> test_expect_success "$command: nested submodules are checked out" '
> prolog &&
> reset_work_tree_to_interested no_submodule &&
> (
> cd submodule_update &&
> - git branch -t modify_sub1_recursively origin/modify_sub1_recursively &&
> + test_branch_t_output modify_sub1_recursively origin/modify_sub1_recursively &&
> $command modify_sub1_recursively &&
> test_superproject_content origin/modify_sub1_recursively &&
> test_submodule_content sub1 origin/modify_sub1_recursively &&
> @@ -740,7 +752,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t remove_sub1 origin/remove_sub1 &&
> + test_branch_t_output remove_sub1 origin/remove_sub1 &&
> $command remove_sub1 &&
> test_superproject_content origin/remove_sub1 &&
> ! test -e sub1 &&
> @@ -753,7 +765,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t remove_sub1 origin/remove_sub1 &&
> + test_branch_t_output remove_sub1 origin/remove_sub1 &&
> replace_gitfile_with_git_dir sub1 &&
> rm -rf .git/modules &&
> $command remove_sub1 &&
> @@ -769,7 +781,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
> + test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
> $command replace_sub1_with_file &&
> test_superproject_content origin/replace_sub1_with_file &&
> test -f sub1
> @@ -786,7 +798,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
> + test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
> : >sub1/untrackedfile &&
> test_must_fail $command replace_sub1_with_file &&
> test_superproject_content origin/add_sub1 &&
> @@ -801,7 +813,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested add_nested_sub &&
> (
> cd submodule_update &&
> - git branch -t no_submodule origin/no_submodule &&
> + test_branch_t_output no_submodule origin/no_submodule &&
> $command no_submodule &&
> test_superproject_content origin/no_submodule &&
> ! test_path_is_dir sub1 &&
> @@ -817,7 +829,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t modify_sub1 origin/modify_sub1 &&
> + test_branch_t_output modify_sub1 origin/modify_sub1 &&
> $command modify_sub1 &&
> test_superproject_content origin/modify_sub1 &&
> test_submodule_content sub1 origin/modify_sub1
> @@ -830,7 +842,7 @@ test_submodule_recursing_with_args_common () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t invalid_sub1 origin/invalid_sub1 &&
> + test_branch_t_output invalid_sub1 origin/invalid_sub1 &&
> test_must_fail $command invalid_sub1 2>err &&
> test_i18ngrep sub1 err &&
> test_superproject_content origin/add_sub1 &&
> @@ -844,13 +856,13 @@ test_submodule_recursing_with_args_common () {
> (
> cd submodule_update &&
> git -C sub1 checkout -b keep_branch &&
> - git -C sub1 rev-parse HEAD >expect &&
> - git branch -t modify_sub1 origin/modify_sub1 &&
> + git -C sub1 rev-parse HEAD >expect.rev-parse &&
> + test_branch_t_output modify_sub1 origin/modify_sub1 &&
> $command modify_sub1 &&
> test_superproject_content origin/modify_sub1 &&
> test_submodule_content sub1 origin/modify_sub1 &&
> git -C sub1 rev-parse keep_branch >actual &&
> - test_cmp expect actual &&
> + test_cmp expect.rev-parse actual &&
> test_must_fail git -C sub1 symbolic-ref HEAD
> )
> '
> @@ -894,7 +906,7 @@ test_submodule_switch_recursing_with_args () {
> reset_work_tree_to_interested no_submodule &&
> (
> cd submodule_update &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> : >sub1 &&
> test_must_fail $command add_sub1 &&
> test_superproject_content origin/no_submodule &&
> @@ -908,7 +920,7 @@ test_submodule_switch_recursing_with_args () {
> reset_work_tree_to_interested no_submodule &&
> (
> cd submodule_update &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> : >sub1 &&
> mkdir .git/info &&
> echo sub1 >.git/info/exclude &&
> @@ -925,7 +937,7 @@ test_submodule_switch_recursing_with_args () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
> + test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
> $command replace_sub1_with_directory &&
> test_superproject_content origin/replace_sub1_with_directory &&
> test_submodule_content sub1 origin/replace_sub1_with_directory
> @@ -937,7 +949,7 @@ test_submodule_switch_recursing_with_args () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
> + test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
> replace_gitfile_with_git_dir sub1 &&
> rm -rf .git/modules &&
> $command replace_sub1_with_directory &&
> @@ -954,7 +966,7 @@ test_submodule_switch_recursing_with_args () {
> (
> cd submodule_update &&
> rm -rf .git/modules/sub1/info &&
> - git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
> + test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
> mkdir .git/modules/sub1/info &&
> echo ignored >.git/modules/sub1/info/exclude &&
> : >sub1/ignored &&
> @@ -969,7 +981,7 @@ test_submodule_switch_recursing_with_args () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t modify_sub1 origin/modify_sub1 &&
> + test_branch_t_output modify_sub1 origin/modify_sub1 &&
> git -c submodule.recurse=true $cmd_args modify_sub1 &&
> test_superproject_content origin/modify_sub1 &&
> test_submodule_content sub1 origin/modify_sub1
> @@ -981,7 +993,7 @@ test_submodule_switch_recursing_with_args () {
> reset_work_tree_to_interested add_nested_sub &&
> (
> cd submodule_update &&
> - git branch -t modify_sub1_recursively origin/modify_sub1_recursively &&
> + test_branch_t_output modify_sub1_recursively origin/modify_sub1_recursively &&
> $command modify_sub1_recursively &&
> test_superproject_content origin/modify_sub1_recursively &&
> test_submodule_content sub1 origin/modify_sub1_recursively &&
> @@ -1009,7 +1021,7 @@ test_submodule_forced_switch_recursing_with_args () {
> reset_work_tree_to_interested no_submodule &&
> (
> cd submodule_update &&
> - git branch -t add_sub1 origin/add_sub1 &&
> + test_branch_t_output add_sub1 origin/add_sub1 &&
> >sub1 &&
> $command add_sub1 &&
> test_superproject_content origin/add_sub1 &&
> @@ -1023,7 +1035,7 @@ test_submodule_forced_switch_recursing_with_args () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
> + test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
> $command replace_sub1_with_directory &&
> test_superproject_content origin/replace_sub1_with_directory
> )
> @@ -1034,7 +1046,7 @@ test_submodule_forced_switch_recursing_with_args () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
> + test_branch_t_output replace_sub1_with_directory origin/replace_sub1_with_directory &&
> replace_gitfile_with_git_dir sub1 &&
> rm -rf .git/modules/sub1 &&
> $command replace_sub1_with_directory &&
> @@ -1049,7 +1061,7 @@ test_submodule_forced_switch_recursing_with_args () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
> + test_branch_t_output replace_sub1_with_file origin/replace_sub1_with_file &&
> : >sub1/expect &&
> $command replace_sub1_with_file &&
> test_superproject_content origin/replace_sub1_with_file
> @@ -1062,7 +1074,7 @@ test_submodule_forced_switch_recursing_with_args () {
> reset_work_tree_to_interested invalid_sub1 &&
> (
> cd submodule_update &&
> - git branch -t valid_sub1 origin/valid_sub1 &&
> + test_branch_t_output valid_sub1 origin/valid_sub1 &&
> $command valid_sub1 &&
> test_superproject_content origin/valid_sub1 &&
> test_submodule_content sub1 origin/valid_sub1
> @@ -1077,7 +1089,7 @@ test_submodule_forced_switch_recursing_with_args () {
> reset_work_tree_to_interested add_sub1 &&
> (
> cd submodule_update &&
> - git branch -t modify_sub1 origin/modify_sub1 &&
> + test_branch_t_output modify_sub1 origin/modify_sub1 &&
> echo "gitdir: bogus/path" >sub1/.git &&
> $command modify_sub1 &&
> test_superproject_content origin/modify_sub1 &&
> --
> 2.38.0.1471.ge4d8947e7aa
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v2 09/10] read-tree: add "--super-prefix" option, eliminate global
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (7 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 08/10] submodule tests: test "git branch -t" output and stderr Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 22:28 ` Glen Choo
2022-11-14 10:08 ` [PATCH v2 10/10] fetch: rename "--submodule-prefix" to "--super-prefix" Ævar Arnfjörð Bjarmason
` (4 subsequent siblings)
13 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
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>
---
Documentation/git.txt | 8 +-------
builtin.h | 4 ----
builtin/checkout.c | 2 +-
builtin/read-tree.c | 1 +
cache.h | 2 --
entry.c | 12 ++++++------
entry.h | 6 +++++-
environment.c | 13 -------------
git.c | 37 +++++--------------------------------
submodule.c | 27 +++++++++------------------
submodule.h | 5 ++---
t/t1001-read-tree-m-2way.sh | 2 +-
t/t5616-partial-clone.sh | 2 +-
unpack-trees.c | 23 +++++++++++++----------
unpack-trees.h | 1 +
15 files changed, 46 insertions(+), 99 deletions(-)
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 1d33e083ab8..f9a7a4554cd 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
diff --git a/builtin.h b/builtin.h
index 8901a34d6bf..8264b7e5241 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
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2a132392fbe..dc008fb45e8 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -231,7 +231,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)
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index f4cbe460b97..4b6f22e58c1 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),
diff --git a/cache.h b/cache.h
index 26ed03bd6de..a4a0377b800 100644
--- a/cache.h
+++ b/cache.h
@@ -504,7 +504,6 @@ 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"
@@ -590,7 +589,6 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
int get_common_dir(struct strbuf *sb, const char *gitdir);
const char *get_git_namespace(void);
const char *strip_namespace(const char *namespaced_ref);
-const char *get_super_prefix(void);
const char *get_git_work_tree(void);
/*
diff --git a/entry.c b/entry.c
index 616e4f073c1..971ab268714 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)
diff --git a/entry.h b/entry.h
index 9be4659881e..2d4fbb88c8f 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);
diff --git a/environment.c b/environment.c
index 18d042b467d..1ee3686fd8a 100644
--- a/environment.c
+++ b/environment.c
@@ -102,8 +102,6 @@ char *git_work_tree_cfg;
static char *git_namespace;
-static char *super_prefix;
-
/*
* Repository-local GIT_* environment variables; see cache.h for details.
*/
@@ -121,7 +119,6 @@ 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
@@ -234,16 +231,6 @@ const char *strip_namespace(const char *namespaced_ref)
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;
/*
diff --git a/git.c b/git.c
index 2bca22cfd9a..00baaf23590 100644
--- a/git.c
+++ b/git.c
@@ -14,9 +14,8 @@
* RUN_SETUP for reading from the configuration file.
*/
#define NEED_WORK_TREE (1<<3)
-#define SUPPORT_SUPER_PREFIX (1<<4)
-#define DELAY_PAGER_CONFIG (1<<5)
-#define NO_PARSEOPT (1<<6) /* parse-options is not used */
+#define DELAY_PAGER_CONFIG (1<<4)
+#define NO_PARSEOPT (1<<5) /* parse-options is not used */
struct cmd_struct {
const char *cmd;
@@ -29,8 +28,7 @@ const char git_usage_string[] =
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
- " [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
- " <command> [<args>]");
+ " [--config-env=<name>=<envvar>] <command> [<args>]");
const char git_more_info_string[] =
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);
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;
@@ -449,11 +433,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
trace_repo_setup(prefix);
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)
setup_work_tree();
@@ -504,7 +483,7 @@ static struct cmd_struct commands[] = {
{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
{ "checkout--worker", cmd_checkout__worker,
- RUN_SETUP | NEED_WORK_TREE | SUPPORT_SUPER_PREFIX },
+ RUN_SETUP | NEED_WORK_TREE },
{ "checkout-index", cmd_checkout_index,
RUN_SETUP | NEED_WORK_TREE},
{ "cherry", cmd_cherry, RUN_SETUP },
@@ -583,7 +562,7 @@ static struct cmd_struct commands[] = {
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
{ "push", cmd_push, RUN_SETUP },
{ "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 },
{ "receive-pack", cmd_receive_pack },
{ "reflog", cmd_reflog, RUN_SETUP },
@@ -727,9 +706,6 @@ static void execv_dashed_external(const char **argv)
struct child_process cmd = CHILD_PROCESS_INIT;
int status;
- if (get_super_prefix())
- die(_("%s doesn't support --super-prefix"), argv[0]);
-
if (use_pager == -1 && !is_builtin(argv[0]))
use_pager = check_pager_config(argv[0]);
commit_pager_choice();
@@ -799,9 +775,6 @@ static int run_argv(int *argcp, const char ***argv)
*/
trace2_cmd_name("_run_git_alias_");
- if (get_super_prefix())
- die("%s doesn't support --super-prefix", **argv);
-
commit_pager_choice();
strvec_push(&cmd.args, "git");
diff --git a/submodule.c b/submodule.c
index d9fd0af81b6..5ac4e1b0568 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2048,14 +2048,6 @@ void submodule_unset_core_worktree(const struct submodule *sub)
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)
{
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2074,7 +2066,7 @@ static int submodule_has_dirty_index(const struct submodule *sub)
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;
prepare_submodule_repo_env(&cp.env);
@@ -2083,10 +2075,10 @@ static void submodule_reset_index(const char *path)
cp.no_stdin = 1;
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 */
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());
@@ -2099,10 +2091,9 @@ static void submodule_reset_index(const char *path)
* For edge cases (a submodule coming into existence or removing a submodule)
* pass NULL for old or new respectively.
*/
-int submodule_move_head(const char *path,
- const char *old_head,
- const char *new_head,
- unsigned flags)
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
+ unsigned flags)
{
int ret = 0;
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2148,7 +2139,7 @@ int submodule_move_head(const char *path,
strbuf_release(&gitdir);
/* make sure the index is clean as well */
- submodule_reset_index(path);
+ submodule_reset_index(path, NULL);
}
if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
@@ -2166,9 +2157,9 @@ int submodule_move_head(const char *path,
cp.no_stdin = 1;
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_pushf(&cp.args, "--super-prefix=%s%s/",
+ (super_prefix ? super_prefix : ""), path);
if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN)
strvec_push(&cp.args, "-n");
diff --git a/submodule.h b/submodule.h
index e5ee13fb06a..36a7f7c5b32 100644
--- a/submodule.h
+++ b/submodule.h
@@ -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_FORCE (1<<1)
-int submodule_move_head(const char *path,
- const char *old,
- const char *new_head,
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
unsigned flags);
void submodule_unset_core_worktree(const struct submodule *sub);
diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh
index 516a6112fdc..3fb1b0c162d 100755
--- a/t/t1001-read-tree-m-2way.sh
+++ b/t/t1001-read-tree-m-2way.sh
@@ -370,7 +370,7 @@ test_expect_success 'read-tree supports the super-prefix' '
cat <<-EOF >expect &&
error: Updating '\''fictional/a'\'' would lose untracked files in it
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
'
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index e56466580cf..18375bff535 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,7 +644,7 @@ test_expect_success 'repack does not loosen promisor objects' '
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
test_config_global protocol.file.allow always &&
diff --git a/unpack-trees.c b/unpack-trees.c
index bae812156c4..61c02285454 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -71,7 +71,7 @@ static const char *unpack_plumbing_errors[NB_UNPACK_TREES_WARNING_TYPES] = {
? ((o)->msgs[(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
@@ -83,7 +83,6 @@ static const char *super_prefixed(const char *path)
static unsigned idx = ARRAY_SIZE(buf) - 1;
if (super_prefix_len < 0) {
- const char *super_prefix = get_super_prefix();
if (!super_prefix) {
super_prefix_len = 0;
} else {
@@ -236,7 +235,8 @@ static int add_rejected_path(struct unpack_trees_options *o,
return -1;
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
@@ -263,7 +263,8 @@ static void display_error_msgs(struct unpack_trees_options *o)
error_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -290,7 +291,8 @@ static void display_warning_msgs(struct unpack_trees_options *o)
warning_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -312,7 +314,7 @@ static int check_submodule_move_head(const struct cache_entry *ce,
if (o->reset)
flags |= SUBMODULE_MOVE_HEAD_FORCE;
- if (submodule_move_head(ce->name, old_id, new_id, flags))
+ if (submodule_move_head(ce->name, NULL, old_id, new_id, flags))
return add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
return 0;
}
@@ -415,6 +417,7 @@ static int check_updates(struct unpack_trees_options *o,
int i, pc_workers, pc_threshold;
trace_performance_enter();
+ state.super_prefix = o->super_prefix;
state.force = 1;
state.quiet = 1;
state.refresh_cache = 1;
@@ -445,7 +448,7 @@ static int check_updates(struct unpack_trees_options *o,
if (ce->ce_flags & CE_WT_REMOVE) {
display_progress(progress, ++cnt);
- unlink_entry(ce);
+ unlink_entry(ce, o->super_prefix);
}
}
@@ -2958,8 +2961,8 @@ int bind_merge(const struct cache_entry * const *src,
if (a && old)
return o->quiet ? -1 :
error(ERRORMSG(o, ERROR_BIND_OVERLAP),
- super_prefixed(a->name),
- super_prefixed(old->name));
+ super_prefixed(a->name, o->super_prefix),
+ super_prefixed(old->name, o->super_prefix));
if (!a)
return keep_entry(old, o);
else
@@ -3020,7 +3023,7 @@ int stash_worktree_untracked_merge(const struct cache_entry * const *src,
if (worktree && untracked)
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);
}
diff --git a/unpack-trees.h b/unpack-trees.h
index efb9edfbb27..9b81e284073 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -74,6 +74,7 @@ struct unpack_trees_options {
dry_run;
enum unpack_trees_reset_type reset;
const char *prefix;
+ const char *super_prefix;
int cache_bottom;
struct pathspec *pathspec;
merge_fn_t fn;
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v2 09/10] read-tree: add "--super-prefix" option, eliminate global
2022-11-14 10:08 ` [PATCH v2 09/10] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
@ 2022-11-14 22:28 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-14 22:28 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> 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>
> ---
> Documentation/git.txt | 8 +-------
> builtin.h | 4 ----
> builtin/checkout.c | 2 +-
> builtin/read-tree.c | 1 +
> cache.h | 2 --
> entry.c | 12 ++++++------
> entry.h | 6 +++++-
> environment.c | 13 -------------
> git.c | 37 +++++--------------------------------
> submodule.c | 27 +++++++++------------------
> submodule.h | 5 ++---
> t/t1001-read-tree-m-2way.sh | 2 +-
> t/t5616-partial-clone.sh | 2 +-
> unpack-trees.c | 23 +++++++++++++----------
> unpack-trees.h | 1 +
> 15 files changed, 46 insertions(+), 99 deletions(-)
>
> diff --git a/Documentation/git.txt b/Documentation/git.txt
> index 1d33e083ab8..f9a7a4554cd 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
> diff --git a/builtin.h b/builtin.h
> index 8901a34d6bf..8264b7e5241 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
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index 2a132392fbe..dc008fb45e8 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -231,7 +231,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)
> diff --git a/builtin/read-tree.c b/builtin/read-tree.c
> index f4cbe460b97..4b6f22e58c1 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),
> diff --git a/cache.h b/cache.h
> index 26ed03bd6de..a4a0377b800 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -504,7 +504,6 @@ 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"
> @@ -590,7 +589,6 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
> int get_common_dir(struct strbuf *sb, const char *gitdir);
> const char *get_git_namespace(void);
> const char *strip_namespace(const char *namespaced_ref);
> -const char *get_super_prefix(void);
> const char *get_git_work_tree(void);
>
> /*
> diff --git a/entry.c b/entry.c
> index 616e4f073c1..971ab268714 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)
> diff --git a/entry.h b/entry.h
> index 9be4659881e..2d4fbb88c8f 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);
> diff --git a/environment.c b/environment.c
> index 18d042b467d..1ee3686fd8a 100644
> --- a/environment.c
> +++ b/environment.c
> @@ -102,8 +102,6 @@ char *git_work_tree_cfg;
>
> static char *git_namespace;
>
> -static char *super_prefix;
> -
> /*
> * Repository-local GIT_* environment variables; see cache.h for details.
> */
> @@ -121,7 +119,6 @@ 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
> @@ -234,16 +231,6 @@ const char *strip_namespace(const char *namespaced_ref)
> 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;
>
> /*
> diff --git a/git.c b/git.c
> index 2bca22cfd9a..00baaf23590 100644
> --- a/git.c
> +++ b/git.c
> @@ -14,9 +14,8 @@
> * RUN_SETUP for reading from the configuration file.
> */
> #define NEED_WORK_TREE (1<<3)
> -#define SUPPORT_SUPER_PREFIX (1<<4)
> -#define DELAY_PAGER_CONFIG (1<<5)
> -#define NO_PARSEOPT (1<<6) /* parse-options is not used */
> +#define DELAY_PAGER_CONFIG (1<<4)
> +#define NO_PARSEOPT (1<<5) /* parse-options is not used */
>
> struct cmd_struct {
> const char *cmd;
> @@ -29,8 +28,7 @@ const char git_usage_string[] =
> " [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
> " [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
> " [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
> - " [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
> - " <command> [<args>]");
> + " [--config-env=<name>=<envvar>] <command> [<args>]");
>
> const char git_more_info_string[] =
> 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);
> 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;
> @@ -449,11 +433,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
> trace_repo_setup(prefix);
> 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)
> setup_work_tree();
>
> @@ -504,7 +483,7 @@ static struct cmd_struct commands[] = {
> { "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
> { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
> { "checkout--worker", cmd_checkout__worker,
> - RUN_SETUP | NEED_WORK_TREE | SUPPORT_SUPER_PREFIX },
> + RUN_SETUP | NEED_WORK_TREE },
> { "checkout-index", cmd_checkout_index,
> RUN_SETUP | NEED_WORK_TREE},
> { "cherry", cmd_cherry, RUN_SETUP },
> @@ -583,7 +562,7 @@ static struct cmd_struct commands[] = {
> { "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
> { "push", cmd_push, RUN_SETUP },
> { "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 },
> { "receive-pack", cmd_receive_pack },
> { "reflog", cmd_reflog, RUN_SETUP },
> @@ -727,9 +706,6 @@ static void execv_dashed_external(const char **argv)
> struct child_process cmd = CHILD_PROCESS_INIT;
> int status;
>
> - if (get_super_prefix())
> - die(_("%s doesn't support --super-prefix"), argv[0]);
> -
> if (use_pager == -1 && !is_builtin(argv[0]))
> use_pager = check_pager_config(argv[0]);
> commit_pager_choice();
> @@ -799,9 +775,6 @@ static int run_argv(int *argcp, const char ***argv)
> */
> trace2_cmd_name("_run_git_alias_");
>
> - if (get_super_prefix())
> - die("%s doesn't support --super-prefix", **argv);
> -
> commit_pager_choice();
>
> strvec_push(&cmd.args, "git");
> diff --git a/submodule.c b/submodule.c
> index d9fd0af81b6..5ac4e1b0568 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -2048,14 +2048,6 @@ void submodule_unset_core_worktree(const struct submodule *sub)
> 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)
> {
> struct child_process cp = CHILD_PROCESS_INIT;
> @@ -2074,7 +2066,7 @@ static int submodule_has_dirty_index(const struct submodule *sub)
> 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;
> prepare_submodule_repo_env(&cp.env);
> @@ -2083,10 +2075,10 @@ static void submodule_reset_index(const char *path)
> cp.no_stdin = 1;
> 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 */
> 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());
>
> @@ -2099,10 +2091,9 @@ static void submodule_reset_index(const char *path)
> * For edge cases (a submodule coming into existence or removing a submodule)
> * pass NULL for old or new respectively.
> */
> -int submodule_move_head(const char *path,
> - const char *old_head,
> - const char *new_head,
> - unsigned flags)
> +int submodule_move_head(const char *path, const char *super_prefix,
> + const char *old_head, const char *new_head,
> + unsigned flags)
> {
> int ret = 0;
> struct child_process cp = CHILD_PROCESS_INIT;
> @@ -2148,7 +2139,7 @@ int submodule_move_head(const char *path,
> strbuf_release(&gitdir);
>
> /* make sure the index is clean as well */
> - submodule_reset_index(path);
> + submodule_reset_index(path, NULL);
Shouldn't we be passing the super prefix? i.e.
submodule_reset_index(path, super_prefix)
> }
>
> if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
> @@ -2166,9 +2157,9 @@ int submodule_move_head(const char *path,
> cp.no_stdin = 1;
> 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_pushf(&cp.args, "--super-prefix=%s%s/",
> + (super_prefix ? super_prefix : ""), path);
>
> if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN)
> strvec_push(&cp.args, "-n");
> diff --git a/submodule.h b/submodule.h
> index e5ee13fb06a..36a7f7c5b32 100644
> --- a/submodule.h
> +++ b/submodule.h
> @@ -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_FORCE (1<<1)
> -int submodule_move_head(const char *path,
> - const char *old,
> - const char *new_head,
> +int submodule_move_head(const char *path, const char *super_prefix,
> + const char *old_head, const char *new_head,
> unsigned flags);
>
> void submodule_unset_core_worktree(const struct submodule *sub);
> diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh
> index 516a6112fdc..3fb1b0c162d 100755
> --- a/t/t1001-read-tree-m-2way.sh
> +++ b/t/t1001-read-tree-m-2way.sh
> @@ -370,7 +370,7 @@ test_expect_success 'read-tree supports the super-prefix' '
> cat <<-EOF >expect &&
> error: Updating '\''fictional/a'\'' would lose untracked files in it
> 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
> '
>
> diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
> index e56466580cf..18375bff535 100755
> --- a/t/t5616-partial-clone.sh
> +++ b/t/t5616-partial-clone.sh
> @@ -644,7 +644,7 @@ test_expect_success 'repack does not loosen promisor objects' '
> 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
> test_config_global protocol.file.allow always &&
>
> diff --git a/unpack-trees.c b/unpack-trees.c
> index bae812156c4..61c02285454 100644
> --- a/unpack-trees.c
> +++ b/unpack-trees.c
> @@ -71,7 +71,7 @@ static const char *unpack_plumbing_errors[NB_UNPACK_TREES_WARNING_TYPES] = {
> ? ((o)->msgs[(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
> @@ -83,7 +83,6 @@ static const char *super_prefixed(const char *path)
> static unsigned idx = ARRAY_SIZE(buf) - 1;
>
> if (super_prefix_len < 0) {
> - const char *super_prefix = get_super_prefix();
> if (!super_prefix) {
> super_prefix_len = 0;
> } else {
> @@ -236,7 +235,8 @@ static int add_rejected_path(struct unpack_trees_options *o,
> return -1;
>
> 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
> @@ -263,7 +263,8 @@ static void display_error_msgs(struct unpack_trees_options *o)
> error_displayed = 1;
> for (i = 0; i < rejects->nr; i++)
> 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);
> }
> string_list_clear(rejects, 0);
> @@ -290,7 +291,8 @@ static void display_warning_msgs(struct unpack_trees_options *o)
> warning_displayed = 1;
> for (i = 0; i < rejects->nr; i++)
> 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);
> }
> string_list_clear(rejects, 0);
> @@ -312,7 +314,7 @@ static int check_submodule_move_head(const struct cache_entry *ce,
> if (o->reset)
> flags |= SUBMODULE_MOVE_HEAD_FORCE;
>
> - if (submodule_move_head(ce->name, old_id, new_id, flags))
> + if (submodule_move_head(ce->name, NULL, old_id, new_id, flags))
Similarly, shouldn't this be
- submodule_move_head(ce->name, NULL, old_id, new_id, flags)
+ 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 0;
> }
> @@ -415,6 +417,7 @@ static int check_updates(struct unpack_trees_options *o,
> int i, pc_workers, pc_threshold;
>
> trace_performance_enter();
> + state.super_prefix = o->super_prefix;
> state.force = 1;
> state.quiet = 1;
> state.refresh_cache = 1;
> @@ -445,7 +448,7 @@ static int check_updates(struct unpack_trees_options *o,
>
> if (ce->ce_flags & CE_WT_REMOVE) {
> display_progress(progress, ++cnt);
> - unlink_entry(ce);
> + unlink_entry(ce, o->super_prefix);
> }
> }
>
> @@ -2958,8 +2961,8 @@ int bind_merge(const struct cache_entry * const *src,
> if (a && old)
> return o->quiet ? -1 :
> error(ERRORMSG(o, ERROR_BIND_OVERLAP),
> - super_prefixed(a->name),
> - super_prefixed(old->name));
> + super_prefixed(a->name, o->super_prefix),
> + super_prefixed(old->name, o->super_prefix));
> if (!a)
> return keep_entry(old, o);
> else
> @@ -3020,7 +3023,7 @@ int stash_worktree_untracked_merge(const struct cache_entry * const *src,
>
> if (worktree && untracked)
> 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);
> }
> diff --git a/unpack-trees.h b/unpack-trees.h
> index efb9edfbb27..9b81e284073 100644
> --- a/unpack-trees.h
> +++ b/unpack-trees.h
> @@ -74,6 +74,7 @@ struct unpack_trees_options {
> dry_run;
> enum unpack_trees_reset_type reset;
> const char *prefix;
> + const char *super_prefix;
> int cache_bottom;
> struct pathspec *pathspec;
> merge_fn_t fn;
> --
> 2.38.0.1471.ge4d8947e7aa
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v2 10/10] fetch: rename "--submodule-prefix" to "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (8 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 09/10] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
@ 2022-11-14 10:08 ` Ævar Arnfjörð Bjarmason
2022-11-14 22:31 ` Glen Choo
2022-11-14 21:59 ` [PATCH v2 00/10] Get rid of "git --super-prefix" Taylor Blau
` (3 subsequent siblings)
13 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-14 10:08 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
In preceding commits we've introduced a command-level "--super-prefix"
option, which unlike the "git --super-prefix" it replaced doesn't rely
on setenv() or getenv(), it's just a normal command-line option that
the command passes down.
Since we've done that, let's rename the "--submodule-prefix" option
added in 7dce19d374a (fetch/pull: Add the --recurse-submodules option,
2010-11-12) to "--super-prefix" for consistency. This:
* Allows us to use OPT__SUPER_PREFIX().
* Leaves an unspecified "--super-prefix" with a "NULL" value, rather
than an empty string, as is the case with the other "--super-prefix"
users. We coerce the NULL to "" in submodule.c before using it.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
Documentation/fetch-options.txt | 5 -----
builtin/fetch.c | 7 +++----
submodule.c | 23 +++++++++++------------
3 files changed, 14 insertions(+), 21 deletions(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 622bd84768b..20cbd2c2910 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -241,11 +241,6 @@ endif::git-pull[]
linkgit:git-config[1].
ifndef::git-pull[]
---submodule-prefix=<path>::
- Prepend <path> to paths printed in informative messages
- such as "Fetching submodule foo". This option is used
- internally when recursing over submodules.
-
--recurse-submodules-default=[yes|on-demand]::
This option is used internally to temporarily provide a
non-negative default value for the --recurse-submodules
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7378cafeec9..353bcd36d24 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -74,7 +74,7 @@ static struct string_list deepen_not = STRING_LIST_INIT_NODUP;
static struct strbuf default_rla = STRBUF_INIT;
static struct transport *gtransport;
static struct transport *gsecondary;
-static const char *submodule_prefix = "";
+static const char *super_prefix;
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
@@ -195,8 +195,7 @@ static struct option builtin_fetch_options[] = {
OPT_SET_INT_F(0, "refetch", &refetch,
N_("re-fetch without negotiating common commits"),
1, PARSE_OPT_NONEG),
- { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
- N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
+ OPT__SUPER_PREFIX(&super_prefix),
OPT_CALLBACK_F(0, "recurse-submodules-default",
&recurse_submodules_default, N_("on-demand"),
N_("default for recursive fetching of submodules "
@@ -2300,7 +2299,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
add_options_to_argv(&options);
result = fetch_submodules(the_repository,
&options,
- submodule_prefix,
+ super_prefix,
recurse_submodules,
recurse_submodules_default,
verbosity < 0,
diff --git a/submodule.c b/submodule.c
index 5ac4e1b0568..1e4eee3492b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1376,7 +1376,7 @@ struct submodule_parallel_fetch {
int changed_count;
struct strvec args;
struct repository *r;
- const char *prefix;
+ const char *super_prefix;
int command_line_option;
int default_option;
int quiet;
@@ -1567,7 +1567,7 @@ get_fetch_task_from_index(struct submodule_parallel_fetch *spf,
if (task->repo) {
if (!spf->quiet)
strbuf_addf(err, _("Fetching submodule %s%s\n"),
- spf->prefix, ce->name);
+ spf->super_prefix, ce->name);
spf->index_count++;
return task;
@@ -1629,7 +1629,7 @@ get_fetch_task_from_changed(struct submodule_parallel_fetch *spf,
if (!spf->quiet)
strbuf_addf(err,
_("Fetching submodule %s%s at commit %s\n"),
- spf->prefix, task->sub->path,
+ spf->super_prefix, task->sub->path,
find_unique_abbrev(cs_data->super_oid,
DEFAULT_ABBREV));
@@ -1687,11 +1687,10 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
strvec_pushv(&cp->args, task->git_args.v);
strvec_pushv(&cp->args, spf->args.v);
strvec_push(&cp->args, task->default_argv);
- strvec_push(&cp->args, "--submodule-prefix");
+ strvec_push(&cp->args, "--super-prefix");
- strbuf_addf(&submodule_prefix, "%s%s/",
- spf->prefix,
- task->sub->path);
+ strbuf_addf(&submodule_prefix, "%s%s/", spf->super_prefix,
+ task->sub->path);
strvec_push(&cp->args, submodule_prefix.buf);
*task_cb = task;
@@ -1707,7 +1706,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
spf->oid_fetch_tasks_nr--;
strbuf_addf(&submodule_prefix, "%s%s/",
- spf->prefix, task->sub->path);
+ spf->super_prefix, task->sub->path);
child_process_init(cp);
prepare_submodule_repo_env_in_gitdir(&cp->env);
@@ -1717,7 +1716,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
strvec_init(&cp->args);
strvec_pushv(&cp->args, spf->args.v);
strvec_push(&cp->args, "on-demand");
- strvec_push(&cp->args, "--submodule-prefix");
+ strvec_push(&cp->args, "--super-prefix");
strvec_push(&cp->args, submodule_prefix.buf);
/* NEEDSWORK: have get_default_remote from submodule--helper */
@@ -1813,7 +1812,7 @@ static int fetch_finish(int retvalue, struct strbuf *err,
int fetch_submodules(struct repository *r,
const struct strvec *options,
- const char *prefix, int command_line_option,
+ const char *super_prefix, int command_line_option,
int default_option,
int quiet, int max_parallel_jobs)
{
@@ -1835,7 +1834,7 @@ int fetch_submodules(struct repository *r,
spf.command_line_option = command_line_option;
spf.default_option = default_option;
spf.quiet = quiet;
- spf.prefix = prefix;
+ spf.super_prefix = super_prefix ? super_prefix : "";
if (!r->worktree)
goto out;
@@ -1847,7 +1846,7 @@ int fetch_submodules(struct repository *r,
for (i = 0; i < options->nr; i++)
strvec_push(&spf.args, options->v[i]);
strvec_push(&spf.args, "--recurse-submodules-default");
- /* default value, "--submodule-prefix" and its value are added later */
+ /* default value, "--super-prefix" and its value are added later */
calculate_changed_submodule_paths(r, &spf.changed_submodule_names);
string_list_sort(&spf.changed_submodule_names);
--
2.38.0.1471.ge4d8947e7aa
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v2 10/10] fetch: rename "--submodule-prefix" to "--super-prefix"
2022-11-14 10:08 ` [PATCH v2 10/10] fetch: rename "--submodule-prefix" to "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-11-14 22:31 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-14 22:31 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Thanks for picking this up, especially since you feel "meh" about it :)
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> In preceding commits we've introduced a command-level "--super-prefix"
> option, which unlike the "git --super-prefix" it replaced doesn't rely
> on setenv() or getenv(), it's just a normal command-line option that
> the command passes down.
>
> Since we've done that, let's rename the "--submodule-prefix" option
> added in 7dce19d374a (fetch/pull: Add the --recurse-submodules option,
> 2010-11-12) to "--super-prefix" for consistency. This:
>
> * Allows us to use OPT__SUPER_PREFIX().
> * Leaves an unspecified "--super-prefix" with a "NULL" value, rather
> than an empty string, as is the case with the other "--super-prefix"
> users. We coerce the NULL to "" in submodule.c before using it.
[...]
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> Documentation/fetch-options.txt | 5 -----
> builtin/fetch.c | 7 +++----
> submodule.c | 23 +++++++++++------------
> 3 files changed, 14 insertions(+), 21 deletions(-)
>
> diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
> index 622bd84768b..20cbd2c2910 100644
> --- a/Documentation/fetch-options.txt
> +++ b/Documentation/fetch-options.txt
> @@ -241,11 +241,6 @@ endif::git-pull[]
> linkgit:git-config[1].
>
> ifndef::git-pull[]
> ---submodule-prefix=<path>::
> - Prepend <path> to paths printed in informative messages
> - such as "Fetching submodule foo". This option is used
> - internally when recursing over submodules.
> -
> --recurse-submodules-default=[yes|on-demand]::
> This option is used internally to temporarily provide a
> non-negative default value for the --recurse-submodules
> diff --git a/builtin/fetch.c b/builtin/fetch.c
> index 7378cafeec9..353bcd36d24 100644
> --- a/builtin/fetch.c
> +++ b/builtin/fetch.c
> @@ -74,7 +74,7 @@ static struct string_list deepen_not = STRING_LIST_INIT_NODUP;
> static struct strbuf default_rla = STRBUF_INIT;
> static struct transport *gtransport;
> static struct transport *gsecondary;
> -static const char *submodule_prefix = "";
> +static const char *super_prefix;
Is there a reason we can't keep the '= ""'?
> static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
> static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
> static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
> @@ -195,8 +195,7 @@ static struct option builtin_fetch_options[] = {
> OPT_SET_INT_F(0, "refetch", &refetch,
> N_("re-fetch without negotiating common commits"),
> 1, PARSE_OPT_NONEG),
> - { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
> - N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
> + OPT__SUPER_PREFIX(&super_prefix),
> OPT_CALLBACK_F(0, "recurse-submodules-default",
> &recurse_submodules_default, N_("on-demand"),
> N_("default for recursive fetching of submodules "
> @@ -2300,7 +2299,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
> add_options_to_argv(&options);
> result = fetch_submodules(the_repository,
> &options,
> - submodule_prefix,
> + super_prefix,
> recurse_submodules,
> recurse_submodules_default,
> verbosity < 0,
> diff --git a/submodule.c b/submodule.c
> index 5ac4e1b0568..1e4eee3492b 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1376,7 +1376,7 @@ struct submodule_parallel_fetch {
> int changed_count;
> struct strvec args;
> struct repository *r;
> - const char *prefix;
> + const char *super_prefix;
> int command_line_option;
> int default_option;
> int quiet;
> @@ -1567,7 +1567,7 @@ get_fetch_task_from_index(struct submodule_parallel_fetch *spf,
> if (task->repo) {
> if (!spf->quiet)
> strbuf_addf(err, _("Fetching submodule %s%s\n"),
> - spf->prefix, ce->name);
> + spf->super_prefix, ce->name);
>
> spf->index_count++;
> return task;
> @@ -1629,7 +1629,7 @@ get_fetch_task_from_changed(struct submodule_parallel_fetch *spf,
> if (!spf->quiet)
> strbuf_addf(err,
> _("Fetching submodule %s%s at commit %s\n"),
> - spf->prefix, task->sub->path,
> + spf->super_prefix, task->sub->path,
> find_unique_abbrev(cs_data->super_oid,
> DEFAULT_ABBREV));
>
> @@ -1687,11 +1687,10 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
> strvec_pushv(&cp->args, task->git_args.v);
> strvec_pushv(&cp->args, spf->args.v);
> strvec_push(&cp->args, task->default_argv);
> - strvec_push(&cp->args, "--submodule-prefix");
> + strvec_push(&cp->args, "--super-prefix");
>
> - strbuf_addf(&submodule_prefix, "%s%s/",
> - spf->prefix,
> - task->sub->path);
> + strbuf_addf(&submodule_prefix, "%s%s/", spf->super_prefix,
> + task->sub->path);
> strvec_push(&cp->args, submodule_prefix.buf);
> *task_cb = task;
>
> @@ -1707,7 +1706,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
> spf->oid_fetch_tasks_nr--;
>
> strbuf_addf(&submodule_prefix, "%s%s/",
> - spf->prefix, task->sub->path);
> + spf->super_prefix, task->sub->path);
>
> child_process_init(cp);
> prepare_submodule_repo_env_in_gitdir(&cp->env);
> @@ -1717,7 +1716,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
> strvec_init(&cp->args);
> strvec_pushv(&cp->args, spf->args.v);
> strvec_push(&cp->args, "on-demand");
> - strvec_push(&cp->args, "--submodule-prefix");
> + strvec_push(&cp->args, "--super-prefix");
> strvec_push(&cp->args, submodule_prefix.buf);
>
> /* NEEDSWORK: have get_default_remote from submodule--helper */
> @@ -1813,7 +1812,7 @@ static int fetch_finish(int retvalue, struct strbuf *err,
>
> int fetch_submodules(struct repository *r,
> const struct strvec *options,
> - const char *prefix, int command_line_option,
> + const char *super_prefix, int command_line_option,
> int default_option,
> int quiet, int max_parallel_jobs)
> {
> @@ -1835,7 +1834,7 @@ int fetch_submodules(struct repository *r,
> spf.command_line_option = command_line_option;
> spf.default_option = default_option;
> spf.quiet = quiet;
> - spf.prefix = prefix;
> + spf.super_prefix = super_prefix ? super_prefix : "";
>
> if (!r->worktree)
> goto out;
> @@ -1847,7 +1846,7 @@ int fetch_submodules(struct repository *r,
> for (i = 0; i < options->nr; i++)
> strvec_push(&spf.args, options->v[i]);
> strvec_push(&spf.args, "--recurse-submodules-default");
> - /* default value, "--submodule-prefix" and its value are added later */
> + /* default value, "--super-prefix" and its value are added later */
>
> calculate_changed_submodule_paths(r, &spf.changed_submodule_names);
> string_list_sort(&spf.changed_submodule_names);
> --
> 2.38.0.1471.ge4d8947e7aa
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 00/10] Get rid of "git --super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (9 preceding siblings ...)
2022-11-14 10:08 ` [PATCH v2 10/10] fetch: rename "--submodule-prefix" to "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-11-14 21:59 ` Taylor Blau
2022-11-14 23:20 ` Glen Choo
` (2 subsequent siblings)
13 siblings, 0 replies; 105+ messages in thread
From: Taylor Blau @ 2022-11-14 21:59 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason
Cc: git, Glen Choo, Taylor Blau, Robert Coup
On Mon, Nov 14, 2022 at 11:08:40AM +0100, Ævar Arnfjörð Bjarmason wrote:
> = Relation to other submissions
>
> This is a non-RFC version of my earlier RFC to get rid of
> "--super-prefix"[1], which itself was an alternate proposal to Glen's
> [2]. Per [3] he's agreed to go with this approach.
Thanks for working it out together, and for a clear summary of how this
series interacts with and depends on others in-flight.
Thanks,
Taylor
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 00/10] Get rid of "git --super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (10 preceding siblings ...)
2022-11-14 21:59 ` [PATCH v2 00/10] Get rid of "git --super-prefix" Taylor Blau
@ 2022-11-14 23:20 ` Glen Choo
2022-11-14 23:39 ` Glen Choo
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
13 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-14 23:20 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Thanks for taking this forward as a non-RFC (and sorry for the
coordinating confusion last week). I'm really happy to see this go
forward.
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> = Summary
>
> What's "--super-prefix"? The "git" command takes an "internal use
> only" "--super-prefix" option, which is used to inform processes
> invoked in submodules what the path prefix to the invoking
> superproject is.
>
> This is so so that e.g. "git submodule absorbgitdirs" can report
> "sub-1/sub-2", instead of "sub-2" when being invoked in the "sub-1"
> submodule.
>
> For this the "--super-prefix" facility has been doing a
> setenv("GIT_INTERNAL_SUPER_PREFIX", "sub-1/") as soon as it got the
> "--supre-prefix=sub-1/". We'd then pass that along via the environment
> when invoking the sub-process.
>
> As this series shows we don't need such a hands-off global facility to
> do this, we can instead just pass the relevant context directly in
> each command. E.g. "git submodule absorbgitdirs" can pass the path to
> the "git submodule absorbgitdirs" sub-process it's about to invoke.
>
To play devil's advocate, we don't need it now, but one could argue that
we'll need it in the future, and having some global facility for this
would continue to be helpful. In [1], I mentioned that it is "helpful"
in this way, but that this "helpfulness" is a trap, because we want to
be moving more things in-process anyway (and we're making pretty good
strides in that direction), and adding more global state makes it harder
to reason about who should own the variables when we libify the
internals (do we move the state into per-process struct?
the_repository? something else?)
In addition, you also mentioned earlier in the [1] thread that this
global state also makes it possible accidentally affect commands we
didn't mean to, and having less global state makes behavior easier to
reason about.
So I think the argument I find most convincing isn't just "We don't need
it now.", but also "Global state is the wrong way to do this, so let's
stop.".
[1] https://lore.kernel.org/git/kl6l5yfm2taf.fsf@chooglen-macbookpro.roam.corp.google.com
> It's also proposing to replace Glen's one-patch[6], which is working
> around the problem shown in the test added in 1/10 here. Per
> downthread of [7] I think Glen was aiming for getting a more narrow
> fix in case we split off 9/10 here into some later fix.
>
> As we're fixing an edge case in something that's always been broken
> (and thus wouldn't backport) I think it's better to just fix the
> problem directly, rather than introducing new "--super-prefix" use,
> just to take it away later.
(I'll share my thoughts on this on another email).
> = Changes since the RFC
>
> * Added Glen's "git fetch" test as a 1/10, with an updated commit message
> * Updated 2/10's commit message for the non-RFC, and adjusted and
> incorporated a variant of Glen's fsmonitor test change.
> * 9/10: Correctly re-arrange bitfield define's when removing one, make
> the test added in 1/10 pass.
>
> * 10/10: New commit to make "git fetch" use our own "--super-prefix"
> instead of its "--submodule-prefix", which makes it consistent with
> the other command-level "--super-prefix" introduced here.
>
> Personally I'm rather "meh" on this. It's not actually needed by the
> main body of the series, but Glen seems to prefer it in[9], and
> doing it is easy enough.
>
> That change is a pure refactoring clean-up for consistency. The only
> reason it's 10/10 and not 1/10 is because it uses the
> "OPT__SUPER_PREFIX()" introduced in 2/10.
Thanks for this, I really appreciate it :)
> = CI & fetch URL
>
> Passing at: https://github.com/avar/git/tree/avar/nuke-global-super-prefix-use-local-2
>
> 1. https://lore.kernel.org/git/RFC-cover-0.8-00000000000-20221109T192315Z-avarab@gmail.com/
> 2. https://lore.kernel.org/git/20221109004708.97668-1-chooglen@google.com/
> 3. https://lore.kernel.org/git/kl6l5yfm2taf.fsf@chooglen-macbookpro.roam.corp.google.com/
> 4. c0c4f4d1c33 (Merge branch 'ab/submodule-helper-prep-only' into next, 2022-11-08)
> 5. https://lore.kernel.org/git/patch-1.1-34b54fdd9bb-20221109T020347Z-avarab@gmail.com/
> 6. https://lore.kernel.org/git/pull.1378.git.git.1668210935360.gitgitgadget@gmail.com/
> 7. https://lore.kernel.org/git/221111.86fsepmbhe.gmgdl@evledraar.gmail.com/
> 8. https://lore.kernel.org/git/20221109004708.97668-3-chooglen@google.com/
> 9. https://lore.kernel.org/git/kl6lsfip0yfx.fsf@chooglen-macbookpro.roam.corp.google.com/
>
> Glen Choo (1):
> read-tree + fetch tests: test failing "--super-prefix" interaction
>
> Ævar Arnfjörð Bjarmason (9):
> submodule--helper: don't use global --super-prefix in "absorbgitdirs"
> submodule--helper: "deinit" has never used "--super-prefix"
> submodule--helper: convert "foreach" to its own "--super-prefix"
> submodule--helper: convert "sync" to its own "--super-prefix"
> submodule--helper: convert "status" to its own "--super-prefix"
> submodule--helper: convert "{update,clone}" to their own
> "--super-prefix"
> submodule tests: test "git branch -t" output and stderr
> read-tree: add "--super-prefix" option, eliminate global
> fetch: rename "--submodule-prefix" to "--super-prefix"
>
> Documentation/fetch-options.txt | 5 --
> Documentation/git.txt | 8 +--
> builtin.h | 4 --
> builtin/checkout.c | 2 +-
> builtin/fetch.c | 7 +--
> builtin/read-tree.c | 1 +
> builtin/submodule--helper.c | 95 ++++++++++++++++++--------------
> cache.h | 2 -
> entry.c | 12 ++--
> entry.h | 6 +-
> environment.c | 13 -----
> git.c | 41 +++-----------
> parse-options.h | 4 ++
> submodule.c | 70 +++++++++++------------
> submodule.h | 12 ++--
> t/lib-submodule-update.sh | 98 ++++++++++++++++++---------------
> t/t1001-read-tree-m-2way.sh | 2 +-
> t/t5616-partial-clone.sh | 43 +++++++++++++++
> t/t7527-builtin-fsmonitor.sh | 33 +++--------
> unpack-trees.c | 23 ++++----
> unpack-trees.h | 1 +
> 21 files changed, 244 insertions(+), 238 deletions(-)
>
> Range-diff against v1:
> -: ----------- > 1: 1114a4ff666 read-tree + fetch tests: test failing "--super-prefix" interaction
> 1: ad0356b596f ! 2: 5a35f7b75b3 submodule--helper: don't use global --super-prefix in "absorbgitdirs"
> @@ Commit message
> declare "fsmonitor--daemon" as accepting it too, even though it
> doesn't care about it.
>
> - There's a parallel proposal to remove "--super-prefix" as an option to
> - "git" in [3], and some of the approach might be the easiest route in
> - some cases.
> -
> 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
> @@ Commit message
> stone makes such an eventual change easier, as we'll need to deal with
> less global state at that point.
>
> + The "fsmonitor--daemon" test adjusted here was added in [3]. The
> + comment added in that commit has been out-of-date from the beginning,
> + and the "have_t2_error_event()" was being overly specific in testing
> + for a bug that we *don't* have. Let's instead test for the stdout and
> + stderr that we *do have*.
> +
> 1. 74866d75793 (git: make super-prefix option, 2016-10-07)
> 2. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
> 2022-05-26)
> - 3. https://lore.kernel.org/git/20221109004708.97668-1-chooglen@google.com/
> + 3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
> + 2022-05-26)
>
> + Signed-off-by: Glen Choo <chooglen@google.com>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>
> ## builtin/submodule--helper.c ##
> @@ submodule.h: void submodule_unset_core_worktree(const struct submodule *sub);
>
> /*
> * Return the absolute path of the working tree of the superproject, which this
> +
> + ## t/t7527-builtin-fsmonitor.sh ##
> +@@ t/t7527-builtin-fsmonitor.sh: test_expect_success 'submodule always visited' '
> + # the submodule, and someone does a `git submodule absorbgitdirs`
> + # in the super, Git will recursively invoke `git submodule--helper`
> + # to do the work and this may try to read the index. This will
> +-# try to start the daemon in the submodule *and* pass (either
> +-# directly or via inheritance) the `--super-prefix` arg to the
> +-# `git fsmonitor--daemon start` command inside the submodule.
> +-# This causes a warning because fsmonitor--daemon does take that
> +-# global arg (see the table in git.c)
> +-#
> +-# This causes a warning when trying to start the daemon that is
> +-# somewhat confusing. It does not seem to hurt anything because
> +-# the fsmonitor code maps the query failure into a trivial response
> +-# and does the work anyway.
> +-#
> +-# It would be nice to silence the warning, however.
> +-
> +-have_t2_error_event () {
> +- log=$1
> +- msg="fsmonitor--daemon doesnQt support --super-prefix" &&
> +-
> +- tr '\047' Q <$1 | grep -e "$msg"
> +-}
> ++# try to start the daemon in the submodule.
> +
> + test_expect_success "stray submodule super-prefix warning" '
> + test_when_finished "rm -rf super; \
> +- rm -rf sub; \
> +- rm super-sub.trace" &&
> ++ rm -rf sub" &&
> +
> + create_super super &&
> + create_sub sub &&
> +@@ t/t7527-builtin-fsmonitor.sh: test_expect_success "stray submodule super-prefix warning" '
> +
> + test_path_is_dir super/dir_1/dir_2/sub/.git &&
> +
> +- GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
> +- git -C super submodule absorbgitdirs &&
> +-
> +- ! have_t2_error_event super-sub.trace
> ++ cat >expect <<-\EOF &&
> ++ Migrating git directory of '\''dir_1/dir_2/sub'\'' from '\''dir_1/dir_2/sub/.git'\'' to '\''.git/modules/dir_1/dir_2/sub'\''
> ++ EOF
> ++ git -C super submodule absorbgitdirs >out 2>actual &&
> ++ test_cmp expect actual &&
> ++ test_must_be_empty out
> + '
> +
> + # On a case-insensitive file system, confirm that the daemon
> 2: 87a780eb9bf = 3: a7a1f9487dc submodule--helper: "deinit" has never used "--super-prefix"
> 3: 4858e2ad0ed = 4: 935d8070834 submodule--helper: convert "foreach" to its own "--super-prefix"
> 4: 5ffe4407e46 = 5: 933c752513d submodule--helper: convert "sync" to its own "--super-prefix"
> 5: a46540b63c2 = 6: 67273f729e0 submodule--helper: convert "status" to its own "--super-prefix"
> 6: 78ebf0e2abf = 7: eaa73f5b1e4 submodule--helper: convert "{update,clone}" to their own "--super-prefix"
> 7: 00a9e789be7 = 8: 172b5865811 submodule tests: test "git branch -t" output and stderr
> 8: 3ba894a6698 ! 9: 9fdeab60773 read-tree: add "--super-prefix" option, eliminate global
> @@ git.c
> */
> #define NEED_WORK_TREE (1<<3)
> -#define SUPPORT_SUPER_PREFIX (1<<4)
> - #define DELAY_PAGER_CONFIG (1<<5)
> - #define NO_PARSEOPT (1<<6) /* parse-options is not used */
> +-#define DELAY_PAGER_CONFIG (1<<5)
> +-#define NO_PARSEOPT (1<<6) /* parse-options is not used */
> ++#define DELAY_PAGER_CONFIG (1<<4)
> ++#define NO_PARSEOPT (1<<5) /* parse-options is not used */
>
> + struct cmd_struct {
> + const char *cmd;
> @@ git.c: const char git_usage_string[] =
> " [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
> " [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
> @@ t/t1001-read-tree-m-2way.sh: test_expect_success 'read-tree supports the super-p
> '
>
>
> + ## t/t5616-partial-clone.sh ##
> +@@ t/t5616-partial-clone.sh: test_expect_success 'repack does not loosen promisor objects' '
> + 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
> + test_config_global protocol.file.allow always &&
> +
> +
> ## unpack-trees.c ##
> @@ unpack-trees.c: static const char *unpack_plumbing_errors[NB_UNPACK_TREES_WARNING_TYPES] = {
> ? ((o)->msgs[(type)]) \
> -: ----------- > 10: 100ba36dfb7 fetch: rename "--submodule-prefix" to "--super-prefix"
> --
> 2.38.0.1471.ge4d8947e7aa
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 00/10] Get rid of "git --super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (11 preceding siblings ...)
2022-11-14 23:20 ` Glen Choo
@ 2022-11-14 23:39 ` Glen Choo
2022-11-15 1:27 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
13 siblings, 1 reply; 105+ messages in thread
From: Glen Choo @ 2022-11-14 23:39 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git, Taylor Blau
Cc: Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> It's also proposing to replace Glen's one-patch[6], which is working
> around the problem shown in the test added in 1/10 here. Per
> downthread of [7] I think Glen was aiming for getting a more narrow
> fix in case we split off 9/10 here into some later fix.
>
> As we're fixing an edge case in something that's always been broken
> (and thus wouldn't backport) I think it's better to just fix the
> problem directly, rather than introducing new "--super-prefix" use,
> just to take it away later.
I still prefer that we take the one-patch to unbreak new releases,
because partial clone + submodules is absolutely broken (e.g. it's
already causing quite a lot of headaches at $DAYJOB) and the patch is
obviously harmless.
And more importantly, it lets us take our time with this series and get
it right without time pressure. It's not as pressing as, e.g. a
regression fix, but it does render certain Git setups unusable.
With regards to urgency and when to choose "small and harmless fixes vs
bigger and better fixes", I think Junio has generally made those calls
in the past. @Taylor if you have an opinion, I'd love to hear it.
> 6. https://lore.kernel.org/git/pull.1378.git.git.1668210935360.gitgitgadget@gmail.com/
> 7. https://lore.kernel.org/git/221111.86fsepmbhe.gmgdl@evledraar.gmail.com/
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 00/10] Get rid of "git --super-prefix"
2022-11-14 23:39 ` Glen Choo
@ 2022-11-15 1:27 ` Ævar Arnfjörð Bjarmason
2022-11-16 21:07 ` Glen Choo
0 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-15 1:27 UTC (permalink / raw)
To: Glen Choo; +Cc: git, Taylor Blau, Robert Coup
On Mon, Nov 14 2022, Glen Choo wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> It's also proposing to replace Glen's one-patch[6], which is working
>> around the problem shown in the test added in 1/10 here. Per
>> downthread of [7] I think Glen was aiming for getting a more narrow
>> fix in case we split off 9/10 here into some later fix.
>>
>> As we're fixing an edge case in something that's always been broken
>> (and thus wouldn't backport) I think it's better to just fix the
>> problem directly, rather than introducing new "--super-prefix" use,
>> just to take it away later.
>
> I still prefer that we take the one-patch to unbreak new releases,
> because partial clone + submodules is absolutely broken (e.g. it's
> already causing quite a lot of headaches at $DAYJOB) and the patch is
> obviously harmless.
>
> And more importantly, it lets us take our time with this series and get
> it right without time pressure. It's not as pressing as, e.g. a
> regression fix, but it does render certain Git setups unusable.
>
> With regards to urgency and when to choose "small and harmless fixes vs
> bigger and better fixes", I think Junio has generally made those calls
> in the past. @Taylor if you have an opinion, I'd love to hear it.
I feel like I'm missing something here. What's the regression? The test
you're adding here didn't work at all until 0f5e8851737 (Merge branch
'rc/fetch-refetch', 2022-04-04), as the command didn't exist yet. That
commit went out with v2.36.0.
If it never worked there's no regression, and we wouldn't be merging
down a fix for older point-releases.
Or is there some case I've missed here which did work before, doesn't
now, but just isn't captured in this test? If so what case is that, and
when did it break?
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 00/10] Get rid of "git --super-prefix"
2022-11-15 1:27 ` Ævar Arnfjörð Bjarmason
@ 2022-11-16 21:07 ` Glen Choo
2022-11-17 18:07 ` Ævar Arnfjörð Bjarmason
0 siblings, 1 reply; 105+ messages in thread
From: Glen Choo @ 2022-11-16 21:07 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git, Taylor Blau, Robert Coup
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> On Mon, Nov 14 2022, Glen Choo wrote:
>
>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>>
>>> It's also proposing to replace Glen's one-patch[6], which is working
>>> around the problem shown in the test added in 1/10 here. Per
>>> downthread of [7] I think Glen was aiming for getting a more narrow
>>> fix in case we split off 9/10 here into some later fix.
>>>
>>> As we're fixing an edge case in something that's always been broken
>>> (and thus wouldn't backport) I think it's better to just fix the
>>> problem directly, rather than introducing new "--super-prefix" use,
>>> just to take it away later.
>>
>> I still prefer that we take the one-patch to unbreak new releases,
>> because partial clone + submodules is absolutely broken (e.g. it's
>> already causing quite a lot of headaches at $DAYJOB) and the patch is
>> obviously harmless.
>>
>> And more importantly, it lets us take our time with this series and get
>> it right without time pressure. It's not as pressing as, e.g. a
>> regression fix, but it does render certain Git setups unusable.
>>
>> With regards to urgency and when to choose "small and harmless fixes vs
>> bigger and better fixes", I think Junio has generally made those calls
>> in the past. @Taylor if you have an opinion, I'd love to hear it.
>
> I feel like I'm missing something here. What's the regression? The test
> you're adding here didn't work at all until 0f5e8851737 (Merge branch
> 'rc/fetch-refetch', 2022-04-04), as the command didn't exist yet. That
> commit went out with v2.36.0.
>
> If it never worked there's no regression, and we wouldn't be merging
> down a fix for older point-releases.
>
> Or is there some case I've missed here which did work before, doesn't
> now, but just isn't captured in this test? If so what case is that, and
> when did it break?
Right, this wasn't meant to be a regression fix at all. There's good
reason to believe that this was always broken, so I never went digging
to see if it ever worked.
Even so, it doesn't change the fact that it's a use case that we've
expected to work, but doesn't due to some internal silliness, and that
we could fix it without invoking questions of the "--super-prefix"
design and dragging out the process (which is admittedly what I should
have done in the first place). Since we have such an easy fix in front
of us, I don't feel good about not fixing this before the next release.
At any rate, I'm wiling to accept that I'm being overly cautious,
because it's quite likely that this series will make it into the next
release. (We could technically we unbreak 'next', though I don't know
who distributes that other than internally @ Google.) I'm ok to drop my
patch for now, but I'll revive it if it starts to look like this series
won't make it into the next release.
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 00/10] Get rid of "git --super-prefix"
2022-11-16 21:07 ` Glen Choo
@ 2022-11-17 18:07 ` Ævar Arnfjörð Bjarmason
2022-11-21 19:16 ` Glen Choo
0 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-17 18:07 UTC (permalink / raw)
To: Glen Choo; +Cc: git, Taylor Blau, Robert Coup
On Wed, Nov 16 2022, Glen Choo wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> On Mon, Nov 14 2022, Glen Choo wrote:
>>
>>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>>>
>>>> It's also proposing to replace Glen's one-patch[6], which is working
>>>> around the problem shown in the test added in 1/10 here. Per
>>>> downthread of [7] I think Glen was aiming for getting a more narrow
>>>> fix in case we split off 9/10 here into some later fix.
>>>>
>>>> As we're fixing an edge case in something that's always been broken
>>>> (and thus wouldn't backport) I think it's better to just fix the
>>>> problem directly, rather than introducing new "--super-prefix" use,
>>>> just to take it away later.
>>>
>>> I still prefer that we take the one-patch to unbreak new releases,
>>> because partial clone + submodules is absolutely broken (e.g. it's
>>> already causing quite a lot of headaches at $DAYJOB) and the patch is
>>> obviously harmless.
>>>
>>> And more importantly, it lets us take our time with this series and get
>>> it right without time pressure. It's not as pressing as, e.g. a
>>> regression fix, but it does render certain Git setups unusable.
>>>
>>> With regards to urgency and when to choose "small and harmless fixes vs
>>> bigger and better fixes", I think Junio has generally made those calls
>>> in the past. @Taylor if you have an opinion, I'd love to hear it.
>>
>> I feel like I'm missing something here. What's the regression? The test
>> you're adding here didn't work at all until 0f5e8851737 (Merge branch
>> 'rc/fetch-refetch', 2022-04-04), as the command didn't exist yet. That
>> commit went out with v2.36.0.
>>
>> If it never worked there's no regression, and we wouldn't be merging
>> down a fix for older point-releases.
>>
>> Or is there some case I've missed here which did work before, doesn't
>> now, but just isn't captured in this test? If so what case is that, and
>> when did it break?
>
> Right, this wasn't meant to be a regression fix at all. There's good
> reason to believe that this was always broken, so I never went digging
> to see if it ever worked.
>
> Even so, it doesn't change the fact that it's a use case that we've
> expected to work, but doesn't due to some internal silliness, and that
> we could fix it without invoking questions of the "--super-prefix"
> design and dragging out the process (which is admittedly what I should
> have done in the first place). Since we have such an easy fix in front
> of us, I don't feel good about not fixing this before the next release.
>
> At any rate, I'm wiling to accept that I'm being overly cautious,
> because it's quite likely that this series will make it into the next
> release. (We could technically we unbreak 'next', though I don't know
> who distributes that other than internally @ Google.) I'm ok to drop my
> patch for now, but I'll revive it if it starts to look like this series
> won't make it into the next release.
Understood, I'm re-rolling this v2, will send it out soon.
I'll keep that patch out for now, but if we're starting to run up
against the next release how about we split it out? So it'll depend on
how fast we can review & test this, and if/when Taylor is OK with
merging it down.
I really don't care if the fix comes first, but just thought I was
missing something and it didn't seem urgent, as it was in the "never
worked" and not "a regression" category AFAICT. But if you'd still like
it shout, and I'll just stack it at the start...
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v2 00/10] Get rid of "git --super-prefix"
2022-11-17 18:07 ` Ævar Arnfjörð Bjarmason
@ 2022-11-21 19:16 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-21 19:16 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git, Taylor Blau, Robert Coup
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> On Wed, Nov 16 2022, Glen Choo wrote:
>
>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>>
>>> On Mon, Nov 14 2022, Glen Choo wrote:
>>>
>>>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>>>>
>>>>> It's also proposing to replace Glen's one-patch[6], which is working
>>>>> around the problem shown in the test added in 1/10 here. Per
>>>>> downthread of [7] I think Glen was aiming for getting a more narrow
>>>>> fix in case we split off 9/10 here into some later fix.
>>>>>
>>>>> As we're fixing an edge case in something that's always been broken
>>>>> (and thus wouldn't backport) I think it's better to just fix the
>>>>> problem directly, rather than introducing new "--super-prefix" use,
>>>>> just to take it away later.
>>>>
>>>> I still prefer that we take the one-patch to unbreak new releases,
>>>> because partial clone + submodules is absolutely broken (e.g. it's
>>>> already causing quite a lot of headaches at $DAYJOB) and the patch is
>>>> obviously harmless.
>>>>
>>>> And more importantly, it lets us take our time with this series and get
>>>> it right without time pressure. It's not as pressing as, e.g. a
>>>> regression fix, but it does render certain Git setups unusable.
>>>>
>>>> With regards to urgency and when to choose "small and harmless fixes vs
>>>> bigger and better fixes", I think Junio has generally made those calls
>>>> in the past. @Taylor if you have an opinion, I'd love to hear it.
>>>
>>> I feel like I'm missing something here. What's the regression? The test
>>> you're adding here didn't work at all until 0f5e8851737 (Merge branch
>>> 'rc/fetch-refetch', 2022-04-04), as the command didn't exist yet. That
>>> commit went out with v2.36.0.
>>>
>>> If it never worked there's no regression, and we wouldn't be merging
>>> down a fix for older point-releases.
>>>
>>> Or is there some case I've missed here which did work before, doesn't
>>> now, but just isn't captured in this test? If so what case is that, and
>>> when did it break?
>>
>> Right, this wasn't meant to be a regression fix at all. There's good
>> reason to believe that this was always broken, so I never went digging
>> to see if it ever worked.
>>
>> Even so, it doesn't change the fact that it's a use case that we've
>> expected to work, but doesn't due to some internal silliness, and that
>> we could fix it without invoking questions of the "--super-prefix"
>> design and dragging out the process (which is admittedly what I should
>> have done in the first place). Since we have such an easy fix in front
>> of us, I don't feel good about not fixing this before the next release.
>>
>> At any rate, I'm wiling to accept that I'm being overly cautious,
>> because it's quite likely that this series will make it into the next
>> release. (We could technically we unbreak 'next', though I don't know
>> who distributes that other than internally @ Google.) I'm ok to drop my
>> patch for now, but I'll revive it if it starts to look like this series
>> won't make it into the next release.
>
> Understood, I'm re-rolling this v2, will send it out soon.
>
> I'll keep that patch out for now, but if we're starting to run up
> against the next release how about we split it out? So it'll depend on
> how fast we can review & test this, and if/when Taylor is OK with
> merging it down.
>
> I really don't care if the fix comes first, but just thought I was
> missing something and it didn't seem urgent, as it was in the "never
> worked" and not "a regression" category AFAICT. But if you'd still like
> it shout, and I'll just stack it at the start...
That sounds good, thanks :) That's very helpful of you, and I appreciate
you making the way forward clear.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v3 0/9] Get rid of "git --super-prefix"
2022-11-14 10:08 ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
` (12 preceding siblings ...)
2022-11-14 23:39 ` Glen Choo
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 1/9] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
` (10 more replies)
13 siblings, 11 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
= Summary
What's "--super-prefix"? The "git" command takes an "internal use
only" "--super-prefix" option, which is used to inform processes
invoked in submodules what the path prefix to the invoking
superproject is.
This is so so that e.g. "git submodule absorbgitdirs" can report
"sub-1/sub-2", instead of "sub-2" when being invoked in the "sub-1"
submodule.
For this the "--super-prefix" facility has been doing a
setenv("GIT_INTERNAL_SUPER_PREFIX", "sub-1/") as soon as it got the
"--supre-prefix=sub-1/". We'd then pass that along via the environment
when invoking the sub-process.
As this series shows we don't need such a hands-off global facility to
do this, we can instead just pass the relevant context directly in
each command. E.g. "git submodule absorbgitdirs" can pass the path to
the "git submodule absorbgitdirs" sub-process it's about to invoke.
= Relation to other submissions
This is on top of "ab/submodule-helper-prep-only" and
"ab/submodule-no-abspath", buth currently in "next".
= Changes since v2:
* Fixes for test_when_finished() in test setup, and got rid of
redundant test_config_global.
* There's a new 2/9, which passes along get_super_prefix() as a
parameter. This allows us to gradually replace it, and drop the
*_sp() variants of functions that the previous version introduced,
and it adds "super_prefix" to the absorb_git_dir_into_superproject()
call in submodule_move_head(), which as Glen noticed I'd missed
* Squashed the "deinit" change into that 2/9.
* Explain why we keep the "fsmonitor" test bits that we do.
* Dropped the new "git branch" output tests, turns out I was just
wrong, and was conflating it with the subsequent read-tree
invocation...
So, this should address all outstanding feedbakc, unless I've missed
something.
The one loose end here is that I still have no idea if you can invoke
get "read-tree" to invoke that submodule_move_head() in such a way as
to have the "super_prefix" used, I've failed to come up with a test
case for that.
But for the purposes of this topic it doesn't really matter. In 8/10
we'll start passing the new "--super-prefix" that "read-tree" gets
down to that function. At worst we're handing it to it redundantly,
but that was the case before too.
So we can leave potentially turning that into a "NULL" for some other
time, for now providing the "super_prefix" is harmless, and guarantees
that we avoid any regression in that area from not providing it, in
case I've missed a way to have it matter in that case.
= CI & fetch URL
Passing at: https://github.com/avar/git/tree/avar/nuke-global-super-prefix-use-local-3
Glen Choo (1):
read-tree + fetch tests: test failing "--super-prefix" interaction
Ævar Arnfjörð Bjarmason (8):
submodule.c & submodule--helper: pass along "super_prefix" param
submodule--helper: don't use global --super-prefix in "absorbgitdirs"
submodule--helper: convert "foreach" to its own "--super-prefix"
submodule--helper: convert "sync" to its own "--super-prefix"
submodule--helper: convert "status" to its own "--super-prefix"
submodule--helper: convert "{update,clone}" to their own
"--super-prefix"
read-tree: add "--super-prefix" option, eliminate global
fetch: rename "--submodule-prefix" to "--super-prefix"
Documentation/fetch-options.txt | 5 --
Documentation/git.txt | 8 +--
builtin.h | 4 --
builtin/checkout.c | 2 +-
builtin/fetch.c | 7 ++-
builtin/read-tree.c | 1 +
builtin/rm.c | 2 +-
builtin/submodule--helper.c | 87 ++++++++++++++++++---------------
cache.h | 2 -
entry.c | 12 ++---
entry.h | 6 ++-
environment.c | 13 -----
git.c | 41 +++-------------
parse-options.h | 4 ++
submodule.c | 73 +++++++++++++--------------
submodule.h | 8 +--
t/t1001-read-tree-m-2way.sh | 2 +-
t/t5616-partial-clone.sh | 43 ++++++++++++++++
t/t7527-builtin-fsmonitor.sh | 33 +++----------
unpack-trees.c | 23 +++++----
unpack-trees.h | 1 +
21 files changed, 180 insertions(+), 197 deletions(-)
Range-diff against v2:
1: 1114a4ff666 ! 1: c930fc38356 read-tree + fetch tests: test failing "--super-prefix" interaction
@@ t/t5616-partial-clone.sh: test_expect_success 'repack does not loosen promisor o
+ # setup
+ test_config_global protocol.file.allow always &&
+
++ test_when_finished "rm -rf src-sub" &&
+ git init src-sub &&
+ git -C src-sub config uploadpack.allowfilter 1 &&
+ git -C src-sub config uploadpack.allowanysha1inwant 1 &&
@@ t/t5616-partial-clone.sh: test_expect_success 'repack does not loosen promisor o
+ git -C src-sub commit -m "submodule two" &&
+ SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
+
++ test_when_finished "rm -rf src-super" &&
+ git init src-super &&
+ git -C src-super config uploadpack.allowfilter 1 &&
+ git -C src-super config uploadpack.allowanysha1inwant 1 &&
@@ t/t5616-partial-clone.sh: test_expect_success 'repack does not loosen promisor o
+ git -C src-super commit -m "superproject two" &&
+
+ # the fetch
-+ test_when_finished "rm -rf src-super src-sub client" &&
-+
-+ test_config_global protocol.file.allow always &&
++ test_when_finished "rm -rf client" &&
+ git clone --filter=blob:none --also-filter-submodules \
+ --recurse-submodules "file://$(pwd)/src-super" client &&
+
3: a7a1f9487dc ! 2: 2e4a2236898 submodule--helper: "deinit" has never used "--super-prefix"
@@ Metadata
Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## Commit message ##
- submodule--helper: "deinit" has never used "--super-prefix"
+ submodule.c & submodule--helper: pass along "super_prefix" param
- The "deinit_submodule()" function has never been able to use the "git
- --super-prefix". It will call "absorb_git_dir_into_superproject()",
- but it will only do so from the top-level project.
+ Start passing the "super_prefix" along as a parameter to
+ get_submodule_displaypath() and absorb_git_dir_into_superproject(),
+ rather than get the value directly as a global.
- If "absorbgitdirs" recurses it will use the "path" passed to
- "absorb_git_dir_into_superproject()" in "deinit_submodule()" as its
- starting "--super-prefix".
+ This is in preparation for subsequent commits, where we'll gradually
+ phase out get_super_prefix() for an alternative way of getting the
+ "super_prefix".
- So, let's introduce a "get_submodule_displaypath_sp()" helper, and
- make our existing "get_submodule_displaypath()" a wrapper for it. In a
- subsequent commit the wrapper will be going away, as the rest of the
- commands here will stop using the global "get_super_prefix()".
+ Most of the users of this get a get_super_prefix() value, either
+ directly or by indirection. The exceptions are:
+
+ - builtin/rm.c: Doesn't declare SUPPORT_SUPER_PREFIX, so we'd have
+ died if this was provided, so it's safe to passs "NULL".
+
+ - deinit_submodule(): The "deinit_submodule()" function has never been
+ able to use the "git -super-prefix". It will call
+ "absorb_git_dir_into_superproject()", but it will only do so from the
+ top-level project.
+
+ If "absorbgitdirs" recurses it will use the "path" passed to
+ "absorb_git_dir_into_superproject()" in "deinit_submodule()" as its
+ starting "--super-prefix". So we can safely remove the
+ get_super_prefix() call here, and pass NULL instead.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ ## builtin/rm.c ##
+@@ builtin/rm.c: static void submodules_absorb_gitdir_if_needed(void)
+ continue;
+
+ if (!submodule_uses_gitfile(name))
+- absorb_git_dir_into_superproject(name);
++ absorb_git_dir_into_superproject(name, NULL);
+ }
+ }
+
+
## builtin/submodule--helper.c ##
@@ builtin/submodule--helper.c: static char *resolve_relative_url(const char *rel_url, const char *up_path, int
}
/* the result should be freed by the caller. */
-static char *get_submodule_displaypath(const char *path, const char *prefix)
-+static char *get_submodule_displaypath_sp(const char *path, const char *prefix,
-+ const char *super_prefix)
++static char *get_submodule_displaypath(const char *path, const char *prefix,
++ const char *super_prefix)
{
- const char *super_prefix = get_super_prefix();
-
if (prefix && super_prefix) {
BUG("cannot have prefix '%s' and superprefix '%s'",
prefix, super_prefix);
-@@ builtin/submodule--helper.c: static char *get_submodule_displaypath(const char *path, const char *prefix)
+@@ builtin/submodule--helper.c: static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
+ struct child_process cp = CHILD_PROCESS_INIT;
+ char *displaypath;
+
+- displaypath = get_submodule_displaypath(path, info->prefix);
++ displaypath = get_submodule_displaypath(path, info->prefix,
++ get_super_prefix());
+
+ sub = submodule_from_path(the_repository, null_oid(), path);
+
+@@ builtin/submodule--helper.c: static void init_submodule(const char *path, const char *prefix,
+ const char *upd;
+ char *url = NULL, *displaypath;
+
+- displaypath = get_submodule_displaypath(path, prefix);
++ displaypath = get_submodule_displaypath(path, prefix,
++ get_super_prefix());
+
+ sub = submodule_from_path(the_repository, null_oid(), path);
+
+@@ builtin/submodule--helper.c: static void status_submodule(const char *path, const struct object_id *ce_oid,
+ die(_("no submodule mapping found in .gitmodules for path '%s'"),
+ path);
+
+- displaypath = get_submodule_displaypath(path, prefix);
++ displaypath = get_submodule_displaypath(path, prefix,
++ get_super_prefix());
+
+ if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
+ print_status(flags, 'U', path, null_oid(), displaypath);
+@@ builtin/submodule--helper.c: static void generate_submodule_summary(struct summary_cb *info,
+ dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
}
- }
-+static char *get_submodule_displaypath(const char *path, const char *prefix)
-+{
-+ const char *super_prefix = get_super_prefix();
-+
-+ return get_submodule_displaypath_sp(path, prefix, super_prefix);
-+}
-+
- static char *compute_rev_name(const char *sub_path, const char* object_id)
- {
- struct strbuf sb = STRBUF_INIT;
+- displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
++ displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
++ get_super_prefix());
+
+ if (!missing_src && !missing_dst) {
+ struct child_process cp_rev_list = CHILD_PROCESS_INIT;
+@@ builtin/submodule--helper.c: static void sync_submodule(const char *path, const char *prefix,
+ super_config_url = xstrdup("");
+ }
+
+- displaypath = get_submodule_displaypath(path, prefix);
++ displaypath = get_submodule_displaypath(path, prefix,
++ get_super_prefix());
+
+ if (!(flags & OPT_QUIET))
+ printf(_("Synchronizing submodule url for '%s'\n"),
@@ builtin/submodule--helper.c: static void deinit_submodule(const char *path, const char *prefix,
if (!sub || !sub->name)
goto cleanup;
- displaypath = get_submodule_displaypath(path, prefix);
-+ displaypath = get_submodule_displaypath_sp(path, prefix, NULL);
++ displaypath = get_submodule_displaypath(path, prefix, NULL);
/* remove the submodule work tree (unless the user already did it) */
if (is_directory(path)) {
+@@ builtin/submodule--helper.c: static void deinit_submodule(const char *path, const char *prefix,
+ ".git file by using absorbgitdirs."),
+ displaypath);
+
+- absorb_git_dir_into_superproject(path);
++ absorb_git_dir_into_superproject(path, NULL);
+
+ }
+
+@@ builtin/submodule--helper.c: static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
+ enum submodule_update_type update_type;
+ char *key;
+ const struct update_data *ud = suc->update_data;
+- char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
++ char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
++ get_super_prefix());
+ struct strbuf sb = STRBUF_INIT;
+ int needs_cloning = 0;
+ int need_free_url = 0;
+@@ builtin/submodule--helper.c: static int update_submodules(struct update_data *update_data)
+ goto fail;
+
+ update_data->displaypath = get_submodule_displaypath(
+- update_data->sm_path, update_data->prefix);
++ update_data->sm_path, update_data->prefix,
++ get_super_prefix());
+ code = update_submodule(update_data);
+ FREE_AND_NULL(update_data->displaypath);
+ fail:
+@@ builtin/submodule--helper.c: static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
+ int i;
+ struct pathspec pathspec = { 0 };
+ struct module_list list = MODULE_LIST_INIT;
++ const char *super_prefix;
+ struct option embed_gitdir_options[] = {
+ OPT_END()
+ };
+@@ builtin/submodule--helper.c: static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
+ if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
+ goto cleanup;
+
++ super_prefix = get_super_prefix();
+ for (i = 0; i < list.nr; i++)
+- absorb_git_dir_into_superproject(list.entries[i]->name);
++ absorb_git_dir_into_superproject(list.entries[i]->name,
++ super_prefix);
+
+ ret = 0;
+ cleanup:
+
+ ## submodule.c ##
+@@ submodule.c: int submodule_move_head(const char *path,
+ if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
+ if (old_head) {
+ if (!submodule_uses_gitfile(path))
+- absorb_git_dir_into_superproject(path);
++ absorb_git_dir_into_superproject(path,
++ get_super_prefix());
+ } else {
+ struct strbuf gitdir = STRBUF_INIT;
+ submodule_name_to_gitdir(&gitdir, the_repository,
+@@ submodule.c: static void relocate_single_git_dir_into_superproject(const char *path)
+ strbuf_release(&new_gitdir);
+ }
+
+-static void absorb_git_dir_into_superproject_recurse(const char *path)
++static void absorb_git_dir_into_superproject_recurse(const char *path,
++ const char *super_prefix)
+ {
+
+ struct child_process cp = CHILD_PROCESS_INIT;
+@@ submodule.c: static void absorb_git_dir_into_superproject_recurse(const char *path)
+ cp.dir = path;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+- strvec_pushf(&cp.args, "--super-prefix=%s%s/",
+- get_super_prefix_or_empty(), path);
++ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
++ super_prefix : "", path);
+ strvec_pushl(&cp.args, "submodule--helper",
+ "absorbgitdirs", NULL);
+ prepare_submodule_repo_env(&cp.env);
+@@ submodule.c: static void absorb_git_dir_into_superproject_recurse(const char *path)
+ * having its git directory within the working tree to the git dir nested
+ * in its superprojects git dir under modules/.
+ */
+-void absorb_git_dir_into_superproject(const char *path)
++void absorb_git_dir_into_superproject(const char *path,
++ const char *super_prefix)
+ {
+ int err_code;
+ const char *sub_git_dir;
+@@ submodule.c: void absorb_git_dir_into_superproject(const char *path)
+ }
+ strbuf_release(&gitdir);
+
+- absorb_git_dir_into_superproject_recurse(path);
++ absorb_git_dir_into_superproject_recurse(path, super_prefix);
+ }
+
+ int get_superproject_working_tree(struct strbuf *buf)
+
+ ## submodule.h ##
+@@ submodule.h: 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(const char *path,
++ const char *super_prefix);
+
+ /*
+ * Return the absolute path of the working tree of the superproject, which this
2: 5a35f7b75b3 ! 3: 6e10a47c60a submodule--helper: don't use global --super-prefix in "absorbgitdirs"
@@ Commit message
stone makes such an eventual change easier, as we'll need to deal with
less global state at that point.
- The "fsmonitor--daemon" test adjusted here was added in [3]. The
- comment added in that commit has been out-of-date from the beginning,
- and the "have_t2_error_event()" was being overly specific in testing
- for a bug that we *don't* have. Let's instead test for the stdout and
- stderr that we *do have*.
+ The "fsmonitor--daemon" test adjusted here was added in [3]. To assert
+ that it didn't run into the "--super-prefix" message it was asserting
+ the output it didn't have. Let's instead assert the full output that
+ we *do* have, which we can do here as this is based on a change[4] to
+ make it predictable (until [4] it contained absolute paths).
+
+ We could also remove the test entirely (as [5] did), but even though
+ the initial reason for having it is gone we're still getting some
+ marginal benefit from testing the "fsmonitor" and "submodule
+ absorbgitdirs" interaction, so let's keep it.
+
+ The change here to have either a NULL or non-"" string as a
+ "super_prefix" instead of the previous arrangement of "" or non-"" is
+ somewhat arbitrary. We could also decide to never have to check for
+ NULL.
+
+ As we'll be changing the rest of the "git --super-prefix" users to the
+ same pattern, leaving them all consistent makes sense. Why not pick ""
+ over NULL? Because that's how the "prefix" works[6], and having
+ "prefix" and "super_prefix" work the same way will be less
+ confusing. That "prefix" picked NULL instead of "" is itself
+ arbitrary, but as it's easy to make this small bit of our overall API
+ consistent, let's go with that.
1. 74866d75793 (git: make super-prefix option, 2016-10-07)
2. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
+ 4. https://lore.kernel.org/git/patch-1.1-34b54fdd9bb-20221109T020347Z-avarab@gmail.com/
+ 5. https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com/
+ 6. 9725c8dda20 (built-ins: trust the "prefix" from run_builtin(),
+ 2022-02-16)
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
@@ builtin/submodule--helper.c: static int absorb_git_dirs(int argc, const char **a
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
+- const char *super_prefix;
+ const char *super_prefix = NULL;
struct option embed_gitdir_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
@@ builtin/submodule--helper.c: static int absorb_git_dirs(int argc, const char **a
};
const char *const git_submodule_helper_usage[] = {
@@ builtin/submodule--helper.c: static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
+ if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
goto cleanup;
+- super_prefix = get_super_prefix();
for (i = 0; i < list.nr; i++)
-- absorb_git_dir_into_superproject(list.entries[i]->name);
-+ absorb_git_dir_into_superproject_sp(list.entries[i]->name,
-+ super_prefix);
-
- ret = 0;
- cleanup:
+ absorb_git_dir_into_superproject(list.entries[i]->name,
+ super_prefix);
@@ builtin/submodule--helper.c: int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
@@ submodule.c: static void relocate_single_git_dir_into_superproject(const char *p
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,
++ 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);
-@@ submodule.c: static void relocate_single_git_dir_into_superproject(const char *path)
- strbuf_release(&new_gitdir);
- }
-
--static void absorb_git_dir_into_superproject_recurse(const char *path)
-+static void absorb_git_dir_into_superproject_recurse(const char *path,
-+ const char *super_prefix)
- {
-
- struct child_process cp = CHILD_PROCESS_INIT;
-@@ submodule.c: static void absorb_git_dir_into_superproject_recurse(const char *path)
+@@ submodule.c: static void absorb_git_dir_into_superproject_recurse(const char *path,
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
-- strvec_pushf(&cp.args, "--super-prefix=%s%s/",
-- get_super_prefix_or_empty(), path);
+- strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+- super_prefix : "", path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
@@ submodule.c: static void absorb_git_dir_into_superproject_recurse(const char *pa
prepare_submodule_repo_env(&cp.env);
if (run_command(&cp))
die(_("could not recurse into submodule '%s'"), path);
-@@ submodule.c: static void absorb_git_dir_into_superproject_recurse(const char *path)
- * having its git directory within the working tree to the git dir nested
- * in its superprojects git dir under modules/.
- */
--void absorb_git_dir_into_superproject(const char *path)
-+void absorb_git_dir_into_superproject_sp(const char *path,
-+ const char *super_prefix)
- {
- int err_code;
- const char *sub_git_dir;
-@@ submodule.c: void absorb_git_dir_into_superproject(const char *path)
+@@ submodule.c: void absorb_git_dir_into_superproject(const char *path,
char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
if (!starts_with(real_sub_git_dir, real_common_git_dir))
@@ submodule.c: void absorb_git_dir_into_superproject(const char *path)
free(real_sub_git_dir);
free(real_common_git_dir);
- }
- strbuf_release(&gitdir);
-
-- absorb_git_dir_into_superproject_recurse(path);
-+ absorb_git_dir_into_superproject_recurse(path, super_prefix);
- }
-
- int get_superproject_working_tree(struct strbuf *buf)
-
- ## submodule.h ##
-@@ submodule.h: 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);
-+}
-
- /*
- * Return the absolute path of the working tree of the superproject, which this
## t/t7527-builtin-fsmonitor.sh ##
@@ t/t7527-builtin-fsmonitor.sh: test_expect_success 'submodule always visited' '
4: 935d8070834 ! 4: da86eb3b867 submodule--helper: convert "foreach" to its own "--super-prefix"
@@ builtin/submodule--helper.c: struct foreach_cb {
int recursive;
};
@@ builtin/submodule--helper.c: static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
- struct child_process cp = CHILD_PROCESS_INIT;
char *displaypath;
-- displaypath = get_submodule_displaypath(path, info->prefix);
-+ displaypath = get_submodule_displaypath_sp(path, info->prefix,
-+ info->super_prefix);
+ displaypath = get_submodule_displaypath(path, info->prefix,
+- get_super_prefix());
++ info->super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ builtin/submodule--helper.c: static void runcommand_in_submodule_cb(const struct
if (info->quiet)
strvec_push(&cpr.args, "--quiet");
@@ builtin/submodule--helper.c: static int module_foreach(int argc, const char **argv, const char *prefix)
- struct foreach_cb info = FOREACH_CB_INIT;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
-+ const char *super_prefix = NULL;
struct option module_foreach_options[] = {
-+ OPT__SUPER_PREFIX(&super_prefix),
++ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
OPT_BOOL(0, "recursive", &info.recursive,
N_("recurse into nested submodules")),
-@@ builtin/submodule--helper.c: static int module_foreach(int argc, const char **argv, const char *prefix)
- info.argc = argc;
- info.argv = argv;
- info.prefix = prefix;
-+ info.super_prefix = super_prefix;
-
- for_each_listed_submodule(&list, runcommand_in_submodule_cb, &info);
-
@@ builtin/submodule--helper.c: int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
5: 933c752513d ! 5: 2eb583148a6 submodule--helper: convert "sync" to its own "--super-prefix"
@@ builtin/submodule--helper.c: static void sync_submodule(const char *path, const
super_config_url = xstrdup("");
}
-- displaypath = get_submodule_displaypath(path, prefix);
-+ displaypath = get_submodule_displaypath_sp(path, prefix, super_prefix);
+- displaypath = get_submodule_displaypath(path, prefix,
+- get_super_prefix());
++ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ builtin/submodule--helper.c: static void sync_submodule_cb(const struct cache_en
static int module_sync(int argc, const char **argv, const char *prefix)
@@ builtin/submodule--helper.c: static int module_sync(int argc, const char **argv, const char *prefix)
- struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
int recursive = 0;
-+ const char *super_prefix = NULL;
struct option module_sync_options[] = {
-+ OPT__SUPER_PREFIX(&super_prefix),
++ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
OPT_BOOL(0, "recursive", &recursive,
N_("recurse into nested submodules")),
-@@ builtin/submodule--helper.c: static int module_sync(int argc, const char **argv, const char *prefix)
- goto cleanup;
-
- info.prefix = prefix;
-+ info.super_prefix = super_prefix;
- if (quiet)
- info.flags |= OPT_QUIET;
- if (recursive)
@@ builtin/submodule--helper.c: static int module_set_url(int argc, const char **argv, const char *prefix)
config_name = xstrfmt("submodule.%s.url", path);
6: 67273f729e0 ! 6: 8d8925c7e1f submodule--helper: convert "status" to its own "--super-prefix"
@@ builtin/submodule--helper.c: static void status_submodule(const char *path, cons
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
-- displaypath = get_submodule_displaypath(path, prefix);
-+ displaypath = get_submodule_displaypath_sp(path, prefix, super_prefix);
+- displaypath = get_submodule_displaypath(path, prefix,
+- get_super_prefix());
++ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ builtin/submodule--helper.c: static void status_submodule_cb(const struct cache_
static int module_status(int argc, const char **argv, const char *prefix)
@@ builtin/submodule--helper.c: static int module_status(int argc, const char **argv, const char *prefix)
- struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
-+ const char *super_prefix = NULL;
struct option module_status_options[] = {
-+ OPT__SUPER_PREFIX(&super_prefix),
++ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress submodule status output")),
OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
-@@ builtin/submodule--helper.c: static int module_status(int argc, const char **argv, const char *prefix)
- goto cleanup;
-
- info.prefix = prefix;
-+ info.super_prefix = super_prefix;
- if (quiet)
- info.flags |= OPT_QUIET;
-
@@ builtin/submodule--helper.c: int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
7: eaa73f5b1e4 ! 7: 754a7489aa5 submodule--helper: convert "{update,clone}" to their own "--super-prefix"
@@ Commit message
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## builtin/submodule--helper.c ##
-@@ builtin/submodule--helper.c: static char *get_submodule_displaypath_sp(const char *path, const char *prefix,
- }
- }
-
--static char *get_submodule_displaypath(const char *path, const char *prefix)
--{
-- const char *super_prefix = get_super_prefix();
--
-- return get_submodule_displaypath_sp(path, prefix, super_prefix);
--}
--
- static char *compute_rev_name(const char *sub_path, const char* object_id)
- {
- struct strbuf sb = STRBUF_INIT;
@@ builtin/submodule--helper.c: static int starts_with_dot_dot_slash(const char *const path)
struct init_cb {
@@ builtin/submodule--helper.c: static void init_submodule(const char *path, const
const char *upd;
char *url = NULL, *displaypath;
-- displaypath = get_submodule_displaypath(path, prefix);
-+ displaypath = get_submodule_displaypath_sp(path, prefix, super_prefix);
+- displaypath = get_submodule_displaypath(path, prefix,
+- get_super_prefix());
++ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ builtin/submodule--helper.c: struct summary_cb {
unsigned int for_status: 1;
unsigned int files: 1;
@@ builtin/submodule--helper.c: static void generate_submodule_summary(struct summary_cb *info,
- dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
}
-- displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
-+ displaypath = get_submodule_displaypath_sp(p->sm_path, info->prefix,
-+ info->super_prefix);
+ displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
+- get_super_prefix());
++ info->super_prefix);
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ builtin/submodule--helper.c: static void submodule_update_clone_release(struct s
enum submodule_update_type update_default;
struct object_id suboid;
@@ builtin/submodule--helper.c: static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
- enum submodule_update_type update_type;
char *key;
const struct update_data *ud = suc->update_data;
-- char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
-+ char *displaypath = get_submodule_displaypath_sp(ce->name, ud->prefix,
-+ ud->super_prefix);
+ char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
+- get_super_prefix());
++ ud->super_prefix);
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ builtin/submodule--helper.c: static void update_data_to_args(const struct update
if (update_data->quiet)
strvec_push(args, "--quiet");
@@ builtin/submodule--helper.c: static int update_submodules(struct update_data *update_data)
- if (code)
- goto fail;
-- update_data->displaypath = get_submodule_displaypath(
-- update_data->sm_path, update_data->prefix);
-+ update_data->displaypath = get_submodule_displaypath_sp(
-+ update_data->sm_path, update_data->prefix,
+ update_data->displaypath = get_submodule_displaypath(
+ update_data->sm_path, update_data->prefix,
+- get_super_prefix());
+ update_data->super_prefix);
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ builtin/submodule--helper.c: static int module_update(int argc, const char **argv, const char *prefix)
- struct list_objects_filter_options filter_options =
LIST_OBJECTS_FILTER_INIT;
int ret;
-+ const char *super_prefix = NULL;
struct option module_update_options[] = {
-+ OPT__SUPER_PREFIX(&super_prefix),
++ OPT__SUPER_PREFIX(&opt.super_prefix),
OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
OPT_BOOL(0, "init", &opt.init,
N_("initialize uninitialized submodules before update")),
@@ builtin/submodule--helper.c: static int module_update(int argc, const char **argv, const char *prefix)
-
- opt.filter_options = &filter_options;
- opt.prefix = prefix;
-+ opt.super_prefix = super_prefix;
-
- if (opt.update_default)
- opt.update_strategy.type = opt.update_default;
-@@ builtin/submodule--helper.c: static int module_update(int argc, const char **argv, const char *prefix)
module_list_active(&list);
info.prefix = opt.prefix;
-+ info.super_prefix = super_prefix;
++ info.super_prefix = opt.super_prefix;
if (opt.quiet)
info.flags |= OPT_QUIET;
8: 172b5865811 < -: ----------- submodule tests: test "git branch -t" output and stderr
9: 9fdeab60773 ! 8: f952fa3d01f read-tree: add "--super-prefix" option, eliminate global
@@ submodule.c: static void submodule_reset_index(const char *path)
{
int ret = 0;
struct child_process cp = CHILD_PROCESS_INIT;
+@@ submodule.c: int submodule_move_head(const char *path,
+ if (old_head) {
+ if (!submodule_uses_gitfile(path))
+ absorb_git_dir_into_superproject(path,
+- get_super_prefix());
++ super_prefix);
+ } else {
+ struct strbuf gitdir = STRBUF_INIT;
+ submodule_name_to_gitdir(&gitdir, the_repository,
@@ submodule.c: int submodule_move_head(const char *path,
strbuf_release(&gitdir);
10: 100ba36dfb7 = 9: 1aa4019527a fetch: rename "--submodule-prefix" to "--super-prefix"
--
2.38.0.1509.g9445af83948
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v3 1/9] read-tree + fetch tests: test failing "--super-prefix" interaction
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 2/9] submodule.c & submodule--helper: pass along "super_prefix" param Ævar Arnfjörð Bjarmason
` (9 subsequent siblings)
10 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
From: Glen Choo <chooglen@google.com>
Ever since "git fetch --refetch" was introduced in 0f5e8851737 (Merge
branch 'rc/fetch-refetch', 2022-04-04) the test being added here would
fail. This is because "restore" will "read-tree .. --reset <hash>",
which will in turn invoke "fetch". The "fetch" will then die with:
fatal: fetch doesn't support --super-prefix
This edge case and other "--super-prefix" bugs will be fixed in
subsequent commits, but let's first add a "test_expect_failure" test
for it. It passes until the very last command in the test.
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 037941b95d2..2846ec6629c 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
grep "loosen_unused_packed_objects/loosened:0" trace
'
+test_expect_failure 'lazy-fetch in submodule succeeds' '
+ # setup
+ test_config_global protocol.file.allow always &&
+
+ test_when_finished "rm -rf src-sub" &&
+ git init src-sub &&
+ git -C src-sub config uploadpack.allowfilter 1 &&
+ git -C src-sub config uploadpack.allowanysha1inwant 1 &&
+
+ # This blob must be missing in the subsequent commit.
+ echo foo >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule one" &&
+ SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
+
+ echo bar >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule two" &&
+ SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
+
+ test_when_finished "rm -rf src-super" &&
+ git init src-super &&
+ git -C src-super config uploadpack.allowfilter 1 &&
+ git -C src-super config uploadpack.allowanysha1inwant 1 &&
+ git -C src-super submodule add ../src-sub src-sub &&
+
+ git -C src-super/src-sub checkout $SUB_ONE &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject one" &&
+
+ git -C src-super/src-sub checkout $SUB_TWO &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject two" &&
+
+ # the fetch
+ test_when_finished "rm -rf client" &&
+ git clone --filter=blob:none --also-filter-submodules \
+ --recurse-submodules "file://$(pwd)/src-super" client &&
+
+ # Trigger lazy-fetch from the superproject
+ git -C client restore --recurse-submodules --source=HEAD^ :/
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v3 2/9] submodule.c & submodule--helper: pass along "super_prefix" param
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 1/9] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 3/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
` (8 subsequent siblings)
10 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
Start passing the "super_prefix" along as a parameter to
get_submodule_displaypath() and absorb_git_dir_into_superproject(),
rather than get the value directly as a global.
This is in preparation for subsequent commits, where we'll gradually
phase out get_super_prefix() for an alternative way of getting the
"super_prefix".
Most of the users of this get a get_super_prefix() value, either
directly or by indirection. The exceptions are:
- builtin/rm.c: Doesn't declare SUPPORT_SUPER_PREFIX, so we'd have
died if this was provided, so it's safe to passs "NULL".
- deinit_submodule(): The "deinit_submodule()" function has never been
able to use the "git -super-prefix". It will call
"absorb_git_dir_into_superproject()", but it will only do so from the
top-level project.
If "absorbgitdirs" recurses it will use the "path" passed to
"absorb_git_dir_into_superproject()" in "deinit_submodule()" as its
starting "--super-prefix". So we can safely remove the
get_super_prefix() call here, and pass NULL instead.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/rm.c | 2 +-
builtin/submodule--helper.c | 35 ++++++++++++++++++++++-------------
submodule.c | 15 +++++++++------
submodule.h | 3 ++-
4 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/builtin/rm.c b/builtin/rm.c
index 05bfe20a469..24e13f6e899 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -86,7 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void)
continue;
if (!submodule_uses_gitfile(name))
- absorb_git_dir_into_superproject(name);
+ absorb_git_dir_into_superproject(name, NULL);
}
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index c75e9e86b06..dc220d3348b 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -113,10 +113,9 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int
}
/* the result should be freed by the caller. */
-static char *get_submodule_displaypath(const char *path, const char *prefix)
+static char *get_submodule_displaypath(const char *path, const char *prefix,
+ const char *super_prefix)
{
- const char *super_prefix = get_super_prefix();
-
if (prefix && super_prefix) {
BUG("cannot have prefix '%s' and superprefix '%s'",
prefix, super_prefix);
@@ -294,7 +293,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
struct child_process cp = CHILD_PROCESS_INIT;
char *displaypath;
- displaypath = get_submodule_displaypath(path, info->prefix);
+ displaypath = get_submodule_displaypath(path, info->prefix,
+ get_super_prefix());
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -447,7 +447,8 @@ static void init_submodule(const char *path, const char *prefix,
const char *upd;
char *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -624,7 +625,8 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ -948,7 +950,8 @@ static void generate_submodule_summary(struct summary_cb *info,
dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
}
- displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
+ displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
+ get_super_prefix());
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ -1239,7 +1242,8 @@ static void sync_submodule(const char *path, const char *prefix,
super_config_url = xstrdup("");
}
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ -1365,7 +1369,7 @@ static void deinit_submodule(const char *path, const char *prefix,
if (!sub || !sub->name)
goto cleanup;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix, NULL);
/* remove the submodule work tree (unless the user already did it) */
if (is_directory(path)) {
@@ -1379,7 +1383,7 @@ static void deinit_submodule(const char *path, const char *prefix,
".git file by using absorbgitdirs."),
displaypath);
- absorb_git_dir_into_superproject(path);
+ absorb_git_dir_into_superproject(path, NULL);
}
@@ -1958,7 +1962,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
enum submodule_update_type update_type;
char *key;
const struct update_data *ud = suc->update_data;
- char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
+ char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
+ get_super_prefix());
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ -2608,7 +2613,8 @@ static int update_submodules(struct update_data *update_data)
goto fail;
update_data->displaypath = get_submodule_displaypath(
- update_data->sm_path, update_data->prefix);
+ update_data->sm_path, update_data->prefix,
+ get_super_prefix());
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ -2828,6 +2834,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
+ const char *super_prefix;
struct option embed_gitdir_options[] = {
OPT_END()
};
@@ -2843,8 +2850,10 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
goto cleanup;
+ super_prefix = get_super_prefix();
for (i = 0; i < list.nr; i++)
- absorb_git_dir_into_superproject(list.entries[i]->name);
+ absorb_git_dir_into_superproject(list.entries[i]->name,
+ super_prefix);
ret = 0;
cleanup:
diff --git a/submodule.c b/submodule.c
index c47358097fd..d339ce3b62c 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2139,7 +2139,8 @@ int submodule_move_head(const char *path,
if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
if (old_head) {
if (!submodule_uses_gitfile(path))
- absorb_git_dir_into_superproject(path);
+ absorb_git_dir_into_superproject(path,
+ get_super_prefix());
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2313,7 +2314,8 @@ static void relocate_single_git_dir_into_superproject(const char *path)
strbuf_release(&new_gitdir);
}
-static void absorb_git_dir_into_superproject_recurse(const char *path)
+static void absorb_git_dir_into_superproject_recurse(const char *path,
+ const char *super_prefix)
{
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2321,8 +2323,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/",
- get_super_prefix_or_empty(), path);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+ super_prefix : "", path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
prepare_submodule_repo_env(&cp.env);
@@ -2335,7 +2337,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
* having its git directory within the working tree to the git dir nested
* in its superprojects git dir under modules/.
*/
-void absorb_git_dir_into_superproject(const char *path)
+void absorb_git_dir_into_superproject(const char *path,
+ const char *super_prefix)
{
int err_code;
const char *sub_git_dir;
@@ -2384,7 +2387,7 @@ void absorb_git_dir_into_superproject(const char *path)
}
strbuf_release(&gitdir);
- absorb_git_dir_into_superproject_recurse(path);
+ absorb_git_dir_into_superproject_recurse(path, super_prefix);
}
int get_superproject_working_tree(struct strbuf *buf)
diff --git a/submodule.h b/submodule.h
index b52a4ff1e73..f90ee547d08 100644
--- a/submodule.h
+++ b/submodule.h
@@ -164,7 +164,8 @@ 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(const char *path,
+ const char *super_prefix);
/*
* Return the absolute path of the working tree of the superproject, which this
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v3 3/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 1/9] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 2/9] submodule.c & submodule--helper: pass along "super_prefix" param Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-22 19:53 ` Glen Choo
2022-11-19 12:41 ` [PATCH v3 4/9] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
` (7 subsequent siblings)
10 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
The "--super-prefix" facility was introduced in [1] has always been a
transitory hack, which is why we've made it an error to supply it as
an option to "git" to commands that don't know about it.
That's been a good goal, as it has a global effect we haven't wanted
calls to get_super_prefix() from built-ins we didn't expect.
But it has meant that when we've had chains of different built-ins
using it all of the processes in that "chain" have needed to support
it, and worse processes that don't need it have needed to ask for
"SUPPORT_SUPER_PREFIX" because their parent process needs it.
That's how "fsmonitor--daemon" ended up with it, per [2] it's called
from (among other things) "submodule--helper absorbgitdirs", but as we
declared "submodule--helper" as "SUPPORT_SUPER_PREFIX" we needed to
declare "fsmonitor--daemon" as accepting it too, even though it
doesn't care about it.
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.
Let's instead accept a hidden "--super-prefix" option to
"submodule--helper absorbgitdirs" itself.
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.
The "fsmonitor--daemon" test adjusted here was added in [3]. To assert
that it didn't run into the "--super-prefix" message it was asserting
the output it didn't have. Let's instead assert the full output that
we *do* have, which we can do here as this is based on a change[4] to
make it predictable (until [4] it contained absolute paths).
We could also remove the test entirely (as [5] did), but even though
the initial reason for having it is gone we're still getting some
marginal benefit from testing the "fsmonitor" and "submodule
absorbgitdirs" interaction, so let's keep it.
The change here to have either a NULL or non-"" string as a
"super_prefix" instead of the previous arrangement of "" or non-"" is
somewhat arbitrary. We could also decide to never have to check for
NULL.
As we'll be changing the rest of the "git --super-prefix" users to the
same pattern, leaving them all consistent makes sense. Why not pick ""
over NULL? Because that's how the "prefix" works[6], and having
"prefix" and "super_prefix" work the same way will be less
confusing. That "prefix" picked NULL instead of "" is itself
arbitrary, but as it's easy to make this small bit of our overall API
consistent, let's go with that.
1. 74866d75793 (git: make super-prefix option, 2016-10-07)
2. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
4. https://lore.kernel.org/git/patch-1.1-34b54fdd9bb-20221109T020347Z-avarab@gmail.com/
5. https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com/
6. 9725c8dda20 (built-ins: trust the "prefix" from run_builtin(),
2022-02-16)
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 7 +++----
git.c | 2 +-
parse-options.h | 4 ++++
submodule.c | 12 +++++++-----
t/t7527-builtin-fsmonitor.sh | 33 ++++++++-------------------------
5 files changed, 23 insertions(+), 35 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index dc220d3348b..9f6ebc64140 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2834,8 +2834,9 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
- const char *super_prefix;
+ const char *super_prefix = NULL;
struct option embed_gitdir_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT_END()
};
const char *const git_submodule_helper_usage[] = {
@@ -2850,7 +2851,6 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
goto cleanup;
- super_prefix = get_super_prefix();
for (i = 0; i < list.nr; i++)
absorb_git_dir_into_superproject(list.entries[i]->name,
super_prefix);
@@ -3391,8 +3391,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
- get_super_prefix())
+ strcmp(subcmd, "sync") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
diff --git a/git.c b/git.c
index 10202a7f126..b1b7e1a837e 100644
--- a/git.c
+++ b/git.c
@@ -539,7 +539,7 @@ static struct cmd_struct commands[] = {
{ "format-patch", cmd_format_patch, RUN_SETUP },
{ "fsck", cmd_fsck, RUN_SETUP },
{ "fsck-objects", cmd_fsck, RUN_SETUP },
- { "fsmonitor--daemon", cmd_fsmonitor__daemon, SUPPORT_SUPER_PREFIX | RUN_SETUP },
+ { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP },
{ "gc", cmd_gc, RUN_SETUP },
{ "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
{ "grep", cmd_grep, RUN_SETUP_GENTLY },
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 d339ce3b62c..3383c47c719 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2269,7 +2269,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;
@@ -2303,7 +2304,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);
@@ -2323,10 +2324,11 @@ static void absorb_git_dir_into_superproject_recurse(const char *path,
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
- super_prefix : "", path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+ super_prefix : "", path);
+
prepare_submodule_repo_env(&cp.env);
if (run_command(&cp))
die(_("could not recurse into submodule '%s'"), path);
@@ -2380,7 +2382,7 @@ void absorb_git_dir_into_superproject(const char *path,
char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
if (!starts_with(real_sub_git_dir, real_common_git_dir))
- relocate_single_git_dir_into_superproject(path);
+ relocate_single_git_dir_into_superproject(path, super_prefix);
free(real_sub_git_dir);
free(real_common_git_dir);
diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
index 4abc74db2bb..31526937d95 100755
--- a/t/t7527-builtin-fsmonitor.sh
+++ b/t/t7527-builtin-fsmonitor.sh
@@ -866,30 +866,11 @@ test_expect_success 'submodule always visited' '
# the submodule, and someone does a `git submodule absorbgitdirs`
# in the super, Git will recursively invoke `git submodule--helper`
# to do the work and this may try to read the index. This will
-# try to start the daemon in the submodule *and* pass (either
-# directly or via inheritance) the `--super-prefix` arg to the
-# `git fsmonitor--daemon start` command inside the submodule.
-# This causes a warning because fsmonitor--daemon does take that
-# global arg (see the table in git.c)
-#
-# This causes a warning when trying to start the daemon that is
-# somewhat confusing. It does not seem to hurt anything because
-# the fsmonitor code maps the query failure into a trivial response
-# and does the work anyway.
-#
-# It would be nice to silence the warning, however.
-
-have_t2_error_event () {
- log=$1
- msg="fsmonitor--daemon doesnQt support --super-prefix" &&
-
- tr '\047' Q <$1 | grep -e "$msg"
-}
+# try to start the daemon in the submodule.
test_expect_success "stray submodule super-prefix warning" '
test_when_finished "rm -rf super; \
- rm -rf sub; \
- rm super-sub.trace" &&
+ rm -rf sub" &&
create_super super &&
create_sub sub &&
@@ -904,10 +885,12 @@ test_expect_success "stray submodule super-prefix warning" '
test_path_is_dir super/dir_1/dir_2/sub/.git &&
- GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
- git -C super submodule absorbgitdirs &&
-
- ! have_t2_error_event super-sub.trace
+ cat >expect <<-\EOF &&
+ Migrating git directory of '\''dir_1/dir_2/sub'\'' from '\''dir_1/dir_2/sub/.git'\'' to '\''.git/modules/dir_1/dir_2/sub'\''
+ EOF
+ git -C super submodule absorbgitdirs >out 2>actual &&
+ test_cmp expect actual &&
+ test_must_be_empty out
'
# On a case-insensitive file system, confirm that the daemon
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v3 3/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-11-19 12:41 ` [PATCH v3 3/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
@ 2022-11-22 19:53 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-22 19:53 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> The "fsmonitor--daemon" test adjusted here was added in [3]. To assert
> that it didn't run into the "--super-prefix" message it was asserting
> the output it didn't have. Let's instead assert the full output that
> we *do* have, which we can do here as this is based on a change[4] to
> make it predictable (until [4] it contained absolute paths).
>
> We could also remove the test entirely (as [5] did), but even though
> the initial reason for having it is gone we're still getting some
> marginal benefit from testing the "fsmonitor" and "submodule
> absorbgitdirs" interaction, so let's keep it.
I'm a bit ambivalent on this, especially since we're testing "submodule
absorbgitdirs" output in "fsmonitor" tests, but as you say, there is
some benefit in testing the interaction. I think we'll have to change
the test though...
> The change here to have either a NULL or non-"" string as a
> "super_prefix" instead of the previous arrangement of "" or non-"" is
> somewhat arbitrary. We could also decide to never have to check for
> NULL.
>
> As we'll be changing the rest of the "git --super-prefix" users to the
> same pattern, leaving them all consistent makes sense. Why not pick ""
> over NULL? Because that's how the "prefix" works[6], and having
> "prefix" and "super_prefix" work the same way will be less
> confusing. That "prefix" picked NULL instead of "" is itself
> arbitrary, but as it's easy to make this small bit of our overall API
> consistent, let's go with that.
Okay, I find consistency with "prefix" convincing, and I do hope that we
use "" someday :)
> index 4abc74db2bb..31526937d95 100755
> --- a/t/t7527-builtin-fsmonitor.sh
> +++ b/t/t7527-builtin-fsmonitor.sh
> @@ -866,30 +866,11 @@ test_expect_success 'submodule always visited' '
> # the submodule, and someone does a `git submodule absorbgitdirs`
> # in the super, Git will recursively invoke `git submodule--helper`
> # to do the work and this may try to read the index. This will
> -# try to start the daemon in the submodule *and* pass (either
> -# directly or via inheritance) the `--super-prefix` arg to the
> -# `git fsmonitor--daemon start` command inside the submodule.
> -# This causes a warning because fsmonitor--daemon does take that
> -# global arg (see the table in git.c)
We've removed mentions of the "--super-prefix", as we should, since
fsmonitor doesn't need to care about "--super-prefix" any more...
> @@ -904,10 +885,12 @@ test_expect_success "stray submodule super-prefix warning" '
>
> test_path_is_dir super/dir_1/dir_2/sub/.git &&
>
> - GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
> - git -C super submodule absorbgitdirs &&
> -
> - ! have_t2_error_event super-sub.trace
> + cat >expect <<-\EOF &&
> + Migrating git directory of '\''dir_1/dir_2/sub'\'' from '\''dir_1/dir_2/sub/.git'\'' to '\''.git/modules/dir_1/dir_2/sub'\''
> + EOF
> + git -C super submodule absorbgitdirs >out 2>actual &&
> + test_cmp expect actual &&
> + test_must_be_empty out
> '
So let's adjust the test to match what we're testing. It's not the
--super-prefix any more, it's the interaction between "submodule
absorbgitdirs" and "fsmonitor--daemon", so perhaps something like:
diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
index 31526937d9..9f947341f5 100755
--- a/t/t7527-builtin-fsmonitor.sh
+++ b/t/t7527-builtin-fsmonitor.sh
@@ -868,7 +868,7 @@ test_expect_success 'submodule always visited' '
# to do the work and this may try to read the index. This will
# try to start the daemon in the submodule.
-test_expect_success "stray submodule super-prefix warning" '
+test_expect_success "submodule absorbgitdirs implicitly starts daemon" '
test_when_finished "rm -rf super; \
rm -rf sub" &&
@@ -888,9 +888,14 @@ test_expect_success "stray submodule super-prefix warning" '
cat >expect <<-\EOF &&
Migrating git directory of '\''dir_1/dir_2/sub'\'' from '\''dir_1/dir_2/sub/.git'\'' to '\''.git/modules/dir_1/dir_2/sub'\''
EOF
- git -C super submodule absorbgitdirs >out 2>actual &&
+ GIT_TRACE2_EVENT="$PWD/.git/trace_absorbgitdirs" \
+ git -C super submodule absorbgitdirs >out 2>actual &&
test_cmp expect actual &&
- test_must_be_empty out
+ test_must_be_empty out &&
+
+ # Confirm that the trace2 log contains a record of the
+ # daemon starting.
+ test_subcommand git fsmonitor--daemon start <.git/trace_absorbgitdirs
'
# On a case-insensitive file system, confirm that the daemon
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v3 4/9] submodule--helper: convert "foreach" to its own "--super-prefix"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (2 preceding siblings ...)
2022-11-19 12:41 ` [PATCH v3 3/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 5/9] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
` (6 subsequent siblings)
10 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper foreach" to use its own "--super-prefix", instead
of relying on the global "--super-prefix" argument to "git"
itself. See that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 9f6ebc64140..7c6f367fa00 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -278,6 +278,7 @@ struct foreach_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
int quiet;
int recursive;
};
@@ -294,7 +295,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
char *displaypath;
displaypath = get_submodule_displaypath(path, info->prefix,
- get_super_prefix());
+ info->super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -364,10 +365,10 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_pushl(&cpr.args, "--super-prefix", NULL);
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive",
NULL);
+ strvec_pushl(&cpr.args, "--super-prefix", NULL);
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (info->quiet)
strvec_push(&cpr.args, "--quiet");
@@ -391,6 +392,7 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
struct option module_foreach_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
OPT_BOOL(0, "recursive", &info.recursive,
N_("recurse into nested submodules")),
@@ -3390,8 +3392,8 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && get_super_prefix())
+ strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v3 5/9] submodule--helper: convert "sync" to its own "--super-prefix"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (3 preceding siblings ...)
2022-11-19 12:41 ` [PATCH v3 4/9] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 6/9] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
` (5 subsequent siblings)
10 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper sync" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 7c6f367fa00..7ac51c3506d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1208,12 +1208,13 @@ static int module_summary(int argc, const char **argv, const char *prefix)
struct sync_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define SYNC_CB_INIT { 0 }
static void sync_submodule(const char *path, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
const struct submodule *sub;
char *remote_key = NULL;
@@ -1244,8 +1245,7 @@ static void sync_submodule(const char *path, const char *prefix,
super_config_url = xstrdup("");
}
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ -1282,10 +1282,11 @@ static void sync_submodule(const char *path, const char *prefix,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "sync",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
+
if (flags & OPT_QUIET)
strvec_push(&cpr.args, "--quiet");
@@ -1308,7 +1309,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct sync_cb *info = cb_data;
- sync_submodule(list_item->name, info->prefix, info->flags);
+ sync_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_sync(int argc, const char **argv, const char *prefix)
@@ -1319,6 +1321,7 @@ static int module_sync(int argc, const char **argv, const char *prefix)
int quiet = 0;
int recursive = 0;
struct option module_sync_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
OPT_BOOL(0, "recursive", &recursive,
N_("recurse into nested submodules")),
@@ -2887,7 +2890,7 @@ static int module_set_url(int argc, const char **argv, const char *prefix)
config_name = xstrfmt("submodule.%s.url", path);
config_set_in_gitmodules_file_gently(config_name, newurl);
- sync_submodule(path, prefix, quiet ? OPT_QUIET : 0);
+ sync_submodule(path, prefix, NULL, quiet ? OPT_QUIET : 0);
free(config_name);
@@ -3392,8 +3395,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
- get_super_prefix())
+ strcmp(subcmd, "status") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v3 6/9] submodule--helper: convert "status" to its own "--super-prefix"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (4 preceding siblings ...)
2022-11-19 12:41 ` [PATCH v3 5/9] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 7/9] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
` (4 subsequent siblings)
10 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 7ac51c3506d..8a186b61b9d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -573,6 +573,7 @@ static int module_init(int argc, const char **argv, const char *prefix)
struct status_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define STATUS_CB_INIT { 0 }
@@ -611,7 +612,7 @@ static int handle_submodule_head_ref(const char *refname UNUSED,
static void status_submodule(const char *path, const struct object_id *ce_oid,
unsigned int ce_flags, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
char *displaypath;
struct strvec diff_files_args = STRVEC_INIT;
@@ -627,8 +628,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ -686,10 +686,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "status",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (flags & OPT_CACHED)
strvec_push(&cpr.args, "--cached");
@@ -713,7 +713,7 @@ static void status_submodule_cb(const struct cache_entry *list_item,
struct status_cb *info = cb_data;
status_submodule(list_item->name, &list_item->oid, list_item->ce_flags,
- info->prefix, info->flags);
+ info->prefix, info->super_prefix, info->flags);
}
static int module_status(int argc, const char **argv, const char *prefix)
@@ -723,6 +723,7 @@ static int module_status(int argc, const char **argv, const char *prefix)
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
struct option module_status_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress submodule status output")),
OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
@@ -3395,7 +3396,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && get_super_prefix())
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v3 7/9] submodule--helper: convert "{update,clone}" to their own "--super-prefix"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (5 preceding siblings ...)
2022-11-19 12:41 ` [PATCH v3 6/9] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-19 12:41 ` [PATCH v3 8/9] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
` (3 subsequent siblings)
10 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git".
We need to convert both of these away from the global "--super-prefix"
at the same time, because "update" will call "clone", but "clone"
itself didn't make use of the global "--super-prefix" for displaying
paths. It was only on the list of sub-commands that accepted it
because "update"'s use of it would set it in its environment.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 32 +++++++++++++-------------------
git.c | 2 +-
2 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 8a186b61b9d..b1945a06da1 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -437,11 +437,13 @@ static int starts_with_dot_dot_slash(const char *const path)
struct init_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define INIT_CB_INIT { 0 }
static void init_submodule(const char *path, const char *prefix,
+ const char *super_prefix,
unsigned int flags)
{
const struct submodule *sub;
@@ -449,8 +451,7 @@ static void init_submodule(const char *path, const char *prefix,
const char *upd;
char *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -526,7 +527,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct init_cb *info = cb_data;
- init_submodule(list_item->name, info->prefix, info->flags);
+ init_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_init(int argc, const char **argv, const char *prefix)
@@ -792,6 +794,7 @@ struct summary_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
unsigned int cached: 1;
unsigned int for_status: 1;
unsigned int files: 1;
@@ -954,7 +957,7 @@ static void generate_submodule_summary(struct summary_cb *info,
}
displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
- get_super_prefix());
+ info->super_prefix);
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ -1893,6 +1896,7 @@ static void submodule_update_clone_release(struct submodule_update_clone *suc)
struct update_data {
const char *prefix;
+ const char *super_prefix;
char *displaypath;
enum submodule_update_type update_default;
struct object_id suboid;
@@ -1969,7 +1973,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
char *key;
const struct update_data *ud = suc->update_data;
char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
- get_super_prefix());
+ ud->super_prefix);
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ -2449,11 +2453,11 @@ static void update_data_to_args(const struct update_data *update_data,
{
enum submodule_update_type update_type = update_data->update_default;
+ strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
if (update_data->displaypath) {
strvec_push(args, "--super-prefix");
strvec_pushf(args, "%s/", update_data->displaypath);
}
- strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
if (update_data->quiet)
strvec_push(args, "--quiet");
@@ -2620,7 +2624,7 @@ static int update_submodules(struct update_data *update_data)
update_data->displaypath = get_submodule_displaypath(
update_data->sm_path, update_data->prefix,
- get_super_prefix());
+ update_data->super_prefix);
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ -2646,6 +2650,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
LIST_OBJECTS_FILTER_INIT;
int ret;
struct option module_update_options[] = {
+ OPT__SUPER_PREFIX(&opt.super_prefix),
OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
OPT_BOOL(0, "init", &opt.init,
N_("initialize uninitialized submodules before update")),
@@ -2742,6 +2747,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
module_list_active(&list);
info.prefix = opt.prefix;
+ info.super_prefix = opt.super_prefix;
if (opt.quiet)
info.flags |= OPT_QUIET;
@@ -3368,8 +3374,6 @@ static int module_add(int argc, const char **argv, const char *prefix)
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
{
- const char *cmd = argv[0];
- const char *subcmd;
parse_opt_subcommand_fn *fn = NULL;
const char *const usage[] = {
N_("git submodule--helper <command>"),
@@ -3393,16 +3397,6 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
OPT_END()
};
argc = parse_options(argc, argv, prefix, options, usage, 0);
- subcmd = argv[0];
-
- if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- get_super_prefix())
- /*
- * xstrfmt() rather than "%s %s" to keep the translated
- * string identical to git.c's.
- */
- die(_("%s doesn't support --super-prefix"),
- xstrfmt("'%s %s'", cmd, subcmd));
return fn(argc, argv, prefix);
}
diff --git a/git.c b/git.c
index b1b7e1a837e..2bca22cfd9a 100644
--- a/git.c
+++ b/git.c
@@ -610,7 +610,7 @@ static struct cmd_struct commands[] = {
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
- { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX },
+ { "submodule--helper", cmd_submodule__helper, RUN_SETUP },
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v3 8/9] read-tree: add "--super-prefix" option, eliminate global
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (6 preceding siblings ...)
2022-11-19 12:41 ` [PATCH v3 7/9] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-22 19:57 ` Glen Choo
2022-11-19 12:41 ` [PATCH v3 9/9] fetch: rename "--submodule-prefix" to "--super-prefix" Ævar Arnfjörð Bjarmason
` (2 subsequent siblings)
10 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
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>
---
Documentation/git.txt | 8 +-------
builtin.h | 4 ----
builtin/checkout.c | 2 +-
builtin/read-tree.c | 1 +
cache.h | 2 --
entry.c | 12 ++++++------
entry.h | 6 +++++-
environment.c | 13 -------------
git.c | 37 +++++--------------------------------
submodule.c | 29 ++++++++++-------------------
submodule.h | 5 ++---
t/t1001-read-tree-m-2way.sh | 2 +-
t/t5616-partial-clone.sh | 2 +-
unpack-trees.c | 23 +++++++++++++----------
unpack-trees.h | 1 +
15 files changed, 47 insertions(+), 100 deletions(-)
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 1d33e083ab8..f9a7a4554cd 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
diff --git a/builtin.h b/builtin.h
index 8901a34d6bf..8264b7e5241 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
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2a132392fbe..dc008fb45e8 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -231,7 +231,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)
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index f4cbe460b97..4b6f22e58c1 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),
diff --git a/cache.h b/cache.h
index 26ed03bd6de..a4a0377b800 100644
--- a/cache.h
+++ b/cache.h
@@ -504,7 +504,6 @@ 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"
@@ -590,7 +589,6 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
int get_common_dir(struct strbuf *sb, const char *gitdir);
const char *get_git_namespace(void);
const char *strip_namespace(const char *namespaced_ref);
-const char *get_super_prefix(void);
const char *get_git_work_tree(void);
/*
diff --git a/entry.c b/entry.c
index 616e4f073c1..971ab268714 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)
diff --git a/entry.h b/entry.h
index 9be4659881e..2d4fbb88c8f 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);
diff --git a/environment.c b/environment.c
index 18d042b467d..1ee3686fd8a 100644
--- a/environment.c
+++ b/environment.c
@@ -102,8 +102,6 @@ char *git_work_tree_cfg;
static char *git_namespace;
-static char *super_prefix;
-
/*
* Repository-local GIT_* environment variables; see cache.h for details.
*/
@@ -121,7 +119,6 @@ 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
@@ -234,16 +231,6 @@ const char *strip_namespace(const char *namespaced_ref)
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;
/*
diff --git a/git.c b/git.c
index 2bca22cfd9a..00baaf23590 100644
--- a/git.c
+++ b/git.c
@@ -14,9 +14,8 @@
* RUN_SETUP for reading from the configuration file.
*/
#define NEED_WORK_TREE (1<<3)
-#define SUPPORT_SUPER_PREFIX (1<<4)
-#define DELAY_PAGER_CONFIG (1<<5)
-#define NO_PARSEOPT (1<<6) /* parse-options is not used */
+#define DELAY_PAGER_CONFIG (1<<4)
+#define NO_PARSEOPT (1<<5) /* parse-options is not used */
struct cmd_struct {
const char *cmd;
@@ -29,8 +28,7 @@ const char git_usage_string[] =
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
- " [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
- " <command> [<args>]");
+ " [--config-env=<name>=<envvar>] <command> [<args>]");
const char git_more_info_string[] =
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);
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;
@@ -449,11 +433,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
trace_repo_setup(prefix);
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)
setup_work_tree();
@@ -504,7 +483,7 @@ static struct cmd_struct commands[] = {
{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
{ "checkout--worker", cmd_checkout__worker,
- RUN_SETUP | NEED_WORK_TREE | SUPPORT_SUPER_PREFIX },
+ RUN_SETUP | NEED_WORK_TREE },
{ "checkout-index", cmd_checkout_index,
RUN_SETUP | NEED_WORK_TREE},
{ "cherry", cmd_cherry, RUN_SETUP },
@@ -583,7 +562,7 @@ static struct cmd_struct commands[] = {
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
{ "push", cmd_push, RUN_SETUP },
{ "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 },
{ "receive-pack", cmd_receive_pack },
{ "reflog", cmd_reflog, RUN_SETUP },
@@ -727,9 +706,6 @@ static void execv_dashed_external(const char **argv)
struct child_process cmd = CHILD_PROCESS_INIT;
int status;
- if (get_super_prefix())
- die(_("%s doesn't support --super-prefix"), argv[0]);
-
if (use_pager == -1 && !is_builtin(argv[0]))
use_pager = check_pager_config(argv[0]);
commit_pager_choice();
@@ -799,9 +775,6 @@ static int run_argv(int *argcp, const char ***argv)
*/
trace2_cmd_name("_run_git_alias_");
- if (get_super_prefix())
- die("%s doesn't support --super-prefix", **argv);
-
commit_pager_choice();
strvec_push(&cmd.args, "git");
diff --git a/submodule.c b/submodule.c
index 3383c47c719..f8497793790 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2048,14 +2048,6 @@ void submodule_unset_core_worktree(const struct submodule *sub)
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)
{
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2074,7 +2066,7 @@ static int submodule_has_dirty_index(const struct submodule *sub)
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;
prepare_submodule_repo_env(&cp.env);
@@ -2083,10 +2075,10 @@ static void submodule_reset_index(const char *path)
cp.no_stdin = 1;
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 */
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());
@@ -2099,10 +2091,9 @@ static void submodule_reset_index(const char *path)
* For edge cases (a submodule coming into existence or removing a submodule)
* pass NULL for old or new respectively.
*/
-int submodule_move_head(const char *path,
- const char *old_head,
- const char *new_head,
- unsigned flags)
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
+ unsigned flags)
{
int ret = 0;
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2140,7 +2131,7 @@ int submodule_move_head(const char *path,
if (old_head) {
if (!submodule_uses_gitfile(path))
absorb_git_dir_into_superproject(path,
- get_super_prefix());
+ super_prefix);
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2149,7 +2140,7 @@ int submodule_move_head(const char *path,
strbuf_release(&gitdir);
/* make sure the index is clean as well */
- submodule_reset_index(path);
+ submodule_reset_index(path, NULL);
}
if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
@@ -2167,9 +2158,9 @@ int submodule_move_head(const char *path,
cp.no_stdin = 1;
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_pushf(&cp.args, "--super-prefix=%s%s/",
+ (super_prefix ? super_prefix : ""), path);
if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN)
strvec_push(&cp.args, "-n");
diff --git a/submodule.h b/submodule.h
index f90ee547d08..c55a25ca37d 100644
--- a/submodule.h
+++ b/submodule.h
@@ -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_FORCE (1<<1)
-int submodule_move_head(const char *path,
- const char *old,
- const char *new_head,
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
unsigned flags);
void submodule_unset_core_worktree(const struct submodule *sub);
diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh
index 516a6112fdc..3fb1b0c162d 100755
--- a/t/t1001-read-tree-m-2way.sh
+++ b/t/t1001-read-tree-m-2way.sh
@@ -370,7 +370,7 @@ test_expect_success 'read-tree supports the super-prefix' '
cat <<-EOF >expect &&
error: Updating '\''fictional/a'\'' would lose untracked files in it
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
'
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 2846ec6629c..f519d2a87a7 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,7 +644,7 @@ test_expect_success 'repack does not loosen promisor objects' '
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
test_config_global protocol.file.allow always &&
diff --git a/unpack-trees.c b/unpack-trees.c
index bae812156c4..61c02285454 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -71,7 +71,7 @@ static const char *unpack_plumbing_errors[NB_UNPACK_TREES_WARNING_TYPES] = {
? ((o)->msgs[(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
@@ -83,7 +83,6 @@ static const char *super_prefixed(const char *path)
static unsigned idx = ARRAY_SIZE(buf) - 1;
if (super_prefix_len < 0) {
- const char *super_prefix = get_super_prefix();
if (!super_prefix) {
super_prefix_len = 0;
} else {
@@ -236,7 +235,8 @@ static int add_rejected_path(struct unpack_trees_options *o,
return -1;
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
@@ -263,7 +263,8 @@ static void display_error_msgs(struct unpack_trees_options *o)
error_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -290,7 +291,8 @@ static void display_warning_msgs(struct unpack_trees_options *o)
warning_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -312,7 +314,7 @@ static int check_submodule_move_head(const struct cache_entry *ce,
if (o->reset)
flags |= SUBMODULE_MOVE_HEAD_FORCE;
- if (submodule_move_head(ce->name, old_id, new_id, flags))
+ if (submodule_move_head(ce->name, NULL, old_id, new_id, flags))
return add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
return 0;
}
@@ -415,6 +417,7 @@ static int check_updates(struct unpack_trees_options *o,
int i, pc_workers, pc_threshold;
trace_performance_enter();
+ state.super_prefix = o->super_prefix;
state.force = 1;
state.quiet = 1;
state.refresh_cache = 1;
@@ -445,7 +448,7 @@ static int check_updates(struct unpack_trees_options *o,
if (ce->ce_flags & CE_WT_REMOVE) {
display_progress(progress, ++cnt);
- unlink_entry(ce);
+ unlink_entry(ce, o->super_prefix);
}
}
@@ -2958,8 +2961,8 @@ int bind_merge(const struct cache_entry * const *src,
if (a && old)
return o->quiet ? -1 :
error(ERRORMSG(o, ERROR_BIND_OVERLAP),
- super_prefixed(a->name),
- super_prefixed(old->name));
+ super_prefixed(a->name, o->super_prefix),
+ super_prefixed(old->name, o->super_prefix));
if (!a)
return keep_entry(old, o);
else
@@ -3020,7 +3023,7 @@ int stash_worktree_untracked_merge(const struct cache_entry * const *src,
if (worktree && untracked)
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);
}
diff --git a/unpack-trees.h b/unpack-trees.h
index efb9edfbb27..9b81e284073 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -74,6 +74,7 @@ struct unpack_trees_options {
dry_run;
enum unpack_trees_reset_type reset;
const char *prefix;
+ const char *super_prefix;
int cache_bottom;
struct pathspec *pathspec;
merge_fn_t fn;
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v3 8/9] read-tree: add "--super-prefix" option, eliminate global
2022-11-19 12:41 ` [PATCH v3 8/9] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
@ 2022-11-22 19:57 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-22 19:57 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> @@ -2149,7 +2140,7 @@ int submodule_move_head(const char *path,
> strbuf_release(&gitdir);
>
> /* make sure the index is clean as well */
> - submodule_reset_index(path);
> + submodule_reset_index(path, NULL);
> }
>
> if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
Here, and..
> @@ -312,7 +314,7 @@ static int check_submodule_move_head(const struct cache_entry *ce,
> if (o->reset)
> flags |= SUBMODULE_MOVE_HEAD_FORCE;
>
> - if (submodule_move_head(ce->name, old_id, new_id, flags))
> + if (submodule_move_head(ce->name, NULL, old_id, new_id, flags))
> return add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
> return 0;
> }
here I think we should be passing a non-NULL value to super_prefix.
Perhaps this was missed when going through the v2 feedback [1]?
[1] https://lore.kernel.org/git/kl6lv8nhnpba.fsf@chooglen-macbookpro.roam.corp.google.com
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v3 9/9] fetch: rename "--submodule-prefix" to "--super-prefix"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (7 preceding siblings ...)
2022-11-19 12:41 ` [PATCH v3 8/9] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
@ 2022-11-19 12:41 ` Ævar Arnfjörð Bjarmason
2022-11-22 22:29 ` [PATCH v3 0/9] Get rid of "git --super-prefix" Glen Choo
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
10 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-11-19 12:41 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
In preceding commits we've introduced a command-level "--super-prefix"
option, which unlike the "git --super-prefix" it replaced doesn't rely
on setenv() or getenv(), it's just a normal command-line option that
the command passes down.
Since we've done that, let's rename the "--submodule-prefix" option
added in 7dce19d374a (fetch/pull: Add the --recurse-submodules option,
2010-11-12) to "--super-prefix" for consistency. This:
* Allows us to use OPT__SUPER_PREFIX().
* Leaves an unspecified "--super-prefix" with a "NULL" value, rather
than an empty string, as is the case with the other "--super-prefix"
users. We coerce the NULL to "" in submodule.c before using it.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
Documentation/fetch-options.txt | 5 -----
builtin/fetch.c | 7 +++----
submodule.c | 23 +++++++++++------------
3 files changed, 14 insertions(+), 21 deletions(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 622bd84768b..20cbd2c2910 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -241,11 +241,6 @@ endif::git-pull[]
linkgit:git-config[1].
ifndef::git-pull[]
---submodule-prefix=<path>::
- Prepend <path> to paths printed in informative messages
- such as "Fetching submodule foo". This option is used
- internally when recursing over submodules.
-
--recurse-submodules-default=[yes|on-demand]::
This option is used internally to temporarily provide a
non-negative default value for the --recurse-submodules
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7378cafeec9..353bcd36d24 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -74,7 +74,7 @@ static struct string_list deepen_not = STRING_LIST_INIT_NODUP;
static struct strbuf default_rla = STRBUF_INIT;
static struct transport *gtransport;
static struct transport *gsecondary;
-static const char *submodule_prefix = "";
+static const char *super_prefix;
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
@@ -195,8 +195,7 @@ static struct option builtin_fetch_options[] = {
OPT_SET_INT_F(0, "refetch", &refetch,
N_("re-fetch without negotiating common commits"),
1, PARSE_OPT_NONEG),
- { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
- N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
+ OPT__SUPER_PREFIX(&super_prefix),
OPT_CALLBACK_F(0, "recurse-submodules-default",
&recurse_submodules_default, N_("on-demand"),
N_("default for recursive fetching of submodules "
@@ -2300,7 +2299,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
add_options_to_argv(&options);
result = fetch_submodules(the_repository,
&options,
- submodule_prefix,
+ super_prefix,
recurse_submodules,
recurse_submodules_default,
verbosity < 0,
diff --git a/submodule.c b/submodule.c
index f8497793790..3e0aaaa2af0 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1376,7 +1376,7 @@ struct submodule_parallel_fetch {
int changed_count;
struct strvec args;
struct repository *r;
- const char *prefix;
+ const char *super_prefix;
int command_line_option;
int default_option;
int quiet;
@@ -1567,7 +1567,7 @@ get_fetch_task_from_index(struct submodule_parallel_fetch *spf,
if (task->repo) {
if (!spf->quiet)
strbuf_addf(err, _("Fetching submodule %s%s\n"),
- spf->prefix, ce->name);
+ spf->super_prefix, ce->name);
spf->index_count++;
return task;
@@ -1629,7 +1629,7 @@ get_fetch_task_from_changed(struct submodule_parallel_fetch *spf,
if (!spf->quiet)
strbuf_addf(err,
_("Fetching submodule %s%s at commit %s\n"),
- spf->prefix, task->sub->path,
+ spf->super_prefix, task->sub->path,
find_unique_abbrev(cs_data->super_oid,
DEFAULT_ABBREV));
@@ -1687,11 +1687,10 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
strvec_pushv(&cp->args, task->git_args.v);
strvec_pushv(&cp->args, spf->args.v);
strvec_push(&cp->args, task->default_argv);
- strvec_push(&cp->args, "--submodule-prefix");
+ strvec_push(&cp->args, "--super-prefix");
- strbuf_addf(&submodule_prefix, "%s%s/",
- spf->prefix,
- task->sub->path);
+ strbuf_addf(&submodule_prefix, "%s%s/", spf->super_prefix,
+ task->sub->path);
strvec_push(&cp->args, submodule_prefix.buf);
*task_cb = task;
@@ -1707,7 +1706,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
spf->oid_fetch_tasks_nr--;
strbuf_addf(&submodule_prefix, "%s%s/",
- spf->prefix, task->sub->path);
+ spf->super_prefix, task->sub->path);
child_process_init(cp);
prepare_submodule_repo_env_in_gitdir(&cp->env);
@@ -1717,7 +1716,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
strvec_init(&cp->args);
strvec_pushv(&cp->args, spf->args.v);
strvec_push(&cp->args, "on-demand");
- strvec_push(&cp->args, "--submodule-prefix");
+ strvec_push(&cp->args, "--super-prefix");
strvec_push(&cp->args, submodule_prefix.buf);
/* NEEDSWORK: have get_default_remote from submodule--helper */
@@ -1813,7 +1812,7 @@ static int fetch_finish(int retvalue, struct strbuf *err,
int fetch_submodules(struct repository *r,
const struct strvec *options,
- const char *prefix, int command_line_option,
+ const char *super_prefix, int command_line_option,
int default_option,
int quiet, int max_parallel_jobs)
{
@@ -1835,7 +1834,7 @@ int fetch_submodules(struct repository *r,
spf.command_line_option = command_line_option;
spf.default_option = default_option;
spf.quiet = quiet;
- spf.prefix = prefix;
+ spf.super_prefix = super_prefix ? super_prefix : "";
if (!r->worktree)
goto out;
@@ -1847,7 +1846,7 @@ int fetch_submodules(struct repository *r,
for (i = 0; i < options->nr; i++)
strvec_push(&spf.args, options->v[i]);
strvec_push(&spf.args, "--recurse-submodules-default");
- /* default value, "--submodule-prefix" and its value are added later */
+ /* default value, "--super-prefix" and its value are added later */
calculate_changed_submodule_paths(r, &spf.changed_submodule_names);
string_list_sort(&spf.changed_submodule_names);
--
2.38.0.1509.g9445af83948
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v3 0/9] Get rid of "git --super-prefix"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (8 preceding siblings ...)
2022-11-19 12:41 ` [PATCH v3 9/9] fetch: rename "--submodule-prefix" to "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-11-22 22:29 ` Glen Choo
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
10 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-11-22 22:29 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Thanks! I think we're close to getting this merged :)
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> = Changes since v2:
>
> * Fixes for test_when_finished() in test setup, and got rid of
> redundant test_config_global.
>
> * There's a new 2/9, which passes along get_super_prefix() as a
> parameter. This allows us to gradually replace it, and drop the
> *_sp() variants of functions that the previous version introduced,
> and it adds "super_prefix" to the absorb_git_dir_into_superproject()
> call in submodule_move_head(), which as Glen noticed I'd missed
>
> * Squashed the "deinit" change into that 2/9.
>
> * Explain why we keep the "fsmonitor" test bits that we do.
>
> * Dropped the new "git branch" output tests, turns out I was just
> wrong, and was conflating it with the subsequent read-tree
> invocation...
>
> So, this should address all outstanding feedbakc, unless I've missed
> something.
As noted in [1], I think we might have missed some sites where we should
pass super_prefix.
[1] https://lore.kernel.org/git/kl6lcz9eep9k.fsf@chooglen-macbookpro.roam.corp.google.com,
> The one loose end here is that I still have no idea if you can invoke
> get "read-tree" to invoke that submodule_move_head() in such a way as
> to have the "super_prefix" used, I've failed to come up with a test
> case for that.
>
> But for the purposes of this topic it doesn't really matter. In 8/10
> we'll start passing the new "--super-prefix" that "read-tree" gets
> down to that function. At worst we're handing it to it redundantly,
> but that was the case before too.
>
> So we can leave potentially turning that into a "NULL" for some other
> time, for now providing the "super_prefix" is harmless, and guarantees
> that we avoid any regression in that area from not providing it, in
> case I've missed a way to have it matter in that case.
Yeah, I tried to do the same too, and it turned out to be harder than
expected. The "absorbgitdir during read-tree" code is definitely in use
(e.g. by t1013), so it's certainly possible, but as you noted, I don't
really think it matters as long as we avoid a regression for the time
being.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v4 0/9] Get rid of "git --super-prefix"
2022-11-19 12:41 ` [PATCH v3 0/9] " Ævar Arnfjörð Bjarmason
` (9 preceding siblings ...)
2022-11-22 22:29 ` [PATCH v3 0/9] Get rid of "git --super-prefix" Glen Choo
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests Ævar Arnfjörð Bjarmason
` (11 more replies)
10 siblings, 12 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
For a general summary see the v3's CL at
https://lore.kernel.org/git/cover-v3-0.9-00000000000-20221119T122853Z-avarab@gmail.com/
Changes since v4:
* This isn't on top of the now-ejected "ab/submodule-no-abspath" any
longer. Per
https://lore.kernel.org/git/kl6la647ow7e.fsf@chooglen-macbookpro.roam.corp.google.com/
we're not changing the output here anymore
* Extract & amend the test that "ab/submodule-no-abspath" added to
test the existing behavior (using $(pwd) now).
* There were a couple of cases where I missed passing the
"super_prefix", per earlier discussions we haven't found cases where
it's used in practice, but let's keep diligently passing it along.
* I ejected the previous 10/10 to refactor "git fetch". I have more
patches on top of this to do some post-refactoring (e.g. saving
memory churn by getting rid of "submodule_prefix" from "struct
repository"), but none of that's essential for now, so let's drop
that patch.
Junio: There's a conflict here in t/t7527* with
ed/fsmonitor-inotify. The conflict is easily solved. This side should
be kept, except for the new "git -C ..." command that was added to
test_when_finished(), which needs to be carried over. A --remerge-diff
off the solved conflict:
diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
remerge CONFLICT (content): Merge conflict in t/t7527-builtin-fsmonitor.sh
index 40c96c5f819..963c4df461e 100755
--- a/t/t7527-builtin-fsmonitor.sh
+++ b/t/t7527-builtin-fsmonitor.sh
@@ -933,20 +933,8 @@ test_expect_success 'submodule always visited' '
# to do the work and this may try to read the index. This will
# try to start the daemon in the submodule.
-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 4824f33224f (read-tree: add "--super-prefix" option, eliminate global)
test_expect_success "submodule absorbgitdirs implicitly starts daemon" '
- test_when_finished "rm -rf super; \
-================================
-have_t2_error_event () {
- log=$1
- msg="fsmonitor--daemon doesnQt support --super-prefix" &&
-
- tr '\047' Q <$1 | grep -e "$msg"
-}
-
-test_expect_success "stray submodule super-prefix warning" '
test_when_finished "git -C super/dir_1/dir_2/sub fsmonitor--daemon stop; \
rm -rf super; \
->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> f4fb2e9797d (Merge branch 'so/diff-merges-more' into seen)
rm -rf sub; \
rm super-sub.trace" &&
Branch & passing CI at:
https://github.com/avar/git/tree/avar/nuke-global-super-prefix-use-local-4
Glen Choo (1):
read-tree + fetch tests: test failing "--super-prefix" interaction
Ævar Arnfjörð Bjarmason (8):
submodule absorbgitdirs tests: add missing "Migrating git..." tests
submodule.c & submodule--helper: pass along "super_prefix" param
submodule--helper: don't use global --super-prefix in "absorbgitdirs"
submodule--helper: convert "foreach" to its own "--super-prefix"
submodule--helper: convert "sync" to its own "--super-prefix"
submodule--helper: convert "status" to its own "--super-prefix"
submodule--helper: convert "{update,clone}" to their own
"--super-prefix"
read-tree: add "--super-prefix" option, eliminate global
Documentation/git.txt | 8 +--
builtin.h | 4 --
builtin/checkout.c | 2 +-
builtin/read-tree.c | 1 +
builtin/rm.c | 2 +-
builtin/submodule--helper.c | 87 ++++++++++++++++--------------
cache.h | 2 -
entry.c | 12 ++---
entry.h | 6 ++-
environment.c | 13 -----
git.c | 41 +++-----------
parse-options.h | 4 ++
submodule.c | 50 ++++++++---------
submodule.h | 8 +--
t/t1001-read-tree-m-2way.sh | 2 +-
t/t5616-partial-clone.sh | 43 +++++++++++++++
t/t7412-submodule-absorbgitdirs.sh | 64 +++++++++++++++++++---
t/t7527-builtin-fsmonitor.sh | 36 +++++--------
unpack-trees.c | 24 +++++----
unpack-trees.h | 1 +
20 files changed, 230 insertions(+), 180 deletions(-)
Range-diff against v3:
1: 5f463bbefb5 ! 1: f479003941b submodule--helper absorbgitdirs: no abspaths in "Migrating git..."
@@ Metadata
Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## Commit message ##
- submodule--helper absorbgitdirs: no abspaths in "Migrating git..."
+ submodule absorbgitdirs tests: add missing "Migrating git..." tests
- Change the "Migrating git directory" messages to avoid emitting
- absolute paths. We could use "old_git_dir" and "new_gitdir.buf" here
- sometimes, but not in all the cases covered by these tests,
- i.e. sometimes the latter will be an absolute path with a different
- prefix.
+ Fix a blind spots in the tests surrounding "submodule absorbgitdirs"
+ and test what output we emit, and how emitted the message and behavior
+ interacts with a "git worktree" where the repository isn't at the base
+ of the working directory.
- So let's just strip off the common prefix of the two strings, which
- handles the cases where we have nested submodules nicely. Note that
- this case is different than the one in get_submodule_displaypath() in
- "builtin/submodule--helper.c" handles, as we're dealing with the paths
- to the two ".git" here, not worktree paths.
-
- Before this change we had no tests at all for this "Migrating git
- directory" output.
+ The "$(pwd)" instead of "$PWD" here is needed due to Windows, where
+ the latter will be a path like "/d/a/git/[...]", whereas we need
+ "D:/a/git/[...]".
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- ## submodule.c ##
-@@ submodule.c: static void relocate_single_git_dir_into_superproject(const char *path)
- char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL;
- struct strbuf new_gitdir = STRBUF_INIT;
- const struct submodule *sub;
-+ size_t off = 0;
-
- if (submodule_uses_worktrees(path))
- die(_("relocate_gitdir for submodule '%s' with "
-@@ submodule.c: static void relocate_single_git_dir_into_superproject(const char *path)
- die(_("could not create directory '%s'"), new_gitdir.buf);
- real_new_git_dir = real_pathdup(new_gitdir.buf, 1);
-
-- fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"),
-+ while (real_old_git_dir[off] && real_new_git_dir[off] &&
-+ 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,
-- real_old_git_dir, real_new_git_dir);
-+ real_old_git_dir + off, real_new_git_dir + off);
-
- relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
-
-
## t/t7412-submodule-absorbgitdirs.sh ##
+@@ t/t7412-submodule-absorbgitdirs.sh: TEST_PASSES_SANITIZE_LEAK=true
+ . ./test-lib.sh
+
+ test_expect_success 'setup a real submodule' '
++ cwd="$(pwd)" &&
+ git init sub1 &&
+ test_commit -C sub1 first &&
+ git submodule add ./sub1 &&
@@ t/t7412-submodule-absorbgitdirs.sh: test_expect_success 'setup a real submodule' '
'
@@ t/t7412-submodule-absorbgitdirs.sh: test_expect_success 'setup a real submodule'
git status >expect.1 &&
git -C sub1 rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
-+ cat >expect <<-\EOF &&
-+ Migrating git directory of '\''sub1'\'' from '\''sub1/.git'\'' to '\''.git/modules/sub1'\''
++ cat >expect <<-EOF &&
++ Migrating git directory of '\''sub1'\'' from
++ '\''$cwd/sub1/.git'\'' to
++ '\''$cwd/.git/modules/sub1'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
@@ t/t7412-submodule-absorbgitdirs.sh: test_expect_success 'setup nested submodule'
git status >expect.1 &&
git -C sub1/nested rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
-+ cat >expect <<-\EOF &&
-+ Migrating git directory of '\''sub1/nested'\'' from '\''sub1/nested/.git'\'' to '\''.git/modules/sub1/modules/nested'\''
++ cat >expect <<-EOF &&
++ Migrating git directory of '\''sub1/nested'\'' from
++ '\''$cwd/sub1/nested/.git'\'' to
++ '\''$cwd/.git/modules/sub1/modules/nested'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
@@ t/t7412-submodule-absorbgitdirs.sh: test_expect_success 're-setup nested submodu
git status >expect.1 &&
git -C sub1/nested rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
-+ cat >expect <<-\EOF &&
-+ Migrating git directory of '\''sub1'\'' from '\''sub1/.git'\'' to '\''.git/modules/sub1'\''
++ cat >expect <<-EOF &&
++ Migrating git directory of '\''sub1'\'' from
++ '\''$cwd/sub1/.git'\'' to
++ '\''$cwd/.git/modules/sub1'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
test -f sub1/.git &&
test -f sub1/nested/.git &&
test -d .git/modules/sub1/modules/nested &&
+@@ t/t7412-submodule-absorbgitdirs.sh: test_expect_success 'absorb the git dir in a nested submodule' '
+ test_cmp expect.2 actual.2
+ '
+
++test_expect_success 'absorb the git dir outside of primary worktree' '
++ test_when_finished "rm -rf repo-bare.git" &&
++ git clone --bare . repo-bare.git &&
++ test_when_finished "rm -rf repo-wt" &&
++ git -C repo-bare.git worktree add ../repo-wt &&
++
++ test_when_finished "rm -f .gitconfig" &&
++ test_config_global protocol.file.allow always &&
++ git -C repo-wt submodule update --init &&
++ git init repo-wt/sub2 &&
++ test_commit -C repo-wt/sub2 A &&
++ git -C repo-wt submodule add ./sub2 sub2 &&
++ cat >expect <<-EOF &&
++ Migrating git directory of '\''sub2'\'' from
++ '\''$cwd/repo-wt/sub2/.git'\'' to
++ '\''$cwd/repo-bare.git/worktrees/repo-wt/modules/sub2'\''
++ EOF
++ DO_IT=1 git -C repo-wt submodule absorbgitdirs 2>actual &&
++ test_cmp expect actual
++'
++
+ test_expect_success 'setup a gitlink with missing .gitmodules entry' '
+ git init sub2 &&
+ test_commit -C sub2 first &&
@@ t/t7412-submodule-absorbgitdirs.sh: test_expect_success 'setup a gitlink with missing .gitmodules entry' '
test_expect_success 'absorbing the git dir fails for incomplete submodules' '
git status >expect.1 &&
2: c930fc38356 = 2: 6424307a432 read-tree + fetch tests: test failing "--super-prefix" interaction
3: 2e4a2236898 = 3: b2e543bde03 submodule.c & submodule--helper: pass along "super_prefix" param
4: 6e10a47c60a ! 4: bde9038c4e3 submodule--helper: don't use global --super-prefix in "absorbgitdirs"
@@ submodule.c: int validate_submodule_git_dir(char *git_dir, const char *submodule
char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL;
struct strbuf new_gitdir = STRBUF_INIT;
@@ submodule.c: 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"),
+ real_new_git_dir = real_pathdup(new_gitdir.buf, 1);
+
+ fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"),
- get_super_prefix_or_empty(), path,
+ super_prefix ? super_prefix : "", path,
- real_old_git_dir + off, real_new_git_dir + off);
+ real_old_git_dir, real_new_git_dir);
relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
@@ submodule.c: static void absorb_git_dir_into_superproject_recurse(const char *path,
@@ t/t7527-builtin-fsmonitor.sh: test_expect_success 'submodule always visited' '
-}
+# try to start the daemon in the submodule.
- test_expect_success "stray submodule super-prefix warning" '
+-test_expect_success "stray submodule super-prefix warning" '
++test_expect_success "submodule absorbgitdirs implicitly starts daemon" '
test_when_finished "rm -rf super; \
-- rm -rf sub; \
-- rm super-sub.trace" &&
-+ rm -rf sub" &&
-
- create_super super &&
- create_sub sub &&
+ rm -rf sub; \
+ rm super-sub.trace" &&
@@ t/t7527-builtin-fsmonitor.sh: test_expect_success "stray submodule super-prefix warning" '
test_path_is_dir super/dir_1/dir_2/sub/.git &&
-- GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
-- git -C super submodule absorbgitdirs &&
--
-- ! have_t2_error_event super-sub.trace
-+ cat >expect <<-\EOF &&
-+ Migrating git directory of '\''dir_1/dir_2/sub'\'' from '\''dir_1/dir_2/sub/.git'\'' to '\''.git/modules/dir_1/dir_2/sub'\''
++ cwd="$(cd super && pwd)" &&
++ cat >expect <<-EOF &&
++ Migrating git directory of '\''dir_1/dir_2/sub'\'' from
++ '\''$cwd/dir_1/dir_2/sub/.git'\'' to
++ '\''$cwd/.git/modules/dir_1/dir_2/sub'\''
+ EOF
-+ git -C super submodule absorbgitdirs >out 2>actual &&
+ GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
+- git -C super submodule absorbgitdirs &&
++ git -C super submodule absorbgitdirs >out 2>actual &&
+ test_cmp expect actual &&
-+ test_must_be_empty out
++ test_must_be_empty out &&
+
+- ! have_t2_error_event super-sub.trace
++ # Confirm that the trace2 log contains a record of the
++ # daemon starting.
++ test_subcommand git fsmonitor--daemon start <super-sub.trace
'
# On a case-insensitive file system, confirm that the daemon
5: da86eb3b867 = 5: 4da58e7ea50 submodule--helper: convert "foreach" to its own "--super-prefix"
6: 2eb583148a6 = 6: 8dff576df7d submodule--helper: convert "sync" to its own "--super-prefix"
7: 8d8925c7e1f = 7: 8800a433e29 submodule--helper: convert "status" to its own "--super-prefix"
8: 754a7489aa5 = 8: 54c1e29de1e submodule--helper: convert "{update,clone}" to their own "--super-prefix"
9: f952fa3d01f ! 9: 4824f33224f read-tree: add "--super-prefix" option, eliminate global
@@ submodule.c: int submodule_move_head(const char *path,
/* make sure the index is clean as well */
- submodule_reset_index(path);
-+ submodule_reset_index(path, NULL);
++ submodule_reset_index(path, super_prefix);
}
if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
@@ unpack-trees.c: static int check_submodule_move_head(const struct cache_entry *c
flags |= SUBMODULE_MOVE_HEAD_FORCE;
- if (submodule_move_head(ce->name, old_id, new_id, flags))
-+ if (submodule_move_head(ce->name, NULL, 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 0;
}
@@ unpack-trees.c: int stash_worktree_untracked_merge(const struct cache_entry * co
## unpack-trees.h ##
@@ unpack-trees.h: struct unpack_trees_options {
- dry_run;
+ skip_cache_tree_update;
enum unpack_trees_reset_type reset;
const char *prefix;
+ const char *super_prefix;
10: 1aa4019527a < -: ----------- fetch: rename "--submodule-prefix" to "--super-prefix"
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v4 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 20:54 ` Glen Choo
2022-12-15 9:32 ` [PATCH v4 2/9] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
` (10 subsequent siblings)
11 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
Fix a blind spots in the tests surrounding "submodule absorbgitdirs"
and test what output we emit, and how emitted the message and behavior
interacts with a "git worktree" where the repository isn't at the base
of the working directory.
The "$(pwd)" instead of "$PWD" here is needed due to Windows, where
the latter will be a path like "/d/a/git/[...]", whereas we need
"D:/a/git/[...]".
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/t7412-submodule-absorbgitdirs.sh | 64 ++++++++++++++++++++++++++----
1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
index 2859695c6d2..d556342ea57 100755
--- a/t/t7412-submodule-absorbgitdirs.sh
+++ b/t/t7412-submodule-absorbgitdirs.sh
@@ -10,6 +10,7 @@ TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup a real submodule' '
+ cwd="$(pwd)" &&
git init sub1 &&
test_commit -C sub1 first &&
git submodule add ./sub1 &&
@@ -18,13 +19,21 @@ test_expect_success 'setup a real submodule' '
'
test_expect_success 'absorb the git dir' '
+ >expect &&
+ >actual &&
>expect.1 &&
>expect.2 &&
>actual.1 &&
>actual.2 &&
git status >expect.1 &&
git -C sub1 rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub1'\'' from
+ '\''$cwd/sub1/.git'\'' to
+ '\''$cwd/.git/modules/sub1'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
git fsck &&
test -f sub1/.git &&
test -d .git/modules/sub1 &&
@@ -37,7 +46,8 @@ test_expect_success 'absorb the git dir' '
test_expect_success 'absorbing does not fail for deinitialized submodules' '
test_when_finished "git submodule update --init" &&
git submodule deinit --all &&
- git submodule absorbgitdirs &&
+ git submodule absorbgitdirs 2>err &&
+ test_must_be_empty err &&
test -d .git/modules/sub1 &&
test -d sub1 &&
! test -e sub1/.git
@@ -56,7 +66,13 @@ test_expect_success 'setup nested submodule' '
test_expect_success 'absorb the git dir in a nested submodule' '
git status >expect.1 &&
git -C sub1/nested rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub1/nested'\'' from
+ '\''$cwd/sub1/nested/.git'\'' to
+ '\''$cwd/.git/modules/sub1/modules/nested'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
test -f sub1/nested/.git &&
test -d .git/modules/sub1/modules/nested &&
git status >actual.1 &&
@@ -87,7 +103,13 @@ test_expect_success 're-setup nested submodule' '
test_expect_success 'absorb the git dir in a nested submodule' '
git status >expect.1 &&
git -C sub1/nested rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub1'\'' from
+ '\''$cwd/sub1/.git'\'' to
+ '\''$cwd/.git/modules/sub1'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
test -f sub1/.git &&
test -f sub1/nested/.git &&
test -d .git/modules/sub1/modules/nested &&
@@ -97,6 +119,27 @@ test_expect_success 'absorb the git dir in a nested submodule' '
test_cmp expect.2 actual.2
'
+test_expect_success 'absorb the git dir outside of primary worktree' '
+ test_when_finished "rm -rf repo-bare.git" &&
+ git clone --bare . repo-bare.git &&
+ test_when_finished "rm -rf repo-wt" &&
+ git -C repo-bare.git worktree add ../repo-wt &&
+
+ test_when_finished "rm -f .gitconfig" &&
+ test_config_global protocol.file.allow always &&
+ git -C repo-wt submodule update --init &&
+ git init repo-wt/sub2 &&
+ test_commit -C repo-wt/sub2 A &&
+ git -C repo-wt submodule add ./sub2 sub2 &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub2'\'' from
+ '\''$cwd/repo-wt/sub2/.git'\'' to
+ '\''$cwd/repo-bare.git/worktrees/repo-wt/modules/sub2'\''
+ EOF
+ DO_IT=1 git -C repo-wt submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup a gitlink with missing .gitmodules entry' '
git init sub2 &&
test_commit -C sub2 first &&
@@ -107,7 +150,11 @@ test_expect_success 'setup a gitlink with missing .gitmodules entry' '
test_expect_success 'absorbing the git dir fails for incomplete submodules' '
git status >expect.1 &&
git -C sub2 rev-parse HEAD >expect.2 &&
- test_must_fail git submodule absorbgitdirs &&
+ cat >expect <<-\EOF &&
+ fatal: could not lookup name for submodule '\''sub2'\''
+ EOF
+ test_must_fail git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
git -C sub2 fsck &&
test -d sub2/.git &&
git status >actual &&
@@ -127,8 +174,11 @@ test_expect_success 'setup a submodule with multiple worktrees' '
'
test_expect_success 'absorbing fails for a submodule with multiple worktrees' '
- test_must_fail git submodule absorbgitdirs sub3 2>error &&
- test_i18ngrep "not supported" error
+ cat >expect <<-\EOF &&
+ fatal: could not lookup name for submodule '\''sub2'\''
+ EOF
+ test_must_fail git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual
'
test_done
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v4 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests
2022-12-15 9:32 ` [PATCH v4 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests Ævar Arnfjörð Bjarmason
@ 2022-12-15 20:54 ` Glen Choo
2022-12-20 10:32 ` Ævar Arnfjörð Bjarmason
0 siblings, 1 reply; 105+ messages in thread
From: Glen Choo @ 2022-12-15 20:54 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
No comment on the structure of the tests themselves; those look good to
me.
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
> index 2859695c6d2..d556342ea57 100755
> --- a/t/t7412-submodule-absorbgitdirs.sh
> +++ b/t/t7412-submodule-absorbgitdirs.sh
> @@ -10,6 +10,7 @@ TEST_PASSES_SANITIZE_LEAK=true
> . ./test-lib.sh
>
> test_expect_success 'setup a real submodule' '
> + cwd="$(pwd)" &&
> git init sub1 &&
> test_commit -C sub1 first &&
> git submodule add ./sub1 &&
[...]
> @@ -18,13 +19,21 @@ test_expect_success 'setup a real submodule' '
> '
>
> test_expect_success 'absorb the git dir' '
> + >expect &&
> + >actual &&
> >expect.1 &&
> >expect.2 &&
> >actual.1 &&
> >actual.2 &&
> git status >expect.1 &&
> git -C sub1 rev-parse HEAD >expect.2 &&
> - git submodule absorbgitdirs &&
> + cat >expect <<-EOF &&
> + Migrating git directory of '\''sub1'\'' from
> + '\''$cwd/sub1/.git'\'' to
> + '\''$cwd/.git/modules/sub1'\''
> + EOF
> + git submodule absorbgitdirs 2>actual &&
> + test_cmp expect actual &&
> git fsck &&
> test -f sub1/.git &&
> test -d .git/modules/sub1 &&
I thought that we typically avoid setting environment variables in the
test cases themselves, so when we set environment variables to be read
in later tests, we typically set them outside of the test case (e.g.
t/t5526-fetch-submodules.sh).
> @@ -97,6 +119,27 @@ test_expect_success 'absorb the git dir in a nested submodule' '
> test_cmp expect.2 actual.2
> '
>
> +test_expect_success 'absorb the git dir outside of primary worktree' '
> + test_when_finished "rm -rf repo-bare.git" &&
> + git clone --bare . repo-bare.git &&
> + test_when_finished "rm -rf repo-wt" &&
> + git -C repo-bare.git worktree add ../repo-wt &&
> +
> + test_when_finished "rm -f .gitconfig" &&
> + test_config_global protocol.file.allow always &&
> + git -C repo-wt submodule update --init &&
> + git init repo-wt/sub2 &&
> + test_commit -C repo-wt/sub2 A &&
> + git -C repo-wt submodule add ./sub2 sub2 &&
> + cat >expect <<-EOF &&
> + Migrating git directory of '\''sub2'\'' from
> + '\''$cwd/repo-wt/sub2/.git'\'' to
> + '\''$cwd/repo-bare.git/worktrees/repo-wt/modules/sub2'\''
> + EOF
> + DO_IT=1 git -C repo-wt submodule absorbgitdirs 2>actual &&
DO_IT is a leftover from dev?
(I'm also curious as to what it does :)).
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v4 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests
2022-12-15 20:54 ` Glen Choo
@ 2022-12-20 10:32 ` Ævar Arnfjörð Bjarmason
0 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 10:32 UTC (permalink / raw)
To: Glen Choo; +Cc: git, Taylor Blau, Robert Coup
On Thu, Dec 15 2022, Glen Choo wrote:
> No comment on the structure of the tests themselves; those look good to
> me.
>
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
>> index 2859695c6d2..d556342ea57 100755
>> --- a/t/t7412-submodule-absorbgitdirs.sh
>> +++ b/t/t7412-submodule-absorbgitdirs.sh
>> @@ -10,6 +10,7 @@ TEST_PASSES_SANITIZE_LEAK=true
>> . ./test-lib.sh
>>
>> test_expect_success 'setup a real submodule' '
>> + cwd="$(pwd)" &&
>> git init sub1 &&
>> test_commit -C sub1 first &&
>> git submodule add ./sub1 &&
>
> [...]
>
>> @@ -18,13 +19,21 @@ test_expect_success 'setup a real submodule' '
>> '
>>
>> test_expect_success 'absorb the git dir' '
>> + >expect &&
>> + >actual &&
>> >expect.1 &&
>> >expect.2 &&
>> >actual.1 &&
>> >actual.2 &&
>> git status >expect.1 &&
>> git -C sub1 rev-parse HEAD >expect.2 &&
>> - git submodule absorbgitdirs &&
>> + cat >expect <<-EOF &&
>> + Migrating git directory of '\''sub1'\'' from
>> + '\''$cwd/sub1/.git'\'' to
>> + '\''$cwd/.git/modules/sub1'\''
>> + EOF
>> + git submodule absorbgitdirs 2>actual &&
>> + test_cmp expect actual &&
>> git fsck &&
>> test -f sub1/.git &&
>> test -d .git/modules/sub1 &&
>
> I thought that we typically avoid setting environment variables in the
> test cases themselves, so when we set environment variables to be read
> in later tests, we typically set them outside of the test case (e.g.
> t/t5526-fetch-submodules.sh).
We could do it either way, but no, I think the preferred style is to do
such setup/assignment in a test_expect_success, we don't run our tests
as "set -e", so we'd miss any errors (however unlikely in this case)
from the commands outside test bodies.
See e.g. t0002-gitfile.sh for the same pattern, i.e. setting the "$REAL"
variable in the setup "test_expect_success", then using it later.
>> @@ -97,6 +119,27 @@ test_expect_success 'absorb the git dir in a nested submodule' '
>> test_cmp expect.2 actual.2
>> '
>>
>> +test_expect_success 'absorb the git dir outside of primary worktree' '
>> + test_when_finished "rm -rf repo-bare.git" &&
>> + git clone --bare . repo-bare.git &&
>> + test_when_finished "rm -rf repo-wt" &&
>> + git -C repo-bare.git worktree add ../repo-wt &&
>> +
>> + test_when_finished "rm -f .gitconfig" &&
>> + test_config_global protocol.file.allow always &&
>> + git -C repo-wt submodule update --init &&
>> + git init repo-wt/sub2 &&
>> + test_commit -C repo-wt/sub2 A &&
>> + git -C repo-wt submodule add ./sub2 sub2 &&
>> + cat >expect <<-EOF &&
>> + Migrating git directory of '\''sub2'\'' from
>> + '\''$cwd/repo-wt/sub2/.git'\'' to
>> + '\''$cwd/repo-bare.git/worktrees/repo-wt/modules/sub2'\''
>> + EOF
>> + DO_IT=1 git -C repo-wt submodule absorbgitdirs 2>actual &&
>
> DO_IT is a leftover from dev?
>
> (I'm also curious as to what it does :)).
Oops, will fix! It was just something for ad-hoc getenv()-debugging that
escaped the lab.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v4 2/9] read-tree + fetch tests: test failing "--super-prefix" interaction
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 3/9] submodule.c & submodule--helper: pass along "super_prefix" param Ævar Arnfjörð Bjarmason
` (9 subsequent siblings)
11 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
From: Glen Choo <chooglen@google.com>
Ever since "git fetch --refetch" was introduced in 0f5e8851737 (Merge
branch 'rc/fetch-refetch', 2022-04-04) the test being added here would
fail. This is because "restore" will "read-tree .. --reset <hash>",
which will in turn invoke "fetch". The "fetch" will then die with:
fatal: fetch doesn't support --super-prefix
This edge case and other "--super-prefix" bugs will be fixed in
subsequent commits, but let's first add a "test_expect_failure" test
for it. It passes until the very last command in the test.
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 037941b95d2..2846ec6629c 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
grep "loosen_unused_packed_objects/loosened:0" trace
'
+test_expect_failure 'lazy-fetch in submodule succeeds' '
+ # setup
+ test_config_global protocol.file.allow always &&
+
+ test_when_finished "rm -rf src-sub" &&
+ git init src-sub &&
+ git -C src-sub config uploadpack.allowfilter 1 &&
+ git -C src-sub config uploadpack.allowanysha1inwant 1 &&
+
+ # This blob must be missing in the subsequent commit.
+ echo foo >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule one" &&
+ SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
+
+ echo bar >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule two" &&
+ SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
+
+ test_when_finished "rm -rf src-super" &&
+ git init src-super &&
+ git -C src-super config uploadpack.allowfilter 1 &&
+ git -C src-super config uploadpack.allowanysha1inwant 1 &&
+ git -C src-super submodule add ../src-sub src-sub &&
+
+ git -C src-super/src-sub checkout $SUB_ONE &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject one" &&
+
+ git -C src-super/src-sub checkout $SUB_TWO &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject two" &&
+
+ # the fetch
+ test_when_finished "rm -rf client" &&
+ git clone --filter=blob:none --also-filter-submodules \
+ --recurse-submodules "file://$(pwd)/src-super" client &&
+
+ # Trigger lazy-fetch from the superproject
+ git -C client restore --recurse-submodules --source=HEAD^ :/
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v4 3/9] submodule.c & submodule--helper: pass along "super_prefix" param
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 2/9] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
` (8 subsequent siblings)
11 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
Start passing the "super_prefix" along as a parameter to
get_submodule_displaypath() and absorb_git_dir_into_superproject(),
rather than get the value directly as a global.
This is in preparation for subsequent commits, where we'll gradually
phase out get_super_prefix() for an alternative way of getting the
"super_prefix".
Most of the users of this get a get_super_prefix() value, either
directly or by indirection. The exceptions are:
- builtin/rm.c: Doesn't declare SUPPORT_SUPER_PREFIX, so we'd have
died if this was provided, so it's safe to passs "NULL".
- deinit_submodule(): The "deinit_submodule()" function has never been
able to use the "git -super-prefix". It will call
"absorb_git_dir_into_superproject()", but it will only do so from the
top-level project.
If "absorbgitdirs" recurses it will use the "path" passed to
"absorb_git_dir_into_superproject()" in "deinit_submodule()" as its
starting "--super-prefix". So we can safely remove the
get_super_prefix() call here, and pass NULL instead.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/rm.c | 2 +-
builtin/submodule--helper.c | 35 ++++++++++++++++++++++-------------
submodule.c | 15 +++++++++------
submodule.h | 3 ++-
4 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/builtin/rm.c b/builtin/rm.c
index d4989d4d863..4a4aec0d00e 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -86,7 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void)
continue;
if (!submodule_uses_gitfile(name))
- absorb_git_dir_into_superproject(name);
+ absorb_git_dir_into_superproject(name, NULL);
}
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 05f2c9bc985..da844cad5ce 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -113,10 +113,9 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int
}
/* the result should be freed by the caller. */
-static char *get_submodule_displaypath(const char *path, const char *prefix)
+static char *get_submodule_displaypath(const char *path, const char *prefix,
+ const char *super_prefix)
{
- const char *super_prefix = get_super_prefix();
-
if (prefix && super_prefix) {
BUG("cannot have prefix '%s' and superprefix '%s'",
prefix, super_prefix);
@@ -294,7 +293,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
struct child_process cp = CHILD_PROCESS_INIT;
char *displaypath;
- displaypath = get_submodule_displaypath(path, info->prefix);
+ displaypath = get_submodule_displaypath(path, info->prefix,
+ get_super_prefix());
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -447,7 +447,8 @@ static void init_submodule(const char *path, const char *prefix,
const char *upd;
char *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -624,7 +625,8 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ -948,7 +950,8 @@ static void generate_submodule_summary(struct summary_cb *info,
dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
}
- displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
+ displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
+ get_super_prefix());
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ -1239,7 +1242,8 @@ static void sync_submodule(const char *path, const char *prefix,
super_config_url = xstrdup("");
}
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ -1365,7 +1369,7 @@ static void deinit_submodule(const char *path, const char *prefix,
if (!sub || !sub->name)
goto cleanup;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix, NULL);
/* remove the submodule work tree (unless the user already did it) */
if (is_directory(path)) {
@@ -1379,7 +1383,7 @@ static void deinit_submodule(const char *path, const char *prefix,
".git file by using absorbgitdirs."),
displaypath);
- absorb_git_dir_into_superproject(path);
+ absorb_git_dir_into_superproject(path, NULL);
}
@@ -1958,7 +1962,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
enum submodule_update_type update_type;
char *key;
const struct update_data *ud = suc->update_data;
- char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
+ char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
+ get_super_prefix());
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ -2608,7 +2613,8 @@ static int update_submodules(struct update_data *update_data)
goto fail;
update_data->displaypath = get_submodule_displaypath(
- update_data->sm_path, update_data->prefix);
+ update_data->sm_path, update_data->prefix,
+ get_super_prefix());
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ -2828,6 +2834,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
+ const char *super_prefix;
struct option embed_gitdir_options[] = {
OPT_END()
};
@@ -2843,8 +2850,10 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
goto cleanup;
+ super_prefix = get_super_prefix();
for (i = 0; i < list.nr; i++)
- absorb_git_dir_into_superproject(list.entries[i]->name);
+ absorb_git_dir_into_superproject(list.entries[i]->name,
+ super_prefix);
ret = 0;
cleanup:
diff --git a/submodule.c b/submodule.c
index 8ac2fca855d..bf19598b8c2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2145,7 +2145,8 @@ int submodule_move_head(const char *path,
if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
if (old_head) {
if (!submodule_uses_gitfile(path))
- absorb_git_dir_into_superproject(path);
+ absorb_git_dir_into_superproject(path,
+ get_super_prefix());
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2315,7 +2316,8 @@ static void relocate_single_git_dir_into_superproject(const char *path)
strbuf_release(&new_gitdir);
}
-static void absorb_git_dir_into_superproject_recurse(const char *path)
+static void absorb_git_dir_into_superproject_recurse(const char *path,
+ const char *super_prefix)
{
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2323,8 +2325,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/",
- get_super_prefix_or_empty(), path);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+ super_prefix : "", path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
prepare_submodule_repo_env(&cp.env);
@@ -2337,7 +2339,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
* having its git directory within the working tree to the git dir nested
* in its superprojects git dir under modules/.
*/
-void absorb_git_dir_into_superproject(const char *path)
+void absorb_git_dir_into_superproject(const char *path,
+ const char *super_prefix)
{
int err_code;
const char *sub_git_dir;
@@ -2386,7 +2389,7 @@ void absorb_git_dir_into_superproject(const char *path)
}
strbuf_release(&gitdir);
- absorb_git_dir_into_superproject_recurse(path);
+ absorb_git_dir_into_superproject_recurse(path, super_prefix);
}
int get_superproject_working_tree(struct strbuf *buf)
diff --git a/submodule.h b/submodule.h
index b52a4ff1e73..f90ee547d08 100644
--- a/submodule.h
+++ b/submodule.h
@@ -164,7 +164,8 @@ 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(const char *path,
+ const char *super_prefix);
/*
* Return the absolute path of the working tree of the superproject, which this
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v4 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (2 preceding siblings ...)
2022-12-15 9:32 ` [PATCH v4 3/9] submodule.c & submodule--helper: pass along "super_prefix" param Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 21:05 ` Glen Choo
2022-12-15 9:32 ` [PATCH v4 5/9] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
` (7 subsequent siblings)
11 siblings, 1 reply; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
The "--super-prefix" facility was introduced in [1] has always been a
transitory hack, which is why we've made it an error to supply it as
an option to "git" to commands that don't know about it.
That's been a good goal, as it has a global effect we haven't wanted
calls to get_super_prefix() from built-ins we didn't expect.
But it has meant that when we've had chains of different built-ins
using it all of the processes in that "chain" have needed to support
it, and worse processes that don't need it have needed to ask for
"SUPPORT_SUPER_PREFIX" because their parent process needs it.
That's how "fsmonitor--daemon" ended up with it, per [2] it's called
from (among other things) "submodule--helper absorbgitdirs", but as we
declared "submodule--helper" as "SUPPORT_SUPER_PREFIX" we needed to
declare "fsmonitor--daemon" as accepting it too, even though it
doesn't care about it.
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.
Let's instead accept a hidden "--super-prefix" option to
"submodule--helper absorbgitdirs" itself.
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.
The "fsmonitor--daemon" test adjusted here was added in [3]. To assert
that it didn't run into the "--super-prefix" message it was asserting
the output it didn't have. Let's instead assert the full output that
we *do* have, which we can do here as this is based on a change[4] to
make it predictable (until [4] it contained absolute paths).
We could also remove the test entirely (as [5] did), but even though
the initial reason for having it is gone we're still getting some
marginal benefit from testing the "fsmonitor" and "submodule
absorbgitdirs" interaction, so let's keep it.
The change here to have either a NULL or non-"" string as a
"super_prefix" instead of the previous arrangement of "" or non-"" is
somewhat arbitrary. We could also decide to never have to check for
NULL.
As we'll be changing the rest of the "git --super-prefix" users to the
same pattern, leaving them all consistent makes sense. Why not pick ""
over NULL? Because that's how the "prefix" works[6], and having
"prefix" and "super_prefix" work the same way will be less
confusing. That "prefix" picked NULL instead of "" is itself
arbitrary, but as it's easy to make this small bit of our overall API
consistent, let's go with that.
1. 74866d75793 (git: make super-prefix option, 2016-10-07)
2. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
4. https://lore.kernel.org/git/patch-1.1-34b54fdd9bb-20221109T020347Z-avarab@gmail.com/
5. https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com/
6. 9725c8dda20 (built-ins: trust the "prefix" from run_builtin(),
2022-02-16)
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 7 +++----
git.c | 2 +-
parse-options.h | 4 ++++
submodule.c | 12 +++++++-----
t/t7527-builtin-fsmonitor.sh | 36 ++++++++++++++----------------------
5 files changed, 29 insertions(+), 32 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index da844cad5ce..b8b2bc776d1 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2834,8 +2834,9 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
- const char *super_prefix;
+ const char *super_prefix = NULL;
struct option embed_gitdir_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT_END()
};
const char *const git_submodule_helper_usage[] = {
@@ -2850,7 +2851,6 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
goto cleanup;
- super_prefix = get_super_prefix();
for (i = 0; i < list.nr; i++)
absorb_git_dir_into_superproject(list.entries[i]->name,
super_prefix);
@@ -3391,8 +3391,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
- get_super_prefix())
+ strcmp(subcmd, "sync") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
diff --git a/git.c b/git.c
index 277a8cce840..e473b4b7d72 100644
--- a/git.c
+++ b/git.c
@@ -539,7 +539,7 @@ static struct cmd_struct commands[] = {
{ "format-patch", cmd_format_patch, RUN_SETUP },
{ "fsck", cmd_fsck, RUN_SETUP },
{ "fsck-objects", cmd_fsck, RUN_SETUP },
- { "fsmonitor--daemon", cmd_fsmonitor__daemon, SUPPORT_SUPER_PREFIX | RUN_SETUP },
+ { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP },
{ "gc", cmd_gc, RUN_SETUP },
{ "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
{ "grep", cmd_grep, RUN_SETUP_GENTLY },
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 bf19598b8c2..46a03473195 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2275,7 +2275,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;
@@ -2305,7 +2306,7 @@ static void relocate_single_git_dir_into_superproject(const char *path)
real_new_git_dir = real_pathdup(new_gitdir.buf, 1);
fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"),
- get_super_prefix_or_empty(), path,
+ super_prefix ? super_prefix : "", path,
real_old_git_dir, real_new_git_dir);
relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
@@ -2325,10 +2326,11 @@ static void absorb_git_dir_into_superproject_recurse(const char *path,
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
- super_prefix : "", path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+ super_prefix : "", path);
+
prepare_submodule_repo_env(&cp.env);
if (run_command(&cp))
die(_("could not recurse into submodule '%s'"), path);
@@ -2382,7 +2384,7 @@ void absorb_git_dir_into_superproject(const char *path,
char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
if (!starts_with(real_sub_git_dir, real_common_git_dir))
- relocate_single_git_dir_into_superproject(path);
+ relocate_single_git_dir_into_superproject(path, super_prefix);
free(real_sub_git_dir);
free(real_common_git_dir);
diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
index 4abc74db2bb..76d0220daa0 100755
--- a/t/t7527-builtin-fsmonitor.sh
+++ b/t/t7527-builtin-fsmonitor.sh
@@ -866,27 +866,9 @@ test_expect_success 'submodule always visited' '
# the submodule, and someone does a `git submodule absorbgitdirs`
# in the super, Git will recursively invoke `git submodule--helper`
# to do the work and this may try to read the index. This will
-# try to start the daemon in the submodule *and* pass (either
-# directly or via inheritance) the `--super-prefix` arg to the
-# `git fsmonitor--daemon start` command inside the submodule.
-# This causes a warning because fsmonitor--daemon does take that
-# global arg (see the table in git.c)
-#
-# This causes a warning when trying to start the daemon that is
-# somewhat confusing. It does not seem to hurt anything because
-# the fsmonitor code maps the query failure into a trivial response
-# and does the work anyway.
-#
-# It would be nice to silence the warning, however.
-
-have_t2_error_event () {
- log=$1
- msg="fsmonitor--daemon doesnQt support --super-prefix" &&
-
- tr '\047' Q <$1 | grep -e "$msg"
-}
+# try to start the daemon in the submodule.
-test_expect_success "stray submodule super-prefix warning" '
+test_expect_success "submodule absorbgitdirs implicitly starts daemon" '
test_when_finished "rm -rf super; \
rm -rf sub; \
rm super-sub.trace" &&
@@ -904,10 +886,20 @@ test_expect_success "stray submodule super-prefix warning" '
test_path_is_dir super/dir_1/dir_2/sub/.git &&
+ cwd="$(cd super && pwd)" &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''dir_1/dir_2/sub'\'' from
+ '\''$cwd/dir_1/dir_2/sub/.git'\'' to
+ '\''$cwd/.git/modules/dir_1/dir_2/sub'\''
+ EOF
GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
- git -C super submodule absorbgitdirs &&
+ git -C super submodule absorbgitdirs >out 2>actual &&
+ test_cmp expect actual &&
+ test_must_be_empty out &&
- ! have_t2_error_event super-sub.trace
+ # Confirm that the trace2 log contains a record of the
+ # daemon starting.
+ test_subcommand git fsmonitor--daemon start <super-sub.trace
'
# On a case-insensitive file system, confirm that the daemon
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v4 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-12-15 9:32 ` [PATCH v4 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
@ 2022-12-15 21:05 ` Glen Choo
0 siblings, 0 replies; 105+ messages in thread
From: Glen Choo @ 2022-12-15 21:05 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> Let's instead assert the full output that
> we *do* have, which we can do here as this is based on a change[4] to
> make it predictable (until [4] it contained absolute paths).
> ...
> 4. https://lore.kernel.org/git/patch-1.1-34b54fdd9bb-20221109T020347Z-avarab@gmail.com/
This sentence is stale now, since the test uses absolute paths.
> @@ -904,10 +886,20 @@ test_expect_success "stray submodule super-prefix warning" '
>
> test_path_is_dir super/dir_1/dir_2/sub/.git &&
>
> + cwd="$(cd super && pwd)" &&
> + cat >expect <<-EOF &&
> + Migrating git directory of '\''dir_1/dir_2/sub'\'' from
> + '\''$cwd/dir_1/dir_2/sub/.git'\'' to
> + '\''$cwd/.git/modules/dir_1/dir_2/sub'\''
> + EOF
Namely, this test uses absolute paths.
> GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
> - git -C super submodule absorbgitdirs &&
> + git -C super submodule absorbgitdirs >out 2>actual &&
> + test_cmp expect actual &&
> + test_must_be_empty out &&
>
> - ! have_t2_error_event super-sub.trace
> + # Confirm that the trace2 log contains a record of the
> + # daemon starting.
> + test_subcommand git fsmonitor--daemon start <super-sub.trace
> '
>
> # On a case-insensitive file system, confirm that the daemon
> --
> 2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v4 5/9] submodule--helper: convert "foreach" to its own "--super-prefix"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (3 preceding siblings ...)
2022-12-15 9:32 ` [PATCH v4 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 6/9] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
` (6 subsequent siblings)
11 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper foreach" to use its own "--super-prefix", instead
of relying on the global "--super-prefix" argument to "git"
itself. See that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b8b2bc776d1..2a6ced13f6d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -278,6 +278,7 @@ struct foreach_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
int quiet;
int recursive;
};
@@ -294,7 +295,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
char *displaypath;
displaypath = get_submodule_displaypath(path, info->prefix,
- get_super_prefix());
+ info->super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -364,10 +365,10 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_pushl(&cpr.args, "--super-prefix", NULL);
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive",
NULL);
+ strvec_pushl(&cpr.args, "--super-prefix", NULL);
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (info->quiet)
strvec_push(&cpr.args, "--quiet");
@@ -391,6 +392,7 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
struct option module_foreach_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
OPT_BOOL(0, "recursive", &info.recursive,
N_("recurse into nested submodules")),
@@ -3390,8 +3392,8 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && get_super_prefix())
+ strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v4 6/9] submodule--helper: convert "sync" to its own "--super-prefix"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (4 preceding siblings ...)
2022-12-15 9:32 ` [PATCH v4 5/9] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 7/9] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
` (5 subsequent siblings)
11 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper sync" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 2a6ced13f6d..7262ce72edf 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1208,12 +1208,13 @@ static int module_summary(int argc, const char **argv, const char *prefix)
struct sync_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define SYNC_CB_INIT { 0 }
static void sync_submodule(const char *path, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
const struct submodule *sub;
char *remote_key = NULL;
@@ -1244,8 +1245,7 @@ static void sync_submodule(const char *path, const char *prefix,
super_config_url = xstrdup("");
}
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ -1282,10 +1282,11 @@ static void sync_submodule(const char *path, const char *prefix,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "sync",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
+
if (flags & OPT_QUIET)
strvec_push(&cpr.args, "--quiet");
@@ -1308,7 +1309,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct sync_cb *info = cb_data;
- sync_submodule(list_item->name, info->prefix, info->flags);
+ sync_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_sync(int argc, const char **argv, const char *prefix)
@@ -1319,6 +1321,7 @@ static int module_sync(int argc, const char **argv, const char *prefix)
int quiet = 0;
int recursive = 0;
struct option module_sync_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
OPT_BOOL(0, "recursive", &recursive,
N_("recurse into nested submodules")),
@@ -2887,7 +2890,7 @@ static int module_set_url(int argc, const char **argv, const char *prefix)
config_name = xstrfmt("submodule.%s.url", path);
config_set_in_gitmodules_file_gently(config_name, newurl);
- sync_submodule(path, prefix, quiet ? OPT_QUIET : 0);
+ sync_submodule(path, prefix, NULL, quiet ? OPT_QUIET : 0);
free(config_name);
@@ -3392,8 +3395,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
- get_super_prefix())
+ strcmp(subcmd, "status") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v4 7/9] submodule--helper: convert "status" to its own "--super-prefix"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (5 preceding siblings ...)
2022-12-15 9:32 ` [PATCH v4 6/9] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 8/9] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
` (4 subsequent siblings)
11 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 7262ce72edf..448896f1b1d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -573,6 +573,7 @@ static int module_init(int argc, const char **argv, const char *prefix)
struct status_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define STATUS_CB_INIT { 0 }
@@ -611,7 +612,7 @@ static int handle_submodule_head_ref(const char *refname UNUSED,
static void status_submodule(const char *path, const struct object_id *ce_oid,
unsigned int ce_flags, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
char *displaypath;
struct strvec diff_files_args = STRVEC_INIT;
@@ -627,8 +628,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ -686,10 +686,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "status",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (flags & OPT_CACHED)
strvec_push(&cpr.args, "--cached");
@@ -713,7 +713,7 @@ static void status_submodule_cb(const struct cache_entry *list_item,
struct status_cb *info = cb_data;
status_submodule(list_item->name, &list_item->oid, list_item->ce_flags,
- info->prefix, info->flags);
+ info->prefix, info->super_prefix, info->flags);
}
static int module_status(int argc, const char **argv, const char *prefix)
@@ -723,6 +723,7 @@ static int module_status(int argc, const char **argv, const char *prefix)
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
struct option module_status_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress submodule status output")),
OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
@@ -3395,7 +3396,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && get_super_prefix())
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v4 8/9] submodule--helper: convert "{update,clone}" to their own "--super-prefix"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (6 preceding siblings ...)
2022-12-15 9:32 ` [PATCH v4 7/9] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:32 ` [PATCH v4 9/9] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
` (3 subsequent siblings)
11 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git".
We need to convert both of these away from the global "--super-prefix"
at the same time, because "update" will call "clone", but "clone"
itself didn't make use of the global "--super-prefix" for displaying
paths. It was only on the list of sub-commands that accepted it
because "update"'s use of it would set it in its environment.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 32 +++++++++++++-------------------
git.c | 2 +-
2 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 448896f1b1d..a0aa4635a0c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -437,11 +437,13 @@ static int starts_with_dot_dot_slash(const char *const path)
struct init_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define INIT_CB_INIT { 0 }
static void init_submodule(const char *path, const char *prefix,
+ const char *super_prefix,
unsigned int flags)
{
const struct submodule *sub;
@@ -449,8 +451,7 @@ static void init_submodule(const char *path, const char *prefix,
const char *upd;
char *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -526,7 +527,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct init_cb *info = cb_data;
- init_submodule(list_item->name, info->prefix, info->flags);
+ init_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_init(int argc, const char **argv, const char *prefix)
@@ -792,6 +794,7 @@ struct summary_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
unsigned int cached: 1;
unsigned int for_status: 1;
unsigned int files: 1;
@@ -954,7 +957,7 @@ static void generate_submodule_summary(struct summary_cb *info,
}
displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
- get_super_prefix());
+ info->super_prefix);
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ -1893,6 +1896,7 @@ static void submodule_update_clone_release(struct submodule_update_clone *suc)
struct update_data {
const char *prefix;
+ const char *super_prefix;
char *displaypath;
enum submodule_update_type update_default;
struct object_id suboid;
@@ -1969,7 +1973,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
char *key;
const struct update_data *ud = suc->update_data;
char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
- get_super_prefix());
+ ud->super_prefix);
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ -2449,11 +2453,11 @@ static void update_data_to_args(const struct update_data *update_data,
{
enum submodule_update_type update_type = update_data->update_default;
+ strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
if (update_data->displaypath) {
strvec_push(args, "--super-prefix");
strvec_pushf(args, "%s/", update_data->displaypath);
}
- strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
if (update_data->quiet)
strvec_push(args, "--quiet");
@@ -2620,7 +2624,7 @@ static int update_submodules(struct update_data *update_data)
update_data->displaypath = get_submodule_displaypath(
update_data->sm_path, update_data->prefix,
- get_super_prefix());
+ update_data->super_prefix);
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ -2646,6 +2650,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
LIST_OBJECTS_FILTER_INIT;
int ret;
struct option module_update_options[] = {
+ OPT__SUPER_PREFIX(&opt.super_prefix),
OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
OPT_BOOL(0, "init", &opt.init,
N_("initialize uninitialized submodules before update")),
@@ -2742,6 +2747,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
module_list_active(&list);
info.prefix = opt.prefix;
+ info.super_prefix = opt.super_prefix;
if (opt.quiet)
info.flags |= OPT_QUIET;
@@ -3368,8 +3374,6 @@ static int module_add(int argc, const char **argv, const char *prefix)
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
{
- const char *cmd = argv[0];
- const char *subcmd;
parse_opt_subcommand_fn *fn = NULL;
const char *const usage[] = {
N_("git submodule--helper <command>"),
@@ -3393,16 +3397,6 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
OPT_END()
};
argc = parse_options(argc, argv, prefix, options, usage, 0);
- subcmd = argv[0];
-
- if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- get_super_prefix())
- /*
- * xstrfmt() rather than "%s %s" to keep the translated
- * string identical to git.c's.
- */
- die(_("%s doesn't support --super-prefix"),
- xstrfmt("'%s %s'", cmd, subcmd));
return fn(argc, argv, prefix);
}
diff --git a/git.c b/git.c
index e473b4b7d72..2c31ba27040 100644
--- a/git.c
+++ b/git.c
@@ -610,7 +610,7 @@ static struct cmd_struct commands[] = {
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
- { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX },
+ { "submodule--helper", cmd_submodule__helper, RUN_SETUP },
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v4 9/9] read-tree: add "--super-prefix" option, eliminate global
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (7 preceding siblings ...)
2022-12-15 9:32 ` [PATCH v4 8/9] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
@ 2022-12-15 9:32 ` Ævar Arnfjörð Bjarmason
2022-12-15 21:19 ` [PATCH v4 0/9] Get rid of "git --super-prefix" Glen Choo
` (2 subsequent siblings)
11 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-15 9:32 UTC (permalink / raw)
To: git
Cc: Glen Choo, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
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>
---
Documentation/git.txt | 8 +-------
builtin.h | 4 ----
builtin/checkout.c | 2 +-
builtin/read-tree.c | 1 +
cache.h | 2 --
entry.c | 12 ++++++------
entry.h | 6 +++++-
environment.c | 13 -------------
git.c | 37 +++++--------------------------------
submodule.c | 29 ++++++++++-------------------
submodule.h | 5 ++---
t/t1001-read-tree-m-2way.sh | 2 +-
t/t5616-partial-clone.sh | 2 +-
unpack-trees.c | 24 ++++++++++++++----------
unpack-trees.h | 1 +
15 files changed, 48 insertions(+), 100 deletions(-)
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 1d33e083ab8..f9a7a4554cd 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
diff --git a/builtin.h b/builtin.h
index aa955466b4e..46cc7897898 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
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a0142c815fd..cd04f0bf572 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)
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index f702f9d47bb..3ce75417833 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),
diff --git a/cache.h b/cache.h
index 07d40b0964b..7f7e2b5a38f 100644
--- a/cache.h
+++ b/cache.h
@@ -480,7 +480,6 @@ 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"
@@ -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);
const char *get_git_namespace(void);
const char *strip_namespace(const char *namespaced_ref);
-const char *get_super_prefix(void);
const char *get_git_work_tree(void);
/*
diff --git a/entry.c b/entry.c
index 616e4f073c1..971ab268714 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)
diff --git a/entry.h b/entry.h
index 9be4659881e..2d4fbb88c8f 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);
diff --git a/environment.c b/environment.c
index 18d042b467d..1ee3686fd8a 100644
--- a/environment.c
+++ b/environment.c
@@ -102,8 +102,6 @@ char *git_work_tree_cfg;
static char *git_namespace;
-static char *super_prefix;
-
/*
* Repository-local GIT_* environment variables; see cache.h for details.
*/
@@ -121,7 +119,6 @@ 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
@@ -234,16 +231,6 @@ const char *strip_namespace(const char *namespaced_ref)
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;
/*
diff --git a/git.c b/git.c
index 2c31ba27040..32a5be68a17 100644
--- a/git.c
+++ b/git.c
@@ -14,9 +14,8 @@
* RUN_SETUP for reading from the configuration file.
*/
#define NEED_WORK_TREE (1<<3)
-#define SUPPORT_SUPER_PREFIX (1<<4)
-#define DELAY_PAGER_CONFIG (1<<5)
-#define NO_PARSEOPT (1<<6) /* parse-options is not used */
+#define DELAY_PAGER_CONFIG (1<<4)
+#define NO_PARSEOPT (1<<5) /* parse-options is not used */
struct cmd_struct {
const char *cmd;
@@ -29,8 +28,7 @@ const char git_usage_string[] =
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
- " [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
- " <command> [<args>]");
+ " [--config-env=<name>=<envvar>] <command> [<args>]");
const char git_more_info_string[] =
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);
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;
@@ -449,11 +433,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
trace_repo_setup(prefix);
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)
setup_work_tree();
@@ -504,7 +483,7 @@ static struct cmd_struct commands[] = {
{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
{ "checkout--worker", cmd_checkout__worker,
- RUN_SETUP | NEED_WORK_TREE | SUPPORT_SUPER_PREFIX },
+ RUN_SETUP | NEED_WORK_TREE },
{ "checkout-index", cmd_checkout_index,
RUN_SETUP | NEED_WORK_TREE},
{ "cherry", cmd_cherry, RUN_SETUP },
@@ -583,7 +562,7 @@ static struct cmd_struct commands[] = {
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
{ "push", cmd_push, RUN_SETUP },
{ "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 },
{ "receive-pack", cmd_receive_pack },
{ "reflog", cmd_reflog, RUN_SETUP },
@@ -727,9 +706,6 @@ static void execv_dashed_external(const char **argv)
struct child_process cmd = CHILD_PROCESS_INIT;
int status;
- if (get_super_prefix())
- die(_("%s doesn't support --super-prefix"), argv[0]);
-
if (use_pager == -1 && !is_builtin(argv[0]))
use_pager = check_pager_config(argv[0]);
commit_pager_choice();
@@ -799,9 +775,6 @@ static int run_argv(int *argcp, const char ***argv)
*/
trace2_cmd_name("_run_git_alias_");
- if (get_super_prefix())
- die("%s doesn't support --super-prefix", **argv);
-
commit_pager_choice();
strvec_push(&cmd.args, "git");
diff --git a/submodule.c b/submodule.c
index 46a03473195..d730b64b072 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2054,14 +2054,6 @@ void submodule_unset_core_worktree(const struct submodule *sub)
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)
{
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);
}
-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;
prepare_submodule_repo_env(&cp.env);
@@ -2089,10 +2081,10 @@ static void submodule_reset_index(const char *path)
cp.no_stdin = 1;
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 */
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());
@@ -2105,10 +2097,9 @@ static void submodule_reset_index(const char *path)
* For edge cases (a submodule coming into existence or removing a submodule)
* pass NULL for old or new respectively.
*/
-int submodule_move_head(const char *path,
- const char *old_head,
- const char *new_head,
- unsigned flags)
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
+ unsigned flags)
{
int ret = 0;
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2146,7 +2137,7 @@ int submodule_move_head(const char *path,
if (old_head) {
if (!submodule_uses_gitfile(path))
absorb_git_dir_into_superproject(path,
- get_super_prefix());
+ super_prefix);
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2155,7 +2146,7 @@ int submodule_move_head(const char *path,
strbuf_release(&gitdir);
/* 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)) {
@@ -2173,9 +2164,9 @@ int submodule_move_head(const char *path,
cp.no_stdin = 1;
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_pushf(&cp.args, "--super-prefix=%s%s/",
+ (super_prefix ? super_prefix : ""), path);
if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN)
strvec_push(&cp.args, "-n");
diff --git a/submodule.h b/submodule.h
index f90ee547d08..c55a25ca37d 100644
--- a/submodule.h
+++ b/submodule.h
@@ -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_FORCE (1<<1)
-int submodule_move_head(const char *path,
- const char *old,
- const char *new_head,
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
unsigned flags);
void submodule_unset_core_worktree(const struct submodule *sub);
diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh
index 516a6112fdc..3fb1b0c162d 100755
--- a/t/t1001-read-tree-m-2way.sh
+++ b/t/t1001-read-tree-m-2way.sh
@@ -370,7 +370,7 @@ test_expect_success 'read-tree supports the super-prefix' '
cat <<-EOF >expect &&
error: Updating '\''fictional/a'\'' would lose untracked files in it
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
'
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 2846ec6629c..f519d2a87a7 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,7 +644,7 @@ test_expect_success 'repack does not loosen promisor objects' '
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
test_config_global protocol.file.allow always &&
diff --git a/unpack-trees.c b/unpack-trees.c
index 8a762aa0772..2b8e5da4c21 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -71,7 +71,7 @@ static const char *unpack_plumbing_errors[NB_UNPACK_TREES_WARNING_TYPES] = {
? ((o)->msgs[(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
@@ -83,7 +83,6 @@ static const char *super_prefixed(const char *path)
static unsigned idx = ARRAY_SIZE(buf) - 1;
if (super_prefix_len < 0) {
- const char *super_prefix = get_super_prefix();
if (!super_prefix) {
super_prefix_len = 0;
} else {
@@ -236,7 +235,8 @@ static int add_rejected_path(struct unpack_trees_options *o,
return -1;
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
@@ -263,7 +263,8 @@ static void display_error_msgs(struct unpack_trees_options *o)
error_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -290,7 +291,8 @@ static void display_warning_msgs(struct unpack_trees_options *o)
warning_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -312,7 +314,8 @@ static int check_submodule_move_head(const struct cache_entry *ce,
if (o->reset)
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 0;
}
@@ -415,6 +418,7 @@ static int check_updates(struct unpack_trees_options *o,
int i, pc_workers, pc_threshold;
trace_performance_enter();
+ state.super_prefix = o->super_prefix;
state.force = 1;
state.quiet = 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) {
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)
return o->quiet ? -1 :
error(ERRORMSG(o, ERROR_BIND_OVERLAP),
- super_prefixed(a->name),
- super_prefixed(old->name));
+ super_prefixed(a->name, o->super_prefix),
+ super_prefixed(old->name, o->super_prefix));
if (!a)
return keep_entry(old, o);
else
@@ -3021,7 +3025,7 @@ int stash_worktree_untracked_merge(const struct cache_entry * const *src,
if (worktree && untracked)
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);
}
diff --git a/unpack-trees.h b/unpack-trees.h
index 6ab0d74c84d..3a7b3e5f007 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -75,6 +75,7 @@ struct unpack_trees_options {
skip_cache_tree_update;
enum unpack_trees_reset_type reset;
const char *prefix;
+ const char *super_prefix;
int cache_bottom;
struct pathspec *pathspec;
merge_fn_t fn;
--
2.39.0.rc2.1048.g0e5493b8d5b
^ permalink raw reply related [flat|nested] 105+ messages in thread
* Re: [PATCH v4 0/9] Get rid of "git --super-prefix"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (8 preceding siblings ...)
2022-12-15 9:32 ` [PATCH v4 9/9] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
@ 2022-12-15 21:19 ` Glen Choo
2022-12-15 22:19 ` Junio C Hamano
2022-12-15 22:12 ` Junio C Hamano
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
11 siblings, 1 reply; 105+ messages in thread
From: Glen Choo @ 2022-12-15 21:19 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git
Cc: Taylor Blau, Robert Coup, Ævar Arnfjörð Bjarmason,
Emily Shaffer
Thanks! I only spotted typos this time, so I think this is ready to
merge once we fix those.
(FYI I will be OOO for the next 3 weeks or so, so don't wait on a
response from me :))
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> Changes since v4:
> * I ejected the previous 10/10 to refactor "git fetch". I have more
> patches on top of this to do some post-refactoring (e.g. saving
> memory churn by getting rid of "submodule_prefix" from "struct
> repository"), but none of that's essential for now, so let's drop
> that patch.
Okay, dropping the "git fetch" refactor probably makes sense in light of
bigger refactoring.
This might be premature (since the patches aren't out yet), but I'm a
bit apprehensive about removing "submodule_prefix" from "struct
repository". You've noted that it isn't needed right now (which I'll
grant), but it feels taking away API features that we'll need soon™ to,
e.g. run library functions against arbitrary repositories, some of which
may need additional submodule information. Feel free to CC me on those
patches, perhaps my fears will be unfounded :)
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v4 0/9] Get rid of "git --super-prefix"
2022-12-15 21:19 ` [PATCH v4 0/9] Get rid of "git --super-prefix" Glen Choo
@ 2022-12-15 22:19 ` Junio C Hamano
0 siblings, 0 replies; 105+ messages in thread
From: Junio C Hamano @ 2022-12-15 22:19 UTC (permalink / raw)
To: Glen Choo
Cc: Ævar Arnfjörð Bjarmason, git, Taylor Blau,
Robert Coup, Emily Shaffer
Glen Choo <chooglen@google.com> writes:
> Thanks! I only spotted typos this time, so I think this is ready to
> merge once we fix those.
>
> (FYI I will be OOO for the next 3 weeks or so, so don't wait on a
> response from me :))
>
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> Changes since v4:
>> * I ejected the previous 10/10 to refactor "git fetch". I have more
>> patches on top of this to do some post-refactoring (e.g. saving
>> memory churn by getting rid of "submodule_prefix" from "struct
>> repository"), but none of that's essential for now, so let's drop
>> that patch.
>
> Okay, dropping the "git fetch" refactor probably makes sense in light of
> bigger refactoring.
>
> This might be premature (since the patches aren't out yet), but I'm a
> bit apprehensive about removing "submodule_prefix" from "struct
> repository". You've noted that it isn't needed right now (which I'll
> grant), but it feels taking away API features that we'll need soon™ to,
> e.g. run library functions against arbitrary repositories, some of which
> may need additional submodule information. Feel free to CC me on those
> patches, perhaps my fears will be unfounded :)
Thanks, both. Will await for the hopefully final update.
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v4 0/9] Get rid of "git --super-prefix"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (9 preceding siblings ...)
2022-12-15 21:19 ` [PATCH v4 0/9] Get rid of "git --super-prefix" Glen Choo
@ 2022-12-15 22:12 ` Junio C Hamano
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
11 siblings, 0 replies; 105+ messages in thread
From: Junio C Hamano @ 2022-12-15 22:12 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason
Cc: git, Glen Choo, Taylor Blau, Robert Coup
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v5 0/9] Get rid of "git --super-prefix"
2022-12-15 9:32 ` [PATCH v4 " Ævar Arnfjörð Bjarmason
` (10 preceding siblings ...)
2022-12-15 22:12 ` Junio C Hamano
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests Ævar Arnfjörð Bjarmason
` (8 more replies)
11 siblings, 9 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
For a general summary see the v3's CL at
https://lore.kernel.org/git/cover-v3-0.9-00000000000-20221119T122853Z-avarab@gmail.com/
[Trivial] changes since v4:
* Remove stray ad-hoc testing env variable from test.
* s/passs/pass/ typo fix
* Adjust commit message for the tests not checking relative paths anymore.
Branch & passing CI at:
https://github.com/avar/git/tree/avar/nuke-global-super-prefix-use-local-5
Glen Choo (1):
read-tree + fetch tests: test failing "--super-prefix" interaction
Ævar Arnfjörð Bjarmason (8):
submodule absorbgitdirs tests: add missing "Migrating git..." tests
submodule.c & submodule--helper: pass along "super_prefix" param
submodule--helper: don't use global --super-prefix in "absorbgitdirs"
submodule--helper: convert "foreach" to its own "--super-prefix"
submodule--helper: convert "sync" to its own "--super-prefix"
submodule--helper: convert "status" to its own "--super-prefix"
submodule--helper: convert "{update,clone}" to their own
"--super-prefix"
read-tree: add "--super-prefix" option, eliminate global
Documentation/git.txt | 8 +--
builtin.h | 4 --
builtin/checkout.c | 2 +-
builtin/read-tree.c | 1 +
builtin/rm.c | 2 +-
builtin/submodule--helper.c | 87 ++++++++++++++++--------------
cache.h | 2 -
entry.c | 12 ++---
entry.h | 6 ++-
environment.c | 13 -----
git.c | 41 +++-----------
parse-options.h | 4 ++
submodule.c | 50 ++++++++---------
submodule.h | 8 +--
t/t1001-read-tree-m-2way.sh | 2 +-
t/t5616-partial-clone.sh | 43 +++++++++++++++
t/t7412-submodule-absorbgitdirs.sh | 64 +++++++++++++++++++---
t/t7527-builtin-fsmonitor.sh | 36 +++++--------
unpack-trees.c | 24 +++++----
unpack-trees.h | 1 +
20 files changed, 230 insertions(+), 180 deletions(-)
Range-diff against v4:
1: f479003941b ! 1: f062cb2f265 submodule absorbgitdirs tests: add missing "Migrating git..." tests
@@ t/t7412-submodule-absorbgitdirs.sh: test_expect_success 'absorb the git dir in a
+ '\''$cwd/repo-wt/sub2/.git'\'' to
+ '\''$cwd/repo-bare.git/worktrees/repo-wt/modules/sub2'\''
+ EOF
-+ DO_IT=1 git -C repo-wt submodule absorbgitdirs 2>actual &&
++ git -C repo-wt submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual
+'
+
2: 6424307a432 = 2: 5fa05492b62 read-tree + fetch tests: test failing "--super-prefix" interaction
3: b2e543bde03 ! 3: 3fb2a1b16cd submodule.c & submodule--helper: pass along "super_prefix" param
@@ Commit message
directly or by indirection. The exceptions are:
- builtin/rm.c: Doesn't declare SUPPORT_SUPER_PREFIX, so we'd have
- died if this was provided, so it's safe to passs "NULL".
+ died if this was provided, so it's safe to pass "NULL".
- deinit_submodule(): The "deinit_submodule()" function has never been
able to use the "git -super-prefix". It will call
"absorb_git_dir_into_superproject()", but it will only do so from the
top-level project.
- If "absorbgitdirs" recurses it will use the "path" passed to
+ If "absorbgitdirs" recurses will use the "path" passed to
"absorb_git_dir_into_superproject()" in "deinit_submodule()" as its
starting "--super-prefix". So we can safely remove the
get_super_prefix() call here, and pass NULL instead.
4: bde9038c4e3 ! 4: 0b30497f187 submodule--helper: don't use global --super-prefix in "absorbgitdirs"
@@ Commit message
The "fsmonitor--daemon" test adjusted here was added in [3]. To assert
that it didn't run into the "--super-prefix" message it was asserting
the output it didn't have. Let's instead assert the full output that
- we *do* have, which we can do here as this is based on a change[4] to
- make it predictable (until [4] it contained absolute paths).
+ we *do* have, using the same pattern as a preceding change to
+ "t/t7412-submodule-absorbgitdirs.sh" used.
- We could also remove the test entirely (as [5] did), but even though
+ We could also remove the test entirely (as [4] did), but even though
the initial reason for having it is gone we're still getting some
marginal benefit from testing the "fsmonitor" and "submodule
absorbgitdirs" interaction, so let's keep it.
@@ Commit message
As we'll be changing the rest of the "git --super-prefix" users to the
same pattern, leaving them all consistent makes sense. Why not pick ""
- over NULL? Because that's how the "prefix" works[6], and having
+ over NULL? Because that's how the "prefix" works[5], and having
"prefix" and "super_prefix" work the same way will be less
confusing. That "prefix" picked NULL instead of "" is itself
arbitrary, but as it's easy to make this small bit of our overall API
@@ Commit message
2022-05-26)
3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
- 4. https://lore.kernel.org/git/patch-1.1-34b54fdd9bb-20221109T020347Z-avarab@gmail.com/
- 5. https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com/
- 6. 9725c8dda20 (built-ins: trust the "prefix" from run_builtin(),
+ 4. https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com/
+ 5. 9725c8dda20 (built-ins: trust the "prefix" from run_builtin(),
2022-02-16)
Signed-off-by: Glen Choo <chooglen@google.com>
5: 4da58e7ea50 = 5: 13f1f0db07a submodule--helper: convert "foreach" to its own "--super-prefix"
6: 8dff576df7d = 6: ace2920ccff submodule--helper: convert "sync" to its own "--super-prefix"
7: 8800a433e29 = 7: 1ccd1a57b64 submodule--helper: convert "status" to its own "--super-prefix"
8: 54c1e29de1e = 8: 72e774ebb06 submodule--helper: convert "{update,clone}" to their own "--super-prefix"
9: 4824f33224f = 9: 48ba8d4938c read-tree: add "--super-prefix" option, eliminate global
--
2.39.0.1071.g97ce8966538
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v5 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 2/9] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
` (7 subsequent siblings)
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
Fix a blind spots in the tests surrounding "submodule absorbgitdirs"
and test what output we emit, and how emitted the message and behavior
interacts with a "git worktree" where the repository isn't at the base
of the working directory.
The "$(pwd)" instead of "$PWD" here is needed due to Windows, where
the latter will be a path like "/d/a/git/[...]", whereas we need
"D:/a/git/[...]".
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/t7412-submodule-absorbgitdirs.sh | 64 ++++++++++++++++++++++++++----
1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
index 2859695c6d2..f7783218576 100755
--- a/t/t7412-submodule-absorbgitdirs.sh
+++ b/t/t7412-submodule-absorbgitdirs.sh
@@ -10,6 +10,7 @@ TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup a real submodule' '
+ cwd="$(pwd)" &&
git init sub1 &&
test_commit -C sub1 first &&
git submodule add ./sub1 &&
@@ -18,13 +19,21 @@ test_expect_success 'setup a real submodule' '
'
test_expect_success 'absorb the git dir' '
+ >expect &&
+ >actual &&
>expect.1 &&
>expect.2 &&
>actual.1 &&
>actual.2 &&
git status >expect.1 &&
git -C sub1 rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub1'\'' from
+ '\''$cwd/sub1/.git'\'' to
+ '\''$cwd/.git/modules/sub1'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
git fsck &&
test -f sub1/.git &&
test -d .git/modules/sub1 &&
@@ -37,7 +46,8 @@ test_expect_success 'absorb the git dir' '
test_expect_success 'absorbing does not fail for deinitialized submodules' '
test_when_finished "git submodule update --init" &&
git submodule deinit --all &&
- git submodule absorbgitdirs &&
+ git submodule absorbgitdirs 2>err &&
+ test_must_be_empty err &&
test -d .git/modules/sub1 &&
test -d sub1 &&
! test -e sub1/.git
@@ -56,7 +66,13 @@ test_expect_success 'setup nested submodule' '
test_expect_success 'absorb the git dir in a nested submodule' '
git status >expect.1 &&
git -C sub1/nested rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub1/nested'\'' from
+ '\''$cwd/sub1/nested/.git'\'' to
+ '\''$cwd/.git/modules/sub1/modules/nested'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
test -f sub1/nested/.git &&
test -d .git/modules/sub1/modules/nested &&
git status >actual.1 &&
@@ -87,7 +103,13 @@ test_expect_success 're-setup nested submodule' '
test_expect_success 'absorb the git dir in a nested submodule' '
git status >expect.1 &&
git -C sub1/nested rev-parse HEAD >expect.2 &&
- git submodule absorbgitdirs &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub1'\'' from
+ '\''$cwd/sub1/.git'\'' to
+ '\''$cwd/.git/modules/sub1'\''
+ EOF
+ git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
test -f sub1/.git &&
test -f sub1/nested/.git &&
test -d .git/modules/sub1/modules/nested &&
@@ -97,6 +119,27 @@ test_expect_success 'absorb the git dir in a nested submodule' '
test_cmp expect.2 actual.2
'
+test_expect_success 'absorb the git dir outside of primary worktree' '
+ test_when_finished "rm -rf repo-bare.git" &&
+ git clone --bare . repo-bare.git &&
+ test_when_finished "rm -rf repo-wt" &&
+ git -C repo-bare.git worktree add ../repo-wt &&
+
+ test_when_finished "rm -f .gitconfig" &&
+ test_config_global protocol.file.allow always &&
+ git -C repo-wt submodule update --init &&
+ git init repo-wt/sub2 &&
+ test_commit -C repo-wt/sub2 A &&
+ git -C repo-wt submodule add ./sub2 sub2 &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''sub2'\'' from
+ '\''$cwd/repo-wt/sub2/.git'\'' to
+ '\''$cwd/repo-bare.git/worktrees/repo-wt/modules/sub2'\''
+ EOF
+ git -C repo-wt submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup a gitlink with missing .gitmodules entry' '
git init sub2 &&
test_commit -C sub2 first &&
@@ -107,7 +150,11 @@ test_expect_success 'setup a gitlink with missing .gitmodules entry' '
test_expect_success 'absorbing the git dir fails for incomplete submodules' '
git status >expect.1 &&
git -C sub2 rev-parse HEAD >expect.2 &&
- test_must_fail git submodule absorbgitdirs &&
+ cat >expect <<-\EOF &&
+ fatal: could not lookup name for submodule '\''sub2'\''
+ EOF
+ test_must_fail git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual &&
git -C sub2 fsck &&
test -d sub2/.git &&
git status >actual &&
@@ -127,8 +174,11 @@ test_expect_success 'setup a submodule with multiple worktrees' '
'
test_expect_success 'absorbing fails for a submodule with multiple worktrees' '
- test_must_fail git submodule absorbgitdirs sub3 2>error &&
- test_i18ngrep "not supported" error
+ cat >expect <<-\EOF &&
+ fatal: could not lookup name for submodule '\''sub2'\''
+ EOF
+ test_must_fail git submodule absorbgitdirs 2>actual &&
+ test_cmp expect actual
'
test_done
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 2/9] read-tree + fetch tests: test failing "--super-prefix" interaction
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 3/9] submodule.c & submodule--helper: pass along "super_prefix" param Ævar Arnfjörð Bjarmason
` (6 subsequent siblings)
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
From: Glen Choo <chooglen@google.com>
Ever since "git fetch --refetch" was introduced in 0f5e8851737 (Merge
branch 'rc/fetch-refetch', 2022-04-04) the test being added here would
fail. This is because "restore" will "read-tree .. --reset <hash>",
which will in turn invoke "fetch". The "fetch" will then die with:
fatal: fetch doesn't support --super-prefix
This edge case and other "--super-prefix" bugs will be fixed in
subsequent commits, but let's first add a "test_expect_failure" test
for it. It passes until the very last command in the test.
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 037941b95d2..2846ec6629c 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
grep "loosen_unused_packed_objects/loosened:0" trace
'
+test_expect_failure 'lazy-fetch in submodule succeeds' '
+ # setup
+ test_config_global protocol.file.allow always &&
+
+ test_when_finished "rm -rf src-sub" &&
+ git init src-sub &&
+ git -C src-sub config uploadpack.allowfilter 1 &&
+ git -C src-sub config uploadpack.allowanysha1inwant 1 &&
+
+ # This blob must be missing in the subsequent commit.
+ echo foo >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule one" &&
+ SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
+
+ echo bar >src-sub/file &&
+ git -C src-sub add file &&
+ git -C src-sub commit -m "submodule two" &&
+ SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
+
+ test_when_finished "rm -rf src-super" &&
+ git init src-super &&
+ git -C src-super config uploadpack.allowfilter 1 &&
+ git -C src-super config uploadpack.allowanysha1inwant 1 &&
+ git -C src-super submodule add ../src-sub src-sub &&
+
+ git -C src-super/src-sub checkout $SUB_ONE &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject one" &&
+
+ git -C src-super/src-sub checkout $SUB_TWO &&
+ git -C src-super add src-sub &&
+ git -C src-super commit -m "superproject two" &&
+
+ # the fetch
+ test_when_finished "rm -rf client" &&
+ git clone --filter=blob:none --also-filter-submodules \
+ --recurse-submodules "file://$(pwd)/src-super" client &&
+
+ # Trigger lazy-fetch from the superproject
+ git -C client restore --recurse-submodules --source=HEAD^ :/
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 3/9] submodule.c & submodule--helper: pass along "super_prefix" param
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 1/9] submodule absorbgitdirs tests: add missing "Migrating git..." tests Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 2/9] read-tree + fetch tests: test failing "--super-prefix" interaction Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
` (5 subsequent siblings)
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
Start passing the "super_prefix" along as a parameter to
get_submodule_displaypath() and absorb_git_dir_into_superproject(),
rather than get the value directly as a global.
This is in preparation for subsequent commits, where we'll gradually
phase out get_super_prefix() for an alternative way of getting the
"super_prefix".
Most of the users of this get a get_super_prefix() value, either
directly or by indirection. The exceptions are:
- builtin/rm.c: Doesn't declare SUPPORT_SUPER_PREFIX, so we'd have
died if this was provided, so it's safe to pass "NULL".
- deinit_submodule(): The "deinit_submodule()" function has never been
able to use the "git -super-prefix". It will call
"absorb_git_dir_into_superproject()", but it will only do so from the
top-level project.
If "absorbgitdirs" recurses will use the "path" passed to
"absorb_git_dir_into_superproject()" in "deinit_submodule()" as its
starting "--super-prefix". So we can safely remove the
get_super_prefix() call here, and pass NULL instead.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/rm.c | 2 +-
builtin/submodule--helper.c | 35 ++++++++++++++++++++++-------------
submodule.c | 15 +++++++++------
submodule.h | 3 ++-
4 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/builtin/rm.c b/builtin/rm.c
index d4989d4d863..4a4aec0d00e 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -86,7 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void)
continue;
if (!submodule_uses_gitfile(name))
- absorb_git_dir_into_superproject(name);
+ absorb_git_dir_into_superproject(name, NULL);
}
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 05f2c9bc985..da844cad5ce 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -113,10 +113,9 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int
}
/* the result should be freed by the caller. */
-static char *get_submodule_displaypath(const char *path, const char *prefix)
+static char *get_submodule_displaypath(const char *path, const char *prefix,
+ const char *super_prefix)
{
- const char *super_prefix = get_super_prefix();
-
if (prefix && super_prefix) {
BUG("cannot have prefix '%s' and superprefix '%s'",
prefix, super_prefix);
@@ -294,7 +293,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
struct child_process cp = CHILD_PROCESS_INIT;
char *displaypath;
- displaypath = get_submodule_displaypath(path, info->prefix);
+ displaypath = get_submodule_displaypath(path, info->prefix,
+ get_super_prefix());
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -447,7 +447,8 @@ static void init_submodule(const char *path, const char *prefix,
const char *upd;
char *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -624,7 +625,8 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ -948,7 +950,8 @@ static void generate_submodule_summary(struct summary_cb *info,
dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
}
- displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
+ displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
+ get_super_prefix());
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ -1239,7 +1242,8 @@ static void sync_submodule(const char *path, const char *prefix,
super_config_url = xstrdup("");
}
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix,
+ get_super_prefix());
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ -1365,7 +1369,7 @@ static void deinit_submodule(const char *path, const char *prefix,
if (!sub || !sub->name)
goto cleanup;
- displaypath = get_submodule_displaypath(path, prefix);
+ displaypath = get_submodule_displaypath(path, prefix, NULL);
/* remove the submodule work tree (unless the user already did it) */
if (is_directory(path)) {
@@ -1379,7 +1383,7 @@ static void deinit_submodule(const char *path, const char *prefix,
".git file by using absorbgitdirs."),
displaypath);
- absorb_git_dir_into_superproject(path);
+ absorb_git_dir_into_superproject(path, NULL);
}
@@ -1958,7 +1962,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
enum submodule_update_type update_type;
char *key;
const struct update_data *ud = suc->update_data;
- char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
+ char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
+ get_super_prefix());
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ -2608,7 +2613,8 @@ static int update_submodules(struct update_data *update_data)
goto fail;
update_data->displaypath = get_submodule_displaypath(
- update_data->sm_path, update_data->prefix);
+ update_data->sm_path, update_data->prefix,
+ get_super_prefix());
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ -2828,6 +2834,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
+ const char *super_prefix;
struct option embed_gitdir_options[] = {
OPT_END()
};
@@ -2843,8 +2850,10 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
goto cleanup;
+ super_prefix = get_super_prefix();
for (i = 0; i < list.nr; i++)
- absorb_git_dir_into_superproject(list.entries[i]->name);
+ absorb_git_dir_into_superproject(list.entries[i]->name,
+ super_prefix);
ret = 0;
cleanup:
diff --git a/submodule.c b/submodule.c
index 8ac2fca855d..bf19598b8c2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2145,7 +2145,8 @@ int submodule_move_head(const char *path,
if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
if (old_head) {
if (!submodule_uses_gitfile(path))
- absorb_git_dir_into_superproject(path);
+ absorb_git_dir_into_superproject(path,
+ get_super_prefix());
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2315,7 +2316,8 @@ static void relocate_single_git_dir_into_superproject(const char *path)
strbuf_release(&new_gitdir);
}
-static void absorb_git_dir_into_superproject_recurse(const char *path)
+static void absorb_git_dir_into_superproject_recurse(const char *path,
+ const char *super_prefix)
{
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2323,8 +2325,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/",
- get_super_prefix_or_empty(), path);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+ super_prefix : "", path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
prepare_submodule_repo_env(&cp.env);
@@ -2337,7 +2339,8 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
* having its git directory within the working tree to the git dir nested
* in its superprojects git dir under modules/.
*/
-void absorb_git_dir_into_superproject(const char *path)
+void absorb_git_dir_into_superproject(const char *path,
+ const char *super_prefix)
{
int err_code;
const char *sub_git_dir;
@@ -2386,7 +2389,7 @@ void absorb_git_dir_into_superproject(const char *path)
}
strbuf_release(&gitdir);
- absorb_git_dir_into_superproject_recurse(path);
+ absorb_git_dir_into_superproject_recurse(path, super_prefix);
}
int get_superproject_working_tree(struct strbuf *buf)
diff --git a/submodule.h b/submodule.h
index b52a4ff1e73..f90ee547d08 100644
--- a/submodule.h
+++ b/submodule.h
@@ -164,7 +164,8 @@ 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(const char *path,
+ const char *super_prefix);
/*
* Return the absolute path of the working tree of the superproject, which this
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs"
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
` (2 preceding siblings ...)
2022-12-20 12:39 ` [PATCH v5 3/9] submodule.c & submodule--helper: pass along "super_prefix" param Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 5/9] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
` (4 subsequent siblings)
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
The "--super-prefix" facility was introduced in [1] has always been a
transitory hack, which is why we've made it an error to supply it as
an option to "git" to commands that don't know about it.
That's been a good goal, as it has a global effect we haven't wanted
calls to get_super_prefix() from built-ins we didn't expect.
But it has meant that when we've had chains of different built-ins
using it all of the processes in that "chain" have needed to support
it, and worse processes that don't need it have needed to ask for
"SUPPORT_SUPER_PREFIX" because their parent process needs it.
That's how "fsmonitor--daemon" ended up with it, per [2] it's called
from (among other things) "submodule--helper absorbgitdirs", but as we
declared "submodule--helper" as "SUPPORT_SUPER_PREFIX" we needed to
declare "fsmonitor--daemon" as accepting it too, even though it
doesn't care about it.
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.
Let's instead accept a hidden "--super-prefix" option to
"submodule--helper absorbgitdirs" itself.
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.
The "fsmonitor--daemon" test adjusted here was added in [3]. To assert
that it didn't run into the "--super-prefix" message it was asserting
the output it didn't have. Let's instead assert the full output that
we *do* have, using the same pattern as a preceding change to
"t/t7412-submodule-absorbgitdirs.sh" used.
We could also remove the test entirely (as [4] did), but even though
the initial reason for having it is gone we're still getting some
marginal benefit from testing the "fsmonitor" and "submodule
absorbgitdirs" interaction, so let's keep it.
The change here to have either a NULL or non-"" string as a
"super_prefix" instead of the previous arrangement of "" or non-"" is
somewhat arbitrary. We could also decide to never have to check for
NULL.
As we'll be changing the rest of the "git --super-prefix" users to the
same pattern, leaving them all consistent makes sense. Why not pick ""
over NULL? Because that's how the "prefix" works[5], and having
"prefix" and "super_prefix" work the same way will be less
confusing. That "prefix" picked NULL instead of "" is itself
arbitrary, but as it's easy to make this small bit of our overall API
consistent, let's go with that.
1. 74866d75793 (git: make super-prefix option, 2016-10-07)
2. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
3. 53fcfbc84f6 (fsmonitor--daemon: allow --super-prefix argument,
2022-05-26)
4. https://lore.kernel.org/git/20221109004708.97668-5-chooglen@google.com/
5. 9725c8dda20 (built-ins: trust the "prefix" from run_builtin(),
2022-02-16)
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 7 +++----
git.c | 2 +-
parse-options.h | 4 ++++
submodule.c | 12 +++++++-----
t/t7527-builtin-fsmonitor.sh | 36 ++++++++++++++----------------------
5 files changed, 29 insertions(+), 32 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index da844cad5ce..b8b2bc776d1 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2834,8 +2834,9 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
- const char *super_prefix;
+ const char *super_prefix = NULL;
struct option embed_gitdir_options[] = {
+ OPT__SUPER_PREFIX(&super_prefix),
OPT_END()
};
const char *const git_submodule_helper_usage[] = {
@@ -2850,7 +2851,6 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
goto cleanup;
- super_prefix = get_super_prefix();
for (i = 0; i < list.nr; i++)
absorb_git_dir_into_superproject(list.entries[i]->name,
super_prefix);
@@ -3391,8 +3391,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
- get_super_prefix())
+ strcmp(subcmd, "sync") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
diff --git a/git.c b/git.c
index 277a8cce840..e473b4b7d72 100644
--- a/git.c
+++ b/git.c
@@ -539,7 +539,7 @@ static struct cmd_struct commands[] = {
{ "format-patch", cmd_format_patch, RUN_SETUP },
{ "fsck", cmd_fsck, RUN_SETUP },
{ "fsck-objects", cmd_fsck, RUN_SETUP },
- { "fsmonitor--daemon", cmd_fsmonitor__daemon, SUPPORT_SUPER_PREFIX | RUN_SETUP },
+ { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP },
{ "gc", cmd_gc, RUN_SETUP },
{ "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
{ "grep", cmd_grep, RUN_SETUP_GENTLY },
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 bf19598b8c2..46a03473195 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2275,7 +2275,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;
@@ -2305,7 +2306,7 @@ static void relocate_single_git_dir_into_superproject(const char *path)
real_new_git_dir = real_pathdup(new_gitdir.buf, 1);
fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"),
- get_super_prefix_or_empty(), path,
+ super_prefix ? super_prefix : "", path,
real_old_git_dir, real_new_git_dir);
relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
@@ -2325,10 +2326,11 @@ static void absorb_git_dir_into_superproject_recurse(const char *path,
cp.dir = path;
cp.git_cmd = 1;
cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
- super_prefix : "", path);
strvec_pushl(&cp.args, "submodule--helper",
"absorbgitdirs", NULL);
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ?
+ super_prefix : "", path);
+
prepare_submodule_repo_env(&cp.env);
if (run_command(&cp))
die(_("could not recurse into submodule '%s'"), path);
@@ -2382,7 +2384,7 @@ void absorb_git_dir_into_superproject(const char *path,
char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
if (!starts_with(real_sub_git_dir, real_common_git_dir))
- relocate_single_git_dir_into_superproject(path);
+ relocate_single_git_dir_into_superproject(path, super_prefix);
free(real_sub_git_dir);
free(real_common_git_dir);
diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
index 4abc74db2bb..76d0220daa0 100755
--- a/t/t7527-builtin-fsmonitor.sh
+++ b/t/t7527-builtin-fsmonitor.sh
@@ -866,27 +866,9 @@ test_expect_success 'submodule always visited' '
# the submodule, and someone does a `git submodule absorbgitdirs`
# in the super, Git will recursively invoke `git submodule--helper`
# to do the work and this may try to read the index. This will
-# try to start the daemon in the submodule *and* pass (either
-# directly or via inheritance) the `--super-prefix` arg to the
-# `git fsmonitor--daemon start` command inside the submodule.
-# This causes a warning because fsmonitor--daemon does take that
-# global arg (see the table in git.c)
-#
-# This causes a warning when trying to start the daemon that is
-# somewhat confusing. It does not seem to hurt anything because
-# the fsmonitor code maps the query failure into a trivial response
-# and does the work anyway.
-#
-# It would be nice to silence the warning, however.
-
-have_t2_error_event () {
- log=$1
- msg="fsmonitor--daemon doesnQt support --super-prefix" &&
-
- tr '\047' Q <$1 | grep -e "$msg"
-}
+# try to start the daemon in the submodule.
-test_expect_success "stray submodule super-prefix warning" '
+test_expect_success "submodule absorbgitdirs implicitly starts daemon" '
test_when_finished "rm -rf super; \
rm -rf sub; \
rm super-sub.trace" &&
@@ -904,10 +886,20 @@ test_expect_success "stray submodule super-prefix warning" '
test_path_is_dir super/dir_1/dir_2/sub/.git &&
+ cwd="$(cd super && pwd)" &&
+ cat >expect <<-EOF &&
+ Migrating git directory of '\''dir_1/dir_2/sub'\'' from
+ '\''$cwd/dir_1/dir_2/sub/.git'\'' to
+ '\''$cwd/.git/modules/dir_1/dir_2/sub'\''
+ EOF
GIT_TRACE2_EVENT="$PWD/super-sub.trace" \
- git -C super submodule absorbgitdirs &&
+ git -C super submodule absorbgitdirs >out 2>actual &&
+ test_cmp expect actual &&
+ test_must_be_empty out &&
- ! have_t2_error_event super-sub.trace
+ # Confirm that the trace2 log contains a record of the
+ # daemon starting.
+ test_subcommand git fsmonitor--daemon start <super-sub.trace
'
# On a case-insensitive file system, confirm that the daemon
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 5/9] submodule--helper: convert "foreach" to its own "--super-prefix"
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
` (3 preceding siblings ...)
2022-12-20 12:39 ` [PATCH v5 4/9] submodule--helper: don't use global --super-prefix in "absorbgitdirs" Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 6/9] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
` (3 subsequent siblings)
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper foreach" to use its own "--super-prefix", instead
of relying on the global "--super-prefix" argument to "git"
itself. See that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b8b2bc776d1..2a6ced13f6d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -278,6 +278,7 @@ struct foreach_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
int quiet;
int recursive;
};
@@ -294,7 +295,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
char *displaypath;
displaypath = get_submodule_displaypath(path, info->prefix,
- get_super_prefix());
+ info->super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -364,10 +365,10 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_pushl(&cpr.args, "--super-prefix", NULL);
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive",
NULL);
+ strvec_pushl(&cpr.args, "--super-prefix", NULL);
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (info->quiet)
strvec_push(&cpr.args, "--quiet");
@@ -391,6 +392,7 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
struct option module_foreach_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
OPT_BOOL(0, "recursive", &info.recursive,
N_("recurse into nested submodules")),
@@ -3390,8 +3392,8 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
- strcmp(subcmd, "sync") && get_super_prefix())
+ strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 6/9] submodule--helper: convert "sync" to its own "--super-prefix"
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
` (4 preceding siblings ...)
2022-12-20 12:39 ` [PATCH v5 5/9] submodule--helper: convert "foreach" to its own "--super-prefix" Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 7/9] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
` (2 subsequent siblings)
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper sync" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 2a6ced13f6d..7262ce72edf 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1208,12 +1208,13 @@ static int module_summary(int argc, const char **argv, const char *prefix)
struct sync_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define SYNC_CB_INIT { 0 }
static void sync_submodule(const char *path, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
const struct submodule *sub;
char *remote_key = NULL;
@@ -1244,8 +1245,7 @@ static void sync_submodule(const char *path, const char *prefix,
super_config_url = xstrdup("");
}
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if (!(flags & OPT_QUIET))
printf(_("Synchronizing submodule url for '%s'\n"),
@@ -1282,10 +1282,11 @@ static void sync_submodule(const char *path, const char *prefix,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "sync",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
+
if (flags & OPT_QUIET)
strvec_push(&cpr.args, "--quiet");
@@ -1308,7 +1309,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct sync_cb *info = cb_data;
- sync_submodule(list_item->name, info->prefix, info->flags);
+ sync_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_sync(int argc, const char **argv, const char *prefix)
@@ -1319,6 +1321,7 @@ static int module_sync(int argc, const char **argv, const char *prefix)
int quiet = 0;
int recursive = 0;
struct option module_sync_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
OPT_BOOL(0, "recursive", &recursive,
N_("recurse into nested submodules")),
@@ -2887,7 +2890,7 @@ static int module_set_url(int argc, const char **argv, const char *prefix)
config_name = xstrfmt("submodule.%s.url", path);
config_set_in_gitmodules_file_gently(config_name, newurl);
- sync_submodule(path, prefix, quiet ? OPT_QUIET : 0);
+ sync_submodule(path, prefix, NULL, quiet ? OPT_QUIET : 0);
free(config_name);
@@ -3392,8 +3395,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && strcmp(subcmd, "sync") &&
- get_super_prefix())
+ strcmp(subcmd, "status") && get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 7/9] submodule--helper: convert "status" to its own "--super-prefix"
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
` (5 preceding siblings ...)
2022-12-20 12:39 ` [PATCH v5 6/9] submodule--helper: convert "sync" " Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 8/9] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 9/9] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git" itself. See
that earlier commit for the rationale and background.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 7262ce72edf..448896f1b1d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -573,6 +573,7 @@ static int module_init(int argc, const char **argv, const char *prefix)
struct status_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define STATUS_CB_INIT { 0 }
@@ -611,7 +612,7 @@ static int handle_submodule_head_ref(const char *refname UNUSED,
static void status_submodule(const char *path, const struct object_id *ce_oid,
unsigned int ce_flags, const char *prefix,
- unsigned int flags)
+ const char *super_prefix, unsigned int flags)
{
char *displaypath;
struct strvec diff_files_args = STRVEC_INIT;
@@ -627,8 +628,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
print_status(flags, 'U', path, null_oid(), displaypath);
@@ -686,10 +686,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
cpr.dir = path;
prepare_submodule_repo_env(&cpr.env);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
strvec_pushl(&cpr.args, "submodule--helper", "status",
"--recursive", NULL);
+ strvec_push(&cpr.args, "--super-prefix");
+ strvec_pushf(&cpr.args, "%s/", displaypath);
if (flags & OPT_CACHED)
strvec_push(&cpr.args, "--cached");
@@ -713,7 +713,7 @@ static void status_submodule_cb(const struct cache_entry *list_item,
struct status_cb *info = cb_data;
status_submodule(list_item->name, &list_item->oid, list_item->ce_flags,
- info->prefix, info->flags);
+ info->prefix, info->super_prefix, info->flags);
}
static int module_status(int argc, const char **argv, const char *prefix)
@@ -723,6 +723,7 @@ static int module_status(int argc, const char **argv, const char *prefix)
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
struct option module_status_options[] = {
+ OPT__SUPER_PREFIX(&info.super_prefix),
OPT__QUIET(&quiet, N_("suppress submodule status output")),
OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
@@ -3395,7 +3396,7 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
subcmd = argv[0];
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- strcmp(subcmd, "status") && get_super_prefix())
+ get_super_prefix())
/*
* xstrfmt() rather than "%s %s" to keep the translated
* string identical to git.c's.
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 8/9] submodule--helper: convert "{update,clone}" to their own "--super-prefix"
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
` (6 preceding siblings ...)
2022-12-20 12:39 ` [PATCH v5 7/9] submodule--helper: convert "status" " Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
2022-12-20 12:39 ` [PATCH v5 9/9] read-tree: add "--super-prefix" option, eliminate global Ævar Arnfjörð Bjarmason
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
As with a preceding commit to convert "absorbgitdirs", we can convert
"submodule--helper status" to use its own "--super-prefix", instead of
relying on the global "--super-prefix" argument to "git".
We need to convert both of these away from the global "--super-prefix"
at the same time, because "update" will call "clone", but "clone"
itself didn't make use of the global "--super-prefix" for displaying
paths. It was only on the list of sub-commands that accepted it
because "update"'s use of it would set it in its environment.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
builtin/submodule--helper.c | 32 +++++++++++++-------------------
git.c | 2 +-
2 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 448896f1b1d..a0aa4635a0c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -437,11 +437,13 @@ static int starts_with_dot_dot_slash(const char *const path)
struct init_cb {
const char *prefix;
+ const char *super_prefix;
unsigned int flags;
};
#define INIT_CB_INIT { 0 }
static void init_submodule(const char *path, const char *prefix,
+ const char *super_prefix,
unsigned int flags)
{
const struct submodule *sub;
@@ -449,8 +451,7 @@ static void init_submodule(const char *path, const char *prefix,
const char *upd;
char *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix,
- get_super_prefix());
+ displaypath = get_submodule_displaypath(path, prefix, super_prefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -526,7 +527,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data
{
struct init_cb *info = cb_data;
- init_submodule(list_item->name, info->prefix, info->flags);
+ init_submodule(list_item->name, info->prefix, info->super_prefix,
+ info->flags);
}
static int module_init(int argc, const char **argv, const char *prefix)
@@ -792,6 +794,7 @@ struct summary_cb {
int argc;
const char **argv;
const char *prefix;
+ const char *super_prefix;
unsigned int cached: 1;
unsigned int for_status: 1;
unsigned int files: 1;
@@ -954,7 +957,7 @@ static void generate_submodule_summary(struct summary_cb *info,
}
displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
- get_super_prefix());
+ info->super_prefix);
if (!missing_src && !missing_dst) {
struct child_process cp_rev_list = CHILD_PROCESS_INIT;
@@ -1893,6 +1896,7 @@ static void submodule_update_clone_release(struct submodule_update_clone *suc)
struct update_data {
const char *prefix;
+ const char *super_prefix;
char *displaypath;
enum submodule_update_type update_default;
struct object_id suboid;
@@ -1969,7 +1973,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
char *key;
const struct update_data *ud = suc->update_data;
char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
- get_super_prefix());
+ ud->super_prefix);
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
int need_free_url = 0;
@@ -2449,11 +2453,11 @@ static void update_data_to_args(const struct update_data *update_data,
{
enum submodule_update_type update_type = update_data->update_default;
+ strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
if (update_data->displaypath) {
strvec_push(args, "--super-prefix");
strvec_pushf(args, "%s/", update_data->displaypath);
}
- strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
if (update_data->quiet)
strvec_push(args, "--quiet");
@@ -2620,7 +2624,7 @@ static int update_submodules(struct update_data *update_data)
update_data->displaypath = get_submodule_displaypath(
update_data->sm_path, update_data->prefix,
- get_super_prefix());
+ update_data->super_prefix);
code = update_submodule(update_data);
FREE_AND_NULL(update_data->displaypath);
fail:
@@ -2646,6 +2650,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
LIST_OBJECTS_FILTER_INIT;
int ret;
struct option module_update_options[] = {
+ OPT__SUPER_PREFIX(&opt.super_prefix),
OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
OPT_BOOL(0, "init", &opt.init,
N_("initialize uninitialized submodules before update")),
@@ -2742,6 +2747,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
module_list_active(&list);
info.prefix = opt.prefix;
+ info.super_prefix = opt.super_prefix;
if (opt.quiet)
info.flags |= OPT_QUIET;
@@ -3368,8 +3374,6 @@ static int module_add(int argc, const char **argv, const char *prefix)
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
{
- const char *cmd = argv[0];
- const char *subcmd;
parse_opt_subcommand_fn *fn = NULL;
const char *const usage[] = {
N_("git submodule--helper <command>"),
@@ -3393,16 +3397,6 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
OPT_END()
};
argc = parse_options(argc, argv, prefix, options, usage, 0);
- subcmd = argv[0];
-
- if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
- get_super_prefix())
- /*
- * xstrfmt() rather than "%s %s" to keep the translated
- * string identical to git.c's.
- */
- die(_("%s doesn't support --super-prefix"),
- xstrfmt("'%s %s'", cmd, subcmd));
return fn(argc, argv, prefix);
}
diff --git a/git.c b/git.c
index e473b4b7d72..2c31ba27040 100644
--- a/git.c
+++ b/git.c
@@ -610,7 +610,7 @@ static struct cmd_struct commands[] = {
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
- { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX },
+ { "submodule--helper", cmd_submodule__helper, RUN_SETUP },
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread
* [PATCH v5 9/9] read-tree: add "--super-prefix" option, eliminate global
2022-12-20 12:39 ` [PATCH v5 " Ævar Arnfjörð Bjarmason
` (7 preceding siblings ...)
2022-12-20 12:39 ` [PATCH v5 8/9] submodule--helper: convert "{update,clone}" to their " Ævar Arnfjörð Bjarmason
@ 2022-12-20 12:39 ` Ævar Arnfjörð Bjarmason
8 siblings, 0 replies; 105+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-20 12:39 UTC (permalink / raw)
To: git
Cc: Glen Choo, Junio C Hamano, Taylor Blau, Robert Coup,
Ævar Arnfjörð Bjarmason
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>
---
Documentation/git.txt | 8 +-------
builtin.h | 4 ----
builtin/checkout.c | 2 +-
builtin/read-tree.c | 1 +
cache.h | 2 --
entry.c | 12 ++++++------
entry.h | 6 +++++-
environment.c | 13 -------------
git.c | 37 +++++--------------------------------
submodule.c | 29 ++++++++++-------------------
submodule.h | 5 ++---
t/t1001-read-tree-m-2way.sh | 2 +-
t/t5616-partial-clone.sh | 2 +-
unpack-trees.c | 24 ++++++++++++++----------
unpack-trees.h | 1 +
15 files changed, 48 insertions(+), 100 deletions(-)
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 1d33e083ab8..f9a7a4554cd 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
diff --git a/builtin.h b/builtin.h
index aa955466b4e..46cc7897898 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
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a0142c815fd..cd04f0bf572 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)
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index f702f9d47bb..3ce75417833 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),
diff --git a/cache.h b/cache.h
index 07d40b0964b..7f7e2b5a38f 100644
--- a/cache.h
+++ b/cache.h
@@ -480,7 +480,6 @@ 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"
@@ -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);
const char *get_git_namespace(void);
const char *strip_namespace(const char *namespaced_ref);
-const char *get_super_prefix(void);
const char *get_git_work_tree(void);
/*
diff --git a/entry.c b/entry.c
index 616e4f073c1..971ab268714 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)
diff --git a/entry.h b/entry.h
index 9be4659881e..2d4fbb88c8f 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);
diff --git a/environment.c b/environment.c
index 18d042b467d..1ee3686fd8a 100644
--- a/environment.c
+++ b/environment.c
@@ -102,8 +102,6 @@ char *git_work_tree_cfg;
static char *git_namespace;
-static char *super_prefix;
-
/*
* Repository-local GIT_* environment variables; see cache.h for details.
*/
@@ -121,7 +119,6 @@ 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
@@ -234,16 +231,6 @@ const char *strip_namespace(const char *namespaced_ref)
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;
/*
diff --git a/git.c b/git.c
index 2c31ba27040..32a5be68a17 100644
--- a/git.c
+++ b/git.c
@@ -14,9 +14,8 @@
* RUN_SETUP for reading from the configuration file.
*/
#define NEED_WORK_TREE (1<<3)
-#define SUPPORT_SUPER_PREFIX (1<<4)
-#define DELAY_PAGER_CONFIG (1<<5)
-#define NO_PARSEOPT (1<<6) /* parse-options is not used */
+#define DELAY_PAGER_CONFIG (1<<4)
+#define NO_PARSEOPT (1<<5) /* parse-options is not used */
struct cmd_struct {
const char *cmd;
@@ -29,8 +28,7 @@ const char git_usage_string[] =
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
- " [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
- " <command> [<args>]");
+ " [--config-env=<name>=<envvar>] <command> [<args>]");
const char git_more_info_string[] =
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);
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;
@@ -449,11 +433,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
trace_repo_setup(prefix);
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)
setup_work_tree();
@@ -504,7 +483,7 @@ static struct cmd_struct commands[] = {
{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
{ "checkout--worker", cmd_checkout__worker,
- RUN_SETUP | NEED_WORK_TREE | SUPPORT_SUPER_PREFIX },
+ RUN_SETUP | NEED_WORK_TREE },
{ "checkout-index", cmd_checkout_index,
RUN_SETUP | NEED_WORK_TREE},
{ "cherry", cmd_cherry, RUN_SETUP },
@@ -583,7 +562,7 @@ static struct cmd_struct commands[] = {
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
{ "push", cmd_push, RUN_SETUP },
{ "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 },
{ "receive-pack", cmd_receive_pack },
{ "reflog", cmd_reflog, RUN_SETUP },
@@ -727,9 +706,6 @@ static void execv_dashed_external(const char **argv)
struct child_process cmd = CHILD_PROCESS_INIT;
int status;
- if (get_super_prefix())
- die(_("%s doesn't support --super-prefix"), argv[0]);
-
if (use_pager == -1 && !is_builtin(argv[0]))
use_pager = check_pager_config(argv[0]);
commit_pager_choice();
@@ -799,9 +775,6 @@ static int run_argv(int *argcp, const char ***argv)
*/
trace2_cmd_name("_run_git_alias_");
- if (get_super_prefix())
- die("%s doesn't support --super-prefix", **argv);
-
commit_pager_choice();
strvec_push(&cmd.args, "git");
diff --git a/submodule.c b/submodule.c
index 46a03473195..d730b64b072 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2054,14 +2054,6 @@ void submodule_unset_core_worktree(const struct submodule *sub)
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)
{
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);
}
-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;
prepare_submodule_repo_env(&cp.env);
@@ -2089,10 +2081,10 @@ static void submodule_reset_index(const char *path)
cp.no_stdin = 1;
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 */
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());
@@ -2105,10 +2097,9 @@ static void submodule_reset_index(const char *path)
* For edge cases (a submodule coming into existence or removing a submodule)
* pass NULL for old or new respectively.
*/
-int submodule_move_head(const char *path,
- const char *old_head,
- const char *new_head,
- unsigned flags)
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
+ unsigned flags)
{
int ret = 0;
struct child_process cp = CHILD_PROCESS_INIT;
@@ -2146,7 +2137,7 @@ int submodule_move_head(const char *path,
if (old_head) {
if (!submodule_uses_gitfile(path))
absorb_git_dir_into_superproject(path,
- get_super_prefix());
+ super_prefix);
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2155,7 +2146,7 @@ int submodule_move_head(const char *path,
strbuf_release(&gitdir);
/* 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)) {
@@ -2173,9 +2164,9 @@ int submodule_move_head(const char *path,
cp.no_stdin = 1;
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_pushf(&cp.args, "--super-prefix=%s%s/",
+ (super_prefix ? super_prefix : ""), path);
if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN)
strvec_push(&cp.args, "-n");
diff --git a/submodule.h b/submodule.h
index f90ee547d08..c55a25ca37d 100644
--- a/submodule.h
+++ b/submodule.h
@@ -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_FORCE (1<<1)
-int submodule_move_head(const char *path,
- const char *old,
- const char *new_head,
+int submodule_move_head(const char *path, const char *super_prefix,
+ const char *old_head, const char *new_head,
unsigned flags);
void submodule_unset_core_worktree(const struct submodule *sub);
diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh
index 516a6112fdc..3fb1b0c162d 100755
--- a/t/t1001-read-tree-m-2way.sh
+++ b/t/t1001-read-tree-m-2way.sh
@@ -370,7 +370,7 @@ test_expect_success 'read-tree supports the super-prefix' '
cat <<-EOF >expect &&
error: Updating '\''fictional/a'\'' would lose untracked files in it
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
'
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 2846ec6629c..f519d2a87a7 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,7 +644,7 @@ test_expect_success 'repack does not loosen promisor objects' '
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
test_config_global protocol.file.allow always &&
diff --git a/unpack-trees.c b/unpack-trees.c
index 8a762aa0772..2b8e5da4c21 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -71,7 +71,7 @@ static const char *unpack_plumbing_errors[NB_UNPACK_TREES_WARNING_TYPES] = {
? ((o)->msgs[(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
@@ -83,7 +83,6 @@ static const char *super_prefixed(const char *path)
static unsigned idx = ARRAY_SIZE(buf) - 1;
if (super_prefix_len < 0) {
- const char *super_prefix = get_super_prefix();
if (!super_prefix) {
super_prefix_len = 0;
} else {
@@ -236,7 +235,8 @@ static int add_rejected_path(struct unpack_trees_options *o,
return -1;
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
@@ -263,7 +263,8 @@ static void display_error_msgs(struct unpack_trees_options *o)
error_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -290,7 +291,8 @@ static void display_warning_msgs(struct unpack_trees_options *o)
warning_displayed = 1;
for (i = 0; i < rejects->nr; i++)
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);
}
string_list_clear(rejects, 0);
@@ -312,7 +314,8 @@ static int check_submodule_move_head(const struct cache_entry *ce,
if (o->reset)
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 0;
}
@@ -415,6 +418,7 @@ static int check_updates(struct unpack_trees_options *o,
int i, pc_workers, pc_threshold;
trace_performance_enter();
+ state.super_prefix = o->super_prefix;
state.force = 1;
state.quiet = 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) {
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)
return o->quiet ? -1 :
error(ERRORMSG(o, ERROR_BIND_OVERLAP),
- super_prefixed(a->name),
- super_prefixed(old->name));
+ super_prefixed(a->name, o->super_prefix),
+ super_prefixed(old->name, o->super_prefix));
if (!a)
return keep_entry(old, o);
else
@@ -3021,7 +3025,7 @@ int stash_worktree_untracked_merge(const struct cache_entry * const *src,
if (worktree && untracked)
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);
}
diff --git a/unpack-trees.h b/unpack-trees.h
index 6ab0d74c84d..3a7b3e5f007 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -75,6 +75,7 @@ struct unpack_trees_options {
skip_cache_tree_update;
enum unpack_trees_reset_type reset;
const char *prefix;
+ const char *super_prefix;
int cache_bottom;
struct pathspec *pathspec;
merge_fn_t fn;
--
2.39.0.1071.g97ce8966538
^ permalink raw reply related [flat|nested] 105+ messages in thread