С Mercurial, как я могу «сжать» серию изменений до одного? - PullRequest
95 голосов
/ 29 июля 2009

Допустим, у меня есть локальное и удаленное хранилище Mercurial. Теперь я начинаю работать над функцией. Я работаю над этим, и когда я думаю, что это сделано, я фиксирую изменения. Протестировав его немного больше, я обнаружил, что могу улучшить эту функцию, внеся изменения в код. Я делаю изменения и фиксирую. Через 20 минут я обнаружил, что в этой новой функции есть ошибка, поэтому я исправляю ее и фиксирую тоже.

Теперь у меня есть 3 набора изменений, которые я действительно хотел бы отправить в удаленный репозиторий, например, одним набором изменений с сообщением «Реализация функции X».

Как я могу сделать это без особых хлопот? Я полагаю, что мог бы сделать это с патчами, но это похоже на большую работу.

Ответы [ 11 ]

51 голосов
/ 13 октября 2009

Расширение histedit - это именно то, что вы ищете.

hg histedit -o

или

hg histedit --outgoing

выведет список исходящих изменений. Из списка вы можете

  • Сложите 2 или более наборов изменений, создав один набор
  • Удалите наборы изменений, удалив их из истории
  • Переупорядочивайте ревизии так, как вам нравится.

histedit запросит у вас новое сообщение о фиксации свернутых наборов изменений, которое по умолчанию соответствует двум сообщениям с разделением "\ n *** \ n".

Вы также можете получить аналогичные результаты, используя расширение mq, но это намного сложнее.

Вы также можете использовать расширение свертывания, чтобы просто свернуть, но оно не обеспечивает такой приятный пользовательский интерфейс и не позволяет редактировать полученное сообщение о коммите. Редактирование полученного сообщения о фиксации также позволяет очистить окончательное сообщение, которое я всегда использую.

38 голосов
/ 29 июля 2009
20 голосов
/ 30 июля 2009

Да, вы можете сделать это с патчами: Давайте предположим, что ваша работа находится в ревизиях от 100 до 110 включительно

  1. Создать патч:

    % hg export -o mypatch 100:110 --git

  2. Обновление до 99:

    % hg update 99

  3. Примените патч с параметром --no-commit (иначе вы вернете все свои наборы изменений):

    % hg import --no-commit mypatch

  4. Совершить все изменения сразу:

    % hg commit

  5. Теперь у вас есть две головы (110 и 111), которые должны быть эквивалентны с точки зрения файлов, которые они производят в вашем рабочем каталоге - возможно, рассмотрите их для здравого смысла перед удалением старых:

    % hg strip 100

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

19 голосов
/ 12 мая 2011

Если вы используете TortoiseHg, команда use может просто выбрать две ревизии (используйте CTRL для выбора непоследовательных), щелкните правой кнопкой мыши и выберите «История сжатия» .

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

Вы можете просто удалить старые списки изменений, если они вам больше не нужны: используйте для этого расширения MQ . Опять же, в TortoiseHg: щелкните правой кнопкой мыши первый список изменений, который необходимо удалить со всеми его потомками, «Изменить историю -> Удалить» .

18 голосов
/ 03 марта 2011

Мой предпочтительный метод использования mq для этого сворачивания - это использование TortoiseHg , как описано здесь . Однако это легко сделать из командной строки, например:

hg qimport -r <first>:<last> 
    -- where <first> and <last> are the first and last changesets 
    -- in the range of revisions you want to collapse

hg qpop <first>.diff
    -- remove all except for the first patch from the queue
    -- note: mq names patches <#>.diff when it imports them, so we're using that here

hg qfold <next>.diff
    -- where <next> is <first>+1, then <first>+2, until you've reached <last>

hg qfinish -a
    -- apply the folded changeset back into the repository

(Возможно, есть лучший способ сделать шаг qfold, но я не знаю об этом, так как обычно я использую TortoiseHg для этой операции.)

Сначала это кажется немного сложным, но как только вы начали использовать mq, это довольно просто и естественно - плюс вы можете делать с mq все что угодно, что может быть очень удобно!

4 голосов
/ 06 января 2012

hg collapse и hg histedit являются лучшими способами. Или, скорее, было бы лучшим способом, если бы они работали надежно ... Я получил histedit, чтобы аварийно завершить работу с дампом стека в течение трех минут. Collapse не намного лучше.

Думаю, я мог бы поделиться двумя другими БКМ:

  1. hg rebase --collapse

    Это расширение распространяется с Mercurial. У меня еще не было проблем с этим. Возможно, вам придется поиграть в некоторые игры, чтобы обойти ограничения hg rebase - в основном, он не любит перебазирование к предку в той же ветви, именованной или по умолчанию, хотя это допускает перебазирование между (именованными) ветвями.

  2. Переместить репозиторий (foo/.hg) в рабочий каталог (bar) и его файлы. Не наоборот.

Некоторые люди говорили о создании двух деревьев клонов и копировании файлов между ними. Или исправление между ними. Вместо этого легче перемещать каталоги .hg.

hg clone project work
... lots of edits
... hg pull, merge, resolve
hg clone project, clean
mv work/.hg .hg.work
mv clean/.hg work/.hg
cd work
... if necessary, pull, nerge, reconcile - but that would only happen because of a race
hg push

Это работает до тех пор, пока настоящие репозитории, деревья .hg, не зависят от рабочего каталога и его файлов.

Если они не независимы ...

2 голосов
/ 29 июля 2009

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

http://martinfowler.com/bliki/MercurialSquashCommit.html

0 голосов
/ 16 октября 2018

Да, strip --keep работает на авторский вопрос. Но это немного отличалось от других, например, если у вас версия от 1 до 30, но вы хотите свернуть версию 12-15. Другие решения работают, но не strip --keep.

0 голосов
/ 09 ноября 2016

Предположим, у вас есть два неопубликованных коммита THIS и THAT в Mercurial, и им нравится присоединяться к одному коммиту в THIS point ::

... --> THIS --> ... --> THAT --> ... --> LAST

Убедитесь, что ваши коммиты не опубликованы ::

$ hg glog -r "draft() & ($THIS | $THAT)"

Обновление до LAST commit ::

$ hg up

и импорт фиксирует до THIS в MQ ::

$ hg qimport $THIS::.

Отменить все исправления и применить только сначала THIS ::

$ hg qpop -a
$ hg qpush
$ hg qapplied
... THIS ...

Присоединяйтесь с THAT ::

$ hg qfold $THATNAME

ПРИМЕЧАНИЕ Чтобы найти имя THATNAME используйте ::

$ hg qseries

Применить все патчи и переместить их в историю репозитория ::

$ hg qpush -a
$ hg qfinish -a

Мой пост по теме Присоединение к двум коммитам в Mercurial .

0 голосов
/ 23 мая 2014

Почему бы не просто hg strip --keep команда?

Затем вы можете зафиксировать все изменения как один коммит.

...