Subject: [PATCH v2] transport.c: mark push status strings for translation

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Sat, 16 Nov 2013 10:19:46 +0700

Mark strings like "[up to date]" passed to print_ref_status() for
translation with N_() instead of _() so they can remain untranslated
in porcelain mode.

While at there, mark some error strings in git push for translation
too.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
Reviewed-by: Jonathan Nieder <[email-masked]>
---
 builtin/push.c |  8 +++---
 transport.c    | 81 ++++++++++++++++++++++++++++++++++------------------------
 2 files changed, 52 insertions(+), 37 deletions(-)

diff --git a/builtin/push.c b/builtin/push.c
index 7b1b66c..22e2d4c 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -319,7 +319,7 @@ static int push_with_options(struct transport *transport, int flags)
 
 	if (!is_empty_cas(&cas)) {
 		if (!transport->smart_options)
-			die("underlying transport does not support --%s option",
+			die(_("underlying transport does not support --%s option"),
 			    CAS_OPT_NAME);
 		transport->smart_options->cas = &cas;
 	}
@@ -426,7 +426,7 @@ static int option_parse_recurse_submodules(const struct option *opt,
 
 	if (*flags & (TRANSPORT_RECURSE_SUBMODULES_CHECK |
 		      TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND))
-		die("%s can only be used once.", opt->long_name);
+		die(_("%s can only be used once."), opt->long_name);
 
 	if (arg) {
 		if (!strcmp(arg, "check"))
@@ -434,9 +434,9 @@ static int option_parse_recurse_submodules(const struct option *opt,
 		else if (!strcmp(arg, "on-demand"))
 			*flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
 		else
-			die("bad %s argument: %s", opt->long_name, arg);
+			die(_("bad %s argument: %s"), opt->long_name, arg);
 	} else
-		die("option %s needs an argument (check|on-demand)",
+		die(_("option %s needs an argument (check|on-demand)"),
 				opt->long_name);
 
 	return 0;
diff --git a/transport.c b/transport.c
index 7202b77..1fb92a1 100644
--- a/transport.c
+++ b/transport.c
@@ -14,6 +14,7 @@
 #include "url.h"
 #include "submodule.h"
 #include "string-list.h"
+#include "utf8.h"
 
 /* rsync support */
 
@@ -627,16 +628,23 @@ static void print_ref_status(char flag, const char *summary, struct ref *to, str
 		else
 			fprintf(stdout, "%s\n", summary);
 	} else {
-		fprintf(stderr, " %c %-*s ", flag, TRANSPORT_SUMMARY_WIDTH, summary);
+		int width = TRANSPORT_SUMMARY_WIDTH;
+		const char *localized_summary = _(summary);
+		/*
+		 * Compensate for the invisible bytes in utf-8
+		 * strings. The expression below is guaranteed always
+		 * positive (or zero in case of ascii strings) because
+		 * none of the doublewidth characters are ASCII
+		 * characters.
+		 */
+		width += strlen(localized_summary) - utf8_strwidth(localized_summary);
+		fprintf(stderr, " %c %-*s ", flag, width, localized_summary);
 		if (from)
 			fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
 		else
 			fputs(prettify_refname(to->name), stderr);
-		if (msg) {
-			fputs(" (", stderr);
-			fputs(msg, stderr);
-			fputc(')', stderr);
-		}
+		if (msg)
+			fprintf(stderr, " (%s)", _(msg));
 		fputc('\n', stderr);
 	}
 }
@@ -649,11 +657,11 @@ static const char *status_abbrev(unsigned char sha1[20])
 static void print_ok_ref_status(struct ref *ref, int porcelain)
 {
 	if (ref->deletion)
-		print_ref_status('-', "[deleted]", ref, NULL, NULL, porcelain);
+		print_ref_status('-', N_("[deleted]"), ref, NULL, NULL, porcelain);
 	else if (is_null_sha1(ref->old_sha1))
 		print_ref_status('*',
-			(!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" :
-			"[new branch]"),
+			(!prefixcmp(ref->name, "refs/tags/") ? N_("[new tag]") :
+			 N_("[new branch]")),
 			ref, ref->peer_ref, NULL, porcelain);
 	else {
 		char quickref[84];
@@ -664,7 +672,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain)
 		if (ref->forced_update) {
 			strcat(quickref, "...");
 			type = '+';
-			msg = "forced update";
+			msg = N_("forced update");
 		} else {
 			strcat(quickref, "..");
 			type = ' ';
@@ -678,50 +686,57 @@ static void print_ok_ref_status(struct ref *ref, int porcelain)
 
 static int print_one_push_status(struct ref *ref, const char *dest, int count, int porcelain)
 {
-	if (!count)
-		fprintf(porcelain ? stdout : stderr, "To %s\n", dest);
+	if (!count) {
+		if (porcelain)
+			fprintf(stdout, "To %s\n", dest);
+		else
+			fprintf_ln(stderr, _("To %s"), dest);
+	}
 
 	switch(ref->status) {
 	case REF_STATUS_NONE:
-		print_ref_status('X', "[no match]", ref, NULL, NULL, porcelain);
+		print_ref_status('X', N_("[no match]"), ref, NULL,
+				 NULL, porcelain);
 		break;
 	case REF_STATUS_REJECT_NODELETE:
-		print_ref_status('!', "[rejected]", ref, NULL,
-						 "remote does not support deleting refs", porcelain);
+		print_ref_status('!', N_("[rejected]"), ref, NULL,
+				 N_("remote does not support deleting refs"),
+				 porcelain);
 		break;
 	case REF_STATUS_UPTODATE:
-		print_ref_status('=', "[up to date]", ref,
-						 ref->peer_ref, NULL, porcelain);
+		print_ref_status('=', N_("[up to date]"), ref,
+				 ref->peer_ref, NULL, porcelain);
 		break;
 	case REF_STATUS_REJECT_NONFASTFORWARD:
-		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
-						 "non-fast-forward", porcelain);
+		print_ref_status('!', N_("[rejected]"), ref, ref->peer_ref,
+				 N_("non-fast-forward"), porcelain);
 		break;
 	case REF_STATUS_REJECT_ALREADY_EXISTS:
-		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
-						 "already exists", porcelain);
+		print_ref_status('!', N_("[rejected]"), ref, ref->peer_ref,
+				 N_("already exists"), porcelain);
 		break;
 	case REF_STATUS_REJECT_FETCH_FIRST:
-		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
-						 "fetch first", porcelain);
+		print_ref_status('!', N_("[rejected]"), ref, ref->peer_ref,
+				 N_("fetch first"), porcelain);
 		break;
 	case REF_STATUS_REJECT_NEEDS_FORCE:
-		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
-						 "needs force", porcelain);
+		print_ref_status('!', N_("[rejected]"), ref, ref->peer_ref,
+				 N_("needs force"), porcelain);
 		break;
 	case REF_STATUS_REJECT_STALE:
-		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
-						 "stale info", porcelain);
+		print_ref_status('!', N_("[rejected]"), ref, ref->peer_ref,
+				 N_("stale info"), porcelain);
 		break;
 	case REF_STATUS_REMOTE_REJECT:
-		print_ref_status('!', "[remote rejected]", ref,
-						 ref->deletion ? NULL : ref->peer_ref,
-						 ref->remote_status, porcelain);
+		print_ref_status('!', N_("[remote rejected]"), ref,
+				 ref->deletion ? NULL : ref->peer_ref,
+				 ref->remote_status, porcelain);
 		break;
 	case REF_STATUS_EXPECTING_REPORT:
-		print_ref_status('!', "[remote failure]", ref,
-						 ref->deletion ? NULL : ref->peer_ref,
-						 "remote failed to report status", porcelain);
+		print_ref_status('!', N_("[remote failure]"), ref,
+				 ref->deletion ? NULL : ref->peer_ref,
+				 N_("remote failed to report status"),
+				 porcelain);
 		break;
 	case REF_STATUS_OK:
 		print_ok_ref_status(ref, porcelain);
-- 
1.8.2.83.gc99314b