]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/log.c
log: convert to parse-options
[thirdparty/git.git] / builtin / log.c
CommitLineData
70827b15
LT
1/*
2 * Builtin "git log" and related commands (show, whatchanged)
3 *
4 * (C) Copyright 2006 Linus Torvalds
5 * 2006 Junio Hamano
6 */
7#include "cache.h"
6b2f2d98 8#include "color.h"
70827b15
LT
9#include "commit.h"
10#include "diff.h"
11#include "revision.h"
12#include "log-tree.h"
91efcf60 13#include "builtin.h"
5d7eeee2 14#include "tag.h"
cf39f54e 15#include "reflog-walk.h"
5d23e133 16#include "patch-ids.h"
a5a27c79 17#include "run-command.h"
2bda2cf4 18#include "shortlog.h"
f2968022 19#include "remote.h"
b079c50e 20#include "string-list.h"
fff02ee6 21#include "parse-options.h"
70827b15 22
dd0ffd5b
HO
23/* Set a default date-time format for git log ("log.date" config variable) */
24static const char *default_date_mode = NULL;
25
0f03ca94 26static int default_show_root = 1;
8a3d203b 27static int decoration_style;
1c40c36b 28static int decoration_given;
d54276f2 29static const char *fmt_patch_subject_prefix = "PATCH";
94c22a5e 30static const char *fmt_pretty;
0f03ca94 31
1c40c36b 32static const char * const builtin_log_usage[] = {
1c370ea4 33 "git log [<options>] [<since>..<until>] [[--] <path>...]\n"
1c40c36b
CMN
34 " or: git show [options] <object>...",
35 NULL
36};
1c370ea4 37
8a3d203b
JH
38static int parse_decoration_style(const char *var, const char *value)
39{
40 switch (git_config_maybe_bool(var, value)) {
41 case 1:
42 return DECORATE_SHORT_REFS;
43 case 0:
44 return 0;
45 default:
46 break;
47 }
48 if (!strcmp(value, "full"))
49 return DECORATE_FULL_REFS;
50 else if (!strcmp(value, "short"))
51 return DECORATE_SHORT_REFS;
52 return -1;
53}
54
1c40c36b
CMN
55static int decorate_callback(const struct option *opt, const char *arg, int unset)
56{
57 if (unset)
58 decoration_style = 0;
59 else if (arg)
60 decoration_style = parse_decoration_style("command line", arg);
61 else
62 decoration_style = DECORATE_SHORT_REFS;
63
64 if (decoration_style < 0)
65 die("invalid --decorate option: %s", arg);
66
67 decoration_given = 1;
68
69 return 0;
70}
71
a633fca0 72static void cmd_log_init(int argc, const char **argv, const char *prefix,
32962c9b 73 struct rev_info *rev, struct setup_revision_opt *opt)
70827b15 74{
5b163603 75 struct userformat_want w;
1c40c36b
CMN
76 int quiet = 0, source = 0;
77
78 const struct option builtin_log_options[] = {
79 OPT_BOOLEAN(0, "quiet", &quiet, "supress diff output"),
80 OPT_BOOLEAN(0, "source", &source, "show source"),
81 { OPTION_CALLBACK, 0, "decorate", NULL, NULL, "decorate options",
82 PARSE_OPT_OPTARG, decorate_callback},
83 OPT_END()
84 };
85
86 argc = parse_options(argc, argv, prefix,
87 builtin_log_options, builtin_log_usage,
88 PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
89 PARSE_OPT_KEEP_DASHDASH);
52883fbd 90
70827b15
LT
91 rev->abbrev = DEFAULT_ABBREV;
92 rev->commit_format = CMIT_FMT_DEFAULT;
94c22a5e 93 if (fmt_pretty)
4da45bef 94 get_commit_format(fmt_pretty, rev);
70827b15 95 rev->verbose_header = 1;
8f67f8ae 96 DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
0f03ca94 97 rev->show_root_diff = default_show_root;
d54276f2 98 rev->subject_prefix = fmt_patch_subject_prefix;
5ec11af6 99 DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV);
dd0ffd5b
HO
100
101 if (default_date_mode)
102 rev->date_mode = parse_date_format(default_date_mode);
103
32962c9b 104 argc = setup_revisions(argc, argv, rev, opt);
dd0ffd5b 105
1c40c36b
CMN
106 /* Any arguments at this point are not recognized */
107 if (argc > 1)
108 die("unrecognized argument: %s", argv[1]);
109
5b163603
JG
110 memset(&w, 0, sizeof(w));
111 userformat_find_requirements(NULL, &w);
112
113 if (!rev->show_notes_given && (!rev->pretty_given || w.notes))
66b2ed09 114 rev->show_notes = 1;
894a9d33
TR
115 if (rev->show_notes)
116 init_display_notes(&rev->notes_opt);
66b2ed09 117
9dafea26
TH
118 if (rev->diffopt.pickaxe || rev->diffopt.filter)
119 rev->always_show_header = 0;
8f67f8ae 120 if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
750f7b66
LT
121 rev->always_show_header = 0;
122 if (rev->diffopt.nr_paths != 1)
123 usage("git logs can only follow renames on one pathname at a time");
124 }
1c40c36b
CMN
125
126 if (source)
127 rev->show_source = 1;
635530a2
JH
128
129 /*
4f62c2bc 130 * defeat log.decorate configuration interacting with --pretty=raw
635530a2
JH
131 * from the command line.
132 */
4f62c2bc
JH
133 if (!decoration_given && rev->pretty_given
134 && rev->commit_format == CMIT_FMT_RAW)
635530a2
JH
135 decoration_style = 0;
136
33e7018c
LH
137 if (decoration_style) {
138 rev->show_decorations = 1;
139 load_ref_decorations(decoration_style);
140 }
1fda91b5 141 setup_pager();
9dafea26
TH
142}
143
252a7c02
LT
144/*
145 * This gives a rough estimate for how many commits we
146 * will print out in the list.
147 */
148static int estimate_commit_count(struct rev_info *rev, struct commit_list *list)
149{
150 int n = 0;
151
152 while (list) {
153 struct commit *commit = list->item;
154 unsigned int flags = commit->object.flags;
252a7c02 155 list = list->next;
7dc0fe3b 156 if (!(flags & (TREESAME | UNINTERESTING)))
53b2c823 157 n++;
252a7c02
LT
158 }
159 return n;
160}
161
162static void show_early_header(struct rev_info *rev, const char *stage, int nr)
163{
164 if (rev->shown_one) {
165 rev->shown_one = 0;
166 if (rev->commit_format != CMIT_FMT_ONELINE)
167 putchar(rev->diffopt.line_termination);
168 }
169 printf("Final output: %d %s\n", nr, stage);
170}
171
2af202be 172static struct itimerval early_output_timer;
252a7c02 173
cdcefbc9
LT
174static void log_show_early(struct rev_info *revs, struct commit_list *list)
175{
176 int i = revs->early_output;
252a7c02 177 int show_header = 1;
cdcefbc9
LT
178
179 sort_in_topological_order(&list, revs->lifo);
180 while (list && i) {
181 struct commit *commit = list->item;
252a7c02
LT
182 switch (simplify_commit(revs, commit)) {
183 case commit_show:
184 if (show_header) {
185 int n = estimate_commit_count(revs, list);
186 show_early_header(revs, "incomplete", n);
187 show_header = 0;
188 }
189 log_tree_commit(revs, commit);
190 i--;
191 break;
192 case commit_ignore:
193 break;
194 case commit_error:
195 return;
196 }
cdcefbc9 197 list = list->next;
cdcefbc9 198 }
252a7c02
LT
199
200 /* Did we already get enough commits for the early output? */
201 if (!i)
202 return;
203
204 /*
205 * ..if no, then repeat it twice a second until we
206 * do.
207 *
208 * NOTE! We don't use "it_interval", because if the
209 * reader isn't listening, we want our output to be
210 * throttled by the writing, and not have the timer
211 * trigger every second even if we're blocked on a
212 * reader!
213 */
214 early_output_timer.it_value.tv_sec = 0;
215 early_output_timer.it_value.tv_usec = 500000;
216 setitimer(ITIMER_REAL, &early_output_timer, NULL);
cdcefbc9
LT
217}
218
219static void early_output(int signal)
220{
221 show_early_output = log_show_early;
222}
223
224static void setup_early_output(struct rev_info *rev)
225{
226 struct sigaction sa;
cdcefbc9
LT
227
228 /*
229 * Set up the signal handler, minimally intrusively:
230 * we only set a single volatile integer word (not
231 * using sigatomic_t - trying to avoid unnecessary
232 * system dependencies and headers), and using
233 * SA_RESTART.
234 */
235 memset(&sa, 0, sizeof(sa));
236 sa.sa_handler = early_output;
237 sigemptyset(&sa.sa_mask);
238 sa.sa_flags = SA_RESTART;
239 sigaction(SIGALRM, &sa, NULL);
240
241 /*
242 * If we can get the whole output in less than a
243 * tenth of a second, don't even bother doing the
244 * early-output thing..
245 *
246 * This is a one-time-only trigger.
247 */
252a7c02
LT
248 early_output_timer.it_value.tv_sec = 0;
249 early_output_timer.it_value.tv_usec = 100000;
250 setitimer(ITIMER_REAL, &early_output_timer, NULL);
cdcefbc9
LT
251}
252
253static void finish_early_output(struct rev_info *rev)
254{
252a7c02 255 int n = estimate_commit_count(rev, rev->commits);
cdcefbc9 256 signal(SIGALRM, SIG_IGN);
252a7c02 257 show_early_header(rev, "done", n);
cdcefbc9
LT
258}
259
9dafea26
TH
260static int cmd_log_walk(struct rev_info *rev)
261{
262 struct commit *commit;
70827b15 263
cdcefbc9
LT
264 if (rev->early_output)
265 setup_early_output(rev);
266
3d51e1b5
MK
267 if (prepare_revision_walk(rev))
268 die("revision walk setup failed");
cdcefbc9
LT
269
270 if (rev->early_output)
271 finish_early_output(rev);
272
036d17fe 273 /*
84102a33
PVM
274 * For --check and --exit-code, the exit code is based on CHECK_FAILED
275 * and HAS_CHANGES being accumulated in rev->diffopt, so be careful to
276 * retain that state information if replacing rev->diffopt in this loop
036d17fe 277 */
70827b15 278 while ((commit = get_revision(rev)) != NULL) {
251df09b
MM
279 if (!log_tree_commit(rev, commit) &&
280 rev->max_count >= 0)
281 /*
282 * We decremented max_count in get_revision,
283 * but we didn't actually show the commit.
284 */
285 rev->max_count++;
a6c73064
JS
286 if (!rev->reflog_info) {
287 /* we allow cycles in reflog ancestry */
288 free(commit->buffer);
289 commit->buffer = NULL;
290 }
cb115748
LT
291 free_commit_list(commit->parents);
292 commit->parents = NULL;
70827b15 293 }
036d17fe
PVM
294 if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
295 DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
296 return 02;
297 }
84102a33 298 return diff_result_code(&rev->diffopt, 0);
70827b15
LT
299}
300
ef90d6d4 301static int git_log_config(const char *var, const char *value, void *cb)
0f03ca94 302{
94c22a5e
CR
303 if (!strcmp(var, "format.pretty"))
304 return git_config_string(&fmt_pretty, var, value);
70cff3ac
BH
305 if (!strcmp(var, "format.subjectprefix"))
306 return git_config_string(&fmt_patch_subject_prefix, var, value);
dd0ffd5b
HO
307 if (!strcmp(var, "log.date"))
308 return git_config_string(&default_date_mode, var, value);
eb734454 309 if (!strcmp(var, "log.decorate")) {
8a3d203b
JH
310 decoration_style = parse_decoration_style(var, value);
311 if (decoration_style < 0)
312 decoration_style = 0; /* maybe warn? */
eb734454
SD
313 return 0;
314 }
0f03ca94
PB
315 if (!strcmp(var, "log.showroot")) {
316 default_show_root = git_config_bool(var, value);
317 return 0;
318 }
5e11bee6
NR
319 if (!prefixcmp(var, "color.decorate."))
320 return parse_decorate_color_config(var, 15, value);
321
ef90d6d4 322 return git_diff_ui_config(var, value, cb);
0f03ca94
PB
323}
324
a633fca0 325int cmd_whatchanged(int argc, const char **argv, const char *prefix)
70827b15
LT
326{
327 struct rev_info rev;
32962c9b 328 struct setup_revision_opt opt;
70827b15 329
ef90d6d4 330 git_config(git_log_config, NULL);
6b2f2d98
MK
331
332 if (diff_use_color_default == -1)
333 diff_use_color_default = git_use_color_default;
334
db6296a5 335 init_revisions(&rev, prefix);
70827b15 336 rev.diff = 1;
9202434c 337 rev.simplify_history = 0;
32962c9b
JH
338 memset(&opt, 0, sizeof(opt));
339 opt.def = "HEAD";
340 cmd_log_init(argc, argv, prefix, &rev, &opt);
9dafea26
TH
341 if (!rev.diffopt.output_format)
342 rev.diffopt.output_format = DIFF_FORMAT_RAW;
343 return cmd_log_walk(&rev);
70827b15
LT
344}
345
56122ed8
JS
346static void show_tagger(char *buf, int len, struct rev_info *rev)
347{
ea718e65 348 struct strbuf out = STRBUF_INIT;
56122ed8 349
ea718e65 350 pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode,
a6fa5992 351 get_log_output_encoding());
ca4ca9ed 352 printf("%s", out.buf);
ea718e65 353 strbuf_release(&out);
56122ed8
JS
354}
355
356static int show_object(const unsigned char *sha1, int show_tag_object,
357 struct rev_info *rev)
5d7eeee2
JS
358{
359 unsigned long size;
21666f1a
NP
360 enum object_type type;
361 char *buf = read_sha1_file(sha1, &type, &size);
5d7eeee2
JS
362 int offset = 0;
363
364 if (!buf)
365 return error("Could not read object %s", sha1_to_hex(sha1));
366
56122ed8
JS
367 if (show_tag_object)
368 while (offset < size && buf[offset] != '\n') {
369 int new_offset = offset + 1;
5d7eeee2
JS
370 while (new_offset < size && buf[new_offset++] != '\n')
371 ; /* do nothing */
56122ed8
JS
372 if (!prefixcmp(buf + offset, "tagger "))
373 show_tagger(buf + offset + 7,
374 new_offset - offset - 7, rev);
5d7eeee2
JS
375 offset = new_offset;
376 }
377
378 if (offset < size)
379 fwrite(buf + offset, size - offset, 1, stdout);
380 free(buf);
381 return 0;
382}
383
384static int show_tree_object(const unsigned char *sha1,
385 const char *base, int baselen,
671f0707 386 const char *pathname, unsigned mode, int stage, void *context)
5d7eeee2
JS
387{
388 printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
389 return 0;
390}
391
b4490059
JH
392static void show_rev_tweak_rev(struct rev_info *rev, struct setup_revision_opt *opt)
393{
2bf65873
JH
394 if (rev->ignore_merges) {
395 /* There was no "-m" on the command line */
396 rev->ignore_merges = 0;
397 if (!rev->first_parent_only && !rev->combine_merges) {
398 /* No "--first-parent", "-c", nor "--cc" */
399 rev->combine_merges = 1;
400 rev->dense_combined_merges = 1;
401 }
402 }
b4490059
JH
403 if (!rev->diffopt.output_format)
404 rev->diffopt.output_format = DIFF_FORMAT_PATCH;
405}
406
a633fca0 407int cmd_show(int argc, const char **argv, const char *prefix)
70827b15
LT
408{
409 struct rev_info rev;
5d7eeee2 410 struct object_array_entry *objects;
32962c9b 411 struct setup_revision_opt opt;
5d7eeee2 412 int i, count, ret = 0;
70827b15 413
ef90d6d4 414 git_config(git_log_config, NULL);
6b2f2d98
MK
415
416 if (diff_use_color_default == -1)
417 diff_use_color_default = git_use_color_default;
418
db6296a5 419 init_revisions(&rev, prefix);
70827b15 420 rev.diff = 1;
70827b15 421 rev.always_show_header = 1;
70827b15 422 rev.no_walk = 1;
32962c9b
JH
423 memset(&opt, 0, sizeof(opt));
424 opt.def = "HEAD";
b4490059 425 opt.tweak = show_rev_tweak_rev;
32962c9b 426 cmd_log_init(argc, argv, prefix, &rev, &opt);
5d7eeee2
JS
427
428 count = rev.pending.nr;
429 objects = rev.pending.objects;
430 for (i = 0; i < count && !ret; i++) {
431 struct object *o = objects[i].item;
432 const char *name = objects[i].name;
433 switch (o->type) {
434 case OBJ_BLOB:
56122ed8 435 ret = show_object(o->sha1, 0, NULL);
5d7eeee2
JS
436 break;
437 case OBJ_TAG: {
438 struct tag *t = (struct tag *)o;
439
ae03ee64
JK
440 if (rev.shown_one)
441 putchar('\n');
56122ed8 442 printf("%stag %s%s\n",
8f67f8ae 443 diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
5d7eeee2 444 t->tag,
8f67f8ae 445 diff_get_color_opt(&rev.diffopt, DIFF_RESET));
56122ed8 446 ret = show_object(o->sha1, 1, &rev);
ae03ee64 447 rev.shown_one = 1;
d2dadfe8
JH
448 if (ret)
449 break;
450 o = parse_object(t->tagged->sha1);
451 if (!o)
452 ret = error("Could not read object %s",
453 sha1_to_hex(t->tagged->sha1));
454 objects[i].item = o;
5d7eeee2
JS
455 i--;
456 break;
457 }
458 case OBJ_TREE:
ae03ee64
JK
459 if (rev.shown_one)
460 putchar('\n');
5d7eeee2 461 printf("%stree %s%s\n\n",
8f67f8ae 462 diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
5d7eeee2 463 name,
8f67f8ae 464 diff_get_color_opt(&rev.diffopt, DIFF_RESET));
5d7eeee2 465 read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
671f0707 466 show_tree_object, NULL);
ae03ee64 467 rev.shown_one = 1;
5d7eeee2
JS
468 break;
469 case OBJ_COMMIT:
470 rev.pending.nr = rev.pending.alloc = 0;
471 rev.pending.objects = NULL;
472 add_object_array(o, name, &rev.pending);
473 ret = cmd_log_walk(&rev);
474 break;
475 default:
476 ret = error("Unknown type: %d", o->type);
477 }
478 }
479 free(objects);
480 return ret;
70827b15
LT
481}
482
cf39f54e
LT
483/*
484 * This is equivalent to "git log -g --abbrev-commit --pretty=oneline"
485 */
486int cmd_log_reflog(int argc, const char **argv, const char *prefix)
487{
488 struct rev_info rev;
32962c9b 489 struct setup_revision_opt opt;
cf39f54e 490
ef90d6d4 491 git_config(git_log_config, NULL);
6b2f2d98
MK
492
493 if (diff_use_color_default == -1)
494 diff_use_color_default = git_use_color_default;
495
cf39f54e
LT
496 init_revisions(&rev, prefix);
497 init_reflog_walk(&rev.reflog_info);
498 rev.abbrev_commit = 1;
499 rev.verbose_header = 1;
32962c9b
JH
500 memset(&opt, 0, sizeof(opt));
501 opt.def = "HEAD";
502 cmd_log_init(argc, argv, prefix, &rev, &opt);
cf39f54e
LT
503
504 /*
505 * This means that we override whatever commit format the user gave
506 * on the cmd line. Sad, but cmd_log_init() currently doesn't
507 * allow us to set a different default.
508 */
509 rev.commit_format = CMIT_FMT_ONELINE;
4da45bef 510 rev.use_terminator = 1;
cf39f54e
LT
511 rev.always_show_header = 1;
512
cf39f54e
LT
513 return cmd_log_walk(&rev);
514}
515
a633fca0 516int cmd_log(int argc, const char **argv, const char *prefix)
70827b15
LT
517{
518 struct rev_info rev;
32962c9b 519 struct setup_revision_opt opt;
70827b15 520
ef90d6d4 521 git_config(git_log_config, NULL);
6b2f2d98
MK
522
523 if (diff_use_color_default == -1)
524 diff_use_color_default = git_use_color_default;
525
db6296a5 526 init_revisions(&rev, prefix);
70827b15 527 rev.always_show_header = 1;
32962c9b
JH
528 memset(&opt, 0, sizeof(opt));
529 opt.def = "HEAD";
530 cmd_log_init(argc, argv, prefix, &rev, &opt);
9dafea26 531 return cmd_log_walk(&rev);
70827b15 532}
91efcf60 533
c06d2daa 534/* format-patch */
0377db77 535
917a8f89 536static const char *fmt_patch_suffix = ".patch";
49604a4d 537static int numbered = 0;
a567fdcb 538static int auto_number = 1;
20ff0680 539
0db5260b
JW
540static char *default_attach = NULL;
541
ca9e0a1b
SB
542static struct string_list extra_hdr;
543static struct string_list extra_to;
544static struct string_list extra_cc;
3ee79d9f
DB
545
546static void add_header(const char *value)
547{
ca9e0a1b 548 struct string_list_item *item;
3ee79d9f 549 int len = strlen(value);
c8c4450e 550 while (len && value[len - 1] == '\n')
3ee79d9f 551 len--;
ca9e0a1b 552
3ee79d9f 553 if (!strncasecmp(value, "to: ", 4)) {
1d2f80fa 554 item = string_list_append(&extra_to, value + 4);
ca9e0a1b
SB
555 len -= 4;
556 } else if (!strncasecmp(value, "cc: ", 4)) {
1d2f80fa 557 item = string_list_append(&extra_cc, value + 4);
ca9e0a1b
SB
558 len -= 4;
559 } else {
1d2f80fa 560 item = string_list_append(&extra_hdr, value);
3ee79d9f 561 }
ca9e0a1b
SB
562
563 item->string[len] = '\0';
3ee79d9f
DB
564}
565
30984ed2
TR
566#define THREAD_SHALLOW 1
567#define THREAD_DEEP 2
6622d9c7
SB
568static int thread;
569static int do_signoff;
570static const char *signature = git_version_string;
30984ed2 571
ef90d6d4 572static int git_format_config(const char *var, const char *value, void *cb)
20ff0680
JS
573{
574 if (!strcmp(var, "format.headers")) {
d7fb91c6
JH
575 if (!value)
576 die("format.headers without value");
3ee79d9f 577 add_header(value);
20ff0680
JS
578 return 0;
579 }
70cff3ac
BH
580 if (!strcmp(var, "format.suffix"))
581 return git_config_string(&fmt_patch_suffix, var, value);
ae6c098f
SD
582 if (!strcmp(var, "format.to")) {
583 if (!value)
584 return config_error_nonbool(var);
1d2f80fa 585 string_list_append(&extra_to, value);
ae6c098f
SD
586 return 0;
587 }
fe8928e6
MV
588 if (!strcmp(var, "format.cc")) {
589 if (!value)
590 return config_error_nonbool(var);
1d2f80fa 591 string_list_append(&extra_cc, value);
fe8928e6
MV
592 return 0;
593 }
a159ca0c 594 if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
f3aafa4d
RA
595 return 0;
596 }
49604a4d 597 if (!strcmp(var, "format.numbered")) {
90f5c186 598 if (value && !strcasecmp(value, "auto")) {
49604a4d
BG
599 auto_number = 1;
600 return 0;
601 }
49604a4d 602 numbered = git_config_bool(var, value);
a567fdcb 603 auto_number = auto_number && numbered;
49604a4d
BG
604 return 0;
605 }
0db5260b
JW
606 if (!strcmp(var, "format.attach")) {
607 if (value && *value)
608 default_attach = xstrdup(value);
609 else
610 default_attach = xstrdup(git_version_string);
611 return 0;
612 }
30984ed2
TR
613 if (!strcmp(var, "format.thread")) {
614 if (value && !strcasecmp(value, "deep")) {
615 thread = THREAD_DEEP;
616 return 0;
617 }
618 if (value && !strcasecmp(value, "shallow")) {
619 thread = THREAD_SHALLOW;
620 return 0;
621 }
622 thread = git_config_bool(var, value) && THREAD_SHALLOW;
623 return 0;
624 }
1d1876e9
HV
625 if (!strcmp(var, "format.signoff")) {
626 do_signoff = git_config_bool(var, value);
627 return 0;
628 }
6622d9c7
SB
629 if (!strcmp(var, "format.signature"))
630 return git_config_string(&signature, var, value);
dbd21447 631
ef90d6d4 632 return git_log_config(var, value, cb);
20ff0680
JS
633}
634
81f3a188 635static FILE *realstdout = NULL;
efd02016 636static const char *output_directory = NULL;
9800a754 637static int outdir_offset;
81f3a188 638
cd2ef591 639static int reopen_stdout(struct commit *commit, struct rev_info *rev)
0377db77 640{
cd2ef591 641 struct strbuf filename = STRBUF_INIT;
c06d2daa 642 int suffix_len = strlen(fmt_patch_suffix) + 1;
0377db77 643
2448482b 644 if (output_directory) {
cd2ef591
SB
645 strbuf_addstr(&filename, output_directory);
646 if (filename.len >=
647 PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len)
c06d2daa 648 return error("name of output directory is too long");
cd2ef591
SB
649 if (filename.buf[filename.len - 1] != '/')
650 strbuf_addch(&filename, '/');
2448482b 651 }
0377db77 652
cd2ef591 653 get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
e6ff0f42 654
90b19941 655 if (!DIFF_OPT_TST(&rev->diffopt, QUICK))
cd2ef591 656 fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
ec2956df 657
cd2ef591
SB
658 if (freopen(filename.buf, "w", stdout) == NULL)
659 return error("Cannot open patch file %s", filename.buf);
c06d2daa 660
cd2ef591 661 strbuf_release(&filename);
e6ff0f42 662 return 0;
0377db77
JS
663}
664
5d23e133 665static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
9c6efa36
JS
666{
667 struct rev_info check_rev;
668 struct commit *commit;
669 struct object *o1, *o2;
670 unsigned flags1, flags2;
9c6efa36
JS
671
672 if (rev->pending.nr != 2)
673 die("Need exactly one range.");
674
675 o1 = rev->pending.objects[0].item;
676 flags1 = o1->flags;
677 o2 = rev->pending.objects[1].item;
678 flags2 = o2->flags;
679
680 if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
681 die("Not a range.");
682
5d23e133 683 init_patch_ids(ids);
9c6efa36
JS
684
685 /* given a range a..b get all patch ids for b..a */
db6296a5 686 init_revisions(&check_rev, prefix);
9c6efa36
JS
687 o1->flags ^= UNINTERESTING;
688 o2->flags ^= UNINTERESTING;
689 add_pending_object(&check_rev, o1, "o1");
690 add_pending_object(&check_rev, o2, "o2");
3d51e1b5
MK
691 if (prepare_revision_walk(&check_rev))
692 die("revision walk setup failed");
9c6efa36
JS
693
694 while ((commit = get_revision(&check_rev)) != NULL) {
695 /* ignore merges */
696 if (commit->parents && commit->parents->next)
697 continue;
698
5d23e133 699 add_commit_patch_id(commit, ids);
9c6efa36
JS
700 }
701
702 /* reset for next revision walk */
81db0941
JS
703 clear_commit_marks((struct commit *)o1,
704 SEEN | UNINTERESTING | SHOWN | ADDED);
705 clear_commit_marks((struct commit *)o2,
706 SEEN | UNINTERESTING | SHOWN | ADDED);
9c6efa36
JS
707 o1->flags = flags1;
708 o2->flags = flags2;
709}
710
e1a37346 711static void gen_message_id(struct rev_info *info, char *base)
d1566f78 712{
774751a8 713 const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME);
d1566f78
JT
714 const char *email_start = strrchr(committer, '<');
715 const char *email_end = strrchr(committer, '>');
f285a2d7 716 struct strbuf buf = STRBUF_INIT;
e1a37346 717 if (!email_start || !email_end || email_start > email_end - 1)
d1566f78 718 die("Could not extract email from committer identity.");
e1a37346
DB
719 strbuf_addf(&buf, "%s.%lu.git.%.*s", base,
720 (unsigned long) time(NULL),
721 (int)(email_end - email_start - 1), email_start + 1);
722 info->message_id = strbuf_detach(&buf, NULL);
d1566f78
JT
723}
724
6622d9c7
SB
725static void print_signature(void)
726{
727 if (signature && *signature)
728 printf("-- \n%s\n\n", signature);
729}
730
2bda2cf4
DB
731static void make_cover_letter(struct rev_info *rev, int use_stdout,
732 int numbered, int numbered_files,
733 struct commit *origin,
734 int nr, struct commit **list, struct commit *head)
a5a27c79
DB
735{
736 const char *committer;
a5a27c79
DB
737 const char *subject_start = NULL;
738 const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n";
739 const char *msg;
740 const char *extra_headers = rev->extra_headers;
2bda2cf4 741 struct shortlog log;
f285a2d7 742 struct strbuf sb = STRBUF_INIT;
2bda2cf4 743 int i;
330db18c 744 const char *encoding = "UTF-8";
39fe578b 745 struct diff_options opts;
267123b4 746 int need_8bit_cte = 0;
cd2ef591 747 struct commit *commit = NULL;
a5a27c79
DB
748
749 if (rev->commit_format != CMIT_FMT_EMAIL)
750 die("Cover letter needs email format");
751
cd2ef591 752 committer = git_committer_info(0);
6df514af 753
cd2ef591
SB
754 if (!numbered_files) {
755 /*
756 * We fake a commit for the cover letter so we get the filename
757 * desired.
758 */
759 commit = xcalloc(1, sizeof(*commit));
760 commit->buffer = xmalloc(400);
761 snprintf(commit->buffer, 400,
762 "tree 0000000000000000000000000000000000000000\n"
763 "parent %s\n"
764 "author %s\n"
765 "committer %s\n\n"
766 "cover letter\n",
108dab28 767 sha1_to_hex(head->object.sha1), committer, committer);
cd2ef591
SB
768 }
769
770 if (!use_stdout && reopen_stdout(commit, rev))
a5a27c79
DB
771 return;
772
cd2ef591 773 if (commit) {
a5a27c79 774
cd2ef591
SB
775 free(commit->buffer);
776 free(commit);
777 }
a5a27c79 778
108dab28 779 log_write_email_headers(rev, head, &subject_start, &extra_headers,
267123b4 780 &need_8bit_cte);
a5a27c79 781
0a7f4483
JS
782 for (i = 0; !need_8bit_cte && i < nr; i++)
783 if (has_non_ascii(list[i]->buffer))
784 need_8bit_cte = 1;
785
a5a27c79 786 msg = body;
a5a27c79
DB
787 pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
788 encoding);
789 pp_title_line(CMIT_FMT_EMAIL, &msg, &sb, subject_start, extra_headers,
267123b4 790 encoding, need_8bit_cte);
a5a27c79
DB
791 pp_remainder(CMIT_FMT_EMAIL, &msg, &sb, 0);
792 printf("%s\n", sb.buf);
793
794 strbuf_release(&sb);
795
2bda2cf4 796 shortlog_init(&log);
859c4fbe
JS
797 log.wrap_lines = 1;
798 log.wrap = 72;
799 log.in1 = 2;
800 log.in2 = 4;
2bda2cf4
DB
801 for (i = 0; i < nr; i++)
802 shortlog_add_commit(&log, list[i]);
803
804 shortlog_output(&log);
805
a5a27c79 806 /*
2bda2cf4 807 * We can only do diffstat with a unique reference point
a5a27c79
DB
808 */
809 if (!origin)
810 return;
811
5d02294c
JS
812 memcpy(&opts, &rev->diffopt, sizeof(opts));
813 opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
a5a27c79 814
39fe578b
DB
815 diff_setup_done(&opts);
816
817 diff_tree_sha1(origin->tree->object.sha1,
818 head->tree->object.sha1,
819 "", &opts);
820 diffcore_std(&opts);
821 diff_flush(&opts);
a5a27c79 822
a5a27c79 823 printf("\n");
6622d9c7 824 print_signature();
d1566f78
JT
825}
826
8419d2ee
JH
827static const char *clean_message_id(const char *msg_id)
828{
829 char ch;
830 const char *a, *z, *m;
8419d2ee
JH
831
832 m = msg_id;
833 while ((ch = *m) && (isspace(ch) || (ch == '<')))
834 m++;
835 a = m;
836 z = NULL;
837 while ((ch = *m)) {
838 if (!isspace(ch) && (ch != '>'))
839 z = m;
840 m++;
841 }
842 if (!z)
843 die("insane in-reply-to: %s", msg_id);
844 if (++z == m)
845 return a;
182af834 846 return xmemdupz(a, z - a);
8419d2ee
JH
847}
848
9800a754
JH
849static const char *set_outdir(const char *prefix, const char *output_directory)
850{
851 if (output_directory && is_absolute_path(output_directory))
852 return output_directory;
853
854 if (!prefix || !*prefix) {
855 if (output_directory)
856 return output_directory;
857 /* The user did not explicitly ask for "./" */
858 outdir_offset = 2;
859 return "./";
860 }
861
862 outdir_offset = strlen(prefix);
863 if (!output_directory)
864 return prefix;
865
866 return xstrdup(prefix_filename(prefix, outdir_offset,
867 output_directory));
868}
869
fff02ee6
SB
870static const char * const builtin_format_patch_usage[] = {
871 "git format-patch [options] [<since> | <revision range>]",
872 NULL
873};
874
875static int keep_subject = 0;
876
877static int keep_callback(const struct option *opt, const char *arg, int unset)
878{
879 ((struct rev_info *)opt->value)->total = -1;
880 keep_subject = 1;
881 return 0;
882}
883
884static int subject_prefix = 0;
885
886static int subject_prefix_callback(const struct option *opt, const char *arg,
887 int unset)
888{
889 subject_prefix = 1;
890 ((struct rev_info *)opt->value)->subject_prefix = arg;
891 return 0;
892}
893
1af4731b
JH
894static int numbered_cmdline_opt = 0;
895
fff02ee6
SB
896static int numbered_callback(const struct option *opt, const char *arg,
897 int unset)
898{
1af4731b 899 *(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
fff02ee6
SB
900 if (unset)
901 auto_number = 0;
902 return 0;
903}
904
905static int no_numbered_callback(const struct option *opt, const char *arg,
906 int unset)
907{
908 return numbered_callback(opt, arg, 1);
909}
910
911static int output_directory_callback(const struct option *opt, const char *arg,
912 int unset)
913{
914 const char **dir = (const char **)opt->value;
915 if (*dir)
916 die("Two output directories?");
917 *dir = arg;
918 return 0;
919}
920
921static int thread_callback(const struct option *opt, const char *arg, int unset)
922{
923 int *thread = (int *)opt->value;
924 if (unset)
925 *thread = 0;
926 else if (!arg || !strcmp(arg, "shallow"))
927 *thread = THREAD_SHALLOW;
928 else if (!strcmp(arg, "deep"))
929 *thread = THREAD_DEEP;
930 else
931 return 1;
932 return 0;
933}
934
935static int attach_callback(const struct option *opt, const char *arg, int unset)
936{
937 struct rev_info *rev = (struct rev_info *)opt->value;
938 if (unset)
939 rev->mime_boundary = NULL;
940 else if (arg)
941 rev->mime_boundary = arg;
942 else
943 rev->mime_boundary = git_version_string;
944 rev->no_inline = unset ? 0 : 1;
945 return 0;
946}
947
948static int inline_callback(const struct option *opt, const char *arg, int unset)
949{
950 struct rev_info *rev = (struct rev_info *)opt->value;
951 if (unset)
952 rev->mime_boundary = NULL;
953 else if (arg)
954 rev->mime_boundary = arg;
955 else
956 rev->mime_boundary = git_version_string;
957 rev->no_inline = 0;
958 return 0;
959}
960
961static int header_callback(const struct option *opt, const char *arg, int unset)
962{
c4260034
SB
963 if (unset) {
964 string_list_clear(&extra_hdr, 0);
965 string_list_clear(&extra_to, 0);
966 string_list_clear(&extra_cc, 0);
967 } else {
968 add_header(arg);
969 }
fff02ee6
SB
970 return 0;
971}
972
ae6c098f
SD
973static int to_callback(const struct option *opt, const char *arg, int unset)
974{
c4260034
SB
975 if (unset)
976 string_list_clear(&extra_to, 0);
977 else
1d2f80fa 978 string_list_append(&extra_to, arg);
fff02ee6
SB
979 return 0;
980}
981
982static int cc_callback(const struct option *opt, const char *arg, int unset)
983{
c4260034
SB
984 if (unset)
985 string_list_clear(&extra_cc, 0);
986 else
1d2f80fa 987 string_list_append(&extra_cc, arg);
fff02ee6
SB
988 return 0;
989}
990
a633fca0 991int cmd_format_patch(int argc, const char **argv, const char *prefix)
91efcf60
JH
992{
993 struct commit *commit;
994 struct commit **list = NULL;
995 struct rev_info rev;
32962c9b 996 struct setup_revision_opt s_r_opt;
fff02ee6 997 int nr = 0, total, i;
0377db77 998 int use_stdout = 0;
fa0f02df 999 int start_number = -1;
e6ff0f42 1000 int numbered_files = 0; /* _just_ numbers */
9c6efa36 1001 int ignore_if_in_upstream = 0;
a5a27c79 1002 int cover_letter = 0;
2bda2cf4 1003 int boundary_count = 0;
37c22a4b 1004 int no_binary_diff = 0;
a5a27c79 1005 struct commit *origin = NULL, *head = NULL;
76af0734 1006 const char *in_reply_to = NULL;
5d23e133 1007 struct patch_ids ids;
cf2251b6 1008 char *add_signoff = NULL;
f285a2d7 1009 struct strbuf buf = STRBUF_INIT;
1d46f2ea 1010 int use_patch_format = 0;
fff02ee6
SB
1011 const struct option builtin_format_patch_options[] = {
1012 { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
1013 "use [PATCH n/m] even with a single patch",
1014 PARSE_OPT_NOARG, numbered_callback },
1015 { OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
1016 "use [PATCH] even with multiple patches",
1017 PARSE_OPT_NOARG, no_numbered_callback },
1018 OPT_BOOLEAN('s', "signoff", &do_signoff, "add Signed-off-by:"),
1019 OPT_BOOLEAN(0, "stdout", &use_stdout,
1020 "print patches to standard out"),
1021 OPT_BOOLEAN(0, "cover-letter", &cover_letter,
1022 "generate a cover letter"),
1023 OPT_BOOLEAN(0, "numbered-files", &numbered_files,
1024 "use simple number sequence for output file names"),
1025 OPT_STRING(0, "suffix", &fmt_patch_suffix, "sfx",
1026 "use <sfx> instead of '.patch'"),
1027 OPT_INTEGER(0, "start-number", &start_number,
1028 "start numbering patches at <n> instead of 1"),
1029 { OPTION_CALLBACK, 0, "subject-prefix", &rev, "prefix",
1030 "Use [<prefix>] instead of [PATCH]",
1031 PARSE_OPT_NONEG, subject_prefix_callback },
1032 { OPTION_CALLBACK, 'o', "output-directory", &output_directory,
1033 "dir", "store resulting files in <dir>",
1034 PARSE_OPT_NONEG, output_directory_callback },
1035 { OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL,
1036 "don't strip/add [PATCH]",
1037 PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
1038 OPT_BOOLEAN(0, "no-binary", &no_binary_diff,
1039 "don't output binary diffs"),
1040 OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
1041 "don't include a patch matching a commit upstream"),
2cfa8330
BG
1042 { OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
1043 "show patch format instead of default (patch + stat)",
1044 PARSE_OPT_NONEG | PARSE_OPT_NOARG },
fff02ee6
SB
1045 OPT_GROUP("Messaging"),
1046 { OPTION_CALLBACK, 0, "add-header", NULL, "header",
c4260034 1047 "add email header", 0, header_callback },
ae6c098f 1048 { OPTION_CALLBACK, 0, "to", NULL, "email", "add To: header",
c4260034 1049 0, to_callback },
fff02ee6 1050 { OPTION_CALLBACK, 0, "cc", NULL, "email", "add Cc: header",
c4260034 1051 0, cc_callback },
fff02ee6
SB
1052 OPT_STRING(0, "in-reply-to", &in_reply_to, "message-id",
1053 "make first mail a reply to <message-id>"),
1054 { OPTION_CALLBACK, 0, "attach", &rev, "boundary",
1055 "attach the patch", PARSE_OPT_OPTARG,
1056 attach_callback },
1057 { OPTION_CALLBACK, 0, "inline", &rev, "boundary",
1058 "inline the patch",
1059 PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
1060 inline_callback },
1061 { OPTION_CALLBACK, 0, "thread", &thread, "style",
1062 "enable message threading, styles: shallow, deep",
1063 PARSE_OPT_OPTARG, thread_callback },
6622d9c7
SB
1064 OPT_STRING(0, "signature", &signature, "signature",
1065 "add a signature"),
fff02ee6
SB
1066 OPT_END()
1067 };
91efcf60 1068
ca9e0a1b
SB
1069 extra_hdr.strdup_strings = 1;
1070 extra_to.strdup_strings = 1;
1071 extra_cc.strdup_strings = 1;
ef90d6d4 1072 git_config(git_format_config, NULL);
db6296a5 1073 init_revisions(&rev, prefix);
91efcf60
JH
1074 rev.commit_format = CMIT_FMT_EMAIL;
1075 rev.verbose_header = 1;
1076 rev.diff = 1;
2c642ed8 1077 rev.no_merges = 1;
8f67f8ae 1078 DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
dbd21447 1079 rev.subject_prefix = fmt_patch_subject_prefix;
32962c9b
JH
1080 memset(&s_r_opt, 0, sizeof(s_r_opt));
1081 s_r_opt.def = "HEAD";
20ff0680 1082
0db5260b
JW
1083 if (default_attach) {
1084 rev.mime_boundary = default_attach;
1085 rev.no_inline = 1;
1086 }
1087
2448482b
JS
1088 /*
1089 * Parse the arguments before setup_revisions(), or something
2dc189a3 1090 * like "git format-patch -o a123 HEAD^.." may fail; a123 is
2448482b
JS
1091 * possibly a valid SHA1.
1092 */
37782920 1093 argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
fff02ee6 1094 builtin_format_patch_usage,
382da402
FC
1095 PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
1096 PARSE_OPT_KEEP_DASHDASH);
2448482b 1097
1d1876e9
HV
1098 if (do_signoff) {
1099 const char *committer;
1100 const char *endpos;
1101 committer = git_committer_info(IDENT_ERROR_ON_NO_NAME);
1102 endpos = strchr(committer, '>');
1103 if (!endpos)
1104 die("bogus committer info %s", committer);
1105 add_signoff = xmemdupz(committer, endpos - committer + 1);
1106 }
1107
ca9e0a1b
SB
1108 for (i = 0; i < extra_hdr.nr; i++) {
1109 strbuf_addstr(&buf, extra_hdr.items[i].string);
3ee79d9f
DB
1110 strbuf_addch(&buf, '\n');
1111 }
1112
ca9e0a1b 1113 if (extra_to.nr)
3ee79d9f 1114 strbuf_addstr(&buf, "To: ");
ca9e0a1b 1115 for (i = 0; i < extra_to.nr; i++) {
3ee79d9f
DB
1116 if (i)
1117 strbuf_addstr(&buf, " ");
ca9e0a1b
SB
1118 strbuf_addstr(&buf, extra_to.items[i].string);
1119 if (i + 1 < extra_to.nr)
3ee79d9f
DB
1120 strbuf_addch(&buf, ',');
1121 strbuf_addch(&buf, '\n');
1122 }
1123
ca9e0a1b 1124 if (extra_cc.nr)
3ee79d9f 1125 strbuf_addstr(&buf, "Cc: ");
ca9e0a1b 1126 for (i = 0; i < extra_cc.nr; i++) {
3ee79d9f
DB
1127 if (i)
1128 strbuf_addstr(&buf, " ");
ca9e0a1b
SB
1129 strbuf_addstr(&buf, extra_cc.items[i].string);
1130 if (i + 1 < extra_cc.nr)
3ee79d9f
DB
1131 strbuf_addch(&buf, ',');
1132 strbuf_addch(&buf, '\n');
1133 }
1134
2af202be 1135 rev.extra_headers = strbuf_detach(&buf, NULL);
3ee79d9f 1136
add5c8a5 1137 if (start_number < 0)
fa0f02df 1138 start_number = 1;
ca6b91d2
JM
1139
1140 /*
1141 * If numbered is set solely due to format.numbered in config,
1142 * and it would conflict with --keep-subject (-k) from the
1143 * command line, reset "numbered".
1144 */
1145 if (numbered && keep_subject && !numbered_cmdline_opt)
1146 numbered = 0;
1147
63b398a4 1148 if (numbered && keep_subject)
8ac80a57 1149 die ("-n and -k are mutually exclusive.");
2d9e4a47
RJ
1150 if (keep_subject && subject_prefix)
1151 die ("--subject-prefix and -k are mutually exclusive.");
8ac80a57 1152
32962c9b 1153 argc = setup_revisions(argc, argv, &rev, &s_r_opt);
2448482b
JS
1154 if (argc > 1)
1155 die ("unrecognized argument: %s", argv[1]);
0377db77 1156
02bc5b03
BG
1157 if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
1158 die("--name-only does not make sense");
1159 if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
1160 die("--name-status does not make sense");
1161 if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
1162 die("--check does not make sense");
1163
1164 if (!use_patch_format &&
1165 (!rev.diffopt.output_format ||
1166 rev.diffopt.output_format == DIFF_FORMAT_PATCH))
1167 rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;
1168
1169 /* Always generate a patch */
1170 rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
c9b5ef99 1171
37c22a4b 1172 if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
8f67f8ae 1173 DIFF_OPT_SET(&rev.diffopt, BINARY);
e47f306d 1174
894a9d33
TR
1175 if (rev.show_notes)
1176 init_display_notes(&rev.notes_opt);
1177
9800a754
JH
1178 if (!use_stdout)
1179 output_directory = set_outdir(prefix, output_directory);
38a94bb6
TRC
1180 else
1181 setup_pager();
77e565d8 1182
efd02016
JH
1183 if (output_directory) {
1184 if (use_stdout)
1185 die("standard output, or directory, which one?");
1186 if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
0721c314
TR
1187 die_errno("Could not create directory '%s'",
1188 output_directory);
efd02016
JH
1189 }
1190
1f1e895f 1191 if (rev.pending.nr == 1) {
8a1d076e
JH
1192 if (rev.max_count < 0 && !rev.show_root_diff) {
1193 /*
1194 * This is traditional behaviour of "git format-patch
1195 * origin" that prepares what the origin side still
1196 * does not have.
1197 */
7c496280 1198 rev.pending.objects[0].item->flags |= UNINTERESTING;
3384a2df 1199 add_head_to_pending(&rev);
7c496280 1200 }
8a1d076e
JH
1201 /*
1202 * Otherwise, it is "format-patch -22 HEAD", and/or
1203 * "format-patch --root HEAD". The user wants
1204 * get_revision() to do the usual traversal.
7c496280 1205 */
e686eb98 1206 }
68c2ec7f
JH
1207
1208 /*
1209 * We cannot move this anywhere earlier because we do want to
9517e6b8 1210 * know if --root was given explicitly from the command line.
68c2ec7f
JH
1211 */
1212 rev.show_root_diff = 1;
1213
a5a27c79
DB
1214 if (cover_letter) {
1215 /* remember the range */
a5a27c79
DB
1216 int i;
1217 for (i = 0; i < rev.pending.nr; i++) {
1218 struct object *o = rev.pending.objects[i].item;
2bda2cf4 1219 if (!(o->flags & UNINTERESTING))
a5a27c79
DB
1220 head = (struct commit *)o;
1221 }
a5a27c79
DB
1222 /* We can't generate a cover letter without any patches */
1223 if (!head)
1224 return 0;
1225 }
e686eb98 1226
657ab61e
KB
1227 if (ignore_if_in_upstream) {
1228 /* Don't say anything if head and upstream are the same. */
1229 if (rev.pending.nr == 2) {
1230 struct object_array_entry *o = rev.pending.objects;
1231 if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
1232 return 0;
1233 }
5d23e133 1234 get_patch_ids(&rev, &ids, prefix);
657ab61e 1235 }
9c6efa36 1236
81f3a188 1237 if (!use_stdout)
f5788250 1238 realstdout = xfdopen(xdup(1), "w");
81f3a188 1239
3d51e1b5
MK
1240 if (prepare_revision_walk(&rev))
1241 die("revision walk setup failed");
2bda2cf4 1242 rev.boundary = 1;
91efcf60 1243 while ((commit = get_revision(&rev)) != NULL) {
2bda2cf4 1244 if (commit->object.flags & BOUNDARY) {
2bda2cf4
DB
1245 boundary_count++;
1246 origin = (boundary_count == 1) ? commit : NULL;
1247 continue;
1248 }
1249
9c6efa36 1250 if (ignore_if_in_upstream &&
5d23e133 1251 has_commit_patch_id(commit, &ids))
9c6efa36
JS
1252 continue;
1253
91efcf60 1254 nr++;
83572c1a 1255 list = xrealloc(list, nr * sizeof(list[0]));
91efcf60
JH
1256 list[nr - 1] = commit;
1257 }
0377db77 1258 total = nr;
49604a4d
BG
1259 if (!keep_subject && auto_number && total > 1)
1260 numbered = 1;
596524b3 1261 if (numbered)
fa0f02df 1262 rev.total = total + start_number - 1;
b079c50e
TR
1263 if (in_reply_to || thread || cover_letter)
1264 rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));
1265 if (in_reply_to) {
1266 const char *msgid = clean_message_id(in_reply_to);
1d2f80fa 1267 string_list_append(rev.ref_message_ids, msgid);
b079c50e 1268 }
108dab28
SB
1269 rev.numbered_files = numbered_files;
1270 rev.patch_suffix = fmt_patch_suffix;
a5a27c79
DB
1271 if (cover_letter) {
1272 if (thread)
1273 gen_message_id(&rev, "cover");
1274 make_cover_letter(&rev, use_stdout, numbered, numbered_files,
2bda2cf4 1275 origin, nr, list, head);
a5a27c79
DB
1276 total++;
1277 start_number--;
1278 }
1279 rev.add_signoff = add_signoff;
91efcf60
JH
1280 while (0 <= --nr) {
1281 int shown;
1282 commit = list[nr];
add5c8a5 1283 rev.nr = total - nr + (start_number - 1);
d1566f78 1284 /* Make the second and subsequent mails replies to the first */
cc35de84 1285 if (thread) {
a5a27c79 1286 /* Have we already had a message ID? */
e1a37346 1287 if (rev.message_id) {
a5a27c79 1288 /*
30984ed2
TR
1289 * For deep threading: make every mail
1290 * a reply to the previous one, no
1291 * matter what other options are set.
1292 *
1293 * For shallow threading:
1294 *
2175c10d
TR
1295 * Without --cover-letter and
1296 * --in-reply-to, make every mail a
1297 * reply to the one before.
1298 *
1299 * With --in-reply-to but no
1300 * --cover-letter, make every mail a
1301 * reply to the <reply-to>.
1302 *
1303 * With --cover-letter, make every
1304 * mail but the cover letter a reply
1305 * to the cover letter. The cover
1306 * letter is a reply to the
1307 * --in-reply-to, if specified.
a5a27c79 1308 */
30984ed2
TR
1309 if (thread == THREAD_SHALLOW
1310 && rev.ref_message_ids->nr > 0
2175c10d 1311 && (!cover_letter || rev.nr > 1))
e1a37346
DB
1312 free(rev.message_id);
1313 else
1d2f80fa
JP
1314 string_list_append(rev.ref_message_ids,
1315 rev.message_id);
cc35de84 1316 }
e1a37346 1317 gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
d1566f78 1318 }
6df514af 1319
cd2ef591
SB
1320 if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit,
1321 &rev))
a5a27c79 1322 die("Failed to create output files");
91efcf60
JH
1323 shown = log_tree_commit(&rev, commit);
1324 free(commit->buffer);
1325 commit->buffer = NULL;
add5c8a5
JH
1326
1327 /* We put one extra blank line between formatted
1328 * patches and this flag is used by log-tree code
1329 * to see if it needs to emit a LF before showing
1330 * the log; when using one file per patch, we do
1331 * not want the extra blank line.
1332 */
1333 if (!use_stdout)
1334 rev.shown_one = 0;
698ce6f8
JS
1335 if (shown) {
1336 if (rev.mime_boundary)
1337 printf("\n--%s%s--\n\n\n",
1338 mime_boundary_leader,
1339 rev.mime_boundary);
1340 else
6622d9c7 1341 print_signature();
698ce6f8 1342 }
0377db77
JS
1343 if (!use_stdout)
1344 fclose(stdout);
91efcf60
JH
1345 }
1346 free(list);
ca9e0a1b
SB
1347 string_list_clear(&extra_to, 0);
1348 string_list_clear(&extra_cc, 0);
1349 string_list_clear(&extra_hdr, 0);
5d23e133
JH
1350 if (ignore_if_in_upstream)
1351 free_patch_ids(&ids);
91efcf60
JH
1352 return 0;
1353}
1354
e827633a
RS
1355static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
1356{
1357 unsigned char sha1[20];
1358 if (get_sha1(arg, sha1) == 0) {
1359 struct commit *commit = lookup_commit_reference(sha1);
1360 if (commit) {
1361 commit->object.flags |= flags;
1362 add_pending_object(revs, &commit->object, arg);
1363 return 0;
1364 }
1365 }
1366 return -1;
1367}
1368
28a53178
EFL
1369static const char * const cherry_usage[] = {
1370 "git cherry [-v] [<upstream> [<head> [<limit>]]]",
1371 NULL
1372};
1373
a3a32e7f
JN
1374static void print_commit(char sign, struct commit *commit, int verbose,
1375 int abbrev)
1376{
1377 if (!verbose) {
1378 printf("%c %s\n", sign,
1379 find_unique_abbrev(commit->object.sha1, abbrev));
1380 } else {
1381 struct strbuf buf = STRBUF_INIT;
1382 struct pretty_print_context ctx = {0};
1383 pretty_print_commit(CMIT_FMT_ONELINE, commit, &buf, &ctx);
1384 printf("%c %s %s\n", sign,
1385 find_unique_abbrev(commit->object.sha1, abbrev),
1386 buf.buf);
1387 strbuf_release(&buf);
1388 }
1389}
1390
e827633a
RS
1391int cmd_cherry(int argc, const char **argv, const char *prefix)
1392{
1393 struct rev_info revs;
5d23e133 1394 struct patch_ids ids;
e827633a
RS
1395 struct commit *commit;
1396 struct commit_list *list = NULL;
f2968022 1397 struct branch *current_branch;
e827633a
RS
1398 const char *upstream;
1399 const char *head = "HEAD";
1400 const char *limit = NULL;
28a53178 1401 int verbose = 0, abbrev = 0;
e827633a 1402
28a53178
EFL
1403 struct option options[] = {
1404 OPT__ABBREV(&abbrev),
fd03881a 1405 OPT__VERBOSE(&verbose, "be verbose"),
28a53178
EFL
1406 OPT_END()
1407 };
e827633a 1408
28a53178 1409 argc = parse_options(argc, argv, prefix, options, cherry_usage, 0);
fef34270 1410
e827633a 1411 switch (argc) {
e827633a 1412 case 3:
28a53178 1413 limit = argv[2];
e827633a
RS
1414 /* FALLTHROUGH */
1415 case 2:
28a53178
EFL
1416 head = argv[1];
1417 /* FALLTHROUGH */
1418 case 1:
1419 upstream = argv[0];
e827633a
RS
1420 break;
1421 default:
f2968022
MH
1422 current_branch = branch_get(NULL);
1423 if (!current_branch || !current_branch->merge
1424 || !current_branch->merge[0]
1425 || !current_branch->merge[0]->dst) {
1426 fprintf(stderr, "Could not find a tracked"
1427 " remote branch, please"
1428 " specify <upstream> manually.\n");
28a53178 1429 usage_with_options(cherry_usage, options);
f2968022
MH
1430 }
1431
1432 upstream = current_branch->merge[0]->dst;
e827633a
RS
1433 }
1434
1435 init_revisions(&revs, prefix);
1436 revs.diff = 1;
1437 revs.combine_merges = 0;
1438 revs.ignore_merges = 1;
8f67f8ae 1439 DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
e827633a
RS
1440
1441 if (add_pending_commit(head, &revs, 0))
1442 die("Unknown commit %s", head);
1443 if (add_pending_commit(upstream, &revs, UNINTERESTING))
1444 die("Unknown commit %s", upstream);
1445
1446 /* Don't say anything if head and upstream are the same. */
1447 if (revs.pending.nr == 2) {
1448 struct object_array_entry *o = revs.pending.objects;
1449 if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
1450 return 0;
1451 }
1452
5d23e133 1453 get_patch_ids(&revs, &ids, prefix);
e827633a
RS
1454
1455 if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
1456 die("Unknown commit %s", limit);
1457
1458 /* reverse the list of commits */
3d51e1b5
MK
1459 if (prepare_revision_walk(&revs))
1460 die("revision walk setup failed");
e827633a
RS
1461 while ((commit = get_revision(&revs)) != NULL) {
1462 /* ignore merges */
1463 if (commit->parents && commit->parents->next)
1464 continue;
1465
1466 commit_list_insert(commit, &list);
1467 }
1468
1469 while (list) {
e827633a
RS
1470 char sign = '+';
1471
1472 commit = list->item;
5d23e133 1473 if (has_commit_patch_id(commit, &ids))
e827633a 1474 sign = '-';
a3a32e7f 1475 print_commit(sign, commit, verbose, abbrev);
e827633a
RS
1476 list = list->next;
1477 }
1478
5d23e133 1479 free_patch_ids(&ids);
e827633a
RS
1480 return 0;
1481}