[PATCH/RFC] Extended SHA1 -- "rev^#" syntax to mean "all parents"

Subsystems: the rest

3 messages, 3 authors, 2016-06-15 · open the first message on its own page

[PATCH/RFC] Extended SHA1 -- "rev^#" syntax to mean "all parents"

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:24

A short-hand "rev^#" is understood to be "all parents of the
named commit" with this patch.  So you can do

	git show v1.0.0^#

to view the parents of a merge commit,

	gitk ^v1.0.0^# v1.0.4

to view the log between two revs (including the bottom one), and

	git diff --cc v1.1.0 v1.0.0^#

to inspect what got changed from the merge parents of v1.0.0 to v1.1.0.

This might be just my shiny new toy that is not very useful in
practice.  I needed it to do the multi-tree diff on Len's
infamous 12-way Octopus; typing "diff --cc funmerge funmerge^1
funmerge^2 funmerge^3 ..." was too painful.

Signed-off-by: Junio C Hamano <redacted>

---

 revision.c |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/revision.c b/revision.c
index f2a9f25..194f35b 100644
--- a/revision.c
+++ b/revision.c
@@ -477,6 +477,36 @@ static void handle_all(struct rev_info *
 	for_each_ref(handle_one_ref);
 }
 
+static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
+{
+	unsigned char sha1[20];
+	struct object *it;
+	struct commit *commit;
+	struct commit_list *parents;
+
+	if (*arg == '^') {
+		flags ^= UNINTERESTING;
+		arg++;
+	}
+	if (get_sha1(arg, sha1))
+		return 0;
+	while (1) {
+		it = get_reference(revs, arg, sha1, 0);
+		if (strcmp(it->type, tag_type))
+			break;
+		memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20);
+	}
+	if (strcmp(it->type, commit_type))
+		return 0;
+	commit = (struct commit *)it;
+	for (parents = commit->parents; parents; parents = parents->next) {
+		it = &parents->item->object;
+		it->flags |= flags;
+		add_pending_object(revs, it, arg);
+	}
+	return 1;
+}
+
 void init_revisions(struct rev_info *revs)
 {
 	memset(revs, 0, sizeof(*revs));
@@ -746,6 +776,13 @@ int setup_revisions(int argc, const char
 			}
 			*dotdot = '.';
 		}
+		dotdot = strstr(arg, "^#");
+		if (dotdot && !dotdot[2]) {
+			*dotdot = 0;
+			if (add_parents_only(revs, arg, flags))
+				continue;
+			*dotdot = '^';
+		}
 		local_flags = 0;
 		if (*arg == '^') {
 			local_flags = UNINTERESTING;
-- 
1.3.1.ga0c5

Re: [PATCH/RFC] Extended SHA1 -- "rev^#" syntax to mean "all parents"

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:42:24

Hi,

On Sat, 29 Apr 2006, Junio C Hamano wrote:
A short-hand "rev^#" is understood to be "all parents of the
named commit" with this patch.
Just my 2/100: Why not "rev^*"? I could remember that more easily.

Ciao,
Dscho

Re: [PATCH/RFC] Extended SHA1 -- "rev^#" syntax to mean "all parents"

From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:42:24


On Sat, 29 Apr 2006, Johannes Schindelin wrote:
quoted
A short-hand "rev^#" is understood to be "all parents of the
named commit" with this patch.
Just my 2/100: Why not "rev^*"? I could remember that more easily.
Yeah, that (or ^@ - to match shell "$1" "$2" .. "$@") was my reaction too.

The "rev^#" thing should to my mind return the _number_ of parents, the 
same way "$#" does in shell. I actually pronounce that '#' character 
mentally as "number", but maybe that's just because I'm totally mentally 
damaged by shell programming, and everybody else probably calls it "hash" 
(and some people apparently call it "pound", for some really sick reason).

So "rev^#" literally reads as "revision parent number" to me. Useful? 
Maybe. Maybe not.

		Linus
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help