Mercurial > public > mercurial-scm > hg
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. |