2015-07-04 2 views
17

У меня есть простая проблема. Я случайно сделал фиксацию в моем локальном репозитории. Я не толкал или не тянул, или что-то еще с момента совершения. Как мне отменить эту фиксацию и вернуть рабочую копию в состояние, которое было до совершения, поэтому я могу сделать то, что должен был сделать?Mercurial: как отменить последний разблокированный коммит?

Вы можете подозревать, что это дубликат, поэтому я объясню, почему следующие вопросы разные, или не ответили на мой вопрос:

Mercurial undo last commit

Ответ на это один гласит, что вы можете сделать это с hg commit --amend, но не объясняет , как или привести пример этого. Помощник Меркураила не говорит мне об этом.

How do you "rollback" last commit on Mercurial?

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

Edit 1

Чтобы быть более конкретным, я совершил много изменений файлов, когда я действительно хочу им совершить по одному. Как мне вернуться, чтобы я мог это сделать?

ответ

23

Говоря на языке мерзавца, вы смотрите на git reset --mixed HEAD^
hard бы отменить изменения, делая свою работу «исчезает» (я предполагаю, что это не вариант)
soft бы отменить фиксацию, но сохранить ранее совершили больше файлов индексируется (то есть отслеживается)
mixed сохраняет ваши измененные файлы на месте, но сообщает индексу об отмене фиксации. в git-talk: git st скажет Changes not staged for commit

Как это сделать в меркуриальном/hg? Должно быть ответ в Mercurial (hg) equivalent of git reset (--mixed or --soft)

hg strip --keep --rev .
--keep: do not modify working directory during strip
--rev . (точка означает последнюю фиксацию.прочитать ответ sid0 в отношении потомков)

Смотрите также git-reset docs, Difference git reset soft/mixed, git/hg Command equivalence table

19

Хорошо, я думаю, я нашел ответ, это для того, чтобы расширение strip, и используйте следующую команду:

hg strip -r -1 --keep 

Это срывает последнюю версию из repostiory (-r -1 бит), и опция --keep означает, что в рабочую копию не внесены изменения. Таким образом, вы получаете рабочую копию точно так же, как и до фиксации, и никакой последней фиксации в репозитории.

Я не эксперт по ртути, поэтому используйте на свой страх и риск.

+3

1. JFYI '--keep' нужна только если вы изменили рабочий Dir и хотите, чтобы сохранить эти изменения. Если ты хочешь "...верните мою рабочую копию в состояние, которое было до фиксации », вы можете пропустить --keep 2.« Команда strip удаляет указанные изменения и все их потомки »- это ваше дело (удаление подсказки), это не имеет значения, но в общий случай индивидуальное удаление коммитов в середине истории может быть лучше с расширением 'histedit' –

+1

Ну, чтобы вернуть рабочую копию в состояние, которое было незадолго до моего совершения, важно, чтобы вы использовали' --keep', иначе вы возвращаются к предыдущему фиксации и не возвращаются к состоянию, которое было непосредственно перед этим фиксацией. – crobar

1

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

Шаг за шагом:

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> 

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

0

комментируя и разрабатывая сообщение @ crobar, причина в том, что символов недостаточно.

при совершении локального коммита (без нажатия), затем запустите hg strip -r -1 --keep, он удалит предыдущее commit AND и сохранит список файлов, ожидающих их отправки. в основном это полная отмена. , если я использую hg stripe -r -1 без --keep, он по-прежнему удаляет ваш предыдущий коммит. НО, когда я пытаюсь перечислить файлы, которые будут совершены, он не может найти изменения, поэтому я бы не рекомендовал это делать.

Если я сделаю фиксацию, тогда сделаю push (на удаленный), тогда сделаем hg strip -r -1 --keep, он делает именно то, что должен делать, НО, когда вы делаете еще одно коммит, а затем нажмите, он создает другую ветвь.

I.E. 

o----o----Branch(local) 
     \ 
     \ 
     --o----o----o----Branch(with previous push) 

мой источник/ссылка: тестирование этих сценариям

Смежные вопросы