Mercurial > public > mercurial-scm > hg
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 |