log.c 50.6 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->hash, 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 483
	    !textconv_object(obj_context.path, obj_context.mode, oidc.hash, 1, &buf, &size))
		return stream_blob_to_fd(1, oid->hash, 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 1045
	fprintf(rev->diffopt.file, "\n");
	print_signature(rev->diffopt.file);
1046 1047
}

1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
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)
1064
		die(_("insane in-reply-to: %s"), msg_id);
1065 1066
	if (++z == m)
		return a;
P
Pierre Habouzit 已提交
1067
	return xmemdupz(a, z - a);
1068 1069
}

1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
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));
}

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

1115 1116
static int numbered_cmdline_opt = 0;

1117 1118 1119
static int numbered_callback(const struct option *opt, const char *arg,
			     int unset)
{
1120
	*(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
	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)
1137
		die(_("Two output directories?"));
1138 1139 1140 1141 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
	*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)
{
1184 1185 1186 1187 1188 1189 1190
	if (unset) {
		string_list_clear(&extra_hdr, 0);
		string_list_clear(&extra_to, 0);
		string_list_clear(&extra_cc, 0);
	} else {
	    add_header(arg);
	}
1191 1192 1193
	return 0;
}

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

static int cc_callback(const struct option *opt, const char *arg, int unset)
{
1205 1206 1207
	if (unset)
		string_list_clear(&extra_cc, 0);
	else
1208
		string_list_append(&extra_cc, arg);
1209 1210 1211
	return 0;
}

1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
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;
}

1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
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;

1241 1242 1243 1244 1245
	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) {
1246 1247 1248 1249 1250
		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;
1251
			struct object_id oid;
1252

1253
			if (get_oid(upstream, &oid))
1254
				die(_("Failed to resolve '%s' as a valid ref."), upstream);
1255
			commit = lookup_commit_or_die(oid.hash, "upstream base");
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
			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."));
		}
	}
1268 1269 1270 1271 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

	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) {
1342
		struct object_id oid;
1343 1344 1345
		struct object_id *patch_id;
		if (commit->util)
			continue;
1346
		if (commit_patch_id(commit, &diffopt, oid.hash, 0))
1347 1348 1349
			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;
1350
		oidcpy(patch_id, &oid);
1351 1352 1353 1354
		bases->nr_patch_id++;
	}
}

1355
static void print_bases(struct base_tree_info *bases, FILE *file)
1356 1357 1358 1359 1360 1361 1362 1363
{
	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 */
1364
	fprintf(file, "base-commit: %s\n", oid_to_hex(&bases->base_commit));
1365 1366 1367

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

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

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

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

1472 1473 1474
	extra_hdr.strdup_strings = 1;
	extra_to.strdup_strings = 1;
	extra_cc.strdup_strings = 1;
1475
	init_log_defaults();
1476
	git_config(git_format_config, NULL);
1477
	init_revisions(&rev, prefix);
1478
	rev.commit_format = CMIT_FMT_EMAIL;
1479
	rev.expand_tabs_in_log_default = 0;
1480 1481
	rev.verbose_header = 1;
	rev.diff = 1;
1482
	rev.max_parents = 1;
1483
	DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
1484
	rev.subject_prefix = fmt_patch_subject_prefix;
1485 1486
	memset(&s_r_opt, 0, sizeof(s_r_opt));
	s_r_opt.def = "HEAD";
1487
	s_r_opt.revarg_opt = REVARG_COMMITTISH;
1488

1489 1490 1491 1492 1493
	if (default_attach) {
		rev.mime_boundary = default_attach;
		rev.no_inline = 1;
	}

1494 1495
	/*
	 * Parse the arguments before setup_revisions(), or something
1496
	 * like "git format-patch -o a123 HEAD^.." may fail; a123 is
1497 1498
	 * possibly a valid SHA1.
	 */
1499
	argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
1500
			     builtin_format_patch_usage,
1501 1502
			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
			     PARSE_OPT_KEEP_DASHDASH);
1503

1504 1505 1506 1507 1508 1509 1510 1511
	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);
	}

1512 1513
	for (i = 0; i < extra_hdr.nr; i++) {
		strbuf_addstr(&buf, extra_hdr.items[i].string);
D
Daniel Barkalow 已提交
1514 1515 1516
		strbuf_addch(&buf, '\n');
	}

1517
	if (extra_to.nr)
D
Daniel Barkalow 已提交
1518
		strbuf_addstr(&buf, "To: ");
1519
	for (i = 0; i < extra_to.nr; i++) {
D
Daniel Barkalow 已提交
1520 1521
		if (i)
			strbuf_addstr(&buf, "    ");
1522 1523
		strbuf_addstr(&buf, extra_to.items[i].string);
		if (i + 1 < extra_to.nr)
D
Daniel Barkalow 已提交
1524 1525 1526 1527
			strbuf_addch(&buf, ',');
		strbuf_addch(&buf, '\n');
	}

1528
	if (extra_cc.nr)
D
Daniel Barkalow 已提交
1529
		strbuf_addstr(&buf, "Cc: ");
1530
	for (i = 0; i < extra_cc.nr; i++) {
D
Daniel Barkalow 已提交
1531 1532
		if (i)
			strbuf_addstr(&buf, "    ");
1533 1534
		strbuf_addstr(&buf, extra_cc.items[i].string);
		if (i + 1 < extra_cc.nr)
D
Daniel Barkalow 已提交
1535 1536 1537 1538
			strbuf_addch(&buf, ',');
		strbuf_addch(&buf, '\n');
	}

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

1541 1542 1543 1544 1545
	if (from) {
		if (split_ident_line(&rev.from_ident, from, strlen(from)))
			die(_("invalid ident line: %s"), from);
	}

1546
	if (start_number < 0)
1547
		start_number = 1;
1548 1549 1550 1551 1552 1553 1554 1555 1556

	/*
	 * 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;

1557
	if (numbered && keep_subject)
1558
		die (_("-n and -k are mutually exclusive."));
1559
	if (keep_subject && subject_prefix)
1560
		die (_("--subject-prefix and -k are mutually exclusive."));
1561
	rev.preserve_subject = keep_subject;
1562

1563
	argc = setup_revisions(argc, argv, &rev, &s_r_opt);
1564
	if (argc > 1)
1565
		die (_("unrecognized argument: %s"), argv[1]);
1566

1567
	if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
1568
		die(_("--name-only does not make sense"));
1569
	if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
1570
		die(_("--name-status does not make sense"));
1571
	if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
1572
		die(_("--check does not make sense"));
1573 1574 1575 1576 1577 1578 1579 1580

	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;
1581

1582 1583
	rev.zero_commit = zero_commit;

1584
	if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
1585
		DIFF_OPT_SET(&rev.diffopt, BINARY);
1586

1587 1588 1589
	if (rev.show_notes)
		init_display_notes(&rev.notes_opt);

1590 1591 1592
	if (!output_directory && !use_stdout)
		output_directory = config_output_directory;

1593 1594
	if (!use_stdout)
		output_directory = set_outdir(prefix, output_directory);
1595 1596
	else
		setup_pager();
1597

1598
	if (output_directory) {
1599 1600
		if (rev.diffopt.use_color != GIT_COLOR_ALWAYS)
			rev.diffopt.use_color = GIT_COLOR_NEVER;
1601
		if (use_stdout)
1602
			die(_("standard output, or directory, which one?"));
1603
		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
1604
			die_errno(_("Could not create directory '%s'"),
1605
				  output_directory);
1606 1607
	}

1608
	if (rev.pending.nr == 1) {
1609 1610
		int check_head = 0;

1611 1612 1613 1614 1615 1616
		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 已提交
1617
			rev.pending.objects[0].item->flags |= UNINTERESTING;
1618
			add_head_to_pending(&rev);
1619
			check_head = 1;
J
Junio C Hamano 已提交
1620
		}
1621 1622 1623 1624
		/*
		 * 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 已提交
1625
		 */
1626 1627 1628 1629 1630

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

		if (check_head) {
1631
			struct object_id oid;
1632
			const char *ref, *v;
1633
			ref = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
1634
						 oid.hash, NULL);
1635 1636
			if (ref && skip_prefix(ref, "refs/heads/", &v))
				branch_name = xstrdup(v);
1637 1638 1639
			else
				branch_name = xstrdup(""); /* no branch */
		}
1640
	}
1641 1642 1643

	/*
	 * We cannot move this anywhere earlier because we do want to
1644
	 * know if --root was given explicitly from the command line.
1645 1646 1647
	 */
	rev.show_root_diff = 1;

1648 1649 1650 1651
	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;
1652
			if (oidcmp(&o[0].item->oid, &o[1].item->oid) == 0)
1653 1654
				return 0;
		}
1655
		get_patch_ids(&rev, &ids);
1656
	}
1657

1658
	if (prepare_revision_walk(&rev))
1659
		die(_("revision walk setup failed"));
1660
	rev.boundary = 1;
1661
	while ((commit = get_revision(&rev)) != NULL) {
1662 1663 1664 1665 1666 1667
		if (commit->object.flags & BOUNDARY) {
			boundary_count++;
			origin = (boundary_count == 1) ? commit : NULL;
			continue;
		}

J
Junio C Hamano 已提交
1668
		if (ignore_if_in_upstream && has_commit_patch_id(commit, &ids))
1669 1670
			continue;

1671
		nr++;
1672
		REALLOC_ARRAY(list, nr);
1673 1674
		list[nr - 1] = commit;
	}
1675 1676 1677
	if (nr == 0)
		/* nothing to do */
		return 0;
1678
	total = nr;
1679 1680
	if (!keep_subject && auto_number && total > 1)
		numbered = 1;
1681
	if (numbered)
1682
		rev.total = total + start_number - 1;
1683 1684 1685 1686 1687 1688 1689
	if (cover_letter == -1) {
		if (config_cover_letter == COVER_AUTO)
			cover_letter = (total > 1);
		else
			cover_letter = (config_cover_letter == COVER_ON);
	}

1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701
	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);
	}

1702
	memset(&bases, 0, sizeof(bases));
1703
	if (base_commit || base_auto) {
1704 1705 1706 1707 1708
		struct commit *base = get_base_commit(base_commit, list, nr);
		reset_revision_walk();
		prepare_bases(&bases, base, list, nr);
	}

1709 1710 1711 1712
	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);
1713
		string_list_append(rev.ref_message_ids, msgid);
1714
	}
1715
	rev.numbered_files = just_numbers;
1716
	rev.patch_suffix = fmt_patch_suffix;
1717 1718 1719
	if (cover_letter) {
		if (thread)
			gen_message_id(&rev, "cover");
1720
		make_cover_letter(&rev, use_stdout,
1721
				  origin, nr, list, branch_name, quiet);
1722
		print_bases(&bases, rev.diffopt.file);
1723 1724 1725
		total++;
		start_number--;
	}
1726
	rev.add_signoff = do_signoff;
1727 1728 1729
	while (0 <= --nr) {
		int shown;
		commit = list[nr];
1730
		rev.nr = total - nr + (start_number - 1);
1731
		/* Make the second and subsequent mails replies to the first */
1732
		if (thread) {
1733
			/* Have we already had a message ID? */
1734
			if (rev.message_id) {
1735
				/*
1736 1737 1738 1739 1740 1741
				 * For deep threading: make every mail
				 * a reply to the previous one, no
				 * matter what other options are set.
				 *
				 * For shallow threading:
				 *
1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
				 * 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.
1755
				 */
1756 1757
				if (thread == THREAD_SHALLOW
				    && rev.ref_message_ids->nr > 0
1758
				    && (!cover_letter || rev.nr > 1))
1759 1760
					free(rev.message_id);
				else
1761 1762
					string_list_append(rev.ref_message_ids,
							   rev.message_id);
1763
			}
1764
			gen_message_id(&rev, oid_to_hex(&commit->object.oid));
1765
		}
1766

1767
		if (!use_stdout &&
1768
		    open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
1769
			die(_("Failed to create output files"));
1770
		shown = log_tree_commit(&rev, commit);
1771
		free_commit_buffer(commit);
1772 1773 1774 1775 1776 1777 1778 1779 1780

		/* 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;
1781 1782
		if (shown) {
			if (rev.mime_boundary)
1783
				fprintf(rev.diffopt.file, "\n--%s%s--\n\n\n",
1784 1785 1786
				       mime_boundary_leader,
				       rev.mime_boundary);
			else
1787 1788
				print_signature(rev.diffopt.file);
			print_bases(&bases, rev.diffopt.file);
1789
		}
1790
		if (!use_stdout)
1791
			fclose(rev.diffopt.file);
1792 1793
	}
	free(list);
1794
	free(branch_name);
1795 1796 1797
	string_list_clear(&extra_to, 0);
	string_list_clear(&extra_cc, 0);
	string_list_clear(&extra_hdr, 0);
1798 1799
	if (ignore_if_in_upstream)
		free_patch_ids(&ids);
1800 1801 1802
	return 0;
}

R
Rene Scharfe 已提交
1803 1804
static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
{
1805 1806 1807
	struct object_id oid;
	if (get_oid(arg, &oid) == 0) {
		struct commit *commit = lookup_commit_reference(oid.hash);
R
Rene Scharfe 已提交
1808 1809 1810 1811 1812 1813 1814 1815 1816
		if (commit) {
			commit->object.flags |= flags;
			add_pending_object(revs, &commit->object, arg);
			return 0;
		}
	}
	return -1;
}

E
Erik Faye-Lund 已提交
1817
static const char * const cherry_usage[] = {
1818
	N_("git cherry [-v] [<upstream> [<head> [<limit>]]]"),
E
Erik Faye-Lund 已提交
1819 1820 1821
	NULL
};

1822
static void print_commit(char sign, struct commit *commit, int verbose,
1823
			 int abbrev, FILE *file)
1824 1825
{
	if (!verbose) {
1826
		fprintf(file, "%c %s\n", sign,
B
brian m. carlson 已提交
1827
		       find_unique_abbrev(commit->object.oid.hash, abbrev));
1828 1829
	} else {
		struct strbuf buf = STRBUF_INIT;
1830
		pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
1831
		fprintf(file, "%c %s %s\n", sign,
B
brian m. carlson 已提交
1832
		       find_unique_abbrev(commit->object.oid.hash, abbrev),
1833 1834 1835 1836 1837
		       buf.buf);
		strbuf_release(&buf);
	}
}

R
Rene Scharfe 已提交
1838 1839 1840
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
	struct rev_info revs;
1841
	struct patch_ids ids;
R
Rene Scharfe 已提交
1842 1843
	struct commit *commit;
	struct commit_list *list = NULL;
1844
	struct branch *current_branch;
R
Rene Scharfe 已提交
1845 1846 1847
	const char *upstream;
	const char *head = "HEAD";
	const char *limit = NULL;
E
Erik Faye-Lund 已提交
1848
	int verbose = 0, abbrev = 0;
R
Rene Scharfe 已提交
1849

E
Erik Faye-Lund 已提交
1850 1851
	struct option options[] = {
		OPT__ABBREV(&abbrev),
1852
		OPT__VERBOSE(&verbose, N_("be verbose")),
E
Erik Faye-Lund 已提交
1853 1854
		OPT_END()
	};
R
Rene Scharfe 已提交
1855

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

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

	init_revisions(&revs, prefix);
1880
	revs.max_parents = 1;
R
Rene Scharfe 已提交
1881 1882

	if (add_pending_commit(head, &revs, 0))
1883
		die(_("Unknown commit %s"), head);
R
Rene Scharfe 已提交
1884
	if (add_pending_commit(upstream, &revs, UNINTERESTING))
1885
		die(_("Unknown commit %s"), upstream);
R
Rene Scharfe 已提交
1886 1887 1888 1889

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

1894
	get_patch_ids(&revs, &ids);
R
Rene Scharfe 已提交
1895 1896

	if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
1897
		die(_("Unknown commit %s"), limit);
R
Rene Scharfe 已提交
1898 1899

	/* reverse the list of commits */
1900
	if (prepare_revision_walk(&revs))
1901
		die(_("revision walk setup failed"));
R
Rene Scharfe 已提交
1902 1903 1904 1905 1906 1907 1908 1909
	while ((commit = get_revision(&revs)) != NULL) {
		commit_list_insert(commit, &list);
	}

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

		commit = list->item;
1910
		if (has_commit_patch_id(commit, &ids))
R
Rene Scharfe 已提交
1911
			sign = '-';
1912
		print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
R
Rene Scharfe 已提交
1913 1914 1915
		list = list->next;
	}

1916
	free_patch_ids(&ids);
R
Rene Scharfe 已提交
1917 1918
	return 0;
}