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>
This commit is contained in:
parent
b9aa901856
commit
5b16360330
@ -36,6 +36,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int decoration_style = 0;
|
int decoration_style = 0;
|
||||||
|
struct userformat_want w;
|
||||||
|
|
||||||
rev->abbrev = DEFAULT_ABBREV;
|
rev->abbrev = DEFAULT_ABBREV;
|
||||||
rev->commit_format = CMIT_FMT_DEFAULT;
|
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);
|
usage(builtin_log_usage);
|
||||||
argc = setup_revisions(argc, argv, rev, opt);
|
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;
|
rev->show_notes = 1;
|
||||||
if (rev->show_notes)
|
if (rev->show_notes)
|
||||||
init_display_notes(&rev->notes_opt);
|
init_display_notes(&rev->notes_opt);
|
||||||
|
5
commit.h
5
commit.h
@ -74,11 +74,16 @@ struct pretty_print_context
|
|||||||
struct reflog_walk_info *reflog_info;
|
struct reflog_walk_info *reflog_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct userformat_want {
|
||||||
|
unsigned notes:1;
|
||||||
|
};
|
||||||
|
|
||||||
extern int has_non_ascii(const char *text);
|
extern int has_non_ascii(const char *text);
|
||||||
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
|
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
|
||||||
extern char *reencode_commit_message(const struct commit *commit,
|
extern char *reencode_commit_message(const struct commit *commit,
|
||||||
const char **encoding_p);
|
const char **encoding_p);
|
||||||
extern void get_commit_format(const char *arg, struct rev_info *);
|
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,
|
extern void format_commit_message(const struct commit *commit,
|
||||||
const char *format, struct strbuf *sb,
|
const char *format, struct strbuf *sb,
|
||||||
const struct pretty_print_context *context);
|
const struct pretty_print_context *context);
|
||||||
|
40
pretty.c
40
pretty.c
@ -775,10 +775,13 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
|
|||||||
}
|
}
|
||||||
return 0; /* unknown %g placeholder */
|
return 0; /* unknown %g placeholder */
|
||||||
case 'N':
|
case 'N':
|
||||||
format_display_notes(commit->object.sha1, sb,
|
if (c->pretty_ctx->show_notes) {
|
||||||
git_log_output_encoding ? git_log_output_encoding
|
format_display_notes(commit->object.sha1, sb,
|
||||||
: git_commit_encoding, 0);
|
git_log_output_encoding ? git_log_output_encoding
|
||||||
return 1;
|
: git_commit_encoding, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For the rest we have to parse the commit header. */
|
/* 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;
|
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,
|
void format_commit_message(const struct commit *commit,
|
||||||
const char *format, struct strbuf *sb,
|
const char *format, struct strbuf *sb,
|
||||||
const struct pretty_print_context *pretty_ctx)
|
const struct pretty_print_context *pretty_ctx)
|
||||||
|
Loading…
Reference in New Issue
Block a user