Mercurial: как изменить последний коммит?
Я ищу ответную часть git commit --amend
в Mercurial, то есть способ изменить коммит, с которым связана моя рабочая копия. Требования к этой процедуре внесения поправок:
если возможно, он не должен требовать каких-либо расширений. Он не должен требовать расширений не по умолчанию, то есть расширений, которые не поставляются с официальной установкой Mercurial.
если обязательство по изменению является одним из руководителей моего текущего филиала, новый руководитель создавать не следует. Если фиксация не является заголовком, может быть создан новый заголовок.
процедура должна быть безопасной, так что если по каким-либо причинам изменение не удастся, я хочу восстановить ту же рабочую копию и состояние хранилища, что и до внесения изменений. Другими словами, если само изменение может потерпеть неудачу, должна существовать отказоустойчивая процедура для восстановления рабочей копии и состояния хранилища. Я имею в виду "сбои", которые лежат в природе процедуры внесения изменений (например, конфликты), а не проблемы, связанные с файловой системой (например, ограничения доступа, невозможность заблокировать файл для записи, ...)
Обновление (1):
- процедура должна быть автоматизируемой, поэтому она может выполняться клиентом с графическим интерфейсом без какого-либо вмешательства пользователя.
Обновление (2):
- файлы в рабочем каталоге не должны быть затронуты (могут быть блокировки файловой системы на некоторых измененных файлах). Это особенно означает, что возможный подход ни в коем случае не может требовать чистого рабочего каталога.
6 ответов
С выпуском Mercurial 2.2 вы можете использовать --amend
вариант с hg commit
обновить последний коммит текущим рабочим каталогом
Флаг --amend может использоваться для изменения родительского элемента рабочего каталога новым коммитом, который содержит изменения в родительском элементе в дополнение к тем, о которых в настоящее время сообщает hg status, если они есть. Старый коммит хранится в резервном пакете в.hg/strip-backup (см. Hg help bundle и hg help unbundle о том, как его восстановить).
Сообщение, пользователь и дата взяты из исправленного коммита, если не указано иное. Если сообщение не указано в командной строке, редактор откроется с сообщением исправленного коммита.
Самое замечательное в том, что этот механизм является "безопасным", поскольку он опирается на относительно новую функцию "Фазы" для предотвращения обновлений, которые могли бы изменить историю, которая уже стала доступной за пределами локального репозитория.
У вас есть 3 варианта редактирования коммитов в Mercurial:
hg strip --keep --rev -1
отмените последний (1) коммит (ы), так что вы можете сделать это снова (см. этот ответ для получения дополнительной информации).Использование расширения MQ, которое поставляется с Mercurial
Даже если он не поставляется с Mercurial, расширение Histedit стоит упомянуть
Вы также можете посмотреть страницу истории редактирования вики Mercurial.
Короче говоря, редактирование истории действительно сложно и не рекомендуется. И если вы уже отодвинули свои изменения, вы ничего не можете сделать, кроме как, если вы полностью контролируете все остальные клоны.
Я не очень знаком с git commit --amend
Команда, но AFAIK, Histedit - это то, что кажется самым близким подходом, но, к сожалению, он не поставляется с Mercurial. MQ действительно сложен в использовании, но вы можете делать с ним почти все.
GUI эквивалент для hg commit --amend
:
Это также работает из графического интерфейса TortoiseHG (я использую v2.5):
Перейдите к представлению "Зафиксировать" или в представлении рабочей среды выберите запись "Рабочий каталог". Кнопка "Подтвердить" имеет параметр "Изменить текущую редакцию" (нажмите на стрелку раскрывающегося списка кнопки, чтобы найти ее).
||
||
\/
Будьте бдительны:
Эта дополнительная опция будет включена, только если версия mercurial имеет версию не ниже 2.2.0, а текущая версия не является публичной, не является патчем и не имеет дочерних элементов. [...]
Нажатие на кнопку вызовет 'commit --amend', чтобы "изменить" ревизию.
Подробнее об этом на канале разработчиков THG
Я настраиваюсь на то, что написал Кртек. Более конкретно решение 1:
Предположения:
- Вы совершили одну (!) ревизию, но еще не добавили ее
- Вы хотите изменить этот набор изменений (например, добавить, удалить или изменить файлы и / или сообщение о коммите)
Решение:
- использование
hg rollback
отменить последний коммит - совершить снова с новыми изменениями на месте
Откат действительно отменяет последнюю операцию. Его способ работы довольно прост: обычные операции в HG будут добавлять только файлы; это включает в себя фиксацию. Mercurial отслеживает длины файлов последней транзакции и поэтому может полностью отменить один шаг, обрезав файлы до их старых длин.
Предполагая, что вы еще не распространили свои изменения, вот что вы можете сделать.
Добавьте к вашему.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
,
Конечно, эта процедура крайне не рекомендуется и рискованно. Сделайте резервную копию всего, прежде чем сделать это!
Как заметка, я делал это миллионы раз на частных репозиториях.
Последние версии 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 для полного описания evolve
расширение.
Может не решить всех проблем в исходном вопросе, но поскольку это, кажется, де-факто сообщение о том, как Mercurial может изменить предыдущий коммит, я добавлю информацию на 2 цента.
Если вы похожи на меня и хотите изменить предыдущее сообщение фиксации (исправить опечатку и т. Д.), Не добавляя никаких файлов, это сработает.
hg commit -X 'glob:**' --amend
Без каких-либо шаблонов включения или исключения hg commit
по умолчанию будет включать все файлы в рабочий каталог. Применение выкройки-X 'glob:**'
исключит все возможные файлы, позволяя только изменить сообщение фиксации.
Функционально он такой же, как git commit --amend
когда в index/stage нет файлов.
Другим решением может быть использование uncommit
команда для исключения определенного файла из текущего коммита.
hg uncommit [file/directory]
Это очень полезно, если вы хотите сохранить текущую фиксацию и отменить выбор некоторых файлов из фиксации (особенно полезно для files/directories
были удалены).