changeset 498:990e07054f29

replay: fix potential over-reporting of edited files in hg changelog
author Augie Fackler <durin42@gmail.com>
date Fri, 16 Oct 2009 18:37:19 -0400
parents cad864ed29de
children 1fd3cfa47c5e
files hgsubversion/editor.py hgsubversion/replay.py
diffstat 2 files changed, 24 insertions(+), 1 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',
+        'exception', 'maybeedits',
     ]
 
     def __init__(self, ui):
@@ -57,6 +57,7 @@ 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:
@@ -280,6 +281,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})
         return path
 
@@ -326,6 +328,11 @@ 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
@@ -85,6 +85,22 @@ 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))