builtin-log.c 26.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 * Builtin "git log" and related commands (show, whatchanged)
 *
 * (C) Copyright 2006 Linus Torvalds
 *		 2006 Junio Hamano
 */
#include "cache.h"
#include "commit.h"
#include "diff.h"
#include "revision.h"
#include "log-tree.h"
12
#include "builtin.h"
13
#include "tag.h"
L
Linus Torvalds 已提交
14
#include "reflog-walk.h"
15
#include "patch-ids.h"
16
#include "refs.h"
17
#include "run-command.h"
18

19
static int default_show_root = 1;
20
static const char *fmt_patch_subject_prefix = "PATCH";
21

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
static void add_name_decoration(const char *prefix, const char *name, struct object *obj)
{
	int plen = strlen(prefix);
	int nlen = strlen(name);
	struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + plen + nlen);
	memcpy(res->name, prefix, plen);
	memcpy(res->name + plen, name, nlen + 1);
	res->next = add_decoration(&name_decoration, obj, res);
}

static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
	struct object *obj = parse_object(sha1);
	if (!obj)
		return 0;
	add_name_decoration("", refname, obj);
	while (obj->type == OBJ_TAG) {
		obj = ((struct tag *)obj)->tagged;
		if (!obj)
			break;
		add_name_decoration("tag: ", refname, obj);
	}
	return 0;
}

47
static void cmd_log_init(int argc, const char **argv, const char *prefix,
48 49
		      struct rev_info *rev)
{
J
Junio C Hamano 已提交
50
	int i;
51
	int decorate = 0;
J
Junio C Hamano 已提交
52

53 54 55
	rev->abbrev = DEFAULT_ABBREV;
	rev->commit_format = CMIT_FMT_DEFAULT;
	rev->verbose_header = 1;
56
	DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
57
	rev->show_root_diff = default_show_root;
58
	rev->subject_prefix = fmt_patch_subject_prefix;
59
	argc = setup_revisions(argc, argv, rev, "HEAD");
60 61
	if (rev->diffopt.pickaxe || rev->diffopt.filter)
		rev->always_show_header = 0;
62
	if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
63 64 65 66
		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 已提交
67 68
	for (i = 1; i < argc; i++) {
		const char *arg = argv[i];
69
		if (!strcmp(arg, "--decorate")) {
70 71 72 73
			if (!decorate)
				for_each_ref(add_ref_decoration, NULL);
			decorate = 1;
		} else
J
Junio C Hamano 已提交
74 75
			die("unrecognized argument: %s", arg);
	}
76 77
}

L
Linus Torvalds 已提交
78 79 80 81 82 83 84 85 86 87 88 89
/*
 * 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;
90
		if (!(flags & (TREESAME | UNINTERESTING)))
L
Linus Torvalds 已提交
91
			n++;
L
Linus Torvalds 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
	}
	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);
}

struct itimerval early_output_timer;

108 109 110
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
	int i = revs->early_output;
L
Linus Torvalds 已提交
111
	int show_header = 1;
112 113 114 115

	sort_in_topological_order(&list, revs->lifo);
	while (list && i) {
		struct commit *commit = list->item;
L
Linus Torvalds 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
		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;
		}
131 132
		list = list->next;
	}
L
Linus Torvalds 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150

	/* 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);
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
}

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 已提交
182 183 184
	early_output_timer.it_value.tv_sec = 0;
	early_output_timer.it_value.tv_usec = 100000;
	setitimer(ITIMER_REAL, &early_output_timer, NULL);
185 186 187 188
}

static void finish_early_output(struct rev_info *rev)
{
L
Linus Torvalds 已提交
189
	int n = estimate_commit_count(rev, rev->commits);
190
	signal(SIGALRM, SIG_IGN);
L
Linus Torvalds 已提交
191
	show_early_header(rev, "done", n);
192 193
}

194 195 196
static int cmd_log_walk(struct rev_info *rev)
{
	struct commit *commit;
197

198 199 200
	if (rev->early_output)
		setup_early_output(rev);

201
	prepare_revision_walk(rev);
202 203 204 205

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

206 207
	while ((commit = get_revision(rev)) != NULL) {
		log_tree_commit(rev, commit);
208 209 210 211 212
		if (!rev->reflog_info) {
			/* we allow cycles in reflog ancestry */
			free(commit->buffer);
			commit->buffer = NULL;
		}
L
Linus Torvalds 已提交
213 214
		free_commit_list(commit->parents);
		commit->parents = NULL;
215 216 217 218
	}
	return 0;
}

219 220
static int git_log_config(const char *var, const char *value)
{
221 222
	if (!strcmp(var, "format.subjectprefix")) {
		if (!value)
223
			config_error_nonbool(var);
224 225 226
		fmt_patch_subject_prefix = xstrdup(value);
		return 0;
	}
227 228 229 230 231 232 233
	if (!strcmp(var, "log.showroot")) {
		default_show_root = git_config_bool(var, value);
		return 0;
	}
	return git_diff_ui_config(var, value);
}

234
int cmd_whatchanged(int argc, const char **argv, const char *prefix)
235 236 237
{
	struct rev_info rev;

238
	git_config(git_log_config);
239
	init_revisions(&rev, prefix);
240
	rev.diff = 1;
L
Linus Torvalds 已提交
241
	rev.simplify_history = 0;
242
	cmd_log_init(argc, argv, prefix, &rev);
243 244 245
	if (!rev.diffopt.output_format)
		rev.diffopt.output_format = DIFF_FORMAT_RAW;
	return cmd_log_walk(&rev);
246 247
}

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
static void show_tagger(char *buf, int len, struct rev_info *rev)
{
	char *email_end, *p;
	unsigned long date;
	int tz;

	email_end = memchr(buf, '>', len);
	if (!email_end)
		return;
	p = ++email_end;
	while (isspace(*p))
		p++;
	date = strtoul(p, &p, 10);
	while (isspace(*p))
		p++;
	tz = (int)strtol(p, NULL, 10);
	printf("Tagger: %.*s\nDate:   %s\n", (int)(email_end - buf), buf,
	       show_date(date, tz, rev->date_mode));
}

static int show_object(const unsigned char *sha1, int show_tag_object,
	struct rev_info *rev)
270 271
{
	unsigned long size;
272 273
	enum object_type type;
	char *buf = read_sha1_file(sha1, &type, &size);
274 275 276 277 278
	int offset = 0;

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

279 280 281
	if (show_tag_object)
		while (offset < size && buf[offset] != '\n') {
			int new_offset = offset + 1;
282 283
			while (new_offset < size && buf[new_offset++] != '\n')
				; /* do nothing */
284 285 286
			if (!prefixcmp(buf + offset, "tagger "))
				show_tagger(buf + offset + 7,
					    new_offset - offset - 7, rev);
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
			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,
		const char *pathname, unsigned mode, int stage)
{
	printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
	return 0;
}

304
int cmd_show(int argc, const char **argv, const char *prefix)
305 306
{
	struct rev_info rev;
307 308
	struct object_array_entry *objects;
	int i, count, ret = 0;
309

310
	git_config(git_log_config);
311
	init_revisions(&rev, prefix);
312 313 314 315 316 317
	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;
318
	cmd_log_init(argc, argv, prefix, &rev);
319 320 321 322 323 324 325 326

	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:
327
			ret = show_object(o->sha1, 0, NULL);
328 329 330 331
			break;
		case OBJ_TAG: {
			struct tag *t = (struct tag *)o;

332
			printf("%stag %s%s\n",
333
					diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
334
					t->tag,
335
					diff_get_color_opt(&rev.diffopt, DIFF_RESET));
336
			ret = show_object(o->sha1, 1, &rev);
337 338 339 340 341 342
			objects[i].item = (struct object *)t->tagged;
			i--;
			break;
		}
		case OBJ_TREE:
			printf("%stree %s%s\n\n",
343
					diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
344
					name,
345
					diff_get_color_opt(&rev.diffopt, DIFF_RESET));
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
			read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
					show_tree_object);
			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;
361 362
}

L
Linus Torvalds 已提交
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
/*
 * 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;

	git_config(git_log_config);
	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;
	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);
}

394
int cmd_log(int argc, const char **argv, const char *prefix)
395 396 397
{
	struct rev_info rev;

398
	git_config(git_log_config);
399
	init_revisions(&rev, prefix);
400
	rev.always_show_header = 1;
401
	cmd_log_init(argc, argv, prefix, &rev);
402
	return cmd_log_walk(&rev);
403
}
404

405 406 407
/* format-patch */
#define FORMAT_PATCH_NAME_MAX 64

408 409 410 411 412 413
static int istitlechar(char c)
{
	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
		(c >= '0' && c <= '9') || c == '.' || c == '_';
}

414 415
static char *extra_headers = NULL;
static int extra_headers_size = 0;
416
static const char *fmt_patch_suffix = ".patch";
417 418
static int numbered = 0;
static int auto_number = 0;
419 420 421 422

static int git_format_config(const char *var, const char *value)
{
	if (!strcmp(var, "format.headers")) {
423 424 425 426 427
		int len;

		if (!value)
			die("format.headers without value");
		len = strlen(value);
428 429 430
		while (value[len - 1] == '\n')
			len--;
		extra_headers_size += len + 2;
J
Jonas Fonseca 已提交
431
		extra_headers = xrealloc(extra_headers, extra_headers_size);
432
		extra_headers[extra_headers_size - len - 2] = 0;
433
		strcat(extra_headers, value);
434 435
		extra_headers[extra_headers_size - 2] = '\n';
		extra_headers[extra_headers_size - 1] = 0;
436 437
		return 0;
	}
438 439
	if (!strcmp(var, "format.suffix")) {
		if (!value)
440
			return config_error_nonbool(var);
441 442 443
		fmt_patch_suffix = xstrdup(value);
		return 0;
	}
444
	if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
445 446
		return 0;
	}
447
	if (!strcmp(var, "format.numbered")) {
448
		if (value && !strcasecmp(value, "auto")) {
449 450 451 452 453 454
			auto_number = 1;
			return 0;
		}
		numbered = git_config_bool(var, value);
		return 0;
	}
455

456
	return git_log_config(var, value);
457 458 459
}


460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
static const char *get_oneline_for_filename(struct commit *commit,
					    int keep_subject)
{
	static char filename[PATH_MAX];
	char *sol;
	int len = 0;
	int suffix_len = strlen(fmt_patch_suffix) + 1;

	sol = strstr(commit->buffer, "\n\n");
	if (!sol)
		filename[0] = '\0';
	else {
		int j, space = 0;

		sol += 2;
		/* strip [PATCH] or [PATCH blabla] */
		if (!keep_subject && !prefixcmp(sol, "[PATCH")) {
			char *eos = strchr(sol + 6, ']');
			if (eos) {
				while (isspace(*eos))
					eos++;
				sol = eos;
			}
		}

		for (j = 0;
		     j < FORMAT_PATCH_NAME_MAX - suffix_len - 5 &&
			     len < sizeof(filename) - suffix_len &&
			     sol[j] && sol[j] != '\n';
		     j++) {
			if (istitlechar(sol[j])) {
				if (space) {
					filename[len++] = '-';
					space = 0;
				}
				filename[len++] = sol[j];
				if (sol[j] == '.')
					while (sol[j + 1] == '.')
						j++;
			} else
				space = 1;
		}
		while (filename[len - 1] == '.'
		       || filename[len - 1] == '-')
			len--;
		filename[len] = '\0';
	}
	return filename;
}

510
static FILE *realstdout = NULL;
511
static const char *output_directory = NULL;
512

513
static int reopen_stdout(const char *oneline, int nr, int total)
514
{
515
	char filename[PATH_MAX];
516
	int len = 0;
517
	int suffix_len = strlen(fmt_patch_suffix) + 1;
518

519
	if (output_directory) {
520 521 522
		len = snprintf(filename, sizeof(filename), "%s",
				output_directory);
		if (len >=
523 524
		    sizeof(filename) - FORMAT_PATCH_NAME_MAX - suffix_len)
			return error("name of output directory is too long");
525 526 527
		if (filename[len - 1] != '/')
			filename[len++] = '/';
	}
528

529 530 531 532 533 534
	if (!oneline)
		len += sprintf(filename + len, "%d", nr);
	else {
		len += sprintf(filename + len, "%04d-", nr);
		len += snprintf(filename + len, sizeof(filename) - len - 1
				- suffix_len, "%s", oneline);
535
		strcpy(filename + len, fmt_patch_suffix);
536
	}
537

538
	fprintf(realstdout, "%s\n", filename);
539 540 541
	if (freopen(filename, "w", stdout) == NULL)
		return error("Cannot open patch file %s",filename);

542
	return 0;
543 544
}

545
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
{
	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.");

563
	init_patch_ids(ids);
564 565

	/* given a range a..b get all patch ids for b..a */
566
	init_revisions(&check_rev, prefix);
567 568 569 570 571 572 573 574 575 576 577
	o1->flags ^= UNINTERESTING;
	o2->flags ^= UNINTERESTING;
	add_pending_object(&check_rev, o1, "o1");
	add_pending_object(&check_rev, o2, "o2");
	prepare_revision_walk(&check_rev);

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

578
		add_commit_patch_id(commit, ids);
579 580 581
	}

	/* reset for next revision walk */
582 583 584 585
	clear_commit_marks((struct commit *)o1,
			SEEN | UNINTERESTING | SHOWN | ADDED);
	clear_commit_marks((struct commit *)o2,
			SEEN | UNINTERESTING | SHOWN | ADDED);
586 587 588 589
	o1->flags = flags1;
	o2->flags = flags2;
}

590
static void gen_message_id(struct rev_info *info, char *base)
591
{
592
	const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME);
593 594
	const char *email_start = strrchr(committer, '<');
	const char *email_end = strrchr(committer, '>');
595 596
	struct strbuf buf;
	if (!email_start || !email_end || email_start > email_end - 1)
597
		die("Could not extract email from committer identity.");
598 599 600 601 602
	strbuf_init(&buf, 0);
	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);
603 604
}

605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
static void make_cover_letter(struct rev_info *rev,
		int use_stdout, int numbered, int numbered_files,
			      struct commit *origin, struct commit *head)
{
	const char *committer;
	const char *origin_sha1, *head_sha1;
	const char *argv[7];
	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;
	struct strbuf sb;
	const char *encoding = "utf-8";

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

	if (!use_stdout && reopen_stdout(numbered_files ?
				NULL : "cover-letter", 0, rev->total))
		return;

	origin_sha1 = sha1_to_hex(origin ? origin->object.sha1 : null_sha1);
	head_sha1 = sha1_to_hex(head->object.sha1);

	log_write_email_headers(rev, head_sha1, &subject_start, &extra_headers);

	committer = git_committer_info(0);

	msg = body;
	strbuf_init(&sb, 0);
	pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
		     encoding);
	pp_title_line(CMIT_FMT_EMAIL, &msg, &sb, subject_start, extra_headers,
		      encoding, 0);
	pp_remainder(CMIT_FMT_EMAIL, &msg, &sb, 0);
	printf("%s\n", sb.buf);

	strbuf_release(&sb);

	/*
	 * We can only do diffstat with a unique reference point, and
	 * log is a bit tricky, so just skip it.
	 */
	if (!origin)
		return;

	argv[0] = "shortlog";
	argv[1] = head_sha1;
	argv[2] = "--not";
	argv[3] = origin_sha1;
	argv[4] = "--";
	argv[5] = NULL;
	fflush(stdout);
	run_command_v_opt(argv, RUN_GIT_CMD);

	argv[0] = "diff";
	argv[1] = "--stat";
	argv[2] = "--summary";
	argv[3] = head_sha1;
	argv[4] = "--not";
	argv[5] = origin_sha1;
	argv[6] = "--";
	argv[7] = NULL;
	fflush(stdout);
	run_command_v_opt(argv, RUN_GIT_CMD);

	fflush(stdout);
	printf("\n");
}

675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
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 已提交
694
	return xmemdupz(a, z - a);
695 696
}

697
int cmd_format_patch(int argc, const char **argv, const char *prefix)
698 699 700 701
{
	struct commit *commit;
	struct commit **list = NULL;
	struct rev_info rev;
702
	int nr = 0, total, i, j;
703
	int use_stdout = 0;
704
	int start_number = -1;
705
	int keep_subject = 0;
706
	int numbered_files = 0;		/* _just_ numbers */
707
	int subject_prefix = 0;
708
	int ignore_if_in_upstream = 0;
709
	int thread = 0;
710 711
	int cover_letter = 0;
	struct commit *origin = NULL, *head = NULL;
712
	const char *in_reply_to = NULL;
713
	struct patch_ids ids;
J
Junio C Hamano 已提交
714
	char *add_signoff = NULL;
715

716
	git_config(git_format_config);
717
	init_revisions(&rev, prefix);
718 719 720 721 722
	rev.commit_format = CMIT_FMT_EMAIL;
	rev.verbose_header = 1;
	rev.diff = 1;
	rev.combine_merges = 0;
	rev.ignore_merges = 1;
723
	rev.diffopt.msg_sep = "";
724
	DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
725

726
	rev.subject_prefix = fmt_patch_subject_prefix;
727 728
	rev.extra_headers = extra_headers;

729 730
	/*
	 * Parse the arguments before setup_revisions(), or something
731
	 * like "git format-patch -o a123 HEAD^.." may fail; a123 is
732 733 734 735
	 * possibly a valid SHA1.
	 */
	for (i = 1, j = 1; i < argc; i++) {
		if (!strcmp(argv[i], "--stdout"))
736
			use_stdout = 1;
737 738 739
		else if (!strcmp(argv[i], "-n") ||
				!strcmp(argv[i], "--numbered"))
			numbered = 1;
740 741 742 743 744
		else if (!strcmp(argv[i], "-N") ||
				!strcmp(argv[i], "--no-numbered")) {
			numbered = 0;
			auto_number = 0;
		}
745
		else if (!prefixcmp(argv[i], "--start-number="))
746
			start_number = strtol(argv[i] + 15, NULL, 10);
747 748
		else if (!strcmp(argv[i], "--numbered-files"))
			numbered_files = 1;
749 750 751 752 753
		else if (!strcmp(argv[i], "--start-number")) {
			i++;
			if (i == argc)
				die("Need a number for --start-number");
			start_number = strtol(argv[i], NULL, 10);
J
Junio C Hamano 已提交
754 755
		}
		else if (!strcmp(argv[i], "-k") ||
756 757 758
				!strcmp(argv[i], "--keep-subject")) {
			keep_subject = 1;
			rev.total = -1;
J
Junio C Hamano 已提交
759
		}
760 761
		else if (!strcmp(argv[i], "--output-directory") ||
			 !strcmp(argv[i], "-o")) {
762
			i++;
763 764 765 766 767
			if (argc <= i)
				die("Which directory?");
			if (output_directory)
				die("Two output directories?");
			output_directory = argv[i];
768
		}
J
Junio C Hamano 已提交
769 770
		else if (!strcmp(argv[i], "--signoff") ||
			 !strcmp(argv[i], "-s")) {
E
Eric W. Biederman 已提交
771 772
			const char *committer;
			const char *endpos;
773
			committer = git_committer_info(IDENT_ERROR_ON_NO_NAME);
E
Eric W. Biederman 已提交
774
			endpos = strchr(committer, '>');
J
Junio C Hamano 已提交
775 776
			if (!endpos)
				die("bogos committer info %s\n", committer);
P
Pierre Habouzit 已提交
777
			add_signoff = xmemdupz(committer, endpos - committer + 1);
J
Junio C Hamano 已提交
778
		}
779
		else if (!strcmp(argv[i], "--attach")) {
780
			rev.mime_boundary = git_version_string;
781 782 783 784 785 786 787 788 789 790 791
			rev.no_inline = 1;
		}
		else if (!prefixcmp(argv[i], "--attach=")) {
			rev.mime_boundary = argv[i] + 9;
			rev.no_inline = 1;
		}
		else if (!strcmp(argv[i], "--inline")) {
			rev.mime_boundary = git_version_string;
			rev.no_inline = 0;
		}
		else if (!prefixcmp(argv[i], "--inline=")) {
792
			rev.mime_boundary = argv[i] + 9;
793 794
			rev.no_inline = 0;
		}
795 796
		else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
			ignore_if_in_upstream = 1;
797 798
		else if (!strcmp(argv[i], "--thread"))
			thread = 1;
799
		else if (!prefixcmp(argv[i], "--in-reply-to="))
800 801 802 803 804 805
			in_reply_to = argv[i] + 14;
		else if (!strcmp(argv[i], "--in-reply-to")) {
			i++;
			if (i == argc)
				die("Need a Message-Id for --in-reply-to");
			in_reply_to = argv[i];
806 807 808 809
		} else if (!prefixcmp(argv[i], "--subject-prefix=")) {
			subject_prefix = 1;
			rev.subject_prefix = argv[i] + 17;
		} else if (!prefixcmp(argv[i], "--suffix="))
810
			fmt_patch_suffix = argv[i] + 9;
811 812
		else if (!strcmp(argv[i], "--cover-letter"))
			cover_letter = 1;
813
		else
814
			argv[j++] = argv[i];
815
	}
816 817
	argc = j;

818
	if (start_number < 0)
819
		start_number = 1;
820
	if (numbered && keep_subject)
821
		die ("-n and -k are mutually exclusive.");
822 823
	if (keep_subject && subject_prefix)
		die ("--subject-prefix and -k are mutually exclusive.");
824 825
	if (numbered_files && use_stdout)
		die ("--numbered-files and --stdout are mutually exclusive.");
826

827 828 829
	argc = setup_revisions(argc, argv, &rev, "HEAD");
	if (argc > 1)
		die ("unrecognized argument: %s", argv[1]);
830

831
	if (!rev.diffopt.output_format)
832
		rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
833

834 835
	if (!DIFF_OPT_TST(&rev.diffopt, TEXT))
		DIFF_OPT_SET(&rev.diffopt, BINARY);
836

837
	if (!output_directory && !use_stdout)
838 839
		output_directory = prefix;

840 841 842 843 844 845 846 847
	if (output_directory) {
		if (use_stdout)
			die("standard output, or directory, which one?");
		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
			die("Could not create directory %s",
			    output_directory);
	}

848
	if (rev.pending.nr == 1) {
849 850 851 852 853 854
		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 已提交
855
			rev.pending.objects[0].item->flags |= UNINTERESTING;
856
			add_head_to_pending(&rev);
J
Junio C Hamano 已提交
857
		}
858 859 860 861
		/*
		 * 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 已提交
862
		 */
863
	}
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
	if (cover_letter) {
		/* remember the range */
		int negative_count = 0;
		int i;
		for (i = 0; i < rev.pending.nr; i++) {
			struct object *o = rev.pending.objects[i].item;
			if (o->flags & UNINTERESTING) {
				origin = (struct commit *)o;
				negative_count++;
			} else
				head = (struct commit *)o;
		}
		/* Multiple origins don't work for diffstat. */
		if (negative_count > 1)
			origin = NULL;
		/* We can't generate a cover letter without any patches */
		if (!head)
			return 0;
	}
883

884
	if (ignore_if_in_upstream)
885
		get_patch_ids(&rev, &ids, prefix);
886

887
	if (!use_stdout)
888
		realstdout = xfdopen(xdup(1), "w");
889

890 891
	prepare_revision_walk(&rev);
	while ((commit = get_revision(&rev)) != NULL) {
892 893 894
		/* ignore merges */
		if (commit->parents && commit->parents->next)
			continue;
895 896

		if (ignore_if_in_upstream &&
897
				has_commit_patch_id(commit, &ids))
898 899
			continue;

900
		nr++;
J
Jonas Fonseca 已提交
901
		list = xrealloc(list, nr * sizeof(list[0]));
902 903
		list[nr - 1] = commit;
	}
904
	total = nr;
905 906
	if (!keep_subject && auto_number && total > 1)
		numbered = 1;
907
	if (numbered)
908
		rev.total = total + start_number - 1;
909 910
	if (in_reply_to)
		rev.ref_message_id = clean_message_id(in_reply_to);
911 912 913 914 915 916 917 918 919
	if (cover_letter) {
		if (thread)
			gen_message_id(&rev, "cover");
		make_cover_letter(&rev, use_stdout, numbered, numbered_files,
				  origin, head);
		total++;
		start_number--;
	}
	rev.add_signoff = add_signoff;
920 921 922
	while (0 <= --nr) {
		int shown;
		commit = list[nr];
923
		rev.nr = total - nr + (start_number - 1);
924
		/* Make the second and subsequent mails replies to the first */
925
		if (thread) {
926
			/* Have we already had a message ID? */
927
			if (rev.message_id) {
928 929 930 931 932 933
				/*
				 * If we've got the ID to be a reply
				 * to, discard the current ID;
				 * otherwise, make everything a reply
				 * to that.
				 */
934 935 936 937
				if (rev.ref_message_id)
					free(rev.message_id);
				else
					rev.ref_message_id = rev.message_id;
938
			}
939
			gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
940
		}
941 942 943 944
		if (!use_stdout && reopen_stdout(numbered_files ? NULL :
				get_oneline_for_filename(commit, keep_subject),
				rev.nr, rev.total))
			die("Failed to create output files");
945 946 947
		shown = log_tree_commit(&rev, commit);
		free(commit->buffer);
		commit->buffer = NULL;
948 949 950 951 952 953 954 955 956

		/* 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;
957 958 959 960 961 962 963 964
		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);
		}
965 966
		if (!use_stdout)
			fclose(stdout);
967 968
	}
	free(list);
969 970
	if (ignore_if_in_upstream)
		free_patch_ids(&ids);
971 972 973
	return 0;
}

R
Rene Scharfe 已提交
974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992
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[] =
"git-cherry [-v] <upstream> [<head>] [<limit>]";
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
	struct rev_info revs;
993
	struct patch_ids ids;
R
Rene Scharfe 已提交
994 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 1022 1023 1024
	struct commit *commit;
	struct commit_list *list = NULL;
	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++;
	}

	switch (argc) {
	case 4:
		limit = argv[3];
		/* FALLTHROUGH */
	case 3:
		head = argv[2];
		/* FALLTHROUGH */
	case 2:
		upstream = argv[1];
		break;
	default:
		usage(cherry_usage);
	}

	init_revisions(&revs, prefix);
	revs.diff = 1;
	revs.combine_merges = 0;
	revs.ignore_merges = 1;
1025
	DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
R
Rene Scharfe 已提交
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

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

1039
	get_patch_ids(&revs, &ids, prefix);
R
Rene Scharfe 已提交
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057

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

	/* reverse the list of commits */
	prepare_revision_walk(&revs);
	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;
1058
		if (has_commit_patch_id(commit, &ids))
R
Rene Scharfe 已提交
1059 1060 1061
			sign = '-';

		if (verbose) {
1062 1063 1064
			struct strbuf buf;
			strbuf_init(&buf, 0);
			pretty_print_commit(CMIT_FMT_ONELINE, commit,
1065
			                    &buf, 0, NULL, NULL, 0, 0);
R
Rene Scharfe 已提交
1066
			printf("%c %s %s\n", sign,
1067 1068
			       sha1_to_hex(commit->object.sha1), buf.buf);
			strbuf_release(&buf);
R
Rene Scharfe 已提交
1069 1070 1071 1072 1073 1074 1075 1076 1077
		}
		else {
			printf("%c %s\n", sign,
			       sha1_to_hex(commit->object.sha1));
		}

		list = list->next;
	}

1078
	free_patch_ids(&ids);
R
Rene Scharfe 已提交
1079 1080
	return 0;
}