mercurial/merge.py
changeset 3732 ffe9fef84801
parent 3731 b4af5f92e04b
child 3733 9e67fecbfd16
equal deleted inserted replaced
3731:b4af5f92e04b 3732:ffe9fef84801
    85         if f not in man:
    85         if f not in man:
    86             action.append((f, "f"))
    86             action.append((f, "f"))
    87 
    87 
    88     return action
    88     return action
    89 
    89 
    90 def nonoverlap(d1, d2, d3):
       
    91     "Return list of elements in d1 not in d2 or d3"
       
    92 
       
    93     l = []
       
    94     for d in d1:
       
    95         if d not in d3 and d not in d2:
       
    96             l.append(d)
       
    97 
       
    98     l.sort()
       
    99     return l
       
   100 
       
   101 def findold(fctx, limit):
       
   102     "find files that path was copied from, back to linkrev limit"
       
   103 
       
   104     old = {}
       
   105     orig = fctx.path()
       
   106     visit = [fctx]
       
   107     while visit:
       
   108         fc = visit.pop()
       
   109         if fc.rev() < limit:
       
   110             continue
       
   111         if fc.path() != orig and fc.path() not in old:
       
   112             old[fc.path()] = 1
       
   113         visit += fc.parents()
       
   114 
       
   115     old = old.keys()
       
   116     old.sort()
       
   117     return old
       
   118 
       
   119 def findcopies(repo, m1, m2, ma, limit):
    90 def findcopies(repo, m1, m2, ma, limit):
   120     """
    91     """
   121     Find moves and copies between m1 and m2 back to limit linkrev
    92     Find moves and copies between m1 and m2 back to limit linkrev
   122     """
    93     """
       
    94 
       
    95     def findold(fctx):
       
    96         "find files that path was copied from, back to linkrev limit"
       
    97         old = {}
       
    98         orig = fctx.path()
       
    99         visit = [fctx]
       
   100         while visit:
       
   101             fc = visit.pop()
       
   102             if fc.rev() < limit:
       
   103                 continue
       
   104             if fc.path() != orig and fc.path() not in old:
       
   105                 old[fc.path()] = 1
       
   106             visit += fc.parents()
       
   107 
       
   108         old = old.keys()
       
   109         old.sort()
       
   110         return old
       
   111 
       
   112     def nonoverlap(d1, d2, d3):
       
   113         "Return list of elements in d1 not in d2 or d3"
       
   114         l = [d for d in d1 if d not in d3 and d not in d2]
       
   115         l.sort()
       
   116         return l
       
   117 
       
   118     def checkcopies(c, man):
       
   119         '''check possible copies for filectx c'''
       
   120         for of in findold(c):
       
   121             if of not in man:
       
   122                 return
       
   123             c2 = ctx(of, man[of])
       
   124             ca = c.ancestor(c2)
       
   125             if not ca or c == ca or c2 == ca:
       
   126                 return
       
   127             if ca.path() == c.path() or ca.path() == c2.path():
       
   128                 copy[c.path()] = of
   123 
   129 
   124     if not repo.ui.configbool("merge", "followcopies", True):
   130     if not repo.ui.configbool("merge", "followcopies", True):
   125         return {}
   131         return {}
   126 
   132 
   127     # avoid silly behavior for update from empty dir
   133     # avoid silly behavior for update from empty dir
   132     copy = {}
   138     copy = {}
   133     u1 = nonoverlap(m1, m2, ma)
   139     u1 = nonoverlap(m1, m2, ma)
   134     u2 = nonoverlap(m2, m1, ma)
   140     u2 = nonoverlap(m2, m1, ma)
   135     ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20]))
   141     ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20]))
   136 
   142 
   137     def checkpair(c, f2, man):
       
   138         ''' check if an apparent pair actually matches '''
       
   139         if f2 not in man:
       
   140             return
       
   141         c2 = ctx(f2, man[f2])
       
   142         ca = c.ancestor(c2)
       
   143         if not ca or c == ca or c2 == ca:
       
   144             return
       
   145         if ca.path() == c.path() or ca.path() == c2.path():
       
   146             copy[c.path()] = f2
       
   147 
       
   148     for f in u1:
   143     for f in u1:
   149         c = ctx(dcopies.get(f, f), m1[f])
   144         checkcopies(ctx(dcopies.get(f, f), m1[f]), m2)
   150         for of in findold(c, limit):
       
   151             checkpair(c, of, m2)
       
   152 
   145 
   153     for f in u2:
   146     for f in u2:
   154         c = ctx(f, m2[f])
   147         checkcopies(ctx(f, m2[f]), m1)
   155         for of in findold(c, limit):
       
   156             checkpair(c, of, m1)
       
   157 
   148 
   158     return copy
   149     return copy
   159 
   150 
   160 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
   151 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
   161     """
   152     """