git-manpages-l10n: how Git's manual pages get translated
Translation of git manpages
At a glance
- What is it?
- The git-manpages-l10n repository holds the translations of the Git documentation, and it is a good example of a translation workflow built around gettext and po4a rather than around a documentation generator, with a coordinator merging upstream changes and language teams working through Weblate or the Git workflow. It suits a translator or a maintainer who wants to contribute to Git's documentation, and the thing to read first is that the project is explicitly not about translating Git itself.
- Who is it for?
- Adopt this workflow, or one like it, if you maintain a documentation set that is translated in many languages and upstream moves faster than your translators can follow, because the gettext and po4a arrangement lets a coordinator re-merge upstream text while keeping the translated strings.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 12 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A translation project that is not about translating Git
This project holds the translations for the documentation of Git, and the document describes how you can contribute to the effort of enhancing the language coverage and maintaining the translation.
The first clarification in the README is important, because the repository name invites the wrong reading. This project is not about translating Git itself, although the base content, the manpages, is extracted from it. Git uses a workflow for translations which is different from the one used by Git Manpages, and the project points to its own specific instructions instead.
That difference is the whole design decision here. The Git project itself manages its own translations with a workflow built for the Git project. The manpages, which are written in Asciidoc with some custom macros, are extracted and handled here by a different mechanism so that the translations can be maintained in a way that survives the upstream project changing.
The project is GPL-2.0 licensed, the primary language is recorded as Python because of the helper scripts, the last push was on 2026-10-11, and there are no GitHub releases, which is what you would expect from a repository whose content is a set of po files rather than a program.
The topic tags are documentation, git, hacktoberfest and l10n, and the repository layout supports that description: an `en/` directory holding the English Asciidoc sources, a `po/` directory holding the gettext files, `scripts/` for the helper tooling, `ci/` for the continuous integration setup, an `addenda/` directory, and a `TEAMS` file at the root recording who looks after which language.
po4a turns Asciidoc into po files and keeps the inline formatting
The mechanics of the translation are worth understanding, because they explain why the repository has the shape it has.
The project relies on the Git project itself for the original version of the Git manpages and documents. In order to allow the translations in a maintainable way over the changes to the Git project, the source files are processed with a converter named po4a. This tool converts the source files into gettext po files which can be processed just like gettext internationalization files.
The source files for the manpages are written in Asciidoc with some custom macros. Although the documents are split into simple paragraphs by po4a for translations, Asciidoc inline formatting marks are retained. That is the detail that makes the approach work. A translator sees prose broken into paragraphs, which is what a gettext tool expects, but the formatting marks survive so that the rendered output still has bold, italics and code formatting in the right places.
The two character language translation codes are defined by ISO_639-1, as stated in the gettext manual's appendix on usual language codes. That is why the file naming convention is `documentation.XX.po` with XX being the locale, and why the README gives examples like `de`, `is`, `pt_BR` and `zh_CN`, which is a hint about the mix of regional variants in the set.
The Makefile shows the same split in build terms. The English sources are `en/*.adoc` with subdirectories for config and includes, the documentation sources are the `en/git*.adoc` files, and the language list is derived directly from the po files present, `ALL_LANGUAGES = $(subst po/documentation.,,$(subst .po,,$(LANGUAGE_PO)))`. A new language therefore appears in the build by existing as a po file, with no separate registration step in the build system itself.
The data flow, and who does what
The README includes an ASCII diagram of the overall data flow, and reading it tells you exactly how a change in the upstream Git project reaches a translated man page.
The steps it lays out are these.
The original documentation files are tagged for a new release. The L10n coordinator pulls from the source and updates the local documentation source files and the message template `po/documentation.pot`, and merges the changes into all the `po/documentation.XX.po` files. Updated files are then available on Weblate.org, and the language team pulls from the Git doc translation repository. The language team updates the message file `documentation.XX.po`. The L10n coordinator pulls from the language team. And the L10n coordinator updates the translated source files for external use.
The loop closes on itself, and the shape of it is the interesting part. Upstream changes do not arrive as a diff to be re-applied to each translation. They arrive as a regenerated message template, which is then merged into every language file at once. A translator who has already translated a string sees it unchanged, and a translator working on a changed string sees only the changed part.
That is the difference between a translation workflow that scales and one that does not, and it is why the coordinator role exists at all. There is exactly one person merging upstream into all the po files, and one person pulling the results back, and the translators in between never have to reconcile two versions of the same document.
The scripts in the repository reflect the same arrangement. There is a `set-priorities` script, a `pre-translate-po` script, an `update-sources` script, a `create_po4a_conf` script and a `generate-make-deps` script, and the Makefile invokes them in the right order for each target, so the coordinator's side is automated even though the human step in the middle is not.
Two ways to contribute, and the project prefers the web one
There are basically two ways to translate the documents, and the README is clear about the preference.
The first uses the standard Git workflow, similar to any software project. The second uses the more accessible web tool at Weblate.org and is the preferred way of contributing.
The Weblate route is the interesting one because of a mechanism that is unusual in open source translation work. The translation files are uploaded to the hosted Weblate website, where contributors can easily translate the documents and use all the helpers that are provided. Contributors to Git manpages translation are asked to acknowledge the project's code of contributors. And the web application handles your submissions and generates a Git commit in the local repository of Weblate after one day of inactivity.
That last sentence is the key. Weblate does not hold the authority to push into the translation repository, so a day's inactivity is treated as the signal that a submission is finished. The commit is then generated on the Weblate side, and the coordinator pulls it in the same way as a contribution from a language team, which is step five of the data flow.
There is one thing a contributor cannot do, and the README is direct about it. You cannot directly create a new language in Weblate by yourself, but you can request the creation of the language to the maintainer. Upon receiving this request, the maintainer will create the po translation file and push it, and Weblate will then update the list of available languages accordingly.
For the Git workflow route, the documentation is more involved because there is a first-time setup to do. If the language you plan to translate is already listed, you can jump to the language's management page and start fixing translations or tackling untranslated content. If a dedicated team exists for your language, which you check in the `TEAMS` file in the repository directory, you fork the dedicated repository; otherwise you fork this project and start translating. When committing, you are asked to follow the code of contribution and add your Signed-off-by line. And if there are multiple contributors for the same language, you are asked to coordinate and nominate a team leader, so that the L10n coordinator only needs to interact with one person per language.
Adding a language by hand, and building the result
The manual route for a first-time language is a sequence of concrete steps, and it is worth reading because it shows what the generated files look like.
You initialise the translation po file by running `msginit --local=XX` in the `po/` directory, where XX is the locale, for example `de`, `is`, `pt_BR` or `zh_CN`. Then you pre-translate the file for unchanged strings with `scripts/pre-translate-po po/documentation.XX.po`, which creates a file corresponding to the newly created translation and makes it ready for your translations.
Then you edit the automatically generated copyright info in the new `documentation.XX.po` to be correct. The example given is for Icelandic, and the diff shows what changes: the placeholder line for the package name becomes a line naming Git documentation, and the copyright holder line is replaced with the real name and address.
There is a second automatic substitution to do as well. The reference to PACKAGE VERSION in the PO header entry has to become just Git Documentation, done with a one line perl in-place edit:
perl -pi -e 's/(?<="Project-Id-Version: )PACKAGE VERSION/Git
Documentation/' documentation.XX.poOnce the translation is done and tested, you commit the `documentation.XX.po` files and ask the L10n coordinator to pull from you.
Testing your changes is the part that catches the errors, and the tooling for it is specific. Before being able to compile the documents you need a working compilation toolchain, which you get by running `sh ci/install_po4a.sh` to install a patched version of po4a and `bundle install` to install asciidoctor. Before you submit your changes you run `bundle exec make all`. On systems with GNU gettext, which is everything except Solaris, and with po4a, this will try to merge the translations with the source asciidoc files.
The patched po4a is the detail to notice. The upstream tool does not quite do what this project needs, so the project ships a patch and installs that version rather than the stock one, and the CI script exists to do it. The `Gemfile` at the root and the `bundle install` step are the Ruby side of the toolchain, and `asciidoctor-extensions.rb` in the repository root holds the custom macros the source files use.
Editorial conclusion
Adopt this workflow, or one like it, if you maintain a documentation set that is translated in many languages and upstream moves faster than your translators can follow, because the gettext and po4a arrangement lets a coordinator re-merge upstream text while keeping the translated strings. Do not start a new language in Weblate yourself, since the maintainer has to create the po file first, and check first which of the two contribution routes suits you, because the web tool is preferred while the Git workflow is the fallback for contributors who cannot or do not want to use Weblate.
Frequently asked questions
What does the git-manpages-l10n repository hold?
It holds the translations for the documentation of Git, the man pages. The project is explicitly not about translating Git itself, even though the base content is extracted from it, because Git uses a different translation workflow and this project handles the man pages with gettext and po4a.
How are the Git man pages translated?
The English Asciidoc sources are processed with po4a, which converts them into gettext po files that can be handled like any gettext internationalization file. The documents are split into simple paragraphs for translation while Asciidoc inline formatting marks are retained, and the language codes are the two character ISO 639-1 ones.
How do upstream Git documentation changes reach the translators?
The L10n coordinator pulls from the source, updates the local documentation source files and the message template po/documentation.pot, and merges those changes into all the po/documentation.XX.po files. The language team then works on the updated files, and the coordinator pulls the results back and updates the translated source files for external use.
Which way of contributing does the project prefer?
The web tool at Weblate.org, described as the more accessible way and the preferred one. The translation files are uploaded to the hosted site, and the web application handles your submissions and generates a Git commit in the local Weblate repository after one day of inactivity. The standard Git workflow is the alternative.
How do I add a translation for a brand new language?
In Weblate you cannot create a new language yourself, you have to request it from the maintainer, who then creates the po file and pushes it. Doing it by hand means forking the repository, running msginit --local=XX in the po directory, pre-translating with scripts/pre-translate-po, correcting the generated copyright header and the PACKAGE VERSION reference, and then asking the L10n coordinator to pull your work.
Is git-manpages-l10n still being maintained?
The repository is not archived and the last push was on 2026-10-11. There are no GitHub releases, the licence is GPL-2.0, and the root holds a TEAMS file recording the dedicated team for each language along with the po, en, scripts, ci and addenda directories.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jnavila-git-manpages-l10n)Was this useful?