1. Основы git, основы make

Цель работы

Создать репозиторий для проекта на лабораторные работы. Репозиторий должен содержать исходный код, конфигурационный файл .clang-format, файл .gitignore и простейший Makefile. Отработать этапы создания коммита и просмотр истории репозитория.

Инструкции по выполнению лабораторной работ смотрите раздел Руководство

Подготовка к работе

Формат вывода команды git log по умолчанию не очень удобен для анализа.

Пример:

$ git log

commit 7198ea228bf5d2f4aea7824f0f0688ddab6a8e25
Merge: 6e71962 4877c36
Author: Evgeny Pimenov <evgeny-p@users.noreply.github.com>
Date:   Tue Feb 16 14:44:21 2016 +0600

Merge branch 'solver'

commit 4877c368dc49037df8decad065d374d567e7e1d9
Author: Evgeny Pimenov <evgeny-p@users.noreply.github.com>
Date:   Tue Feb 16 14:44:06 2016 +0600

Add unit tests

commit 398bdc86f674e3f0410d6a6bdc74b3953625c4df
Author: Evgeny Pimenov <evgeny-p@users.noreply.github.com>
Date:   Tue Feb 16 14:43:40 2016 +0600

Implement quadratic equation solver

commit b5ef5db8508e310f3a41adaea06459edda114568
Author: Evgeny Pimenov <evgeny-p@users.noreply.github.com>
Date:   Tue Feb 16 14:41:51 2016 +0600

Validate user input

commit d4bbead33b6d1f66169c46c189196f6c83b75e0a
Author: Evgeny Pimenov <evgeny-p@users.noreply.github.com>
Date:   Tue Feb 16 14:41:18 2016 +0600

Implement input-output functions

commit 6e71962d03e17154d72b7f3cb95ea4ba2a3d2d1c
Author: Evgeny Pimenov <evgeny-p@users.noreply.github.com>
Date:   Tue Feb 16 14:40:52 2016 +0600

Implement helloworld program

commit de2f75641cfb773f35cd434e5f7861e7195445b3
Author: Evgeny Pimenov <evgeny-p@users.noreply.github.com>
Date:   Tue Feb 16 14:39:51 2016 +0600

Initial commit

В качестве альтернативы можно запускать git log с несколькими параметрами:

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

*   7198ea2 (HEAD, main) Merge branch 'solver'
|\
| * 4877c36 (solver) Add unit tests
| * 398bdc8 Implement quadratic equation solver
| * b5ef5db Validate user input
| * d4bbead Implement input-output functions
|/
* 6e71962 Implement helloworld program
* de2f756 Initial commit

Описание используемых параметров доступно в мануале команды git log.

Для упрощения ввода команды, можно создать алиас (синоним). Для этого нужно выполнить в терминале:

git config --global alias.hist "log --oneline --decorate --graph --all"

После чего станет доступна команда git hist:

$ git hist

*   7198ea2 (HEAD, main) Merge branch 'solver'
|\
| * 4877c36 (solver) Add unit tests
| * 398bdc8 Implement quadratic equation solver
| * b5ef5db Validate user input
| * d4bbead Implement input-output functions
|/
* 6e71962 Implement helloworld program
* de2f756 Initial commit

Подробнее об алиасах: Git Aliases.

Make

Make — утилита для преобразования файлов из одной формы в другую. Чаще всего применяется для сборки приложений.

Мейкфайл состоит из правил вида:

<цель> : <зависимость> ...
        <команда>
        ...

Здесь:

  • <цель> — имя файла, который должен быть создан или обновлен в результате выполнения правила. В простейшем случае однофайлового приложения это имя исполняемого файла.

  • <зависимость> — имя входного файла, необходимого для получения целевого файла. В простейшем случае — имя файла с исходным кодом.

  • <команды> — инструкции командной оболочки. В простейшем случае — запуск компилятора.

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

Официальная документация: GNU Make.

.gitignore

В процессе работы над проектом в рабочем каталоге могут появляться файлы, которые не должны попадать в репозиторий. Например:

  • Артефакты сборки: исполняемые файлы, объектные файлы *.o.

  • Бекап-файлы используемого текстового редактора (.main.c.swp, main.c~, #main.c# и т. д.).

  • Специфичные для пользователя настройки среды разработки или специфичные для платформы проектные файлы.

Для того, чтобы такие файлы не были закоммичены случайно, а также не отображались в выводе команды git status, используется файл .gitignore. В него записываются имена и маски файлов, которые git должен игнорировать.

Официальная документация: gitignore.

Содержание коммитов

Основной принцип: один коммит включает в себя только одно изменение. Изменения в каждом коммите самодостаточны и независимы.

Нарушение этого принципа легко заметить при написании заголовка коммита. Если заголовок выглядит как «Format source code AND implement user input validation AND fix crash», значит один коммит включает в себя слишком много изменений. В данном примере изменения следует разделить на три коммита.

Это не означает, что в каждом коммите может быть изменена только одна строка кода или затронут только один файл. Например, если требуется переименовать функцию, которая используется в сотне файлов, то выполнить переименование во всех точках вызова логично в одном коммите.

Оформление коммитов

Заголовок коммита пишется на английском языке, в императиве. Начинается с заглавной буквы, точка в конце не ставится.

Неправильно: implemented request handling.

Правильно: Implement request handling

Подробнее: How to Write a Git Commit Message

Перемещение по истории коммитов

Для перемещения по истории коммитов необходимо, чтобы все изменения были закоммичены. Т.е. не должно быть файлов в состоянии modified или staged.

Один из способов перемещения по истории — использование команды git checkout.

Руководство

Предупреждение

Не следует коммитить артефакты сборки (исполняемые и объектные файлы).

Во время выполнения работы до и после команд git add, git commit следует выполнять git status и git hist и анализировать их вывод.

  1. Создайте репозиторий для ЛР, склонировав по ssh-ссылке:

  2. Добавьте в репозиторий файл .clang-format из предыдущей работы:

    wget https://csc-software-development.readthedocs.io/ru/2023/_static/.clang-format
    
  3. Реализуйте приложение «Hello, World».

  4. Напишите простейший Makefile для сборки приложения. Приложение следует компилировать с опциями -Wall -Werror. Компиляция должна проходить без ошибок.

  5. Добавьте в репозиторий файл .gitignore, настройте игнорирование файлов.

  6. Реализуйте часть функциональности приложения geometry:

    Ввод и вывод окружностей в формате WKT, проверка корректности входных данных.

Для получения дополнительной информации по реализации приложения смотри раздел Проект на лабораторные работы.

  1. При необходимости отредактируйте Makefile и .gitignore под новое приложение.

  2. Загрузите изменения на GitHub. После завершения работы назначте её на ревью своему преподавателю практики.

10. Локально отработайте перемещение по истории репозитория. Переместитесь по истории к первому коммиту. Посмотрите содержимое файлов. Вернитесь к последнему коммиту.

Пример содержания коммитов:

  • Add .clang-format

  • Implement «Hello, World» application

  • Add Makefile

  • Add .gitignore

  • Implement input and ouput of circle from stdin

Контрольные вопросы

  1. Что такое коммит?

  2. Этапы создания коммита.

  3. В каких состояниях может находиться файл в репозитории? Как происходит изменение состояния файла?

  4. Зачем нужен файл .gitignore?