Добавить в корзинуПозвонить
Найти в Дзене
Машинное обучение

Rust Project показал, как на самом деле выглядит поддержка большого языка, когда вокруг компилятора живут отдельные инструменты: Cargo

, Clippy, rustfmt, rust-analyzer, Miri и другие. Проблема простая: эти проекты удобнее развивать в отдельных репозиториях, потому что у них свои команды, CI, ревью и процессы. Но при этом они должны регулярно синхронизироваться с rust-lang/rust, потому что nightly-сборки, rustup-компоненты и внутренние compiler API завязаны на центральный репозиторий. Обычные варианты плохо масштабируются: - monorepo даёт атомарные изменения, но делает вход в проект тяжелее и привязывает всех к процессам compiler team - git submodules простые, но ломают DX: забытые --recursive, грязные состояния, случайные изменения SHA и невозможность нормально менять родительский проект и инструмент в одном PR - git subtree лучше подходит для атомарных изменений, но на масштабе Rust стал слишком медленным, особенно для Miri, где синхронизация могла не завершаться часами Поэтому Rust использует Josh - инструмент на Rust для быстрых и обратимых фильтров поверх git-истории. В статье его по сути называют “git subtree

Rust Project показал, как на самом деле выглядит поддержка большого языка, когда вокруг компилятора живут отдельные инструменты: Cargo, Clippy, rustfmt, rust-analyzer, Miri и другие.

Проблема простая: эти проекты удобнее развивать в отдельных репозиториях, потому что у них свои команды, CI, ревью и процессы. Но при этом они должны регулярно синхронизироваться с rust-lang/rust, потому что nightly-сборки, rustup-компоненты и внутренние compiler API завязаны на центральный репозиторий.

Обычные варианты плохо масштабируются:

- monorepo даёт атомарные изменения, но делает вход в проект тяжелее и привязывает всех к процессам compiler team

- git submodules простые, но ломают DX: забытые --recursive, грязные состояния, случайные изменения SHA и невозможность нормально менять родительский проект и инструмент в одном PR

- git subtree лучше подходит для атомарных изменений, но на масштабе Rust стал слишком медленным, особенно для Miri, где синхронизация могла не завершаться часами

Поэтому Rust использует Josh - инструмент на Rust для быстрых и обратимых фильтров поверх git-истории. В статье его по сути называют “git subtree on steroids”: тот же смысл bidirectional sync, но быстрее и с более чистой историей.

Поверх Josh команда сделала josh-sync - небольшой Rust-инструмент, который унифицирует pull/push-синхронизацию между rust-lang/rust и дочерними проектами. Часть операций уже автоматизирована через GitHub Actions: CI может сам открыть PR на синхронизацию и сообщить в Zulip, если нужен ручной разбор конфликта.

Сейчас Josh используют для Miri, Rust Analyzer, compiler-builtins, stdarch и Rust Compiler Development Guide. Clippy и часть других проектов ещё остаются на subtree, но план - постепенно мигрировать и их.

Это пример инженерной инфраструктуры вокруг языка. Rust масштабируется не только через типы, borrow checker и compiler work, но и через скучную, сложную механику сопровождения десятков связанных репозиториев, где один breaking change во внутреннем API не должен случайно сломать nightly-инструменты.

Josh здесь закрывает именно эту боль: сохранить независимость репозиториев, но при этом дать возможность синхронно менять компилятор и завязанные на него инструменты без адского ручного sync-процесса.

https://blog.rust-lang.org/inside-rust/2026/06/04/how-josh-helps-rust-manage-code-across-multiple-repositories/