С Mercurial, как я могу "сжать" серию наборов изменений в один перед нажатием?

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

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

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

Ответ 2

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

hg histedit -o

или

hg histedit --outgoing

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

  • Сложите 2 или более набора изменений, создающих один набор изменений.
  • Удалите изменения, удаляя их из истории
  • Изменить порядок изменений, как вам нравится.

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

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

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

Ответ 3

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

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

Вы можете просто удалить старые списки изменений, если они вам больше не нужны: используйте расширения MQ. Опять же, в TortoiseHg: щелкните правой кнопкой мыши на первом списке изменений, который нужно удалить со всеми его потомками, "Изменить историю → Стрип" .

Ответ 4

Да, вы можете сделать это с помощью патчей: Предположим, что ваша работа находится в наборах изменений от 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

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

Ответ 5

Мой предпочтительный метод использования 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, которые могут быть очень удобными!

Ответ 6

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, не зависят от рабочего каталога и его файлов.

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

Ответ 8

HistEdit будет делать то, что вы хотите, но это, вероятно, перебор. Если вам нужно только сфотографировать несколько наборов изменений, это сделает Collapse Extension.

Ответ 9

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

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

Ответ 10

Предположим, что у вас два неопубликованных THIS и THAT совершают в Mercurial и, как и они, присоединяются к одиночной фиксации в точке THIS::

... --> 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.