Mercurial > hgsubversion
diff svnwrap/svn_swig_wrapper.py @ 89:edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Calling it repeatedly is expensive, files and directories are created,
svn transport layer is reset.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Fri, 14 Nov 2008 16:18:24 -0600 |
parents | b033d74be76b |
children | 7486c6f6cccc |
line wrap: on
line diff
--- a/svnwrap/svn_swig_wrapper.py +++ b/svnwrap/svn_swig_wrapper.py @@ -14,6 +14,14 @@ from svn import ra if (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_MICRO) < (1, 5, 0): #pragma: no cover raise ImportError, 'You must have Subversion 1.5.0 or newer and matching SWIG bindings.' +class SubversionRepoCanNotReplay(Exception): + """Exception raised when the svn server is too old to have replay. + """ + +class SubversionRepoCanNotDiff(Exception): + """Exception raised when the svn API diff3() command cannot be used + """ + def optrev(revnum): optrev = core.svn_opt_revision_t() optrev.kind = core.svn_opt_revision_number @@ -111,6 +119,7 @@ class SubversionRepo(object): self.subdir = url[len(repo_root):] if not self.subdir or self.subdir[-1] != '/': self.subdir += '/' + self.hasdiff3 = True def init_ra_and_client(self): """Initializes the RA and client layers, because sometimes getting @@ -367,6 +376,8 @@ class SubversionRepo(object): deleted=True, ignore_type=False): """Gets a unidiff of path at revision against revision-1. """ + if not self.hasdiff3: + raise SubversionRepoCanNotDiff() # works around an svn server keeping too many open files (observed # in an svnserve from the 1.2 era) self.init_ra_and_client() @@ -380,24 +391,34 @@ class SubversionRepo(object): other_rev = revision - 1 old_cwd = os.getcwd() tmpdir = tempfile.mkdtemp('svnwrap_temp') + out, err = None, None try: # hot tip: the swig bridge doesn't like StringIO for these bad boys out_path = os.path.join(tmpdir, 'diffout') error_path = os.path.join(tmpdir, 'differr') - out, err = None, None + out = open(out_path, 'w') + err = open(error_path, 'w') try: - out = open(out_path, 'w') - err = open(error_path, 'w') client.diff3([], url2, optrev(other_rev), url, optrev(revision), True, True, deleted, ignore_type, 'UTF-8', out, err, self.client_context, self.pool) - finally: - if out: out.close() - if err: err.close() + except core.SubversionException, e: + # "Can't write to stream: The handle is invalid." + # This error happens systematically under Windows, possibly + # related to file handles being non-write shareable by default. + if e.apr_err != 720006: + raise + self.hasdiff3 = False + raise SubversionRepoCanNotDiff() + out.close() + err.close() + out, err = None, None assert len(open(error_path).read()) == 0 diff = open(out_path).read() return diff finally: + if out: out.close() + if err: err.close() shutil.rmtree(tmpdir) os.chdir(old_cwd) @@ -473,7 +494,3 @@ class SubversionRepo(object): """ kind = ra.check_path(self.ra, path.strip('/'), revision) return _svntypes.get(kind) - -class SubversionRepoCanNotReplay(Exception): - """Exception raised when the svn server is too old to have replay. - """