Re: [PATCH] Initialize notes trees if %N is used and no --show-notes given
- From
Jeff King <peff@peff.net>
- Date
- Apr 7, 2010, 06:36 UTC
- Message-ID
- <20100407063642.GA5399@coredump.intra.peff.net>
- In-Reply-To
- <7v39z7g4zp.fsf@alter.siamese.dyndns.org>
On Tue, Apr 06, 2010 at 11:18:34PM -0700, Junio C Hamano wrote:
> As Peff pointed out, %d does things lazily, but I suspect it might be hard > to do a similar initialization for %N.
I think you would just have to stuff the notes-related options from the rev-list options into the pretty-print context, which would then make them available to the user-format callback.
> I wonder if we can inspect-but-not-use format string before we even start > walking, to see if we need notes (when we see %N).
I have considered something like the patch below before, but it is not 100% accurate. Part of the parsing happens in strbuf_expand, but parsing of things like %w(...) happens ad-hoc inside the formatting callback (so we would see "%w(%N)" as wanting notes, when it doesn't really. In theory it would be nicer if we separated syntax and semantics, so I could parse %X(...) as "the %X placeholder with ... as arguments" without having to actually understand what %X does. In practice, it doesn't matter here because we don't have very many placeholders that take arbitrary arguments.
The patch below is totally untested and just meant to illustrate the approach. Use caution.
diff --git a/commit.h b/commit.h index 2b7fd89..5081389 100644 --- 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_fill_want(const char *format, 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); diff --git a/pretty.c b/pretty.c index 6ba3da8..8ed3d36 100644 --- a/pretty.c +++ b/pretty.c @@ -855,6 +855,24 @@ 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; + switch (*placeholder) { + case 'N': w->notes = 1; + } + return 0; +} + +void userformat_fill_want(const char *format, struct userformat_want *w) +{ + struct strbuf dummy = STRBUF_INIT; + memset(w, 0, sizeof(*w)); + strbuf_expand(&dummy, 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)