Patchwork D9608: copies: stop attempt to avoid extra dict copies around branching

login
register
mail settings
Submitter phabricator
Date Dec. 15, 2020, 9:07 a.m.
Message ID <differential-rev-PHID-DREV-6vnez5j32jsrygxrejsw-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47906/
State Superseded
Headers show

Comments

phabricator - Dec. 15, 2020, 9:07 a.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  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.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9608

AFFECTED FILES
  mercurial/copies.py

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -382,9 +382,11 @@ 
 
                 if copies is None:
                     # this is a root
-                    copies = {}
-
-                newcopies = copies
+                    newcopies = copies = {}
+                elif remaining_children:
+                    newcopies = copies.copy()
+                else:
+                    newcopies = copies
                 # chain the data in the edge with the existing data
                 if changes is not None:
                     childcopies = {}
@@ -402,8 +404,6 @@ 
                             newcopies[dest] = (current_rev, source)
                         assert newcopies is not copies
                     if changes.removed:
-                        if newcopies is copies:
-                            newcopies = copies.copy()
                         for f in changes.removed:
                             if f in newcopies:
                                 if newcopies is copies:
@@ -416,9 +416,6 @@ 
                 # that child). See comment below for details.
                 if current_copies is None:
                     current_copies = newcopies
-                elif current_copies is newcopies:
-                    # nothing to merge:
-                    pass
                 else:
                     # we are the second parent to work on c, we need to merge our
                     # work with the other.