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
  • Уроки
  • База знаний
  • Собеседование
Cluster

← все кластеры

Удалённые репозитории и командная работа

Что делает push/pull/fetch, что такое tracking branch, чем origin отличается от upstream в fork-моделях и когда force-push допустим. Базовый блок для любой команды, где код едет дальше своего ноутбука.

6 вопросов · ~30 мин чтения

Questions

На этой странице

  1. 01В чём разница между `git fetch` и `git pull`?
  2. 02Что такое tracking branch и как работает `@{upstream}`?
  3. 03origin vs upstream в fork-моделях. Куда пушу, откуда тяну?
  4. 04Когда force-push допустим, когда катастрофа?
  5. 05git push отказывает с `rejected (non-fast-forward)`. Что произошло?
  6. 06В чём практическая разница между clone и fork?

#git-fetch-vs-pull

juniorчасто

В чём разница между `git fetch` и `git pull`?

Что отвечать

`git fetch` тащит коммиты с remote и обновляет remote-tracking ветки (например `origin/main`), но **твою локальную ветку не двигает**. `git pull` это `git fetch` + сразу попытаться объединить с твоей локальной веткой - по умолчанию через merge, что создаёт merge-коммит если main и твоя ветка разошлись. Многие команды настраивают `git config pull.rebase true` чтобы pull делал fetch + rebase вместо merge - история чище.

Что хотят услышать

Кандидат должен: - сказать что fetch безопаснее: видишь что приехало, потом решаешь merge или rebase - объяснить что `pull --rebase` ребейзит **только твои локальные коммиты поверх свежего remote**, чужие удалённые коммиты не переписываются - это распространённое заблуждение - назвать `git config --global pull.rebase true` как разумный дефолт, и `git config --global pull.ff only` как ещё более строгий вариант (только fast-forward, иначе error) - упомянуть `git pull --autostash` для случая когда есть незакоммиченные изменения

Подводные камни

  • ✗ Сказать «pull --rebase переписывает удалённые коммиты» - на самом деле только твои локальные коммиты идут поверх remote, чужие не трогаются
  • ✗ Думать что `git pull` без аргументов всегда подтягивает текущую ветку - нужен tracking branch, иначе придётся `git pull origin main`
  • ✗ Делать `git pull` поверх грязного working tree - merge упадёт, лучше stash или autostash

Follow-up

  • ? Что покажет `git log HEAD..origin/main` после fetch?
  • ? Чем `pull.ff only` отличается от `pull.rebase true`?
  • ? Как откатить неудачный `git pull`?

Глубина в базе знаний

  • git fetch
  • git pull
  • Tracking branch
tags: remote, fetch, pull

#git-tracking-branch-upstream

intermediateиногда

Что такое tracking branch и как работает `@{upstream}`?

Что отвечать

Tracking branch - связка локальной ветки с remote-веткой. Хранится в `.git/config` блоком `[branch \"feature\"] remote = origin, merge = refs/heads/feature`. Даёт `git pull`/`git push` без аргументов, `git status` начинает показывать «ahead 2, behind 1», и появляется синтаксис `@{upstream}` (короче `@{u}`) для ссылки на отслеживаемую remote-ветку: `git log @{u}..` покажет твои локальные коммиты, которых ещё нет на remote.

Что хотят услышать

Senior должен: - назвать `git push -u origin feature` (или `--set-upstream`) как способ создать tracking при первом push - сказать что `git switch -c feature origin/feature` создаёт ветку с уже настроенным tracking - объяснить `@{u}` и `@{push}` - первая указывает откуда тянем, вторая куда пушим (часто совпадают, но в triangular workflow бывают разные) - упомянуть `git branch --set-upstream-to origin/feature` для привязки уже существующей локальной ветки - назвать `git fetch --prune` чтобы удалить tracking-ветки, которых уже нет на remote (после merge PR на сервере)

Подводные камни

  • ✗ Сказать «tracking branch автоматически появляется» - не появляется, нужен `-u` при первом push
  • ✗ Думать что `git checkout feature` всегда создаст tracking - создаст только если есть `origin/feature` и нет локальной
  • ✗ Не делать `git fetch --prune` - локально копятся мёртвые `origin/old-feature` после merge PR

Follow-up

  • ? Что покажет `git branch -vv`?
  • ? Чем `@{push}` отличается от `@{upstream}`?
  • ? Как одной командой настроить tracking для уже существующей ветки?

Глубина в базе знаний

  • Tracking branch
  • git push
  • git fetch
  • upstream vs origin
tags: remote, tracking, config

#git-origin-vs-upstream-fork

intermediateиногда

origin vs upstream в fork-моделях. Куда пушу, откуда тяну?

Что отвечать

Когда форкаешь чужой репо: `origin` это **твой fork** (туда пушишь свои ветки и PR'ы), `upstream` это **родительский репо** (оттуда тянешь чужие изменения чтобы быть в синхроне). Добавляется так: `git remote add upstream <url-родителя>`. Workflow: `git fetch upstream` → `git rebase upstream/main` на своей ветке → `git push origin feature`. Это конвенция, имена `origin`/`upstream` не зарезервированы Git'ом, можно называть как угодно, но почти все используют их.

Что хотят услышать

Senior должен: - сказать что fork-модель это triangular workflow: один remote читаешь, в другой пишешь - назвать конкретный workflow: `git fetch upstream` + `git rebase upstream/main` (или merge) + push в свой origin + PR в upstream - упомянуть `git remote -v` как способ посмотреть все remotes и убедиться что push идёт куда надо - сказать что без upstream твой fork быстро устареет и PR'ы будут конфликтовать с актуальным main - назвать `gh repo sync` как удобный шорткат через GitHub CLI

Подводные камни

  • ✗ Случайно пушнуть в upstream вместо origin - обычно прав не хватит, но если ты maintainer обоих - снесёшь чужой main
  • ✗ Не настраивать upstream вовсе - твой fork отстаёт, PR'ы конфликтуют, maintainer'ы злятся
  • ✗ Перепутать `upstream` в значении remote (имя) и `upstream` в значении tracking-ветка (`@{upstream}`) - это два разных понятия с одним словом

Follow-up

  • ? Что покажет `git remote -v` в forked-репо после `git remote add upstream`?
  • ? Как одной командой синхронизировать fork с upstream через `gh`?
  • ? Чем `origin` в fork-репо отличается от `origin` в обычном clone?

Глубина в базе знаний

  • upstream vs origin
  • Fork vs clone
  • git remote
tags: remote, fork, oss

#git-force-push-when-allowed

seniorчасто

Когда force-push допустим, когда катастрофа?

Что отвечать

Допустим: на своей feature-ветке после `git rebase main` или `git commit --amend` - ты переписал свои собственные локальные коммиты и пушишь обновлённую версию. Катастрофа: на shared-ветке (main, develop, release/*), где другие разработчики ждут стабильных SHA. Force-push в main снесёт коммиты, которые попали туда между твоими push'ами, и ничего не предупредит. Минимально безопасный вариант для feature - `git push --force-with-lease`.

Что хотят услышать

Senior должен: - назвать конкретные сценарии «можно»: после rebase, amend, squash своей feature-ветки, на которую ещё никто не подписался - сказать что на main / release-ветках force-push должен быть запрещён через GitHub/GitLab branch protection - не через культуру, через техническую защиту - объяснить `--force-with-lease`: команда отказывается пушить если remote двинулся с твоего последнего fetch - защита от затирания коммитов, появившихся между твоим fetch и push - упомянуть `--force-if-includes` (Git 2.30+) как ещё более строгая проверка - учитывает не только сам ref, но и был ли он fetched в твоей текущей сессии

Подводные камни

  • ✗ Сказать «force-push это всегда плохо» - на своей feature-ветке после rebase это нормальная работа
  • ✗ Полагаться на `--force-with-lease` как абсолютную защиту - если коллега сделал fetch но не подтянул в свою локальную, lease этого не увидит
  • ✗ Force-push'нуть в main и думать что reflog на сервере спасёт - на bare-репо reflog обычно отключён

Follow-up

  • ? Чем `--force-with-lease` отличается от `--force-if-includes`?
  • ? Как настроить запрет force-push в main через GitHub branch protection?
  • ? Что произойдёт после force-push в main с CI на других ветках?

Глубина в базе знаний

  • Force push
  • git push
  • Branch protection rules
tags: remote, force-push, safety

#git-push-rejected-non-ff

intermediateчасто

git push отказывает с `rejected (non-fast-forward)`. Что произошло?

Что отвечать

Кто-то запушил в ту же ветку после твоего последнего fetch. Git защищает remote от того чтобы твой push «прыгнул» через чужие коммиты и потерял их. Лечение: `git fetch` → посмотреть что приехало через `git log HEAD..@{u}` → `git rebase @{u}` (или `git pull --rebase`) → разрулить конфликты если есть → снова `git push`. Никакого `--force` без понимания что именно переписываешь.

Что хотят услышать

Кандидат должен: - назвать причину одной фразой: «remote ушёл вперёд, ваш push не fast-forward» - дать правильный workflow: fetch → посмотреть diff → rebase или merge → push, без force как первого инстинкта - сказать что на shared-ветке предпочтительнее rebase своих коммитов поверх свежего origin (чище история), на long-lived feature с несколькими авторами - merge (чтобы не переписать чужие SHA) - упомянуть что non-fast-forward это не баг, а защита: если force'нуть слепо - снесёшь чужие коммиты

Подводные камни

  • ✗ Сразу делать `git push --force` - снесёшь то, что коллега только что запушил
  • ✗ Делать `git pull` без `--rebase` на feature-ветке - получишь merge-коммит из неоткуда в PR
  • ✗ Не посмотреть `git log HEAD..@{u}` перед merge/rebase - не поймёшь что приехало

Follow-up

  • ? Что покажет `git log HEAD..origin/main`?
  • ? Чем `git pull --rebase` лучше `git pull` для feature-ветки?
  • ? Как настроить чтобы `git push` по умолчанию пушил только текущую ветку?

Глубина в базе знаний

  • git push
  • git fetch
  • git rebase
  • Fast-forward merge
tags: remote, push, fast-forward

#git-clone-vs-fork

juniorиногда

В чём практическая разница между clone и fork?

Что отвечать

`clone` это Git-операция: создаёт локальную копию репо и настраивает `origin` на источник. Работа с правами: пушнуть в origin сможешь только если у тебя write-доступ к этому репо. `fork` это GitHub/GitLab-операция: создаёт серверную копию репо под твоим аккаунтом (с твоими правами), которую ты потом клонируешь себе. Fork нужен когда у тебя нет write в исходный репо, но ты хочешь слать туда PR'ы.

Что хотят услышать

Кандидат должен: - различить «локальная копия» (clone) и «серверная копия под другим аккаунтом» (fork) - это два разных уровня - сказать что в команде с прямым доступом в репо fork не нужен, достаточно clone + branch-per-feature - назвать fork как стандарт для OSS: maintainer не даёт write случайным контрибьюторам, контрибьютор форкает, пушит в свой fork, открывает PR - упомянуть `gh repo fork --clone` как одну команду fork+clone - сказать что fork и clone независимы: можешь форкнуть в браузере и не клонировать, и наоборот клонировать чужой репо без fork

Подводные камни

  • ✗ Делать fork когда у тебя есть write в репо - получишь два места куда пушить и запутаешься
  • ✗ Думать что fork это git fork - такой команды нет, fork только в UI/CLI хостинга
  • ✗ Клонировать fork и не настроить upstream - не сможешь подтягивать обновления из родительского репо

Follow-up

  • ? Какие remotes будут после `gh repo fork --clone <repo>`?
  • ? Что произойдёт при PR из ветки твоего fork в upstream?
  • ? Когда maintainer'у удобнее принять патч через push-доступ vs через PR с fork?

Глубина в базе знаний

  • git clone
  • Fork vs clone
  • upstream vs origin
tags: remote, clone, forkbook: github.for.next.generation.coders.epub:ch4
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.