Как мне указать базу слияния для использования в «HG слияния» - PullRequest
6 голосов
/ 19 февраля 2012

Я пытаюсь сделать сложное слияние в сложном хранилище hg. Я не доволен «новейшим общим предком», который Mercurial выбирает в качестве «базы» для выполнения слияния.

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

Возможно ли это, и если да, то как?

Ответы [ 3 ]

15 голосов
/ 24 февраля 2012

Mercurial 3.0: Теперь вы можете выбрать предка для использования в качестве базы слияния. Вы делаете это, устанавливая merge.preferancestor. Mercurial расскажет вам об этом, когда это будет иметь смысл. В приведенном ниже примере вы увидите:

$ hg merge
note: using eb49ad46fd72 as ancestor of 333411d2f751 and 7d1f71140c74
      alternatively, use --config merge.preferancestor=fdf4b78f5292
merging x
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

Mercurial до версии 3.0: Lazy Badger правильно, что вы не можете выбрать предка, выбранного Mercurial при использовании его из командной строки. Тем не менее, вы можете сделать это внутренне, и не так уж сложно написать расширение для этого:

from mercurial import extensions, commands, scmutil
from mercurial import merge as mergemod

saved_ancestor = None

def update(orig, repo, node, branchmerge, force, partial, ancestor=None):
    if saved_ancestor:
        ancestor = scmutil.revsingle(repo, saved_ancestor).node()
    return orig(repo, node, branchmerge, force, partial, ancestor)

def merge(orig, ui, repo, node=None, **opts):
    global saved_ancestor
    saved_ancestor = opts.get('ancestor')
    return orig(ui, repo, node, **opts)

def extsetup(ui):
    extensions.wrapfunction(mergemod, 'update', update)
    entry = extensions.wrapcommand(commands.table, 'merge', merge)
    entry[1].append(('', 'ancestor', '', 'override ancestor', 'REV'))

Поместите это в файл и загрузите расширение. Теперь вы можете использовать

hg merge --ancestor X

чтобы переопределить нормального предка. Как вы узнали, это действительно имеет значение, если есть несколько возможных предков. Такая ситуация возникает, если у вас есть перекрестные слияния. Вы можете создать такой случай с помощью этих команд:

hg init; echo a > x; hg commit -A -m a x
hg update 0; echo b >> x; hg commit -m b
hg update 0; echo c >> x; hg commit -m c
hg update 1; hg merge --tool internal:local 2; echo c >> x; hg commit -m bc
hg update 2; hg merge --tool internal:local 1; echo b >> x; hg commit -m cb

График выглядит так:

@    changeset: 4:333411d2f751
|\
+---o  changeset: 3:7d1f71140c74
| |/
| o  changeset: 2:fdf4b78f5292
| |
o |  changeset: 1:eb49ad46fd72
|/
o  changeset: 0:e72ddea4d238

При обычном слиянии вы получаете набор изменений eb49ad46fd72 в качестве предка, а файл x содержит:

a
c
b
c

Если вместо этого вы используете hg merge --ancestor 2, вы получите другой результат:

a
b
c
b

В обоих случаях мой KDiff3 мог автоматически обрабатывать слияние, не сообщая о каких-либо конфликтах. Если я использую «рекурсивную» стратегию слияния и выберу e72ddea4d238 в качестве предка, то у меня возникнет разумный конфликт. Git по умолчанию использует стратегию рекурсивного слияния.

1 голос
/ 19 февраля 2012

База просто используется как еще один вход для вашего инструмента слияния. Если вы отключите premerge в своей конфигурации инструмента слияния (premerge делает «очевидный выбор» для вас, когда нет конфликтов) и вызовете инструмент слияния вручную, предоставив копии 3-х ревизий, которые вы хотите, как локальную, удаленную и базовую, вы можно получить все, что вы хотите в вашем инструменте слияния. Только левый родитель и правый родитель фактически зарегистрированы в слиянии.

0 голосов
/ 19 февраля 2012

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

Если вы хотите выполнить слияние и не хотите переосмыслить (потому что ваши логические основы показывают / меня / неверные предположения и решение-path) вы можете пойти клон-rebase-merge-export-import patch patch

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...