Merge branch 'master' of https://github.com/git/git Upstream adds 18 new translatable messages. * 'master' of https://github.com/git/git: (41 commits) A bit more on top of 2.54-rc0 ... Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
diff --git a/po/.gitattributes b/po/.gitattributes new file mode 100644 index 0000000..284af6b --- /dev/null +++ b/po/.gitattributes
@@ -0,0 +1,35 @@ +# Git Attributes for PO Files +# +# This file configures Git filters to automatically strip location information +# from PO files when committing, producing cleaner diffs and saving repository +# space. +# +# Two filter types are used: +# 1. gettext-no-location: Strips both filenames and line numbers +# (e.g., removes "#: main.c:123" entirely) +# 2. gettext-no-line-number: Preserves filenames but removes line numbers, which +# requires gettext 0.20 or higher +# (e.g., "#: main.c:123" becomes "#: main.c") +# +# See `po/README.md` for instructions on setting up the required filter drivers. + +# Default: Strip the whole location comments for all .po files +*.po filter=gettext-no-location + +# Legacy, unmaintained PO files: filter disabled to avoid index vs +# working-tree mismatch (these files still have location comments). +el.po -filter +is.po -filter +it.po -filter +ko.po -filter +pl.po -filter +pt_PT.po -filter + +# These files use gettext-no-line-number (keep filenames, strip line +# numbers). The choice is per l10n team preference. Requires gettext 0.20+. +# The only benefit is locating source files from location comments when +# the .po file is not updated from the POT via make po-update. +ca.po filter=gettext-no-line-number +id.po filter=gettext-no-line-number +zh_CN.po filter=gettext-no-line-number +zh_TW.po filter=gettext-no-line-number
diff --git a/po/AGENTS.md b/po/AGENTS.md new file mode 100644 index 0000000..feb90d4 --- /dev/null +++ b/po/AGENTS.md
@@ -0,0 +1,877 @@ +# Instructions for AI Agents + +This file gives specific instructions for AI agents that perform +housekeeping tasks for Git l10n. Use of AI is optional; many successful +l10n teams work well without it. + +The section "Housekeeping tasks for localization workflows" documents the +most commonly used housekeeping tasks: + +1. Generating or updating po/git.pot +2. Updating po/XX.po +3. Translating po/XX.po +4. Reviewing translation quality + + +## Background knowledge for localization workflows + +Essential background for the workflows below; understand these concepts before +performing any housekeeping tasks in this document. + +### Language code and notation (XX, ll, ll\_CC) + +**XX** is a placeholder for the language code: either `ll` (ISO 639) or +`ll_CC` (e.g. `de`, `zh_CN`). It appears in the PO file header metadata +(e.g. `"Language: zh_CN\n"`) and is typically used to name the PO file: +`po/XX.po`. + + +### Header Entry + +The **header entry** is the first entry in every `po/XX.po`. It has an empty +`msgid`; translation metadata (project, language, plural rules, encoding, etc.) +is stored in `msgstr`, as in this example: + +```po +msgid "" +msgstr "" +"Project-Id-Version: Git\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +``` + +**CRITICAL**: Do not edit the header's `msgstr` while translating. It holds +metadata only and must be left unchanged. + + +### Glossary Section + +PO files may have a glossary in comments before the header entry (first +`msgid ""`), giving terminology guidelines (e.g.): + +```po +# Git glossary for Chinese translators +# +# English | Chinese +# ---------------------------------+-------------------------------------- +# 3-way merge | 三路合并 +# ... +``` + +**IMPORTANT**: Read and use the glossary when translating or reviewing. It is +in `#` comments only. Leave that comment block unchanged. + + +### PO entry structure (single-line and multi-line) + +PO entries are `msgid` / `msgstr` pairs. Plural messages add `msgid_plural` and +`msgstr[n]`. The `msgid` is the immutable source; `msgstr` is the target +translation. Each side may be a single quoted string or a multi-line block. +In the multi-line form the header line is often `msgid ""` / `msgstr ""`, with +the real text split across following quoted lines (concatenated by Gettext). + +**Single-line entries**: + +```po +msgid "commit message" +msgstr "提交说明" +``` + +**Multi-line entries**: + +```po +msgid "" +"Line 1\n" +"Line 2" +msgstr "" +"行 1\n" +"行 2" +``` + +**CRITICAL**: Do **not** use `grep '^msgstr ""'` to find untranslated entries; +multi-line `msgstr` blocks use the same opening line, so grep gives false +positives. Use `msgattrib` (next section). + + +### Locating untranslated, fuzzy, and obsolete entries + +Use `msgattrib` to list untranslated, fuzzy, and obsolete entries. Task 3 +(translating `po/XX.po`) uses these commands. + +- **Untranslated**: `msgattrib --untranslated --no-obsolete po/XX.po` +- **Fuzzy**: `msgattrib --only-fuzzy --no-obsolete po/XX.po` +- **Obsolete** (`#~`): `msgattrib --obsolete --no-wrap po/XX.po` + + +### Translating fuzzy entries + +Fuzzy entries need re-translation because the source text changed. The format +differs by file type: + +- **PO file**: A `#, fuzzy` tag in the entry comments marks the entry as fuzzy. +- **JSON file**: The entry has `"fuzzy": true`. + +**Translation principles**: Re-translate the `msgstr` (and, for plural entries, +`msgstr[n]`) into the target language. Do **not** modify `msgid` or +`msgid_plural`. After translation, **clear the fuzzy mark**: in PO, remove the +`#, fuzzy` tag from comments; in JSON, omit or set `fuzzy` to `false`. + + +### Preserving Special Characters + +Preserve escape sequences (`\n`, `\"`, `\\`, `\t`), placeholders (`%s`, `%d`, +etc.), and quotes exactly as in `msgid`. Only reorder placeholders with +positional syntax when needed (see Placeholder Reordering below). + + +### Placeholder Reordering + +When reordering placeholders relative to `msgid`, use positional syntax (`%n$`) +where *n* is the 1-based argument index, so each argument still binds to the +right value. Preserve width and precision modifiers, and place `%n$` before +them (see examples below). + +**Example 1** (placeholder reordering with precision): + +```po +msgid "missing environment variable '%s' for configuration '%.*s'" +msgstr "配置 '%3$.*2$s' 缺少环境变量 '%1$s'" +``` + +`%s` → argument 1 → `%1$s`. `%.*s` needs precision (arg 2) and string (arg 3) → +`%3$.*2$s`. + +**Example 2** (multi-line, four `%s` reordered): + +```po +msgid "" +"Path updated: %s renamed to %s in %s, inside a directory that was renamed in " +"%s; moving it to %s." +msgstr "" +"路径已更新:%1$s 在 %3$s 中被重命名为 %2$s,而其所在目录又在 %4$s 中被重命" +"名,因此将其移动到 %5$s。" +``` + +Original order 1,2,3,4,5; in translation 1,3,2,4,5. Each line must be a +complete quoted string. + +**Example 3** (no placeholder reordering): + +```po +msgid "MIDX %s must be an ancestor of %s" +msgstr "MIDX %s 必须是 %s 的祖先" +``` + +Argument order is still 1,2 in translation, so `%n$` is not needed. +If no placeholder reordering occurs, you **must not** introduce `%n$` +syntax; keep the original non-positional placeholders (`%s`, `%d`, etc.). + + +### Validating PO File Format + +Check the PO file using the command below: + +```shell +msgfmt --check -o /dev/null po/XX.po +``` + +Common validation errors include: +- Unclosed quotes +- Missing escape sequences +- Invalid placeholder syntax +- Malformed multi-line entries +- Incorrect line breaks in multi-line strings + +On failure, `msgfmt` prints the line number; fix the PO at that line. + + +### Using git-po-helper + +[git-po-helper](https://github.com/git-l10n/git-po-helper) supports Git l10n with +**quality checking** (git-l10n PR conventions) and **AI-assisted translation** +(subcommands for automated workflows). Housekeeping tasks in this document use +it when available; otherwise rely on gettext tools. + + +#### Splitting large PO files + +When a PO file is too large for translation or review, use `git-po-helper +msg-select` to split it by entry index. + +- **Entry 0** is the header (included by default; use `--no-header` to omit). +- **Entries 1, 2, 3, …** are content entries. +- **Range format**: `--range "1-50"` (entries 1 through 50), `--range "-50"` + (first 50 entries), `--range "51-"` (from entry 51 to end). Shortcuts: + `--head N` (first N), `--tail N` (last N), `--since N` (from N to end). +- **Output format**: PO by default; use `--json` for GETTEXT JSON. See the + "GETTEXT JSON format" section (under git-po-helper) for details. +- **State filter**: Use `--translated`, `--untranslated`, `--fuzzy` to filter + by state (OR relationship). Use `--no-obsolete` to exclude obsolete entries; + `--with-obsolete` to include (default). Use `--only-same` or `--only-obsolete` + for a single state. Range applies to the filtered list. + +```shell +# First 50 entries (header + entries 1–50) +git-po-helper msg-select --range "-50" po/in.po -o po/out.po + +# Entries 51–100 +git-po-helper msg-select --range "51-100" po/in.po -o po/out.po + +# Entries 101 to end +git-po-helper msg-select --range "101-" po/in.po -o po/out.po + +# Entries 1–50 without header (content only) +git-po-helper msg-select --range "1-50" --no-header po/in.po -o po/frag.po + +# Output as JSON; select untranslated and fuzzy entries, exclude obsolete +git-po-helper msg-select --json --untranslated --fuzzy --no-obsolete po/in.po >po/filtered.json +``` + + +#### Comparing PO files for translation and review + +`git-po-helper compare` shows PO changes with full entry context (unlike +`git diff`). Redirect output to a file: it is empty when there are no new or +changed entries; otherwise it contains a valid PO header. + +```shell +# Get full context of local changes (HEAD vs working tree) +git-po-helper compare po/XX.po -o po/out.po + +# Get full context of changes in a specific commit (parent vs commit) +git-po-helper compare --commit <commit> po/XX.po -o po/out.po + +# Get full context of changes since a commit (commit vs working tree) +git-po-helper compare --since <commit> po/XX.po -o po/out.po + +# Get full context between two commits +git-po-helper compare -r <commit1>..<commit2> po/XX.po -o po/out.po + +# Get full context of two worktree files +git-po-helper compare po/old.po po/new.po -o po/out.po + +# Check msgid consistency (detect tampering); no output means target matches source +git-po-helper compare --msgid po/old.po po/new.po >po/out.po +``` + +**Options summary** + +| Option | Meaning | +|---------------------|------------------------------------------------| +| (none) | Compare HEAD with working tree (local changes) | +| `--commit <commit>` | Compare parent of commit with the commit | +| `--since <commit>` | Compare commit with working tree | +| `-r x..y` | Compare revision x with revision y | +| `-r x..` | Compare revision x with working tree | +| `-r x` | Compare parent of x with x | + + +#### Concatenating multiple PO/JSON files + +`git-po-helper msg-cat` merges PO, POT, or gettext JSON inputs into one stream. +Duplicate `msgid` values keep the first occurrence in file order. Write with +`-o <file>` or stdout (`-o -` or omit); `--json` selects JSON output, else PO. + +```shell +# Convert JSON to PO (e.g. after translation) +git-po-helper msg-cat --unset-fuzzy -o po/out.po po/in.json + +# Merge multiple PO files +git-po-helper msg-cat -o po/out.po po/in-1.po po/in-2.json +``` + + +#### GETTEXT JSON format + +The **GETTEXT JSON** format is an internal format defined by `git-po-helper` +for convenient batch processing of translation and related tasks by AI models. +`git-po-helper msg-select`, `git-po-helper msg-cat`, and `git-po-helper compare` +read and write this format. + +**Top-level structure**: + +```json +{ + "header_comment": "string", + "header_meta": "string", + "entries": [ /* array of entry objects */ ] +} +``` + +| Field | Description | +|------------------|--------------------------------------------------------------------------------| +| `header_comment` | Lines above the first `msgid ""` (comments, glossary), directly concatenated. | +| `header_meta` | Encoded `msgstr` of the header entry (Project-Id-Version, Plural-Forms, etc.). | +| `entries` | List of PO entries. Order matches source. | + +**Entry object** (each element of `entries`): + +| Field | Type | Description | +|-----------------|----------|--------------------------------------------------------------| +| `msgid` | string | Singular message ID. PO escapes encoded (e.g. `\n` → `\\n`). | +| `msgstr` | []string | Translation forms as a **JSON array only**. Details below. | +| `msgid_plural` | string | Plural form of msgid. Omit for non-plural. | +| `comments` | []string | Comment lines (`#`, `#.`, `#:`, `#,`, etc.). | +| `fuzzy` | bool | True if entry has fuzzy flag. | +| `obsolete` | bool | True for `#~` obsolete entries. Omit if false. | + +**`msgstr` array (required shape)**: + +- **Always** a JSON array of strings, never a single string. One element = singular + (PO `msgstr` / `msgstr[0]`); multiple elements = plural forms in order + (`msgstr[0]`, `msgstr[1]`, …). +- Omit the key or use an empty array when the entry is untranslated. + +**Example (single-line entry)**: + +```json +{ + "header_comment": "# Glossary:\\n# term1\\tTranslation 1\\n#\\n", + "header_meta": "Project-Id-Version: git\\nContent-Type: text/plain; charset=UTF-8\\n", + "entries": [ + { + "msgid": "Hello", + "msgstr": ["你好"], + "comments": ["#. Comment for translator\\n", "#: src/file.c:10\\n"], + "fuzzy": false + } + ] +} +``` + +**Example (plural entry)**: + +```json +{ + "msgid": "One file", + "msgid_plural": "%d files", + "msgstr": ["一个文件", "%d 个文件"], + "comments": ["#, c-format\\n"] +} +``` + +**Example (fuzzy entry before translation)**: + +```json +{ + "msgid": "Old message", + "msgstr": ["旧翻译。"], + "comments": ["#, fuzzy\\n"], + "fuzzy": true +} +``` + +**Translation notes for GETTEXT JSON files**: + +- **Preserve structure**: Keep `header_comment`, `header_meta`, `msgid`, + `msgid_plural` unchanged. +- **Fuzzy entries**: Entries extracted from fuzzy PO entries have `"fuzzy": true`. + After translating, **remove the `fuzzy` field** or set it to `false` in the + output JSON. The merge step uses `--unset-fuzzy`, which can also remove the + `fuzzy` field. +- **Placeholders**: Preserve `%s`, `%d`, etc. exactly; use `%n$` when + reordering (see "Placeholder Reordering" above). + + +### Quality checklist + +- **Accuracy**: Faithful to original meaning; no omissions or distortions. +- **Fuzzy entries**: Re-translate fully and clear the fuzzy flag (see + "Translating fuzzy entries" above). +- **Terminology**: Consistent with glossary (see "Glossary Section" above) or + domain standards. +- **Grammar and fluency**: Correct and natural in the target language. +- **Placeholders**: Preserve variables (`%s`, `{name}`, `$1`) exactly; use + positional parameters when reordering (see "Placeholder Reordering" above). +- **Special characters**: Preserve escape sequences (`\n`, `\"`, `\\`, `\t`), + placeholders exactly as in `msgid`. See "Preserving Special Characters" above. +- **Plurals and gender**: Correct forms and agreement. +- **Context fit**: Suitable for UI space, tone, and use (e.g. error vs. tooltip). +- **Cultural appropriateness**: No offensive or ambiguous content. +- **Consistency**: Match prior translations of the same source. +- **Technical integrity**: Do not translate code, paths, commands, brands, or + proper nouns. +- **Readability**: Clear, concise, and user-friendly. + + +## Housekeeping tasks for localization workflows + +For common housekeeping tasks, follow the steps in the matching subsection +below. + + +### Task 1: Generating or updating po/git.pot + +When asked to generate or update `po/git.pot` (or the like): + +1. **Directly execute** the command `make po/git.pot` without checking + if the file exists beforehand. + +2. **Do not verify** the generated file after execution. Simply run the + command and consider the task complete. + + +### Task 2: Updating po/XX.po + +When asked to update `po/XX.po` (or the like): + +1. **Directly execute** the command `make po-update PO_FILE=po/XX.po` + without reading or checking the file content beforehand. + +2. **Do not verify, translate, or review** the updated file after execution. + Simply run the command and consider the task complete. + + +### Task 3: Translating po/XX.po + +To translate `po/XX.po`, use the steps below. The script uses gettext or +`git-po-helper` depending on what is installed; JSON export (when available) +supports batch translation rather than per-entry work. + +**Workflow loop**: Steps 1→2→3→4→5→6→7 form a loop. After step 6 succeeds, +**always** go to step 7, which returns to step 1. The **only** exit to step 8 +is when step 2 finds `po/l10n-pending.po` empty. Do not skip step 7 or jump to +step 8 after step 6. + +1. **Extract entries to translate**: **Directly execute** the script below—it is + authoritative; do not reimplement. It generates `po/l10n-pending.po` with + messages that need translation. + + ```shell + l10n_extract_pending () { + test $# -ge 1 || { echo "Usage: l10n_extract_pending <po-file>" >&2; return 1; } + PO_FILE="$1" + PENDING="po/l10n-pending.po" + PENDING_FUZZY="${PENDING}.fuzzy" + PENDING_REFER="${PENDING}.fuzzy.reference" + PENDING_UNTRANS="${PENDING}.untranslated" + rm -f "$PENDING" + + if command -v git-po-helper >/dev/null 2>&1 + then + git-po-helper msg-select --untranslated --fuzzy --no-obsolete -o "$PENDING" "$PO_FILE" + else + msgattrib --untranslated --no-obsolete "$PO_FILE" >"${PENDING_UNTRANS}" + msgattrib --only-fuzzy --no-obsolete --clear-fuzzy --empty "$PO_FILE" >"${PENDING_FUZZY}" + msgattrib --only-fuzzy --no-obsolete "$PO_FILE" >"${PENDING_REFER}" + msgcat --use-first "${PENDING_UNTRANS}" "${PENDING_FUZZY}" >"$PENDING" + rm -f "${PENDING_UNTRANS}" "${PENDING_FUZZY}" + fi + if test -s "$PENDING" + then + msgfmt --stat -o /dev/null "$PENDING" || true + echo "Pending file is not empty; there are still entries to translate." + else + echo "No entries need translation." + return 1 + fi + } + # Run the extraction. Example: l10n_extract_pending po/zh_CN.po + l10n_extract_pending po/XX.po + ``` + +2. **Check generated file**: If `po/l10n-pending.po` is empty or does not exist, + translation is complete; go to step 8. Otherwise proceed to step 3. + +3. **Prepare one batch for translation**: Batching keeps each run small so the + model can complete translation within limited context. **BEFORE translating**, + **directly execute** the script below—it is authoritative; do not reimplement. + Based on which file the script produces: if `po/l10n-todo.json` exists, go to + step 4a; if `po/l10n-todo.po` exists, go to step 4b. + + ```shell + l10n_one_batch () { + test $# -ge 1 || { echo "Usage: l10n_one_batch <po-file> [min_batch_size]" >&2; return 1; } + PO_FILE="$1" + min_batch_size=${2:-100} + PENDING="po/l10n-pending.po" + TODO_JSON="po/l10n-todo.json" + TODO_PO="po/l10n-todo.po" + DONE_JSON="po/l10n-done.json" + DONE_PO="po/l10n-done.po" + rm -f "$TODO_JSON" "$TODO_PO" "$DONE_JSON" "$DONE_PO" + + ENTRY_COUNT=$(grep -c '^msgid ' "$PENDING" 2>/dev/null || echo 0) + ENTRY_COUNT=$((ENTRY_COUNT > 0 ? ENTRY_COUNT - 1 : 0)) + + if test "$ENTRY_COUNT" -gt $min_batch_size + then + if test "$ENTRY_COUNT" -gt $((min_batch_size * 8)) + then + NUM=$((min_batch_size * 2)) + elif test "$ENTRY_COUNT" -gt $((min_batch_size * 4)) + then + NUM=$((min_batch_size + min_batch_size / 2)) + else + NUM=$min_batch_size + fi + BATCHING=1 + else + NUM=$ENTRY_COUNT + BATCHING= + fi + + if command -v git-po-helper >/dev/null 2>&1 + then + if test -n "$BATCHING" + then + git-po-helper msg-select --json --head "$NUM" -o "$TODO_JSON" "$PENDING" + echo "Processing batch of $NUM entries (out of $ENTRY_COUNT remaining)" + else + git-po-helper msg-select --json -o "$TODO_JSON" "$PENDING" + echo "Processing all $ENTRY_COUNT entries at once" + fi + else + if test -n "$BATCHING" + then + awk -v num="$NUM" '/^msgid / && count++ > num {exit} 1' "$PENDING" | + tac | awk '/^$/ {found=1} found' | tac >"$TODO_PO" + echo "Processing batch of $NUM entries (out of $ENTRY_COUNT remaining)" + else + cp "$PENDING" "$TODO_PO" + echo "Processing all $ENTRY_COUNT entries at once" + fi + fi + } + # Prepare one batch; shrink 2nd arg when batches exceed agent capacity. + l10n_one_batch po/XX.po 100 + ``` + +4a. **Translate JSON batch** (`po/l10n-todo.json` → `po/l10n-done.json`): + + - **Task**: Translate `po/l10n-todo.json` (input, GETTEXT JSON) into + `po/l10n-done.json` (output, GETTEXT JSON). See the "GETTEXT JSON format" + section above for format details and translation rules. + - **Reference glossary**: Read the glossary from the batch file's + `header_comment` (see "Glossary Section" above) and use it for + consistent terminology. + - **When translating**: Follow the "Quality checklist" above for correctness + and quality. Handle escape sequences (`\n`, `\"`, `\\`, `\t`), placeholders, + and quotes correctly as in `msgid`. For JSON, correctly escape and unescape + these sequences when reading and writing. Modify `msgstr` and `msgstr[n]` + (for plural entries); clear the fuzzy flag (omit or set `fuzzy` to `false`). + Do **not** modify `msgid` or `msgid_plural`. + +4b. **Translate PO batch** (`po/l10n-todo.po` → `po/l10n-done.po`): + + - **Task**: Translate `po/l10n-todo.po` (input, GETTEXT PO) into + `po/l10n-done.po` (output, GETTEXT PO). + - **Reference glossary**: Read the glossary from the pending file header + (see "Glossary Section" above) and use it for consistent terminology. + - **When translating**: Follow the "Quality checklist" above for correctness + and quality. Preserve escape sequences (`\n`, `\"`, `\\`, `\t`), placeholders, + and quotes as in `msgid`. Modify `msgstr` and `msgstr[n]` (for plural + entries); remove the `#, fuzzy` tag from comments when done. Do **not** + modify `msgid` or `msgid_plural`. + +5. **Validate `po/l10n-done.po`**: + + Run the validation script below. If it fails, fix per the errors and notes, + re-run until it succeeds. + + ```shell + l10n_validate_done () { + DONE_PO="po/l10n-done.po" + DONE_JSON="po/l10n-done.json" + PENDING="po/l10n-pending.po" + + if test -f "$DONE_JSON" && { ! test -f "$DONE_PO" || test "$DONE_JSON" -nt "$DONE_PO"; } + then + git-po-helper msg-cat --unset-fuzzy -o "$DONE_PO" "$DONE_JSON" || { + echo "ERROR [JSON to PO conversion]: Fix $DONE_JSON and re-run." >&2 + return 1 + } + fi + + # Check 1: msgid should not be modified + MSGID_OUT=$(git-po-helper compare -q --msgid --assert-no-changes \ + "$PENDING" "$DONE_PO" 2>&1) + MSGID_RC=$? + if test $MSGID_RC -ne 0 || test -n "$MSGID_OUT" + then + echo "ERROR [msgid modified]: The following entries appeared after" >&2 + echo "translation because msgid was altered. Fix in $DONE_PO." >&2 + echo "$MSGID_OUT" >&2 + return 1 + fi + + # Check 2: PO format (see "Validating PO File Format" for error handling) + MSGFMT_OUT=$(msgfmt --check -o /dev/null "$DONE_PO" 2>&1) + MSGFMT_RC=$? + if test $MSGFMT_RC -ne 0 + then + echo "ERROR [PO format]: Fix errors in $DONE_PO." >&2 + echo "$MSGFMT_OUT" >&2 + return 1 + fi + + echo "Validation passed." + } + l10n_validate_done + ``` + + If the script fails, fix **directly in `po/l10n-done.po`**. Re-run + `l10n_validate_done` until it succeeds. Editing `po/l10n-done.json` is not + recommended because it adds an extra JSON-to-PO conversion step. Use the + error message to decide: + + - **`[msgid modified]`**: The listed entries have altered `msgid`; restore + them to match `po/l10n-pending.po`. + - **`[PO format]`**: `msgfmt` reports line numbers; fix the errors in place. + See "Validating PO File Format" for common issues. + + +6. **Merge translation results into `po/XX.po`**: Run the script below. If it + fails, fix the file the error names: **`[JSON to PO conversion]`** → + `po/l10n-done.json`; **`[msgcat merge]`** → `po/l10n-done.po`. Re-run until + it succeeds. + + ```shell + l10n_merge_batch () { + test $# -ge 1 || { echo "Usage: l10n_merge_batch <po-file>" >&2; return 1; } + PO_FILE="$1" + DONE_PO="po/l10n-done.po" + DONE_JSON="po/l10n-done.json" + MERGED="po/l10n-done.merged" + PENDING="po/l10n-pending.po" + PENDING_REFER="${PENDING}.fuzzy.reference" + TODO_JSON="po/l10n-todo.json" + TODO_PO="po/l10n-todo.po" + if test -f "$DONE_JSON" && { ! test -f "$DONE_PO" || test "$DONE_JSON" -nt "$DONE_PO"; } + then + git-po-helper msg-cat --unset-fuzzy -o "$DONE_PO" "$DONE_JSON" || { + echo "ERROR [JSON to PO conversion]: Fix $DONE_JSON and re-run." >&2 + return 1 + } + fi + msgcat --use-first "$DONE_PO" "$PO_FILE" >"$MERGED" || { + echo "ERROR [msgcat merge]: Fix errors in $DONE_PO and re-run." >&2 + return 1 + } + mv "$MERGED" "$PO_FILE" + rm -f "$TODO_JSON" "$TODO_PO" "$DONE_JSON" "$DONE_PO" "$PENDING_REFER" + } + # Run the merge. Example: l10n_merge_batch po/zh_CN.po + l10n_merge_batch po/XX.po + ``` + +7. **Loop**: **MUST** return to step 1 (Extract entries) and repeat the cycle. + Do **not** skip this step or go to step 8. Step 8 (below) runs **only** + when step 2 finds no more entries and redirects there. + +8. **Only after loop exits**: Run the command below to validate the PO file and + display the report. The process ends here. + + ```shell + msgfmt --check --stat -o /dev/null po/XX.po + ``` + + +### Task 4: Review translation quality + +Review may target the full `po/XX.po`, a specific commit, or changes since a +commit. When asked to review, follow the steps below. + +**Workflow**: Follow steps in order. Do **NOT** use `git show`, `git diff`, +`git format-patch`, or similar to get changes—they break PO context; use **only** +`git-po-helper compare` for extraction. Without `git-po-helper`, refuse the task. +Steps 3→4→5→6→7 loop: after step 6, **always** go to step 7 (back to step 3). +The **only** ways to step 8 are when step 4 finds `po/review-todo.json` missing +or empty (no batch left to review), or when step 1 finds `po/review-result.json` +already present. + +1. **Check for existing review (resume support)**: Evaluate the following in order: + + - If `po/review-input.po` does **not** exist, proceed to step 2 (Extract + entries) for a fresh start. + - Else If `po/review-result.json` exists, go to step 8 (only after loop exits). + - Else If `po/review-done.json` exists, go to step 6 (Rename result). + - Else if `po/review-todo.json` exists, go to step 5 (Review the current + batch). + - Else go to step 3 (Prepare one batch). + +2. **Extract entries**: Run `git-po-helper compare` with the desired range and + redirect the output to `po/review-input.po`. See "Comparing PO files for + translation and review" under git-po-helper for options. + +3. **Prepare one batch**: Batching keeps each run small so the model can + complete review within limited context. **Directly execute** the script + below—it is authoritative; do not reimplement. + + ```shell + review_one_batch () { + min_batch_size=${1:-100} + INPUT_PO="po/review-input.po" + PENDING="po/review-pending.po" + TODO="po/review-todo.json" + DONE="po/review-done.json" + BATCH_FILE="po/review-batch.txt" + + if test ! -f "$INPUT_PO" + then + rm -f "$TODO" + echo >&2 "cannot find $INPUT_PO, nothing for review" + return 1 + fi + if test ! -f "$PENDING" || test "$INPUT_PO" -nt "$PENDING" + then + rm -f "$BATCH_FILE" "$TODO" "$DONE" + rm -f po/review-result*.json + cp "$INPUT_PO" "$PENDING" + fi + + ENTRY_COUNT=$(grep -c '^msgid ' "$PENDING" 2>/dev/null || echo 0) + ENTRY_COUNT=$((ENTRY_COUNT > 0 ? ENTRY_COUNT - 1 : 0)) + if test "$ENTRY_COUNT" -eq 0 + then + rm -f "$TODO" + echo >&2 "No entries left for review" + return 1 + fi + + if test "$ENTRY_COUNT" -gt $min_batch_size + then + if test "$ENTRY_COUNT" -gt $((min_batch_size * 8)) + then + NUM=$((min_batch_size * 2)) + elif test "$ENTRY_COUNT" -gt $((min_batch_size * 4)) + then + NUM=$((min_batch_size + min_batch_size / 2)) + else + NUM=$min_batch_size + fi + else + NUM=$ENTRY_COUNT + fi + + BATCH=$(cat "$BATCH_FILE" 2>/dev/null || echo 0) + BATCH=$((BATCH + 1)) + echo "$BATCH" >"$BATCH_FILE" + + git-po-helper msg-select --json --head "$NUM" -o "$TODO" "$PENDING" + git-po-helper msg-select --since "$((NUM + 1))" -o "${PENDING}.tmp" "$PENDING" + mv "${PENDING}.tmp" "$PENDING" + echo "Processing batch $BATCH ($NUM entries out of $ENTRY_COUNT)" + } + # The parameter controls batch size; reduce if the batch file is too large. + review_one_batch 100 + ``` + +4. **Check todo file**: If `po/review-todo.json` does not exist or is empty, + review is complete; go to step 8 (only after loop exits). Otherwise proceed to + step 5. + +5. **Review the current batch**: Review translations in `po/review-todo.json` + and write findings to `po/review-done.json` as follows: + - Use "Background knowledge for localization workflows" for PO/JSON structure, + placeholders, and terminology. + - If `header_comment` includes a glossary, follow it for consistency. + - Do **not** review the header (`header_comment`, `header_meta`). + - For every other entry, check the entry's `msgstr` **array** (translation + forms) against `msgid` / `msgid_plural` using the "Quality checklist" above. + - Write JSON per "Review result JSON format" below; use `{"issues": []}` when + there are no issues. **Always** write `po/review-done.json`—it marks the + batch complete. + +6. **Rename result**: Rename `po/review-done.json` to `po/review-result-<N>.json`, + where N is the value in `po/review-batch.txt` (the batch just completed). + Run the script below: + + ```shell + review_rename_result () { + TODO="po/review-todo.json" + DONE="po/review-done.json" + BATCH_FILE="po/review-batch.txt" + if test -f "$DONE" + then + N=$(cat "$BATCH_FILE" 2>/dev/null) || { echo "ERROR: $BATCH_FILE not found." >&2; return 1; } + mv "$DONE" "po/review-result-$N.json" + echo "Renamed to po/review-result-$N.json" + fi + rm -f "$TODO" + } + review_rename_result + ``` + +7. **Loop**: **MUST** return to step 3 (Prepare one batch) and repeat the cycle. + Do **not** skip this step or go to step 8. Step 8 is reached **only** when + step 4 finds `po/review-todo.json` missing or empty. + +8. **Only after loop exits**: **Directly execute** the command below. It merges + results, applies suggestions, and displays the report. The process ends here. + + ```shell + git-po-helper agent-run review --report po + ``` + + **Do not** run cleanup or delete intermediate files. Keep them for inspection + or resumption. + +**Review result JSON format**: + +The **Review result JSON** format defines the structure for translation +review reports. For each entry with translation issues, create an issue +object as follows: + +- Copy the original entry's `msgid`, optional `msgid_plural`, and optional + `msgstr` array (original translation forms) into the issue object. Use the + same shape as GETTEXT JSON: `msgstr` is **always a JSON array** when present + (one element singular, multiple for plural). +- Write a summary of all issues found for this entry in `description`. +- Set `score` according to the severity of issues found for this entry, + from 0 to 3 (0 = critical; 1 = major; 2 = minor; 3 = perfect, no issues). + **Lower score means more severe issues.** +- Place the suggested translation in **`suggest_msgstr`** as a **JSON array**: + one string for singular, multiple strings for plural forms in order. This is + required for `git-po-helper` to apply suggestions. +- Include only entries with issues (score less than 3). When no issues are + found in the batch, write `{"issues": []}`. + +Example review result (with issues): + +```json +{ + "issues": [ + { + "msgid": "commit", + "msgstr": ["委托"], + "score": 0, + "description": "Terminology error: 'commit' should be translated as '提交'", + "suggest_msgstr": ["提交"] + }, + { + "msgid": "repository", + "msgid_plural": "repositories", + "msgstr": ["版本库", "版本库"], + "score": 2, + "description": "Consistency issue: suggest using '仓库' consistently", + "suggest_msgstr": ["仓库", "仓库"] + } + ] +} +``` + +Field descriptions for each issue object (element of the `issues` array): + +- `msgid` (and optional `msgid_plural` for plural entries): Original source text. +- `msgstr` (optional): JSON array of original translation forms (same meaning as + in GETTEXT JSON entries). +- `suggest_msgstr`: JSON array of suggested translation forms; **must be an + array** (e.g. `["提交"]` for singular). Plural entries use multiple elements + in order. +- `score`: 0–3 (0 = critical; 1 = major; 2 = minor; 3 = perfect, no issues). +- `description`: Brief summary of the issue. + + +## Human translators remain in control + +Git translation is human-driven; language team leaders and contributors are +responsible for maintaining translation quality and consistency. + +AI-generated output should always be treated as drafts that must be reviewed +and approved by someone who understands both the technical context and the +target language. The best results come from combining AI efficiency with human +judgment, cultural insight, and community engagement.
diff --git a/po/README.md b/po/README.md index ec08aa2..c418487 100644 --- a/po/README.md +++ b/po/README.md
@@ -159,38 +159,6 @@ and these location lines will help translation tools to locate translation context easily. -Once you are done testing the translation (see below), it's better -to commit a location-less "po/XX.po" file to save repository space -and make a user-friendly patch for review. - -To save a location-less "po/XX.po" automatically in repository, you -can: - -First define a new attribute for "po/XX.po" by appending the following -line in ".git/info/attributes": - -``` -/po/XX.po filter=gettext-no-location -``` - -Then define the driver for the "gettext-no-location" clean filter to -strip out both filenames and locations from the contents as follows: - -```shell -git config --global filter.gettext-no-location.clean \ - "msgcat --no-location -" -``` - -For users who have gettext version 0.20 or higher, it is also possible -to define a clean filter to preserve filenames but not locations: - -```shell -git config --global filter.gettext-no-location.clean \ - "msgcat --add-location=file -" -``` - -You're now ready to ask the l10n coordinator to pull from you. - ## Fuzzy translation @@ -229,6 +197,45 @@ ``` +## Preparing a "XX.po" file for commit + +Once you are done testing the translation, it's better to commit a +location-less "po/XX.po" file to save repository space and make a +user-friendly patch for review. + +To save a location-less "po/XX.po" automatically in the repository, +follow these steps: + +First, check which filter is configured for your "po/XX.po" file: + +``` +git check-attr filter po/XX.po +``` + +The filter configuration is defined in the "po/.gitattributes" file. + +Then define the driver for the filter. Most languages use the +"gettext-no-location" clean filter, which strips out both filenames and line +numbers from location comments. To set this up, run the following command: + +```shell +git config --global filter.gettext-no-location.clean \ + "msgcat --no-location -" +``` + +Some PO files use the "gettext-no-line-number" clean filter, which keeps +filenames but strips line numbers. This filter requires gettext 0.20 or +later. The only benefit is being able to locate source files from location +comments when the .po file is not updated from the POT via `make po-update`. + +```shell +git config --global filter.gettext-no-line-number.clean \ + "msgcat --add-location=file -" +``` + +You're now ready to ask the l10n coordinator to pull from you. + + ## Marking strings for translation (This is done by the core developers). @@ -392,15 +399,30 @@ changed to account for translations as they're added. +## AI-assisted translation and review + +[po/AGENTS.md](AGENTS.md) describes optional workflows for AI coding assistants +that help with Git localization: updating templates and PO files, translating +`po/XX.po`, and reviewing translations. Those workflows often use git-po-helper +together with the gettext tools; see the PO helper section below for what the +program does and how to build or install it. AI assistants are optional; treat +their output as a draft and have it reviewed by contributors who know Git and +the target language well. + +When you prompt a coding assistant, mention that file explicitly, for example: +"Translate po/XX.po with reference to po/AGENTS.md" (replace XX with your +language code). + + ## PO helper -To make the maintenance of "XX.po" easier, the l10n coordinator and l10n -team leaders can use a helper program named "git-po-helper". It is a -wrapper to gettext suite, specifically written for the purpose of Git -l10n workflow. +`git-po-helper` is a helper for Git l10n coordinators and contributors. It +automates checks that contributions follow project conventions (PO syntax, +commit messages, which paths may change, and related rules) and can work with +AI coding agents for tasks such as translating new entries, and reviewing +translations. -To build and install the helper program from source, see -[git-po-helper/README][]. +Build and install instructions are in [git-po-helper/README][]. ## Conventions
diff --git a/po/ca.po b/po/ca.po index 8dc21f3..742109c 100644 --- a/po/ca.po +++ b/po/ca.po
@@ -512,8 +512,8 @@ #, c-format msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Descarta el canvi de mode de l'índex i de l'arbre de treball [y,n,q,a,d" -"%s,?]? " +"Descarta el canvi de mode de l'índex i de l'arbre de treball " +"[y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -3879,11 +3879,11 @@ #: builtin/branch.c msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" -"la branca amb --recurse-submodules només es pot utilitzar si submodule." -"propagateBranches està habilitat" +"la branca amb --recurse-submodules només es pot utilitzar si " +"submodule.propagateBranches està habilitat" #: builtin/branch.c msgid "--recurse-submodules can only be used to create branches" @@ -7983,11 +7983,11 @@ #: builtin/fetch.c msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" -"--filter només es pot utilitzar amb el remot configurat en extensions." -"partialclone" +"--filter només es pot utilitzar amb el remot configurat en " +"extensions.partialclone" #: builtin/fetch.c msgid "--atomic can only be used when fetching from one remote" @@ -11436,8 +11436,8 @@ "| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <referència-notes>] add [-f] [--allow-empty] [--" -"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | -" -"F <fitxer> | (-c | -C) <objecte>] [<objecte>]" +"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | " +"-F <fitxer> | (-c | -C) <objecte>] [<objecte>]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" @@ -11451,8 +11451,8 @@ "| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <referència-notes>] append [--allow-empty] [--" -"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | -" -"F <fitxer> | (-c | -C) <objecte>] [<objecte>] [-e]" +"[no-]separator|--separator=<salt-paràgraf>] [--[no-]stripspace] [-m <msg> | " +"-F <fitxer> | (-c | -C) <objecte>] [<objecte>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" @@ -13231,8 +13231,8 @@ #: builtin/rebase.c #, c-format msgid "" -"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"stop" -"\"." +"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and " +"\"stop\"." msgstr "" "tipus buit «%s» no reconegut; els valors vàlids són \"drop\", \"keep\" i " "\"stop\"." @@ -14440,8 +14440,8 @@ msgstr "" "Els reempaquetaments incrementals són incompatibles amb els índexs de mapes " "de bits. Useu\n" -"--no-write-bitmap-index o inhabiliteu el paràmetre de configuració pack." -"writeBitmaps." +"--no-write-bitmap-index o inhabiliteu el paràmetre de configuració " +"pack.writeBitmaps." #: builtin/repack.c msgid "could not start pack-objects to repack promisor objects" @@ -19350,11 +19350,11 @@ #: commit-graph.c #, c-format msgid "" -"attempting to write a commit-graph, but 'commitGraph." -"changedPathsVersion' (%d) is not supported" +"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' " +"(%d) is not supported" msgstr "" -"s'ha intentat escriure un graf de comissió, però no s'admet 'commitGraph." -"changedPathsVersion' (%d)" +"s'ha intentat escriure un graf de comissió, però no s'admet " +"'commitGraph.changedPathsVersion' (%d)" #: commit-graph.c msgid "too many commits to write graph" @@ -22940,8 +22940,8 @@ #, c-format msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x" msgstr "" -"la signatura de l'índex multipaquet 0x%08x no coincideix amb la signatura 0x" -"%08x" +"la signatura de l'índex multipaquet 0x%08x no coincideix amb la signatura " +"0x%08x" #: midx.c #, c-format
diff --git a/po/es.po b/po/es.po index 1ff5ff3..aa1bb9b 100644 --- a/po/es.po +++ b/po/es.po
@@ -391,8 +391,8 @@ #, c-format, perl-format msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"¿Aplicar cambio de modo para el índice y el árbol de trabajo [y,n,q,a," -"d%s,?]? " +"¿Aplicar cambio de modo para el índice y el árbol de trabajo " +"[y,n,q,a,d%s,?]? " #, c-format, perl-format msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? " @@ -2294,9 +2294,9 @@ "=<term>] [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] " "[<paths>...]" msgstr "" -"git bisect--helper --bisect-start [--term-{new,bad}=<término> --term-{old," -"good}=<término>] [--no-checkout] [--first-parent] [<malo> [<bueno>...]] [--] " -"[<rutas>...]" +"git bisect--helper --bisect-start [--term-{new,bad}=<término> --term-" +"{old,good}=<término>] [--no-checkout] [--first-parent] [<malo> [<bueno>...]] " +"[--] [<rutas>...]" msgid "git bisect--helper --bisect-state (bad|new) [<rev>]" msgstr "git bisect--helper --bisect-state (bad|new) [<rev>]" @@ -2983,11 +2983,11 @@ msgstr "¡HEAD no encontrado dentro de refs/heads!" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" -"branch con --recurse-submodules solo se puede usar si submodule." -"propagateBranches está habilitado" +"branch con --recurse-submodules solo se puede usar si " +"submodule.propagateBranches está habilitado" msgid "--recurse-submodules can only be used to create branches" msgstr "--recurse-submodules solo se puede usar para crear ramas" @@ -5983,11 +5983,11 @@ msgstr "el protocolo no soporta --negotiate-only, saliendo" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" -"--filter solo puede ser usado con el remoto configurado en extensions." -"partialclone" +"--filter solo puede ser usado con el remoto configurado en " +"extensions.partialclone" msgid "--atomic can only be used when fetching from one remote" msgstr "--atomic solo se puede usar cuando se busca desde un control remoto" @@ -8914,8 +8914,8 @@ msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" msgstr "" -"deshabilitando escritura bitmap, paquetes son divididos debido a pack." -"packSizeLimit" +"deshabilitando escritura bitmap, paquetes son divididos debido a " +"pack.packSizeLimit" msgid "Writing objects" msgstr "Escribiendo objetos" @@ -9489,8 +9489,8 @@ msgid "" "\n" "To avoid automatically configuring upstream branches when their name\n" -"doesn't match the local branch, see option 'simple' of branch." -"autoSetupMerge\n" +"doesn't match the local branch, see option 'simple' of " +"branch.autoSetupMerge\n" "in 'git help config'.\n" msgstr "" "\n"
diff --git a/po/ga.po b/po/ga.po index 4c05a25..2d8065b 100644 --- a/po/ga.po +++ b/po/ga.po
@@ -382,8 +382,8 @@ #, c-format msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"An bhfuil an píosa beag seo le fáil réidh ón innéacs agus ón gcrann oibre [y," -"n,q,a,d%s,?]? " +"An bhfuil an píosa beag seo le fáil réidh ón innéacs agus ón gcrann oibre " +"[y,n,q,a,d%s,?]? " msgid "" "y - discard this hunk from index and worktree\n" @@ -402,8 +402,8 @@ #, c-format msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Cuir athrú mód i bhfeidhm ar an innéacs agus ar an gcrann oibre [y,n,q,a," -"d%s,?]? " +"Cuir athrú mód i bhfeidhm ar an innéacs agus ar an gcrann oibre " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? " @@ -413,14 +413,14 @@ #, c-format msgid "Apply addition to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Cuir an breiseán i bhfeidhm ar an innéacs agus ar an gcrann oibre [y,n,q,a," -"d%s,?]? " +"Cuir an breiseán i bhfeidhm ar an innéacs agus ar an gcrann oibre " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Cuir an píosa seo i bhfeidhm ar an innéacs agus ar an gcrann oibre [y,n,q,a," -"d%s,?]? " +"Cuir an píosa seo i bhfeidhm ar an innéacs agus ar an gcrann oibre " +"[y,n,q,a,d%s,?]? " msgid "" "y - apply this hunk to index and worktree\n" @@ -3114,11 +3114,11 @@ msgstr "Ní fhaightear CEAD thíos na refs/heads!" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" -"ní féidir brainse le --recurse-submodules a úsáid ach amháin má tá submodule." -"propagateBranches cumasaithe" +"ní féidir brainse le --recurse-submodules a úsáid ach amháin má tá " +"submodule.propagateBranches cumasaithe" msgid "--recurse-submodules can only be used to create branches" msgstr "Ní féidir --recurse-submodules a úsáid ach chun brainsí a chruthú" @@ -6034,8 +6034,8 @@ "'strip-if-invalid' is not a valid mode for git fast-export with --signed-" "commits=<mode>" msgstr "" -"'strip-if-invalid' ní mód bailí é seo le haghaidh easpórtáil le haghaidh git fast-export le --signed-" -"commits=<mód>" +"'strip-if-invalid' ní mód bailí é seo le haghaidh easpórtáil le haghaidh git " +"fast-export le --signed-commits=<mód>" #, c-format msgid "" @@ -6067,8 +6067,8 @@ "'strip-if-invalid' is not a valid mode for git fast-export with --signed-" "tags=<mode>" msgstr "" -"'strip-if-invalid' ní mód bailí é seo le haghaidh git fast-export le --signed-" -"tags=<mode>" +"'strip-if-invalid' ní mód bailí é seo le haghaidh git fast-export le --" +"signed-tags=<mode>" #, c-format msgid "" @@ -7048,8 +7048,8 @@ msgstr "ní thacaíonn an prótacal le --negotiate-only, ag scoir" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" "--filter Ní féidir ach an scagaire a úsáid ach leis an iargúlta cumraithe in " "extensions.partialclone" @@ -7584,8 +7584,8 @@ msgid "" "skipping incremental-repack task because core.multiPackIndex is disabled" msgstr "" -"ag scipeáil an tasc athphacála incriminteach mar go bhfuil core." -"multiPackIndex díchumasaithe" +"ag scipeáil an tasc athphacála incriminteach mar go bhfuil " +"core.multiPackIndex díchumasaithe" msgid "failed to perform geometric repack" msgstr "theip ar athphacáil gheoiméadrach a dhéanamh" @@ -10097,8 +10097,8 @@ msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" msgstr "" -"scríobh bitmap a dhíchumasú, roinntear pacáistí mar gheall ar pack." -"packSizeLimit" +"scríobh bitmap a dhíchumasú, roinntear pacáistí mar gheall ar " +"pack.packSizeLimit" msgid "Writing objects" msgstr "Rudaí a scríobh" @@ -11904,8 +11904,8 @@ msgstr "" "Tá tagairtí contrártha sa\n" "tagarmharc sprice nua ag an gcianrialtán atá tú ag iarraidh a athainmniú. Is " -"dóichí gur mar gheall ar iarracht a dhéanamh cianrialtán a neadú ann féin, e." -"g. trí 'tuismitheoir' a athainmniú go 'tuismitheoir/leanbh'\n" +"dóichí gur mar gheall ar iarracht a dhéanamh cianrialtán a neadú ann féin, " +"e.g. trí 'tuismitheoir' a athainmniú go 'tuismitheoir/leanbh'\n" "nó trí chianrialtán a dhí-neadú, e.g. an bealach eile.\n" "\n" "Más amhlaidh atá, is féidir leat é seo a réiteach tríd an\n" @@ -16114,11 +16114,11 @@ #, c-format msgid "" -"attempting to write a commit-graph, but 'commitGraph." -"changedPathsVersion' (%d) is not supported" +"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' " +"(%d) is not supported" msgstr "" -"ag iarraidh commit-graph a scríobh, ach tá 'commitGraph." -"changedPathsVersion' (%d) ní thacaítear leis" +"ag iarraidh commit-graph a scríobh, ach tá 'commitGraph.changedPathsVersion' " +"(%d) ní thacaítear leis" msgid "too many commits to write graph" msgstr "an iomarca gealltanais graf a scríobh" @@ -18266,8 +18266,8 @@ "given pattern contains NULL byte (via -f <file>). This is only supported " "with -P under PCRE v2" msgstr "" -"tá byte NULL (trí -f<file>) i bpatrún tugtha. Ní thacaítear leis seo ach le -" -"P faoi PCRE v2" +"tá byte NULL (trí -f<file>) i bpatrún tugtha. Ní thacaítear leis seo ach le " +"-P faoi PCRE v2" #, c-format msgid "'%s': unable to read %s" @@ -18433,8 +18433,8 @@ msgstr "" "Rinneadh neamhaird ar an gcroca '%s' toisc nach bhfuil sé socraithe mar " "infheidhmithe.\n" -"Is féidir leat an rabhadh seo a dhíchumasú le `git config set advice." -"ignoredHook false `." +"Is féidir leat an rabhadh seo a dhíchumasú le `git config set " +"advice.ignoredHook false `." msgid "not a git repository" msgstr "ní stór git é"
diff --git a/po/ru.po b/po/ru.po index 3e56eb5..e8845ca 100644 --- a/po/ru.po +++ b/po/ru.po
@@ -369,8 +369,8 @@ #, c-format msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Отменить изменения режима доступа в индексе и рабочем каталоге [y,n,q,a," -"d%s,?]? " +"Отменить изменения режима доступа в индексе и рабочем каталоге " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? " @@ -400,8 +400,8 @@ #, c-format msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Применить изменения режима доступа к индексу и рабочему каталогу [y,n,q,a," -"d%s,?]? " +"Применить изменения режима доступа к индексу и рабочему каталогу " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? " @@ -2966,8 +2966,8 @@ msgstr "HEAD не найден в refs/heads!" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" msgid "--recurse-submodules can only be used to create branches" @@ -3997,8 +3997,8 @@ "clean.requireForce defaults to true and neither -i, -n, nor -f given; " "refusing to clean" msgstr "" -"clean.requireForce установлен по умолчанию как true и ни одна из опций -i, -" -"n или -f не указана; отказ очистки" +"clean.requireForce установлен по умолчанию как true и ни одна из опций -i, " +"-n или -f не указана; отказ очистки" msgid "-x and -X cannot be used together" msgstr "нельзя использовать одновременно -x и -X" @@ -5890,8 +5890,8 @@ msgstr "" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" msgid "--atomic can only be used when fetching from one remote" @@ -8385,8 +8385,8 @@ msgid "Please stage your changes to .gitmodules or stash them to proceed" msgstr "" -"Чтобы продолжить, проиндексируйте или спрячьте ваши изменения в файле ." -"gitmodules" +"Чтобы продолжить, проиндексируйте или спрячьте ваши изменения в " +"файле .gitmodules" #, c-format msgid "%.*s is in index" @@ -16134,8 +16134,8 @@ msgstr "" "Перехватчик «%s» был проигнорирован, так как он не установлен как " "исполняемый.\n" -"Вы можете отключить это предупреждение с помощью команды «git config advice." -"ignoredHook false»." +"Вы можете отключить это предупреждение с помощью команды «git config " +"advice.ignoredHook false»." #, c-format msgid "argument to --packfile must be a valid hash (got '%s')"