91 for f in deleted + removed: |
91 for f in deleted + removed: |
92 if f not in m2: |
92 if f not in m2: |
93 action.append((f, "f")) |
93 action.append((f, "f")) |
94 |
94 |
95 return action |
95 return action |
|
96 |
|
97 def nonoverlap(d1, d2): |
|
98 """ |
|
99 Return list of elements in d1 not in d2 |
|
100 """ |
|
101 |
|
102 l = [] |
|
103 for d in d1: |
|
104 if d not in d2: |
|
105 l.append(d) |
|
106 |
|
107 l.sort() |
|
108 return l |
|
109 |
|
110 def findold(fctx, limit): |
|
111 """ |
|
112 find files that path was copied from, back to linkrev limit |
|
113 """ |
|
114 |
|
115 old = {} |
|
116 orig = fctx.path() |
|
117 visit = [fctx] |
|
118 while visit: |
|
119 fc = visit.pop() |
|
120 if fc.rev() < limit: |
|
121 continue |
|
122 if fc.path() != orig and fc.path() not in old: |
|
123 old[fc.path()] = 1 |
|
124 visit += fc.parents() |
|
125 |
|
126 old = old.keys() |
|
127 old.sort() |
|
128 return old |
|
129 |
|
130 def findcopies(repo, m1, m2, limit): |
|
131 """ |
|
132 Find moves and copies between m1 and m2 back to limit linkrev |
|
133 """ |
|
134 |
|
135 copy = {} |
|
136 match = {} |
|
137 u1 = nonoverlap(m1, m2) |
|
138 u2 = nonoverlap(m2, m1) |
|
139 ctx = util.cachefunc(lambda f,n: repo.filectx(f, fileid=n[:20])) |
|
140 |
|
141 def checkpair(c, f2, man): |
|
142 ''' check if an apparent pair actually matches ''' |
|
143 c2 = ctx(f2, man[f2]) |
|
144 ca = c.ancestor(c2) |
|
145 if ca: |
|
146 copy[c.path()] = f2 |
|
147 copy[f2] = c.path() |
|
148 |
|
149 for f in u1: |
|
150 c = ctx(f, m1[f]) |
|
151 for of in findold(c, limit): |
|
152 if of in m2: |
|
153 checkpair(c, of, m2) |
|
154 else: |
|
155 match.setdefault(of, []).append(f) |
|
156 |
|
157 for f in u2: |
|
158 c = ctx(f, m2[f]) |
|
159 for of in findold(c, limit): |
|
160 if of in m1: |
|
161 checkpair(c, of, m1) |
|
162 elif of in match: |
|
163 for mf in match[of]: |
|
164 checkpair(c, mf, m1) |
|
165 |
|
166 return copy |
96 |
167 |
97 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial): |
168 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial): |
98 """ |
169 """ |
99 Merge manifest m1 with m2 using ancestor ma and generate merge action list |
170 Merge manifest m1 with m2 using ancestor ma and generate merge action list |
100 """ |
171 """ |
287 |
358 |
288 if not force: |
359 if not force: |
289 checkunknown(repo, m2, status) |
360 checkunknown(repo, m2, status) |
290 if not branchmerge: |
361 if not branchmerge: |
291 action += forgetremoved(m2, status) |
362 action += forgetremoved(m2, status) |
|
363 |
|
364 copy = {} |
|
365 if not (backwards or overwrite): |
|
366 copy = findcopies(repo, m1, m2, repo.changelog.rev(pa)) |
|
367 |
292 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial) |
368 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial) |
293 del m1, m2, ma |
369 del m1, m2, ma |
294 |
370 |
295 ### apply phase |
371 ### apply phase |
296 |
372 |