Mercurial: как изменить последний коммит? - PullRequest
207 голосов
/ 18 ноября 2011

Я ищу ответную часть git commit --amend в Mercurial, то есть способ изменить коммит, с которым связана моя рабочая копия.Я заинтересован только в последнем коммите, а не в произвольном раннем коммите.

Требования к этой процедуре внесения изменений:

  • , если возможно, он не должен требоватьлюбые расширения.Он должен не требовать расширений не по умолчанию , то есть расширений, которые не поставляются с официальной установкой Mercurial.

  • , если обязательство по внесению изменений является одной из моих текущихветвь, не нужно создавать новую голову .Если фиксация не является заголовком, может быть создан новый заголовок.

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

Обновление (1):

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

Обновление (2):

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

Ответы [ 7 ]

284 голосов
/ 02 мая 2012

С выпуском Mercurial 2.2 вы можете использовать опцию --amend с hg commit, чтобы обновить последний коммит текущим рабочим каталогом

Из команды ссылка на строку :

Флаг --amend можно использовать для изменения родительского элемента рабочего каталога с помощью нового коммита, который содержит изменения в родительском элементе в дополнение к тем, о которых в настоящее время сообщает hgстатус, если есть.Старый коммит хранится в резервном пакете в .hg / strip-backup (см. Hg help bundle и hg help unbundle о том, как его восстановить).

Сообщение, пользователь и дата берутся из исправленного коммита, если толькоуказано.Если сообщение не указано в командной строке, редактор откроется с сообщением исправленного коммита.

Самое замечательное, что этот механизм "безопасен", поскольку он опирается наотносительно новая функция «Фазы» для предотвращения обновлений, которые могли бы изменить историю, которая уже была сделана доступной за пределами локального репозитория.

51 голосов
/ 18 ноября 2011

У вас есть 3 варианта редактирования коммитов в Mercurial:

  1. hg strip --keep --rev -1 отменить последний (1) коммит (ы), поэтому вы можете сделать это снова (см. этот ответ для получения дополнительной информации).

  2. Использование расширения MQ , поставляемого с Mercurial

  3. Даже если он не поставляется с Mercurial, расширение Histedit стоит упомянуть

Вы также можете заглянуть на страницу История редактирования вики Mercurial.

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

Я не очень знаком с командой git commit --amend, но AFAIK, Histedit - это то, что кажется самым близким подходом, но, к сожалению, оно не поставляется с Mercurial. MQ действительно сложен в использовании, но с ним можно делать практически все.

38 голосов
/ 04 января 2013

GUI эквивалент для hg commit --amend:

Это также работает из графического интерфейса TortoiseHG (я использую v2.5):

Перейдите в представление «Зафиксировать» или в представлении рабочей среды выберите запись «Рабочий каталог». Кнопка «Подтвердить» имеет параметр «Изменить текущую редакцию» (нажмите на стрелку раскрывающегося списка кнопки, чтобы найти ее).

enter image description here

          ||
          ||
          \/

enter image description here

Предостережение emptor :

Эта дополнительная опция будет включена, только если версия Mercurial по крайней мере 2.2.0, и если текущая ревизия не является общедоступной, не является патчем и не имеет дети. [...]

Нажатие на кнопку вызовет 'commit --amend' чтобы 'исправить' ревизию.

Подробнее об этом на канале разработчиков THG

7 голосов
/ 18 ноября 2011

Предполагая, что вы еще не распространили свои изменения, вот что вы можете сделать.

  • Добавьте к своему .hgrc:

    [extensions]
    mq =
    
  • В вашем хранилище:

    hg qimport -r0:tip
    hg qpop -a
    

    Конечно, вам не нужно начинать с нулевой ревизии или извлекать все патчи, поскольку достаточно только одного всплывающего окна (hg qpop) (см. Ниже).

  • удалите последнюю запись в файле .hg/patches/series или патчи, которые вам не нравятся. Переупорядочение тоже возможно.

  • hg qpush -a; hg qfinish -a
  • удалите файлы .diff (не примененные исправления), все еще находящиеся в .hg / patches (в вашем случае должен быть один).

Если вы не хотите от до забрать все вашего патча, вы можете отредактировать его с помощью hg qimport -r0:tip (или аналогичного), затем отредактировать материал и использовать hg qrefresh объединить изменения в самый верхний патч в вашем стеке. Читать hg help qrefresh.

Редактируя .hg/patches/series, вы даже можете удалить несколько патчей или изменить их порядок. Если ваша последняя ревизия - 99, вы можете просто использовать hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -a.

Конечно, эта процедура крайне не рекомендуется и рискованна . Сделайте резервную копию всего, прежде чем сделать это!

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

7 голосов
/ 18 ноября 2011

Я настраиваюсь на то, что написал krtek. Более конкретно решение 1:

Предположения:

  • вы зафиксировали один (!) Набор изменений, но еще не нажали его
  • вы хотите изменить этот набор изменений (например, добавить, удалить или изменить файлы и / или сообщение о коммите)

Решение:

  • используйте hg rollback, чтобы отменить последний коммит
  • зафиксировать снова с новыми изменениями на месте

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

2 голосов
/ 06 марта 2018

Последние версии Mercurial включают расширение evolve, которое предоставляет команду hg amend.Это позволяет вносить изменения в коммит, не теряя историю пред-изменений в вашем контроле версий.

hg поправить [ОПЦИЯ] ... [ФАЙЛ] ...

псевдонимы: обновить

объединить ревизию с обновлениями и заменить ее новой

Commits a new changeset incorporating both the changes to the given files
and all the changes from the current parent changeset into the repository.

See 'hg commit' for details about committing changes.

If you don't specify -m, the parent's message will be reused.

Behind the scenes, Mercurial first commits the update as a regular child
of the current parent. Then it creates a new commit on the parent's
parents with the updated contents. Then it changes the working copy parent
to this new combined changeset. Finally, the old changeset and its update
are hidden from 'hg log' (unless you use --hidden with log).

См. https://www.mercurial -scm.org / doc / evolution / user-guide.html# example-3 -mend-a-changeset-with-evolve для полного описания расширения evolve.

0 голосов
/ 03 июля 2019

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

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

hg commit -X 'glob:**' --amend

Без шаблонов включения или исключения hg commit по умолчанию включает все файлы в рабочем каталоге. Применение шаблона -X 'glob:**' исключит все возможные файлы, позволяя только изменять сообщение фиксации.

Функционально это то же самое, что и git commit --amend, когда нет файлов в индексе / рабочей области.

...