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.
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
| File | Chinese | Japanese | Korean |
|---|---|---|---|
| index.md | Done | Done | Missing |
| getting-started.md | Done | Outdated | Outdated |
| configuration.md | Missing | Missing | Missing |
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:
| Advantage | Description |
|---|---|
| No extra markers | Files themselves are the data source |
| Auto-sync | Git history fully synced with code |
| Precise tracking | Know the time and author of each change |
| Team-friendly | Integrates 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:
- Identify Conflict Content
<<<<<<< HEAD
This is the main branch update content
=======
This is the translation branch content
>>>>>>> feature/update-zh-translation
-
Assess Conflict Nature
- Is it translation-related content?
- What changes were made to the source file?
-
Resolve Conflict
- If it’s a translation update: Keep translation branch content
- If source file has new content: Re-translate after merging
-
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:
| Feature | Value |
|---|---|
| Timestamp comparison | Automatic outdated translation detection |
| No extra markers | Keep files clean |
| Team collaboration | Integrate into existing workflows |
| History tracking | Every change is traceable |
| CI/CD integration | Automated 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: