博客

LunariaJS + Git:基于版本控制的本地化工作流

讲解 LunariaJS 如何利用 Git 追踪本地化变更,学习通过 Git 提交历史识别翻译更新、检测过时内容,实现与团队协作无缝集成的本地化工作流。

LibDoc Team 2026年3月6日 LunariaJS 专栏 49 分钟阅读
#LunariaJS #Git #版本控制 #工作流 #团队协作

LunariaJS + Git:基于版本控制的本地化工作流

在前面几篇文章中,我们介绍了 LunariaJS 的安装、配置和仪表板使用。你可能已经注意到,LunariaJS 的一个核心特性是基于 Git 的工作流。今天,让我们深入探讨 LunariaJS 如何利用 Git 来追踪本地化变更,以及如何设计高效的团队协作工作流。

💡 官方文档LunariaJS 中文文档 - Git 工作流

为什么需要 Git 集成?

传统本地化管理的困境

在没有 Git 集成的情况下,管理翻译状态通常需要:

方式一:手动维护表格

文件中文日文韩文
index.md
getting-started.md⚠️⚠️
configuration.md

问题

  • 表格容易与实际文件不同步
  • 不知道”⚠️”具体落后多少
  • 更新表格是额外的维护负担

方式二:依赖翻译平台的版本控制

一些在线翻译平台(如 Crowdin)有自己的版本控制系统。

问题

  • 与代码仓库分离
  • 需要配置同步机制
  • 可能出现版本不一致

方式三:在文件中添加标记

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

问题

  • 污染文件内容
  • 容易忘记更新标记
  • 难以批量分析

LunariaJS 的 Git 集成优势

LunariaJS 选择了一条不同的路:直接使用 Git 提交历史来判断翻译状态

核心优势

优势说明
无需额外标记文件本身就是数据源
自动同步Git 历史与代码完全同步
精确追踪知道每次变更的时间和作者
团队友好融入现有的 Git 工作流

Git 追踪机制详解

基本原理

LunariaJS 通过以下步骤判断翻译状态:

1. 获取文件最后修改时间

使用 git log 命令获取每个文件的最后修改提交:

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

2. 对比源文件和翻译文件的时间戳

源文件 (en/getting-started.md):  2026-02-28 14:30
翻译文件 (zh-cn/getting-started.md): 2026-02-20 10:15

时间差: 8 天
状态: 过时 (Outdated)

3. 生成状态报告

根据时间戳对比,为每个翻译文件生成状态。

文件变更检测算法

LunariaJS 使用以下算法检测文件变更:

// 简化的算法逻辑
function getTranslationStatus(sourceFile: File, translationFile: File): Status {
  // 情况 1: 翻译文件不存在
  if (!translationFile.exists()) {
    return 'missing';
  }

  // 获取最后修改时间
  const sourceLastModified = getLastCommitTime(sourceFile);
  const translationLastModified = getLastCommitTime(translationFile);

  // 情况 2: 翻译比源文件新或同步
  if (translationLastModified >= sourceLastModified) {
    return 'done';
  }

  // 情况 3: 源文件比翻译新
  return 'outdated';
}

Git 提交时间戳解析

# 获取文件的最后修改提交
$ git log -1 --format="%H %ct %s" -- docs/en/getting-started.md

abc1234567 1709123400 "Update getting-started documentation"

输出解析

  • %H:完整提交哈希
  • %ct:Unix 时间戳
  • %s:提交消息

过时翻译检测原理

时间戳对比策略

LunariaJS 使用”最后修改时间”策略来判断翻译是否过时:

时间线示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶
         │                      │                    │
      2月20日                2月25日               2月28日
         │                      │                    │
    中文翻译更新           英文源文件更新         当前时间
    (commit: def5678)      (commit: abc1234)
         │                      │
         └──────────────────────┘
                时间差 8 天

             状态: 过时 🟡

为什么不用内容对比?

你可能会问:为什么不用 git diff 直接对比内容?

内容对比的问题

  • 计算成本高(需要读取和解析每个文件)
  • 无法处理结构相同但内容不同的情况
  • 对大型项目性能影响大

时间戳对比的优势

  • 计算成本低(只需读取 Git 元数据)
  • 性能稳定,不受文件大小影响
  • 语义清晰:源文件更新后翻译就是”过时”

特殊情况处理

情况 1:源文件和翻译同时更新

# 同一次提交中更新了源文件和翻译
$ git log --oneline -- docs/en/guide.md docs/zh-cn/guide.md
abc1234 (HEAD) Update guide documentation

结果:状态为 done

情况 2:只更新了翻译文件

# 只更新了翻译,源文件未变
$ 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

结果:状态为 done

情况 3:格式调整但不影响内容

# 源文件只是格式调整
$ git show abc1234 --stat
docs/en/guide.md | 2 +-
# 只是调整空格或换行

结果:状态为 outdated ⚠️(保守策略)

💡 这是 LunariaJS 的保守设计选择。如果你确定翻译仍然有效,可以在提交消息中添加 [skip lunaria] 标记。

分支策略与本地化

主分支翻译管理

大多数项目在主分支(mainmaster)上管理翻译:

main

  ├── docs/en/           # 源语言(英语)
  │   ├── index.md
  │   └── guide.md

  ├── docs/zh-cn/        # 中文翻译
  │   ├── index.md
  │   └── guide.md

  └── docs/ja/           # 日文翻译
      ├── index.md
      └── guide.md

LunariaJS 配置

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

功能分支的翻译处理

当开发新功能时,通常会创建功能分支:

main

  └── feature/new-api-docs

        └── docs/en/api/new-endpoint.md  # 新增源文件

问题:新功能分支的翻译如何处理?

策略一:功能分支不翻译

  • 源文件先在功能分支完成
  • 合并到主分支后再开始翻译
  • 优点:避免翻译冲突
  • 缺点:用户看到缺失翻译

策略二:同步翻译

feature/new-api-docs

  ├── docs/en/api/new-endpoint.md
  ├── docs/zh-cn/api/new-endpoint.md
  └── docs/ja/api/new-endpoint.md
  • 优点:功能上线时翻译同步完成
  • 缺点:需要协调翻译时间

策略三:使用草稿标记

---
title: New API Endpoint
draft: true  # 标记为草稿,不显示在公开站点
---
  • 源文件完成后移除草稿标记
  • 翻译文件也可以使用草稿标记

合并时的翻译冲突解决

当源文件更新与翻译更新发生冲突:

# 场景:主分支更新了源文件,PR 分支更新了翻译
$ git merge feature/update-zh-translation
CONFLICT (content): Merge conflict in docs/zh-cn/guide.md

解决步骤

  1. 识别冲突内容
<<<<<<< HEAD
这是主分支的更新内容
=======
这是翻译分支的内容
>>>>>>> feature/update-zh-translation
  1. 评估冲突性质

    • 是否是翻译相关的内容?
    • 源文件有什么变更?
  2. 解决冲突

    • 如果是翻译更新:保留翻译分支的内容
    • 如果源文件有新内容:合并后重新翻译
  3. 验证翻译一致性

# 构建仪表板检查状态
npx lunaria build --verbose

团队协作工作流

翻译贡献者工作流

场景:社区贡献者想要帮助翻译

步骤 1:查看仪表板

访问项目的 LunariaJS 仪表板,找到需要翻译的文件。

步骤 2:Fork 并创建分支

# Fork 项目后
git clone https://github.com/your-username/project-name.git
cd project-name
git checkout -b translate/zh-cn-guide

步骤 3:翻译文件

# 创建或更新翻译文件
# docs/zh-cn/guide.md

步骤 4:提交并创建 PR

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

步骤 5:PR 审查

维护者审查翻译质量和准确性。

代码审查中的翻译检查

在 PR 审查时,可以添加翻译状态检查:

# .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  # 获取完整历史

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

      - name: Check Translation Status
        run: |
          # 检查是否有新增的缺失翻译
          node scripts/check-new-missing.js

翻译更新 PR 流程

自动化流程

源文件更新


CI 检测到过时翻译


创建翻译更新 Issue


翻译贡献者认领


提交翻译更新 PR


审查合并


仪表板更新 ✅

Issue 自动创建示例

当检测到大量过时翻译时,可以自动创建 Issue:

## 🌙 翻译同步提醒

### 概要
- 过时翻译数量: 12
- 影响语言: 中文 (5), 日文 (4), 韩文 (3)

### 需要更新的文件

| 文件 | 语言 | 落后天数 |
|------|------|----------|
| getting-started.md | 中文 | 8 |
| configuration.md | 日文 | 5 |
| api/overview.md | 韩文 | 3 |

### 行动
请各位翻译贡献者认领并更新相关翻译。

---
*此 Issue 由 LunariaJS 自动生成*

Git 集成最佳实践

1. 保持提交粒度适中

推荐做法

# 每个翻译文件单独提交
git add docs/zh-cn/guide.md
git commit -m "Translate guide to Chinese"

# 或相关文件一起提交
git add docs/zh-cn/
git commit -m "Update Chinese translations for v2.0"

不推荐

# 混合源代码和翻译的提交
git add .
git commit -m "Various updates"

2. 使用有意义的提交消息

推荐格式

[i18n/zh-cn] Translate guide.md

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

Related: #123

3. 利用 Git Blame 追踪翻译历史

# 查看翻译文件的修改历史
git blame docs/zh-cn/guide.md

# 查看特定行的最后修改
git blame -L 10,20 docs/zh-cn/guide.md

4. 使用 Git Hooks 自动化

# pre-commit hook
#!/bin/bash

# 检查是否有源文件更新但翻译未更新
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. 配置 .gitattributes

# .gitattributes
# 标记翻译文件的语言
docs/zh-cn/*.md linguist-language=Markdown
docs/ja/*.md linguist-language=Markdown

# 在 git diff 中更好地显示变更
*.md text eol=lf

高级 Git 集成技巧

1. 使用 Git 别名简化操作

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

使用:

git lunaria build
git i18n-status

2. 多仓库翻译管理

对于 Monorepo 项目:

{
  "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. 使用子模块管理翻译

# 添加翻译子模块
git submodule add https://github.com/org/translations.git i18n

# 更新翻译
git submodule update --remote i18n

4. 翻译分支策略

main

  ├── i18n/zh-cn    # 中文翻译分支

  ├── i18n/ja       # 日文翻译分支

  └── i18n/ko       # 韩文翻译分支

每个翻译分支由对应的语言维护者管理,定期合并回主分支。

常见问题与解决方案

Q1:Git 历史不完整导致状态错误

问题:浅克隆(shallow clone)没有完整历史。

解决方案

# 获取完整历史
git fetch --unshallow

# 或在 CI 中配置
- uses: actions/checkout@v4
  with:
    fetch-depth: 0  # 完整历史

Q2:大文件翻译追踪性能问题

问题:项目文件过多导致构建缓慢。

解决方案

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

Q3:重命名文件后状态丢失

问题:文件重命名后 Git 历史追踪断开。

解决方案

# 使用 git mv 保留历史
git mv docs/old-name.md docs/new-name.md

总结

LunariaJS 与 Git 的深度集成带来了强大的本地化管理能力:

特性价值
时间戳对比自动检测过时翻译
无额外标记保持文件干净
团队协作融入现有工作流
历史追踪可追溯每次变更
CI/CD 集成自动化翻译检查

关键要点

  • Git 提交时间是判断翻译状态的核心依据
  • 使用有意义的工作流处理分支和合并
  • 利用 CI/CD 自动化翻译状态检查
  • 保持良好的提交习惯便于追踪

下一步

下一篇文章,我们将探讨 LunariaJS 与 Astro Starlight 的完美集成,学习如何:

  • 安装和配置 @lunariajs/starlight
  • 将仪表板嵌入文档站点
  • 构建三语言文档站点实战
  • 解决常见集成问题

敬请期待!


💡 推荐阅读