Mercurial - вернуться к старой версии и продолжить оттуда

Я использую Mercurial локально для проекта (это единственное репо, в котором нет выталкивания / вытягивания в / из другого места).

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

Меня немного смущают команды branch / revert / update -C в Mercurial. В основном я хочу вернуться к версии 38 (в настоящее время на 45), и мои следующие коммиты будут иметь 38 в качестве родителя и продолжить оттуда. Меня не волнует, что ревизии 39-45 потеряны навсегда или окажутся в собственной тупиковой ветке.

Какая команда / набор команд мне нужна?


person Paolo    schedule 29.03.2010    source источник
comment
Для всех, кого это интересует, это появилось на соответствующей боковой панели, что является отличным объяснением возврата и обновления: stackoverflow.com/questions/2506803/   -  person Paolo    schedule 29.03.2010


Ответы (7)


hg update [-r REV]

Если позже вы сделаете коммит, вы фактически создадите новую ветку. Тогда вы можете продолжить работу только с этой веткой или со временем объединить с ней существующую.

person van    schedule 29.03.2010
comment
следующая фиксация создаст новую ветку. Если вы не уверены, просто сделайте резервную копию своего репозитория (с рабочей копией), попробуйте - результат не нравится - ›начните с нуля бесплатно - person van; 29.03.2010
comment
Это сомнительный ответ, поскольку он объединяет ваши текущие изменения со старой версией, чего, вероятно, вы не хотите делать. Правильный ответ должен быть hg revert. - person Trevor de Koekkoek; 03.11.2014
comment
Ответ хорош, за исключением бит о слиянии (я не думаю, что спрашивающий захочет слить). - person ctrl-alt-delor; 23.04.2016
comment
@NeonWarge REV - это просто заполнитель для версии. Это может быть его номер, его хеш, закладка и так далее. Тревор: это не сомнительно, потому что ничего не объединяет. Не нужно. - person DanMan; 23.07.2016

Вот шпаргалка по командам:

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

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

  • hg branch запускает новую именованную ветку. Думайте об именованной ветке как о метке, которую вы назначаете ревизиям. Так что если вы сделаете hg branch red, то следующие ревизии будут отмечены как принадлежащие "красной" ветке. Это может быть хорошим способом организовать ревизии, особенно когда разные люди работают над разными ветвями, и вы позже захотите увидеть, откуда произошла ревизия. Но вы не хотите использовать его в своей ситуации.

Если вы используете hg update --rev 38, то изменения 39–45 останутся тупиком - болтающейся головой, как мы это называем. При отправке вы получите предупреждение, так как вы будете создавать «несколько голов» в репозитории, в который отправляете. Предупреждение есть, потому что оставлять такие головы невежливо, поскольку они предполагают, что кому-то нужно выполнить слияние. Но в вашем случае вы можете просто пойти и hg push --force, так как вы действительно хотите оставить это висеть.

Если вы еще не разместили ревизию 39-45 где-то еще, вы можете оставить их в секрете. Это очень просто: с hg clone --rev 38 foo foo-38 вы получите новый локальный клон, который содержит только до версии 38. Вы можете продолжить работу в foo-38 и продвигать новые (хорошие) наборы изменений, которые вы создаете. У вас останутся старые (плохие) версии в вашем foo клоне. (Вы можете переименовывать клоны по своему усмотрению, например, foo на foo-bad и foo-38 на foo.)

Наконец, вы также можете использовать hg revert --all --rev 38, а затем выполнить фиксацию. Это создаст ревизию 46, которая выглядит идентично ревизии 38. Затем вы продолжите работу с ревизии 46. Это не создаст вилку в истории таким же явным образом, как это сделал hg update, но, с другой стороны, вы не получите жалоб на имея несколько голов. Я бы использовал hg revert, если бы я сотрудничал с другими, которые уже сделали свою собственную работу на основе ревизии 45. В противном случае hg update является более явным.

person Martin Geisler    schedule 02.04.2010
comment
УДИВИТЕЛЬНЫЙ ответ. Я использовал hg revert --all --rev ##, и это спасло мою задницу: D - person Van Thoai Nguyen; 30.05.2012
comment
Не лучше ли также закрыть ветвь болтающейся головы? Это предотвратит появление предупреждений в репозитории в будущем. См. stackoverflow.com/a/3688320/900130 - person Zoltán; 10.09.2014
comment
примечание: hg revert --all --rev xxx изменит локальные файлы, необходимые для возврата из того места, где вы находитесь в локальном репо. Таким образом, вам нужно обновить до того места, с которого вы хотите вернуться. - person Vincent; 03.05.2017
comment
Чтобы перейти к более ранней версии, мне сначала пришлось сделать откат, а затем выполнить обновление. Это, как говорится, менее непрозрачное объяснение, чем большинство других. - person CodeLurker; 10.03.2019

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

hg revert path/to/file -r-2

Этот -2 вернется к версии перед последней фиксацией, использование -1 просто вернет текущие незафиксированные изменения.

person hyde    schedule 09.04.2013
comment
Я считаю это чрезвычайно полезным. Конечно, для опции -r вы можете просто указать номер версии - person Alex; 10.12.2013
comment
Вы также можете выбрать конкретную версию. например hg revert path/to/file -r478 - person hookenz; 04.09.2019

ИМХО, hg strip -r 39 этот случай лучше подходит.

Он требует включения расширения mq и имеет те же ограничения, что и «метод клонирования репо», рекомендованный Мартином Гейслером: если набор изменений был каким-то образом опубликован, он (вероятно) вернется в ваше репо в какой-то момент времени, потому что вы только изменили ваше местное репо.

person magras    schedule 14.10.2013
comment
Не знал об этом. Легче и чище, чем удаление и повторное клонирование репо. Спасибо. - person Reinstate Monica -- notmaynard; 31.12.2014

После использования hg update -r REV в ответе не было ясно, как зафиксировать это изменение, чтобы затем можно было нажать.

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

Мне нужно было сначала внести изменения в любой файл (скажем, в README), чтобы Mercurial распознал, что я сделал новое изменение, а затем я мог это зафиксировать.

Затем были созданы две головы, как уже упоминалось.

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

Тогда я смог толкнуть.

person Brian Gershon    schedule 16.08.2013
comment
вы можете сделать commit --close-branch на старой ветке. Вы также можете push -f вставлять новые головы, но это может вызвать путаницу относительно того, какая из них текущая. - person ctrl-alt-delor; 23.04.2016

Приведенные выше ответы были очень полезны, и я многому научился. Однако для моих нужд краткий ответ:

hg revert --all --rev ${1}

hg commit -m "Restoring branch ${1} as default"

где ${1} - номер ревизии или имя ветки. Эти две строки на самом деле являются частью сценария bash, но они отлично работают сами по себе, если вы хотите сделать это вручную.

Это полезно, если вам нужно добавить оперативное исправление в ветку выпуска, но нужно выполнить сборку по умолчанию (до тех пор, пока мы не получим правильные инструменты CI и не сможем строить из веток, а позже также покончим с ветвями выпуска).

person Brian Carr    schedule 25.03.2016

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

person Geoff Kendall    schedule 26.10.2017