Skip to content

Commit 754395d

Browse files
pcloudsgitster
authored andcommitted
fetch: align per-ref summary report in UTF-8 locales
fetch does printf("%-*s", width, "foo") where "foo" can be a utf-8 string, but width is in bytes, not columns. For ASCII it's fine as one byte takes one column. For utf-8, this may result in misaligned ref summary table. Introduce gettext_width() function that returns the string length in columns (currently only supports utf-8 locales). Make the code use TRANSPORT_SUMMARY(x) where the length is compensated properly in non-English locales. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b521831 commit 754395d

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

builtin/fetch.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,8 @@ static int update_local_ref(struct ref *ref,
255255
if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
256256
if (verbosity > 0)
257257
strbuf_addf(display, "= %-*s %-*s -> %s",
258-
TRANSPORT_SUMMARY_WIDTH,
259-
_("[up to date]"), REFCOL_WIDTH,
260-
remote, pretty_ref);
258+
TRANSPORT_SUMMARY(_("[up to date]")),
259+
REFCOL_WIDTH, remote, pretty_ref);
261260
return 0;
262261
}
263262

@@ -271,7 +270,7 @@ static int update_local_ref(struct ref *ref,
271270
*/
272271
strbuf_addf(display,
273272
_("! %-*s %-*s -> %s (can't fetch in current branch)"),
274-
TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
273+
TRANSPORT_SUMMARY(_("[rejected]")),
275274
REFCOL_WIDTH, remote, pretty_ref);
276275
return 1;
277276
}
@@ -282,7 +281,7 @@ static int update_local_ref(struct ref *ref,
282281
r = s_update_ref("updating tag", ref, 0);
283282
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
284283
r ? '!' : '-',
285-
TRANSPORT_SUMMARY_WIDTH, _("[tag update]"),
284+
TRANSPORT_SUMMARY(_("[tag update]")),
286285
REFCOL_WIDTH, remote, pretty_ref,
287286
r ? _(" (unable to update local ref)") : "");
288287
return r;
@@ -317,7 +316,7 @@ static int update_local_ref(struct ref *ref,
317316
r = s_update_ref(msg, ref, 0);
318317
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
319318
r ? '!' : '*',
320-
TRANSPORT_SUMMARY_WIDTH, what,
319+
TRANSPORT_SUMMARY(what),
321320
REFCOL_WIDTH, remote, pretty_ref,
322321
r ? _(" (unable to update local ref)") : "");
323322
return r;
@@ -357,7 +356,7 @@ static int update_local_ref(struct ref *ref,
357356
return r;
358357
} else {
359358
strbuf_addf(display, "! %-*s %-*s -> %s %s",
360-
TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
359+
TRANSPORT_SUMMARY(_("[rejected]")),
361360
REFCOL_WIDTH, remote, pretty_ref,
362361
_("(non-fast-forward)"));
363362
return 1;
@@ -554,7 +553,7 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
554553
result |= delete_ref(ref->name, NULL, 0);
555554
if (verbosity >= 0) {
556555
fprintf(stderr, " x %-*s %-*s -> %s\n",
557-
TRANSPORT_SUMMARY_WIDTH, _("[deleted]"),
556+
TRANSPORT_SUMMARY(_("[deleted]")),
558557
REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name));
559558
warn_dangling_symref(stderr, dangling_msg, ref->name);
560559
}

gettext.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "git-compat-util.h"
66
#include "gettext.h"
7+
#include "strbuf.h"
8+
#include "utf8.h"
79

810
#ifndef NO_GETTEXT
911
# include <locale.h>
@@ -27,10 +29,9 @@ int use_gettext_poison(void)
2729
#endif
2830

2931
#ifndef NO_GETTEXT
32+
static const char *charset;
3033
static void init_gettext_charset(const char *domain)
3134
{
32-
const char *charset;
33-
3435
/*
3536
This trick arranges for messages to be emitted in the user's
3637
requested encoding, but avoids setting LC_CTYPE from the
@@ -128,4 +129,14 @@ void git_setup_gettext(void)
128129
init_gettext_charset("git");
129130
textdomain("git");
130131
}
132+
133+
/* return the number of columns of string 's' in current locale */
134+
int gettext_width(const char *s)
135+
{
136+
static int is_utf8 = -1;
137+
if (is_utf8 == -1)
138+
is_utf8 = !strcmp(charset, "UTF-8");
139+
140+
return is_utf8 ? utf8_strwidth(s) : strlen(s);
141+
}
131142
#endif

gettext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@
3030

3131
#ifndef NO_GETTEXT
3232
extern void git_setup_gettext(void);
33+
extern int gettext_width(const char *s);
3334
#else
3435
static inline void git_setup_gettext(void)
3536
{
3637
}
38+
static inline int gettext_width(const char *s)
39+
{
40+
return strlen(s);
41+
}
3742
#endif
3843

3944
#ifdef GETTEXT_POISON

transport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct transport {
106106
#define TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND 256
107107

108108
#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
109+
#define TRANSPORT_SUMMARY(x) (int)(TRANSPORT_SUMMARY_WIDTH + strlen(x) - gettext_width(x)), (x)
109110

110111
/* Returns a transport suitable for the url */
111112
struct transport *transport_get(struct remote *, const char *);

0 commit comments

Comments
 (0)