Как мне отложить кучу незафиксированных изменений во время работы над чем-то другим

98

Если у меня есть куча незафиксированных изменений и я хочу отложить их, вместо этого работая над чем-то другим, а затем (например, через несколько дней) вернуться к ним и продолжить работу. Какой рабочий процесс для этого был бы самым простым? (Пока у меня есть только опыт работы с базовыми функциями Mercurial). Моим обычным методом было создание новой ветки с помощью клона, но могли быть способы получше.

Эрик
источник

Ответы:

133

У вас есть несколько вариантов:

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

    hg shelve --all --name "UnfinishedChanges"
    
    hg unshelve --name "UnfinishedChanges"
    

    Обновление / редактирование : в более новых версиях Mercurial может потребоваться использование

    hg shelve -n "UnfinishedChanges"
    hg unshelve "UnfinishedChanges"
    

    Вы все еще можете использовать его --nameв качестве альтернативы -n, но, похоже, ртуть больше не нравится --name. Кроме того, --allбольше не требуется, и Mercurial действительно будет волноваться по этому поводу.

  2. Заплатите очередь элементов, используя mq. В некоторых отношениях он не слишком отличается от полки, но ведет себя иначе. Конечный результат тот же, изменения удаляются и могут быть дополнительно применены позже. При нажатии патчи являются логическими наборами изменений, при открытии они сохраняются в другом месте и не являются частью истории наборов изменений.

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. Зафиксируйте их локально, обновите до предыдущего набора изменений и продолжайте работу, используя анонимные ветки (или несколько головок). Если вы хотите внести изменения, вы можете объединить головы. Если вы не хотите изменений, вы можете удалить набор изменений.

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. Зафиксируйте их в названной ветке. Затем рабочий процесс становится таким же, как для варианта 3 - объединить или разделить, когда вы будете готовы.

    hg branch "NewBranch"
    hg commit -m"Commiting unfinished work to temporary named branch."
    hg update <previous branch name>
    

Лично я использую вариант 3 или 4, так как я не против удаления наборов изменений или частичного кода проверки (если это в конечном итоге не будет продвинуто). Это можно использовать в сочетании с новым материалом Phase, чтобы при необходимости скрыть ваши локальные наборы изменений от других пользователей.

Я также использую эту rebaseкоманду для перемещения наборов изменений, чтобы избежать слияний, когда слияние ничего не добавит в историю кода. Слияния, которые я обычно сохраняю для активности между важными ветвями (например, веток выпуска) или активности из более долгоживущей ветки функций. Также есть histeditкоманда, которую я использую для сжатия наборов изменений, где их «болтливость» снижает ценность.

Очереди исправлений также являются распространенным механизмом для этого, но они имеют семантику стека. Вы нажимаете и выталкиваете патчи, но патч, который находится «под» другим патчем в стеке, требует, чтобы и патч, находящийся наверху, также был вставлен.

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

Адам Хоулдсворт
источник
Спасибо за отличный ответ и полезные примеры. Вы случайно не знаете, можно ли использовать закладки hg?
Erik
@Erik Возможно, но у меня нет опыта его использования.
Адам Хоулдсворт
2
Закладки могут использоваться для помощи с вариантом 3 - вы можете использовать их, чтобы пометить ревизию, которую вы создали для хранения вашего изменения. Они не могут справиться с задачей самостоятельно.
Steve Kaye
вариант --allне распознается. по умолчанию все изменения в любом случае откладываются.
naXa
@naXa Привет, приятель, если одна из моих команд немного неверна (возможно, потому, что версия изменилась), пожалуйста, не стесняйтесь редактировать ответ, и я одобряю его, если необходимо :-)
Адам Хоулдсворт
23

Лично мне не нравится ни один из опубликованных ответов:

  1. Мне не нравится ветвление клонов, потому что мне нравится, чтобы в каждом проекте был только один каталог. Работа с разными каталогами одновременно полностью портит историю последних файлов моих редакторов. Я всегда меняю не тот файл. Так что я больше этим не занимаюсь.
  2. Я использую shelveдля быстрых исправлений (просто чтобы переместить мои незавершенные изменения в другую ветку, если я пойму, что ошибаюсь). Вы говорите о днях, я бы ни за что не откладывал что-то на несколько дней.
  3. Я думаю, mqэто слишком сложно для такой обычной ситуации

Я думаю, что лучший способ - просто зафиксировать свои изменения, чем вернуться к набору изменений, прежде чем начинать эти изменения и работать оттуда. Есть несколько мелких проблем, позвольте мне проиллюстрировать:

Допустим, у вас есть набор изменений A. Затем вы начинаете свои изменения. На этом этапе вы хотите отложить это на время. Прежде всего, завершите свою работу:

hg ci -m "Working on new stuff"

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

hg bookmark new-stuff

Вернитесь к набору изменений перед этими изменениями

hg update A

Отсюда вы работаете и генерируете набор изменений C. Теперь у вас есть 2 головы (B и C), вы будете предупреждены, когда попытаетесь нажать. Вы можете нажать только одну ветку, указав ее заголовок:

hg push -r C

Или вы можете изменить фазу new-stuffветки на секретную. Секретные изменения не будут отправлены.

hg phase -r new-stuff --secret --force
Рафаэль Пикколо
источник
Спасибо за подробный ответ! Мне очень нравится читать рабочие процессы людей для решения этих (обычных?) Проблем.
Эрик
Я думаю, что mqэто слишком сложно только для этой ситуации, но у него достаточно широкий спектр применений, в том числе и этот, поэтому стоит потратить время на то, чтобы свободно владеть им.
Norman Gray
12

Чтобы сохранить локальные незавершенные изменения, мне проще всего сохранить их в виде файла исправления.

hg diff > /tmp/`hg id -i`.patch

и когда вам нужно вернуться в предыдущее состояние:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch
мапчук
источник
Я бы раздеться /tmpи , hg id -iи он будет работать на Windoze тоже.
анатолий техтоник 08
И hg upне нужен там.
анатолий техтоник 08
1
@techtonik Что произойдет, если я наложу патч на другую ревизию? Особенно, если исправлены файлы.
mapcuk
Mercurial попытается объединить его, и вам все равно придется иметь дело с конфликтом.
анатолий техтоник
6

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

  • MyProject.Root
  • MyProject.BugFix1
  • MyProject.BugFix2
  • MyProject.FeatureChange1
  • MyProject.FeatureChange2

Все 4 дочерних элемента клонируются из корня и выталкивают / вытягивают в / из корня. Затем корень выталкивает / извлекает из главного репо в сети / Интернете. Корень действует как ваша личная плацдарма.

Итак, в вашем случае вы просто клонируете новое репо и начинаете работать. Оставьте свою «отложенную» работу в покое в другом репо. Это так просто.

Единственным недостатком является использование дискового пространства, но если бы это было проблемой, вы бы вообще не использовали DVCS;) О, и это действительно загрязняет ваш список «недавних проектов» Visual Studio, но какого черта.

[Редактировать следующие комментарии]: -

В заключение ... то, что вы делаете, совершенно нормально и нормально. Я бы сказал, что это лучший способ работы, если верно следующее: 1) это недолговечный 2) вам не нужно сотрудничать с другими разработчиками 3) изменения не должны покидать ваш компьютер до фиксации / время нажатия.

nbevans
источник
Есть ли причина не использовать ветки? Это то, для чего они нужны, и они намного быстрее, чем репо-клонирование.
Адам Хоулдсворт
В моем вопросе я заявил следующее: Мой обычный метод - создать новую ветку с помощью клона, но могут быть способы получше.
Эрик
1
@AdamHouldsworth, технически это ветки ... просто недолговечные. Создавать именованную ветку для недолговечной работы - это совершенно глупо. Он злоупотребляет целью названных веток, которые предназначены для долгоживущих историй работы.
nbevans
@NathanE Если вы думаете, что именованные ветки для недолговечной работы «совершенно глупы», то есть также анонимные ветвления, полки или очередь исправлений в качестве других легких вариантов. Повторное клонирование, на мой взгляд, столь же глупо перед лицом других вариантов - это одно из потенциальных преимуществ - наличие двух наборов кода, открытых в двух экземплярах VS, но мне редко приходится это делать, поэтому использование клонов само собой разумеющееся не не служи мне. Просто для пояснения, я не голосовал против.
Адам Хоулдсворт
@NathanE Они также не являются исключительными для «долгоживущих историй работы», это просто то, в чем они хороши, если вы следите за непрерывной интеграцией. Прямо из документации : «Разветвления возникают, если линии разработки расходятся», если вы откладываете работу над чем-то другим, это для меня звучит как расхождение, независимо от того, насколько оно долгое.
Адам Хоулдсворт