#include "log-tree.h"
#include "reflog-walk.h"
#include "refs.h"
+#include "string-list.h"
struct decoration name_decoration = { "object names" };
struct object *obj = parse_object(sha1);
if (!obj)
return 0;
+ if (!cb_data || *(int *)cb_data == DECORATE_SHORT_REFS)
+ refname = prettify_refname(refname);
add_name_decoration("", refname, obj);
while (obj->type == OBJ_TAG) {
obj = ((struct tag *)obj)->tagged;
return 0;
}
-void load_ref_decorations(void)
+void load_ref_decorations(int flags)
{
static int loaded;
if (!loaded) {
loaded = 1;
- for_each_ref(add_ref_decoration, NULL);
+ for_each_ref(add_ref_decoration, &flags);
+ head_ref(add_ref_decoration, &flags);
}
}
*/
static int detect_any_signoff(char *letter, int size)
{
- char ch, *cp;
+ char *cp;
int seen_colon = 0;
int seen_at = 0;
int seen_name = 0;
int seen_head = 0;
cp = letter + size;
- while (letter <= --cp && (ch = *cp) == '\n')
+ while (letter <= --cp && *cp == '\n')
continue;
while (letter <= cp) {
- ch = *cp--;
+ char ch = *cp--;
if (ch == '\n')
break;
return result;
}
-static int has_non_ascii(const char *s)
+void get_patch_filename(struct commit *commit, int nr, const char *suffix,
+ struct strbuf *buf)
{
- int ch;
- if (!s)
- return 0;
- while ((ch = *s++) != '\0') {
- if (non_ascii(ch))
- return 1;
+ int suffix_len = strlen(suffix) + 1;
+ int start_len = buf->len;
+
+ strbuf_addf(buf, commit ? "%04d-" : "%d", nr);
+ if (commit) {
+ int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len;
+ struct pretty_print_context ctx = {0};
+ ctx.date_mode = DATE_NORMAL;
+
+ format_commit_message(commit, "%f", buf, &ctx);
+ if (max_len < buf->len)
+ strbuf_setlen(buf, max_len);
+ strbuf_addstr(buf, suffix);
}
- return 0;
}
-void log_write_email_headers(struct rev_info *opt, const char *name,
+void log_write_email_headers(struct rev_info *opt, struct commit *commit,
const char **subject_p,
const char **extra_headers_p,
int *need_8bit_cte_p)
{
const char *subject = NULL;
const char *extra_headers = opt->extra_headers;
+ const char *name = sha1_to_hex(commit->object.sha1);
*need_8bit_cte_p = 0; /* unknown */
if (opt->total > 0) {
printf("Message-Id: <%s>\n", opt->message_id);
graph_show_oneline(opt->graph);
}
- if (opt->ref_message_id) {
- printf("In-Reply-To: <%s>\nReferences: <%s>\n",
- opt->ref_message_id, opt->ref_message_id);
+ if (opt->ref_message_ids && opt->ref_message_ids->nr > 0) {
+ int i, n;
+ n = opt->ref_message_ids->nr;
+ printf("In-Reply-To: <%s>\n", opt->ref_message_ids->items[n-1].string);
+ for (i = 0; i < n; i++)
+ printf("%s<%s>\n", (i > 0 ? "\t" : "References: "),
+ opt->ref_message_ids->items[i].string);
graph_show_oneline(opt->graph);
}
if (opt->mime_boundary) {
static char subject_buffer[1024];
static char buffer[1024];
+ struct strbuf filename = STRBUF_INIT;
*need_8bit_cte_p = -1; /* NEVER */
snprintf(subject_buffer, sizeof(subject_buffer) - 1,
"%s"
mime_boundary_leader, opt->mime_boundary);
extra_headers = subject_buffer;
+ get_patch_filename(opt->numbered_files ? NULL : commit, opt->nr,
+ opt->patch_suffix, &filename);
snprintf(buffer, sizeof(buffer) - 1,
"\n--%s%s\n"
"Content-Type: text/x-patch;"
- " name=\"%s.diff\"\n"
+ " name=\"%s\"\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Disposition: %s;"
- " filename=\"%s.diff\"\n\n",
+ " filename=\"%s\"\n\n",
mime_boundary_leader, opt->mime_boundary,
- name,
+ filename.buf,
opt->no_inline ? "attachment" : "inline",
- name);
+ filename.buf);
opt->diffopt.stat_sep = buffer;
+ strbuf_release(&filename);
}
*subject_p = subject;
*extra_headers_p = extra_headers;
struct strbuf msgbuf = STRBUF_INIT;
struct log_info *log = opt->loginfo;
struct commit *commit = log->commit, *parent = log->parent;
- int abbrev = opt->diffopt.abbrev;
int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
- const char *subject = NULL, *extra_headers = opt->extra_headers;
- int need_8bit_cte = 0;
+ const char *extra_headers = opt->extra_headers;
+ struct pretty_print_context ctx = {0};
opt->loginfo = NULL;
if (!opt->verbose_header) {
}
/*
- * If use_terminator is set, add a newline at the end of the entry.
+ * If use_terminator is set, we already handled any record termination
+ * at the end of the last record.
* Otherwise, add a diffopt.line_termination character before all
* entries but the first. (IOW, as a separator between entries)
*/
*/
if (opt->commit_format == CMIT_FMT_EMAIL) {
- log_write_email_headers(opt, sha1_to_hex(commit->object.sha1),
- &subject, &extra_headers,
- &need_8bit_cte);
+ log_write_email_headers(opt, commit, &ctx.subject, &extra_headers,
+ &ctx.need_8bit_cte);
} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
if (opt->commit_format != CMIT_FMT_ONELINE)
*/
show_reflog_message(opt->reflog_info,
opt->commit_format == CMIT_FMT_ONELINE,
- opt->date_mode);
+ opt->date_mode_explicit ?
+ opt->date_mode :
+ DATE_NORMAL);
if (opt->commit_format == CMIT_FMT_ONELINE)
return;
}
/*
* And then the pretty-printed message itself
*/
- if (need_8bit_cte >= 0)
- need_8bit_cte = has_non_ascii(opt->add_signoff);
- pretty_print_commit(opt->commit_format, commit, &msgbuf,
- abbrev, subject, extra_headers, opt->date_mode,
- need_8bit_cte);
+ if (ctx.need_8bit_cte >= 0)
+ ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
+ ctx.date_mode = opt->date_mode;
+ ctx.abbrev = opt->diffopt.abbrev;
+ ctx.after_subject = extra_headers;
+ ctx.reflog_info = opt->reflog_info;
+ pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
if (opt->add_signoff)
append_signoff(&msgbuf, opt->add_signoff);