builtin-log.c 34.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 "color.h"
9 10 11 12
#include "commit.h"
#include "diff.h"
#include "revision.h"
#include "log-tree.h"
13
#include "builtin.h"
14
#include "tag.h"
L
Linus Torvalds 已提交
15
#include "reflog-walk.h"
16
#include "patch-ids.h"
17
#include "run-command.h"
18
#include "shortlog.h"
19
#include "remote.h"
20
#include "string-list.h"
21
#include "parse-options.h"
22

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

26
static int default_show_root = 1;
27
static const char *fmt_patch_subject_prefix = "PATCH";
28
static const char *fmt_pretty;
29

30 31 32 33
static const char * const builtin_log_usage =
	"git log [<options>] [<since>..<until>] [[--] <path>...]\n"
	"   or: git show [options] <object>...";

34
static void cmd_log_init(int argc, const char **argv, const char *prefix,
35 36
		      struct rev_info *rev)
{
J
Junio C Hamano 已提交
37
	int i;
38
	int decoration_style = 0;
J
Junio C Hamano 已提交
39

40 41
	rev->abbrev = DEFAULT_ABBREV;
	rev->commit_format = CMIT_FMT_DEFAULT;
42
	if (fmt_pretty)
43
		get_commit_format(fmt_pretty, rev);
44
	rev->verbose_header = 1;
45
	DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
46
	rev->show_root_diff = default_show_root;
47
	rev->subject_prefix = fmt_patch_subject_prefix;
J
Jeff King 已提交
48
	DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV);
H
Heikki Orsila 已提交
49 50 51 52

	if (default_date_mode)
		rev->date_mode = parse_date_format(default_date_mode);

53 54 55 56 57 58
	/*
	 * Check for -h before setup_revisions(), or "git log -h" will
	 * fail when run without a git directory.
	 */
	if (argc == 2 && !strcmp(argv[1], "-h"))
		usage(builtin_log_usage);
59
	argc = setup_revisions(argc, argv, rev, "HEAD");
H
Heikki Orsila 已提交
60

61 62 63
	if (!rev->show_notes_given && !rev->pretty_given)
		rev->show_notes = 1;

64 65
	if (rev->diffopt.pickaxe || rev->diffopt.filter)
		rev->always_show_header = 0;
66
	if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
67 68 69 70
		rev->always_show_header = 0;
		if (rev->diffopt.nr_paths != 1)
			usage("git logs can only follow renames on one pathname at a time");
	}
J
Junio C Hamano 已提交
71 72
	for (i = 1; i < argc; i++) {
		const char *arg = argv[i];
73
		if (!strcmp(arg, "--decorate")) {
74 75 76 77 78 79 80 81 82
			decoration_style = DECORATE_SHORT_REFS;
		} else if (!prefixcmp(arg, "--decorate=")) {
			const char *v = skip_prefix(arg, "--decorate=");
			if (!strcmp(v, "full"))
				decoration_style = DECORATE_FULL_REFS;
			else if (!strcmp(v, "short"))
				decoration_style = DECORATE_SHORT_REFS;
			else
				die("invalid --decorate option: %s", arg);
83 84
		} else if (!strcmp(arg, "--source")) {
			rev->show_source = 1;
85 86
		} else if (!strcmp(arg, "-h")) {
			usage(builtin_log_usage);
87
		} else
J
Junio C Hamano 已提交
88 89
			die("unrecognized argument: %s", arg);
	}
90 91 92 93
	if (decoration_style) {
		rev->show_decorations = 1;
		load_ref_decorations(decoration_style);
	}
94 95
}

L
Linus Torvalds 已提交
96 97 98 99 100 101 102 103 104 105 106 107
/*
 * 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;
108
		if (!(flags & (TREESAME | UNINTERESTING)))
L
Linus Torvalds 已提交
109
			n++;
L
Linus Torvalds 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123
	}
	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);
	}
	printf("Final output: %d %s\n", nr, stage);
}

124
static struct itimerval early_output_timer;
L
Linus Torvalds 已提交
125

126 127 128
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
	int i = revs->early_output;
L
Linus Torvalds 已提交
129
	int show_header = 1;
130 131 132 133

	sort_in_topological_order(&list, revs->lifo);
	while (list && i) {
		struct commit *commit = list->item;
L
Linus Torvalds 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
		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:
			return;
		}
149 150
		list = list->next;
	}
L
Linus Torvalds 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

	/* Did we already get enough commits for the early output? */
	if (!i)
		return;

	/*
	 * ..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);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
}

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 已提交
200 201 202
	early_output_timer.it_value.tv_sec = 0;
	early_output_timer.it_value.tv_usec = 100000;
	setitimer(ITIMER_REAL, &early_output_timer, NULL);
203 204 205 206
}

static void finish_early_output(struct rev_info *rev)
{
L
Linus Torvalds 已提交
207
	int n = estimate_commit_count(rev, rev->commits);
208
	signal(SIGALRM, SIG_IGN);
L
Linus Torvalds 已提交
209
	show_early_header(rev, "done", n);
210 211
}

212 213 214
static int cmd_log_walk(struct rev_info *rev)
{
	struct commit *commit;
215

216 217 218
	if (rev->early_output)
		setup_early_output(rev);

219 220
	if (prepare_revision_walk(rev))
		die("revision walk setup failed");
221 222 223 224

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

225
	/*
226 227 228
	 * 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
229
	 */
230 231
	while ((commit = get_revision(rev)) != NULL) {
		log_tree_commit(rev, commit);
232 233 234 235 236
		if (!rev->reflog_info) {
			/* we allow cycles in reflog ancestry */
			free(commit->buffer);
			commit->buffer = NULL;
		}
L
Linus Torvalds 已提交
237 238
		free_commit_list(commit->parents);
		commit->parents = NULL;
239
	}
240 241 242 243
	if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
	    DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
		return 02;
	}
244
	return diff_result_code(&rev->diffopt, 0);
245 246
}

247
static int git_log_config(const char *var, const char *value, void *cb)
248
{
249 250
	if (!strcmp(var, "format.pretty"))
		return git_config_string(&fmt_pretty, var, value);
251 252
	if (!strcmp(var, "format.subjectprefix"))
		return git_config_string(&fmt_patch_subject_prefix, var, value);
H
Heikki Orsila 已提交
253 254
	if (!strcmp(var, "log.date"))
		return git_config_string(&default_date_mode, var, value);
255 256 257 258
	if (!strcmp(var, "log.showroot")) {
		default_show_root = git_config_bool(var, value);
		return 0;
	}
259
	return git_diff_ui_config(var, value, cb);
260 261
}

262
int cmd_whatchanged(int argc, const char **argv, const char *prefix)
263 264 265
{
	struct rev_info rev;

266
	git_config(git_log_config, NULL);
267 268 269 270

	if (diff_use_color_default == -1)
		diff_use_color_default = git_use_color_default;

271
	init_revisions(&rev, prefix);
272
	rev.diff = 1;
L
Linus Torvalds 已提交
273
	rev.simplify_history = 0;
274
	cmd_log_init(argc, argv, prefix, &rev);
275 276 277
	if (!rev.diffopt.output_format)
		rev.diffopt.output_format = DIFF_FORMAT_RAW;
	return cmd_log_walk(&rev);
278 279
}

280 281
static void show_tagger(char *buf, int len, struct rev_info *rev)
{
282
	struct strbuf out = STRBUF_INIT;
283

284 285 286
	pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode,
		git_log_output_encoding ?
		git_log_output_encoding: git_commit_encoding);
287
	printf("%s", out.buf);
288
	strbuf_release(&out);
289 290 291 292
}

static int show_object(const unsigned char *sha1, int show_tag_object,
	struct rev_info *rev)
293 294
{
	unsigned long size;
295 296
	enum object_type type;
	char *buf = read_sha1_file(sha1, &type, &size);
297 298 299 300 301
	int offset = 0;

	if (!buf)
		return error("Could not read object %s", sha1_to_hex(sha1));

302 303 304
	if (show_tag_object)
		while (offset < size && buf[offset] != '\n') {
			int new_offset = offset + 1;
305 306
			while (new_offset < size && buf[new_offset++] != '\n')
				; /* do nothing */
307 308 309
			if (!prefixcmp(buf + offset, "tagger "))
				show_tagger(buf + offset + 7,
					    new_offset - offset - 7, rev);
310 311 312 313 314 315 316 317 318 319 320
			offset = new_offset;
		}

	if (offset < size)
		fwrite(buf + offset, size - offset, 1, stdout);
	free(buf);
	return 0;
}

static int show_tree_object(const unsigned char *sha1,
		const char *base, int baselen,
321
		const char *pathname, unsigned mode, int stage, void *context)
322 323 324 325 326
{
	printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
	return 0;
}

327
int cmd_show(int argc, const char **argv, const char *prefix)
328 329
{
	struct rev_info rev;
330 331
	struct object_array_entry *objects;
	int i, count, ret = 0;
332

333
	git_config(git_log_config, NULL);
334 335 336 337

	if (diff_use_color_default == -1)
		diff_use_color_default = git_use_color_default;

338
	init_revisions(&rev, prefix);
339 340 341 342 343 344
	rev.diff = 1;
	rev.combine_merges = 1;
	rev.dense_combined_merges = 1;
	rev.always_show_header = 1;
	rev.ignore_merges = 0;
	rev.no_walk = 1;
345
	cmd_log_init(argc, argv, prefix, &rev);
346 347 348 349 350 351 352 353

	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:
354
			ret = show_object(o->sha1, 0, NULL);
355 356 357 358
			break;
		case OBJ_TAG: {
			struct tag *t = (struct tag *)o;

359 360
			if (rev.shown_one)
				putchar('\n');
361
			printf("%stag %s%s\n",
362
					diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
363
					t->tag,
364
					diff_get_color_opt(&rev.diffopt, DIFF_RESET));
365
			ret = show_object(o->sha1, 1, &rev);
366
			rev.shown_one = 1;
367 368 369 370 371 372 373
			if (ret)
				break;
			o = parse_object(t->tagged->sha1);
			if (!o)
				ret = error("Could not read object %s",
					    sha1_to_hex(t->tagged->sha1));
			objects[i].item = o;
374 375 376 377
			i--;
			break;
		}
		case OBJ_TREE:
378 379
			if (rev.shown_one)
				putchar('\n');
380
			printf("%stree %s%s\n\n",
381
					diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
382
					name,
383
					diff_get_color_opt(&rev.diffopt, DIFF_RESET));
384
			read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
385
					show_tree_object, NULL);
386
			rev.shown_one = 1;
387 388 389 390 391 392 393 394 395 396 397 398 399
			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:
			ret = error("Unknown type: %d", o->type);
		}
	}
	free(objects);
	return ret;
400 401
}

L
Linus Torvalds 已提交
402 403 404 405 406 407 408
/*
 * 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;

409
	git_config(git_log_config, NULL);
410 411 412 413

	if (diff_use_color_default == -1)
		diff_use_color_default = git_use_color_default;

L
Linus Torvalds 已提交
414 415 416 417 418 419 420 421 422 423 424 425
	init_revisions(&rev, prefix);
	init_reflog_walk(&rev.reflog_info);
	rev.abbrev_commit = 1;
	rev.verbose_header = 1;
	cmd_log_init(argc, argv, prefix, &rev);

	/*
	 * This means that we override whatever commit format the user gave
	 * on the cmd line.  Sad, but cmd_log_init() currently doesn't
	 * allow us to set a different default.
	 */
	rev.commit_format = CMIT_FMT_ONELINE;
426
	rev.use_terminator = 1;
L
Linus Torvalds 已提交
427 428 429 430 431 432 433 434 435 436 437
	rev.always_show_header = 1;

	/*
	 * We get called through "git reflog", so unlike the other log
	 * routines, we need to set up our pager manually..
	 */
	setup_pager();

	return cmd_log_walk(&rev);
}

438
int cmd_log(int argc, const char **argv, const char *prefix)
439 440 441
{
	struct rev_info rev;

442
	git_config(git_log_config, NULL);
443 444 445 446

	if (diff_use_color_default == -1)
		diff_use_color_default = git_use_color_default;

447
	init_revisions(&rev, prefix);
448
	rev.always_show_header = 1;
449
	cmd_log_init(argc, argv, prefix, &rev);
450
	return cmd_log_walk(&rev);
451
}
452

453
/* format-patch */
454

455
static const char *fmt_patch_suffix = ".patch";
456
static int numbered = 0;
457
static int auto_number = 1;
458

459 460
static char *default_attach = NULL;

D
Daniel Barkalow 已提交
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
static char **extra_hdr;
static int extra_hdr_nr;
static int extra_hdr_alloc;

static char **extra_to;
static int extra_to_nr;
static int extra_to_alloc;

static char **extra_cc;
static int extra_cc_nr;
static int extra_cc_alloc;

static void add_header(const char *value)
{
	int len = strlen(value);
476
	while (len && value[len - 1] == '\n')
D
Daniel Barkalow 已提交
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
		len--;
	if (!strncasecmp(value, "to: ", 4)) {
		ALLOC_GROW(extra_to, extra_to_nr + 1, extra_to_alloc);
		extra_to[extra_to_nr++] = xstrndup(value + 4, len - 4);
		return;
	}
	if (!strncasecmp(value, "cc: ", 4)) {
		ALLOC_GROW(extra_cc, extra_cc_nr + 1, extra_cc_alloc);
		extra_cc[extra_cc_nr++] = xstrndup(value + 4, len - 4);
		return;
	}
	ALLOC_GROW(extra_hdr, extra_hdr_nr + 1, extra_hdr_alloc);
	extra_hdr[extra_hdr_nr++] = xstrndup(value, len);
}

492 493 494
#define THREAD_SHALLOW 1
#define THREAD_DEEP 2
static int thread = 0;
495
static int do_signoff = 0;
496

497
static int git_format_config(const char *var, const char *value, void *cb)
498 499
{
	if (!strcmp(var, "format.headers")) {
500 501
		if (!value)
			die("format.headers without value");
D
Daniel Barkalow 已提交
502
		add_header(value);
503 504
		return 0;
	}
505 506
	if (!strcmp(var, "format.suffix"))
		return git_config_string(&fmt_patch_suffix, var, value);
507 508 509 510 511 512 513
	if (!strcmp(var, "format.cc")) {
		if (!value)
			return config_error_nonbool(var);
		ALLOC_GROW(extra_cc, extra_cc_nr + 1, extra_cc_alloc);
		extra_cc[extra_cc_nr++] = xstrdup(value);
		return 0;
	}
514
	if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
515 516
		return 0;
	}
517
	if (!strcmp(var, "format.numbered")) {
518
		if (value && !strcasecmp(value, "auto")) {
519 520 521 522
			auto_number = 1;
			return 0;
		}
		numbered = git_config_bool(var, value);
523
		auto_number = auto_number && numbered;
524 525
		return 0;
	}
526 527 528 529 530 531 532
	if (!strcmp(var, "format.attach")) {
		if (value && *value)
			default_attach = xstrdup(value);
		else
			default_attach = xstrdup(git_version_string);
		return 0;
	}
533 534 535 536 537 538 539 540 541 542 543 544
	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;
	}
545 546 547 548
	if (!strcmp(var, "format.signoff")) {
		do_signoff = git_config_bool(var, value);
		return 0;
	}
549

550
	return git_log_config(var, value, cb);
551 552
}

553
static FILE *realstdout = NULL;
554
static const char *output_directory = NULL;
555
static int outdir_offset;
556

557
static int reopen_stdout(struct commit *commit, struct rev_info *rev)
558
{
559
	struct strbuf filename = STRBUF_INIT;
560
	int suffix_len = strlen(fmt_patch_suffix) + 1;
561

562
	if (output_directory) {
563 564 565
		strbuf_addstr(&filename, output_directory);
		if (filename.len >=
		    PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len)
566
			return error("name of output directory is too long");
567 568
		if (filename.buf[filename.len - 1] != '/')
			strbuf_addch(&filename, '/');
569
	}
570

571
	get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
572

573
	if (!DIFF_OPT_TST(&rev->diffopt, QUICK))
574
		fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
N
Nate Case 已提交
575

576 577
	if (freopen(filename.buf, "w", stdout) == NULL)
		return error("Cannot open patch file %s", filename.buf);
578

579
	strbuf_release(&filename);
580
	return 0;
581 582
}

583
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
{
	struct rev_info check_rev;
	struct commit *commit;
	struct object *o1, *o2;
	unsigned flags1, flags2;

	if (rev->pending.nr != 2)
		die("Need exactly one range.");

	o1 = rev->pending.objects[0].item;
	flags1 = o1->flags;
	o2 = rev->pending.objects[1].item;
	flags2 = o2->flags;

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

601
	init_patch_ids(ids);
602 603

	/* given a range a..b get all patch ids for b..a */
604
	init_revisions(&check_rev, prefix);
605 606 607 608
	o1->flags ^= UNINTERESTING;
	o2->flags ^= UNINTERESTING;
	add_pending_object(&check_rev, o1, "o1");
	add_pending_object(&check_rev, o2, "o2");
609 610
	if (prepare_revision_walk(&check_rev))
		die("revision walk setup failed");
611 612 613 614 615 616

	while ((commit = get_revision(&check_rev)) != NULL) {
		/* ignore merges */
		if (commit->parents && commit->parents->next)
			continue;

617
		add_commit_patch_id(commit, ids);
618 619 620
	}

	/* reset for next revision walk */
621 622 623 624
	clear_commit_marks((struct commit *)o1,
			SEEN | UNINTERESTING | SHOWN | ADDED);
	clear_commit_marks((struct commit *)o2,
			SEEN | UNINTERESTING | SHOWN | ADDED);
625 626 627 628
	o1->flags = flags1;
	o2->flags = flags2;
}

629
static void gen_message_id(struct rev_info *info, char *base)
630
{
631
	const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME);
632 633
	const char *email_start = strrchr(committer, '<');
	const char *email_end = strrchr(committer, '>');
634
	struct strbuf buf = STRBUF_INIT;
635
	if (!email_start || !email_end || email_start > email_end - 1)
636
		die("Could not extract email from committer identity.");
637 638 639 640
	strbuf_addf(&buf, "%s.%lu.git.%.*s", base,
		    (unsigned long) time(NULL),
		    (int)(email_end - email_start - 1), email_start + 1);
	info->message_id = strbuf_detach(&buf, NULL);
641 642
}

643 644 645 646
static void make_cover_letter(struct rev_info *rev, int use_stdout,
			      int numbered, int numbered_files,
			      struct commit *origin,
			      int nr, struct commit **list, struct commit *head)
647 648 649 650 651 652
{
	const char *committer;
	const char *subject_start = NULL;
	const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n";
	const char *msg;
	const char *extra_headers = rev->extra_headers;
653
	struct shortlog log;
654
	struct strbuf sb = STRBUF_INIT;
655
	int i;
656
	const char *encoding = "UTF-8";
657
	struct diff_options opts;
J
Junio C Hamano 已提交
658
	int need_8bit_cte = 0;
659
	struct commit *commit = NULL;
660 661 662 663

	if (rev->commit_format != CMIT_FMT_EMAIL)
		die("Cover letter needs email format");

664
	committer = git_committer_info(0);
665

666 667 668 669 670 671 672 673 674 675 676 677 678
	if (!numbered_files) {
		/*
		 * We fake a commit for the cover letter so we get the filename
		 * desired.
		 */
		commit = xcalloc(1, sizeof(*commit));
		commit->buffer = xmalloc(400);
		snprintf(commit->buffer, 400,
			"tree 0000000000000000000000000000000000000000\n"
			"parent %s\n"
			"author %s\n"
			"committer %s\n\n"
			"cover letter\n",
679
			sha1_to_hex(head->object.sha1), committer, committer);
680 681 682
	}

	if (!use_stdout && reopen_stdout(commit, rev))
683 684
		return;

685
	if (commit) {
686

687 688 689
		free(commit->buffer);
		free(commit);
	}
690

691
	log_write_email_headers(rev, head, &subject_start, &extra_headers,
J
Junio C Hamano 已提交
692
				&need_8bit_cte);
693

694 695 696 697
	for (i = 0; !need_8bit_cte && i < nr; i++)
		if (has_non_ascii(list[i]->buffer))
			need_8bit_cte = 1;

698 699 700 701
	msg = body;
	pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
		     encoding);
	pp_title_line(CMIT_FMT_EMAIL, &msg, &sb, subject_start, extra_headers,
J
Junio C Hamano 已提交
702
		      encoding, need_8bit_cte);
703 704 705 706 707
	pp_remainder(CMIT_FMT_EMAIL, &msg, &sb, 0);
	printf("%s\n", sb.buf);

	strbuf_release(&sb);

708
	shortlog_init(&log);
709 710 711 712
	log.wrap_lines = 1;
	log.wrap = 72;
	log.in1 = 2;
	log.in2 = 4;
713 714 715 716 717
	for (i = 0; i < nr; i++)
		shortlog_add_commit(&log, list[i]);

	shortlog_output(&log);

718
	/*
719
	 * We can only do diffstat with a unique reference point
720 721 722 723
	 */
	if (!origin)
		return;

724 725
	memcpy(&opts, &rev->diffopt, sizeof(opts));
	opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
726

727 728 729 730 731 732 733
	diff_setup_done(&opts);

	diff_tree_sha1(origin->tree->object.sha1,
		       head->tree->object.sha1,
		       "", &opts);
	diffcore_std(&opts);
	diff_flush(&opts);
734 735

	printf("\n");
736 737
}

738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
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)
		die("insane in-reply-to: %s", msg_id);
	if (++z == m)
		return a;
P
Pierre Habouzit 已提交
757
	return xmemdupz(a, z - a);
758 759
}

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
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));
}

781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
static const char * const builtin_format_patch_usage[] = {
	"git format-patch [options] [<since> | <revision range>]",
	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;
}

805 806
static int numbered_cmdline_opt = 0;

807 808 809
static int numbered_callback(const struct option *opt, const char *arg,
			     int unset)
{
810
	*(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
	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)
		die("Two output directories?");
	*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)
{
	add_header(arg);
	return 0;
}

static int cc_callback(const struct option *opt, const char *arg, int unset)
{
	ALLOC_GROW(extra_cc, extra_cc_nr + 1, extra_cc_alloc);
	extra_cc[extra_cc_nr++] = xstrdup(arg);
	return 0;
}

885
int cmd_format_patch(int argc, const char **argv, const char *prefix)
886 887 888 889
{
	struct commit *commit;
	struct commit **list = NULL;
	struct rev_info rev;
890
	int nr = 0, total, i;
891
	int use_stdout = 0;
892
	int start_number = -1;
893
	int numbered_files = 0;		/* _just_ numbers */
894
	int ignore_if_in_upstream = 0;
895
	int cover_letter = 0;
896
	int boundary_count = 0;
897
	int no_binary_diff = 0;
898
	struct commit *origin = NULL, *head = NULL;
899
	const char *in_reply_to = NULL;
900
	struct patch_ids ids;
J
Junio C Hamano 已提交
901
	char *add_signoff = NULL;
902
	struct strbuf buf = STRBUF_INIT;
903
	int use_patch_format = 0;
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934
	const struct option builtin_format_patch_options[] = {
		{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
			    "use [PATCH n/m] even with a single patch",
			    PARSE_OPT_NOARG, numbered_callback },
		{ OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
			    "use [PATCH] even with multiple patches",
			    PARSE_OPT_NOARG, no_numbered_callback },
		OPT_BOOLEAN('s', "signoff", &do_signoff, "add Signed-off-by:"),
		OPT_BOOLEAN(0, "stdout", &use_stdout,
			    "print patches to standard out"),
		OPT_BOOLEAN(0, "cover-letter", &cover_letter,
			    "generate a cover letter"),
		OPT_BOOLEAN(0, "numbered-files", &numbered_files,
			    "use simple number sequence for output file names"),
		OPT_STRING(0, "suffix", &fmt_patch_suffix, "sfx",
			    "use <sfx> instead of '.patch'"),
		OPT_INTEGER(0, "start-number", &start_number,
			    "start numbering patches at <n> instead of 1"),
		{ OPTION_CALLBACK, 0, "subject-prefix", &rev, "prefix",
			    "Use [<prefix>] instead of [PATCH]",
			    PARSE_OPT_NONEG, subject_prefix_callback },
		{ OPTION_CALLBACK, 'o', "output-directory", &output_directory,
			    "dir", "store resulting files in <dir>",
			    PARSE_OPT_NONEG, output_directory_callback },
		{ OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL,
			    "don't strip/add [PATCH]",
			    PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
		OPT_BOOLEAN(0, "no-binary", &no_binary_diff,
			    "don't output binary diffs"),
		OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
			    "don't include a patch matching a commit upstream"),
935 936 937
		{ OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
		  "show patch format instead of default (patch + stat)",
		  PARSE_OPT_NONEG | PARSE_OPT_NOARG },
938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
		OPT_GROUP("Messaging"),
		{ OPTION_CALLBACK, 0, "add-header", NULL, "header",
			    "add email header", PARSE_OPT_NONEG,
			    header_callback },
		{ OPTION_CALLBACK, 0, "cc", NULL, "email", "add Cc: header",
			    PARSE_OPT_NONEG, cc_callback },
		OPT_STRING(0, "in-reply-to", &in_reply_to, "message-id",
			    "make first mail a reply to <message-id>"),
		{ OPTION_CALLBACK, 0, "attach", &rev, "boundary",
			    "attach the patch", PARSE_OPT_OPTARG,
			    attach_callback },
		{ OPTION_CALLBACK, 0, "inline", &rev, "boundary",
			    "inline the patch",
			    PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
			    inline_callback },
		{ OPTION_CALLBACK, 0, "thread", &thread, "style",
			    "enable message threading, styles: shallow, deep",
			    PARSE_OPT_OPTARG, thread_callback },
		OPT_END()
	};
958

959
	git_config(git_format_config, NULL);
960
	init_revisions(&rev, prefix);
961 962 963 964 965
	rev.commit_format = CMIT_FMT_EMAIL;
	rev.verbose_header = 1;
	rev.diff = 1;
	rev.combine_merges = 0;
	rev.ignore_merges = 1;
966
	DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
967

968
	rev.subject_prefix = fmt_patch_subject_prefix;
969

970 971 972 973 974
	if (default_attach) {
		rev.mime_boundary = default_attach;
		rev.no_inline = 1;
	}

975 976
	/*
	 * Parse the arguments before setup_revisions(), or something
977
	 * like "git format-patch -o a123 HEAD^.." may fail; a123 is
978 979
	 * possibly a valid SHA1.
	 */
980
	argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
981
			     builtin_format_patch_usage,
982 983
			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
			     PARSE_OPT_KEEP_DASHDASH);
984

985 986 987 988 989 990 991 992 993 994
	if (do_signoff) {
		const char *committer;
		const char *endpos;
		committer = git_committer_info(IDENT_ERROR_ON_NO_NAME);
		endpos = strchr(committer, '>');
		if (!endpos)
			die("bogus committer info %s", committer);
		add_signoff = xmemdupz(committer, endpos - committer + 1);
	}

D
Daniel Barkalow 已提交
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
	for (i = 0; i < extra_hdr_nr; i++) {
		strbuf_addstr(&buf, extra_hdr[i]);
		strbuf_addch(&buf, '\n');
	}

	if (extra_to_nr)
		strbuf_addstr(&buf, "To: ");
	for (i = 0; i < extra_to_nr; i++) {
		if (i)
			strbuf_addstr(&buf, "    ");
		strbuf_addstr(&buf, extra_to[i]);
		if (i + 1 < extra_to_nr)
			strbuf_addch(&buf, ',');
		strbuf_addch(&buf, '\n');
	}

	if (extra_cc_nr)
		strbuf_addstr(&buf, "Cc: ");
	for (i = 0; i < extra_cc_nr; i++) {
		if (i)
			strbuf_addstr(&buf, "    ");
		strbuf_addstr(&buf, extra_cc[i]);
		if (i + 1 < extra_cc_nr)
			strbuf_addch(&buf, ',');
		strbuf_addch(&buf, '\n');
	}

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

1024
	if (start_number < 0)
1025
		start_number = 1;
1026 1027 1028 1029 1030 1031 1032 1033 1034

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

1035
	if (numbered && keep_subject)
1036
		die ("-n and -k are mutually exclusive.");
1037 1038
	if (keep_subject && subject_prefix)
		die ("--subject-prefix and -k are mutually exclusive.");
1039

1040 1041 1042
	argc = setup_revisions(argc, argv, &rev, "HEAD");
	if (argc > 1)
		die ("unrecognized argument: %s", argv[1]);
1043

1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
	if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
		die("--name-only does not make sense");
	if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
		die("--name-status does not make sense");
	if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
		die("--check does not make sense");

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

1059
	if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
1060
		DIFF_OPT_SET(&rev.diffopt, BINARY);
1061

1062 1063
	if (!use_stdout)
		output_directory = set_outdir(prefix, output_directory);
1064

1065 1066 1067 1068
	if (output_directory) {
		if (use_stdout)
			die("standard output, or directory, which one?");
		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
1069 1070
			die_errno("Could not create directory '%s'",
				  output_directory);
1071 1072
	}

1073
	if (rev.pending.nr == 1) {
1074 1075 1076 1077 1078 1079
		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 已提交
1080
			rev.pending.objects[0].item->flags |= UNINTERESTING;
1081
			add_head_to_pending(&rev);
J
Junio C Hamano 已提交
1082
		}
1083 1084 1085 1086
		/*
		 * 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 已提交
1087
		 */
1088
	}
1089 1090 1091 1092 1093 1094 1095

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

1096 1097 1098 1099 1100
	if (cover_letter) {
		/* remember the range */
		int i;
		for (i = 0; i < rev.pending.nr; i++) {
			struct object *o = rev.pending.objects[i].item;
1101
			if (!(o->flags & UNINTERESTING))
1102 1103 1104 1105 1106 1107
				head = (struct commit *)o;
		}
		/* We can't generate a cover letter without any patches */
		if (!head)
			return 0;
	}
1108

1109
	if (ignore_if_in_upstream)
1110
		get_patch_ids(&rev, &ids, prefix);
1111

1112
	if (!use_stdout)
1113
		realstdout = xfdopen(xdup(1), "w");
1114

1115 1116
	if (prepare_revision_walk(&rev))
		die("revision walk setup failed");
1117
	rev.boundary = 1;
1118
	while ((commit = get_revision(&rev)) != NULL) {
1119 1120 1121 1122 1123 1124
		if (commit->object.flags & BOUNDARY) {
			boundary_count++;
			origin = (boundary_count == 1) ? commit : NULL;
			continue;
		}

1125 1126 1127
		/* ignore merges */
		if (commit->parents && commit->parents->next)
			continue;
1128 1129

		if (ignore_if_in_upstream &&
1130
				has_commit_patch_id(commit, &ids))
1131 1132
			continue;

1133
		nr++;
J
Jonas Fonseca 已提交
1134
		list = xrealloc(list, nr * sizeof(list[0]));
1135 1136
		list[nr - 1] = commit;
	}
1137
	total = nr;
1138 1139
	if (!keep_subject && auto_number && total > 1)
		numbered = 1;
1140
	if (numbered)
1141
		rev.total = total + start_number - 1;
1142 1143 1144 1145 1146 1147
	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);
		string_list_append(msgid, rev.ref_message_ids);
	}
1148 1149
	rev.numbered_files = numbered_files;
	rev.patch_suffix = fmt_patch_suffix;
1150 1151 1152 1153
	if (cover_letter) {
		if (thread)
			gen_message_id(&rev, "cover");
		make_cover_letter(&rev, use_stdout, numbered, numbered_files,
1154
				  origin, nr, list, head);
1155 1156 1157 1158
		total++;
		start_number--;
	}
	rev.add_signoff = add_signoff;
1159 1160 1161
	while (0 <= --nr) {
		int shown;
		commit = list[nr];
1162
		rev.nr = total - nr + (start_number - 1);
1163
		/* Make the second and subsequent mails replies to the first */
1164
		if (thread) {
1165
			/* Have we already had a message ID? */
1166
			if (rev.message_id) {
1167
				/*
1168 1169 1170 1171 1172 1173
				 * For deep threading: make every mail
				 * a reply to the previous one, no
				 * matter what other options are set.
				 *
				 * For shallow threading:
				 *
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
				 * 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.
1187
				 */
1188 1189
				if (thread == THREAD_SHALLOW
				    && rev.ref_message_ids->nr > 0
1190
				    && (!cover_letter || rev.nr > 1))
1191 1192
					free(rev.message_id);
				else
1193 1194
					string_list_append(rev.message_id,
							   rev.ref_message_ids);
1195
			}
1196
			gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
1197
		}
1198

1199 1200
		if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit,
						 &rev))
1201
			die("Failed to create output files");
1202 1203 1204
		shown = log_tree_commit(&rev, commit);
		free(commit->buffer);
		commit->buffer = NULL;
1205 1206 1207 1208 1209 1210 1211 1212 1213

		/* 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;
1214 1215 1216 1217 1218 1219 1220 1221
		if (shown) {
			if (rev.mime_boundary)
				printf("\n--%s%s--\n\n\n",
				       mime_boundary_leader,
				       rev.mime_boundary);
			else
				printf("-- \n%s\n\n", git_version_string);
		}
1222 1223
		if (!use_stdout)
			fclose(stdout);
1224 1225
	}
	free(list);
1226 1227
	if (ignore_if_in_upstream)
		free_patch_ids(&ids);
1228 1229 1230
	return 0;
}

R
Rene Scharfe 已提交
1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
{
	unsigned char sha1[20];
	if (get_sha1(arg, sha1) == 0) {
		struct commit *commit = lookup_commit_reference(sha1);
		if (commit) {
			commit->object.flags |= flags;
			add_pending_object(revs, &commit->object, arg);
			return 0;
		}
	}
	return -1;
}

static const char cherry_usage[] =
1246
"git cherry [-v] [<upstream> [<head> [<limit>]]]";
R
Rene Scharfe 已提交
1247 1248 1249
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
	struct rev_info revs;
1250
	struct patch_ids ids;
R
Rene Scharfe 已提交
1251 1252
	struct commit *commit;
	struct commit_list *list = NULL;
1253
	struct branch *current_branch;
R
Rene Scharfe 已提交
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264
	const char *upstream;
	const char *head = "HEAD";
	const char *limit = NULL;
	int verbose = 0;

	if (argc > 1 && !strcmp(argv[1], "-v")) {
		verbose = 1;
		argc--;
		argv++;
	}

1265 1266 1267
	if (argc > 1 && !strcmp(argv[1], "-h"))
		usage(cherry_usage);

R
Rene Scharfe 已提交
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
	switch (argc) {
	case 4:
		limit = argv[3];
		/* FALLTHROUGH */
	case 3:
		head = argv[2];
		/* FALLTHROUGH */
	case 2:
		upstream = argv[1];
		break;
	default:
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
		current_branch = branch_get(NULL);
		if (!current_branch || !current_branch->merge
					|| !current_branch->merge[0]
					|| !current_branch->merge[0]->dst) {
			fprintf(stderr, "Could not find a tracked"
					" remote branch, please"
					" specify <upstream> manually.\n");
			usage(cherry_usage);
		}

		upstream = current_branch->merge[0]->dst;
R
Rene Scharfe 已提交
1290 1291 1292 1293 1294 1295
	}

	init_revisions(&revs, prefix);
	revs.diff = 1;
	revs.combine_merges = 0;
	revs.ignore_merges = 1;
1296
	DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
R
Rene Scharfe 已提交
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309

	if (add_pending_commit(head, &revs, 0))
		die("Unknown commit %s", head);
	if (add_pending_commit(upstream, &revs, UNINTERESTING))
		die("Unknown commit %s", upstream);

	/* Don't say anything if head and upstream are the same. */
	if (revs.pending.nr == 2) {
		struct object_array_entry *o = revs.pending.objects;
		if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
			return 0;
	}

1310
	get_patch_ids(&revs, &ids, prefix);
R
Rene Scharfe 已提交
1311 1312 1313 1314 1315

	if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
		die("Unknown commit %s", limit);

	/* reverse the list of commits */
1316 1317
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
R
Rene Scharfe 已提交
1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329
	while ((commit = get_revision(&revs)) != NULL) {
		/* ignore merges */
		if (commit->parents && commit->parents->next)
			continue;

		commit_list_insert(commit, &list);
	}

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

		commit = list->item;
1330
		if (has_commit_patch_id(commit, &ids))
R
Rene Scharfe 已提交
1331 1332 1333
			sign = '-';

		if (verbose) {
1334
			struct strbuf buf = STRBUF_INIT;
1335
			struct pretty_print_context ctx = {0};
1336
			pretty_print_commit(CMIT_FMT_ONELINE, commit,
1337
					    &buf, &ctx);
R
Rene Scharfe 已提交
1338
			printf("%c %s %s\n", sign,
1339 1340
			       sha1_to_hex(commit->object.sha1), buf.buf);
			strbuf_release(&buf);
R
Rene Scharfe 已提交
1341 1342 1343 1344 1345 1346 1347 1348 1349
		}
		else {
			printf("%c %s\n", sign,
			       sha1_to_hex(commit->object.sha1));
		}

		list = list->next;
	}

1350
	free_patch_ids(&ids);
R
Rene Scharfe 已提交
1351 1352
	return 0;
}