From: Junio C Hamano <gitster@pobox.com>
Date: Tue, 31 May 2011 19:19:11 +0000 (-0700)
Subject: Merge branch 'jk/format-patch-am'
X-Git-Tag: v1.7.6-rc0~2
X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/f67d2e82d6d2fd385d3d20e8d348eaf69dc95041

Merge branch 'jk/format-patch-am'

* jk/format-patch-am:
format-patch: preserve subject newlines with -k
clean up calling conventions for pretty.c functions
pretty: add pp_commit_easy function for simple callers
mailinfo: always clean up rfc822 header folding
t: test subject handling in format-patch / am pipeline

Conflicts:
builtin/branch.c
builtin/log.c
commit.h
---

f67d2e82d6d2fd385d3d20e8d348eaf69dc95041
diff --cc builtin/branch.c
index 9cca1b9afc,d8f15221ed..d6ab93bfbb
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@@ -391,30 -390,6 +391,28 @@@ static int matches_merge_filter(struct 
  	return (is_merged == (merge_filter == SHOW_MERGED));
  }
  
 +static void add_verbose_info(struct strbuf *out, struct ref_item *item,
 +			     int verbose, int abbrev)
 +{
 +	struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT;
 +	const char *sub = " **** invalid ref ****";
 +	struct commit *commit = item->commit;
 +
 +	if (commit && !parse_commit(commit)) {
- 		struct pretty_print_context ctx = {0};
- 		pretty_print_commit(CMIT_FMT_ONELINE, commit,
- 				    &subject, &ctx);
++		pp_commit_easy(CMIT_FMT_ONELINE, commit, &subject);
 +		sub = subject.buf;
 +	}
 +
 +	if (item->kind == REF_LOCAL_BRANCH)
 +		fill_tracking_info(&stat, item->name, verbose > 1);
 +
 +	strbuf_addf(out, " %s %s%s",
 +		find_unique_abbrev(item->commit->object.sha1, abbrev),
 +		stat.buf, sub);
 +	strbuf_release(&stat);
 +	strbuf_release(&subject);
 +}
 +
  static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
  			   int abbrev, int current, char *prefix)
  {
diff --cc builtin/checkout.c
index 4761769512,c1759dc3a4..28cdc51b85
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@@ -303,12 -297,11 +303,11 @@@ static void show_local_changes(struct o
  	run_diff_index(&rev, 0);
  }
  
 -static void describe_detached_head(char *msg, struct commit *commit)
 +static void describe_detached_head(const char *msg, struct commit *commit)
  {
  	struct strbuf sb = STRBUF_INIT;
- 	struct pretty_print_context ctx = {0};
  	parse_commit(commit);
- 	pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);
+ 	pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb);
  	fprintf(stderr, "%s %s... %s\n", msg,
  		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
  	strbuf_release(&sb);
@@@ -589,128 -577,6 +588,126 @@@ static void update_refs_for_switch(stru
  		report_tracking(new);
  }
  
 +struct rev_list_args {
 +	int argc;
 +	int alloc;
 +	const char **argv;
 +};
 +
 +static void add_one_rev_list_arg(struct rev_list_args *args, const char *s)
 +{
 +	ALLOC_GROW(args->argv, args->argc + 1, args->alloc);
 +	args->argv[args->argc++] = s;
 +}
 +
 +static int add_one_ref_to_rev_list_arg(const char *refname,
 +				       const unsigned char *sha1,
 +				       int flags,
 +				       void *cb_data)
 +{
 +	add_one_rev_list_arg(cb_data, refname);
 +	return 0;
 +}
 +
 +static int clear_commit_marks_from_one_ref(const char *refname,
 +				      const unsigned char *sha1,
 +				      int flags,
 +				      void *cb_data)
 +{
 +	struct commit *commit = lookup_commit_reference_gently(sha1, 1);
 +	if (commit)
 +		clear_commit_marks(commit, -1);
 +	return 0;
 +}
 +
 +static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
 +{
- 	struct pretty_print_context ctx = { 0 };
- 
 +	parse_commit(commit);
 +	strbuf_addstr(sb, "  ");
 +	strbuf_addstr(sb,
 +		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
 +	strbuf_addch(sb, ' ');
- 	pretty_print_commit(CMIT_FMT_ONELINE, commit, sb, &ctx);
++	pp_commit_easy(CMIT_FMT_ONELINE, commit, sb);
 +	strbuf_addch(sb, '\n');
 +}
 +
 +#define ORPHAN_CUTOFF 4
 +static void suggest_reattach(struct commit *commit, struct rev_info *revs)
 +{
 +	struct commit *c, *last = NULL;
 +	struct strbuf sb = STRBUF_INIT;
 +	int lost = 0;
 +	while ((c = get_revision(revs)) != NULL) {
 +		if (lost < ORPHAN_CUTOFF)
 +			describe_one_orphan(&sb, c);
 +		last = c;
 +		lost++;
 +	}
 +	if (ORPHAN_CUTOFF < lost) {
 +		int more = lost - ORPHAN_CUTOFF;
 +		if (more == 1)
 +			describe_one_orphan(&sb, last);
 +		else
 +			strbuf_addf(&sb, _(" ... and %d more.\n"), more);
 +	}
 +
 +	fprintf(stderr,
 +		Q_(
 +		/* The singular version */
 +		"Warning: you are leaving %d commit behind, "
 +		"not connected to\n"
 +		"any of your branches:\n\n"
 +		"%s\n"
 +		"If you want to keep it by creating a new branch, "
 +		"this may be a good time\nto do so with:\n\n"
 +		" git branch new_branch_name %s\n\n",
 +		/* The plural version */
 +		"Warning: you are leaving %d commits behind, "
 +		"not connected to\n"
 +		"any of your branches:\n\n"
 +		"%s\n"
 +		"If you want to keep them by creating a new branch, "
 +		"this may be a good time\nto do so with:\n\n"
 +		" git branch new_branch_name %s\n\n",
 +		/* Give ngettext() the count */
 +		lost),
 +		lost,
 +		sb.buf,
 +		sha1_to_hex(commit->object.sha1));
 +	strbuf_release(&sb);
 +}
 +
 +/*
 + * We are about to leave commit that was at the tip of a detached
 + * HEAD.  If it is not reachable from any ref, this is the last chance
 + * for the user to do so without resorting to reflog.
 + */
 +static void orphaned_commit_warning(struct commit *commit)
 +{
 +	struct rev_list_args args = { 0, 0, NULL };
 +	struct rev_info revs;
 +
 +	add_one_rev_list_arg(&args, "(internal)");
 +	add_one_rev_list_arg(&args, sha1_to_hex(commit->object.sha1));
 +	add_one_rev_list_arg(&args, "--not");
 +	for_each_ref(add_one_ref_to_rev_list_arg, &args);
 +	add_one_rev_list_arg(&args, "--");
 +	add_one_rev_list_arg(&args, NULL);
 +
 +	init_revisions(&revs, NULL);
 +	if (setup_revisions(args.argc - 1, args.argv, &revs, NULL) != 1)
 +		die(_("internal error: only -- alone should have been left"));
 +	if (prepare_revision_walk(&revs))
 +		die(_("internal error in revision walk"));
 +	if (!(commit->object.flags & UNINTERESTING))
 +		suggest_reattach(commit, &revs);
 +	else
 +		describe_detached_head(_("Previous HEAD position was"), commit);
 +
 +	clear_commit_marks(commit, -1);
 +	for_each_ref(clear_commit_marks_from_one_ref, NULL);
 +}
 +
  static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
  {
  	int ret = 0;
diff --cc builtin/log.c
index 224b167920,0e46e5ae95..5c2af59004
--- a/builtin/log.c
+++ b/builtin/log.c
@@@ -758,14 -714,11 +760,12 @@@ static void print_signature(void
  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)
 +			      int nr, struct commit **list, struct commit *head,
 +			      int quiet)
  {
  	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;
  	struct shortlog log;
  	struct strbuf sb = STRBUF_INIT;
  	int i;
@@@ -773,9 -726,10 +773,10 @@@
  	struct diff_options opts;
  	int need_8bit_cte = 0;
  	struct commit *commit = NULL;
+ 	struct pretty_print_context pp = {0};
  
  	if (rev->commit_format != CMIT_FMT_EMAIL)
 -		die("Cover letter needs email format");
 +		die(_("Cover letter needs email format"));
  
  	committer = git_committer_info(0);
  
@@@ -1177,9 -1128,10 +1178,10 @@@ int cmd_format_patch(int argc, const ch
  		numbered = 0;
  
  	if (numbered && keep_subject)
 -		die ("-n and -k are mutually exclusive.");
 +		die (_("-n and -k are mutually exclusive."));
  	if (keep_subject && subject_prefix)
 -		die ("--subject-prefix and -k are mutually exclusive.");
 +		die (_("--subject-prefix and -k are mutually exclusive."));
+ 	rev.preserve_subject = keep_subject;
  
  	argc = setup_revisions(argc, argv, &rev, &s_r_opt);
  	if (argc > 1)
@@@ -1402,23 -1354,6 +1404,22 @@@ static const char * const cherry_usage[
  	NULL
  };
  
 +static void print_commit(char sign, struct commit *commit, int verbose,
 +			 int abbrev)
 +{
 +	if (!verbose) {
 +		printf("%c %s\n", sign,
 +		       find_unique_abbrev(commit->object.sha1, abbrev));
 +	} else {
 +		struct strbuf buf = STRBUF_INIT;
- 		struct pretty_print_context ctx = {0};
- 		pretty_print_commit(CMIT_FMT_ONELINE, commit, &buf, &ctx);
++		pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
 +		printf("%c %s %s\n", sign,
 +		       find_unique_abbrev(commit->object.sha1, abbrev),
 +		       buf.buf);
 +		strbuf_release(&buf);
 +	}
 +}
 +
  int cmd_cherry(int argc, const char **argv, const char *prefix)
  {
  	struct rev_info revs;
diff --cc builtin/merge.c
index 5a2a1eb797,c902e81cf1..325891edb6
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@@ -345,12 -340,12 +346,12 @@@ static void squash_message(void
  		strbuf_addch(&out, '\n');
  		strbuf_addf(&out, "commit %s\n",
  			sha1_to_hex(commit->object.sha1));
- 		pretty_print_commit(rev.commit_format, commit, &out, &ctx);
+ 		pretty_print_commit(&ctx, commit, &out);
  	}
  	if (write(fd, out.buf, out.len) < 0)
 -		die_errno("Writing SQUASH_MSG");
 +		die_errno(_("Writing SQUASH_MSG"));
  	if (close(fd))
 -		die_errno("Finishing SQUASH_MSG");
 +		die_errno(_("Finishing SQUASH_MSG"));
  	strbuf_release(&out);
  }
  
diff --cc commit.h
index 3114bd1781,e985dcc6e5..a2d571b974
--- a/commit.h
+++ b/commit.h
@@@ -68,7 -68,9 +68,8 @@@ enum cmit_fmt 
  	CMIT_FMT_UNSPECIFIED
  };
  
 -struct pretty_print_context
 -{
 +struct pretty_print_context {
+ 	enum cmit_fmt fmt;
  	int abbrev;
  	const char *subject;
  	const char *after_subject;
diff --cc revision.h
index 4499cebded,f8ddd83e79..3d64adad18
--- a/revision.h
+++ b/revision.h
@@@ -91,10 -88,10 +91,11 @@@ struct rev_info 
  			show_notes_given:1,
  			pretty_given:1,
  			abbrev_commit:1,
 +			abbrev_commit_given:1,
  			use_terminator:1,
  			missing_newline:1,
- 			date_mode_explicit:1;
+ 			date_mode_explicit:1,
+ 			preserve_subject:1;
  	unsigned int	disable_stdin:1;
  
  	enum date_mode date_mode;