Изменение сообщения git commit после push (учитывая, что никто не вытащил с пульта)

984

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

Есть ли способ сделать это?

K_U
источник
Что вы пробовали? Предполагая, что вы уже знаете, как изменить сообщение о коммите, а затем попытаетесь нажать, Git скажет вам, что вам нужно сделать, чтобы это произошло.
Эндрю Маршалл
1
Смотрите ответ на вопрос "Как мне отредактировать неверное сообщение о коммите в git (я нажал)?" stackoverflow.com/a/457396/444639
Майк Райландер
4
Объявление об этом - Google Вопрос о git commit Rank № 1!
Маниш Шривастава
Если вы исправляете коммит HEAD и обычно проталкиваете (без --force), то, что удивительно, это не дает сбоя. Сообщение о подтверждении HEAD обновляется с измененным идентификатором принятия. Это означает, что другие идентификаторы фиксации, кроме HEAD, остаются неизменными. Я заметил это поведение с версией git 2.8.1.
irsis

Ответы:

1375

Изменение истории

Если это самый последний коммит, вы можете просто сделать это:

git commit --amend

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

Нажимать

И затем, когда вы нажимаете, сделайте это:

git push --force-with-lease <repository> <branch>

Или вы можете использовать «+»:

git push <repository> +<branch>

Или вы можете использовать --force:

git push --force <repository> <branch>

Будьте осторожны при использовании этих команд.

  • Если кто-то еще отправил изменения в ту же ветку, вы, вероятно, захотите избежать уничтожения этих изменений. --force-with-leaseВариант является самым безопасным, потому что он будет прерван , если есть какие - либо изменения вверх по течению (

  • Если вы не укажете ветку явно, Git будет использовать настройки push по умолчанию. Если заданная по умолчанию настройка push - «match», вы можете уничтожить изменения в нескольких ветвях одновременно.

Вытащить / извлечь потом

Любой, кто уже вытащил, теперь получит сообщение об ошибке, и ему нужно будет обновить (при условии, что они не вносят никаких изменений самостоятельно), выполнив что-то вроде этого:

git fetch origin
git reset --hard origin/master # Loses local commits

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

Примечание об изменении истории

Уничтоженные данные - это просто старое сообщение о коммите, но они --forceэтого не знают и с удовольствием удалят и другие данные. Поэтому подумайте: --force«Я хочу уничтожить данные, и я точно знаю, какие данные уничтожаются». Но когда уничтоженные данные фиксируются, вы часто можете восстановить старые коммиты из журнала изменений - данные фактически осиротели, а не уничтожены (хотя осиротевшие коммиты периодически удаляются).

Если вы не думаете, что уничтожаете данные, тогда держитесь подальше от --force... могут случиться плохие вещи .

Вот почему --force-with-leaseнесколько безопаснее.

Дитрих Эпп
источник
13
Будьте осторожны с этим «исправлением», так как если у них есть какие-либо локальные, невыдвинутые коммиты, они будут «потеряны» ( потерянные действительно означающие осиротевшие , но их восстановление неочевидно).
Эндрю Маршалл
1
вы, вероятно, захотите указать имя ветви, когда нажимаете --force, иначе вы можете нажать больше, чем ожидали.
user693960
1
@ user693960: Git будет выдвигать только то, что вы настроили.
Дитрих Эпп
10
Просто git push --forceбез опций <repository> и <branch> работает, если у вас настроен апстрим.
ahnbizcad
2
Можете привести пример <repository>? Это origin? org/repo? Или просто repo?
MikeSchinkel
440

Просто скажи :

git commit --amend -m "New commit message"

а потом

git push --force
Маниш Шривастава
источник
8
В моем случае git push origin <BRANCH-NAME>не сработало, пришлось использовать git push --forceкак объяснил в принятом ответе.
Габриэль
1
это не работает для меня. надо нас git push --force, иначе толчок не пройдет.
ahnbizcad
4
@ahnbizcad, это должно работать. Просто убедитесь, что название ветки правильное.
Уильям
3
Я болею за простоту в вашем объяснении! Я использую его чаще, чем часто
Vasikos
3
Я успешно применил эту команду только после того, как временно «снял защиту» с моей ветки, что произошло в моем проекте, размещенном на GitLab. Если у вас есть эта проблема, прежде чем применять эти команды, пожалуйста, обратитесь к этому stackoverflow.com/a/32267118/1423345, чтобы «снять защиту» с ветки, и вы можете «защитить» ее снова после того, как внесете изменения в сообщение фиксации :)
John
262

Чтобы отредактировать коммит, отличный от самого последнего:

Шаг 1 : git rebase -i HEAD~nсделать интерактивную перезагрузку для последних nзатронутых коммитов. (т. е. если вы хотите изменить сообщение о коммите 3 коммитов назад, сделайте git rebase -i HEAD~3)

Git откроет редактор для обработки этих коммитов, обратите внимание на эту команду:

#  r, reword = use commit, but edit the commit message

это именно то, что нам нужно!

Шаг2 : изменение pickв rтечение этих фиксаций , которые вы хотите обновить сообщение. Не беспокойтесь об изменении сообщения коммита здесь, оно будет проигнорировано. Вы сделаете это на следующем шаге. Сохраните и закройте редактор.

Обратите внимание, что если вы редактируете план перебазирования, но он не запускает процесс переименования файлов, выполните:

git rebase --continue

Если вы хотите изменить текстовый редактор, используемый для интерактивного сеанса (например, с vi по умолчанию на nano), запустите:

GIT_EDITOR=nano git rebase -i HEAD~n

Шаг 3 : Git будет открывать другой редактор для каждой ревизии, которую вы поместили rранее. Обновите сообщение, как вам нравится, затем сохраните и закройте редактор.

Шаг 4 : После всех коммитов сообщения обновляются. Вы можете сделать, git push -fчтобы обновить пульт.

Цзиньсун Ли
источник
21
Это должен быть принятый ответ, так как он дает возможность изменить другие коммиты, чем последний коммит, в отличие от принятого ответа. Ты спас мой день. Спасибо!
xZero
1
Выберите n = 3 для последних 3 git rebase -i HEAD~3
коммитов
Если вы редактируете свой план перебазирования, но процесс переименования файлов не начинается, запустите git rebase --continue. И если вы хотите изменить текстовый редактор, используемый для интерактивного сеанса (например, с по умолчанию viна nano), запустите GIT_EDITOR=nano git rebase -i HEAD~n.
Джейми Берч
Я отредактировал это, чтобы добавить немного больше информации. Взгляни, пожалуйста. Это был ответ на то, что я хотел сделать, но я прокрутил его, потому что у него не было заголовка.
Кип
Я предложил изменить, чтобы добавить в ответ полезный комментарий @JamieBirch, возможно, захотите просмотреть.
Notts90 поддерживает Монику
44

Используйте эти два шага в консоли:

git commit --amend -m "new commit message"

а потом

git push -f

Выполнено :)

Абдул Ризван
источник
Спасибо, это шаги только для внесения поправок в последний комментарий, или его можно использовать и для старых комментариев?
Джей
@ Извините за поздний ответ, эти шаги только для внесения изменений в последнее сообщение о коммите.
Абдул Ризван
19

Следует отметить, что если вы используете push --forceс несколькими ссылками, они ВСЕ будут изменены в результате. Обязательно обратите внимание на то, где настроено ваше git-репо. К счастью, есть способ немного защитить процесс, указав одну ветвь для обновления. Читайте со страниц руководства пользователя git:

Обратите внимание, что --force применяется ко всем ссылкам, которые передаются, следовательно, используя его с push.default, установленным на совпадение, или с несколькими назначениями push, настроенными с удаленным. *. Push может перезаписывать ссылки, отличные от текущей ветви (включая локальные ссылки, которые строго за своим удаленным коллегой). Чтобы принудительно нажать только одну ветвь, используйте + перед refspec для push (например, git push origin + master, чтобы принудительно нажать на главную ветвь).

Стив Беннер
источник
3
Очень важное замечание.
Петер - Восстановить Монику
ни один из силовых ответов не работает для меня, потому что у меня нет прав ForcePush на сервере. Вместо этого я хочу выполнить коммит, который изменяет предыдущее сообщение коммита. Я мог бы написать «сообщение коммита изменено» в разделе комментариев этого коммита.
nurettin
11

Если вы хотите изменить старый коммит, а не последний, вам нужно будет использовать rebaseкоманду, как описано здесь, на странице справки Github , в разделе « Изменение сообщения старых или нескольких сообщений коммита ».

Carlos
источник
11

Команда 1 .

git commit --amend -m "New and correct message"

Затем,

Команда 2 .

git push origin --force
Тео Чунг Пинг
источник
8
git commit --amend

затем отредактируйте и измените сообщение в текущем окне. После этого делай

git push --force-with-lease
Beu
источник
2

Другой вариант - создать дополнительную «фиксацию ошибок» (и push), которая ссылается на объект фиксации, содержащий ошибку - новая фиксация ошибок также обеспечивает исправление. Ошибочная фиксация - это фиксация без существенных изменений кода, но с важным сообщением о фиксации - например, добавьте один пробел в ваш файл readme и зафиксируйте это изменение с важным сообщением фиксации или используйте опцию git --allow-empty. Это, конечно, проще и безопаснее, чем перебазирование, оно не изменяет истинную историю и сохраняет дерево ветвей чистым (используяamendтакже является хорошим выбором, если вы исправляете самый последний коммит, но ошибочный коммит может быть хорошим выбором для более старых коммитов). Этот тип вещей случается так редко, что достаточно просто документировать ошибку. В будущем, если вам потребуется выполнить поиск в журнале git по ключевому слову функции, оригинальная (ошибочная) фиксация может не появиться, поскольку в этой оригинальной фиксации использовалось неверное ключевое слово (оригинальная опечатка) - однако ключевое слово появится в сообщении об ошибке, которое затем укажет вам исходный коммит с опечаткой. Вот пример:

$ git log
commit 0c28141c68adae276840f17ccd4766542c33cf1d
Автор: Первый Последний 
Дата: ср. 8 августа 15:55:52 2018 -0600

    Ошибочные коммиты:
    Этот коммит не имеет существенного изменения кода.
    Этот коммит предоставляется только для документирования исправления к предыдущему сообщению коммита.
    Это относится к фиксации объекта e083a7abd8deb5776cb304fa13731a4182a24be1
    Исходное неверное сообщение о коммите:
        Изменен цвет фона на красный
    Исправление (* изменение выделено *):
        Изменен цвет фона на * синий *

commit 032d0ff0601bff79bdef3c6f0a02ebfa061c4ad4
Автор: Первый Последний 
Дата: ср. 8 августа 15:43:16 2018 -0600

    Некоторое временное сообщение о коммите

commit e083a7abd8deb5776cb304fa13731a4182a24be1
Автор: Первый Последний 
Дата: ср. 8 августа 13:31:32 2018 -0600

    Изменен цвет фона на красный
rob_7cc
источник
грабить, это выглядит многообещающе. Можете ли вы показать команды, необходимые для выполнения "исправления ошибок". только этот пост отображается в Google на этих условиях.
Джим
1
«Ошибочный коммит» - это просто обычный коммит с сообщением, которое ссылается на предыдущий ошибочный коммит, документируя и предоставляя исправление предыдущей ошибки. git commit -m “fixed feature A”(Предположим, что git присваивает этому идентификатору фиксации e3ab7312 ... ... (позже вы поймете, что ваше сообщение было неверным, поэтому внесите несущественное изменение в файл, например добавьте пробел в файл readme, или воспользуйтесь параметром —allow-emptygit). .. git commit -m “Errata commit for previous commit e3ab7312... original message should have been ‘fixed feature *B*’'' '
rob_7cc
1
... если вам позже понадобится найти в журнале git ссылки на «функцию B», появится сообщение об ошибке, но сообщение об ошибке содержит ссылку на исходный идентификатор фиксации, который обеспечивает полную отслеживаемость. Кстати, термин «errata commit» не является чем-то особенным (в git нет ни команды «errata», ни опции) ... это всего лишь моя терминология для обычного коммита, который обеспечивает исправление предыдущего коммита с ошибкой / опечаткой.
rob_7cc
грабить, это отлично сработало. Я смог добавить новый пустой коммит с правильным описанием, который указывает на исходный коммит, используя SHA. теперь оба показаны в моей «цепочке мерзавцев» для модулей. Спасибо!
Джим
Я рад, что это сработало для вас. Я использую ту же технику для исправления ошибок в сообщениях коммитов. Как альтернатива, я только недавно обнаружил, что git notes это будет служить той же цели, что и «ошибочный коммит». Просто добавьте примечание к предыдущему коммиту, чтобы комментировать или исправлять любые ошибки в сообщении о https://git-scm.com/docs/git-notes
коммите
0

Это работает для меня довольно хорошо,

git checkout origin / branchname

если вы уже в ветке то лучше сделать тянуть или ребазировать

git pull

или

git -c core.quotepath=false fetch origin --progress --prune

Позже вы можете просто использовать

git commit --amend -m "Your message here"

или если вы хотите открыть текстовый редактор, используйте

git commit --amend

Я предпочту использовать текстовый редактор, если у вас много комментариев. Вы можете установить предпочитаемый текстовый редактор с помощью команды

git config --global core.editor your_preffered_editor_here

В любом случае, когда вы закончите изменять сообщение коммита, сохраните его и выйдите

а потом беги

git push --force

И вы сделали

Hasasn
источник
0

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

отредактируйте ваше сообщение

git commit --amend

подтолкнуть к разрыву

git push --force <repository> <branch>

затем добавьте --force к вашей команде push на конвейере

git ftp push --force

Это удалит ваш предыдущий коммит (ы) и подтолкнет ваш текущий.

удалить --force после первого нажатия

я попробовал это на конвейере bitbucket и он работает нормально

Абдалла Аввад Альхвалда
источник