[#8375] svn fixes
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index e858947..4fbb768 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -19,6 +19,7 @@
 import json
 import os
 import stat
+from operator import itemgetter
 import mimetypes
 import logging
 import string
@@ -1207,7 +1208,7 @@
             added=sorted(diffs['added']),
             removed=sorted(diffs['removed']),
             changed=sorted(diffs['changed']),
-            copied=sorted(diffs['copied']),
+            copied=sorted(diffs['copied'], key=itemgetter('new', 'old')),  # this is a list of dicts
             renamed=sorted(diffs['renamed']),
             total=diffs['total'])
 
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index a01fdd4..5b40b5d 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -32,6 +32,7 @@
 import tempfile
 from shutil import rmtree
 
+import six
 import tg
 import pysvn
 from paste.deploy.converters import asbool, asint
@@ -218,12 +219,12 @@
         # check for svn version 1.7 or later
         stdout, stderr, returncode = self.check_call(['svn', '--version'])
         pattern = r'version (?P<maj>\d+)\.(?P<min>\d+)'
-        m = re.search(pattern, stdout)
+        m = re.search(pattern, six.ensure_text(stdout))
         return m and (int(m.group('maj')) * 10 + int(m.group('min'))) >= 17
 
     def check_call(self, cmd, fail_on_error=True):
         p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
-        stdout, stderr = p.communicate(input='p\n')
+        stdout, stderr = p.communicate(input=b'p\n')
         if p.returncode != 0 and fail_on_error:
             self._repo.set_status('ready')
             raise SVNCalledProcessError(cmd, p.returncode, stdout, stderr)
@@ -236,7 +237,7 @@
         def set_hook(hook_name):
             fn = os.path.join(self._repo.fs_path, self._repo.name,
                               'hooks', hook_name)
-            with open(fn, 'wb') as fp:
+            with open(fn, 'w') as fp:
                 fp.write('#!/bin/sh\n')
             os.chmod(fn, 0o755)
 
@@ -611,7 +612,7 @@
             url=self._repo.refresh_url())
         fn = os.path.join(self._repo.fs_path, self._repo.name,
                           'hooks', 'post-commit')
-        with open(fn, 'wb') as fp:
+        with open(fn, 'w') as fp:
             fp.write(text)
         os.chmod(fn, 0o755)
 
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 6cd8976..14e6602 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -682,8 +682,7 @@
             # BSON datetime resolution is to 1 millisecond, not 1 microsecond
             # like Python. Round this now so it'll match the value that's
             # pulled from MongoDB in the tests.
-            ci.authored.date = dt.replace(
-                microsecond=dt.microsecond / 1000 * 1000)
+            ci.authored.date = dt.replace(microsecond=dt.microsecond // 1000 * 1000)
             ci.message = 'summary\n\nddescription'
             ci.set_context(self.repo)
             ci.tree_id = 't_' + object_id