Changeset 782 for git/branches/dmik/log-tree.c
- Timestamp:
- Jun 23, 2014, 9:45:51 PM (11 years ago)
- Location:
- git/branches/dmik
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
git/branches/dmik ¶
- Property svn:mergeinfo changed
/git/vendor/2.0.0 (added) merged: 777 /git/vendor/current merged: 772,774,776
- Property svn:mergeinfo changed
-
TabularUnified git/branches/dmik/log-tree.c ¶
r626 r782 10 10 #include "color.h" 11 11 #include "gpg-interface.h" 12 #include "sequencer.h" 13 #include "line-log.h" 12 14 13 15 struct decoration name_decoration = { "object names" }; … … 97 99 enum decoration_type type = DECORATION_NONE; 98 100 99 if ( !prefixcmp(refname, "refs/replace/")) {101 if (starts_with(refname, "refs/replace/")) { 100 102 unsigned char original_sha1[20]; 101 if (! read_replace_refs)103 if (!check_replace_refs) 102 104 return 0; 103 105 if (get_sha1_hex(refname + 13, original_sha1)) { … … 115 117 return 0; 116 118 117 if ( !prefixcmp(refname, "refs/heads/"))119 if (starts_with(refname, "refs/heads/")) 118 120 type = DECORATION_REF_LOCAL; 119 else if ( !prefixcmp(refname, "refs/remotes/"))121 else if (starts_with(refname, "refs/remotes/")) 120 122 type = DECORATION_REF_REMOTE; 121 else if ( !prefixcmp(refname, "refs/tags/"))123 else if (starts_with(refname, "refs/tags/")) 122 124 type = DECORATION_REF_TAG; 123 else if (! prefixcmp(refname, "refs/stash"))125 else if (!strcmp(refname, "refs/stash")) 124 126 type = DECORATION_REF_STASH; 125 else if (! prefixcmp(refname, "HEAD"))127 else if (!strcmp(refname, "HEAD")) 126 128 type = DECORATION_REF_HEAD; 127 129 … … 133 135 if (!obj) 134 136 break; 137 if (!obj->parsed) 138 parse_object(obj->sha1); 135 139 add_name_decoration(DECORATION_REF_TAG, refname, obj); 136 140 } … … 175 179 } 176 180 177 void show_decorations(struct rev_info *opt, struct commit *commit) 181 /* 182 * The caller makes sure there is no funny color before 183 * calling. format_decorations makes sure the same after return. 184 */ 185 void format_decorations(struct strbuf *sb, 186 const struct commit *commit, 187 int use_color) 178 188 { 179 189 const char *prefix; 180 190 struct name_decoration *decoration; 181 191 const char *color_commit = 182 diff_get_color _opt(&opt->diffopt, DIFF_COMMIT);192 diff_get_color(use_color, DIFF_COMMIT); 183 193 const char *color_reset = 184 decorate_get_color_opt(&opt->diffopt, DECORATION_NONE); 185 186 if (opt->show_source && commit->util) 187 printf("\t%s", (char *) commit->util); 188 if (!opt->show_decorations) 189 return; 194 decorate_get_color(use_color, DECORATION_NONE); 195 190 196 decoration = lookup_decoration(&name_decoration, &commit->object); 191 197 if (!decoration) … … 193 199 prefix = " ("; 194 200 while (decoration) { 195 printf("%s", prefix);196 fputs(decorate_get_color_opt(&opt->diffopt, decoration->type),197 stdout);201 strbuf_addstr(sb, color_commit); 202 strbuf_addstr(sb, prefix); 203 strbuf_addstr(sb, decorate_get_color(use_color, decoration->type)); 198 204 if (decoration->type == DECORATION_REF_TAG) 199 fputs("tag: ", stdout); 200 printf("%s", decoration->name); 201 fputs(color_reset, stdout); 202 fputs(color_commit, stdout); 205 strbuf_addstr(sb, "tag: "); 206 strbuf_addstr(sb, decoration->name); 207 strbuf_addstr(sb, color_reset); 203 208 prefix = ", "; 204 209 decoration = decoration->next; 205 210 } 206 putchar(')'); 207 } 208 209 /* 210 * Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches 211 * Signed-off-by: and Acked-by: lines. 212 */ 213 static int detect_any_signoff(char *letter, int size) 214 { 215 char *cp; 216 int seen_colon = 0; 217 int seen_at = 0; 218 int seen_name = 0; 219 int seen_head = 0; 220 221 cp = letter + size; 222 while (letter <= --cp && *cp == '\n') 223 continue; 224 225 while (letter <= cp) { 226 char ch = *cp--; 227 if (ch == '\n') 228 break; 229 230 if (!seen_at) { 231 if (ch == '@') 232 seen_at = 1; 233 continue; 234 } 235 if (!seen_colon) { 236 if (ch == '@') 237 return 0; 238 else if (ch == ':') 239 seen_colon = 1; 240 else 241 seen_name = 1; 242 continue; 243 } 244 if (('A' <= ch && ch <= 'Z') || 245 ('a' <= ch && ch <= 'z') || 246 ch == '-') { 247 seen_head = 1; 248 continue; 249 } 250 /* no empty last line doesn't match */ 251 return 0; 252 } 253 return seen_head && seen_name; 254 } 255 256 static void append_signoff(struct strbuf *sb, const char *signoff) 257 { 258 static const char signed_off_by[] = "Signed-off-by: "; 259 size_t signoff_len = strlen(signoff); 260 int has_signoff = 0; 261 char *cp; 262 263 cp = sb->buf; 264 265 /* First see if we already have the sign-off by the signer */ 266 while ((cp = strstr(cp, signed_off_by))) { 267 268 has_signoff = 1; 269 270 cp += strlen(signed_off_by); 271 if (cp + signoff_len >= sb->buf + sb->len) 272 break; 273 if (strncmp(cp, signoff, signoff_len)) 274 continue; 275 if (!isspace(cp[signoff_len])) 276 continue; 277 /* we already have him */ 211 strbuf_addstr(sb, color_commit); 212 strbuf_addch(sb, ')'); 213 strbuf_addstr(sb, color_reset); 214 } 215 216 void show_decorations(struct rev_info *opt, struct commit *commit) 217 { 218 struct strbuf sb = STRBUF_INIT; 219 220 if (opt->show_source && commit->util) 221 printf("\t%s", (char *) commit->util); 222 if (!opt->show_decorations) 278 223 return; 279 } 280 281 if (!has_signoff) 282 has_signoff = detect_any_signoff(sb->buf, sb->len); 283 284 if (!has_signoff) 285 strbuf_addch(sb, '\n'); 286 287 strbuf_addstr(sb, signed_off_by); 288 strbuf_add(sb, signoff, signoff_len); 289 strbuf_addch(sb, '\n'); 224 format_decorations(&sb, commit, opt->diffopt.use_color); 225 fputs(sb.buf, stdout); 226 strbuf_release(&sb); 290 227 } 291 228 … … 300 237 } 301 238 302 void get_patch_filename(struct commit *commit, int nr, const char *suffix, 303 struct strbuf *buf) 304 { 305 int suffix_len = strlen(suffix) + 1; 306 int start_len = buf->len; 307 308 strbuf_addf(buf, commit ? "%04d-" : "%d", nr); 309 if (commit) { 310 int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len; 311 struct pretty_print_context ctx = {0}; 312 ctx.date_mode = DATE_NORMAL; 313 314 format_commit_message(commit, "%f", buf, &ctx); 315 if (max_len < buf->len) 316 strbuf_setlen(buf, max_len); 317 strbuf_addstr(buf, suffix); 318 } 239 void fmt_output_subject(struct strbuf *filename, 240 const char *subject, 241 struct rev_info *info) 242 { 243 const char *suffix = info->patch_suffix; 244 int nr = info->nr; 245 int start_len = filename->len; 246 int max_len = start_len + FORMAT_PATCH_NAME_MAX - (strlen(suffix) + 1); 247 248 if (0 < info->reroll_count) 249 strbuf_addf(filename, "v%d-", info->reroll_count); 250 strbuf_addf(filename, "%04d-%s", nr, subject); 251 252 if (max_len < filename->len) 253 strbuf_setlen(filename, max_len); 254 strbuf_addstr(filename, suffix); 255 } 256 257 void fmt_output_commit(struct strbuf *filename, 258 struct commit *commit, 259 struct rev_info *info) 260 { 261 struct pretty_print_context ctx = {0}; 262 struct strbuf subject = STRBUF_INIT; 263 264 format_commit_message(commit, "%f", &subject, &ctx); 265 fmt_output_subject(filename, subject.buf, info); 266 strbuf_release(&subject); 319 267 } 320 268 … … 385 333 extra_headers = subject_buffer; 386 334 387 get_patch_filename(opt->numbered_files ? NULL : commit, opt->nr, 388 opt->patch_suffix, &filename); 335 if (opt->numbered_files) 336 strbuf_addf(&filename, "%d", opt->nr); 337 else 338 fmt_output_commit(&filename, commit, opt); 389 339 snprintf(buffer, sizeof(buffer) - 1, 390 340 "\n--%s%s\n" … … 432 382 status = verify_signed_buffer(payload.buf, payload.len, 433 383 signature.buf, signature.len, 434 &gpg_output );384 &gpg_output, NULL); 435 385 if (status && !gpg_output.len) 436 386 strbuf_addstr(&gpg_output, "No signature\n"); … … 496 446 497 447 payload_size = parse_signature(extra->value, extra->len); 498 if ((extra->len <= payload_size) || 499 (verify_signed_buffer(extra->value, payload_size, 500 extra->value + payload_size, 501 extra->len - payload_size, 502 &verify_message) && 503 verify_message.len <= gpg_message_offset)) { 504 strbuf_addstr(&verify_message, "No signature\n"); 505 status = -1; 506 } 507 else if (strstr(verify_message.buf + gpg_message_offset, 508 ": Good signature from ")) 509 status = 0; 510 else 511 status = -1; 448 status = -1; 449 if (extra->len > payload_size) 450 if (verify_signed_buffer(extra->value, payload_size, 451 extra->value + payload_size, 452 extra->len - payload_size, 453 &verify_message, NULL)) { 454 if (verify_message.len <= gpg_message_offset) 455 strbuf_addstr(&verify_message, "No signature\n"); 456 else 457 status = 0; 458 } 512 459 513 460 show_sig_lines(opt, status, verify_message.buf); … … 538 485 539 486 opt->loginfo = NULL; 540 ctx.show_notes = opt->show_notes;541 487 if (!opt->verbose_header) { 542 488 graph_show_commit(opt->graph); … … 614 560 find_unique_abbrev(parent->object.sha1, 615 561 abbrev_commit)); 562 fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), stdout); 616 563 show_decorations(opt, commit); 617 printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));618 564 if (opt->commit_format == CMIT_FMT_ONELINE) { 619 565 putchar(' '); … … 630 576 */ 631 577 show_reflog_message(opt->reflog_info, 632 opt->commit_format == CMIT_FMT_ONELINE, 633 opt->date_mode_explicit ? 634 opt->date_mode : 635 DATE_NORMAL); 578 opt->commit_format == CMIT_FMT_ONELINE, 579 opt->date_mode, 580 opt->date_mode_explicit); 636 581 if (opt->commit_format == CMIT_FMT_ONELINE) 637 582 return; … … 647 592 return; 648 593 594 if (opt->show_notes) { 595 int raw; 596 struct strbuf notebuf = STRBUF_INIT; 597 598 raw = (opt->commit_format == CMIT_FMT_USERFORMAT); 599 format_display_notes(commit->object.sha1, ¬ebuf, 600 get_log_output_encoding(), raw); 601 ctx.notes_message = notebuf.len 602 ? strbuf_detach(¬ebuf, NULL) 603 : xcalloc(1, 1); 604 } 605 649 606 /* 650 607 * And then the pretty-printed message itself 651 608 */ 652 if (ctx.need_8bit_cte >= 0) 653 ctx.need_8bit_cte = has_non_ascii(opt->add_signoff); 609 if (ctx.need_8bit_cte >= 0 && opt->add_signoff) 610 ctx.need_8bit_cte = 611 has_non_ascii(fmt_name(getenv("GIT_COMMITTER_NAME"), 612 getenv("GIT_COMMITTER_EMAIL"))); 654 613 ctx.date_mode = opt->date_mode; 614 ctx.date_mode_explicit = opt->date_mode_explicit; 655 615 ctx.abbrev = opt->diffopt.abbrev; 656 616 ctx.after_subject = extra_headers; … … 658 618 ctx.reflog_info = opt->reflog_info; 659 619 ctx.fmt = opt->commit_format; 620 ctx.mailmap = opt->mailmap; 621 ctx.color = opt->diffopt.use_color; 622 ctx.output_encoding = get_log_output_encoding(); 623 if (opt->from_ident.mail_begin && opt->from_ident.name_begin) 624 ctx.from_ident = &opt->from_ident; 660 625 pretty_print_commit(&ctx, commit, &msgbuf); 661 626 662 627 if (opt->add_signoff) 663 append_signoff(&msgbuf, opt->add_signoff); 628 append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP); 629 630 if ((ctx.fmt != CMIT_FMT_USERFORMAT) && 631 ctx.notes_message && *ctx.notes_message) { 632 if (ctx.fmt == CMIT_FMT_EMAIL) { 633 strbuf_addstr(&msgbuf, "---\n"); 634 opt->shown_dashes = 1; 635 } 636 strbuf_addstr(&msgbuf, ctx.notes_message); 637 } 638 664 639 if (opt->show_log_size) { 665 640 printf("log size %i\n", (int)msgbuf.len); … … 683 658 if (!opt->missing_newline) 684 659 graph_show_padding(opt->graph); 685 putchar( '\n');660 putchar(opt->diffopt.line_termination); 686 661 } 687 662 688 663 strbuf_release(&msgbuf); 664 free(ctx.notes_message); 689 665 } 690 666 691 667 int log_tree_diff_flush(struct rev_info *opt) 692 668 { 669 opt->shown_dashes = 0; 693 670 diffcore_std(&opt->diffopt); 694 671 … … 702 679 703 680 if (opt->loginfo && !opt->no_commit_id) { 704 /* When showing a verbose header (i.e. log message),705 * and not in --pretty=oneline format, we would want706 * an extra newline between the end of log and the707 * output for readability.708 */709 681 show_log(opt); 710 682 if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) && 711 683 opt->verbose_header && 712 684 opt->commit_format != CMIT_FMT_ONELINE) { 685 /* 686 * When showing a verbose header (i.e. log message), 687 * and not in --pretty=oneline format, we would want 688 * an extra newline between the end of log and the 689 * diff/diffstat output for readability. 690 */ 713 691 int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH; 714 if ((pch & opt->diffopt.output_format) == pch)715 printf("---");716 692 if (opt->diffopt.output_prefix) { 717 693 struct strbuf *msg = NULL; … … 720 696 fwrite(msg->buf, msg->len, 1, stdout); 721 697 } 698 699 /* 700 * We may have shown three-dashes line early 701 * between notes and the log message, in which 702 * case we only want a blank line after the 703 * notes without (an extra) three-dashes line. 704 * Otherwise, we show the three-dashes line if 705 * we are showing the patch with diffstat, but 706 * in that case, there is no extra blank line 707 * after the three-dashes line. 708 */ 709 if (!opt->shown_dashes && 710 (pch & opt->diffopt.output_format) == pch) 711 printf("---"); 722 712 putchar('\n'); 723 713 } … … 742 732 int showed_log; 743 733 struct commit_list *parents; 744 unsigned const char *sha1 = commit->object.sha1;734 unsigned const char *sha1; 745 735 746 736 if (!opt->diff && !DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)) 747 737 return 0; 748 738 739 parse_commit_or_die(commit); 740 sha1 = commit->tree->object.sha1; 741 749 742 /* Root commit? */ 750 parents = commit->parents;743 parents = get_saved_parents(opt, commit); 751 744 if (!parents) { 752 745 if (opt->show_root_diff) { … … 769 762 * we merged _in_. 770 763 */ 771 diff_tree_sha1(parents->item->object.sha1, sha1, "", &opt->diffopt); 764 parse_commit_or_die(parents->item); 765 diff_tree_sha1(parents->item->tree->object.sha1, 766 sha1, "", &opt->diffopt); 772 767 log_tree_diff_flush(opt); 773 768 return !opt->loginfo; … … 782 777 struct commit *parent = parents->item; 783 778 784 diff_tree_sha1(parent->object.sha1, sha1, "", &opt->diffopt); 779 parse_commit_or_die(parent); 780 diff_tree_sha1(parent->tree->object.sha1, 781 sha1, "", &opt->diffopt); 785 782 log_tree_diff_flush(opt); 786 783 … … 806 803 opt->loginfo = &log; 807 804 805 if (opt->line_level_traverse) 806 return line_log_print(opt, commit); 807 808 if (opt->track_linear && !opt->linear && !opt->reverse_output_stage) 809 printf("\n%s\n", opt->break_bar); 808 810 shown = log_tree_diff(opt, commit, &log); 809 811 if (!shown && opt->loginfo && opt->always_show_header) { … … 812 814 shown = 1; 813 815 } 816 if (opt->track_linear && !opt->linear && opt->reverse_output_stage) 817 printf("\n%s\n", opt->break_bar); 814 818 opt->loginfo = NULL; 815 819 maybe_flush_or_die(stdout, "stdout");
Note:
See TracChangeset
for help on using the changeset viewer.