comparison mercurial/merge.py @ 27657:7b5c8c8a2f8c

merge: add options to warn or ignore on colliding unknown files A 'colliding unknown file' is a file that meets all of the following conditions: - is untracked or ignored on disk - is present in the changeset being merged or updated to - has different contents Previously, we would always abort whenever we saw such files. With this config option we can choose to warn and back the unknown files up instead, or even forgo the warning entirely and silently back the unknown files up. Common use cases for this configuration include a large scale transition of formerly ignored unknown files to tracked files. In some cases the files can be given new names, but in other cases, external "convention over configuration" constraints have determined that the file must retain the same name as before.
author Siddharth Agarwal <sid0@fb.com>
date Sat, 02 Jan 2016 03:11:52 -0800
parents 57c0d4888ca8
children da5634e1b8a3
comparison
equal deleted inserted replaced
27656:57c0d4888ca8 27657:7b5c8c8a2f8c
571 files. For some actions, the result is to abort; for others, it is to 571 files. For some actions, the result is to abort; for others, it is to
572 choose a different action. 572 choose a different action.
573 """ 573 """
574 conflicts = set() 574 conflicts = set()
575 if not force: 575 if not force:
576 config = repo.ui.config('merge', 'checkunknown', default='abort')
577 valid = ['abort', 'ignore', 'warn']
578 if config not in valid:
579 validstr = ', '.join(["'" + v + "'" for v in valid])
580 raise error.ConfigError(_("merge.checkunknown not valid "
581 "('%s' is none of %s)")
582 % (config, validstr))
583
576 for f, (m, args, msg) in actions.iteritems(): 584 for f, (m, args, msg) in actions.iteritems():
577 if m in ('c', 'dc'): 585 if m in ('c', 'dc'):
578 if _checkunknownfile(repo, wctx, mctx, f): 586 if _checkunknownfile(repo, wctx, mctx, f):
579 conflicts.add(f) 587 conflicts.add(f)
580 elif m == 'dg': 588 elif m == 'dg':
581 if _checkunknownfile(repo, wctx, mctx, f, args[0]): 589 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
582 conflicts.add(f) 590 conflicts.add(f)
583 591
584 for f in sorted(conflicts): 592 if config == 'abort':
585 repo.ui.warn(_("%s: untracked file differs\n") % f) 593 for f in sorted(conflicts):
586 if conflicts: 594 repo.ui.warn(_("%s: untracked file differs\n") % f)
587 raise error.Abort(_("untracked files in working directory differ " 595 if conflicts:
588 "from files in requested revision")) 596 raise error.Abort(_("untracked files in working directory "
597 "differ from files in requested revision"))
598 elif config == 'warn':
599 for f in sorted(conflicts):
600 repo.ui.warn(_("%s: replacing untracked file\n") % f)
589 601
590 for f, (m, args, msg) in actions.iteritems(): 602 for f, (m, args, msg) in actions.iteritems():
603 backup = f in conflicts
591 if m == 'c': 604 if m == 'c':
592 flags, = args 605 flags, = args
593 actions[f] = ('g', (flags, False), msg) 606 actions[f] = ('g', (flags, backup), msg)
594 elif m == 'cm': 607 elif m == 'cm':
595 fl2, anc = args 608 fl2, anc = args
596 different = _checkunknownfile(repo, wctx, mctx, f) 609 different = _checkunknownfile(repo, wctx, mctx, f)
597 if different: 610 if different:
598 actions[f] = ('m', (f, f, None, False, anc), 611 actions[f] = ('m', (f, f, None, False, anc),
599 "remote differs from untracked local") 612 "remote differs from untracked local")
600 else: 613 else:
601 actions[f] = ('g', (fl2, False), "remote created") 614 actions[f] = ('g', (fl2, backup), "remote created")
602 615
603 def _forgetremoved(wctx, mctx, branchmerge): 616 def _forgetremoved(wctx, mctx, branchmerge):
604 """ 617 """
605 Forget removed files 618 Forget removed files
606 619