]> rtime.felk.cvut.cz Git - git.git/blobdiff - pretty.c
Merge branch 'wp/pretty-enhancement'
[git.git] / pretty.c
index c2c8901f8f826ea2d81e7c0185abd81964288112..8b18efda9cd6eb615900687c0205daa832794c92 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -18,7 +18,9 @@ static struct cmt_fmt_map {
        int is_alias;
        const char *user_format;
 } *commit_formats;
+static size_t builtin_formats_len;
 static size_t commit_formats_len;
+static size_t commit_formats_alloc;
 static struct cmt_fmt_map *find_commit_format(const char *sought);
 
 static void save_user_format(struct rev_info *rev, const char *cp, int is_tformat)
@@ -30,6 +32,52 @@ static void save_user_format(struct rev_info *rev, const char *cp, int is_tforma
        rev->commit_format = CMIT_FMT_USERFORMAT;
 }
 
+static int git_pretty_formats_config(const char *var, const char *value, void *cb)
+{
+       struct cmt_fmt_map *commit_format = NULL;
+       const char *name;
+       const char *fmt;
+       int i;
+
+       if (prefixcmp(var, "pretty."))
+               return 0;
+
+       name = var + strlen("pretty.");
+       for (i = 0; i < builtin_formats_len; i++) {
+               if (!strcmp(commit_formats[i].name, name))
+                       return 0;
+       }
+
+       for (i = builtin_formats_len; i < commit_formats_len; i++) {
+               if (!strcmp(commit_formats[i].name, name)) {
+                       commit_format = &commit_formats[i];
+                       break;
+               }
+       }
+
+       if (!commit_format) {
+               ALLOC_GROW(commit_formats, commit_formats_len+1,
+                          commit_formats_alloc);
+               commit_format = &commit_formats[commit_formats_len];
+               memset(commit_format, 0, sizeof(*commit_format));
+               commit_formats_len++;
+       }
+
+       commit_format->name = xstrdup(name);
+       commit_format->format = CMIT_FMT_USERFORMAT;
+       git_config_string(&fmt, var, value);
+       if (!prefixcmp(fmt, "format:") || !prefixcmp(fmt, "tformat:")) {
+               commit_format->is_tformat = fmt[0] == 't';
+               fmt = strchr(fmt, ':') + 1;
+       } else if (strchr(fmt, '%'))
+               commit_format->is_tformat = 1;
+       else
+               commit_format->is_alias = 1;
+       commit_format->user_format = fmt;
+
+       return 0;
+}
+
 static void setup_commit_formats(void)
 {
        struct cmt_fmt_map builtin_formats[] = {
@@ -42,10 +90,12 @@ static void setup_commit_formats(void)
                { "oneline",    CMIT_FMT_ONELINE,       1 }
        };
        commit_formats_len = ARRAY_SIZE(builtin_formats);
-       commit_formats = xmalloc(commit_formats_len *
-                                sizeof(*builtin_formats));
+       builtin_formats_len = commit_formats_len;
+       ALLOC_GROW(commit_formats, commit_formats_len, commit_formats_alloc);
        memcpy(commit_formats, builtin_formats,
               sizeof(*builtin_formats)*ARRAY_SIZE(builtin_formats));
+
+       git_config(git_pretty_formats_config, NULL);
 }
 
 static struct cmt_fmt_map *find_commit_format_recursive(const char *sought,
@@ -116,6 +166,10 @@ void get_commit_format(const char *arg, struct rev_info *rev)
 
        rev->commit_format = commit_format->format;
        rev->use_terminator = commit_format->is_tformat;
+       if (commit_format->format == CMIT_FMT_USERFORMAT) {
+               save_user_format(rev, commit_format->user_format,
+                                commit_format->is_tformat);
+       }
 }
 
 /*
@@ -770,7 +824,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                if (add_again(sb, &c->abbrev_commit_hash))
                        return 1;
                strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1,
-                                                    DEFAULT_ABBREV));
+                                                    c->pretty_ctx->abbrev));
                c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
                return 1;
        case 'T':               /* tree hash */
@@ -780,7 +834,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                if (add_again(sb, &c->abbrev_tree_hash))
                        return 1;
                strbuf_addstr(sb, find_unique_abbrev(commit->tree->object.sha1,
-                                                    DEFAULT_ABBREV));
+                                                    c->pretty_ctx->abbrev));
                c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;
                return 1;
        case 'P':               /* parent hashes */
@@ -797,7 +851,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                        if (p != commit->parents)
                                strbuf_addch(sb, ' ');
                        strbuf_addstr(sb, find_unique_abbrev(
-                                       p->item->object.sha1, DEFAULT_ABBREV));
+                                       p->item->object.sha1,
+                                       c->pretty_ctx->abbrev));
                }
                c->abbrev_parent_hashes.len = sb->len -
                                              c->abbrev_parent_hashes.off;
@@ -854,6 +909,10 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
        case 'e':       /* encoding */
                strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
                return 1;
+       case 'B':       /* raw body */
+               /* message_off is always left at the initial newline */
+               strbuf_addstr(sb, msg + c->message_off + 1);
+               return 1;
        }
 
        /* Now we need to parse the commit message. */