|
| 1 | +# `rustfmt` subtree sync procedure |
| 2 | + |
| 3 | +Note that `rustfmt` has not migrated to `josh` yet, so the git subtree sync is somewhat involved. |
| 4 | +This procedure is mostly adapted from the `clippy` subtree sync process at |
| 5 | +<https://doc.rust-lang.org/stable/clippy/development/infrastructure/sync.html>, but adapted for |
| 6 | +`rustfmt`. We are keeping a separate copy of the instructions for `rustfmt` in case `clippy` moves |
| 7 | +off of `git subtree` in the mean time (and also slightly adjusted to be `rustfmt`-specific. |
| 8 | + |
| 9 | +> [!NOTE] |
| 10 | +> |
| 11 | +> Note that AFAIK, eventually both `clippy` and `rustfmt` would like to move to the `josh`-sync |
| 12 | +> workflow, just that `rustfmt` is blocked on actually doing a bidirectional sync first, while |
| 13 | +> `clippy` is sorting out some issues related to tags and git history (due to usage of `git |
| 14 | +> subtree`). |
| 15 | +
|
| 16 | +## Tooling |
| 17 | + |
| 18 | +The `git-subtree` tooling still has a bug that prevents it from working properly with the |
| 19 | +`rust-lang/rust` repository. This means that you need to build and use a patched version of |
| 20 | +`git-subtree`. |
| 21 | + |
| 22 | +> [!NOTE] |
| 23 | +> |
| 24 | +> The patched version of `git-subtree` is the sources corresponding to the stale PR |
| 25 | +> <https://github.com/gitgitgadget/git/pull/493>. |
| 26 | +
|
| 27 | +On Linux, place `git-subtree` under `/usr/lib/git-core` (make sure to keep a backup copy of the |
| 28 | +'standard' `git-subtree`), and make sure it has proper permissions: |
| 29 | + |
| 30 | +```sh |
| 31 | +$ sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree |
| 32 | +$ sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree |
| 33 | +$ sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree |
| 34 | +``` |
| 35 | + |
| 36 | +> [!NOTE] |
| 37 | +> |
| 38 | +> Running `git subtree push` for the first time requires building a cache, which involves going |
| 39 | +> through the entire history of `rustfmt` once. You likely will need to increase the stack limit via |
| 40 | +> |
| 41 | +> ```sh |
| 42 | +> $ ulimit -s 60000 |
| 43 | +> ``` |
| 44 | +
|
| 45 | +> [!NOTE] |
| 46 | +> |
| 47 | +> The following steps assume that you have configured the `rustfmt` remote as `upstream`, i.e. |
| 48 | +> |
| 49 | +> ```sh |
| 50 | +> $ git remote add upstream git@github.com:rust-lang/rustfmt |
| 51 | +> ``` |
| 52 | +
|
| 53 | +## Subtree push direction: syncing changes from `rust-lang/rust` to `rustfmt` |
| 54 | +
|
| 55 | +> [!WARNING] |
| 56 | +> |
| 57 | +> **For this subtree-push direction, all commands described must be run within the `rust-lang/rust` |
| 58 | +> checkout.** |
| 59 | +
|
| 60 | +### 1. Acquire a checkout of `rust-lang/rust` |
| 61 | +
|
| 62 | +Either acquire a clone of `rust-lang/rust`, or if you already have a checkout, make sure the |
| 63 | +checkout is up-to-date via `git fetch`. |
| 64 | +
|
| 65 | +### 2. Checkout the commit from the latest available nightly |
| 66 | +
|
| 67 | + You can fetch the commit hash of the latest available nightly by inspecting `rustup check` output. |
| 68 | +
|
| 69 | +### 3. Sync changes from the `rust`-copy of `rustfmt` to your `rustfmt` fork |
| 70 | +
|
| 71 | +> [!WARNING] |
| 72 | +> |
| 73 | +> **Make sure to either use a fresh branch, e.g. `subtree-push`, or delete the branch beforehand**. |
| 74 | +> Changes cannot be fast forwarded and you have to run this command again. |
| 75 | +
|
| 76 | +```sh |
| 77 | +$ git subtree push -P src/tools/rustfmt /path/to/rustfmt/checkout subtree-push |
| 78 | +``` |
| 79 | +
|
| 80 | +Most of the time, you will need to create a **merge commit** in the `rustfmt` repository. Note that |
| 81 | +this must be done in the subtree repo (i.e. `rustfmt` repo) and not in the `rust`-copy of `rustfmt`. |
| 82 | +
|
| 83 | +Assuming the `upstream` remote is the `rust-lang/rust` remote: |
| 84 | +
|
| 85 | +```sh |
| 86 | +$ git fetch upstream |
| 87 | +$ git switch subtree-push |
| 88 | +$ git merge upstream/main --no-ff |
| 89 | +``` |
| 90 | +
|
| 91 | +> [!WARNING] |
| 92 | +> |
| 93 | +> You may have to manually resolve certain merge conflicts. Pay extra attention when resolving them, |
| 94 | +> since it's easy to accidentally resolve the conflict in incorrect ways. |
| 95 | +
|
| 96 | +> [!TIP] |
| 97 | +> |
| 98 | +> Subtree syncs are one of the rare occasions where a merge commit is allowed in a PR. |
| 99 | +
|
| 100 | +### 4. Bump the nightly toolchain version in the `rustfmt` repository |
| 101 | +
|
| 102 | +Using the same latest nightly date (that you can obtain by inspecting `rustup check` output), |
| 103 | +manually edit `rust-toolchain`: |
| 104 | +
|
| 105 | +```diff |
| 106 | + [toolchain] |
| 107 | +-channel = "nightly-2025-04-02" |
| 108 | ++channel = "nightly-$LATEST_NIGHTLY_DATE" |
| 109 | + components = ["llvm-tools", "rustc-dev"] |
| 110 | +``` |
| 111 | +
|
| 112 | +Substituting `$LATEST_NIGHTLY_DATE` with the latest nightly date. |
| 113 | +
|
| 114 | +Create a separate commit dedicated to making the `rust-toolchain` change. You can use [the following |
| 115 | +commit message template](#rust-toolchain-bump-commit-message-template). |
| 116 | +
|
| 117 | +#### `rust-toolchain` bump commit message template |
| 118 | +
|
| 119 | +```text |
| 120 | +chore: bump rustfmt toolchain to nightly-$LATEST_NIGHTLY_DATE |
| 121 | +
|
| 122 | +Bumping the toolchain version as part of a git subtree push. |
| 123 | +
|
| 124 | +current toolchain (nightly-$CURRENT_NIGHTLY_DATE): |
| 125 | + - $CURRENT_NIGHTLY_VERSION-nightly ($CURRENT_NIGHTLY_HASH $CURRENT_NIGHTLY_DATE) |
| 126 | +
|
| 127 | +latest toolchain (nightly-$LATEST_NIGHTLY_DATE): |
| 128 | + - $LATEST_NIGHTLY_VERSION-nightly ($LATEST_NIGHTLY_HASH $LATEST_NIGHTLY_DATE) |
| 129 | +``` |
| 130 | +
|
| 131 | +Substituting the placeholders with the right information. |
| 132 | +
|
| 133 | +> [!TIP] |
| 134 | +> |
| 135 | +> Example bump commit message: |
| 136 | +> |
| 137 | +> ```text |
| 138 | +> chore: bump rustfmt toolchain to nightly-2025-10-07 |
| 139 | +> |
| 140 | +> Bumping the toolchain version as part of a git subtree push. |
| 141 | +> |
| 142 | +> current toolchain (nightly-2025-04-02): - 1.88.0-nightly (e2014e876 2025-04-01) |
| 143 | +> |
| 144 | +> latest toolchain (nightly-2025-10-07): - 1.92.0-nightly (f6aa851db 2025-10-07) |
| 145 | +> ``` |
| 146 | +
|
| 147 | +### 5. Open a PR against `rustfmt` |
| 148 | +
|
| 149 | +And wait for the sync PR to be merged. The `rustfmt` maintainers will run Diff Check against the PR |
| 150 | +to catch any unexpected formatting changes. Once Diff Check failures are investigated and are |
| 151 | +resolved, the PR can then be merged. |
| 152 | +
|
| 153 | +For the PR: |
| 154 | +
|
| 155 | +- Use the title `subtree-push nightly-$LATEST_NIGHTLY_DATE` for consistency with previous |
| 156 | + subtree-pushes. |
| 157 | +- Include a copy of the bump commit message in the PR description for quick reference. Feel free to |
| 158 | + include additional notes that might be helpful for the maintainers when reviewing. |
| 159 | +
|
| 160 | +> [!TIP] |
| 161 | +> |
| 162 | +> Example subtree-push PR title and description: |
| 163 | +> |
| 164 | +> **PR title**: `subtree-push nightly-2025-10-07` |
| 165 | +> |
| 166 | +> **PR description**: |
| 167 | +> |
| 168 | +> ```text |
| 169 | +> Bumping the toolchain version as part of a git subtree push. |
| 170 | +> |
| 171 | +> current toolchain (nightly-2025-04-02): |
| 172 | +> - 1.88.0-nightly (e2014e876 2025-04-01) |
| 173 | +> |
| 174 | +> latest toolchain (nightly-2025-10-07): |
| 175 | +> - 1.92.0-nightly (f6aa851db 2025-10-07) |
| 176 | +> ``` |
| 177 | +
|
| 178 | +> [!WARNING] |
| 179 | +> |
| 180 | +> Make sure to immediately follow-up with a subtree-pull direction, syncing `rustfmt` to |
| 181 | +> `rust-lang/rust`. We need the {subtree-push, subtree-pull} directions to be performed in |
| 182 | +> lock-step, to minimize any changes in between that makes the logistics more complex. |
| 183 | +
|
| 184 | +## Subtree pull direction: syncing from `rustfmt` to `rust-lang/rust` |
| 185 | +
|
| 186 | +> [!WARNING] |
| 187 | +> |
| 188 | +> For this **subtree-pull** direction, all commands must also be performed within the |
| 189 | +> `rust-lang/rust` checkout. |
| 190 | +
|
| 191 | +### 1. Make sure latest `main` of `rust-lang/rust` is checked out |
| 192 | +
|
| 193 | +### 2. Sync `rustfmt` `main` to the `rust`-copy of `rustfmt` |
| 194 | +
|
| 195 | +```sh |
| 196 | +$ git switch -c rustfmt-subtree-update |
| 197 | +$ git subtree pull -P src/tools/rustfmt /path/to/rustfmt/checkout main |
| 198 | +``` |
| 199 | +
|
| 200 | +### 3. Open a PR against `rust-lang/rust` |
| 201 | +
|
| 202 | +Use the PR title |
| 203 | +
|
| 204 | +> `rustfmt` subtree update |
| 205 | +
|
| 206 | +so that `triagebot` will not warn against the PR containing a merge commit, and makes it easy for |
| 207 | +`rustfmt` maintainers to discover. |
| 208 | +
|
| 209 | +Back link to the `rustfmt` subtree-push PR as helpful context. |
0 commit comments