comparison mercurial/merge.py @ 3732:ffe9fef84801

merge: pull findcopies helpers inside, refactor checkpair to checkcopies
author Matt Mackall <mpm@selenic.com>
date Thu, 30 Nov 2006 17:36:33 -0600
parents b4af5f92e04b
children 9e67fecbfd16
comparison
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 """