summaryrefslogtreecommitdiff
path: root/commit.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-12-25 11:48:35 -0800
committerJunio C Hamano <junkio@cox.net>2006-12-26 00:52:13 -0800
commit52883fbd767f8a79a6f98a08907d0a9f6ba1ece1 (patch)
tree7b148784dc3ffe306d2a9bfbd823c7414e0327b9 /commit.c
parent4b2bced55948422198dad92dcbf4b5b98913f1e7 (diff)
downloadgit-52883fbd767f8a79a6f98a08907d0a9f6ba1ece1.tar.gz
Teach log family --encoding
Updated commit objects record the encoding used in their encoding header. This updates the log family to reencode it into the encoding specified in i18n.commitencoding (or the default, which is "utf-8") upon output. To force a specific encoding that is different, log family takes command line flag --encoding=<encoding>; giving --encoding=none entirely disables the reencoding and lets you view log messges in their original encoding. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'commit.c')
-rw-r--r--commit.c61
1 files changed, 58 insertions, 3 deletions
diff --git a/commit.c b/commit.c
index 289ef65eb1..df4bc0775a 100644
--- a/commit.c
+++ b/commit.c
@@ -1,6 +1,7 @@
#include "cache.h"
#include "tag.h"
#include "commit.h"
+#include "utf8.h"
int save_commit_buffer = 1;
@@ -563,10 +564,53 @@ static int add_merge_info(enum cmit_fmt fmt, char *buf, const struct commit *com
return offset;
}
-unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
- unsigned long len, char *buf, unsigned long space,
+static char *get_header(const struct commit *commit, const char *key)
+{
+ int key_len = strlen(key);
+ const char *line = commit->buffer;
+
+ for (;;) {
+ const char *eol = strchr(line, '\n'), *next;
+
+ if (line == eol)
+ return NULL;
+ if (!eol) {
+ eol = line + strlen(line);
+ next = NULL;
+ } else
+ next = eol + 1;
+ if (!strncmp(line, key, key_len) && line[key_len] == ' ') {
+ int len = eol - line - key_len;
+ char *ret = xmalloc(len);
+ memcpy(ret, line + key_len + 1, len - 1);
+ ret[len - 1] = '\0';
+ return ret;
+ }
+ line = next;
+ }
+}
+
+static char *logmsg_reencode(const struct commit *commit)
+{
+ char *encoding = get_header(commit, "encoding");
+ char *out;
+
+ if (!encoding || !strcmp(encoding, git_commit_encoding))
+ return NULL;
+ out = reencode_string(commit->buffer, git_commit_encoding, encoding);
+ free(encoding);
+ if (!out)
+ return NULL;
+ return out;
+}
+
+unsigned long pretty_print_commit(enum cmit_fmt fmt,
+ const struct commit *commit,
+ unsigned long len,
+ char *buf, unsigned long space,
int abbrev, const char *subject,
- const char *after_subject, int relative_date)
+ const char *after_subject,
+ int relative_date)
{
int hdr = 1, body = 0;
unsigned long offset = 0;
@@ -574,6 +618,15 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
int parents_shown = 0;
const char *msg = commit->buffer;
int plain_non_ascii = 0;
+ char *reencoded = NULL;
+
+ if (*git_commit_encoding) {
+ reencoded = logmsg_reencode(commit);
+ if (reencoded) {
+ msg = reencoded;
+ len = strlen(msg);
+ }
+ }
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
indent = 0;
@@ -721,6 +774,8 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
if (fmt == CMIT_FMT_EMAIL && !body)
buf[offset++] = '\n';
buf[offset] = '\0';
+
+ free(reencoded);
return offset;
}