ИПР 2026 · 2 курс
Git
Базовый функционал
и принципы
Лекция 1 из 2
01
План лекции
02
Раздел | Результат |
Модель Git | Снапшоты, объекты и граф истории |
Локальная работа | Рабочий каталог, индекс, HEAD и diff |
Ветки и merge | Указатели, fast-forward и конфликт |
Обмен | remote, clone, fetch, pull и push |
Работа в команде | Ветка задачи, review и понятные коммиты |
Зачем нужна система контроля версий
04
Вчера программа работала
Сегодня вы добавили новую возможность, а товарищ одновременно исправил ошибку.
Нужно ответить
Что изменилось?
Как вернуть рабочую версию?
Как сохранить обе полезные правки?
project-final/
project-final2/
project-final-really/
Копии папок не описывают связи между версиями и быстро перестают помогать.
Что хранит система контроля версий
05
01
Состояния проекта
Какие файлы и содержимое были сохранены
02
Связи
Какая версия стала основой следующей
03
Изменения
Чем два состояния отличаются
04
Объяснения
Зачем автор сделал коммит
Git хранит данные. Смысл сообщения коммита формулирует человек.
Централизованная и распределённая модели
06
Модель | Пример | Практическое следствие |
Централизованная | Subversion | Публикация коммита требует доступа к центральному репозиторию |
Распределённая | Git, Mercurial | Коммиты, история и ветки доступны локально |
Команда может выбрать один из распределенных репозиториев, главным по соглашению
Зачем вам нужно знать о Git
04
Для работы на курсах
На многих курсах вам требуется работать с manytask, который основан на Gitlab, который является хостингом для Git
python
advanced-python
C++
Git и платформы
07
Git
Работает локально
Хранит объекты и ссылки
Создаёт коммиты и ветки
GitHub / GitLab
Размещает репозитории
Добавляет права и обсуждения
Запускает проверки
Регистрация на платформах не нужна для первых экспериментов с Git.
Что доступно без интернета?
08
Изменить файл
Создать коммит
Посмотреть историю
Отправить коммит коллеге
?
Ответ сформулируем через устройство локального репозитория.
Коммит фиксирует снапшот
09
Снапшот A
Снапшот B
diff
Git сохраняет выбранное состояние проекта. Разницу между снапшотами он вычисляет при сравнении.
Сжатие и дельты оптимизируют хранение, но не меняют модель снапшотов.
Четыре типа объектов Git
10
Объект | Что содержит |
blob | Содержимое файла; имени файла внутри нет |
tree | Имена, режимы и ссылки на blobs и поддеревья |
commit | Корневое дерево, родителей, автора, время и сообщение |
tag | Данные аннотированной метки и ссылку на объект |
Имя и путь живут в tree. Blob хранит содержимое.
Как коммит связан со снапшотом
11
commit
tree
tree docs/
blob README
blob guide
root tree
docs/
Коммит знает о файлах через корневое дерево; пути не записаны внутри blob.
Идентификатор объекта
12
type + size + content
↓
object id
Меняется при изменении содержимого или метаданных
Полный идентификатор может использовать SHA-1 или SHA-256
Хэш идентифицирует содержимое, но сам по себе не удостоверяет личность автора.
История Git — направленный ациклический граф
13
M
B
C
A
результат слияния
параллельные коммиты
общий предок
Стрелка направлена от коммита к родителю. Время создания не задаёт родство.
Почему одинаковые файлы не гарантируют одинаковый коммит
14
Коммит X
Коммит Y
То же дерево файлов
Родитель A
Сообщение «Fix typo»
Автор и время X
То же дерево файлов
Родитель B
Сообщение «Polish docs»
Автор и время Y
Изменение сообщения или родителя создаёт новый объект commit.
Рабочий каталог, индекс и HEAD
15
Рабочий каталог
working tree
Индекс
staging area
Снимок HEAD
repository
git add
git commit
редактируем
готовим следующий снимок
сохраняем историю
Один файл может одновременно иметь подготовленные и неподготовленные изменения.
Состояния файлов
16
Состояние | Смысл |
Untracked | Путь ещё не входит в снимки Git |
Modified | Отслеживаемый файл отличается от выбранной версии |
Staged | Версия в индексе отличается от HEAD |
Ignored | Неотслеживаемый путь исключён правилами игнорирования |
git status объединяет информацию о нескольких сравнениях.
Демонстрация: создаём репозиторий
ДЕМО 1
17
git --version
mkdir git-lab
cd git-lab
git init -b main
git config user.name "Student"
git config user.email "student@example.com"
git config core.editor vim
Локальные настройки
Имя и email входят в метаданные коммита
Эти данные не связаны с GitHub
Без --global настройки действуют только в рамках проекта
Первый осмысленный коммит
ДЕМО 1
18
printf '# Git lab\n' > README.md
printf 'Hello\n' > greeting.txt
printf 'build/\n*.log\n.env\n' > .gitignore
git status
git add README.md greeting.txt .gitignore
git diff --staged
git commit -m "Create the learning repository"
Перед commit
Прочитать status
Выбрать файлы
Проверить diff --staged
Один коммит удобно посвящать одной объяснимой задаче.
git add запоминает содержимое в момент вызова
19
printf '\nFirst useful change.\n' >> README.md
git add README.md
printf '\nUnfinished idea.\n' >> README.md
git status --short
git diff
git diff --staged
В индексе
First useful change.
В рабочем файле
+ Unfinished idea.
Последующее редактирование файла не обновляет индекс автоматически.
Что сравнивают команды diff
21
Команда | Слева | Справа |
git diff | Индекс | Рабочий каталог |
git diff --staged | HEAD | Индекс |
git diff HEAD | HEAD | Рабочий каталог |
git diff A B | Состояние A | Состояние B |
Пустой git diff не означает, что изменений нет: они могут уже находиться в индексе.
Что делает .gitignore
22
build/
*.log
.env
Помогает
Не добавлять результаты сборки
Не показывать логи как untracked
Не коммитить локальные настройки случайно
Не делает
Не удаляет файл с диска
Не прекращает отслеживание автоматически
Не стирает прошлые коммиты
git check-ignore -v build/output.o
git rm --cached local-settings.txt
Правило влияет на обычное добавление новых путей, но не переписывает уже существующую историю.
Читаем историю
23
git log --oneline --decorate --graph --all
git show HEAD
git diff HEAD~1 HEAD
git log -p -- README.md
Что искать
Текущую ветку
Родителей коммита
Изменённые строки
Историю конкретного пути
HEAD~1 означает первого родителя текущего коммита.
Проверяем модель через cat-file
24
git cat-file -p HEAD
git cat-file -p 'HEAD^{tree}'
git cat-file -p HEAD:README.md
commit
tree
blob
Проверка понимания
25
Почему git diff пустой,
а git diff --staged показывает изменения?
Ветка — подвижная ссылка на коммит
26
A
B
C
main
Новый коммит
двигает ссылку текущей ветки
Создание ветки не копирует файлы и не создаёт новый commit.
HEAD обозначает текущую позицию
27
HEAD
feature-docs
commit C
Обычно HEAD указывает на ветку,
а ветка — на коммит.
git switch меняет HEAD и, когда это безопасно, обновляет индекс и рабочие файлы.
Перед переключением ветки полезно проверить git status.
Демонстрация: создаём ветку
ВЕТКИ
28
git branch
git switch -c feature-docs
mkdir docs
printf 'Use git status before committing.\n' > docs/guide.md
git add docs/guide.md
git commit -m "Add a short contribution guide"
git switch main
git log --oneline --decorate --graph --all
После switch main
docs/guide.md отсутствует
feature-docs указывает на новый commit
main остаётся на предке
switch и restore разделяют две задачи checkout
29
Старая форма | Специализированная команда | Задача |
git checkout main | git switch main | Переключить ветку |
git checkout -b feature | git switch -c feature | Создать ветку и перейти |
git checkout -- file.txt | git restore -- file.txt | Изменить рабочий файл |
Fast-forward: передвигается только ссылка
30
A
B
C
main до merge
feature-docs
git merge --ff-only feature-docs
После merge main указывает на C. Новый commit не создаётся.
Трёхстороннее слияние
31
M
B
C
A
общий предок
две вершины
commit с двумя родителями
Правки в одном файле не гарантируют конфликт. Git сравнивает изменения относительно общего предка.
Демонстрация: создаём понятный конфликт
ДЕМО 2
32
git switch -c feature-greeting
printf 'Hello, student\n' > greeting.txt
git add greeting.txt
git commit -m "Address the student"
git switch main
printf 'Hello, team\n' > greeting.txt
git add greeting.txt
git commit -m "Address the team"
git merge feature-greeting
Ожидаемый результат
merge остановится
Git не знает, каким должен быть корректный общий текст.
Маркеры текстового конфликта
33
<<<<<<< HEAD
Hello, team
=======
Hello, student
>>>>>>> feature-greeting
текущая ветка
вливаемая ветка
Обе версии уже сохранены в коммитах. Человек выбирает корректный результат по смыслу проекта.
Разрешение конфликта
34
printf 'Hello, students and team\n' > greeting.txt
git add greeting.txt
git diff --staged
git commit -m "Merge the two greetings"
git log --oneline --decorate --graph --all
git cat-file -p HEAD
Проверить
В файле нет маркеров
Результат имеет смысл
HEAD содержит два parent
Тесты проходят
git merge --abort
--abort используют вместо завершения merge, пока конфликт ещё не закоммичен.
Автоматический merge не гарантирует корректность
35
Ветка A
Переименовала функцию
Ветка B
Добавила вызов старого имени
в другом файле
Текст может слиться без конфликта, а программа перестанет работать.
Две разные задачи restore
36
Цель | Команда | Что останется |
Убрать файл из следующего коммита | git restore --staged -- README.md | Правки рабочего файла |
Отбросить неподготовленные правки | git restore -- README.md | Версия файла из индекса |
Перед второй командой прочитайте git diff -- README.md: неподготовленные правки будут потеряны.
Три похожих имени в работе с remote
37
Имя | Где находится и что означает |
main | Наша локальная ветка |
origin/main | Локальная ссылка на последнее полученное состояние main на origin |
main на origin | Ветка в другом репозитории; она могла измениться после обмена |
origin — имя адреса в настройках Git
clone, fetch, pull и push
38
Локальный
репозиторий
Другой
репозиторий
fetch / clone
push
pull = fetch + интеграция
Незакоммиченные правки и индекс команда push не отправляет.
fetch обновляет знания о remote
39
main
origin/main
A
B
C
git fetch origin
Рабочий файл остаётся прежним
После fetch локальная main может отставать от origin/main.
pull получает и интегрирует изменения
40
git pull --ff-only
1
fetch
2
fast-forward
Если истории разошлись, --ff-only останавливается. Сначала исследуйте граф, затем выбирайте merge или rebase осознанно.
Два разработчика без внешнего сервера
ДЕМО 3 · ЧАСТЬ 1
41
git init --bare -b main ../git-remote.git
git remote add origin ../git-remote.git
git remote -v
git push -u origin main
git clone ../git-remote.git ../git-colleague
cd ../git-colleague
git config user.name "Colleague"
git config user.email "colleague@example.com"
bare-репозиторий
Хранит данные Git без обычного рабочего каталога и играет роль точки обмена.
-u настраивает upstream
После fetch рабочий файл ещё старый
ДЕМО 3 · ЧАСТЬ 2
42
printf '\nA note from a colleague.\n' >> README.md
git add README.md
git commit -m "Add a colleague note"
git push origin main
cd ../git-lab
git fetch origin
git log --oneline --decorate --graph --all
cat README.md
git diff main origin/main
git pull --ff-only
cat README.md
Пауза после fetch
main не сдвинулась
origin/main сдвинулась
README ещё старый
После pull --ff-only обновятся main и рабочий файл.
Отклонённый push сообщает о расхождении
43
! [rejected] main -> main (non-fast-forward)
Что делать
Получить изменения
Посмотреть граф
Понять причину расхождения
Выбрать merge или rebase по правилам команды
Чего не делать автоматически
force push не является стандартным исправлением этой ситуации.
Минимальный рабочий процесс в команде
44
01
Обновить main и создать ветку задачи
02
Изменить код, проверить diff и тесты
03
Создать понятные коммиты
04
Опубликовать ветку через push -u
05
Открыть PR/MR и пройти review
06
Объединить по правилам команды
Конкретная стратегия ветвления и слияния определяется правилами проекта.
Pull Request и git pull решают разные задачи
45
Понятие | Где существует | Назначение |
Pull Request / Merge Request | На платформе | Обсудить, проверить и одобрить изменение |
git pull | В Git-клиенте | Получить и интегрировать изменения |
git merge | В Git-репозитории | Объединить истории |
Одобрение предложения и слияние ветки — разные действия.
Практика после лекции
46
1
Два коммита с объяснением содержимого каждого
2
Файл одновременно staged и modified
3
Fast-forward, затем merge-коммит
4
Намеренный конфликт и осмысленное разрешение
5
Обмен через bare-репозиторий и второй клон
Критерий: объяснить состояние working tree, index, HEAD и веток после каждого шага.
Вопросы для самопроверки
47
Локальная модель
Почему правка после add может не войти в commit?
Вопросы для самопроверки
47
Локальная модель
Почему правка после add может не войти в commit?
Чем ветка отличается от commit?
Вопросы для самопроверки
47
Локальная модель
Почему правка после add может не войти в commit?
Чем ветка отличается от commit?
Почему время не определяет родство?
Вопросы для самопроверки
47
Локальная модель
Почему правка после add может не войти в commit?
Чем ветка отличается от commit?
Почему время не определяет родство?
Когда merge обходится без нового commit?
Вопросы для самопроверки
47
Локальная модель
Обмен и корректность
Почему правка после add может не войти в commit?
Чем ветка отличается от commit?
Почему время не определяет родство?
Когда merge обходится без нового commit?
Что меняет fetch и чего не меняет?
Вопросы для самопроверки
47
Локальная модель
Обмен и корректность
Почему правка после add может не войти в commit?
Чем ветка отличается от commit?
Почему время не определяет родство?
Когда merge обходится без нового commit?
Что меняет fetch и чего не меняет?
Почему одинаковые файлы не дают тот же commit?
Вопросы для самопроверки
47
Локальная модель
Обмен и корректность
Почему правка после add может не войти в commit?
Чем ветка отличается от commit?
Почему время не определяет родство?
Когда merge обходится без нового commit?
Что меняет fetch и чего не меняет?
Почему одинаковые файлы не дают тот же commit?
Почему merge без конфликта требует тестов?
Вопросы для самопроверки
47
Локальная модель
Обмен и корректность
Почему правка после add может не войти в commit?
Чем ветка отличается от commit?
Почему время не определяет родство?
Когда merge обходится без нового commit?
Что меняет fetch и чего не меняет?
Почему одинаковые файлы не дают тот же commit?
Почему merge без конфликта требует тестов?
Когда коллега увидит локальный commit?
Модель базовой работы
48
working tree
index
commit
branch / HEAD
add
commit
Коммиты образуют граф через parent-связи
Ветки и remote-tracking ветки — подвижные ссылки
Команды меняют конкретные данные или ссылки
Проверяйте status, diff и граф перед необратимыми действиями
Следующая лекция: изменение и исследование истории, восстановление и дополнительные инструменты.
Приложение: карта базовых команд
СПРАВОЧНО
49
Задача | Команды |
Состояние и различия | status · diff · diff --staged |
История и объекты | log · show · cat-file |
Подготовка и сохранение | add · commit |
Ветки | branch · switch · merge |
Рабочие файлы | restore · rm · mv |
Обмен | clone · fetch · pull · push |
Материалы для продолжения
СПРАВОЧНО
50
Pro Git
git-scm.com/book
Справка команд
git help COMMAND · git-scm.com/docs
Практика
git-katas
Следующая лекция
Rebase · reset · revert · reflog · bisect
Главное после занятия: открыть собственный репозиторий и проверить модель командами