Skip to content

Commit 381dcdb

Browse files
committed
Add a rustfmt-specific copy of subtree sync procedure
1 parent 51c5a47 commit 381dcdb

File tree

2 files changed

+213
-0
lines changed

2 files changed

+213
-0
lines changed

Contributing.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ accessing the correct field on the config struct, e.g., `config.max_width()`. Mo
269269
functions have a `Config`, or one can be accessed via a visitor or context of
270270
some kind.
271271

272+
## Subtree syncs
273+
274+
Refer to [*Subtree sync procedure*](./Subtree%20sync%20procedure.md).
275+
272276

273277
[rustfmt-zulip]:
274278
https://rust-lang.zulipchat.com/#narrow/channel/357797-t-rustfmt

Subtree sync procedure.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
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

Comments
 (0)