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

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

Ветки, merge, rebase, cherry-pick

Сравнение merge и rebase, fast-forward vs no-ff vs squash, когда и зачем cherry-pick, что делает interactive rebase. Стандартный блок для собесов на любую роль, где Git больше чем «push в main».

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

Questions

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

  1. 01Чем merge отличается от rebase с точки зрения истории?
  2. 02Fast-forward vs no-ff vs squash при merge PR. Кто что хочет видеть в main?
  3. 03Когда честно нужен `git cherry-pick`? Почему он плохой default?
  4. 04Что делает interactive rebase? Какие команды доступны?
  5. 05Как Git разрешает merge-конфликт. Что такое three-way merge?
  6. 06Golden rule of rebasing - что это и почему её нарушать дорого?

#git-merge-vs-rebase-history

juniorчасто

Чем merge отличается от rebase с точки зрения истории?

Что отвечать

`merge` сохраняет историю как есть: остаются два ствола и появляется merge-коммит с двумя родителями. `rebase` берёт коммиты твоей ветки, отрезает их и наклеивает поверх target-ветки - получается линейная история, но **с новыми SHA**, потому что у коммитов поменялся родитель. Merge безопасен и не переписывает, rebase даёт чистую историю ценой переписанных коммитов.

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

Кандидат должен: - сказать что rebase переписывает SHA коммитов, merge - нет - объяснить почему линейная история удобнее для `git log`, `bisect`, и для PR-обзора, а merge-коммит «съедает» контекст и плохо читается - назвать когда merge лучше: feature-ветки которые шли долго, и в истории важно видеть «здесь параллельный поток разрабатывался» - назвать когда rebase лучше: подтянуть свежий main перед PR, синхронизировать локальную ветку без merge-коммита - упомянуть что в больших командах часто принят rebase локально + merge при слиянии PR (см. squash-merge ниже)

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

  • ✗ Сказать «rebase лучше merge всегда» - не лучше, на shared-ветке rebase ломает чужие копии
  • ✗ Думать что merge без конфликтов это всегда fast-forward - не всегда, если main продвинулся, будет three-way merge
  • ✗ Перепутать `git rebase main` (вытащить мои коммиты поверх main) и `git rebase --onto` (переставить произвольный диапазон)

Follow-up

  • ? Что произойдёт с SHA коммитов после `git rebase main` в feature-ветке?
  • ? Как откатить неудачный rebase?
  • ? Чем three-way merge отличается от fast-forward?

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

  • git merge
  • git rebase
  • Fast-forward merge
  • Стратегии merge PR (GitHub)
tags: branching, merge, rebasebook: git.merge.vs.rebase.bytebytego.pdf · github.for.next.generation.coders.epub:ch5

#git-ff-noff-squash

intermediateчасто

Fast-forward vs no-ff vs squash при merge PR. Кто что хочет видеть в main?

Что отвечать

`fast-forward` сдвигает указатель ветки вперёд без merge-коммита - история линейная, но нет следов где был PR. `--no-ff` создаёт merge-коммит даже когда возможен ff - в истории остаётся «купол» каждой фичи, удобно искать «откуда пришло». `squash` схлопывает все коммиты PR в один новый коммит на target - чистая история, но индивидуальные коммиты PR теряются вместе с reflog и blame.

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

Senior должен: - назвать trade-off: ff = чистота, теряется граница PR; no-ff = видна граница, но история шумнее; squash = одна точка на PR, но теряются авторы внутренних коммитов и review-сделки - сказать что squash хорош когда коммиты PR это «черновики» (`fix typo`, `wip`, `address review`), плох когда коммиты логически независимы и атомарны - упомянуть что GitHub/GitLab позволяют включить только один из трёх режимов через branch protection / repo settings - назвать что после squash в GitHub автор итогового коммита это тот кто нажал merge, а оригинальный автор едет в Co-authored-by

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

  • ✗ Сказать «squash это безопасный rebase» - нет, squash удаляет все промежуточные коммиты, rebase их сохраняет
  • ✗ Думать что `--no-ff` это «medium безопасный» merge - это просто запрет fast-forward, риски те же
  • ✗ Использовать squash на 30-коммитном PR с осмысленными атомарными коммитами - потеряешь всю историю

Follow-up

  • ? Что покажет `git log --graph --oneline` после squash-merge vs no-ff?
  • ? Как настроить «только squash» в GitHub branch protection?
  • ? Где будут оригинальные SHA коммитов PR после squash?

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

  • git merge
  • Стратегии merge PR (GitHub)
  • Fast-forward merge
  • Pull Request (PR)
tags: branching, merge, prbook: git.merge.vs.rebase.bytebytego.pdf

#git-cherry-pick-when-honest

intermediateиногда

Когда честно нужен `git cherry-pick`? Почему он плохой default?

Что отвечать

Честный кейс: хотфикс на main, который нужно ещё и на release-ветку, не перенося остальные коммиты feature-ветки. Cherry-pick копирует конкретный коммит как **новый** (новый SHA, тот же diff) на текущую ветку. Плохой default, потому что: дублирует коммиты в истории (потом merge может конфликтовать сам с собой), теряет контекст («почему этот коммит здесь»), и не подхватывает зависимые коммиты из той же ветки.

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

Кандидат должен: - назвать release-ветки и hotfix-портирование как главный законный кейс - сказать что cherry-pick создаёт новый коммит с другим SHA, но тем же diff - **two commits with the same change** в истории - упомянуть `git cherry-pick -x` для добавления ссылки `(cherry picked from commit <sha>)` в сообщение - помогает потом найти оригинал - предупредить про конфликт-при-merge: если потом ветку с оригиналом сливают в release - Git увидит два коммита с одним diff и может задать вопросы - назвать `git cherry-pick -m N` для cherry-pick merge-коммита (нужно указать какого родителя считать «основным»)

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

  • ✗ Использовать cherry-pick вместо merge для регулярной синхронизации веток - получишь дублированные коммиты и зависимости порвутся
  • ✗ Сделать cherry-pick без `-x` и потом не найти откуда пришёл коммит
  • ✗ Cherry-pick merge-коммита без `-m` - получишь ошибку «is a merge but no -m option was given»

Follow-up

  • ? Что добавляет флаг `-x` в сообщение коммита?
  • ? Как cherry-pick диапазон коммитов `A..B`?
  • ? Что произойдёт если cherry-pick конфликтует - команды для resolve?

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

  • git cherry-pick
  • git merge
  • git rebase
tags: branching, cherry-pick, hotfix

#git-interactive-rebase-commands

intermediateчасто

Что делает interactive rebase? Какие команды доступны?

Что отвечать

`git rebase -i <base>` открывает редактор со списком коммитов от base до HEAD и предлагает действие на каждый: `pick` (оставить как есть), `reword` (изменить сообщение), `edit` (остановиться, дать поправить и продолжить), `squash` (склеить с предыдущим, сообщения объединяются), `fixup` (как squash, но сообщение этого коммита выкидывается), `drop` (удалить), `exec <cmd>` (запустить команду после применения коммита). Переставляешь строки - меняется порядок.

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

Senior должен: - назвать `fixup` как самый частый кейс перед PR: убрать `wip` и `fix typo`-коммиты в основной коммит - объяснить `git commit --fixup=<sha>` + `git rebase -i --autosquash` как удобный workflow: коммитишь правки сразу с метаданными для будущего автосквоша - сказать что interactive rebase это переписывание истории, SHA меняются, делать только на локальных не-shared коммитах - упомянуть `git rebase -i --root` для редактирования включая самый первый коммит - назвать что при `edit` ты можешь сделать `git reset HEAD^`, раскинуть коммит на несколько и продолжить через `git rebase --continue`

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

  • ✗ Использовать `squash` когда нужен `fixup` - получишь редактор с двумя сообщениями вместо одного
  • ✗ Сделать `git rebase -i` на ветке, которую уже пушнул и кто-то её забрал - сломаешь чужие копии
  • ✗ Забыть `git rebase --continue` после `edit` - застрянешь в полу-rebase'е и `git status` покажет странное

Follow-up

  • ? Чем `git commit --fixup=<sha>` лучше ручного `edit` в rebase?
  • ? Что делает `exec` строка в todo-листе interactive rebase?
  • ? Как отменить начатый interactive rebase?

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

  • git rebase
  • Interactive rebase
  • git commit --amend
tags: branching, rebase, history

#git-three-way-merge

seniorиногда

Как Git разрешает merge-конфликт. Что такое three-way merge?

Что отвечать

Git берёт три версии одного и того же файла: твою (HEAD), их (MERGE_HEAD) и общую базу - merge-base, последний общий предок. Для каждого hunk сравнивает: если только одна сторона изменила - берёт её; если обе изменили **одинаково** - берёт; если по-разному - это конфликт, в файл пишутся маркеры `<<<<<<< HEAD ... ======= ... >>>>>>> MERGE_HEAD`. После руками-resolve делаешь `git add` и `git commit` (или `git merge --continue`).

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

Senior должен: - назвать три «версии» (ours/theirs/base) и сказать что merge-base находится через walk по графу до общего предка - объяснить разницу `--ours` и `--theirs` в `git checkout` во время конфликта - выбрать одну сторону целиком для файла - упомянуть `git mergetool` и популярные backend'ы (vimdiff, meld, VSCode) - но в проде ручной resolve часто быстрее - назвать `git config merge.conflictStyle diff3` для добавления блока `||||||| base` в маркеры - часто упрощает resolve - сказать что `rerere` (`reuse recorded resolution`) запоминает resolve и применяет автоматом при повторе того же конфликта

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

  • ✗ Сказать «merge сам разрулит всё что Git считает разрешимым» - разрулит, но если изменения по-разному в одной строке - это конфликт всегда, без эвристик
  • ✗ Перепутать ours и theirs в `git checkout --ours` во время rebase - там семантика инвертирована относительно merge (см. документацию)
  • ✗ Закоммитить файл с маркерами `<<<<<<<` внутри - попадёт в историю

Follow-up

  • ? Что произойдёт при merge без общей базы (`--allow-unrelated-histories`)?
  • ? Как `git config merge.conflictStyle diff3` меняет маркеры?
  • ? Чем `rerere` полезен в long-running feature-ветках?

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

  • git merge
  • Стратегии merge PR (GitHub)
  • Auto-merge для PR
tags: branching, merge, conflict

#git-golden-rule-rebase

seniorиногда

Golden rule of rebasing - что это и почему её нарушать дорого?

Что отвечать

Правило: **не делай rebase на коммитах, которые уже опубликованы и на которые могут опираться другие**. Rebase переписывает SHA. Если коллега уже забрал твою ветку и работает поверх неё - после твоего rebase + force-push его локальные коммиты ссылаются на «исчезнувшие» SHA, у него `git pull` будет рисовать дубли, его новые коммиты окажутся «бесхозными». Лечится синхронизированно или вообще никак.

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

Senior должен: - сформулировать правило одним предложением и объяснить **зачем** оно есть (через переписанные SHA), а не «потому что так принято» - назвать исключение: feature-ветка с одним владельцем - своя, туда rebase + force-push (лучше `--force-with-lease`) ок - сказать что `git push --force-with-lease` отказывается пушить, если remote-ветка двинулась с твоего последнего fetch - защита от затирания чужих коммитов - назвать координацию через PR-описание / Slack как обязательный шаг даже на feature-ветке с двумя соавторами - упомянуть что на main / release-ветках force-push должен быть запрещён через branch protection

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

  • ✗ Считать что `--force-with-lease` абсолютно безопасен - не абсолютно, если коллега сделал fetch но не подтянул в local - его коммиты ты не увидишь
  • ✗ Делать rebase на main и потом force-push в main - это снос истории для всей команды
  • ✗ Спорить «но история же чище» - на shared-ветке цена чистоты это пересборка чужой работы

Follow-up

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

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

  • git rebase
  • Force push
  • Branch protection rules
tags: branching, rebase, force-push
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки