Skip to content

Commit 44d589c

Browse files
authored
Merge pull request #837 from git/ngettext-microproject
SoC-2026: add new microproject related to Q_ / ngettext usage
2 parents 309b802 + 2dcabc4 commit 44d589c

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

links/mentoring/soc/SoC-2026-Microprojects.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,87 @@ with Git's dedicated test helpers like `test_path_is_file`.
5757
- If you can't find any instances to fix, let us know what search command you
5858
used
5959

60+
### Fix Improper Pluralization to Use `ngettext()`
61+
62+
Help improve Git's internationalization (i18n) support by finding
63+
translatable strings that include a numeric placeholder (`%d` or
64+
`%i`) but use `_()` instead of `Q_()`. This matters because
65+
some languages (like Polish) have more than two plural forms, and
66+
`Q_()` is the only correct way to handle them.
67+
68+
For example, the Polish word for "file" changes form depending on count:
69+
70+
- 1 → *plik*
71+
- 2 - 4 → *pliki*
72+
- 5 - 21 → *plików*
73+
- 22 - 24 → *pliki*
74+
- 25 - 31 → *plików*
75+
76+
A call like `_("Split into %d hunks.")` cannot be correctly translated
77+
for all counts. It must be rewritten using `Q_()` which is an alias
78+
for `ngettext()`.
79+
80+
#### Steps to Complete
81+
82+
1. Find candidate strings using:
83+
84+
```bash
85+
git grep '[^Q]_("[^"]*%[id]' -- '*.c'
86+
```
87+
88+
2. Review the results and identify strings where the number genuinely
89+
controls a **count of things** (hunks, branches, objects, etc.). Skip
90+
messages where `%d` refers to something that is never pluralized,
91+
such as an error code, a line number, or a timeout value:
92+
93+
```c
94+
// NOT a pluralization candidate — error code is never "plural"
95+
die_errno(_("unable to get credential storage lock in %d ms"), timeout_ms);
96+
97+
// IS a candidate — hunk count should be pluralized
98+
_("Split into %d hunks.")
99+
```
100+
101+
3. Rewrite the candidate using `ngettext()`:
102+
103+
```c
104+
// Before:
105+
printf(_("Split into %d hunks."), n);
106+
107+
// After:
108+
printf(Q_("Split into %d hunk.",
109+
"Split into %d hunks.", n), n);
110+
```
111+
112+
4. Build and run the relevant tests to confirm nothing is broken.
113+
114+
#### Notes
115+
116+
- Pick **one source file** with a small number of instances to keep
117+
the patch focused and reviewable.
118+
- There are known candidates in `add-patch.c`, `archive-zip.c`,
119+
`builtin/checkout.c`, `builtin/describe.c`, `builtin/fsck.c` — so
120+
there should be plenty to choose from.
121+
- Each logical change (e.g., one function or one file) should ideally
122+
be its own commit.
123+
- Follow Git's commit message conventions.
124+
- Before starting, ask on the mailing list to confirm no one else is
125+
working on the same file.
126+
127+
#### Need Help?
128+
129+
- See the [gettext manual on plural forms](https://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms)
130+
for background on why `ngettext()` is necessary.
131+
- Search the codebase for existing `Q_()` usages as examples
132+
of the correct pattern:
133+
134+
```bash
135+
git grep -3 'Q_(' -- '*.c'
136+
```
137+
138+
- If you can't find any unfixed instances, let us know the search command
139+
you used so we can retire this microproject idea.
140+
60141

61142
### Add more builtin patterns for userdiff
62143

0 commit comments

Comments
 (0)