diff --git a/vcsserver/base.py b/vcsserver/base.py --- a/vcsserver/base.py +++ b/vcsserver/base.py @@ -114,13 +114,13 @@ def archive_repo(walker, archive_dest_pa f'Remote does not support: "{kind}" archive type.') for f in walker(commit_id, archive_at_path): - f_path = os.path.join(safe_bytes(archive_dir_name), f.path.lstrip(b'/')) + f_path = os.path.join(safe_bytes(archive_dir_name), safe_bytes(f.path).lstrip(b'/')) try: archiver.addfile(f_path, f.mode, f.is_link, f.raw_bytes()) except NoContentException: # NOTE(marcink): this is a special case for SVN so we can create "empty" # directories which arent supported by archiver - archiver.addfile(os.path.join(f_path, b'.dir'), f.mode, f.is_link, '') + archiver.addfile(os.path.join(f_path, b'.dir'), f.mode, f.is_link, b'') if write_metadata: metadata = dict([ diff --git a/vcsserver/remote/git.py b/vcsserver/remote/git.py --- a/vcsserver/remote/git.py +++ b/vcsserver/remote/git.py @@ -1127,6 +1127,7 @@ class GitRemote(RemoteBase): @reraise_safe_exceptions def diff(self, wire, commit_id_1, commit_id_2, file_filter, opt_ignorews, context): repo_init = self._factory.repo_libgit2(wire) + with repo_init as repo: swap = True flags = 0 @@ -1152,7 +1153,7 @@ class GitRemote(RemoteBase): if file_filter: for p in diff_obj: if p.delta.old_file.path == file_filter: - return p.patch or '' + return p.data or '' # fo matching path == no diff return '' return diff_obj.patch or '' diff --git a/vcsserver/remote/hg.py b/vcsserver/remote/hg.py --- a/vcsserver/remote/hg.py +++ b/vcsserver/remote/hg.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - +import binascii import io import logging import stat @@ -471,7 +471,9 @@ class HgRemote(RemoteBase): repo = self._factory.repo(wire) if file_filter: - match_filter = match(file_filter[0], '', [file_filter[1]]) + # unpack the file-filter + repo_path, node_path = file_filter + match_filter = match(safe_bytes(repo_path), b'', [safe_bytes(node_path)]) else: match_filter = file_filter opts = diffopts(git=opt_git, ignorews=opt_ignorews, context=context, showfunc=1) @@ -683,7 +685,7 @@ class HgRemote(RemoteBase): rev = rev + -1 try: ctx = self._get_ctx(repo, rev) - except (TypeError, RepoLookupError) as e: + except (TypeError, RepoLookupError, binascii.Error) as e: e._org_exc_tb = traceback.format_exc() raise exceptions.LookupException(e)(rev) except LookupError as e: diff --git a/vcsserver/remote/svn.py b/vcsserver/remote/svn.py --- a/vcsserver/remote/svn.py +++ b/vcsserver/remote/svn.py @@ -559,6 +559,7 @@ class SvnRemote(RemoteBase): """ Special recursive svn repo walker """ + root_dir = safe_bytes(root_dir) filemode_default = 0o100644 filemode_executable = 0o100755 @@ -574,7 +575,8 @@ class SvnRemote(RemoteBase): for _f_name, _f_data, _f_type in walk_tree(root, new_root, _commit_id): yield _f_name, _f_data, _f_type else: - f_path = os.path.join(root_dir, f_name).rstrip('/') + + f_path = os.path.join(root_dir, f_name).rstrip(b'/') prop_list = svn.fs.node_proplist(root, f_path) f_mode = filemode_default @@ -697,6 +699,11 @@ class SvnDiffer(object): def _generate_node_diff( self, buf, change, tgt_path, tgt_base, src_path, src_base): + + tgt_path = safe_str(tgt_path) + src_path = safe_str(src_path) + + if self.src_rev == self.tgt_rev and tgt_base == src_base: # makes consistent behaviour with git/hg to return empty diff if # we compare same revisions @@ -754,6 +761,7 @@ class SvnDiffer(object): ignore_blank_lines=self.ignore_whitespace, ignore_case=False, ignore_space_changes=self.ignore_whitespace) + buf.writelines(udiff) def _get_mime_type(self, path): @@ -774,6 +782,7 @@ class SvnDiffer(object): return [] content = svn.core.Stream( svn.fs.file_contents(fs_root, node_path)).read() + return content.splitlines(True) diff --git a/vcsserver/svn_diff.py b/vcsserver/svn_diff.py --- a/vcsserver/svn_diff.py +++ b/vcsserver/svn_diff.py @@ -161,6 +161,7 @@ def unified_diff(fromlines, tolines, con See `get_filtered_hunks` for the parameter descriptions. """ # TODO: johbo: Check if this can be nicely integrated into the matching + if ignore_space_changes: fromlines = [l.strip() for l in fromlines] tolines = [l.strip() for l in tolines]