Skip to content

Commit

Permalink
blame: allow blame --reverse --first-parent when it makes sense
Browse files Browse the repository at this point in the history
Allow combining --reverse and --first-parent if initial commit of
specified range is at the first-parent chain starting from the final
commit. Disable the prepare_revision_walk()'s builtin children
collection, instead picking only the ones which are along the first
parent chain.

Signed-off-by: Max Kirillov <max@max630.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Max Kirillov authored and Junio C Hamano committed Oct 30, 2015
1 parent 1b0d400 commit 700fd28
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
32 changes: 30 additions & 2 deletions builtin/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -2502,6 +2502,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
long dashdash_pos, lno;
char *final_commit_name = NULL;
enum object_type type;
struct commit *final_commit = NULL;

static struct string_list range_list;
static int output_option = 0, opt = 0;
Expand Down Expand Up @@ -2689,11 +2690,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
}
else if (contents_from)
die("--contents and --children do not blend well.");
else if (revs.first_parent_only)
die("combining --first-parent and --reverse is not supported");
else {
final_commit_name = prepare_initial(&sb);
sb.commits.compare = compare_commits_by_reverse_commit_date;
if (revs.first_parent_only)
revs.children.name = NULL;
}

if (!sb.final) {
Expand All @@ -2710,6 +2711,14 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
else if (contents_from)
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)
die("--reverse and --first-parent together require specified latest commit");
else
final_commit = (struct commit*) entry->item;
}

/*
* If we have bottom, this will mark the ancestors of the
* bottom commits we would reach while traversing as
Expand All @@ -2718,6 +2727,25 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
if (prepare_revision_walk(&revs))
die(_("revision walk setup failed"));

if (reverse && revs.first_parent_only) {
struct commit *c = final_commit;

sb.revs->children.name = "children";
while (c->parents &&
hashcmp(c->object.sha1, sb.final->object.sha1)) {
struct commit_list *l = xcalloc(1, sizeof(*l));

l->item = c;
if (add_decoration(&sb.revs->children,
&c->parents->item->object, l))
die("BUG: not unique item in first-parent chain");
c = c->parents->item;
}

if (hashcmp(c->object.sha1, sb.final->object.sha1))
die("--reverse --first-parent together require range along first-parent chain");
}

if (is_null_sha1(sb.final->object.sha1)) {
o = sb.final->util;
sb.final_buf = xmemdupz(o->file.ptr, o->file.size);
Expand Down
2 changes: 1 addition & 1 deletion t/t8009-blame-vs-topicbranches.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ test_expect_success setup '
test_merge A3 C1
'

test_expect_failure 'blame --reverse --first-parent finds A1' '
test_expect_success 'blame --reverse --first-parent finds A1' '
git blame --porcelain --reverse --first-parent A0..A3 -- file.t >actual_full &&
head -n 1 <actual_full | sed -e "s/ .*//" >actual &&
git rev-parse A1 >expect &&
Expand Down

0 comments on commit 700fd28

Please sign in to comment.