Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/merge.py @ 23638:09be050ca98c
merge: let bid merge work on the file->action dict
By moving the conversion from the file->action dict after the bid
merge code, bid merge can be simplified a little.
A few tests are affected by this change. Where we used to iterate over
the actions first in order of the action type ('g', 'r', etc.) [1], we
now iterate in order of filename. This difference affects the order of
debug log statements.
[1] And then in the non-deterministic order of files in the manifest
dictionary (the order returned from manifest.diff()).
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Thu, 11 Dec 2014 20:56:53 -0800 |
parents | 13f53a2aa342 |
children | 35c724903157 |
comparison
equal
deleted
inserted
replaced
23637:13f53a2aa342 | 23638:09be050ca98c |
---|---|
523 else: assert False, m | 523 else: assert False, m |
524 if aborts: | 524 if aborts: |
525 raise util.Abort(_("untracked files in working directory differ " | 525 raise util.Abort(_("untracked files in working directory differ " |
526 "from files in requested revision")) | 526 "from files in requested revision")) |
527 | 527 |
528 # Convert to dictionary-of-lists format | |
529 actionbyfile = actions | |
530 actions = dict((m, []) for m in 'a f g cd dc r dm dg m e k'.split()) | |
531 for f, (m, args, msg) in actionbyfile.iteritems(): | |
532 actions[m].append((f, args, msg)) | |
533 | |
534 return actions, diverge, renamedelete | 528 return actions, diverge, renamedelete |
535 | 529 |
536 def _resolvetrivial(repo, wctx, mctx, ancestor, actions): | 530 def _resolvetrivial(repo, wctx, mctx, ancestor, actions): |
537 """Resolves false conflicts where the nodeid changed but the content | 531 """Resolves false conflicts where the nodeid changed but the content |
538 remained the same.""" | 532 remained the same.""" |
581 acceptremote, followcopies) | 575 acceptremote, followcopies) |
582 if diverge is None: # and renamedelete is None. | 576 if diverge is None: # and renamedelete is None. |
583 # Arbitrarily pick warnings from first iteration | 577 # Arbitrarily pick warnings from first iteration |
584 diverge = diverge1 | 578 diverge = diverge1 |
585 renamedelete = renamedelete1 | 579 renamedelete = renamedelete1 |
586 for m, l in sorted(actions.items()): | 580 for f, a in sorted(actions.iteritems()): |
587 for a in l: | 581 m, args, msg = a |
588 f, args, msg = a | 582 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m)) |
589 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m)) | 583 if f in fbids: |
590 if f in fbids: | 584 d = fbids[f] |
591 d = fbids[f] | 585 if m in d: |
592 if m in d: | 586 d[m].append(a) |
593 d[m].append(a) | |
594 else: | |
595 d[m] = [a] | |
596 else: | 587 else: |
597 fbids[f] = {m: [a]} | 588 d[m] = [a] |
589 else: | |
590 fbids[f] = {m: [a]} | |
598 | 591 |
599 # Pick the best bid for each file | 592 # Pick the best bid for each file |
600 repo.ui.note(_('\nauction for merging merge bids\n')) | 593 repo.ui.note(_('\nauction for merging merge bids\n')) |
601 actions = dict((m, []) for m in actions.keys()) | 594 actions = {} |
602 for f, bids in sorted(fbids.items()): | 595 for f, bids in sorted(fbids.items()): |
603 # bids is a mapping from action method to list af actions | 596 # bids is a mapping from action method to list af actions |
604 # Consensus? | 597 # Consensus? |
605 if len(bids) == 1: # all bids are the same kind of method | 598 if len(bids) == 1: # all bids are the same kind of method |
606 m, l = bids.items()[0] | 599 m, l = bids.items()[0] |
607 if util.all(a == l[0] for a in l[1:]): # len(bids) is > 1 | 600 if util.all(a == l[0] for a in l[1:]): # len(bids) is > 1 |
608 repo.ui.note(" %s: consensus for %s\n" % (f, m)) | 601 repo.ui.note(" %s: consensus for %s\n" % (f, m)) |
609 actions[m].append(l[0]) | 602 actions[f] = l[0] |
610 continue | 603 continue |
611 # If keep is an option, just do it. | 604 # If keep is an option, just do it. |
612 if 'k' in bids: | 605 if 'k' in bids: |
613 repo.ui.note(" %s: picking 'keep' action\n" % f) | 606 repo.ui.note(" %s: picking 'keep' action\n" % f) |
614 actions['k'].append(bids['k'][0]) | 607 actions[f] = bids['k'][0] |
615 continue | 608 continue |
616 # If there are gets and they all agree [how could they not?], do it. | 609 # If there are gets and they all agree [how could they not?], do it. |
617 if 'g' in bids: | 610 if 'g' in bids: |
618 ga0 = bids['g'][0] | 611 ga0 = bids['g'][0] |
619 if util.all(a == ga0 for a in bids['g'][1:]): | 612 if util.all(a == ga0 for a in bids['g'][1:]): |
620 repo.ui.note(" %s: picking 'get' action\n" % f) | 613 repo.ui.note(" %s: picking 'get' action\n" % f) |
621 actions['g'].append(ga0) | 614 actions[f] = ga0 |
622 continue | 615 continue |
623 # TODO: Consider other simple actions such as mode changes | 616 # TODO: Consider other simple actions such as mode changes |
624 # Handle inefficient democrazy. | 617 # Handle inefficient democrazy. |
625 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f) | 618 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f) |
626 for m, l in sorted(bids.items()): | 619 for m, l in sorted(bids.items()): |
628 repo.ui.note(' %s -> %s\n' % (msg, m)) | 621 repo.ui.note(' %s -> %s\n' % (msg, m)) |
629 # Pick random action. TODO: Instead, prompt user when resolving | 622 # Pick random action. TODO: Instead, prompt user when resolving |
630 m, l = bids.items()[0] | 623 m, l = bids.items()[0] |
631 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') % | 624 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') % |
632 (f, m)) | 625 (f, m)) |
633 actions[m].append(l[0]) | 626 actions[f] = l[0] |
634 continue | 627 continue |
635 repo.ui.note(_('end of auction\n\n')) | 628 repo.ui.note(_('end of auction\n\n')) |
629 | |
630 # Convert to dictionary-of-lists format | |
631 actionbyfile = actions | |
632 actions = dict((m, []) for m in 'a f g cd dc r dm dg m e k'.split()) | |
633 for f, (m, args, msg) in actionbyfile.iteritems(): | |
634 actions[m].append((f, args, msg)) | |
636 | 635 |
637 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions) | 636 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions) |
638 | 637 |
639 if wctx.rev() is None: | 638 if wctx.rev() is None: |
640 ractions, factions = _forgetremoved(wctx, mctx, branchmerge) | 639 ractions, factions = _forgetremoved(wctx, mctx, branchmerge) |