Команда git commit делает для проекта снимок текущего состояния изменений, которые были добавлены в раздел проиндексированных файлов. Такие зафиксированные снимки состояния можно рассматривать как «безопасные» версии проекта — Git не будет их менять, пока вы явным образом не попросите об этом. Перед выполнением команды git commit необходимо использовать команду git add, чтобы добавить («проиндексировать») в проект изменения, которые будут сохранены в коммите. Эти две команды, git commit и git add, используются чаще всего.

Коммит в Git и коммит в SVN

Несмотря на одинаковое название, команда git commit не имеет ничего общего с командой svn commit. Этот общеупотребительный термин может запутать новичков в Git, имеющих опыт работы с SVN, поэтому важно подчеркнуть разницу. Разница между git commit и svn commit — это разница между моделью централизованного приложения (SVN) и моделью распределенного приложения (Git). В SVN при выполнении коммита изменения передаются из локального клиента SVN в удаленный централизованный общий репозиторий SVN. В Git репозитории распределены, коммиты снимков состояния выполняются в локальный репозиторий, и для этого совершенно не нужно взаимодействовать с другими репозиториями Git. Позже коммиты Git можно будет передать в произвольный удаленный репозиторий.

Порядок действий

Не вдаваясь в подробности, Git можно рассматривать как утилиту управления временной шкалой. Коммиты — основные конструктивные элементы временной шкалы проекта Git. Их можно рассматривать как снимки состояния или контрольные точки на временной шкале проекта Git. Коммиты создаются с помощью команды git commit, которая делает снимок состояния проекта на данный момент времени. Коммиты снимков состояния Git всегда выполняются в локальный репозиторий. В этом и заключается фундаментальное отличие от SVN, где коммит рабочей копии выполняется в центральный репозиторий. Git же, напротив, не принуждает вас взаимодействовать с центральным репозиторием до тех пор, пока вы не будете к этому готовы. Как раздел проиндексированных файлов является буфером между рабочим каталогом и историей проекта, так и локальный репозиторий разработчика является буфером между его вкладом в проект и центральным репозиторием.

Это меняет базовую модель разработки для пользователей Git. Вместо того чтобы вносить изменения и выполнять коммиты непосредственно в центральный репозиторий, разработчики Git могут накапливать коммиты в своем локальном репозитории. Такой подход имеет множество преимуществ по сравнению с совместной работой в стиле SVN: он упрощает разделение функции на мелкие коммиты, объединение связанных коммитов и очистку локальной истории перед ее публикацией в центральном репозитории. Он также позволяет разработчикам работать в изолированной среде, откладывая интеграцию до тех пор, пока наработки не будут готовы к слиянию с наработками других пользователей. Но хотя изоляция и отложенная интеграция удобны с точки зрения одного разработчика, при командной работе желательно выполнять интеграции часто и маленькими блоками. Для получения дополнительных рекомендаций по совместной работе в Git читайте, как команды структурируют свой рабочий процесс в Git.

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

Помимо различий между SVN и Git с практической точки зрения, их базовая реализация также основывается на совершенно разных концепциях проектирования. SVN отслеживает различия в файле, тогда как модель управления версиями Git базируется на снимках состояния. Например, в коммите SVN содержатся различия исходного файла и файла, добавленного в хранилище. А Git записывает в каждом коммите все содержимое каждого файла.

Обучающий материал по Git: снимки состояния, а не различия

Такой подход позволяет выполнять многие операции в Git намного быстрее, чем в SVN, поскольку конкретную версию файла не нужно «собирать» из его различий — во внутренней базе данных Git находится уже готовая редакция каждого файла.

Модель снимков состояния Git влияет практически на все аспекты модели управления версиями, от инструментов ветвления и слияния до рабочих процессов при совместной работе.

Распространенные опции

git commit

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

git commit -a

Выполнение коммита состояния со всеми изменениями в рабочем каталоге. Эта команда включает только модификации отслеживаемых файлов (тех, которые были в какой-то момент добавлены в историю с помощью команды git add).

git commit -m "комментарий к коммиту"

Быстрая команда, которая создает коммит с указанным комментарием. По умолчанию команда git commit открывает локально настроенный текстовый редактор с предложением ввести комментарий к коммиту. При передаче параметра -m текстовый редактор не открывается, а используется подставленный комментарий.

git commit -am "комментарий к коммиту"

Мощная пользовательская команда, состоящая из параметров -a и -m. Эта комбинация создает коммит всех проиндексированных изменений и добавляет к коммиту подставленный комментарий.

git commit --amend

Этот параметр добавляет команде commit новый уровень функциональности. При передаче этого параметра будет изменен последний коммит. Вместо создания нового коммита проиндексированные изменения будут добавлены в предыдущий коммит. Кроме того, эта команда откроет настроенный текстовый редактор системы с предложением изменить указанный ранее комментарий к коммиту.

Примеры

Сохранение изменений с помощью команды commit

В следующем примере предполагается, что вы изменили некоторое содержимое файла hello.py в текущей ветке и готовы сделать коммит в историю проекта. Прежде всего, необходимо проиндексировать файл с помощью команды git add, а после этого вы сможете сделать коммит проиндексированного снимка состояния.

git add hello.py

Эта команда добавит файл hello.py в раздел проиндексированных файлов Git. Проверить результат команды можно с помощью git status.

git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
  new file: hello.py

Окрашенный зеленым цветом вывод «new file: hello.py» сообщает о том, что файл hello.py будет сохранен при выполнении следующего коммита. Коммит выполняется с помощью указанной ниже команды.

git commit

Эта команда откроет текстовый редактор (настраиваемый через git config) для ввода комментария к коммиту и покажет список файлов, которые будут зафиксированы в этом коммите:

# Введите комментарий к коммиту, описывающий внесенные изменения. Строчки, начинающиеся
# с символа #, будут игнорироваться, а пустой комментарий приведет к отмене коммита.
# В главной ветке
# Коммит следующих изменений:
# (используйте "git reset HEAD ..." для отмены коммита)
#
#modified: hello.py

Особых требований для комментариев к коммиту в Git нет, но обычно первая строка содержит описания коммита длиной до 50 символов, затем следует пустая строка и детальное пояснение того, что было изменено. Пример:

Изменение сообщения, выводимого файлом hello.py
- Добавление в функцию sayHello() вывода имени пользователя - Добавление в функцию sayGoodbye() более понятного сообщения

Обычно первая строка комментария к коммиту аналогична теме электронного письма. Остальная часть комментария считается телом сообщения и используется для детального описания набора изменений в коммите. Многие разработчики предпочитают использовать в комментариях настоящее время. Так комментарий становится больше похож на список действий в репозитории, благодаря чему многие операции перезаписи истории становятся более интуитивно понятными.
 

Обновление коммита (параметр amend)

Продолжим работу с файлом hello.py из примера выше. Давайте внесем в файл hello.py новые изменения и запустим следующие команды:

git add hello.py
git commit --amend

Снова откроется настроенный текстовый редактор. Но на этот раз он будет содержать комментарий к коммиту, который мы уже вводили ранее. Это указывает на то, что мы не создаем новый коммит, а редактируем последний.

Резюме

Команда git commit является одной из основных и первостепенных функций Git. Для выбора изменений, которые будут добавлены в следующий коммит, сначала используется команда git add. Затем запускается команда git commit, которая создает снимок проиндексированных изменений на временной шкале истории проектов Git. Подробнее об использовании команды git add см. на соответствующей странице. Команда git status может использоваться для изучения состояния раздела проиндексированных файлов и ожидающего коммита.

Модели коммитов в SVN и в Git существенно отличаются, но из-за общей терминологии часто возникает путаница. Если вы начинаете работу в Git, имея опыт работы с SVN, вам будет полезно знать, что коммиты в Git — простая операция, которую следует выполнять часто. В SVN коммит — сложная операция, связанная с выполнением удаленного запроса, тогда как в Git коммиты выполняются локально и по более эффективному алгоритму.

Готовы изучить Git?

Попробуйте это интерактивное учебное руководство.

Начните прямо сейчас