builtin-log.c 29.5 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 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
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)
273 274
{
	unsigned long size;
275 276
	enum object_type type;
	char *buf = read_sha1_file(sha1, &type, &size);
277 278 279 280 281
	int offset = 0;

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

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

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

313
	git_config(git_log_config, NULL);
314 315 316 317

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

318
	init_revisions(&rev, prefix);
319 320 321 322 323 324
	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;
325
	cmd_log_init(argc, argv, prefix, &rev);
326 327 328 329 330 331 332 333

	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:
334
			ret = show_object(o->sha1, 0, NULL);
335 336 337 338
			break;
		case OBJ_TAG: {
			struct tag *t = (struct tag *)o;

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

L
Linus Torvalds 已提交
376 377 378 379 380 381 382
/*
 * 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;

383
	git_config(git_log_config, NULL);
384 385 386 387

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

L
Linus Torvalds 已提交
388 389 390 391 392 393 394 395 396 397 398 399
	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;
400
	rev.use_terminator = 1;
L
Linus Torvalds 已提交
401 402 403 404 405 406 407 408 409 410 411
	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);
}

412
int cmd_log(int argc, const char **argv, const char *prefix)
413 414 415
{
	struct rev_info rev;

416
	git_config(git_log_config, NULL);
417 418 419 420

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

421
	init_revisions(&rev, prefix);
422
	rev.always_show_header = 1;
423
	cmd_log_init(argc, argv, prefix, &rev);
424
	return cmd_log_walk(&rev);
425
}
426

427 428 429
/* format-patch */
#define FORMAT_PATCH_NAME_MAX 64

430 431 432 433 434 435
static int istitlechar(char c)
{
	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
		(c >= '0' && c <= '9') || c == '.' || c == '_';
}

436
static const char *fmt_patch_suffix = ".patch";
437
static int numbered = 0;
438
static int auto_number = 1;
439

D
Daniel Barkalow 已提交
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
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);
455
	while (len && value[len - 1] == '\n')
D
Daniel Barkalow 已提交
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
		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);
}

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

501
	return git_log_config(var, value, cb);
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 546 547 548 549 550 551 552 553 554
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;
}

555
static FILE *realstdout = NULL;
556
static const char *output_directory = NULL;
557

558
static int reopen_stdout(const char *oneline, int nr, int total)
559
{
560
	char filename[PATH_MAX];
561
	int len = 0;
562
	int suffix_len = strlen(fmt_patch_suffix) + 1;
563

564
	if (output_directory) {
565 566 567
		len = snprintf(filename, sizeof(filename), "%s",
				output_directory);
		if (len >=
568 569
		    sizeof(filename) - FORMAT_PATCH_NAME_MAX - suffix_len)
			return error("name of output directory is too long");
570 571 572
		if (filename[len - 1] != '/')
			filename[len++] = '/';
	}
573

574 575 576 577 578 579
	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);
580
		strcpy(filename + len, fmt_patch_suffix);
581
	}
582

583
	fprintf(realstdout, "%s\n", filename);
584 585 586
	if (freopen(filename, "w", stdout) == NULL)
		return error("Cannot open patch file %s",filename);

587
	return 0;
588 589
}

590
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
{
	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.");

608
	init_patch_ids(ids);
609 610

	/* given a range a..b get all patch ids for b..a */
611
	init_revisions(&check_rev, prefix);
612 613 614 615
	o1->flags ^= UNINTERESTING;
	o2->flags ^= UNINTERESTING;
	add_pending_object(&check_rev, o1, "o1");
	add_pending_object(&check_rev, o2, "o2");
616 617
	if (prepare_revision_walk(&check_rev))
		die("revision walk setup failed");
618 619 620 621 622 623

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

624
		add_commit_patch_id(commit, ids);
625 626 627
	}

	/* reset for next revision walk */
628 629 630 631
	clear_commit_marks((struct commit *)o1,
			SEEN | UNINTERESTING | SHOWN | ADDED);
	clear_commit_marks((struct commit *)o2,
			SEEN | UNINTERESTING | SHOWN | ADDED);
632 633 634 635
	o1->flags = flags1;
	o2->flags = flags2;
}

636
static void gen_message_id(struct rev_info *info, char *base)
637
{
638
	const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME);
639 640
	const char *email_start = strrchr(committer, '<');
	const char *email_end = strrchr(committer, '>');
641
	struct strbuf buf = STRBUF_INIT;
642
	if (!email_start || !email_end || email_start > email_end - 1)
643
		die("Could not extract email from committer identity.");
644 645 646 647
	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);
648 649
}

650 651 652 653
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)
654 655
{
	const char *committer;
656
	char *head_sha1;
657 658 659 660
	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;
661
	struct shortlog log;
662
	struct strbuf sb = STRBUF_INIT;
663
	int i;
664
	const char *encoding = "utf-8";
665
	struct diff_options opts;
J
Junio C Hamano 已提交
666
	int need_8bit_cte = 0;
667 668 669 670 671 672 673 674 675 676

	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 已提交
677 678
	log_write_email_headers(rev, head_sha1, &subject_start, &extra_headers,
				&need_8bit_cte);
679 680 681 682 683 684 685

	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 已提交
686
		      encoding, need_8bit_cte);
687 688 689 690 691
	pp_remainder(CMIT_FMT_EMAIL, &msg, &sb, 0);
	printf("%s\n", sb.buf);

	strbuf_release(&sb);

692
	shortlog_init(&log);
693 694 695 696
	log.wrap_lines = 1;
	log.wrap = 72;
	log.in1 = 2;
	log.in2 = 4;
697 698 699 700 701
	for (i = 0; i < nr; i++)
		shortlog_add_commit(&log, list[i]);

	shortlog_output(&log);

702
	/*
703
	 * We can only do diffstat with a unique reference point
704 705 706 707
	 */
	if (!origin)
		return;

708 709
	memcpy(&opts, &rev->diffopt, sizeof(opts));
	opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
710

711 712 713 714 715 716 717
	diff_setup_done(&opts);

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

	printf("\n");
720 721
}

722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
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 已提交
741
	return xmemdupz(a, z - a);
742 743
}

744
int cmd_format_patch(int argc, const char **argv, const char *prefix)
745 746 747 748
{
	struct commit *commit;
	struct commit **list = NULL;
	struct rev_info rev;
749
	int nr = 0, total, i, j;
750
	int use_stdout = 0;
751
	int start_number = -1;
752
	int keep_subject = 0;
753
	int numbered_files = 0;		/* _just_ numbers */
754
	int subject_prefix = 0;
755
	int ignore_if_in_upstream = 0;
756
	int thread = 0;
757
	int cover_letter = 0;
758
	int boundary_count = 0;
759
	int no_binary_diff = 0;
760
	struct commit *origin = NULL, *head = NULL;
761
	const char *in_reply_to = NULL;
762
	struct patch_ids ids;
J
Junio C Hamano 已提交
763
	char *add_signoff = NULL;
764
	struct strbuf buf = STRBUF_INIT;
765

766
	git_config(git_format_config, NULL);
767
	init_revisions(&rev, prefix);
768 769 770 771 772
	rev.commit_format = CMIT_FMT_EMAIL;
	rev.verbose_header = 1;
	rev.diff = 1;
	rev.combine_merges = 0;
	rev.ignore_merges = 1;
773
	DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
774

775
	rev.subject_prefix = fmt_patch_subject_prefix;
776

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

D
Daniel Barkalow 已提交
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900
	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);

901
	if (start_number < 0)
902
		start_number = 1;
903
	if (numbered && keep_subject)
904
		die ("-n and -k are mutually exclusive.");
905 906
	if (keep_subject && subject_prefix)
		die ("--subject-prefix and -k are mutually exclusive.");
907 908
	if (numbered_files && use_stdout)
		die ("--numbered-files and --stdout are mutually exclusive.");
909

910 911 912
	argc = setup_revisions(argc, argv, &rev, "HEAD");
	if (argc > 1)
		die ("unrecognized argument: %s", argv[1]);
913

914 915
	if (!rev.diffopt.output_format
		|| rev.diffopt.output_format == DIFF_FORMAT_PATCH)
916
		rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
917

918
	if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
919
		DIFF_OPT_SET(&rev.diffopt, BINARY);
920

921
	if (!output_directory && !use_stdout)
922 923
		output_directory = prefix;

924 925 926 927 928 929 930 931
	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);
	}

932
	if (rev.pending.nr == 1) {
933 934 935 936 937 938
		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 已提交
939
			rev.pending.objects[0].item->flags |= UNINTERESTING;
940
			add_head_to_pending(&rev);
J
Junio C Hamano 已提交
941
		}
942 943 944 945
		/*
		 * 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 已提交
946
		 */
947
	}
948 949 950 951 952
	if (cover_letter) {
		/* remember the range */
		int i;
		for (i = 0; i < rev.pending.nr; i++) {
			struct object *o = rev.pending.objects[i].item;
953
			if (!(o->flags & UNINTERESTING))
954 955 956 957 958 959
				head = (struct commit *)o;
		}
		/* We can't generate a cover letter without any patches */
		if (!head)
			return 0;
	}
960

961
	if (ignore_if_in_upstream)
962
		get_patch_ids(&rev, &ids, prefix);
963

964
	if (!use_stdout)
965
		realstdout = xfdopen(xdup(1), "w");
966

967 968
	if (prepare_revision_walk(&rev))
		die("revision walk setup failed");
969
	rev.boundary = 1;
970
	while ((commit = get_revision(&rev)) != NULL) {
971 972 973 974 975 976
		if (commit->object.flags & BOUNDARY) {
			boundary_count++;
			origin = (boundary_count == 1) ? commit : NULL;
			continue;
		}

977 978 979
		/* ignore merges */
		if (commit->parents && commit->parents->next)
			continue;
980 981

		if (ignore_if_in_upstream &&
982
				has_commit_patch_id(commit, &ids))
983 984
			continue;

985
		nr++;
J
Jonas Fonseca 已提交
986
		list = xrealloc(list, nr * sizeof(list[0]));
987 988
		list[nr - 1] = commit;
	}
989
	total = nr;
990 991
	if (!keep_subject && auto_number && total > 1)
		numbered = 1;
992
	if (numbered)
993
		rev.total = total + start_number - 1;
994 995
	if (in_reply_to)
		rev.ref_message_id = clean_message_id(in_reply_to);
996 997 998 999
	if (cover_letter) {
		if (thread)
			gen_message_id(&rev, "cover");
		make_cover_letter(&rev, use_stdout, numbered, numbered_files,
1000
				  origin, nr, list, head);
1001 1002 1003 1004
		total++;
		start_number--;
	}
	rev.add_signoff = add_signoff;
1005 1006 1007
	while (0 <= --nr) {
		int shown;
		commit = list[nr];
1008
		rev.nr = total - nr + (start_number - 1);
1009
		/* Make the second and subsequent mails replies to the first */
1010
		if (thread) {
1011
			/* Have we already had a message ID? */
1012
			if (rev.message_id) {
1013 1014 1015 1016 1017 1018
				/*
				 * If we've got the ID to be a reply
				 * to, discard the current ID;
				 * otherwise, make everything a reply
				 * to that.
				 */
1019 1020 1021 1022
				if (rev.ref_message_id)
					free(rev.message_id);
				else
					rev.ref_message_id = rev.message_id;
1023
			}
1024
			gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
1025
		}
1026 1027 1028 1029
		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");
1030 1031 1032
		shown = log_tree_commit(&rev, commit);
		free(commit->buffer);
		commit->buffer = NULL;
1033 1034 1035 1036 1037 1038 1039 1040 1041

		/* 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;
1042 1043 1044 1045 1046 1047 1048 1049
		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);
		}
1050 1051
		if (!use_stdout)
			fclose(stdout);
1052 1053
	}
	free(list);
1054 1055
	if (ignore_if_in_upstream)
		free_patch_ids(&ids);
1056 1057 1058
	return 0;
}

R
Rene Scharfe 已提交
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
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[] =
1074
"git cherry [-v] [<upstream>] [<head>] [<limit>]";
R
Rene Scharfe 已提交
1075 1076 1077
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
	struct rev_info revs;
1078
	struct patch_ids ids;
R
Rene Scharfe 已提交
1079 1080
	struct commit *commit;
	struct commit_list *list = NULL;
1081
	struct branch *current_branch;
R
Rene Scharfe 已提交
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
	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:
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
		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 已提交
1115 1116 1117 1118 1119 1120
	}

	init_revisions(&revs, prefix);
	revs.diff = 1;
	revs.combine_merges = 0;
	revs.ignore_merges = 1;
1121
	DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
R
Rene Scharfe 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134

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

1135
	get_patch_ids(&revs, &ids, prefix);
R
Rene Scharfe 已提交
1136 1137 1138 1139 1140

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

	/* reverse the list of commits */
1141 1142
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
R
Rene Scharfe 已提交
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
	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;
1155
		if (has_commit_patch_id(commit, &ids))
R
Rene Scharfe 已提交
1156 1157 1158
			sign = '-';

		if (verbose) {
1159
			struct strbuf buf = STRBUF_INIT;
1160
			pretty_print_commit(CMIT_FMT_ONELINE, commit,
1161
			                    &buf, 0, NULL, NULL, 0, 0);
R
Rene Scharfe 已提交
1162
			printf("%c %s %s\n", sign,
1163 1164
			       sha1_to_hex(commit->object.sha1), buf.buf);
			strbuf_release(&buf);
R
Rene Scharfe 已提交
1165 1166 1167 1168 1169 1170 1171 1172 1173
		}
		else {
			printf("%c %s\n", sign,
			       sha1_to_hex(commit->object.sha1));
		}

		list = list->next;
	}

1174
	free_patch_ids(&ids);
R
Rene Scharfe 已提交
1175 1176
	return 0;
}