builtin-log.c 30.0 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

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

24
static int default_show_root = 1;
25
static const char *fmt_patch_subject_prefix = "PATCH";
26
static const char *fmt_pretty;
27

28
static void cmd_log_init(int argc, const char **argv, const char *prefix,
29 30
		      struct rev_info *rev)
{
J
Junio C Hamano 已提交
31 32
	int i;

33 34
	rev->abbrev = DEFAULT_ABBREV;
	rev->commit_format = CMIT_FMT_DEFAULT;
35
	if (fmt_pretty)
36
		get_commit_format(fmt_pretty, rev);
37
	rev->verbose_header = 1;
38
	DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
39
	rev->show_root_diff = default_show_root;
40
	rev->subject_prefix = fmt_patch_subject_prefix;
J
Jeff King 已提交
41
	DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV);
H
Heikki Orsila 已提交
42 43 44 45

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

46
	argc = setup_revisions(argc, argv, rev, "HEAD");
H
Heikki Orsila 已提交
47

48 49
	if (rev->diffopt.pickaxe || rev->diffopt.filter)
		rev->always_show_header = 0;
50
	if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
51 52 53 54
		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 已提交
55 56
	for (i = 1; i < argc; i++) {
		const char *arg = argv[i];
57
		if (!strcmp(arg, "--decorate")) {
R
René Scharfe 已提交
58
			load_ref_decorations();
59
			rev->show_decorations = 1;
60 61
		} else if (!strcmp(arg, "--source")) {
			rev->show_source = 1;
62
		} else
J
Junio C Hamano 已提交
63 64
			die("unrecognized argument: %s", arg);
	}
65 66
}

L
Linus Torvalds 已提交
67 68 69 70 71 72 73 74 75 76 77 78
/*
 * 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;
79
		if (!(flags & (TREESAME | UNINTERESTING)))
L
Linus Torvalds 已提交
80
			n++;
L
Linus Torvalds 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
	}
	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;

97 98 99
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
	int i = revs->early_output;
L
Linus Torvalds 已提交
100
	int show_header = 1;
101 102 103 104

	sort_in_topological_order(&list, revs->lifo);
	while (list && i) {
		struct commit *commit = list->item;
L
Linus Torvalds 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
		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;
		}
120 121
		list = list->next;
	}
L
Linus Torvalds 已提交
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

	/* 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);
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
}

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 已提交
171 172 173
	early_output_timer.it_value.tv_sec = 0;
	early_output_timer.it_value.tv_usec = 100000;
	setitimer(ITIMER_REAL, &early_output_timer, NULL);
174 175 176 177
}

static void finish_early_output(struct rev_info *rev)
{
L
Linus Torvalds 已提交
178
	int n = estimate_commit_count(rev, rev->commits);
179
	signal(SIGALRM, SIG_IGN);
L
Linus Torvalds 已提交
180
	show_early_header(rev, "done", n);
181 182
}

183 184 185
static int cmd_log_walk(struct rev_info *rev)
{
	struct commit *commit;
186

187 188 189
	if (rev->early_output)
		setup_early_output(rev);

190 191
	if (prepare_revision_walk(rev))
		die("revision walk setup failed");
192 193 194 195

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

196
	/*
197 198 199
	 * 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
200
	 */
201 202
	while ((commit = get_revision(rev)) != NULL) {
		log_tree_commit(rev, commit);
203 204 205 206 207
		if (!rev->reflog_info) {
			/* we allow cycles in reflog ancestry */
			free(commit->buffer);
			commit->buffer = NULL;
		}
L
Linus Torvalds 已提交
208 209
		free_commit_list(commit->parents);
		commit->parents = NULL;
210
	}
211 212 213 214
	if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
	    DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
		return 02;
	}
215
	return diff_result_code(&rev->diffopt, 0);
216 217
}

218
static int git_log_config(const char *var, const char *value, void *cb)
219
{
220 221
	if (!strcmp(var, "format.pretty"))
		return git_config_string(&fmt_pretty, var, value);
222 223
	if (!strcmp(var, "format.subjectprefix"))
		return git_config_string(&fmt_patch_subject_prefix, var, value);
H
Heikki Orsila 已提交
224 225
	if (!strcmp(var, "log.date"))
		return git_config_string(&default_date_mode, var, value);
226 227 228 229
	if (!strcmp(var, "log.showroot")) {
		default_show_root = git_config_bool(var, value);
		return 0;
	}
230
	return git_diff_ui_config(var, value, cb);
231 232
}

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

237
	git_config(git_log_config, NULL);
238 239 240 241

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

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

251 252
static void show_tagger(char *buf, int len, struct rev_info *rev)
{
253
	struct strbuf out = STRBUF_INIT;
254

255 256 257 258 259
	pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode,
		git_log_output_encoding ?
		git_log_output_encoding: git_commit_encoding);
	printf("%s\n", out.buf);
	strbuf_release(&out);
260 261 262 263
}

static int show_object(const unsigned char *sha1, int show_tag_object,
	struct rev_info *rev)
264 265
{
	unsigned long size;
266 267
	enum object_type type;
	char *buf = read_sha1_file(sha1, &type, &size);
268 269 270 271 272
	int offset = 0;

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

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

298
int cmd_show(int argc, const char **argv, const char *prefix)
299 300
{
	struct rev_info rev;
301 302
	struct object_array_entry *objects;
	int i, count, ret = 0;
303

304
	git_config(git_log_config, NULL);
305 306 307 308

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

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

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

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

L
Linus Torvalds 已提交
367 368 369 370 371 372 373
/*
 * 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;

374
	git_config(git_log_config, NULL);
375 376 377 378

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

L
Linus Torvalds 已提交
379 380 381 382 383 384 385 386 387 388 389 390
	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;
391
	rev.use_terminator = 1;
L
Linus Torvalds 已提交
392 393 394 395 396 397 398 399 400 401 402
	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);
}

403
int cmd_log(int argc, const char **argv, const char *prefix)
404 405 406
{
	struct rev_info rev;

407
	git_config(git_log_config, NULL);
408 409 410 411

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

412
	init_revisions(&rev, prefix);
413
	rev.always_show_header = 1;
414
	cmd_log_init(argc, argv, prefix, &rev);
415
	return cmd_log_walk(&rev);
416
}
417

418 419 420
/* format-patch */
#define FORMAT_PATCH_NAME_MAX 64

421 422 423 424 425 426
static int istitlechar(char c)
{
	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
		(c >= '0' && c <= '9') || c == '.' || c == '_';
}

427
static const char *fmt_patch_suffix = ".patch";
428
static int numbered = 0;
429
static int auto_number = 1;
430

D
Daniel Barkalow 已提交
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
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);
446
	while (len && value[len - 1] == '\n')
D
Daniel Barkalow 已提交
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
		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);
}

462
static int git_format_config(const char *var, const char *value, void *cb)
463 464
{
	if (!strcmp(var, "format.headers")) {
465 466
		if (!value)
			die("format.headers without value");
D
Daniel Barkalow 已提交
467
		add_header(value);
468 469
		return 0;
	}
470 471
	if (!strcmp(var, "format.suffix"))
		return git_config_string(&fmt_patch_suffix, var, value);
472 473 474 475 476 477 478
	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;
	}
479
	if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
480 481
		return 0;
	}
482
	if (!strcmp(var, "format.numbered")) {
483
		if (value && !strcasecmp(value, "auto")) {
484 485 486 487
			auto_number = 1;
			return 0;
		}
		numbered = git_config_bool(var, value);
488
		auto_number = auto_number && numbered;
489 490
		return 0;
	}
491

492
	return git_log_config(var, value, cb);
493 494 495
}


496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
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;
}

546
static FILE *realstdout = NULL;
547
static const char *output_directory = NULL;
548
static int outdir_offset;
549

550
static int reopen_stdout(const char *oneline, int nr, int total)
551
{
552
	char filename[PATH_MAX];
553
	int len = 0;
554
	int suffix_len = strlen(fmt_patch_suffix) + 1;
555

556
	if (output_directory) {
557 558 559
		len = snprintf(filename, sizeof(filename), "%s",
				output_directory);
		if (len >=
560 561
		    sizeof(filename) - FORMAT_PATCH_NAME_MAX - suffix_len)
			return error("name of output directory is too long");
562 563 564
		if (filename[len - 1] != '/')
			filename[len++] = '/';
	}
565

566 567 568 569 570 571
	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);
572
		strcpy(filename + len, fmt_patch_suffix);
573
	}
574

575
	fprintf(realstdout, "%s\n", filename + outdir_offset);
576 577 578
	if (freopen(filename, "w", stdout) == NULL)
		return error("Cannot open patch file %s",filename);

579
	return 0;
580 581
}

582
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
{
	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.");

600
	init_patch_ids(ids);
601 602

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

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

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

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

628
static void gen_message_id(struct rev_info *info, char *base)
629
{
630
	const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME);
631 632
	const char *email_start = strrchr(committer, '<');
	const char *email_end = strrchr(committer, '>');
633
	struct strbuf buf = STRBUF_INIT;
634
	if (!email_start || !email_end || email_start > email_end - 1)
635
		die("Could not extract email from committer identity.");
636 637 638 639
	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);
640 641
}

642 643 644 645
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)
646 647
{
	const char *committer;
648
	char *head_sha1;
649 650 651 652
	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 660 661 662 663 664 665 666 667 668

	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;

	head_sha1 = sha1_to_hex(head->object.sha1);

J
Junio C Hamano 已提交
669 670
	log_write_email_headers(rev, head_sha1, &subject_start, &extra_headers,
				&need_8bit_cte);
671 672 673 674 675 676 677

	committer = git_committer_info(0);

	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 已提交
678
		      encoding, need_8bit_cte);
679 680 681 682 683
	pp_remainder(CMIT_FMT_EMAIL, &msg, &sb, 0);
	printf("%s\n", sb.buf);

	strbuf_release(&sb);

684
	shortlog_init(&log);
685 686 687 688
	log.wrap_lines = 1;
	log.wrap = 72;
	log.in1 = 2;
	log.in2 = 4;
689 690 691 692 693
	for (i = 0; i < nr; i++)
		shortlog_add_commit(&log, list[i]);

	shortlog_output(&log);

694
	/*
695
	 * We can only do diffstat with a unique reference point
696 697 698 699
	 */
	if (!origin)
		return;

700 701
	memcpy(&opts, &rev->diffopt, sizeof(opts));
	opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
702

703 704 705 706 707 708 709
	diff_setup_done(&opts);

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

	printf("\n");
712 713
}

714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
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 已提交
733
	return xmemdupz(a, z - a);
734 735
}

736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
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));
}

757
int cmd_format_patch(int argc, const char **argv, const char *prefix)
758 759 760 761
{
	struct commit *commit;
	struct commit **list = NULL;
	struct rev_info rev;
762
	int nr = 0, total, i, j;
763
	int use_stdout = 0;
764
	int start_number = -1;
765
	int keep_subject = 0;
766
	int numbered_files = 0;		/* _just_ numbers */
767
	int subject_prefix = 0;
768
	int ignore_if_in_upstream = 0;
769
	int thread = 0;
770
	int cover_letter = 0;
771
	int boundary_count = 0;
772
	int no_binary_diff = 0;
773
	struct commit *origin = NULL, *head = NULL;
774
	const char *in_reply_to = NULL;
775
	struct patch_ids ids;
J
Junio C Hamano 已提交
776
	char *add_signoff = NULL;
777
	struct strbuf buf = STRBUF_INIT;
778

779
	git_config(git_format_config, NULL);
780
	init_revisions(&rev, prefix);
781 782 783 784 785
	rev.commit_format = CMIT_FMT_EMAIL;
	rev.verbose_header = 1;
	rev.diff = 1;
	rev.combine_merges = 0;
	rev.ignore_merges = 1;
786
	DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
787

788
	rev.subject_prefix = fmt_patch_subject_prefix;
789

790 791
	/*
	 * Parse the arguments before setup_revisions(), or something
792
	 * like "git format-patch -o a123 HEAD^.." may fail; a123 is
793 794 795 796
	 * possibly a valid SHA1.
	 */
	for (i = 1, j = 1; i < argc; i++) {
		if (!strcmp(argv[i], "--stdout"))
797
			use_stdout = 1;
798 799 800
		else if (!strcmp(argv[i], "-n") ||
				!strcmp(argv[i], "--numbered"))
			numbered = 1;
801 802 803 804 805
		else if (!strcmp(argv[i], "-N") ||
				!strcmp(argv[i], "--no-numbered")) {
			numbered = 0;
			auto_number = 0;
		}
806
		else if (!prefixcmp(argv[i], "--start-number="))
807
			start_number = strtol(argv[i] + 15, NULL, 10);
808 809
		else if (!strcmp(argv[i], "--numbered-files"))
			numbered_files = 1;
810 811 812 813 814
		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 已提交
815
		}
816 817 818 819
		else if (!prefixcmp(argv[i], "--cc=")) {
			ALLOC_GROW(extra_cc, extra_cc_nr + 1, extra_cc_alloc);
			extra_cc[extra_cc_nr++] = xstrdup(argv[i] + 5);
		}
J
Junio C Hamano 已提交
820
		else if (!strcmp(argv[i], "-k") ||
821 822 823
				!strcmp(argv[i], "--keep-subject")) {
			keep_subject = 1;
			rev.total = -1;
J
Junio C Hamano 已提交
824
		}
825 826
		else if (!strcmp(argv[i], "--output-directory") ||
			 !strcmp(argv[i], "-o")) {
827
			i++;
828 829 830 831 832
			if (argc <= i)
				die("Which directory?");
			if (output_directory)
				die("Two output directories?");
			output_directory = argv[i];
833
		}
J
Junio C Hamano 已提交
834 835
		else if (!strcmp(argv[i], "--signoff") ||
			 !strcmp(argv[i], "-s")) {
E
Eric W. Biederman 已提交
836 837
			const char *committer;
			const char *endpos;
838
			committer = git_committer_info(IDENT_ERROR_ON_NO_NAME);
E
Eric W. Biederman 已提交
839
			endpos = strchr(committer, '>');
J
Junio C Hamano 已提交
840
			if (!endpos)
841
				die("bogus committer info %s", committer);
P
Pierre Habouzit 已提交
842
			add_signoff = xmemdupz(committer, endpos - committer + 1);
J
Junio C Hamano 已提交
843
		}
844
		else if (!strcmp(argv[i], "--attach")) {
845
			rev.mime_boundary = git_version_string;
846 847 848 849 850 851 852 853 854 855 856
			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=")) {
857
			rev.mime_boundary = argv[i] + 9;
858 859
			rev.no_inline = 0;
		}
860 861
		else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
			ignore_if_in_upstream = 1;
862 863
		else if (!strcmp(argv[i], "--thread"))
			thread = 1;
864
		else if (!prefixcmp(argv[i], "--in-reply-to="))
865 866 867 868 869 870
			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];
871 872 873 874
		} else if (!prefixcmp(argv[i], "--subject-prefix=")) {
			subject_prefix = 1;
			rev.subject_prefix = argv[i] + 17;
		} else if (!prefixcmp(argv[i], "--suffix="))
875
			fmt_patch_suffix = argv[i] + 9;
876 877
		else if (!strcmp(argv[i], "--cover-letter"))
			cover_letter = 1;
878 879
		else if (!strcmp(argv[i], "--no-binary"))
			no_binary_diff = 1;
880
		else
881
			argv[j++] = argv[i];
882
	}
883 884
	argc = j;

D
Daniel Barkalow 已提交
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
	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');
	}

	rev.extra_headers = strbuf_detach(&buf, 0);

914
	if (start_number < 0)
915
		start_number = 1;
916
	if (numbered && keep_subject)
917
		die ("-n and -k are mutually exclusive.");
918 919
	if (keep_subject && subject_prefix)
		die ("--subject-prefix and -k are mutually exclusive.");
920 921
	if (numbered_files && use_stdout)
		die ("--numbered-files and --stdout are mutually exclusive.");
922

923 924 925
	argc = setup_revisions(argc, argv, &rev, "HEAD");
	if (argc > 1)
		die ("unrecognized argument: %s", argv[1]);
926

927 928
	if (!rev.diffopt.output_format
		|| rev.diffopt.output_format == DIFF_FORMAT_PATCH)
929
		rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
930

931
	if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
932
		DIFF_OPT_SET(&rev.diffopt, BINARY);
933

934 935
	if (!use_stdout)
		output_directory = set_outdir(prefix, output_directory);
936

937 938 939 940 941 942 943 944
	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);
	}

945
	if (rev.pending.nr == 1) {
946 947 948 949 950 951
		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 已提交
952
			rev.pending.objects[0].item->flags |= UNINTERESTING;
953
			add_head_to_pending(&rev);
J
Junio C Hamano 已提交
954
		}
955 956 957 958
		/*
		 * 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 已提交
959
		 */
960
	}
961 962 963 964 965 966 967

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

968 969 970 971 972
	if (cover_letter) {
		/* remember the range */
		int i;
		for (i = 0; i < rev.pending.nr; i++) {
			struct object *o = rev.pending.objects[i].item;
973
			if (!(o->flags & UNINTERESTING))
974 975 976 977 978 979
				head = (struct commit *)o;
		}
		/* We can't generate a cover letter without any patches */
		if (!head)
			return 0;
	}
980

981
	if (ignore_if_in_upstream)
982
		get_patch_ids(&rev, &ids, prefix);
983

984
	if (!use_stdout)
985
		realstdout = xfdopen(xdup(1), "w");
986

987 988
	if (prepare_revision_walk(&rev))
		die("revision walk setup failed");
989
	rev.boundary = 1;
990
	while ((commit = get_revision(&rev)) != NULL) {
991 992 993 994 995 996
		if (commit->object.flags & BOUNDARY) {
			boundary_count++;
			origin = (boundary_count == 1) ? commit : NULL;
			continue;
		}

997 998 999
		/* ignore merges */
		if (commit->parents && commit->parents->next)
			continue;
1000 1001

		if (ignore_if_in_upstream &&
1002
				has_commit_patch_id(commit, &ids))
1003 1004
			continue;

1005
		nr++;
J
Jonas Fonseca 已提交
1006
		list = xrealloc(list, nr * sizeof(list[0]));
1007 1008
		list[nr - 1] = commit;
	}
1009
	total = nr;
1010 1011
	if (!keep_subject && auto_number && total > 1)
		numbered = 1;
1012
	if (numbered)
1013
		rev.total = total + start_number - 1;
1014 1015
	if (in_reply_to)
		rev.ref_message_id = clean_message_id(in_reply_to);
1016 1017 1018 1019
	if (cover_letter) {
		if (thread)
			gen_message_id(&rev, "cover");
		make_cover_letter(&rev, use_stdout, numbered, numbered_files,
1020
				  origin, nr, list, head);
1021 1022 1023 1024
		total++;
		start_number--;
	}
	rev.add_signoff = add_signoff;
1025 1026 1027
	while (0 <= --nr) {
		int shown;
		commit = list[nr];
1028
		rev.nr = total - nr + (start_number - 1);
1029
		/* Make the second and subsequent mails replies to the first */
1030
		if (thread) {
1031
			/* Have we already had a message ID? */
1032
			if (rev.message_id) {
1033 1034 1035 1036 1037 1038
				/*
				 * If we've got the ID to be a reply
				 * to, discard the current ID;
				 * otherwise, make everything a reply
				 * to that.
				 */
1039 1040 1041 1042
				if (rev.ref_message_id)
					free(rev.message_id);
				else
					rev.ref_message_id = rev.message_id;
1043
			}
1044
			gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
1045
		}
1046 1047 1048 1049
		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");
1050 1051 1052
		shown = log_tree_commit(&rev, commit);
		free(commit->buffer);
		commit->buffer = NULL;
1053 1054 1055 1056 1057 1058 1059 1060 1061

		/* 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;
1062 1063 1064 1065 1066 1067 1068 1069
		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);
		}
1070 1071
		if (!use_stdout)
			fclose(stdout);
1072 1073
	}
	free(list);
1074 1075
	if (ignore_if_in_upstream)
		free_patch_ids(&ids);
1076 1077 1078
	return 0;
}

R
Rene Scharfe 已提交
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
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[] =
1094
"git cherry [-v] [<upstream> [<head> [<limit>]]]";
R
Rene Scharfe 已提交
1095 1096 1097
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
	struct rev_info revs;
1098
	struct patch_ids ids;
R
Rene Scharfe 已提交
1099 1100
	struct commit *commit;
	struct commit_list *list = NULL;
1101
	struct branch *current_branch;
R
Rene Scharfe 已提交
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
	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:
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
		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 已提交
1135 1136 1137 1138 1139 1140
	}

	init_revisions(&revs, prefix);
	revs.diff = 1;
	revs.combine_merges = 0;
	revs.ignore_merges = 1;
1141
	DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
R
Rene Scharfe 已提交
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154

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

1155
	get_patch_ids(&revs, &ids, prefix);
R
Rene Scharfe 已提交
1156 1157 1158 1159 1160

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

	/* reverse the list of commits */
1161 1162
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
R
Rene Scharfe 已提交
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
	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;
1175
		if (has_commit_patch_id(commit, &ids))
R
Rene Scharfe 已提交
1176 1177 1178
			sign = '-';

		if (verbose) {
1179
			struct strbuf buf = STRBUF_INIT;
1180
			pretty_print_commit(CMIT_FMT_ONELINE, commit,
1181
			                    &buf, 0, NULL, NULL, 0, 0);
R
Rene Scharfe 已提交
1182
			printf("%c %s %s\n", sign,
1183 1184
			       sha1_to_hex(commit->object.sha1), buf.buf);
			strbuf_release(&buf);
R
Rene Scharfe 已提交
1185 1186 1187 1188 1189 1190 1191 1192 1193
		}
		else {
			printf("%c %s\n", sign,
			       sha1_to_hex(commit->object.sha1));
		}

		list = list->next;
	}

1194
	free_patch_ids(&ids);
R
Rene Scharfe 已提交
1195 1196
	return 0;
}