comparison mercurial/merge.py @ 28022:e397b58c0563

rebase: respect checkunknown and checkignored in more cases checkunknown and checkignored are currently respected for updates and regular merges, but not for certain kinds of rebases. To be precise, they aren't respected for rebases when: (1) we're rebasing while currently on the destination commit, and (2) an untracked or ignored file F is currently in the working copy, and (3) the same file F is in a source commit, and (4) F has different contents in the source commit. This happens because rebases set force to True when calling merge.update. Setting force to True makes a lot of sense in general, but it turns out the force option is overloaded: there's a deprecated '--force' option in merge that allows you to merge in outstanding changes, including changes in untracked files. We use the 'mergeforce' parameter to tell those two cases apart. I think the behavior during rebases when checkunknown is 'abort' (the default) is wrong -- we should abort on or overwrite differing untracked files, not try to merge them in. However that currently breaks rebases by aborting in the middle -- we need better handling for that case before we can change the default.
author Siddharth Agarwal <sid0@fb.com>
date Wed, 03 Feb 2016 13:12:06 -0800
parents cffa46cbdb8f
children 19424f960bf5
comparison
equal deleted inserted replaced
28021:d0d805df6a44 28022:e397b58c0563
632 ignoredconflicts = set([c for c in conflicts 632 ignoredconflicts = set([c for c in conflicts
633 if repo.dirstate._ignore(c)]) 633 if repo.dirstate._ignore(c)])
634 unknownconflicts = conflicts - ignoredconflicts 634 unknownconflicts = conflicts - ignoredconflicts
635 collectconflicts(ignoredconflicts, ignoredconfig) 635 collectconflicts(ignoredconflicts, ignoredconfig)
636 collectconflicts(unknownconflicts, unknownconfig) 636 collectconflicts(unknownconflicts, unknownconfig)
637 else:
638 for f, (m, args, msg) in actions.iteritems():
639 if m == 'cm':
640 fl2, anc = args
641 different = _checkunknownfile(repo, wctx, mctx, f)
642 if repo.dirstate._ignore(f):
643 config = ignoredconfig
644 else:
645 config = unknownconfig
646
647 # The behavior when force is True is described by this table:
648 # config different mergeforce | action backup
649 # * n * | get n
650 # * y y | merge -
651 # abort y n | merge - (1)
652 # warn y n | warn + get y
653 # ignore y n | get y
654 #
655 # (1) this is probably the wrong behavior here -- we should
656 # probably abort, but some actions like rebases currently
657 # don't like an abort happening in the middle of
658 # merge.update.
659 if not different:
660 actions[f] = ('g', (fl2, False), "remote created")
661 elif mergeforce or config == 'abort':
662 actions[f] = ('m', (f, f, None, False, anc),
663 "remote differs from untracked local")
664 elif config == 'abort':
665 abortconflicts.add(f)
666 else:
667 if config == 'warn':
668 warnconflicts.add(f)
669 actions[f] = ('g', (fl2, True), "remote created")
637 670
638 for f in sorted(abortconflicts): 671 for f in sorted(abortconflicts):
639 repo.ui.warn(_("%s: untracked file differs\n") % f) 672 repo.ui.warn(_("%s: untracked file differs\n") % f)
640 if abortconflicts: 673 if abortconflicts:
641 raise error.Abort(_("untracked files in working directory " 674 raise error.Abort(_("untracked files in working directory "
647 for f, (m, args, msg) in actions.iteritems(): 680 for f, (m, args, msg) in actions.iteritems():
648 backup = f in conflicts 681 backup = f in conflicts
649 if m == 'c': 682 if m == 'c':
650 flags, = args 683 flags, = args
651 actions[f] = ('g', (flags, backup), msg) 684 actions[f] = ('g', (flags, backup), msg)
652 elif m == 'cm':
653 fl2, anc = args
654 different = _checkunknownfile(repo, wctx, mctx, f)
655 if different:
656 actions[f] = ('m', (f, f, None, False, anc),
657 "remote differs from untracked local")
658 else:
659 actions[f] = ('g', (fl2, backup), "remote created")
660 685
661 def _forgetremoved(wctx, mctx, branchmerge): 686 def _forgetremoved(wctx, mctx, branchmerge):
662 """ 687 """
663 Forget removed files 688 Forget removed files
664 689