summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5d23e13)
raw | patch | inline | side by side (parent: 5d23e13)
author | Junio C Hamano <junkio@cox.net> | |
Mon, 9 Apr 2007 10:40:38 +0000 (03:40 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Thu, 12 Apr 2007 03:02:03 +0000 (20:02 -0700) |
This is meant to be a saner replacement for "git-cherry".
When used with "A...B", this filters out commits whose patch
text has the same patch-id as a commit on the other side. It
would probably most useful to use with --left-right.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When used with "A...B", this filters out commits whose patch
text has the same patch-id as a commit on the other side. It
would probably most useful to use with --left-right.
Signed-off-by: Junio C Hamano <junkio@cox.net>
revision.c | patch | blob | history | |
revision.h | patch | blob | history |
diff --git a/revision.c b/revision.c
index 486393cb0835ce70f685d665b916e1b67974f184..e9de8650d37398b5d46256eced053f3b7dd4e25a 100644 (file)
--- a/revision.c
+++ b/revision.c
#include "revision.h"
#include "grep.h"
#include "reflog-walk.h"
+#include "patch-ids.h"
static char *path_name(struct name_path *path, const char *name)
{
@@ -422,6 +423,86 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st
}
}
+static void cherry_pick_list(struct commit_list *list)
+{
+ struct commit_list *p;
+ int left_count = 0, right_count = 0;
+ int left_first;
+ struct patch_ids ids;
+
+ /* First count the commits on the left and on the right */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ unsigned flags = commit->object.flags;
+ if (flags & BOUNDARY)
+ ;
+ else if (flags & SYMMETRIC_LEFT)
+ left_count++;
+ else
+ right_count++;
+ }
+
+ left_first = left_count < right_count;
+ init_patch_ids(&ids);
+
+ /* Compute patch-ids for one side */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ unsigned flags = commit->object.flags;
+
+ if (flags & BOUNDARY)
+ continue;
+ /*
+ * If we have fewer left, left_first is set and we omit
+ * commits on the right branch in this loop. If we have
+ * fewer right, we skip the left ones.
+ */
+ if (left_first != !!(flags & SYMMETRIC_LEFT))
+ continue;
+ commit->util = add_commit_patch_id(commit, &ids);
+ }
+
+ /* Check the other side */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ struct patch_id *id;
+ unsigned flags = commit->object.flags;
+
+ if (flags & BOUNDARY)
+ continue;
+ /*
+ * If we have fewer left, left_first is set and we omit
+ * commits on the left branch in this loop.
+ */
+ if (left_first == !!(flags & SYMMETRIC_LEFT))
+ continue;
+
+ /*
+ * Have we seen the same patch id?
+ */
+ id = has_commit_patch_id(commit, &ids);
+ if (!id)
+ continue;
+ id->seen = 1;
+ commit->object.flags |= SHOWN;
+ }
+
+ /* Now check the original side for seen ones */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ struct patch_id *ent;
+
+ ent = commit->util;
+ if (!ent)
+ continue;
+ if (ent->seen)
+ commit->object.flags |= SHOWN;
+ commit->util = NULL;
+ }
+
+ free_patch_ids(&ids);
+}
+
static void limit_list(struct rev_info *revs)
{
struct commit_list *list = revs->commits;
continue;
p = &commit_list_insert(commit, p)->next;
}
+ if (revs->cherry_pick)
+ cherry_pick_list(newlist);
+
revs->commits = newlist;
}
@@ -913,6 +997,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->left_right = 1;
continue;
}
+ if (!strcmp(arg, "--cherry-pick")) {
+ revs->cherry_pick = 1;
+ continue;
+ }
if (!strcmp(arg, "--objects")) {
revs->tag_objects = 1;
revs->tree_objects = 1;
diff --git a/revision.h b/revision.h
index 5f3f628a9b1ec278dddc1d894066ab1278f6e473..8a026184287479272ececf5cf3d5000c52007553 100644 (file)
--- a/revision.h
+++ b/revision.h
left_right:1,
parents:1,
reverse:1,
+ cherry_pick:1,
first_parent_only:1;
/* Diff flags */