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')"