1 of 56

ИПР 2026 · 2 курс

Git

Базовый функционал

и принципы

Лекция 1 из 2

01

2 of 56

План лекции

02

Раздел

Результат

Модель Git

Снапшоты, объекты и граф истории

Локальная работа

Рабочий каталог, индекс, HEAD и diff

Ветки и merge

Указатели, fast-forward и конфликт

Обмен

remote, clone, fetch, pull и push

Работа в команде

Ветка задачи, review и понятные коммиты

3 of 56

Зачем нужна система контроля версий

04

Вчера программа работала

Сегодня вы добавили новую возможность, а товарищ одновременно исправил ошибку.

Нужно ответить

Что изменилось?

Как вернуть рабочую версию?

Как сохранить обе полезные правки?

project-final/

project-final2/

project-final-really/

Копии папок не описывают связи между версиями и быстро перестают помогать.

4 of 56

Что хранит система контроля версий

05

01

Состояния проекта

Какие файлы и содержимое были сохранены

02

Связи

Какая версия стала основой следующей

03

Изменения

Чем два состояния отличаются

04

Объяснения

Зачем автор сделал коммит

Git хранит данные. Смысл сообщения коммита формулирует человек.

5 of 56

Централизованная и распределённая модели

06

Модель

Пример

Практическое следствие

Централизованная

Subversion

Публикация коммита требует доступа к центральному репозиторию

Распределённая

Git, Mercurial

Коммиты, история и ветки доступны локально

Команда может выбрать один из распределенных репозиториев, главным по соглашению

6 of 56

Зачем вам нужно знать о Git

04

Для работы на курсах

На многих курсах вам требуется работать с manytask, который основан на Gitlab, который является хостингом для Git

python

advanced-python

C++

7 of 56

Git и платформы

07

Git

Работает локально

Хранит объекты и ссылки

Создаёт коммиты и ветки

GitHub / GitLab

Размещает репозитории

Добавляет права и обсуждения

Запускает проверки

Регистрация на платформах не нужна для первых экспериментов с Git.

8 of 56

Что доступно без интернета?

08

Изменить файл

Создать коммит

Посмотреть историю

Отправить коммит коллеге

?

Ответ сформулируем через устройство локального репозитория.

9 of 56

Коммит фиксирует снапшот

09

Снапшот A

Снапшот B

diff

Git сохраняет выбранное состояние проекта. Разницу между снапшотами он вычисляет при сравнении.

Сжатие и дельты оптимизируют хранение, но не меняют модель снапшотов.

10 of 56

Четыре типа объектов Git

10

Объект

Что содержит

blob

Содержимое файла; имени файла внутри нет

tree

Имена, режимы и ссылки на blobs и поддеревья

commit

Корневое дерево, родителей, автора, время и сообщение

tag

Данные аннотированной метки и ссылку на объект

Имя и путь живут в tree. Blob хранит содержимое.

11 of 56

Как коммит связан со снапшотом

11

commit

tree

tree docs/

blob README

blob guide

root tree

docs/

Коммит знает о файлах через корневое дерево; пути не записаны внутри blob.

12 of 56

Идентификатор объекта

12

type + size + content

↓

object id

​

Меняется при изменении содержимого или метаданных

Полный идентификатор может использовать SHA-1 или SHA-256

Хэш идентифицирует содержимое, но сам по себе не удостоверяет личность автора.

13 of 56

История Git — направленный ациклический граф

13

M

B

C

A

результат слияния

параллельные коммиты

общий предок

Стрелка направлена от коммита к родителю. Время создания не задаёт родство.

14 of 56

Почему одинаковые файлы не гарантируют одинаковый коммит

14

Коммит X

Коммит Y

То же дерево файлов

Родитель A

Сообщение «Fix typo»

Автор и время X

То же дерево файлов

Родитель B

Сообщение «Polish docs»

Автор и время Y

Изменение сообщения или родителя создаёт новый объект commit.

15 of 56

Рабочий каталог, индекс и HEAD

15

Рабочий каталог

working tree

Индекс

staging area

Снимок HEAD

repository

git add

git commit

редактируем

готовим следующий снимок

сохраняем историю

Один файл может одновременно иметь подготовленные и неподготовленные изменения.

16 of 56

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

16

Состояние

Смысл

Untracked

Путь ещё не входит в снимки Git

Modified

Отслеживаемый файл отличается от выбранной версии

Staged

Версия в индексе отличается от HEAD

Ignored

Неотслеживаемый путь исключён правилами игнорирования

git status объединяет информацию о нескольких сравнениях.

17 of 56

Демонстрация: создаём репозиторий

ДЕМО 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 настройки действуют только в рамках проекта

18 of 56

Первый осмысленный коммит

ДЕМО 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

Один коммит удобно посвящать одной объяснимой задаче.

19 of 56

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.

Последующее редактирование файла не обновляет индекс автоматически.

20 of 56

Что сравнивают команды diff

21

Команда

Слева

Справа

git diff

Индекс

Рабочий каталог

git diff --staged

HEAD

Индекс

git diff HEAD

HEAD

Рабочий каталог

git diff A B

Состояние A

Состояние B

Пустой git diff не означает, что изменений нет: они могут уже находиться в индексе.

21 of 56

Что делает .gitignore

22

build/

*.log

.env

Помогает

Не добавлять результаты сборки

Не показывать логи как untracked

Не коммитить локальные настройки случайно

Не делает

Не удаляет файл с диска

Не прекращает отслеживание автоматически

Не стирает прошлые коммиты

git check-ignore -v build/output.o

git rm --cached local-settings.txt

Правило влияет на обычное добавление новых путей, но не переписывает уже существующую историю.

22 of 56

Читаем историю

23

git log --oneline --decorate --graph --all

git show HEAD

git diff HEAD~1 HEAD

git log -p -- README.md

Что искать

Текущую ветку

Родителей коммита

Изменённые строки

Историю конкретного пути

HEAD~1 означает первого родителя текущего коммита.

23 of 56

Проверяем модель через cat-file

24

git cat-file -p HEAD

git cat-file -p 'HEAD^{tree}'

git cat-file -p HEAD:README.md

commit

tree

blob

24 of 56

Проверка понимания

25

Почему git diff пустой,

а git diff --staged показывает изменения?

25 of 56

Ветка — подвижная ссылка на коммит

26

A

B

C

main

Новый коммит

двигает ссылку текущей ветки

Создание ветки не копирует файлы и не создаёт новый commit.

26 of 56

HEAD обозначает текущую позицию

27

HEAD

feature-docs

commit C

Обычно HEAD указывает на ветку,

а ветка — на коммит.

git switch меняет HEAD и, когда это безопасно, обновляет индекс и рабочие файлы.

Перед переключением ветки полезно проверить git status.

27 of 56

Демонстрация: создаём ветку

ВЕТКИ

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 остаётся на предке

28 of 56

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

Изменить рабочий файл

29 of 56

Fast-forward: передвигается только ссылка

30

A

B

C

main до merge

feature-docs

git merge --ff-only feature-docs

После merge main указывает на C. Новый commit не создаётся.

30 of 56

Трёхстороннее слияние

31

M

B

C

A

общий предок

две вершины

commit с двумя родителями

Правки в одном файле не гарантируют конфликт. Git сравнивает изменения относительно общего предка.

31 of 56

Демонстрация: создаём понятный конфликт

ДЕМО 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 не знает, каким должен быть корректный общий текст.

32 of 56

Маркеры текстового конфликта

33

<<<<<<< HEAD

Hello, team

=======

Hello, student

>>>>>>> feature-greeting

текущая ветка

вливаемая ветка

Обе версии уже сохранены в коммитах. Человек выбирает корректный результат по смыслу проекта.

33 of 56

Разрешение конфликта

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, пока конфликт ещё не закоммичен.

34 of 56

Автоматический merge не гарантирует корректность

35

Ветка A

Переименовала функцию

Ветка B

Добавила вызов старого имени

в другом файле

Текст может слиться без конфликта, а программа перестанет работать.

35 of 56

Две разные задачи restore

36

Цель

Команда

Что останется

Убрать файл из следующего коммита

git restore --staged -- README.md

Правки рабочего файла

Отбросить неподготовленные правки

git restore -- README.md

Версия файла из индекса

Перед второй командой прочитайте git diff -- README.md: неподготовленные правки будут потеряны.

36 of 56

Три похожих имени в работе с remote

37

Имя

Где находится и что означает

main

Наша локальная ветка

origin/main

Локальная ссылка на последнее полученное состояние main на origin

main на origin

Ветка в другом репозитории; она могла измениться после обмена

origin — имя адреса в настройках Git

37 of 56

clone, fetch, pull и push

38

Локальный

репозиторий

Другой

репозиторий

fetch / clone

push

pull = fetch + интеграция

Незакоммиченные правки и индекс команда push не отправляет.

38 of 56

fetch обновляет знания о remote

39

main

origin/main

A

B

C

git fetch origin

Рабочий файл остаётся прежним

После fetch локальная main может отставать от origin/main.

39 of 56

pull получает и интегрирует изменения

40

git pull --ff-only

1

fetch

2

fast-forward

Если истории разошлись, --ff-only останавливается. Сначала исследуйте граф, затем выбирайте merge или rebase осознанно.

40 of 56

Два разработчика без внешнего сервера

ДЕМО 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

41 of 56

После 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 и рабочий файл.

42 of 56

Отклонённый push сообщает о расхождении

43

! [rejected] main -> main (non-fast-forward)

Что делать

Получить изменения

Посмотреть граф

Понять причину расхождения

Выбрать merge или rebase по правилам команды

Чего не делать автоматически

force push не является стандартным исправлением этой ситуации.

43 of 56

Минимальный рабочий процесс в команде

44

01

Обновить main и создать ветку задачи

02

Изменить код, проверить diff и тесты

03

Создать понятные коммиты

04

Опубликовать ветку через push -u

05

Открыть PR/MR и пройти review

06

Объединить по правилам команды

Конкретная стратегия ветвления и слияния определяется правилами проекта.

44 of 56

Pull Request и git pull решают разные задачи

45

Понятие

Где существует

Назначение

Pull Request / Merge Request

На платформе

Обсудить, проверить и одобрить изменение

git pull

В Git-клиенте

Получить и интегрировать изменения

git merge

В Git-репозитории

Объединить истории

Одобрение предложения и слияние ветки — разные действия.

45 of 56

Практика после лекции

46

1

Два коммита с объяснением содержимого каждого

2

Файл одновременно staged и modified

3

Fast-forward, затем merge-коммит

4

Намеренный конфликт и осмысленное разрешение

5

Обмен через bare-репозиторий и второй клон

Критерий: объяснить состояние working tree, index, HEAD и веток после каждого шага.

46 of 56

Вопросы для самопроверки

47

Локальная модель

Почему правка после add может не войти в commit?

​

47 of 56

Вопросы для самопроверки

47

Локальная модель

Почему правка после add может не войти в commit?

Чем ветка отличается от commit?

​

​

48 of 56

Вопросы для самопроверки

47

Локальная модель

Почему правка после add может не войти в commit?

Чем ветка отличается от commit?

Почему время не определяет родство?

​

49 of 56

Вопросы для самопроверки

47

Локальная модель

Почему правка после add может не войти в commit?

Чем ветка отличается от commit?

Почему время не определяет родство?

Когда merge обходится без нового commit?

50 of 56

Вопросы для самопроверки

47

Локальная модель

Обмен и корректность

Почему правка после add может не войти в commit?

Чем ветка отличается от commit?

Почему время не определяет родство?

Когда merge обходится без нового commit?

Что меняет fetch и чего не меняет?

​

​

​

51 of 56

Вопросы для самопроверки

47

Локальная модель

Обмен и корректность

Почему правка после add может не войти в commit?

Чем ветка отличается от commit?

Почему время не определяет родство?

Когда merge обходится без нового commit?

Что меняет fetch и чего не меняет?

Почему одинаковые файлы не дают тот же commit?

​

52 of 56

Вопросы для самопроверки

47

Локальная модель

Обмен и корректность

Почему правка после add может не войти в commit?

Чем ветка отличается от commit?

Почему время не определяет родство?

Когда merge обходится без нового commit?

Что меняет fetch и чего не меняет?

Почему одинаковые файлы не дают тот же commit?

Почему merge без конфликта требует тестов?

​

53 of 56

Вопросы для самопроверки

47

Локальная модель

Обмен и корректность

Почему правка после add может не войти в commit?

Чем ветка отличается от commit?

Почему время не определяет родство?

Когда merge обходится без нового commit?

Что меняет fetch и чего не меняет?

Почему одинаковые файлы не дают тот же commit?

Почему merge без конфликта требует тестов?

Когда коллега увидит локальный commit?

54 of 56

Модель базовой работы

48

working tree

index

commit

branch / HEAD

add

commit

Коммиты образуют граф через parent-связи

Ветки и remote-tracking ветки — подвижные ссылки

Команды меняют конкретные данные или ссылки

Проверяйте status, diff и граф перед необратимыми действиями

Следующая лекция: изменение и исследование истории, восстановление и дополнительные инструменты.

55 of 56

Приложение: карта базовых команд

СПРАВОЧНО

49

Задача

Команды

Состояние и различия

status · diff · diff --staged

История и объекты

log · show · cat-file

Подготовка и сохранение

add · commit

Ветки

branch · switch · merge

Рабочие файлы

restore · rm · mv

Обмен

clone · fetch · pull · push

56 of 56

Материалы для продолжения

СПРАВОЧНО

50

Pro Git

git-scm.com/book

Справка команд

git help COMMAND · git-scm.com/docs

Практика

git-katas

Следующая лекция

Rebase · reset · revert · reflog · bisect

Главное после занятия: открыть собственный репозиторий и проверить модель командами