Mercurial 3.0: È ora possibile selezionare l'antenato da utilizzare come base di unione. Lo fai impostando merge.preferancestor
. Mercurial te ne parlerà quando questo ha senso. Con l'esempio di seguito, si dovrebbe vedere:
$ 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 prima della versione 3.0: pigro Badger è corretto che non è possibile scegliere l'antenato scelto da Mercurial quando lo si utilizza dalla riga di comando. Tuttavia, è possibile farlo internamente e non è troppo difficile da scrivere un'estensione per questo:
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'))
mettere questo in un file e caricare l'estensione. È ora possibile utilizzare
hg merge --ancestor X
per sovrascrivere il normale antenato. Come hai scoperto, questo fa fa la differenza se ci sono diversi possibili antenati. Questa situazione si presenta se vi sono fusioni incrociate. È possibile creare un caso del genere con questi comandi:
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
Il grafico si presenta così:
@ changeset: 4:333411d2f751
|\
+---o changeset: 3:7d1f71140c74
| |/
| o changeset: 2:fdf4b78f5292
| |
o | changeset: 1:eb49ad46fd72
|/
o changeset: 0:e72ddea4d238
Se si uniscono normalmente si ottiene changeset eb49ad46fd72
come l'antenato e il file x
contiene:
a
c
b
c
Se si utilizza invece hg merge --ancestor 2
si ottiene un risultato diverso:
a
b
c
b
In entrambi i casi, il mio KDiff3 è stato in grado di gestire l'unione automaticamente senza segnalare alcun conflitto. Se utilizzo la strategia di unione "ricorsiva" e scelgo come antenato lo e72ddea4d238
, allora mi viene presentato un conflitto ragionevole. Git utilizza la strategia di unione ricorsiva per impostazione predefinita.
È un WOW! Funziona perfettamente. Grazie mille. In effetti, non capisco perché questa funzione non sia inclusa in Mercurial. Nella maggior parte dei casi non è necessario, ma nei casi in cui è necessario può risparmiare ore di risoluzione dei conflitti o addirittura impedire l'unione automatica errata. Ho appena riscontrato tali problemi dopo modifiche inaccurate al repository. –