log.c 50.9 KB
Newer Older
1 2 3 4 5 6 7
/*
 * Builtin "git log" and related commands (show, whatchanged)
 *
 * (C) Copyright 2006 Linus Torvalds
 *		 2006 Junio Hamano
 */
#include "cache.h"
8
#include "refs.h"
9
#include "color.h"
10 11 12 13
#include "commit.h"
#include "diff.h"
#include "revision.h"
#include "log-tree.h"
14
#include "builtin.h"
15
#include "tag.h"
L
Linus Torvalds 已提交
16
#include "reflog-walk.h"
17
#include "patch-ids.h"
18
#include "run-command.h"
19
#include "shortlog.h"
20
#include "remote.h"
21
#include "string-list.h"
22
#include "parse-options.h"
23
#include "line-log.h"
24
#include "branch.h"
25
#include "streaming.h"
26
#include "version.h"
A
Antoine Pelisse 已提交
27
#include "mailmap.h"
28
#include "gpg-interface.h"
29

H
Heikki Orsila 已提交
30 31 32
/* Set a default date-time format for git log ("log.date" config variable) */
static const char *default_date_mode = NULL;

33
static int default_abbrev_commit;
34
static int default_show_root = 1;
35
static int default_follow;
36
static int default_show_signature;
J
Junio C Hamano 已提交
37
static int decoration_style;
38
static int decoration_given;
39
static int use_mailmap_config;
40
static const char *fmt_patch_subject_prefix = "PATCH";
41
static const char *fmt_pretty;
42

43
static const char * const builtin_log_usage[] = {
44
	N_("git log [<options>] [<revision-range>] [[--] <path>...]"),
J
Junio C Hamano 已提交
45
	N_("git show [<options>] <object>..."),
46 47
	NULL
};
48

49 50 51 52 53 54
struct line_opt_callback_data {
	struct rev_info *rev;
	const char *prefix;
	struct string_list args;
};

J
Junio C Hamano 已提交
55 56 57 58 59 60 61 62 63 64 65 66 67 68
static int parse_decoration_style(const char *var, const char *value)
{
	switch (git_config_maybe_bool(var, value)) {
	case 1:
		return DECORATE_SHORT_REFS;
	case 0:
		return 0;
	default:
		break;
	}
	if (!strcmp(value, "full"))
		return DECORATE_FULL_REFS;
	else if (!strcmp(value, "short"))
		return DECORATE_SHORT_REFS;
69 70
	else if (!strcmp(value, "auto"))
		return (isatty(1) || pager_in_use()) ? DECORATE_SHORT_REFS : 0;
J
Junio C Hamano 已提交
71 72 73
	return -1;
}

74 75 76 77 78 79 80 81 82 83
static int decorate_callback(const struct option *opt, const char *arg, int unset)
{
	if (unset)
		decoration_style = 0;
	else if (arg)
		decoration_style = parse_decoration_style("command line", arg);
	else
		decoration_style = DECORATE_SHORT_REFS;

	if (decoration_style < 0)
84
		die(_("invalid --decorate option: %s"), arg);
85 86 87 88 89 90

	decoration_given = 1;

	return 0;
}

91 92 93 94 95 96 97 98 99 100 101 102 103
static int log_line_range_callback(const struct option *option, const char *arg, int unset)
{
	struct line_opt_callback_data *data = option->value;

	if (!arg)
		return -1;

	data->rev->line_level_traverse = 1;
	string_list_append(&data->args, arg);

	return 0;
}

104 105 106
static void init_log_defaults(void)
{
	init_grep_defaults();
107
	init_diff_ui_defaults();
108 109
}

110
static void cmd_log_init_defaults(struct rev_info *rev)
111
{
112
	if (fmt_pretty)
113
		get_commit_format(fmt_pretty, rev);
114 115
	if (default_follow)
		DIFF_OPT_SET(&rev->diffopt, DEFAULT_FOLLOW_RENAMES);
116
	rev->verbose_header = 1;
117
	DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
118
	rev->diffopt.stat_width = -1; /* use full terminal width */
119
	rev->diffopt.stat_graph_width = -1; /* respect statGraphWidth config */
120
	rev->abbrev_commit = default_abbrev_commit;
121
	rev->show_root_diff = default_show_root;
122
	rev->subject_prefix = fmt_patch_subject_prefix;
123
	rev->show_signature = default_show_signature;
J
Jeff King 已提交
124
	DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV);
H
Heikki Orsila 已提交
125 126

	if (default_date_mode)
127
		parse_date_format(default_date_mode, &rev->date_mode);
128
	rev->diffopt.touched_flags = 0;
129
}
H
Heikki Orsila 已提交
130

131 132 133 134
static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
			 struct rev_info *rev, struct setup_revision_opt *opt)
{
	struct userformat_want w;
A
Antoine Pelisse 已提交
135
	int quiet = 0, source = 0, mailmap = 0;
136
	static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
137 138

	const struct option builtin_log_options[] = {
139
		OPT__QUIET(&quiet, N_("suppress diff output")),
F
Felipe Contreras 已提交
140 141
		OPT_BOOL(0, "source", &source, N_("show source")),
		OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
142
		{ OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
143
		  PARSE_OPT_OPTARG, decorate_callback},
144
		OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
145
			     N_("Process line range n,m in file, counting from 1"),
146
			     log_line_range_callback),
147 148 149
		OPT_END()
	};

150 151 152
	line_cb.rev = rev;
	line_cb.prefix = prefix;

153
	mailmap = use_mailmap_config;
154 155 156 157
	argc = parse_options(argc, argv, prefix,
			     builtin_log_options, builtin_log_usage,
			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
			     PARSE_OPT_KEEP_DASHDASH);
J
Junio C Hamano 已提交
158

159 160
	if (quiet)
		rev->diffopt.output_format |= DIFF_FORMAT_NO_OUTPUT;
J
Jeff King 已提交
161
	argc = setup_revisions(argc, argv, rev, opt);
H
Heikki Orsila 已提交
162

163 164
	/* Any arguments at this point are not recognized */
	if (argc > 1)
165
		die(_("unrecognized argument: %s"), argv[1]);
166

167 168 169 170
	memset(&w, 0, sizeof(w));
	userformat_find_requirements(NULL, &w);

	if (!rev->show_notes_given && (!rev->pretty_given || w.notes))
171
		rev->show_notes = 1;
172 173
	if (rev->show_notes)
		init_display_notes(&rev->notes_opt);
174

175 176
	if (rev->diffopt.pickaxe || rev->diffopt.filter ||
	    DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES))
177
		rev->always_show_header = 0;
178 179 180

	if (source)
		rev->show_source = 1;
181

A
Antoine Pelisse 已提交
182 183 184 185 186
	if (mailmap) {
		rev->mailmap = xcalloc(1, sizeof(struct string_list));
		read_mailmap(rev->mailmap, NULL);
	}

187 188 189 190 191 192 193 194 195 196
	if (rev->pretty_given && rev->commit_format == CMIT_FMT_RAW) {
		/*
		 * "log --pretty=raw" is special; ignore UI oriented
		 * configuration variables such as decoration.
		 */
		if (!decoration_given)
			decoration_style = 0;
		if (!rev->abbrev_commit_given)
			rev->abbrev_commit = 0;
	}
197

198 199 200 201
	if (decoration_style) {
		rev->show_decorations = 1;
		load_ref_decorations(decoration_style);
	}
202 203 204 205

	if (rev->line_level_traverse)
		line_log_init(rev, line_cb.prefix, &line_cb.args);

206
	setup_pager();
207 208
}

209 210 211 212 213 214 215
static void cmd_log_init(int argc, const char **argv, const char *prefix,
			 struct rev_info *rev, struct setup_revision_opt *opt)
{
	cmd_log_init_defaults(rev);
	cmd_log_init_finish(argc, argv, prefix, rev, opt);
}

L
Linus Torvalds 已提交
216 217 218 219 220 221 222 223 224 225 226 227
/*
 * This gives a rough estimate for how many commits we
 * will print out in the list.
 */
static int estimate_commit_count(struct rev_info *rev, struct commit_list *list)
{
	int n = 0;

	while (list) {
		struct commit *commit = list->item;
		unsigned int flags = commit->object.flags;
		list = list->next;
228
		if (!(flags & (TREESAME | UNINTERESTING)))
L
Linus Torvalds 已提交
229
			n++;
L
Linus Torvalds 已提交
230 231 232 233 234 235 236 237 238 239 240
	}
	return n;
}

static void show_early_header(struct rev_info *rev, const char *stage, int nr)
{
	if (rev->shown_one) {
		rev->shown_one = 0;
		if (rev->commit_format != CMIT_FMT_ONELINE)
			putchar(rev->diffopt.line_termination);
	}
241
	fprintf(rev->diffopt.file, _("Final output: %d %s\n"), nr, stage);
L
Linus Torvalds 已提交
242 243
}

244
static struct itimerval early_output_timer;
L
Linus Torvalds 已提交
245

246 247
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
248
	int i = revs->early_output, close_file = revs->diffopt.close_file;
L
Linus Torvalds 已提交
249
	int show_header = 1;
250

251
	revs->diffopt.close_file = 0;
J
Junio C Hamano 已提交
252
	sort_in_topological_order(&list, revs->sort_order);
253 254
	while (list && i) {
		struct commit *commit = list->item;
L
Linus Torvalds 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267
		switch (simplify_commit(revs, commit)) {
		case commit_show:
			if (show_header) {
				int n = estimate_commit_count(revs, list);
				show_early_header(revs, "incomplete", n);
				show_header = 0;
			}
			log_tree_commit(revs, commit);
			i--;
			break;
		case commit_ignore:
			break;
		case commit_error:
268 269
			if (close_file)
				fclose(revs->diffopt.file);
L
Linus Torvalds 已提交
270 271
			return;
		}
272 273
		list = list->next;
	}
L
Linus Torvalds 已提交
274 275

	/* Did we already get enough commits for the early output? */
276 277 278
	if (!i) {
		if (close_file)
			fclose(revs->diffopt.file);
L
Linus Torvalds 已提交
279
		return;
280
	}
L
Linus Torvalds 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293 294

	/*
	 * ..if no, then repeat it twice a second until we
	 * do.
	 *
	 * NOTE! We don't use "it_interval", because if the
	 * reader isn't listening, we want our output to be
	 * throttled by the writing, and not have the timer
	 * trigger every second even if we're blocked on a
	 * reader!
	 */
	early_output_timer.it_value.tv_sec = 0;
	early_output_timer.it_value.tv_usec = 500000;
	setitimer(ITIMER_REAL, &early_output_timer, NULL);
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
}

static void early_output(int signal)
{
	show_early_output = log_show_early;
}

static void setup_early_output(struct rev_info *rev)
{
	struct sigaction sa;

	/*
	 * Set up the signal handler, minimally intrusively:
	 * we only set a single volatile integer word (not
	 * using sigatomic_t - trying to avoid unnecessary
	 * system dependencies and headers), and using
	 * SA_RESTART.
	 */
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = early_output;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	sigaction(SIGALRM, &sa, NULL);

	/*
	 * If we can get the whole output in less than a
	 * tenth of a second, don't even bother doing the
	 * early-output thing..
	 *
	 * This is a one-time-only trigger.
	 */
L
Linus Torvalds 已提交
326 327 328
	early_output_timer.it_value.tv_sec = 0;
	early_output_timer.it_value.tv_usec = 100000;
	setitimer(ITIMER_REAL, &early_output_timer, NULL);
329 330 331 332
}

static void finish_early_output(struct rev_info *rev)
{
L
Linus Torvalds 已提交
333
	int n = estimate_commit_count(rev, rev->commits);
334
	signal(SIGALRM, SIG_IGN);
L
Linus Torvalds 已提交
335
	show_early_header(rev, "done", n);
336 337
}

338 339 340
static int cmd_log_walk(struct rev_info *rev)
{
	struct commit *commit;
341
	int saved_nrl = 0;
342
	int saved_dcctc = 0, close_file = rev->diffopt.close_file;
343

344 345 346
	if (rev->early_output)
		setup_early_output(rev);

347
	if (prepare_revision_walk(rev))
348
		die(_("revision walk setup failed"));
349 350 351 352

	if (rev->early_output)
		finish_early_output(rev);

353
	/*
354 355 356
	 * For --check and --exit-code, the exit code is based on CHECK_FAILED
	 * and HAS_CHANGES being accumulated in rev->diffopt, so be careful to
	 * retain that state information if replacing rev->diffopt in this loop
357
	 */
358
	rev->diffopt.close_file = 0;
359
	while ((commit = get_revision(rev)) != NULL) {
J
Junio C Hamano 已提交
360
		if (!log_tree_commit(rev, commit) && rev->max_count >= 0)
361 362 363 364 365
			/*
			 * We decremented max_count in get_revision,
			 * but we didn't actually show the commit.
			 */
			rev->max_count++;
366 367
		if (!rev->reflog_info) {
			/* we allow cycles in reflog ancestry */
368
			free_commit_buffer(commit);
369
		}
L
Linus Torvalds 已提交
370 371
		free_commit_list(commit->parents);
		commit->parents = NULL;
372 373 374 375
		if (saved_nrl < rev->diffopt.needed_rename_limit)
			saved_nrl = rev->diffopt.needed_rename_limit;
		if (rev->diffopt.degraded_cc_to_c)
			saved_dcctc = 1;
376
	}
377 378
	rev->diffopt.degraded_cc_to_c = saved_dcctc;
	rev->diffopt.needed_rename_limit = saved_nrl;
379 380
	if (close_file)
		fclose(rev->diffopt.file);
381

382 383 384 385
	if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
	    DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
		return 02;
	}
386
	return diff_result_code(&rev->diffopt, 0);
387 388
}

389
static int git_log_config(const char *var, const char *value, void *cb)
390
{
391 392
	const char *slot_name;

393 394
	if (!strcmp(var, "format.pretty"))
		return git_config_string(&fmt_pretty, var, value);
395 396
	if (!strcmp(var, "format.subjectprefix"))
		return git_config_string(&fmt_patch_subject_prefix, var, value);
397 398 399 400
	if (!strcmp(var, "log.abbrevcommit")) {
		default_abbrev_commit = git_config_bool(var, value);
		return 0;
	}
H
Heikki Orsila 已提交
401 402
	if (!strcmp(var, "log.date"))
		return git_config_string(&default_date_mode, var, value);
403
	if (!strcmp(var, "log.decorate")) {
J
Junio C Hamano 已提交
404 405 406
		decoration_style = parse_decoration_style(var, value);
		if (decoration_style < 0)
			decoration_style = 0; /* maybe warn? */
407 408
		return 0;
	}
409 410 411 412
	if (!strcmp(var, "log.showroot")) {
		default_show_root = git_config_bool(var, value);
		return 0;
	}
413 414 415 416
	if (!strcmp(var, "log.follow")) {
		default_follow = git_config_bool(var, value);
		return 0;
	}
417
	if (skip_prefix(var, "color.decorate.", &slot_name))
418
		return parse_decorate_color_config(var, slot_name, value);
419 420 421 422
	if (!strcmp(var, "log.mailmap")) {
		use_mailmap_config = git_config_bool(var, value);
		return 0;
	}
423 424 425 426
	if (!strcmp(var, "log.showsignature")) {
		default_show_signature = git_config_bool(var, value);
		return 0;
	}
427

J
Junio C Hamano 已提交
428 429
	if (grep_config(var, value, cb) < 0)
		return -1;
430
	if (git_gpg_config(var, value, cb) < 0)
J
Junio C Hamano 已提交
431
		return -1;
432
	return git_diff_ui_config(var, value, cb);
433 434
}

435
int cmd_whatchanged(int argc, const char **argv, const char *prefix)
436 437
{
	struct rev_info rev;
438
	struct setup_revision_opt opt;
439

440
	init_log_defaults();
441
	git_config(git_log_config, NULL);
442

443
	init_revisions(&rev, prefix);
444
	rev.diff = 1;
L
Linus Torvalds 已提交
445
	rev.simplify_history = 0;
446 447
	memset(&opt, 0, sizeof(opt));
	opt.def = "HEAD";
448
	opt.revarg_opt = REVARG_COMMITTISH;
449
	cmd_log_init(argc, argv, prefix, &rev, &opt);
450 451 452
	if (!rev.diffopt.output_format)
		rev.diffopt.output_format = DIFF_FORMAT_RAW;
	return cmd_log_walk(&rev);
453 454
}

455 456
static void show_tagger(char *buf, int len, struct rev_info *rev)
{
457
	struct strbuf out = STRBUF_INIT;
458
	struct pretty_print_context pp = {0};
459

460 461 462
	pp.fmt = rev->commit_format;
	pp.date_mode = rev->date_mode;
	pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
463
	fprintf(rev->diffopt.file, "%s", out.buf);
464
	strbuf_release(&out);
465 466
}

467
static int show_blob_object(const struct object_id *oid, struct rev_info *rev, const char *obj_name)
468
{
469
	struct object_id oidc;
470 471 472 473
	struct object_context obj_context;
	char *buf;
	unsigned long size;

474
	fflush(rev->diffopt.file);
475 476
	if (!DIFF_OPT_TOUCHED(&rev->diffopt, ALLOW_TEXTCONV) ||
	    !DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
477
		return stream_blob_to_fd(1, oid, NULL, 0);
478

479
	if (get_sha1_with_context(obj_name, 0, oidc.hash, &obj_context))
480
		die(_("Not a valid object name %s"), obj_name);
481
	if (!obj_context.path[0] ||
482
	    !textconv_object(obj_context.path, obj_context.mode, &oidc, 1, &buf, &size))
483
		return stream_blob_to_fd(1, oid, NULL, 0);
484 485

	if (!buf)
486
		die(_("git show %s: bad file"), obj_name);
487 488 489

	write_or_die(1, buf, size);
	return 0;
490 491
}

492
static int show_tag_object(const struct object_id *oid, struct rev_info *rev)
493 494
{
	unsigned long size;
495
	enum object_type type;
496
	char *buf = read_sha1_file(oid->hash, &type, &size);
497 498 499
	int offset = 0;

	if (!buf)
500
		return error(_("Could not read object %s"), oid_to_hex(oid));
501

502 503 504 505 506
	assert(type == OBJ_TAG);
	while (offset < size && buf[offset] != '\n') {
		int new_offset = offset + 1;
		while (new_offset < size && buf[new_offset++] != '\n')
			; /* do nothing */
507
		if (starts_with(buf + offset, "tagger "))
508 509 510 511
			show_tagger(buf + offset + 7,
				    new_offset - offset - 7, rev);
		offset = new_offset;
	}
512 513

	if (offset < size)
514
		fwrite(buf + offset, size - offset, 1, rev->diffopt.file);
515 516 517 518 519
	free(buf);
	return 0;
}

static int show_tree_object(const unsigned char *sha1,
520
		struct strbuf *base,
521
		const char *pathname, unsigned mode, int stage, void *context)
522
{
523 524
	FILE *file = context;
	fprintf(file, "%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
525 526 527
	return 0;
}

J
Junio C Hamano 已提交
528 529
static void show_setup_revisions_tweak(struct rev_info *rev,
				       struct setup_revision_opt *opt)
J
Junio C Hamano 已提交
530
{
531 532 533 534
	if (rev->ignore_merges) {
		/* There was no "-m" on the command line */
		rev->ignore_merges = 0;
		if (!rev->first_parent_only && !rev->combine_merges) {
J
Justin Lebar 已提交
535
			/* No "--first-parent", "-c", or "--cc" */
536 537 538 539
			rev->combine_merges = 1;
			rev->dense_combined_merges = 1;
		}
	}
J
Junio C Hamano 已提交
540 541 542 543
	if (!rev->diffopt.output_format)
		rev->diffopt.output_format = DIFF_FORMAT_PATCH;
}

544
int cmd_show(int argc, const char **argv, const char *prefix)
545 546
{
	struct rev_info rev;
547
	struct object_array_entry *objects;
548
	struct setup_revision_opt opt;
549
	struct pathspec match_all;
550
	int i, count, ret = 0;
551

552
	init_log_defaults();
553
	git_config(git_log_config, NULL);
554

555
	memset(&match_all, 0, sizeof(match_all));
556
	init_revisions(&rev, prefix);
557 558
	rev.diff = 1;
	rev.always_show_header = 1;
559
	rev.no_walk = REVISION_WALK_NO_WALK_SORTED;
560 561
	rev.diffopt.stat_width = -1; 	/* Scale to real terminal size */

562 563
	memset(&opt, 0, sizeof(opt));
	opt.def = "HEAD";
J
Junio C Hamano 已提交
564
	opt.tweak = show_setup_revisions_tweak;
565
	cmd_log_init(argc, argv, prefix, &rev, &opt);
566

567 568 569
	if (!rev.no_walk)
		return cmd_log_walk(&rev);

570 571 572 573 574 575 576
	count = rev.pending.nr;
	objects = rev.pending.objects;
	for (i = 0; i < count && !ret; i++) {
		struct object *o = objects[i].item;
		const char *name = objects[i].name;
		switch (o->type) {
		case OBJ_BLOB:
577
			ret = show_blob_object(&o->oid, &rev, name);
578 579 580 581
			break;
		case OBJ_TAG: {
			struct tag *t = (struct tag *)o;

582 583
			if (rev.shown_one)
				putchar('\n');
584
			fprintf(rev.diffopt.file, "%stag %s%s\n",
585
					diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
586
					t->tag,
587
					diff_get_color_opt(&rev.diffopt, DIFF_RESET));
588
			ret = show_tag_object(&o->oid, &rev);
589
			rev.shown_one = 1;
590 591
			if (ret)
				break;
B
brian m. carlson 已提交
592
			o = parse_object(t->tagged->oid.hash);
593
			if (!o)
594
				ret = error(_("Could not read object %s"),
595
					    oid_to_hex(&t->tagged->oid));
596
			objects[i].item = o;
597 598 599 600
			i--;
			break;
		}
		case OBJ_TREE:
601 602
			if (rev.shown_one)
				putchar('\n');
603
			fprintf(rev.diffopt.file, "%stree %s%s\n\n",
604
					diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
605
					name,
606
					diff_get_color_opt(&rev.diffopt, DIFF_RESET));
607
			read_tree_recursive((struct tree *)o, "", 0, 0, &match_all,
608
					show_tree_object, rev.diffopt.file);
609
			rev.shown_one = 1;
610 611 612 613 614 615 616 617
			break;
		case OBJ_COMMIT:
			rev.pending.nr = rev.pending.alloc = 0;
			rev.pending.objects = NULL;
			add_object_array(o, name, &rev.pending);
			ret = cmd_log_walk(&rev);
			break;
		default:
618
			ret = error(_("Unknown type: %d"), o->type);
619 620 621 622
		}
	}
	free(objects);
	return ret;
623 624
}

L
Linus Torvalds 已提交
625 626 627 628 629 630
/*
 * This is equivalent to "git log -g --abbrev-commit --pretty=oneline"
 */
int cmd_log_reflog(int argc, const char **argv, const char *prefix)
{
	struct rev_info rev;
631
	struct setup_revision_opt opt;
L
Linus Torvalds 已提交
632

633
	init_log_defaults();
634
	git_config(git_log_config, NULL);
635

L
Linus Torvalds 已提交
636 637 638
	init_revisions(&rev, prefix);
	init_reflog_walk(&rev.reflog_info);
	rev.verbose_header = 1;
639 640
	memset(&opt, 0, sizeof(opt));
	opt.def = "HEAD";
641
	cmd_log_init_defaults(&rev);
642
	rev.abbrev_commit = 1;
L
Linus Torvalds 已提交
643
	rev.commit_format = CMIT_FMT_ONELINE;
644
	rev.use_terminator = 1;
L
Linus Torvalds 已提交
645
	rev.always_show_header = 1;
646
	cmd_log_init_finish(argc, argv, prefix, &rev, &opt);
L
Linus Torvalds 已提交
647 648 649 650

	return cmd_log_walk(&rev);
}

J
Junio C Hamano 已提交
651 652
static void log_setup_revisions_tweak(struct rev_info *rev,
				      struct setup_revision_opt *opt)
653 654 655 656
{
	if (DIFF_OPT_TST(&rev->diffopt, DEFAULT_FOLLOW_RENAMES) &&
	    rev->prune_data.nr == 1)
		DIFF_OPT_SET(&rev->diffopt, FOLLOW_RENAMES);
657 658 659 660

	/* Turn --cc/-c into -p --cc/-c when -p was not given */
	if (!rev->diffopt.output_format && rev->combine_merges)
		rev->diffopt.output_format = DIFF_FORMAT_PATCH;
661 662 663 664

	/* Turn -m on when --cc/-c was given */
	if (rev->combine_merges)
		rev->ignore_merges = 0;
665 666
}

667
int cmd_log(int argc, const char **argv, const char *prefix)
668 669
{
	struct rev_info rev;
670
	struct setup_revision_opt opt;
671

672
	init_log_defaults();
673
	git_config(git_log_config, NULL);
674

675
	init_revisions(&rev, prefix);
676
	rev.always_show_header = 1;
677 678
	memset(&opt, 0, sizeof(opt));
	opt.def = "HEAD";
679
	opt.revarg_opt = REVARG_COMMITTISH;
J
Junio C Hamano 已提交
680
	opt.tweak = log_setup_revisions_tweak;
681
	cmd_log_init(argc, argv, prefix, &rev, &opt);
682
	return cmd_log_walk(&rev);
683
}
684

685
/* format-patch */
686

687
static const char *fmt_patch_suffix = ".patch";
688
static int numbered = 0;
689
static int auto_number = 1;
690

691 692
static char *default_attach = NULL;

693 694 695
static struct string_list extra_hdr = STRING_LIST_INIT_NODUP;
static struct string_list extra_to = STRING_LIST_INIT_NODUP;
static struct string_list extra_cc = STRING_LIST_INIT_NODUP;
D
Daniel Barkalow 已提交
696 697 698

static void add_header(const char *value)
{
699
	struct string_list_item *item;
D
Daniel Barkalow 已提交
700
	int len = strlen(value);
701
	while (len && value[len - 1] == '\n')
D
Daniel Barkalow 已提交
702
		len--;
703

D
Daniel Barkalow 已提交
704
	if (!strncasecmp(value, "to: ", 4)) {
705
		item = string_list_append(&extra_to, value + 4);
706 707
		len -= 4;
	} else if (!strncasecmp(value, "cc: ", 4)) {
708
		item = string_list_append(&extra_cc, value + 4);
709 710
		len -= 4;
	} else {
711
		item = string_list_append(&extra_hdr, value);
D
Daniel Barkalow 已提交
712
	}
713 714

	item->string[len] = '\0';
D
Daniel Barkalow 已提交
715 716
}

717 718
#define THREAD_SHALLOW 1
#define THREAD_DEEP 2
719 720
static int thread;
static int do_signoff;
721
static int base_auto;
722
static char *from;
723
static const char *signature = git_version_string;
724
static const char *signature_file;
725
static int config_cover_letter;
726
static const char *config_output_directory;
727 728 729 730 731 732 733

enum {
	COVER_UNSET,
	COVER_OFF,
	COVER_ON,
	COVER_AUTO
};
734

735
static int git_format_config(const char *var, const char *value, void *cb)
736 737
{
	if (!strcmp(var, "format.headers")) {
738
		if (!value)
739
			die(_("format.headers without value"));
D
Daniel Barkalow 已提交
740
		add_header(value);
741 742
		return 0;
	}
743 744
	if (!strcmp(var, "format.suffix"))
		return git_config_string(&fmt_patch_suffix, var, value);
745 746 747
	if (!strcmp(var, "format.to")) {
		if (!value)
			return config_error_nonbool(var);
748
		string_list_append(&extra_to, value);
749 750
		return 0;
	}
751 752 753
	if (!strcmp(var, "format.cc")) {
		if (!value)
			return config_error_nonbool(var);
754
		string_list_append(&extra_cc, value);
755 756
		return 0;
	}
P
Pang Yan Han 已提交
757
	if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff") ||
758
	    !strcmp(var, "color.ui") || !strcmp(var, "diff.submodule")) {
759 760
		return 0;
	}
761
	if (!strcmp(var, "format.numbered")) {
762
		if (value && !strcasecmp(value, "auto")) {
763 764 765 766
			auto_number = 1;
			return 0;
		}
		numbered = git_config_bool(var, value);
767
		auto_number = auto_number && numbered;
768 769
		return 0;
	}
770 771 772 773 774 775 776
	if (!strcmp(var, "format.attach")) {
		if (value && *value)
			default_attach = xstrdup(value);
		else
			default_attach = xstrdup(git_version_string);
		return 0;
	}
777 778 779 780 781 782 783 784 785 786 787 788
	if (!strcmp(var, "format.thread")) {
		if (value && !strcasecmp(value, "deep")) {
			thread = THREAD_DEEP;
			return 0;
		}
		if (value && !strcasecmp(value, "shallow")) {
			thread = THREAD_SHALLOW;
			return 0;
		}
		thread = git_config_bool(var, value) && THREAD_SHALLOW;
		return 0;
	}
789 790 791 792
	if (!strcmp(var, "format.signoff")) {
		do_signoff = git_config_bool(var, value);
		return 0;
	}
793 794
	if (!strcmp(var, "format.signature"))
		return git_config_string(&signature, var, value);
795 796
	if (!strcmp(var, "format.signaturefile"))
		return git_config_pathname(&signature_file, var, value);
797 798 799 800 801 802 803 804
	if (!strcmp(var, "format.coverletter")) {
		if (value && !strcasecmp(value, "auto")) {
			config_cover_letter = COVER_AUTO;
			return 0;
		}
		config_cover_letter = git_config_bool(var, value) ? COVER_ON : COVER_OFF;
		return 0;
	}
805 806
	if (!strcmp(var, "format.outputdirectory"))
		return git_config_string(&config_output_directory, var, value);
807 808 809 810
	if (!strcmp(var, "format.useautobase")) {
		base_auto = git_config_bool(var, value);
		return 0;
	}
811 812 813 814 815 816 817 818 819 820 821
	if (!strcmp(var, "format.from")) {
		int b = git_config_maybe_bool(var, value);
		free(from);
		if (b < 0)
			from = xstrdup(value);
		else if (b)
			from = xstrdup(git_committer_info(IDENT_NO_DATE));
		else
			from = NULL;
		return 0;
	}
822

823
	return git_log_config(var, value, cb);
824 825
}

826
static const char *output_directory = NULL;
827
static int outdir_offset;
828

829
static int open_next_file(struct commit *commit, const char *subject,
830
			 struct rev_info *rev, int quiet)
831
{
832
	struct strbuf filename = STRBUF_INIT;
833
	int suffix_len = strlen(rev->patch_suffix) + 1;
834

835
	if (output_directory) {
836 837 838
		strbuf_addstr(&filename, output_directory);
		if (filename.len >=
		    PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len)
839
			return error(_("name of output directory is too long"));
840
		strbuf_complete(&filename, '/');
841
	}
842

843 844
	if (rev->numbered_files)
		strbuf_addf(&filename, "%d", rev->nr);
845 846
	else if (commit)
		fmt_output_commit(&filename, commit, rev);
847
	else
848
		fmt_output_subject(&filename, subject, rev);
849

850
	if (!quiet)
851
		printf("%s\n", filename.buf + outdir_offset);
N
Nate Case 已提交
852

853
	if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL)
854
		return error(_("Cannot open patch file %s"), filename.buf);
855

856
	strbuf_release(&filename);
857
	return 0;
858 859
}

860
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
861 862
{
	struct rev_info check_rev;
863
	struct commit *commit, *c1, *c2;
864 865 866 867
	struct object *o1, *o2;
	unsigned flags1, flags2;

	if (rev->pending.nr != 2)
868
		die(_("Need exactly one range."));
869 870 871

	o1 = rev->pending.objects[0].item;
	o2 = rev->pending.objects[1].item;
872
	flags1 = o1->flags;
873
	flags2 = o2->flags;
B
brian m. carlson 已提交
874 875
	c1 = lookup_commit_reference(o1->oid.hash);
	c2 = lookup_commit_reference(o2->oid.hash);
876 877

	if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
878
		die(_("Not a range."));
879

880
	init_patch_ids(ids);
881 882

	/* given a range a..b get all patch ids for b..a */
883
	init_revisions(&check_rev, rev->prefix);
884
	check_rev.max_parents = 1;
885 886 887 888
	o1->flags ^= UNINTERESTING;
	o2->flags ^= UNINTERESTING;
	add_pending_object(&check_rev, o1, "o1");
	add_pending_object(&check_rev, o2, "o2");
889
	if (prepare_revision_walk(&check_rev))
890
		die(_("revision walk setup failed"));
891 892

	while ((commit = get_revision(&check_rev)) != NULL) {
893
		add_commit_patch_id(commit, ids);
894 895 896
	}

	/* reset for next revision walk */
897 898
	clear_commit_marks(c1, SEEN | UNINTERESTING | SHOWN | ADDED);
	clear_commit_marks(c2, SEEN | UNINTERESTING | SHOWN | ADDED);
899 900 901 902
	o1->flags = flags1;
	o2->flags = flags2;
}

903
static void gen_message_id(struct rev_info *info, char *base)
904
{
905
	struct strbuf buf = STRBUF_INIT;
906
	strbuf_addf(&buf, "%s.%lu.git.%s", base,
907
		    (unsigned long) time(NULL),
908
		    git_committer_info(IDENT_NO_NAME|IDENT_NO_DATE|IDENT_STRICT));
909
	info->message_id = strbuf_detach(&buf, NULL);
910 911
}

912
static void print_signature(FILE *file)
913
{
914 915 916
	if (!signature || !*signature)
		return;

917
	fprintf(file, "-- \n%s", signature);
918
	if (signature[strlen(signature)-1] != '\n')
919 920
		putc('\n', file);
	putc('\n', file);
921 922
}

923 924 925 926 927 928 929 930
static void add_branch_description(struct strbuf *buf, const char *branch_name)
{
	struct strbuf desc = STRBUF_INIT;
	if (!branch_name || !*branch_name)
		return;
	read_branch_desc(&desc, branch_name);
	if (desc.len) {
		strbuf_addch(buf, '\n');
931
		strbuf_addbuf(buf, &desc);
932 933
		strbuf_addch(buf, '\n');
	}
934
	strbuf_release(&desc);
935 936
}

937 938 939
static char *find_branch_name(struct rev_info *rev)
{
	int i, positive = -1;
940 941
	struct object_id branch_oid;
	const struct object_id *tip_oid;
942
	const char *ref, *v;
943 944 945 946 947 948 949 950 951 952 953 954 955
	char *full_ref, *branch = NULL;

	for (i = 0; i < rev->cmdline.nr; i++) {
		if (rev->cmdline.rev[i].flags & UNINTERESTING)
			continue;
		if (positive < 0)
			positive = i;
		else
			return NULL;
	}
	if (positive < 0)
		return NULL;
	ref = rev->cmdline.rev[positive].name;
956 957
	tip_oid = &rev->cmdline.rev[positive].item->oid;
	if (dwim_ref(ref, strlen(ref), branch_oid.hash, &full_ref) &&
958
	    skip_prefix(full_ref, "refs/heads/", &v) &&
959
	    !oidcmp(tip_oid, &branch_oid))
960
		branch = xstrdup(v);
961 962 963 964
	free(full_ref);
	return branch;
}

965 966
static void make_cover_letter(struct rev_info *rev, int use_stdout,
			      struct commit *origin,
967
			      int nr, struct commit **list,
968
			      const char *branch_name,
969
			      int quiet)
970 971 972 973
{
	const char *committer;
	const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n";
	const char *msg;
974
	struct shortlog log;
975
	struct strbuf sb = STRBUF_INIT;
976
	int i;
977
	const char *encoding = "UTF-8";
978
	struct diff_options opts;
J
Junio C Hamano 已提交
979
	int need_8bit_cte = 0;
980
	struct pretty_print_context pp = {0};
981
	struct commit *head = list[0];
982

983
	if (!cmit_fmt_is_mail(rev->commit_format))
984
		die(_("Cover letter needs email format"));
985

986
	committer = git_committer_info(0);
987

988
	if (!use_stdout &&
989
	    open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
990 991
		return;

992
	log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
J
Junio C Hamano 已提交
993
				&need_8bit_cte);
994

J
Jeff King 已提交
995
	for (i = 0; !need_8bit_cte && i < nr; i++) {
996
		const char *buf = get_commit_buffer(list[i], NULL);
J
Jeff King 已提交
997
		if (has_non_ascii(buf))
998
			need_8bit_cte = 1;
J
Jeff King 已提交
999 1000
		unuse_commit_buffer(list[i], buf);
	}
1001

1002 1003 1004
	if (!branch_name)
		branch_name = find_branch_name(rev);

1005
	msg = body;
1006
	pp.fmt = CMIT_FMT_EMAIL;
1007
	pp.date_mode.type = DATE_RFC2822;
1008 1009 1010
	pp_user_info(&pp, NULL, &sb, committer, encoding);
	pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
	pp_remainder(&pp, &msg, &sb, 0);
1011
	add_branch_description(&sb, branch_name);
1012
	fprintf(rev->diffopt.file, "%s\n", sb.buf);
1013 1014 1015

	strbuf_release(&sb);

1016
	shortlog_init(&log);
1017 1018 1019 1020
	log.wrap_lines = 1;
	log.wrap = 72;
	log.in1 = 2;
	log.in2 = 4;
1021
	log.file = rev->diffopt.file;
1022 1023 1024 1025 1026
	for (i = 0; i < nr; i++)
		shortlog_add_commit(&log, list[i]);

	shortlog_output(&log);

1027
	/*
1028
	 * We can only do diffstat with a unique reference point
1029 1030 1031 1032
	 */
	if (!origin)
		return;

1033 1034
	memcpy(&opts, &rev->diffopt, sizeof(opts));
	opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
1035

1036 1037
	diff_setup_done(&opts);

B
brian m. carlson 已提交
1038 1039
	diff_tree_sha1(origin->tree->object.oid.hash,
		       head->tree->object.oid.hash,
1040 1041 1042
		       "", &opts);
	diffcore_std(&opts);
	diff_flush(&opts);
1043

1044
	fprintf(rev->diffopt.file, "\n");
1045 1046
}

1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
static const char *clean_message_id(const char *msg_id)
{
	char ch;
	const char *a, *z, *m;

	m = msg_id;
	while ((ch = *m) && (isspace(ch) || (ch == '<')))
		m++;
	a = m;
	z = NULL;
	while ((ch = *m)) {
		if (!isspace(ch) && (ch != '>'))
			z = m;
		m++;
	}
	if (!z)
1063
		die(_("insane in-reply-to: %s"), msg_id);
1064 1065
	if (++z == m)
		return a;
P
Pierre Habouzit 已提交
1066
	return xmemdupz(a, z - a);
1067 1068
}

1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
static const char *set_outdir(const char *prefix, const char *output_directory)
{
	if (output_directory && is_absolute_path(output_directory))
		return output_directory;

	if (!prefix || !*prefix) {
		if (output_directory)
			return output_directory;
		/* The user did not explicitly ask for "./" */
		outdir_offset = 2;
		return "./";
	}

	outdir_offset = strlen(prefix);
	if (!output_directory)
		return prefix;

	return xstrdup(prefix_filename(prefix, outdir_offset,
				       output_directory));
}

1090
static const char * const builtin_format_patch_usage[] = {
1091
	N_("git format-patch [<options>] [<since> | <revision-range>]"),
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
	NULL
};

static int keep_subject = 0;

static int keep_callback(const struct option *opt, const char *arg, int unset)
{
	((struct rev_info *)opt->value)->total = -1;
	keep_subject = 1;
	return 0;
}

static int subject_prefix = 0;

static int subject_prefix_callback(const struct option *opt, const char *arg,
			    int unset)
{
	subject_prefix = 1;
	((struct rev_info *)opt->value)->subject_prefix = arg;
	return 0;
}

1114 1115 1116 1117 1118
static int rfc_callback(const struct option *opt, const char *arg, int unset)
{
	return subject_prefix_callback(opt, "RFC PATCH", unset);
}

1119 1120
static int numbered_cmdline_opt = 0;

1121 1122 1123
static int numbered_callback(const struct option *opt, const char *arg,
			     int unset)
{
1124
	*(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
	if (unset)
		auto_number =  0;
	return 0;
}

static int no_numbered_callback(const struct option *opt, const char *arg,
				int unset)
{
	return numbered_callback(opt, arg, 1);
}

static int output_directory_callback(const struct option *opt, const char *arg,
			      int unset)
{
	const char **dir = (const char **)opt->value;
	if (*dir)
1141
		die(_("Two output directories?"));
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
	*dir = arg;
	return 0;
}

static int thread_callback(const struct option *opt, const char *arg, int unset)
{
	int *thread = (int *)opt->value;
	if (unset)
		*thread = 0;
	else if (!arg || !strcmp(arg, "shallow"))
		*thread = THREAD_SHALLOW;
	else if (!strcmp(arg, "deep"))
		*thread = THREAD_DEEP;
	else
		return 1;
	return 0;
}

static int attach_callback(const struct option *opt, const char *arg, int unset)
{
	struct rev_info *rev = (struct rev_info *)opt->value;
	if (unset)
		rev->mime_boundary = NULL;
	else if (arg)
		rev->mime_boundary = arg;
	else
		rev->mime_boundary = git_version_string;
	rev->no_inline = unset ? 0 : 1;
	return 0;
}

static int inline_callback(const struct option *opt, const char *arg, int unset)
{
	struct rev_info *rev = (struct rev_info *)opt->value;
	if (unset)
		rev->mime_boundary = NULL;
	else if (arg)
		rev->mime_boundary = arg;
	else
		rev->mime_boundary = git_version_string;
	rev->no_inline = 0;
	return 0;
}

static int header_callback(const struct option *opt, const char *arg, int unset)
{
1188 1189 1190 1191 1192 1193 1194
	if (unset) {
		string_list_clear(&extra_hdr, 0);
		string_list_clear(&extra_to, 0);
		string_list_clear(&extra_cc, 0);
	} else {
	    add_header(arg);
	}
1195 1196 1197
	return 0;
}

1198 1199
static int to_callback(const struct option *opt, const char *arg, int unset)
{
1200 1201 1202
	if (unset)
		string_list_clear(&extra_to, 0);
	else
1203
		string_list_append(&extra_to, arg);
1204 1205 1206 1207 1208
	return 0;
}

static int cc_callback(const struct option *opt, const char *arg, int unset)
{
1209 1210 1211
	if (unset)
		string_list_clear(&extra_cc, 0);
	else
1212
		string_list_append(&extra_cc, arg);
1213 1214 1215
	return 0;
}

1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
static int from_callback(const struct option *opt, const char *arg, int unset)
{
	char **from = opt->value;

	free(*from);

	if (unset)
		*from = NULL;
	else if (arg)
		*from = xstrdup(arg);
	else
		*from = xstrdup(git_committer_info(IDENT_NO_DATE));
	return 0;
}

1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244
struct base_tree_info {
	struct object_id base_commit;
	int nr_patch_id, alloc_patch_id;
	struct object_id *patch_id;
};

static struct commit *get_base_commit(const char *base_commit,
				      struct commit **list,
				      int total)
{
	struct commit *base = NULL;
	struct commit **rev;
	int i = 0, rev_nr = 0;

1245 1246 1247 1248 1249
	if (base_commit && strcmp(base_commit, "auto")) {
		base = lookup_commit_reference_by_name(base_commit);
		if (!base)
			die(_("Unknown commit %s"), base_commit);
	} else if ((base_commit && !strcmp(base_commit, "auto")) || base_auto) {
1250 1251 1252 1253 1254
		struct branch *curr_branch = branch_get(NULL);
		const char *upstream = branch_get_upstream(curr_branch, NULL);
		if (upstream) {
			struct commit_list *base_list;
			struct commit *commit;
1255
			struct object_id oid;
1256

1257
			if (get_oid(upstream, &oid))
1258
				die(_("Failed to resolve '%s' as a valid ref."), upstream);
1259
			commit = lookup_commit_or_die(oid.hash, "upstream base");
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271
			base_list = get_merge_bases_many(commit, total, list);
			/* There should be one and only one merge base. */
			if (!base_list || base_list->next)
				die(_("Could not find exact merge base."));
			base = base_list->item;
			free_commit_list(base_list);
		} else {
			die(_("Failed to get upstream, if you want to record base commit automatically,\n"
			      "please use git branch --set-upstream-to to track a remote branch.\n"
			      "Or you could specify base commit by --base=<base-commit-id> manually."));
		}
	}
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345

	ALLOC_ARRAY(rev, total);
	for (i = 0; i < total; i++)
		rev[i] = list[i];

	rev_nr = total;
	/*
	 * Get merge base through pair-wise computations
	 * and store it in rev[0].
	 */
	while (rev_nr > 1) {
		for (i = 0; i < rev_nr / 2; i++) {
			struct commit_list *merge_base;
			merge_base = get_merge_bases(rev[2 * i], rev[2 * i + 1]);
			if (!merge_base || merge_base->next)
				die(_("Failed to find exact merge base"));

			rev[i] = merge_base->item;
		}

		if (rev_nr % 2)
			rev[i] = rev[2 * i];
		rev_nr = (rev_nr + 1) / 2;
	}

	if (!in_merge_bases(base, rev[0]))
		die(_("base commit should be the ancestor of revision list"));

	for (i = 0; i < total; i++) {
		if (base == list[i])
			die(_("base commit shouldn't be in revision list"));
	}

	free(rev);
	return base;
}

static void prepare_bases(struct base_tree_info *bases,
			  struct commit *base,
			  struct commit **list,
			  int total)
{
	struct commit *commit;
	struct rev_info revs;
	struct diff_options diffopt;
	int i;

	if (!base)
		return;

	diff_setup(&diffopt);
	DIFF_OPT_SET(&diffopt, RECURSIVE);
	diff_setup_done(&diffopt);

	oidcpy(&bases->base_commit, &base->object.oid);

	init_revisions(&revs, NULL);
	revs.max_parents = 1;
	revs.topo_order = 1;
	for (i = 0; i < total; i++) {
		list[i]->object.flags &= ~UNINTERESTING;
		add_pending_object(&revs, &list[i]->object, "rev_list");
		list[i]->util = (void *)1;
	}
	base->object.flags |= UNINTERESTING;
	add_pending_object(&revs, &base->object, "base");

	if (prepare_revision_walk(&revs))
		die(_("revision walk setup failed"));
	/*
	 * Traverse the commits list, get prerequisite patch ids
	 * and stuff them in bases structure.
	 */
	while ((commit = get_revision(&revs)) != NULL) {
1346
		struct object_id oid;
1347 1348 1349
		struct object_id *patch_id;
		if (commit->util)
			continue;
1350
		if (commit_patch_id(commit, &diffopt, oid.hash, 0))
1351 1352 1353
			die(_("cannot get patch id"));
		ALLOC_GROW(bases->patch_id, bases->nr_patch_id + 1, bases->alloc_patch_id);
		patch_id = bases->patch_id + bases->nr_patch_id;
1354
		oidcpy(patch_id, &oid);
1355 1356 1357 1358
		bases->nr_patch_id++;
	}
}

1359
static void print_bases(struct base_tree_info *bases, FILE *file)
1360 1361 1362 1363 1364 1365 1366 1367
{
	int i;

	/* Only do this once, either for the cover or for the first one */
	if (is_null_oid(&bases->base_commit))
		return;

	/* Show the base commit */
1368
	fprintf(file, "\nbase-commit: %s\n", oid_to_hex(&bases->base_commit));
1369 1370 1371

	/* Show the prerequisite patches */
	for (i = bases->nr_patch_id - 1; i >= 0; i--)
1372
		fprintf(file, "prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
1373 1374 1375 1376 1377 1378 1379

	free(bases->patch_id);
	bases->nr_patch_id = 0;
	bases->alloc_patch_id = 0;
	oidclr(&bases->base_commit);
}

1380
int cmd_format_patch(int argc, const char **argv, const char *prefix)
1381 1382 1383 1384
{
	struct commit *commit;
	struct commit **list = NULL;
	struct rev_info rev;
1385
	struct setup_revision_opt s_r_opt;
1386
	int nr = 0, total, i;
1387
	int use_stdout = 0;
1388
	int start_number = -1;
1389
	int just_numbers = 0;
1390
	int ignore_if_in_upstream = 0;
1391
	int cover_letter = -1;
1392
	int boundary_count = 0;
1393
	int no_binary_diff = 0;
1394
	int zero_commit = 0;
1395
	struct commit *origin = NULL;
1396
	const char *in_reply_to = NULL;
1397
	struct patch_ids ids;
1398
	struct strbuf buf = STRBUF_INIT;
1399
	int use_patch_format = 0;
1400
	int quiet = 0;
1401
	int reroll_count = -1;
1402
	char *branch_name = NULL;
1403 1404 1405
	char *base_commit = NULL;
	struct base_tree_info bases;

1406 1407
	const struct option builtin_format_patch_options[] = {
		{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
1408
			    N_("use [PATCH n/m] even with a single patch"),
1409 1410
			    PARSE_OPT_NOARG, numbered_callback },
		{ OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
1411
			    N_("use [PATCH] even with multiple patches"),
1412
			    PARSE_OPT_NOARG, no_numbered_callback },
F
Felipe Contreras 已提交
1413 1414
		OPT_BOOL('s', "signoff", &do_signoff, N_("add Signed-off-by:")),
		OPT_BOOL(0, "stdout", &use_stdout,
1415
			    N_("print patches to standard out")),
F
Felipe Contreras 已提交
1416
		OPT_BOOL(0, "cover-letter", &cover_letter,
1417
			    N_("generate a cover letter")),
F
Felipe Contreras 已提交
1418
		OPT_BOOL(0, "numbered-files", &just_numbers,
1419 1420 1421
			    N_("use simple number sequence for output file names")),
		OPT_STRING(0, "suffix", &fmt_patch_suffix, N_("sfx"),
			    N_("use <sfx> instead of '.patch'")),
1422
		OPT_INTEGER(0, "start-number", &start_number,
1423
			    N_("start numbering patches at <n> instead of 1")),
1424
		OPT_INTEGER('v', "reroll-count", &reroll_count,
1425
			    N_("mark the series as Nth re-roll")),
1426 1427 1428
		{ OPTION_CALLBACK, 0, "rfc", &rev, NULL,
			    N_("Use [RFC PATCH] instead of [PATCH]"),
			    PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback },
1429 1430
		{ OPTION_CALLBACK, 0, "subject-prefix", &rev, N_("prefix"),
			    N_("Use [<prefix>] instead of [PATCH]"),
1431 1432
			    PARSE_OPT_NONEG, subject_prefix_callback },
		{ OPTION_CALLBACK, 'o', "output-directory", &output_directory,
1433
			    N_("dir"), N_("store resulting files in <dir>"),
1434 1435
			    PARSE_OPT_NONEG, output_directory_callback },
		{ OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL,
1436
			    N_("don't strip/add [PATCH]"),
1437
			    PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
1438 1439
		OPT_BOOL(0, "no-binary", &no_binary_diff,
			 N_("don't output binary diffs")),
1440 1441
		OPT_BOOL(0, "zero-commit", &zero_commit,
			 N_("output all-zero hash in From header")),
1442 1443
		OPT_BOOL(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
			 N_("don't include a patch matching a commit upstream")),
1444
		{ OPTION_SET_INT, 'p', "no-stat", &use_patch_format, NULL,
1445
		  N_("show patch format instead of default (patch + stat)"),
1446
		  PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1},
1447 1448 1449 1450
		OPT_GROUP(N_("Messaging")),
		{ OPTION_CALLBACK, 0, "add-header", NULL, N_("header"),
			    N_("add email header"), 0, header_callback },
		{ OPTION_CALLBACK, 0, "to", NULL, N_("email"), N_("add To: header"),
1451
			    0, to_callback },
1452
		{ OPTION_CALLBACK, 0, "cc", NULL, N_("email"), N_("add Cc: header"),
1453
			    0, cc_callback },
1454 1455 1456
		{ OPTION_CALLBACK, 0, "from", &from, N_("ident"),
			    N_("set From address to <ident> (or committer ident if absent)"),
			    PARSE_OPT_OPTARG, from_callback },
1457 1458 1459 1460
		OPT_STRING(0, "in-reply-to", &in_reply_to, N_("message-id"),
			    N_("make first mail a reply to <message-id>")),
		{ OPTION_CALLBACK, 0, "attach", &rev, N_("boundary"),
			    N_("attach the patch"), PARSE_OPT_OPTARG,
1461
			    attach_callback },
1462 1463
		{ OPTION_CALLBACK, 0, "inline", &rev, N_("boundary"),
			    N_("inline the patch"),
1464 1465
			    PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
			    inline_callback },
1466 1467
		{ OPTION_CALLBACK, 0, "thread", &thread, N_("style"),
			    N_("enable message threading, styles: shallow, deep"),
1468
			    PARSE_OPT_OPTARG, thread_callback },
1469 1470
		OPT_STRING(0, "signature", &signature, N_("signature"),
			    N_("add a signature")),
1471 1472
		OPT_STRING(0, "base", &base_commit, N_("base-commit"),
			   N_("add prerequisite tree info to the patch series")),
1473 1474
		OPT_FILENAME(0, "signature-file", &signature_file,
				N_("add a signature from a file")),
1475
		OPT__QUIET(&quiet, N_("don't print the patch filenames")),
1476 1477
		OPT_END()
	};
1478

1479 1480 1481
	extra_hdr.strdup_strings = 1;
	extra_to.strdup_strings = 1;
	extra_cc.strdup_strings = 1;
1482
	init_log_defaults();
1483
	git_config(git_format_config, NULL);
1484
	init_revisions(&rev, prefix);
1485
	rev.commit_format = CMIT_FMT_EMAIL;
1486
	rev.expand_tabs_in_log_default = 0;
1487 1488
	rev.verbose_header = 1;
	rev.diff = 1;
1489
	rev.max_parents = 1;
1490
	DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
1491
	rev.subject_prefix = fmt_patch_subject_prefix;
1492 1493
	memset(&s_r_opt, 0, sizeof(s_r_opt));
	s_r_opt.def = "HEAD";
1494
	s_r_opt.revarg_opt = REVARG_COMMITTISH;
1495

1496 1497 1498 1499 1500
	if (default_attach) {
		rev.mime_boundary = default_attach;
		rev.no_inline = 1;
	}

1501 1502
	/*
	 * Parse the arguments before setup_revisions(), or something
1503
	 * like "git format-patch -o a123 HEAD^.." may fail; a123 is
1504 1505
	 * possibly a valid SHA1.
	 */
1506
	argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
1507
			     builtin_format_patch_usage,
1508 1509
			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
			     PARSE_OPT_KEEP_DASHDASH);
1510

1511 1512 1513 1514 1515 1516 1517 1518
	if (0 < reroll_count) {
		struct strbuf sprefix = STRBUF_INIT;
		strbuf_addf(&sprefix, "%s v%d",
			    rev.subject_prefix, reroll_count);
		rev.reroll_count = reroll_count;
		rev.subject_prefix = strbuf_detach(&sprefix, NULL);
	}

1519 1520
	for (i = 0; i < extra_hdr.nr; i++) {
		strbuf_addstr(&buf, extra_hdr.items[i].string);
D
Daniel Barkalow 已提交
1521 1522 1523
		strbuf_addch(&buf, '\n');
	}

1524
	if (extra_to.nr)
D
Daniel Barkalow 已提交
1525
		strbuf_addstr(&buf, "To: ");
1526
	for (i = 0; i < extra_to.nr; i++) {
D
Daniel Barkalow 已提交
1527 1528
		if (i)
			strbuf_addstr(&buf, "    ");
1529 1530
		strbuf_addstr(&buf, extra_to.items[i].string);
		if (i + 1 < extra_to.nr)
D
Daniel Barkalow 已提交
1531 1532 1533 1534
			strbuf_addch(&buf, ',');
		strbuf_addch(&buf, '\n');
	}

1535
	if (extra_cc.nr)
D
Daniel Barkalow 已提交
1536
		strbuf_addstr(&buf, "Cc: ");
1537
	for (i = 0; i < extra_cc.nr; i++) {
D
Daniel Barkalow 已提交
1538 1539
		if (i)
			strbuf_addstr(&buf, "    ");
1540 1541
		strbuf_addstr(&buf, extra_cc.items[i].string);
		if (i + 1 < extra_cc.nr)
D
Daniel Barkalow 已提交
1542 1543 1544 1545
			strbuf_addch(&buf, ',');
		strbuf_addch(&buf, '\n');
	}

1546
	rev.extra_headers = strbuf_detach(&buf, NULL);
D
Daniel Barkalow 已提交
1547

1548 1549 1550 1551 1552
	if (from) {
		if (split_ident_line(&rev.from_ident, from, strlen(from)))
			die(_("invalid ident line: %s"), from);
	}

1553
	if (start_number < 0)
1554
		start_number = 1;
1555 1556 1557 1558 1559 1560 1561 1562 1563

	/*
	 * If numbered is set solely due to format.numbered in config,
	 * and it would conflict with --keep-subject (-k) from the
	 * command line, reset "numbered".
	 */
	if (numbered && keep_subject && !numbered_cmdline_opt)
		numbered = 0;

1564
	if (numbered && keep_subject)
1565
		die (_("-n and -k are mutually exclusive."));
1566
	if (keep_subject && subject_prefix)
1567
		die (_("--subject-prefix/--rfc and -k are mutually exclusive."));
1568
	rev.preserve_subject = keep_subject;
1569

1570
	argc = setup_revisions(argc, argv, &rev, &s_r_opt);
1571
	if (argc > 1)
1572
		die (_("unrecognized argument: %s"), argv[1]);
1573

1574
	if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
1575
		die(_("--name-only does not make sense"));
1576
	if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
1577
		die(_("--name-status does not make sense"));
1578
	if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
1579
		die(_("--check does not make sense"));
1580 1581 1582 1583 1584 1585 1586 1587

	if (!use_patch_format &&
		(!rev.diffopt.output_format ||
		 rev.diffopt.output_format == DIFF_FORMAT_PATCH))
		rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;

	/* Always generate a patch */
	rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
1588

1589 1590
	rev.zero_commit = zero_commit;

1591
	if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
1592
		DIFF_OPT_SET(&rev.diffopt, BINARY);
1593

1594 1595 1596
	if (rev.show_notes)
		init_display_notes(&rev.notes_opt);

1597 1598 1599
	if (!output_directory && !use_stdout)
		output_directory = config_output_directory;

1600 1601
	if (!use_stdout)
		output_directory = set_outdir(prefix, output_directory);
1602 1603
	else
		setup_pager();
1604

1605
	if (output_directory) {
1606 1607
		if (rev.diffopt.use_color != GIT_COLOR_ALWAYS)
			rev.diffopt.use_color = GIT_COLOR_NEVER;
1608
		if (use_stdout)
1609
			die(_("standard output, or directory, which one?"));
1610
		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
1611
			die_errno(_("Could not create directory '%s'"),
1612
				  output_directory);
1613 1614
	}

1615
	if (rev.pending.nr == 1) {
1616 1617
		int check_head = 0;

1618 1619 1620 1621 1622 1623
		if (rev.max_count < 0 && !rev.show_root_diff) {
			/*
			 * This is traditional behaviour of "git format-patch
			 * origin" that prepares what the origin side still
			 * does not have.
			 */
J
Junio C Hamano 已提交
1624
			rev.pending.objects[0].item->flags |= UNINTERESTING;
1625
			add_head_to_pending(&rev);
1626
			check_head = 1;
J
Junio C Hamano 已提交
1627
		}
1628 1629 1630 1631
		/*
		 * Otherwise, it is "format-patch -22 HEAD", and/or
		 * "format-patch --root HEAD".  The user wants
		 * get_revision() to do the usual traversal.
J
Junio C Hamano 已提交
1632
		 */
1633 1634 1635 1636 1637

		if (!strcmp(rev.pending.objects[0].name, "HEAD"))
			check_head = 1;

		if (check_head) {
1638
			struct object_id oid;
1639
			const char *ref, *v;
1640
			ref = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
1641
						 oid.hash, NULL);
1642 1643
			if (ref && skip_prefix(ref, "refs/heads/", &v))
				branch_name = xstrdup(v);
1644 1645 1646
			else
				branch_name = xstrdup(""); /* no branch */
		}
1647
	}
1648 1649 1650

	/*
	 * We cannot move this anywhere earlier because we do want to
1651
	 * know if --root was given explicitly from the command line.
1652 1653 1654
	 */
	rev.show_root_diff = 1;

1655 1656 1657 1658
	if (ignore_if_in_upstream) {
		/* Don't say anything if head and upstream are the same. */
		if (rev.pending.nr == 2) {
			struct object_array_entry *o = rev.pending.objects;
1659
			if (oidcmp(&o[0].item->oid, &o[1].item->oid) == 0)
1660 1661
				return 0;
		}
1662
		get_patch_ids(&rev, &ids);
1663
	}
1664

1665
	if (prepare_revision_walk(&rev))
1666
		die(_("revision walk setup failed"));
1667
	rev.boundary = 1;
1668
	while ((commit = get_revision(&rev)) != NULL) {
1669 1670 1671 1672 1673 1674
		if (commit->object.flags & BOUNDARY) {
			boundary_count++;
			origin = (boundary_count == 1) ? commit : NULL;
			continue;
		}

J
Junio C Hamano 已提交
1675
		if (ignore_if_in_upstream && has_commit_patch_id(commit, &ids))
1676 1677
			continue;

1678
		nr++;
1679
		REALLOC_ARRAY(list, nr);
1680 1681
		list[nr - 1] = commit;
	}
1682 1683 1684
	if (nr == 0)
		/* nothing to do */
		return 0;
1685
	total = nr;
1686 1687 1688 1689 1690 1691
	if (cover_letter == -1) {
		if (config_cover_letter == COVER_AUTO)
			cover_letter = (total > 1);
		else
			cover_letter = (config_cover_letter == COVER_ON);
	}
1692 1693 1694 1695
	if (!keep_subject && auto_number && (total > 1 || cover_letter))
		numbered = 1;
	if (numbered)
		rev.total = total + start_number - 1;
1696

1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708
	if (!signature) {
		; /* --no-signature inhibits all signatures */
	} else if (signature && signature != git_version_string) {
		; /* non-default signature already set */
	} else if (signature_file) {
		struct strbuf buf = STRBUF_INIT;

		if (strbuf_read_file(&buf, signature_file, 128) < 0)
			die_errno(_("unable to read signature file '%s'"), signature_file);
		signature = strbuf_detach(&buf, NULL);
	}

1709
	memset(&bases, 0, sizeof(bases));
1710
	if (base_commit || base_auto) {
1711 1712 1713 1714 1715
		struct commit *base = get_base_commit(base_commit, list, nr);
		reset_revision_walk();
		prepare_bases(&bases, base, list, nr);
	}

1716 1717 1718 1719
	if (in_reply_to || thread || cover_letter)
		rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));
	if (in_reply_to) {
		const char *msgid = clean_message_id(in_reply_to);
1720
		string_list_append(rev.ref_message_ids, msgid);
1721
	}
1722
	rev.numbered_files = just_numbers;
1723
	rev.patch_suffix = fmt_patch_suffix;
1724 1725 1726
	if (cover_letter) {
		if (thread)
			gen_message_id(&rev, "cover");
1727
		make_cover_letter(&rev, use_stdout,
1728
				  origin, nr, list, branch_name, quiet);
1729
		print_bases(&bases, rev.diffopt.file);
1730
		print_signature(rev.diffopt.file);
1731 1732 1733
		total++;
		start_number--;
	}
1734
	rev.add_signoff = do_signoff;
1735 1736 1737
	while (0 <= --nr) {
		int shown;
		commit = list[nr];
1738
		rev.nr = total - nr + (start_number - 1);
1739
		/* Make the second and subsequent mails replies to the first */
1740
		if (thread) {
1741
			/* Have we already had a message ID? */
1742
			if (rev.message_id) {
1743
				/*
1744 1745 1746 1747 1748 1749
				 * For deep threading: make every mail
				 * a reply to the previous one, no
				 * matter what other options are set.
				 *
				 * For shallow threading:
				 *
1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762
				 * Without --cover-letter and
				 * --in-reply-to, make every mail a
				 * reply to the one before.
				 *
				 * With --in-reply-to but no
				 * --cover-letter, make every mail a
				 * reply to the <reply-to>.
				 *
				 * With --cover-letter, make every
				 * mail but the cover letter a reply
				 * to the cover letter.  The cover
				 * letter is a reply to the
				 * --in-reply-to, if specified.
1763
				 */
1764 1765
				if (thread == THREAD_SHALLOW
				    && rev.ref_message_ids->nr > 0
1766
				    && (!cover_letter || rev.nr > 1))
1767 1768
					free(rev.message_id);
				else
1769 1770
					string_list_append(rev.ref_message_ids,
							   rev.message_id);
1771
			}
1772
			gen_message_id(&rev, oid_to_hex(&commit->object.oid));
1773
		}
1774

1775
		if (!use_stdout &&
1776
		    open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
1777
			die(_("Failed to create output files"));
1778
		shown = log_tree_commit(&rev, commit);
1779
		free_commit_buffer(commit);
1780 1781 1782 1783 1784 1785 1786 1787 1788

		/* We put one extra blank line between formatted
		 * patches and this flag is used by log-tree code
		 * to see if it needs to emit a LF before showing
		 * the log; when using one file per patch, we do
		 * not want the extra blank line.
		 */
		if (!use_stdout)
			rev.shown_one = 0;
1789
		if (shown) {
1790
			print_bases(&bases, rev.diffopt.file);
1791
			if (rev.mime_boundary)
1792
				fprintf(rev.diffopt.file, "\n--%s%s--\n\n\n",
1793 1794 1795
				       mime_boundary_leader,
				       rev.mime_boundary);
			else
1796
				print_signature(rev.diffopt.file);
1797
		}
1798
		if (!use_stdout)
1799
			fclose(rev.diffopt.file);
1800 1801
	}
	free(list);
1802
	free(branch_name);
1803 1804 1805
	string_list_clear(&extra_to, 0);
	string_list_clear(&extra_cc, 0);
	string_list_clear(&extra_hdr, 0);
1806 1807
	if (ignore_if_in_upstream)
		free_patch_ids(&ids);
1808 1809 1810
	return 0;
}

R
Rene Scharfe 已提交
1811 1812
static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
{
1813 1814 1815
	struct object_id oid;
	if (get_oid(arg, &oid) == 0) {
		struct commit *commit = lookup_commit_reference(oid.hash);
R
Rene Scharfe 已提交
1816 1817 1818 1819 1820 1821 1822 1823 1824
		if (commit) {
			commit->object.flags |= flags;
			add_pending_object(revs, &commit->object, arg);
			return 0;
		}
	}
	return -1;
}

E
Erik Faye-Lund 已提交
1825
static const char * const cherry_usage[] = {
1826
	N_("git cherry [-v] [<upstream> [<head> [<limit>]]]"),
E
Erik Faye-Lund 已提交
1827 1828 1829
	NULL
};

1830
static void print_commit(char sign, struct commit *commit, int verbose,
1831
			 int abbrev, FILE *file)
1832 1833
{
	if (!verbose) {
1834
		fprintf(file, "%c %s\n", sign,
B
brian m. carlson 已提交
1835
		       find_unique_abbrev(commit->object.oid.hash, abbrev));
1836 1837
	} else {
		struct strbuf buf = STRBUF_INIT;
1838
		pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
1839
		fprintf(file, "%c %s %s\n", sign,
B
brian m. carlson 已提交
1840
		       find_unique_abbrev(commit->object.oid.hash, abbrev),
1841 1842 1843 1844 1845
		       buf.buf);
		strbuf_release(&buf);
	}
}

R
Rene Scharfe 已提交
1846 1847 1848
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
	struct rev_info revs;
1849
	struct patch_ids ids;
R
Rene Scharfe 已提交
1850 1851
	struct commit *commit;
	struct commit_list *list = NULL;
1852
	struct branch *current_branch;
R
Rene Scharfe 已提交
1853 1854 1855
	const char *upstream;
	const char *head = "HEAD";
	const char *limit = NULL;
E
Erik Faye-Lund 已提交
1856
	int verbose = 0, abbrev = 0;
R
Rene Scharfe 已提交
1857

E
Erik Faye-Lund 已提交
1858 1859
	struct option options[] = {
		OPT__ABBREV(&abbrev),
1860
		OPT__VERBOSE(&verbose, N_("be verbose")),
E
Erik Faye-Lund 已提交
1861 1862
		OPT_END()
	};
R
Rene Scharfe 已提交
1863

E
Erik Faye-Lund 已提交
1864
	argc = parse_options(argc, argv, prefix, options, cherry_usage, 0);
1865

R
Rene Scharfe 已提交
1866 1867
	switch (argc) {
	case 3:
E
Erik Faye-Lund 已提交
1868
		limit = argv[2];
R
Rene Scharfe 已提交
1869 1870
		/* FALLTHROUGH */
	case 2:
E
Erik Faye-Lund 已提交
1871 1872 1873 1874
		head = argv[1];
		/* FALLTHROUGH */
	case 1:
		upstream = argv[0];
R
Rene Scharfe 已提交
1875 1876
		break;
	default:
1877
		current_branch = branch_get(NULL);
1878
		upstream = branch_get_upstream(current_branch, NULL);
1879
		if (!upstream) {
1880
			fprintf(stderr, _("Could not find a tracked"
1881
					" remote branch, please"
1882
					" specify <upstream> manually.\n"));
E
Erik Faye-Lund 已提交
1883
			usage_with_options(cherry_usage, options);
1884
		}
R
Rene Scharfe 已提交
1885 1886 1887
	}

	init_revisions(&revs, prefix);
1888
	revs.max_parents = 1;
R
Rene Scharfe 已提交
1889 1890

	if (add_pending_commit(head, &revs, 0))
1891
		die(_("Unknown commit %s"), head);
R
Rene Scharfe 已提交
1892
	if (add_pending_commit(upstream, &revs, UNINTERESTING))
1893
		die(_("Unknown commit %s"), upstream);
R
Rene Scharfe 已提交
1894 1895 1896 1897

	/* Don't say anything if head and upstream are the same. */
	if (revs.pending.nr == 2) {
		struct object_array_entry *o = revs.pending.objects;
1898
		if (oidcmp(&o[0].item->oid, &o[1].item->oid) == 0)
R
Rene Scharfe 已提交
1899 1900 1901
			return 0;
	}

1902
	get_patch_ids(&revs, &ids);
R
Rene Scharfe 已提交
1903 1904

	if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
1905
		die(_("Unknown commit %s"), limit);
R
Rene Scharfe 已提交
1906 1907

	/* reverse the list of commits */
1908
	if (prepare_revision_walk(&revs))
1909
		die(_("revision walk setup failed"));
R
Rene Scharfe 已提交
1910 1911 1912 1913 1914 1915 1916 1917
	while ((commit = get_revision(&revs)) != NULL) {
		commit_list_insert(commit, &list);
	}

	while (list) {
		char sign = '+';

		commit = list->item;
1918
		if (has_commit_patch_id(commit, &ids))
R
Rene Scharfe 已提交
1919
			sign = '-';
1920
		print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
R
Rene Scharfe 已提交
1921 1922 1923
		list = list->next;
	}

1924
	free_patch_ids(&ids);
R
Rene Scharfe 已提交
1925 1926
	return 0;
}