pretty: --format output should honor logOutputEncoding

One can set an alias $ git config [--global] alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit --date=local" to see the log as a pretty tree (like *gitk* but in a terminal). However, log messages written in an encoding i18n.commitEncoding which differs from terminal encoding are shown corrupted even when i18n.logOutputEncoding and terminal encoding are the same (e.g. log messages committed on a Cygwin box with Windows-1251 encoding seen on a Linux box with a UTF-8 encoding and vice versa). To simplify an example we can say the following two commands are expected to give the same output to a terminal: $ git log --oneline --no-color $ git log --pretty=format:'%h %s' However, the former pays attention to i18n.logOutputEncoding configuration, while the latter does not when it formats "%s". The same corruption is true for $ git diff --submodule=log and $ git rev-list --pretty=format:%s HEAD and $ git reset --hard This patch makes pretty --format honor logOutputEncoding when it formats log message. Signed-off-by: Alexey Shumkin <Alex.Crezoff@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Alexey Shumkin committed Jun 26, 2013 at 14:19 UTC ecaee8050cec23eb4cf082512e907e3e52c20b57
9 files changed +35 -28
builtin/reset.c
+4 -1
@@ -93,10 +93,12 @@ static int reset_index(const unsigned char *sha1, int reset_type, int quiet)
93 static void print_new_head_line(struct commit *commit)
94 {
95 const char *hex, *body;
96 + char *msg;
97
98 hex = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
99 printf(_("HEAD is now at %s"), hex);
99 - body = strstr(commit->buffer, "\n\n");
100 + msg = logmsg_reencode(commit, NULL, get_log_output_encoding());
101 + body = strstr(msg, "\n\n");
102 if (body) {
103 const char *eol;
104 size_t len;
@@ -107,6 +109,7 @@ static void print_new_head_line(struct commit *commit)
109 }
110 else
111 printf("\n");
112 + logmsg_free(msg, commit);
113 }
114
115 static void update_index_from_diff(struct diff_queue_struct *q,
builtin/rev-list.c
+1
@@ -111,6 +111,7 @@ static void show_commit(struct commit *commit, void *data)
111 ctx.date_mode = revs->date_mode;
112 ctx.date_mode_explicit = revs->date_mode_explicit;
113 ctx.fmt = revs->commit_format;
114 + ctx.output_encoding = get_log_output_encoding();
115 pretty_print_commit(&ctx, commit, &buf);
116 if (revs->graph) {
117 if (buf.len) {
builtin/shortlog.c
+1
@@ -137,6 +137,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
137 ctx.subject = "";
138 ctx.after_subject = "";
139 ctx.date_mode = DATE_NORMAL;
140 + ctx.output_encoding = get_log_output_encoding();
141 pretty_print_commit(&ctx, commit, &ufbuf);
142 buffer = ufbuf.buf;
143 } else if (*buffer) {
log-tree.c
+1
@@ -616,6 +616,7 @@ void show_log(struct rev_info *opt)
616 ctx.fmt = opt->commit_format;
617 ctx.mailmap = opt->mailmap;
618 ctx.color = opt->diffopt.use_color;
619 + ctx.output_encoding = get_log_output_encoding();
620 pretty_print_commit(&ctx, commit, &msgbuf);
621
622 if (opt->add_signoff)
submodule.c
+1
@@ -226,6 +226,7 @@ static void print_submodule_summary(struct rev_info *rev, FILE *f,
226 while ((commit = get_revision(rev))) {
227 struct pretty_print_context ctx = {0};
228 ctx.date_mode = rev->date_mode;
229 + ctx.output_encoding = get_log_output_encoding();
230 strbuf_setlen(&sb, 0);
231 strbuf_addstr(&sb, line_prefix);
232 if (commit->object.flags & SYMMETRIC_LEFT) {
t/t4041-diff-submodule-option.sh
+5 -5
@@ -94,7 +94,7 @@ test_expect_success 'diff.submodule does not affect plumbing' '
94 commit_file sm1 &&
95 head2=$(add_file sm1 foo3)
96
97 -test_expect_failure 'modified submodule(forward)' '
97 +test_expect_success 'modified submodule(forward)' '
98 git diff-index -p --submodule=log HEAD >actual &&
99 cat >expected <<-EOF &&
100 Submodule sm1 $head1..$head2:
@@ -103,7 +103,7 @@ test_expect_failure 'modified submodule(forward)' '
103 test_cmp expected actual
104 '
105
106 -test_expect_failure 'modified submodule(forward)' '
106 +test_expect_success 'modified submodule(forward)' '
107 git diff --submodule=log >actual &&
108 cat >expected <<-EOF &&
109 Submodule sm1 $head1..$head2:
@@ -112,7 +112,7 @@ test_expect_failure 'modified submodule(forward)' '
112 test_cmp expected actual
113 '
114
115 -test_expect_failure 'modified submodule(forward) --submodule' '
115 +test_expect_success 'modified submodule(forward) --submodule' '
116 git diff --submodule >actual &&
117 cat >expected <<-EOF &&
118 Submodule sm1 $head1..$head2:
@@ -143,7 +143,7 @@ head3=$(
143 git rev-parse --short --verify HEAD
144 )
145
146 -test_expect_failure 'modified submodule(backward)' '
146 +test_expect_success 'modified submodule(backward)' '
147 git diff-index -p --submodule=log HEAD >actual &&
148 cat >expected <<-EOF &&
149 Submodule sm1 $head2..$head3 (rewind):
@@ -154,7 +154,7 @@ test_expect_failure 'modified submodule(backward)' '
154 '
155
156 head4=$(add_file sm1 foo4 foo5)
157 -test_expect_failure 'modified submodule(backward and forward)' '
157 +test_expect_success 'modified submodule(backward and forward)' '
158 git diff-index -p --submodule=log HEAD >actual &&
159 cat >expected <<-EOF &&
160 Submodule sm1 $head2...$head4:
t/t4205-log-pretty-formats.sh
+17 -17
@@ -69,7 +69,7 @@ test_expect_success 'alias user-defined tformat with %s (iso-8859-1 encoding)' '
69 test_cmp expected-s actual-s
70 '
71
72 -test_expect_failure 'alias user-defined tformat with %s (utf-8 encoding)' '
72 +test_expect_success 'alias user-defined tformat with %s (utf-8 encoding)' '
73 git log --oneline >expected-s &&
74 git log --pretty="tformat:%h %s" >actual-s &&
75 test_cmp expected-s actual-s
@@ -108,19 +108,19 @@ test_expect_success 'alias loop' '
108 test_must_fail git log --pretty=test-foo
109 '
110
111 -test_expect_failure 'NUL separation' '
111 +test_expect_success 'NUL separation' '
112 printf "add bar\0$(commit_msg)" >expected &&
113 git log -z --pretty="format:%s" >actual &&
114 test_cmp expected actual
115 '
116
117 -test_expect_failure 'NUL termination' '
117 +test_expect_success 'NUL termination' '
118 printf "add bar\0$(commit_msg)\0" >expected &&
119 git log -z --pretty="tformat:%s" >actual &&
120 test_cmp expected actual
121 '
122
123 -test_expect_failure 'NUL separation with --stat' '
123 +test_expect_success 'NUL separation with --stat' '
124 stat0_part=$(git diff --stat HEAD^ HEAD) &&
125 stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
126 printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n" >expected &&
@@ -145,7 +145,7 @@ test_expect_success 'setup more commits' '
145 head4=$(git rev-parse --verify --short HEAD~3)
146 '
147
148 -test_expect_failure 'left alignment formatting' "
148 +test_expect_success 'left alignment formatting' "
149 git log --pretty='format:%<(40)%s' >actual &&
150 # complete the incomplete line at the end
151 echo >>actual &&
@@ -158,7 +158,7 @@ EOF
158 test_cmp expected actual
159 "
160
161 -test_expect_failure 'left alignment formatting at the nth column' "
161 +test_expect_success 'left alignment formatting at the nth column' "
162 git log --pretty='format:%h %<|(40)%s' >actual &&
163 # complete the incomplete line at the end
164 echo >>actual &&
@@ -171,7 +171,7 @@ EOF
171 test_cmp expected actual
172 "
173
174 -test_expect_failure 'left alignment formatting with no padding' "
174 +test_expect_success 'left alignment formatting with no padding' "
175 git log --pretty='format:%<(1)%s' >actual &&
176 # complete the incomplete line at the end
177 echo >>actual &&
@@ -184,7 +184,7 @@ EOF
184 test_cmp expected actual
185 "
186
187 -test_expect_failure 'left alignment formatting with trunc' "
187 +test_expect_success 'left alignment formatting with trunc' "
188 git log --pretty='format:%<(10,trunc)%s' >actual &&
189 # complete the incomplete line at the end
190 echo >>actual &&
@@ -197,7 +197,7 @@ EOF
197 test_cmp expected actual
198 "
199
200 -test_expect_failure 'left alignment formatting with ltrunc' "
200 +test_expect_success 'left alignment formatting with ltrunc' "
201 git log --pretty='format:%<(10,ltrunc)%s' >actual &&
202 # complete the incomplete line at the end
203 echo >>actual &&
@@ -210,7 +210,7 @@ EOF
210 test_cmp expected actual
211 "
212
213 -test_expect_failure 'left alignment formatting with mtrunc' "
213 +test_expect_success 'left alignment formatting with mtrunc' "
214 git log --pretty='format:%<(10,mtrunc)%s' >actual &&
215 # complete the incomplete line at the end
216 echo >>actual &&
@@ -223,7 +223,7 @@ EOF
223 test_cmp expected actual
224 "
225
226 -test_expect_failure 'right alignment formatting' "
226 +test_expect_success 'right alignment formatting' "
227 git log --pretty='format:%>(40)%s' >actual &&
228 # complete the incomplete line at the end
229 echo >>actual &&
@@ -236,7 +236,7 @@ EOF
236 test_cmp expected actual
237 "
238
239 -test_expect_failure 'right alignment formatting at the nth column' "
239 +test_expect_success 'right alignment formatting at the nth column' "
240 git log --pretty='format:%h %>|(40)%s' >actual &&
241 # complete the incomplete line at the end
242 echo >>actual &&
@@ -249,7 +249,7 @@ EOF
249 test_cmp expected actual
250 "
251
252 -test_expect_failure 'right alignment formatting with no padding' "
252 +test_expect_success 'right alignment formatting with no padding' "
253 git log --pretty='format:%>(1)%s' >actual &&
254 # complete the incomplete line at the end
255 echo >>actual &&
@@ -262,7 +262,7 @@ EOF
262 test_cmp expected actual
263 "
264
265 -test_expect_failure 'center alignment formatting' "
265 +test_expect_success 'center alignment formatting' "
266 git log --pretty='format:%><(40)%s' >actual &&
267 # complete the incomplete line at the end
268 echo >>actual &&
@@ -275,7 +275,7 @@ EOF
275 test_cmp expected actual
276 "
277
278 -test_expect_failure 'center alignment formatting at the nth column' "
278 +test_expect_success 'center alignment formatting at the nth column' "
279 git log --pretty='format:%h %><|(40)%s' >actual &&
280 # complete the incomplete line at the end
281 echo >>actual &&
@@ -288,7 +288,7 @@ EOF
288 test_cmp expected actual
289 "
290
291 -test_expect_failure 'center alignment formatting with no padding' "
291 +test_expect_success 'center alignment formatting with no padding' "
292 git log --pretty='format:%><(1)%s' >actual &&
293 # complete the incomplete line at the end
294 echo >>actual &&
@@ -301,7 +301,7 @@ EOF
301 test_cmp expected actual
302 "
303
304 -test_expect_failure 'left/right alignment formatting with stealing' "
304 +test_expect_success 'left/right alignment formatting with stealing' "
305 git commit --amend -m short --author 'long long long <long@me.com>' &&
306 git log --pretty='format:%<(10,trunc)%s%>>(10,ltrunc)% an' >actual &&
307 # complete the incomplete line at the end
t/t6006-rev-list-format.sh
+4 -4
@@ -141,7 +141,7 @@ commit $head1
141 iso-8859-1
142 EOF
143
144 -test_format failure subject %s <<EOF
144 +test_format subject %s <<EOF
145 commit $head2
146 $changed
147 commit $head1
@@ -153,7 +153,7 @@ commit $head2
153 commit $head1
154 EOF
155
156 -test_format failure raw-body %B <<EOF
156 +test_format raw-body %B <<EOF
157 commit $head2
158 $changed
159
@@ -247,7 +247,7 @@ commit $head1
247 iso-8859-1
248 EOF
249
250 -test_format failure complex-subject %s <<EOF
250 +test_format complex-subject %s <<EOF
251 commit $head3
252 Test printing of complex bodies
253 commit $head2
@@ -256,7 +256,7 @@ commit $head1
256 $added
257 EOF
258
259 -test_format failure complex-body %b <<EOF
259 +test_format complex-body %b <<EOF
260 commit $head3
261 This commit message is much longer than the others,
262 and it will be encoded in iso8859-1. We should therefore
t/t7102-reset.sh
+1 -1
@@ -55,7 +55,7 @@ check_changes () {
55 done | test_cmp .cat_expect -
56 }
57
58 -test_expect_failure 'reset --hard message' '
58 +test_expect_success 'reset --hard message' '
59 hex=$(git log -1 --format="%h") &&
60 git reset --hard > .actual &&
61 echo HEAD is now at $hex $(commit_msg) > .expected &&