changeset 528:052050ca59d6

replay: disable maybeedit filtering, could discard copy records Copy records were not taken in account when telling whether a file was changed or not. Besides, the only place maybeedits were added was when recording directory copies.
author Patrick Mezard <pmezard@gmail.com>
date Fri, 29 Jan 2010 23:36:14 +0100
parents 2be9f14bd23f
children 68667b627bd5
files hgsubversion/editor.py hgsubversion/replay.py hgsubversion/stupid.py
diffstat 3 files changed, 22 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/hgsubversion/editor.py
+++ b/hgsubversion/editor.py
@@ -35,7 +35,7 @@ class RevisionData(object):
     __slots__ = [
         'file', 'files', 'deleted', 'rev', 'execfiles', 'symlinks', 'batons',
         'copies', 'missing', 'emptybranches', 'base', 'externals', 'ui',
-        'exception', 'maybeedits',
+        'exception',
     ]
 
     def __init__(self, ui):
@@ -57,7 +57,6 @@ class RevisionData(object):
         self.base = None
         self.externals = {}
         self.exception = None
-        self.maybeedits = set()
 
     def set(self, path, data, isexec=False, islink=False):
         if islink:
@@ -283,8 +282,7 @@ class HgEditor(delta.Editor):
                 parentctx = self.repo.changectx(parentid)
                 for k, v in copies.iteritems():
                     if util.issamefile(parentctx, cp_f_ctx, v):
-                        self.current.maybeedits.add(k)
-                        self.current.copies.update({k: v})
+                        self.current.copies[k] = v
         return path
 
     @ieditor
@@ -330,11 +328,6 @@ class HgEditor(delta.Editor):
                 or self.current.file in self.current.missing), '%s not found' % self.current.file
         if self.current.file in self.current.missing:
             return lambda x: None
-        # If we apply a textdelta, the body of the file is going to change.
-        # There's little reason to check and see if it matches the parent, because
-        # that's extremely unlikely. If we see cases where that happens,
-        # maybe this line can go, but until then, it stays.
-        self.current.maybeedits.discard(self.current.file)
         base = self.current.files[self.current.file]
         source = cStringIO.StringIO(base)
         target = cStringIO.StringIO()
--- a/hgsubversion/replay.py
+++ b/hgsubversion/replay.py
@@ -86,22 +86,6 @@ def convert_rev(ui, meta, svn, r, tbdelt
         if not meta.is_path_valid(f):
             continue
         p, b = meta.split_branch_path(f)[:2]
-        # Subversion sometimes "over reports" edits from our perspective,
-        # typically when a directory is restored from some past version.
-        # This isn't something we can detect reliably until the end of
-        # the delta edit, so we have to punt this detection until here
-        # This just verifies that if the file content is identical
-        # in the parent and the to-be-committed file, we don't bother
-        # marking it in the changelog as modified in this revision.
-        if f in current.maybeedits:
-            pctx = meta.repo[meta.get_parent_revision(rev.revnum, b)]
-            if p in pctx and pctx[p].data() == current.files[f]:
-                flags = pctx[p].flags()
-                is_exec = current.execfiles.get(f, 'x' in flags)
-                is_link = current.symlinks.get(f, 'l' in flags)
-                if is_link == ('l' in flags) and is_exec == ('x' in flags):
-                    # file is wholly unchanged, we can skip it
-                    continue
         if b not in branch_batches:
             branch_batches[b] = []
         branch_batches[b].append((p, f))
--- a/hgsubversion/stupid.py
+++ b/hgsubversion/stupid.py
@@ -203,20 +203,28 @@ def diff_branchrev(ui, svn, meta, branch
         assert m in files_data
         link_files[m] = False
 
+    unknown_files = set()
     for p in r.paths:
-        if p.startswith(diff_path) and r.paths[p].action == 'D':
-            if diff_path:
-                p2 = p[len(diff_path)+1:].strip('/')
-            else:
-                p2 = p
-            if p2 in parentctx:
-                files_data[p2] = None
-                continue
+        action = r.paths[p].action
+        if not p.startswith(diff_path) or action not in 'DR':
+            continue
+        if diff_path:
+            p2 = p[len(diff_path)+1:].strip('/')
+        else:
+            p2 = p
+        if p2 in parentctx:
+            toucheds = [p2]
+        else:
             # If this isn't in the parent ctx, it must've been a dir
-            files_data.update([(f, None) for f in parentctx if f.startswith(p2 + '/')])
+            toucheds = [f for f in parentctx if f.startswith(p2 + '/')]
+        if action == 'R':
+            # Files were replaced, we don't know if they still exist
+            unknown_files.update(toucheds)
+        else:
+            files_data.update((f, None) for f in toucheds)
 
-    for f in files_data:
-        touched_files[f] = 1
+    touched_files.update((f, 1) for f in files_data)
+    touched_files.update((f, 1) for f in unknown_files)
 
     copies = getcopies(svn, meta, branch, diff_path, r, touched_files,
                        parentctx)
@@ -225,7 +233,7 @@ def diff_branchrev(ui, svn, meta, branch
         if path in files_data and files_data[path] is None:
             raise IOError()
 
-        if path in binary_files:
+        if path in binary_files or path in unknown_files:
             pa = path
             if diff_path:
                 pa = diff_path + '/' + path