diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 9aff980..33c29f7 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -92,6 +92,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
char comment[1000];
char *buffer;
unsigned int size;
+ int encoding_is_utf8;
setup_ident();
git_config(git_default_config);
@@ -117,6 +118,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
parents++;
}
+ encoding_is_utf8 = !strcmp(git_commit_encoding, "utf-8");
+
init_buffer(&buffer, &size);
add_buffer(&buffer, &size, "tree %s\n", sha1_to_hex(tree_sha1));
@@ -130,7 +133,11 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
/* Person/date information */
add_buffer(&buffer, &size, "author %s\n", git_author_info(1));
- add_buffer(&buffer, &size, "committer %s\n\n", git_committer_info(1));
+ add_buffer(&buffer, &size, "committer %s\n", git_committer_info(1));
+ if (!encoding_is_utf8)
+ add_buffer(&buffer, &size,
+ "encoding %s\n", git_commit_encoding);
+ add_buffer(&buffer, &size, "\n");
/* And add the comment */
while (fgets(comment, sizeof(comment), stdin) != NULL)
@@ -138,16 +145,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
/* And check the encoding */
buffer[size] = '\0';
- if (strcmp(git_commit_encoding, "utf-8")) {
- /*
- * Add trailing section: this is safe because
- * add_buffer always allocates one byte more.
- */
- size++;
- add_buffer(&buffer, &size,
- "encoding %s\n", git_commit_encoding);
- }
- else if (!is_utf8(buffer))
+ if (encoding_is_utf8 && !is_utf8(buffer))
fprintf(stderr, commit_utf8_warn);
if (!write_sha1_file(buffer, size, commit_type, commit_sha1)) {diff --git a/commit.c b/commit.c
index 58c4ecb..3132323 100644
--- a/commit.c
+++ b/commit.c
@@ -598,56 +598,43 @@ static int add_merge_info(enum cmit_fmt fmt, char *buf, const struct commit *com
return offset;
}
-const char *commit_trailer(const struct commit *commit)
+static char *get_header(const struct commit *commit, const char *key)
{
- unsigned long size, len;
- char type[10];
+ int key_len = strlen(key);
+ const char *line = commit->buffer;
- if (sha1_object_info(commit->object.sha1, type, &size))
- return NULL;
- len = strlen(commit->buffer);
- if (len == size)
- return NULL;
- return commit->buffer + len + 1;
-}
-
-char *find_commit_trailer(const struct commit *commit, const char *key)
-{
- const char *trailer = commit_trailer(commit);
- int keylen = strlen(key);
- if (!trailer)
- return NULL;
- while (*trailer) {
- const char *eol = strchr(trailer, '\n');
- if (!eol)
- eol = trailer + strlen(trailer);
- if (!strncmp(trailer, key, keylen) && trailer[keylen] == ' ') {
- int valsz = eol - trailer - keylen;
- char *val = xmalloc(valsz + 1);
- memcpy(val, trailer + keylen + 1, valsz);
- val[valsz] = '\0';
- if (val[valsz-1] == '\n')
- val[valsz-1] = '\0';
- return val;
+ 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;
}
- if (!eol)
- break;
- trailer = eol + 1;
+ line = next;
}
- return NULL;
}
static char *logmsg_to_utf8(const struct commit *commit)
{
- char *encoding = find_commit_trailer(commit, "encoding");
+ char *encoding = get_header(commit, "encoding");
char *out;
if (!encoding)
- return commit->buffer;
+ return NULL;
out = reencode_string(commit->buffer, "utf-8", encoding);
free(encoding);
if (!out)
- return commit->buffer;
+ return NULL;
return out;
}
@@ -662,11 +649,12 @@ 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;
- int msg_reencoded = 0;
+ char *reencoded = NULL;
if (strcmp(git_commit_encoding, "utf-8") && i18n_log_to_utf8) {
- msg = logmsg_to_utf8(commit);
- msg_reencoded = 1;
+ reencoded = logmsg_to_utf8(commit);
+ if (reencoded)
+ msg = reencoded;
}
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)@@ -816,8 +804,8 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
buf[offset++] = '\n';
buf[offset] = '\0';
- if (msg_reencoded)
- free((char*)msg);
+ if (reencoded)
+ free(reencoded);
return offset;
}
--
1.4.4.3.g0001f-dirty