Git fork
at reftables-rust 460 lines 14 kB view raw view rendered
1# Core GIT Translations 2 3This directory holds the translations for the core of Git. This document 4describes how you can contribute to the effort of enhancing the language 5coverage and maintaining the translation. 6 7The localization (l10n) coordinator, Jiang Xin <worldhello.net@gmail.com>, 8coordinates our localization effort in the l10n coordinator repository: 9 10 https://github.com/git-l10n/git-po/ 11 12We will use XX as an alias to refer to the language translation code in 13the following paragraphs, for example we use "po/XX.po" to refer to the 14translation file for a specific language. But this doesn't mean that 15the language code has only two letters. The language code can be in one 16of two forms: "ll" or "ll\_CC". Here "ll" is the ISO 639 two-letter 17language code and "CC" is the ISO 3166 two-letter code for country names 18and subdivisions. For example: "de" for German language code, "zh\_CN" 19for Simplified Chinese language code. 20 21 22## Contributing to an existing translation 23 24As a contributor for a language XX, you should first check TEAMS file in 25this directory to see whether a dedicated repository for your language XX 26exists. Fork the dedicated repository and start to work if it exists. 27 28Sometime, contributors may find that the translations of their Git 29distributions are quite different with the translations of the 30corresponding version from Git official. This is because some Git 31distributions (such as from Ubuntu, etc.) have their own l10n workflow. 32For this case, wrong translations should be reported and fixed through 33their workflows. 34 35 36## Creating a new language translation 37 38If you are the first contributor for the language XX, please fork this 39repository, prepare and/or update the translated message file "po/XX.po" 40(described later), and ask the l10n coordinator to pull your work. 41 42If there are multiple contributors for the same language, please first 43coordinate among yourselves and nominate the team leader for your 44language, so that the l10n coordinator only needs to interact with one 45person per language. 46 47 48## Translation Process Flow 49 50The overall data-flow looks like this: 51 52 +-------------------+ +------------------+ 53 | Git source code | ----(2)---> | L10n coordinator | 54 | repository | <---(5)---- | repository | 55 +-------------------+ +------------------+ 56 | | ^ 57 (1) (3) (4) 58 V v | 59 +----------------------------------+ 60 | Language Team XX | 61 +----------------------------------+ 62 63- Translatable strings are marked in the source file. 64- Language teams can start translation iterations at any time, even 65 before the l10n window opens: 66 67 + Pull from the master branch of the source (1) 68 + Update the message file by running "make po-update PO\_FILE=po/XX.po" 69 + Translate the message file "po/XX.po" 70 71- The L10n coordinator pulls from source and announces the l10n window 72 open (2) 73- Language team pulls from the l10n coordinator, starts another 74 translation iteration against the l10n coordinator's tree (3) 75 76 + Run "git pull --rebase" from the l10n coordinator 77 + Update the message file by running "make po-update PO\_FILE=po/XX.po" 78 + Translate the message file "po/XX.po" 79 + Squash trivial l10n git commits using "git rebase -i" 80 81- Language team sends pull request to the l10n coordinator (4) 82- L10n coordinator checks and merges 83- L10n coordinator asks the result to be pulled (5). 84 85 86## Dynamically generated POT files 87 88POT files are templates for l10n contributors to create or update their 89translation files. We used to have the "po/git.pot" file which was 90generated by the l10n coordinator, but this file had been removed from 91the tree. 92 93The two POT files "po/git.pot" and "po/git-core.pot" can be created 94dynamically when necessary. 95 96L10n contributors use "po/git.pot" to prepare translations for their 97languages, but they are not expected to modify it. The "po/git.pot" file 98can be generated manually with the following command: 99 100```shell 101make po/git.pot 102``` 103 104The "po/git-core.pot" file is the template for core translations. A core 105translation is the minimum set of work necessary to complete a 106translation of a new language. Since there are more than 5000 messages 107in the full set of template message file "po/git.pot" that need to be 108translated, this is not a piece of cake for new language contributors. 109 110The "core" template file "po/git-core.pot" can be generated manually 111by running: 112 113```shell 114make po/git-core.pot 115``` 116 117 118## Initializing a "XX.po" file 119 120(This is done by the language teams). 121 122If your language XX does not have translated message file "po/XX.po" yet, 123you add a translation for the first time by running: 124 125```shell 126make po-init PO_FILE=po/XX.po 127``` 128 129where XX is the locale, e.g. "de", "is", "pt\_BR", "zh\_CN", etc. 130 131The newly generated message file "po/XX.po" is based on the core pot 132file "po/git-core.pot", so it contains only a minimal set of messages 133and it's a good start for a new language contribution. 134 135Once you are done testing the translation (see below), commit the result 136and ask the l10n coordinator to pull from you. 137 138 139## Updating a "XX.po" file 140 141(This is done by the language teams). 142 143If you are replacing translation strings in an existing "XX.po" file to 144improve the translation, just edit the file. 145 146If you want to find new translatable strings in source files of upstream 147repository and propagate them to your "po/XX.po", run command: 148 149```shell 150make po-update PO_FILE=po/XX.po 151``` 152 153It will: 154 155- Call "make po/git.pot" to generate new "po/git.pot" file 156- Call "msgmerge --add-location --backup=off -U po/XX.po po/git.pot" 157 to update your "po/XX.po" 158- The "--add-location" option for msgmerge will add location lines, 159 and these location lines will help translation tools to locate 160 translation context easily. 161 162Once you are done testing the translation (see below), it's better 163to commit a location-less "po/XX.po" file to save repository space 164and make a user-friendly patch for review. 165 166To save a location-less "po/XX.po" automatically in repository, you 167can: 168 169First define a new attribute for "po/XX.po" by appending the following 170line in ".git/info/attributes": 171 172``` 173/po/XX.po filter=gettext-no-location 174``` 175 176Then define the driver for the "gettext-no-location" clean filter to 177strip out both filenames and locations from the contents as follows: 178 179```shell 180git config --global filter.gettext-no-location.clean \ 181 "msgcat --no-location -" 182``` 183 184For users who have gettext version 0.20 or higher, it is also possible 185to define a clean filter to preserve filenames but not locations: 186 187```shell 188git config --global filter.gettext-no-location.clean \ 189 "msgcat --add-location=file -" 190``` 191 192You're now ready to ask the l10n coordinator to pull from you. 193 194 195## Fuzzy translation 196 197Fuzzy translation is a translation marked by comment "fuzzy" to let you 198know that the translation is out of date because the "msgid" has been 199changed. A fuzzy translation will be ignored when compiling using "msgfmt". 200Fuzzy translation can be marked by hands, but for most cases they are 201marked automatically when running "msgmerge" to update your "XX.po" file. 202 203After fixing the corresponding translation, you must remove the "fuzzy" 204tag in the comment. 205 206 207## Testing your changes 208 209(This is done by the language teams, after creating or updating "XX.po" file). 210 211Before you submit your changes go back to the top-level and do: 212 213```shell 214make 215``` 216 217On systems with GNU gettext (i.e. not Solaris) this will compile your 218changed PO file with `msgfmt --check`, the --check option flags many 219common errors, e.g. missing printf format strings, or translated 220messages that deviate from the originals in whether they begin/end 221with a newline or not. 222 223L10n coordinator will check your contributions using a helper program 224(see "PO helper" section below): 225 226```shell 227git-po-helper check-po po/XX.po 228git-po-helper check-commits <rev-list-opts> 229``` 230 231 232## Marking strings for translation 233 234(This is done by the core developers). 235 236Before strings can be translated they first have to be marked for 237translation. 238 239Git uses an internationalization interface that wraps the system's 240gettext library, so most of the advice in your gettext documentation 241(on GNU systems `info gettext` in a terminal) applies. 242 243General advice: 244 245- Don't mark everything for translation, only strings which will be 246 read by humans (the porcelain interface) should be translated. 247 248 The output from Git's plumbing utilities will primarily be read by 249 programs and would break scripts under non-C locales if it was 250 translated. Plumbing strings should not be translated, since 251 they're part of Git's API. 252 253- Adjust the strings so that they're easy to translate. Most of the 254 advice in `info '(gettext)Preparing Strings'` applies here. 255 256- Strings referencing numbers of items may need to be split into singular and 257 plural forms; see the Q\_() wrapper in the C sub-section below for an 258 example. 259 260- If something is unclear or ambiguous you can use a "TRANSLATORS" 261 comment to tell the translators what to make of it. These will be 262 extracted by xgettext(1) and put in the "po/\*.po" files, e.g. from 263 git-am.sh: 264 265 ```shell 266 # TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a] 267 # in your translation. The program will only accept English 268 # input at this point. 269 gettext "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all " 270 ``` 271 272 Or in C, from builtin/revert.c: 273 274 ```c 275 /* TRANSLATORS: %s will be "revert" or "cherry-pick" */ 276 die(_("%s: Unable to write new index file"), action_name(opts)); 277 ``` 278 279We provide wrappers for C, Shell and Perl programs. Here's how they're 280used: 281 282 283### C 284 285Include builtin.h at the top, it'll pull in gettext.h, which 286defines the gettext interface. Consult with the list if you need to 287use gettext.h directly. 288 289The C interface is a subset of the normal GNU gettext 290interface. We currently export these functions: 291 292- \_() 293 294 Mark and translate a string. E.g.: 295 296 ```c 297 printf(_("HEAD is now at %s"), hex); 298 ``` 299 300- Q\_() 301 302 Mark and translate a plural string. E.g.: 303 304 ```c 305 printf(Q_("%d commit", "%d commits", number_of_commits)); 306 ``` 307 308 This is just a wrapper for the ngettext() function. 309 310- N\_() 311 312 A no-op pass-through macro for marking strings inside static 313 initializations, e.g.: 314 315 ```c 316 static const char *reset_type_names[] = { 317 N_("mixed"), N_("soft"), N_("hard"), N_("merge"), N_("keep"), NULL 318 }; 319 ``` 320 321 And then, later: 322 323 ```c 324 die(_("%s reset is not allowed in a bare repository"), 325 _(reset_type_names[reset_type])); 326 ``` 327 328 Here `_()` couldn't have statically determined what the translation 329 string will be, but since it was already marked for translation 330 with `N_()` the look-up in the message catalog will succeed. 331 332 333### Shell 334 335The Git gettext shell interface is just a wrapper for 336gettext.sh. Import it right after git-sh-setup like this: 337 338```shell 339. git-sh-setup 340. git-sh-i18n 341``` 342 343And then use the `gettext` or `eval_gettext` functions: 344 345```shell 346# For constant interface messages: 347gettext "A message for the user"; echo 348 349# To interpolate variables: 350details="oh noes" 351eval_gettext "An error occurred: \$details"; echo 352``` 353 354In addition we have wrappers for messages that end with a trailing 355newline. I.e. you could write the above as: 356 357```shell 358# For constant interface messages: 359gettextln "A message for the user" 360 361# To interpolate variables: 362details="oh noes" 363eval_gettextln "An error occurred: \$details" 364``` 365 366More documentation about the interface is available in the GNU info 367page: `info '(gettext)sh'`. Looking at git-am.sh (the first shell 368command to be translated) for examples is also useful: 369 370```shell 371git log --reverse -p --grep=i18n git-am.sh 372``` 373 374 375### Perl 376 377The Git::I18N module provides a limited subset of the 378Locale::Messages functionality, e.g.: 379 380```perl 381use Git::I18N; 382print __("Welcome to Git!\n"); 383printf __("The following error occurred: %s\n"), $error; 384``` 385 386Run `perldoc perl/Git/I18N.pm` for more info. 387 388 389## Testing marked strings 390 391Git's tests are run under `LANG=C LC_ALL=C`. So the tests do not need be 392changed to account for translations as they're added. 393 394 395## PO helper 396 397To make the maintenance of "XX.po" easier, the l10n coordinator and l10n 398team leaders can use a helper program named "git-po-helper". It is a 399wrapper to gettext suite, specifically written for the purpose of Git 400l10n workflow. 401 402To build and install the helper program from source, see 403[git-po-helper/README][]. 404 405 406## Conventions 407 408There are some conventions that l10n contributors must follow: 409 410- The subject of each l10n commit should be prefixed with "l10n: ". 411 412- Do not use non-ASCII characters in the subject of a commit. 413 414- The length of commit subject (first line of the commit log) should 415 be no more than 50 characters, and the length of other lines of the 416 commit log should be no more than 72 characters. 417 418- Add "Signed-off-by" trailer to your commit log, like other commits 419 in Git. You can automatically add the trailer by committing with 420 the following command: 421 422 ```shell 423 git commit -s 424 ``` 425 426- Check syntax with "msgfmt" or the following command before creating 427 your commit: 428 429 ```shell 430 git-po-helper check-po <XX.po> 431 ``` 432 433- Squash trivial commits to make history clear. 434 435- DO NOT edit files outside "po/" directory. 436 437- Other subsystems ("git-gui", "gitk", and Git itself) have their 438 own workflow. See [Documentation/SubmittingPatches][] for 439 instructions on how to contribute patches to these subsystems. 440 441 442To contribute for a new l10n language, contributor should follow 443additional conventions: 444 445- Initialize proper filename of the "XX.po" file conforming to 446 iso-639 and iso-3166. 447 448- Must complete a minimal translation based on the "Core 449 translation". See that section above. 450 451- Add a new entry in the "po/TEAMS" file with proper format, and check 452 the syntax of "po/TEAMS" by running the following command: 453 454 ```shell 455 git-po-helper team --check 456 ``` 457 458 459[git-po-helper/README]: https://github.com/git-l10n/git-po-helper#readme 460[Documentation/SubmittingPatches]: Documentation/SubmittingPatches