Лекция 1. Системы контроля версий и Git
Зачем нужен контроль версий, история от SCCS до Git, централизованная и распределённая модели, устройство Git, первые команды, гигиена коммитов, ветки, слияние и конфликты, откат, Git Flow.
Первая лекция курса: откуда взялся контроль версий, чем распределённая модель Git отличается от централизованных систем и как выглядит базовый рабочий цикл в консоли — от git init до слияния веток и разрешения конфликтов. Лекция заканчивается договорённостями о ветках в команде (Git Flow).
Понятия коммит, ветка и слияние одинаковы во всех системах контроля версий, отличаются только команды. Освойте консольный Git: IDE прячет часть действий, а на работе руками делать всё равно придётся.
1. Вступление: здесь не школа
- Лектор не может долго говорить, поэтому лекции, скорее всего, будут заканчиваться раньше полутора часов.
- За студентами никто бегать не будет. В прошлом году мамы первокурсников создали «родительский комитет» и пришли в деканат жаловаться, что практик не ставит лабы; их отправили обратно. Здесь каждый сам отвечает за свои поступки.
- Около 20 % покидают университет после первого семестра: академ или отчисление. Не потому что преподаватели злые, а потому что ребята не поняли, куда попали. Программа стала заметно сильнее.
- Практики — работающие люди, не штатные сотрудники университета, платят им немного. Если не учиться самому, ни лектор, ни практики не помогут.
- Сакральных знаний на лекциях нет: всё есть в интернете и на YouTube. Лекция — один из способов получить информацию, не единственный.
- Первые два семестра нужно выжить, дальше легче.
2. Зачем нужен контроль версий
- Контролем версий пользовались все: «документ», «документ 1», «финал», «финал-финал». Пока файл один и работаете вы один, это терпимо.
- С кодом иначе: файлов много, изменения несколько раз в день. Нужно знать, где и что менялось, и уметь откатить одно изменение, сохранив остальные.
- Проблема поставлена не вчера: первая система контроля версий появилась в 1972 году.
3. История: централизованные системы
| Год | Система | Что нового |
|---|---|---|
| 1972 | SCCS, Bell Labs (Марк Рочкинд) | первая система; инструмент одиночного разработчика; наружу из Bell Labs не вышла |
| 1982 | RCS | первая общедоступная; всё ещё для одного человека |
| 1986 | CVS | клиент-серверная модель, фиксация изменений (check-in, будущий коммит) и откаты; позже в том же духе — Subversion (SVN) |
В 1972 году командной разработки, тимлидов и Agile не было: код писали «супермонстры», совмещавшие аналитика, разработчика и тестировщика, в основном на ассемблере и C.
Как работала централизованная модель. Тимлид ставит задачи, админ нарезает код на куски и раздаёт участникам. Каждый работает над своим куском, в конце дня всё сливается на сервере, конфликты разрешает админ. Так до сих пор работает часть американских корпораций.
Достоинства (думайте как начальники):
- Безопасность: разработчик видит только свой кусок, при компрометации его учётки весь проект не утечёт. Для сравнения: игры сейчас утекают целиком за неделю до релиза.
- Контроль: админ видит, кто сколько и куда закоммитил, кто работает, а кто нет.
- Одна точка администрирования.
Недостатки:
- Медленно: каждая операция идёт через сервер.
- Согласованные изменения в разных модулях (клиент и сервер) одному разработчику не видны целиком, ошибки всплывают при слиянии.
- Весь продукт контролирует один человек, который нарезает код; таких людей мало и стоят они дорого.
- Нужна сеть с толстым каналом: в 1986 и даже в 2000 году работать можно было только в офисе.
- Единая точка отказа: пожар или потоп — и сервер потерян. Пример из начала 2000-х в районе Невской Дубровки: RAID уже был, но серверная сгорела, и данные пропали.
4. Git и распределённая модель
- В 2005 году Линус Торвальдс написал Git для разработки ядра Linux: над ядром работало распределённое сообщество, и схема с одним админом ему не подходила.
- Каждый разработчик клонирует полную копию репозитория и работает в ней. Сливаться в центральный репозиторий нужно не в конце дня, а когда задача решена.
- Дальше начинаются гонки: кто первым запушил, у того проблем нет; остальные накладывают свои изменения поверх чужих и получают конфликты слияния.
- Квалификация разработчиков нужна заметно выше: в централизованной модели можно было набирать дешёвый аутсорс, здесь нужны люди, понимающие проект целиком.
- Появился GitHub, и Git стал стандартом индустрии.
Недостатки распределённой модели:
- Безопасность: у каждого полная копия. Компании заставляют подписывать бумагу об ответственности за ноутбук: не оставлять в кафе, на заправке, на заднем сиденье машины.
- Хранение: у каждого вся история, а это обычно старый проект с огромным числом коммитов.
- Закладки: в распределённой команде один человек может внести бэкдор, и без ревью и автоматических проверок он попадёт в проект. После 2022 года выяснилось, что многие open-source компоненты, которыми пользуется промышленность, содержали скрытую функциональность. Отсюда требования: обязательное ревью и пайплайн с проверками.
- Нужна культура: дисциплина ложится на команду, а не на сервер.
- Неявный минус: раньше в 8–10 вечера закрывали ноутбук и уходили домой, теперь можно коммитить в полночь с дачи.
Бинарные файлы (картинки, собранные библиотеки, исполняемые файлы) Git хранит плохо: не умеет считать разницу между версиями и кладёт файл целиком при каждом коммите. Такие файлы перечисляют в .gitignore — списке того, что не должно попадать под контроль версий.
Git — не единственная система, и в компании может использоваться другая. Но понятия коммит, ветка, merge везде одни и те же, отличаются команды и детали. Без контроля версий современной разработки нет.
5. Как Git устроен внутри
- Добавленные файлы сжимаются алгоритмом zlib (тот же, что в zip). Текст сжимается отлично, поэтому Git и заточен под текст.
- От сжатого содержимого считается хэш SHA-1, он становится уникальным идентификатором объекта.
- При создании Git считали, что длины SHA-1 хватит навсегда, как когда-то «одного мегабайта памяти хватит всем». По словам лектора, в старых проектах с огромным числом коммитов случаются коллизии, и там увеличивают длину ключа.
- Первая версия файла хранится полностью, дальше фиксируются только изменения: что добавили, что убрали. При переключении на другой коммит Git убирает из рабочей папки текущий файл и распаковывает нужную версию.
6. Первые команды
Два способа начать работу на локальной машине:
git init # новый проект с нуля, «сразу по-правильному»
git clone <url> # клонировать готовый репозиторий: настройки уже сделаны, init не нуженНа работе, скорее всего, выдадут станцию с уже установленным Git. На Windows Git ставится со своей консолью; есть графические клиенты и интеграция в IDE, но базовые команды нужно знать.
git status # состояние репозитория
git add <файл> # взять файл под контроль; можно по маске *.txt, папку или всё сразу: git add .
git commit -m "сообщение" # зафиксировать добавленные файлы в текущем состоянии
git log # история коммитов- Новый файл в
git statusпоказан как untracked: Git его не отслеживает, файл можно менять и удалять, Git не заметит. Послеgit addфайл отслеживается, но состояние ещё не зафиксировано — для этого нужен коммит. - При
git initсоздаётся одна ветка,master. В новых версиях ветка по умолчанию называетсяmain, старые репозитории просят переименовать. Ветку можно создать только от коммита, поэтому сначала нужны коммиты.
7. Гигиена коммитов
- У коммита обязательно есть сообщение, и это не набор букв: «добавил новый файл», «изменил содержимое». В корпоративной разработке — номер тикета: «задача выполнена в рамках тикета такого-то».
- Через 3–6 месяцев вы вернётесь к проекту и увидите историю из бессмысленных сообщений — придётся вспоминать, что делали.
- CI/CD-системы парсят сообщения: увидев номер тикета, подтягивают сценарий и запускают автосборку. Мусор в сообщении — сборка не запустится.
- Git персонифицирован: каждый коммит подписан именем и email, по каждому багу можно найти автора. Без этой настройки первый коммит не создастся:
git config --global user.name "Имя Фамилия"
git config --global user.email "you@company.com"Корпоративный ящик — для работы, личный — для своих проектов.
8. Ветки
Зачем: проект из пяти модулей, нужно параллельно разрабатывать два новых. Без веток пришлось бы делать последовательно. С ветками команды работают параллельно в независимых копиях, а конфликты откладываются до слияния.
git branch lesson && git checkout lesson # создать ветку и переключиться, два шага
git checkout -b lesson # то же одной командой- Сразу после создания
masterи новая ветка указывают на один и тот же коммит. - Демо: в новой ветке добавили файл и закоммитили, переключились на
master— файл исчез: Git убрал файлы ветки и распаковал последний коммитmaster. Так команды не мешают друг другу. - IDE делает
addиcommitодной кнопкой, но это два действия.
9. Слияние и конфликты
git checkout master
git merge lesson # влить ветку lesson в master- Обычно команды пишут разные файлы, и слияние проходит автоматически: в 95 % случаев auto-merge отрабатывает.
- Если два человека правили одно место одного файла, возникает merge conflict. Бояться не нужно: Git сообщает, что автоматическое слияние не отработало, и человек разрешает конфликт руками.
- В файле появляются маркеры: между
<<<<<<< HEADи=======ваш вариант, между=======и>>>>>>> lessonвходящий. Оставляете нужное, убираете маркеры. - После разрешения конфликта коммит не появляется сам: нужны
git addиgit commit. - После merge обе ветки продолжают существовать: можно работать в ветке дальше и сливать ещё раз.
- В реальности слияние в основную ветку делает тимлид, поэтому в GitHub и GitLab есть pull request / merge request: вы открываете запрос, лид проверяет, потом решаете вместе.
10. Откат
- На последний коммит указывает
HEAD. Откатиться на коммитов назад можно без хэша:git reset HEAD~N; журнал всех перемещенийHEADпоказываетgit reflog, и на его записи тоже можно откатываться. - Отменять коммиты можно, только пока они не отправлены на удалённый сервер. После push историю не переписывают: идёте к старшим, «ребята, я накосячил, помогите».
11. Бинарники: SVN против Git
Subversion спокойно хранит бинарники, и при переходе с SVN на Git по привычке заливали картинки и документацию. В Git каждый коммит с бинарником кладёт файл целиком: проект на 10 гигабайт, три коммита — три копии.
12. Как работать с ветками
- Ветки использовать обязательно. Когда все коммитят в
main, непонятно, кто что и зачем сделал. - Работайте в ветке: боитесь потерять данные — делайте хоть сто коммитов, потом один merge. В
mainостаются два коммита: начальный и коммит слияния. Основное тело продукта чистое, его можно отдавать заказчику и коллегам. - Ветка остаётся локальной, отправлять её на сервер не обязательно. Удалить:
git branch -d lesson(-D— принудительно). - После удаления ветки коммиты никуда не деваются: зная хэш, можно сделать checkout на коммит и продолжить от него. Лектор проверял, работает, но делать так не рекомендует.
13. Соглашения в команде: Git Flow
- Собрали команду — договоритесь, как вести контроль версий и называть ветки. Общепринятых схем несколько; на лекции разобран Git Flow, который покрывает около 80 % случаев.
- Основная ветка —
develop. В неё попадают только финальные сборки по версиям (v1, v2 и так далее), любые другие коммиты туда запрещены. - Ошибка в конкретной сборке: от нужного коммита создаётся ветка hotfix, там исправляется эта сборка, исправление вливается обратно.
- Фичи, патчи и баги делаются в отдельных ветках. Разработчик закончил ветку — слил её; раз в месяц всё собирают вместе и получают релиз.
- Заказчик видит чистую историю релизов и никогда не видит develop с патчами. Что происходит на вашем компьютере, никого не волнует: ветвитесь как хотите, главное донести до релиза чистую историю.
- Антипример: компания на контракте должна была выпускать продукт раз в месяц. Новички заводили ветку на каждую задачу и никогда их не сливали. В итоге «продукт 1, 2, 3, 4», и релиз раз в месяц стал невозможен.
14. Зачем поддерживать старые версии
- Выпустили пять версий, что-то падает, простой приносит убытки — нужно срочно вернуться на три версии назад. Или после второй версии нашли бэкдор.
- На практике никто не ставит последнюю версию: выкатили в декабре новую ERP, и ни один IT-директор не рискнёт местом, чтобы её поставить. Один заказчик сидит на одной версии, два других — на другой.
- Приходит заказчик с деньгами: «всё новое не надо, но в пятой версии добавили поддержку iOS, сделайте мне её в мою версию». Тогда от его версии делается ветка, и iOS добавляется туда. Это коммерческая разработка.
15. Вопрос из зала: почему не собирается
Файлы .cpp компилируются в объектные файлы, затем линкуются в исполняемый. Если старый исполняемый файл в этот момент запущен, он занят, и линкер не сможет записать новый на его место — сначала закройте программу. В IDE конфигурации debug и release собирают разные исполняемые файлы: проверьте, какую конфигурацию запускаете.
Частые ошибки
- Бессмысленное сообщение коммита. Через полгода не вспомните, что делали, а CI не найдёт номер тикета.
- Коммит без настроенных
user.nameиuser.email. Первый коммит просто не создастся. - Бинарники в репозитории. Каждый коммит хранит файл целиком; пишите такие файлы в
.gitignore. - Работа прямо в
main. История захламляется, непонятно, кто что сделал; работайте в ветке и сливайте одним merge. - Переписывание истории после push. Отменять коммиты можно только локально; после отправки — только вместе со старшими.
- Забытый коммит после разрешения конфликта. Маркеры убраны, но нужны ещё
git addиgit commit. - Считать
addиcommitодним действием. IDE делает их одной кнопкой, но это два шага.
Мини-тренажёр
- Чем клон (
git clone) отличается отgit init? - Файл показан как untracked. Что это значит и какая команда это изменит?
- Почему Git плохо хранит картинки и что с этим делать?
- Перечислите две команды, без которых не создастся первый коммит.
- После
git mergeв файле появились маркеры<<<<<<<и>>>>>>>. Что делать по шагам? - В какую ветку по Git Flow попадают только финальные сборки и где чинят ошибку конкретной сборки?
- Почему после удаления локальной ветки коммиты не пропадают?
Ответы
git cloneкопирует готовый репозиторий с уже сделанными настройками,git initсоздаёт пустой репозиторий с нуля.- Git не отслеживает файл: изменения и удаление не заметит.
git add <файл>берёт его под контроль. - Git не умеет считать разницу между версиями бинарника и кладёт файл целиком при каждом коммите; такие файлы перечисляют в
.gitignore. git config --global user.name "…"иgit config --global user.email "…".- Выбрать нужный вариант между маркерами, удалить маркеры, затем
git addиgit commit. - В
develop; ошибку чинят в ветке hotfix, созданной от коммита нужной сборки, и вливают обратно. - Ветка — только указатель на коммит; сами коммиты остаются в репозитории, и зная хэш, на них можно сделать checkout.
Шпаргалка
| Задача | Команда |
|---|---|
| Начать | git init или git clone <url> |
| Представиться | git config --global user.name "…", git config --global user.email "…" |
| Что происходит | git status, git log |
| Взять под контроль | git add <файл>, git add . |
| Зафиксировать | git commit -m "что сделано" |
| Ветка | git checkout -b lesson; удалить git branch -d lesson |
| Переключиться | git checkout master |
| Слить | git merge lesson, конфликт разрешить руками, затем add и commit |
| Откатить локально | git reset HEAD~N, история перемещений git reflog |
| Не хранить | бинарники и артефакты сборки — в .gitignore |
| Git Flow | develop только для релизов; фичи, баги, hotfix — в отдельных ветках |
Актуальная версия: https://m3105.ru/notes/instrumentalnye-sredstva-razrabotki-po/sistemy-kontrolya-versiy-i-git
Проверь себя
12 вопросов по материалу лекции. Результаты хранятся только в вашем браузере.
Двенадцать вопросов по лабораторной работе по Git: клонирование, ветки, коммиты, просмотр истории и изменений.
- 12 вопросов
- Результат виден сразу после каждого ответа
- Порядок вопросов случайный

Комментарии0
Пока никто ничего не написал.
Войдите, чтобы оставить комментарий