Blog

LunariaJS + Git - Version Control-based Localization Workflow

Learn how LunariaJS uses Git to track localization changes, identify translation updates through Git commit history, detect outdated content, and implement a localization workflow seamlessly integrated with team collaboration.

LibDoc Team March 6, 2026 LunariaJS Series 79 min read
#LunariaJS #Git #version control #workflow #team collaboration

LunariaJS + Git - Version Control-based Localization Workflow

In previous articles, we covered LunariaJS’s installation, configuration, and dashboard usage. You may have noticed that one of LunariaJS’s core features is Git-based workflow. Today, let’s dive into how LunariaJS uses Git to track localization changes and how to design efficient team collaboration workflows.

💡 Official Documentation: LunariaJS Documentation - Git Workflow

Why Git Integration?

Dilemma of Traditional Localization Management

Without Git integration, managing translation status usually requires:

Method 1: Manual Spreadsheet Maintenance

FileChineseJapaneseKorean
index.mdDoneDoneMissing
getting-started.mdDoneOutdatedOutdated
configuration.mdMissingMissingMissing

Problems:

  • Spreadsheet easily gets out of sync with actual files
  • Don’t know exactly how far behind “Outdated” is
  • Updating the spreadsheet is extra maintenance burden

Method 2: Relying on Translation Platform Version Control

Some online translation platforms (like Crowdin) have their own version control systems.

Problems:

  • Separate from code repository
  • Requires sync mechanism configuration
  • Potential version inconsistency

Method 3: Adding Markers in Files

<!-- TODO: Translate to Chinese -->
<!-- LAST_UPDATED: 2026-02-20 -->
<!-- STATUS: OUTDATED -->

Problems:

  • Pollutes file content
  • Easy to forget updating markers
  • Hard to analyze in bulk

LunariaJS Git Integration Advantages

LunariaJS chose a different path: directly use Git commit history to determine translation status.

Core Advantages:

AdvantageDescription
No extra markersFiles themselves are the data source
Auto-syncGit history fully synced with code
Precise trackingKnow the time and author of each change
Team-friendlyIntegrates into existing Git workflow

Git Tracking Mechanism Details

Basic Principles

LunariaJS determines translation status through these steps:

1. Get File Last Modified Time

Use git log command to get each file’s last modified commit:

git log -1 --format="%H %ct" -- path/to/file.md

2. Compare Source and Translation File Timestamps

Source file (en/getting-started.md):  2026-02-28 14:30
Translation file (zh-cn/getting-started.md): 2026-02-20 10:15

Time difference: 8 days
Status: Outdated

3. Generate Status Report

Generate status for each translation file based on timestamp comparison.

File Change Detection Algorithm

LunariaJS uses the following algorithm to detect file changes:

// Simplified algorithm logic
function getTranslationStatus(sourceFile: File, translationFile: File): Status {
  // Case 1: Translation file doesn't exist
  if (!translationFile.exists()) {
    return 'missing';
  }

  // Get last modified times
  const sourceLastModified = getLastCommitTime(sourceFile);
  const translationLastModified = getLastCommitTime(translationFile);

  // Case 2: Translation is newer or synced with source
  if (translationLastModified >= sourceLastModified) {
    return 'done';
  }

  // Case 3: Source file is newer than translation
  return 'outdated';
}

Git Commit Timestamp Parsing

# Get file's last modified commit
$ git log -1 --format="%H %ct %s" -- docs/en/getting-started.md

abc1234567 1709123400 "Update getting-started documentation"

Output Parsing:

  • %H: Full commit hash
  • %ct: Unix timestamp
  • %s: Commit message

Outdated Translation Detection Principles

Timestamp Comparison Strategy

LunariaJS uses “last modified time” strategy to determine if translations are outdated:

Timeline Example:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶
         │                      │                    │
      Feb 20                 Feb 25               Feb 28
         │                      │                    │
    Chinese translation    English source       Current time
    updated (commit: def5678)  updated (commit: abc1234)
         │                      │
         └──────────────────────┘
                Time difference: 8 days

             Status: Outdated 🟡

Why Not Use Content Comparison?

You might ask: Why not use git diff to directly compare content?

Content Comparison Problems:

  • High computational cost (requires reading and parsing each file)
  • Can’t handle cases with same structure but different content
  • Significant performance impact on large projects

Timestamp Comparison Advantages:

  • Low computational cost (only need to read Git metadata)
  • Stable performance, unaffected by file size
  • Clear semantics: translation is “outdated” after source file update

Special Case Handling

Case 1: Source and Translation Updated Together

# Both source and translation updated in same commit
$ git log --oneline -- docs/en/guide.md docs/zh-cn/guide.md
abc1234 (HEAD) Update guide documentation

Result: Status is done

Case 2: Only Translation File Updated

# Only translation updated, source unchanged
$ git log -1 -- docs/zh-cn/guide.md
abc1234 (HEAD) Update Chinese translation
$ git log -1 -- docs/en/guide.md
def5678 (HEAD~1) Original guide

Result: Status is done

Case 3: Format Adjustment Without Content Changes

# Source file only has format adjustment
$ git show abc1234 --stat
docs/en/guide.md | 2 +-
# Just adjusted whitespace or line breaks

Result: Status is outdated (conservative strategy)

This is LunariaJS’s conservative design choice. If you’re certain the translation is still valid, you can add a [skip lunaria] marker in the commit message.

Branch Strategy and Localization

Main Branch Translation Management

Most projects manage translations on the main branch (main or master):

main

  ├── docs/en/           # Source language (English)
  │   ├── index.md
  │   └── guide.md

  ├── docs/zh-cn/        # Chinese translation
  │   ├── index.md
  │   └── guide.md

  └── docs/ja/           # Japanese translation
      ├── index.md
      └── guide.md

LunariaJS Configuration:

{
  "sourceLanguage": "en",
  "languages": ["en", "zh-cn", "ja"],
  "files": [
    {
      "sourcePath": "docs/en/{slug}.md",
      "localizationPath": "docs/{lang}/{slug}.md"
    }
  ]
}

Feature Branch Translation Handling

When developing new features, feature branches are typically created:

main

  └── feature/new-api-docs

        └── docs/en/api/new-endpoint.md  # New source file

Question: How should translations for new feature branches be handled?

Strategy 1: No Translation on Feature Branches

  • Source files completed first in feature branch
  • Translation starts after merging to main branch
  • Pros: Avoid translation conflicts
  • Cons: Users see missing translations

Strategy 2: Synchronized Translation

feature/new-api-docs

  ├── docs/en/api/new-endpoint.md
  ├── docs/zh-cn/api/new-endpoint.md
  └── docs/ja/api/new-endpoint.md
  • Pros: Translation complete when feature launches
  • Cons: Requires coordinating translation timing

Strategy 3: Use Draft Markers

---
title: New API Endpoint
draft: true  # Marked as draft, not shown on public site
---
  • Remove draft marker after source file is complete
  • Translation files can also use draft markers

Resolving Translation Conflicts During Merge

When source file updates conflict with translation updates:

# Scenario: Main branch updated source file, PR branch updated translation
$ git merge feature/update-zh-translation
CONFLICT (content): Merge conflict in docs/zh-cn/guide.md

Resolution Steps:

  1. Identify Conflict Content
<<<<<<< HEAD
This is the main branch update content
=======
This is the translation branch content
>>>>>>> feature/update-zh-translation
  1. Assess Conflict Nature

    • Is it translation-related content?
    • What changes were made to the source file?
  2. Resolve Conflict

    • If it’s a translation update: Keep translation branch content
    • If source file has new content: Re-translate after merging
  3. Verify Translation Consistency

# Build dashboard to check status
npx lunaria build --verbose

Team Collaboration Workflow

Translation Contributor Workflow

Scenario: Community contributor wants to help with translation

Step 1: View Dashboard

Visit the project’s LunariaJS dashboard to find files needing translation.

Step 2: Fork and Create Branch

# After forking project
git clone https://github.com/your-username/project-name.git
cd project-name
git checkout -b translate/zh-cn-guide

Step 3: Translate File

# Create or update translation file
# docs/zh-cn/guide.md

Step 4: Commit and Create PR

git add docs/zh-cn/guide.md
git commit -m "Translate guide to Chinese"
git push origin translate/zh-cn-guide

Step 5: PR Review

Maintainers review translation quality and accuracy.

Translation Status Checks in Code Review

Add translation status checks during PR review:

# .github/workflows/translation-check.yml
name: Translation Check

on: [pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Get full history

      - name: Build Lunaria Dashboard
        run: |
          npm ci
          npx lunaria build

      - name: Check Translation Status
        run: |
          # Check for new missing translations
          node scripts/check-new-missing.js

Translation Update PR Process

Automated Process:

Source file updated


CI detects outdated translation


Create translation update Issue


Translation contributor claims


Submit translation update PR


Review and merge


Dashboard updated

Automatic Issue Creation Example

When detecting many outdated translations, issues can be automatically created:

## Translation Sync Reminder

### Summary
- Outdated translations: 12
- Affected languages: Chinese (5), Japanese (4), Korean (3)

### Files Needing Updates

| File | Language | Days Behind |
|------|----------|-------------|
| getting-started.md | Chinese | 8 |
| configuration.md | Japanese | 5 |
| api/overview.md | Korean | 3 |

### Action
Please translation contributors claim and update related translations.

---
*This Issue was automatically generated by LunariaJS*

Git Integration Best Practices

1. Keep Commit Granularity Appropriate

Recommended:

# Single commit per translation file
git add docs/zh-cn/guide.md
git commit -m "Translate guide to Chinese"

# Or commit related files together
git add docs/zh-cn/
git commit -m "Update Chinese translations for v2.0"

Not Recommended:

# Mixed source code and translation commits
git add .
git commit -m "Various updates"

2. Use Meaningful Commit Messages

Recommended Format:

[i18n/zh-cn] Translate guide.md

- Translate introduction section
- Update code examples
- Fix terminology consistency

Related: #123

3. Use Git Blame to Track Translation History

# View translation file modification history
git blame docs/zh-cn/guide.md

# View last modification of specific lines
git blame -L 10,20 docs/zh-cn/guide.md

4. Use Git Hooks for Automation

# pre-commit hook
#!/bin/bash

# Check if source files updated but translations not updated
npm run lunaria:check-outdated

if [ $? -ne 0 ]; then
  echo "Warning: Some translations are outdated!"
  echo "Run 'npx lunaria build' to see details."
fi

5. Configure .gitattributes

# .gitattributes
# Mark translation file languages
docs/zh-cn/*.md linguist-language=Markdown
docs/ja/*.md linguist-language=Markdown

# Better display changes in git diff
*.md text eol=lf

Advanced Git Integration Tips

1. Use Git Aliases to Simplify Operations

# ~/.gitconfig
[alias]
    lunaria = "!f() { npx lunaria \"$@\"; }; f"
    i18n-status = "!f() { npx lunaria build && npx lunaria preview; }; f"

Usage:

git lunaria build
git i18n-status

2. Multi-repository Translation Management

For Monorepo projects:

{
  "files": [
    {
      "sourcePath": "packages/core/docs/{slug}.md",
      "localizationPath": "packages/core/i18n/{lang}/{slug}.md"
    },
    {
      "sourcePath": "packages/cli/docs/{slug}.md",
      "localizationPath": "packages/cli/i18n/{lang}/{slug}.md"
    }
  ]
}

3. Use Submodules to Manage Translations

# Add translation submodule
git submodule add https://github.com/org/translations.git i18n

# Update translations
git submodule update --remote i18n

4. Translation Branch Strategy

main

  ├── i18n/zh-cn    # Chinese translation branch

  ├── i18n/ja       # Japanese translation branch

  └── i18n/ko       # Korean translation branch

Each translation branch is managed by corresponding language maintainers and periodically merged back to main branch.

Common Issues and Solutions

Q1: Incomplete Git History Causing Status Errors

Problem: Shallow clone doesn’t have complete history.

Solution:

# Get complete history
git fetch --unshallow

# Or configure in CI
- uses: actions/checkout@v4
  with:
    fetch-depth: 0  # Complete history

Q2: Large File Translation Tracking Performance Issues

Problem: Too many project files causing slow builds.

Solution:

{
  "files": [
    {
      "sourcePath": "docs/{slug}.md",
      "localizationPath": "i18n/{lang}/docs/{slug}.md",
      "include": ["**/*.md"],
      "exclude": ["**/draft/**", "**/internal/**"]
    }
  ]
}

Q3: Status Lost After File Rename

Problem: Git history tracking broken after file rename.

Solution:

# Use git mv to preserve history
git mv docs/old-name.md docs/new-name.md

Summary

LunariaJS’s deep integration with Git brings powerful localization management capabilities:

FeatureValue
Timestamp comparisonAutomatic outdated translation detection
No extra markersKeep files clean
Team collaborationIntegrate into existing workflows
History trackingEvery change is traceable
CI/CD integrationAutomated translation checks

Key Points:

  • Git commit time is the core basis for determining translation status
  • Use meaningful workflows for branching and merging
  • Leverage CI/CD for automated translation status checks
  • Maintain good commit habits for easier tracking

Next Steps

In the next article, we’ll explore LunariaJS’s perfect integration with Astro Starlight, learning how to:

  • Install and configure @lunariajs/starlight
  • Embed dashboard into documentation site
  • Build a trilingual documentation site hands-on
  • Solve common integration issues

Stay tuned!


💡 Recommended Reading: