mirror of
https://github.com/git/git
synced 2024-08-27 11:39:22 +00:00
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>
This commit is contained in:
parent
4b2bced559
commit
52883fbd76
|
@ -20,6 +20,8 @@ void add_head(struct rev_info *revs);
|
||||||
static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||||
struct rev_info *rev)
|
struct rev_info *rev)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
rev->abbrev = DEFAULT_ABBREV;
|
rev->abbrev = DEFAULT_ABBREV;
|
||||||
rev->commit_format = CMIT_FMT_DEFAULT;
|
rev->commit_format = CMIT_FMT_DEFAULT;
|
||||||
rev->verbose_header = 1;
|
rev->verbose_header = 1;
|
||||||
|
@ -27,8 +29,21 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||||
argc = setup_revisions(argc, argv, rev, "HEAD");
|
argc = setup_revisions(argc, argv, rev, "HEAD");
|
||||||
if (rev->diffopt.pickaxe || rev->diffopt.filter)
|
if (rev->diffopt.pickaxe || rev->diffopt.filter)
|
||||||
rev->always_show_header = 0;
|
rev->always_show_header = 0;
|
||||||
if (argc > 1)
|
for (i = 1; i < argc; i++) {
|
||||||
die("unrecognized argument: %s", argv[1]);
|
const char *arg = argv[i];
|
||||||
|
if (!strncmp(arg, "--encoding=", 11)) {
|
||||||
|
arg += 11;
|
||||||
|
if (MAX_ENCODING_LENGTH <= strlen(arg))
|
||||||
|
die(" Value of output encoding '%s' too long",
|
||||||
|
arg);
|
||||||
|
if (strcmp(arg, "none"))
|
||||||
|
strcpy(git_commit_encoding, arg);
|
||||||
|
else
|
||||||
|
git_commit_encoding[0] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
die("unrecognized argument: %s", arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_log_walk(struct rev_info *rev)
|
static int cmd_log_walk(struct rev_info *rev)
|
||||||
|
|
61
commit.c
61
commit.c
|
@ -1,6 +1,7 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
int save_commit_buffer = 1;
|
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;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
|
static char *get_header(const struct commit *commit, const char *key)
|
||||||
unsigned long len, char *buf, unsigned long space,
|
{
|
||||||
|
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,
|
int abbrev, const char *subject,
|
||||||
const char *after_subject, int relative_date)
|
const char *after_subject,
|
||||||
|
int relative_date)
|
||||||
{
|
{
|
||||||
int hdr = 1, body = 0;
|
int hdr = 1, body = 0;
|
||||||
unsigned long offset = 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;
|
int parents_shown = 0;
|
||||||
const char *msg = commit->buffer;
|
const char *msg = commit->buffer;
|
||||||
int plain_non_ascii = 0;
|
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)
|
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
|
||||||
indent = 0;
|
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)
|
if (fmt == CMIT_FMT_EMAIL && !body)
|
||||||
buf[offset++] = '\n';
|
buf[offset++] = '\n';
|
||||||
buf[offset] = '\0';
|
buf[offset] = '\0';
|
||||||
|
|
||||||
|
free(reencoded);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ struct rev_info {
|
||||||
const char *ref_message_id;
|
const char *ref_message_id;
|
||||||
const char *add_signoff;
|
const char *add_signoff;
|
||||||
const char *extra_headers;
|
const char *extra_headers;
|
||||||
|
const char *log_reencode;
|
||||||
|
|
||||||
/* Filter by commit log message */
|
/* Filter by commit log message */
|
||||||
struct grep_opt *grep_filter;
|
struct grep_opt *grep_filter;
|
||||||
|
|
Loading…
Reference in a new issue