comparison mercurial/copies.py @ 46184:cb8b2ee89a5d

copies: stop attempt to avoid extra dict copies around branching In the python code, we attempt to avoid unnecessary dict copies when gathering copy information. However that logic is wobbly and I keep running into case where independent branches affects each others. With the current code we can't ensure we are the only "user" of dict when dealing with merge. This caused havoc in the next series on tests I am about to introduce. So for now I am disabling the faulty optimisation. I believe we will need a dedicated overlay to deal with the "copy on write logic" to have something correct. I am also hoping to find time to build dedicated test case for this category of problem instead of relying on side effect in other tests. However for now I am focussing on another issue. Differential Revision: https://phab.mercurial-scm.org/D9608
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 15 Dec 2020 00:29:29 +0100
parents ee63c1173c1b
children 599d247af600
comparison
equal deleted inserted replaced
46183:ee63c1173c1b 46184:cb8b2ee89a5d
381 else: 381 else:
382 copies = all_copies.pop(parent_rev, None) 382 copies = all_copies.pop(parent_rev, None)
383 383
384 if copies is None: 384 if copies is None:
385 # this is a root 385 # this is a root
386 copies = {} 386 newcopies = copies = {}
387 387 elif remaining_children:
388 newcopies = copies 388 newcopies = copies.copy()
389 else:
390 newcopies = copies
389 # chain the data in the edge with the existing data 391 # chain the data in the edge with the existing data
390 if changes is not None: 392 if changes is not None:
391 childcopies = {} 393 childcopies = {}
392 if parent == 1: 394 if parent == 1:
393 childcopies = changes.copied_from_p1 395 childcopies = changes.copied_from_p1
401 if prev is not None and prev[1] is not None: 403 if prev is not None and prev[1] is not None:
402 source = prev[1] 404 source = prev[1]
403 newcopies[dest] = (current_rev, source) 405 newcopies[dest] = (current_rev, source)
404 assert newcopies is not copies 406 assert newcopies is not copies
405 if changes.removed: 407 if changes.removed:
406 if newcopies is copies:
407 newcopies = copies.copy()
408 for f in changes.removed: 408 for f in changes.removed:
409 if f in newcopies: 409 if f in newcopies:
410 if newcopies is copies: 410 if newcopies is copies:
411 # copy on write to avoid affecting potential other 411 # copy on write to avoid affecting potential other
412 # branches. when there are no other branches, this 412 # branches. when there are no other branches, this
415 newcopies[f] = (current_rev, None) 415 newcopies[f] = (current_rev, None)
416 # check potential need to combine the data from another parent (for 416 # check potential need to combine the data from another parent (for
417 # that child). See comment below for details. 417 # that child). See comment below for details.
418 if current_copies is None: 418 if current_copies is None:
419 current_copies = newcopies 419 current_copies = newcopies
420 elif current_copies is newcopies:
421 # nothing to merge:
422 pass
423 else: 420 else:
424 # we are the second parent to work on c, we need to merge our 421 # we are the second parent to work on c, we need to merge our
425 # work with the other. 422 # work with the other.
426 # 423 #
427 # In case of conflict, parent 1 take precedence over parent 2. 424 # In case of conflict, parent 1 take precedence over parent 2.