git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/4] git-log --cherry-pick A...B

From
Junio C Hamano <junkio@cox.net>
Date
Apr 10, 2007, 22:40 UTC
Message-ID
<7vfy77ua3o.fsf_-_@assigned-by-dhcp.cox.net>
In-Reply-To
<7virc524cd.fsf_-_@assigned-by-dhcp.cox.net>
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>
---
 revision.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 revision.h |    1 +
 2 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/revision.c b/revision.c
index 486393c..e9de865 100644
--- a/revision.c
+++ b/revision.c
@@ -8,6 +8,7 @@
 #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;
@@ -449,6 +530,9 @@ static void limit_list(struct rev_info *revs)
 			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 55e6b53..b69624a 100644
--- a/revision.h
+++ b/revision.h
@@ -47,6 +47,7 @@ struct rev_info {
 			left_right:1,
 			parents:1,
 			reverse:1,
+			cherry_pick:1,
 			first_parent_only:1;
 
 	/* Diff flags */
-- 
1.5.1.777.gd14d3
Previous: Johannes SchindelinNext: Junio C Hamano
Message 15 of 19 in “How can I easily verify my diffs are in parent branch?”
  1. Alex BenneeApr 4, 2007
  2. Alex RiesenApr 4, 2007
  3. Andy ParkinsApr 4, 2007
  4. Linus TorvaldsApr 4, 2007
  5. Junio C HamanoApr 5, 2007
  6. David KågedalApr 5, 2007
  7. Junio C HamanoApr 5, 2007
  8. Document --left-right option to rev-list.Brian Gernhardt, Apr 5, 2007
  9. Junio C HamanoApr 5, 2007
  10. Alex RiesenApr 7, 2007
  11. 1/2 git-log --cherry-pickJunio C Hamano, Apr 9, 2007
  12. 1/4 Add %m to '--pretty=format:'Junio C Hamano, Apr 10, 2007
  13. 2/4 Refactor patch-id filtering out of git-cherry and git-format-patch.Junio C Hamano, Apr 10, 2007
  14. Johannes SchindelinApr 14, 2007
  15. 3/4 git-log --cherry-pick A...BJunio C Hamano, Apr 10, 2007
  16. 4/4 Documentation: --cherry-pickJunio C Hamano, Apr 10, 2007
  17. 2/2 Add %m to '--pretty=format:'Junio C Hamano, Apr 9, 2007
  18. Alex BenneeApr 11, 2007
  19. Linus TorvaldsApr 11, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.