Show More
@@ -196,30 +196,13 b' def _changesetforwardcopies(a, b, match)' | |||||
196 | children[p].append(r) |
|
196 | children[p].append(r) | |
197 |
|
197 | |||
198 | roots = set(children) - set(missingrevs) |
|
198 | roots = set(children) - set(missingrevs) | |
199 | # 'work' contains 3-tuples of a (revision number, parent number, copies). |
|
199 | work = list(roots) | |
200 | # The parent number is only used for knowing which parent the copies dict |
|
200 | all_copies = {r: {} for r in roots} | |
201 | # came from. |
|
|||
202 | # NOTE: To reduce costly copying the 'copies' dicts, we reuse the same |
|
|||
203 | # instance for *one* of the child nodes (the last one). Once an instance |
|
|||
204 | # has been put on the queue, it is thus no longer safe to modify it. |
|
|||
205 | # Conversely, it *is* safe to modify an instance popped off the queue. |
|
|||
206 | work = [(r, 1, {}) for r in roots] |
|
|||
207 | heapq.heapify(work) |
|
201 | heapq.heapify(work) | |
208 | alwaysmatch = match.always() |
|
202 | alwaysmatch = match.always() | |
209 | while work: |
|
203 | while work: | |
210 |
r |
|
204 | r = heapq.heappop(work) | |
211 | if work and work[0][0] == r: |
|
205 | copies = all_copies.pop(r) | |
212 | # We are tracing copies from both parents |
|
|||
213 | r, i2, copies2 = heapq.heappop(work) |
|
|||
214 | for dst, src in copies2.items(): |
|
|||
215 | # Unlike when copies are stored in the filelog, we consider |
|
|||
216 | # it a copy even if the destination already existed on the |
|
|||
217 | # other branch. It's simply too expensive to check if the |
|
|||
218 | # file existed in the manifest. |
|
|||
219 | if dst not in copies: |
|
|||
220 | # If it was copied on the p1 side, leave it as copied from |
|
|||
221 | # that side, even if it was also copied on the p2 side. |
|
|||
222 | copies[dst] = copies2[dst] |
|
|||
223 | if r == b.rev(): |
|
206 | if r == b.rev(): | |
224 | return copies |
|
207 | return copies | |
225 | for i, c in enumerate(children[r]): |
|
208 | for i, c in enumerate(children[r]): | |
@@ -245,7 +228,28 b' def _changesetforwardcopies(a, b, match)' | |||||
245 | for f in childctx.filesremoved(): |
|
228 | for f in childctx.filesremoved(): | |
246 | if f in newcopies: |
|
229 | if f in newcopies: | |
247 | del newcopies[f] |
|
230 | del newcopies[f] | |
248 | heapq.heappush(work, (c, parent, newcopies)) |
|
231 | othercopies = all_copies.get(c) | |
|
232 | if othercopies is None: | |||
|
233 | heapq.heappush(work, c) | |||
|
234 | all_copies[c] = newcopies | |||
|
235 | else: | |||
|
236 | # we are the second parent to work on c, we need to merge our | |||
|
237 | # work with the other. | |||
|
238 | # | |||
|
239 | # Unlike when copies are stored in the filelog, we consider | |||
|
240 | # it a copy even if the destination already existed on the | |||
|
241 | # other branch. It's simply too expensive to check if the | |||
|
242 | # file existed in the manifest. | |||
|
243 | # | |||
|
244 | # In case of conflict, parent 1 take precedence over parent 2. | |||
|
245 | # This is an arbitrary choice made anew when implementing | |||
|
246 | # changeset based copies. It was made without regards with | |||
|
247 | # potential filelog related behavior. | |||
|
248 | if parent == 1: | |||
|
249 | othercopies.update(newcopies) | |||
|
250 | else: | |||
|
251 | newcopies.update(othercopies) | |||
|
252 | all_copies[c] = newcopies | |||
249 | assert False |
|
253 | assert False | |
250 |
|
254 | |||
251 |
|
255 |
General Comments 0
You need to be logged in to leave comments.
Login now