Forking workflow
Изучите forking workflow для open source: форк, клонирование, push и открытие pull request без прав на запись в основной репозиторий.
Обзор
Forking workflow — это стандартная модель для open-source проектов и любых ситуаций, когда контрибьюторам нельзя доверять прямой push-доступ к основному репозиторию. Вместо того чтобы пушить в общий репозиторий, каждый участник работает в собственной серверной копии — форке — и предлагает изменения через pull request. Именно так миллионы контрибуций ежедневно попадают в проекты на GitHub и GitLab.
На этой странице объясняется, что такое форк, чем он отличается от workflow с общим репозиторием, какие именно команды нужны для клонирования, настройки remote, push и открытия pull request, а также — самое важное — как поддерживать форк в актуальном состоянии, чтобы ваши изменения легко мержились.
Ключевое отличие
В workflow с ветками функций все пушат ветки в один общий репозиторий. Forking workflow добавляет ещё один уровень: теперь существуют два серверных репозитория — официальный upstream-репозиторий, в который вы не можете писать, и ваш форк, которым вы полностью управляете. Вы пушите в свой форк и просите upstream забрать изменения оттуда.
Это иногда называют треугольным workflow из-за того, как соотносятся три копии:
upstream (official repo, read-only to you)
▲ │
pull │ │ fork (one click, server-side)
request │ ▼
your fork (origin) ──clone──▶ your laptop
◀──push──Вы fetch-аете из upstream, push-аете в origin (ваш форк), а pull request — это мост, который просит мейнтейнера забрать вашу ветку из вашего форка в upstream.
Шаг за шагом
1. Форкните upstream-репозиторий на хостинговой платформе. Это создаёт your-fork под вашим аккаунтом — полную серверную копию.
2. Клонируйте ваш форк на компьютер:
git clone https://github.com/you/project.git
cd project3. Добавьте upstream как remote, чтобы получать последние изменения проекта:
git remote add upstream https://github.com/original/project.gitТеперь у вашего клона два remote. Проверьте их с помощью git remote -v:
origin https://github.com/you/project.git (fetch)
origin https://github.com/you/project.git (push)
upstream https://github.com/original/project.git (fetch)
upstream https://github.com/original/project.git (push)origin указывает на ваш форк (куда вы пушите); upstream указывает на официальный репозиторий (откуда вы fetch-аете). См. git remote для управления ими.
4. Создайте ветку и работайте. Всегда ответвляйтесь от актуального main — никогда не коммитьте напрямую в main вашего форка, чтобы он оставался чистым зеркалом upstream:
git switch -c fix/typo-in-docs
# ...make changes and commit...
git push -u origin fix/typo-in-docsФлаг -u (--set-upstream) связывает вашу локальную ветку с веткой в форке, поэтому в дальнейшем достаточно просто запустить git push.
5. Откройте pull request из ветки вашего форка в основную ветку upstream. В веб-интерфейсе для этого есть кнопка; с помощью CLI GitHub это можно сделать из терминала:
gh pr create --base main --head you:fix/typo-in-docsМейнтейнеры ревьюят изменения, при необходимости запрашивают правки и мержат после одобрения. Если просят внести правки, закоммитьте и снова запустите git push — открытый pull request обновится автоматически.
Синхронизация с upstream
Пока вы работаете, проект продолжает развиваться, поэтому обновляйте форк из upstream перед созданием новых веток. Используйте git fetch для загрузки коммитов из upstream, а затем git merge (или rebase) для их применения:
git switch main
git fetch upstream
git merge upstream/main # fast-forward main onto upstream
git push origin main # update your fork's main on the serverПоскольку вы никогда сами не коммитите в main, этот merge всегда является чистым fast-forward — без конфликтов. Это можно обеспечить с помощью git merge --ff-only upstream/main, который завершится с ошибкой, если main разошёлся с upstream.
Обновление ветки функции в процессе работы
Если ваша ветка отстала, пока идёт ревью, перенесите новые коммиты из upstream в неё. Rebase сохраняет линейную историю, которую мейнтейнеры обычно предпочитают:
git fetch upstream
git switch fix/typo-in-docs
git rebase upstream/main
git push --force-with-lease # rewrite your fork's branch safely--force-with-lease откажется перезаписывать remote, если кто-то другой успел запушить за это время, что делает его значительно безопаснее обычного --force. Если вы предпочитаете не переписывать историю, запустите вместо этого git merge upstream/main. Подробности см. в git rebase и merge conflicts.
Почему это работает
Модель с форками позволяет проекту принимать контрибуции от кого угодно, при этом официальный репозиторий остаётся под строгим контролем — только мейнтейнеры могут мержить. Участникам не нужны специальные права доступа, ревью проходит публично в каждом pull request, а история upstream остаётся чистой. Для ненадёжного и масштабного сотрудничества это самый безопасный из распространённых Git workflow.
Используйте его, когда контрибьюторам нельзя доверять push-доступ (большинство open-source проектов). Когда все в одной команде и заслуживают доверия, более простой workflow с ветками функций или Gitflow позволяет обойтись без лишнего форка. Сравните их бок о бок в разделе Git workflows.