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