changeset 864:39d45f2190ee

Merge
author Augie Fackler <raf@durin42.com>
date Thu, 19 Apr 2012 17:30:08 -0500
parents 6ef6c413d6de (diff) c24130e9ddb7 (current diff)
children 04729f3a3d17
files hgsubversion/stupid.py
diffstat 2 files changed, 42 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/hgsubversion/editor.py
+++ b/hgsubversion/editor.py
@@ -10,6 +10,18 @@ import svnwrap
 import util
 import svnexternals
 
+class NeverClosingStringIO(object):
+    def __init__(self):
+        self._fp = cStringIO.StringIO()
+
+    def __getattr__(self, name):
+        return getattr(self._fp, name)
+
+    def close(self):
+        # svn 1.7 apply_delta driver now calls close() on passed file
+        # object which prevent us from calling getvalue() afterwards.
+        pass
+
 class RevisionData(object):
 
     __slots__ = [
@@ -331,7 +343,7 @@ class HgEditor(svnwrap.Editor):
         if self.current.file in self.current.missing:
             return lambda x: None
         base = self.current.files[self.current.file]
-        target = cStringIO.StringIO()
+        target = NeverClosingStringIO()
         self.stream = target
 
         handler = svnwrap.apply_txdelta(base, target)
@@ -342,13 +354,10 @@ class HgEditor(svnwrap.Editor):
             try:
                 if not self.meta.is_path_valid(self.current.file):
                     return
-                # Already get and store the value here, because calling
-                # handler(window) seems to close the target in Subversion 1.7.
-                val = target.getvalue()
                 handler(window)
                 # window being None means commit this file
                 if not window:
-                    self.current.files[self.current.file] = val
+                    self.current.files[self.current.file] = target.getvalue()
             except svnwrap.SubversionException, e: # pragma: no cover
                 if e.args[1] == svnwrap.ERR_INCOMPLETE_DATA:
                     self.current.missing.add(self.current.file)
--- a/hgsubversion/stupid.py
+++ b/hgsubversion/stupid.py
@@ -80,6 +80,10 @@ class filediff:
     def isempty(self):
         return (not self.diff and not self.binary and not self.hasprops)
 
+    def maybedir(self):
+        return (not self.diff and not self.binary and self.hasprops
+                and self.symlink is None and self.executable is None)
+
 def parsediff(diff):
     changes = {}
     headers = headers_re.split(diff)[1:]
@@ -320,6 +324,23 @@ def diff_branchrev(ui, svn, meta, branch
     touched_files.update(files_data)
     touched_files.update(unknown_files)
 
+    # As of svn 1.7, diff may contain a lot of property changes for
+    # directories. We do not what to include these in our touched
+    # files list so we try to filter them while minimizing the number
+    # of svn API calls.
+    property_files = set(f.name for f in changed if f.maybedir())
+    property_files.discard('.')
+    touched_files.discard('.')
+    branchprefix = (branchpath and branchpath + '/') or branchpath
+    for f in list(property_files):
+        if f in parentctx:
+            continue
+        # We can be smarter here by checking if f is a subcomponent
+        # of a know path in parentctx or touched_files. KISS for now.
+        kind = svn.checkpath(branchprefix + f, r.revnum)
+        if kind == 'd':
+            touched_files.discard(f)
+
     copies = getcopies(svn, meta, branch, branchpath, r, touched_files,
                        parentctx)
 
@@ -694,7 +715,13 @@ def convert_rev(ui, meta, svn, r, tbdelt
                 deleted_branches[b] = parentctx.node()
             continue
 
-        incremental = (meta.revmap.oldest > 0)
+        # The nullrev check might not be necessary in theory but svn <
+        # 1.7 failed to diff branch creation so the diff_branchrev()
+        # path does not support this case with svn >= 1.7. We can fix
+        # it, or we can force the existing fetch_branchrev() path. Do
+        # the latter for now.
+        incremental = (meta.revmap.oldest > 0 and
+                       parentctx.rev() != node.nullrev)
 
         if incremental:
             try: