#include "cache.h"
+#include "config.h"
#include "commit.h"
#include "utf8.h"
#include "diff.h"
size_t body_off;
/* The following ones are relative to the result struct strbuf. */
- struct chunk abbrev_commit_hash;
- struct chunk abbrev_tree_hash;
- struct chunk abbrev_parent_hashes;
size_t wrap_start;
};
-static int add_again(struct strbuf *sb, struct chunk *chunk)
-{
- if (chunk->len) {
- strbuf_adddup(sb, chunk->off, chunk->len);
- return 1;
- }
-
- /*
- * We haven't seen this chunk before. Our caller is surely
- * going to add it the hard way now. Remember the most likely
- * start of the to-be-added chunk: the current end of the
- * struct strbuf.
- */
- chunk->off = sb->len;
- return 0;
-}
-
static void parse_commit_header(struct format_commit_context *context)
{
const char *msg = context->message;
struct format_commit_context *c)
{
const char *rest = placeholder;
+ const char *basic_color = NULL;
if (placeholder[1] == '(') {
const char *begin = placeholder + 2;
if (!end)
return 0;
+
if (skip_prefix(begin, "auto,", &begin)) {
if (!want_color(c->pretty_ctx->color))
return end - placeholder + 1;
+ } else if (skip_prefix(begin, "always,", &begin)) {
+ /* nothing to do; we do not respect want_color at all */
+ } else {
+ /* the default is the same as "auto" */
+ if (!want_color(c->pretty_ctx->color))
+ return end - placeholder + 1;
}
+
if (color_parse_mem(begin, end - begin, color) < 0)
die(_("unable to parse --pretty format"));
strbuf_addstr(sb, color);
return end - placeholder + 1;
}
+
+ /*
+ * We handle things like "%C(red)" above; for historical reasons, there
+ * are a few colors that can be specified without parentheses (and
+ * they cannot support things like "auto" or "always" at all).
+ */
if (skip_prefix(placeholder + 1, "red", &rest))
- strbuf_addstr(sb, GIT_COLOR_RED);
+ basic_color = GIT_COLOR_RED;
else if (skip_prefix(placeholder + 1, "green", &rest))
- strbuf_addstr(sb, GIT_COLOR_GREEN);
+ basic_color = GIT_COLOR_GREEN;
else if (skip_prefix(placeholder + 1, "blue", &rest))
- strbuf_addstr(sb, GIT_COLOR_BLUE);
+ basic_color = GIT_COLOR_BLUE;
else if (skip_prefix(placeholder + 1, "reset", &rest))
- strbuf_addstr(sb, GIT_COLOR_RESET);
+ basic_color = GIT_COLOR_RESET;
+
+ if (basic_color && want_color(c->pretty_ctx->color))
+ strbuf_addstr(sb, basic_color);
+
return rest - placeholder;
}
/* these depend on the commit */
if (!commit->object.parsed)
- parse_object(commit->object.oid.hash);
+ parse_object(&commit->object.oid);
switch (placeholder[0]) {
case 'H': /* commit hash */
return 1;
case 'h': /* abbreviated commit hash */
strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
- if (add_again(sb, &c->abbrev_commit_hash)) {
- strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
- return 1;
- }
strbuf_add_unique_abbrev(sb, commit->object.oid.hash,
c->pretty_ctx->abbrev);
strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
- c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
return 1;
case 'T': /* tree hash */
strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid));
return 1;
case 't': /* abbreviated tree hash */
- if (add_again(sb, &c->abbrev_tree_hash))
- return 1;
strbuf_add_unique_abbrev(sb, commit->tree->object.oid.hash,
c->pretty_ctx->abbrev);
- c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;
return 1;
case 'P': /* parent hashes */
for (p = commit->parents; p; p = p->next) {
}
return 1;
case 'p': /* abbreviated parent hashes */
- if (add_again(sb, &c->abbrev_parent_hashes))
- return 1;
for (p = commit->parents; p; p = p->next) {
if (p != commit->parents)
strbuf_addch(sb, ' ');
strbuf_add_unique_abbrev(sb, p->item->object.oid.hash,
c->pretty_ctx->abbrev);
}
- c->abbrev_parent_hashes.len = sb->len -
- c->abbrev_parent_hashes.off;
return 1;
case 'm': /* left/right/bottom */
strbuf_addstr(sb, get_revision_mark(NULL, commit));