{"thread":{"id":"30308","subject":"[PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","startedAt":"2012-04-23T12:30:20Z","lastAt":"2012-05-09T12:29:22Z","messageCount":43,"participants":["Nguyễn Thái Ngọc Duy","Jonathan Nieder","Junio C Hamano","Ævar Arnfjörð Bjarmason","Nguyen Thai Ngoc Duy","Johannes Sixt","Zbigniew Jędrzejewski-Szmek"],"isPatch":true,"patchVersion":1,"patchTotal":10},"messages":[{"id":"189864","messageId":"1335184230-8870-1-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":null,"subject":"[PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:20Z","receivedAt":"2012-04-23T12:30:20Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Compared to v1 [1], parseopt patch is taken out. I attempted to\nconvert all struct option, and it turned into a huge series [2]. Not\nsure how to submit that series yet.\n\nApart from that, Makefile is updated to make sure xgettext scan all\nfiles, including header files. fprintf_ln() now uses fputc (so do a\nfew other places). About 4 more sentences in plural forms are detected\nand converted to Q_().\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/195623\n[2] https://github.com/pclouds/git/tree/parseopt-i18n\n\nJonathan Nieder (1):\n  i18n: mark relative dates for translation\n\nNguyễn Thái Ngọc Duy (9):\n  Makefile: feed all header files to xgettext\n  Add three convenient format printing functions with \\n automatically\n    appended\n  i18n: help: mark strings for translation\n  i18n: make warn_dangling_symref() automatically append \\n\n  i18n: remote: mark strings for translation\n  i18n: apply: mark strings for translation\n  i18n: apply: update say_patch_name to give translators complete\n    sentence\n  i18n: index-pack: mark strings for translation\n  i18n: bundle: mark strings for translation\n\n Makefile             |   49 +++++++----\n builtin/apply.c      |  206 ++++++++++++++++++++++++---------------------\n builtin/fetch.c      |    4 +-\n builtin/help.c       |   48 +++++-----\n builtin/index-pack.c |  125 +++++++++++++++-------------\n builtin/remote.c     |  227 +++++++++++++++++++++++++++-----------------------\n bundle.c             |   38 +++++----\n cache.h              |    6 +-\n date.c               |   95 ++++++++++++---------\n generate-cmdlist.sh  |    2 +-\n git.c                |    2 +-\n help.c               |   32 +++++---\n refs.c               |    1 +\n strbuf.c             |   33 +++++++\n strbuf.h             |    7 ++\n test-date.c          |    7 +-\n 16 files changed, 504 insertions(+), 378 deletions(-)\n\n-- \n1.7.8.36.g69ee2\n"},{"id":"189865","messageId":"1335184230-8870-2-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 01/10] Makefile: feed all header files to xgettext","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:21Z","receivedAt":"2012-04-23T12:30:21Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Translation markers may be present in header files too. Make sure we\ndon't miss any.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Makefile |   48 +++++++++++++++++++++++++++++++-----------------\n 1 files changed, 31 insertions(+), 17 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex be1957a..dab7362 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -386,6 +386,7 @@ XDIFF_OBJS =\n VCSSVN_H =\n VCSSVN_OBJS =\n VCSSVN_TEST_OBJS =\n+MISC_H =\n EXTRA_CPPFLAGS =\n LIB_H =\n LIB_OBJS =\n@@ -543,6 +544,35 @@ LIB_FILE=libgit.a\n XDIFF_LIB=xdiff/lib.a\n VCSSVN_LIB=vcs-svn/lib.a\n \n+XDIFF_H += xdiff/xinclude.h\n+XDIFF_H += xdiff/xmacros.h\n+XDIFF_H += xdiff/xdiff.h\n+XDIFF_H += xdiff/xtypes.h\n+XDIFF_H += xdiff/xutils.h\n+XDIFF_H += xdiff/xprepare.h\n+XDIFF_H += xdiff/xdiffi.h\n+XDIFF_H += xdiff/xemit.h\n+\n+VCSSVN_H += vcs-svn/line_buffer.h\n+VCSSVN_H += vcs-svn/sliding_window.h\n+VCSSVN_H += vcs-svn/repo_tree.h\n+VCSSVN_H += vcs-svn/fast_export.h\n+VCSSVN_H += vcs-svn/svndiff.h\n+VCSSVN_H += vcs-svn/svndump.h\n+\n+MISC_H += branch.h\n+MISC_H += bundle.h\n+MISC_H += bisect.h\n+MISC_H += fetch-pack.h\n+MISC_H += thread-utils.h\n+MISC_H += send-pack.h\n+MISC_H += shortlog.h\n+MISC_H += reachable.h\n+MISC_H += wt-status.h\n+MISC_H += tar.h\n+MISC_H += url.h\n+MISC_H += walker.h\n+\n LIB_H += advice.h\n LIB_H += archive.h\n LIB_H += argv-array.h\n@@ -2170,24 +2200,8 @@ connect.o transport.o url.o http-backend.o: url.h\n http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h\n http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h\n \n-XDIFF_H += xdiff/xinclude.h\n-XDIFF_H += xdiff/xmacros.h\n-XDIFF_H += xdiff/xdiff.h\n-XDIFF_H += xdiff/xtypes.h\n-XDIFF_H += xdiff/xutils.h\n-XDIFF_H += xdiff/xprepare.h\n-XDIFF_H += xdiff/xdiffi.h\n-XDIFF_H += xdiff/xemit.h\n-\n xdiff-interface.o $(XDIFF_OBJS): $(XDIFF_H)\n \n-VCSSVN_H += vcs-svn/line_buffer.h\n-VCSSVN_H += vcs-svn/sliding_window.h\n-VCSSVN_H += vcs-svn/repo_tree.h\n-VCSSVN_H += vcs-svn/fast_export.h\n-VCSSVN_H += vcs-svn/svndiff.h\n-VCSSVN_H += vcs-svn/svndump.h\n-\n $(VCSSVN_OBJS) $(VCSSVN_TEST_OBJS): $(LIB_H) $(VCSSVN_H)\n endif\n \n@@ -2282,7 +2296,7 @@ XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \\\n \t--keyword=_ --keyword=N_ --keyword=\"Q_:1,2\"\n XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell\n XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl\n-LOCALIZED_C := $(C_OBJ:o=c)\n+LOCALIZED_C := $(C_OBJ:o=c) $(LIB_H) $(XDIFF_H) $(VCSSVN_H) $(MISC_H)\n LOCALIZED_SH := $(SCRIPT_SH)\n LOCALIZED_PERL := $(SCRIPT_PERL)\n \n-- \n1.7.8.36.g69ee2\n"},{"id":"189866","messageId":"1335184230-8870-3-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 02/10] Add three convenient format printing functions with \\n automatically appended","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:22Z","receivedAt":"2012-04-23T12:30:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"These functions are helpful when we do not want to expose \\n to\ntranslators. For example\n\n    printf(\"hello world\\n\");\n\ncan be converted to\n\n    printf_ln(_(\"hello world\"));\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n strbuf.c |   33 +++++++++++++++++++++++++++++++++\n strbuf.h |    7 +++++++\n 2 files changed, 40 insertions(+), 0 deletions(-)\n\ndiff --git a/strbuf.c b/strbuf.c\nindex 5135d59..82d1fa2 100644\n--- a/strbuf.c\n+++ b/strbuf.c\n@@ -464,3 +464,36 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,\n {\n \tstrbuf_add_urlencode(sb, s, strlen(s), reserved);\n }\n+\n+void strbuf_addf_ln(struct strbuf *sb, const char *fmt, ...)\n+{\n+\tva_list ap;\n+\tva_start(ap, fmt);\n+\tstrbuf_vaddf(sb, fmt, ap);\n+\tva_end(ap);\n+\tstrbuf_addch(sb, '\\n');\n+}\n+\n+int printf_ln(const char *fmt, ...)\n+{\n+\tint ret;\n+\tva_list ap;\n+\tva_start(ap, fmt);\n+\tret = vprintf(fmt, ap);\n+\tva_end(ap);\n+\tif (ret >= 0)\n+\t\tret += printf(\"\\n\");\n+\treturn ret;\n+}\n+\n+int fprintf_ln(FILE *fp, const char *fmt, ...)\n+{\n+\tint ret;\n+\tva_list ap;\n+\tva_start(ap, fmt);\n+\tret = vfprintf(fp, fmt, ap);\n+\tva_end(ap);\n+\tif (ret >= 0 && fputc('\\n', fp) != EOF)\n+\t\tret++;\n+\treturn ret;\n+}\ndiff --git a/strbuf.h b/strbuf.h\nindex 3effaa8..b888d40 100644\n--- a/strbuf.h\n+++ b/strbuf.h\n@@ -99,6 +99,8 @@ __attribute__((format (printf,2,3)))\n extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);\n __attribute__((format (printf,2,0)))\n extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);\n+__attribute__((format (printf,2,3)))\n+extern void strbuf_addf_ln(struct strbuf *sb, const char *fmt, ...);\n \n extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);\n \n@@ -129,4 +131,9 @@ extern void strbuf_add_urlencode(struct strbuf *, const char *, size_t,\n extern void strbuf_addstr_urlencode(struct strbuf *, const char *,\n \t\t\t\t    int reserved);\n \n+__attribute__((format (printf,1,2)))\n+extern int printf_ln(const char *fmt, ...);\n+__attribute__((format (printf,2,3)))\n+extern int fprintf_ln(FILE *fp, const char *fmt, ...);\n+\n #endif /* STRBUF_H */\n-- \n1.7.8.36.g69ee2\n"},{"id":"189867","messageId":"1335184230-8870-4-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 03/10] i18n: mark relative dates for translation","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:23Z","receivedAt":"2012-04-23T12:30:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Jonathan Nieder <jrnieder@gmail.com>\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h     |    6 +--\n date.c      |   95 ++++++++++++++++++++++++++++++++++------------------------\n test-date.c |    7 ++--\n 3 files changed, 62 insertions(+), 46 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex a8aceb5..aa9f8f9 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -906,10 +906,8 @@ enum date_mode {\n };\n \n const char *show_date(unsigned long time, int timezone, enum date_mode mode);\n-const char *show_date_relative(unsigned long time, int tz,\n-\t\t\t       const struct timeval *now,\n-\t\t\t       char *timebuf,\n-\t\t\t       size_t timebuf_size);\n+void show_date_relative(unsigned long time, int tz, const struct timeval *now,\n+\t\t\tstruct strbuf *timebuf);\n int parse_date(const char *date, char *buf, int bufsize);\n int parse_date_basic(const char *date, unsigned long *timestamp, int *offset);\n void datestamp(char *buf, int bufsize);\ndiff --git a/date.c b/date.c\nindex a5055ca..1fdcf7c 100644\n--- a/date.c\n+++ b/date.c\n@@ -86,83 +86,98 @@ static int local_tzoffset(unsigned long time)\n \treturn offset * eastwest;\n }\n \n-const char *show_date_relative(unsigned long time, int tz,\n+void show_date_relative(unsigned long time, int tz,\n \t\t\t       const struct timeval *now,\n-\t\t\t       char *timebuf,\n-\t\t\t       size_t timebuf_size)\n+\t\t\t       struct strbuf *timebuf)\n {\n \tunsigned long diff;\n-\tif (now->tv_sec < time)\n-\t\treturn \"in the future\";\n+\tif (now->tv_sec < time) {\n+\t\tstrbuf_addstr(timebuf, _(\"in the future\"));\n+\t\treturn;\n+\t}\n \tdiff = now->tv_sec - time;\n \tif (diff < 90) {\n-\t\tsnprintf(timebuf, timebuf_size, \"%lu seconds ago\", diff);\n-\t\treturn timebuf;\n+\t\tstrbuf_addf(timebuf,\n+\t\t\t Q_(\"%lu second ago\", \"%lu seconds ago\", diff), diff);\n+\t\treturn;\n \t}\n \t/* Turn it into minutes */\n \tdiff = (diff + 30) / 60;\n \tif (diff < 90) {\n-\t\tsnprintf(timebuf, timebuf_size, \"%lu minutes ago\", diff);\n-\t\treturn timebuf;\n+\t\tstrbuf_addf(timebuf,\n+\t\t\t Q_(\"%lu minute ago\", \"%lu minutes ago\", diff), diff);\n+\t\treturn;\n \t}\n \t/* Turn it into hours */\n \tdiff = (diff + 30) / 60;\n \tif (diff < 36) {\n-\t\tsnprintf(timebuf, timebuf_size, \"%lu hours ago\", diff);\n-\t\treturn timebuf;\n+\t\tstrbuf_addf(timebuf,\n+\t\t\t Q_(\"%lu hour ago\", \"%lu hours ago\", diff), diff);\n+\t\treturn;\n \t}\n \t/* We deal with number of days from here on */\n \tdiff = (diff + 12) / 24;\n \tif (diff < 14) {\n-\t\tsnprintf(timebuf, timebuf_size, \"%lu days ago\", diff);\n-\t\treturn timebuf;\n+\t\tstrbuf_addf(timebuf,\n+\t\t\t Q_(\"%lu day ago\", \"%lu days ago\", diff), diff);\n+\t\treturn;\n \t}\n \t/* Say weeks for the past 10 weeks or so */\n \tif (diff < 70) {\n-\t\tsnprintf(timebuf, timebuf_size, \"%lu weeks ago\", (diff + 3) / 7);\n-\t\treturn timebuf;\n+\t\tstrbuf_addf(timebuf,\n+\t\t\t Q_(\"%lu week ago\", \"%lu weeks ago\", (diff + 3) / 7),\n+\t\t\t (diff + 3) / 7);\n+\t\treturn;\n \t}\n \t/* Say months for the past 12 months or so */\n \tif (diff < 365) {\n-\t\tsnprintf(timebuf, timebuf_size, \"%lu months ago\", (diff + 15) / 30);\n-\t\treturn timebuf;\n+\t\tstrbuf_addf(timebuf,\n+\t\t\t Q_(\"%lu month ago\", \"%lu months ago\", (diff + 15) / 30),\n+\t\t\t (diff + 15) / 30);\n+\t\treturn;\n \t}\n \t/* Give years and months for 5 years or so */\n \tif (diff < 1825) {\n \t\tunsigned long totalmonths = (diff * 12 * 2 + 365) / (365 * 2);\n \t\tunsigned long years = totalmonths / 12;\n \t\tunsigned long months = totalmonths % 12;\n-\t\tint n;\n-\t\tn = snprintf(timebuf, timebuf_size, \"%lu year%s\",\n-\t\t\t\tyears, (years > 1 ? \"s\" : \"\"));\n-\t\tif (months)\n-\t\t\tsnprintf(timebuf + n, timebuf_size - n,\n-\t\t\t\t\t\", %lu month%s ago\",\n-\t\t\t\t\tmonths, (months > 1 ? \"s\" : \"\"));\n-\t\telse\n-\t\t\tsnprintf(timebuf + n, timebuf_size - n, \" ago\");\n-\t\treturn timebuf;\n+\t\tif (months) {\n+\t\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\t\tstrbuf_addf(&sb, Q_(\"%lu year\", \"%lu years\", years), years);\n+\t\t\t/* TRANSLATORS: \"%s\" is \"<n> years\" */\n+\t\t\tstrbuf_addf(timebuf,\n+\t\t\t\t Q_(\"%s, %lu month ago\", \"%s, %lu months ago\", months),\n+\t\t\t\t sb.buf, months);\n+\t\t\tstrbuf_release(&sb);\n+\t\t} else\n+\t\t\tstrbuf_addf(timebuf,\n+\t\t\t\t Q_(\"%lu year ago\", \"%lu years ago\", years), years);\n+\t\treturn;\n \t}\n \t/* Otherwise, just years. Centuries is probably overkill. */\n-\tsnprintf(timebuf, timebuf_size, \"%lu years ago\", (diff + 183) / 365);\n-\treturn timebuf;\n+\tstrbuf_addf(timebuf,\n+\t\t Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n+\t\t (diff + 183) / 365);\n }\n \n const char *show_date(unsigned long time, int tz, enum date_mode mode)\n {\n \tstruct tm *tm;\n-\tstatic char timebuf[200];\n+\tstatic struct strbuf timebuf = STRBUF_INIT;\n \n \tif (mode == DATE_RAW) {\n-\t\tsnprintf(timebuf, sizeof(timebuf), \"%lu %+05d\", time, tz);\n-\t\treturn timebuf;\n+\t\tstrbuf_reset(&timebuf);\n+\t\tstrbuf_addf(&timebuf, \"%lu %+05d\", time, tz);\n+\t\treturn timebuf.buf;\n \t}\n \n \tif (mode == DATE_RELATIVE) {\n \t\tstruct timeval now;\n+\n+\t\tstrbuf_reset(&timebuf);\n \t\tgettimeofday(&now, NULL);\n-\t\treturn show_date_relative(time, tz, &now,\n-\t\t\t\t\t  timebuf, sizeof(timebuf));\n+\t\tshow_date_relative(time, tz, &now, &timebuf);\n+\t\treturn timebuf.buf;\n \t}\n \n \tif (mode == DATE_LOCAL)\n@@ -171,23 +186,25 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)\n \ttm = time_to_tm(time, tz);\n \tif (!tm)\n \t\treturn NULL;\n+\n+\tstrbuf_reset(&timebuf);\n \tif (mode == DATE_SHORT)\n-\t\tsprintf(timebuf, \"%04d-%02d-%02d\", tm->tm_year + 1900,\n+\t\tstrbuf_addf(&timebuf, \"%04d-%02d-%02d\", tm->tm_year + 1900,\n \t\t\t\ttm->tm_mon + 1, tm->tm_mday);\n \telse if (mode == DATE_ISO8601)\n-\t\tsprintf(timebuf, \"%04d-%02d-%02d %02d:%02d:%02d %+05d\",\n+\t\tstrbuf_addf(&timebuf, \"%04d-%02d-%02d %02d:%02d:%02d %+05d\",\n \t\t\t\ttm->tm_year + 1900,\n \t\t\t\ttm->tm_mon + 1,\n \t\t\t\ttm->tm_mday,\n \t\t\t\ttm->tm_hour, tm->tm_min, tm->tm_sec,\n \t\t\t\ttz);\n \telse if (mode == DATE_RFC2822)\n-\t\tsprintf(timebuf, \"%.3s, %d %.3s %d %02d:%02d:%02d %+05d\",\n+\t\tstrbuf_addf(&timebuf, \"%.3s, %d %.3s %d %02d:%02d:%02d %+05d\",\n \t\t\tweekday_names[tm->tm_wday], tm->tm_mday,\n \t\t\tmonth_names[tm->tm_mon], tm->tm_year + 1900,\n \t\t\ttm->tm_hour, tm->tm_min, tm->tm_sec, tz);\n \telse\n-\t\tsprintf(timebuf, \"%.3s %.3s %d %02d:%02d:%02d %d%c%+05d\",\n+\t\tstrbuf_addf(&timebuf, \"%.3s %.3s %d %02d:%02d:%02d %d%c%+05d\",\n \t\t\t\tweekday_names[tm->tm_wday],\n \t\t\t\tmonth_names[tm->tm_mon],\n \t\t\t\ttm->tm_mday,\n@@ -195,7 +212,7 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)\n \t\t\t\ttm->tm_year + 1900,\n \t\t\t\t(mode == DATE_LOCAL) ? 0 : ' ',\n \t\t\t\ttz);\n-\treturn timebuf;\n+\treturn timebuf.buf;\n }\n \n /*\ndiff --git a/test-date.c b/test-date.c\nindex 6bcd5b0..10afaab 100644\n--- a/test-date.c\n+++ b/test-date.c\n@@ -7,13 +7,14 @@ static const char *usage_msg = \"\\n\"\n \n static void show_dates(char **argv, struct timeval *now)\n {\n-\tchar buf[128];\n+\tstruct strbuf buf = STRBUF_INIT;\n \n \tfor (; *argv; argv++) {\n \t\ttime_t t = atoi(*argv);\n-\t\tshow_date_relative(t, 0, now, buf, sizeof(buf));\n-\t\tprintf(\"%s -> %s\\n\", *argv, buf);\n+\t\tshow_date_relative(t, 0, now, &buf);\n+\t\tprintf(\"%s -> %s\\n\", *argv, buf.buf);\n \t}\n+\tstrbuf_release(&buf);\n }\n \n static void parse_dates(char **argv, struct timeval *now)\n-- \n1.7.8.36.g69ee2\n"},{"id":"189868","messageId":"1335184230-8870-5-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 04/10] i18n: help: mark strings for translation","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:24Z","receivedAt":"2012-04-23T12:30:24Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This patch also marks most common commands' synopsis for translation\nso that \"git help\" gives a friendly listing.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Makefile            |    1 +\n builtin/help.c      |   48 ++++++++++++++++++++++++------------------------\n generate-cmdlist.sh |    2 +-\n git.c               |    2 +-\n help.c              |   32 ++++++++++++++++++++------------\n 5 files changed, 47 insertions(+), 38 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex dab7362..39a3c6b 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -563,6 +563,7 @@ VCSSVN_H += vcs-svn/svndump.h\n MISC_H += branch.h\n MISC_H += bundle.h\n MISC_H += bisect.h\n+MISC_H += common-cmds.h\n MISC_H += fetch-pack.h\n MISC_H += thread-utils.h\n MISC_H += send-pack.h\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 61ff798..96a462c 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -54,7 +54,7 @@ static enum help_format parse_help_format(const char *format)\n \t\treturn HELP_FORMAT_INFO;\n \tif (!strcmp(format, \"web\") || !strcmp(format, \"html\"))\n \t\treturn HELP_FORMAT_WEB;\n-\tdie(\"unrecognized help format '%s'\", format);\n+\tdie(_(\"unrecognized help format '%s'\"), format);\n }\n \n static const char *get_man_viewer_info(const char *name)\n@@ -82,7 +82,7 @@ static int check_emacsclient_version(void)\n \tec_process.err = -1;\n \tec_process.stdout_to_stderr = 1;\n \tif (start_command(&ec_process))\n-\t\treturn error(\"Failed to start emacsclient.\");\n+\t\treturn error(_(\"Failed to start emacsclient.\"));\n \n \tstrbuf_read(&buffer, ec_process.err, 20);\n \tclose(ec_process.err);\n@@ -95,7 +95,7 @@ static int check_emacsclient_version(void)\n \n \tif (prefixcmp(buffer.buf, \"emacsclient\")) {\n \t\tstrbuf_release(&buffer);\n-\t\treturn error(\"Failed to parse emacsclient version.\");\n+\t\treturn error(_(\"Failed to parse emacsclient version.\"));\n \t}\n \n \tstrbuf_remove(&buffer, 0, strlen(\"emacsclient\"));\n@@ -103,7 +103,7 @@ static int check_emacsclient_version(void)\n \n \tif (version < 22) {\n \t\tstrbuf_release(&buffer);\n-\t\treturn error(\"emacsclient version '%d' too old (< 22).\",\n+\t\treturn error(_(\"emacsclient version '%d' too old (< 22).\"),\n \t\t\tversion);\n \t}\n \n@@ -121,7 +121,7 @@ static void exec_woman_emacs(const char *path, const char *page)\n \t\t\tpath = \"emacsclient\";\n \t\tstrbuf_addf(&man_page, \"(woman \\\"%s\\\")\", page);\n \t\texeclp(path, \"emacsclient\", \"-e\", man_page.buf, (char *)NULL);\n-\t\twarning(\"failed to exec '%s': %s\", path, strerror(errno));\n+\t\twarning(_(\"failed to exec '%s': %s\"), path, strerror(errno));\n \t}\n }\n \n@@ -149,7 +149,7 @@ static void exec_man_konqueror(const char *path, const char *page)\n \t\t\tpath = \"kfmclient\";\n \t\tstrbuf_addf(&man_page, \"man:%s(1)\", page);\n \t\texeclp(path, filename, \"newTab\", man_page.buf, (char *)NULL);\n-\t\twarning(\"failed to exec '%s': %s\", path, strerror(errno));\n+\t\twarning(_(\"failed to exec '%s': %s\"), path, strerror(errno));\n \t}\n }\n \n@@ -158,7 +158,7 @@ static void exec_man_man(const char *path, const char *page)\n \tif (!path)\n \t\tpath = \"man\";\n \texeclp(path, \"man\", page, (char *)NULL);\n-\twarning(\"failed to exec '%s': %s\", path, strerror(errno));\n+\twarning(_(\"failed to exec '%s': %s\"), path, strerror(errno));\n }\n \n static void exec_man_cmd(const char *cmd, const char *page)\n@@ -166,7 +166,7 @@ static void exec_man_cmd(const char *cmd, const char *page)\n \tstruct strbuf shell_cmd = STRBUF_INIT;\n \tstrbuf_addf(&shell_cmd, \"%s %s\", cmd, page);\n \texecl(\"/bin/sh\", \"sh\", \"-c\", shell_cmd.buf, (char *)NULL);\n-\twarning(\"failed to exec '%s': %s\", cmd, strerror(errno));\n+\twarning(_(\"failed to exec '%s': %s\"), cmd, strerror(errno));\n }\n \n static void add_man_viewer(const char *name)\n@@ -206,8 +206,8 @@ static int add_man_viewer_path(const char *name,\n \tif (supported_man_viewer(name, len))\n \t\tdo_add_man_viewer_info(name, len, value);\n \telse\n-\t\twarning(\"'%s': path for unsupported man viewer.\\n\"\n-\t\t\t\"Please consider using 'man.<tool>.cmd' instead.\",\n+\t\twarning(_(\"'%s': path for unsupported man viewer.\\n\"\n+\t\t\t  \"Please consider using 'man.<tool>.cmd' instead.\"),\n \t\t\tname);\n \n \treturn 0;\n@@ -218,8 +218,8 @@ static int add_man_viewer_cmd(const char *name,\n \t\t\t      const char *value)\n {\n \tif (supported_man_viewer(name, len))\n-\t\twarning(\"'%s': cmd for supported man viewer.\\n\"\n-\t\t\t\"Please consider using 'man.<tool>.path' instead.\",\n+\t\twarning(_(\"'%s': cmd for supported man viewer.\\n\"\n+\t\t\t  \"Please consider using 'man.<tool>.path' instead.\"),\n \t\t\tname);\n \telse\n \t\tdo_add_man_viewer_info(name, len, value);\n@@ -280,11 +280,11 @@ void list_common_cmds_help(void)\n \t\t\tlongest = strlen(common_cmds[i].name);\n \t}\n \n-\tputs(\"The most commonly used git commands are:\");\n+\tputs(_(\"The most commonly used git commands are:\"));\n \tfor (i = 0; i < ARRAY_SIZE(common_cmds); i++) {\n \t\tprintf(\"   %s   \", common_cmds[i].name);\n \t\tmput_char(' ', longest - strlen(common_cmds[i].name));\n-\t\tputs(common_cmds[i].help);\n+\t\tputs(_(common_cmds[i].help));\n \t}\n }\n \n@@ -348,7 +348,7 @@ static void exec_viewer(const char *name, const char *page)\n \telse if (info)\n \t\texec_man_cmd(info, page);\n \telse\n-\t\twarning(\"'%s': unknown man viewer.\", name);\n+\t\twarning(_(\"'%s': unknown man viewer.\"), name);\n }\n \n static void show_man_page(const char *git_cmd)\n@@ -365,7 +365,7 @@ static void show_man_page(const char *git_cmd)\n \tif (fallback)\n \t\texec_viewer(fallback, page);\n \texec_viewer(\"man\", page);\n-\tdie(\"no man viewer handled the request\");\n+\tdie(_(\"no man viewer handled the request\"));\n }\n \n static void show_info_page(const char *git_cmd)\n@@ -373,7 +373,7 @@ static void show_info_page(const char *git_cmd)\n \tconst char *page = cmd_to_page(git_cmd);\n \tsetenv(\"INFOPATH\", system_path(GIT_INFO_PATH), 1);\n \texeclp(\"info\", \"info\", \"gitman\", page, (char *)NULL);\n-\tdie(\"no info viewer handled the request\");\n+\tdie(_(\"no info viewer handled the request\"));\n }\n \n static void get_html_page_path(struct strbuf *page_path, const char *page)\n@@ -384,7 +384,7 @@ static void get_html_page_path(struct strbuf *page_path, const char *page)\n \t/* Check that we have a git documentation directory. */\n \tif (stat(mkpath(\"%s/git.html\", html_path), &st)\n \t    || !S_ISREG(st.st_mode))\n-\t\tdie(\"'%s': not a documentation directory.\", html_path);\n+\t\tdie(_(\"'%s': not a documentation directory.\"), html_path);\n \n \tstrbuf_init(page_path, 0);\n \tstrbuf_addf(page_path, \"%s/%s.html\", html_path, page);\n@@ -424,16 +424,16 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \tparsed_help_format = help_format;\n \n \tif (show_all) {\n-\t\tprintf(\"usage: %s\\n\\n\", git_usage_string);\n-\t\tlist_commands(\"git commands\", &main_cmds, &other_cmds);\n-\t\tprintf(\"%s\\n\", git_more_info_string);\n+\t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n+\t\tlist_commands(_(\"git commands\"), &main_cmds, &other_cmds);\n+\t\tprintf(\"%s\\n\", _(git_more_info_string));\n \t\treturn 0;\n \t}\n \n \tif (!argv[0]) {\n-\t\tprintf(\"usage: %s\\n\\n\", git_usage_string);\n+\t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n \t\tlist_common_cmds_help();\n-\t\tprintf(\"\\n%s\\n\", git_more_info_string);\n+\t\tprintf(\"\\n%s\\n\", _(git_more_info_string));\n \t\treturn 0;\n \t}\n \n@@ -445,7 +445,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \n \talias = alias_lookup(argv[0]);\n \tif (alias && !is_git_command(argv[0])) {\n-\t\tprintf(\"`git %s' is aliased to `%s'\\n\", argv[0], alias);\n+\t\tprintf_ln(_(\"`git %s' is aliased to `%s'\"), argv[0], alias);\n \t\treturn 0;\n \t}\n \ndiff --git a/generate-cmdlist.sh b/generate-cmdlist.sh\nindex 1093ef4..9a4c9b9 100755\n--- a/generate-cmdlist.sh\n+++ b/generate-cmdlist.sh\n@@ -16,7 +16,7 @@ do\n      /^NAME/,/git-'\"$cmd\"'/H\n      ${\n \t    x\n-\t    s/.*git-'\"$cmd\"' - \\(.*\\)/  {\"'\"$cmd\"'\", \"\\1\"},/\n+\t    s/.*git-'\"$cmd\"' - \\(.*\\)/  {\"'\"$cmd\"'\", N_(\"\\1\")},/\n \t    p\n      }' \"Documentation/git-$cmd.txt\"\n done\ndiff --git a/git.c b/git.c\nindex 3805616..4486deb 100644\n--- a/git.c\n+++ b/git.c\n@@ -13,7 +13,7 @@ const char git_usage_string[] =\n \t\"           <command> [<args>]\";\n \n const char git_more_info_string[] =\n-\t\"See 'git help <command>' for more information on a specific command.\";\n+\tN_(\"See 'git help <command>' for more information on a specific command.\");\n \n static struct startup_info git_startup_info;\n static int use_pager = -1;\ndiff --git a/help.c b/help.c\nindex 14eefc9..9e6e0f2 100644\n--- a/help.c\n+++ b/help.c\n@@ -217,8 +217,9 @@ void list_commands(const char *title, struct cmdnames *main_cmds,\n \n \tif (main_cmds->cnt) {\n \t\tconst char *exec_path = git_exec_path();\n-\t\tprintf(\"available %s in '%s'\\n\", title, exec_path);\n-\t\tprintf(\"----------------\");\n+\t\tprintf_ln(_(\"available %s in '%s'\"), title, exec_path);\n+\t\t/* TRANSLATORS: this must align with \"available %s in '%s'\" */\n+\t\tprintf(_(\"----------------\"));\n \t\tmput_char('-', strlen(title) + strlen(exec_path));\n \t\tputchar('\\n');\n \t\tpretty_print_string_list(main_cmds, longest);\n@@ -226,8 +227,12 @@ void list_commands(const char *title, struct cmdnames *main_cmds,\n \t}\n \n \tif (other_cmds->cnt) {\n-\t\tprintf(\"%s available from elsewhere on your $PATH\\n\", title);\n-\t\tprintf(\"---------------------------------------\");\n+\t\tprintf_ln(_(\"%s available from elsewhere on your $PATH\"), title);\n+\t\t/* TRANSLATORS:\n+\t\t * this must align with\n+\t\t * \"%s available from elsewhere on your $PATH\"\n+\t\t */\n+\t\tprintf(_(\"---------------------------------------\"));\n \t\tmput_char('-', strlen(title));\n \t\tputchar('\\n');\n \t\tpretty_print_string_list(other_cmds, longest);\n@@ -341,7 +346,7 @@ const char *help_unknown_cmd(const char *cmd)\n \t      sizeof(*main_cmds.names), levenshtein_compare);\n \n \tif (!main_cmds.cnt)\n-\t\tdie (\"Uh oh. Your system reports no Git commands at all.\");\n+\t\tdie(_(\"Uh oh. Your system reports no Git commands at all.\"));\n \n \t/* skip and count prefix matches */\n \tfor (n = 0; n < main_cmds.cnt && !main_cmds.names[n]->len; n++)\n@@ -362,23 +367,26 @@ const char *help_unknown_cmd(const char *cmd)\n \t\tconst char *assumed = main_cmds.names[0]->name;\n \t\tmain_cmds.names[0] = NULL;\n \t\tclean_cmdnames(&main_cmds);\n-\t\tfprintf(stderr, \"WARNING: You called a Git command named '%s', \"\n-\t\t\t\"which does not exist.\\n\"\n-\t\t\t\"Continuing under the assumption that you meant '%s'\\n\",\n+\t\tfprintf_ln(stderr,\n+\t\t\t   _(\"WARNING: You called a Git command named '%s', \"\n+\t\t\t     \"which does not exist.\\n\"\n+\t\t\t     \"Continuing under the assumption that you meant '%s'\"),\n \t\t\tcmd, assumed);\n \t\tif (autocorrect > 0) {\n-\t\t\tfprintf(stderr, \"in %0.1f seconds automatically...\\n\",\n+\t\t\tfprintf_ln(stderr, _(\"in %0.1f seconds automatically...\"),\n \t\t\t\t(float)autocorrect/10.0);\n \t\t\tpoll(NULL, 0, autocorrect * 100);\n \t\t}\n \t\treturn assumed;\n \t}\n \n-\tfprintf(stderr, \"git: '%s' is not a git command. See 'git --help'.\\n\", cmd);\n+\tfprintf_ln(stderr, _(\"git: '%s' is not a git command. See 'git --help'.\"), cmd);\n \n \tif (SIMILAR_ENOUGH(best_similarity)) {\n-\t\tfprintf(stderr, \"\\nDid you mean %s?\\n\",\n-\t\t\tn < 2 ? \"this\": \"one of these\");\n+\t\tfprintf_ln(stderr,\n+\t\t\t   Q_(\"\\nDid you mean this?\",\n+\t\t\t      \"\\nDid you mean one of these?\",\n+\t\t\t   n));\n \n \t\tfor (i = 0; i < n; i++)\n \t\t\tfprintf(stderr, \"\\t%s\\n\", main_cmds.names[i]->name);\n-- \n1.7.8.36.g69ee2\n"},{"id":"189869","messageId":"1335184230-8870-6-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 05/10] i18n: make warn_dangling_symref() automatically append \\n","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:25Z","receivedAt":"2012-04-23T12:30:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This helps remove \\n from translatable strings\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/fetch.c  |    4 ++--\n builtin/remote.c |    4 ++--\n refs.c           |    1 +\n 3 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 65f5f9b..a8c3e4c 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -537,8 +537,8 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)\n \tint result = 0;\n \tstruct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);\n \tconst char *dangling_msg = dry_run\n-\t\t? _(\"   (%s will become dangling)\\n\")\n-\t\t: _(\"   (%s has become dangling)\\n\");\n+\t\t? _(\"   (%s will become dangling)\")\n+\t\t: _(\"   (%s has become dangling)\");\n \n \tfor (ref = stale_refs; ref; ref = ref->next) {\n \t\tif (!dry_run)\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex fec92bc..1b03473 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -1260,8 +1260,8 @@ static int prune_remote(const char *remote, int dry_run)\n \tint result = 0, i;\n \tstruct ref_states states;\n \tconst char *dangling_msg = dry_run\n-\t\t? \" %s will become dangling!\\n\"\n-\t\t: \" %s has become dangling!\\n\";\n+\t\t? \" %s will become dangling!\"\n+\t\t: \" %s has become dangling!\";\n \n \tmemset(&states, 0, sizeof(states));\n \tget_remote_ref_states(remote, &states, GET_REF_STATES);\ndiff --git a/refs.c b/refs.c\nindex c9f6835..052c2f6 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -395,6 +395,7 @@ static int warn_if_dangling_symref(const char *refname, const unsigned char *sha\n \t\treturn 0;\n \n \tfprintf(d->fp, d->msg_fmt, refname);\n+\tfputc('\\n', d->fp);\n \treturn 0;\n }\n \n-- \n1.7.8.36.g69ee2\n"},{"id":"189870","messageId":"1335184230-8870-7-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 06/10] i18n: remote: mark strings for translation","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:26Z","receivedAt":"2012-04-23T12:30:26Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/remote.c |  227 +++++++++++++++++++++++++++++-------------------------\n 1 files changed, 121 insertions(+), 106 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 1b03473..51434fa 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -95,9 +95,9 @@ static int fetch_remote(const char *name)\n \t\targv[1] = \"-v\";\n \t\targv[2] = name;\n \t}\n-\tprintf(\"Updating %s\\n\", name);\n+\tprintf_ln(_(\"Updating %s\"), name);\n \tif (run_command_v_opt(argv, RUN_GIT_CMD))\n-\t\treturn error(\"Could not fetch %s\", name);\n+\t\treturn error(_(\"Could not fetch %s\"), name);\n \treturn 0;\n }\n \n@@ -127,8 +127,8 @@ static int add_branch(const char *key, const char *branchname,\n }\n \n static const char mirror_advice[] =\n-\"--mirror is dangerous and deprecated; please\\n\"\n-\"\\t use --mirror=fetch or --mirror=push instead\";\n+N_(\"--mirror is dangerous and deprecated; please\\n\"\n+   \"\\t use --mirror=fetch or --mirror=push instead\");\n \n static int parse_mirror_opt(const struct option *opt, const char *arg, int not)\n {\n@@ -136,7 +136,7 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)\n \tif (not)\n \t\t*mirror = MIRROR_NONE;\n \telse if (!arg) {\n-\t\twarning(\"%s\", mirror_advice);\n+\t\twarning(\"%s\", _(mirror_advice));\n \t\t*mirror = MIRROR_BOTH;\n \t}\n \telse if (!strcmp(arg, \"fetch\"))\n@@ -144,7 +144,7 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)\n \telse if (!strcmp(arg, \"push\"))\n \t\t*mirror = MIRROR_PUSH;\n \telse\n-\t\treturn error(\"unknown mirror argument: %s\", arg);\n+\t\treturn error(_(\"unknown mirror argument: %s\"), arg);\n \treturn 0;\n }\n \n@@ -182,9 +182,9 @@ static int add(int argc, const char **argv)\n \t\tusage_with_options(builtin_remote_add_usage, options);\n \n \tif (mirror && master)\n-\t\tdie(\"specifying a master branch makes no sense with --mirror\");\n+\t\tdie(_(\"specifying a master branch makes no sense with --mirror\"));\n \tif (mirror && !(mirror & MIRROR_FETCH) && track.nr)\n-\t\tdie(\"specifying branches to track makes sense only with fetch mirrors\");\n+\t\tdie(_(\"specifying branches to track makes sense only with fetch mirrors\"));\n \n \tname = argv[0];\n \turl = argv[1];\n@@ -192,11 +192,11 @@ static int add(int argc, const char **argv)\n \tremote = remote_get(name);\n \tif (remote && (remote->url_nr > 1 || strcmp(name, remote->url[0]) ||\n \t\t\tremote->fetch_refspec_nr))\n-\t\tdie(\"remote %s already exists.\", name);\n+\t\tdie(_(\"remote %s already exists.\"), name);\n \n \tstrbuf_addf(&buf2, \"refs/heads/test:refs/remotes/%s/test\", name);\n \tif (!valid_fetch_refspec(buf2.buf))\n-\t\tdie(\"'%s' is not a valid remote name\", name);\n+\t\tdie(_(\"'%s' is not a valid remote name\"), name);\n \n \tstrbuf_addf(&buf, \"remote.%s.url\", name);\n \tif (git_config_set(buf.buf, url))\n@@ -240,7 +240,7 @@ static int add(int argc, const char **argv)\n \t\tstrbuf_addf(&buf2, \"refs/remotes/%s/%s\", name, master);\n \n \t\tif (create_symref(buf.buf, buf2.buf, \"remote add\"))\n-\t\t\treturn error(\"Could not setup master '%s'\", master);\n+\t\t\treturn error(_(\"Could not setup master '%s'\"), master);\n \t}\n \n \tstrbuf_release(&buf);\n@@ -296,7 +296,7 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\tinfo = item->util;\n \t\tif (type == REMOTE) {\n \t\t\tif (info->remote_name)\n-\t\t\t\twarning(\"more than one %s\", orig_key);\n+\t\t\t\twarning(_(\"more than one %s\"), orig_key);\n \t\t\tinfo->remote_name = xstrdup(value);\n \t\t} else if (type == MERGE) {\n \t\t\tchar *space = strchr(value, ' ');\n@@ -336,7 +336,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat\n \n \tfor (i = 0; i < states->remote->fetch_refspec_nr; i++)\n \t\tif (get_fetch_map(remote_refs, states->remote->fetch + i, &tail, 1))\n-\t\t\tdie(\"Could not get fetch map for refspec %s\",\n+\t\t\tdie(_(\"Could not get fetch map for refspec %s\"),\n \t\t\t\tstates->remote->fetch_refspec[i]);\n \n \tstates->new.strdup_strings = 1;\n@@ -437,7 +437,7 @@ static int get_push_ref_states_noquery(struct ref_states *states)\n \n \tstates->push.strdup_strings = 1;\n \tif (!remote->push_refspec_nr) {\n-\t\titem = string_list_append(&states->push, \"(matching)\");\n+\t\titem = string_list_append(&states->push, _(\"(matching)\"));\n \t\tinfo = item->util = xcalloc(sizeof(struct push_info), 1);\n \t\tinfo->status = PUSH_STATUS_NOTQUERIED;\n \t\tinfo->dest = xstrdup(item->string);\n@@ -445,11 +445,11 @@ static int get_push_ref_states_noquery(struct ref_states *states)\n \tfor (i = 0; i < remote->push_refspec_nr; i++) {\n \t\tstruct refspec *spec = remote->push + i;\n \t\tif (spec->matching)\n-\t\t\titem = string_list_append(&states->push, \"(matching)\");\n+\t\t\titem = string_list_append(&states->push, _(\"(matching)\"));\n \t\telse if (strlen(spec->src))\n \t\t\titem = string_list_append(&states->push, spec->src);\n \t\telse\n-\t\t\titem = string_list_append(&states->push, \"(delete)\");\n+\t\t\titem = string_list_append(&states->push, _(\"(delete)\"));\n \n \t\tinfo = item->util = xcalloc(sizeof(struct push_info), 1);\n \t\tinfo->forced = spec->force;\n@@ -592,19 +592,19 @@ static int migrate_file(struct remote *remote)\n \tstrbuf_addf(&buf, \"remote.%s.url\", remote->name);\n \tfor (i = 0; i < remote->url_nr; i++)\n \t\tif (git_config_set_multivar(buf.buf, remote->url[i], \"^$\", 0))\n-\t\t\treturn error(\"Could not append '%s' to '%s'\",\n+\t\t\treturn error(_(\"Could not append '%s' to '%s'\"),\n \t\t\t\t\tremote->url[i], buf.buf);\n \tstrbuf_reset(&buf);\n \tstrbuf_addf(&buf, \"remote.%s.push\", remote->name);\n \tfor (i = 0; i < remote->push_refspec_nr; i++)\n \t\tif (git_config_set_multivar(buf.buf, remote->push_refspec[i], \"^$\", 0))\n-\t\t\treturn error(\"Could not append '%s' to '%s'\",\n+\t\t\treturn error(_(\"Could not append '%s' to '%s'\"),\n \t\t\t\t\tremote->push_refspec[i], buf.buf);\n \tstrbuf_reset(&buf);\n \tstrbuf_addf(&buf, \"remote.%s.fetch\", remote->name);\n \tfor (i = 0; i < remote->fetch_refspec_nr; i++)\n \t\tif (git_config_set_multivar(buf.buf, remote->fetch_refspec[i], \"^$\", 0))\n-\t\t\treturn error(\"Could not append '%s' to '%s'\",\n+\t\t\treturn error(_(\"Could not append '%s' to '%s'\"),\n \t\t\t\t\tremote->fetch_refspec[i], buf.buf);\n \tif (remote->origin == REMOTE_REMOTES)\n \t\tpath = git_path(\"remotes/%s\", remote->name);\n@@ -636,30 +636,30 @@ static int mv(int argc, const char **argv)\n \n \toldremote = remote_get(rename.old);\n \tif (!oldremote)\n-\t\tdie(\"No such remote: %s\", rename.old);\n+\t\tdie(_(\"No such remote: %s\"), rename.old);\n \n \tif (!strcmp(rename.old, rename.new) && oldremote->origin != REMOTE_CONFIG)\n \t\treturn migrate_file(oldremote);\n \n \tnewremote = remote_get(rename.new);\n \tif (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr))\n-\t\tdie(\"remote %s already exists.\", rename.new);\n+\t\tdie(_(\"remote %s already exists.\"), rename.new);\n \n \tstrbuf_addf(&buf, \"refs/heads/test:refs/remotes/%s/test\", rename.new);\n \tif (!valid_fetch_refspec(buf.buf))\n-\t\tdie(\"'%s' is not a valid remote name\", rename.new);\n+\t\tdie(_(\"'%s' is not a valid remote name\"), rename.new);\n \n \tstrbuf_reset(&buf);\n \tstrbuf_addf(&buf, \"remote.%s\", rename.old);\n \tstrbuf_addf(&buf2, \"remote.%s\", rename.new);\n \tif (git_config_rename_section(buf.buf, buf2.buf) < 1)\n-\t\treturn error(\"Could not rename config section '%s' to '%s'\",\n+\t\treturn error(_(\"Could not rename config section '%s' to '%s'\"),\n \t\t\t\tbuf.buf, buf2.buf);\n \n \tstrbuf_reset(&buf);\n \tstrbuf_addf(&buf, \"remote.%s.fetch\", rename.new);\n \tif (git_config_set_multivar(buf.buf, NULL, NULL, 1))\n-\t\treturn error(\"Could not remove config section '%s'\", buf.buf);\n+\t\treturn error(_(\"Could not remove config section '%s'\"), buf.buf);\n \tstrbuf_addf(&old_remote_context, \":refs/remotes/%s/\", rename.old);\n \tfor (i = 0; i < oldremote->fetch_refspec_nr; i++) {\n \t\tchar *ptr;\n@@ -674,13 +674,13 @@ static int mv(int argc, const char **argv)\n \t\t\t\t      strlen(rename.old), rename.new,\n \t\t\t\t      strlen(rename.new));\n \t\t} else\n-\t\t\twarning(\"Not updating non-default fetch respec\\n\"\n-\t\t\t\t\"\\t%s\\n\"\n-\t\t\t\t\"\\tPlease update the configuration manually if necessary.\",\n+\t\t\twarning(_(\"Not updating non-default fetch respec\\n\"\n+\t\t\t\t  \"\\t%s\\n\"\n+\t\t\t\t  \"\\tPlease update the configuration manually if necessary.\"),\n \t\t\t\tbuf2.buf);\n \n \t\tif (git_config_set_multivar(buf.buf, buf2.buf, \"^$\", 0))\n-\t\t\treturn error(\"Could not append '%s'\", buf.buf);\n+\t\t\treturn error(_(\"Could not append '%s'\"), buf.buf);\n \t}\n \n \tread_branches();\n@@ -691,7 +691,7 @@ static int mv(int argc, const char **argv)\n \t\t\tstrbuf_reset(&buf);\n \t\t\tstrbuf_addf(&buf, \"branch.%s.remote\", item->string);\n \t\t\tif (git_config_set(buf.buf, rename.new)) {\n-\t\t\t\treturn error(\"Could not set '%s'\", buf.buf);\n+\t\t\t\treturn error(_(\"Could not set '%s'\"), buf.buf);\n \t\t\t}\n \t\t}\n \t}\n@@ -713,7 +713,7 @@ static int mv(int argc, const char **argv)\n \t\tif (!(flag & REF_ISSYMREF))\n \t\t\tcontinue;\n \t\tif (delete_ref(item->string, NULL, REF_NODEREF))\n-\t\t\tdie(\"deleting '%s' failed\", item->string);\n+\t\t\tdie(_(\"deleting '%s' failed\"), item->string);\n \t}\n \tfor (i = 0; i < remote_branches.nr; i++) {\n \t\tstruct string_list_item *item = remote_branches.items + i;\n@@ -728,7 +728,7 @@ static int mv(int argc, const char **argv)\n \t\tstrbuf_addf(&buf2, \"remote: renamed %s to %s\",\n \t\t\t\titem->string, buf.buf);\n \t\tif (rename_ref(item->string, buf.buf, buf2.buf))\n-\t\t\tdie(\"renaming '%s' failed\", item->string);\n+\t\t\tdie(_(\"renaming '%s' failed\"), item->string);\n \t}\n \tfor (i = 0; i < remote_branches.nr; i++) {\n \t\tstruct string_list_item *item = remote_branches.items + i;\n@@ -747,7 +747,7 @@ static int mv(int argc, const char **argv)\n \t\tstrbuf_addf(&buf3, \"remote: renamed %s to %s\",\n \t\t\t\titem->string, buf.buf);\n \t\tif (create_symref(buf.buf, buf2.buf, buf3.buf))\n-\t\t\tdie(\"creating '%s' failed\", buf.buf);\n+\t\t\tdie(_(\"creating '%s' failed\"), buf.buf);\n \t}\n \treturn 0;\n }\n@@ -761,7 +761,7 @@ static int remove_branches(struct string_list *branches)\n \t\tunsigned char *sha1 = item->util;\n \n \t\tif (delete_ref(refname, sha1, 0))\n-\t\t\tresult |= error(\"Could not remove branch %s\", refname);\n+\t\t\tresult |= error(_(\"Could not remove branch %s\"), refname);\n \t}\n \treturn result;\n }\n@@ -789,14 +789,14 @@ static int rm(int argc, const char **argv)\n \n \tremote = remote_get(argv[1]);\n \tif (!remote)\n-\t\tdie(\"No such remote: %s\", argv[1]);\n+\t\tdie(_(\"No such remote: %s\"), argv[1]);\n \n \tknown_remotes.to_delete = remote;\n \tfor_each_remote(add_known_remote, &known_remotes);\n \n \tstrbuf_addf(&buf, \"remote.%s\", remote->name);\n \tif (git_config_rename_section(buf.buf, NULL) < 1)\n-\t\treturn error(\"Could not remove config section '%s'\", buf.buf);\n+\t\treturn error(_(\"Could not remove config section '%s'\"), buf.buf);\n \n \tread_branches();\n \tfor (i = 0; i < branch_list.nr; i++) {\n@@ -830,11 +830,12 @@ static int rm(int argc, const char **argv)\n \tstring_list_clear(&branches, 1);\n \n \tif (skipped.nr) {\n-\t\tfprintf(stderr, skipped.nr == 1 ?\n-\t\t\t\"Note: A branch outside the refs/remotes/ hierarchy was not removed;\\n\"\n-\t\t\t\"to delete it, use:\\n\" :\n-\t\t\t\"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\\n\"\n-\t\t\t\"to delete them, use:\\n\");\n+\t\tfprintf_ln(stderr,\n+\t\t\t   Q_(\"Note: A branch outside the refs/remotes/ hierarchy was not removed;\\n\"\n+\t\t\t      \"to delete it, use:\",\n+\t\t\t      \"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\\n\"\n+\t\t\t      \"to delete them, use:\",\n+\t\t\t      skipped.nr));\n \t\tfor (i = 0; i < skipped.nr; i++)\n \t\t\tfprintf(stderr, \"  git branch -d %s\\n\",\n \t\t\t\tskipped.items[i].string);\n@@ -886,7 +887,7 @@ static int get_remote_ref_states(const char *name,\n \n \tstates->remote = remote_get(name);\n \tif (!states->remote)\n-\t\treturn error(\"No such remote: %s\", name);\n+\t\treturn error(_(\"No such remote: %s\"), name);\n \n \tread_branches();\n \n@@ -939,14 +940,14 @@ static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n \t\tconst char *fmt = \"%s\";\n \t\tconst char *arg = \"\";\n \t\tif (string_list_has_string(&states->new, name)) {\n-\t\t\tfmt = \" new (next fetch will store in remotes/%s)\";\n+\t\t\tfmt = _(\" new (next fetch will store in remotes/%s)\");\n \t\t\targ = states->remote->name;\n \t\t} else if (string_list_has_string(&states->tracked, name))\n-\t\t\targ = \" tracked\";\n+\t\t\targ = _(\" tracked\");\n \t\telse if (string_list_has_string(&states->stale, name))\n-\t\t\targ = \" stale (use 'git remote prune' to remove)\";\n+\t\t\targ = _(\" stale (use 'git remote prune' to remove)\");\n \t\telse\n-\t\t\targ = \" ???\";\n+\t\t\targ = _(\" ???\");\n \t\tprintf(\"    %-*s\", info->width, name);\n \t\tprintf(fmt, arg);\n \t\tprintf(\"\\n\");\n@@ -987,21 +988,21 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)\n \tint i;\n \n \tif (branch_info->rebase && branch_info->merge.nr > 1) {\n-\t\terror(\"invalid branch.%s.merge; cannot rebase onto > 1 branch\",\n+\t\terror(_(\"invalid branch.%s.merge; cannot rebase onto > 1 branch\"),\n \t\t\titem->string);\n \t\treturn 0;\n \t}\n \n \tprintf(\"    %-*s \", show_info->width, item->string);\n \tif (branch_info->rebase) {\n-\t\tprintf(\"rebases onto remote %s\\n\", merge->items[0].string);\n+\t\tprintf_ln(_(\"rebases onto remote %s\"), merge->items[0].string);\n \t\treturn 0;\n \t} else if (show_info->any_rebase) {\n-\t\tprintf(\" merges with remote %s\\n\", merge->items[0].string);\n-\t\talso = \"    and with remote\";\n+\t\tprintf_ln(_(\" merges with remote %s\"), merge->items[0].string);\n+\t\talso = _(\"    and with remote\");\n \t} else {\n-\t\tprintf(\"merges with remote %s\\n\", merge->items[0].string);\n-\t\talso = \"   and with remote\";\n+\t\tprintf_ln(_(\"merges with remote %s\"), merge->items[0].string);\n+\t\talso = _(\"   and with remote\");\n \t}\n \tfor (i = 1; i < merge->nr; i++)\n \t\tprintf(\"    %-*s %s %s\\n\", show_info->width, \"\", also,\n@@ -1043,36 +1044,43 @@ static int show_push_info_item(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *show_info = cb_data;\n \tstruct push_info *push_info = item->util;\n-\tchar *src = item->string, *status = NULL;\n+\tconst char *src = item->string, *status = NULL;\n \n \tswitch (push_info->status) {\n \tcase PUSH_STATUS_CREATE:\n-\t\tstatus = \"create\";\n+\t\tstatus = _(\"create\");\n \t\tbreak;\n \tcase PUSH_STATUS_DELETE:\n-\t\tstatus = \"delete\";\n-\t\tsrc = \"(none)\";\n+\t\tstatus = _(\"delete\");\n+\t\tsrc = _(\"(none)\");\n \t\tbreak;\n \tcase PUSH_STATUS_UPTODATE:\n-\t\tstatus = \"up to date\";\n+\t\tstatus = _(\"up to date\");\n \t\tbreak;\n \tcase PUSH_STATUS_FASTFORWARD:\n-\t\tstatus = \"fast-forwardable\";\n+\t\tstatus = _(\"fast-forwardable\");\n \t\tbreak;\n \tcase PUSH_STATUS_OUTOFDATE:\n-\t\tstatus = \"local out of date\";\n+\t\tstatus = _(\"local out of date\");\n \t\tbreak;\n \tcase PUSH_STATUS_NOTQUERIED:\n \t\tbreak;\n \t}\n-\tif (status)\n-\t\tprintf(\"    %-*s %s to %-*s (%s)\\n\", show_info->width, src,\n-\t\t\tpush_info->forced ? \"forces\" : \"pushes\",\n-\t\t\tshow_info->width2, push_info->dest, status);\n-\telse\n-\t\tprintf(\"    %-*s %s to %s\\n\", show_info->width, src,\n-\t\t\tpush_info->forced ? \"forces\" : \"pushes\",\n-\t\t\tpush_info->dest);\n+\tif (status) {\n+\t\tif (push_info->forced)\n+\t\t\tprintf_ln(_(\"    %-*s forces to %-*s (%s)\"), show_info->width, src,\n+\t\t\t       show_info->width2, push_info->dest, status);\n+\t\telse\n+\t\t\tprintf_ln(_(\"    %-*s pushes to %-*s (%s)\"), show_info->width, src,\n+\t\t\t       show_info->width2, push_info->dest, status);\n+\t} else {\n+\t\tif (push_info->forced)\n+\t\t\tprintf_ln(_(\"    %-*s forces to %s\"), show_info->width, src,\n+\t\t\t       push_info->dest);\n+\t\telse\n+\t\t\tprintf_ln(_(\"    %-*s pushes to %s\"), show_info->width, src,\n+\t\t\t       push_info->dest);\n+\t}\n \treturn 0;\n }\n \n@@ -1107,9 +1115,9 @@ static int show(int argc, const char **argv)\n \n \t\tget_remote_ref_states(*argv, &states, query_flag);\n \n-\t\tprintf(\"* remote %s\\n\", *argv);\n-\t\tprintf(\"  Fetch URL: %s\\n\", states.remote->url_nr > 0 ?\n-\t\t\tstates.remote->url[0] : \"(no URL)\");\n+\t\tprintf_ln(_(\"* remote %s\"), *argv);\n+\t\tprintf_ln(_(\"  Fetch URL: %s\"), states.remote->url_nr > 0 ?\n+\t\t       states.remote->url[0] : _(\"(no URL)\"));\n \t\tif (states.remote->pushurl_nr) {\n \t\t\turl = states.remote->pushurl;\n \t\t\turl_nr = states.remote->pushurl_nr;\n@@ -1118,18 +1126,18 @@ static int show(int argc, const char **argv)\n \t\t\turl_nr = states.remote->url_nr;\n \t\t}\n \t\tfor (i = 0; i < url_nr; i++)\n-\t\t\tprintf(\"  Push  URL: %s\\n\", url[i]);\n+\t\t\tprintf_ln(_(\"  Push  URL: %s\"), url[i]);\n \t\tif (!i)\n-\t\t\tprintf(\"  Push  URL: %s\\n\", \"(no URL)\");\n+\t\t\tprintf_ln(_(\"  Push  URL: %s\"), \"(no URL)\");\n \t\tif (no_query)\n-\t\t\tprintf(\"  HEAD branch: (not queried)\\n\");\n+\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), \"(not queried)\");\n \t\telse if (!states.heads.nr)\n-\t\t\tprintf(\"  HEAD branch: (unknown)\\n\");\n+\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), \"(unknown)\");\n \t\telse if (states.heads.nr == 1)\n-\t\t\tprintf(\"  HEAD branch: %s\\n\", states.heads.items[0].string);\n+\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), states.heads.items[0].string);\n \t\telse {\n-\t\t\tprintf(\"  HEAD branch (remote HEAD is ambiguous,\"\n-\t\t\t       \" may be one of the following):\\n\");\n+\t\t\tprintf(_(\"  HEAD branch (remote HEAD is ambiguous,\"\n+\t\t\t\t \" may be one of the following):\\n\"));\n \t\t\tfor (i = 0; i < states.heads.nr; i++)\n \t\t\t\tprintf(\"    %s\\n\", states.heads.items[i].string);\n \t\t}\n@@ -1140,9 +1148,10 @@ static int show(int argc, const char **argv)\n \t\tfor_each_string_list(&states.tracked, add_remote_to_show_info, &info);\n \t\tfor_each_string_list(&states.stale, add_remote_to_show_info, &info);\n \t\tif (info.list->nr)\n-\t\t\tprintf(\"  Remote branch%s:%s\\n\",\n-\t\t\t       info.list->nr > 1 ? \"es\" : \"\",\n-\t\t\t\tno_query ? \" (status not queried)\" : \"\");\n+\t\t\tprintf_ln(Q_(\"  Remote branch:%s\",\n+\t\t\t\t     \"  Remote branches:%s\",\n+\t\t\t\t     info.list->nr),\n+\t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n \t\tfor_each_string_list(info.list, show_remote_info_item, &info);\n \t\tstring_list_clear(info.list, 0);\n \n@@ -1151,23 +1160,25 @@ static int show(int argc, const char **argv)\n \t\tinfo.any_rebase = 0;\n \t\tfor_each_string_list(&branch_list, add_local_to_show_info, &info);\n \t\tif (info.list->nr)\n-\t\t\tprintf(\"  Local branch%s configured for 'git pull':\\n\",\n-\t\t\t       info.list->nr > 1 ? \"es\" : \"\");\n+\t\t\tprintf_ln(Q_(\"  Local branch configured for 'git pull':\",\n+\t\t\t\t     \"  Local branches configured for 'git pull':\",\n+\t\t\t\t     info.list->nr));\n \t\tfor_each_string_list(info.list, show_local_info_item, &info);\n \t\tstring_list_clear(info.list, 0);\n \n \t\t/* git push info */\n \t\tif (states.remote->mirror)\n-\t\t\tprintf(\"  Local refs will be mirrored by 'git push'\\n\");\n+\t\t\tprintf_ln(_(\"  Local refs will be mirrored by 'git push'\"));\n \n \t\tinfo.width = info.width2 = 0;\n \t\tfor_each_string_list(&states.push, add_push_to_show_info, &info);\n \t\tqsort(info.list->items, info.list->nr,\n \t\t\tsizeof(*info.list->items), cmp_string_with_push);\n \t\tif (info.list->nr)\n-\t\t\tprintf(\"  Local ref%s configured for 'git push'%s:\\n\",\n-\t\t\t\tinfo.list->nr > 1 ? \"s\" : \"\",\n-\t\t\t\tno_query ? \" (status not queried)\" : \"\");\n+\t\t\tprintf_ln(Q_(\"  Local ref configured for 'git push'%s:\",\n+\t\t\t\t     \"  Local refs configured for 'git push'%s:\",\n+\t\t\t\t     info.list->nr),\n+\t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n \t\tfor_each_string_list(info.list, show_push_info_item, &info);\n \t\tstring_list_clear(info.list, 0);\n \n@@ -1202,10 +1213,10 @@ static int set_head(int argc, const char **argv)\n \t\tmemset(&states, 0, sizeof(states));\n \t\tget_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);\n \t\tif (!states.heads.nr)\n-\t\t\tresult |= error(\"Cannot determine remote HEAD\");\n+\t\t\tresult |= error(_(\"Cannot determine remote HEAD\"));\n \t\telse if (states.heads.nr > 1) {\n-\t\t\tresult |= error(\"Multiple remote HEAD branches. \"\n-\t\t\t\t\t\"Please choose one explicitly with:\");\n+\t\t\tresult |= error(_(\"Multiple remote HEAD branches. \"\n+\t\t\t\t\t  \"Please choose one explicitly with:\"));\n \t\t\tfor (i = 0; i < states.heads.nr; i++)\n \t\t\t\tfprintf(stderr, \"  git remote set-head %s %s\\n\",\n \t\t\t\t\targv[0], states.heads.items[i].string);\n@@ -1214,7 +1225,7 @@ static int set_head(int argc, const char **argv)\n \t\tfree_remote_ref_states(&states);\n \t} else if (opt_d && !opt_a && argc == 1) {\n \t\tif (delete_ref(buf.buf, NULL, REF_NODEREF))\n-\t\t\tresult |= error(\"Could not delete %s\", buf.buf);\n+\t\t\tresult |= error(_(\"Could not delete %s\"), buf.buf);\n \t} else\n \t\tusage_with_options(builtin_remote_sethead_usage, options);\n \n@@ -1222,9 +1233,9 @@ static int set_head(int argc, const char **argv)\n \t\tstrbuf_addf(&buf2, \"refs/remotes/%s/%s\", argv[0], head_name);\n \t\t/* make sure it's valid */\n \t\tif (!ref_exists(buf2.buf))\n-\t\t\tresult |= error(\"Not a valid ref: %s\", buf2.buf);\n+\t\t\tresult |= error(_(\"Not a valid ref: %s\"), buf2.buf);\n \t\telse if (create_symref(buf.buf, buf2.buf, \"remote set-head\"))\n-\t\t\tresult |= error(\"Could not setup %s\", buf.buf);\n+\t\t\tresult |= error(_(\"Could not setup %s\"), buf.buf);\n \t\tif (opt_a)\n \t\t\tprintf(\"%s/HEAD set to %s\\n\", argv[0], head_name);\n \t\tfree(head_name);\n@@ -1260,18 +1271,18 @@ static int prune_remote(const char *remote, int dry_run)\n \tint result = 0, i;\n \tstruct ref_states states;\n \tconst char *dangling_msg = dry_run\n-\t\t? \" %s will become dangling!\"\n-\t\t: \" %s has become dangling!\";\n+\t\t? _(\" %s will become dangling!\")\n+\t\t: _(\" %s has become dangling!\");\n \n \tmemset(&states, 0, sizeof(states));\n \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n \n \tif (states.stale.nr) {\n-\t\tprintf(\"Pruning %s\\n\", remote);\n-\t\tprintf(\"URL: %s\\n\",\n+\t\tprintf_ln(_(\"Pruning %s\"), remote);\n+\t\tprintf_ln(_(\"URL: %s\"),\n \t\t       states.remote->url_nr\n \t\t       ? states.remote->url[0]\n-\t\t       : \"(no URL)\");\n+\t\t       : _(\"(no URL)\"));\n \t}\n \n \tfor (i = 0; i < states.stale.nr; i++) {\n@@ -1280,8 +1291,12 @@ static int prune_remote(const char *remote, int dry_run)\n \t\tif (!dry_run)\n \t\t\tresult |= delete_ref(refname, NULL, 0);\n \n-\t\tprintf(\" * [%s] %s\\n\", dry_run ? \"would prune\" : \"pruned\",\n-\t\t       abbrev_ref(refname, \"refs/remotes/\"));\n+\t\tif (dry_run)\n+\t\t\tprintf_ln(_(\" * [would prune] %s\"),\n+\t\t\t       abbrev_ref(refname, \"refs/remotes/\"));\n+\t\telse\n+\t\t\tprintf_ln(_(\" * [pruned] %s\"),\n+\t\t\t       abbrev_ref(refname, \"refs/remotes/\"));\n \t\twarn_dangling_symref(stdout, dangling_msg, refname);\n \t}\n \n@@ -1369,7 +1384,7 @@ static int set_remote_branches(const char *remotename, const char **branches,\n \tstrbuf_addf(&key, \"remote.%s.fetch\", remotename);\n \n \tif (!remote_is_configured(remotename))\n-\t\tdie(\"No such remote '%s'\", remotename);\n+\t\tdie(_(\"No such remote '%s'\"), remotename);\n \tremote = remote_get(remotename);\n \n \tif (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) {\n@@ -1396,7 +1411,7 @@ static int set_branches(int argc, const char **argv)\n \targc = parse_options(argc, argv, NULL, options,\n \t\t\t     builtin_remote_setbranches_usage, 0);\n \tif (argc == 0) {\n-\t\terror(\"no remote specified\");\n+\t\terror(_(\"no remote specified\"));\n \t\tusage_with_options(builtin_remote_setbranches_usage, options);\n \t}\n \targv[argc] = NULL;\n@@ -1429,7 +1444,7 @@ static int set_url(int argc, const char **argv)\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n \tif (add_mode && delete_mode)\n-\t\tdie(\"--add --delete doesn't make sense\");\n+\t\tdie(_(\"--add --delete doesn't make sense\"));\n \n \tif (argc < 3 || argc > 4 || ((add_mode || delete_mode) && argc != 3))\n \t\tusage_with_options(builtin_remote_seturl_usage, options);\n@@ -1443,7 +1458,7 @@ static int set_url(int argc, const char **argv)\n \t\toldurl = newurl;\n \n \tif (!remote_is_configured(remotename))\n-\t\tdie(\"No such remote '%s'\", remotename);\n+\t\tdie(_(\"No such remote '%s'\"), remotename);\n \tremote = remote_get(remotename);\n \n \tif (push_mode) {\n@@ -1469,7 +1484,7 @@ static int set_url(int argc, const char **argv)\n \n \t/* Old URL specified. Demand that one matches. */\n \tif (regcomp(&old_regex, oldurl, REG_EXTENDED))\n-\t\tdie(\"Invalid old URL pattern: %s\", oldurl);\n+\t\tdie(_(\"Invalid old URL pattern: %s\"), oldurl);\n \n \tfor (i = 0; i < urlset_nr; i++)\n \t\tif (!regexec(&old_regex, urlset[i], 0, NULL, 0))\n@@ -1477,9 +1492,9 @@ static int set_url(int argc, const char **argv)\n \t\telse\n \t\t\tnegative_matches++;\n \tif (!delete_mode && !matches)\n-\t\tdie(\"No such URL found: %s\", oldurl);\n+\t\tdie(_(\"No such URL found: %s\"), oldurl);\n \tif (delete_mode && !negative_matches && !push_mode)\n-\t\tdie(\"Will not delete all non-push URLs\");\n+\t\tdie(_(\"Will not delete all non-push URLs\"));\n \n \tregfree(&old_regex);\n \n@@ -1580,7 +1595,7 @@ int cmd_remote(int argc, const char **argv, const char *prefix)\n \telse if (!strcmp(argv[0], \"update\"))\n \t\tresult = update(argc, argv);\n \telse {\n-\t\terror(\"Unknown subcommand: %s\", argv[0]);\n+\t\terror(_(\"Unknown subcommand: %s\"), argv[0]);\n \t\tusage_with_options(builtin_remote_usage, options);\n \t}\n \n-- \n1.7.8.36.g69ee2\n"},{"id":"189871","messageId":"1335184230-8870-8-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 07/10] i18n: apply: mark strings for translation","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:27Z","receivedAt":"2012-04-23T12:30:27Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/apply.c |  174 +++++++++++++++++++++++++++++--------------------------\n 1 files changed, 91 insertions(+), 83 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 389898f..4bb6354 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -103,7 +103,7 @@ static void parse_whitespace_option(const char *option)\n \t\tws_error_action = correct_ws_error;\n \t\treturn;\n \t}\n-\tdie(\"unrecognized whitespace option '%s'\", option);\n+\tdie(_(\"unrecognized whitespace option '%s'\"), option);\n }\n \n static void parse_ignorewhitespace_option(const char *option)\n@@ -118,7 +118,7 @@ static void parse_ignorewhitespace_option(const char *option)\n \t\tws_ignore_action = ignore_ws_change;\n \t\treturn;\n \t}\n-\tdie(\"unrecognized whitespace ignore option '%s'\", option);\n+\tdie(_(\"unrecognized whitespace ignore option '%s'\"), option);\n }\n \n static void set_default_whitespace_mode(const char *whitespace_option)\n@@ -770,7 +770,7 @@ static int has_epoch_timestamp(const char *nameline)\n \tif (!stamp) {\n \t\tstamp = xmalloc(sizeof(*stamp));\n \t\tif (regcomp(stamp, stamp_regexp, REG_EXTENDED)) {\n-\t\t\twarning(\"Cannot prepare timestamp regexp %s\",\n+\t\t\twarning(_(\"Cannot prepare timestamp regexp %s\"),\n \t\t\t\tstamp_regexp);\n \t\t\treturn 0;\n \t\t}\n@@ -779,7 +779,7 @@ static int has_epoch_timestamp(const char *nameline)\n \tstatus = regexec(stamp, timestamp, ARRAY_SIZE(m), m, 0);\n \tif (status) {\n \t\tif (status != REG_NOMATCH)\n-\t\t\twarning(\"regexec returned %d for input: %s\",\n+\t\t\twarning(_(\"regexec returned %d for input: %s\"),\n \t\t\t\tstatus, timestamp);\n \t\treturn 0;\n \t}\n@@ -857,7 +857,7 @@ static void parse_traditional_patch(const char *first, const char *second, struc\n \t\t}\n \t}\n \tif (!name)\n-\t\tdie(\"unable to find filename in patch at line %d\", linenr);\n+\t\tdie(_(\"unable to find filename in patch at line %d\"), linenr);\n }\n \n static int gitdiff_hdrend(const char *line, struct patch *patch)\n@@ -886,17 +886,17 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n \t\tname = orig_name;\n \t\tlen = strlen(name);\n \t\tif (isnull)\n-\t\t\tdie(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\", name, linenr);\n+\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, linenr);\n \t\tanother = find_name(line, NULL, p_value, TERM_TAB);\n \t\tif (!another || memcmp(another, name, len + 1))\n-\t\t\tdie(\"git apply: bad git-diff - inconsistent %s filename on line %d\", oldnew, linenr);\n+\t\t\tdie(_(\"git apply: bad git-diff - inconsistent %s filename on line %d\"), oldnew, linenr);\n \t\tfree(another);\n \t\treturn orig_name;\n \t}\n \telse {\n \t\t/* expect \"/dev/null\" */\n \t\tif (memcmp(\"/dev/null\", line, 9) || line[9] != '\\n')\n-\t\t\tdie(\"git apply: bad git-diff - expected /dev/null on line %d\", linenr);\n+\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null on line %d\"), linenr);\n \t\treturn NULL;\n \t}\n }\n@@ -1327,7 +1327,7 @@ static void recount_diff(char *line, int size, struct fragment *fragment)\n \t\t\tbreak;\n \t\t}\n \t\tif (ret) {\n-\t\t\twarning(\"recount: unexpected line: %.*s\",\n+\t\t\twarning(_(\"recount: unexpected line: %.*s\"),\n \t\t\t\t(int)linelen(line, size), line);\n \t\t\treturn;\n \t\t}\n@@ -1384,7 +1384,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc\n \t\t\tstruct fragment dummy;\n \t\t\tif (parse_fragment_header(line, len, &dummy) < 0)\n \t\t\t\tcontinue;\n-\t\t\tdie(\"patch fragment without header at line %d: %.*s\",\n+\t\t\tdie(_(\"patch fragment without header at line %d: %.*s\"),\n \t\t\t    linenr, (int)len-1, line);\n \t\t}\n \n@@ -1401,8 +1401,12 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc\n \t\t\t\tcontinue;\n \t\t\tif (!patch->old_name && !patch->new_name) {\n \t\t\t\tif (!patch->def_name)\n-\t\t\t\t\tdie(\"git diff header lacks filename information when removing \"\n-\t\t\t\t\t    \"%d leading pathname components (line %d)\" , p_value, linenr);\n+\t\t\t\t\tdie(Q_(\"git diff header lacks filename information when removing \"\n+\t\t\t\t\t       \"%d leading pathname component (line %d)\",\n+\t\t\t\t\t       \"git diff header lacks filename information when removing \"\n+\t\t\t\t\t       \"%d leading pathname components (line %d)\",\n+\t\t\t\t\t       p_value),\n+\t\t\t\t\t    p_value, linenr);\n \t\t\t\tpatch->old_name = patch->new_name = patch->def_name;\n \t\t\t}\n \t\t\tif (!patch->is_delete && !patch->new_name)\n@@ -1556,9 +1560,9 @@ static int parse_fragment(char *line, unsigned long size,\n \tpatch->lines_deleted += deleted;\n \n \tif (0 < patch->is_new && oldlines)\n-\t\treturn error(\"new file depends on old contents\");\n+\t\treturn error(_(\"new file depends on old contents\"));\n \tif (0 < patch->is_delete && newlines)\n-\t\treturn error(\"deleted file still has contents\");\n+\t\treturn error(_(\"deleted file still has contents\"));\n \treturn offset;\n }\n \n@@ -1576,7 +1580,7 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc\n \t\tfragment->linenr = linenr;\n \t\tlen = parse_fragment(line, size, patch, fragment);\n \t\tif (len <= 0)\n-\t\t\tdie(\"corrupt patch at line %d\", linenr);\n+\t\t\tdie(_(\"corrupt patch at line %d\"), linenr);\n \t\tfragment->patch = line;\n \t\tfragment->size = len;\n \t\toldlines += fragment->oldlines;\n@@ -1612,12 +1616,14 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc\n \t\tpatch->is_delete = 0;\n \n \tif (0 < patch->is_new && oldlines)\n-\t\tdie(\"new file %s depends on old contents\", patch->new_name);\n+\t\tdie(_(\"new file %s depends on old contents\"), patch->new_name);\n \tif (0 < patch->is_delete && newlines)\n-\t\tdie(\"deleted file %s still has contents\", patch->old_name);\n+\t\tdie(_(\"deleted file %s still has contents\"), patch->old_name);\n \tif (!patch->is_delete && !newlines && context)\n-\t\tfprintf(stderr, \"** warning: file %s becomes empty but \"\n-\t\t\t\"is not deleted\\n\", patch->new_name);\n+\t\tfprintf_ln(stderr,\n+\t\t\t   _(\"** warning: \"\n+\t\t\t     \"file %s becomes empty but is not deleted\"),\n+\t\t\t   patch->new_name);\n \n \treturn offset;\n }\n@@ -1755,7 +1761,7 @@ static struct fragment *parse_binary_hunk(char **buf_p,\n  corrupt:\n \tfree(data);\n \t*status_p = -1;\n-\terror(\"corrupt binary patch at line %d: %.*s\",\n+\terror(_(\"corrupt binary patch at line %d: %.*s\"),\n \t      linenr-1, llen-1, buffer);\n \treturn NULL;\n }\n@@ -1784,7 +1790,7 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)\n \tforward = parse_binary_hunk(&buffer, &size, &status, &used);\n \tif (!forward && !status)\n \t\t/* there has to be one hunk (forward hunk) */\n-\t\treturn error(\"unrecognized binary patch at line %d\", linenr-1);\n+\t\treturn error(_(\"unrecognized binary patch at line %d\"), linenr-1);\n \tif (status)\n \t\t/* otherwise we already gave an error message */\n \t\treturn status;\n@@ -1863,7 +1869,7 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)\n \t\t */\n \t\tif ((apply || check) &&\n \t\t    (!patch->is_binary && !metadata_changes(patch)))\n-\t\t\tdie(\"patch with only garbage at line %d\", linenr);\n+\t\t\tdie(_(\"patch with only garbage at line %d\"), linenr);\n \t}\n \n \treturn offset + hdrsize + patchsize;\n@@ -1953,11 +1959,11 @@ static int read_old_data(struct stat *st, const char *path, struct strbuf *buf)\n \tswitch (st->st_mode & S_IFMT) {\n \tcase S_IFLNK:\n \t\tif (strbuf_readlink(buf, path, st->st_size) < 0)\n-\t\t\treturn error(\"unable to read symlink %s\", path);\n+\t\t\treturn error(_(\"unable to read symlink %s\"), path);\n \t\treturn 0;\n \tcase S_IFREG:\n \t\tif (strbuf_read_file(buf, path, st->st_size) != st->st_size)\n-\t\t\treturn error(\"unable to open or read %s\", path);\n+\t\t\treturn error(_(\"unable to open or read %s\"), path);\n \t\tconvert_to_git(path, buf->buf, buf->len, buf, 0);\n \t\treturn 0;\n \tdefault:\n@@ -2028,7 +2034,7 @@ static void update_pre_post_images(struct image *preimage,\n \t\t\tctx++;\n \t\t}\n \t\tif (preimage->nr <= ctx)\n-\t\t\tdie(\"oops\");\n+\t\t\tdie(_(\"oops\"));\n \n \t\t/* and copy it in, while fixing the line length */\n \t\tlen = preimage->line[ctx].len;\n@@ -2540,7 +2546,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tif (apply_verbosely)\n-\t\t\t\terror(\"invalid start of line: '%c'\", first);\n+\t\t\t\terror(_(\"invalid start of line: '%c'\"), first);\n \t\t\treturn -1;\n \t\t}\n \t\tif (added_blank_line) {\n@@ -2657,9 +2663,11 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,\n \t\t\tint offset = applied_pos - pos;\n \t\t\tif (apply_in_reverse)\n \t\t\t\toffset = 0 - offset;\n-\t\t\tfprintf(stderr,\n-\t\t\t\t\"Hunk #%d succeeded at %d (offset %d lines).\\n\",\n-\t\t\t\tnth_fragment, applied_pos + 1, offset);\n+\t\t\tfprintf_ln(stderr,\n+\t\t\t\t   Q_(\"Hunk #%d succeeded at %d (offset %d line).\",\n+\t\t\t\t      \"Hunk #%d succeeded at %d (offset %d lines).\",\n+\t\t\t\t      offset),\n+\t\t\t\t   nth_fragment, applied_pos + 1, offset);\n \t\t}\n \n \t\t/*\n@@ -2668,13 +2676,13 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,\n \t\t */\n \t\tif ((leading != frag->leading) ||\n \t\t    (trailing != frag->trailing))\n-\t\t\tfprintf(stderr, \"Context reduced to (%ld/%ld)\"\n-\t\t\t\t\" to apply fragment at %d\\n\",\n-\t\t\t\tleading, trailing, applied_pos+1);\n+\t\t\tfprintf_ln(stderr, _(\"Context reduced to (%ld/%ld)\"\n+\t\t\t\t\t     \" to apply fragment at %d\"),\n+\t\t\t\t   leading, trailing, applied_pos+1);\n \t\tupdate_image(img, applied_pos, &preimage, &postimage);\n \t} else {\n \t\tif (apply_verbosely)\n-\t\t\terror(\"while searching for:\\n%.*s\",\n+\t\t\terror(_(\"while searching for:\\n%.*s\"),\n \t\t\t      (int)(old - oldlines), oldlines);\n \t}\n \n@@ -2693,7 +2701,7 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)\n \tvoid *dst;\n \n \tif (!fragment)\n-\t\treturn error(\"missing binary patch data for '%s'\",\n+\t\treturn error(_(\"missing binary patch data for '%s'\"),\n \t\t\t     patch->new_name ?\n \t\t\t     patch->new_name :\n \t\t\t     patch->old_name);\n@@ -2790,13 +2798,13 @@ static int apply_binary(struct image *img, struct patch *patch)\n \t\t * in the patch->fragments->{patch,size}.\n \t\t */\n \t\tif (apply_binary_fragment(img, patch))\n-\t\t\treturn error(\"binary patch does not apply to '%s'\",\n+\t\t\treturn error(_(\"binary patch does not apply to '%s'\"),\n \t\t\t\t     name);\n \n \t\t/* verify that the result matches */\n \t\thash_sha1_file(img->buf, img->len, blob_type, sha1);\n \t\tif (strcmp(sha1_to_hex(sha1), patch->new_sha1_prefix))\n-\t\t\treturn error(\"binary patch to '%s' creates incorrect result (expecting %s, got %s)\",\n+\t\t\treturn error(_(\"binary patch to '%s' creates incorrect result (expecting %s, got %s)\"),\n \t\t\t\tname, patch->new_sha1_prefix, sha1_to_hex(sha1));\n \t}\n \n@@ -2817,7 +2825,7 @@ static int apply_fragments(struct image *img, struct patch *patch)\n \twhile (frag) {\n \t\tnth++;\n \t\tif (apply_one_fragment(img, frag, inaccurate_eof, ws_rule, nth)) {\n-\t\t\terror(\"patch failed: %s:%ld\", name, frag->oldpos);\n+\t\t\terror(_(\"patch failed: %s:%ld\"), name, frag->oldpos);\n \t\t\tif (!apply_with_reject)\n \t\t\t\treturn -1;\n \t\t\tfrag->rejected = 1;\n@@ -2932,14 +2940,14 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *\n \tif (!(patch->is_copy || patch->is_rename) &&\n \t    (tpatch = in_fn_table(patch->old_name)) != NULL && !to_be_deleted(tpatch)) {\n \t\tif (was_deleted(tpatch)) {\n-\t\t\treturn error(\"patch %s has been renamed/deleted\",\n+\t\t\treturn error(_(\"patch %s has been renamed/deleted\"),\n \t\t\t\tpatch->old_name);\n \t\t}\n \t\t/* We have a patched copy in memory use that */\n \t\tstrbuf_add(&buf, tpatch->result, tpatch->resultsize);\n \t} else if (cached) {\n \t\tif (read_file_or_gitlink(ce, &buf))\n-\t\t\treturn error(\"read of %s failed\", patch->old_name);\n+\t\t\treturn error(_(\"read of %s failed\"), patch->old_name);\n \t} else if (patch->old_name) {\n \t\tif (S_ISGITLINK(patch->old_mode)) {\n \t\t\tif (ce) {\n@@ -2953,7 +2961,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *\n \t\t\t}\n \t\t} else {\n \t\t\tif (read_old_data(st, patch->old_name, &buf))\n-\t\t\t\treturn error(\"read of %s failed\", patch->old_name);\n+\t\t\t\treturn error(_(\"read of %s failed\"), patch->old_name);\n \t\t}\n \t}\n \n@@ -2968,7 +2976,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *\n \tfree(image.line_allocated);\n \n \tif (0 < patch->is_delete && patch->resultsize)\n-\t\treturn error(\"removal patch leaves file contents\");\n+\t\treturn error(_(\"removal patch leaves file contents\"));\n \n \treturn 0;\n }\n@@ -2989,7 +2997,7 @@ static int check_to_create_blob(const char *new_name, int ok_if_exists)\n \t\tif (has_symlink_leading_path(new_name, strlen(new_name)))\n \t\t\treturn 0;\n \n-\t\treturn error(\"%s: already exists in working directory\", new_name);\n+\t\treturn error(_(\"%s: already exists in working directory\"), new_name);\n \t}\n \telse if ((errno != ENOENT) && (errno != ENOTDIR))\n \t\treturn error(\"%s: %s\", new_name, strerror(errno));\n@@ -3027,12 +3035,12 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s\n \tif (!(patch->is_copy || patch->is_rename) &&\n \t    (tpatch = in_fn_table(old_name)) != NULL && !to_be_deleted(tpatch)) {\n \t\tif (was_deleted(tpatch))\n-\t\t\treturn error(\"%s: has been deleted/renamed\", old_name);\n+\t\t\treturn error(_(\"%s: has been deleted/renamed\"), old_name);\n \t\tst_mode = tpatch->new_mode;\n \t} else if (!cached) {\n \t\tstat_ret = lstat(old_name, st);\n \t\tif (stat_ret && errno != ENOENT)\n-\t\t\treturn error(\"%s: %s\", old_name, strerror(errno));\n+\t\t\treturn error(_(\"%s: %s\"), old_name, strerror(errno));\n \t}\n \n \tif (to_be_deleted(tpatch))\n@@ -3043,7 +3051,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s\n \t\tif (pos < 0) {\n \t\t\tif (patch->is_new < 0)\n \t\t\t\tgoto is_new;\n-\t\t\treturn error(\"%s: does not exist in index\", old_name);\n+\t\t\treturn error(_(\"%s: does not exist in index\"), old_name);\n \t\t}\n \t\t*ce = active_cache[pos];\n \t\tif (stat_ret < 0) {\n@@ -3057,13 +3065,13 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s\n \t\t\t\treturn -1;\n \t\t}\n \t\tif (!cached && verify_index_match(*ce, st))\n-\t\t\treturn error(\"%s: does not match index\", old_name);\n+\t\t\treturn error(_(\"%s: does not match index\"), old_name);\n \t\tif (cached)\n \t\t\tst_mode = (*ce)->ce_mode;\n \t} else if (stat_ret < 0) {\n \t\tif (patch->is_new < 0)\n \t\t\tgoto is_new;\n-\t\treturn error(\"%s: %s\", old_name, strerror(errno));\n+\t\treturn error(_(\"%s: %s\"), old_name, strerror(errno));\n \t}\n \n \tif (!cached && !tpatch)\n@@ -3074,9 +3082,9 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s\n \tif (!patch->old_mode)\n \t\tpatch->old_mode = st_mode;\n \tif ((st_mode ^ patch->old_mode) & S_IFMT)\n-\t\treturn error(\"%s: wrong type\", old_name);\n+\t\treturn error(_(\"%s: wrong type\"), old_name);\n \tif (st_mode != patch->old_mode)\n-\t\twarning(\"%s has type %o, expected %o\",\n+\t\twarning(_(\"%s has type %o, expected %o\"),\n \t\t\told_name, st_mode, patch->old_mode);\n \tif (!patch->new_mode && !patch->is_delete)\n \t\tpatch->new_mode = st_mode;\n@@ -3126,7 +3134,7 @@ static int check_patch(struct patch *patch)\n \t\tif (check_index &&\n \t\t    cache_name_pos(new_name, strlen(new_name)) >= 0 &&\n \t\t    !ok_if_exists)\n-\t\t\treturn error(\"%s: already exists in index\", new_name);\n+\t\t\treturn error(_(\"%s: already exists in index\"), new_name);\n \t\tif (!cached) {\n \t\t\tint err = check_to_create_blob(new_name, ok_if_exists);\n \t\t\tif (err)\n@@ -3145,13 +3153,13 @@ static int check_patch(struct patch *patch)\n \t\tif (!patch->new_mode)\n \t\t\tpatch->new_mode = patch->old_mode;\n \t\tif ((patch->old_mode ^ patch->new_mode) & S_IFMT)\n-\t\t\treturn error(\"new mode (%o) of %s does not match old mode (%o)%s%s\",\n+\t\t\treturn error(_(\"new mode (%o) of %s does not match old mode (%o)%s%s\"),\n \t\t\t\tpatch->new_mode, new_name, patch->old_mode,\n \t\t\t\tsame ? \"\" : \" of \", same ? \"\" : old_name);\n \t}\n \n \tif (apply_data(patch, &st, ce) < 0)\n-\t\treturn error(\"%s: patch does not apply\", name);\n+\t\treturn error(_(\"%s: patch does not apply\"), name);\n \tpatch->rejected = 0;\n \treturn 0;\n }\n@@ -3219,7 +3227,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n \n \t\tce = make_cache_entry(patch->old_mode, sha1_ptr, name, 0, 0);\n \t\tif (!ce)\n-\t\t\tdie(\"make_cache_entry failed for path '%s'\", name);\n+\t\t\tdie(_(\"make_cache_entry failed for path '%s'\"), name);\n \t\tif (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD))\n \t\t\tdie (\"Could not add %s to temporary index\", name);\n \t}\n@@ -3362,7 +3370,7 @@ static void remove_file(struct patch *patch, int rmdir_empty)\n {\n \tif (update_index) {\n \t\tif (remove_file_from_cache(patch->old_name) < 0)\n-\t\t\tdie(\"unable to remove %s from index\", patch->old_name);\n+\t\t\tdie(_(\"unable to remove %s from index\"), patch->old_name);\n \t}\n \tif (!cached) {\n \t\tif (!remove_or_warn(patch->old_mode, patch->old_name) && rmdir_empty) {\n@@ -3389,19 +3397,19 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned\n \t\tconst char *s = buf;\n \n \t\tif (get_sha1_hex(s + strlen(\"Subproject commit \"), ce->sha1))\n-\t\t\tdie(\"corrupt patch for subproject %s\", path);\n+\t\t\tdie(_(\"corrupt patch for subproject %s\"), path);\n \t} else {\n \t\tif (!cached) {\n \t\t\tif (lstat(path, &st) < 0)\n-\t\t\t\tdie_errno(\"unable to stat newly created file '%s'\",\n+\t\t\t\tdie_errno(_(\"unable to stat newly created file '%s'\"),\n \t\t\t\t\t  path);\n \t\t\tfill_stat_cache_info(ce, &st);\n \t\t}\n \t\tif (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)\n-\t\t\tdie(\"unable to create backing store for newly created file %s\", path);\n+\t\t\tdie(_(\"unable to create backing store for newly created file %s\"), path);\n \t}\n \tif (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)\n-\t\tdie(\"unable to add cache entry for %s\", path);\n+\t\tdie(_(\"unable to add cache entry for %s\"), path);\n }\n \n static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)\n@@ -3434,7 +3442,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,\n \tstrbuf_release(&nbuf);\n \n \tif (close(fd) < 0)\n-\t\tdie_errno(\"closing file '%s'\", path);\n+\t\tdie_errno(_(\"closing file '%s'\"), path);\n \treturn 0;\n }\n \n@@ -3483,7 +3491,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned\n \t\t\t++nr;\n \t\t}\n \t}\n-\tdie_errno(\"unable to write file '%s' mode %o\", path, mode);\n+\tdie_errno(_(\"unable to write file '%s' mode %o\"), path, mode);\n }\n \n static void create_file(struct patch *patch)\n@@ -3546,7 +3554,7 @@ static int write_out_one_reject(struct patch *patch)\n \t * contents are marked \"rejected\" at the patch level.\n \t */\n \tif (!patch->new_name)\n-\t\tdie(\"internal error\");\n+\t\tdie(_(\"internal error\"));\n \n \t/* Say this even without --verbose */\n \tsay_patch_name(stderr, \"Applying patch \", patch, \" with\");\n@@ -3555,7 +3563,7 @@ static int write_out_one_reject(struct patch *patch)\n \tcnt = strlen(patch->new_name);\n \tif (ARRAY_SIZE(namebuf) <= cnt + 5) {\n \t\tcnt = ARRAY_SIZE(namebuf) - 5;\n-\t\twarning(\"truncating .rej filename to %.*s.rej\",\n+\t\twarning(_(\"truncating .rej filename to %.*s.rej\"),\n \t\t\tcnt - 1, patch->new_name);\n \t}\n \tmemcpy(namebuf, patch->new_name, cnt);\n@@ -3563,7 +3571,7 @@ static int write_out_one_reject(struct patch *patch)\n \n \trej = fopen(namebuf, \"w\");\n \tif (!rej)\n-\t\treturn error(\"cannot open %s: %s\", namebuf, strerror(errno));\n+\t\treturn error(_(\"cannot open %s: %s\"), namebuf, strerror(errno));\n \n \t/* Normal git tools never deal with .rej, so do not pretend\n \t * this is a git patch by saying --git nor give extended\n@@ -3576,10 +3584,10 @@ static int write_out_one_reject(struct patch *patch)\n \t     frag;\n \t     cnt++, frag = frag->next) {\n \t\tif (!frag->rejected) {\n-\t\t\tfprintf(stderr, \"Hunk #%d applied cleanly.\\n\", cnt);\n+\t\t\tfprintf_ln(stderr, _(\"Hunk #%d applied cleanly.\"), cnt);\n \t\t\tcontinue;\n \t\t}\n-\t\tfprintf(stderr, \"Rejected hunk #%d.\\n\", cnt);\n+\t\tfprintf_ln(stderr, _(\"Rejected hunk #%d.\"), cnt);\n \t\tfprintf(rej, \"%.*s\", frag->size, frag->patch);\n \t\tif (frag->patch[frag->size-1] != '\\n')\n \t\t\tfputc('\\n', rej);\n@@ -3720,7 +3728,7 @@ static int apply_patch(int fd, const char *filename, int options)\n \t}\n \n \tif (!list && !skipped_patch)\n-\t\tdie(\"unrecognized input\");\n+\t\tdie(_(\"unrecognized input\"));\n \n \tif (whitespace_error && (ws_error_action == die_on_ws_error))\n \t\tapply = 0;\n@@ -3731,7 +3739,7 @@ static int apply_patch(int fd, const char *filename, int options)\n \n \tif (check_index) {\n \t\tif (read_cache() < 0)\n-\t\t\tdie(\"unable to read index file\");\n+\t\t\tdie(_(\"unable to read index file\"));\n \t}\n \n \tif ((check || apply) &&\n@@ -3924,10 +3932,10 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tif (!force_apply && (diffstat || numstat || summary || check || fake_ancestor))\n \t\tapply = 0;\n \tif (check_index && is_not_gitdir)\n-\t\tdie(\"--index outside a repository\");\n+\t\tdie(_(\"--index outside a repository\"));\n \tif (cached) {\n \t\tif (is_not_gitdir)\n-\t\t\tdie(\"--cached outside a repository\");\n+\t\t\tdie(_(\"--cached outside a repository\"));\n \t\tcheck_index = 1;\n \t}\n \tfor (i = 0; i < argc; i++) {\n@@ -3943,7 +3951,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \n \t\tfd = open(arg, O_RDONLY);\n \t\tif (fd < 0)\n-\t\t\tdie_errno(\"can't open patch '%s'\", arg);\n+\t\t\tdie_errno(_(\"can't open patch '%s'\"), arg);\n \t\tread_stdin = 0;\n \t\tset_default_whitespace_mode(whitespace_option);\n \t\terrs |= apply_patch(fd, arg, options);\n@@ -3957,32 +3965,32 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t    squelch_whitespace_errors < whitespace_error) {\n \t\t\tint squelched =\n \t\t\t\twhitespace_error - squelch_whitespace_errors;\n-\t\t\twarning(\"squelched %d \"\n-\t\t\t\t\"whitespace error%s\",\n-\t\t\t\tsquelched,\n-\t\t\t\tsquelched == 1 ? \"\" : \"s\");\n+\t\t\twarning(Q_(\"squelched %d whitespace error\",\n+\t\t\t\t   \"squelched %d whitespace errors\",\n+\t\t\t\t   squelched),\n+\t\t\t\tsquelched);\n \t\t}\n \t\tif (ws_error_action == die_on_ws_error)\n-\t\t\tdie(\"%d line%s add%s whitespace errors.\",\n-\t\t\t    whitespace_error,\n-\t\t\t    whitespace_error == 1 ? \"\" : \"s\",\n-\t\t\t    whitespace_error == 1 ? \"s\" : \"\");\n+\t\t\tdie(Q_(\"%d line adds whitespace errors.\",\n+\t\t\t       \"%d lines add whitespace errors.\",\n+\t\t\t       whitespace_error),\n+\t\t\t    whitespace_error);\n \t\tif (applied_after_fixing_ws && apply)\n \t\t\twarning(\"%d line%s applied after\"\n \t\t\t\t\" fixing whitespace errors.\",\n \t\t\t\tapplied_after_fixing_ws,\n \t\t\t\tapplied_after_fixing_ws == 1 ? \"\" : \"s\");\n \t\telse if (whitespace_error)\n-\t\t\twarning(\"%d line%s add%s whitespace errors.\",\n-\t\t\t\twhitespace_error,\n-\t\t\t\twhitespace_error == 1 ? \"\" : \"s\",\n-\t\t\t\twhitespace_error == 1 ? \"s\" : \"\");\n+\t\t\twarning(Q_(\"%d line adds whitespace errors.\",\n+\t\t\t\t   \"%d lines add whitespace errors.\",\n+\t\t\t\t   whitespace_error),\n+\t\t\t\twhitespace_error);\n \t}\n \n \tif (update_index) {\n \t\tif (write_cache(newfd, active_cache, active_nr) ||\n \t\t    commit_locked_index(&lock_file))\n-\t\t\tdie(\"Unable to write new index file\");\n+\t\t\tdie(_(\"Unable to write new index file\"));\n \t}\n \n \treturn !!errs;\n-- \n1.7.8.36.g69ee2\n"},{"id":"189872","messageId":"1335184230-8870-9-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 08/10] i18n: apply: update say_patch_name to give translators complete sentence","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:28Z","receivedAt":"2012-04-23T12:30:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/apply.c |   32 ++++++++++++++++++++------------\n 1 files changed, 20 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 4bb6354..c768b7f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -335,22 +335,25 @@ static void clear_image(struct image *image)\n \timage->len = 0;\n }\n \n-static void say_patch_name(FILE *output, const char *pre,\n-\t\t\t   struct patch *patch, const char *post)\n+/* fmt must contain _one_ %s and no other substitution */\n+static void say_patch_name(FILE *output, const char *fmt, struct patch *patch)\n {\n-\tfputs(pre, output);\n+\tstruct strbuf sb = STRBUF_INIT;\n+\n \tif (patch->old_name && patch->new_name &&\n \t    strcmp(patch->old_name, patch->new_name)) {\n-\t\tquote_c_style(patch->old_name, NULL, output, 0);\n-\t\tfputs(\" => \", output);\n-\t\tquote_c_style(patch->new_name, NULL, output, 0);\n+\t\tquote_c_style(patch->old_name, &sb, NULL, 0);\n+\t\tstrbuf_addstr(&sb, \" => \");\n+\t\tquote_c_style(patch->new_name, &sb, NULL, 0);\n \t} else {\n \t\tconst char *n = patch->new_name;\n \t\tif (!n)\n \t\t\tn = patch->old_name;\n-\t\tquote_c_style(n, NULL, output, 0);\n+\t\tquote_c_style(n, &sb, NULL, 0);\n \t}\n-\tfputs(post, output);\n+\tfprintf(output, fmt, sb.buf);\n+\tfputc('\\n', output);\n+\tstrbuf_release(&sb);\n }\n \n #define CHUNKSIZE (8192)\n@@ -3172,7 +3175,7 @@ static int check_patch_list(struct patch *patch)\n \twhile (patch) {\n \t\tif (apply_verbosely)\n \t\t\tsay_patch_name(stderr,\n-\t\t\t\t       \"Checking patch \", patch, \"...\\n\");\n+\t\t\t\t       _(\"Checking patch %s...\"), patch);\n \t\terr |= check_patch(patch);\n \t\tpatch = patch->next;\n \t}\n@@ -3536,6 +3539,7 @@ static int write_out_one_reject(struct patch *patch)\n \tchar namebuf[PATH_MAX];\n \tstruct fragment *frag;\n \tint cnt = 0;\n+\tstruct strbuf sb = STRBUF_INIT;\n \n \tfor (cnt = 0, frag = patch->fragments; frag; frag = frag->next) {\n \t\tif (!frag->rejected)\n@@ -3546,7 +3550,7 @@ static int write_out_one_reject(struct patch *patch)\n \tif (!cnt) {\n \t\tif (apply_verbosely)\n \t\t\tsay_patch_name(stderr,\n-\t\t\t\t       \"Applied patch \", patch, \" cleanly.\\n\");\n+\t\t\t\t       _(\"Applied patch %s cleanly.\"), patch);\n \t\treturn 0;\n \t}\n \n@@ -3557,8 +3561,12 @@ static int write_out_one_reject(struct patch *patch)\n \t\tdie(_(\"internal error\"));\n \n \t/* Say this even without --verbose */\n-\tsay_patch_name(stderr, \"Applying patch \", patch, \" with\");\n-\tfprintf(stderr, \" %d rejects...\\n\", cnt);\n+\tstrbuf_addf(&sb, Q_(\"Applying patch %%s with %d reject...\",\n+\t\t\t    \"Applying patch %%s with %d rejects...\",\n+\t\t\t    cnt),\n+\t\t    cnt);\n+\tsay_patch_name(stderr, sb.buf, patch);\n+\tstrbuf_release(&sb);\n \n \tcnt = strlen(patch->new_name);\n \tif (ARRAY_SIZE(namebuf) <= cnt + 5) {\n-- \n1.7.8.36.g69ee2\n"},{"id":"189873","messageId":"1335184230-8870-10-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 09/10] i18n: index-pack: mark strings for translation","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:29Z","receivedAt":"2012-04-23T12:30:29Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/index-pack.c |  125 +++++++++++++++++++++++++++-----------------------\n 1 files changed, 68 insertions(+), 57 deletions(-)\n\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex dd1c5c9..83555e5 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -81,7 +81,7 @@ static int mark_link(struct object *obj, int type, void *data)\n \t\treturn -1;\n \n \tif (type != OBJ_ANY && obj->type != type)\n-\t\tdie(\"object type mismatch at %s\", sha1_to_hex(obj->sha1));\n+\t\tdie(_(\"object type mismatch at %s\"), sha1_to_hex(obj->sha1));\n \n \tobj->flags |= FLAG_LINK;\n \treturn 0;\n@@ -101,7 +101,7 @@ static void check_object(struct object *obj)\n \t\tunsigned long size;\n \t\tint type = sha1_object_info(obj->sha1, &size);\n \t\tif (type != obj->type || type <= 0)\n-\t\t\tdie(\"object of unexpected type\");\n+\t\t\tdie(_(\"object of unexpected type\"));\n \t\tobj->flags |= FLAG_CHECKED;\n \t\treturn;\n \t}\n@@ -138,15 +138,18 @@ static void *fill(int min)\n \tif (min <= input_len)\n \t\treturn input_buffer + input_offset;\n \tif (min > sizeof(input_buffer))\n-\t\tdie(\"cannot fill %d bytes\", min);\n+\t\tdie(Q_(\"cannot fill %d byte\",\n+\t\t       \"cannot fill %d bytes\",\n+\t\t       min),\n+\t\t    min);\n \tflush();\n \tdo {\n \t\tssize_t ret = xread(input_fd, input_buffer + input_len,\n \t\t\t\tsizeof(input_buffer) - input_len);\n \t\tif (ret <= 0) {\n \t\t\tif (!ret)\n-\t\t\t\tdie(\"early EOF\");\n-\t\t\tdie_errno(\"read error on input\");\n+\t\t\t\tdie(_(\"early EOF\"));\n+\t\t\tdie_errno(_(\"read error on input\"));\n \t\t}\n \t\tinput_len += ret;\n \t\tif (from_stdin)\n@@ -158,14 +161,14 @@ static void *fill(int min)\n static void use(int bytes)\n {\n \tif (bytes > input_len)\n-\t\tdie(\"used more bytes than were available\");\n+\t\tdie(_(\"used more bytes than were available\"));\n \tinput_crc32 = crc32(input_crc32, input_buffer + input_offset, bytes);\n \tinput_len -= bytes;\n \tinput_offset += bytes;\n \n \t/* make sure off_t is sufficiently large not to wrap */\n \tif (signed_add_overflows(consumed_bytes, bytes))\n-\t\tdie(\"pack too large for current definition of off_t\");\n+\t\tdie(_(\"pack too large for current definition of off_t\"));\n \tconsumed_bytes += bytes;\n }\n \n@@ -181,12 +184,12 @@ static const char *open_pack_file(const char *pack_name)\n \t\t} else\n \t\t\toutput_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);\n \t\tif (output_fd < 0)\n-\t\t\tdie_errno(\"unable to create '%s'\", pack_name);\n+\t\t\tdie_errno(_(\"unable to create '%s'\"), pack_name);\n \t\tpack_fd = output_fd;\n \t} else {\n \t\tinput_fd = open(pack_name, O_RDONLY);\n \t\tif (input_fd < 0)\n-\t\t\tdie_errno(\"cannot open packfile '%s'\", pack_name);\n+\t\t\tdie_errno(_(\"cannot open packfile '%s'\"), pack_name);\n \t\toutput_fd = -1;\n \t\tpack_fd = input_fd;\n \t}\n@@ -200,7 +203,7 @@ static void parse_pack_header(void)\n \n \t/* Header consistency check */\n \tif (hdr->hdr_signature != htonl(PACK_SIGNATURE))\n-\t\tdie(\"pack signature mismatch\");\n+\t\tdie(_(\"pack signature mismatch\"));\n \tif (!pack_version_ok(hdr->hdr_version))\n \t\tdie(\"pack version %\"PRIu32\" unsupported\",\n \t\t\tntohl(hdr->hdr_version));\n@@ -220,7 +223,7 @@ static NORETURN void bad_object(unsigned long offset, const char *format, ...)\n \tva_start(params, format);\n \tvsnprintf(buf, sizeof(buf), format, params);\n \tva_end(params);\n-\tdie(\"pack has bad object at offset %lu: %s\", offset, buf);\n+\tdie(_(\"pack has bad object at offset %lu: %s\"), offset, buf);\n }\n \n static struct base_data *alloc_base_data(void)\n@@ -294,7 +297,7 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)\n \t\tuse(input_len - stream.avail_in);\n \t} while (status == Z_OK);\n \tif (stream.total_out != size || status != Z_STREAM_END)\n-\t\tbad_object(offset, \"inflate returned %d\", status);\n+\t\tbad_object(offset, _(\"inflate returned %d\"), status);\n \tgit_inflate_end(&stream);\n \treturn buf;\n }\n@@ -339,7 +342,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_\n \t\twhile (c & 128) {\n \t\t\tbase_offset += 1;\n \t\t\tif (!base_offset || MSB(base_offset, 7))\n-\t\t\t\tbad_object(obj->idx.offset, \"offset value overflow for delta base object\");\n+\t\t\t\tbad_object(obj->idx.offset, _(\"offset value overflow for delta base object\"));\n \t\t\tp = fill(1);\n \t\t\tc = *p;\n \t\t\tuse(1);\n@@ -347,7 +350,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_\n \t\t}\n \t\tdelta_base->offset = obj->idx.offset - base_offset;\n \t\tif (delta_base->offset <= 0 || delta_base->offset >= obj->idx.offset)\n-\t\t\tbad_object(obj->idx.offset, \"delta base offset is out of bound\");\n+\t\t\tbad_object(obj->idx.offset, _(\"delta base offset is out of bound\"));\n \t\tbreak;\n \tcase OBJ_COMMIT:\n \tcase OBJ_TREE:\n@@ -355,7 +358,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_\n \tcase OBJ_TAG:\n \t\tbreak;\n \tdefault:\n-\t\tbad_object(obj->idx.offset, \"unknown object type %d\", obj->type);\n+\t\tbad_object(obj->idx.offset, _(\"unknown object type %d\"), obj->type);\n \t}\n \tobj->hdr_size = consumed_bytes - obj->idx.offset;\n \n@@ -384,9 +387,12 @@ static void *get_data_from_pack(struct object_entry *obj)\n \t\tssize_t n = (len < 64*1024) ? len : 64*1024;\n \t\tn = pread(pack_fd, inbuf, n, from);\n \t\tif (n < 0)\n-\t\t\tdie_errno(\"cannot pread pack file\");\n+\t\t\tdie_errno(_(\"cannot pread pack file\"));\n \t\tif (!n)\n-\t\t\tdie(\"premature end of pack file, %lu bytes missing\", len);\n+\t\t\tdie(Q_(\"premature end of pack file, %lu byte missing\",\n+\t\t\t       \"premature end of pack file, %lu bytes missing\",\n+\t\t\t       len),\n+\t\t\t    len);\n \t\tfrom += n;\n \t\tlen -= n;\n \t\tstream.next_in = inbuf;\n@@ -396,7 +402,7 @@ static void *get_data_from_pack(struct object_entry *obj)\n \n \t/* This has been inflated OK when first encountered, so... */\n \tif (status != Z_STREAM_END || stream.total_out != obj->size)\n-\t\tdie(\"serious inflate inconsistency\");\n+\t\tdie(_(\"serious inflate inconsistency\"));\n \n \tgit_inflate_end(&stream);\n \tfree(inbuf);\n@@ -467,10 +473,10 @@ static void sha1_object(const void *data, unsigned long size,\n \t\tunsigned long has_size;\n \t\thas_data = read_sha1_file(sha1, &has_type, &has_size);\n \t\tif (!has_data)\n-\t\t\tdie(\"cannot read existing object %s\", sha1_to_hex(sha1));\n+\t\t\tdie(_(\"cannot read existing object %s\"), sha1_to_hex(sha1));\n \t\tif (size != has_size || type != has_type ||\n \t\t    memcmp(data, has_data, size) != 0)\n-\t\t\tdie(\"SHA1 COLLISION FOUND WITH %s !\", sha1_to_hex(sha1));\n+\t\t\tdie(_(\"SHA1 COLLISION FOUND WITH %s !\"), sha1_to_hex(sha1));\n \t\tfree(has_data);\n \t}\n \tif (strict) {\n@@ -479,7 +485,7 @@ static void sha1_object(const void *data, unsigned long size,\n \t\t\tif (blob)\n \t\t\t\tblob->object.flags |= FLAG_CHECKED;\n \t\t\telse\n-\t\t\t\tdie(\"invalid blob object %s\", sha1_to_hex(sha1));\n+\t\t\t\tdie(_(\"invalid blob object %s\"), sha1_to_hex(sha1));\n \t\t} else {\n \t\t\tstruct object *obj;\n \t\t\tint eaten;\n@@ -491,11 +497,11 @@ static void sha1_object(const void *data, unsigned long size,\n \t\t\t */\n \t\t\tobj = parse_object_buffer(sha1, type, size, buf, &eaten);\n \t\t\tif (!obj)\n-\t\t\t\tdie(\"invalid %s\", typename(type));\n+\t\t\t\tdie(_(\"invalid %s\"), typename(type));\n \t\t\tif (fsck_object(obj, 1, fsck_error_function))\n-\t\t\t\tdie(\"Error in object\");\n+\t\t\t\tdie(_(\"Error in object\"));\n \t\t\tif (fsck_walk(obj, mark_link, NULL))\n-\t\t\t\tdie(\"Not all child objects of %s are reachable\", sha1_to_hex(obj->sha1));\n+\t\t\t\tdie(_(\"Not all child objects of %s are reachable\"), sha1_to_hex(obj->sha1));\n \n \t\t\tif (obj->type == OBJ_TREE) {\n \t\t\t\tstruct tree *item = (struct tree *) obj;\n@@ -567,7 +573,7 @@ static void *get_base_data(struct base_data *c)\n \t\t\t\t&c->size);\n \t\t\tfree(raw);\n \t\t\tif (!c->data)\n-\t\t\t\tbad_object(obj->idx.offset, \"failed to apply delta\");\n+\t\t\t\tbad_object(obj->idx.offset, _(\"failed to apply delta\"));\n \t\t\tbase_cache_used += c->size;\n \t\t\tprune_base_data(c);\n \t\t}\n@@ -593,7 +599,7 @@ static void resolve_delta(struct object_entry *delta_obj,\n \t\t\t\t   delta_data, delta_obj->size, &result->size);\n \tfree(delta_data);\n \tif (!result->data)\n-\t\tbad_object(delta_obj->idx.offset, \"failed to apply delta\");\n+\t\tbad_object(delta_obj->idx.offset, _(\"failed to apply delta\"));\n \tsha1_object(result->data, result->size, delta_obj->real_type,\n \t\t    delta_obj->idx.sha1);\n \tnr_resolved_deltas++;\n@@ -697,7 +703,7 @@ static void parse_pack_objects(unsigned char *sha1)\n \t */\n \tif (verbose)\n \t\tprogress = start_progress(\n-\t\t\t\tfrom_stdin ? \"Receiving objects\" : \"Indexing objects\",\n+\t\t\t\tfrom_stdin ? _(\"Receiving objects\") : _(\"Indexing objects\"),\n \t\t\t\tnr_objects);\n \tfor (i = 0; i < nr_objects; i++) {\n \t\tstruct object_entry *obj = &objects[i];\n@@ -719,15 +725,15 @@ static void parse_pack_objects(unsigned char *sha1)\n \tflush();\n \tgit_SHA1_Final(sha1, &input_ctx);\n \tif (hashcmp(fill(20), sha1))\n-\t\tdie(\"pack is corrupted (SHA1 mismatch)\");\n+\t\tdie(_(\"pack is corrupted (SHA1 mismatch)\"));\n \tuse(20);\n \n \t/* If input_fd is a file, we should have reached its end now. */\n \tif (fstat(input_fd, &st))\n-\t\tdie_errno(\"cannot fstat packfile\");\n+\t\tdie_errno(_(\"cannot fstat packfile\"));\n \tif (S_ISREG(st.st_mode) &&\n \t\t\tlseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)\n-\t\tdie(\"pack has junk at the end\");\n+\t\tdie(_(\"pack has junk at the end\"));\n \n \tif (!nr_deltas)\n \t\treturn;\n@@ -745,7 +751,7 @@ static void parse_pack_objects(unsigned char *sha1)\n \t *   for some more deltas.\n \t */\n \tif (verbose)\n-\t\tprogress = start_progress(\"Resolving deltas\", nr_deltas);\n+\t\tprogress = start_progress(_(\"Resolving deltas\"), nr_deltas);\n \tfor (i = 0; i < nr_objects; i++) {\n \t\tstruct object_entry *obj = &objects[i];\n \t\tstruct base_data *base_obj = alloc_base_data();\n@@ -778,7 +784,7 @@ static int write_compressed(struct sha1file *f, void *in, unsigned int size)\n \t} while (status == Z_OK);\n \n \tif (status != Z_STREAM_END)\n-\t\tdie(\"unable to deflate appended object (%d)\", status);\n+\t\tdie(_(\"unable to deflate appended object (%d)\"), status);\n \tsize = stream.total_out;\n \tgit_deflate_end(&stream);\n \treturn size;\n@@ -857,7 +863,7 @@ static void fix_unresolved_deltas(struct sha1file *f, int nr_unresolved)\n \n \t\tif (check_sha1_signature(d->base.sha1, base_obj->data,\n \t\t\t\tbase_obj->size, typename(type)))\n-\t\t\tdie(\"local object %s is corrupt\", sha1_to_hex(d->base.sha1));\n+\t\t\tdie(_(\"local object %s is corrupt\"), sha1_to_hex(d->base.sha1));\n \t\tbase_obj->obj = append_obj_to_pack(f, d->base.sha1,\n \t\t\t\t\tbase_obj->data, base_obj->size, type);\n \t\tfind_unresolved_deltas(base_obj);\n@@ -881,7 +887,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,\n \t\tfsync_or_die(output_fd, curr_pack_name);\n \t\terr = close(output_fd);\n \t\tif (err)\n-\t\t\tdie_errno(\"error while closing pack file\");\n+\t\t\tdie_errno(_(\"error while closing pack file\"));\n \t}\n \n \tif (keep_msg) {\n@@ -894,7 +900,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,\n \n \t\tif (keep_fd < 0) {\n \t\t\tif (errno != EEXIST)\n-\t\t\t\tdie_errno(\"cannot write keep file '%s'\",\n+\t\t\t\tdie_errno(_(\"cannot write keep file '%s'\"),\n \t\t\t\t\t  keep_name);\n \t\t} else {\n \t\t\tif (keep_msg_len > 0) {\n@@ -902,7 +908,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,\n \t\t\t\twrite_or_die(keep_fd, \"\\n\", 1);\n \t\t\t}\n \t\t\tif (close(keep_fd) != 0)\n-\t\t\t\tdie_errno(\"cannot close written keep file '%s'\",\n+\t\t\t\tdie_errno(_(\"cannot close written keep file '%s'\"),\n \t\t\t\t    keep_name);\n \t\t\treport = \"keep\";\n \t\t}\n@@ -915,7 +921,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,\n \t\t\tfinal_pack_name = name;\n \t\t}\n \t\tif (move_temp_to_file(curr_pack_name, final_pack_name))\n-\t\t\tdie(\"cannot store pack file\");\n+\t\t\tdie(_(\"cannot store pack file\"));\n \t} else if (from_stdin)\n \t\tchmod(final_pack_name, 0444);\n \n@@ -926,7 +932,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,\n \t\t\tfinal_index_name = name;\n \t\t}\n \t\tif (move_temp_to_file(curr_index_name, final_index_name))\n-\t\t\tdie(\"cannot store index file\");\n+\t\t\tdie(_(\"cannot store index file\"));\n \t} else\n \t\tchmod(final_index_name, 0444);\n \n@@ -1015,9 +1021,9 @@ static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)\n \tstruct packed_git *p = add_packed_git(pack_name, strlen(pack_name), 1);\n \n \tif (!p)\n-\t\tdie(\"Cannot open existing pack file '%s'\", pack_name);\n+\t\tdie(_(\"Cannot open existing pack file '%s'\"), pack_name);\n \tif (open_pack_index(p))\n-\t\tdie(\"Cannot open existing pack idx file for '%s'\", pack_name);\n+\t\tdie(_(\"Cannot open existing pack idx file for '%s'\"), pack_name);\n \n \t/* Read the attributes from the existing idx file */\n \topts->version = p->index_version;\n@@ -1064,15 +1070,18 @@ static void show_pack_info(int stat_only)\n \t}\n \n \tif (baseobjects)\n-\t\tprintf(\"non delta: %d object%s\\n\",\n-\t\t       baseobjects, baseobjects > 1 ? \"s\" : \"\");\n+\t\tprintf_ln(Q_(\"non delta: %d object\",\n+\t\t\t     \"non delta: %d objects\",\n+\t\t\t     baseobjects),\n+\t\t\t  baseobjects);\n \tfor (i = 0; i < deepest_delta; i++) {\n \t\tif (!chain_histogram[i])\n \t\t\tcontinue;\n-\t\tprintf(\"chain length = %d: %lu object%s\\n\",\n-\t\t       i + 1,\n-\t\t       chain_histogram[i],\n-\t\t       chain_histogram[i] > 1 ? \"s\" : \"\");\n+\t\tprintf_ln(Q_(\"chain length = %d: %lu object\",\n+\t\t\t     \"chain length = %d: %lu objects\",\n+\t\t\t     chain_histogram[i]),\n+\t\t\t  i + 1,\n+\t\t\t  chain_histogram[i]);\n \t}\n }\n \n@@ -1095,7 +1104,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \treset_pack_idx_option(&opts);\n \tgit_config(git_index_pack_config, &opts);\n \tif (prefix && chdir(prefix))\n-\t\tdie(\"Cannot come back to cwd\");\n+\t\tdie(_(\"Cannot come back to cwd\"));\n \n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n@@ -1128,10 +1137,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \t\t\t\thdr->hdr_signature = htonl(PACK_SIGNATURE);\n \t\t\t\thdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));\n \t\t\t\tif (*c != ',')\n-\t\t\t\t\tdie(\"bad %s\", arg);\n+\t\t\t\t\tdie(_(\"bad %s\"), arg);\n \t\t\t\thdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));\n \t\t\t\tif (*c)\n-\t\t\t\t\tdie(\"bad %s\", arg);\n+\t\t\t\t\tdie(_(\"bad %s\"), arg);\n \t\t\t\tinput_len = sizeof(*hdr);\n \t\t\t} else if (!strcmp(arg, \"-v\")) {\n \t\t\t\tverbose = 1;\n@@ -1143,11 +1152,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \t\t\t\tchar *c;\n \t\t\t\topts.version = strtoul(arg + 16, &c, 10);\n \t\t\t\tif (opts.version > 2)\n-\t\t\t\t\tdie(\"bad %s\", arg);\n+\t\t\t\t\tdie(_(\"bad %s\"), arg);\n \t\t\t\tif (*c == ',')\n \t\t\t\t\topts.off32_limit = strtoul(c+1, &c, 0);\n \t\t\t\tif (*c || opts.off32_limit & 0x80000000)\n-\t\t\t\t\tdie(\"bad %s\", arg);\n+\t\t\t\t\tdie(_(\"bad %s\"), arg);\n \t\t\t} else\n \t\t\t\tusage(index_pack_usage);\n \t\t\tcontinue;\n@@ -1161,11 +1170,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \tif (!pack_name && !from_stdin)\n \t\tusage(index_pack_usage);\n \tif (fix_thin_pack && !from_stdin)\n-\t\tdie(\"--fix-thin cannot be used without --stdin\");\n+\t\tdie(_(\"--fix-thin cannot be used without --stdin\"));\n \tif (!index_name && pack_name) {\n \t\tint len = strlen(pack_name);\n \t\tif (!has_extension(pack_name, \".pack\"))\n-\t\t\tdie(\"packfile name '%s' does not end with '.pack'\",\n+\t\t\tdie(_(\"packfile name '%s' does not end with '.pack'\"),\n \t\t\t    pack_name);\n \t\tindex_name_buf = xmalloc(len);\n \t\tmemcpy(index_name_buf, pack_name, len - 5);\n@@ -1175,7 +1184,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \tif (keep_msg && !keep_name && pack_name) {\n \t\tint len = strlen(pack_name);\n \t\tif (!has_extension(pack_name, \".pack\"))\n-\t\t\tdie(\"packfile name '%s' does not end with '.pack'\",\n+\t\t\tdie(_(\"packfile name '%s' does not end with '.pack'\"),\n \t\t\t    pack_name);\n \t\tkeep_name_buf = xmalloc(len);\n \t\tmemcpy(keep_name_buf, pack_name, len - 5);\n@@ -1184,7 +1193,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \t}\n \tif (verify) {\n \t\tif (!index_name)\n-\t\t\tdie(\"--verify with no packfile name given\");\n+\t\t\tdie(_(\"--verify with no packfile name given\"));\n \t\tread_idx_option(&opts, index_name);\n \t\topts.flags |= WRITE_IDX_VERIFY | WRITE_IDX_STRICT;\n \t}\n@@ -1208,7 +1217,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \t\t\tint nr_unresolved = nr_deltas - nr_resolved_deltas;\n \t\t\tint nr_objects_initial = nr_objects;\n \t\t\tif (nr_unresolved <= 0)\n-\t\t\t\tdie(\"confusion beyond insanity\");\n+\t\t\t\tdie(_(\"confusion beyond insanity\"));\n \t\t\tobjects = xrealloc(objects,\n \t\t\t\t\t   (nr_objects + nr_unresolved + 1)\n \t\t\t\t\t   * sizeof(*objects));\n@@ -1227,7 +1236,9 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)\n \t\t\t\t    \"(disk corruption?)\", curr_pack);\n \t\t}\n \t\tif (nr_deltas != nr_resolved_deltas)\n-\t\t\tdie(\"pack has %d unresolved deltas\",\n+\t\t\tdie(Q_(\"pack has %d unresolved delta\",\n+\t\t\t       \"pack has %d unresolved deltas\",\n+\t\t\t       nr_deltas - nr_resolved_deltas),\n \t\t\t    nr_deltas - nr_resolved_deltas);\n \t}\n \tfree(deltas);\n-- \n1.7.8.36.g69ee2\n"},{"id":"189874","messageId":"1335184230-8870-11-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 10/10] i18n: bundle: mark strings for translation","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-23T12:30:30Z","receivedAt":"2012-04-23T12:30:30Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n bundle.c |   38 +++++++++++++++++++++-----------------\n 1 files changed, 21 insertions(+), 17 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex d9cfd90..6d21c77 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -33,7 +33,7 @@ static int parse_bundle_header(int fd, struct bundle_header *header,\n \tif (strbuf_getwholeline_fd(&buf, fd, '\\n') ||\n \t    strcmp(buf.buf, bundle_signature)) {\n \t\tif (report_path)\n-\t\t\terror(\"'%s' does not look like a v2 bundle file\",\n+\t\t\terror(_(\"'%s' does not look like a v2 bundle file\"),\n \t\t\t      report_path);\n \t\tstatus = -1;\n \t\tgoto abort;\n@@ -60,7 +60,7 @@ static int parse_bundle_header(int fd, struct bundle_header *header,\n \t\t    (40 <= buf.len && !isspace(buf.buf[40])) ||\n \t\t    (!is_prereq && buf.len <= 40)) {\n \t\t\tif (report_path)\n-\t\t\t\terror(\"unrecognized header: %s%s (%d)\",\n+\t\t\t\terror(_(\"unrecognized header: %s%s (%d)\"),\n \t\t\t\t      (is_prereq ? \"-\" : \"\"), buf.buf, (int)buf.len);\n \t\t\tstatus = -1;\n \t\t\tbreak;\n@@ -86,7 +86,7 @@ int read_bundle_header(const char *path, struct bundle_header *header)\n \tint fd = open(path, O_RDONLY);\n \n \tif (fd < 0)\n-\t\treturn error(\"could not open '%s'\", path);\n+\t\treturn error(_(\"could not open '%s'\"), path);\n \treturn parse_bundle_header(fd, header, path);\n }\n \n@@ -137,7 +137,7 @@ int verify_bundle(struct bundle_header *header, int verbose)\n \tstruct object_array refs;\n \tstruct commit *commit;\n \tint i, ret = 0, req_nr;\n-\tconst char *message = \"Repository lacks these prerequisite commits:\";\n+\tconst char *message = _(\"Repository lacks these prerequisite commits:\");\n \n \tinit_revisions(&revs, NULL);\n \tfor (i = 0; i < p->nr; i++) {\n@@ -161,7 +161,7 @@ int verify_bundle(struct bundle_header *header, int verbose)\n \trevs.leak_pending = 1;\n \n \tif (prepare_revision_walk(&revs))\n-\t\tdie(\"revision walk setup failed\");\n+\t\tdie(_(\"revision walk setup failed\"));\n \n \ti = req_nr;\n \twhile (i && (commit = get_revision(&revs)))\n@@ -183,12 +183,16 @@ int verify_bundle(struct bundle_header *header, int verbose)\n \t\tstruct ref_list *r;\n \n \t\tr = &header->references;\n-\t\tprintf(\"The bundle contains %d ref%s\\n\",\n-\t\t       r->nr, (1 < r->nr) ? \"s\" : \"\");\n+\t\tprintf_ln(Q_(\"The bundle contains %d ref\",\n+\t\t\t     \"The bundle contains %d refs\",\n+\t\t\t     r->nr),\n+\t\t\t  r->nr);\n \t\tlist_refs(r, 0, NULL);\n \t\tr = &header->prerequisites;\n-\t\tprintf(\"The bundle requires these %d ref%s\\n\",\n-\t\t       r->nr, (1 < r->nr) ? \"s\" : \"\");\n+\t\tprintf_ln(Q_(\"The bundle requires this ref\",\n+\t\t\t     \"The bundle requires these %d refs\",\n+\t\t\t     r->nr),\n+\t\t\t  r->nr);\n \t\tlist_refs(r, 0, NULL);\n \t}\n \treturn ret;\n@@ -283,13 +287,13 @@ int create_bundle(struct bundle_header *header, const char *path,\n \tstrbuf_release(&buf);\n \tfclose(rls_fout);\n \tif (finish_command(&rls))\n-\t\treturn error(\"rev-list died\");\n+\t\treturn error(_(\"rev-list died\"));\n \n \t/* write references */\n \targc = setup_revisions(argc, argv, &revs, NULL);\n \n \tif (argc > 1)\n-\t\treturn error(\"unrecognized argument: %s'\", argv[1]);\n+\t\treturn error(_(\"unrecognized argument: %s'\"), argv[1]);\n \n \tobject_array_remove_duplicates(&revs.pending);\n \n@@ -324,7 +328,7 @@ int create_bundle(struct bundle_header *header, const char *path,\n \t\t * constraints.\n \t\t */\n \t\tif (!(e->item->flags & SHOWN) && e->item->type == OBJ_COMMIT) {\n-\t\t\twarning(\"ref '%s' is excluded by the rev-list options\",\n+\t\t\twarning(_(\"ref '%s' is excluded by the rev-list options\"),\n \t\t\t\te->name);\n \t\t\tfree(ref);\n \t\t\tcontinue;\n@@ -369,7 +373,7 @@ int create_bundle(struct bundle_header *header, const char *path,\n \t\tfree(ref);\n \t}\n \tif (!ref_count)\n-\t\tdie (\"Refusing to create empty bundle.\");\n+\t\tdie(_(\"Refusing to create empty bundle.\"));\n \n \t/* end header */\n \twrite_or_die(bundle_fd, \"\\n\", 1);\n@@ -387,7 +391,7 @@ int create_bundle(struct bundle_header *header, const char *path,\n \trls.out = bundle_fd;\n \trls.git_cmd = 1;\n \tif (start_command(&rls))\n-\t\treturn error(\"Could not spawn pack-objects\");\n+\t\treturn error(_(\"Could not spawn pack-objects\"));\n \n \t/*\n \t * start_command closed bundle_fd if it was > 1\n@@ -405,10 +409,10 @@ int create_bundle(struct bundle_header *header, const char *path,\n \t}\n \tclose(rls.in);\n \tif (finish_command(&rls))\n-\t\treturn error (\"pack-objects died\");\n+\t\treturn error(_(\"pack-objects died\"));\n \tif (!bundle_to_stdout) {\n \t\tif (commit_lock_file(&lock))\n-\t\t\tdie_errno(\"cannot create '%s'\", path);\n+\t\t\tdie_errno(_(\"cannot create '%s'\"), path);\n \t}\n \treturn 0;\n }\n@@ -430,6 +434,6 @@ int unbundle(struct bundle_header *header, int bundle_fd, int flags)\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n \tif (run_command(&ip))\n-\t\treturn error(\"index-pack died\");\n+\t\treturn error(_(\"index-pack died\"));\n \treturn 0;\n }\n-- \n1.7.8.36.g69ee2\n"},{"id":"189886","messageId":"20120423161536.GE4832@burratino","threadId":"30308","inReplyTo":"1335184230-8870-3-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 02/10] Add three convenient format printing functions with \\n automatically appended","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-23T16:15:36Z","receivedAt":"2012-04-23T16:15:36Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyễn Thái Ngọc Duy wrote:\n\n> --- a/strbuf.c\n> +++ b/strbuf.c\n> @@ -464,3 +464,36 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,\n[...]\n> +int printf_ln(const char *fmt, ...)\n> +{\n> +\tint ret;\n> +\tva_list ap;\n> +\tva_start(ap, fmt);\n> +\tret = vprintf(fmt, ap);\n> +\tva_end(ap);\n> +\tif (ret >= 0)\n> +\t\tret += printf(\"\\n\");\n\nMissed a spot.  I'd do\n\n\tif (ret < 0 || putchar('\\n') == EOF)\n\t\treturn -1;\n\treturn ret + 1;\n\nAnd likewise, for the fprintf version:\n\n\tif (ret < 0 || putc('\\n', fp) == EOF)\n\t\treturn -1;\n\treturn ret + 1;\n\nHope that helps,\nJonathan\n"},{"id":"189889","messageId":"20120423163032.GF4832@burratino","threadId":"30308","inReplyTo":"1335184230-8870-5-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 04/10] i18n: help: mark strings for translation","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-23T16:30:32Z","receivedAt":"2012-04-23T16:30:32Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyễn Thái Ngọc Duy wrote:\n\n> --- a/help.c\n> +++ b/help.c\n> @@ -217,8 +217,9 @@ void list_commands(const char *title, struct cmdnames *main_cmds,\n>  \n>  \tif (main_cmds->cnt) {\n>  \t\tconst char *exec_path = git_exec_path();\n> -\t\tprintf(\"available %s in '%s'\\n\", title, exec_path);\n> -\t\tprintf(\"----------------\");\n> +\t\tprintf_ln(_(\"available %s in '%s'\"), title, exec_path);\n> +\t\t/* TRANSLATORS: this must align with \"available %s in '%s'\" */\n> +\t\tprintf(_(\"----------------\"));\n>  \t\tmput_char('-', strlen(title) + strlen(exec_path));\n\nYuck. :)\n\nI would be tempted to do:\n\n\tstatic int strbuf_utf8_width(const struct strbuf *sb)\n\t{\n\t\tchar char *p = sb->buf;\n\t\tsize_t remainder = sb->len;\n\t\tint width;\n\n\t\twidth = utf8_width(&p, &remainder);\n\t\tif (!p || remainder)\n\t\t\treturn sb->len;\n\t\treturn width;\n\t}\n\t...\n\n\t\tstruct strbuf sb = STRBUF_INIT;\n\t\tconst char *p;\n\n\t\tstrbuf_addf(&sb, _(\"available %s in '%s'\"), title, exec_path);\n\t\tfwrite(sb.buf, sb.len, 1, stdout);\n\t\tputchar('\\n');\n\n\t\t/* NEEDSWORK: handle non-UTF8 locales? */\n\t\tmput_char('-', strbuf_utf8_width(&sb));\n\n\t\tstrbuf_release(&sb);\n"},{"id":"189894","messageId":"20120423164118.GG4832@burratino","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-23T16:41:18Z","receivedAt":"2012-04-23T16:41:18Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyễn Thái Ngọc Duy wrote:\n\n> Compared to v1 [1], parseopt patch is taken out. I attempted to\n> convert all struct option, and it turned into a huge series [2]. Not\n> sure how to submit that series yet.\n\nWith the exception of the two nits mentioned, looks good.  I haven't\ntested yet with GETTEXT_POISON=Yes, though.  Thanks for your\nperseverance.\n\nJonathan\n"},{"id":"189903","messageId":"xmqqaa22jor5.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"20120423163032.GF4832@burratino","subject":"Re: [PATCH 04/10] i18n: help: mark strings for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-23T18:18:22Z","receivedAt":"2012-04-23T18:18:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> Nguyễn Thái Ngọc Duy wrote:\n>\n>> --- a/help.c\n>> +++ b/help.c\n>> @@ -217,8 +217,9 @@ void list_commands(const char *title, struct cmdnames *main_cmds,\n>>  \n>>  \tif (main_cmds->cnt) {\n>>  \t\tconst char *exec_path = git_exec_path();\n>> -\t\tprintf(\"available %s in '%s'\\n\", title, exec_path);\n>> -\t\tprintf(\"----------------\");\n>> +\t\tprintf_ln(_(\"available %s in '%s'\"), title, exec_path);\n>> +\t\t/* TRANSLATORS: this must align with \"available %s in '%s'\" */\n>> +\t\tprintf(_(\"----------------\"));\n>>  \t\tmput_char('-', strlen(title) + strlen(exec_path));\n>\n> Yuck. :)\n\nYuck indeed.  Do we even care these pseudo-underline?  Wouldn't a simple\nand clean \"blank line\" look better?\n"},{"id":"189905","messageId":"20120423183439.GA12916@burratino","threadId":"30308","inReplyTo":"xmqqaa22jor5.fsf@junio.mtv.corp.google.com","subject":"Re: [PATCH 04/10] i18n: help: mark strings for translation","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-23T18:34:39Z","receivedAt":"2012-04-23T18:34:39Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n\n>                                                        Wouldn't a simple\n> and clean \"blank line\" look better?\n\nYes, based on a quick test with \"vi\" it looks reasonable.  Thanks for\na sanity check.\n"},{"id":"189906","messageId":"xmqq62cqjn0f.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-23T18:56:00Z","receivedAt":"2012-04-23T18:56:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This series looked sensible overall, so I'll queue but please eyeball my\nconflict resolutions after I push it out on 'pu' in several hours.\n\nThanks, both.\n"},{"id":"189912","messageId":"CACBZZX54AmWcCqD=BDx5MspRJSrLWUh5dfo=nrc8-x-Bei6MAA@mail.gmail.com","threadId":"30308","inReplyTo":"xmqq62cqjn0f.fsf@junio.mtv.corp.google.com","subject":"Re: [PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2012-04-23T20:06:36Z","receivedAt":"2012-04-23T20:06:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Mon, Apr 23, 2012 at 20:56, Junio C Hamano <gitster@pobox.com> wrote:\n> This series looked sensible overall, so I'll queue but please eyeball my\n> conflict resolutions after I push it out on 'pu' in several hours.\n\nSame here. It looks good to me. Thanks for working on this.\n\nSome of it uses strings concated to other strings, but in those cases\nit would be tricky to provide the translators with all the\nalternatives, and in any case it's a huge improvement on not making\nthings translatable at all.\n"},{"id":"189966","messageId":"20120424121953.GA25944@do","threadId":"30308","inReplyTo":"1335184230-8870-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-24T12:19:53Z","receivedAt":"2012-04-24T12:19:53Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Apr 23, 2012 at 07:30:20PM +0700, Nguyễn Thái Ngọc Duy wrote:\n> I attempted to\n> convert all struct option, and it turned into a huge series [2]. Not\n> sure how to submit that series yet.\n>\n> [2] https://github.com/pclouds/git/tree/parseopt-i18n\n\nThe 62 patch series looks lame compared to this approach, but cross\ncompile guys, including myself, will hate me in principle.\n\nThe idea is modify all git commands and output all marked strings in\n\"struct option\" and usage strings, instead of manually marking them\none by one. The marked strings will be collected by xgettext just like\nanother source file.\n\nThis adds a runnable git as a dependency to git.pot. But changes are\nmuch cleaner and devs don't need to care about i18n when they update\n\"struct option\". Big plus to me. Introduction of new parse_options()\ncall sites still require attention though.\n\nJust a PoC patch for string generation (about 1000 new strings by the\nway). When GIT_I18N is set, git will print then quit. Good to go?\n\n-- 8< --\ndiff --git a/Makefile b/Makefile\nindex dab7362..5de3f1f 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2306,8 +2306,18 @@ LOCALIZED_SH += t/t0200/test.sh\n LOCALIZED_PERL += t/t0200/test.perl\n endif\n \n+I18N_CMDS =\n+I18N_CMDS += add apply archive bisect--helper branch cat-file check-attr checkout checkout-index\n+I18N_CMDS += cherry cherry-pick clean clone commit config count-objects describe fast-export fetch\n+I18N_CMDS += fmt-merge-msg for-each-ref format-patch fsck gc grep hash-object init-db log ls-files\n+I18N_CMDS += ls-tree merge merge-base merge-file mktree mv name-rev notes pack-objects pack-refs\n+I18N_CMDS += prune prune-packed push read-tree remote replace rerere reset revert rm shortlog show-branch\n+I18N_CMDS += show-ref status symbolic-ref tag update-index update-ref update-server-info verify-pack\n+I18N_CMDS += verify-tag write-tree\n+\n po/git.pot: $(LOCALIZED_C)\n-\t$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)\n+\tfor cmd in $(I18N_CMDS); do GIT_I18N=1 ./git $$cmd; done > text.c\n+\t$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C) text.c\n \t$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \\\n \t\t$(LOCALIZED_SH)\n \t$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_PERL) \\\ndiff --git a/archive.c b/archive.c\nindex 1ee837d..311fd18 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -361,6 +361,8 @@ static int parse_archive_args(int argc, const char **argv,\n \t\tOPT_END()\n \t};\n \n+\tif (generate_parseopt_strings(__FILE__, __LINE__, opts, archive_usage))\n+\t\texit(0);\n \targc = parse_options(argc, argv, NULL, opts, archive_usage, 0);\n \n \tif (remote)\ndiff --git a/builtin/add.c b/builtin/add.c\nindex b79336d..2d886f6 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -375,6 +375,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tgit_config(add_config, NULL);\n \n+\tGEN_PARSEOPT(builtin_add_options, builtin_add_usage);\n \targc = parse_options(argc, argv, prefix, builtin_add_options,\n \t\t\t  builtin_add_usage, PARSE_OPT_KEEP_ARGV0);\n \tif (patch_interactive)\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 389898f..1d02cf7 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -3916,6 +3916,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tif (apply_default_ignorewhitespace)\n \t\tparse_ignorewhitespace_option(apply_default_ignorewhitespace);\n \n+\tGEN_PARSEOPT(builtin_apply_options, apply_usage);\n \targc = parse_options(argc, argv, prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n \ndiff --git a/builtin/archive.c b/builtin/archive.c\nindex 931956d..545f82e 100644\n--- a/builtin/archive.c\n+++ b/builtin/archive.c\n@@ -97,6 +97,12 @@ int cmd_archive(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tif (generate_parseopt_strings(__FILE__, __LINE__, local_opts, NULL)) {\n+\t\t/* dummy args just enough to get to parse_archive_args() */\n+\t\twrite_archive(0, NULL, NULL, 0, NULL, 0);\n+\t\tassert(!\"archive.c:parse_archive_args() should have called exit(0)\");\n+\t\treturn 0;\n+\t}\n \targc = parse_options(argc, argv, prefix, local_opts, NULL,\n \t\t\t     PARSE_OPT_KEEP_ALL);\n \ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 8d325a5..4155f31 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -20,6 +20,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_bisect_helper_usage);\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_bisect_helper_usage, 0);\n \ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex a9845bb..1431ea0 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -2322,6 +2322,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \tsave_commit_buffer = 0;\n \tdashdash_pos = 0;\n \n+\tGEN_PARSEOPT(options, blame_opt_usage);\n \tparse_options_start(&ctx, argc, argv, prefix, options,\n \t\t\t    PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0);\n \tfor (;;) {\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex d8cccf7..488e643 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -734,6 +734,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_END(),\n \t};\n \n+\tGEN_PARSEOPT(options, builtin_branch_usage);\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage_with_options(builtin_branch_usage, options);\n \ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 36a9104..8ea3891 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -282,6 +282,7 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_cat_file_config, NULL);\n \n+\tGEN_PARSEOPT(options, cat_file_usage);\n \tif (argc != 3 && argc != 2)\n \t\tusage_with_options(cat_file_usage, options);\n \ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 44c421e..e31acba 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -96,6 +96,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\tGEN_PARSEOPT(check_attr_options, check_attr_usage);\n \targc = parse_options(argc, argv, prefix, check_attr_options,\n \t\t\t     check_attr_usage, PARSE_OPT_KEEP_DASHDASH);\n \ndiff --git a/builtin/checkout-index.c b/builtin/checkout-index.c\nindex c16d82b..8b784de 100644\n--- a/builtin/checkout-index.c\n+++ b/builtin/checkout-index.c\n@@ -220,6 +220,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)\n \t\tdie(\"invalid cache\");\n \t}\n \n+\tGEN_PARSEOPT(builtin_checkout_index_options, builtin_checkout_index_usage);\n \targc = parse_options(argc, argv, prefix, builtin_checkout_index_options,\n \t\t\tbuiltin_checkout_index_usage, 0);\n \tstate.force = force;\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 6b9061f..58c27b4 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -964,6 +964,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \topts.track = BRANCH_TRACK_UNSPECIFIED;\n \n+\tGEN_PARSEOPT(options, checkout_usage);\n \targc = parse_options(argc, argv, prefix, options, checkout_usage,\n \t\t\t     PARSE_OPT_KEEP_DASHDASH);\n \ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 0c7b3d0..77bb90d 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -67,6 +67,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \telse\n \t\tconfig_set = 1;\n \n+\tGEN_PARSEOPT(options, builtin_clean_usage);\n \targc = parse_options(argc, argv, prefix, options, builtin_clean_usage,\n \t\t\t     0);\n \ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex bbd5c96..b8837ef 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -632,6 +632,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tjunk_pid = getpid();\n \n \tpacket_trace_identity(\"clone\");\n+\tGEN_PARSEOPT(builtin_clone_options, builtin_clone_usage);\n \targc = parse_options(argc, argv, prefix, builtin_clone_options,\n \t\t\t     builtin_clone_usage, 0);\n \ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 7808be3..7de09ff 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1229,6 +1229,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n \t\tOPT_END(),\n \t};\n \n+\tGEN_PARSEOPT(builtin_status_options, builtin_status_usage);\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage_with_options(builtin_status_usage, builtin_status_options);\n \n@@ -1416,6 +1417,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \tstruct commit *current_head = NULL;\n \tstruct commit_extra_header *extra = NULL;\n \n+\tGEN_PARSEOPT(builtin_commit_options, builtin_commit_usage);\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage_with_options(builtin_commit_usage, builtin_commit_options);\n \ndiff --git a/builtin/config.c b/builtin/config.c\nindex 33c8820..3389778 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -369,6 +369,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \n \tgiven_config_file = getenv(CONFIG_ENVIRONMENT);\n \n+\tGEN_PARSEOPT(builtin_config_options, builtin_config_usage);\n \targc = parse_options(argc, argv, prefix, builtin_config_options,\n \t\t\t     builtin_config_usage,\n \t\t\t     PARSE_OPT_STOP_AT_NON_OPTION);\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex c37cb98..5c2756e 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -83,6 +83,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)\n \t\tOPT_END(),\n \t};\n \n+\tGEN_PARSEOPT(opts, count_objects_usage);\n \targc = parse_options(argc, argv, prefix, opts, count_objects_usage, 0);\n \t/* we do not take arguments other than flags for now */\n \tif (argc)\ndiff --git a/builtin/describe.c b/builtin/describe.c\nindex 9f63067..11b5858 100644\n--- a/builtin/describe.c\n+++ b/builtin/describe.c\n@@ -421,6 +421,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(options, describe_usage);\n \targc = parse_options(argc, argv, prefix, options, describe_usage, 0);\n \tif (abbrev < 0)\n \t\tabbrev = DEFAULT_ABBREV;\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 19509ea..88ff132 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -651,6 +651,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, fast_export_usage);\n \tif (argc == 1)\n \t\tusage_with_options (fast_export_usage, options);\n \ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 65f5f9b..f8c624b 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -953,6 +953,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \tfor (i = 1; i < argc; i++)\n \t\tstrbuf_addf(&default_rla, \" %s\", argv[i]);\n \n+\tGEN_PARSEOPT(builtin_fetch_options, builtin_fetch_usage);\n \targc = parse_options(argc, argv, prefix,\n \t\t\t     builtin_fetch_options, builtin_fetch_usage, 0);\n \ndiff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c\nindex c81a7fe..98917f5 100644\n--- a/builtin/fmt-merge-msg.c\n+++ b/builtin/fmt-merge-msg.c\n@@ -451,6 +451,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \tstruct fmt_merge_msg_opts opts;\n \n \tgit_config(fmt_merge_msg_config, NULL);\n+\tGEN_PARSEOPT(options, fmt_merge_msg_usage);\n \targc = parse_options(argc, argv, prefix, options, fmt_merge_msg_usage,\n \t\t\t     0);\n \tif (argc > 0)\ndiff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c\nindex b01d76a..26b9404 100644\n--- a/builtin/for-each-ref.c\n+++ b/builtin/for-each-ref.c\n@@ -1005,6 +1005,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \t\tOPT_END(),\n \t};\n \n+\tGEN_PARSEOPT(opts, for_each_ref_usage);\n \tparse_options(argc, argv, prefix, opts, for_each_ref_usage, 0);\n \tif (maxcount < 0) {\n \t\terror(\"invalid --count argument: `%d'\", maxcount);\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex a710227..51fccd1 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -633,6 +633,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \terrors_found = 0;\n \tread_replace_refs = 0;\n \n+\tGEN_PARSEOPT(fsck_opts,  fsck_usage);\n \targc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);\n \n \tif (show_progress == -1)\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 271376d..49e57ee 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -197,6 +197,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)\n \tif (pack_refs < 0)\n \t\tpack_refs = !is_bare_repository();\n \n+\tGEN_PARSEOPT(builtin_gc_options, builtin_gc_usage);\n \targc = parse_options(argc, argv, prefix, builtin_gc_options,\n \t\t\t     builtin_gc_usage, 0);\n \tif (argc > 0)\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 643938d..5808242 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -790,6 +790,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t * 'git grep -h', unlike 'git grep -h <pattern>', is a request\n \t * to show usage information and exit.\n \t */\n+\tGEN_PARSEOPT(options, grep_usage);\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage_with_options(grep_usage, options);\n \ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 33911fd..50af09e 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -86,6 +86,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \n \ttype = blob_type;\n \n+\tGEN_PARSEOPT(hash_object_options, hash_object_usage);\n \targc = parse_options(argc, argv, NULL, hash_object_options,\n \t\t\t     hash_object_usage, 0);\n \ndiff --git a/builtin/help.c b/builtin/help.c\nindex 61ff798..b189d3f 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -419,6 +419,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \tenum help_format parsed_help_format;\n \tload_command_list(\"git-\", &main_cmds, &other_cmds);\n \n+\tGEN_PARSEOPT(builtin_help_options, builtin_help_usage);\n \targc = parse_options(argc, argv, prefix, builtin_help_options,\n \t\t\tbuiltin_help_usage, 0);\n \tparsed_help_format = help_format;\ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex 0dacb8b..f63a7de 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -495,6 +495,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(init_db_options, init_db_usage);\n \targc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);\n \n \tif (real_git_dir && !is_absolute_path(real_git_dir))\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 02d070b..28b4706 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -103,6 +103,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,\n \t\tOPT_END()\n \t};\n \n+\tif (generate_parseopt_strings(__FILE__, __LINE__, builtin_log_options, builtin_log_usage))\n+\t\texit(0);\n \targc = parse_options(argc, argv, prefix,\n \t\t\t     builtin_log_options, builtin_log_usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |\n@@ -1165,6 +1167,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t * like \"git format-patch -o a123 HEAD^..\" may fail; a123 is\n \t * possibly a valid SHA1.\n \t */\n+\tGEN_PARSEOPT(builtin_format_patch_options, builtin_format_patch_usage);\n \targc = parse_options(argc, argv, prefix, builtin_format_patch_options,\n \t\t\t     builtin_format_patch_usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |\n@@ -1500,6 +1503,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, cherry_usage);\n \targc = parse_options(argc, argv, prefix, options, cherry_usage, 0);\n \n \tswitch (argc) {\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 7cff175..7cc7b98 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -500,6 +500,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(builtin_ls_files_options, ls_files_usage);\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage_with_options(ls_files_usage, builtin_ls_files_options);\n \ndiff --git a/builtin/ls-tree.c b/builtin/ls-tree.c\nindex 6b666e1..41d7940 100644\n--- a/builtin/ls-tree.c\n+++ b/builtin/ls-tree.c\n@@ -150,6 +150,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)\n \tif (prefix && *prefix)\n \t\tchomp_prefix = strlen(prefix);\n \n+\tGEN_PARSEOPT(ls_tree_options, ls_tree_usage);\n \targc = parse_options(argc, argv, prefix, ls_tree_options,\n \t\t\t     ls_tree_usage, 0);\n \tif (full_tree) {\ndiff --git a/builtin/merge-base.c b/builtin/merge-base.c\nindex 4f30f1b..6e663a6 100644\n--- a/builtin/merge-base.c\n+++ b/builtin/merge-base.c\n@@ -86,6 +86,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(options, merge_base_usage);\n \targc = parse_options(argc, argv, prefix, options, merge_base_usage, 0);\n \tif (!octopus && !reduce && argc < 2)\n \t\tusage_with_options(merge_base_usage, options);\ndiff --git a/builtin/merge-file.c b/builtin/merge-file.c\nindex 237abd3..31336c4 100644\n--- a/builtin/merge-file.c\n+++ b/builtin/merge-file.c\n@@ -57,6 +57,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)\n \t\t\txmp.style = git_xmerge_style;\n \t}\n \n+\tGEN_PARSEOPT(options, merge_file_usage);\n \targc = parse_options(argc, argv, prefix, options, merge_file_usage, 0);\n \tif (argc != 3)\n \t\tusage_with_options(merge_file_usage, options);\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 08e01e8..8c0fc7f 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1153,6 +1153,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \tstruct commit_list **remotes = &remoteheads;\n \tvoid *branch_to_free;\n \n+\tGEN_PARSEOPT(builtin_merge_options, builtin_merge_usage);\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage_with_options(builtin_merge_usage, builtin_merge_options);\n \ndiff --git a/builtin/mktree.c b/builtin/mktree.c\nindex 4ae1c41..d842fee 100644\n--- a/builtin/mktree.c\n+++ b/builtin/mktree.c\n@@ -156,6 +156,7 @@ int cmd_mktree(int ac, const char **av, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(option, mktree_usage);\n \tac = parse_options(ac, av, prefix, option, mktree_usage, 0);\n \n \twhile (!got_eof) {\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 2a144b0..c3a4efa 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -72,6 +72,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\tGEN_PARSEOPT(builtin_mv_options, builtin_mv_usage);\n \targc = parse_options(argc, argv, prefix, builtin_mv_options,\n \t\t\t     builtin_mv_usage, 0);\n \tif (--argc < 1)\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 1b37458..5b4fc54 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -240,6 +240,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(opts, name_rev_usage);\n \targc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0);\n \tif (!!all + !!transform_stdin + !!argc > 1) {\n \t\terror(\"Specify either a list, or --all, not both!\");\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 3644d14..33eca95 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -492,6 +492,7 @@ static int list(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_notes_list_usage);\n \tif (argc)\n \t\targc = parse_options(argc, argv, prefix, options,\n \t\t\t\t     git_notes_list_usage, 0);\n@@ -547,6 +548,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_notes_add_usage);\n \targc = parse_options(argc, argv, prefix, options, git_notes_add_usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n@@ -619,6 +621,7 @@ static int copy(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_notes_copy_usage);\n \targc = parse_options(argc, argv, prefix, options, git_notes_copy_usage,\n \t\t\t     0);\n \n@@ -705,6 +708,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \tint edit = !strcmp(argv[0], \"edit\");\n \n \tusage = edit ? git_notes_edit_usage : git_notes_append_usage;\n+\tGEN_PARSEOPT(options, usage);\n \targc = parse_options(argc, argv, prefix, options, usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n@@ -752,6 +756,7 @@ static int show(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_notes_show_usage);\n \targc = parse_options(argc, argv, prefix, options, git_notes_show_usage,\n \t\t\t     0);\n \n@@ -878,6 +883,7 @@ static int merge(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_notes_merge_usage);\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_notes_merge_usage, 0);\n \n@@ -989,6 +995,7 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)\n \tstruct notes_tree *t;\n \tint retval = 0;\n \n+\tGEN_PARSEOPT(options, git_notes_remove_usage);\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_notes_remove_usage, 0);\n \n@@ -1026,6 +1033,7 @@ static int prune(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_notes_prune_usage);\n \targc = parse_options(argc, argv, prefix, options, git_notes_prune_usage,\n \t\t\t     0);\n \n@@ -1047,6 +1055,7 @@ static int prune(int argc, const char **argv, const char *prefix)\n static int get_ref(int argc, const char **argv, const char *prefix)\n {\n \tstruct option options[] = { OPT_END() };\n+\tGEN_PARSEOPT(options, git_notes_get_ref_usage);\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_notes_get_ref_usage, 0);\n \n@@ -1069,6 +1078,23 @@ int cmd_notes(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tif (generate_parseopt_strings(__FILE__, __LINE__,\n+\t\t\t\t      options, git_notes_usage)) {\n+\t\tconst char *edit_cmd[] = { \"edit\", NULL };\n+\t\tconst char *append_cmd[] = { \"append\", NULL };\n+\t\tlist(0, NULL, NULL);\n+\t\tadd(0, NULL, NULL);\n+\t\tcopy(0, NULL, NULL);\n+\t\tappend_edit(0, edit_cmd, NULL);\n+\t\tappend_edit(0, append_cmd, NULL);\n+\t\tshow(0, NULL, NULL);\n+\t\tmerge(0, NULL, NULL);\n+\t\tremove_cmd(0, NULL, NULL);\n+\t\tprune(0, NULL, NULL);\n+\t\tget_ref(0, NULL, NULL);\n+\t\treturn 0;\n+\t}\n+\n \tgit_config(git_default_config, NULL);\n \targc = parse_options(argc, argv, prefix, options, git_notes_usage,\n \t\t\t     PARSE_OPT_STOP_AT_NON_OPTION);\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 7b07c09..05665ad 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -2413,6 +2413,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)\n \t\tpack_compression_level = core_compression_level;\n \n \tprogress = isatty(2);\n+\tGEN_PARSEOPT(pack_objects_options, pack_usage);\n \targc = parse_options(argc, argv, prefix, pack_objects_options,\n \t\t\t     pack_usage, 0);\n \ndiff --git a/builtin/pack-refs.c b/builtin/pack-refs.c\nindex 39a9d89..f3292c4 100644\n--- a/builtin/pack-refs.c\n+++ b/builtin/pack-refs.c\n@@ -15,6 +15,7 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT(0, \"prune\", &flags, \"prune loose refs (default)\", PACK_REFS_PRUNE),\n \t\tOPT_END(),\n \t};\n+\tGEN_PARSEOPT(opts, pack_refs_usage);\n \tif (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))\n \t\tusage_with_options(pack_refs_usage, opts);\n \treturn pack_refs(flags);\ndiff --git a/builtin/prune-packed.c b/builtin/prune-packed.c\nindex b58a2e1..222a726 100644\n--- a/builtin/prune-packed.c\n+++ b/builtin/prune-packed.c\n@@ -78,6 +78,7 @@ int cmd_prune_packed(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(prune_packed_options, prune_packed_usage);\n \targc = parse_options(argc, argv, prefix, prune_packed_options,\n \t\t\t     prune_packed_usage, 0);\n \ndiff --git a/builtin/prune.c b/builtin/prune.c\nindex b99b635..faac378 100644\n--- a/builtin/prune.c\n+++ b/builtin/prune.c\n@@ -142,6 +142,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)\n \tread_replace_refs = 0;\n \tinit_revisions(&revs, prefix);\n \n+\tGEN_PARSEOPT(options, prune_usage);\n \targc = parse_options(argc, argv, prefix, options, prune_usage, 0);\n \twhile (argc--) {\n \t\tunsigned char sha1[20];\ndiff --git a/builtin/push.c b/builtin/push.c\nindex d315475..fb00e0b 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -268,6 +268,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n \n \tpacket_trace_identity(\"push\");\n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(options, push_usage);\n \targc = parse_options(argc, argv, prefix, options, push_usage, 0);\n \n \tif (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))\ndiff --git a/builtin/read-tree.c b/builtin/read-tree.c\nindex df6c4c8..b6c5c58 100644\n--- a/builtin/read-tree.c\n+++ b/builtin/read-tree.c\n@@ -145,6 +145,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\tGEN_PARSEOPT(read_tree_options, read_tree_usage);\n \targc = parse_options(argc, argv, unused_prefix, read_tree_options,\n \t\t\t     read_tree_usage, 0);\n \ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex fec92bc..97da0d5 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -175,6 +175,7 @@ static int add(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, builtin_remote_add_usage);\n \targc = parse_options(argc, argv, NULL, options, builtin_remote_add_usage,\n \t\t\t     0);\n \n@@ -627,6 +628,8 @@ static int mv(int argc, const char **argv)\n \tstruct rename_info rename;\n \tint i, refspec_updated = 0;\n \n+\tGEN_PARSEOPT(options, builtin_remote_rename_usage);\n+\n \tif (argc != 3)\n \t\tusage_with_options(builtin_remote_rename_usage, options);\n \n@@ -784,6 +787,7 @@ static int rm(int argc, const char **argv)\n \tcb_data.skipped = &skipped;\n \tcb_data.keep = &known_remotes;\n \n+\tGEN_PARSEOPT(options, builtin_remote_rm_usage);\n \tif (argc != 2)\n \t\tusage_with_options(builtin_remote_rm_usage, options);\n \n@@ -1087,6 +1091,7 @@ static int show(int argc, const char **argv)\n \tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n \tstruct show_info info;\n \n+\tGEN_PARSEOPT(options, builtin_remote_show_usage);\n \targc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,\n \t\t\t     0);\n \n@@ -1190,6 +1195,7 @@ static int set_head(int argc, const char **argv)\n \t\t\t    \"delete refs/remotes/<name>/HEAD\"),\n \t\tOPT_END()\n \t};\n+\tGEN_PARSEOPT(options, builtin_remote_sethead_usage);\n \targc = parse_options(argc, argv, NULL, options, builtin_remote_sethead_usage,\n \t\t\t     0);\n \tif (argc)\n@@ -1243,6 +1249,7 @@ static int prune(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, builtin_remote_prune_usage);\n \targc = parse_options(argc, argv, NULL, options, builtin_remote_prune_usage,\n \t\t\t     0);\n \n@@ -1312,6 +1319,7 @@ static int update(int argc, const char **argv)\n \n \tfetch_argv = xmalloc(sizeof(char *) * (argc+5));\n \n+\tGEN_PARSEOPT(options, builtin_remote_update_usage);\n \targc = parse_options(argc, argv, NULL, options, builtin_remote_update_usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n@@ -1393,6 +1401,7 @@ static int set_branches(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, builtin_remote_setbranches_usage);\n \targc = parse_options(argc, argv, NULL, options,\n \t\t\t     builtin_remote_setbranches_usage, 0);\n \tif (argc == 0) {\n@@ -1425,6 +1434,7 @@ static int set_url(int argc, const char **argv)\n \t\t\t    \"delete URLs\"),\n \t\tOPT_END()\n \t};\n+\tGEN_PARSEOPT(options, builtin_remote_seturl_usage);\n \targc = parse_options(argc, argv, NULL, options, builtin_remote_seturl_usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n@@ -1556,6 +1566,21 @@ int cmd_remote(int argc, const char **argv, const char *prefix)\n \t};\n \tint result;\n \n+\tif (generate_parseopt_strings(__FILE__, __LINE__,\n+\t\t\t\t      options, builtin_remote_usage)) {\n+\n+\t\t/* these just generate strings and do nothing */\n+\t\tadd(0, NULL);\n+\t\tmv(0, NULL);\n+\t\tprune(0, NULL);\n+\t\trm(0, NULL);\n+\t\tset_branches(0, NULL);\n+\t\tset_head(0, NULL);\n+\t\tset_url(0, NULL);\n+\t\tshow(0, NULL);\n+\t\tupdate(0, NULL);\n+\t\treturn 0;\n+\t}\n \targc = parse_options(argc, argv, prefix, options, builtin_remote_usage,\n \t\tPARSE_OPT_STOP_AT_NON_OPTION);\n \ndiff --git a/builtin/replace.c b/builtin/replace.c\nindex 4a8970e..e4ec1c2 100644\n--- a/builtin/replace.c\n+++ b/builtin/replace.c\n@@ -121,6 +121,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, git_replace_usage);\n \targc = parse_options(argc, argv, prefix, options, git_replace_usage, 0);\n \n \tif (list && delete)\ndiff --git a/builtin/rerere.c b/builtin/rerere.c\nindex 08213c7..bef1b0a 100644\n--- a/builtin/rerere.c\n+++ b/builtin/rerere.c\n@@ -57,6 +57,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)\n \t\tOPT_END(),\n \t};\n \n+\tGEN_PARSEOPT(options, rerere_usage);\n \targc = parse_options(argc, argv, prefix, options, rerere_usage, 0);\n \n \tif (autoupdate == 1)\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 8c2c1d5..7d56fb9 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -251,6 +251,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\tGEN_PARSEOPT(options, git_reset_usage);\n \targc = parse_options(argc, argv, prefix, options, git_reset_usage,\n \t\t\t\t\t\tPARSE_OPT_KEEP_DASHDASH);\n \ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex e6840f2..8d7bb74 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -126,6 +126,8 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \t\t\tdie(_(\"program error\"));\n \t}\n \n+\tif (generate_parseopt_strings(__FILE__, __LINE__, options, usage_str))\n+\t\texit(0);\n \targc = parse_options(argc, argv, NULL, options, usage_str,\n \t\t\tPARSE_OPT_KEEP_ARGV0 |\n \t\t\tPARSE_OPT_KEEP_UNKNOWN);\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 90c8a50..126efc6 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -148,6 +148,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\tGEN_PARSEOPT(builtin_rm_options, builtin_rm_usage);\n \targc = parse_options(argc, argv, prefix, builtin_rm_options,\n \t\t\t     builtin_rm_usage, 0);\n \tif (!argc)\ndiff --git a/builtin/shortlog.c b/builtin/shortlog.c\nindex 37f3193..bf46bf3 100644\n--- a/builtin/shortlog.c\n+++ b/builtin/shortlog.c\n@@ -265,6 +265,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)\n \tgit_config(git_default_config, NULL);\n \tshortlog_init(&log);\n \tinit_revisions(&rev, prefix);\n+\tGEN_PARSEOPT(options, shortlog_usage);\n \tparse_options_start(&ctx, argc, argv, prefix, options,\n \t\t\t    PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0);\n \ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex a59e088..7e2dd31 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -691,6 +691,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tav = default_arg;\n \t}\n \n+\tGEN_PARSEOPT(builtin_show_branch_options, show_branch_usage);\n \tac = parse_options(ac, av, prefix, builtin_show_branch_options,\n \t\t\t   show_branch_usage, PARSE_OPT_STOP_AT_NON_OPTION);\n \tif (all_heads)\ndiff --git a/builtin/show-ref.c b/builtin/show-ref.c\nindex 3911661..72805a2 100644\n--- a/builtin/show-ref.c\n+++ b/builtin/show-ref.c\n@@ -208,6 +208,7 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage_with_options(show_ref_usage, show_ref_options);\n \n+\tGEN_PARSEOPT(show_ref_options, show_ref_usage);\n \targc = parse_options(argc, argv, prefix, show_ref_options,\n \t\t\t     show_ref_usage, PARSE_OPT_NO_INTERNAL_HELP);\n \ndiff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c\nindex 801d62e..8915c03 100644\n--- a/builtin/symbolic-ref.c\n+++ b/builtin/symbolic-ref.c\n@@ -42,6 +42,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(options, git_symbolic_ref_usage);\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_symbolic_ref_usage, 0);\n \tif (msg &&!*msg)\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex fe7e5e5..bcc5517 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -478,6 +478,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \n \tmemset(&opt, 0, sizeof(opt));\n \n+\tGEN_PARSEOPT(options, git_tag_usage);\n \targc = parse_options(argc, argv, prefix, options, git_tag_usage, 0);\n \n \tif (keyid) {\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex a6a23fa..710b983 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -794,6 +794,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tGEN_PARSEOPT(options, update_index_usage);\n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage(update_index_usage[0]);\n \ndiff --git a/builtin/update-ref.c b/builtin/update-ref.c\nindex 835c62a..ab2bde2 100644\n--- a/builtin/update-ref.c\n+++ b/builtin/update-ref.c\n@@ -23,6 +23,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(options, git_update_ref_usage);\n \targc = parse_options(argc, argv, prefix, options, git_update_ref_usage,\n \t\t\t     0);\n \tif (msg && !*msg)\ndiff --git a/builtin/update-server-info.c b/builtin/update-server-info.c\nindex 0d63c44..fbf5e1f 100644\n--- a/builtin/update-server-info.c\n+++ b/builtin/update-server-info.c\n@@ -16,6 +16,7 @@ int cmd_update_server_info(int argc, const char **argv, const char *prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(options, update_server_info_usage);\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     update_server_info_usage, 0);\n \tif (argc > 0)\ndiff --git a/builtin/verify-pack.c b/builtin/verify-pack.c\nindex e841b4a..099ea2a 100644\n--- a/builtin/verify-pack.c\n+++ b/builtin/verify-pack.c\n@@ -71,6 +71,7 @@ int cmd_verify_pack(int argc, const char **argv, const char *prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(verify_pack_options, verify_pack_usage);\n \targc = parse_options(argc, argv, prefix, verify_pack_options,\n \t\t\t     verify_pack_usage, 0);\n \tif (argc < 1)\ndiff --git a/builtin/verify-tag.c b/builtin/verify-tag.c\nindex 986789f..35f9fa4 100644\n--- a/builtin/verify-tag.c\n+++ b/builtin/verify-tag.c\n@@ -76,6 +76,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_verify_tag_config, NULL);\n \n+\tGEN_PARSEOPT(verify_tag_options, verify_tag_usage);\n \targc = parse_options(argc, argv, prefix, verify_tag_options,\n \t\t\t     verify_tag_usage, PARSE_OPT_KEEP_ARGV0);\n \tif (argc <= i)\ndiff --git a/builtin/write-tree.c b/builtin/write-tree.c\nindex b223af4..417c7ac 100644\n--- a/builtin/write-tree.c\n+++ b/builtin/write-tree.c\n@@ -34,6 +34,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)\n \t};\n \n \tgit_config(git_default_config, NULL);\n+\tGEN_PARSEOPT(write_tree_options, write_tree_usage);\n \targc = parse_options(argc, argv, unused_prefix, write_tree_options,\n \t\t\t     write_tree_usage, 0);\n \ndiff --git a/gettext.c b/gettext.c\nindex f75bca7..4ab29cd 100644\n--- a/gettext.c\n+++ b/gettext.c\n@@ -4,6 +4,9 @@\n \n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n+#include \"strbuf.h\"\n+#include \"parse-options.h\"\n+#include \"quote.h\"\n \n #ifndef NO_GETTEXT\n #\tinclude <locale.h>\n@@ -129,3 +132,36 @@ void git_setup_gettext(void)\n \ttextdomain(\"git\");\n }\n #endif\n+\n+static void strbuf_quote_gettext(struct strbuf *sb, const char *s)\n+{\n+\tif (!*s)\t\t/* do not generate empty strings */\n+\t\treturn;\n+\tstrbuf_addstr(sb, \"_(\\\"\");\n+\tquote_c_style(s, sb, NULL, 1);\n+\tstrbuf_addstr(sb, \"\\\");\\n\");\n+}\n+\n+int generate_parseopt_strings(const char *file, int line,\n+\t\t\t      const struct option *opts,\n+\t\t\t      const char * const * usagestr)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\n+\tif (!getenv(\"GIT_I18N\"))\n+\t\treturn 0;\n+\n+\tstrbuf_addf(&sb, \"/* parseopt %s:%d */\\n\", file, line);\n+\tfor (; usagestr && *usagestr; usagestr++)\n+\t\tstrbuf_quote_gettext(&sb, *usagestr);\n+\tfor (; opts->type != OPTION_END; opts++) {\n+\t\tif (opts->argh)\n+\t\t\tstrbuf_quote_gettext(&sb, opts->argh);\n+\t\tif (opts->help)\n+\t\t\tstrbuf_quote_gettext(&sb, opts->help);\n+\t}\n+\tstrbuf_addch(&sb, '\\n');\n+\tfputs(sb.buf, stdout);\n+\tstrbuf_release(&sb);\n+\treturn 1;\n+}\ndiff --git a/gettext.h b/gettext.h\nindex 57ba8bb..ae5c874 100644\n--- a/gettext.h\n+++ b/gettext.h\n@@ -59,3 +59,12 @@ const char *Q_(const char *msgid, const char *plu, unsigned long n)\n #define N_(msgid) msgid\n \n #endif\n+\n+struct option;\n+extern int generate_parseopt_strings(const char *file, int line,\n+\t\t\t\t     const struct option *opts,\n+\t\t\t\t     const char * const * usagestr);\n+#define GEN_PARSEOPT(opts, usage) { \\\n+\tif (generate_parseopt_strings(__FILE__, __LINE__, opts, usage)) \\\n+\t\treturn 0; \\\n+\t}\n-- 8< --\n-- \nDuy\n"},{"id":"189988","messageId":"xmqqobqggb8e.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"20120424121953.GA25944@do","subject":"Re: [PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-24T19:50:57Z","receivedAt":"2012-04-24T19:50:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Mon, Apr 23, 2012 at 07:30:20PM +0700, Nguyễn Thái Ngọc Duy wrote:\n>> I attempted to\n>> convert all struct option, and it turned into a huge series [2]. Not\n>> sure how to submit that series yet.\n>>\n>> [2] https://github.com/pclouds/git/tree/parseopt-i18n\n>\n> The 62 patch series looks lame compared to this approach, but cross\n> compile guys, including myself, will hate me in principle.\n>\n> The idea is modify all git commands and output all marked strings in\n> \"struct option\" and usage strings, instead of manually marking them\n> one by one. The marked strings will be collected by xgettext just like\n> another source file.\n\nGaah, my eyes, my eyes.\n\nNo thanks.\n"},{"id":"189990","messageId":"xmqqd36wgam5.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"1335184230-8870-4-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-24T20:04:18Z","receivedAt":"2012-04-24T20:04:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> From: Jonathan Nieder <jrnieder@gmail.com>\n>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n\nLooks nicely done ;-)\n\n>  \t/* Give years and months for 5 years or so */\n>  \tif (diff < 1825) {\n> ...\n>  \t}\n>  \t/* Otherwise, just years. Centuries is probably overkill. */\n> -\tsnprintf(timebuf, timebuf_size, \"%lu years ago\", (diff + 183) / 365);\n> -\treturn timebuf;\n> +\tstrbuf_addf(timebuf,\n> +\t\t Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n> +\t\t (diff + 183) / 365);\n>  }\n\nThis is just a tangent, but could we possibly come here and say \"1 year\nago\"?\n"},{"id":"190050","messageId":"CACsJy8Ae_9wEoNmP81Gqu5kOMGrEKSN9PMvoRXbKh8TnwGVt0A@mail.gmail.com","threadId":"30308","inReplyTo":"xmqqd36wgam5.fsf@junio.mtv.corp.google.com","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-25T10:46:45Z","receivedAt":"2012-04-25T10:46:45Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2012/4/25 Junio C Hamano <gitster@pobox.com>:\n>>       /* Give years and months for 5 years or so */\n>>       if (diff < 1825) {\n>> ...\n>>       }\n>>       /* Otherwise, just years. Centuries is probably overkill. */\n>> -     snprintf(timebuf, timebuf_size, \"%lu years ago\", (diff + 183) / 365);\n>> -     return timebuf;\n>> +     strbuf_addf(timebuf,\n>> +              Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n>> +              (diff + 183) / 365);\n>>  }\n>\n> This is just a tangent, but could we possibly come here and say \"1 year\n> ago\"?\n\nNice catch. Singular form here is unnecessary. If you plan to revert\nthat, please put a comment so nobody will attempt to convert it to\nQ_() again next time while searching for possible candidates.\n-- \nDuy\n"},{"id":"190051","messageId":"4F97DAE4.4070706@viscovery.net","threadId":"30308","inReplyTo":"CACsJy8Ae_9wEoNmP81Gqu5kOMGrEKSN9PMvoRXbKh8TnwGVt0A@mail.gmail.com","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2012-04-25T11:07:16Z","receivedAt":"2012-04-25T11:07:16Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 4/25/2012 12:46, schrieb Nguyen Thai Ngoc Duy:\n> 2012/4/25 Junio C Hamano <gitster@pobox.com>:\n>>>       /* Give years and months for 5 years or so */\n>>>       if (diff < 1825) {\n>>> ...\n>>>       }\n>>>       /* Otherwise, just years. Centuries is probably overkill. */\n>>> -     snprintf(timebuf, timebuf_size, \"%lu years ago\", (diff + 183) / 365);\n>>> -     return timebuf;\n>>> +     strbuf_addf(timebuf,\n>>> +              Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n>>> +              (diff + 183) / 365);\n>>>  }\n>>\n>> This is just a tangent, but could we possibly come here and say \"1 year\n>> ago\"?\n> \n> Nice catch. Singular form here is unnecessary. If you plan to revert\n> that, please put a comment so nobody will attempt to convert it to\n> Q_() again next time while searching for possible candidates.\n\nI am sure that there are languages (Russian? Polish?) where a variation is\nneeded not only for the singular, but also for plural depending on the\nnumber, so we still want to have this wrapped in Q_().\n\n-- Hannes\n"},{"id":"190053","messageId":"1335352913-32684-1-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"20120423183439.GA12916@burratino","subject":"[PATCH] help: replace underlining \"help -a\" headers using hyphens with a blank line","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-25T11:21:53Z","receivedAt":"2012-04-25T11:21:53Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"We want the underline to align with the text above, for example:\n\nThis is a header\n----------------\ncontent...\n\nUnfortunately calculating text length could get complicated because\nthe text could be in any charset in translated Git. Avoid it and print\na blank line (i.e. charset neutral) instead. Readability is not\naffected much. After the change we get:\n\nThis is a header:\n\ncontent...\n\nWhile at it, give translators more context to translate, e.g.\ne.g.  \"git commands available...\" instead of \"%s available...\"\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n 2012/4/24 Jonathan Nieder <jrnieder@gmail.com>:\n > Junio C Hamano wrote:\n >\n >>                                                        Wouldn't a simple\n >> and clean \"blank line\" look better?\n >\n > Yes, based on a quick test with \"vi\" it looks reasonable.  Thanks for\n > a sanity check.\n\n And it does _not_ assume the translated text is in utf-8.\n\n And thanks Junio for fixing the other nit before merging the seriess\n to next. I should have read and reacted on these posts yesterday.\n\n builtin/help.c |    2 +-\n help.c         |   16 +++-------------\n help.h         |    3 +--\n 3 files changed, 5 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 96a462c..e63668a 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -425,7 +425,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \n \tif (show_all) {\n \t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n-\t\tlist_commands(_(\"git commands\"), &main_cmds, &other_cmds);\n+\t\tlist_commands(&main_cmds, &other_cmds);\n \t\tprintf(\"%s\\n\", _(git_more_info_string));\n \t\treturn 0;\n \t}\ndiff --git a/help.c b/help.c\nindex 9e6e0f2..baaf379 100644\n--- a/help.c\n+++ b/help.c\n@@ -203,8 +203,7 @@ void load_command_list(const char *prefix,\n \texclude_cmds(other_cmds, main_cmds);\n }\n \n-void list_commands(const char *title, struct cmdnames *main_cmds,\n-\t\t   struct cmdnames *other_cmds)\n+void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n {\n \tint i, longest = 0;\n \n@@ -217,23 +216,14 @@ void list_commands(const char *title, struct cmdnames *main_cmds,\n \n \tif (main_cmds->cnt) {\n \t\tconst char *exec_path = git_exec_path();\n-\t\tprintf_ln(_(\"available %s in '%s'\"), title, exec_path);\n-\t\t/* TRANSLATORS: this must align with \"available %s in '%s'\" */\n-\t\tprintf(_(\"----------------\"));\n-\t\tmput_char('-', strlen(title) + strlen(exec_path));\n+\t\tprintf_ln(_(\"available git commands in '%s':\"), exec_path);\n \t\tputchar('\\n');\n \t\tpretty_print_string_list(main_cmds, longest);\n \t\tputchar('\\n');\n \t}\n \n \tif (other_cmds->cnt) {\n-\t\tprintf_ln(_(\"%s available from elsewhere on your $PATH\"), title);\n-\t\t/* TRANSLATORS:\n-\t\t * this must align with\n-\t\t * \"%s available from elsewhere on your $PATH\"\n-\t\t */\n-\t\tprintf(_(\"---------------------------------------\"));\n-\t\tmput_char('-', strlen(title));\n+\t\tprintf_ln(_(\"git commands available from elsewhere on your $PATH:\"));\n \t\tputchar('\\n');\n \t\tpretty_print_string_list(other_cmds, longest);\n \t\tputchar('\\n');\ndiff --git a/help.h b/help.h\nindex b6b12d5..dc406c8 100644\n--- a/help.h\n+++ b/help.h\n@@ -25,8 +25,7 @@ extern void add_cmdname(struct cmdnames *cmds, const char *name, int len);\n /* Here we require that excludes is a sorted list. */\n extern void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);\n extern int is_in_cmdlist(struct cmdnames *cmds, const char *name);\n-extern void list_commands(const char *title,\n-\t\t\t  struct cmdnames *main_cmds,\n+extern void list_commands(struct cmdnames *main_cmds,\n \t\t\t  struct cmdnames *other_cmds);\n \n #endif /* HELP_H */\n-- \n1.7.8.36.g69ee2\n"},{"id":"190054","messageId":"4F97DF3D.1000507@in.waw.pl","threadId":"30308","inReplyTo":"4F97DAE4.4070706@viscovery.net","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Zbigniew Jędrzejewski-Szmek","fromEmail":"zbyszek@in.waw.pl","sentAt":"2012-04-25T11:25:49Z","receivedAt":"2012-04-25T11:25:49Z","isPatch":true,"sender":{"key":"zbyszek@in.waw.pl","avatar":"https://avatars.githubusercontent.com/u/349618?v=4"},"body":"On 04/25/2012 01:07 PM, Johannes Sixt wrote:\n> Am 4/25/2012 12:46, schrieb Nguyen Thai Ngoc Duy:\n>> 2012/4/25 Junio C Hamano <gitster@pobox.com>:\n>>>>       /* Give years and months for 5 years or so */\n>>>>       if (diff < 1825) {\n>>>> ...\n>>>>       }\n>>>>       /* Otherwise, just years. Centuries is probably overkill. */\n>>>> -     snprintf(timebuf, timebuf_size, \"%lu years ago\", (diff + 183) / 365);\n>>>> -     return timebuf;\n>>>> +     strbuf_addf(timebuf,\n>>>> +              Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n>>>> +              (diff + 183) / 365);\n>>>>  }\n>>>\n>>> This is just a tangent, but could we possibly come here and say \"1 year\n>>> ago\"?\n>>\n>> Nice catch. Singular form here is unnecessary. If you plan to revert\n>> that, please put a comment so nobody will attempt to convert it to\n>> Q_() again next time while searching for possible candidates.\n> \n> I am sure that there are languages (Russian? Polish?) where a variation is\n> needed not only for the singular, but also for plural depending on the\n> number, so we still want to have this wrapped in Q_().\nYeah, both Polish and Russian...\n\nPolish:\nPlural-Forms: nplurals=3; \\\n  plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n\nRussian:\nPlural-Forms: nplurals=3; \\\n              plural=n%10==1 && n%100!=11 ? 0 : \\\n                     n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n\nLooking at http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html, basically all languages which have nplurals=3 or nplurals=4.\n\nZbyszek\n"},{"id":"190055","messageId":"CACsJy8DEOLTybnmy+_PNdKvR6pVjtxA2+xC8sND8tMfUgw-b4Q@mail.gmail.com","threadId":"30308","inReplyTo":"4F97DAE4.4070706@viscovery.net","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-25T11:29:15Z","receivedAt":"2012-04-25T11:29:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Apr 25, 2012 at 6:07 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n> Am 4/25/2012 12:46, schrieb Nguyen Thai Ngoc Duy:\n>> 2012/4/25 Junio C Hamano <gitster@pobox.com>:\n>>>>       /* Give years and months for 5 years or so */\n>>>>       if (diff < 1825) {\n>>>> ...\n>>>>       }\n>>>>       /* Otherwise, just years. Centuries is probably overkill. */\n>>>> -     snprintf(timebuf, timebuf_size, \"%lu years ago\", (diff + 183) / 365);\n>>>> -     return timebuf;\n>>>> +     strbuf_addf(timebuf,\n>>>> +              Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n>>>> +              (diff + 183) / 365);\n>>>>  }\n>>>\n>>> This is just a tangent, but could we possibly come here and say \"1 year\n>>> ago\"?\n>>\n>> Nice catch. Singular form here is unnecessary. If you plan to revert\n>> that, please put a comment so nobody will attempt to convert it to\n>> Q_() again next time while searching for possible candidates.\n>\n> I am sure that there are languages (Russian? Polish?) where a variation is\n> needed not only for the singular, but also for plural depending on the\n> number, so we still want to have this wrapped in Q_().\n\nSlovenian has special case for one and all numbers ending in 2, 3, 4\n[1]. Oh my..\n\n[1] http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html\n-- \nDuy\n"},{"id":"190057","messageId":"CACsJy8AsmvfTLhAKWfijNcuz868L+KvdJuw5CPUj7KDBVKrL8A@mail.gmail.com","threadId":"30308","inReplyTo":"xmqqobqggb8e.fsf@junio.mtv.corp.google.com","subject":"Re: [PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-25T11:42:00Z","receivedAt":"2012-04-25T11:42:00Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Apr 25, 2012 at 2:50 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> The idea is modify all git commands and output all marked strings in\n>> \"struct option\" and usage strings, instead of manually marking them\n>> one by one. The marked strings will be collected by xgettext just like\n>> another source file.\n>\n> Gaah, my eyes, my eyes.\n>\n> No thanks.\n>\n\nGood. What burned your eyes though? Are you ok with an approach that\ndoes not change source code (much) and still marks strings using an\nexternal tool? I'm looking at sparse, but perhaps a simple perl script\nto look at \"gcc -E\" output and search for \"struct option\" would be\nenough.\n-- \nDuy\n"},{"id":"190062","messageId":"20120425152558.GC31026@burratino","threadId":"30308","inReplyTo":"CACsJy8Ae_9wEoNmP81Gqu5kOMGrEKSN9PMvoRXbKh8TnwGVt0A@mail.gmail.com","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-25T15:25:58Z","receivedAt":"2012-04-25T15:25:58Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyen Thai Ngoc Duy wrote:\n> 2012/4/25 Junio C Hamano <gitster@pobox.com>:\n\n>>> +     strbuf_addf(timebuf,\n>>> +              Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n>>> +              (diff + 183) / 365);\n>>>  }\n>>\n>> This is just a tangent, but could we possibly come here and say \"1 year\n>> ago\"?\n>\n> Nice catch. Singular form here is unnecessary.\n\nI think Junio meant\n\n\t\t\tQ_(\"1 year ago\", \"%lu years ago\", ...)\n\nThat sound reasonable to me.  My only worry is a small one: what\nhappens if we want to change the %lu to some other format specifier\nsome day?  Will xgettext be smart enough to let translators know\nwithout the msgid changing?\n"},{"id":"190064","messageId":"20120425161114.GA32019@burratino","threadId":"30308","inReplyTo":"CACsJy8AsmvfTLhAKWfijNcuz868L+KvdJuw5CPUj7KDBVKrL8A@mail.gmail.com","subject":"Re: [PATCH 00/10] i18n relative dates, help, remote, apply, index-pack and bundle","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-25T16:11:14Z","receivedAt":"2012-04-25T16:11:14Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyen Thai Ngoc Duy wrote:\n\n> Good. What burned your eyes though? Are you ok with an approach that\n> does not change source code (much) and still marks strings using an\n> external tool?\n\nI'd like the translated messages to be marked in the source code if\npossible so future coders know to be careful when changing them.\n\nIf the change can be made and checked by an automated process, that\nwould be great, of course.\n"},{"id":"190065","messageId":"xmqqzk9zdbf7.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"20120425152558.GC31026@burratino","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-25T16:27:24Z","receivedAt":"2012-04-25T16:27:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> Nguyen Thai Ngoc Duy wrote:\n>> 2012/4/25 Junio C Hamano <gitster@pobox.com>:\n>\n>>>> +     strbuf_addf(timebuf,\n>>>> +              Q_(\"%lu year ago\", \"%lu years ago\", (diff + 183) / 365),\n>>>> +              (diff + 183) / 365);\n>>>>  }\n>>>\n>>> This is just a tangent, but could we possibly come here and say \"1 year\n>>> ago\"?\n>>\n>> Nice catch. Singular form here is unnecessary.\n>\n> I think Junio meant\n>\n> \t\t\tQ_(\"1 year ago\", \"%lu years ago\", ...)\n\nNo, I was just being stupid---what I meant was that diff will be so\nlarge that this will always be feeding more than 1 to %lu, so the first\ntemplate string will never be used.\n\nBut it cannot be N_(\"%lu years ago\", number), as others correctly\npointed out.  We want to use ngettext() here, because it is not enough\nto know that number is always greater than 1 to correctly phrase this in\nsome languages.\n"},{"id":"190067","messageId":"20120425172605.GA2578@burratino","threadId":"30308","inReplyTo":"xmqqzk9zdbf7.fsf@junio.mtv.corp.google.com","subject":"Re: [PATCH 03/10] i18n: mark relative dates for translation","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-25T17:26:05Z","receivedAt":"2012-04-25T17:26:05Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n\n>                               what I meant was that diff will be so\n> large that this will always be feeding more than 1 to %lu, so the first\n> template string will never be used.\n>\n> But it cannot be N_(\"%lu years ago\", number), as others correctly\n> pointed out.  We want to use ngettext() here, because it is not enough\n> to know that number is always greater than 1 to correctly phrase this in\n> some languages.\n\nAh, I see now.  Thanks for a patient explanation.\n"},{"id":"190068","messageId":"xmqqpqavd8iv.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"1335352913-32684-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH] help: replace underlining \"help -a\" headers using hyphens with a blank line","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-25T17:30:00Z","receivedAt":"2012-04-25T17:30:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> We want the underline to align with the text above, for example:\n>\n> This is a header\n> ----------------\n> content...\n>\n> Unfortunately calculating text length could get complicated because\n> the text could be in any charset in translated Git. Avoid it and print\n> a blank line (i.e. charset neutral) instead. Readability is not\n> affected much. After the change we get:\n\nWhen I said we do not need *pseudo* underline, I really meant it.  I\ntentatively amended your patch to read like this:\n\n    We used to underline a header text, like this:\n\n        This is a header\n        ----------------\n        content...\n\n    But calculating text length so that the dashes align with the text\n    could get complicated because the text could be in any charset in\n    translated Git.\n\n    There is no point to use this pseudo underline; simply a blank\n    line would do and it even makes it easier to read:\n\n        This is a header\n\n        content...\n\nand adjusted the code to match, but it may make more sense to use the\nGIT_COLOR* stuff for this to highlight the header line, allowing us to\nlose the extra empty line.\n\nThis patch obviously conflicts with your own nd/columns so we may want\nto take this slowly and it is OK to wait until columns graduates.\n"},{"id":"190086","messageId":"xmqqipgnbffm.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"1335184230-8870-11-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 10/10] i18n: bundle: mark strings for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-25T22:43:41Z","receivedAt":"2012-04-25T22:43:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> @@ -283,13 +287,13 @@ int create_bundle(struct bundle_header *header, const char *path,\n>  \tstrbuf_release(&buf);\n>  \tfclose(rls_fout);\n>  \tif (finish_command(&rls))\n> -\t\treturn error(\"rev-list died\");\n> +\t\treturn error(_(\"rev-list died\"));\n>  \n>  \t/* write references */\n>  \targc = setup_revisions(argc, argv, &revs, NULL);\n>  \n>  \tif (argc > 1)\n> -\t\treturn error(\"unrecognized argument: %s'\", argv[1]);\n> +\t\treturn error(_(\"unrecognized argument: %s'\"), argv[1]);\n\nThis is a problem in the original but we see an unmatched sq here.\n"},{"id":"190087","messageId":"xmqqehrbbf4s.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"1335184230-8870-8-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 07/10] i18n: apply: mark strings for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-25T22:50:11Z","receivedAt":"2012-04-25T22:50:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> @@ -886,17 +886,17 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n> ...\n>  \t\tif (!another || memcmp(another, name, len + 1))\n> -\t\t\tdie(\"git apply: bad git-diff - inconsistent %s filename on line %d\", oldnew, linenr);\n> +\t\t\tdie(_(\"git apply: bad git-diff - inconsistent %s filename on line %d\"), oldnew, linenr);\n>  \t\tfree(another);\n>  \t\treturn orig_name;\n>  \t}\n\nIn this function, the parameter oldnew has \"old\" or \"new\" and the\ncallers (gitdiff_oldname() and gitdiff_newname()) do not have it marked\nfor translation.  Even if they did, it would result in a lego\ncomposition, so you may have to switch between two translatable messages\nhere.\n"},{"id":"190088","messageId":"xmqqaa1zbexh.fsf@junio.mtv.corp.google.com","threadId":"30308","inReplyTo":"1335184230-8870-7-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 06/10] i18n: remote: mark strings for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-25T22:54:34Z","receivedAt":"2012-04-25T22:54:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> @@ -761,7 +761,7 @@ static int remove_branches(struct string_list *branches)\n>  \t\tunsigned char *sha1 = item->util;\n>  \n>  \t\tif (delete_ref(refname, sha1, 0))\n> -\t\t\tresult |= error(\"Could not remove branch %s\", refname);\n> +\t\t\tresult |= error(_(\"Could not remove branch %s\"), refname);\n>  \t}\n\nThis is an issue in the original, but almost all messages in this\nutility use sq around names of 'stuff' that can be specified by the end\nuser when it appears as part of a sentence, but not here.\n"},{"id":"190089","messageId":"CACsJy8BNbRFKqBKYLR5OKOEPL3iMdjzfSrSAxSZ489nNNW6rVw@mail.gmail.com","threadId":"30308","inReplyTo":"xmqqaa1zbexh.fsf@junio.mtv.corp.google.com","subject":"Re: [PATCH 06/10] i18n: remote: mark strings for translation","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-26T01:12:34Z","receivedAt":"2012-04-26T01:12:34Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2012/4/26 Junio C Hamano <gitster@pobox.com>:\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>\n>> @@ -761,7 +761,7 @@ static int remove_branches(struct string_list *branches)\n>>               unsigned char *sha1 = item->util;\n>>\n>>               if (delete_ref(refname, sha1, 0))\n>> -                     result |= error(\"Could not remove branch %s\", refname);\n>> +                     result |= error(_(\"Could not remove branch %s\"), refname);\n>>       }\n>\n> This is an issue in the original, but almost all messages in this\n> utility use sq around names of 'stuff' that can be specified by the end\n> user when it appears as part of a sentence, but not here.\n\nIf we are going to make a style consistency patch, should we also\nagree on (at least for this command) whether to write initial letter\nin capital or not?\n-- \nDuy\n"},{"id":"190090","messageId":"CACsJy8CzNx9GP2PSszs2rrkQHr0P6fPVe4+-z4QXJ8k_4hqh9w@mail.gmail.com","threadId":"30308","inReplyTo":"xmqqipgnbffm.fsf@junio.mtv.corp.google.com","subject":"Re: [PATCH 10/10] i18n: bundle: mark strings for translation","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-04-26T01:24:55Z","receivedAt":"2012-04-26T01:24:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Apr 26, 2012 at 5:43 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>\n>> @@ -283,13 +287,13 @@ int create_bundle(struct bundle_header *header, const char *path,\n>>       strbuf_release(&buf);\n>>       fclose(rls_fout);\n>>       if (finish_command(&rls))\n>> -             return error(\"rev-list died\");\n>> +             return error(_(\"rev-list died\"));\n>>\n>>       /* write references */\n>>       argc = setup_revisions(argc, argv, &revs, NULL);\n>>\n>>       if (argc > 1)\n>> -             return error(\"unrecognized argument: %s'\", argv[1]);\n>> +             return error(_(\"unrecognized argument: %s'\"), argv[1]);\n>\n> This is a problem in the original but we see an unmatched sq here.\n\nYeah. I searched the code and that seems the only place with\nunbalanced quotes (both single and double quotes). I'll leave it to\nyou to either drop it or add another one there.\n-- \nDuy\n"},{"id":"190096","messageId":"20120426055359.GA2483@burratino","threadId":"30308","inReplyTo":"CACsJy8CzNx9GP2PSszs2rrkQHr0P6fPVe4+-z4QXJ8k_4hqh9w@mail.gmail.com","subject":"[PATCH] bundle: remove stray single-quote from error message","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-04-26T05:53:59Z","receivedAt":"2012-04-26T05:53:59Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"After running rev-list --boundary to retrieve the list of boundary\ncommits, \"git bundle create\" runs its own revision walk.  If in this\nstage git encounters an unfamiliar option, it writes a message with an\nunbalanced quotation mark:\n\n\terror: unrecognized argument: --foo'\n\nDrop the stray quote to match the \"unrecognized argument: %s\" message\nused elsewhere and save translators some work.\n\nThis is mostly a futureproofing measure: for now, the \"rev-list\n--boundary\" command catches most strange arguments on its own and the\nabove message is not seen unless you try something esoteric like \"git\nbundle create test.bundle --header HEAD\".\n\nReported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nNguyen Thai Ngoc Duy wrote:\n\n> Yeah. I searched the code and that seems the only place with\n> unbalanced quotes (both single and double quotes). I'll leave it to\n> you to either drop it or add another one there.\n\nOk, here you go.\n\n bundle.c |    2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex d9cfd905..27ab32e4 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -289,7 +289,7 @@ int create_bundle(struct bundle_header *header, const char *path,\n \targc = setup_revisions(argc, argv, &revs, NULL);\n \n \tif (argc > 1)\n-\t\treturn error(\"unrecognized argument: %s'\", argv[1]);\n+\t\treturn error(\"unrecognized argument: %s\", argv[1]);\n \n \tobject_array_remove_duplicates(&revs.pending);\n \n-- \n1.7.10\n"},{"id":"190910","messageId":"1336310002-3769-1-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"xmqqehrbbf4s.fsf@junio.mtv.corp.google.com","subject":"[PATCH] apply: remove lego in i18n string in gitdiff_verify_name","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-05-06T13:13:22Z","receivedAt":"2012-05-06T13:13:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Currently it marks the string \"...inconsistent %s filename...\" where\n%s is either \"old\" or \"new\" from caller. Make it two strings\n\"...inconsistent new filename...\" and \"...inconsistent old filename...\"\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n On Thu, Apr 26, 2012 at 5:50 AM, Junio C Hamano <gitster@pobox.com> wrote:\n > In this function, the parameter oldnew has \"old\" or \"new\" and the\n > callers (gitdiff_oldname() and gitdiff_newname()) do not have it marked\n > for translation.  Even if they did, it would result in a lego\n > composition, so you may have to switch between two translatable messages\n > here.\n\n Makes sense.\n\n builtin/apply.c |   10 ++++++----\n 1 files changed, 6 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 725712d..1edd3f7 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -919,7 +919,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)\n  * their names against any previous information, just\n  * to make sure..\n  */\n-static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)\n+static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, int new)\n {\n \tif (!orig_name && !isnull)\n \t\treturn find_name(line, NULL, p_value, TERM_TAB);\n@@ -934,7 +934,9 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, linenr);\n \t\tanother = find_name(line, NULL, p_value, TERM_TAB);\n \t\tif (!another || memcmp(another, name, len + 1))\n-\t\t\tdie(_(\"git apply: bad git-diff - inconsistent %s filename on line %d\"), oldnew, linenr);\n+\t\t\tdie(new ?\n+\t\t\t    _(\"git apply: bad git-diff - inconsistent new filename on line %d\") :\n+\t\t\t    _(\"git apply: bad git-diff - inconsistent old filename on line %d\"), linenr);\n \t\tfree(another);\n \t\treturn orig_name;\n \t}\n@@ -949,7 +951,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n static int gitdiff_oldname(const char *line, struct patch *patch)\n {\n \tchar *orig = patch->old_name;\n-\tpatch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, \"old\");\n+\tpatch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, 0);\n \tif (orig != patch->old_name)\n \t\tfree(orig);\n \treturn 0;\n@@ -958,7 +960,7 @@ static int gitdiff_oldname(const char *line, struct patch *patch)\n static int gitdiff_newname(const char *line, struct patch *patch)\n {\n \tchar *orig = patch->new_name;\n-\tpatch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, \"new\");\n+\tpatch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, 1);\n \tif (orig != patch->new_name)\n \t\tfree(orig);\n \treturn 0;\n-- \n1.7.8.36.g69ee2\n"},{"id":"191015","messageId":"7vwr4n6fcj.fsf@alter.siamese.dyndns.org","threadId":"30308","inReplyTo":"1336310002-3769-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH] apply: remove lego in i18n string in gitdiff_verify_name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-07T18:00:44Z","receivedAt":"2012-05-07T18:00:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Currently it marks the string \"...inconsistent %s filename...\" where\n> %s is either \"old\" or \"new\" from caller. Make it two strings\n> \"...inconsistent new filename...\" and \"...inconsistent old filename...\"\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  On Thu, Apr 26, 2012 at 5:50 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>  > In this function, the parameter oldnew has \"old\" or \"new\" and the\n>  > callers (gitdiff_oldname() and gitdiff_newname()) do not have it marked\n>  > for translation.  Even if they did, it would result in a lego\n>  > composition, so you may have to switch between two translatable messages\n>  > here.\n>\n>  Makes sense.\n>\n>  builtin/apply.c |   10 ++++++----\n>  1 files changed, 6 insertions(+), 4 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index 725712d..1edd3f7 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -919,7 +919,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)\n>   * their names against any previous information, just\n>   * to make sure..\n>   */\n> -static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)\n> +static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, int new)\n>  {\n\nThis change is unwarranted, though.  The callers were much clearer when\nthey passed \"old\" vs \"new\"; now they pass an unexplained 0 vs 1.\n"},{"id":"191090","messageId":"1336484307-31553-1-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"7vwr4n6fcj.fsf@alter.siamese.dyndns.org","subject":"[PATCH] apply: remove lego in i18n string in gitdiff_verify_name","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-05-08T13:38:27Z","receivedAt":"2012-05-08T13:38:27Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Currently it marks the string \"...inconsistent %s filename...\" where\n%s is either \"old\" or \"new\" from caller. From a translator point of\nview, nothing hints what \"%s\" may be. Make it two strings\n\"...inconsistent new filename...\" and \"...inconsistent old\nfilename...\"\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n On Tue, May 8, 2012 at 1:00 AM, Junio C Hamano <gitster@pobox.com> wrote:\n >> diff --git a/builtin/apply.c b/builtin/apply.c\n >> index 725712d..1edd3f7 100644\n >> --- a/builtin/apply.c\n >> +++ b/builtin/apply.c\n >> @@ -919,7 +919,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)\n >>   * their names against any previous information, just\n >>   * to make sure..\n >>   */\n >> -static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)\n >> +static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, int new)\n >>  {\n >\n > This change is unwarranted, though.  The callers were much clearer when\n > they passed \"old\" vs \"new\"; now they pass an unexplained 0 vs 1.\n\n Hmm.. how about this?\n\n builtin/apply.c |   11 +++++++++--\n 1 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 725712d..92ba925 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -933,8 +933,15 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, linenr);\n \t\tanother = find_name(line, NULL, p_value, TERM_TAB);\n-\t\tif (!another || memcmp(another, name, len + 1))\n-\t\t\tdie(_(\"git apply: bad git-diff - inconsistent %s filename on line %d\"), oldnew, linenr);\n+\t\tif (!another || memcmp(another, name, len + 1)) {\n+\t\t\tif (!strcmp(oldnew, \"old\"))\n+\t\t\t\tdie(_(\"git apply: bad git-diff - inconsistent old filename on line %d\"), linenr);\n+\t\t\telse if (!strcmp(oldnew, \"new\"))\n+\t\t\t\tdie(_(\"git apply: bad git-diff - inconsistent new filename on line %d\"), linenr);\n+\t\t\telse\n+\t\t\t\tdie(\"BUG: please add a new full string for '%s' similar to above code.\\n\"\n+\t\t\t\t    \"It makes translators' life much simpler. Thanks!\", oldnew);\n+\t\t}\n \t\tfree(another);\n \t\treturn orig_name;\n \t}\n-- \n1.7.8.36.g69ee2\n"},{"id":"191122","messageId":"7vd36ewqi2.fsf@alter.siamese.dyndns.org","threadId":"30308","inReplyTo":"1336484307-31553-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH] apply: remove lego in i18n string in gitdiff_verify_name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-08T17:07:33Z","receivedAt":"2012-05-08T17:07:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Currently it marks the string \"...inconsistent %s filename...\" where\n> %s is either \"old\" or \"new\" from caller. From a translator point of\n> view, nothing hints what \"%s\" may be. Make it two strings\n> \"...inconsistent new filename...\" and \"...inconsistent old\n> filename...\"\n\nTrue.  Also depending on 'old' vs 'new', the translation of \"filename\" or\nother parts of the message may have to inflect/conjugate, so the original\nmessage structure was very unfriendly to i18n.\n\n> +\t\tif (!another || memcmp(another, name, len + 1)) {\n> +\t\t\tif (!strcmp(oldnew, \"old\"))\n> +\t\t\t\tdie(_(\"git apply: bad git-diff - inconsistent old filename on line %d\"), linenr);\n> +\t\t\telse if (!strcmp(oldnew, \"new\"))\n> +\t\t\t\tdie(_(\"git apply: bad git-diff - inconsistent new filename on line %d\"), linenr);\n> +\t\t\telse\n> +\t\t\t\tdie(\"BUG: please add a new full string for '%s' similar to above code.\\n\"\n> +\t\t\t\t    \"It makes translators' life much simpler. Thanks!\", oldnew);\n> +\t\t}\n\nI think this is way over-engineered.  enum { DIFF_OLD = 0, DIFF_NEW = 1 }\nor even passing 'n' vs 'o' was what I was expecting to see.\n"},{"id":"191193","messageId":"1336566562-21933-1-git-send-email-pclouds@gmail.com","threadId":"30308","inReplyTo":"7vd36ewqi2.fsf@alter.siamese.dyndns.org","subject":"[PATCH] apply: remove lego in i18n string in gitdiff_verify_name","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-05-09T12:29:22Z","receivedAt":"2012-05-09T12:29:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Currently it marks the string \"...inconsistent %s filename...\" where\n%s is either \"old\" or \"new\" from caller. From a translator point of\nview, nothing hints what \"%s\" may be and what grammatical form it may\nuse.\n\nMake it two strings \"...inconsistent new filename...\" and\n\"...inconsistent old filename...\"\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Another try. enum this time.\n\n builtin/apply.c |   17 +++++++++++++----\n 1 files changed, 13 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 725712d..3362f4a 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -910,6 +910,11 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)\n \treturn -1;\n }\n \n+enum diff_filename {\n+\tDIFF_OLD,\n+\tDIFF_NEW\n+};\n+\n /*\n  * We're anal about diff header consistency, to make\n  * sure that we don't end up having strange ambiguous\n@@ -919,7 +924,8 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)\n  * their names against any previous information, just\n  * to make sure..\n  */\n-static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)\n+static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n+\t\t\t\t enum diff_filename oldnew)\n {\n \tif (!orig_name && !isnull)\n \t\treturn find_name(line, NULL, p_value, TERM_TAB);\n@@ -934,7 +940,10 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, linenr);\n \t\tanother = find_name(line, NULL, p_value, TERM_TAB);\n \t\tif (!another || memcmp(another, name, len + 1))\n-\t\t\tdie(_(\"git apply: bad git-diff - inconsistent %s filename on line %d\"), oldnew, linenr);\n+\t\t\tdie(oldnew == DIFF_OLD ?\n+\t\t\t    _(\"git apply: bad git-diff - inconsistent old filename on line %d\") :\n+\t\t\t    _(\"git apply: bad git-diff - inconsistent new filename on line %d\"),\n+\t\t\t    linenr);\n \t\tfree(another);\n \t\treturn orig_name;\n \t}\n@@ -949,7 +958,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n static int gitdiff_oldname(const char *line, struct patch *patch)\n {\n \tchar *orig = patch->old_name;\n-\tpatch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, \"old\");\n+\tpatch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, DIFF_OLD);\n \tif (orig != patch->old_name)\n \t\tfree(orig);\n \treturn 0;\n@@ -958,7 +967,7 @@ static int gitdiff_oldname(const char *line, struct patch *patch)\n static int gitdiff_newname(const char *line, struct patch *patch)\n {\n \tchar *orig = patch->new_name;\n-\tpatch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, \"new\");\n+\tpatch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, DIFF_NEW);\n \tif (orig != patch->new_name)\n \t\tfree(orig);\n \treturn 0;\n-- \n1.7.8.36.g69ee2\n"}]}