Mercurial - вернуться к старой версии и продолжить оттуда - PullRequest
248 голосов
/ 29 марта 2010

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

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

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

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

Ответы [ 7 ]

397 голосов
/ 02 апреля 2010

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

  • 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 является более явным.

147 голосов
/ 29 марта 2010
hg update [-r REV]

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

29 голосов
/ 09 апреля 2013

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

hg revert path/to/file -r-2

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

7 голосов
/ 14 октября 2013

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

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

6 голосов
/ 17 августа 2013

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

Если вы просто попытаетесь зафиксировать после обновления, Mercurial не подумает, что есть какие-либо изменения.

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

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

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

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

5 голосов
/ 25 марта 2016

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

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

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

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

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

1 голос
/ 26 октября 2017

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

...