Mercurial: как отменить последний нефиксированный коммит?
Я случайно сделал коммит в свой локальный репозиторий. Чтобы быть более конкретным, я зафиксировал изменения во множестве файлов одновременно, когда я хотел зафиксировать их по одному.
Как мне отменить этот коммит и вернуть мою рабочую копию в состояние, в котором она была до коммита, чтобы я мог сделать то, что должен был сделать в первую очередь?
Я не толкнул или потянул или что-нибудь еще с момента совершения.
Вы можете подозревать, что это дубликат, поэтому я объясню, почему следующие вопросы отличаются, или не отвечу на мой вопрос:
Mercurial отменить последний коммит
Ответ на этот вопрос гласит, что вы можете сделать это с hg commit --amend
, но не объясняет, как или привести пример этого. Меркуриальная помощь не объясняет это и для меня.
Как вы "откатываете" последний коммит на Mercurial?
Штаты использовать hg rollback
, Эта команда явно устарела, я все равно пытался ее использовать, но получил сообщение: информация об откате недоступна. Жаль, что это не работает, поскольку это будет действительно интуитивно понятный способ достичь того, чего я хочу.
4 ответа
Основываясь на информации из этого вопроса:
hg strip --keep --rev .
--keep: do not modify working directory during strip
--rev .
(точка обозначает последний коммит. прочитайте ответ sid0 относительно потомков)
Для людей, более знакомых с языком git, вы ищете git reset --mixed HEAD^
hard
что бы отменить ваши изменения, заставив вашу работу "исчезнуть" (я полагаю, что это не вариант)
soft
отменяет фиксацию, но сохраняет индексируемые ранее зафиксированные файлы (то есть отслеживаемые)
mixed
сохраняет ваши измененные файлы на месте, но указывает индексу отменить фиксацию. в git-говорить: git st
я бы сказал Changes not staged for commit
См. Также git-reset docs, Разница git reset soft / mixed, git / hg Таблица эквивалентности команд
Хорошо, я думаю, что нашел ответ, это чтобы включить strip
расширение и используйте следующую команду:
hg strip -r -1 --keep
Это удаляет последнюю ревизию из хранилища (-r -1
немного), а --keep
опция означает, что в рабочую копию не вносятся изменения. Таким образом, вы получите рабочую копию в точности так, как это было непосредственно перед фиксацией, и никакой последней фиксации в хранилище.
Я не специалист по ртути, поэтому пользуйтесь на свой страх и риск.
Комментировать и уточнять причину сообщения @crobar # символов недостаточно.
когда делаете локальный коммит (без push), тогда запускаете hg strip -r -1 --keep
, он удаляет ваш предыдущий коммит и сохраняет ваш список файлов, ожидающих отправки. в основном это полная отмена. если я использую hg stripe -r -1
без --keep
, он по-прежнему удаляет ваш предыдущий коммит, НО, когда я пытаюсь перечислить файлы для фиксации, он не может найти изменения, поэтому я бы не рекомендовал делать это.
если я сделаю коммит, сделайте толчок (к удаленному), затем сделайте hg strip -r -1 --keep
, он делает именно то, что должен делать, НО, когда вы делаете еще один коммит и затем нажимаете, он создает другую ветвь.
I.E.
o----o----Branch(local)
\
\
--o----o----o----Branch(with previous push)
мой источник / ссылка: тестирование этих сценариев
В этой ситуации я бы сделал новую ветвь с нужными мне изменениями, прежде чем я думал об удалении неправильного набора изменений. Поэтому в этом случае мне нужно вернуться к ревизии до того, как я сделал неправильный коммит, заново сделать свои изменения и затем сделать несколько коммитов, по одному для каждого файла.
Шаг за шагом:
1) Вернитесь до плохого коммита.
% cd <top of repo>
% hg log -l 5
<identify the last good revision>
% hg update -r <last good revision number>
2) Переделать изменения: я получу патч, который описывает изменения, которые я хочу, и применю его к дереву. (Я предполагаю, что совет в настоящее время указывает, где мы начали)
% hg diff -r .:tip | patch -p1
patching file a/b/c/d
patching file a/b/e/f
3) Сделайте новые коммиты: мы вернулись в состояние до того, как вы сделали коммит, который вы хотели разделить. Делать hg status
и посмотрите на измененные файлы, убедитесь, что все так, как вы ожидаете. На этом этапе вы можете либо зафиксировать файлы один за другим, назвав их в командной строке, или использовать расширение вроде record
или же crecord
интерактивно выбрать их.
% hg commit a/b/c/d
% hg commit a/b/e/f
...или же...
% hg crecord
<select files in UI>
% hg crecord
<select files in UI>
В итоге вы получите репо, которое выглядит так:
o----o----B
\
\
--o----o----o----T
Где B - старый плохой коммит, а T - новый совет репо. Если вы хотите сделать эту ветку закрытой, чтобы она не отображалась в журналах и т. Д., Вы можете...
% hg update -r <revision B>
% hg commit --close_branch
% hg update -r tip
Если вы хотите полностью удалить его, вы можете удалить его.
% hg strip -r <revision B>
В любом случае, ваш журнал будет выглядеть так, как будто ничего не произошло.