Как сделать вишню - выбрать одну ревизию в Mercurial?

В Mercurial/TortoiseHg, приведенном ниже, самый простой способ объединить ревизию "G" в репо A без принятия D, E и F (предположим, что G не имеет зависимости от D, E или F).

Repo A: A - B - C

Repo B (Clone of A) A - B - C - D - E - F - G

Лучше ли патч?

Ответ 1

Тонфа прав. То, что вы описываете, не "сливается" (или "толкает" или "тянет" ); это "вишневый сбор". Push или pull перемещают все изменения с одного репо на другое, которые еще не находятся в этом репо. "Слияние" принимает две "головы" и объединяет их в новый набор изменений, что сочетание обоих.

Если вам действительно нужно переместить G, но вы не можете оставить D, E, F, вам нужно "hg export" G из репо A, а затем "hg import" в репо A. Расширение трансплантата является оберткой вокруг экспорта/импорта с некоторыми тонкостями, чтобы избежать перемещения одного и того же набора изменений за несколько раз.

Однако, недостаток использования импорта/экспорта, трансплантации и набора вишни в целом заключается в том, что вы не можете переместиться через G без своих предков, потому что в Mercurial имя набора изменений является его "хешид", который включает хешиды своих родителей. Разные родители (G новый родитель будет C, а не F) означает другой хешид, поэтому он больше не G - это работа G, а новый набор изменений по имени.

Перемещение по G как что-то новое, позвольте ему назвать G '(Gee prime), для некоторых целей не имеет большого значения, но для других это большая лаваш. Когда скоро repo B получит новый набор изменений, H, и вы хотите переместить его над своим родителем, будет изменяться с G на G ', которые имеют разные хэши. Это означает, что H будет двигаться по мере того, как H '- 100 изменяет набор строк вниз, и у вас будут разные хешиды для всего, потому что вы не могли выдержать D, E, F в репо A.

Вещи получат еще больше от удара, если/когда вы хотите переместить материал из Repo A в Repo B (противоположное направление вашего предыдущего хода). Если вы попытаетесь выполнить простой "hg push" от A до B, вы получите G '(и H' и последующие потомки), которые будут дублированы наборами изменений, которые у вас уже есть в Repo B.

Что же, ваши варианты?

  • Не волнует. Ваши данные все еще там, вы просто получаете одни и те же команды с разными именами и больше работаете над будущими обменами между двумя репозиториями. Это не так, просто немного неуклюжий, и некоторым людям все равно.
  • Переместите все D, E и F на Repo A. Вы можете переместить все изменения, если они безвредны, и избежать всех проблем. Если они не настолько безобидны, вы можете переместить их, а затем сделать "hg backout", чтобы отменить эффекты D, E и F в новом наборе изменений H.
  • Дайте G лучший исходный код для начала. Это означает, что я должен упомянуть об этом, потому что слишком поздно идти по этому маршруту (без история редактирования). То, что вы должны были сделать до работы над набором изменений G, было hg update C. Если G не полагается или не нуждается в наборах изменений D, E и F, то это не должен быть их ребенок.

Если вместо этого вы сначала обновляетесь до C, у вас будет такой граф:

A - B - C - D - E - F
          \
            G

тогда весь ответ на этот вопрос будет просто hg push -r G ../repoA, а G будет двигаться чисто, сохраняя тот же самый хэш, и D, E и F не будут с ним идти.

UPDATE:

Как указано в комментариях. С современными Mercurials команда hg graft - идеальный способ сделать это.

Ответ 2

Ссылаясь на заголовок, в котором рассматривается выбор вишни в целом, я приведу пример работы в одном репо, так как поисковые системы Интернета могут привлечь сюда людей для сбора вишни в целом. Работая в одном репозитории, это будет сделано с помощью hg graft:

hg update C
hg graft G

Результат:

            G'
          / 
A - B - C - D - E - F - G

Дополнительное предупреждение: два набора изменений будут рассматриваться как независимые, параллельные коммиты в одних и тех же файлах и могут привести к конфликтам слияния, поэтому в целом для управления веткими следует избегать выбора вишни. Например, если G является исправлением ошибки, применяемым к ветки стабильной версии, отмеченной как 1.0.1, вам следует скорее объединить ветвь freeze с ней и время от времени объединить ветвь master с freeze фиктивные исправления.