From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: "SZEDER Gábor" <szeder.dev@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] blame: default to HEAD in a bare repo when no start commit is given
Date: Mon, 08 Apr 2019 17:48:21 +0200 [thread overview]
Message-ID: <875zroa46y.fsf@evledraar.gmail.com> (raw)
In-Reply-To: <20190408143046.GF8796@szeder.dev>
On Mon, Apr 08 2019, SZEDER Gábor wrote:
> On Mon, Apr 08, 2019 at 02:44:59PM +0200, Ævar Arnfjörð Bjarmason wrote:
>>
>> On Mon, Apr 08 2019, SZEDER Gábor wrote:
>>
>> > When 'git blame' is invoked without specifying the commit to start
>> > blaming from, it starts from the given file's state in the work tree.
>> > However, when invoked in a bare repository without a start commit,
>> > then there is no work tree state to start from, and it dies with the
>> > following error message:
>> >
>> > $ git rev-parse --is-bare-repository
>> > true
>> > $ git blame file.c
>> > fatal: this operation must be run in a work tree
>> >
>> > This is misleading, because it implies that 'git blame' doesn't work
>> > in bare repositories at all, but it does, in fact, work just fine when
>> > it is given a commit to start from.
>> >
>> > We could improve the error message, of course, but let's just default
>> > to HEAD in a bare repository instead, as most likely that is what the
>> > user wanted anyway (if they wanted to start from an other commit, then
>> > they would have specified that in the first place).
>> >
>> > 'git annotate' is just a thin wrapper around 'git blame', so in the
>> > same situation it printed the same misleading error message, and this
>> > patch fixes it, too.
>> >
>> > Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
>>
>> There was the explicit decision not to fall back to HEAD in 1cfe77333f
>> ("git-blame: no rev means start from the working tree file.",
>> 2007-01-30). This change makes sense to me, but perhaps some discussion
>> or reference to the previous commit is warranted?
>
> I don't think so, because that doesn't apply here, since it doesn't
> really make much sense to talk about a working tree file in a bare
> repo.
I mean for context in the sense that the current error we display we
haven't always shown, and explicitly started doing in that commit (but
for another purpose...).
>> Although from skimming the thread from back then it seems to be "not
>> HEAD but working tree file", not "let's not use HEAD in bare repos".
>>
>> > builtin/blame.c | 13 +++++++++++++
>> > t/annotate-tests.sh | 8 ++++++++
>> > 2 files changed, 21 insertions(+)
>> >
>> > diff --git a/builtin/blame.c b/builtin/blame.c
>> > index 177c1022a0..21cde57e71 100644
>> > --- a/builtin/blame.c
>> > +++ b/builtin/blame.c
>> > @@ -27,6 +27,7 @@
>> > #include "object-store.h"
>> > #include "blame.h"
>> > #include "string-list.h"
>> > +#include "refs.h"
>> >
>> > static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
>> >
>> > @@ -993,6 +994,18 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
>> >
>> > revs.disable_stdin = 1;
>> > setup_revisions(argc, argv, &revs, NULL);
>> > + if (!revs.pending.nr && is_bare_repository()) {
>> > + struct commit *head_commit;
>> > + struct object_id head_oid;
>> > +
>> > + if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
>> > + &head_oid, NULL) ||
>> > + !(head_commit = lookup_commit_reference_gently(revs.repo,
>> > + &head_oid, 1)))
>> > + die("no such ref: HEAD");
>> > +
>> > + add_pending_object(&revs, &head_commit->object, "HEAD");
>> > + }
>>
>> With this patch, if I have a bare repo without a HEAD I now get:
>>
>> fatal: no such ref: HEAD
>
> This is the same error message as in a regular repo without HEAD.
> That's good: it's consistent, and it tells what the actual problem is.
>
> Though perhaps too terse and the error message from 'git log' would
> apply just as well and be more friendly:
>
> fatal: your current branch 'master' does not have any commits yet
>
>> Instead of:
>>
>> fatal: this operation must be run in a work tree
>>
>> Both are bad & misleading, perhaps we can instead say something like:
>>
>> die(_("in a bare repository you must specify a ref to blame from, we tried and failed to implicitly use HEAD"));
Yeah, I missed that it's the same message as with no HEAD in a non-bare
repo. Makes sense.
> The point of this patch is that you don't necessarily have to specify
> the starting ref in a bare repo anymore.
>
>> Along with a test for what we do in bare repos without a HEAD....?
>
> How can a repo have no HEAD? Maybe I'm missing something, but I only
> see the following cases:
>
> - An empty repo: there is nothing to blame there at all in the first
> place.
>
> - An orphan branch in a non-bare repo: there is nothing to blame
> there.
>
> - The user is looking for trouble, and ran 'git update-ref -d HEAD',
> as you mentioned below, or something else with similar results.
> "If it hurts, don't it" applies.
>
> - Some sort of repo corruption that left the refs in a sorry state.
> The user has more serious problems than the error message from
> 'git blame'.
>
> So I doubt that any of these cases are worth dealing with and testing
> specifically in a bare repo.
If you setup a repo to manually fetch refspecs you can end up without a
HEAD but still be able to 'blame' stuff. I don't think that happens with
non-bare, but does with bare. E.g. I set up some server-side "blame"
that supports the "master" branch of several repos like that in the
past, and just plain 'git blame' throws the old message.
So maybe since we're checking is_bare_repository() it's worth improving
the error while we're at it, or at least testing that bare & non-bare do
the same thing.
>>
>> >
>> > init_scoreboard(&sb);
>> > sb.revs = &revs;
>> > diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
>> > index 6da48a2e0a..d933af5714 100644
>> > --- a/t/annotate-tests.sh
>> > +++ b/t/annotate-tests.sh
>> > @@ -68,6 +68,14 @@ test_expect_success 'blame 1 author' '
>> > check_count A 2
>> > '
>> >
>> > +test_expect_success 'blame in a bare repo without starting commit' '
>> > + git clone --bare . bare.git &&
>> > + (
>> > + cd bare.git &&
>> > + check_count A 2
>> > + )
>>
>> ....just 'git update-ref -d HEAD` after this and a test for 'git blame
>> <file>' here would test bare without HEAD.
>>
>> > test_expect_success 'blame by tag objects' '
>> > git tag -m "test tag" testTag &&
>> > git tag -m "test tag #2" testTag2 testTag &&
next prev parent reply other threads:[~2019-04-08 15:48 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-07 23:43 [PATCH] blame: default to HEAD in a bare repo when no start commit is given SZEDER Gábor
2019-04-08 0:42 ` Eric Sunshine
2019-04-08 12:44 ` Ævar Arnfjörð Bjarmason
2019-04-08 14:30 ` SZEDER Gábor
2019-04-08 15:48 ` Ævar Arnfjörð Bjarmason [this message]
2019-04-09 8:13 ` 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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=875zroa46y.fsf@evledraar.gmail.com \
--to=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=szeder.dev@gmail.com \
/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.
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 NNTP newsgroup(s).