Mercurial Отменить слияние
Есть сценарий, где мы намеренно объединили именованную ветку (ABC
) в наш default
ветка.
hg rollback
это не вариант, потому что с тех пор было несколько коммитов.
Есть ли способ отменить это?
4 ответа
Если вы не опубликовали репо публично, вы можете сделать это
hg clone -r (parent1 of bad merge) -r (parent2 of bad merge) old new
и удалите старый репо.
Вам понадобится расширение Mq. Если он не включен, сделайте это, добавив его в свой Mercurial.ini
или же .hgrc
файл.
[extensions]
hgext.mq=
Если вы не знакомы с ним, расширение Mq позволяет вам манипулировать историей. Хорошей новостью является то, что это позволит нам исправить ваше репо. Плохая новость заключается в том, что любому, у кого есть клон испорченного репо, придется его клонировать снова, потому что мы будем менять историю.
Во-первых, сделайте еще один клон вашего репо, чтобы мы ничего не испортили.
Теперь найдите идентификатор ревизии набора изменений слияния (который слился default
и ваша названная ветка). Запиши это. Мы будем ссылаться на это как changesetM
, Теперь найдите идентификатор ревизии следующего набора изменений. Запиши это. Мы будем ссылаться на это как changesetN
,
Когда у вас есть эти два идентификатора ревизии, перейдите в командную строку и cd
в ваш репо. Затем введите следующее, заменив changeset[M|N]
с соответствующим идентификатором ревизии:
$ hg qimport -r changesetN:tip
# This will add all of your changes since the merge to the queue
$ hg qpop -a
# This pops them all out of your history.
$ hg strip changesetM
# This removes the merge changeset.
$ hg update -C default
# Make sure we're on the default branch
$ hg qpush -a
# Take the changesets in the queue and push them back onto your history.
$ hg qfinish -a
# Remove changesets from the queue and finalize them as normal changesets.
По сути, вы перебираете новые наборы изменений поверх ветви по умолчанию, удаляя набор изменений в процессе. Когда вы закончите, вам нужно будет отправить изменения в новый репозиторий на сервере, и ваши коллеги будут клонировать свежие копии.
Наконец, если у вас есть другие вопросы по Mercurial, также http://kiln.stackexchange.com/.
ОБНОВИТЬ
Я забыл упомянуть: если кто-то основал изменения на чем-то, что было только в другой ветке, возможно, что hg qpush -a
не удастся. Вы увидите foo.txt.rej
а также foo.txt.orig
файл лежал вокруг. К сожалению, вам придется исправить это самостоятельно. Чтобы исправить это, откройте оригинальный файл, .orig
файл, а .rej
выберите нужные изменения, чтобы сохранить их в исходном файле. После слияния используйте hg qrefresh
обновить этот патч до нового, объединенного патча. От их, вы должны быть в состоянии бежать hg qpush -a
снова и продолжим. Если вы снова столкнетесь с той же ошибкой в другом патче, просто следуйте тому же процессу.
Я столкнулся со следующим сценарием сегодня:
@ changeset: 1728:5d703e1051d3
|\ parent: 1727:1a5f73b5edb4
| | parent: 1720:65ddd0bde225
| | user: nn
| | date: Wed Feb 27 10:35:00 2013 +0100
| | summary: Merge with SomeBranch
| |
| o changeset: 1727:1a5f73b5edb4
| | user: nn
| | date: Wed Feb 27 10:34:30 2013 +0100
| | summary: lorem ipsum
| |
[some more changesets]
| |
o | changeset: 1720:65ddd0bde225
| | branch: SomeBranch
| | user: nn
| | date: Wed Feb 27 07:44:46 2013 +0100
| | summary: lorem ipsum
Где SomeBranch не должен был быть объединен с дефолтом. Чтобы решить эту проблему, мы использовали backout
команда с parent
вариант вот так:
hg backout --rev=1728 --parent=1727
Этим вы не отменяете само слияние: при просмотре графа ветвей (либо с журналом графа, либо в TortoiseHg) вы все равно увидите, что SomeBranch переходит в состояние по умолчанию на r1728. Однако результат объединения отменяется, что означает, что набор изменений, содержащий отказ (r1729 в моем случае), идентичен r1727.