Skip to content

Commit 3a14bcf

Browse files
committed
l10n: add .gitattributes to simplify location filtering
To simplify the location filtering process for l10n contributors when committing po/XX.po files, add filter attributes for selected PO files to the repository. This ensures all contributors automatically get the same filter configuration without manual setup in .git/info/attributes. The default filter (gettext-no-location) is applied to all .po files except: - Legacy, unmaintained PO files that still contain location comments. Leaving the filter off avoids index vs working-tree discrepancies for these files. The CI pipeline will report an error when future updates touch these legacy files. - Some PO files use a different filter that strips only line numbers from location comments while keeping filenames. Contributors still need to manually define the filter drivers via git-config as documented in po/README.md. Four PO files that use location filtering (po/ca.po, po/es.po, po/ga.po, po/ru.po) were batch-modified so their on-disk format matches the filter output (e.g. line wrapping), avoiding index vs working-tree mismatch. Additionally, po/README.md has been reorganized: the material on preparing location-less PO files for commit has been moved from "Updating a XX.po file" to a separate "Preparing a XX.po file for commit" section. This prevents AI agents from introducing unrelated operations when updating PO files. Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
1 parent 2565546 commit 3a14bcf

6 files changed

Lines changed: 161 additions & 119 deletions

File tree

po/.gitattributes

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Git Attributes for PO Files
2+
#
3+
# This file configures Git filters to automatically strip location information
4+
# from PO files when committing, producing cleaner diffs and saving repository
5+
# space.
6+
#
7+
# Two filter types are used:
8+
# 1. gettext-no-location: Strips both filenames and line numbers
9+
# (e.g., removes "#: main.c:123" entirely)
10+
# 2. gettext-no-line-number: Preserves filenames but removes line numbers, which
11+
# requires gettext 0.20 or higher
12+
# (e.g., "#: main.c:123" becomes "#: main.c")
13+
#
14+
# See `po/README.md` for instructions on setting up the required filter drivers.
15+
16+
# Default: Strip the whole location comments for all .po files
17+
*.po filter=gettext-no-location
18+
19+
# Legacy, unmaintained PO files: filter disabled to avoid index vs
20+
# working-tree mismatch (these files still have location comments).
21+
el.po -filter
22+
is.po -filter
23+
it.po -filter
24+
ko.po -filter
25+
pl.po -filter
26+
pt_PT.po -filter
27+
28+
# These files use gettext-no-line-number (keep filenames, strip line
29+
# numbers). The choice is per l10n team preference. Requires gettext 0.20+.
30+
# The only benefit is locating source files from location comments when
31+
# the .po file is not updated from the POT via make po-update.
32+
ca.po filter=gettext-no-line-number
33+
id.po filter=gettext-no-line-number
34+
zh_CN.po filter=gettext-no-line-number
35+
zh_TW.po filter=gettext-no-line-number

po/README.md

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -159,38 +159,6 @@ It will:
159159
and these location lines will help translation tools to locate
160160
translation context easily.
161161

162-
Once you are done testing the translation (see below), it's better
163-
to commit a location-less "po/XX.po" file to save repository space
164-
and make a user-friendly patch for review.
165-
166-
To save a location-less "po/XX.po" automatically in repository, you
167-
can:
168-
169-
First define a new attribute for "po/XX.po" by appending the following
170-
line in ".git/info/attributes":
171-
172-
```
173-
/po/XX.po filter=gettext-no-location
174-
```
175-
176-
Then define the driver for the "gettext-no-location" clean filter to
177-
strip out both filenames and locations from the contents as follows:
178-
179-
```shell
180-
git config --global filter.gettext-no-location.clean \
181-
"msgcat --no-location -"
182-
```
183-
184-
For users who have gettext version 0.20 or higher, it is also possible
185-
to define a clean filter to preserve filenames but not locations:
186-
187-
```shell
188-
git config --global filter.gettext-no-location.clean \
189-
"msgcat --add-location=file -"
190-
```
191-
192-
You're now ready to ask the l10n coordinator to pull from you.
193-
194162

195163
## Fuzzy translation
196164

@@ -229,6 +197,45 @@ git-po-helper check-commits <rev-list-opts>
229197
```
230198

231199

200+
## Preparing a "XX.po" file for commit
201+
202+
Once you are done testing the translation, it's better to commit a
203+
location-less "po/XX.po" file to save repository space and make a
204+
user-friendly patch for review.
205+
206+
To save a location-less "po/XX.po" automatically in the repository,
207+
follow these steps:
208+
209+
First, check which filter is configured for your "po/XX.po" file:
210+
211+
```
212+
git check-attr filter po/XX.po
213+
```
214+
215+
The filter configuration is defined in the "po/.gitattributes" file.
216+
217+
Then define the driver for the filter. Most languages use the
218+
"gettext-no-location" clean filter, which strips out both filenames and line
219+
numbers from location comments. To set this up, run the following command:
220+
221+
```shell
222+
git config --global filter.gettext-no-location.clean \
223+
"msgcat --no-location -"
224+
```
225+
226+
Some PO files use the "gettext-no-line-number" clean filter, which keeps
227+
filenames but strips line numbers. This filter requires gettext 0.20 or
228+
later. The only benefit is being able to locate source files from location
229+
comments when the .po file is not updated from the POT via `make po-update`.
230+
231+
```shell
232+
git config --global filter.gettext-no-line-number.clean \
233+
"msgcat --add-location=file -"
234+
```
235+
236+
You're now ready to ask the l10n coordinator to pull from you.
237+
238+
232239
## Marking strings for translation
233240

234241
(This is done by the core developers).

po/ca.po

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,8 @@ msgstr ""
512512
#, c-format
513513
msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
514514
msgstr ""
515-
"Descarta el canvi de mode de l'índex i de l'arbre de treball [y,n,q,a,d"
516-
"%s,?]? "
515+
"Descarta el canvi de mode de l'índex i de l'arbre de treball "
516+
"[y,n,q,a,d%s,?]? "
517517

518518
#: add-patch.c
519519
#, c-format
@@ -3879,11 +3879,11 @@ msgstr "HEAD no trobat sota refs/heads!"
38793879

38803880
#: builtin/branch.c
38813881
msgid ""
3882-
"branch with --recurse-submodules can only be used if submodule."
3883-
"propagateBranches is enabled"
3882+
"branch with --recurse-submodules can only be used if "
3883+
"submodule.propagateBranches is enabled"
38843884
msgstr ""
3885-
"la branca amb --recurse-submodules només es pot utilitzar si submodule."
3886-
"propagateBranches està habilitat"
3885+
"la branca amb --recurse-submodules només es pot utilitzar si "
3886+
"submodule.propagateBranches està habilitat"
38873887

38883888
#: builtin/branch.c
38893889
msgid "--recurse-submodules can only be used to create branches"
@@ -7983,11 +7983,11 @@ msgstr "el protocol no admet --negotiate-only, se surt"
79837983

79847984
#: builtin/fetch.c
79857985
msgid ""
7986-
"--filter can only be used with the remote configured in extensions."
7987-
"partialclone"
7986+
"--filter can only be used with the remote configured in "
7987+
"extensions.partialclone"
79887988
msgstr ""
7989-
"--filter només es pot utilitzar amb el remot configurat en extensions."
7990-
"partialclone"
7989+
"--filter només es pot utilitzar amb el remot configurat en "
7990+
"extensions.partialclone"
79917991

79927992
#: builtin/fetch.c
79937993
msgid "--atomic can only be used when fetching from one remote"
@@ -11436,8 +11436,8 @@ msgid ""
1143611436
"| -C) <object>] [<object>] [-e]"
1143711437
msgstr ""
1143811438
"git notes [--ref <referència-notes>] add [-f] [--allow-empty] [--"
11439-
"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | -"
11440-
"F <fitxer> | (-c | -C) <objecte>] [<objecte>]"
11439+
"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | "
11440+
"-F <fitxer> | (-c | -C) <objecte>] [<objecte>]"
1144111441

1144211442
#: builtin/notes.c
1144311443
msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"
@@ -11451,8 +11451,8 @@ msgid ""
1145111451
"| -C) <object>] [<object>] [-e]"
1145211452
msgstr ""
1145311453
"git notes [--ref <referència-notes>] append [--allow-empty] [--"
11454-
"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | -"
11455-
"F <fitxer> | (-c | -C) <objecte>] [<objecte>] [-e]"
11454+
"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | "
11455+
"-F <fitxer> | (-c | -C) <objecte>] [<objecte>] [-e]"
1145611456

1145711457
#: builtin/notes.c
1145811458
msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"
@@ -13231,8 +13231,8 @@ msgstr "--empty=ask és obslolet; utilitzeu '--empty=stop' en el seu lloc."
1323113231
#: builtin/rebase.c
1323213232
#, c-format
1323313233
msgid ""
13234-
"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"stop"
13235-
"\"."
13234+
"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
13235+
"\"stop\"."
1323613236
msgstr ""
1323713237
"tipus buit «%s» no reconegut; els valors vàlids són \"drop\", \"keep\" i "
1323813238
"\"stop\"."
@@ -14440,8 +14440,8 @@ msgid ""
1444014440
msgstr ""
1444114441
"Els reempaquetaments incrementals són incompatibles amb els índexs de mapes "
1444214442
"de bits. Useu\n"
14443-
"--no-write-bitmap-index o inhabiliteu el paràmetre de configuració pack."
14444-
"writeBitmaps."
14443+
"--no-write-bitmap-index o inhabiliteu el paràmetre de configuració "
14444+
"pack.writeBitmaps."
1444514445

1444614446
#: builtin/repack.c
1444714447
msgid "could not start pack-objects to repack promisor objects"
@@ -19350,11 +19350,11 @@ msgstr ""
1935019350
#: commit-graph.c
1935119351
#, c-format
1935219352
msgid ""
19353-
"attempting to write a commit-graph, but 'commitGraph."
19354-
"changedPathsVersion' (%d) is not supported"
19353+
"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
19354+
"(%d) is not supported"
1935519355
msgstr ""
19356-
"s'ha intentat escriure un graf de comissió, però no s'admet 'commitGraph."
19357-
"changedPathsVersion' (%d)"
19356+
"s'ha intentat escriure un graf de comissió, però no s'admet "
19357+
"'commitGraph.changedPathsVersion' (%d)"
1935819358

1935919359
#: commit-graph.c
1936019360
msgid "too many commits to write graph"
@@ -22940,8 +22940,8 @@ msgstr "el fitxer de l'índex multipaquet %s és massa petit"
2294022940
#, c-format
2294122941
msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
2294222942
msgstr ""
22943-
"la signatura de l'índex multipaquet 0x%08x no coincideix amb la signatura 0x"
22944-
"%08x"
22943+
"la signatura de l'índex multipaquet 0x%08x no coincideix amb la signatura "
22944+
"0x%08x"
2294522945

2294622946
#: midx.c
2294722947
#, c-format

po/es.po

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ msgstr ""
391391
#, c-format, perl-format
392392
msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
393393
msgstr ""
394-
"¿Aplicar cambio de modo para el índice y el árbol de trabajo [y,n,q,a,"
395-
"d%s,?]? "
394+
"¿Aplicar cambio de modo para el índice y el árbol de trabajo "
395+
"[y,n,q,a,d%s,?]? "
396396

397397
#, c-format, perl-format
398398
msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
@@ -2294,9 +2294,9 @@ msgid ""
22942294
"=<term>] [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] "
22952295
"[<paths>...]"
22962296
msgstr ""
2297-
"git bisect--helper --bisect-start [--term-{new,bad}=<término> --term-{old,"
2298-
"good}=<término>] [--no-checkout] [--first-parent] [<malo> [<bueno>...]] [--] "
2299-
"[<rutas>...]"
2297+
"git bisect--helper --bisect-start [--term-{new,bad}=<término> --term-"
2298+
"{old,good}=<término>] [--no-checkout] [--first-parent] [<malo> [<bueno>...]] "
2299+
"[--] [<rutas>...]"
23002300

23012301
msgid "git bisect--helper --bisect-state (bad|new) [<rev>]"
23022302
msgstr "git bisect--helper --bisect-state (bad|new) [<rev>]"
@@ -2983,11 +2983,11 @@ msgid "HEAD not found below refs/heads!"
29832983
msgstr "¡HEAD no encontrado dentro de refs/heads!"
29842984

29852985
msgid ""
2986-
"branch with --recurse-submodules can only be used if submodule."
2987-
"propagateBranches is enabled"
2986+
"branch with --recurse-submodules can only be used if "
2987+
"submodule.propagateBranches is enabled"
29882988
msgstr ""
2989-
"branch con --recurse-submodules solo se puede usar si submodule."
2990-
"propagateBranches está habilitado"
2989+
"branch con --recurse-submodules solo se puede usar si "
2990+
"submodule.propagateBranches está habilitado"
29912991

29922992
msgid "--recurse-submodules can only be used to create branches"
29932993
msgstr "--recurse-submodules solo se puede usar para crear ramas"
@@ -5983,11 +5983,11 @@ msgid "protocol does not support --negotiate-only, exiting"
59835983
msgstr "el protocolo no soporta --negotiate-only, saliendo"
59845984

59855985
msgid ""
5986-
"--filter can only be used with the remote configured in extensions."
5987-
"partialclone"
5986+
"--filter can only be used with the remote configured in "
5987+
"extensions.partialclone"
59885988
msgstr ""
5989-
"--filter solo puede ser usado con el remoto configurado en extensions."
5990-
"partialclone"
5989+
"--filter solo puede ser usado con el remoto configurado en "
5990+
"extensions.partialclone"
59915991

59925992
msgid "--atomic can only be used when fetching from one remote"
59935993
msgstr "--atomic solo se puede usar cuando se busca desde un control remoto"
@@ -8914,8 +8914,8 @@ msgstr "objeto esperado en el desplazamiento %<PRIuMAX> en el paquete %s"
89148914

89158915
msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
89168916
msgstr ""
8917-
"deshabilitando escritura bitmap, paquetes son divididos debido a pack."
8918-
"packSizeLimit"
8917+
"deshabilitando escritura bitmap, paquetes son divididos debido a "
8918+
"pack.packSizeLimit"
89198919

89208920
msgid "Writing objects"
89218921
msgstr "Escribiendo objetos"
@@ -9489,8 +9489,8 @@ msgstr ""
94899489
msgid ""
94909490
"\n"
94919491
"To avoid automatically configuring upstream branches when their name\n"
9492-
"doesn't match the local branch, see option 'simple' of branch."
9493-
"autoSetupMerge\n"
9492+
"doesn't match the local branch, see option 'simple' of "
9493+
"branch.autoSetupMerge\n"
94949494
"in 'git help config'.\n"
94959495
msgstr ""
94969496
"\n"

0 commit comments

Comments
 (0)