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

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

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

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

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

7 ответов

Решение
hg update [-r REV]

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

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

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

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

hg revert path/to/file -r-2

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

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

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

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

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

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

Это тогда создало две головы как упомянуто.

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

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

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

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

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

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

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

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

Другие вопросы по тегам