Branchlate· Part 1 of 2
Translations that follow Git branches
The developer syncs their branch, the business fixes copy in the app, CI checks. Nobody waits for anybody, and nobody overwrites anybody's work.
4 min readLire en français
A translated application does not hard-code its text. It uses keys, and one file per language maps each key to its text. The code says “show this key”, the French file answers “Commander”, the English one “Place order”.
<Button>
{t("checkout.submit")}
</Button>In most teams, these files live badly. Developers change them in the code; the business fixes copy in a spreadsheet or a separate tool; someone copies it over by hand, and the two drift apart. Every feature ends with the same question: “is the copy ready?”.
Why follow Git branches
Code lives in branches: each feature has its own, reviewed then merged. Copy should follow the same road, since it changes with the code that displays it. Branchlate starts from that simple idea: one Git branch, one translation branch.
The business works on the feature's branch, before it is merged, without waiting for a release. And translations reach the product with the code that uses them, in the same review.
- DevA branch, a new keyA key added in English, then
branchlate sync. Branchlate creates the same branch from the files; French is missing: red dot. - BusinessTranslates and validates, without touching codeIn the web app, or right on the product through the Chrome extension. The validated text turns green.
- DevPulls the validated copyA second
syncbrings the text back into the files. The developer commits it like any other change. - CIChecks before the merge
branchlate statusfails if a language is incomplete, or if the files are out of sync. - DevMerge, then clean upTranslations reach main through Git, with the code. The translation branch can go.
The challenge. Translations live in two places at once: in the repository's files, which developers change, and in Branchlate, where the business edits them. Both change at the same time, and one side's work must never erase the other's.
Who wins?
Git cannot see Branchlate's database, and the database cannot see Git's history: a real three-way merge, as Git does for code, is impossible. So the rule lives in each text's state: has a human touched it, and did they validate it?
The file and Branchlate both changed: who wins?
- No doten.jsonBranchlatethe code wins
Nobody touched it in Branchlate: it belongs to the code.
—
- Update neededen.jsonBranchlateBranchlate wins, the file is rewritten
It is in the review flow: it is not overwritten silently.
An explicit option lets the code win, and flags the text for review.
- Validateden.jsonBranchlateBranchlate wins, the file is rewritten
A human validated it: it is protected.
Only a forced sync, confirmed key by key, overrides it.
What the developer sees
One command, in the terminal or in CI. It detects the branch, sends the files, and rewrites the ones that changed. A second one is the safety net before the merge.
$ branchlate sync🌿 Branch createdfr ⬇ Local key addedcheckout.submit null✅ Project synced successfully. $ branchlate statusen 100% validatedfr 99% validated- checkout.submit$ echo $?1
What I take from it
- Git stays the road to production: translations travel with the code, in the same review.
- Every text knows who owns it: the code, or the person who validated it.
- CI says no before a missing string reaches production.