Контроль версий с Git
Git — распределённая система контроля версий: каждый клон несёт полную историю, а не тонкую копию центрального сервера. Это и сила, и источник путаницы. Работа с Git — это работа с тремя областями (рабочее дерево, индекс, история) и набором указателей (HEAD, ветки, теги), которые двигаются по графу коммитов. Почти каждая «магическая» ошибка новичка — это неверная модель того, где сейчас находятся эти указатели.
Ключевая идея, которую Git отделяет от «сохранил файл»: коммит фиксирует снимок индекса (staging area), а не текущее содержимое файла на диске. Между «я поменял файл» и «изменение попало в коммит» стоит явный шаг git add. Ветка — это не «копия проекта», а подвижный указатель на коммит. HEAD — указатель на то, где вы сейчас стоите. Понимание этих указателей превращает пугающие ситуации (detached HEAD, конфликт слияния, «пропавший» коммит) в предсказуемые. Полная карта — в слоях ниже.
Карта темы
- Основы Git и три области — распределённая модель, рабочее дерево / индекс / история,
HEAD, повседневные команды. - Индекс и коммиты — что делает
git add, почему коммит фиксирует снимок индекса,-aи его ловушка с новыми файлами. - Просмотр истории —
git log,git show,git diff,git blame; чтение графа коммитов. - Ветки — ветка как указатель,
HEAD, detached HEAD и как из него выйти без потери работы. - Слияние и конфликты — fast-forward vs merge-коммит, как возникает конфликт и как его разрешить.
- Синхронизация с remote —
fetchvspullvspush, tracking-ветки, почемуpull— этоfetch+merge. - Stash — как отложить незакоммиченную работу, стек stash, что НЕ попадает в stash по умолчанию.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
| Считать, что коммит берёт текущий файл с диска | Коммит фиксирует снимок индекса; правки после git add не попадут, пока не сделать add снова |
git commit -a для нового файла | -a добавляет только уже отслеживаемые файлы; новый (untracked) файл в коммит не попадёт |
Коммитить с оставленными маркерами <<<<<<< | В историю уедет неразрешённый конфликт — код не соберётся |
| Работать и коммитить в detached HEAD | Коммиты не привязаны к ветке; переключились — и они «пропали» (доступны только через reflog) |
Считать git pull безопасным «обновлением» | pull = fetch + merge; может создать неожиданный merge-коммит или конфликт |
Удалить ветку с несмёрженной работой (git branch -D) | Коммиты ветки остаются только в reflog и будут собраны GC |
Думать, что git stash сохраняет всё | Untracked и игнорируемые файлы по умолчанию НЕ попадают в stash |
Путать git checkout -- file с «отменить» | Команда затирает несохранённые правки в рабочем дереве безвозвратно |
Значение для собеседований
Git спрашивают почти на любом инженерном интервью — но проверяют не знание команд, а модель состояния репозитория. Кандидат, который объясняет git commit через «сохраняет снимок индекса, на который указывает ветка», сразу выделяется на фоне «ну, сохраняет изменения».
Что обычно проверяют:
- Три области — рабочее дерево, индекс (staging), история — и как
add/commitдвигают данные между ними. - Ветка = указатель на коммит; что такое
HEADи detached HEAD. - Разница
git fetchиgit pull(и почемуpullможет удивить merge-коммитом). - Как возникает конфликт слияния и последовательность его разрешения.
- Что делает
git stashи что в него не попадает. - fast-forward vs merge-коммит.
Типичный неверный ответ: «git pull просто скачивает последнюю версию». Это открывает разговор о том, что pull сливает удалённую ветку в вашу локальную, а значит может создать merge-коммит или конфликт — и что git fetch + осознанный merge/rebase часто предпочтительнее.