mercurial/merge.py
changeset 4007 20da40cc1c73
parent 4006 67982d3ee76c
child 4116 bb70d5fa02ae
equal deleted inserted replaced
4006:67982d3ee76c 4007:20da40cc1c73
   218     backwards = (pa == p2)
   218     backwards = (pa == p2)
   219     action = []
   219     action = []
   220     copy = {}
   220     copy = {}
   221 
   221 
   222     def fmerge(f, f2=None, fa=None):
   222     def fmerge(f, f2=None, fa=None):
   223         """merge executable flags"""
   223         """merge flags"""
   224         if not f2:
   224         if not f2:
   225             f2 = f
   225             f2 = f
   226             fa = f
   226             fa = f
   227         a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
   227         a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
   228         return ((a^b) | (a^c)) ^ a
   228         if ((a^b) | (a^c)) ^ a:
       
   229             return 'x'
       
   230         a, b, c = ma.linkf(fa), m1.linkf(f), m2.linkf(f2)
       
   231         if ((a^b) | (a^c)) ^ a:
       
   232             return 'l'
       
   233         return ''
   229 
   234 
   230     def act(msg, m, f, *args):
   235     def act(msg, m, f, *args):
   231         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   236         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   232         action.append((f, m) + args)
   237         action.append((f, m) + args)
   233 
   238 
   248                     act("versions differ", "m", f, f, f, fmerge(f), False)
   253                     act("versions differ", "m", f, f, f, fmerge(f), False)
   249                 # are we clobbering?
   254                 # are we clobbering?
   250                 # is remote's version newer?
   255                 # is remote's version newer?
   251                 # or are we going back in time and clean?
   256                 # or are we going back in time and clean?
   252                 elif overwrite or m2[f] != a or (backwards and not n[20:]):
   257                 elif overwrite or m2[f] != a or (backwards and not n[20:]):
   253                     act("remote is newer", "g", f, m2.execf(f))
   258                     act("remote is newer", "g", f, m2.flags(f))
   254                 # local is newer, not overwrite, check mode bits
   259                 # local is newer, not overwrite, check mode bits
   255                 elif fmerge(f) != m1.execf(f):
   260                 elif fmerge(f) != m1.flags(f):
   256                     act("update permissions", "e", f, m2.execf(f))
   261                     act("update permissions", "e", f, m2.flags(f))
   257             # contents same, check mode bits
   262             # contents same, check mode bits
   258             elif m1.execf(f) != m2.execf(f):
   263             elif m1.flags(f) != m2.flags(f):
   259                 if overwrite or fmerge(f) != m1.execf(f):
   264                 if overwrite or fmerge(f) != m1.flags(f):
   260                     act("update permissions", "e", f, m2.execf(f))
   265                     act("update permissions", "e", f, m2.flags(f))
   261         elif f in copied:
   266         elif f in copied:
   262             continue
   267             continue
   263         elif f in copy:
   268         elif f in copy:
   264             f2 = copy[f]
   269             f2 = copy[f]
   265             if f2 not in m2: # directory rename
   270             if f2 not in m2: # directory rename
   266                 act("remote renamed directory to " + f2, "d",
   271                 act("remote renamed directory to " + f2, "d",
   267                     f, None, f2, m1.execf(f))
   272                     f, None, f2, m1.flags(f))
   268             elif f2 in m1: # case 2 A,B/B/B
   273             elif f2 in m1: # case 2 A,B/B/B
   269                 act("local copied to " + f2, "m",
   274                 act("local copied to " + f2, "m",
   270                     f, f2, f, fmerge(f, f2, f2), False)
   275                     f, f2, f, fmerge(f, f2, f2), False)
   271             else: # case 4,21 A/B/B
   276             else: # case 4,21 A/B/B
   272                 act("local moved to " + f2, "m",
   277                 act("local moved to " + f2, "m",
   293             continue
   298             continue
   294         if f in copy:
   299         if f in copy:
   295             f2 = copy[f]
   300             f2 = copy[f]
   296             if f2 not in m1: # directory rename
   301             if f2 not in m1: # directory rename
   297                 act("local renamed directory to " + f2, "d",
   302                 act("local renamed directory to " + f2, "d",
   298                     None, f, f2, m2.execf(f))
   303                     None, f, f2, m2.flags(f))
   299             elif f2 in m2: # rename case 1, A/A,B/A
   304             elif f2 in m2: # rename case 1, A/A,B/A
   300                 act("remote copied to " + f, "m",
   305                 act("remote copied to " + f, "m",
   301                     f2, f, f, fmerge(f2, f, f2), False)
   306                     f2, f, f, fmerge(f2, f, f2), False)
   302             else: # case 3,20 A/B/A
   307             else: # case 3,20 A/B/A
   303                 act("remote moved to " + f, "m",
   308                 act("remote moved to " + f, "m",
   304                     f2, f, f, fmerge(f2, f, f2), True)
   309                     f2, f, f, fmerge(f2, f, f2), True)
   305         elif f in ma:
   310         elif f in ma:
   306             if overwrite or backwards:
   311             if overwrite or backwards:
   307                 act("recreating", "g", f, m2.execf(f))
   312                 act("recreating", "g", f, m2.flags(f))
   308             elif n != ma[f]:
   313             elif n != ma[f]:
   309                 if repo.ui.prompt(
   314                 if repo.ui.prompt(
   310                     (_("remote changed %s which local deleted\n") % f) +
   315                     (_("remote changed %s which local deleted\n") % f) +
   311                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
   316                     _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
   312                     act("prompt recreating", "g", f, m2.execf(f))
   317                     act("prompt recreating", "g", f, m2.flags(f))
   313         else:
   318         else:
   314             act("remote created", "g", f, m2.execf(f))
   319             act("remote created", "g", f, m2.flags(f))
   315 
   320 
   316     return action
   321     return action
   317 
   322 
   318 def applyupdates(repo, action, wctx, mctx):
   323 def applyupdates(repo, action, wctx, mctx):
   319     "apply the merge action list to the working directory"
   324     "apply the merge action list to the working directory"
   333                 if inst.errno != errno.ENOENT:
   338                 if inst.errno != errno.ENOENT:
   334                     repo.ui.warn(_("update failed to remove %s: %s!\n") %
   339                     repo.ui.warn(_("update failed to remove %s: %s!\n") %
   335                                  (f, inst.strerror))
   340                                  (f, inst.strerror))
   336             removed += 1
   341             removed += 1
   337         elif m == "m": # merge
   342         elif m == "m": # merge
   338             f2, fd, flag, move = a[2:]
   343             f2, fd, flags, move = a[2:]
   339             r = filemerge(repo, f, f2, wctx, mctx)
   344             r = filemerge(repo, f, f2, wctx, mctx)
   340             if r > 0:
   345             if r > 0:
   341                 unresolved += 1
   346                 unresolved += 1
   342             else:
   347             else:
   343                 if r is None:
   348                 if r is None:
   344                     updated += 1
   349                     updated += 1
   345                 else:
   350                 else:
   346                     merged += 1
   351                     merged += 1
   347                 if f != fd:
   352                 if f != fd:
   348                     repo.ui.debug(_("copying %s to %s\n") % (f, fd))
   353                     repo.ui.debug(_("copying %s to %s\n") % (f, fd))
   349                     repo.wwrite(fd, repo.wread(f), flag and 'x' or '')
   354                     repo.wwrite(fd, repo.wread(f), flags)
   350                     if move:
   355                     if move:
   351                         repo.ui.debug(_("removing %s\n") % f)
   356                         repo.ui.debug(_("removing %s\n") % f)
   352                         os.unlink(repo.wjoin(f))
   357                         os.unlink(repo.wjoin(f))
   353             util.set_exec(repo.wjoin(fd), flag)
   358             util.set_exec(repo.wjoin(fd), "x" in flags)
   354         elif m == "g": # get
   359         elif m == "g": # get
   355             flag = a[2]
   360             flags = a[2]
   356             repo.ui.note(_("getting %s\n") % f)
   361             repo.ui.note(_("getting %s\n") % f)
   357             t = mctx.filectx(f).data()
   362             t = mctx.filectx(f).data()
   358             repo.wwrite(f, t, flag and 'x' or '')
   363             repo.wwrite(f, t, flags)
   359             updated += 1
   364             updated += 1
   360         elif m == "d": # directory rename
   365         elif m == "d": # directory rename
   361             f2, fd, flag = a[2:]
   366             f2, fd, flags = a[2:]
   362             if f:
   367             if f:
   363                 repo.ui.note(_("moving %s to %s\n") % (f, fd))
   368                 repo.ui.note(_("moving %s to %s\n") % (f, fd))
   364                 t = wctx.filectx(f).data()
   369                 t = wctx.filectx(f).data()
   365                 repo.wwrite(fd, t, flag and 'x' or '')
   370                 repo.wwrite(fd, t, flags)
   366                 util.unlink(repo.wjoin(f))
   371                 util.unlink(repo.wjoin(f))
   367             if f2:
   372             if f2:
   368                 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
   373                 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
   369                 t = mctx.filectx(f2).data()
   374                 t = mctx.filectx(f2).data()
   370                 repo.wwrite(fd, t, flag and 'x' or '')
   375                 repo.wwrite(fd, t, flags)
   371             updated += 1
   376             updated += 1
   372         elif m == "e": # exec
   377         elif m == "e": # exec
   373             flag = a[2]
   378             flags = a[2]
   374             util.set_exec(repo.wjoin(f), flag)
   379             util.set_exec(repo.wjoin(f), flags)
   375 
   380 
   376     return updated, merged, removed, unresolved
   381     return updated, merged, removed, unresolved
   377 
   382 
   378 def recordupdates(repo, action, branchmerge):
   383 def recordupdates(repo, action, branchmerge):
   379     "record merge actions to the dirstate"
   384     "record merge actions to the dirstate"