changeset 793:e698be84c22d

pushmod: fix binary files svn:mime-type (issue255) - Handle single directory layout - Reset svn:mime-type when the file is no longer binary
author Patrick Mezard <pmezard@gmail.com>
date Thu, 10 Mar 2011 22:17:56 +0100
parents ba65c0b01d4f
children c32c92fdca5b
files hgsubversion/pushmod.py tests/test_single_dir_clone.py tests/test_util.py
diffstat 3 files changed, 32 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/hgsubversion/pushmod.py
+++ b/hgsubversion/pushmod.py
@@ -122,6 +122,9 @@ def commit(ui, repo, rev_ctx, meta, base
                 props.setdefault(file, {})['svn:executable'] = '*'
             if 'l' in fctx.flags():
                 props.setdefault(file, {})['svn:special'] = '*'
+            isbinary = hgutil.binary(new_data)
+            if isbinary:
+                props.setdefault(file, {})['svn:mime-type'] = 'application/octet-stream'
 
             if file not in parent:
                 renamed = fctx.renamed()
@@ -141,6 +144,8 @@ def commit(ui, repo, rev_ctx, meta, base
                 if ('l' in parent.filectx(file).flags()
                     and 'l' not in rev_ctx.filectx(file).flags()):
                     props.setdefault(file, {})['svn:special'] = None
+                if hgutil.binary(base_data) and not isbinary:
+                    props.setdefault(file, {})['svn:mime-type'] = None
                 action = 'modify'
         else:
             pos = file.rfind('/')
@@ -178,11 +183,7 @@ def commit(ui, repo, rev_ctx, meta, base
         if tf in file_data and tf != ntf:
             file_data[ntf] = file_data[tf]
             if tf in props:
-                props[ntf] = props[tf]
-                del props[tf]
-            if hgutil.binary(file_data[ntf][1]):
-                props.setdefault(ntf, {}).update(props.get(ntf, {}))
-                props.setdefault(ntf, {})['svn:mime-type'] = 'application/octet-stream'
+                props[ntf] = props.pop(tf)
             del file_data[tf]
 
     addeddirs = [svnpath(d) for d in addeddirs]
--- a/tests/test_single_dir_clone.py
+++ b/tests/test_single_dir_clone.py
@@ -92,11 +92,17 @@ class TestSingleDir(test_util.TestBase):
                                           islink=False,
                                           isexec=False,
                                           copied=False)
+            elif path == 'adding_binary':
+                return context.memfilectx(path=path,
+                                          data='\0binary',
+                                          islink=False,
+                                          isexec=False,
+                                          copied=False)
             raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
         ctx = context.memctx(repo,
                              (repo['tip'].node(), node.nullid),
                              'automated test',
-                             ['adding_file'],
+                             ['adding_file', 'adding_binary'],
                              file_callback,
                              'an_author',
                              '2009-10-19 18:49:30 -0500',
@@ -105,6 +111,13 @@ class TestSingleDir(test_util.TestBase):
         hg.update(repo, repo['tip'].node())
         self.pushrevisions()
         self.assertTrue('adding_file' in self.svnls(''))
+        self.assertEqual('application/octet-stream',
+                         self.svnpropget('adding_binary', 'svn:mime-type'))
+        # Now add another commit and test mime-type being reset
+        changes = [('adding_binary', 'adding_binary', 'no longer binary')]
+        self.commitchanges(changes)
+        self.pushrevisions()
+        self.assertEqual('', self.svnpropget('adding_binary', 'svn:mime-type'))
 
     def test_push_single_dir_at_subdir(self):
         repo = self._load_fixture_and_fetch('branch_from_tag.svndump',
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -351,6 +351,18 @@ class TestBase(unittest.TestCase):
         if p.returncode:
             raise Exception('svn co failed on %s: %r' % (svnpath, stderr))
 
+    def svnpropget(self, path, prop, rev='HEAD'):
+        path = self.repo_path + '/' + path
+        path = util.normalize_url(fileurl(path))
+        args = ['svn', 'propget', '-r', str(rev), prop, path]
+        p = subprocess.Popen(args,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        stdout, stderr = p.communicate()
+        if p.returncode:
+            raise Exception('svn ls failed on %s: %r' % (path, stderr))
+        return stdout.strip()
+
     def commitchanges(self, changes, parent='tip', message='automated test'):
         """Commit changes to mercurial directory