С Mercurial, как я могу "сжать" серию изменений до одного?
Допустим, у меня есть локальный и удаленный репозиторий Mercurial. Теперь я начинаю работать над функцией. Я работаю над этим, и когда я думаю, что это сделано, я фиксирую изменения. Протестировав его немного больше, я обнаружил, что могу улучшить эту функцию, внеся изменения в код. Я делаю изменения и фиксирую. Спустя 20 минут я обнаружил, что в этой новой функции есть ошибка, поэтому я ее исправляю и тоже фиксирую.
Теперь у меня есть 3 набора изменений, которые я действительно хотел бы отправить в удаленный репозиторий, например, один набор изменений с сообщением "Реализация функции X".
Как я могу сделать это без особых хлопот? Я считаю, что я мог бы сделать это с патчами, но это похоже на большую работу.
11 ответов
Расширение histedit - это именно то, что вы ищете.
hg histedit -o
или же
hg histedit --outgoing
вызовет список исходящих изменений. Из списка вы можете
- Сложите 2 или более наборов изменений, создав один набор изменений
- Удалите наборы изменений, удалив их из истории
- Изменить порядок наборов, как вам нравится.
histedit запросит у вас новое сообщение о фиксации свернутых наборов изменений, которое по умолчанию будет иметь два сообщения с разделением "\n***\n".
Вы также можете получить аналогичные результаты, используя расширение mq, но это намного сложнее.
Вы также можете использовать расширение свертывания, чтобы просто свернуть, но оно не обеспечивает такой приятный пользовательский интерфейс и не позволяет редактировать полученное сообщение о коммите. Редактирование полученного сообщения фиксации также позволяет очистить окончательное сообщение, которое я всегда использую.
Да, вы можете сделать это с патчами: давайте предположим, что ваша работа состоит из ревизий от 100 до 110 включительно
Создать патч:
% hg export -o mypatch 100:110 --git
Обновление до 99:
% hg update 99
Примените патч с параметром --no-commit (иначе вы вернете все свои наборы изменений):
% hg import --no-commit mypatch
Передайте все изменения сразу:
% hg commit
Теперь у вас есть две главы (110 и 111), которые должны быть эквивалентны с точки зрения файлов, которые они производят в вашем рабочем каталоге - возможно, рассмотрите их для здравомыслия, прежде чем удалять старые:
% hg strip 100
Хорошо, теперь, когда я все это изложил, это кажется длительным, но, выполнив это несколько раз сам, я не считаю, что это слишком хлопотно...
Если вы используете TortoiseHg, используйте можете просто выбрать две ревизии (используйте CTRL для выбора непоследовательных), щелкните правой кнопкой мыши и выберите "История сжатия".
После этого вы получите новый список изменений в новом заголовке, начиная с первого выбранного ранее изменения, он будет содержать все списки изменений потомков между выбранными вами.
Вы можете просто удалить старые списки изменений, если они вам больше не нужны: используйте для этого расширения MQ. Опять же, в TortoiseHg: щелкните правой кнопкой мыши первый список изменений, который необходимо удалить со всеми его потомками, "Изменить историю -> Удалить".
Мой предпочтительный метод использования 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 все что угодно, что может быть очень удобно!
hg collapse
а также hg histedit
являются лучшими способами. Или, скорее, были бы лучшими способами, если бы они работали надежно... Я получил histedit
сбой с дампом стека в течение трех минут. Collapse
не намного лучше.
Думаю, я мог бы поделиться двумя другими BKM:
hg rebase --collapse
Это расширение распространяется с Mercurial. У меня еще не было проблем с этим. Возможно, вам придется играть в некоторые игры, чтобы обойти
hg rebase
ограничения - в основном, он не любит перебазирование к предку в той же ветви, именованной или по умолчанию, хотя он допускает перебазирование между (именованными) ветвями.Переместить хранилище (
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
деревья, не зависят от рабочего каталога и его файлов.
Если они не независимы...
Я никогда не использовал Mercurial, но это звучит очень похоже на то, о чем говорил Мартин Фаулер в своем блоге не так давно:
Предположим, у вас есть два неопубликованных THIS
а также THAT
фиксирует в Mercurial и, как они, чтобы объединиться в один коммит THIS
пункт::
... --> THIS --> ... --> THAT --> ... --> LAST
Убедитесь, что ваши коммиты не опубликованы:
$ hg glog -r "draft() & ($THIS | $THAT)"
Обновить до LAST
совершить::
$ 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".
Да, strip --keep
работает на авторский вопрос. Но это немного отличалось от других, например, если у вас версия от 1 до 30, но вы хотите свернуть версию 12-15. Другие решения работают, но не strip --keep
,
HistEdit будет делать то, что вы хотите, но это, вероятно, излишне. Если единственное, что вам нужно, это сложить вместе несколько наборов изменений, то расширение Collapse выполнит эту работу.
Почему не просто hg strip --keep
команда?
Затем вы можете зафиксировать все изменения как один коммит.