2009-05-12 2 views
55

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

Я знаю, что hg transplant может делать это между ветвями, но мне нужно что-то подобное для совершения кода в настоящей ветке, а не при добавлении наборов изменений из какой-либо другой ветви.

+2

Я спросил это недавно как дубликат. Я не знал о терминологии, поэтому я не нашел этого при поиске. См. Принятый ответ на мой вопрос, который включает hg graft, новый в Mercurial 2.0. http://stackoverflow.com/questions/10288482/workflow-to-backport-change-into-different-mercucial-branch – oob

ответ

33

MQ как Чад упоминается в одном направлении. Существуют также более легкие решения:

  • Record extension, который работает примерно так же, как и запись darcs. Он распространяется с меркуриальным.
  • Shelve extension, который позволяет «отложить» определенные изменения, что позволяет совершать только часть ваших изменений (те, которые не заморожены)
+0

см. Дополнительную информацию в этом ответе: http://stackoverflow.com/a/7768682/411282 –

3

Я считаю, что Mercurial Queues заполняет эту роль для Mercurial. Там есть a pretty good tutorial.

+0

Это похоже на то, что я хочу, однако было бы здорово, если бы процесс был более интерактивным, как hg команда пересадки. – mansu

16

Учебник Mercurial Очереди страшен для этого случая использования. Все примеры, которые я видел, предполагают, что вам еще предстоит совершить фиксацию, и вы обновляете один патч. В большинстве случаев это не так, и у вас есть 2 или 3 фиксации, которые вы хотите сквозировать или изменить каким-то другим способом.

Допустим, у вас есть такого рода истории:

---O---O---A---B---C 

Первый пример заключается в сквош совершает A, B и C. Первый INIT кв.м.:

$ hg qinit 

Теперь нам нужно " import "коммиты A, B и C в очередь исправлений. Предположим, что они являются последними 3 коммитами. Мы можем использовать синтаксис «-N» ревизии импортировать их следующим образом:

$ hg qimport -r -3:-1 

Это означает, что импорт в виде патчей от 3 патчи до последней фиксации. Вы можете проверить статус этих патчей с помощью hg qseries. Он должен показать что-то вроде этого:

$ hg qseries 
101.diff 
102.diff 
103.diff 

Где номера 101, 102 и 103 соответствуют местным номерам ревизий коммитов A, B и C. Теперь эти патчи применяются, что означает, что изменения, которые они описываются уже в рабочей копии. Вы можете избавиться от изменений рабочей копии и удалить их из истории коммитов, сохранив их только в форме патча, используя hg qpop. Вы можете сказать hg qpop; hg qpop, чтобы поп изменения C и B со стека, или указать патч для «pop to». В этом случае, это было бы что-то вроде этого:

$ hg qpop 101.diff 
now at: 101.diff 

Теперь у вас есть патчи для совершает B и C в очереди патч, но они не применяются (их изменения были «потеряны» - они существуют только в области очереди патчей). Теперь вы можете складывать эти патчи в последний, т. Е. Мы создаем новую фиксацию, которая эквивалентна сумме изменений A + B + C.

$ hg qfold -e 102.diff 103.diff 

Это покажет ваш редактор, чтобы вы могли изменить сообщение фиксации.По умолчанию сообщение будет конкатенацией сообщений фиксации для изменений A, B и C, разделенных звездочками. Приятно отметить, что hg qfold выполнит вкладку с завершающими патчами, если вы используете bash и получите сценарий hg-complete. Это оставляет историю, как это, где A + B + C является единственным коммит, который представляет собой комбинацию из 3-х пластырей, которые нас интересуют:

---O---O---A+B+C 

Другой случай использования, если мы имеем такой же истории, как и раньше , но мы хотим удалить патч B и слить A + C. Это на самом деле похоже на выше. Когда вы дойдете до шага qfold, вы просто сложите в последней фиксации, а не последние 2 фиксаций:

$ hg qfold -e 103.diff 

Это оставляет изменения для B в очереди патч, но он не применяется к рабочей копии и его фиксация не в истории. Вы можете увидеть это, запустив:

$ hg qunapplied 
102.diff 

История теперь выглядит следующим образом, где A + C представляет собой одну фиксацию, которая сочетает в себе изменения А и С:

---O---O---A+C 

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

$ hg qpop -a 

в -a означает флаг палить все патчи. Теперь вы можете применить только один вы хотите:

$ hg qpush 103.diff 

Это оставляет вас с этой историей:

---O---O---C 

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

$ hg qfinish -a 

Итак, мы находимся. Теперь вы можете запустить hg push и зафиксировать только то, что хотите, или hg email связный патч в список рассылки.

+0

Очень хорошее сообщение, спасибо! – jv42

2

Попробуйте qct (Qt Commit Tool). Он имеет функцию «выбрать изменения», которая запускает трехсторонний инструмент слияния, чтобы вы могли отменить отдельные изменения. После того, как вы зафиксируете, те изменения, которые вы «расстегнули», возвращаются.

+0

Я этого не знал. Благодарю. – mansu

36

Если вы используете TortoiseHg 1.x для Windows, this feature is implemented beautifully прямо из коробки (не требуется никаких расширений).

  1. Запустите инструмент TortoiseHg Commit Tool.
  2. Выберите файл, для которого вы только хотите внести подмножество из изменений.
  3. Нажмите на Hunk Вкладка выбора в области предварительного просмотра.
  4. Дважды щелкните мышью или используйте пробел до . Переключатель, который должен изменить, должен быть включен в фиксацию.

Для TortoiseHg 2.x, вкладка Выбор Hunk в настоящее время нет. На его месте находится Shelve tool. Он имеет еще несколько функций, чем старый выбор. Эти новые функции стоят за счет некоторой дополнительной сложности.

enter image description here

Обратите внимание, что нет необходимости явно включить расширение Mercurial сукна при использовании этой функции. По словам Стива Борхо (ведущего разработчика TortoiseHg) в response to a different TortoiseHg question: «У нас есть локальная копия расширения полки и звоните прямо в нее».


Для TortoiseHg 2.7+, эта функциональность была улучшена и повторно введена. Он теперь встроен непосредственно в инструмент Commit:

example of change selection in the commit tool

Уведомление в списке файлов слева, что верхний файл проверяется, чтобы указать, он будет включен, второй файл не установлен, поскольку он не будет и третий файл Sample.txt заполняется (индикатор флажка «Нуль»), потому что в фиксацию будут включены только изменения из этого файла.

Изменение в Sample.txt, которое будет включено, проверяется в нижней правой части изменения изображения. Изменения, которые будут исключены, не будут отмечены, а представление diff будет выделено серым цветом. Также обратите внимание, что значок инструмента для полки по-прежнему доступен.

+1

Ага, вот почему я не понял, почему это был вопрос. Это нелегко сделать, если вы не используете TortoiseHg. Я этого не знал. –

+0

Как насчет тех из нас, кто использует версию 2? У http://tortoisehg.bitbucket.org/manual/2.0/commit.html нет вкладки выбора hunk, которую я вижу. – alsuren

+0

@alsuren: см. Обновленный ответ для версии TortoiseHg 2.x – mwolfe02

2

Я использую commit-patch. Это скрипт, который позволяет редактировать diff перед фиксацией. Это действительно приятно с режимом diff-mode и vc-режимами Emacs.

В прошлом я использовал crecord, но у него есть ошибки, связанные с unicode (на самом деле расширение для записи имеет ошибки, от которых зависит crecord).

15

Я чувствую, что мне что-то не хватает, потому что никто этого не предложил.

Обычная команда «hg commit» может использоваться для выборочного выбора того, что нужно совершить (вам не нужно фиксировать все ожидающие изменения в локальном рабочем каталоге).

Если у вас есть набор изменений, как так:

M ext-web/docroot/WEB-INF/liferay-display.xml 
M ext-web/docroot/WEB-INF/liferay-portlet-ext.xml 
M ext-web/docroot/WEB-INF/portlet-ext.xml 

Вы можете совершить только два из этих изменений с ...

hg commit -m "partial commit of working dir changes" ext-web/docroot/WEB-INF/liferay-display.xml ext-web/docroot/WEB-INF/liferay-portlet-ext.xml 

Не супер удобно из командной строки, потому что у вас есть вручную печатать файлы для выборочного фиксации (против процесса check-box графического интерфейса, такого как черепаха), но это примерно так же просто, как и получается, и не требует никаких расширений. И файловое манипулирование, вероятно, может помочь уменьшить типизацию (как это было выше, оба зафиксированных файла однозначно делят «liferay» на их пути.

+6

Многие из других ответов касаются только выборочных изменений внутри каждого файла (хотя неясно, требуется ли это от вопроса, так что у вас есть надпись) –

7

Вы можете использовать record extension, который распространяется вместе с Mercurial.

Вам необходимо включить его в файл ~/.hgrc первый, добавив его в [extensions] разделе:

[extensions] 
record= 

Тогда просто напечатайте hg record вместо hg commit, и вы будете иметь возможность выбрать, какие изменения, которые файлы, которые вы хотите зафиксировать.

Вы также можете использовать crecord extension, который обеспечивает более удобный интерфейс для просмотра и выбора изменений. (Однако он не распространяется вместе с Mercurial, и я видел, как он иногда испортил коммит, поэтому он не является полностью безаварийным.)

+1

crecord имеет преимущество перед записью в том, что вы можете выбрать * parts * of кусок. И интерфейс намного приятнее: D –

+1

Эта страница с расширением записи говорит * Эти расширения устарели, эта функция теперь является частью ядра Mercurial, поскольку hg commit --interactive *. См. [Этот ответ] (http://stackoverflow.com/a/7768682/2072035). – saaj

-1

Сначала вы должны забыть все, что вы когда-либо знали о графическом интерфейсе и вернуться в командную строку. Далее из командной строки выполните следующие действия:

рт.ст. стат> Filelist.txt

Этот ТРУБЫ все измененные файлы в текстовый файл с именем filelist.txt

Следующая редактирования вашего списка файлов, чтобы включать только файлы вы хотите совершить.

Наконец фиксации при помощи набора файлов sytnax:

рт.ст. совершить "набор: 'ListFile: test.txt'"

3

Некоторое время прошло. Кажется, лучший вариант сейчас hg commit --interactive

Смежные вопросы