Изменить сообщение коммита git

Обновлено: 08.07.2024

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

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

Изменение последнего коммита

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

Вы должны быть осторожными, используя этот приём, так как при этом изменяется SHA-1 коммита. Поэтому, как и с операцией rebase — не изменяйте ваш последний коммит, если вы уже отправили его в общий репозиторий.

Выполнение этой команды отобразит в вашем текстовом редакторе список коммитов, в нашем случае, например, следующее:

Важно отметить, что коммиты перечислены в порядке, противоположном порядку, который вы обычно видите при использовании команды log . Если вы выполните log , то увидите следующее:

Обратите внимание на обратный порядок. Команда rebase в интерактивном режиме предоставит вам скрипт, который она будет выполнять. Она начнет с коммита, который вы указали в командной строке ( HEAD~3 ) и повторит изменения, внесённые каждым из коммитов, сверху вниз. Наверху отображается самый старый коммит, а не самый новый, потому что он будет повторен первым.

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

Упорядочивание коммитов

Объединение коммитов

Разбиение коммита

Затем, когда скрипт вернёт вас в командную строку, вам нужно будет отменить индексацию изменений этого коммита, и создать несколько коммитов на основе этих изменений. Когда вы сохраните скрипт и выйдете из редактора, Git переместится на родителя первого коммита в вашем списке, применит первый коммит ( f7f3f6d ), применит второй ( 310154e ), и вернёт вас в консоль. Здесь вы можете отменить коммит с помощью команды git reset HEAD^ , которая, фактически, отменит этот коммит и удалит из индекса изменённые файлы. Теперь вы можете добавлять в индекс и фиксировать файлы, пока не создадите требуемые коммиты, а после этого выполнить команду git rebase --continue :

Git применит последний коммит ( a5f4a0d ) из скрипта, и ваша история примет следующий вид:

Удаление коммита

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

Если во время подобного перебазирования вы поняли, что это была не очень хорошая идея, то всегда можно остановиться. Просто выполните команду git rebase --abort и ваш репозиторий вернётся в то состояние, в котором он был до начала перебазирования.

Если вы завершили перебазирование, а затем решили, что полученный результат это не то, что вам нужно — воспользуйтесь командой git reflog , чтобы восстановить предыдущую версию вашей ветки. Дополнительную информацию по команде reflog можно найти в разделе Восстановление данных главы 10.

Продвинутый инструмент: filter-branch

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

Удаление файла из каждого коммита

Такое случается довольно часто. Кто-нибудь случайно зафиксировал огромный бинарный файл, неосмотрительно выполнив git add . , и вы хотите отовсюду его удалить. Возможно, вы случайно зафиксировали файл, содержащий пароль, а теперь хотите сделать ваш проект общедоступным. В общем, утилиту filter-branch вы, вероятно, захотите использовать, чтобы привести к нужному виду всю вашу историю. Для удаления файла passwords.txt из всей вашей истории вы можете использовать опцию --tree-filter команды filter-branch :

Опция --tree-filter выполняет указанную команду после переключения на каждый коммит и затем повторно фиксирует результаты. В данном примере, вы удаляете файл passwords.txt из каждого снимка вне зависимости от того, существует он или нет. Если вы хотите удалить все случайно зафиксированные резервные копии файлов, созданные текстовым редактором, то вы можете выполнить нечто подобное git filter-branch --tree-filter 'rm -f *~' HEAD .

Вы можете посмотреть, как Git изменит деревья и коммиты, а затем уже переместить указатель ветки. Как правило, хорошим подходом будет выполнение всех этих действий в тестовой ветке и, после проверки полученных результатов, установка на неё указателя основной ветки. Для выполнения filter-branch на всех ваших ветках, вы можете передать команде опцию --all .

Установка подкаталога как корневого каталога проекта

Предположим, вы выполнили импорт из другой системы контроля версий и получили в результате подкаталоги, которые не имеют никакого смысла (trunk, tags и так далее). Если вы хотите сделать подкаталог trunk корневым для каждого коммита, команда filter-branch может помочь вам в этом:

Теперь вашим новым корневым каталогом проекта будет являться подкаталог trunk . Git также автоматически удалит коммиты, которые не затрагивали этот подкаталог.

Глобальное изменение адреса электронной почты

Ещё один типичный случай возникает, когда вы забыли выполнить git config для настройки своего имени и адреса электронной почты перед началом работы, или, возможно, хотите открыть исходные коды вашего рабочего проекта и изменить везде адрес вашей рабочей электронной почты на персональный. В любом случае вы можете изменить адрес электронный почты сразу в нескольких коммитах с помощью команды filter-branch . Вы должны быть осторожны, чтобы изменить только свои адреса электронной почты, для этого используйте опцию --commit-filter :

Эта команда пройдёт по всем коммитам и установит в них ваш новый адрес. Так как коммиты содержат значения SHA-1-хешей их родителей, эта команда изменяет хеш SHA-1 каждого коммита в вашей истории, а не только тех, которые соответствовали адресам электронной почты.


3 ответа 3

Вы можете дать новый заголовок

если хотите отредактировать старый

В похожем вопросе было очень интересное замечание, если вам нужно отредактировать коммит более старый, а не последний, используйте rebase interactive (например тут если искомый коммит 3мя ранее):

git rebase -i HEAD~3

Пометьте нужный коммит как edit , а потом делайте

git commit --amend

А после окончания редактирования коммита сделайте

git rebase --continue

чтобы завершить rebase.
Ну и как написал @Daniil следует потом сделать push force если коммиты уже в удаленном репозитории.

Изменение последнего коммита

Если вы что-либо недоглядели в последнем коммите, то отредактировать его не составит никакого труда. Все, что нужно это добавить изменения обычным образом:


Затем закоммитить изменения с параметром --amend (amend /əˈmɛnd/ — вносить поправки, исправлять, улучшать):

Изменение названия последнего коммита

То же самое, с той лишь разницей что нет необходимости добавлять файлы в коммит. Просто укажите новое название:

Изменение НЕ последнего коммита

image

Тут чуть посложнее, сделайте для начала два коммита, в моем примере они будут называться С1 и С2 :

Для начала выполняем:

image

Откроется редактор, в котором вы можете указать что хотите сделать:

  • r reword переименовать коммит
  • e edit изменить коммит
  • s squash склеить два или больше коммитов (squash /skwɒʃ/ — втиснуть, сжимать, тыква :) )

В ответ получим:

Дальше, как первой части поста где мы меняли последний коммит, делаем изменения и добавляем их:

и коммитим с параметром --amend :

После успешного коммита, следуя подсказке (чуть выше на скриншоте), выполняем:

Тем самым мы возвратимся на ветку master с измененным коммитом, что и требовалось.

Favorite

Добавить в избранное

Изменение самого последнего коммита

Не изменять коммит

Команда выполняет перезапись самого последнего коммита новым.

Измененный коммит

Измененный коммит – это новый объект с другим SHA-1. Предыдущий коммит больше не будет существовать в текущей ветке.

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

Изменение более старых или нескольких коммитов

Команда rebase переписывает историю коммитов, и настоятельно не рекомендуется перебазировать коммиты, которые уже переданы в удаленный репозиторий Git .

Команда отобразит последние X коммитов в текстовом редакторе по умолчанию :

Заключение

Не вносите изменения в принудительные коммиты, так как это может вызвать массу проблем у ваших коллег.

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

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

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