Как отменить несколько коммитов в Mercurial?

У меня есть куча коммитов, скажем, A, B, C, D, и я хочу сохранить B, C и D и сделать коммит (BCD)⁻¹. Как проще всего это сделать, если у меня много коммитов, которые я хочу отменить одновременно?

(Кажется, я припоминаю, что видел вопрос об этом в stackoverflow, в котором предлагалось hg update перейти к A, а затем вызвать hg commit с некоторыми аргументами, но сейчас я не могу найти этот вопрос.)


person Jason Gross    schedule 23.07.2012    source источник


Ответы (3)


Похоже, вы ищете backout. Видеть:

hg help backout

Я не думаю, что он может отменить несколько коммитов за один раз, поэтому вам нужно отменить их по отдельности:

hg backout D
hg backout C
hg backout B

Это создаст три коммита поверх D, которые обратны D, C и B. Если вы хотите объединить эти коммиты в один набор изменений, вы можете свернуть их, используя rebase --collapse или одно из ряда других расширений (например, расширения histedit или mq или collapse).

Если вы не хотите отменять отдельные изменения, а хотите сделать все за один раз, вы можете сделать следующее:

hg update A
hg debugsetparents D
hg commit -m "revert B-D"

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

В качестве альтернативы вы можете поступить так, как предложили Джим и Рафаэль, и решить, что B, C и D находятся в ветке, обновиться до A и продолжить фиксацию там (отделив историю в этот момент). Это может быть более подходящим.

person Laurens Holst    schedule 23.07.2012
comment
Это будет делать то, что я хочу (если я соединю три коммита вместе в mq), но станет громоздким, если есть, скажем, 50 коммитов, которые я хочу отменить. Я ищу что-то более близкое ко второй части принятого ответа в stackoverflow.com/questions/1463340/revert-multiple-git-commits (но для hg), то есть эквивалент hg для git reset --hard A && git reset --soft @{1} && git commit -a - person Jason Gross; 23.07.2012
comment
Я обновил ответ, указав способ сделать это в Mercurial. Однако, как и ответ git, на который вы ссылались, он фактически не отменяет наборы изменений. Это действительно заставляет меня задаться вопросом, почему вы когда-либо хотели отменить такую ​​большую последовательность наборов изменений. Кажется, лучше просто припарковать их на неактивной ветке и продолжить с изменения, которое было до этого. Если вы немного опишете свой вариант использования в своем вопросе, это может помочь вам найти лучшее решение вашей проблемы. - person Laurens Holst; 25.07.2012
comment
Кроме того, вы можете рассмотреть возможность отправки запроса функции в Mercurial, чтобы команда backout принимала набор ревизий, а не только одну ревизию. - person Laurens Holst; 25.07.2012

Самый простой способ:

Вы находитесь в наборе изменений D и хотите завершить эту ветку

hg commit --close-branch -m "Branch closed"

Теперь просто перейдите к набору изменений A и продолжайте свою работу, добавляя новые вещи.

hg up -r A
... change stuff ...
hg ci -m "New stuff"

Ветка с B, C и D будет там, но она будет завершена, она не будет отображаться в hg heads. Это будет неактивная ветвь.

Это легко сделать и выразительно тоже. Если вы посмотрите на график, вы увидите отдельную ветку, которая была закрыта, а «официальная» ветка продолжит свое существование. Гораздо лучше, чем когда эти наборы изменений для возврата и отмены создают шум в вашей ветке.

person Rafael Piccolo    schedule 25.07.2012
comment
Как объяснялось в другом вопросе, при попытке отправить закрытую головку в другой репозиторий вы получить предупреждение о создании нескольких головок. Итак, используйте hg push --force при первом нажатии. Люди, которые тянут закрытую голову, не получат никаких предупреждений. - person mernst; 21.06.2013

Вы ответили на свой вопрос, вернитесь к A и просто продолжайте оттуда. Если вам нужно создать новую голову в этот момент, вам нужно будет внести изменения в тот или иной файл, как описано здесь: Как я могу заставить mercurial принять пустую фиксацию . цепочка сообщений, связанная с из этого сообщения описывается способ использования MqExtension для удаления BCD (если вы их не нажали):

person Jim Downing    schedule 23.07.2012
comment
Это, но только если D является ГОЛОВОЙ. В hg нет сборки мусора, поэтому B, C и D не будут потеряны. D просто останется ГОЛОВОЙ, которую вы можете нажимать или нет — решать вам. - person DanMan; 29.03.2014