pretty: two phase conversion for non utf-8 commits
[gitweb.git] / pretty.c
index e59688bcf5d07b562d11d25fc2d2d70a4388fda7..59472750ada226df15ac90092723b044f4eece6f 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -908,23 +908,6 @@ static void parse_commit_message(struct format_commit_context *c)
        c->commit_message_parsed = 1;
 }
 
-static void format_decoration(struct strbuf *sb, const struct commit *commit)
-{
-       struct name_decoration *d;
-       const char *prefix = " (";
-
-       load_ref_decorations(DECORATE_SHORT_REFS);
-       d = lookup_decoration(&name_decoration, &commit->object);
-       while (d) {
-               strbuf_addstr(sb, prefix);
-               prefix = ", ";
-               strbuf_addstr(sb, d->name);
-               d = d->next;
-       }
-       if (prefix[0] == ',')
-               strbuf_addch(sb, ')');
-}
-
 static void strbuf_wrap(struct strbuf *sb, size_t pos,
                        size_t width, size_t indent1, size_t indent2)
 {
@@ -971,7 +954,8 @@ static int format_reflog_person(struct strbuf *sb,
        return format_person_part(sb, part, ident, strlen(ident), dmode);
 }
 
-static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
+static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
+                               const char *placeholder,
                                void *context)
 {
        struct format_commit_context *c = context;
@@ -1103,7 +1087,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                strbuf_addstr(sb, get_revision_mark(NULL, commit));
                return 1;
        case 'd':
-               format_decoration(sb, commit);
+               load_ref_decorations(DECORATE_SHORT_REFS);
+               format_decorations(sb, commit, 0);
                return 1;
        case 'g':               /* reflog info */
                switch(placeholder[1]) {
@@ -1209,7 +1194,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
        return 0;       /* unknown placeholder */
 }
 
-static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
+static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */
+                                const char *placeholder,
                                 void *context)
 {
        int consumed;
@@ -1289,6 +1275,7 @@ void format_commit_message(const struct commit *commit,
 {
        struct format_commit_context context;
        const char *output_enc = pretty_ctx->output_encoding;
+       const char *utf8 = "UTF-8";
 
        memset(&context, 0, sizeof(context));
        context.commit = commit;
@@ -1301,6 +1288,23 @@ void format_commit_message(const struct commit *commit,
        strbuf_expand(sb, format, format_commit_item, &context);
        rewrap_message_tail(sb, &context, 0, 0, 0);
 
+       if (output_enc) {
+               if (same_encoding(utf8, output_enc))
+                       output_enc = NULL;
+       } else {
+               if (context.commit_encoding &&
+                   !same_encoding(context.commit_encoding, utf8))
+                       output_enc = context.commit_encoding;
+       }
+
+       if (output_enc) {
+               int outsz;
+               char *out = reencode_string_len(sb->buf, sb->len,
+                                               output_enc, utf8, &outsz);
+               if (out)
+                       strbuf_attach(sb, out, outsz, outsz + 1);
+       }
+
        free(context.commit_encoding);
        logmsg_free(context.message, commit);
        free(context.signature_check.gpg_output);