[PATCH] blame: dwim "blame --reverse OLD" as "blame --reverse OLD.."

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead of always requiring both ends of a range, we could DWIM
"OLD", which could be a misspelt "OLD..", to be a range that ends at
the current commit.

Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
---

 * I am not convinced that this is a good change, though.  It is
   true that there is no other sensible interpretation of the user's
   intent when --reverse is given a single positive commit without
   any other revision, but at the same time, this feels a bit too
   much special casing that could hurt casual users when they are
   still forming their mental world model by learning from examples.

 Documentation/blame-options.txt |  5 +++--
 builtin/blame.c                 | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt
index 02cb684..6c6c78f 100644
--- a/Documentation/blame-options.txt
+++ b/Documentation/blame-options.txt
@@ -28,12 +28,13 @@ include::line-range-format.txt[]
 -S <revs-file>::
 	Use revisions from revs-file instead of calling linkgit:git-rev-list[1].
 
---reverse::
+--reverse <rev>..<rev>::
 	Walk history forward instead of backward. Instead of showing
 	the revision in which a line appeared, this shows the last
 	revision in which a line has existed. This requires a range of
 	revision like START..END where the path to blame exists in
-	START.
+	START.  `git blame --reverse START` is taken as `git blame
+	--reverse START..HEAD` for convenience.
 
 -p::
 --porcelain::
diff --git a/builtin/blame.c b/builtin/blame.c
index a027b8a..574b47d 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2447,6 +2447,41 @@ static char *prepare_final(struct scoreboard *sb)
 	return xstrdup_or_null(name);
 }
 
+static const char *dwim_reverse_initial(struct scoreboard *sb)
+{
+	/*
+	 * DWIM "git blame --reverse ONE -- PATH" as
+	 * "git blame --reverse ONE..HEAD -- PATH" but only do so
+	 * when it makes sense.
+	 */
+	struct object *obj;
+	struct commit *head_commit;
+	unsigned char head_sha1[20];
+
+	if (sb->revs->pending.nr != 1)
+		return NULL;
+
+	/* Is that sole rev a committish? */
+	obj = sb->revs->pending.objects[0].item;
+	obj = deref_tag(obj, NULL, 0);
+	if (obj->type != OBJ_COMMIT)
+		return NULL;
+
+	/* Do we have HEAD? */
+	if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_sha1, NULL))
+		return NULL;
+	head_commit = lookup_commit_reference_gently(head_sha1, 1);
+	if (!head_commit)
+		return NULL;
+
+	/* Turn "ONE" into "ONE..HEAD" then */
+	obj->flags |= UNINTERESTING;
+	add_pending_object(sb->revs, &head_commit->object, "HEAD");
+
+	sb->final = (struct commit *)obj;
+	return sb->revs->pending.objects[0].name;
+}
+
 static char *prepare_initial(struct scoreboard *sb)
 {
 	int i;
@@ -2472,6 +2507,9 @@ static char *prepare_initial(struct scoreboard *sb)
 		sb->final = (struct commit *) obj;
 		final_commit_name = revs->pending.objects[i].name;
 	}
+
+	if (!final_commit_name)
+		final_commit_name = dwim_reverse_initial(sb);
 	if (!final_commit_name)
 		die("No commit to dig up from?");
 	return xstrdup(final_commit_name);
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]