Show More
@@ -237,6 +237,41 b' def _computenonoverlap(repo, c1, c2, add' | |||||
237 | % "\n ".join(u2)) |
|
237 | % "\n ".join(u2)) | |
238 | return u1, u2 |
|
238 | return u1, u2 | |
239 |
|
239 | |||
|
240 | def _makegetfctx(ctx): | |||
|
241 | """return a 'getfctx' function suitable for checkcopies usage | |||
|
242 | ||||
|
243 | We have to re-setup the function building 'filectx' for each | |||
|
244 | 'checkcopies' to ensure the linkrev adjustement is properly setup for | |||
|
245 | each. Linkrev adjustment is important to avoid bug in rename | |||
|
246 | detection. Moreover, having a proper '_ancestrycontext' setup ensures | |||
|
247 | the performance impact of this adjustment is kept limited. Without it, | |||
|
248 | each file could do a full dag traversal making the time complexity of | |||
|
249 | the operation explode (see issue4537). | |||
|
250 | ||||
|
251 | This function exists here mostly to limit the impact on stable. Feel | |||
|
252 | free to refactor on default. | |||
|
253 | """ | |||
|
254 | rev = ctx.rev() | |||
|
255 | repo = ctx._repo | |||
|
256 | ac = getattr(ctx, '_ancestrycontext', None) | |||
|
257 | if ac is None: | |||
|
258 | revs = [rev] | |||
|
259 | if rev is None: | |||
|
260 | revs = [p.rev() for p in ctx.parents()] | |||
|
261 | ac = repo.changelog.ancestors(revs, inclusive=True) | |||
|
262 | ctx._ancestrycontext = ac | |||
|
263 | def makectx(f, n): | |||
|
264 | if len(n) != 20: # in a working context? | |||
|
265 | if ctx.rev() is None: | |||
|
266 | return ctx.filectx(f) | |||
|
267 | return repo[None][f] | |||
|
268 | fctx = repo.filectx(f, fileid=n) | |||
|
269 | # setup only needed for filectx not create from a changectx | |||
|
270 | fctx._ancestrycontext = ac | |||
|
271 | fctx._descendantrev = rev | |||
|
272 | return fctx | |||
|
273 | return util.lrucachefunc(makectx) | |||
|
274 | ||||
240 | def mergecopies(repo, c1, c2, ca): |
|
275 | def mergecopies(repo, c1, c2, ca): | |
241 | """ |
|
276 | """ | |
242 | Find moves and copies between context c1 and c2 that are relevant |
|
277 | Find moves and copies between context c1 and c2 that are relevant | |
@@ -283,42 +318,6 b' def mergecopies(repo, c1, c2, ca):' | |||||
283 | m2 = c2.manifest() |
|
318 | m2 = c2.manifest() | |
284 | ma = ca.manifest() |
|
319 | ma = ca.manifest() | |
285 |
|
320 | |||
286 |
|
||||
287 | def setupctx(ctx): |
|
|||
288 | """return a 'getfctx' function suitable for checkcopies usage |
|
|||
289 |
|
||||
290 | We have to re-setup the function building 'filectx' for each |
|
|||
291 | 'checkcopies' to ensure the linkrev adjustement is properly setup for |
|
|||
292 | each. Linkrev adjustment is important to avoid bug in rename |
|
|||
293 | detection. Moreover, having a proper '_ancestrycontext' setup ensures |
|
|||
294 | the performance impact of this adjustment is kept limited. Without it, |
|
|||
295 | each file could do a full dag traversal making the time complexity of |
|
|||
296 | the operation explode (see issue4537). |
|
|||
297 |
|
||||
298 | This function exists here mostly to limit the impact on stable. Feel |
|
|||
299 | free to refactor on default. |
|
|||
300 | """ |
|
|||
301 | rev = ctx.rev() |
|
|||
302 | ac = getattr(ctx, '_ancestrycontext', None) |
|
|||
303 | repo = ctx._repo |
|
|||
304 | if ac is None: |
|
|||
305 | revs = [rev] |
|
|||
306 | if rev is None: |
|
|||
307 | revs = [p.rev() for p in ctx.parents()] |
|
|||
308 | ac = ctx._repo.changelog.ancestors(revs, inclusive=True) |
|
|||
309 | ctx._ancestrycontext = ac |
|
|||
310 | def makectx(f, n): |
|
|||
311 | if len(n) != 20: # in a working context? |
|
|||
312 | if ctx.rev() is None: |
|
|||
313 | return ctx.filectx(f) |
|
|||
314 | return repo[None][f] |
|
|||
315 | fctx = repo.filectx(f, fileid=n) |
|
|||
316 | # setup only needed for filectx not create from a changectx |
|
|||
317 | fctx._ancestrycontext = ac |
|
|||
318 | fctx._descendantrev = rev |
|
|||
319 | return fctx |
|
|||
320 | return util.lrucachefunc(makectx) |
|
|||
321 |
|
||||
322 | copy1, copy2, = {}, {} |
|
321 | copy1, copy2, = {}, {} | |
323 | movewithdir1, movewithdir2 = {}, {} |
|
322 | movewithdir1, movewithdir2 = {}, {} | |
324 | fullcopy1, fullcopy2 = {}, {} |
|
323 | fullcopy1, fullcopy2 = {}, {} | |
@@ -329,11 +328,11 b' def mergecopies(repo, c1, c2, ca):' | |||||
329 | u1, u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) |
|
328 | u1, u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) | |
330 |
|
329 | |||
331 | for f in u1: |
|
330 | for f in u1: | |
332 |
getfctx = |
|
331 | getfctx = _makegetfctx(c1) | |
333 | checkcopies(getfctx, f, m1, m2, ca, limit, diverge, copy1, fullcopy1) |
|
332 | checkcopies(getfctx, f, m1, m2, ca, limit, diverge, copy1, fullcopy1) | |
334 |
|
333 | |||
335 | for f in u2: |
|
334 | for f in u2: | |
336 |
getfctx = |
|
335 | getfctx = _makegetfctx(c2) | |
337 | checkcopies(getfctx, f, m2, m1, ca, limit, diverge, copy2, fullcopy2) |
|
336 | checkcopies(getfctx, f, m2, m1, ca, limit, diverge, copy2, fullcopy2) | |
338 |
|
337 | |||
339 | copy = dict(copy1.items() + copy2.items()) |
|
338 | copy = dict(copy1.items() + copy2.items()) | |
@@ -360,10 +359,10 b' def mergecopies(repo, c1, c2, ca):' | |||||
360 | % "\n ".join(bothnew)) |
|
359 | % "\n ".join(bothnew)) | |
361 | bothdiverge, _copy, _fullcopy = {}, {}, {} |
|
360 | bothdiverge, _copy, _fullcopy = {}, {}, {} | |
362 | for f in bothnew: |
|
361 | for f in bothnew: | |
363 |
getfctx = |
|
362 | getfctx = _makegetfctx(c1) | |
364 | checkcopies(getfctx, f, m1, m2, ca, limit, bothdiverge, |
|
363 | checkcopies(getfctx, f, m1, m2, ca, limit, bothdiverge, | |
365 | _copy, _fullcopy) |
|
364 | _copy, _fullcopy) | |
366 |
getfctx = |
|
365 | getfctx = _makegetfctx(c2) | |
367 | checkcopies(getfctx, f, m2, m1, ca, limit, bothdiverge, |
|
366 | checkcopies(getfctx, f, m2, m1, ca, limit, bothdiverge, | |
368 | _copy, _fullcopy) |
|
367 | _copy, _fullcopy) | |
369 | for of, fl in bothdiverge.items(): |
|
368 | for of, fl in bothdiverge.items(): |
General Comments 0
You need to be logged in to leave comments.
Login now