Get Started
i18n git workflow version-control

How to Manage i18n in Git Workflows

LangCTL Team 6 min read

Translation files are code. They should be versioned, reviewed, and maintained with the same care as any other source file.

But translation files have unique characteristics that can make Git workflows tricky. They’re often edited outside of IDEs, may be modified by non-developers, and changes can span many files simultaneously.

This guide covers practical strategies for managing i18n files in Git-based workflows.

File Organization

How you organize translation files affects how well they work with Git.

Flat structure

/locales
  en.json
  es.json
  fr.json
  de.json

Simple and works for smaller projects. Merges involve entire files, which can be problematic if they’re large.

Nested by feature/module

/locales
  /common
    en.json
    es.json
  /auth
    en.json
    es.json
  /dashboard
    en.json
    es.json

Smaller files mean smaller conflicts. Features can be developed and merged independently.

Language-first vs feature-first

Language-first (shown above): Each language is one file or one directory. Good for translators working on a single language.

Feature-first:

/features
  /auth
    /i18n
      en.json
      es.json
  /dashboard
    /i18n
      en.json
      es.json

Keeps translations close to the code they support. Good for developer-led workflows.

The right choice depends on who edits translations and how your codebase is organized.

Branching Strategies

Feature branches include translations

The simplest approach: feature branches include translation changes alongside code.

# Working on a feature branch
git checkout -b feature/user-profile

# Add code with new translation keys
# Add the translations themselves
# Commit together

git add src/components/Profile.tsx locales/en.json locales/es.json
git commit -m "Add user profile page with translations"

Pros: Changes are atomic; translations ship with features Cons: Translations may conflict if multiple features touch the same files

Separate translation branches

For larger projects, separate branches for translation work:

# Feature branch has placeholder keys
git checkout -b feature/user-profile
# Add code with keys
git commit -m "Add user profile page"

# Translation branch adds the actual strings
git checkout -b translations/user-profile
# Add translations
git commit -m "Add translations for user profile"

# Merge both
git checkout main
git merge feature/user-profile
git merge translations/user-profile

Pros: Translators can work independently; clear separation of concerns Cons: More complex workflow; potential for orphaned keys

Release-based translation updates

Translations updated at release boundaries:

# During sprint, features add placeholder keys
# Before release, translation branch catches up
git checkout -b release/2.1-translations
langctl pull  # or manually update files
git commit -m "Update translations for release 2.1"
git checkout main
git merge release/2.1-translations

Pros: Clean release process; batch translation work Cons: Translations lag behind code; harder to test during development

Handling Merge Conflicts

Translation files in JSON or YAML format are prone to merge conflicts, especially in the common pattern where keys are alphabetized.

Prevention

  • Smaller files: Split translations by feature or module
  • Consistent formatting: Use tools to maintain consistent key order
  • Frequent merges: Don’t let branches diverge too far

Resolution

When conflicts occur:

<<<<<<< HEAD
  "welcome.title": "Welcome back",
  "welcome.subtitle": "We missed you"
=======
  "welcome.title": "Hello again",
  "welcome.new_feature": "Try our new feature"
>>>>>>> feature/new-feature

Usually the resolution is to keep both changes:

  "welcome.title": "Welcome back",
  "welcome.subtitle": "We missed you",
  "welcome.new_feature": "Try our new feature"

For conflicting edits to the same key, you’ll need to decide which version is correct.

Tooling help

Some CLI tools can help detect and resolve translation conflicts:

# After resolving conflicts
langctl validate  # Check for duplicate keys, invalid format

# Some tools offer smart merge
langctl merge --auto  # Attempts to combine changes automatically

Code Review for Translations

Translation changes should go through code review like any other change.

What to review

  • Key naming: Are keys consistent with existing conventions?
  • Missing languages: Do all supported languages have the new keys?
  • Placeholders: Are variables and interpolations correct?
  • Formatting: Does the file maintain consistent structure?

Review checklist

## Translation Review
- [ ] Key names follow project conventions
- [ ] All supported languages updated
- [ ] No hardcoded text in source files
- [ ] Variable placeholders match between languages
- [ ] File formatting is consistent

Automated checks

In CI/CD, validate translation files:

- name: Validate translations
  run: |
    langctl validate
    langctl status --fail-on-missing

This catches missing translations and format errors before merge.

Maintaining Translation History

Git history for translations serves several purposes:

  • Audit trail: Who changed what, when
  • Rollback capability: Revert problematic changes
  • Understanding context: Why was this text changed?

Commit messages

Good commit messages for translations:

Add translations for checkout flow

- New keys: checkout.title, checkout.submit, checkout.cancel
- Updated: cart.empty_message (improved clarity)
- Languages: en, es, fr

Bad commit messages:

Update translations

Keeping history clean

Avoid commits that only fix formatting or key ordering. If tools reorganize your translation files, commit those changes separately:

git commit -m "Reformat translation files (no content changes)"

This keeps content changes separate from formatting noise.

Working with External Translators

When non-developers contribute translations, Git workflows need adaptation.

Option 1: Managed access

Give translators Git access (or access through a platform like GitHub):

  • Create branches for translation work
  • Submit pull requests for review
  • Use review process for quality control

Works if translators are comfortable with Git basics.

Option 2: Sync through tooling

Use a translation platform that syncs with Git:

# Developer workflow
langctl push  # Send keys to platform

# Translator works in web interface

# Developer pulls back
langctl pull
git add locales/
git commit -m "Update translations from platform"

The translation platform handles the translator interface; Git handles versioning.

Option 3: Export/import cycle

For occasional translator involvement:

# Export for translators
langctl export --format xlsx --output translations-for-review.xlsx

# Translators edit spreadsheet
# Import when done
langctl import --file translations-reviewed.xlsx
git add locales/
git commit -m "Import reviewed translations"

Less elegant but works with any translator workflow.

Summary: Best Practices

  1. Organize files to minimize merge conflicts (smaller files, logical grouping)

  2. Include translations in feature branches for atomic changes

  3. Review translation changes like code changes

  4. Automate validation in CI/CD to catch errors early

  5. Write meaningful commit messages that explain what changed

  6. Use tooling to help with sync, validation, and conflict resolution

  7. Plan for non-developer contributors if translators will be involved

Good Git hygiene for translations makes localization sustainable as projects grow.


Next steps: Automating i18n in CI/CD Pipelines covers how to integrate translation validation into your build process.

Ready to simplify your i18n workflow?

LangCTL is a CLI-first translation management tool built for developers. Start for free.