THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1746 lines
43 KiB

  1. #include "cache.h"
  2. #include "commit.h"
  3. #include "utf8.h"
  4. #include "diff.h"
  5. #include "revision.h"
  6. #include "string-list.h"
  7. #include "mailmap.h"
  8. #include "log-tree.h"
  9. #include "notes.h"
  10. #include "color.h"
  11. #include "reflog-walk.h"
  12. #include "gpg-interface.h"
  13. static char *user_format;
  14. static struct cmt_fmt_map {
  15. const char *name;
  16. enum cmit_fmt format;
  17. int is_tformat;
  18. int is_alias;
  19. const char *user_format;
  20. } *commit_formats;
  21. static size_t builtin_formats_len;
  22. static size_t commit_formats_len;
  23. static size_t commit_formats_alloc;
  24. static struct cmt_fmt_map *find_commit_format(const char *sought);
  25. int commit_format_is_empty(enum cmit_fmt fmt)
  26. {
  27. return fmt == CMIT_FMT_USERFORMAT && !*user_format;
  28. }
  29. static void save_user_format(struct rev_info *rev, const char *cp, int is_tformat)
  30. {
  31. free(user_format);
  32. user_format = xstrdup(cp);
  33. if (is_tformat)
  34. rev->use_terminator = 1;
  35. rev->commit_format = CMIT_FMT_USERFORMAT;
  36. }
  37. static int git_pretty_formats_config(const char *var, const char *value, void *cb)
  38. {
  39. struct cmt_fmt_map *commit_format = NULL;
  40. const char *name;
  41. const char *fmt;
  42. int i;
  43. if (!skip_prefix(var, "pretty.", &name))
  44. return 0;
  45. for (i = 0; i < builtin_formats_len; i++) {
  46. if (!strcmp(commit_formats[i].name, name))
  47. return 0;
  48. }
  49. for (i = builtin_formats_len; i < commit_formats_len; i++) {
  50. if (!strcmp(commit_formats[i].name, name)) {
  51. commit_format = &commit_formats[i];
  52. break;
  53. }
  54. }
  55. if (!commit_format) {
  56. ALLOC_GROW(commit_formats, commit_formats_len+1,
  57. commit_formats_alloc);
  58. commit_format = &commit_formats[commit_formats_len];
  59. memset(commit_format, 0, sizeof(*commit_format));
  60. commit_formats_len++;
  61. }
  62. commit_format->name = xstrdup(name);
  63. commit_format->format = CMIT_FMT_USERFORMAT;
  64. if (git_config_string(&fmt, var, value))
  65. return -1;
  66. if (skip_prefix(fmt, "format:", &fmt))
  67. commit_format->is_tformat = 0;
  68. else if (skip_prefix(fmt, "tformat:", &fmt) || strchr(fmt, '%'))
  69. commit_format->is_tformat = 1;
  70. else
  71. commit_format->is_alias = 1;
  72. commit_format->user_format = fmt;
  73. return 0;
  74. }
  75. static void setup_commit_formats(void)
  76. {
  77. struct cmt_fmt_map builtin_formats[] = {
  78. { "raw", CMIT_FMT_RAW, 0 },
  79. { "medium", CMIT_FMT_MEDIUM, 0 },
  80. { "short", CMIT_FMT_SHORT, 0 },
  81. { "email", CMIT_FMT_EMAIL, 0 },
  82. { "fuller", CMIT_FMT_FULLER, 0 },
  83. { "full", CMIT_FMT_FULL, 0 },
  84. { "oneline", CMIT_FMT_ONELINE, 1 }
  85. };
  86. commit_formats_len = ARRAY_SIZE(builtin_formats);
  87. builtin_formats_len = commit_formats_len;
  88. ALLOC_GROW(commit_formats, commit_formats_len, commit_formats_alloc);
  89. memcpy(commit_formats, builtin_formats,
  90. sizeof(*builtin_formats)*ARRAY_SIZE(builtin_formats));
  91. git_config(git_pretty_formats_config, NULL);
  92. }
  93. static struct cmt_fmt_map *find_commit_format_recursive(const char *sought,
  94. const char *original,
  95. int num_redirections)
  96. {
  97. struct cmt_fmt_map *found = NULL;
  98. size_t found_match_len = 0;
  99. int i;
  100. if (num_redirections >= commit_formats_len)
  101. die("invalid --pretty format: "
  102. "'%s' references an alias which points to itself",
  103. original);
  104. for (i = 0; i < commit_formats_len; i++) {
  105. size_t match_len;
  106. if (!starts_with(commit_formats[i].name, sought))
  107. continue;
  108. match_len = strlen(commit_formats[i].name);
  109. if (found == NULL || found_match_len > match_len) {
  110. found = &commit_formats[i];
  111. found_match_len = match_len;
  112. }
  113. }
  114. if (found && found->is_alias) {
  115. found = find_commit_format_recursive(found->user_format,
  116. original,
  117. num_redirections+1);
  118. }
  119. return found;
  120. }
  121. static struct cmt_fmt_map *find_commit_format(const char *sought)
  122. {
  123. if (!commit_formats)
  124. setup_commit_formats();
  125. return find_commit_format_recursive(sought, sought, 0);
  126. }
  127. void get_commit_format(const char *arg, struct rev_info *rev)
  128. {
  129. struct cmt_fmt_map *commit_format;
  130. rev->use_terminator = 0;
  131. if (!arg) {
  132. rev->commit_format = CMIT_FMT_DEFAULT;
  133. return;
  134. }
  135. if (skip_prefix(arg, "format:", &arg)) {
  136. save_user_format(rev, arg, 0);
  137. return;
  138. }
  139. if (!*arg || skip_prefix(arg, "tformat:", &arg) || strchr(arg, '%')) {
  140. save_user_format(rev, arg, 1);
  141. return;
  142. }
  143. commit_format = find_commit_format(arg);
  144. if (!commit_format)
  145. die("invalid --pretty format: %s", arg);
  146. rev->commit_format = commit_format->format;
  147. rev->use_terminator = commit_format->is_tformat;
  148. if (commit_format->format == CMIT_FMT_USERFORMAT) {
  149. save_user_format(rev, commit_format->user_format,
  150. commit_format->is_tformat);
  151. }
  152. }
  153. /*
  154. * Generic support for pretty-printing the header
  155. */
  156. static int get_one_line(const char *msg)
  157. {
  158. int ret = 0;
  159. for (;;) {
  160. char c = *msg++;
  161. if (!c)
  162. break;
  163. ret++;
  164. if (c == '\n')
  165. break;
  166. }
  167. return ret;
  168. }
  169. /* High bit set, or ISO-2022-INT */
  170. static int non_ascii(int ch)
  171. {
  172. return !isascii(ch) || ch == '\033';
  173. }
  174. int has_non_ascii(const char *s)
  175. {
  176. int ch;
  177. if (!s)
  178. return 0;
  179. while ((ch = *s++) != '\0') {
  180. if (non_ascii(ch))
  181. return 1;
  182. }
  183. return 0;
  184. }
  185. static int is_rfc822_special(char ch)
  186. {
  187. switch (ch) {
  188. case '(':
  189. case ')':
  190. case '<':
  191. case '>':
  192. case '[':
  193. case ']':
  194. case ':':
  195. case ';':
  196. case '@':
  197. case ',':
  198. case '.':
  199. case '"':
  200. case '\\':
  201. return 1;
  202. default:
  203. return 0;
  204. }
  205. }
  206. static int needs_rfc822_quoting(const char *s, int len)
  207. {
  208. int i;
  209. for (i = 0; i < len; i++)
  210. if (is_rfc822_special(s[i]))
  211. return 1;
  212. return 0;
  213. }
  214. static int last_line_length(struct strbuf *sb)
  215. {
  216. int i;
  217. /* How many bytes are already used on the last line? */
  218. for (i = sb->len - 1; i >= 0; i--)
  219. if (sb->buf[i] == '\n')
  220. break;
  221. return sb->len - (i + 1);
  222. }
  223. static void add_rfc822_quoted(struct strbuf *out, const char *s, int len)
  224. {
  225. int i;
  226. /* just a guess, we may have to also backslash-quote */
  227. strbuf_grow(out, len + 2);
  228. strbuf_addch(out, '"');
  229. for (i = 0; i < len; i++) {
  230. switch (s[i]) {
  231. case '"':
  232. case '\\':
  233. strbuf_addch(out, '\\');
  234. /* fall through */
  235. default:
  236. strbuf_addch(out, s[i]);
  237. }
  238. }
  239. strbuf_addch(out, '"');
  240. }
  241. enum rfc2047_type {
  242. RFC2047_SUBJECT,
  243. RFC2047_ADDRESS
  244. };
  245. static int is_rfc2047_special(char ch, enum rfc2047_type type)
  246. {
  247. /*
  248. * rfc2047, section 4.2:
  249. *
  250. * 8-bit values which correspond to printable ASCII characters other
  251. * than "=", "?", and "_" (underscore), MAY be represented as those
  252. * characters. (But see section 5 for restrictions.) In
  253. * particular, SPACE and TAB MUST NOT be represented as themselves
  254. * within encoded words.
  255. */
  256. /*
  257. * rule out non-ASCII characters and non-printable characters (the
  258. * non-ASCII check should be redundant as isprint() is not localized
  259. * and only knows about ASCII, but be defensive about that)
  260. */
  261. if (non_ascii(ch) || !isprint(ch))
  262. return 1;
  263. /*
  264. * rule out special printable characters (' ' should be the only
  265. * whitespace character considered printable, but be defensive and use
  266. * isspace())
  267. */
  268. if (isspace(ch) || ch == '=' || ch == '?' || ch == '_')
  269. return 1;
  270. /*
  271. * rfc2047, section 5.3:
  272. *
  273. * As a replacement for a 'word' entity within a 'phrase', for example,
  274. * one that precedes an address in a From, To, or Cc header. The ABNF
  275. * definition for 'phrase' from RFC 822 thus becomes:
  276. *
  277. * phrase = 1*( encoded-word / word )
  278. *
  279. * In this case the set of characters that may be used in a "Q"-encoded
  280. * 'encoded-word' is restricted to: <upper and lower case ASCII
  281. * letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_"
  282. * (underscore, ASCII 95.)>. An 'encoded-word' that appears within a
  283. * 'phrase' MUST be separated from any adjacent 'word', 'text' or
  284. * 'special' by 'linear-white-space'.
  285. */
  286. if (type != RFC2047_ADDRESS)
  287. return 0;
  288. /* '=' and '_' are special cases and have been checked above */
  289. return !(isalnum(ch) || ch == '!' || ch == '*' || ch == '+' || ch == '-' || ch == '/');
  290. }
  291. static int needs_rfc2047_encoding(const char *line, int len,
  292. enum rfc2047_type type)
  293. {
  294. int i;
  295. for (i = 0; i < len; i++) {
  296. int ch = line[i];
  297. if (non_ascii(ch) || ch == '\n')
  298. return 1;
  299. if ((i + 1 < len) && (ch == '=' && line[i+1] == '?'))
  300. return 1;
  301. }
  302. return 0;
  303. }
  304. static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,
  305. const char *encoding, enum rfc2047_type type)
  306. {
  307. static const int max_encoded_length = 76; /* per rfc2047 */
  308. int i;
  309. int line_len = last_line_length(sb);
  310. strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
  311. strbuf_addf(sb, "=?%s?q?", encoding);
  312. line_len += strlen(encoding) + 5; /* 5 for =??q? */
  313. while (len) {
  314. /*
  315. * RFC 2047, section 5 (3):
  316. *
  317. * Each 'encoded-word' MUST represent an integral number of
  318. * characters. A multi-octet character may not be split across
  319. * adjacent 'encoded- word's.
  320. */
  321. const unsigned char *p = (const unsigned char *)line;
  322. int chrlen = mbs_chrlen(&line, &len, encoding);
  323. int is_special = (chrlen > 1) || is_rfc2047_special(*p, type);
  324. /* "=%02X" * chrlen, or the byte itself */
  325. const char *encoded_fmt = is_special ? "=%02X" : "%c";
  326. int encoded_len = is_special ? 3 * chrlen : 1;
  327. /*
  328. * According to RFC 2047, we could encode the special character
  329. * ' ' (space) with '_' (underscore) for readability. But many
  330. * programs do not understand this and just leave the
  331. * underscore in place. Thus, we do nothing special here, which
  332. * causes ' ' to be encoded as '=20', avoiding this problem.
  333. */
  334. if (line_len + encoded_len + 2 > max_encoded_length) {
  335. /* It won't fit with trailing "?=" --- break the line */
  336. strbuf_addf(sb, "?=\n =?%s?q?", encoding);
  337. line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
  338. }
  339. for (i = 0; i < chrlen; i++)
  340. strbuf_addf(sb, encoded_fmt, p[i]);
  341. line_len += encoded_len;
  342. }
  343. strbuf_addstr(sb, "?=");
  344. }
  345. const char *show_ident_date(const struct ident_split *ident,
  346. const struct date_mode *mode)
  347. {
  348. unsigned long date = 0;
  349. long tz = 0;
  350. if (ident->date_begin && ident->date_end)
  351. date = strtoul(ident->date_begin, NULL, 10);
  352. if (date_overflows(date))
  353. date = 0;
  354. else {
  355. if (ident->tz_begin && ident->tz_end)
  356. tz = strtol(ident->tz_begin, NULL, 10);
  357. if (tz >= INT_MAX || tz <= INT_MIN)
  358. tz = 0;
  359. }
  360. return show_date(date, tz, mode);
  361. }
  362. void pp_user_info(struct pretty_print_context *pp,
  363. const char *what, struct strbuf *sb,
  364. const char *line, const char *encoding)
  365. {
  366. struct ident_split ident;
  367. char *line_end;
  368. const char *mailbuf, *namebuf;
  369. size_t namelen, maillen;
  370. int max_length = 78; /* per rfc2822 */
  371. if (pp->fmt == CMIT_FMT_ONELINE)
  372. return;
  373. line_end = strchrnul(line, '\n');
  374. if (split_ident_line(&ident, line, line_end - line))
  375. return;
  376. mailbuf = ident.mail_begin;
  377. maillen = ident.mail_end - ident.mail_begin;
  378. namebuf = ident.name_begin;
  379. namelen = ident.name_end - ident.name_begin;
  380. if (pp->mailmap)
  381. map_user(pp->mailmap, &mailbuf, &maillen, &namebuf, &namelen);
  382. if (pp->fmt == CMIT_FMT_EMAIL) {
  383. if (pp->from_ident && ident_cmp(pp->from_ident, &ident)) {
  384. struct strbuf buf = STRBUF_INIT;
  385. strbuf_addstr(&buf, "From: ");
  386. strbuf_add(&buf, namebuf, namelen);
  387. strbuf_addstr(&buf, " <");
  388. strbuf_add(&buf, mailbuf, maillen);
  389. strbuf_addstr(&buf, ">\n");
  390. string_list_append(&pp->in_body_headers,
  391. strbuf_detach(&buf, NULL));
  392. mailbuf = pp->from_ident->mail_begin;
  393. maillen = pp->from_ident->mail_end - mailbuf;
  394. namebuf = pp->from_ident->name_begin;
  395. namelen = pp->from_ident->name_end - namebuf;
  396. }
  397. strbuf_addstr(sb, "From: ");
  398. if (needs_rfc2047_encoding(namebuf, namelen, RFC2047_ADDRESS)) {
  399. add_rfc2047(sb, namebuf, namelen,
  400. encoding, RFC2047_ADDRESS);
  401. max_length = 76; /* per rfc2047 */
  402. } else if (needs_rfc822_quoting(namebuf, namelen)) {
  403. struct strbuf quoted = STRBUF_INIT;
  404. add_rfc822_quoted(&quoted, namebuf, namelen);
  405. strbuf_add_wrapped_bytes(sb, quoted.buf, quoted.len,
  406. -6, 1, max_length);
  407. strbuf_release(&quoted);
  408. } else {
  409. strbuf_add_wrapped_bytes(sb, namebuf, namelen,
  410. -6, 1, max_length);
  411. }
  412. if (max_length <
  413. last_line_length(sb) + strlen(" <") + maillen + strlen(">"))
  414. strbuf_addch(sb, '\n');
  415. strbuf_addf(sb, " <%.*s>\n", (int)maillen, mailbuf);
  416. } else {
  417. strbuf_addf(sb, "%s: %.*s%.*s <%.*s>\n", what,
  418. (pp->fmt == CMIT_FMT_FULLER) ? 4 : 0, " ",
  419. (int)namelen, namebuf, (int)maillen, mailbuf);
  420. }
  421. switch (pp->fmt) {
  422. case CMIT_FMT_MEDIUM:
  423. strbuf_addf(sb, "Date: %s\n",
  424. show_ident_date(&ident, &pp->date_mode));
  425. break;
  426. case CMIT_FMT_EMAIL:
  427. strbuf_addf(sb, "Date: %s\n",
  428. show_ident_date(&ident, DATE_MODE(RFC2822)));
  429. break;
  430. case CMIT_FMT_FULLER:
  431. strbuf_addf(sb, "%sDate: %s\n", what,
  432. show_ident_date(&ident, &pp->date_mode));
  433. break;
  434. default:
  435. /* notin' */
  436. break;
  437. }
  438. }
  439. static int is_empty_line(const char *line, int *len_p)
  440. {
  441. int len = *len_p;
  442. while (len && isspace(line[len - 1]))
  443. len--;
  444. *len_p = len;
  445. return !len;
  446. }
  447. static const char *skip_empty_lines(const char *msg)
  448. {
  449. for (;;) {
  450. int linelen = get_one_line(msg);
  451. int ll = linelen;
  452. if (!linelen)
  453. break;
  454. if (!is_empty_line(msg, &ll))
  455. break;
  456. msg += linelen;
  457. }
  458. return msg;
  459. }
  460. static void add_merge_info(const struct pretty_print_context *pp,
  461. struct strbuf *sb, const struct commit *commit)
  462. {
  463. struct commit_list *parent = commit->parents;
  464. if ((pp->fmt == CMIT_FMT_ONELINE) || (pp->fmt == CMIT_FMT_EMAIL) ||
  465. !parent || !parent->next)
  466. return;
  467. strbuf_addstr(sb, "Merge:");
  468. while (parent) {
  469. struct commit *p = parent->item;
  470. const char *hex = NULL;
  471. if (pp->abbrev)
  472. hex = find_unique_abbrev(p->object.oid.hash, pp->abbrev);
  473. if (!hex)
  474. hex = oid_to_hex(&p->object.oid);
  475. parent = parent->next;
  476. strbuf_addf(sb, " %s", hex);
  477. }
  478. strbuf_addch(sb, '\n');
  479. }
  480. static char *get_header(const char *msg, const char *key)
  481. {
  482. size_t len;
  483. const char *v = find_commit_header(msg, key, &len);
  484. return v ? xmemdupz(v, len) : NULL;
  485. }
  486. static char *replace_encoding_header(char *buf, const char *encoding)
  487. {
  488. struct strbuf tmp = STRBUF_INIT;
  489. size_t start, len;
  490. char *cp = buf;
  491. /* guess if there is an encoding header before a \n\n */
  492. while (!starts_with(cp, "encoding ")) {
  493. cp = strchr(cp, '\n');
  494. if (!cp || *++cp == '\n')
  495. return buf;
  496. }
  497. start = cp - buf;
  498. cp = strchr(cp, '\n');
  499. if (!cp)
  500. return buf; /* should not happen but be defensive */
  501. len = cp + 1 - (buf + start);
  502. strbuf_attach(&tmp, buf, strlen(buf), strlen(buf) + 1);
  503. if (is_encoding_utf8(encoding)) {
  504. /* we have re-coded to UTF-8; drop the header */
  505. strbuf_remove(&tmp, start, len);
  506. } else {
  507. /* just replaces XXXX in 'encoding XXXX\n' */
  508. strbuf_splice(&tmp, start + strlen("encoding "),
  509. len - strlen("encoding \n"),
  510. encoding, strlen(encoding));
  511. }
  512. return strbuf_detach(&tmp, NULL);
  513. }
  514. const char *logmsg_reencode(const struct commit *commit,
  515. char **commit_encoding,
  516. const char *output_encoding)
  517. {
  518. static const char *utf8 = "UTF-8";
  519. const char *use_encoding;
  520. char *encoding;
  521. const char *msg = get_commit_buffer(commit, NULL);
  522. char *out;
  523. if (!output_encoding || !*output_encoding) {
  524. if (commit_encoding)
  525. *commit_encoding = get_header(msg, "encoding");
  526. return msg;
  527. }
  528. encoding = get_header(msg, "encoding");
  529. if (commit_encoding)
  530. *commit_encoding = encoding;
  531. use_encoding = encoding ? encoding : utf8;
  532. if (same_encoding(use_encoding, output_encoding)) {
  533. /*
  534. * No encoding work to be done. If we have no encoding header
  535. * at all, then there's nothing to do, and we can return the
  536. * message verbatim (whether newly allocated or not).
  537. */
  538. if (!encoding)
  539. return msg;
  540. /*
  541. * Otherwise, we still want to munge the encoding header in the
  542. * result, which will be done by modifying the buffer. If we
  543. * are using a fresh copy, we can reuse it. But if we are using
  544. * the cached copy from get_commit_buffer, we need to duplicate it
  545. * to avoid munging the cached copy.
  546. */
  547. if (msg == get_cached_commit_buffer(commit, NULL))
  548. out = xstrdup(msg);
  549. else
  550. out = (char *)msg;
  551. }
  552. else {
  553. /*
  554. * There's actual encoding work to do. Do the reencoding, which
  555. * still leaves the header to be replaced in the next step. At
  556. * this point, we are done with msg. If we allocated a fresh
  557. * copy, we can free it.
  558. */
  559. out = reencode_string(msg, output_encoding, use_encoding);
  560. if (out)
  561. unuse_commit_buffer(commit, msg);
  562. }
  563. /*
  564. * This replacement actually consumes the buffer we hand it, so we do
  565. * not have to worry about freeing the old "out" here.
  566. */
  567. if (out)
  568. out = replace_encoding_header(out, output_encoding);
  569. if (!commit_encoding)
  570. free(encoding);
  571. /*
  572. * If the re-encoding failed, out might be NULL here; in that
  573. * case we just return the commit message verbatim.
  574. */
  575. return out ? out : msg;
  576. }
  577. static int mailmap_name(const char **email, size_t *email_len,
  578. const char **name, size_t *name_len)
  579. {
  580. static struct string_list *mail_map;
  581. if (!mail_map) {
  582. mail_map = xcalloc(1, sizeof(*mail_map));
  583. read_mailmap(mail_map, NULL);
  584. }
  585. return mail_map->nr && map_user(mail_map, email, email_len, name, name_len);
  586. }
  587. static size_t format_person_part(struct strbuf *sb, char part,
  588. const char *msg, int len,
  589. const struct date_mode *dmode)
  590. {
  591. /* currently all placeholders have same length */
  592. const int placeholder_len = 2;
  593. struct ident_split s;
  594. const char *name, *mail;
  595. size_t maillen, namelen;
  596. if (split_ident_line(&s, msg, len) < 0)
  597. goto skip;
  598. name = s.name_begin;
  599. namelen = s.name_end - s.name_begin;
  600. mail = s.mail_begin;
  601. maillen = s.mail_end - s.mail_begin;
  602. if (part == 'N' || part == 'E') /* mailmap lookup */
  603. mailmap_name(&mail, &maillen, &name, &namelen);
  604. if (part == 'n' || part == 'N') { /* name */
  605. strbuf_add(sb, name, namelen);
  606. return placeholder_len;
  607. }
  608. if (part == 'e' || part == 'E') { /* email */
  609. strbuf_add(sb, mail, maillen);
  610. return placeholder_len;
  611. }
  612. if (!s.date_begin)
  613. goto skip;
  614. if (part == 't') { /* date, UNIX timestamp */
  615. strbuf_add(sb, s.date_begin, s.date_end - s.date_begin);
  616. return placeholder_len;
  617. }
  618. switch (part) {
  619. case 'd': /* date */
  620. strbuf_addstr(sb, show_ident_date(&s, dmode));
  621. return placeholder_len;
  622. case 'D': /* date, RFC2822 style */
  623. strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(RFC2822)));
  624. return placeholder_len;
  625. case 'r': /* date, relative */
  626. strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(RELATIVE)));
  627. return placeholder_len;
  628. case 'i': /* date, ISO 8601-like */
  629. strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(ISO8601)));
  630. return placeholder_len;
  631. case 'I': /* date, ISO 8601 strict */
  632. strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(ISO8601_STRICT)));
  633. return placeholder_len;
  634. }
  635. skip:
  636. /*
  637. * reading from either a bogus commit, or a reflog entry with
  638. * %gn, %ge, etc.; 'sb' cannot be updated, but we still need
  639. * to compute a valid return value.
  640. */
  641. if (part == 'n' || part == 'e' || part == 't' || part == 'd'
  642. || part == 'D' || part == 'r' || part == 'i')
  643. return placeholder_len;
  644. return 0; /* unknown placeholder */
  645. }
  646. struct chunk {
  647. size_t off;
  648. size_t len;
  649. };
  650. enum flush_type {
  651. no_flush,
  652. flush_right,
  653. flush_left,
  654. flush_left_and_steal,
  655. flush_both
  656. };
  657. enum trunc_type {
  658. trunc_none,
  659. trunc_left,
  660. trunc_middle,
  661. trunc_right
  662. };
  663. struct format_commit_context {
  664. const struct commit *commit;
  665. const struct pretty_print_context *pretty_ctx;
  666. unsigned commit_header_parsed:1;
  667. unsigned commit_message_parsed:1;
  668. struct signature_check signature_check;
  669. enum flush_type flush_type;
  670. enum trunc_type truncate;
  671. const char *message;
  672. char *commit_encoding;
  673. size_t width, indent1, indent2;
  674. int auto_color;
  675. int padding;
  676. /* These offsets are relative to the start of the commit message. */
  677. struct chunk author;
  678. struct chunk committer;
  679. size_t message_off;
  680. size_t subject_off;
  681. size_t body_off;
  682. /* The following ones are relative to the result struct strbuf. */
  683. struct chunk abbrev_commit_hash;
  684. struct chunk abbrev_tree_hash;
  685. struct chunk abbrev_parent_hashes;
  686. size_t wrap_start;
  687. };
  688. static int add_again(struct strbuf *sb, struct chunk *chunk)
  689. {
  690. if (chunk->len) {
  691. strbuf_adddup(sb, chunk->off, chunk->len);
  692. return 1;
  693. }
  694. /*
  695. * We haven't seen this chunk before. Our caller is surely
  696. * going to add it the hard way now. Remember the most likely
  697. * start of the to-be-added chunk: the current end of the
  698. * struct strbuf.
  699. */
  700. chunk->off = sb->len;
  701. return 0;
  702. }
  703. static void parse_commit_header(struct format_commit_context *context)
  704. {
  705. const char *msg = context->message;
  706. int i;
  707. for (i = 0; msg[i]; i++) {
  708. const char *name;
  709. int eol;
  710. for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
  711. ; /* do nothing */
  712. if (i == eol) {
  713. break;
  714. } else if (skip_prefix(msg + i, "author ", &name)) {
  715. context->author.off = name - msg;
  716. context->author.len = msg + eol - name;
  717. } else if (skip_prefix(msg + i, "committer ", &name)) {
  718. context->committer.off = name - msg;
  719. context->committer.len = msg + eol - name;
  720. }
  721. i = eol;
  722. }
  723. context->message_off = i;
  724. context->commit_header_parsed = 1;
  725. }
  726. static int istitlechar(char c)
  727. {
  728. return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
  729. (c >= '0' && c <= '9') || c == '.' || c == '_';
  730. }
  731. static void format_sanitized_subject(struct strbuf *sb, const char *msg)
  732. {
  733. size_t trimlen;
  734. size_t start_len = sb->len;
  735. int space = 2;
  736. for (; *msg && *msg != '\n'; msg++) {
  737. if (istitlechar(*msg)) {
  738. if (space == 1)
  739. strbuf_addch(sb, '-');
  740. space = 0;
  741. strbuf_addch(sb, *msg);
  742. if (*msg == '.')
  743. while (*(msg+1) == '.')
  744. msg++;
  745. } else
  746. space |= 1;
  747. }
  748. /* trim any trailing '.' or '-' characters */
  749. trimlen = 0;
  750. while (sb->len - trimlen > start_len &&
  751. (sb->buf[sb->len - 1 - trimlen] == '.'
  752. || sb->buf[sb->len - 1 - trimlen] == '-'))
  753. trimlen++;
  754. strbuf_remove(sb, sb->len - trimlen, trimlen);
  755. }
  756. const char *format_subject(struct strbuf *sb, const char *msg,
  757. const char *line_separator)
  758. {
  759. int first = 1;
  760. for (;;) {
  761. const char *line = msg;
  762. int linelen = get_one_line(line);
  763. msg += linelen;
  764. if (!linelen || is_empty_line(line, &linelen))
  765. break;
  766. if (!sb)
  767. continue;
  768. strbuf_grow(sb, linelen + 2);
  769. if (!first)
  770. strbuf_addstr(sb, line_separator);
  771. strbuf_add(sb, line, linelen);
  772. first = 0;
  773. }
  774. return msg;
  775. }
  776. static void parse_commit_message(struct format_commit_context *c)
  777. {
  778. const char *msg = c->message + c->message_off;
  779. const char *start = c->message;
  780. msg = skip_empty_lines(msg);
  781. c->subject_off = msg - start;
  782. msg = format_subject(NULL, msg, NULL);
  783. msg = skip_empty_lines(msg);
  784. c->body_off = msg - start;
  785. c->commit_message_parsed = 1;
  786. }
  787. static void strbuf_wrap(struct strbuf *sb, size_t pos,
  788. size_t width, size_t indent1, size_t indent2)
  789. {
  790. struct strbuf tmp = STRBUF_INIT;
  791. if (pos)
  792. strbuf_add(&tmp, sb->buf, pos);
  793. strbuf_add_wrapped_text(&tmp, sb->buf + pos,
  794. (int) indent1, (int) indent2, (int) width);
  795. strbuf_swap(&tmp, sb);
  796. strbuf_release(&tmp);
  797. }
  798. static void rewrap_message_tail(struct strbuf *sb,
  799. struct format_commit_context *c,
  800. size_t new_width, size_t new_indent1,
  801. size_t new_indent2)
  802. {
  803. if (c->width == new_width && c->indent1 == new_indent1 &&
  804. c->indent2 == new_indent2)
  805. return;
  806. if (c->wrap_start < sb->len)
  807. strbuf_wrap(sb, c->wrap_start, c->width, c->indent1, c->indent2);
  808. c->wrap_start = sb->len;
  809. c->width = new_width;
  810. c->indent1 = new_indent1;
  811. c->indent2 = new_indent2;
  812. }
  813. static int format_reflog_person(struct strbuf *sb,
  814. char part,
  815. struct reflog_walk_info *log,
  816. const struct date_mode *dmode)
  817. {
  818. const char *ident;
  819. if (!log)
  820. return 2;
  821. ident = get_reflog_ident(log);
  822. if (!ident)
  823. return 2;
  824. return format_person_part(sb, part, ident, strlen(ident), dmode);
  825. }
  826. static size_t parse_color(struct strbuf *sb, /* in UTF-8 */
  827. const char *placeholder,
  828. struct format_commit_context *c)
  829. {
  830. const char *rest = placeholder;
  831. if (placeholder[1] == '(') {
  832. const char *begin = placeholder + 2;
  833. const char *end = strchr(begin, ')');
  834. char color[COLOR_MAXLEN];
  835. if (!end)
  836. return 0;
  837. if (skip_prefix(begin, "auto,", &begin)) {
  838. if (!want_color(c->pretty_ctx->color))
  839. return end - placeholder + 1;
  840. }
  841. if (color_parse_mem(begin, end - begin, color) < 0)
  842. die(_("unable to parse --pretty format"));
  843. strbuf_addstr(sb, color);
  844. return end - placeholder + 1;
  845. }
  846. if (skip_prefix(placeholder + 1, "red", &rest))
  847. strbuf_addstr(sb, GIT_COLOR_RED);
  848. else if (skip_prefix(placeholder + 1, "green", &rest))
  849. strbuf_addstr(sb, GIT_COLOR_GREEN);
  850. else if (skip_prefix(placeholder + 1, "blue", &rest))
  851. strbuf_addstr(sb, GIT_COLOR_BLUE);
  852. else if (skip_prefix(placeholder + 1, "reset", &rest))
  853. strbuf_addstr(sb, GIT_COLOR_RESET);
  854. return rest - placeholder;
  855. }
  856. static size_t parse_padding_placeholder(struct strbuf *sb,
  857. const char *placeholder,
  858. struct format_commit_context *c)
  859. {
  860. const char *ch = placeholder;
  861. enum flush_type flush_type;
  862. int to_column = 0;
  863. switch (*ch++) {
  864. case '<':
  865. flush_type = flush_right;
  866. break;
  867. case '>':
  868. if (*ch == '<') {
  869. flush_type = flush_both;
  870. ch++;
  871. } else if (*ch == '>') {
  872. flush_type = flush_left_and_steal;
  873. ch++;
  874. } else
  875. flush_type = flush_left;
  876. break;
  877. default:
  878. return 0;
  879. }
  880. /* the next value means "wide enough to that column" */
  881. if (*ch == '|') {
  882. to_column = 1;
  883. ch++;
  884. }
  885. if (*ch == '(') {
  886. const char *start = ch + 1;
  887. const char *end = start + strcspn(start, ",)");
  888. char *next;
  889. int width;
  890. if (!end || end == start)
  891. return 0;
  892. width = strtoul(start, &next, 10);
  893. if (next == start || width == 0)
  894. return 0;
  895. c->padding = to_column ? -width : width;
  896. c->flush_type = flush_type;
  897. if (*end == ',') {
  898. start = end + 1;
  899. end = strchr(start, ')');
  900. if (!end || end == start)
  901. return 0;
  902. if (starts_with(start, "trunc)"))
  903. c->truncate = trunc_right;
  904. else if (starts_with(start, "ltrunc)"))
  905. c->truncate = trunc_left;
  906. else if (starts_with(start, "mtrunc)"))
  907. c->truncate = trunc_middle;
  908. else
  909. return 0;
  910. } else
  911. c->truncate = trunc_none;
  912. return end - placeholder + 1;
  913. }
  914. return 0;
  915. }
  916. static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
  917. const char *placeholder,
  918. void *context)
  919. {
  920. struct format_commit_context *c = context;
  921. const struct commit *commit = c->commit;
  922. const char *msg = c->message;
  923. struct commit_list *p;
  924. int h1, h2;
  925. /* these are independent of the commit */
  926. switch (placeholder[0]) {
  927. case 'C':
  928. if (starts_with(placeholder + 1, "(auto)")) {
  929. c->auto_color = 1;
  930. return 7; /* consumed 7 bytes, "C(auto)" */
  931. } else {
  932. int ret = parse_color(sb, placeholder, c);
  933. if (ret)
  934. c->auto_color = 0;
  935. /*
  936. * Otherwise, we decided to treat %C<unknown>
  937. * as a literal string, and the previous
  938. * %C(auto) is still valid.
  939. */
  940. return ret;
  941. }
  942. case 'n': /* newline */
  943. strbuf_addch(sb, '\n');
  944. return 1;
  945. case 'x':
  946. /* %x00 == NUL, %x0a == LF, etc. */
  947. if (0 <= (h1 = hexval_table[0xff & placeholder[1]]) &&
  948. h1 <= 16 &&
  949. 0 <= (h2 = hexval_table[0xff & placeholder[2]]) &&
  950. h2 <= 16) {
  951. strbuf_addch(sb, (h1<<4)|h2);
  952. return 3;
  953. } else
  954. return 0;
  955. case 'w':
  956. if (placeholder[1] == '(') {
  957. unsigned long width = 0, indent1 = 0, indent2 = 0;
  958. char *next;
  959. const char *start = placeholder + 2;
  960. const char *end = strchr(start, ')');
  961. if (!end)
  962. return 0;
  963. if (end > start) {
  964. width = strtoul(start, &next, 10);
  965. if (*next == ',') {
  966. indent1 = strtoul(next + 1, &next, 10);
  967. if (*next == ',') {
  968. indent2 = strtoul(next + 1,
  969. &next, 10);
  970. }
  971. }
  972. if (*next != ')')
  973. return 0;
  974. }
  975. rewrap_message_tail(sb, c, width, indent1, indent2);
  976. return end - placeholder + 1;
  977. } else
  978. return 0;
  979. case '<':
  980. case '>':
  981. return parse_padding_placeholder(sb, placeholder, c);
  982. }
  983. /* these depend on the commit */
  984. if (!commit->object.parsed)
  985. parse_object(commit->object.oid.hash);
  986. switch (placeholder[0]) {
  987. case 'H': /* commit hash */
  988. strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
  989. strbuf_addstr(sb, oid_to_hex(&commit->object.oid));
  990. strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
  991. return 1;
  992. case 'h': /* abbreviated commit hash */
  993. strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
  994. if (add_again(sb, &c->abbrev_commit_hash)) {
  995. strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
  996. return 1;
  997. }
  998. strbuf_addstr(sb, find_unique_abbrev(commit->object.oid.hash,
  999. c->pretty_ctx->abbrev));
  1000. strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
  1001. c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
  1002. return 1;
  1003. case 'T': /* tree hash */
  1004. strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid));
  1005. return 1;
  1006. case 't': /* abbreviated tree hash */
  1007. if (add_again(sb, &c->abbrev_tree_hash))
  1008. return 1;
  1009. strbuf_addstr(sb, find_unique_abbrev(commit->tree->object.oid.hash,
  1010. c->pretty_ctx->abbrev));
  1011. c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;
  1012. return 1;
  1013. case 'P': /* parent hashes */
  1014. for (p = commit->parents; p; p = p->next) {
  1015. if (p != commit->parents)
  1016. strbuf_addch(sb, ' ');
  1017. strbuf_addstr(sb, oid_to_hex(&p->item->object.oid));
  1018. }
  1019. return 1;
  1020. case 'p': /* abbreviated parent hashes */
  1021. if (add_again(sb, &c->abbrev_parent_hashes))
  1022. return 1;
  1023. for (p = commit->parents; p; p = p->next) {
  1024. if (p != commit->parents)
  1025. strbuf_addch(sb, ' ');
  1026. strbuf_addstr(sb, find_unique_abbrev(
  1027. p->item->object.oid.hash,
  1028. c->pretty_ctx->abbrev));
  1029. }
  1030. c->abbrev_parent_hashes.len = sb->len -
  1031. c->abbrev_parent_hashes.off;
  1032. return 1;
  1033. case 'm': /* left/right/bottom */
  1034. strbuf_addstr(sb, get_revision_mark(NULL, commit));
  1035. return 1;
  1036. case 'd':
  1037. load_ref_decorations(DECORATE_SHORT_REFS);
  1038. format_decorations(sb, commit, c->auto_color);
  1039. return 1;
  1040. case 'D':
  1041. load_ref_decorations(DECORATE_SHORT_REFS);
  1042. format_decorations_extended(sb, commit, c->auto_color, "", ", ", "");
  1043. return 1;
  1044. case 'g': /* reflog info */
  1045. switch(placeholder[1]) {
  1046. case 'd': /* reflog selector */
  1047. case 'D':
  1048. if (c->pretty_ctx->reflog_info)
  1049. get_reflog_selector(sb,
  1050. c->pretty_ctx->reflog_info,
  1051. &c->pretty_ctx->date_mode,
  1052. c->pretty_ctx->date_mode_explicit,
  1053. (placeholder[1] == 'd'));
  1054. return 2;
  1055. case 's': /* reflog message */
  1056. if (c->pretty_ctx->reflog_info)
  1057. get_reflog_message(sb, c->pretty_ctx->reflog_info);
  1058. return 2;
  1059. case 'n':
  1060. case 'N':
  1061. case 'e':
  1062. case 'E':
  1063. return format_reflog_person(sb,
  1064. placeholder[1],
  1065. c->pretty_ctx->reflog_info,
  1066. &c->pretty_ctx->date_mode);
  1067. }
  1068. return 0; /* unknown %g placeholder */
  1069. case 'N':
  1070. if (c->pretty_ctx->notes_message) {
  1071. strbuf_addstr(sb, c->pretty_ctx->notes_message);
  1072. return 1;
  1073. }
  1074. return 0;
  1075. }
  1076. if (placeholder[0] == 'G') {
  1077. if (!c->signature_check.result)
  1078. check_commit_signature(c->commit, &(c->signature_check));
  1079. switch (placeholder[1]) {
  1080. case 'G':
  1081. if (c->signature_check.gpg_output)
  1082. strbuf_addstr(sb, c->signature_check.gpg_output);
  1083. break;
  1084. case '?':
  1085. switch (c->signature_check.result) {
  1086. case 'G':
  1087. case 'B':
  1088. case 'U':
  1089. case 'N':
  1090. strbuf_addch(sb, c->signature_check.result);
  1091. }
  1092. break;
  1093. case 'S':
  1094. if (c->signature_check.signer)
  1095. strbuf_addstr(sb, c->signature_check.signer);
  1096. break;
  1097. case 'K':
  1098. if (c->signature_check.key)
  1099. strbuf_addstr(sb, c->signature_check.key);
  1100. break;
  1101. default:
  1102. return 0;
  1103. }
  1104. return 2;
  1105. }
  1106. /* For the rest we have to parse the commit header. */
  1107. if (!c->commit_header_parsed)
  1108. parse_commit_header(c);
  1109. switch (placeholder[0]) {
  1110. case 'a': /* author ... */
  1111. return format_person_part(sb, placeholder[1],
  1112. msg + c->author.off, c->author.len,
  1113. &c->pretty_ctx->date_mode);
  1114. case 'c': /* committer ... */
  1115. return format_person_part(sb, placeholder[1],
  1116. msg + c->committer.off, c->committer.len,
  1117. &c->pretty_ctx->date_mode);
  1118. case 'e': /* encoding */
  1119. if (c->commit_encoding)
  1120. strbuf_addstr(sb, c->commit_encoding);
  1121. return 1;
  1122. case 'B': /* raw body */
  1123. /* message_off is always left at the initial newline */
  1124. strbuf_addstr(sb, msg + c->message_off + 1);
  1125. return 1;
  1126. }
  1127. /* Now we need to parse the commit message. */
  1128. if (!c->commit_message_parsed)
  1129. parse_commit_message(c);
  1130. switch (placeholder[0]) {
  1131. case 's': /* subject */
  1132. format_subject(sb, msg + c->subject_off, " ");
  1133. return 1;
  1134. case 'f': /* sanitized subject */
  1135. format_sanitized_subject(sb, msg + c->subject_off);
  1136. return 1;
  1137. case 'b': /* body */
  1138. strbuf_addstr(sb, msg + c->body_off);
  1139. return 1;
  1140. }
  1141. return 0; /* unknown placeholder */
  1142. }
  1143. static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
  1144. const char *placeholder,
  1145. struct format_commit_context *c)
  1146. {
  1147. struct strbuf local_sb = STRBUF_INIT;
  1148. int total_consumed = 0, len, padding = c->padding;
  1149. if (padding < 0) {
  1150. const char *start = strrchr(sb->buf, '\n');
  1151. int occupied;
  1152. if (!start)
  1153. start = sb->buf;
  1154. occupied = utf8_strnwidth(start, -1, 1);
  1155. padding = (-padding) - occupied;
  1156. }
  1157. while (1) {
  1158. int modifier = *placeholder == 'C';
  1159. int consumed = format_commit_one(&local_sb, placeholder, c);
  1160. total_consumed += consumed;
  1161. if (!modifier)
  1162. break;
  1163. placeholder += consumed;
  1164. if (*placeholder != '%')
  1165. break;
  1166. placeholder++;
  1167. total_consumed++;
  1168. }
  1169. len = utf8_strnwidth(local_sb.buf, -1, 1);
  1170. if (c->flush_type == flush_left_and_steal) {
  1171. const char *ch = sb->buf + sb->len - 1;
  1172. while (len > padding && ch > sb->buf) {
  1173. const char *p;
  1174. if (*ch == ' ') {
  1175. ch--;
  1176. padding++;
  1177. continue;
  1178. }
  1179. /* check for trailing ansi sequences */
  1180. if (*ch != 'm')
  1181. break;
  1182. p = ch - 1;
  1183. while (ch - p < 10 && *p != '\033')
  1184. p--;
  1185. if (*p != '\033' ||
  1186. ch + 1 - p != display_mode_esc_sequence_len(p))
  1187. break;
  1188. /*
  1189. * got a good ansi sequence, put it back to
  1190. * local_sb as we're cutting sb
  1191. */
  1192. strbuf_insert(&local_sb, 0, p, ch + 1 - p);
  1193. ch = p - 1;
  1194. }
  1195. strbuf_setlen(sb, ch + 1 - sb->buf);
  1196. c->flush_type = flush_left;
  1197. }
  1198. if (len > padding) {
  1199. switch (c->truncate) {
  1200. case trunc_left:
  1201. strbuf_utf8_replace(&local_sb,
  1202. 0, len - (padding - 2),
  1203. "..");
  1204. break;
  1205. case trunc_middle:
  1206. strbuf_utf8_replace(&local_sb,
  1207. padding / 2 - 1,
  1208. len - (padding - 2),
  1209. "..");
  1210. break;
  1211. case trunc_right:
  1212. strbuf_utf8_replace(&local_sb,
  1213. padding - 2, len - (padding - 2),
  1214. "..");
  1215. break;
  1216. case trunc_none:
  1217. break;
  1218. }
  1219. strbuf_addbuf(sb, &local_sb);
  1220. } else {
  1221. int sb_len = sb->len, offset = 0;
  1222. if (c->flush_type == flush_left)
  1223. offset = padding - len;
  1224. else if (c->flush_type == flush_both)
  1225. offset = (padding - len) / 2;
  1226. /*
  1227. * we calculate padding in columns, now
  1228. * convert it back to chars
  1229. */
  1230. padding = padding - len + local_sb.len;
  1231. strbuf_addchars(sb, ' ', padding);
  1232. memcpy(sb->buf + sb_len + offset, local_sb.buf,
  1233. local_sb.len);
  1234. }
  1235. strbuf_release(&local_sb);
  1236. c->flush_type = no_flush;
  1237. return total_consumed;
  1238. }
  1239. static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */
  1240. const char *placeholder,
  1241. void *context)
  1242. {
  1243. int consumed;
  1244. size_t orig_len;
  1245. enum {
  1246. NO_MAGIC,
  1247. ADD_LF_BEFORE_NON_EMPTY,
  1248. DEL_LF_BEFORE_EMPTY,
  1249. ADD_SP_BEFORE_NON_EMPTY
  1250. } magic = NO_MAGIC;
  1251. switch (placeholder[0]) {
  1252. case '-':
  1253. magic = DEL_LF_BEFORE_EMPTY;
  1254. break;
  1255. case '+':
  1256. magic = ADD_LF_BEFORE_NON_EMPTY;
  1257. break;
  1258. case ' ':
  1259. magic = ADD_SP_BEFORE_NON_EMPTY;
  1260. break;
  1261. default:
  1262. break;
  1263. }
  1264. if (magic != NO_MAGIC)
  1265. placeholder++;
  1266. orig_len = sb->len;
  1267. if (((struct format_commit_context *)context)->flush_type != no_flush)
  1268. consumed = format_and_pad_commit(sb, placeholder, context);
  1269. else
  1270. consumed = format_commit_one(sb, placeholder, context);
  1271. if (magic == NO_MAGIC)
  1272. return consumed;
  1273. if ((orig_len == sb->len) && magic == DEL_LF_BEFORE_EMPTY) {
  1274. while (sb->len && sb->buf[sb->len - 1] == '\n')
  1275. strbuf_setlen(sb, sb->len - 1);
  1276. } else if (orig_len != sb->len) {
  1277. if (magic == ADD_LF_BEFORE_NON_EMPTY)
  1278. strbuf_insert(sb, orig_len, "\n", 1);
  1279. else if (magic == ADD_SP_BEFORE_NON_EMPTY)
  1280. strbuf_insert(sb, orig_len, " ", 1);
  1281. }
  1282. return consumed + 1;
  1283. }
  1284. static size_t userformat_want_item(struct strbuf *sb, const char *placeholder,
  1285. void *context)
  1286. {
  1287. struct userformat_want *w = context;
  1288. if (*placeholder == '+' || *placeholder == '-' || *placeholder == ' ')
  1289. placeholder++;
  1290. switch (*placeholder) {
  1291. case 'N':
  1292. w->notes = 1;
  1293. break;
  1294. }
  1295. return 0;
  1296. }
  1297. void userformat_find_requirements(const char *fmt, struct userformat_want *w)
  1298. {
  1299. struct strbuf dummy = STRBUF_INIT;
  1300. if (!fmt) {
  1301. if (!user_format)
  1302. return;
  1303. fmt = user_format;
  1304. }
  1305. strbuf_expand(&dummy, fmt, userformat_want_item, w);
  1306. strbuf_release(&dummy);
  1307. }
  1308. void format_commit_message(const struct commit *commit,
  1309. const char *format, struct strbuf *sb,
  1310. const struct pretty_print_context *pretty_ctx)
  1311. {
  1312. struct format_commit_context context;
  1313. const char *output_enc = pretty_ctx->output_encoding;
  1314. const char *utf8 = "UTF-8";
  1315. memset(&context, 0, sizeof(context));
  1316. context.commit = commit;
  1317. context.pretty_ctx = pretty_ctx;
  1318. context.wrap_start = sb->len;
  1319. /*
  1320. * convert a commit message to UTF-8 first
  1321. * as far as 'format_commit_item' assumes it in UTF-8
  1322. */
  1323. context.message = logmsg_reencode(commit,
  1324. &context.commit_encoding,
  1325. utf8);
  1326. strbuf_expand(sb, format, format_commit_item, &context);
  1327. rewrap_message_tail(sb, &context, 0, 0, 0);
  1328. /* then convert a commit message to an actual output encoding */
  1329. if (output_enc) {
  1330. if (same_encoding(utf8, output_enc))
  1331. output_enc = NULL;
  1332. } else {
  1333. if (context.commit_encoding &&
  1334. !same_encoding(context.commit_encoding, utf8))
  1335. output_enc = context.commit_encoding;
  1336. }
  1337. if (output_enc) {
  1338. int outsz;
  1339. char *out = reencode_string_len(sb->buf, sb->len,
  1340. output_enc, utf8, &outsz);
  1341. if (out)
  1342. strbuf_attach(sb, out, outsz, outsz + 1);
  1343. }
  1344. free(context.commit_encoding);
  1345. unuse_commit_buffer(commit, context.message);
  1346. }
  1347. static void pp_header(struct pretty_print_context *pp,
  1348. const char *encoding,
  1349. const struct commit *commit,
  1350. const char **msg_p,
  1351. struct strbuf *sb)
  1352. {
  1353. int parents_shown = 0;
  1354. for (;;) {
  1355. const char *name, *line = *msg_p;
  1356. int linelen = get_one_line(*msg_p);
  1357. if (!linelen)
  1358. return;
  1359. *msg_p += linelen;
  1360. if (linelen == 1)
  1361. /* End of header */
  1362. return;
  1363. if (pp->fmt == CMIT_FMT_RAW) {
  1364. strbuf_add(sb, line, linelen);
  1365. continue;
  1366. }
  1367. if (starts_with(line, "parent ")) {
  1368. if (linelen != 48)
  1369. die("bad parent line in commit");
  1370. continue;
  1371. }
  1372. if (!parents_shown) {
  1373. unsigned num = commit_list_count(commit->parents);
  1374. /* with enough slop */
  1375. strbuf_grow(sb, num * 50 + 20);
  1376. add_merge_info(pp, sb, commit);
  1377. parents_shown = 1;
  1378. }
  1379. /*
  1380. * MEDIUM == DEFAULT shows only author with dates.
  1381. * FULL shows both authors but not dates.
  1382. * FULLER shows both authors and dates.
  1383. */
  1384. if (skip_prefix(line, "author ", &name)) {
  1385. strbuf_grow(sb, linelen + 80);
  1386. pp_user_info(pp, "Author", sb, name, encoding);
  1387. }
  1388. if (skip_prefix(line, "committer ", &name) &&
  1389. (pp->fmt == CMIT_FMT_FULL || pp->fmt == CMIT_FMT_FULLER)) {
  1390. strbuf_grow(sb, linelen + 80);
  1391. pp_user_info(pp, "Commit", sb, name, encoding);
  1392. }
  1393. }
  1394. }
  1395. void pp_title_line(struct pretty_print_context *pp,
  1396. const char **msg_p,
  1397. struct strbuf *sb,
  1398. const char *encoding,
  1399. int need_8bit_cte)
  1400. {
  1401. static const int max_length = 78; /* per rfc2047 */
  1402. struct strbuf title;
  1403. strbuf_init(&title, 80);
  1404. *msg_p = format_subject(&title, *msg_p,
  1405. pp->preserve_subject ? "\n" : " ");
  1406. strbuf_grow(sb, title.len + 1024);
  1407. if (pp->subject) {
  1408. strbuf_addstr(sb, pp->subject);
  1409. if (needs_rfc2047_encoding(title.buf, title.len, RFC2047_SUBJECT))
  1410. add_rfc2047(sb, title.buf, title.len,
  1411. encoding, RFC2047_SUBJECT);
  1412. else
  1413. strbuf_add_wrapped_bytes(sb, title.buf, title.len,
  1414. -last_line_length(sb), 1, max_length);
  1415. } else {
  1416. strbuf_addbuf(sb, &title);
  1417. }
  1418. strbuf_addch(sb, '\n');
  1419. if (need_8bit_cte == 0) {
  1420. int i;
  1421. for (i = 0; i < pp->in_body_headers.nr; i++) {
  1422. if (has_non_ascii(pp->in_body_headers.items[i].string)) {
  1423. need_8bit_cte = 1;
  1424. break;
  1425. }
  1426. }
  1427. }
  1428. if (need_8bit_cte > 0) {
  1429. const char *header_fmt =
  1430. "MIME-Version: 1.0\n"
  1431. "Content-Type: text/plain; charset=%s\n"
  1432. "Content-Transfer-Encoding: 8bit\n";
  1433. strbuf_addf(sb, header_fmt, encoding);
  1434. }
  1435. if (pp->after_subject) {
  1436. strbuf_addstr(sb, pp->after_subject);
  1437. }
  1438. if (pp->fmt == CMIT_FMT_EMAIL) {
  1439. strbuf_addch(sb, '\n');
  1440. }
  1441. if (pp->in_body_headers.nr) {
  1442. int i;
  1443. for (i = 0; i < pp->in_body_headers.nr; i++) {
  1444. strbuf_addstr(sb, pp->in_body_headers.items[i].string);
  1445. free(pp->in_body_headers.items[i].string);
  1446. }
  1447. string_list_clear(&pp->in_body_headers, 0);
  1448. strbuf_addch(sb, '\n');
  1449. }
  1450. strbuf_release(&title);
  1451. }
  1452. void pp_remainder(struct pretty_print_context *pp,
  1453. const char **msg_p,
  1454. struct strbuf *sb,
  1455. int indent)
  1456. {
  1457. int first = 1;
  1458. for (;;) {
  1459. const char *line = *msg_p;
  1460. int linelen = get_one_line(line);
  1461. *msg_p += linelen;
  1462. if (!linelen)
  1463. break;
  1464. if (is_empty_line(line, &linelen)) {
  1465. if (first)
  1466. continue;
  1467. if (pp->fmt == CMIT_FMT_SHORT)
  1468. break;
  1469. }
  1470. first = 0;
  1471. strbuf_grow(sb, linelen + indent + 20);
  1472. if (indent)
  1473. strbuf_addchars(sb, ' ', indent);
  1474. strbuf_add(sb, line, linelen);
  1475. strbuf_addch(sb, '\n');
  1476. }
  1477. }
  1478. void pretty_print_commit(struct pretty_print_context *pp,
  1479. const struct commit *commit,
  1480. struct strbuf *sb)
  1481. {
  1482. unsigned long beginning_of_body;
  1483. int indent = 4;
  1484. const char *msg;
  1485. const char *reencoded;
  1486. const char *encoding;
  1487. int need_8bit_cte = pp->need_8bit_cte;
  1488. if (pp->fmt == CMIT_FMT_USERFORMAT) {
  1489. format_commit_message(commit, user_format, sb, pp);
  1490. return;
  1491. }
  1492. encoding = get_log_output_encoding();
  1493. msg = reencoded = logmsg_reencode(commit, NULL, encoding);
  1494. if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL)
  1495. indent = 0;
  1496. /*
  1497. * We need to check and emit Content-type: to mark it
  1498. * as 8-bit if we haven't done so.
  1499. */
  1500. if (pp->fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) {
  1501. int i, ch, in_body;
  1502. for (in_body = i = 0; (ch = msg[i]); i++) {
  1503. if (!in_body) {
  1504. /* author could be non 7-bit ASCII but
  1505. * the log may be so; skip over the
  1506. * header part first.
  1507. */
  1508. if (ch == '\n' && msg[i+1] == '\n')
  1509. in_body = 1;
  1510. }
  1511. else if (non_ascii(ch)) {
  1512. need_8bit_cte = 1;
  1513. break;
  1514. }
  1515. }
  1516. }
  1517. pp_header(pp, encoding, commit, &msg, sb);
  1518. if (pp->fmt != CMIT_FMT_ONELINE && !pp->subject) {
  1519. strbuf_addch(sb, '\n');
  1520. }
  1521. /* Skip excess blank lines at the beginning of body, if any... */
  1522. msg = skip_empty_lines(msg);
  1523. /* These formats treat the title line specially. */
  1524. if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL)
  1525. pp_title_line(pp, &msg, sb, encoding, need_8bit_cte);
  1526. beginning_of_body = sb->len;
  1527. if (pp->fmt != CMIT_FMT_ONELINE)
  1528. pp_remainder(pp, &msg, sb, indent);
  1529. strbuf_rtrim(sb);
  1530. /* Make sure there is an EOLN for the non-oneline case */
  1531. if (pp->fmt != CMIT_FMT_ONELINE)
  1532. strbuf_addch(sb, '\n');
  1533. /*
  1534. * The caller may append additional body text in e-mail
  1535. * format. Make sure we did not strip the blank line
  1536. * between the header and the body.
  1537. */
  1538. if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
  1539. strbuf_addch(sb, '\n');
  1540. unuse_commit_buffer(commit, reencoded);
  1541. }
  1542. void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,
  1543. struct strbuf *sb)
  1544. {
  1545. struct pretty_print_context pp = {0};
  1546. pp.fmt = fmt;
  1547. pretty_print_commit(&pp, commit, sb);
  1548. }