git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
@ 2015-11-17  1:29 Edmundo Carmona Antoranz
  2015-11-17  5:11 ` Eric Sunshine
  0 siblings, 1 reply; 9+ messages in thread
From: Edmundo Carmona Antoranz @ 2015-11-17  1:29 UTC (permalink / raw)
  To: git; +Cc: max, peff, Edmundo Carmona Antoranz

If a file has been deleted/renamed, blame refused to display
blame content even if the path provided does match an existing
blob on said revision.

$ git status
On branch hide
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    testfile1.txt

no changes added to commit (use "git add" and/or "git commit -a")

Before:
$ git blame testfile1.txt
fatal: cannot stat path 'testfile1.txt': No such file or directory
$ git blame testfile1.txt HEAD
fatal: cannot stat path 'testfile1.txt': No such file or directory

After:
$ git blame testfile1.txt
fatal: Cannot lstat 'testfile1.txt': No such file or directory
$ git blame testfile1.txt HEAD
^da1a96f testfile2.txt (Edmundo Carmona Antoranz 2015-11-10 17:52:00 -0600 1) testfile 2
^da1a96f testfile2.txt (Edmundo Carmona Antoranz 2015-11-10 17:52:00 -0600 2)
^da1a96f testfile2.txt (Edmundo Carmona Antoranz 2015-11-10 17:52:00 -0600 3) Some content

Signed-off-by: Edmundo Carmona Antoranz <eantoranz@gmail.com>
---
 builtin/blame.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 83612f5..856971a 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2683,12 +2683,13 @@ parse_done:
 		argv[argc - 1] = "--";
 
 		setup_work_tree();
-		if (!file_exists(path))
-			die_errno("cannot stat path '%s'", path);
 	}
 
 	revs.disable_stdin = 1;
 	setup_revisions(argc, argv, &revs, NULL);
+	if (!revs.pending.nr && !file_exists(path))
+		die_errno("cannot stat path '%s'", path);
+
 	memset(&sb, 0, sizeof(sb));
 
 	sb.revs = &revs;
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17  1:29 [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided Edmundo Carmona Antoranz
@ 2015-11-17  5:11 ` Eric Sunshine
  2015-11-17 22:48   ` Jeff King
  2015-11-17 23:37   ` Edmundo Carmona Antoranz
  0 siblings, 2 replies; 9+ messages in thread
From: Eric Sunshine @ 2015-11-17  5:11 UTC (permalink / raw)
  To: Edmundo Carmona Antoranz; +Cc: Git List, Max Kirillov, Jeff King

On Mon, Nov 16, 2015 at 8:29 PM, Edmundo Carmona Antoranz
<eantoranz@gmail.com> wrote:
> blame: avoid checking if a file exists on the working tree
> if a revision is provided

This subject is a bit long; try to keep it to about 72 characters or less.

More importantly, though, it doesn't give us a high level overview of
the purpose of the patch, which is that it is fixing blame to work on
a file at a given revision even if the file no longer exists in the
worktree.

> If a file has been deleted/renamed, blame refused to display

Imperative: s/refused/refuses/

> blame content even if the path provided does match an existing
> blob on said revision.

git-blame documentation does not advertise "blame <file> <rev>" as a
valid invocation. It does advertise "blame <rev> -- <file>", and this
case already works correctly even when <file> does not exist in the
worktree.

git-annotate documentation, on the other hand, does advertise
"annotate <file> <rev>", and it fails to work when <file> is absent
from the worktree, so perhaps you want to sell this patch as fixing
git-annotate instead?

> $ git status
> On branch hide
> Changes not staged for commit:
>   (use "git add/rm <file>..." to update what will be committed)
>   (use "git checkout -- <file>..." to discard changes in working directory)
>
>         deleted:    testfile1.txt
>
> no changes added to commit (use "git add" and/or "git commit -a")
>
> Before:
> $ git blame testfile1.txt
> fatal: cannot stat path 'testfile1.txt': No such file or directory
> $ git blame testfile1.txt HEAD
> fatal: cannot stat path 'testfile1.txt': No such file or directory
>
> After:
> $ git blame testfile1.txt
> fatal: Cannot lstat 'testfile1.txt': No such file or directory
> $ git blame testfile1.txt HEAD
> ^da1a96f testfile2.txt (Edmundo Carmona Antoranz 2015-11-10 17:52:00 -0600 1) testfile 2
> ^da1a96f testfile2.txt (Edmundo Carmona Antoranz 2015-11-10 17:52:00 -0600 2)
> ^da1a96f testfile2.txt (Edmundo Carmona Antoranz 2015-11-10 17:52:00 -0600 3) Some content

This example is certainly illustrative, but an even more common case
may be trying to blame/annotate a file which existed in an older
revision but doesn't exist anymore at HEAD, thus is absent from the
worktree. Such a case could likely be described in a sentence or two
without resorting to verbose examples (though, not a big deal if you
keep the example).

A new test or two would be welcome, possibly in t/annotate-tests.sh if
you consider this also fixing git-blame, or in t8001-annotate.sh if
you're selling it only as a fix for git-annotate.

> Signed-off-by: Edmundo Carmona Antoranz <eantoranz@gmail.com>
> ---
> diff --git a/builtin/blame.c b/builtin/blame.c
> @@ -2683,12 +2683,13 @@ parse_done:
>                 argv[argc - 1] = "--";
>
>                 setup_work_tree();
> -               if (!file_exists(path))
> -                       die_errno("cannot stat path '%s'", path);
>         }
>
>         revs.disable_stdin = 1;
>         setup_revisions(argc, argv, &revs, NULL);
> +       if (!revs.pending.nr && !file_exists(path))
> +               die_errno("cannot stat path '%s'", path);
> +
>         memset(&sb, 0, sizeof(sb));
>
>         sb.revs = &revs;
> --
> 2.6.2

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17  5:11 ` Eric Sunshine
@ 2015-11-17 22:48   ` Jeff King
  2015-11-17 23:00     ` Stefan Beller
  2015-11-17 23:01     ` Eric Sunshine
  2015-11-17 23:37   ` Edmundo Carmona Antoranz
  1 sibling, 2 replies; 9+ messages in thread
From: Jeff King @ 2015-11-17 22:48 UTC (permalink / raw)
  To: Eric Sunshine; +Cc: Edmundo Carmona Antoranz, Git List, Max Kirillov

On Tue, Nov 17, 2015 at 12:11:25AM -0500, Eric Sunshine wrote:

> > blame content even if the path provided does match an existing
> > blob on said revision.
> 
> git-blame documentation does not advertise "blame <file> <rev>" as a
> valid invocation. It does advertise "blame <rev> -- <file>", and this
> case already works correctly even when <file> does not exist in the
> worktree.

Hmm. Out of curiosity I tried:

  git blame v2.4.0 -- t/t6031-merge-recursive.sh

and it segfaults. This bisects to Max's recent 1b0d400 (blame: extract
find_single_final, 2015-10-30), but I do not see anything obviously
wrong with it from a quick glance.

-Peff

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17 22:48   ` Jeff King
@ 2015-11-17 23:00     ` Stefan Beller
  2015-11-17 23:01     ` Eric Sunshine
  1 sibling, 0 replies; 9+ messages in thread
From: Stefan Beller @ 2015-11-17 23:00 UTC (permalink / raw)
  To: Jeff King; +Cc: Eric Sunshine, Edmundo Carmona Antoranz, Git List, Max Kirillov

On Tue, Nov 17, 2015 at 2:48 PM, Jeff King <peff@peff.net> wrote:
> On Tue, Nov 17, 2015 at 12:11:25AM -0500, Eric Sunshine wrote:
>
>> > blame content even if the path provided does match an existing
>> > blob on said revision.
>>
>> git-blame documentation does not advertise "blame <file> <rev>" as a
>> valid invocation. It does advertise "blame <rev> -- <file>", and this
>> case already works correctly even when <file> does not exist in the
>> worktree.
>
> Hmm. Out of curiosity I tried:
>
>   git blame v2.4.0 -- t/t6031-merge-recursive.sh
>
> and it segfaults. This bisects to Max's recent 1b0d400 (blame: extract
> find_single_final, 2015-10-30), but I do not see anything obviously
> wrong with it from a quick glance.

it did not fail when running through gdb, so I conclude it is a memory issue
(like using an uninitialized pointer, or memory allocation too small).

valgrind produces:

==18444== Process terminating with default action of signal 11 (SIGSEGV)
==18444==  General Protection Fault
==18444==    at 0x4032121: strcmp (valgrind/memcheck/mc_replace_strmem.c:725)
==18444==    by 0x41A86F: get_origin
(/usr/local/google/home/sbeller/OSS/git/builtin/blame.c:483)
==18444==    by 0x4201EF: cmd_blame
(/usr/local/google/home/sbeller/OSS/git/builtin/blame.c:2763)
==18444==    by 0x405896: run_builtin
(/usr/local/google/home/sbeller/OSS/git/git.c:350)
==18444==    by 0x405AA4: handle_builtin
(/usr/local/google/home/sbeller/OSS/git/git.c:536)
==18444==    by 0x405BC0: run_argv
(/usr/local/google/home/sbeller/OSS/git/git.c:582)
==18444==    by 0x405DB8: main
(/usr/local/google/home/sbeller/OSS/git/git.c:690)
==18444==


>
> -Peff
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17 22:48   ` Jeff King
  2015-11-17 23:00     ` Stefan Beller
@ 2015-11-17 23:01     ` Eric Sunshine
  2015-11-17 23:22       ` Jeff King
  1 sibling, 1 reply; 9+ messages in thread
From: Eric Sunshine @ 2015-11-17 23:01 UTC (permalink / raw)
  To: Jeff King; +Cc: Edmundo Carmona Antoranz, Git List, Max Kirillov

On Tue, Nov 17, 2015 at 5:48 PM, Jeff King <peff@peff.net> wrote:
> On Tue, Nov 17, 2015 at 12:11:25AM -0500, Eric Sunshine wrote:
>> > blame content even if the path provided does match an existing
>> > blob on said revision.
>>
>> git-blame documentation does not advertise "blame <file> <rev>" as a
>> valid invocation. It does advertise "blame <rev> -- <file>", and this
>> case already works correctly even when <file> does not exist in the
>> worktree.
>
> Hmm. Out of curiosity I tried:
>
>   git blame v2.4.0 -- t/t6031-merge-recursive.sh
>
> and it segfaults. This bisects to Max's recent 1b0d400 (blame: extract
> find_single_final, 2015-10-30), but I do not see anything obviously
> wrong with it from a quick glance.

In the original code, sb->final received was assigned value of obj,
which may have gone through deref_tag(), however, after 1b0d400,
sb->final is unconditionally assigned the original value of obj, not
the (potentially) deref'd value.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17 23:01     ` Eric Sunshine
@ 2015-11-17 23:22       ` Jeff King
  2015-11-20  4:38         ` Eric Sunshine
  0 siblings, 1 reply; 9+ messages in thread
From: Jeff King @ 2015-11-17 23:22 UTC (permalink / raw)
  To: Eric Sunshine; +Cc: Edmundo Carmona Antoranz, Git List, Max Kirillov

On Tue, Nov 17, 2015 at 06:01:25PM -0500, Eric Sunshine wrote:

> On Tue, Nov 17, 2015 at 5:48 PM, Jeff King <peff@peff.net> wrote:
> > On Tue, Nov 17, 2015 at 12:11:25AM -0500, Eric Sunshine wrote:
> >> > blame content even if the path provided does match an existing
> >> > blob on said revision.
> >>
> >> git-blame documentation does not advertise "blame <file> <rev>" as a
> >> valid invocation. It does advertise "blame <rev> -- <file>", and this
> >> case already works correctly even when <file> does not exist in the
> >> worktree.
> >
> > Hmm. Out of curiosity I tried:
> >
> >   git blame v2.4.0 -- t/t6031-merge-recursive.sh
> >
> > and it segfaults. This bisects to Max's recent 1b0d400 (blame: extract
> > find_single_final, 2015-10-30), but I do not see anything obviously
> > wrong with it from a quick glance.
> 
> In the original code, sb->final received was assigned value of obj,
> which may have gone through deref_tag(), however, after 1b0d400,
> sb->final is unconditionally assigned the original value of obj, not
> the (potentially) deref'd value.

Good eye. I fed it a tag, find_single_final knows that points to a
commit, then prepare_final casts the tag object to a commit. Whoops.

The patch below fixes it for me. It probably needs a test, but I have to
run for the moment.

-- >8 --
Subject: [PATCH] blame: fix object casting regression

Commit 1b0d400 refactored the prepare_final() function so
that it could be reused in multiple places. Originally, the
loop had two outputs: a commit to stuff into sb->final, and
the name of the commit from the rev->pending array.

After the refactor, that loop is put in its own function
with a single return value: the object_array_entry from the
rev->pending array. This contains both the name and the object,
but with one important difference: the object is the
_original_ object found by the revision parser, not the
dereferenced commit. If one feeds a tag to "git blame", we
end up casting the tag object to a "struct commit", which
causes a segfault.

Instead, let's return the commit (properly casted) directly
from the function, and take the "name" as an optional
out-parameter. This does the right thing, and actually
simplifies the callers, who no longer need to cast or
dereference the object_array_entry themselves.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/blame.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index ac36738..2184e39 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2403,10 +2403,12 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
 	return commit;
 }
 
-static struct object_array_entry *find_single_final(struct rev_info *revs)
+static struct commit *find_single_final(struct rev_info *revs,
+					const char **name_p)
 {
 	int i;
-	struct object_array_entry *found = NULL;
+	struct commit *found = NULL;
+	const char *name = NULL;
 
 	for (i = 0; i < revs->pending.nr; i++) {
 		struct object *obj = revs->pending.objects[i].item;
@@ -2418,22 +2420,20 @@ static struct object_array_entry *find_single_final(struct rev_info *revs)
 			die("Non commit %s?", revs->pending.objects[i].name);
 		if (found)
 			die("More than one commit to dig from %s and %s?",
-			    revs->pending.objects[i].name,
-			    found->name);
-		found = &(revs->pending.objects[i]);
+			    revs->pending.objects[i].name, name);
+		found = (struct commit *)obj;
+		name = revs->pending.objects[i].name;
 	}
+	if (name_p)
+		*name_p = name;
 	return found;
 }
 
 static char *prepare_final(struct scoreboard *sb)
 {
-	struct object_array_entry *found = find_single_final(sb->revs);
-	if (found) {
-		sb->final = (struct commit *) found->item;
-		return xstrdup(found->name);
-	} else {
-		return NULL;
-	}
+	const char *name;
+	sb->final = find_single_final(sb->revs, &name);
+	return xstrdup_or_null(name);
 }
 
 static char *prepare_initial(struct scoreboard *sb)
@@ -2721,11 +2721,9 @@ parse_done:
 		die("Cannot use --contents with final commit object name");
 
 	if (reverse && revs.first_parent_only) {
-		struct object_array_entry *entry = find_single_final(sb.revs);
-		if (!entry)
+		final_commit = find_single_final(sb.revs, NULL);
+		if (!final_commit)
 			die("--reverse and --first-parent together require specified latest commit");
-		else
-			final_commit = (struct commit*) entry->item;
 	}
 
 	/*
-- 
2.6.3.636.g1460207

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17  5:11 ` Eric Sunshine
  2015-11-17 22:48   ` Jeff King
@ 2015-11-17 23:37   ` Edmundo Carmona Antoranz
  2015-11-17 23:47     ` Edmundo Carmona Antoranz
  1 sibling, 1 reply; 9+ messages in thread
From: Edmundo Carmona Antoranz @ 2015-11-17 23:37 UTC (permalink / raw)
  To: Eric Sunshine; +Cc: Git List, Max Kirillov, Jeff King

On Mon, Nov 16, 2015 at 11:11 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:
>
> This subject is a bit long; try to keep it to about 72 characters or less.
>
> More importantly, though, it doesn't give us a high level overview of
> the purpose of the patch, which is that it is fixing blame to work on
> a file at a given revision even if the file no longer exists in the
> worktree.

Sure!

> git-blame documentation does not advertise "blame <file> <rev>" as a
> valid invocation. It does advertise "blame <rev> -- <file>", and this
> case already works correctly even when <file> does not exist in the
> worktree.
>
> git-annotate documentation, on the other hand, does advertise
> "annotate <file> <rev>", and it fails to work when <file> is absent
> from the worktree, so perhaps you want to sell this patch as fixing
> git-annotate instead?

So, do I forget about the blame patch (given that I'm not fixing an
advertised syntax, even if it's supported) and fix annotate instead or
do I fix both? And if I should swing for both, do I create a single
patch or a chain of two patches, one for each builtin?

> This example is certainly illustrative, but an even more common case
> may be trying to blame/annotate a file which existed in an older
> revision but doesn't exist anymore at HEAD, thus is absent from the
> worktree. Such a case could likely be described in a sentence or two
> without resorting to verbose examples (though, not a big deal if you
> keep the example).

K.

>
> A new test or two would be welcome, possibly in t/annotate-tests.sh if
> you consider this also fixing git-blame, or in t8001-annotate.sh if
> you're selling it only as a fix for git-annotate.

I guess I'll wait for feedback about my first question before I decide
what I will do about the tests.

Thank you very much for your comments, Eric.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17 23:37   ` Edmundo Carmona Antoranz
@ 2015-11-17 23:47     ` Edmundo Carmona Antoranz
  0 siblings, 0 replies; 9+ messages in thread
From: Edmundo Carmona Antoranz @ 2015-11-17 23:47 UTC (permalink / raw)
  To: Eric Sunshine; +Cc: Git List, Max Kirillov, Jeff King

On Tue, Nov 17, 2015 at 5:37 PM, Edmundo Carmona Antoranz
<eantoranz@gmail.com> wrote:
> So, do I forget about the blame patch (given that I'm not fixing an
> advertised syntax, even if it's supported) and fix annotate instead or
> do I fix both? And if I should swing for both, do I create a single
> patch or a chain of two patches, one for each builtin?

Actually, cmd_annotate will call cmd_blame so this patch actually
fixes annotate as well (nice unintended consequence).

So I guess it will be a single patch. Let me work on the tests and
then I'll send a patch that will hopefully cover all raised points.

Cheers!

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided
  2015-11-17 23:22       ` Jeff King
@ 2015-11-20  4:38         ` Eric Sunshine
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Sunshine @ 2015-11-20  4:38 UTC (permalink / raw)
  To: Jeff King; +Cc: Edmundo Carmona Antoranz, Git List, Max Kirillov

On Tue, Nov 17, 2015 at 6:22 PM, Jeff King <peff@peff.net> wrote:
> On Tue, Nov 17, 2015 at 06:01:25PM -0500, Eric Sunshine wrote:
>> On Tue, Nov 17, 2015 at 5:48 PM, Jeff King <peff@peff.net> wrote:
>> > Hmm. Out of curiosity I tried:
>> >
>> >   git blame v2.4.0 -- t/t6031-merge-recursive.sh
>> >
>> > and it segfaults. This bisects to Max's recent 1b0d400 (blame: extract
>> > find_single_final, 2015-10-30), but I do not see anything obviously
>> > wrong with it from a quick glance.
>>
>> In the original code, sb->final received was assigned value of obj,
>> which may have gone through deref_tag(), however, after 1b0d400,
>> sb->final is unconditionally assigned the original value of obj, not
>> the (potentially) deref'd value.
>
> Good eye. I fed it a tag, find_single_final knows that points to a
> commit, then prepare_final casts the tag object to a commit. Whoops.
>
> The patch below fixes it for me. It probably needs a test, but I have to
> run for the moment.

Sorry for the late response. This patch mirrors my thoughts on fixing
the bug, and appears correct. For what it's worth:

Reviewed-by: Eric Sunshine <sunshine@sunshineco.com>

> -- >8 --
> Subject: [PATCH] blame: fix object casting regression
>
> Commit 1b0d400 refactored the prepare_final() function so
> that it could be reused in multiple places. Originally, the
> loop had two outputs: a commit to stuff into sb->final, and
> the name of the commit from the rev->pending array.
>
> After the refactor, that loop is put in its own function
> with a single return value: the object_array_entry from the
> rev->pending array. This contains both the name and the object,
> but with one important difference: the object is the
> _original_ object found by the revision parser, not the
> dereferenced commit. If one feeds a tag to "git blame", we
> end up casting the tag object to a "struct commit", which
> causes a segfault.
>
> Instead, let's return the commit (properly casted) directly
> from the function, and take the "name" as an optional
> out-parameter. This does the right thing, and actually
> simplifies the callers, who no longer need to cast or
> dereference the object_array_entry themselves.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
>  builtin/blame.c | 30 ++++++++++++++----------------
>  1 file changed, 14 insertions(+), 16 deletions(-)
>
> diff --git a/builtin/blame.c b/builtin/blame.c
> index ac36738..2184e39 100644
> --- a/builtin/blame.c
> +++ b/builtin/blame.c
> @@ -2403,10 +2403,12 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
>         return commit;
>  }
>
> -static struct object_array_entry *find_single_final(struct rev_info *revs)
> +static struct commit *find_single_final(struct rev_info *revs,
> +                                       const char **name_p)
>  {
>         int i;
> -       struct object_array_entry *found = NULL;
> +       struct commit *found = NULL;
> +       const char *name = NULL;
>
>         for (i = 0; i < revs->pending.nr; i++) {
>                 struct object *obj = revs->pending.objects[i].item;
> @@ -2418,22 +2420,20 @@ static struct object_array_entry *find_single_final(struct rev_info *revs)
>                         die("Non commit %s?", revs->pending.objects[i].name);
>                 if (found)
>                         die("More than one commit to dig from %s and %s?",
> -                           revs->pending.objects[i].name,
> -                           found->name);
> -               found = &(revs->pending.objects[i]);
> +                           revs->pending.objects[i].name, name);
> +               found = (struct commit *)obj;
> +               name = revs->pending.objects[i].name;
>         }
> +       if (name_p)
> +               *name_p = name;
>         return found;
>  }
>
>  static char *prepare_final(struct scoreboard *sb)
>  {
> -       struct object_array_entry *found = find_single_final(sb->revs);
> -       if (found) {
> -               sb->final = (struct commit *) found->item;
> -               return xstrdup(found->name);
> -       } else {
> -               return NULL;
> -       }
> +       const char *name;
> +       sb->final = find_single_final(sb->revs, &name);
> +       return xstrdup_or_null(name);
>  }
>
>  static char *prepare_initial(struct scoreboard *sb)
> @@ -2721,11 +2721,9 @@ parse_done:
>                 die("Cannot use --contents with final commit object name");
>
>         if (reverse && revs.first_parent_only) {
> -               struct object_array_entry *entry = find_single_final(sb.revs);
> -               if (!entry)
> +               final_commit = find_single_final(sb.revs, NULL);
> +               if (!final_commit)
>                         die("--reverse and --first-parent together require specified latest commit");
> -               else
> -                       final_commit = (struct commit*) entry->item;
>         }
>
>         /*
> --
> 2.6.3.636.g1460207
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-11-20  4:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-17  1:29 [PATCH v2] blame: avoid checking if a file exists on the working tree if a revision is provided Edmundo Carmona Antoranz
2015-11-17  5:11 ` Eric Sunshine
2015-11-17 22:48   ` Jeff King
2015-11-17 23:00     ` Stefan Beller
2015-11-17 23:01     ` Eric Sunshine
2015-11-17 23:22       ` Jeff King
2015-11-20  4:38         ` Eric Sunshine
2015-11-17 23:37   ` Edmundo Carmona Antoranz
2015-11-17 23:47     ` Edmundo Carmona Antoranz

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).