diff 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
line wrap: on
line diff
--- a/mercurial/merge.py	Sat Jan 02 03:21:01 2016 -0800
+++ b/mercurial/merge.py	Sat Jan 02 03:11:52 2016 -0800
@@ -573,6 +573,14 @@
     """
     conflicts = set()
     if not force:
+        config = repo.ui.config('merge', 'checkunknown', default='abort')
+        valid = ['abort', 'ignore', 'warn']
+        if config not in valid:
+            validstr = ', '.join(["'" + v + "'" for v in valid])
+            raise error.ConfigError(_("merge.checkunknown not valid "
+                                      "('%s' is none of %s)")
+                                    % (config, validstr))
+
         for f, (m, args, msg) in actions.iteritems():
             if m in ('c', 'dc'):
                 if _checkunknownfile(repo, wctx, mctx, f):
@@ -581,16 +589,21 @@
                 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
                     conflicts.add(f)
 
-        for f in sorted(conflicts):
-            repo.ui.warn(_("%s: untracked file differs\n") % f)
-        if conflicts:
-            raise error.Abort(_("untracked files in working directory differ "
-                                "from files in requested revision"))
+        if config == 'abort':
+            for f in sorted(conflicts):
+                repo.ui.warn(_("%s: untracked file differs\n") % f)
+            if conflicts:
+                raise error.Abort(_("untracked files in working directory "
+                                    "differ from files in requested revision"))
+        elif config == 'warn':
+            for f in sorted(conflicts):
+                repo.ui.warn(_("%s: replacing untracked file\n") % f)
 
     for f, (m, args, msg) in actions.iteritems():
+        backup = f in conflicts
         if m == 'c':
             flags, = args
-            actions[f] = ('g', (flags, False), msg)
+            actions[f] = ('g', (flags, backup), msg)
         elif m == 'cm':
             fl2, anc = args
             different = _checkunknownfile(repo, wctx, mctx, f)
@@ -598,7 +611,7 @@
                 actions[f] = ('m', (f, f, None, False, anc),
                               "remote differs from untracked local")
             else:
-                actions[f] = ('g', (fl2, False), "remote created")
+                actions[f] = ('g', (fl2, backup), "remote created")
 
 def _forgetremoved(wctx, mctx, branchmerge):
     """