-# Copyright (C) 2005-2006 Jelmer Vernooij <jelmer@samba.org>
+# Copyright (C) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
from cStringIO import StringIO
import urllib
-import svn.core, svn.wc, svn.delta
-from svn.core import Pool
-
-from bzrlib.plugins.svn import errors, properties, core
+from bzrlib.plugins.svn.delta import apply_txdelta_handler
+from bzrlib.plugins.svn import core, errors, properties, wc
def parse_externals_description(base_url, val):
"""Parse an svn:externals property value.
inv.add(ie)
-# Deal with Subversion 1.5 and the patched Subversion 1.4 (which are
-# slightly different).
-
-if hasattr(svn.delta, 'tx_invoke_window_handler'):
- def apply_txdelta_handler(src_stream, target_stream, pool):
- assert hasattr(src_stream, 'read')
- assert hasattr(target_stream, 'write')
- window_handler, baton = svn.delta.tx_apply(src_stream, target_stream,
- None, pool)
-
- def wrapper(window):
- window_handler(window, baton)
-
- return wrapper
-else:
- def apply_txdelta_handler(src_stream, target_stream, pool):
- assert hasattr(src_stream, 'read')
- assert hasattr(target_stream, 'write')
- ret = svn.delta.svn_txdelta_apply(src_stream, target_stream, None, pool)
-
- def wrapper(window):
- svn.delta.invoke_txdelta_window_handler(
- ret[1], window, ret[2])
-
- return wrapper
-
-
class SvnRevisionTree(RevisionTree):
"""A tree that existed in a historical Subversion revision."""
def __init__(self, repository, revision_id):
self._repository = repository
self._revision_id = revision_id
- pool = Pool()
(self.branch_path, self.revnum, mapping) = repository.lookup_revision_id(revision_id)
self._inventory = Inventory()
self.id_map = repository.get_fileid_map(self.revnum, self.branch_path,
mapping)
- editor = TreeBuildEditor(self, pool)
+ editor = TreeBuildEditor(self)
self.file_data = {}
root_repos = repository.transport.get_svn_repos_root()
- reporter = repository.transport.do_switch(
- self.revnum, True,
- urlutils.join(root_repos, self.branch_path), editor, pool)
- reporter.set_path("", 0, True, None, pool)
- reporter.finish_report(pool)
- pool.destroy()
+ conn = repository.transport.get_connection()
+ reporter = conn.do_switch(
+ self.revnum, "", True,
+ urlutils.join(root_repos, self.branch_path), editor)
+ try:
+ reporter.set_path("", 0, True)
+ reporter.finish()
+ finally:
+ repository.transport.add_connection(conn)
def get_file_lines(self, file_id):
return osutils.split_lines(self.file_data[file_id])
-class TreeBuildEditor(svn.delta.Editor):
+class TreeBuildEditor:
"""Builds a tree given Subversion tree transform calls."""
- def __init__(self, tree, pool):
+ def __init__(self, tree):
self.tree = tree
self.repository = tree._repository
self.last_revnum = {}
- self.dir_revnum = {}
- self.dir_ignores = {}
- self.pool = pool
def set_target_revision(self, revnum):
self.revnum = revnum
- def open_root(self, revnum, baton):
+ def open_root(self, revnum):
file_id, revision_id = self.tree.id_map[""]
ie = self.tree._inventory.add_path("", 'directory', file_id)
ie.revision = revision_id
self.tree._inventory.revision_id = revision_id
- return file_id
+ return DirectoryTreeEditor(self.tree, file_id)
- def add_directory(self, path, parent_baton, copyfrom_path, copyfrom_revnum, pool):
+ def close(self):
+ pass
+
+ def abort(self):
+ pass
+
+class DirectoryTreeEditor:
+ def __init__(self, tree, file_id):
+ self.tree = tree
+ self.file_id = file_id
+
+ def add_directory(self, path, copyfrom_path=None, copyfrom_revnum=-1):
path = path.decode("utf-8")
file_id, revision_id = self.tree.id_map[path]
ie = self.tree._inventory.add_path(path, 'directory', file_id)
ie.revision = revision_id
- return file_id
+ return DirectoryTreeEditor(self.tree, file_id)
- def change_dir_prop(self, id, name, value, pool):
- if name == properties.PROP_ENTRY_COMMITTED_REV:
- self.dir_revnum[id] = int(value)
- elif name == properties.PROP_IGNORE:
- self.dir_ignores[id] = value
- elif name in (properties.PROP_ENTRY_COMMITTED_DATE,
+ def change_prop(self, name, value):
+ if name in (properties.PROP_ENTRY_COMMITTED_DATE,
+ properties.PROP_ENTRY_COMMITTED_REV,
properties.PROP_ENTRY_LAST_AUTHOR,
properties.PROP_ENTRY_LOCK_TOKEN,
properties.PROP_ENTRY_UUID,
- properties.PROP_EXECUTABLE):
+ properties.PROP_EXECUTABLE,
+ properties.PROP_IGNORE):
pass
elif name.startswith(properties.PROP_WC_PREFIX):
pass
elif name.startswith(properties.PROP_PREFIX):
mutter('unsupported dir property %r', name)
- def change_file_prop(self, id, name, value, pool):
+ def add_file(self, path, copyfrom_path=None, copyfrom_revnum=-1):
+ path = path.decode("utf-8")
+ return FileTreeEditor(self.tree, path)
+
+ def close(self):
+ pass
+
+
+class FileTreeEditor:
+ def __init__(self, tree, path):
+ self.tree = tree
+ self.path = path
+ self.is_executable = False
+ self.is_symlink = False
+ self.last_file_rev = None
+
+ def change_prop(self, name, value):
+ from mapping import SVN_PROP_BZR_PREFIX
+
if name == properties.PROP_EXECUTABLE:
self.is_executable = (value != None)
elif name == properties.PROP_SPECIAL:
elif name.startswith(properties.PROP_PREFIX):
mutter('unsupported file property %r', name)
- def add_file(self, path, parent_id, copyfrom_path, copyfrom_revnum, baton):
- path = path.decode("utf-8")
- self.is_symlink = False
- self.is_executable = False
- return path
-
- def close_dir(self, id):
- if id in self.tree._inventory and self.dir_ignores.has_key(id):
- self.tree._inventory[id].ignores = self.dir_ignores[id]
-
- def close_file(self, path, checksum):
- file_id, revision_id = self.tree.id_map[path]
+ def close(self, checksum=None):
+ file_id, revision_id = self.tree.id_map[self.path]
if self.is_symlink:
- ie = self.tree._inventory.add_path(path, 'symlink', file_id)
+ ie = self.tree._inventory.add_path(self.path, 'symlink', file_id)
else:
- ie = self.tree._inventory.add_path(path, 'file', file_id)
+ ie = self.tree._inventory.add_path(self.path, 'file', file_id)
ie.revision = revision_id
if self.file_stream:
self.file_stream = None
- def close_edit(self):
- pass
-
- def abort_edit(self):
- pass
-
- def apply_textdelta(self, file_id, base_checksum):
+ def apply_textdelta(self, base_checksum=None):
self.file_stream = StringIO()
- return apply_txdelta_handler(StringIO(""), self.file_stream, self.pool)
+ return apply_txdelta_handler("", self.file_stream)
class SvnBasisTree(RevisionTree):
self._inventory = Inventory(root_id=None)
self._repository = workingtree.branch.repository
- def add_file_to_inv(relpath, id, revid, wc):
- props = svn.wc.get_prop_diffs(self.workingtree.abspath(relpath).encode("utf-8"), wc)
- if isinstance(props, list): # Subversion 1.5
- props = props[1]
+ def add_file_to_inv(relpath, id, revid, adm):
+ (delta_props, props) = adm.get_prop_diffs(self.workingtree.abspath(relpath))
if props.has_key(properties.PROP_SPECIAL):
ie = self._inventory.add_path(relpath, 'symlink', id)
ie.symlink_target = open(self._abspath(relpath)).read()[len("link "):]
def find_ids(entry):
relpath = urllib.unquote(entry.url[len(entry.repos):].strip("/"))
- if entry.schedule in (svn.wc.schedule_normal,
- svn.wc.schedule_delete,
- svn.wc.schedule_replace):
+ if entry.schedule in (wc.SCHEDULE_NORMAL,
+ wc.SCHEDULE_DELETE,
+ wc.SCHEDULE_REPLACE):
return self.id_map[workingtree.branch.unprefix(relpath.decode("utf-8"))]
return (None, None)
- def add_dir_to_inv(relpath, wc, parent_id):
- entries = svn.wc.entries_read(wc, False)
+ def add_dir_to_inv(relpath, adm, parent_id):
+ entries = adm.entries_read(False)
entry = entries[""]
(id, revid) = find_ids(entry)
if id == None:
assert entry
if entry.kind == core.NODE_DIR:
- subwc = svn.wc.adm_open3(wc,
+ subwc = wc.WorkingCopy(adm,
self.workingtree.abspath(subrelpath),
False, 0, None)
try:
add_dir_to_inv(subrelpath, subwc, id)
finally:
- svn.wc.adm_close(subwc)
+ subwc.close()
else:
(subid, subrevid) = find_ids(entry)
if subid is not None:
- add_file_to_inv(subrelpath, subid, subrevid, wc)
+ add_file_to_inv(subrelpath, subid, subrevid, adm)
- wc = workingtree._get_wc()
+ adm = workingtree._get_wc()
try:
- add_dir_to_inv(u"", wc, None)
+ add_dir_to_inv(u"", adm, None)
finally:
- svn.wc.adm_close(wc)
+ adm.close()
def _abspath(self, relpath):
- return svn.wc.get_pristine_copy_path(self.workingtree.abspath(relpath).encode("utf-8"))
+ return wc.get_pristine_copy_path(self.workingtree.abspath(relpath).encode("utf-8"))
def get_file_lines(self, file_id):
base_copy = self._abspath(self.id2path(file_id))