linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it works
  • Уроки
  • База знаний
  • Собеседование
home/git/lessons/git-lab-12-1-fork-flow

lesson ── git-labs ── ~25 мин ── 11 шагов

Fork-flow с двумя remote

Цель - руками пройти цикл работы через fork: clone, remote add upstream, ветвиться от свежего upstream, push в свой origin, sync через fetch + rebase + force-with-lease. Без настоящего GitHub: имитируем оригинал и fork двумя локальными bare-репозиториями.

Это тот же сценарий, что в книге, но с автопроверкой каждого шага.

▶ интерактивный sandbox

Поднимется контейнер gitlab/git-base с git, bash, pre-commit. В браузере откроется терминал, можно сразу git init. Каждый шаг проверяется автоматически. Сеть air-gapped, github.com недоступен.

запустить sandbox →

stack ── git · bash · 256 MB RAM · air-gapped · самоуничтожается через 30 мин простоя

Шаги

  1. 01

    Создай два bare-репозитория: оригинал и fork

    Bare-репозиторий - серверная сторона git, без working tree. Имитируем им центральный сервер и форк.

    bash
    cd /home/student/work
    mkdir -p fork-lab && cd fork-lab
    git init --bare original.git  # --bare = серверный репо без working tree
    git init --bare fork.git
    ls -la

    Видишь две .git-папки. Это «GitHub-как-будто».

    ✓ Bare-репозитории на месте.

  2. 02

    Засей оригинал начальным коммитом

    Создадим временный working-репо, сделаем коммит, запушим в bare.

    bash
    cd /home/student/work/fork-lab
    mkdir seed && cd seed
    git init -b main
    echo "v1" > version.txt
    git add . && git commit -m "init"
    # remote = именованный URL для push/fetch; origin - локальный путь до bare-репо
    git remote add origin /home/student/work/fork-lab/original.git
    git push -u origin main       # -u = set-upstream: запомнить связь main -> origin/main
    cd .. && rm -rf seed          # временный репо больше не нужен

    Оригинал теперь содержит один коммит на main.

    ✓ Оригинал засеян. Дальше - имитируем fork.

  3. 03

    Имитируй fork: скопируй оригинал в fork.git

    На настоящем GitHub fork = «скопируй репо в мой namespace». Здесь - просто клонируем оригинал и пушим в fork.git.

    bash
    cd /home/student/work/fork-lab
    git clone original.git seed2
    cd seed2
    # set-url = переключить адрес существующего remote, не добавлять новый
    git remote set-url origin /home/student/work/fork-lab/fork.git
    git push origin main          # пушим уже в fork.git, не в original.git
    cd .. && rm -rf seed2

    Теперь fork.git содержит тот же main, что и original.git. С этого момента они независимы.

    ✓ Fork имитирован. Дальше клонируем его как разработчик.

  4. 04

    Клонируй свой fork как разработчик

    bash
    cd /home/student/work/fork-lab
    git clone fork.git my-work
    cd my-work
    git remote -v                 # -v (verbose) = показать URL для fetch и push

    Видишь один origin -> fork.git. Это твой свежий клон форка.

    ✓ Клон есть. Теперь добавим upstream.

  5. 05

    Добавь оригинал как upstream

    bash
    cd /home/student/work/fork-lab/my-work
    git remote add upstream /home/student/work/fork-lab/original.git
    git fetch upstream            # тянет refs/remotes/upstream/*, локальные ветки не трогает
    git remote -v                 # теперь два remote: origin и upstream

    Теперь два remote: origin (твой fork) и upstream (оригинал). git fetch upstream загружает refs/remotes/upstream/* без трогания твоих локальных веток.

    ✓ Два remote настроены. Теперь имитируем активность в оригинале.

  6. 06

    Имитируй чужой коммит в оригинале

    Другой разработчик что-то запушил в оригинал. Имитируем это:

    bash
    cd /home/student/work/fork-lab
    git clone original.git orig-clone
    cd orig-clone
    echo "v2" > version.txt       # перезаписываем v1 -> v2
    git commit -am "bump to v2"
    git push origin main          # пушим в оригинал (origin тут указывает на original.git)
    cd .. && rm -rf orig-clone

    Оригинал ушёл вперёд. Твой fork - нет, твой clone - нет.

    ✓ Оригинал на 2 коммита, fork и my-work на 1. Расхождение есть.

  7. 07

    Ветвись от свежего upstream/main, не от своего main

    bash
    cd /home/student/work/fork-lab/my-work
    git fetch upstream            # обновить refs/remotes/upstream/main
    # switch -c <new> <start-point>: новая ветка от upstream/main, а не от local main
    git switch -c feat/add-changelog upstream/main

    Обрати внимание: ветка стартует от upstream/main, не от main. main твоего форка отстаёт на v2. upstream/main свежий.

    Сделай коммит:

    bash
    echo "# Changelog" > CHANGELOG.md
    git add . && git commit -m "add changelog"

    ✓ Ветка сделана от upstream, коммит на ней. Дальше - push в origin.

  8. 08

    Пушни ветку в свой fork, не в upstream

    bash
    git push -u origin feat/add-changelog   # -u = настроить tracking origin/feat/add-changelog

    Запомни: пушим в origin (свой fork), не в upstream (оригинал). На настоящем GitHub упсtream обычно read-only для тебя.

    ✓ Ветка в твоём форке. На GitHub отсюда открывается PR.

  9. 09

    Имитируй ещё один коммит в upstream

    Пока ты работал над веткой, в оригинале появился ещё коммит:

    bash
    cd /home/student/work/fork-lab
    git clone original.git orig-clone
    cd orig-clone
    echo 'docs added' > README.md
    git add . && git commit -m "add readme"
    git push origin main
    cd .. && rm -rf orig-clone

    ✓ Оригинал ушёл ещё на коммит. Дальше синхронизация.

  10. 10

    Синхронизируй через rebase на свежий upstream

    bash
    cd /home/student/work/fork-lab/my-work
    git fetch upstream
    git rebase upstream/main      # переписать твои коммиты поверх свежей upstream/main

    Это перепишет твой add changelog поверх свежей upstream/main (которая сейчас содержит init + v2 + readme).

    ✓ Rebase прошёл. История теперь линейная.

  11. 11

    Force-push в свой fork с lease-защитой

    После rebase SHA коммита изменился. Обычный push отказался бы. Используй force-with-lease:

    bash
    # --force-with-lease: force-push с проверкой что remote не ушёл вперёд от твоего вида
    git push --force-with-lease

    --force-with-lease - не просто --force. Он проверяет, что твой fork остался таким, каким ты его последний раз видел. Если кто-то успел запушить туда - команда отменится с ошибкой (stale info).

    На public-репо с одним owner'ом разница не заметна. На совместных ветках - спасает от затирания чужих коммитов.

    ✓ Fork синхронизирован, история линейная. Это и есть «sync fork» из терминала.

Что ты узнал

Fork - два remote: origin (твоя копия) и upstream (оригинал). Ветка создаётся от upstream/main, push'ится в origin/*, sync через fetch+rebase. Force только with-lease.

команды

  • git remote add upstream <url>добавить оригинал как upstream
  • git fetch upstreamполучить обновления оригинала
  • git switch -c feat/x upstream/mainветвиться от свежего upstream
  • git rebase upstream/mainдогнать оригинал после долгой работы
  • git push --force-with-leaseзапушить переписанную ветку безопасно

концепции

  • · fork = твой namespace на сервере, отдельный bare-репо
  • · origin твой, upstream оригинал - не путать
  • · rebase на upstream/main вместо merge для чистой истории

← предыдущая

Trunk-based: фичи под флагами в main

следующая →

git worktree: работать в двух ветках параллельно без stash

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки