All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Kirillov <max@max630.net>
To: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
	Eric Sunshine <sunshine@sunshineco.com>
Cc: Max Kirillov <max@max630.net>, git@vger.kernel.org
Subject: [PATCH v4 3/3] blame: allow blame --reverse --first-parent when it makes sense
Date: Mon, 26 Oct 2015 07:26:57 +0200	[thread overview]
Message-ID: <1445837217-4252-5-git-send-email-max@max630.net> (raw)
In-Reply-To: <1445837217-4252-1-git-send-email-max@max630.net>

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>
---
 builtin/blame.c          | 32 ++++++++++++++++++++++++++++++--
 t/t8009-blame-reverse.sh |  2 +-
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 38f6267..98b1810 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2507,6 +2507,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;
@@ -2697,11 +2698,11 @@ parse_done:
 	}
 	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) {
@@ -2718,6 +2719,14 @@ parse_done:
 	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
@@ -2726,6 +2735,25 @@ parse_done:
 	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);
diff --git a/t/t8009-blame-reverse.sh b/t/t8009-blame-reverse.sh
index 9f40613..4413815 100755
--- a/t/t8009-blame-reverse.sh
+++ b/t/t8009-blame-reverse.sh
@@ -24,7 +24,7 @@ test_expect_failure 'blame --reverse finds B1, not C1' '
 	test_cmp expect actual
 	'
 
-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 -1 <actual_full | sed -e "sX .*XX" >actual &&
 	git rev-parse A1 >expect &&
-- 
2.3.4.2801.g3d0809b

  parent reply	other threads:[~2015-10-26  5:27 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-21  4:08 [PATCH 0/2] blame: allow blame --reverse --first-parent when it makes sense Max Kirillov
2015-10-21  4:08 ` [PATCH 1/2] Add test to describe expectation of blame --reverse with branched history Max Kirillov
2015-10-21  4:08 ` [PATCH 2/2] blame: allow blame --reverse --first-parent when it makes sense Max Kirillov
2015-10-21  4:29   ` Eric Sunshine
2015-10-22  3:52     ` Max Kirillov
2015-10-22  3:51 ` [PATCH v2 0/2] " Max Kirillov
2015-10-22  3:51   ` [PATCH v2 1/2] Add test to describe expectation of blame --reverse with branched history Max Kirillov
2015-10-22  4:19     ` Junio C Hamano
2015-10-22 14:37       ` Max Kirillov
2015-10-22 14:56         ` Max Kirillov
2015-10-22  3:51   ` [PATCH v2 2/2] blame: allow blame --reverse --first-parent when it makes sense Max Kirillov
2015-10-22  4:25     ` Junio C Hamano
2015-10-22 14:56       ` Max Kirillov
2015-10-22 19:11         ` Junio C Hamano
2015-10-25 12:43           ` Max Kirillov
2015-10-25 16:52             ` Junio C Hamano
2015-10-22  4:07   ` [PATCH v3 0/2] " Max Kirillov
2015-10-22  4:07     ` [PATCH v3 1/2] Add test to describe expectation of blame --reverse with branched history Max Kirillov
2015-10-22  4:07     ` [PATCH v3 2/2] blame: allow blame --reverse --first-parent when it makes sense Max Kirillov
2015-10-26  5:26     ` [PATCH v4 0/4] " Max Kirillov
2015-10-26  5:26       ` [PATCH v4 1/3] Add test to describe expectation of blame --reverse with branched history Max Kirillov
2015-10-26  5:41         ` Max Kirillov
2015-10-26  6:27         ` Junio C Hamano
2015-10-27  4:40           ` Max Kirillov
2015-10-27 17:57             ` Junio C Hamano
2015-10-26  5:26       ` [PATCH v4 2/3] blame: extract find_single_final Max Kirillov
2015-10-26  5:26       ` Max Kirillov [this message]
2015-10-30  5:01       ` [PATCH v5 0/3] blame: allow blame --reverse --first-parent when it makes sense Max Kirillov
2015-10-30  5:01         ` [PATCH v5 1/3] blame: test to describe use of blame --reverse --first-parent Max Kirillov
2015-10-30 22:30           ` Junio C Hamano
2015-10-30  5:01         ` [PATCH v5 2/3] blame: extract find_single_final Max Kirillov
2015-10-30  5:01         ` [PATCH v5 3/3] blame: allow blame --reverse --first-parent when it makes sense Max Kirillov
2015-10-26  5:26     ` [PATCH v4 0/4] " Max Kirillov
2015-10-26  5:31       ` Max Kirillov

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=1445837217-4252-5-git-send-email-max@max630.net \
    --to=max@max630.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    --cc=sunshine@sunshineco.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.