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)