git: отменить фиксацию в середине ввода сообщения

132

Я в процессе совершения. Я набрал сообщение о фиксации в vim. Теперь я вспомнил, что мне нужно что-то изменить. Я понимаю, что есть и другие варианты выполнения того, что я хочу, но я хочу знать, есть ли способ прервать фиксацию, но все же сохранить сообщение фиксации, которое я набрал до сих пор.

Александр Берд
источник

Ответы:

85

Да. Запишите сообщение фиксации в другой файл ( :w /some/other/path.txt). Затем выйдите из редактора без сохранения ( :q!). Если вы ранее сохранили файл по исходному пути, удалите все и сначала запишите пустой файл (пустое сообщение о фиксации прервет фиксацию).

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

Или скопируйте сообщение фиксации в один из буферов vim.

Стоит отметить, что на самом деле вам вообще не нужно этого делать : commit --amendпозволяет изменить фиксацию после того, как она была сделана, поэтому простое решение - создать фиксацию с тем, что у вас есть, а затем исправить ее перед нажатием. Вы даже можете просто завершить фиксацию в ее прерванном состоянии reset HEAD~(сбрасывает вас в состояние, в котором ваша рабочая копия была до фиксации), исправить свою рабочую копию, а затем commit -a -c HEAD@{1}использовать старое сообщение фиксации.

Borealid
источник
7
Примечание: выход из vim с помощью ": q!" не прерывает фиксацию, если есть автоматически заполненное сообщение о конфликте слияния. Вместо этого фиксация будет продолжена, и в сообщении не будет указано, какие файлы имели конфликты.
Стивенбез
write the empty file (an empty commit message will abort the commit)часть работала как шарм, спасибо!
Саша Давиденко
184

Если ваш редактор может выйти с кодом ошибки - Git прервет фиксацию. При использовании VIM введите

:cq

для выхода с ненулевым кодом ошибки и прерывания фиксации.

nimrodm
источник
5
Это хороший трюк для прерывания, commit --amendпоскольку в противном случае вам пришлось бы удалить существующее сообщение фиксации и :wq.
Alex Jasmin
2
Хороший трюк! Однако вопрос был в том, как сохранить сообщение фиксации, а не удалить его.
Элайджа Линн
так как же svn это удается? на что он смотрит, кроме кода выхода?
Хаим Герец
1
отлично, когда вы делаете интерактивную перебазировку,
известную как сжатие коммитов
спас мою жизнь, когда я сделал git commit --amendвместо git rebase --continueво время перебазирования.
Weishi Zeng
68

Если у вас открыт vim для записи сообщения о фиксации, просто удалите строки, которые не начинаются с символа #, и git прервет вашу фиксацию.

Aborting commit due to empty commit message.
зетта
источник
11
Это особенно полезно, если вы хотите прервать git commit --amend.
edsko
1
Вопрос был в том, как прервать фиксацию, но сохранить сообщение фиксации. Удаление строк, которые не начинаются с символа #, эффективно удаляет сообщение фиксации, но не сохраняет сообщение фиксации. Не знаю, откуда так много голосов.
Элайджа Линн
2
ggdGбудет вырезать все содержимое сообщения, а затем при следующем запуске vimвы можете только Pтекст, который вы ранее вырезали.
oromoiluig
работает с использованием nano, ctrl + k во всех строках, затем сохранение и выход
прервутся
9

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

bdonlan
источник
7

Да, это возможно. Для фиксации ваш редактор ДОЛЖЕН записать сообщение фиксации в файл .git/COMMIT_EDITMSGи выйти с кодом состояния 0.

Итак, если вы используете VI / VIM, вы можете сделать следующее ...

  1. Напишите сообщение о фиксации.
  2. Сохраните сообщение фиксации с помощью :w(по умолчанию это сохранит текущий контент в .git/COMMIT_EDITMSG)
  3. Выйти из редактора с ошибкой :cq
  4. ... делайте то, что вам нужно ... даже добавляйте / удаляйте файлы в промежуточную область.
  5. Продолжайте редактировать существующее сообщение фиксации с помощью git commit -eF .git/COMMIT_MESSAGE

Он -F /path/to/fileзаполнит редактор любым заданным содержимым из / path / to / file. Однако по умолчанию это немедленно выполнит фиксацию, если вы не предоставите -eфлаг дополнительно для редактирования .

Рудольф Тучек
источник
это работает, но менее предпочтительно, потому что 1) предполагается, что CWD находится там, где находится папка .git. 2) Я использую git worktrees , а с git worktrees .git на самом деле является файлом, указывающим, где находится настоящая папка .git.
Александр Берд
@AlexanderBird, это неправда ... когда вы хотите забрать старое сообщение фиксации на шаге 5), вам просто нужно указать относительный путь (скажем, вы находитесь в /foo/bar/каталоге, относительном от корня проекта), напримерgit commit -eF ../../.git/COMMIT_MESSAGE
Рудольф Тучек
@AlexanderBird круто, еще не заметил с функцией нескольких рабочих деревьев в git. Спасибо за подсказку! Я считаю, что единственным недостатком этого является то, что вам придется держать в голове общий обзор, который не позволяет вам сосредоточиться на реальном коде. И просто для того, чтобы подобрать сообщение о фиксации на «с того места, где я остановился», это немного тяжеловато :)
Рудольф Тучек
1
@AlexanderBird тогда вместо :wdo :sav committmpandgit commit -eF committmp
Hashbrown
0

Обычно я делаю коммиты, IntelliJиспользуя предоставленные терминалы. К сожалению, мои коммиты выполняются вручную:

git commit -m'my message' // etc

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

SovietFrontier
источник
-2

Ответ @bdonlan хорош именно для этого вопроса, но я укажу на ситуацию, когда вам может потребоваться лучшее решение.

Допустим, вы хотите добавить изменения в последнюю фиксацию. Итак, вы делаете, как предложил @bdolan:

git add files
git commit --amend

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

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

Aborting commit due to empty commit message.

И вы вообще не изменили последний коммит.

Дорон Бехар
источник
Если я понимаю, что вы говорите, это проблема, значит, вы ошибаетесь; как показано здесь: git commit; vim ....; git commit --amend; git reset HEAD@{1}. То есть: если я хочу «отменить» поправку, мне не нужно разбивать предыдущую фиксацию. объект фиксации, который был HEAD до изменения, сохраняется как HEAD@{1}. Кроме того, zetta уже предложила удалить все строки без комментариев.
Александр Бёрд,