Skip to content

Commit d016a89

Browse files
author
Junio C Hamano
committed
Merge branch 'jc/cherry'
* jc/cherry: Documentation: --cherry-pick git-log --cherry-pick A...B Refactor patch-id filtering out of git-cherry and git-format-patch. Add %m to '--pretty=format:'
2 parents cd8d918 + 55a643e commit d016a89

File tree

9 files changed

+346
-35
lines changed

9 files changed

+346
-35
lines changed

Documentation/git-rev-list.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SYNOPSIS
2222
[ \--topo-order ]
2323
[ \--parents ]
2424
[ \--left-right ]
25+
[ \--cherry-pick ]
2526
[ \--encoding[=<encoding>] ]
2627
[ \--(author|committer|grep)=<pattern> ]
2728
[ [\--objects | \--objects-edge] [ \--unpacked ] ]
@@ -224,6 +225,20 @@ limiting may be applied.
224225
In addition to the '<commit>' listed on the command
225226
line, read them from the standard input.
226227

228+
--cherry-pick::
229+
230+
Omit any commit that introduces the same change as
231+
another commit on the "other side" when the set of
232+
commits are limited with symmetric difference.
233+
+
234+
For example, if you have two branches, `A` and `B`, a usual way
235+
to list all commits on only one side of them is with
236+
`--left-right`, like the example above in the description of
237+
that option. It however shows the commits that were cherry-picked
238+
from the other branch (for example, "3rd on b" may be cherry-picked
239+
from branch A). With this option, such pairs of commits are
240+
excluded from the output.
241+
227242
-g, --walk-reflogs::
228243

229244
Instead of walking the commit ancestry chain, walk

Documentation/pretty-formats.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ The placeholders are:
117117
- '%Cgreen': switch color to green
118118
- '%Cblue': switch color to blue
119119
- '%Creset': reset color
120+
- '%m': left, right or boundary mark
120121
- '%n': newline
121122

122123

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ LIB_H = \
283283
diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \
284284
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
285285
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
286-
utf8.h reflog-walk.h
286+
utf8.h reflog-walk.h patch-ids.h
287287

288288
DIFF_OBJS = \
289289
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@ -295,6 +295,7 @@ LIB_OBJS = \
295295
date.o diff-delta.o entry.o exec_cmd.o ident.o \
296296
interpolate.o \
297297
lockfile.o \
298+
patch-ids.o \
298299
object.o pack-check.o patch-delta.o path.o pkt-line.o sideband.o \
299300
reachable.o reflog-walk.o \
300301
quote.o read-cache.o refs.o run-command.o dir.o object-refs.o \

builtin-log.c

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "builtin.h"
1313
#include "tag.h"
1414
#include "reflog-walk.h"
15+
#include "patch-ids.h"
1516

1617
static int default_show_root = 1;
1718

@@ -333,25 +334,12 @@ static int reopen_stdout(struct commit *commit, int nr, int keep_subject)
333334

334335
}
335336

336-
static int get_patch_id(struct commit *commit, struct diff_options *options,
337-
unsigned char *sha1)
338-
{
339-
if (commit->parents)
340-
diff_tree_sha1(commit->parents->item->object.sha1,
341-
commit->object.sha1, "", options);
342-
else
343-
diff_root_tree_sha1(commit->object.sha1, "", options);
344-
diffcore_std(options);
345-
return diff_flush_patch_id(options, sha1);
346-
}
347-
348-
static void get_patch_ids(struct rev_info *rev, struct diff_options *options, const char *prefix)
337+
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
349338
{
350339
struct rev_info check_rev;
351340
struct commit *commit;
352341
struct object *o1, *o2;
353342
unsigned flags1, flags2;
354-
unsigned char sha1[20];
355343

356344
if (rev->pending.nr != 2)
357345
die("Need exactly one range.");
@@ -364,10 +352,7 @@ static void get_patch_ids(struct rev_info *rev, struct diff_options *options, co
364352
if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
365353
die("Not a range.");
366354

367-
diff_setup(options);
368-
options->recursive = 1;
369-
if (diff_setup_done(options) < 0)
370-
die("diff_setup_done failed");
355+
init_patch_ids(ids);
371356

372357
/* given a range a..b get all patch ids for b..a */
373358
init_revisions(&check_rev, prefix);
@@ -382,8 +367,7 @@ static void get_patch_ids(struct rev_info *rev, struct diff_options *options, co
382367
if (commit->parents && commit->parents->next)
383368
continue;
384369

385-
if (!get_patch_id(commit, options, sha1))
386-
created_object(sha1, xcalloc(1, sizeof(struct object)));
370+
add_commit_patch_id(commit, ids);
387371
}
388372

389373
/* reset for next revision walk */
@@ -421,7 +405,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
421405
int ignore_if_in_upstream = 0;
422406
int thread = 0;
423407
const char *in_reply_to = NULL;
424-
struct diff_options patch_id_opts;
408+
struct patch_ids ids;
425409
char *add_signoff = NULL;
426410
char message_id[1024];
427411
char ref_message_id[1024];
@@ -559,22 +543,19 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
559543
}
560544

561545
if (ignore_if_in_upstream)
562-
get_patch_ids(&rev, &patch_id_opts, prefix);
546+
get_patch_ids(&rev, &ids, prefix);
563547

564548
if (!use_stdout)
565549
realstdout = fdopen(dup(1), "w");
566550

567551
prepare_revision_walk(&rev);
568552
while ((commit = get_revision(&rev)) != NULL) {
569-
unsigned char sha1[20];
570-
571553
/* ignore merges */
572554
if (commit->parents && commit->parents->next)
573555
continue;
574556

575557
if (ignore_if_in_upstream &&
576-
!get_patch_id(commit, &patch_id_opts, sha1) &&
577-
lookup_object(sha1))
558+
has_commit_patch_id(commit, &ids))
578559
continue;
579560

580561
nr++;
@@ -629,6 +610,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
629610
fclose(stdout);
630611
}
631612
free(list);
613+
if (ignore_if_in_upstream)
614+
free_patch_ids(&ids);
632615
return 0;
633616
}
634617

@@ -651,7 +634,7 @@ static const char cherry_usage[] =
651634
int cmd_cherry(int argc, const char **argv, const char *prefix)
652635
{
653636
struct rev_info revs;
654-
struct diff_options patch_id_opts;
637+
struct patch_ids ids;
655638
struct commit *commit;
656639
struct commit_list *list = NULL;
657640
const char *upstream;
@@ -697,7 +680,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
697680
return 0;
698681
}
699682

700-
get_patch_ids(&revs, &patch_id_opts, prefix);
683+
get_patch_ids(&revs, &ids, prefix);
701684

702685
if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
703686
die("Unknown commit %s", limit);
@@ -713,12 +696,10 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
713696
}
714697

715698
while (list) {
716-
unsigned char sha1[20];
717699
char sign = '+';
718700

719701
commit = list->item;
720-
if (!get_patch_id(commit, &patch_id_opts, sha1) &&
721-
lookup_object(sha1))
702+
if (has_commit_patch_id(commit, &ids))
722703
sign = '-';
723704

724705
if (verbose) {
@@ -736,5 +717,6 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
736717
list = list->next;
737718
}
738719

720+
free_patch_ids(&ids);
739721
return 0;
740722
}

commit.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "pkt-line.h"
55
#include "utf8.h"
66
#include "interpolate.h"
7+
#include "diff.h"
8+
#include "revision.h"
79

810
int save_commit_buffer = 1;
911

@@ -808,7 +810,8 @@ static long format_commit_message(const struct commit *commit,
808810
{ "%Cgreen" }, /* green */
809811
{ "%Cblue" }, /* blue */
810812
{ "%Creset" }, /* reset color */
811-
{ "%n" } /* newline */
813+
{ "%n" }, /* newline */
814+
{ "%m" }, /* left/right/bottom */
812815
};
813816
enum interp_index {
814817
IHASH = 0, IHASH_ABBREV,
@@ -824,14 +827,15 @@ static long format_commit_message(const struct commit *commit,
824827
ISUBJECT,
825828
IBODY,
826829
IRED, IGREEN, IBLUE, IRESET_COLOR,
827-
INEWLINE
830+
INEWLINE,
831+
ILEFT_RIGHT,
828832
};
829833
struct commit_list *p;
830834
char parents[1024];
831835
int i;
832836
enum { HEADER, SUBJECT, BODY } state;
833837

834-
if (INEWLINE + 1 != ARRAY_SIZE(table))
838+
if (ILEFT_RIGHT + 1 != ARRAY_SIZE(table))
835839
die("invalid interp table!");
836840

837841
/* these are independent of the commit */
@@ -852,6 +856,12 @@ static long format_commit_message(const struct commit *commit,
852856
interp_set_entry(table, ITREE_ABBREV,
853857
find_unique_abbrev(commit->tree->object.sha1,
854858
DEFAULT_ABBREV));
859+
interp_set_entry(table, ILEFT_RIGHT,
860+
(commit->object.flags & BOUNDARY)
861+
? "-"
862+
: (commit->object.flags & SYMMETRIC_LEFT)
863+
? "<"
864+
: ">");
855865

856866
parents[1] = 0;
857867
for (i = 0, p = commit->parents;

0 commit comments

Comments
 (0)