Знакомство с Git
Значение для курса
Все последующие выполненные задания (лабораторные работы) должны загружаться в систему GitHub. В качестве ответа на задание необходимо прикреплять ссылку на репозиторий в GitHub.
Введение
Git - система контроля версий, которую используют разработчики ПО для:
- Отслеживания истории изменений в проекте;
- Совместной работы над одним проектом несколькими разработчиками;
- Удобной фиксации изменений в проекте.
Представьте, что вы пишете книгу. Без системы версий каждое исправление - это перезапись файла. Удалили удачную главу вчера - вернуть нельзя. Git же делает «фотографии» проекта в ключевые моменты. Каждая такая «фотография» называется коммитом. Благодаря такой системе, можно:
- Посмотреть, что/когда/кем/почему менялись те или иные файлы;
- Вернуться к любой версии проекта (к любому коммиту);
- Экспериментировать в отдельной «черновой тетради» (ветке), не испортив основной текст;
- Переносить изменения из «черновика» в основной текст (сливать ветки).
По-умолчанию, система Git - это чисто локальная система. Для того, чтобы хранить проект (репозиторий Git) в облаке и фиксировать изменения туда, существуют специальные серверы: GitHub, GitLab, BitBucket, GitVerse, GitFlic и другие. Самым популярным является GitHub, поэтому в дальнейшем курсе будет ориентация именно на него.
Настройка Git на компьютере
Для того, чтобы начать пользоваться системой Git и фиксировать изменения в GitHub, необходимо:
- Установить систему Git на компьютер (https://git-scm.com/install/);
- Пройти регистрацию в системе GitHub, после чего залогиниться в ней (https://github.com/);
- Сгенерировать SSH-ключ на компьютере, согласно инструкции Github «Generating a new SSH key» (https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent);
- Сгенерированный SSH-ключ прикрепить к GitHub аккаунту (Settings -> SSH and GPC keys -> New SSH key).
Создание репозитория в GitHub
Представим, что мы уже написали код локально на компьютере, и хотим разместить его в систему GitHub. Для этого необходимо сначала создать репозиторий на странице GitHub:
- Нажать на кнопку «New» (Рисунок 1);

Рисунок 1 – Создание нового репозитория
- В открывшемся меню:
- ввести название репозитория и его краткое описание;
- НЕ выбирать шаблоны Readme, .gitignore, license файлов;
- нажать на подтверждение создания;
После создания репозитория, пользователя перебрасывает на его страницу. Сейчас в репозитории не хранится ни одного файла.
Однако, все файлы в репозиторий нам не надо помещать. В директории, помимо кода, находятся также и артефакты сборки (.dll, .exe файлы), временные файлы, создаваемые средой разработки. Чтобы их не загружать в репозиторий, необходимо создать файл .gitignore, в котором перечислены файлы/директории, которые стоит игнорировать. Для языков программирования C++, C# рекомендуется использовать шаблон из приложения к уроку (template_gitignore.txt). Данный шаблон необходимо скопировать в корень решения и переименовать в «.gitignore».
Чтобы существующий проект на компьютере залить в репозиторий, необходимо открыть командую строку/терминал в корне решения и выполнить команды:
| № | Команда | Описание |
|---|---|---|
| 1. | git init | локально проинициализирует Git для решения |
| 2. | git add . | локально зафиксирует все файлы для коммита кроме тех, что указаны в .gitignore |
| 3. | git commit -m “first commit” | локально из зафиксированных файлов создаст коммит |
| 4. | git branch -M main | локально создаст ветку main, в которую попадёт ранее созданный коммит |
| 5. | git remote add origin «SSH-ссылка на репозиторий» | создаёт связь локального git с GitHub |
| 6. | git push -u origin main | публикует созданную ветку в GitHub |
После выполнения данных действий, в репозитории появится решение из локальной директории.
GitFlow
GitFlow - наиболее популярный подход к управлению ветками в системе Git. Основная идея заключается в разделении кодовой базы на несколько веток с разными уровнями стабильности.
Согласно данному подходу, выделяют следующие ветки:
- master (main) - ветка для релизов. Это основная ветка, которая всегда содержит стабильный, протестированный и готовый к продакшену код. В нее сливаются только проверенные изменения, которые прошли все этапы тестирования. Эта ветка должна быть «идеальной» - в ней никогда не должно быть багов или незавершенных функций;
- dev (develop) - ветка для активной разработки. Это основная рабочая ветка, куда сливаются все новые функции и исправления. Здесь может находиться экспериментальный код, незавершенные функции и временные решения. Когда наступает время релиза и решение из ветки dev тщательно протестировано, она сливается в master (main) ветку;
- feature - ветки для разработки новой функциональности. Они создаются от dev ветки (содержат все изменения из dev ветки), в которой создаются коммиты, содержащие новые функции. Их названия строятся по шаблону «feature/name-of-feature». Например: «feature/add-user-authentication», «feature/improve-search-algorithm», «feature/add-payment-gateway». Когда нужная функциональность будет разработана, ветка сливается в dev, после чего в ней будет содержаться новая функция;
- fix - ветки для исправления багов и ошибок. Они создаются от dev ветки (содержат все изменения из dev ветки), в которой создаются коммиты, содержащие исправления ошибок. Их названия строятся по шаблону «fix/name-of-fix». Например: «fix/null-reference-exception», «fix/database-connection-timeout», «fix/ui-rendering-bug».
Стоит понимать, что первое время смысла создавать ветку dev нет. Её стоит создавать тогда, когда уже появится первый рабочий прототип решения.
Пример создания веток
Во многие современные IDE встроены удобные инструменты по работе с Git. Примеры будут приводиться для редактора кода Rider.
Ранее в существующее решение был добавлен Git. Теперь при открытии решения в редакторе кода появляется возможность управлять ветками, делать коммиты и загружать изменения в GitHub.
Разберём использование инструментов Git на примере добавления README.MD файла, который содержит описание решения и примеры использования кода.
Создадим ветку «feature/add-readme-file» от текущей «main»:
- Перейдём в список веток (Рисунок 2);

Рисунок 2 – Переход к списку веток
- Нажмём на ветку «main», от которой хотим создать ветку (Рисунок 3);

Рисунок 3 – Переход к созданию ветки
- Введём название для ветки и подтвердим создание, нажав на кнопку «Create» (Рисунок 4).

Рисунок 4 – Ввод имени для ветки
Теперь добавим README файл в интересующий нас проект решения:
- Нажмём правой кнопкой мыши на нужный проект, затем перейдём по вкладкам «Add» -> «File» (Рисунок 5);

Рисунок 5 – Добавление файла
- Введём название для файла (Рисунок 6).

Рисунок 6 – Ввод названия для файла
Далее, после создания файла, его необходимо заполнить. В тексте этого файла можно выделять заголовки, вставлять фрагменты кода и т.д. Для заполнения файла наиболее оптимально использовать GPT-модели. Ниже приведён пример запроса:
Я не знаю, как писать текст в README.MD файле. Давай я тебе декларативно опишу текст, который я хочу видеть, а ты его преобразуешь в язык разметки Markdown?
Data analyze (заголовок первого уровня)
Purpose (заголовок второго уровня)
This module is designed for analyzing data from a statistical perspective:
1) determining whether the data is normally distributed;
2) identifying data that stands out from the general background.
Usage (заголовок второго уровня)
All functions declared in NormalizeChecker class.
WARNING: Class is not implemented now
Все сделанные изменения отображаются во вкладке «Commit» (Рисунок 7).

Рисунок 7 – Список изменений
Видно, что есть группы «Staged» и «Unstaged». В группе «Staged» содержатся изменения, которые попадут в будущий коммит. Те изменения, которые отображаются в группе «Unstaged», в коммит не попадут. Для того, чтобы изменения из «Unstaged» переместились в «Staged», необходимо нажать на значок плюс у нужной папки или файла (Рисунок 8).

Рисунок 8 – Фиксация изменений
После того, как нужные изменения внесены и выбраны, их необходимо зафиксировать, создав коммит. Для этого необходимо сначала ввести текст коммита, а затем нажать на кнопку «Commit and Push». Текст коммита стоит делать кратким, отражающим суть внесённых изменений (Рисунок 9).

Рисунок 9 – Создание коммита
После этого, в репозитории GitHub появится ещё одна ветка «feature/add-readme-file» (Рисунок 10).

Рисунок 10 – Ветки в GitHub после фиксации изменений
При этом, в ветке «main» файла README.MD не будет, а в ветке «feature/add-readme-file» - будет (Рисунок 11).

Рисунок 11 – Наличие файла в разных ветках
Чтобы изменения, сделанные в ветке «feature/add-readme-file» попали в основную ветку «main», необходимо создать «Pull Request» на слияние веток. Для этого необходимо:
- Перейти на вкладку «Pull requests», после чего нажать на кнопку «New pull request» (Рисунок 12);

Рисунок 12 – Создание Pull Request
- Выбрать ветки для слияния. В значении base указывается ветка, в которую сливаются изменения, а в compare - из какой ветки сливаются изменения. После выбора веток необходимо нажать на кнопку «Create pull request» (Рисунок 13);

Рисунок 13 – Выбор веток для слияния
- После создания «Pull request», перед подтверждением слияния веток, можно посмотреть сделанные изменения на вкладке «Files changed». Если внесённые изменения устраивают, то для слияния ветки необходимо нажать на кнопку «Merge pull request» (Рисунок 14);

Рисунок 14 – Слияние веток
- После слияния веток будет предложение удалить «feature/add-readme-file» ветку. Хранить её больше нет смысла, т.к. изменения из этой ветки уже попали в основную, поэтому можно безопасно удалить, нажав на кнопку «Delete branch» (Рисунок 15).

Рисунок 15 – Удаление ветки после слияния
Теперь файл «README.MD» содержится в основной ветке main.