@matheusbsbs / matheus-bagliano / commits / 5b16360330
Fork 0

pretty: Initialize notes if %N is used

When using git log --pretty='%N' without an explicit --show-notes, git would segfault. This patches fixes this behaviour by loading the needed notes datastructures if --pretty is used and the format contains %N. When --pretty='%N' is used together with --no-notes, %N won't be expanded. This is an extension to a proposed patch by Jeff King. Signed-off-by: Johannes Gilger <heipei@hackvalue.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Gilger committed Apr 13, 2010 at 22:31 UTC 5b16360330822527eac1fa84131d185ff784c9fb
3 files changed +46 -5
builtin/log.c
+5 -1
@@ -36,6 +36,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
36 {
37 int i;
38 int decoration_style = 0;
39 + struct userformat_want w;
40
41 rev->abbrev = DEFAULT_ABBREV;
42 rev->commit_format = CMIT_FMT_DEFAULT;
@@ -58,7 +59,10 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
59 usage(builtin_log_usage);
60 argc = setup_revisions(argc, argv, rev, opt);
61
61 - if (!rev->show_notes_given && !rev->pretty_given)
62 + memset(&w, 0, sizeof(w));
63 + userformat_find_requirements(NULL, &w);
64 +
65 + if (!rev->show_notes_given && (!rev->pretty_given || w.notes))
66 rev->show_notes = 1;
67 if (rev->show_notes)
68 init_display_notes(&rev->notes_opt);
commit.h
+5
@@ -74,11 +74,16 @@ struct pretty_print_context
74 struct reflog_walk_info *reflog_info;
75 };
76
77 +struct userformat_want {
78 + unsigned notes:1;
79 +};
80 +
81 extern int has_non_ascii(const char *text);
82 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
83 extern char *reencode_commit_message(const struct commit *commit,
84 const char **encoding_p);
85 extern void get_commit_format(const char *arg, struct rev_info *);
86 +extern void userformat_find_requirements(const char *fmt, struct userformat_want *w);
87 extern void format_commit_message(const struct commit *commit,
88 const char *format, struct strbuf *sb,
89 const struct pretty_print_context *context);
pretty.c
+36 -4
@@ -775,10 +775,13 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
775 }
776 return 0; /* unknown %g placeholder */
777 case 'N':
778 - format_display_notes(commit->object.sha1, sb,
779 - git_log_output_encoding ? git_log_output_encoding
780 - : git_commit_encoding, 0);
781 - return 1;
778 + if (c->pretty_ctx->show_notes) {
779 + format_display_notes(commit->object.sha1, sb,
780 + git_log_output_encoding ? git_log_output_encoding
781 + : git_commit_encoding, 0);
782 + return 1;
783 + }
784 + return 0;
785 }
786
787 /* For the rest we have to parse the commit header. */
@@ -855,6 +858,35 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
858 return consumed + 1;
859 }
860
861 +static size_t userformat_want_item(struct strbuf *sb, const char *placeholder,
862 + void *context)
863 +{
864 + struct userformat_want *w = context;
865 +
866 + if (*placeholder == '+' || *placeholder == '-')
867 + placeholder++;
868 +
869 + switch (*placeholder) {
870 + case 'N':
871 + w->notes = 1;
872 + break;
873 + }
874 + return 0;
875 +}
876 +
877 +void userformat_find_requirements(const char *fmt, struct userformat_want *w)
878 +{
879 + struct strbuf dummy = STRBUF_INIT;
880 +
881 + if (!fmt) {
882 + if (!user_format)
883 + return;
884 + fmt = user_format;
885 + }
886 + strbuf_expand(&dummy, user_format, userformat_want_item, w);
887 + strbuf_release(&dummy);
888 +}
889 +
890 void format_commit_message(const struct commit *commit,
891 const char *format, struct strbuf *sb,
892 const struct pretty_print_context *pretty_ctx)