Git добавить файл в коммит

Обновлено: 30.06.2024

Крайне часто разработчики делают коммит и сразу же понимают, что забыли добавить часть файлов через git add . Оставшуюся часть изменений можно дослать следующим коммитом либо, если изменения ещё не были отправлены во внешнюю систему, можно добавить изменения в текущий коммит. Для этого во время коммита добавляется флаг --amend :

В реальности --amend не добавляет изменения в существующий коммит, этот флаг приводит к откату коммита (через reset) и выполнению нового коммита с новыми данными. Поэтому мы и видим ровно один коммит, хотя команда git commit выполнялась два раза (первый раз — когда сделали ошибочный коммит).

Для того, чтобы не открывался редактор для ввода описания коммита к команде git commit --amend можно добавить опцию --no-edit . В этом случае описание коммита не изменится.

Самостоятельная работа

  1. Выполните все шаги из урока
  2. Залейте изменения на Github

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

Вам ответят команда поддержки Хекслета или другие студенты.

Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?
  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете
  • Статья «Как учиться и справляться с негативными мыслями»
  • Статья «Ловушки обучения»
  • Статья «Сложные простые задачи по программированию»
  • Урок «Как эффективно учиться на Хекслете»
  • Вебинар «Как самостоятельно учиться»

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

Итак, у вас имеется настоящий Git-репозиторий и рабочая копия файлов для некоторого проекта. Вам нужно делать некоторые изменения и фиксировать «снимки» состояния (snapshots) этих изменений в вашем репозитории каждый раз, когда проект достигает состояния, которое вам хотелось бы сохранить.

Запомните, каждый файл в вашем рабочем каталоге может находиться в одном из двух состояний: под версионным контролем (отслеживаемые) и нет (неотслеживаемые). Отслеживаемые файлы — это те файлы, которые были в последнем снимке состояния проекта; они могут быть неизменёнными, изменёнными или подготовленными к коммиту. Если кратко, то отслеживаемые файлы — это те файлы, о которых знает Git.

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

Как только вы отредактируете файлы, Git будет рассматривать их как изменённые, так как вы изменили их с момента последнего коммита. Вы индексируете эти изменения, затем фиксируете все проиндексированные изменения, а затем цикл повторяется.

Жизненный цикл состояний файлов

Определение состояния файлов

Основной инструмент, используемый для определения, какие файлы в каком состоянии находятся — это команда git status . Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:

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

Предположим, вы добавили в свой проект новый файл, простой файл README . Если этого файла раньше не было, и вы выполните git status , вы увидите свой неотслеживаемый файл вот так:

Понять, что новый файл README неотслеживаемый можно по тому, что он находится в секции «Untracked files» в выводе команды status . Статус Untracked означает, что Git видит файл, которого не было в предыдущем снимке состояния (коммите); Git не станет добавлять его в ваши коммиты, пока вы его явно об этом не попросите. Это предохранит вас от случайного добавления в репозиторий сгенерированных бинарных файлов или каких-либо других, которые вы и не думали добавлять. Мы хотели добавить README, так давайте сделаем это.

Отслеживание новых файлов

Для того чтобы начать отслеживать (добавить под версионный контроль) новый файл, используется команда git add . Чтобы начать отслеживание файла README , вы можете выполнить следующее:

Если вы снова выполните команду status , то увидите, что файл README теперь отслеживаемый и добавлен в индекс:

Вы можете видеть, что файл проиндексирован, так как он находится в секции «Changes to be committed». Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды git add , будет добавлена в историю снимков состояния. Как вы помните, когда вы ранее выполнили git init , затем вы выполнили git add (файлы) — это было сделано для того, чтобы добавить файлы в вашем каталоге под версионный контроль. Команда git add принимает параметром путь к файлу или каталогу, если это каталог, команда рекурсивно добавляет все файлы из указанного каталога в индекс.

Индексация изменённых файлов

Давайте модифицируем файл, уже находящийся под версионным контролем. Если вы измените отслеживаемый файл CONTRIBUTING.md и после этого снова выполните команду git status , то результат будет примерно следующим:

Файл CONTRIBUTING.md находится в секции «Changes not staged for commit» — это означает, что отслеживаемый файл был изменён в рабочем каталоге, но пока не проиндексирован. Чтобы проиндексировать его, необходимо выполнить команду git add . Это многофункциональная команда, она используется для добавления под версионный контроль новых файлов, для индексации изменений, а также для других целей, например для указания файлов с исправленным конфликтом слияния. Вам может быть понятнее, если вы будете думать об этом как «добавить этот контент в следующий коммит», а не как «добавить этот файл в проект». Выполним git add , чтобы проиндексировать CONTRIBUTING.md , а затем снова выполним git status :

Теперь оба файла проиндексированы и войдут в следующий коммит. В этот момент вы, предположим, вспомнили одно небольшое изменение, которое вы хотите сделать в CONTRIBUTING.md до коммита. Вы открываете файл, вносите и сохраняете необходимые изменения и вроде бы готовы к коммиту. Но давайте-ка ещё раз выполним git status :

Что за чёрт? Теперь CONTRIBUTING.md отображается как проиндексированный и непроиндексированный одновременно. Как такое возможно? Такая ситуация наглядно демонстрирует, что Git индексирует файл в точности в том состоянии, в котором он находился, когда вы выполнили команду git add . Если вы выполните коммит сейчас, то файл CONTRIBUTING.md попадёт в коммит в том состоянии, в котором он находился, когда вы последний раз выполняли команду git add , а не в том, в котором он находится в вашем рабочем каталоге в момент выполнения git commit . Если вы изменили файл после выполнения git add , вам придётся снова выполнить git add , чтобы проиндексировать последнюю версию файла:

Сокращенный вывод статуса

Вывод команды git status довольно всеобъемлющий и многословный. Git также имеет флаг вывода сокращенного статуса, так что вы можете увидеть изменения в более компактном виде. Если вы выполните git status -s или git status --short вы получите гораздо более упрощенный вывод:

Новые неотслеживаемые файлы помечены ?? слева от них, файлы добавленные в отслеживаемые помечены A , отредактированные файлы помечены M и так далее. В выводе содержится два столбца — в левом указывается статус файла, а в правом модифицирован ли он после этого. К примеру в нашем выводе, файл README модифицирован в рабочем каталоге, но не проиндексирован, а файл lib/simplegit.rb модифицирован и проиндексирован. Файл Rakefile модифицирован, проиндексирован и ещё раз модифицирован, таким образом на данный момент у него есть те изменения, которые попадут в коммит, и те, которые не попадут.

Игнорирование файлов

Зачастую, у вас имеется группа файлов, которые вы не только не хотите автоматически добавлять в репозиторий, но и видеть в списках неотслеживаемых. К таким файлам обычно относятся автоматически генерируемые файлы (различные логи, результаты сборки программ и т. п.). В таком случае, вы можете создать файл .gitignore . с перечислением шаблонов соответствующих таким файлам. Вот пример файла .gitignore :

Первая строка предписывает Git игнорировать любые файлы заканчивающиеся на «.o» или «.a» — объектные и архивные файлы, которые могут появиться во время сборки кода. Вторая строка предписывает игнорировать все файлы заканчивающиеся на тильду (

), которая используется во многих текстовых редакторах, например Emacs, для обозначения временных файлов. Вы можете также включить каталоги log, tmp или pid; автоматически создаваемую документацию; и т. д. и т. п. Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите.

К шаблонам в файле .gitignore применяются следующие правила:

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

Чтобы избежать рекурсии используйте символ слеш (/) в начале шаблона.

Чтобы исключить каталог добавьте слеш (/) в конец шаблона.

Можно инвертировать шаблон, использовав восклицательный знак (!) в качестве первого символа.

Glob-шаблоны представляют собой упрощённые регулярные выражения, используемые командными интерпретаторами. Символ ( * ) соответствует 0 или более символам; последовательность [abc] — любому символу из указанных в скобках (в данном примере a, b или c); знак вопроса ( ? ) соответствует одному символу; и квадратные скобки, в которые заключены символы, разделённые дефисом ( 2 ), соответствуют любому символу из интервала (в данном случае от 0 до 9). Вы также можете использовать две звёздочки, чтобы указать на вложенные каталоги: a/**/z соответствует a/z , a/b/z , a/b/c/z , и так далее.

Вот ещё один пример файла .gitignore :

В простейшем случае репозиторий будет иметь один файл .gitignore в корневом каталоге, правила из которого будут рекурсивно применяться ко всем подкаталогам. Так же возможно использовать .gitignore файлы в подкаталогах. Правила из этих файлов будут применяться только к каталогам, в которых они находятся. Например, репозиторий исходного кода ядра Linux содержит 206 файлов .gitignore .

Детальное рассмотрение использования нескольких .gitignore файлов выходит за пределы этой книги; детали доступны в справке man gitignore .

Просмотр индексированных и неиндексированных изменений

Допустим, вы снова изменили и проиндексировали файл README , а затем изменили файл CONTRIBUTING.md без индексирования. Если вы выполните команду git status , вы опять увидите что-то вроде:

Чтобы увидеть, что же вы изменили, но пока не проиндексировали, наберите git diff без аргументов:

Эта команда сравнивает содержимое вашего рабочего каталога с содержимым индекса. Результат показывает ещё не проиндексированные изменения.

Если вы хотите посмотреть, что вы проиндексировали и что войдёт в следующий коммит, вы можете выполнить git diff --staged . Эта команда сравнивает ваши проиндексированные изменения с последним коммитом:

Важно отметить, что git diff сама по себе не показывает все изменения сделанные с последнего коммита — только те, что ещё не проиндексированы. Такое поведение может сбивать с толку, так как если вы проиндексируете все свои изменения, то git diff ничего не вернёт.

Другой пример: вы проиндексировали файл CONTRIBUTING.md и затем изменили его, вы можете использовать git diff для просмотра как проиндексированных изменений в этом файле, так и тех, что пока не проиндексированы. Если наше окружение выглядит вот так:

Используйте git diff для просмотра непроиндексированных изменений

а так же git diff --cached для просмотра проиндексированных изменений ( --staged и --cached синонимы):

Мы будем продолжать использовать команду git diff различными способами на протяжении всей книги. Существует еще один способ просматривать эти изменения, если вы предпочитаете графический просмотр или внешнюю программу просмотра различий, вместо консоли. Выполнив команду git difftool вместо git diff , вы сможете просмотреть изменения в файле с помощью таких программ как emerge, vimdiff и других (включая коммерческие продукты). Выполните git difftool --tool-help чтобы увидеть какие из них уже установлены в вашей системе.

Коммит изменений

Теперь, когда ваш индекс находится в таком состоянии, как вам и хотелось, вы можете зафиксировать свои изменения. Запомните, всё, что до сих пор не проиндексировано — любые файлы, созданные или изменённые вами, и для которых вы не выполнили git add после редактирования — не войдут в этот коммит. Они останутся изменёнными файлами на вашем диске. В нашем случае, когда вы в последний раз выполняли git status , вы видели что всё проиндексировано, и вот, вы готовы к коммиту. Простейший способ зафиксировать изменения — это набрать git commit :

Эта команда откроет выбранный вами текстовый редактор.

Редактор устанавливается переменной окружения EDITOR — обычно это vim или emacs, хотя вы можете установить любой другой с помощью команды git config --global core.editor , как было показано в главе Введение).

В редакторе будет отображён следующий текст (это пример окна Vim):

Для ещё более подробного напоминания, что же именно вы поменяли, можете передать аргумент -v в команду git commit . Это приведёт к тому, что в комментарий будет также помещена дельта/diff изменений, таким образом вы сможете точно увидеть все изменения которые вы совершили.

Есть и другой способ — вы можете набрать свой комментарий к коммиту в командной строке вместе с командой commit указав его после параметра -m , как в следующем примере:

Итак, вы создали свой первый коммит! Вы можете видеть, что коммит вывел вам немного информации о себе: на какую ветку вы выполнили коммит ( master ), какая контрольная сумма SHA-1 у этого коммита ( 463dc4f ), сколько файлов было изменено, а также статистику по добавленным/удалённым строкам в этом коммите.

Запомните, что коммит сохраняет снимок состояния вашего индекса. Всё, что вы не проиндексировали, так и висит в рабочем каталоге как изменённое; вы можете сделать ещё один коммит, чтобы добавить эти изменения в репозиторий. Каждый раз, когда вы делаете коммит, вы сохраняете снимок состояния вашего проекта, который позже вы можете восстановить или с которым можно сравнить текущее состояние.

Игнорирование индексации

Несмотря на то, что индекс может быть удивительно полезным для создания коммитов именно такими, как вам и хотелось, он временами несколько сложнее, чем вам нужно в процессе работы. Если у вас есть желание пропустить этап индексирования, Git предоставляет простой способ. Добавление параметра -a в команду git commit заставляет Git автоматически индексировать каждый уже отслеживаемый на момент коммита файл, позволяя вам обойтись без git add :

Обратите внимание, что в данном случае перед коммитом вам не нужно выполнять git add для файла CONTRIBUTING.md , потому что флаг -a включает все файлы. Это удобно, но будьте осторожны: флаг -a может включить в коммит нежелательные изменения.

Удаление файлов

Для того чтобы удалить файл из Git, вам необходимо удалить его из отслеживаемых файлов (точнее, удалить его из вашего индекса) а затем выполнить коммит. Это позволяет сделать команда git rm , которая также удаляет файл из вашего рабочего каталога, так что в следующий раз вы не увидите его как «неотслеживаемый».

Если вы просто удалите файл из своего рабочего каталога, он будет показан в секции «Changes not staged for commit» (измененные, но не проиндексированные) вывода команды git status :

Затем, если вы выполните команду git rm , удаление файла попадёт в индекс:

После следующего коммита файл исчезнет и больше не будет отслеживаться. Если вы изменили файл и уже проиндексировали его, вы должны использовать принудительное удаление с помощью параметра -f . Это сделано для повышения безопасности, чтобы предотвратить ошибочное удаление данных, которые ещё не были записаны в снимок состояния и которые нельзя восстановить из Git.

Другая полезная штука, которую вы можете захотеть сделать — это удалить файл из индекса, оставив его при этом в рабочем каталоге. Другими словами, вы можете захотеть оставить файл на жёстком диске, но перестать отслеживать изменения в нём. Это особенно полезно, если вы забыли добавить что-то в файл .gitignore и по ошибке проиндексировали, например, большой файл с логами, или кучу промежуточных файлов компиляции. Чтобы сделать это, используйте опцию --cached :

В команду git rm можно передавать файлы, каталоги или шаблоны. Это означает, что вы можете сделать что-то вроде:

Обратите внимание на обратный слеш ( \ ) перед * . Он необходим из-за того, что Git использует свой собственный обработчик имён файлов вдобавок к обработчику вашего командного интерпретатора. Эта команда удаляет все файлы, имеющие расширение .log и находящиеся в каталоге log/ . Или же вы можете сделать вот так:

Эта команда удаляет все файлы, имена которых заканчиваются на

Перемещение файлов

В отличие от многих других систем контроля версий, Git не отслеживает перемещение файлов явно. Когда вы переименовываете файл в Git, в нём не сохраняется никаких метаданных, говорящих о том, что файл был переименован. Однако, Git довольно умён в плане обнаружения перемещений постфактум — мы рассмотрим обнаружение перемещения файлов чуть позже.

Таким образом, наличие в Git команды mv выглядит несколько странным. Если вам хочется переименовать файл в Git, вы можете сделать что-то вроде:

и это отлично сработает. На самом деле, если вы выполните что-то вроде этого и посмотрите на статус, вы увидите, что Git считает, что произошло переименование файла:

Однако, это эквивалентно выполнению следующих команд:

Git неявно определяет, что произошло переименование, поэтому неважно, переименуете вы файл так или используя команду mv . Единственное отличие состоит лишь в том, что mv — одна команда вместо трёх — это функция для удобства. Важнее другое — вы можете использовать любой удобный способ для переименования файла, а затем воспользоваться командами add/rm перед коммитом.

Видеоурок. Часть 1. Практика, основы работы с коммитами и историей коммитов

Видеоурок. Часть 2. Практика, дополнительные приемы и фишки

Видеоурок. Часть 3. Общие наблюдения и советы. Как делать "хорошие" коммиты

Конспект урока

Краткое содержание урока, основные инструкции для командной строки, полезные ссылки и советы.

Что такое коммит

По-научному это сохранение состояния, фиксация или слепок изменений.

Чуть менее научно, коммит - зафиксированный набор изменений, который показывает, какие файлы изменились и что именно в них изменилось. Рассмотрим на примере.

Как сделать коммит

Представим, что мы добавляем блок учеников на сайт. Добавляем новую разметку в index.html и новые стили в main.css. Чтобы сохранить изменения, нужно их закоммитить. Но предварительно сообщить git, какие именно файлы мы хотим положить в коммит. Команда git add добавляет (или подготавливает) файлы к коммиту. Можно добавить файлы по отдельности, вот так

А можно все сразу

Добавлять все файлы сразу удобно, но стоит всегда внимательно проверять, точно ли мы хотим добавить в коммит все измененные файлы. Если ошиблись и какой-то файл добавлять в коммит не нужно, то можно исключить этот файл из подготовленных.

Создаем сам коммит

Состояние файлов в git. Измененные и подготовленные файлы

Измененные файлы - это те файлы, которые мы успели изменить с момента последнего коммита

Подготовленные файлы отличаются от измененных тем, что они "подготовлены" к коммиту, то есть будут добавлены в следующий коммит.

git add filename добавляет или подготавливает файл к коммиту.
git reset filename удаляет файл из подготовленных к коммиту.

Содержимое файлов при этом не меняется. Один файл может одновременно находиться и в измененных, и в подготовленных. Это происходит, если мы добавили файл, но не закоммитили и продолжили делать в нем измения.

Из чего состоит коммит

Каждый коммит имеет

Как добавить файлы и сделать коммит одной командой

git commit с флагом -a добавит все файлы и создаст коммит. Но осторожно, не увлекайтесь этим, потому что по ошибке легко включить в коммит лишние файлы.

Отслеживаемые и неотслеживаемые файлы

Отслеживаемые файлы - это те, в которых git отлавливает изменения и показывает их через git status и git diff. В нашем проекте файлы index.html и css/main.css - отслеживаемые.

Неотслеживаемые файлы - это файлы, изменения в которых git не отлавливает. Новый файл в проекте по умолчанию попадает в неотслеживаемые. Добавить новый файл в рабочую область git можно командой git add filename

История коммитов, git log

Все коммиты можно посмотреть в истории коммитов. История хранит все данные обо всех коммитах проекта. Показывается история командой

История включает в себя все сведения о коммитах: хэш, автор, дата и список изменений. Список изменений смотреть командой git show по хэшу коммита

Переименование последнего коммита, git commit --amend

Если коммит успели запушить, то переименовывать коммиты нужно осторожно, как именно - во второй части курса.

Откат коммитов, git revert

Если мы сделали неверный коммит и хотим откатить изменения, сделанные в нем, то поможет команда git revert

При этом откроется дефолтный текстовый редактор, который предолжит ввести commit message. Если мы хотим оставить commit message по умолчанию, то можно обойтись без открытия редактора с помощью флажка --no-edit

Работа с файлами

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

При обычном переименовании файла в файловом менеджере или командой mv git сначала показывает 2 файла: старый удаленный и новый неотслеживаемый. Чтобы git понял, что этот файл именно переименованный, нужно сначала добавить эти файлы в подготовленные к коммиту

Тогда при команде git status файл будет отображаться именно как переименованный

Можно избежать этого промежуточного состояния, если переименовать файл в командной строке таким образом

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

Командная строка vs IDE

Работа в PhpStorm продемонстрирована в первых двух частях видео.

Как и в прошлом уроке мы видим, что некоторые вещи удобнее делать в IDE. Например, процесс добавления файлов (git add) в PhpStorm при создании коммита почти не привлекает внимания. Но важно понимать, что такое git add и зачем он нужен. И что любая IDE под капотом все равно выполняет базовые команды git. Просто для нас предоставляется удобная обертка, чтобы мы больше сосредоточились на самом проекте, а не на git.

Наблюдения и советы при работе с коммитами

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

  • коммит - это законченный функционал
  • всегда проверяйте перед коммитом, что в него попадет. git diff - наш лучший друг
  • выделяйте мелкие баги и правки в отдельные коммиты
  • маленький коммит в одну строку - это нормально
  • видите много изменений - подумайте, можно ли разбить их на отдельные коммиты
  • мыслите задачей, а не файлами. Выделяйте полезное действие коммита
  • commit message говорит, ЧТО делает коммит, а не КАК делает
  • коммит-рефакторинг - это нормально. Не стоит мешать его с другими задачами
  • git плохо работает с бинарниками (картинками, pdf, видеофайлами) - видит факт изменения, но не сами изменения
  • подписывайте коммит так, чтобы можно было проследить историю развития проекта

Все эти правила одновременно соблюсти довольно трудно. Это приходит с опытом, но главное - полагаться на здравый смысл. Умение хорошо формировать и подписывать коммиты - один из признаков хорошего разработчика.

Используйте удобные инструменты в IDE, но не забывайте командную строку. В ней вы лучше будете понимать, как устроен git, как он работает

Хорошие и плохие коммиты

С точки зрения git коммиты не бывают плохими и хорошими. Но есть удачные и неудачные подписи к коммитам с точки зрения наших коллег. Несколько примеров

Изменен файл index.html
Добавлен блок новостей
В первом коммите непонятно, что он делает, во втором - ясно описана задача

Изменены стили баннера
Растянули баннер на всю ширину окна
Первый коммит говорит только об изменениях стилей баннера, второй - точно, что именно изменено. Больше информации

Добавлен файл VipClient
Работа с vip-клиентами вынесена в отдельный класс
По первому коммиту можно предположить, что в VipClient мы скорее всего работаем с ВИПами. Во втором коммите это точно понятно, плюс дополнительная информация, что это отдельный класс.

Поправлены стили в main.css
Рефакторинг стилей в main.css
Первый коммит говорит о правке стилей, но непоянтно, что именно поправлено. Бага? Новые значения? Изменен цвет текста по рекомендации дизайнера? Второй коммит ясно указывает, что это рефакторинг

Маленький фикс
Исправлена опечатка в заголовке title страницы "О компании"
Коммит "маленький фикс" даже приблизительно не говорит, в чем он заключается. Второй коммит дает полное представление

Немного о философии коммитов

Концепция коммитов заставляет если не менять подход к разработке, то по-другому к ней относиться. С git нам приходится не просто писать код, а планировать его написание. Планировать задачи, над которыми мы работаем. Декомпозировать задачи, то есть разбивать их на небольшие части.

Мы больше думаем о том, что мы работаем не одни, а в команде. История коммитов общая для всего проекта. Чем лучше мы научимся формировать и подписывать коммиты, тем легче будет ориентироваться в истории нам самим и нашим коллегам.

В любом проекте важны не только код и его структура, но и история коммитов и хорошие commit message.

git good commit message

На этом все. В следующем уроке мы будем больше работать с историей коммитов и посмотрим различные варианты использования команды git log

В предыдущих статьях мы рассказывали, что такое GitHub, как его настроить и как опубликовать свой проект. Но это лишь малая часть его инструментов. Одним из ключевых моментов для GitHub является работа с ветками — разбираемся с ними в этой статье.

Ветка (branch) — это история коммитов. Давайте сначала разберемся, что это такое.

Коммит (commit) — это информация об измененных файлах. Коммит состоит из автора коммита, измененных файлов, HEAD и времени. Для примеров мы будем использовать репозиторий и сделаем первый коммит, который отправим на сервер. Он нужен для того, чтобы разграничивать задачки. Так будет понятно, какой код в истории относится к той или иной задаче, чтобы потом мы могли быстро понять суть.

Например, у нас задача — сделать блок формы. Для этого мы сделаем нужные изменения в файле index.html & style.css, и даже через месяц сможем при помощи истории изменений просмотреть измененные куски кода именно для этого блока.

При помощи команды git log в консоли мы можем отслеживать историю коммитов в ветке.


На самом GitHub мы можем увидеть последний коммит в файле и последний коммит в ветке. Всю историю мы можем просмотреть, кликнув по кнопке n commits, где n — количество запущенных на сервер коммитов. У нас в ветке пока что один коммит, поэтому на ссылке надпись 1 commit.


Сама история будет выглядеть как список коммитов без подробностей об изменённых файлах. Здесь давайте подробнее остановимся на том, что такое HEAD коммита. Это специальный указатель, при помощи которого вы можете гибко управлять коммитами — например, склеивать или сбрасывать до нужного момента.



Теперь подробнее разберем, как создавать коммит. Для начала нам нужно будет поменять файлы или добавить новые, чтобы было что коммитить, так как коммит — это история изменений. Как правило, в коммит включают изменения по одной задаче.

В нашем примере мы изменим содержание страницы index.html и добавим стили в style.css.


Изменения, не включенные в коммит, мы можем просмотреть при помощи команды git status.


Чтобы добавить файлы в коммит, мы будем использовать git add. Здесь мы можем указать нужные нам файлы для коммита, например, index.html. Если после этого мы сделаем git status, то эти файлики подсветятся зелёным — это означает, что мы можем добавить их к коммиту.


Но не всегда удобно вручную вбивать все изменённые файлы. В GitHub мы можем воспользоваться командой git add . — точка означает, что в коммит добавятся все изменённые файлы.


Теперь мы можем создать наш коммит при помощи команды git commit -m ‘текст коммита’. В тексте обычно рассказывается в паре слов о том, что было сделано — например, «добавили стили для index.html». Название коммитов пишут на русском или английском языке — зависит от того, как вы договоритесь с командной. После того, как вы создадите коммит, он появится у вас в истории.


Если мы запушим наш результат на GitHub, то увидим наш коммит.




После того, как мы поменяли наш коммит локально, запушим его на сервер при помощи ключа force. Обычный push не сработает, так как у нас уже есть коммит на сервере — здесь будьте аккуратны, ведь вы меняете историю не только локально, но и удалённо.


Теперь поговорим про ветки (branch). Ветка — это история изменений. Сейчас у в репозитории одна ветка main, в которой хранится стабильная версия. Как правило, новые задачи делаются в новых ветках, а потом вливаются в main после ревью кода.

Посмотрим, как выглядит наша ветка с двумя коммитами в графике.


Представим, что у нас есть задача — сделать форму на главной странице. Для этого создадим новую ветку git checkout -b form-index (ключ -b означает, что мы создаем новую ветку).

Ветки можно просматривать при помощи команды git branch.


История наших коммитов пока одинаковая — что у main, что у form-index. git checkout main без ключа -b означает, что мы переключаемся на уже существующую ветку.

Пробежимся git log и сравним наши ветки.


Тем не менее, если мы зайдем на GitHub, то обнаружим, что у нас там только одна ветка — main. Так происходит, потому что ветка form-index существует пока только на нашем компьютере, то есть локально.


Чтобы наша новая ветка появилась на сервере, нам нужно запушить наши изменения.



Если посмотрим на историю коммитов в form, то увидим, что она отличается от main на один коммит.


Мы можем создавать новые ветки не только из main, но и из других веток — так делают редко. Самое главное здесь понять, что если мы создали новую ветку из другой ветки, то мы наследуем историю коммитов ветки, из которой создали ветвление, но только в момент создания.

Давайте создадим ветку form-index-fix и посмотрим на историю коммитов в ней.


Теперь поэкспериментируем и посмотрим, что будет, если мы внесём изменение в ветку и забудем их закоммитить: обычный механизм через checkout не сработает, консоль попросит закоммитить изменения.


Если ветка потеряла свою актуальность, мы можем её удалить локально при помощи команды git branch -D название ветки. Здесь важно отметить, что вы не можете удалить ветку, если вы сейчас в ней — обязательно нужно переключить её.


Если ветку нужно удалить на сервере, то сделать это можно при помощи интерфейса GitHub — нет рекомендаций, когда нужно удалять удалённые ветки.

Читайте также: