在 Clippy 和 rust-lang/rust 之间同步更改

Clippy 当前使用固定的 nightly 版本构建。

rust-lang/rust 仓库中(rustc 所在的位置),有一个 Clippy 的副本,编译器黑客会不时地修改它,以适应编译器不稳定的 API 中的变化。

我们需要定期将这些更改同步回此仓库,同时在此期间对此仓库所做的更改也需要同步到 rust-lang/rust 仓库。

为了避免 rust-lang/rust PR 队列拥堵,如果没有紧急更改,这种双向同步过程每两周进行一次。同步从 Rust 稳定版本发布之日开始,然后每隔一周进行。这样可以确保我们使此仓库与最新的编译器 API 保持同步,并且 Clippy 中的每个功能在进入 Beta 版之前都可以在 nightly 版本中使用 2 周。作为参考,按照此节奏进行的第一次同步是在 2020-08-27 执行的。

以下部分详细描述了此过程。有关 Rust 仓库中 subtree 的一般信息,请参阅 rustc-dev-guide

修补 git-subtree 以使其与大型仓库一起工作

目前,git-subtree 中存在一个错误,导致它无法与 rust-lang/rust 仓库正常工作。有一个开放的 PR 来修复它,但它已经过时了。在继续执行以下步骤之前,我们需要手动将该修复应用于我们的本地 git-subtree 副本。

您可以从 此处 获取 git-subtree 的修补版本。将此文件放在 /usr/lib/git-core 下(备份之前的文件),并确保它具有正确的权限

sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree
sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree

注意:第一次运行 git subtree push 时,必须构建一个缓存。这涉及完整遍历一次 Clippy 的历史记录。为此,您必须增加堆栈限制,您可以使用 ulimit -s 60000 来执行此操作。请确保从您调用 git subtree 的同一会话中运行 ulimit 命令。

注意:如果您是 Debian 用户,则 dash 是脚本默认使用的 shell,而不是 sh。此 shell 的硬编码递归限制设置为 1,000。为了使此过程正常工作,您需要强制脚本运行 bash。您可以通过编辑 git-subtree 脚本的第一行并将 sh 更改为 bash 来执行此操作。

定义远程仓库

您可能需要定义远程仓库,这样您就不必在每次同步时都键入远程地址。您可以使用以下命令执行此操作(这些命令仍然必须在 rust 目录内运行)

# Set clippy-upstream remote for pulls
$ git remote add clippy-upstream https://github.com/rust-lang/rust-clippy
# Make sure to not push to the upstream repo
$ git remote set-url --push clippy-upstream DISABLED
# Set a local remote
$ git remote add clippy-local /path/to/rust-clippy

注意:以下部分假设您已使用上述远程名称设置了这些远程仓库。

执行从 rust-lang/rust 到 Clippy 的同步

这是同步过程的 TL;DR 版本(以下所有命令都必须在 rust 目录内运行)

  1. 克隆 rust-lang/rust 仓库或确保它是最新的。

  2. 检出最新的可用 nightly 版本的 commit。您可以使用 rustup check 获取它。

  3. 将 Clippy 的 rust 副本的更改同步到您的 Clippy 分支

    # Be sure to either use a net-new branch, e.g. `sync-from-rust`, or delete the branch beforehand
    # because changes cannot be fast forwarded and you have to run this command again.
    git subtree push -P src/tools/clippy clippy-local sync-from-rust
    

    注意:大多数情况下,您必须在 rust-clippy 仓库中创建一个合并 commit(这必须在 Clippy 仓库中完成,而不是在 Clippy 的 rust 副本中完成)

    git fetch upstream  # assuming upstream is the rust-lang/rust remote
    git checkout sync-from-rust
    git merge upstream/master --no-ff
    

    注意:这是 PR 中允许合并 commit 的少数情况之一。

  4. 通过将 rust-toolchain 文件中的日期更改为当前日期并使用消息提交来更新 Clippy 仓库中的 nightly 版本

    git commit -m "Bump nightly version -> YYYY-MM-DD"
    
  5. 打开一个指向 rust-lang/rust-clippy 的 PR 并等待它被合并(为了加快该过程,请在您的 PR 中 ping @rust-lang/clippy 团队和/或在 Zulip 流中询问他们。)

执行从 Clippy 到 rust-lang/rust 的同步

以下所有命令都必须在 rust 目录内运行。

  1. 确保您已检出 rust-lang/rust 的最新 master
  2. rust-lang/rust-clippy master 同步到 Clippy 的 rust 副本
    git checkout -b sync-from-clippy
    git subtree pull -P src/tools/clippy clippy-upstream master
    
  3. 打开一个指向 rust-lang/rust 的 PR