login
Header Space

 
 

[PATCH 2/3] Add '...' operator for revisions

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Junio C Hamano <junkio@...>
Cc: <git@...>, Johannes Schindelin <Johannes.Schindelin@...>, Linus Torvalds <torvalds@...>
Date: Saturday, July 1, 2006 - 7:29 pm

'A...B' is a shortcut for 'A B --not $(git-merge-base --all A B)'.
This XOR-like operation is called symmetric difference in set
theory.

The symbol '...' has been chosen because it's rather similar to the
existing '..' operator and the somewhat more natural caret ('^') is
already taken.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 Documentation/git-rev-list.txt |   14 ++++++++++++
 revision.c                     |   48 +++++++++++++++++++++++++++++++++-------
 2 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index ad6d14c..6c370e1 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -15,6 +15,7 @@ SYNOPSIS
 	     [ \--sparse ]
 	     [ \--no-merges ]
 	     [ \--remove-empty ]
+	     [ \--not ]
 	     [ \--all ]
 	     [ \--topo-order ]
 	     [ \--parents ]
@@ -37,6 +38,14 @@ not in 'baz'".
 A special notation <commit1>..<commit2> can be used as a
 short-hand for {caret}<commit1> <commit2>.
 
+Another special notation is <commit1>...<commit2> which is useful for
+merges.  The resulting set of commits is the symmetric difference
+between the two operands.  The following two commands are equivalent:
+
+------------
+$ git-rev-list A B --not $(git-merge-base --all A B)
+$ git-rev-list A...B
+------------
 
 OPTIONS
 -------
@@ -93,6 +102,11 @@ OPTIONS
 --remove-empty::
 	Stop when a given path disappears from the tree.
 
+--not::
+	Reverses the meaning of the '{caret}' prefix (or lack
+	thereof) for all following revision specifiers, up to
+	the next `--not`.
+
 --all::
 	Pretend as if all the refs in `$GIT_DIR/refs/` are
 	listed on the command line as <commit>.
diff --git a/revision.c b/revision.c
index b963f2a..9eb0b6d 100644
--- a/revision.c
+++ b/revision.c
@@ -536,6 +536,18 @@ void init_revisions(struct rev_info *rev
 	diff_setup(&revs->diffopt);
 }
 
+static void add_pending_commit_list(struct rev_info *revs,
+                                    struct commit_list *commit_list,
+                                    unsigned int flags)
+{
+	while (commit_list) {
+		struct object *object = &commit_list->item->object;
+		object->flags |= flags;
+		add_pending_object(revs, object, sha1_to_hex(object->sha1));
+		commit_list = commit_list->next;
+	}
+}
+
 /*
  * Parse revision information, filling in the "rev_info" structure,
  * and removing the used arguments from the argument list.
@@ -771,27 +783,45 @@ int setup_revisions(int argc, const char
 			unsigned char from_sha1[20];
 			const char *next = dotdot + 2;
 			const char *this = arg;
+			int symmetric = *next == '.';
+			unsigned int flags_exclude = flags ^ UNINTERESTING;
+
 			*dotdot = 0;
+			next += symmetric;
+
 			if (!*next)
 				next = "HEAD";
 			if (dotdot == arg)
 				this = "HEAD";
 			if (!get_sha1(this, from_sha1) &&
 			    !get_sha1(next, sha1)) {
-				struct object *exclude;
-				struct object *include;
-
-				exclude = get_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
-				include = get_reference(revs, next, sha1, flags);
-				if (!exclude || !include)
-					die("Invalid revision range %s..%s", arg, next);
+				struct commit *a, *b;
+				struct commit_list *exclude;
+
+				a = lookup_commit_reference(from_sha1);
+				b = lookup_commit_reference(sha1);
+				if (!a || !b) {
+					die(symmetric ?
+					    "Invalid symmetric difference expression %s...%s" :
+					    "Invalid revision range %s..%s",
+					    arg, next);
+				}
 
 				if (!seen_dashdash) {
 					*dotdot = '.';
 					verify_non_filename(revs->prefix, arg);
 				}
-				add_pending_object(revs, exclude, this);
-				add_pending_object(revs, include, next);
+
+				if (symmetric) {
+					exclude = get_merge_bases_clean(a, b);
+					add_pending_commit_list(revs, exclude,
+					                        flags_exclude);
+					a->object.flags |= flags;
+				} else
+					a->object.flags |= flags_exclude;
+				b->object.flags |= flags;
+				add_pending_object(revs, &a->object, this);
+				add_pending_object(revs, &b->object, next);
 				continue;
 			}
 			*dotdot = '.';
-- 
1.4.1.rc2.gfc04

-
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
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
A note on merging conflicts.., Linus Torvalds, (Fri Jun 30, 10:44 pm)
Re: A note on merging conflicts.., Junio C Hamano, (Fri Jun 30, 11:08 pm)
Re: A note on merging conflicts.., Linus Torvalds, (Fri Jun 30, 11:54 pm)
Re: A note on merging conflicts.., Rene Scharfe, (Sat Jul 1, 11:09 am)
Re: A note on merging conflicts.., Junio C Hamano, (Sat Jul 1, 2:37 pm)
Re: A note on merging conflicts.., Rene Scharfe, (Sat Jul 1, 3:29 pm)
Re: A note on merging conflicts.., Linus Torvalds, (Sat Jul 1, 4:04 pm)
Re: A note on merging conflicts.., Junio C Hamano, (Sat Jul 1, 4:07 pm)
Re: A note on merging conflicts.., Junio C Hamano, (Sat Jul 1, 4:14 pm)
Re: [PATCH 4/3] Fold get_merge_bases_clean() into get_merge_..., Johannes Schindelin, (Sun Jul 2, 5:56 am)
[PATCH 3/3] Make clear_commit_marks() clean harder, Rene Scharfe, (Sat Jul 1, 7:29 pm)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Junio C Hamano, (Mon Jul 3, 5:32 am)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Johannes Schindelin, (Mon Jul 3, 9:56 am)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Junio C Hamano, (Mon Jul 3, 3:47 pm)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Johannes Schindelin, (Mon Jul 3, 5:12 pm)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Linus Torvalds, (Mon Jul 3, 6:55 pm)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Johannes Schindelin, (Tue Jul 4, 3:53 am)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Junio C Hamano, (Tue Jul 4, 4:20 am)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Linus Torvalds, (Mon Jul 3, 1:05 pm)
Re: [PATCH 3/3] Make clear_commit_marks() clean harder, Johannes Schindelin, (Mon Jul 3, 5:08 pm)
[PATCH 2/3] Add '...' operator for revisions, Rene Scharfe, (Sat Jul 1, 7:29 pm)
[PATCH 1/3] Add get_merge_bases_clean(), Rene Scharfe, (Sat Jul 1, 7:29 pm)
Re: [PATCH 1/3] Add get_merge_bases_clean(), Johannes Schindelin, (Sat Jul 1, 7:43 pm)
Re: A note on merging conflicts.., Junio C Hamano, (Sat Jul 1, 3:56 pm)
Re: A note on merging conflicts.., Johannes Schindelin, (Sat Jul 1, 7:01 pm)
Re: A note on merging conflicts.., J. Bruce Fields, (Sat Jul 1, 2:01 pm)
Re: A note on merging conflicts.., Linus Torvalds, (Sat Jul 1, 2:20 pm)
Re: A note on merging conflicts.., Daniel Barkalow, (Sat Jul 1, 6:24 pm)
Re: A note on merging conflicts.., Linus Torvalds, (Sat Jul 1, 6:57 pm)
Re: A note on merging conflicts.., Daniel Barkalow, (Sat Jul 1, 7:25 pm)
Re: A note on merging conflicts.., Linus Torvalds, (Sat Jul 1, 8:08 pm)
Re: A note on merging conflicts.., Daniel Barkalow, (Sat Jul 1, 7:45 pm)
Re: A note on merging conflicts.., Rene Scharfe, (Sun Jul 2, 7:31 am)
Re: A note on merging conflicts.., Daniel Barkalow, (Sun Jul 2, 5:42 pm)
Re: A note on merging conflicts.., Linus Torvalds, (Sat Jul 1, 12:25 pm)
Re: A note on merging conflicts.., Rene Scharfe, (Sat Jul 1, 2:13 pm)
Re: A note on merging conflicts.., Johannes Schindelin, (Sat Jul 1, 11:23 am)
Re: A note on merging conflicts.., Linus Torvalds, (Fri Jun 30, 11:59 pm)
speck-geostationary