Google Copybara:在代码仓库之间迁移代码

Hacker News Top 工具

摘要

Copybara 是 Google 的一个开源工具,用于在代码仓库之间转换和移动代码,通常用于同步机密仓库和公共仓库,保持单一真相来源。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/01 01:55

google/copybara

来源:https://github.com/google/copybara

Copybara

一种用于在代码仓库之间转换和移动代码的工具。

Copybara 是 Google 内部使用的一种工具。它能够在代码仓库之间转换和移动代码。通常,源代码需要存在于多个仓库中,Copybara 让你可以在这些仓库之间转换和移动源代码。一个常见的场景是项目需要维护一个机密仓库和一个公开仓库的同步。Copybara 要求你选择其中一个仓库作为权威仓库,确保始终有一个事实来源。不过,该工具允许向任何仓库贡献代码,并且任何仓库都可以用于发布版本。最常见的使用场景是将代码从一个仓库重复移动到另一个仓库。Copybara 也可以用于一次性将代码迁移到新仓库。

Copybara 的用途示例包括:

  • 将代码片段从机密仓库导入到公开仓库。
  • 将代码从公开仓库导入到机密仓库。
  • 将非权威仓库中的更改导入到权威仓库。

当在非权威仓库中做出更改时(例如,公开仓库中的贡献者),Copybara 会转换该更改并将其移动到权威仓库中的适当位置。任何合并冲突的处理方式与权威仓库中过期更改的处理方式相同。

Copybara 的主要特性之一是无状态,或者更具体地说,它将状态存储在目标仓库中(作为提交消息中的标签)。这使得多个用户(或一个服务)可以为相同的配置/仓库使用 Copybara,并获得相同的结果。

目前,唯一支持的仓库类型是 Git。Copybara 也能够从 Mercurial 仓库读取,但该功能仍处于实验阶段。可扩展的架构允许为几乎任何用例添加自定义的源和目标。未来将添加对其他仓库类型的官方支持。

示例

core.workflow(
    name = "default",
    origin = git.github_origin(
        url = "https://github.com/google/copybara.git",
        ref = "master",
    ),
    destination = git.destination(
        url = "file:///tmp/foo",
    ),
    # 复制所有内容,但如果存在 README_INTERNAL.txt 文件则不删除它
    destination_files = glob(["third_party/copybara/**"], exclude = ["README_INTERNAL.txt"]),
    authoring = authoring.pass_thru("Default email "),
    transformations = [
        core.replace(
            before = "//third_party/bazel/bashunit",
            after = "//another/path:bashunit",
            paths = glob(["**/BUILD"])),
        core.move("", "third_party/copybara")
    ],
)

运行:

$ (mkdir /tmp/foo ; cd /tmp/foo ; git init --bare)
$ copybara copy.bara.sky

Copybara 入门

最简单的入门方式是使用每周的“快照”版本,这些版本包含预构建的二进制文件。请注意,这些版本是自动发布的,没有任何手动测试、版本兼容性或正确性保证。从 https://github.com/google/copybara/releases 选择一个版本。

从源代码构建

要使用未发布的 copybara 版本,你需要从 HEAD 编译。为此,你需要执行以下操作:

  • 安装 JDK 11 (https://www.oracle.com/java/technologies/downloads/#java11)
  • 安装 Bazel (https://bazel.build/install)
  • 在本地克隆 copybara 源代码:
    • git clone https://github.com/google/copybara.git
  • 构建:
    • bazel build //java/com/google/copybara
    • bazel build //java/com/google/copybara:copybara_deploy.jar 以创建可执行的 uberjar
  • 测试:bazel test //... 如果你希望确保没有使用损坏的版本

请注意,某些测试需要安装底层工具(例如 Mercurial、Quilt 等)。如果你的拉取请求与这些模块无关,可以跳过这些测试(我们的 CI 无论如何都会运行所有测试)。

系统包

这些包可以使用你系统的相应包管理器安装。

Arch Linux

使用 Intellij 与 Bazel 插件

如果你使用 Intellij 和 Bazel 插件,请使用此项目配置:

directories:
  copybara/integration
  java/com/google/copybara
  javatests/com/google/copybara
  third_party

targets:
  //copybara/integration/...
  //java/com/google/copybara/...
  //javatests/com/google/copybara/...
  //third_party/...

注意:配置文件可以存储在任何地方,甚至本地文件夹。我们建议使用 VCS(如 git)来存储它们;将其视为源代码。

在 Bazel 中使用预构建的 Copybara

如果使用每周的快照版本,请按以下方式安装 Copybara:

  1. Copybara 附带版本 65.0 的类文件,因此必须使用 Java Runtime 21 或更高版本运行。在你的 .bazelrc 文件中添加:run --java_runtime_version=remotejdk_21
  2. 使用 http_jar 下载发布工件。
    • 在 WORKSPACE 中:load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
    • 在 MODULE.bazel 中:http_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
  3. 在 WORKSPACE 或 MODULE.bazel 中,填写 [version] 占位符:
http_jar(
    name = "com_github_google_copybara",
    # 从 https://github.com/google/copybara/releases/download/[version]/copybara_deploy.jar.sha256 填写
    # sha256 = "",
    urls = ["https://github.com/google/copybara/releases/download/[version]/copybara_deploy.jar"],
)
  1. 在任何 BUILD 文件(也许是 /tools/BUILD.bazel)中声明 java_binary
load("@rules_java//java:java_binary.bzl", "java_binary")

java_binary(
    name = "copybara",
    main_class = "com.google.copybara.Main",
    runtime_deps = ["@com_github_google_copybara//jar"],
)
  1. 使用 bazel run 运行该目标,例如 bazel run //tools:copybara -- migrate copy.bara.sky

从源代码构建 Copybara 作为外部 Bazel 仓库

Copybara 的所有依赖项都定义了便捷宏。将以下代码添加到你的 WORKSPACE 文件中,根据需要替换 {{ sha256sum }}{{ commit }}

http_archive(
    name = "com_github_google_copybara",
    sha256 = "{{ sha256sum }}",
    strip_prefix = "copybara-{{ commit }}",
    url = "https://github.com/google/copybara/archive/{{ commit }}.zip",
)

load("@com_github_google_copybara//:repositories.bzl", "copybara_repositories")
copybara_repositories()

load("@com_github_google_copybara//:repositories.maven.bzl", "copybara_maven_repositories")
copybara_maven_repositories()

load("@com_github_google_copybara//:repositories.go.bzl", "copybara_go_repositories")
copybara_go_repositories()

然后,你可以从工作空间内构建并运行 Copybara 工具:

bazel run @com_github_google_copybara//java/com/google/copybara --

使用 Docker 构建和运行 Copybara

注意:Docker 的使用目前是实验性的,我们欢迎反馈或贡献。

你可以使用 Docker 构建 copybara,如下所示:

docker build --rm -t copybara .

构建完成后,你可以从要使用 Copybara 的代码根目录下运行该镜像:

docker run -it -v "$(pwd)":/usr/src/app copybara help

环境变量

除了向容器传递 cmd 参数外,你还可以设置以下环境变量作为替代方案:

  • COPYBARA_SUBCOMMAND=migrate – 允许你更改运行的命令,默认为 migrate
  • COPYBARA_CONFIG=copy.bara.sky – 允许你指定配置文件的路径,默认为根目录下的 copy.bara.sky
  • COPYBARA_WORKFLOW=default – 允许你指定要运行的工作流,默认为 default
  • COPYBARA_SOURCEREF='' – 允许你指定源引用,默认为无
  • COPYBARA_OPTIONS='' – 允许你指定 copybara 的选项,默认为无
docker run \
  -e COPYBARA_SUBCOMMAND='validate' \
  -e COPYBARA_CONFIG='other.config.sky' \
  -v "$(pwd)":/usr/src/app \
  -it copybara

Git 配置和凭证

有多种方法可以将你的 git 配置和 SSH 凭证分享给 Docker 容器,示例如下:

docker run \
  -v ~/.gitconfig:/root/.gitconfig:ro \
  -v ~/.ssh:/root/.ssh \
  -v ${SSH_AUTH_SOCK}:${SSH_AUTH_SOCK} -e SSH_AUTH_SOCK -v "$(pwd)":/usr/src/app \
  -it copybara

文档

我们仍在完善文档。以下是一些资源:

  • 参考文档
  • 示例
  • 入门教程 (https://blog.kubesimplify.com/moving-code-between-git-repositories-with-copybara)

联系我们

如果你对 Copybara 的工作方式有任何疑问,请通过我们的邮件列表联系我们 (https://groups.google.com/forum/#!forum/copybara-discuss)。

可选提示

  • 如果你想在 Bazel 中看到测试错误,而不是必须 cat 日志,可以在你的 ~/.bazelrc 中添加以下行:test --test_output=streamed

相似文章

GitHub Copilot App

Hacker News Top

GitHub Copilot 是一款 AI 驱动的代码补全工具,通过实时建议代码片段和函数来帮助开发者。