Модуль 1 — Что такое Git и зачем он нужен
Модель данных Git и четыре состояния файла. ~5 минут.
Снимки, не дельты
Когда ты делаешь коммит, Git сохраняет полный снимок всего проекта на этот момент. Не diff от предыдущего коммита — целиком все файлы (с дедупликацией внутри хранилища, поэтому реально места уходит мало).
История — это лента снапшотов:
commit C → index.html app.js README.md (полный снимок) ↑ commit B → index.html app.js (полный снимок, app.js был другой) ↑ commit A → index.html (полный снимок, app.js ещё не было)
Аналогия: фотоальбом, а не дневник правок. Откатиться к любой версии — это просто «достать тот снапшот».
Четыре состояния файла
Один и тот же файл в Git может быть в одном из четырёх состояний. Понимание переходов между ними — ключ ко всему остальному.
1. Untracked — Git не знает о файле
Файл лежит в папке проекта, но никогда не был добавлен в Git. git status покажет его в красной секции «Untracked files».
Пример: создал notes.txt, ещё не делал git add.
2. Modified — Git знает, видит изменения
Файл уже когда-то закоммичен, ты его поменял, но изменения пока не в stage. git status покажет в секции «Changes not staged for commit».
Пример: отредактировал app.py, который был в прошлом коммите.
3. Staged — в индексе, готов к коммиту
Сделал git add: изменения отложены в stage (он же индекс). Это «черновик следующего коммита». В git status — секция «Changes to be committed».
Пример: git add app.py прошёл; git commit ещё нет.
4. Committed — записан в историю
После git commit снимок отправляется в историю репо. С этого момента состояние «зафиксировано» и его можно вытащить обратно когда угодно.
Жизненный цикл одного изменения:
Untracked → (git add) → Staged → (git commit) → Committed
↑
изменил файл → Modified → (git add) → ...
Локально и удалённо
Вся история Git живёт в скрытой папке .git/ внутри проекта — это локальный репозиторий. Никакой связи с интернетом для базовой работы не нужно: коммиты, ветки, история — всё локально.
Удалённый репозиторий — копия твоего репо на сервере (GitHub, GitLab, Bitbucket, свой). С ним общаются через git push (отправить локальные коммиты) и git pull (забрать чужие). Подробности — в Модуле 5.
Проверь себя
todo.md и сохранил. git add ещё не делал. В каком он состоянии?app.py был в прошлом коммите. Ты его отредактировал, сохранил, но git add не делал. В каком состоянии файл?git add app.py. Прошло успешно, git commit ещё не запускал. В каком состоянии файл сейчас?Модуль 2 — Настройка и создание репозитория
Первая конфигурация Git, git init, .gitignore. ~7 минут.
Первая настройка (один раз после установки Git)
Git нужно знать, кто делает коммиты. Это глобальные настройки — задаёшь их один раз, они применяются во всех проектах на этой машине:
git config --global user.name "Твоё Имя"
git config --global user.email "you@example.com"
Проверить, что записалось:
git config --global --list
Создание репозитория: init vs clone
Два способа начать работать с Git в проекте:
git init — новый репозиторий из существующей папки
Зайди в папку проекта (там может быть твой код или ещё ничего) и выполни:
git init
.git/ — здесь будет вся история. Файлы проекта Git не трогает.git clone — скачать существующий репозиторий
git clone <url>
.gitignore — что Git должен игнорировать
Не всё хочется хранить в репо: сборочные артефакты, кэши, секреты, виртуальные окружения. Список того, что Git должен пропустить, лежит в текстовом файле .gitignore в корне проекта. Сам файл — коммитится.
# зависимости / кэши node_modules/ __pycache__/ *.pyc # сборка dist/ build/ # секреты — никогда не коммитить .env .env.local # логи *.log # IDE .vscode/ .idea/
Один паттерн на строку. Поддерживается glob: *.log, build/**. Строки с # — комментарии. Полезный совет: добавь .gitignore в самом начале, до первого коммита — иначе мусор успеет попасть в историю.
Ctrl+Shift+G (или иконка с ветвлением в левой панели). Если репо ещё нет — увидишь кнопку Initialize Repository, она просто запускает git init. Если репо есть — увидишь панель с текущими изменениями: справа от каждого файла кнопки + (stage), ↩ (откатить).Попробуй в тренажёре
Этот терминал поддерживает базовые git-команды. В нём уже «лежат» два файла: README.md и index.html — но пока без git. Сделай по порядку:
git init— создать репоgit status— посмотри, что Git видит (там untracked файлы — мы их подложили)git add .— добавь всё в stagegit status— заметь, как файлы переехали из «Untracked» в «Changes to be committed»git commit -m "init"— зафиксируй первый снимок в историиgit log --oneline— убедись, что коммит появился
Модуль 3 — Базовый рабочий цикл: stage → commit
Главный цикл повседневной работы. ~8 минут.
Три команды, которые ты будешь печатать постоянно
git status
git add <file>
git add a.py b.py.git add .
git status.git commit -m "Добавить кнопку логина"
-m — короткое сообщение. Без него Git откроет редактор.Ctrl+Enter) → коммит. После коммита список изменений очищается.Хорошие сообщения коммитов: правило 50/72
Сообщение коммита — это записка будущему себе и коллегам. Через полгода, когда что-то сломается, ты будешь искать «когда мы это меняли и почему» через git log. Качество сообщений == качество поиска.
Правила
- Title ≤ 50 символов. Помещается в одну строчку любого UI.
- Повелительное наклонение: «Add user auth», «Fix race in pool», «Update README». Не «Added», не «Fixing».
- Смысл, а не механика: «Fix race in connection pool», не «Edit pool.go».
- Если нужна подробность — пустая строка после title, затем тело до 72 символов в строке (отсюда «50/72»).
Хорошо / плохо
✓ Хорошо:
Add login button to header Hooks up to existing /auth/login endpoint. Closes ticket #PAY-142.
✗ Плохо:
fix update file . WIP asdfasdf
Плохие сообщения превращают git log в шум. Лучше потратить 10 секунд на формулировку — это спасает часы будущего поиска.
Разложи файлы по состояниям
Перетащи каждый файл в правильное состояние. У каждого подписано, что с ним только что сделали.
Модуль 4 — Ветки
Параллельные линии работы. ~10 минут.
Что такое ветка
Ветка в Git — это подвижный указатель на коммит. И всё. Не копия файлов, не отдельная папка — просто текстовая ссылка на хэш одного коммита.
Когда ты делаешь новый коммит, ветка-указатель автоматически переезжает на этот новый коммит. Текущая ветка хранится в специальном указателе HEAD.
Аналогия: ветка = параллельная вселенная кода. Можно начать новую линию работы, экспериментировать, а потом либо слить обратно в main, либо удалить, если не получилось.
Команды
git branch
git branch feature-x
feature-x от текущего коммита. На неё не переключается — просто создаётся указатель.git switch feature-x
feature-x. Современный синоним старой команды git checkout feature-x.git switch -c feature-x
git checkout -b feature-x.git merge feature-x
feature-x в текущую. Обычный сценарий: переключился на main, потом мержишь в неё свою feature.Merge vs Rebase — концептуально
Merge
Создаёт merge-коммит с двумя родителями: твой последний коммит и последний коммит сливаемой ветки. История сохраняется как есть — видно, что было параллельно. Безопасно (не переписывает прошлое), но граф становится «лохматым».
Rebase
Переписывает коммиты ветки так, как будто они изначально росли поверх target-ветки. История получается линейной и чистой. Но коммиты пересоздаются с новыми хэшами — нельзя rebase'ить то, что уже запушено и используется другими.
В этом курсе работаем только с merge — он проще и безопаснее для начала.
Поиграй с веткой
Каждая кнопка ниже = одна git-команда. Граф перерисовывается после каждого шага. Рекомендуемый сценарий — сверху вниз, чтобы получить merge-коммит:
- git commit (на main — он сейчас активен) — ещё один коммит на main
- git branch feature — создать ветку feature (указатель)
- git switch feature — переключиться
- git commit — коммит уже на feature
- git switch main — назад на main
- git commit — коммит на main (теперь main и feature разошлись)
- git merge feature — слить
Модуль 5 — Работа с удалённым репозиторием
push, pull, fetch и зачем нужен origin/main. ~7 минут.
Привязка к удалённому репо
Сначала — один раз — указать Git, где живёт удалённая копия:
git remote add origin <url>
origin — традиционное имя для основного удалённого. URL — то, что показывает GitHub/GitLab на странице репо (HTTPS или SSH).Отправить локальные коммиты — push
git push -u origin main
-u (или --set-upstream) запоминает связь «локальная main ↔ origin/main», и дальше можно просто:git push
Забрать чужие коммиты — pull и fetch
git pull
pull = fetch + merge (или + rebase, в зависимости от настроек).git fetch
git log origin/main, и решить, что делать.Что такое origin/main
Это tracking branch — локальный кэш, как ветка main выглядела на удалённом репо при последнем fetch или pull. Может отставать от настоящего origin (пока не сделаешь fetch).
Полезно для сравнения: «что у меня локально нового по сравнению с origin/main» — git log origin/main..HEAD. Или наоборот: «что у origin есть, чего у меня нет» — git log HEAD..origin/main.
↓N ↑M: коммитов позади / впереди origin. Клик по нему — синхронизация.Сценарии — что делать?
Модуль 6 — Конфликты и их разрешение
Когда Git не может слить две ветки сам. ~7 минут.
Почему возникает конфликт
Конфликт = две стороны слияния изменили одну и ту же строку (или соседние строки) одного и того же файла. Git может слить много изменений автоматически — но если две версии правят буквально одно место, он не угадает, какую оставить. Тогда нужно решить руками.
Возникает при git merge, git rebase, git pull (потому что pull = fetch + merge), иногда при cherry-pick и stash pop.
Маркеры конфликта в файле
Когда Git не справляется, он оставляет в файле специальные маркеры:
def hello(): <<<<<<< HEAD print("Привет, мир!") ======= print("Hello, world!") >>>>>>> feature return 0
<<<<<<< HEAD— начало твоей версии (текущая ветка)=======— разделитель>>>>>>> feature— конец входящей версии (название ветки, которую ты сливаешь)
Нужно: выбрать одну версию, или собрать гибрид руками, и обязательно удалить все три маркера. Файл с маркерами — это сломанный код.
Mini merge editor
Жми на hunk — он попадёт в Result. Можно «Accept Both», тогда обе версии останутся (и почти всегда после этого нужна ручная правка).
VSCode Merge Editor — без маркеров вручную
После того, как разрешил конфликт
Маркеры удалены, код собран. Дальше:
git add <file>
git add ., если уверен.git commit
-m — Git сам подставит дефолтное сообщение «Merge branch ...», нужно только сохранить. После — merge завершён.Если решил, что не хочешь продолжать merge — git merge --abort откатит всё к состоянию до начала merge.
Готово 🎉
Курс пройден. Теперь ты умеешь:
- Объяснить модель Git: снимки, не дельты; три состояния файла
- Настраивать Git и инициализировать репозиторий (CLI и VSCode)
- Делать цикл
git add→git commitи писать хорошие сообщения - Работать с ветками:
git branch,git switch,merge - Пушить и пулить с удалённым репо через
origin - Разрешать merge-конфликты в VSCode
Что дальше
Углубление — Pro Git book: бесплатная книга на git-scm.com. Особенно полезны главы про rebase, reflog и тонкости merge-стратегий.