Google Copybara: 在仓库之间转换和移动代码

Google Copybara: 在仓库之间转换和移动代码

Google Copybara 实现仓库间的同步代码移动

Google Copybara 是一个用于在仓库之间转换和移动源代码的工具。它主要用于在机密(私有)仓库与公共仓库之间保持同步,确保代码可以存在于多个位置,同时维护单一的权威事实来源。

核心功能与使用场景

Copybara 允许开发人员在移动代码的同时对内容应用转换。关键使用场景包括:

  • 私有到公共同步: 将机密仓库中的特定代码段导入到公共仓库中。
  • 公共到私有同步: 将代码从公共仓库导入回机密仓库。
  • 贡献管理: 将更改从非权威仓库(例如公共贡献者的 PR)移动到权威仓库,并转换代码以适应内部结构。
  • 一次性迁移: 在保留历史记录的情况下,将代码一次性移动到新仓库。

技术架构与状态管理

Copybara 被设计为无状态的。它并不维护一个记录已移动内容的外部数据库,而是通过在提交信息中使用标签,将状态存储在目标仓库中。这种架构允许多个用户或自动化服务针对相同的仓库运行相同的配置并获得一致的结果。

目前,Copybara 正式支持 Git 仓库,并对 Mercurial 提供实验性支持。其可扩展架构旨在允许为各种使用场景添加定制的来源(origins)和目的地(destinations)。

配置与实现

Copybara 使用配置语言(通常为 .sky 文件)来定义工作流。一个工作流定义了来源、目的地、要移动的文件(使用 globs)以及要应用的转换。

工作流逻辑示例:

core.workflow(
    name = "default",
    origin = git.github_origin(
      url = "https://github.com/google/copybara.git",
      ref = "master",
    ),
    destination = git.destination(
        url = "file:///tmp/foo",
    ),
    destination_files = glob(["third_party/copybara/**"], exclude = ["README_INTERNAL.txt"]),
    transformations = [
        core.replace(
                before = "//third_party/bazel/bashunit",
                after = "//another/path:bashunit",
                paths = glob(["**/BUILD"])),
        core.move("", "third_party/copybara")
    ],
)

安装与部署选项

根据环境的不同,Copybara 可以通过几种方式进行部署:

  • 预构建二进制文件: 每周的快照版本可在 GitHub 上获取,需要 Java Runtime 21 或更高版本。
  • Bazel 构建: 该工具可以使用 JDK 11 和 Bazel 从源码编译。它也可以通过提供的便捷宏作为外部 Bazel 仓库进行集成。
  • Docker: 提供实验性的 Docker 镜像,允许用户通过容器运行 Copybara。此方法支持环境变量(例如 COPYBARA_CONFIGCOPYBARA_WORKFLOW)来控制执行,并允许挂载 .gitconfig 和 SSH 凭据以进行仓库访问。

社区见解与替代方案

用户和开发人员针对 Copybara 与其他版本控制策略的效用提出了几种观点:

  • 单体仓库(Monorepo)生产力: 一些用户报告,在使用 Copybara 管理内部单体仓库的面向公共部分时,生产力得到了显著提升。
  • 历史记录保留: 它被认为是一种有效的“即发即忘”导出工具,可以将文件夹移动到新仓库,同时保留 Git blame 历史记录。
  • 替代方案: 讨论点包括使用 GitLab 的内置镜像功能、Git submodules 或 Git subtrees。提到的其他专用工具还包括 Josh(Rust 项目使用)和来自 Meta 的现已存档的 fbshipit
  • 权衡: 一些贡献者警告说,对于不需要转换或排除项的简单仓库镜像,更简单的内置供应商工具可能更可靠。

"如果你的唯一需求只是同步仓库而不需要排除或转换,我不会费心去用它……Gitlab 有非常简单的方法将代码从 Gitlab 镜像到 Github 或其他 git 供应商/服务器"

"我见过许多团队在拥有公共部分的单体仓库中协作时,生产力得到了显著提升。"

Sources