Введение

«Опишите рабочий процесс с Git» — вопрос, на котором сыпется больше кандидатов, чем на любой вопросе про lifecycle. Кандидат уверенно перечисляет git commit и git push, а на вопрос «что внутри коммита» и «зачем нужен staging» замолкает.

Я провожу технические собеседования и почти всегда задаю этот вопрос. И вот что характерно: человек, который год пишет код на Kotlin, часто не может объяснить, чем git add отличается от git commit. Не потому что глупый — просто Git «просто работает» в Android Studio, и копать в него не было повода.

Пока не пришёл на собеседование. Потому что Git — это не «кнопка в студии», а система с моделью данных, и интервьюер проверяет, понимаете ли вы эту модель. В этой статье разберём её по-честному: что такое коммит, зачем нужен staging, как работают три состояния файла и какие команды реально нужны в работе.

Типичная ошибка: считать, что git commit сам забирает все изменения. Нет — коммит фиксирует только то, что вы добавили в индекс (staging area) командой git add. Всё остальное останется незакоммиченным, и вы узнаете об этом в самый неподходящий момент.

Что такое Git: снапшоты, а не дельты

Начнём с модели данных. SVN и многие старые системы хранят историю как список изменений: версия 1, потом разница к версии 2, потом разница к версии 3. Чтобы восстановить файл на шаге N, системе нужно последовательно применить все разницы.

Git работает иначе. Git — это снапшот-система: каждый коммит хранит полное состояние проекта на этот момент — дерево файлов с их содержимым. Не «что изменилось», а «как выглядел проект целиком». Именно поэтому, по официальной документации, git commit создаёт коммит, который хранит текущее содержимое индекса (то есть снапшот) вместе с сообщением и метаданными.

Из этого следует два важных следствия, которые любят проверять на собеседованиях.

Первое: история в Git — это цепочка коммитов, где каждый коммит ссылается на родителя. Второй коммит знает, что его родитель — первый, третий — что его родитель второй. Поэтому «отмотать» историю можно, просто переходя по ссылкам, а не пересчитывая дельты.

Второе: у коммита есть полные метаданные — автор и коммиттер (имя, почта, время), сообщение и ссылка на родителя. Автор — тот, кто написал изменения, коммиттер — тот, кто зафиксировал. На практике это один человек, но в командах с ревью и переписыванием истории разница видна.

Ключевая мысль

Git хранит снапшоты состояния проекта, а не разницы между версиями. Каждый коммит — это полный снимок дерева файлов плюс метаданные: автор, время, сообщение и ссылка на родительский коммит.

Три состояния файлов: working, staged, committed

Второй фундамент — модель трёх состояний. Любой файл в репозитории в любой момент находится в одном из трёх состояний:

  • modified — вы изменили файл, но Git об этом ещё «не знает» в смысле фиксации;
  • staged — вы отметили файл командой git add, он попал в индекс и будет включён в следующий коммит;
  • committed — изменения зафиксированы в коммите, и Git хранит их в репозитории.

Им соответствуют три раздела: рабочая директория (working directory), индекс (staging area) и репозиторий (repository). Весь ежедневный цикл разработчика — это движение файлов по этой цепочке: изменил → добавил в индекс → закоммитил.

Именно здесь всплывает классический провал на собеседовании: кандидат не может объяснить, зачем вообще нужен staging. Зачем не коммитить сразу всё?

Ответ: staging — это механизм контроля. Он позволяет собрать коммит из нужных кусочков: вы могли за день тронуть три файла, но в один коммит хочется положить только два, потому что третий — это черновой эксперимент, который вы потом откатите. git add file.txt — «возьми этот файл в коммит», git restore --staged file.txt — «убери из индекса, не трогая сам файл».

  • Три состояния: modified, staged, committed — и три раздела: рабочая директория, индекс, репозиторий.
  • Зачем staging: собирать коммиты из нужных изменений и не тащить черновики в историю.
  • Коммит фиксирует только staged-изменения, а не «всё подряд».

Основные команды: как выглядит рабочий день

Теперь соберём команды, которые реально используются каждый день. Не «все команды Git» — их десятки, и зубрить их не нужно. Нужны базовые, и важно понимать, что каждая делает.

git-day.sh
git status                # что изменилось и что в индексе
git add <file>            # положить файл в индекс (staging)
git commit -m "сообщение" # зафиксировать staged-изменения
git log --oneline         # история коммитов
git diff                  # незакоммиченные изменения
git pull                  # забрать изменения из remote
git push                  # отправить свои коммиты в remote

Теперь разберём пару нюансов, которые отделяют «понимаю» от «видел в студии».

git status показывает два списка: staged (изменения в индексе, попадут в коммит) и unstaged (изменения, которые в коммит не попадут). Если вы привыкли просто жать «Commit» в Android Studio — присмотритесь, студия показывает то же самое: чекбоксы — это и есть ваш выбор, что класть в индекс.

git commit -am "..." — сокращение, которое комбинирует add и commit. Важно: -a добавляет в индекс только изменения уже отслеживаемых файлов. Новый файл, который Git ещё не видел, в коммит не попадёт. Именно здесь новички теряют файлы: создали файл, сделали git commit -am, а файл «не закоммитился».

git log --oneline — короткая история. На собеседовании полезно упомянуть, что вы смотрите историю и находите нужные коммиты именно так, а не перебирая всё глазами в студии.

Частый промах кандидатов: сказать «для отката изменений я использую git reset --hard» и не упомянуть, что эта команда безвозвратно стирает незакоммиченные изменения. Для безопасного отката файла в текущем состоянии есть git restore, для отмены коммита — git revert, и только потом стоит говорить про reset.

Коммит-сообщения и гигиена истории

Отдельная тема, которая всплывает на собеседовании middle-уровня, — сообщения коммитов. Не потому что это «магическая» тема, а потому что она показывает, работал ли человек в команде.

Плохие сообщения — fix, update, changes, work, asdf. Через три месяца по такой истории невозможно понять, что менялось и зачем, а git bisect (поиск коммита, который сломал поведение) превращается в гадание.

Что ожидает услышать интервьюер:

  • сообщение отвечает на вопрос «что и зачем изменилось»;
  • мелкие логически завершённые коммиты вместо одного гигантского «итог проекта»;
  • история читается как оглавление: по git log --oneline понятно, где что искать.
  • Умею объяснить, что внутри коммита: снапшот, метаданные, родитель.
  • Могу объяснить разницу между modified, staged и committed.
  • Понимаю, зачем нужен staging и чем git add отличается от git commit.
  • Знаю базовый набор: status, add, commit, log, diff, pull, push.
  • Пишу осмысленные сообщения коммитов, а не «fix» и «update».

Что спрашивают про Git на собеседовании

Соберём, как это звучит в реальных интервью. Чаще всего вопросы такие:

  1. «Расскажите про рабочий процесс: как вы ведёте историю в проекте?»
  2. «Что такое коммит? Что внутри?»
  3. «Зачем нужен staging, почему не коммитить всё сразу?»
  4. «Чем отличается ваш ежедневный цикл от командной строки Git?»
  5. «Как откатить изменение, которое уже закоммичено?»

Обратите внимание: ни одного вопроса «назовите 20 команд». Проверяется модель данных — понимание, что Git работает со снапшотами и что история — это граф коммитов. От этого понимания уже отталкиваются вопросы про ветки, merge и rebase — но это отдельная статья.

Здесь же добавлю практический совет. Я много лет провожу собеседования и вижу: кандидаты, которые не знают базы Git, обычно не знают и других «инструментальных» тем — Gradle, отладки, работы с remote. Это сигнал не «зубрить команды», а закрыть системные пробелы: практиковаться в командной строке, читать, что делает каждая команда, вести собственные пет-проекты с чистой историей. Если это ваш случай — не нужно готовиться в одиночку через десятый гайд. Напишите в Telegram, я провожу диагностику уровня: за 30–40 минут разберём ваши пробелы и составим план роста, без обязательств.

Готовитесь к собеседованию на middle?

Git — только одна из тем, где кандидаты с опытом 1–2 года «плавают» на базовых вопросах. Полная диагностика показывает всю картину: Kotlin, Coroutines, архитектура, ответы на интервью.

Итоги

Git — это не «кнопка в Android Studio», а система со снапшот-моделью. Коммит хранит полное состояние проекта и метаданные, история — это цепочка коммитов со ссылками на родителей, а ежедневный цикл — это движение файлов через три состояния: modified, staged, committed.

Три тезиса, которые стоит унести с собой:

  • Коммит — это снапшот + метаданные. Автор, время, сообщение, ссылка на родителя. Git не хранит «разницы», он хранит состояния.
  • Staging — это контроль, а не бюрократия. git add собирает коммит из нужных изменений, git commit фиксирует ровно то, что в индексе.
  • На собеседовании проверяют модель, а не список команд. Умение объяснить, что внутри коммита и зачем три состояния, ценнее зубрёжки синтаксиса.

Если на половине пунктов чек-листа вы задумались — это нормально, базу Git реально закрыть за несколько дней практики. Но если таких «провалов» накопилось несколько тем подряд, зубрить дальше не стоит. Напишите в Telegram — разберём вашу ситуацию и составим план, как дойти до уверенного middle.