git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Cc: Jonathan Nieder <jrnieder@gmail.com>,
	Zero King <l2dy@macports.org>,
	Git Mailing List <git@vger.kernel.org>
Subject: Re: [Bug] setup_git_env called without repository
Date: Mon, 29 May 2017 11:32:50 -0400	[thread overview]
Message-ID: <20170529153250.zq4qz3s5fmztc6ih@sigill.intra.peff.net> (raw)
In-Reply-To: <CACBZZX4kfNhEOtgpFkWtuTZshJX+tX_Dogd6tk6qEuGX07JqiA@mail.gmail.com>

On Mon, May 29, 2017 at 03:01:11PM +0200, Ævar Arnfjörð Bjarmason wrote:

> On Mon, May 29, 2017 at 1:45 PM, Zero King <l2dy@macports.org> wrote:
> > After upgrading to Git 2.13.0, I'm seeing the following error message
> > when running `git am -h`.
> >
> >    $ git am -h
> >    fatal: BUG: setup_git_env called without repository
> >
> > And with Git built from the next branch:
> >
> >    $ git am -h
> >    BUG: environment.c:172: setup_git_env called without repository
> >    Abort trap: 6
> 
> Jeff, bisects to your b1ef400eec ("setup_git_env: avoid blind
> fall-back to ".git"", 2016-10-20).

Well, yes. But that commit is just making it easier to notice existing
violations of the setup_git_env() rules. The interesting thing is where
the violation comes from. :)

In this case, the "am" builtin uses git_pathdup() and git_config() to
set up some defaults before calling parse_options(), which is where we
handle "-h". Normally that's fine, because it uses the RUN_SETUP flag to
tell the git wrapper to barf if we're not in a repository.

But when the wrapper sees that there is a single command-line argument
and that it's "-h", it skips all of the setup and runs the builtin's
cmd_am() function anyway, under the assumption that the builtin won't do
anything meaningful before noticing the "-h" and dying. This goes back
to Jonathan's 99caeed05 (Let 'git <command> -h' show usage without a git
dir, 2009-11-09).

I have mixed feelings on that commit. It's unquestionably more friendly
to make "git foo -h" work outside of a repository, rather than printing
"Not a git repository". But it does break the assumptions of the cmd_*
functions.

In this case it's fairly harmless. We'd fill in bogus values for the
am_state (a bogus git-dir, but also we'd quietly ignore any repo-level
config when we _are_ in a repo), but those aren't actually used before
we hit the "-h" handling. Conceivably a cmd_* function could show
defaults as part of "-h" output, but I don't know of any cases where
that is true.

I'd be much more worried about cases where the cmd function doesn't
handle "-h" at all, and just proceeds with a broken setup. That said,
it's been this way for almost 8 years. And I see that several commands
already have workarounds for dying early in this case (try grepping for
'"-h"'). So probably we should just follow suit, like:

diff --git a/builtin/am.c b/builtin/am.c
index 0f63dcab1..5ee146bfb 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -2311,6 +2311,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)
 		OPT_END()
 	};
 
+	if (argc == 2 && !strcmp(argv[1], "-h"))
+		usage_with_options(usage, options);
+
 	git_config(git_am_config, NULL);
 
 	am_state_init(&state);

I've used the same incantation there as in other commands; possibly
this should be abstracted to a simple:

  check_help_option(argc, argv, usage, options);

that each builtin could call.

What would be _really_ nice is if the usage/options pointers for each
builtin were made available to git.c, and then it could just call
usage_with_options() itself when it sees "-h". I think that would end up
with more boilerplate than it saves, though, as we'd have to add the
pointer to the definition of each builtin struct in git.c. Possibly it
could be helped with some macro trickery and naming conventions, but I
don't know if it's worth it.

The other thing to add is a test to make sure this doesn't pop up again
in another builtin.  We should be able to do:

  for i in $builtins
  do
	test_expect_success "$i -h works" "
		test_expect_code 129 $i -h
	"
  done

We'd need a list of builtins; probably a "git help --list-builtins"
would be helpful there. I ran something similar by hand and "git am" is
the only command that has this problem (for now, anyway). Interestingly,
"git credential" doesn't parse the "-h" at all, and so it just hangs
waiting for input (and would misbehave by ignoring repo config in this
case!). It should be fixed, too.

I'll try to put together patches in the next day or so. Comments welcome
in the meantime.

-Peff

  reply	other threads:[~2017-05-29 15:33 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-29 11:45 [Bug] setup_git_env called without repository Zero King
2017-05-29 13:01 ` Ævar Arnfjörð Bjarmason
2017-05-29 15:32   ` Jeff King [this message]
2017-05-30  5:09     ` [PATCH 0/8] consistent "-h" handling in builtins Jeff King
2017-05-30  5:11       ` [PATCH 1/8] am: handle "-h" argument earlier Jeff King
2017-05-30  5:43         ` Junio C Hamano
2017-05-30  5:12       ` [PATCH 2/8] credential: handle invalid arguments earlier Jeff King
2017-05-30  5:13       ` [PATCH 3/8] upload-archive: handle "-h" option early Jeff King
2017-05-30  5:15       ` [PATCH 4/8] remote-{ext,fd}: print usage message on invalid arguments Jeff King
2017-05-30  5:16       ` [PATCH 5/8] submodule--helper: show usage for "-h" Jeff King
2017-05-30  5:17       ` [PATCH 6/8] version: convert to parse-options Jeff King
2017-05-30 20:45         ` [PATCH 6.5?/8] version: move --build-options to a test helper Ævar Arnfjörð Bjarmason
2017-05-30 21:05           ` Jeff King
2017-05-31 15:27             ` Johannes Schindelin
2017-05-31 15:31               ` Jeff King
2017-05-31 15:46                 ` Johannes Schindelin
2017-05-31 17:51                   ` Ævar Arnfjörð Bjarmason
2017-05-31 21:06                     ` Jeff King
2017-05-30  5:18       ` [PATCH 7/8] git: add hidden --list-builtins option Jeff King
2017-05-30  5:19       ` [PATCH 8/8] t0012: test "-h" with builtins Jeff King
2017-05-30  6:03         ` Junio C Hamano
2017-05-30  6:05           ` Jeff King
2017-05-30  6:08             ` Junio C Hamano
2017-05-30  6:15               ` Jeff King
2017-05-30 13:23                 ` Junio C Hamano
2017-05-30 15:27                   ` Jeff King
2017-05-30 15:44                     ` Jeff King
2017-05-30 22:39                       ` Junio C Hamano
2017-06-01  4:17                     ` Junio C Hamano
2017-06-01  5:35                       ` Jeff King
2017-06-01  5:42                       ` Junio C Hamano
2017-06-01  5:54                         ` Junio C Hamano
2017-06-01  6:25                           ` Jeff King
2017-06-01  7:51                             ` Junio C Hamano
2017-06-01  6:10                         ` Jeff King
2017-06-13 23:08         ` Jonathan Nieder
2017-06-14 10:03           ` Jeff King
2017-05-30  5:52       ` [PATCH 0/8] consistent "-h" handling in builtins 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=20170529153250.zq4qz3s5fmztc6ih@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jrnieder@gmail.com \
    --cc=l2dy@macports.org \
    /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).