pretty: Initialize notes if %N is used
authorJohannes Gilger <heipei@hackvalue.de>
Tue, 13 Apr 2010 20:31:12 +0000 (22:31 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 14 Apr 2010 01:15:08 +0000 (18:15 -0700)
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>
builtin/log.c
commit.h
pretty.c

index b706a5ff88ec185e63c0aacd109bb16cc54027e3..6208703c061abb868201073795cf516bf81b2602 100644 (file)
@@ -36,6 +36,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
 {
        int i;
        int decoration_style = 0;
+       struct userformat_want w;
 
        rev->abbrev = DEFAULT_ABBREV;
        rev->commit_format = CMIT_FMT_DEFAULT;
@@ -58,7 +59,10 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
                usage(builtin_log_usage);
        argc = setup_revisions(argc, argv, rev, opt);
 
-       if (!rev->show_notes_given && !rev->pretty_given)
+       memset(&w, 0, sizeof(w));
+       userformat_find_requirements(NULL, &w);
+
+       if (!rev->show_notes_given && (!rev->pretty_given || w.notes))
                rev->show_notes = 1;
        if (rev->show_notes)
                init_display_notes(&rev->notes_opt);
index 3cf51665816abb5e5855c036f102019eded23bd6..26ec8c0d1cebcf5e79564be690517cd2eb9c6413 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -74,11 +74,16 @@ struct pretty_print_context
        struct reflog_walk_info *reflog_info;
 };
 
+struct userformat_want {
+       unsigned notes:1;
+};
+
 extern int has_non_ascii(const char *text);
 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
 extern char *reencode_commit_message(const struct commit *commit,
                                     const char **encoding_p);
 extern void get_commit_format(const char *arg, struct rev_info *);
+extern void userformat_find_requirements(const char *fmt, struct userformat_want *w);
 extern void format_commit_message(const struct commit *commit,
                                  const char *format, struct strbuf *sb,
                                  const struct pretty_print_context *context);
index 6ba3da89b7d29ef35a6ac9215b4f3e0abe7a582f..7cb3a2af508bb5667cd74304f72b50766c749990 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -775,10 +775,13 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                }
                return 0;       /* unknown %g placeholder */
        case 'N':
-               format_display_notes(commit->object.sha1, sb,
-                           git_log_output_encoding ? git_log_output_encoding
-                                                   : git_commit_encoding, 0);
-               return 1;
+               if (c->pretty_ctx->show_notes) {
+                       format_display_notes(commit->object.sha1, sb,
+                                   git_log_output_encoding ? git_log_output_encoding
+                                                           : git_commit_encoding, 0);
+                       return 1;
+               }
+               return 0;
        }
 
        /* 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,
        return consumed + 1;
 }
 
+static size_t userformat_want_item(struct strbuf *sb, const char *placeholder,
+                                  void *context)
+{
+       struct userformat_want *w = context;
+
+       if (*placeholder == '+' || *placeholder == '-')
+               placeholder++;
+
+       switch (*placeholder) {
+       case 'N':
+               w->notes = 1;
+               break;
+       }
+       return 0;
+}
+
+void userformat_find_requirements(const char *fmt, struct userformat_want *w)
+{
+       struct strbuf dummy = STRBUF_INIT;
+
+       if (!fmt) {
+               if (!user_format)
+                       return;
+               fmt = user_format;
+       }
+       strbuf_expand(&dummy, user_format, userformat_want_item, w);
+       strbuf_release(&dummy);
+}
+
 void format_commit_message(const struct commit *commit,
                           const char *format, struct strbuf *sb,
                           const struct pretty_print_context *pretty_ctx)