mercurial/merge.py
changeset 23473 922b10c870c5
parent 23448 6a92b5fcfba8
child 23474 9f4ac44a7273
equal deleted inserted replaced
23472:48cdf90f17c5 23473:922b10c870c5
   412     diff = m1.diff(m2)
   412     diff = m1.diff(m2)
   413 
   413 
   414     for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
   414     for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
   415         if partial and not partial(f):
   415         if partial and not partial(f):
   416             continue
   416             continue
   417         if n1 and n2:
   417         if n1 and n2: # file exists on both local and remote side
   418             if f not in ma:
   418             if f not in ma:
   419                 fa = copy.get(f, None)
   419                 fa = copy.get(f, None)
   420                 if fa is not None:
   420                 if fa is not None:
   421                     actions['m'].append((f, (f, f, fa, False, pa.node()),
   421                     actions['m'].append((f, (f, f, fa, False, pa.node()),
   422                                    "both renamed from " + fa))
   422                                    "both renamed from " + fa))
   441                 else: # both changed something
   441                 else: # both changed something
   442                     actions['m'].append((f, (f, f, f, False, pa.node()),
   442                     actions['m'].append((f, (f, f, f, False, pa.node()),
   443                                    "versions differ"))
   443                                    "versions differ"))
   444         elif f in copied: # files we'll deal with on m2 side
   444         elif f in copied: # files we'll deal with on m2 side
   445             pass
   445             pass
   446         elif n1 and f in movewithdir: # directory rename, move local
   446         elif n1: # file exists only on local side
   447             f2 = movewithdir[f]
   447             if f in movewithdir: # directory rename, move local
   448             actions['dm'].append((f2, (f, fl1),
   448                 f2 = movewithdir[f]
   449                             "remote directory rename - move from " + f))
   449                 actions['dm'].append((f2, (f, fl1),
   450         elif n1 and f in copy:
   450                                 "remote directory rename - move from " + f))
   451             f2 = copy[f]
   451             elif f in copy:
   452             actions['m'].append((f, (f, f2, f2, False, pa.node()),
   452                 f2 = copy[f]
   453                             "local copied/moved from " + f2))
   453                 actions['m'].append((f, (f, f2, f2, False, pa.node()),
   454         elif n1 and f in ma: # clean, a different, no remote
   454                                 "local copied/moved from " + f2))
   455             if n1 != ma[f]:
   455             elif f in ma: # clean, a different, no remote
   456                 if acceptremote:
   456                 if n1 != ma[f]:
   457                     actions['r'].append((f, None, "remote delete"))
   457                     if acceptremote:
       
   458                         actions['r'].append((f, None, "remote delete"))
       
   459                     else:
       
   460                         actions['cd'].append((f, None,
       
   461                                               "prompt changed/deleted"))
       
   462                 elif n1[20:] == 'a':
       
   463                     # This extra 'a' is added by working copy manifest to mark
       
   464                     # the file as locally added. We should forget it instead of
       
   465                     # deleting it.
       
   466                     actions['f'].append((f, None, "remote deleted"))
   458                 else:
   467                 else:
   459                     actions['cd'].append((f, None, "prompt changed/deleted"))
   468                     actions['r'].append((f, None, "other deleted"))
   460             elif n1[20:] == 'a':
   469         elif n2: # file exists only on remote side
   461                 # This extra 'a' is added by working copy manifest to mark the
   470             if f in movewithdir:
   462                 # file as locally added. We should forget it instead of
   471                 f2 = movewithdir[f]
   463                 # deleting it.
   472                 actions['dg'].append((f2, (f, fl2),
   464                 actions['f'].append((f, None, "remote deleted"))
   473                                 "local directory rename - get from " + f))
   465             else:
   474             elif f in copy:
   466                 actions['r'].append((f, None, "other deleted"))
   475                 f2 = copy[f]
   467         elif n2 and f in movewithdir:
   476                 if f2 in m2:
   468             f2 = movewithdir[f]
   477                     actions['m'].append((f, (f2, f, f2, False, pa.node()),
   469             actions['dg'].append((f2, (f, fl2),
   478                                     "remote copied from " + f2))
   470                             "local directory rename - get from " + f))
   479                 else:
   471         elif n2 and f in copy:
   480                     actions['m'].append((f, (f2, f, f2, True, pa.node()),
   472             f2 = copy[f]
   481                                     "remote moved from " + f2))
   473             if f2 in m2:
   482             elif f not in ma:
   474                 actions['m'].append((f, (f2, f, f2, False, pa.node()),
   483                 # local unknown, remote created: the logic is described by the
   475                                 "remote copied from " + f2))
   484                 # following table:
   476             else:
   485                 #
   477                 actions['m'].append((f, (f2, f, f2, True, pa.node()),
   486                 # force  branchmerge  different  |  action
   478                                 "remote moved from " + f2))
   487                 #   n         *           n      |    get
   479         elif n2 and f not in ma:
   488                 #   n         *           y      |   abort
   480             # local unknown, remote created: the logic is described by the
   489                 #   y         n           *      |    get
   481             # following table:
   490                 #   y         y           n      |    get
   482             #
   491                 #   y         y           y      |   merge
   483             # force  branchmerge  different  |  action
   492                 #
   484             #   n         *           n      |    get
   493                 # Checking whether the files are different is expensive, so we
   485             #   n         *           y      |   abort
   494                 # don't do that when we can avoid it.
   486             #   y         n           *      |    get
   495                 if force and not branchmerge:
   487             #   y         y           n      |    get
   496                     actions['g'].append((f, (fl2,), "remote created"))
   488             #   y         y           y      |   merge
   497                 else:
   489             #
   498                     different = _checkunknownfile(repo, wctx, p2, f)
   490             # Checking whether the files are different is expensive, so we
   499                     if force and branchmerge and different:
   491             # don't do that when we can avoid it.
   500                         actions['m'].append((f, (f, f, None, False, pa.node()),
   492             if force and not branchmerge:
   501                                         "remote differs from untracked local"))
   493                 actions['g'].append((f, (fl2,), "remote created"))
   502                     elif not force and different:
   494             else:
   503                         aborts.append((f, 'ud'))
       
   504                     else:
       
   505                         actions['g'].append((f, (fl2,), "remote created"))
       
   506             elif n2 != ma[f]:
   495                 different = _checkunknownfile(repo, wctx, p2, f)
   507                 different = _checkunknownfile(repo, wctx, p2, f)
   496                 if force and branchmerge and different:
   508                 if not force and different:
   497                     actions['m'].append((f, (f, f, None, False, pa.node()),
       
   498                                     "remote differs from untracked local"))
       
   499                 elif not force and different:
       
   500                     aborts.append((f, 'ud'))
   509                     aborts.append((f, 'ud'))
   501                 else:
   510                 else:
   502                     actions['g'].append((f, (fl2,), "remote created"))
   511                     if acceptremote:
   503         elif n2 and n2 != ma[f]:
   512                         actions['g'].append((f, (fl2,), "remote recreating"))
   504             different = _checkunknownfile(repo, wctx, p2, f)
   513                     else:
   505             if not force and different:
   514                         actions['dc'].append((f, (fl2,),
   506                 aborts.append((f, 'ud'))
   515                                               "prompt deleted/changed"))
   507             else:
       
   508                 if acceptremote:
       
   509                     actions['g'].append((f, (fl2,), "remote recreating"))
       
   510                 else:
       
   511                     actions['dc'].append((f, (fl2,), "prompt deleted/changed"))
       
   512 
   516 
   513     for f, m in sorted(aborts):
   517     for f, m in sorted(aborts):
   514         if m == 'ud':
   518         if m == 'ud':
   515             repo.ui.warn(_("%s: untracked file differs\n") % f)
   519             repo.ui.warn(_("%s: untracked file differs\n") % f)
   516         else: assert False, m
   520         else: assert False, m