lingo push

更新时间:上个月 · 预计阅读 2 分钟

将源文件推送到引擎,等待运行完成,并将结果写入磁盘。

text
lingo push [patterns...] [--key <pattern>] [--force] [--backfill-missing] [--yes] [--wait] [--estimate]

默认行为——增量推送#

不带任何参数时,lingo push 会以仅增量模式运行:

  1. 为配置中 files 模式匹配到的每个源文件计算哈希
  2. 将每个哈希与锁文件比对,找出发生变更的源文件
  3. 将变更过的源文件作为一次运行上传到引擎
  4. 等待这次运行完成
  5. 将输出写入磁盘
  6. 把新的源文件哈希提交到锁文件

如果自上次成功推送后没有任何源文件发生变化,命令会直接以 ✓ Nothing to push. 结束——无需与服务器往返,也不会消耗令牌。

参数与标志#

位置参数:patterns...——作用域推送#

bash
lingo push docs/en/about.md
lingo push 'docs/en/**/*.md' 'locales/en.json'

将推送范围限制在特定文件上(必须匹配 .lingo/config.json 中已定义的模式)。这会让命令切换到作用域模式:

  • 不再与上一次的源文件做差异比对——所有匹配到的源文件都会被视为在作用域内,即使没有改动。
  • 对于已存在且源文件哈希一致的目标,服务端会执行 noop——引擎会跳过它们,CLI 会将其报告为已缓存。

适合在你只想翻译一个刚更新的文件、又不想重新为整个项目计算哈希时使用,或者想借助 --force 重新翻译单个页面时使用。

--key <pattern>#

bash
lingo push --key auth.login
lingo push --key auth.login --key billing.plan
lingo push --key "auth.*"

仅重新翻译某个模式命中的键,将结果合并到现有译文中,其余所有键都保持字节级完全一致。可重复使用——每个模式对应一个 --key。

键作用域会忽略源内容差异,所以即使某个键的源文本从未变化,也仍会被重新翻译。这正是这个标志的用途:在文案调整、模型切换或术语表更新后,它是官方支持的方式,让你只重做少量字符串,而不用为文件其余部分付费。

--force 不会额外带上其他内容,还会跳过整文件的确认提示。

每个键会如何处理#

在 --key 中点名译文中存在结果
是是重新翻译
是否翻译后新增
否是保留现有译文
否否完全不写入

最后一行正是键作用域与普通 push 的区别。自上次完整 push 以来新加到源文件中的键,不会以源文本形式带入译文——它会被直接留出,等到下一次普通的 lingo push 再进行翻译。

模式如何匹配#

模式命中范围
auth.loginauth.login 和 auth.login.title——绝不会命中 auth.login_url
authauth 及其整个子树——绝不会命中 authority
"auth.*"auth 下的所有内容,包括 auth.login_url,但不包括 auth
"auth*"上述范围再加上 authority——完全不设边界

模式可以精确匹配某个键,也可以按前缀匹配,但前缀必须在 .、/、- 或 [ 的边界处结束,或者作为 glob 进行匹配。数组成员也能通过方括号边界命中,因此 nav.items 会命中 nav.items[0].title。

glob 一定要加引号。 你的 shell 会先展开它们:在 zsh 中,裸写的 --key auth.* 要么会因 no matches found 直接中止,要么——如果目录里刚好有一个像 auth.json 这样的文件——会悄悄变成那个文件名。逗号分隔的值也不是列表:--key "a,b" 是一个字面模式,实际上什么都匹配不到。请改为重复使用这个标志。

它会拒绝哪些情况#

键作用域会明确报出并跳过以下情况,而不是悄悄多做超出你要求的事:

  • 某个 locale 还没有任何译文。 没有可供合并的内容,因此会点名该 locale 并跳过——先用 --backfill-missing 完整翻译一次,再使用 --key。
  • 不能省略键的格式——包括这类文档格式:文档一经编辑,键就会随之变化;以及 xcode-stringsdict:为保持文件有效,必须保留文件所需的复数类别。完整列表请见 Formats。这些文件会被跳过并显示警告,因此一次推送仍然可能将它们与键值文件混合在一起;推送这些文件时请不要使用 --key。
  • 作用域什么都没命中 时,会明确说明,而不是把这次运行报告成已经是最新状态。

即使使用了作用域,按位置排列的成员也会保留其源文本——比如数组元素、Android 的 <string-array> 项以及 <plurals> 数量项——因为一旦移除其中一个,其他项的编号就会随之变化。

它不会推进锁文件#

带键作用域的运行只会翻译文件的一部分,因此会有意保持锁文件中的源哈希不变。该文件中的其他改动仍会保持待处理状态,并由下一次普通的 lingo push 接手处理。

--force / -f#

bash
lingo push docs/en/about.md --force

重新翻译每个匹配到的目标,忽略任何现有译文,并绕过服务端缓存。请务必限制作用域——使用位置模式或 --backfill-missing——除非你真的要处理整个项目:裸写的 lingo push --force 会重新翻译所有已配置的模式,而下面这道确认就是唯一的拦截。

对于一个从未翻译过的项目,本就没有内容可供覆盖,因此 --force 在这里起不了作用;请改用 --backfill-missing。总体而言,这也是更稳妥的习惯:它只会补齐空缺,且绝不会触发提示。

默认情况下,--force 会在执行前提示确认:

text
! --force will retranslate every target for pattern(s): docs/en/about.md and
  overwrite existing translations. Continue? (Yes, retranslate / Cancel)

传入 --yes / -y 可跳过提示(适合 CI)。

如果你只是想重做几条字符串,而不是整个文件,请直接用 --key——你只需为点名的那些键付费。

--backfill-missing#

bash
lingo push --backfill-missing

翻译所有尚不存在的目标文件,覆盖所有已配置模式。它等价于对配置里的全部模式执行一次作用域推送,但只生成缺失的文件。适用于在 targetLocales 中新增语言区域后,或新项目首次推送时使用。

与 --force 搭配使用,可从头重新翻译全部内容:

bash
lingo push --backfill-missing --force --yes

--yes / -y#

跳过 --force 的确认提示。没有 --force 时不会生效,与 --key 一起使用时也同样无效——键作用域本来就不会弹出提示,因为它只会处理你点名的那些键。

--estimate#

bash
lingo push --estimate
lingo push 'docs/en/**/*.md' --estimate

输出本次推送的预估成本,并在不进行翻译的情况下退出。CLI 会执行完整的推送流程——哈希、增量计算,以及上传源文件字节以便服务器规划精确增量——然后让引擎为这次运行估价,而不是直接启动。不会进行任何翻译、写入或计费;锁文件和目标文件都会保持原样。

这里给出的是估算值,不是正式报价。--estimate 可以与作用域以及 --key / --force / --backfill-missing 组合使用,因此你可以精确估算即将执行的这次 push。

如果源内容没有变化,--estimate 会像常规推送一样,通过 ✓ Nothing to push. 直接结束。

如果相同源文件的运行已在进行中,--estimate 会直接失败,而不会为一个只启动到一半的运行估价:

text
Error: Cannot estimate: existing group run_a8c... is already in 'running' state. Change a source file or wait for the run to finish.

输出#

成功时:

text
Pushing source files to localization engine…
✓ Run run_a8c...: localized 12 target file(s), 4 already up-to-date, uploaded 1 new artifact(s).

摘要会拆分为以下几类:

  • 已本地化 N 个目标文件——引擎生成了新的翻译,CLI 已将其写入磁盘。
  • N 个已是最新——命中服务端缓存(源文件一致,目标文件被复用)。
  • 已上传 N 个新工件——这些源文件此前未被引擎见过(二进制/大体积内容只存储一次,后续通过引用复用)。
  • 已跳过 N 个目标(本地有修改)——本地目标哈希与锁文件不一致。使用 --force 重新运行即可覆盖。

如果某个目标失败,CLI 会打印每个失败目标对应的错误信息,并以非零状态退出——这对 CI 很有用:

text
✓ Run run_a8c...: localized 10 target file(s).
  2 target(s) failed:
    locales/de.json: rate limit on engine; retry later
    locales/fr.json: timeout

使用 --estimate 时:

text
Estimating push cost…
› Estimated cost: ~$1.87 (12 target(s), ~48,000 output tokens — estimate, not a quote)
  de: ~$0.9350 (6 target(s), ~24,000 tokens)
  fr: ~$0.9350 (6 target(s), ~24,000 tokens)
  4 target(s) already up-to-date — no cost.
✓ Estimate complete — nothing was translated. Run `lingo push` to start the translation.

重试机制#

锁文件只会在整次运行完全成功后更新。若发生部分失败(例如某个语言区域超时),锁文件中的源文件哈希不会变化,因此下一次执行 lingo push 时会重试相同的差异——无需手动重置。

如果引擎在任何翻译开始前就报错(例如认证或校验失败),则不会写入任何内容,锁文件也保持不变。

常见用法#

CI:合并后翻译#

yaml
- run: lingo push --backfill-missing --yes
- run: git add . && git commit -m "chore: refresh translations" && git push

--backfill-missing 是安全的默认选择:不会覆盖任何内容,只会补齐缺失项。

重做几条字符串#

bash
lingo push --key auth.login --key billing.plan --wait

在文案调整后,仅重新翻译这些指定的键,文件中的其他所有键都保持不变。

单文件迭代#

bash
lingo push docs/en/onboarding.md -f -y

在文案发生较大改动后,只重新翻译一个源文件。跳过提示可加快迭代速度。

新增语言区域#

在 targetLocales 中增加 .lingo/config.json 后:

bash
lingo push --backfill-missing

将整套内容翻译到新的语言区域,同时不会重新翻译已有内容。