Ответ 1
hg update [-r REV]
Если позже вы зафиксируете, вы создадите новую ветку. Затем вы можете продолжать работать только на этой ветке или, в конечном счете, объединить существующий в нее.
Я использую Mercurial локально для проекта (это единственный репо, в котором нет нажатия/вытягивания в/из другого места).
На сегодняшний день он получил линейную историю. Тем не менее, текущая вещь, над которой я сейчас работаю, я понял, это ужасный подход, и я хочу вернуться к версии, прежде чем я ее запустил, и реализовать ее по-другому.
Я немного смущен командами branch
/revert
/update -C
в Mercurial. В основном я хочу вернуться к версии 38 (в настоящее время на 45), и мои следующие коммиты имеют 38 в качестве родителя и продолжаются оттуда. Мне все равно, если изменения 39-45 потеряны навсегда или попадут в тупиковую ветку.
Какую команду/набор команд мне нужно?
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
более явственно.
Я просто столкнулся с ситуацией, когда нужно было вернуть только один файл в предыдущую ревизию сразу после того, как я совершил фиксацию и нажатие. Синтаксис коротких строк для указания этих ревизий не покрывается другими ответами, поэтому здесь выполните команду
hg revert path/to/file -r-2
То, что -2
вернется к версии до последнего фиксации, используя -1
, просто вернет текущие незафиксированные изменения.
IMHO, 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) и использовал это. Затем вы можете просто щелкнуть правой кнопкой мыши на ревизии, которую вы, возможно, захотите вернуться, - со всеми сообщениями фиксации там перед вашими глазами и "Восстановить все файлы". Делает его интуитивно понятным и легко откатывается назад и вперед между версиями набора файлов, что может быть действительно полезно, если вы хотите установить, когда возникла проблема.