cd /news/developer-tools/rewrite-git-commit-messages-safely-w… · home › topics › developer-tools › article
[ARTICLE · art-157940] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Rewrite Git Commit Messages Safely with git-translate-commits

An open-source Python CLI called git-translate-commits translates Git commit messages into a target language, defaulting to a local Argos Translate engine that needs no API key. The tool creates a backup branch and skips already-translated messages by default, and its documentation recommends a dry-run preview on a disposable clone before rewriting history, since rewriting changes commit IDs. The v1.0.1 release requires Python 3.10 or later and is licensed under GPL-3.0-or-later.

by read6 min views1 publishedOct 26, 2026

Mixed-language commit history is easy to create and hard to search. An AI coding assistant may write one commit in English, another in Portuguese, and a third with a Conventional Commit prefix that you still want to keep. The result is a history that is technically valid but less useful to humans and release tooling.

git-translate-commits is an open-source Python CLI for translating commit messages to a target language. Its default engine uses Argos Translate locally. It also has an optional LLM engine, but this tutorial stays on the local path so the example does not need an API key or a network request to a model provider.

The important part is not the translation command by itself. Rewriting commits changes commit IDs, so a safe workflow needs a preview, a backup, a narrow scope, and a clear recovery plan.

Install the release with pipx, preview a translation on a disposable clone, and only then run the rewrite on a repository you control:

pipx install git-translate-commits
git clone https://github.com/example/project.git project-copy
cd project-copy
git-translate-commits --lang en --dry-run
git-translate-commits --lang en

The command creates a backup branch by default before rewriting. Still, treat the operation as history surgery: coordinate with collaborators before force-pushing rewritten refs.

You need:

v1.0.1 release declares requires-python = ">=3.10". pipx, uv, or pip for installation. The project is licensed under GPL-3.0-or-later. The release source and metadata are available at the v1.0.1 tag.

The README recommends an isolated CLI installation with pipx:

pipx install git-translate-commits

You can use uv instead:

uv tool install git-translate-commits

For development or a one-off environment, plain pip is also supported:

python -m pip install git-translate-commits

Verify the installation through the executable and inspect the current options:

git-translate-commits --version
git-translate-commits --help

The v1.0.1 package metadata and the CLI version callback are not currently aligned: the package metadata declares 1.0.1, while the callback reports 1.0.0. That does not change the documented command surface, but it is worth recording when you verify the installation.

Do not begin with your only clone. Make a disposable copy, or clone the repository again for the preview:

git clone https://github.com/your-account/your-project.git history-preview
cd history-preview
git status --short
git-translate-commits --lang en --dry-run

The --lang option is required. The repository documents language codes such as en, pt-BR, es, fr, de, and ja. The default engine is local:

git-translate-commits --lang en --engine local --dry-run

On first use, Argos Translate may download language packs, which the project README describes as roughly 50 MB per pack. After the pack is available, the local engine is designed to run without an API key and without sending commit messages to an LLM provider.

Use the preview to answer three questions before changing anything:

If the preview is too broad, add filters. For example, process one author or a date range:

git-translate-commits --lang en --author "dev@example.com" --dry-run
git-translate-commits --lang en --since "2025-01-01" --until "2025-12-31" --dry-run

Once the preview is acceptable, create a separate working clone or confirm that you can restore the original refs. The default rewrite command is:

git-translate-commits --lang en

The project documents these default protections:

--backup is enabled, so a backup branch is created before changes.--skip-already-translated is enabled, so messages already detected in the target language can be skipped.--preserve-conventional is enabled, so prefixes such as feat:, fix:, and chore: are preserved.Co-authored-by and Signed-off-by are preserved.#123 and JIRA-456 are preserved. You can select branches explicitly instead of processing the current branch:

git-translate-commits --lang en --branch main
git-translate-commits --lang en --branch main --branch release
git-translate-commits --lang en --all-branches

Do not add --force until you understand the confirmation step. The flag skips confirmation, which is useful for automation but removes an intentional before a destructive history rewrite.

A successful command is not enough. Inspect the rewritten history and the generated log:

git status --short
git log --oneline --decorate -n 10
Get-ChildItem .git-translate-log.json
git branch --list

On Unix-like shells, the final command can be replaced with ls -l .git-translate-log.json. The project documents .git-translate-log.json as the JSON operation log containing the mapping of changes.

Then compare representative commits against the backup branch. Commit hashes must change when messages change because the message is part of each commit's identity:

git show backup-before-translation:README.md > $null
git log --format="%h %s" backup-before-translation -n 10
git log --format="%h %s" HEAD -n 10

The exact backup branch name is reported by the tool, so replace backup-before-translation with the name shown in your run. Check authors, timestamps, trailers, issue references, and file contents. The intended change is the commit message, not the tree.

The local engine separates the basic workflow from provider credentials. That makes a dry run easier to reproduce and keeps ordinary commit text on the local machine after language packs are installed. It also makes the trade-off explicit: local neural translation may be less context-aware than an LLM translation, especially for project-specific terminology.

The optional LLM engine is a separate path. Install the extra dependency and configure a provider only when you have accepted the data handling and cost implications:

pipx install "git-translate-commits[llm]"
git-translate-commits --lang en --engine llm --provider openai --model gpt-4o-mini

The repository documents OpenAI, Anthropic, and OpenAI-compatible providers. It also recommends environment variables such as OPENAI_API_KEY and ANTHROPIC_API_KEY. Never put a real key in a commit message, shell history that you intend to share, or an article example.

This is expected. A rewritten commit is a different object, so existing remote branches, pull requests, tags, and clones do not automatically follow it. Coordinate the force-push and ask collaborators to re-clone or carefully reset their local refs.

The tool preserves selected structure, not intent. Review translations containing product names, legal terms, incident details, or specialized abbreviations. A preserved Conventional Commit prefix does not prove that the rest of the message is accurate.

The automatic backup branch helps you recover from a local mistake. It is not a substitute for a verified remote backup, a release tag, or a team communication plan. Do not assume that a backup branch was pushed unless you explicitly verify it.

The local engine and the LLM engine are not equivalent. LLM mode can send commit text to the configured provider and can incur provider charges. Use the local mode for sensitive history unless your organization's policy allows the external provider path.

No. The documented purpose is translating Git commit messages. Verify the working tree and representative file hashes if the history is business-critical.

Yes. Use --since and optionally --until, or filter by --author and --branch.

The default --skip-already-translated behavior is intended for that case. Review the dry-run output because language detection is not perfect.

Only with agreement from everyone consuming it. A rewritten public branch creates coordination work even when the translated messages are correct.

git-translate-commits is most useful when treated as a controlled migration: preview on a disposable clone, use the local engine when privacy matters, keep the automatic backup, verify the log and commit metadata, and coordinate before updating shared refs. The translation is the easy part. The recovery and communication plan are what make the rewrite safe.

Have you standardized mixed-language commit history before, and would you prefer a local translation engine or a reviewed manual rewrite for a shared repository?

AI assistance was used to organize this tutorial and edit its prose. The repository documentation, stable release metadata, license, source behavior, and local test results were checked separately. The article does not claim that the AI ran a production history rewrite.

── more in #developer-tools 4 stories · sorted by recency
── more on @git-translate-commits 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/rewrite-git-commit-m…] indexed:0 read:6min 2026-10-26 · —