Контроль версий: зачем он нужен и базовые понятия Git

Цели урока
  • Объяснить, что такое контроль версий и какие проблемы он решает
  • Определить Repository, Working Directory, Staging Area и Commit
  • Описать путь изменения — от редактирования через Staging до Commit
  • Установить и настроить Git с именем и email

Что мы изучим?

  • Что такое контроль версий (Version Control) и почему им пользуется каждый разработчик.
  • Что такое Git.
  • Три области: Working Directory, Staging Area, Repository.
  • Что такое Commit.
  • Первоначальную настройку Git.

Зачем это нужно?

Знакома такая папка?

project_final.py
project_final_v2.py
project_final_v2_WORKS.py
project_final_v3_dont_touch.py
project_final_v3_fixed_REALLY_FINAL.py

Проблемы:

  • Какая версия работает? Что именно изменилось между v2 и v3?
  • «Я что-то сломал, а вчера всё работало!» Как вернуться к вчерашнему состоянию?
  • Командная работа: два человека отредактировали один и тот же файл. Как объединить изменения, не перезаписав друг друга?
  • Резервная копия: ноутбук украли. Проект потерян?

Контроль версий решает всё это. В каждой софтверной компании мира каждая строка кода управляется с его помощью. Без Git невозможно работать в команде разработки, и на собеседовании ожидают, что вы его знаете.

Объяснение с основ

Что такое контроль версий?

Контроль версий (Version Control) — система, которая записывает историю файлов: каждое изменение, когда оно сделано, кем и зачем. Можно вернуться в любую точку в прошлом, сравнить версии и объединить работу нескольких людей.

Что такое Git?

Git — самая распространённая система контроля версий в мире, с огромным отрывом. Она:

  • Локальная — вся история хранится на вашем компьютере, в скрытой папке .git. Работает даже без интернета.
  • Распределённая — у каждого разработчика есть полная копия всей истории.
  • Быстрая и бесплатная, изначально написана Линусом Торвальдсом, создателем Linux.

Git ≠ GitHub! Git — это инструмент, который работает на вашем компьютере. GitHub — это сайт, который хранит копию вашего репозитория в облаке и добавляет инструменты для совместной и командной работы. Мы познакомимся с ним в третьем уроке.

Repository

Repository (репозиторий, сокращённо Repo) = проект, который отслеживает Git: папка с файлами плюс скрытая папка .git, где хранится вся история.

Commit — снимок

Commit = сохранённый снимок проекта в определённый момент, у которого есть:

  • Сообщение, объясняющее, что изменилось и зачем.
  • Автор (имя и email) и время.
  • Уникальный идентификатор (Hash), например a3f9c21.
  • Ссылка на предыдущий Commit — так образуется цепочка истории.
(a3f9c21) ◄── (7b2e004) ◄── (e91d5aa)   ← HEAD (latest)
"Initial      "Add price     "Fix VAT
 project"      calculator"    rounding"
Аналогия: точки сохранения в игре

Commit = точка сохранения в компьютерной игре. Перед битвой с боссом вы сохраняетесь. Если проиграли — возвращаетесь к этой точке. Разница: в Git каждая точка сохранения остаётся навсегда, с описанием, и можно вернуться к любой из них или сравнить их.

Три области

Это самое важное понятие урока. Каждый файл проекта находится в одной из трёх «областей»:

 Working Directory        Staging Area            Repository (.git)
 (the files you edit)     (ready for the next     (committed history)
                           commit)
       │                        │                        │
       │──── git add ──────────►│                        │
       │                        │──── git commit ───────►│
       │◄──────────────────── (checkout / restore) ──────│
ОбластьЧто этоКак туда попасть
Working DirectoryПапка, в которой вы работаете: файлы в том виде, в каком они сейчас на дискеПросто редактируете файлы
Staging Area (её также называют Index)«Область подготовки»: изменения, которые вы выбрали для следующего Commitgit add
RepositoryСохранённая история: все Commitgit commit

Зачем нужен Staging? Потому что иногда вы изменили 5 файлов, но только 3 из них относятся к одному логическому изменению («исправление бага в калькуляторе»). Staging позволяет выбрать точно, что войдёт в каждый Commit, чтобы каждый Commit был одной логической единицей.

Аналогия: групповая фотография

Working Directory = все люди на мероприятии. Staging Area = люди, которых вы пригласили встать перед камерой («давай, ты, в кадр»). Commit = нажатие кнопки: фото сохраняется в альбоме (Repository) навсегда. Кто не встал перед камерой, того на фото нет, даже если он на мероприятии.

Состояния файлов

СостояниеЗначение
UntrackedНовый файл, который Git ещё не отслеживает
ModifiedИзвестный файл, который изменился с последнего Commit, но ещё не в Staging
StagedИзменение в Staging, готово к Commit
Committed (Unmodified)Идентичен последнему Commit, «чистый»

Синтаксис

Установка: Git был установлен в первый день курса. Проверьте: git --version.

Однократная настройка (один раз на компьютер). Git записывает имя и email в каждый Commit:

git config --global user.name "Dana Cohen"
git config --global user.email "dana@example.com"
git config --global init.defaultBranch main
git config --global core.editor "code --wait"
КомандаЗначение
user.name / user.emailКто написал Commit. В уроке 3 — тот же email, что и в аккаунте GitHub.
init.defaultBranch mainГлавная ветка будет называться main (современное соглашение).
core.editor "code --wait"Если Git нужно открыть редактор, он откроет VS Code.
--globalНастройка действует для всех проектов на компьютере.

Проверка:

git config --global --list

Первый пример кода

Посмотрим на идею «трёх областей» в командах. В следующем уроке подробно разберём каждую.

mkdir ~\dev\kodkod6\git-demo
cd ~\dev\kodkod6\git-demo
git init

Вывод:

Initialized empty Git repository in C:/Users/dana/dev/kodkod6/git-demo/.git/

Теперь есть репозиторий. Создана скрытая папка .git. Её можно увидеть через ls -Force (PowerShell) или ls -a (Bash).

Разбор кода построчно

СтрокаОбъяснение
mkdir ...git-demoОбычная папка для проекта.
cd ...git-demoВойти в неё. Все команды Git действуют на репозиторий текущей папки.
git initinitialize: превращает папку в репозиторий и создаёт внутри неё .git.
.git/«Мозг» репозитория: все Commit, история и настройки. Не трогайте её вручную. Если её удалить, удалится вся история (сами файлы останутся).

Ещё один пример

Путь одного изменения через три области, с git status после каждого шага (все детали — в следующем уроке):

New-Item hello.py
git status
git add hello.py
git status
git commit -m "Add hello.py"
git status

Вывод (сокращённо):

Untracked files:
        hello.py

Changes to be committed:
        new file:   hello.py

[main (root-commit) 3c1f2a9] Add hello.py
 1 file changed, 0 insertions(+), 0 deletions(-)

nothing to commit, working tree clean
ШагСостояние hello.pyОбласть
После New-ItemUntrackedТолько Working Directory
После git addStagedStaging Area
После git commitCommitted, и «working tree clean»Repository

Типичная ошибка

Ошибка 1: git init не в той папке, например в домашней папке (C:\Users\dana) или внутри папки, которая уже находится внутри другого репозитория. Тогда Git отслеживает все файлы на компьютере, или создаются запутанные вложенные репозитории.

Всегда: cd в папку проекта, pwd, чтобы убедиться, и только потом git init. А если ошиблись — удалите скрытую папку .git, созданную по ошибке (только её!).

Ошибка 2: «Я сделал git add, значит, сохранено». Нет! add только подготавливает. В историю сохраняет только commit. А изменение, сделанное после add, не войдёт, пока вы снова не сделаете add.

Ошибка 3: думать, что Git делает резервную копию в облако. Git локален. Если ноутбук потерян, репозиторий потерян вместе с ним — если только вы не сделали push на GitHub (урок 3).

Ошибка 4: не настроить user.name / user.email.

Author identity unknown
*** Please tell me who you are.

Git отказывается делать Commit, не зная, кто автор. Выполните команды config из примера выше.

Практика

Упражнения опираются только на то, что пройдено в этом уроке и в предыдущих. Сначала попробуйте сами, и только потом открывайте решение.

Упражнение 1: Зачем нужен контроль версий?

В папке Дани такие файлы:

project_final.py
project_final_v2.py
project_final_v2_WORKS.py
project_final_v3_dont_touch.py

Назовите три проблемы этого метода и как Git решает каждую.

Показать решение
ПроблемаКак Git её решает
Непонятно, чем отличаются файлы и что изменилось в каждомКаждый Commit сохраняет точно, что изменилось, с сообщением, объясняющим почему
Нельзя узнать, какая версия действительно последняя рабочаяЕсть одна упорядоченная история, и HEAD указывает на текущее состояние
Когда работают несколько человек, каждый добавляет «ещё одну версию»Все работают с одним репозиторием, и Git умеет объединять изменения

Упражнение 2: Три области

Для каждого действия — в какой области находится изменение после него: Working Directory, Staging Area или Repository?

  1. Вы отредактировали calculator.py и сохранили его.
  2. Вы выполнили git add calculator.py.
  3. Вы выполнили git commit -m "Add subtract".
Показать решение
  1. Working Directory — изменение существует только в файле на диске.
  2. Staging Area — изменение отмечено как часть следующего Commit.
  3. Repository — изменение сохранено как снимок в истории.

Упражнение 3: Первая настройка

Напишите команды, которые задают для Git имя Dana Cohen и email dana@example.com, а затем создают новый репозиторий в текущей папке. Зачем Git нужны имя и email?

Показать решение
git config --global user.name "Dana Cohen"
git config --global user.email "dana@example.com"
git init

Git записывает в каждый Commit, кто его сделал. Без имени и email Git не согласится сделать Commit. --global сохраняет настройку один раз для всех репозиториев на компьютере.

Упражнение 4: Цепочка Commit

(a3f9c21) <── (7b2e004) <── (e91d5aa)  <- HEAD
"Initial      "Add price     "Fix VAT
 project"      calculator"    rounding"
  1. Что такое каждый из идентификаторов a3f9c21, 7b2e004, e91d5aa?
  2. На что указывает HEAD?
  3. Почему каждый Commit «указывает» на предыдущий?
Показать решение
  1. Это идентификаторы Commit — каждый Commit получает уникальный идентификатор (здесь сокращённый).
  2. HEAD указывает на текущий Commit — e91d5aa, «Fix VAT rounding». В этом состоянии файлы находятся сейчас.
  3. Так образуется история: от каждого Commit можно вернуться назад, увидеть, что было до него, и вернуться в любую точку в прошлом.

Упражнение 5: Зачем нужна Staging Area?

Сегодня вы изменили в проекте три вещи: исправили баг в калькуляторе, улучшили README и добавили временный тестовый файл, который не хотите сохранять. Как здесь помогает Staging Area?

Показать решение

Staging Area позволяет выбрать, что войдёт в каждый Commit:

  1. git add calculator.py → Commit: «Fix rounding bug in calculator».
  2. git add README.md → Commit: «Improve README».
  3. Временный тестовый файл вообще не добавляется.

Так каждый Commit — это одно логическое изменение с понятным сообщением, а не смесь всего, чего вы касались за день.

Итоги

  • Контроль версий записывает каждое изменение и позволяет возвращаться назад, сравнивать и работать в команде. Git — инструмент. GitHub — сайт, который хранит его в облаке.
  • Repository = проект + скрытая папка .git со всей историей.
  • Commit = снимок с сообщением, автором, временем и идентификатором (Hash).
  • Три области: Working Directory → (git add) → Staging Area → (git commit) → Repository.
  • Однократная настройка: git config --global user.name / user.email.

Официальная документация