git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: Morian Sonnet <moriansonnet@gmail.com>
Cc: sunshine@sunshineco.us, gitgitgadget@gmail.com,
	git@vger.kernel.org, MorianSonnet@googlemail.com,
	gitster@pobox.com
Subject: Re: [PATCH v2 1/1] submodule foreach: fix recursion of options
Date: Wed, 19 Jun 2019 20:19:34 +0200 (CEST)	[thread overview]
Message-ID: <nycvar.QRO.7.76.6.1906191928420.44@tvgsbejvaqbjf.bet> (raw)
In-Reply-To: <201906181515.x5IFF8bg005587@pool-147-74-zam859.wlan.kfa-juelich.de>

Hi Morian,

On Tue, 18 Jun 2019, Morian Sonnet wrote:

> "Morian Sonnet via GitGitGadget" <gitgitgadget@gmail.com> wrote:
>
> > Calling
> >
> >     git submodule foreach --recursive git reset --hard
> >
> > leads to an error stating that the option --hard is unknown to
> > submodule--helper.
> >
> > Reasons:
> >
> > . Above call is internally translated into
> >
> >     git submodule--helper foreach --recursive -- git reset --hard
> >
> > . After calling
> >
> >     git reset --hard
> >
> >   inside the first first level submodule,
> >
> >     git --super-prefix <submodulepath> submodule--helper \
> >       foreach --recursive git reset --hard
> >
> >   is called. Note the missing --.
> >
> > . Due to the removal of PARSE_OPT_KEEP_UNKNOWN in commit a282f5a906 the
> >   option --hard is not passed to
> >
> >     git reset
> >
> >   anymore, but leads to git submodule--helper complaining about an
> >   unknown option.
> >
> > Fix:
> >
> > . Add -- before the command to execute, such that now correctly
> >
> >     git --super-prefix <submodulepath> submodule--helper \
> >       foreach --recursive -- git reset --hard
> >
> >   is called.

This is a good explanation, even if the format is not exactly close to the
existing commit messages ;-) If you look e.g. at
https://github.com/git/git/commit/e5a329a279c7, you will see what I mean:
there is much more "prose" (and less bullet points) going on.

> > Signed-off-by: Morian Sonnet <moriansonnet@googlemail.com>
> > ---
> >  builtin/submodule--helper.c  | 1 +
> >  t/t7407-submodule-foreach.sh | 7 +++++++
> >  2 files changed, 8 insertions(+)
> >
> > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> > index 0bf4aa088e..afaf0819c9 100644
> > --- a/builtin/submodule--helper.c
> > +++ b/builtin/submodule--helper.c
> > @@ -540,6 +540,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
> >  		if (info->quiet)
> >  			argv_array_push(&cpr.args, "--quiet");
> >
> > +		argv_array_push(&cpr.args, "--");

This is obviously correct.

> >  		argv_array_pushv(&cpr.args, info->argv);
> >
> >  		if (run_command(&cpr))
> > diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
> > index 706ae762e0..c554589e6f 100755
> > --- a/t/t7407-submodule-foreach.sh
> > +++ b/t/t7407-submodule-foreach.sh
> > @@ -421,4 +421,11 @@ test_expect_success 'option-like arguments passed to foreach commands are not lo
> >  	test_cmp expected actual
> >  '
> >
> > +test_expect_success 'option-like arguments passed to foreach recurse correctly' '
> > +  (
> > +    cd super &&
> > +    git submodule foreach --recursive git reset --hard
> > +  )

I am terribly sorry that I did not catch this in the first round. I would
find it even easier to read if it used the `-C` option, like so:

	git -C super submodule foreach --recursive git reset --hard

Then you do not need the subshell, and neither the `cd`. It would become a
one-liner.

However, what is less obvious to me is that this would catch the
regression, as I do not see from the context whether the current submodule
structure is deep enough to trigger the reported problem. If I understand
the commit message correctly, `super` would have to contain a submodule
that itself contains a submodule.

If there was only one level of submodules (and from the context of this
diff, it is not clear whether that is the case), the test case would pass
even without the code change to `submodule.c`.

Of course, I can always dig deeper and find out myself (and of course I
did exactly that). But in my mind, that points to something we can
improve.

What I found is that the test case indeed fails without the fixed
`builtin/submodule.c`, but that the nested submodule does not even need to
be checked out, contrary to what I expected after reading the commit
message.

And in fact, the nested submodule is not even checked out in the test
script!

To make this test case more obvious, and at the same time to test a little
more thoroughly, maybe it would make sense to initialize that "inner"
submodule (in this test script, `super/nested1/nested2`), then make it
dirty by changing a file before the `reset --hard`, and afterwards verify
that the file in question was successfully reset.

That way, the test case would start to fail if anybody changed the script
in a way where the submodule nesting was all of a sudden no longer deep
enough to verify what the test case wants to verify.

Otherwise we would risk that this test case would start passing for the
wrong reasons at some stage.

What I have in mind would look somewhat like this:

	: make sure that nested2 is initialized &&
	git -C super/nested1 submodule update --init nested2 &&

	: make sure that nested2 is dirty &&
	echo dirty >super/nested1/nested2/file &&
	test_must_fail git -C super/nested1/nested2 update-index --refresh &&

	git -C super submodule foreach --recursive git reset --hard &&
	: now nested2 is clean &&
	git -C super/nested1/nested2 update-index --refresh


I might be overthinking this, though. Maybe it would be enough to make
sure that nested1/nested2 is a nested submodule, e.g. by something like
this:

	is_submodule () {
		case "$(git -C "${1%/*}" ls-files --stage "${1##*/}")" in
		160000*) return 0;;
		*) return 1;;
		esac
	} &&
	is_submodule super/nested1 &&
	is_submodule super/nested1/nested2 &&
	git -C super submodule foreach --recursive git reset --hard

which has the advantage of looking shorter, but it does not really verify
that `git reset --hard` *has* been working correctly in nested2: it did
not, as that nested submodule was not even initialized at that point.

So I dunno... What do you think? How can we make this test case both more
understandable and more robust against future edits at the same time?

Ciao,
Johannes

> > +'
> > +
> >  test_done
> > --
> > gitgitgadget
>

  reply	other threads:[~2019-06-19 18:19 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-12 18:10 [PATCH 0/1] submodule foreach: fix recursion of options Morian Sonnet via GitGitGadget
2019-06-12 18:10 ` [PATCH 1/1] " Morian Sonnet via GitGitGadget
2019-06-12 19:35   ` Eric Sunshine
2019-06-12 20:28 ` [PATCH v2 0/1] " Morian Sonnet via GitGitGadget
2019-06-12 20:28   ` [PATCH v2 1/1] " Morian Sonnet via GitGitGadget
2019-06-18 15:15     ` Morian Sonnet
2019-06-19 18:19       ` Johannes Schindelin [this message]
2019-06-22 10:54         ` Morian Sonnet
2019-06-24 10:49           ` Johannes Schindelin
2019-06-24 15:40             ` Morian Sonnet
2019-06-24 15:40             ` [PATCH] " Morian Sonnet
2019-06-24 15:47               ` Morian Sonnet
2019-06-24 15:47               ` [PATCH] " Morian Sonnet
2019-06-24 17:47                 ` Johannes Schindelin
2019-06-24 18:16                 ` Junio C Hamano
2019-06-24 20:26                   ` Morian Sonnet
2019-06-24 20:26                   ` [PATCH] " Morian Sonnet
2019-06-25 11:18                     ` Duy Nguyen
2019-06-25 18:18                       ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=nycvar.QRO.7.76.6.1906191928420.44@tvgsbejvaqbjf.bet \
    --to=johannes.schindelin@gmx.de \
    --cc=MorianSonnet@googlemail.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=gitster@pobox.com \
    --cc=moriansonnet@gmail.com \
    --cc=sunshine@sunshineco.us \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).