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

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

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

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

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

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

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

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

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

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

103
static struct itimerval early_output_timer;
L
Linus Torvalds 已提交
104

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

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

	/* 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);
148 149 150 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
}

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

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

191 192 193
static int cmd_log_walk(struct rev_info *rev)
{
	struct commit *commit;
194

195 196 197
	if (rev->early_output)
		setup_early_output(rev);

198 199
	if (prepare_revision_walk(rev))
		die("revision walk setup failed");
200 201 202 203

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

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

226
static int git_log_config(const char *var, const char *value, void *cb)
227
{
228 229
	if (!strcmp(var, "format.pretty"))
		return git_config_string(&fmt_pretty, var, value);
230 231
	if (!strcmp(var, "format.subjectprefix"))
		return git_config_string(&fmt_patch_subject_prefix, var, value);
H
Heikki Orsila 已提交
232 233
	if (!strcmp(var, "log.date"))
		return git_config_string(&default_date_mode, var, value);
234 235 236 237
	if (!strcmp(var, "log.showroot")) {
		default_show_root = git_config_bool(var, value);
		return 0;
	}
238
	return git_diff_ui_config(var, value, cb);
239 240
}

241
int cmd_whatchanged(int argc, const char **argv, const char *prefix)
242 243 244
{
	struct rev_info rev;

245
	git_config(git_log_config, NULL);
246 247 248 249

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

250
	init_revisions(&rev, prefix);
251
	rev.diff = 1;
L
Linus Torvalds 已提交
252
	rev.simplify_history = 0;
253
	cmd_log_init(argc, argv, prefix, &rev);
254 255 256
	if (!rev.diffopt.output_format)
		rev.diffopt.output_format = DIFF_FORMAT_RAW;
	return cmd_log_walk(&rev);
257 258
}

259 260
static void show_tagger(char *buf, int len, struct rev_info *rev)
{
261
	struct strbuf out = STRBUF_INIT;
262

263 264 265
	pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode,
		git_log_output_encoding ?
		git_log_output_encoding: git_commit_encoding);
266
	printf("%s", out.buf);
267
	strbuf_release(&out);
268 269 270 271
}

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

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

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

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

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

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

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

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

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

L
Linus Torvalds 已提交
381 382 383 384 385 386 387
/*
 * 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;

388
	git_config(git_log_config, NULL);
389 390 391 392

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

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

417
int cmd_log(int argc, const char **argv, const char *prefix)
418 419 420
{
	struct rev_info rev;

421
	git_config(git_log_config, NULL);
422 423 424 425

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

426
	init_revisions(&rev, prefix);
427
	rev.always_show_header = 1;
428
	cmd_log_init(argc, argv, prefix, &rev);
429
	return cmd_log_walk(&rev);
430
}
431

432
/* format-patch */
433

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

438 439
static char *default_attach = NULL;

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 472 473
#define THREAD_SHALLOW 1
#define THREAD_DEEP 2
static int thread = 0;
474
static int do_signoff = 0;
475

476
static int git_format_config(const char *var, const char *value, void *cb)
477 478
{
	if (!strcmp(var, "format.headers")) {
479 480
		if (!value)
			die("format.headers without value");
D
Daniel Barkalow 已提交
481
		add_header(value);
482 483
		return 0;
	}
484 485
	if (!strcmp(var, "format.suffix"))
		return git_config_string(&fmt_patch_suffix, var, value);
486 487 488 489 490 491 492
	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;
	}
493
	if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
494 495
		return 0;
	}
496
	if (!strcmp(var, "format.numbered")) {
497
		if (value && !strcasecmp(value, "auto")) {
498 499 500 501
			auto_number = 1;
			return 0;
		}
		numbered = git_config_bool(var, value);
502
		auto_number = auto_number && numbered;
503 504
		return 0;
	}
505 506 507 508 509 510 511
	if (!strcmp(var, "format.attach")) {
		if (value && *value)
			default_attach = xstrdup(value);
		else
			default_attach = xstrdup(git_version_string);
		return 0;
	}
512 513 514 515 516 517 518 519 520 521 522 523
	if (!strcmp(var, "format.thread")) {
		if (value && !strcasecmp(value, "deep")) {
			thread = THREAD_DEEP;
			return 0;
		}
		if (value && !strcasecmp(value, "shallow")) {
			thread = THREAD_SHALLOW;
			return 0;
		}
		thread = git_config_bool(var, value) && THREAD_SHALLOW;
		return 0;
	}
524 525 526 527
	if (!strcmp(var, "format.signoff")) {
		do_signoff = git_config_bool(var, value);
		return 0;
	}
528

529
	return git_log_config(var, value, cb);
530 531
}

532
static FILE *realstdout = NULL;
533
static const char *output_directory = NULL;
534
static int outdir_offset;
535

536
static int reopen_stdout(struct commit *commit, struct rev_info *rev)
537
{
538
	struct strbuf filename = STRBUF_INIT;
539
	int suffix_len = strlen(fmt_patch_suffix) + 1;
540

541
	if (output_directory) {
542 543 544
		strbuf_addstr(&filename, output_directory);
		if (filename.len >=
		    PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len)
545
			return error("name of output directory is too long");
546 547
		if (filename.buf[filename.len - 1] != '/')
			strbuf_addch(&filename, '/');
548
	}
549

550
	get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
551

N
Nate Case 已提交
552
	if (!DIFF_OPT_TST(&rev->diffopt, QUIET))
553
		fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
N
Nate Case 已提交
554

555 556
	if (freopen(filename.buf, "w", stdout) == NULL)
		return error("Cannot open patch file %s", filename.buf);
557

558
	strbuf_release(&filename);
559
	return 0;
560 561
}

562
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
{
	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.");

580
	init_patch_ids(ids);
581 582

	/* given a range a..b get all patch ids for b..a */
583
	init_revisions(&check_rev, prefix);
584 585 586 587
	o1->flags ^= UNINTERESTING;
	o2->flags ^= UNINTERESTING;
	add_pending_object(&check_rev, o1, "o1");
	add_pending_object(&check_rev, o2, "o2");
588 589
	if (prepare_revision_walk(&check_rev))
		die("revision walk setup failed");
590 591 592 593 594 595

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

596
		add_commit_patch_id(commit, ids);
597 598 599
	}

	/* reset for next revision walk */
600 601 602 603
	clear_commit_marks((struct commit *)o1,
			SEEN | UNINTERESTING | SHOWN | ADDED);
	clear_commit_marks((struct commit *)o2,
			SEEN | UNINTERESTING | SHOWN | ADDED);
604 605 606 607
	o1->flags = flags1;
	o2->flags = flags2;
}

608
static void gen_message_id(struct rev_info *info, char *base)
609
{
610
	const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME);
611 612
	const char *email_start = strrchr(committer, '<');
	const char *email_end = strrchr(committer, '>');
613
	struct strbuf buf = STRBUF_INIT;
614
	if (!email_start || !email_end || email_start > email_end - 1)
615
		die("Could not extract email from committer identity.");
616 617 618 619
	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);
620 621
}

622 623 624 625
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)
626 627 628 629 630 631
{
	const char *committer;
	const char *subject_start = NULL;
	const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n";
	const char *msg;
	const char *extra_headers = rev->extra_headers;
632
	struct shortlog log;
633
	struct strbuf sb = STRBUF_INIT;
634
	int i;
635
	const char *encoding = "UTF-8";
636
	struct diff_options opts;
J
Junio C Hamano 已提交
637
	int need_8bit_cte = 0;
638
	struct commit *commit = NULL;
639 640 641 642

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

643
	committer = git_committer_info(0);
644

645 646 647 648 649 650 651 652 653 654 655 656 657
	if (!numbered_files) {
		/*
		 * We fake a commit for the cover letter so we get the filename
		 * desired.
		 */
		commit = xcalloc(1, sizeof(*commit));
		commit->buffer = xmalloc(400);
		snprintf(commit->buffer, 400,
			"tree 0000000000000000000000000000000000000000\n"
			"parent %s\n"
			"author %s\n"
			"committer %s\n\n"
			"cover letter\n",
658
			sha1_to_hex(head->object.sha1), committer, committer);
659 660 661
	}

	if (!use_stdout && reopen_stdout(commit, rev))
662 663
		return;

664
	if (commit) {
665

666 667 668
		free(commit->buffer);
		free(commit);
	}
669

670
	log_write_email_headers(rev, head, &subject_start, &extra_headers,
J
Junio C Hamano 已提交
671
				&need_8bit_cte);
672

673 674 675 676
	for (i = 0; !need_8bit_cte && i < nr; i++)
		if (has_non_ascii(list[i]->buffer))
			need_8bit_cte = 1;

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

	strbuf_release(&sb);

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

	shortlog_output(&log);

697
	/*
698
	 * We can only do diffstat with a unique reference point
699 700 701 702
	 */
	if (!origin)
		return;

703 704
	memcpy(&opts, &rev->diffopt, sizeof(opts));
	opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
705

706 707 708 709 710 711 712
	diff_setup_done(&opts);

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

	printf("\n");
715 716
}

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

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

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
static const char * const builtin_format_patch_usage[] = {
	"git format-patch [options] [<since> | <revision range>]",
	NULL
};

static int keep_subject = 0;

static int keep_callback(const struct option *opt, const char *arg, int unset)
{
	((struct rev_info *)opt->value)->total = -1;
	keep_subject = 1;
	return 0;
}

static int subject_prefix = 0;

static int subject_prefix_callback(const struct option *opt, const char *arg,
			    int unset)
{
	subject_prefix = 1;
	((struct rev_info *)opt->value)->subject_prefix = arg;
	return 0;
}

784 785
static int numbered_cmdline_opt = 0;

786 787 788
static int numbered_callback(const struct option *opt, const char *arg,
			     int unset)
{
789
	*(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
	if (unset)
		auto_number =  0;
	return 0;
}

static int no_numbered_callback(const struct option *opt, const char *arg,
				int unset)
{
	return numbered_callback(opt, arg, 1);
}

static int output_directory_callback(const struct option *opt, const char *arg,
			      int unset)
{
	const char **dir = (const char **)opt->value;
	if (*dir)
		die("Two output directories?");
	*dir = arg;
	return 0;
}

static int thread_callback(const struct option *opt, const char *arg, int unset)
{
	int *thread = (int *)opt->value;
	if (unset)
		*thread = 0;
	else if (!arg || !strcmp(arg, "shallow"))
		*thread = THREAD_SHALLOW;
	else if (!strcmp(arg, "deep"))
		*thread = THREAD_DEEP;
	else
		return 1;
	return 0;
}

static int attach_callback(const struct option *opt, const char *arg, int unset)
{
	struct rev_info *rev = (struct rev_info *)opt->value;
	if (unset)
		rev->mime_boundary = NULL;
	else if (arg)
		rev->mime_boundary = arg;
	else
		rev->mime_boundary = git_version_string;
	rev->no_inline = unset ? 0 : 1;
	return 0;
}

static int inline_callback(const struct option *opt, const char *arg, int unset)
{
	struct rev_info *rev = (struct rev_info *)opt->value;
	if (unset)
		rev->mime_boundary = NULL;
	else if (arg)
		rev->mime_boundary = arg;
	else
		rev->mime_boundary = git_version_string;
	rev->no_inline = 0;
	return 0;
}

static int header_callback(const struct option *opt, const char *arg, int unset)
{
	add_header(arg);
	return 0;
}

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

864
int cmd_format_patch(int argc, const char **argv, const char *prefix)
865 866 867 868
{
	struct commit *commit;
	struct commit **list = NULL;
	struct rev_info rev;
869
	int nr = 0, total, i;
870
	int use_stdout = 0;
871
	int start_number = -1;
872
	int numbered_files = 0;		/* _just_ numbers */
873
	int ignore_if_in_upstream = 0;
874
	int cover_letter = 0;
875
	int boundary_count = 0;
876
	int no_binary_diff = 0;
877
	struct commit *origin = NULL, *head = NULL;
878
	const char *in_reply_to = NULL;
879
	struct patch_ids ids;
J
Junio C Hamano 已提交
880
	char *add_signoff = NULL;
881
	struct strbuf buf = STRBUF_INIT;
882 883 884 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 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932
	const struct option builtin_format_patch_options[] = {
		{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
			    "use [PATCH n/m] even with a single patch",
			    PARSE_OPT_NOARG, numbered_callback },
		{ OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
			    "use [PATCH] even with multiple patches",
			    PARSE_OPT_NOARG, no_numbered_callback },
		OPT_BOOLEAN('s', "signoff", &do_signoff, "add Signed-off-by:"),
		OPT_BOOLEAN(0, "stdout", &use_stdout,
			    "print patches to standard out"),
		OPT_BOOLEAN(0, "cover-letter", &cover_letter,
			    "generate a cover letter"),
		OPT_BOOLEAN(0, "numbered-files", &numbered_files,
			    "use simple number sequence for output file names"),
		OPT_STRING(0, "suffix", &fmt_patch_suffix, "sfx",
			    "use <sfx> instead of '.patch'"),
		OPT_INTEGER(0, "start-number", &start_number,
			    "start numbering patches at <n> instead of 1"),
		{ OPTION_CALLBACK, 0, "subject-prefix", &rev, "prefix",
			    "Use [<prefix>] instead of [PATCH]",
			    PARSE_OPT_NONEG, subject_prefix_callback },
		{ OPTION_CALLBACK, 'o', "output-directory", &output_directory,
			    "dir", "store resulting files in <dir>",
			    PARSE_OPT_NONEG, output_directory_callback },
		{ OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL,
			    "don't strip/add [PATCH]",
			    PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
		OPT_BOOLEAN(0, "no-binary", &no_binary_diff,
			    "don't output binary diffs"),
		OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
			    "don't include a patch matching a commit upstream"),
		OPT_GROUP("Messaging"),
		{ OPTION_CALLBACK, 0, "add-header", NULL, "header",
			    "add email header", PARSE_OPT_NONEG,
			    header_callback },
		{ OPTION_CALLBACK, 0, "cc", NULL, "email", "add Cc: header",
			    PARSE_OPT_NONEG, cc_callback },
		OPT_STRING(0, "in-reply-to", &in_reply_to, "message-id",
			    "make first mail a reply to <message-id>"),
		{ OPTION_CALLBACK, 0, "attach", &rev, "boundary",
			    "attach the patch", PARSE_OPT_OPTARG,
			    attach_callback },
		{ OPTION_CALLBACK, 0, "inline", &rev, "boundary",
			    "inline the patch",
			    PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
			    inline_callback },
		{ OPTION_CALLBACK, 0, "thread", &thread, "style",
			    "enable message threading, styles: shallow, deep",
			    PARSE_OPT_OPTARG, thread_callback },
		OPT_END()
	};
933

934
	git_config(git_format_config, NULL);
935
	init_revisions(&rev, prefix);
936 937 938 939 940
	rev.commit_format = CMIT_FMT_EMAIL;
	rev.verbose_header = 1;
	rev.diff = 1;
	rev.combine_merges = 0;
	rev.ignore_merges = 1;
941
	DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
942

943
	rev.subject_prefix = fmt_patch_subject_prefix;
944

945 946 947 948 949
	if (default_attach) {
		rev.mime_boundary = default_attach;
		rev.no_inline = 1;
	}

950 951
	/*
	 * Parse the arguments before setup_revisions(), or something
952
	 * like "git format-patch -o a123 HEAD^.." may fail; a123 is
953 954
	 * possibly a valid SHA1.
	 */
955
	argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
956 957
			     builtin_format_patch_usage,
			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
958

959 960 961 962 963 964 965 966 967 968
	if (do_signoff) {
		const char *committer;
		const char *endpos;
		committer = git_committer_info(IDENT_ERROR_ON_NO_NAME);
		endpos = strchr(committer, '>');
		if (!endpos)
			die("bogus committer info %s", committer);
		add_signoff = xmemdupz(committer, endpos - committer + 1);
	}

D
Daniel Barkalow 已提交
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
	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');
	}

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

998
	if (start_number < 0)
999
		start_number = 1;
1000 1001 1002 1003 1004 1005 1006 1007 1008

	/*
	 * If numbered is set solely due to format.numbered in config,
	 * and it would conflict with --keep-subject (-k) from the
	 * command line, reset "numbered".
	 */
	if (numbered && keep_subject && !numbered_cmdline_opt)
		numbered = 0;

1009
	if (numbered && keep_subject)
1010
		die ("-n and -k are mutually exclusive.");
1011 1012
	if (keep_subject && subject_prefix)
		die ("--subject-prefix and -k are mutually exclusive.");
1013

1014 1015 1016
	argc = setup_revisions(argc, argv, &rev, "HEAD");
	if (argc > 1)
		die ("unrecognized argument: %s", argv[1]);
1017

1018 1019
	if (!rev.diffopt.output_format
		|| rev.diffopt.output_format == DIFF_FORMAT_PATCH)
1020
		rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
1021

1022
	if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
1023
		DIFF_OPT_SET(&rev.diffopt, BINARY);
1024

1025 1026
	if (!use_stdout)
		output_directory = set_outdir(prefix, output_directory);
1027

1028 1029 1030 1031
	if (output_directory) {
		if (use_stdout)
			die("standard output, or directory, which one?");
		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
1032 1033
			die_errno("Could not create directory '%s'",
				  output_directory);
1034 1035
	}

1036
	if (rev.pending.nr == 1) {
1037 1038 1039 1040 1041 1042
		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 已提交
1043
			rev.pending.objects[0].item->flags |= UNINTERESTING;
1044
			add_head_to_pending(&rev);
J
Junio C Hamano 已提交
1045
		}
1046 1047 1048 1049
		/*
		 * 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 已提交
1050
		 */
1051
	}
1052 1053 1054 1055 1056 1057 1058

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

1059 1060 1061 1062 1063
	if (cover_letter) {
		/* remember the range */
		int i;
		for (i = 0; i < rev.pending.nr; i++) {
			struct object *o = rev.pending.objects[i].item;
1064
			if (!(o->flags & UNINTERESTING))
1065 1066 1067 1068 1069 1070
				head = (struct commit *)o;
		}
		/* We can't generate a cover letter without any patches */
		if (!head)
			return 0;
	}
1071

1072
	if (ignore_if_in_upstream)
1073
		get_patch_ids(&rev, &ids, prefix);
1074

1075
	if (!use_stdout)
1076
		realstdout = xfdopen(xdup(1), "w");
1077

1078 1079
	if (prepare_revision_walk(&rev))
		die("revision walk setup failed");
1080
	rev.boundary = 1;
1081
	while ((commit = get_revision(&rev)) != NULL) {
1082 1083 1084 1085 1086 1087
		if (commit->object.flags & BOUNDARY) {
			boundary_count++;
			origin = (boundary_count == 1) ? commit : NULL;
			continue;
		}

1088 1089 1090
		/* ignore merges */
		if (commit->parents && commit->parents->next)
			continue;
1091 1092

		if (ignore_if_in_upstream &&
1093
				has_commit_patch_id(commit, &ids))
1094 1095
			continue;

1096
		nr++;
J
Jonas Fonseca 已提交
1097
		list = xrealloc(list, nr * sizeof(list[0]));
1098 1099
		list[nr - 1] = commit;
	}
1100
	total = nr;
1101 1102
	if (!keep_subject && auto_number && total > 1)
		numbered = 1;
1103
	if (numbered)
1104
		rev.total = total + start_number - 1;
1105 1106 1107 1108 1109 1110
	if (in_reply_to || thread || cover_letter)
		rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));
	if (in_reply_to) {
		const char *msgid = clean_message_id(in_reply_to);
		string_list_append(msgid, rev.ref_message_ids);
	}
1111 1112
	rev.numbered_files = numbered_files;
	rev.patch_suffix = fmt_patch_suffix;
1113 1114 1115 1116
	if (cover_letter) {
		if (thread)
			gen_message_id(&rev, "cover");
		make_cover_letter(&rev, use_stdout, numbered, numbered_files,
1117
				  origin, nr, list, head);
1118 1119 1120 1121
		total++;
		start_number--;
	}
	rev.add_signoff = add_signoff;
1122 1123 1124
	while (0 <= --nr) {
		int shown;
		commit = list[nr];
1125
		rev.nr = total - nr + (start_number - 1);
1126
		/* Make the second and subsequent mails replies to the first */
1127
		if (thread) {
1128
			/* Have we already had a message ID? */
1129
			if (rev.message_id) {
1130
				/*
1131 1132 1133 1134 1135 1136
				 * For deep threading: make every mail
				 * a reply to the previous one, no
				 * matter what other options are set.
				 *
				 * For shallow threading:
				 *
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
				 * Without --cover-letter and
				 * --in-reply-to, make every mail a
				 * reply to the one before.
				 *
				 * With --in-reply-to but no
				 * --cover-letter, make every mail a
				 * reply to the <reply-to>.
				 *
				 * With --cover-letter, make every
				 * mail but the cover letter a reply
				 * to the cover letter.  The cover
				 * letter is a reply to the
				 * --in-reply-to, if specified.
1150
				 */
1151 1152
				if (thread == THREAD_SHALLOW
				    && rev.ref_message_ids->nr > 0
1153
				    && (!cover_letter || rev.nr > 1))
1154 1155
					free(rev.message_id);
				else
1156 1157
					string_list_append(rev.message_id,
							   rev.ref_message_ids);
1158
			}
1159
			gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
1160
		}
1161

1162 1163
		if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit,
						 &rev))
1164
			die("Failed to create output files");
1165 1166 1167
		shown = log_tree_commit(&rev, commit);
		free(commit->buffer);
		commit->buffer = NULL;
1168 1169 1170 1171 1172 1173 1174 1175 1176

		/* 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;
1177 1178 1179 1180 1181 1182 1183 1184
		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);
		}
1185 1186
		if (!use_stdout)
			fclose(stdout);
1187 1188
	}
	free(list);
1189 1190
	if (ignore_if_in_upstream)
		free_patch_ids(&ids);
1191 1192 1193
	return 0;
}

R
Rene Scharfe 已提交
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
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[] =
1209
"git cherry [-v] [<upstream> [<head> [<limit>]]]";
R
Rene Scharfe 已提交
1210 1211 1212
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
	struct rev_info revs;
1213
	struct patch_ids ids;
R
Rene Scharfe 已提交
1214 1215
	struct commit *commit;
	struct commit_list *list = NULL;
1216
	struct branch *current_branch;
R
Rene Scharfe 已提交
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
	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:
1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
		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 已提交
1250 1251 1252 1253 1254 1255
	}

	init_revisions(&revs, prefix);
	revs.diff = 1;
	revs.combine_merges = 0;
	revs.ignore_merges = 1;
1256
	DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
R
Rene Scharfe 已提交
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269

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

1270
	get_patch_ids(&revs, &ids, prefix);
R
Rene Scharfe 已提交
1271 1272 1273 1274 1275

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

	/* reverse the list of commits */
1276 1277
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
R
Rene Scharfe 已提交
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
	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;
1290
		if (has_commit_patch_id(commit, &ids))
R
Rene Scharfe 已提交
1291 1292 1293
			sign = '-';

		if (verbose) {
1294
			struct strbuf buf = STRBUF_INIT;
1295
			pretty_print_commit(CMIT_FMT_ONELINE, commit,
1296
			                    &buf, 0, NULL, NULL, 0, 0);
R
Rene Scharfe 已提交
1297
			printf("%c %s %s\n", sign,
1298 1299
			       sha1_to_hex(commit->object.sha1), buf.buf);
			strbuf_release(&buf);
R
Rene Scharfe 已提交
1300 1301 1302 1303 1304 1305 1306 1307 1308
		}
		else {
			printf("%c %s\n", sign,
			       sha1_to_hex(commit->object.sha1));
		}

		list = list->next;
	}

1309
	free_patch_ids(&ids);
R
Rene Scharfe 已提交
1310 1311
	return 0;
}