mercurial/merge.py
changeset 45293 4e6a2889dd1d
parent 45292 69691c5b8ce4
child 45296 cb0cd87e16b4
equal deleted inserted replaced
45292:69691c5b8ce4 45293:4e6a2889dd1d
   149                 abortconflicts.update(conflicts)
   149                 abortconflicts.update(conflicts)
   150             elif config == b'warn':
   150             elif config == b'warn':
   151                 warnconflicts.update(conflicts)
   151                 warnconflicts.update(conflicts)
   152 
   152 
   153         checkunknowndirs = _unknowndirschecker()
   153         checkunknowndirs = _unknowndirschecker()
   154         for f, (m, args, msg) in pycompat.iteritems(mresult.actions):
   154         for f, args, msg in mresult.getactions(
   155             if m in (
   155             [
   156                 mergestatemod.ACTION_CREATED,
   156                 mergestatemod.ACTION_CREATED,
   157                 mergestatemod.ACTION_DELETED_CHANGED,
   157                 mergestatemod.ACTION_DELETED_CHANGED,
   158             ):
   158             ]
   159                 if _checkunknownfile(repo, wctx, mctx, f):
   159         ):
   160                     fileconflicts.add(f)
   160             if _checkunknownfile(repo, wctx, mctx, f):
   161                 elif pathconfig and f not in wctx:
   161                 fileconflicts.add(f)
   162                     path = checkunknowndirs(repo, wctx, f)
   162             elif pathconfig and f not in wctx:
   163                     if path is not None:
   163                 path = checkunknowndirs(repo, wctx, f)
   164                         pathconflicts.add(path)
   164                 if path is not None:
   165             elif m == mergestatemod.ACTION_LOCAL_DIR_RENAME_GET:
   165                     pathconflicts.add(path)
   166                 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
   166         for f, args, msg in mresult.getactions(
   167                     fileconflicts.add(f)
   167             [mergestatemod.ACTION_LOCAL_DIR_RENAME_GET]
       
   168         ):
       
   169             if _checkunknownfile(repo, wctx, mctx, f, args[0]):
       
   170                 fileconflicts.add(f)
   168 
   171 
   169         allconflicts = fileconflicts | pathconflicts
   172         allconflicts = fileconflicts | pathconflicts
   170         ignoredconflicts = {c for c in allconflicts if repo.dirstate._ignore(c)}
   173         ignoredconflicts = {c for c in allconflicts if repo.dirstate._ignore(c)}
   171         unknownconflicts = allconflicts - ignoredconflicts
   174         unknownconflicts = allconflicts - ignoredconflicts
   172         collectconflicts(ignoredconflicts, ignoredconfig)
   175         collectconflicts(ignoredconflicts, ignoredconfig)
   173         collectconflicts(unknownconflicts, unknownconfig)
   176         collectconflicts(unknownconflicts, unknownconfig)
   174     else:
   177     else:
   175         for f, (m, args, msg) in pycompat.iteritems(mresult.actions):
   178         for f, args, msg in mresult.getactions(
   176             if m == mergestatemod.ACTION_CREATED_MERGE:
   179             [mergestatemod.ACTION_CREATED_MERGE]
   177                 fl2, anc = args
   180         ):
   178                 different = _checkunknownfile(repo, wctx, mctx, f)
   181             fl2, anc = args
   179                 if repo.dirstate._ignore(f):
   182             different = _checkunknownfile(repo, wctx, mctx, f)
   180                     config = ignoredconfig
   183             if repo.dirstate._ignore(f):
   181                 else:
   184                 config = ignoredconfig
   182                     config = unknownconfig
   185             else:
   183 
   186                 config = unknownconfig
   184                 # The behavior when force is True is described by this table:
   187 
   185                 #  config  different  mergeforce  |    action    backup
   188             # The behavior when force is True is described by this table:
   186                 #    *         n          *       |      get        n
   189             #  config  different  mergeforce  |    action    backup
   187                 #    *         y          y       |     merge       -
   190             #    *         n          *       |      get        n
   188                 #   abort      y          n       |     merge       -   (1)
   191             #    *         y          y       |     merge       -
   189                 #   warn       y          n       |  warn + get     y
   192             #   abort      y          n       |     merge       -   (1)
   190                 #  ignore      y          n       |      get        y
   193             #   warn       y          n       |  warn + get     y
   191                 #
   194             #  ignore      y          n       |      get        y
   192                 # (1) this is probably the wrong behavior here -- we should
   195             #
   193                 #     probably abort, but some actions like rebases currently
   196             # (1) this is probably the wrong behavior here -- we should
   194                 #     don't like an abort happening in the middle of
   197             #     probably abort, but some actions like rebases currently
   195                 #     merge.update.
   198             #     don't like an abort happening in the middle of
   196                 if not different:
   199             #     merge.update.
   197                     mresult.addfile(
   200             if not different:
   198                         f,
   201                 mresult.addfile(
   199                         mergestatemod.ACTION_GET,
   202                     f,
   200                         (fl2, False),
   203                     mergestatemod.ACTION_GET,
   201                         b'remote created',
   204                     (fl2, False),
   202                     )
   205                     b'remote created',
   203                 elif mergeforce or config == b'abort':
   206                 )
   204                     mresult.addfile(
   207             elif mergeforce or config == b'abort':
   205                         f,
   208                 mresult.addfile(
   206                         mergestatemod.ACTION_MERGE,
   209                     f,
   207                         (f, f, None, False, anc),
   210                     mergestatemod.ACTION_MERGE,
   208                         b'remote differs from untracked local',
   211                     (f, f, None, False, anc),
   209                     )
   212                     b'remote differs from untracked local',
   210                 elif config == b'abort':
   213                 )
   211                     abortconflicts.add(f)
   214             elif config == b'abort':
   212                 else:
   215                 abortconflicts.add(f)
   213                     if config == b'warn':
   216             else:
   214                         warnconflicts.add(f)
   217                 if config == b'warn':
   215                     mresult.addfile(
   218                     warnconflicts.add(f)
   216                         f,
   219                 mresult.addfile(
   217                         mergestatemod.ACTION_GET,
   220                     f, mergestatemod.ACTION_GET, (fl2, True), b'remote created',
   218                         (fl2, True),
   221                 )
   219                         b'remote created',
       
   220                     )
       
   221 
   222 
   222     for f in sorted(abortconflicts):
   223     for f in sorted(abortconflicts):
   223         warn = repo.ui.warn
   224         warn = repo.ui.warn
   224         if f in pathconflicts:
   225         if f in pathconflicts:
   225             if repo.wvfs.isfileorlink(f):
   226             if repo.wvfs.isfileorlink(f):
   240         if repo.wvfs.isfileorlink(f):
   241         if repo.wvfs.isfileorlink(f):
   241             repo.ui.warn(_(b"%s: replacing untracked file\n") % f)
   242             repo.ui.warn(_(b"%s: replacing untracked file\n") % f)
   242         else:
   243         else:
   243             repo.ui.warn(_(b"%s: replacing untracked files in directory\n") % f)
   244             repo.ui.warn(_(b"%s: replacing untracked files in directory\n") % f)
   244 
   245 
   245     for f, (m, args, msg) in pycompat.iteritems(mresult.actions):
   246     for f, args, msg in mresult.getactions([mergestatemod.ACTION_CREATED]):
   246         if m == mergestatemod.ACTION_CREATED:
   247         backup = (
   247             backup = (
   248             f in fileconflicts
   248                 f in fileconflicts
   249             or f in pathconflicts
   249                 or f in pathconflicts
   250             or any(p in pathconflicts for p in pathutil.finddirs(f))
   250                 or any(p in pathconflicts for p in pathutil.finddirs(f))
   251         )
   251             )
   252         (flags,) = args
   252             (flags,) = args
   253         mresult.addfile(f, mergestatemod.ACTION_GET, (flags, backup), msg)
   253             mresult.addfile(f, mergestatemod.ACTION_GET, (flags, backup), msg)
       
   254 
   254 
   255 
   255 
   256 def _forgetremoved(wctx, mctx, branchmerge):
   256 def _forgetremoved(wctx, mctx, branchmerge):
   257     """
   257     """
   258     Forget removed files
   258     Forget removed files
   648             self.addfile(f, a, data, msg)
   648             self.addfile(f, a, data, msg)
   649 
   649 
   650     def hasconflicts(self):
   650     def hasconflicts(self):
   651         """ tells whether this merge resulted in some actions which can
   651         """ tells whether this merge resulted in some actions which can
   652         result in conflicts or not """
   652         result in conflicts or not """
   653         for _f, (m, _unused, _unused) in pycompat.iteritems(self._filemapping):
   653         for a in self._actionmapping.keys():
   654             if m not in (
   654             if (
   655                 mergestatemod.ACTION_GET,
   655                 a
   656                 mergestatemod.ACTION_KEEP,
   656                 not in (
   657                 mergestatemod.ACTION_EXEC,
   657                     mergestatemod.ACTION_GET,
   658                 mergestatemod.ACTION_REMOVE,
   658                     mergestatemod.ACTION_KEEP,
   659                 mergestatemod.ACTION_PATH_CONFLICT_RESOLVE,
   659                     mergestatemod.ACTION_EXEC,
       
   660                     mergestatemod.ACTION_REMOVE,
       
   661                     mergestatemod.ACTION_PATH_CONFLICT_RESOLVE,
       
   662                 )
       
   663                 and self._actionmapping[a]
   660             ):
   664             ):
   661                 return True
   665                 return True
   662 
   666 
   663         return False
   667         return False
   664 
   668 
   990 def _resolvetrivial(repo, wctx, mctx, ancestor, mresult):
   994 def _resolvetrivial(repo, wctx, mctx, ancestor, mresult):
   991     """Resolves false conflicts where the nodeid changed but the content
   995     """Resolves false conflicts where the nodeid changed but the content
   992        remained the same."""
   996        remained the same."""
   993     # We force a copy of actions.items() because we're going to mutate
   997     # We force a copy of actions.items() because we're going to mutate
   994     # actions as we resolve trivial conflicts.
   998     # actions as we resolve trivial conflicts.
   995     for f, (m, args, msg) in list(mresult.actions.items()):
   999     for f, args, msg in mresult.getactions(
   996         if (
  1000         [mergestatemod.ACTION_CHANGED_DELETED]
   997             m == mergestatemod.ACTION_CHANGED_DELETED
  1001     ):
   998             and f in ancestor
  1002         if f in ancestor and not wctx[f].cmp(ancestor[f]):
   999             and not wctx[f].cmp(ancestor[f])
       
  1000         ):
       
  1001             # local did change but ended up with same content
  1003             # local did change but ended up with same content
  1002             mresult.addfile(
  1004             mresult.addfile(
  1003                 f, mergestatemod.ACTION_REMOVE, None, b'prompt same'
  1005                 f, mergestatemod.ACTION_REMOVE, None, b'prompt same'
  1004             )
  1006             )
  1005         elif (
  1007 
  1006             m == mergestatemod.ACTION_DELETED_CHANGED
  1008     for f, args, msg in list(
  1007             and f in ancestor
  1009         mresult.getactions([mergestatemod.ACTION_DELETED_CHANGED])
  1008             and not mctx[f].cmp(ancestor[f])
  1010     ):
  1009         ):
  1011         if f in ancestor and not mctx[f].cmp(ancestor[f]):
  1010             # remote did change but ended up with same content
  1012             # remote did change but ended up with same content
  1011             mresult.removefile(f)  # don't get = keep local deleted
  1013             mresult.removefile(f)  # don't get = keep local deleted
  1012 
  1014 
  1013 
  1015 
  1014 def calculateupdates(
  1016 def calculateupdates(