Rev 1242: Make editor API more object oriented. in http://people.samba.org/bzr/jelmer/bzr-svn/0.4/
Jelmer Vernooij
jelmer at samba.org
Thu Jun 19 14:58:51 BST 2008
At http://people.samba.org/bzr/jelmer/bzr-svn/0.4/
------------------------------------------------------------
revno: 1242
revision-id: jelmer at samba.org-20080619135842-8kg5be1na8cgdptp
parent: jelmer at samba.org-20080618115824-vzo020t2d83ik66x
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Thu 2008-06-19 15:58:42 +0200
message:
Make editor API more object oriented.
modified:
__init__.py __init__.py-20051008155114-eae558e6cf149e1d
auth.py auth.py-20071209174622-w8d42k6nm5yhxvi8-1
convert.py svn2bzr.py-20051018015439-cb4563bff29e632d
delta.py delta.py-20080617225125-jeg43afui0czkuwk-1
fetch.py fetch.py-20060625004942-x2lfaib8ra707a8p-1
logwalker.py logwalker.py-20060621215743-c13fhfnyzh1xzwh2-1
ra.py ra.py-20080615005305-t5221niknu8rm6bt-1
revspec.py revspec.py-20071106211507-q4fz2en91yrmjjl8-1
tree.py tree.py-20060624222557-dudlwqcmkf22lt2s-1
=== modified file '__init__.py'
--- a/__init__.py 2008-06-10 21:39:41 +0000
+++ b/__init__.py 2008-06-19 13:58:42 +0000
@@ -74,8 +74,8 @@
warning('No Python bindings for Subversion installed. See the '
'bzr-svn README for details.')
raise bzrlib.errors.BzrError("missing python subversion bindings")
- if (not hasattr(svn.delta, 'svn_delta_invoke_txdelta_window_handler') and
- not hasattr(svn.delta, 'tx_invoke_window_handler')):
+ if (not getattr(svn.delta, 'svn_delta_invoke_txdelta_window_handler', None) and
+ not getattr(svn.delta, 'tx_invoke_window_handler', None)):
warning('Installed Subversion version does not have updated Python '
'bindings. See the bzr-svn README for details.')
raise bzrlib.errors.BzrError("incompatible python subversion bindings")
=== modified file 'auth.py'
--- a/auth.py 2008-06-18 11:58:24 +0000
+++ b/auth.py 2008-06-19 13:58:42 +0000
@@ -143,13 +143,13 @@
ra.get_ssl_server_trust_file_provider(),
]
- if hasattr(ra, 'get_windows_simple_provider'):
+ if getattr(ra, 'get_windows_simple_provider', None):
providers.append(ra.get_windows_simple_provider())
- if hasattr(ra, 'get_keychain_simple_provider'):
+ if getattr(ra, 'get_keychain_simple_provider', None):
providers.append(ra.get_keychain_simple_provider())
- if hasattr(ra, 'get_windows_ssl_server_trust_provider'):
+ if getattr(ra, 'get_windows_ssl_server_trust_provider', None):
providers.append(ra.get_windows_ssl_server_trust_provider())
return providers
=== modified file 'convert.py'
--- a/convert.py 2008-06-05 17:54:39 +0000
+++ b/convert.py 2008-06-19 13:58:42 +0000
@@ -141,7 +141,7 @@
if all:
inter.fetch()
elif (target_repos.is_shared() and
- hasattr(inter, '_supports_branches') and
+ getattr(inter, '_supports_branches', None) and
inter._supports_branches):
inter.fetch(branches=[branch.last_revision() for branch in existing_branches])
=== modified file 'delta.py'
--- a/delta.py 2008-06-17 22:52:33 +0000
+++ b/delta.py 2008-06-19 13:58:42 +0000
@@ -19,11 +19,11 @@
from cStringIO import StringIO
import svn.delta
-if hasattr(svn.delta, 'tx_invoke_window_handler'):
+if getattr(svn.delta, 'tx_invoke_window_handler', None):
def apply_txdelta_handler(sbuf, target_stream):
src_stream = StringIO(sbuf)
- assert hasattr(src_stream, 'read')
- assert hasattr(target_stream, 'write')
+ assert getattr(src_stream, 'read', None) is not None
+ assert getattr(target_stream, 'write', None) is not None
window_handler, baton = svn.delta.tx_apply(src_stream, target_stream,
None)
@@ -34,8 +34,8 @@
else:
def apply_txdelta_handler(sbuf, target_stream):
src_stream = StringIO(sbuf)
- assert hasattr(src_stream, 'read')
- assert hasattr(target_stream, 'write')
+ assert getattr(src_stream, 'read', None) is not None
+ assert getattr(target_stream, 'write', None) is not None
ret = svn.delta.svn_txdelta_apply(src_stream, target_stream, None)
def wrapper(window):
=== modified file 'fetch.py'
--- a/fetch.py 2008-06-18 11:58:24 +0000
+++ b/fetch.py 2008-06-19 13:58:42 +0000
@@ -135,17 +135,17 @@
return (rev, signature)
- def open_root(self, base_revnum, baton):
+ def open_root(self, base_revnum):
if self.old_inventory.root is None:
# First time the root is set
old_file_id = None
file_id = self.mapping.generate_file_id(self.source.uuid, self.revnum, self.branch_path, u"")
- self.dir_baserev[file_id] = []
+ file_parents = []
else:
assert self.old_inventory.root.revision is not None
old_file_id = self.old_inventory.root.file_id
file_id = self._get_id_map().get("", old_file_id)
- self.dir_baserev[file_id] = [self.old_inventory.root.revision]
+ file_parents = [self.old_inventory.root.revision]
if self.inventory.root is not None and \
file_id == self.inventory.root.file_id:
@@ -153,7 +153,28 @@
else:
ie = self.inventory.add_path("", 'directory', file_id)
ie.revision = self.revid
- return (old_file_id, file_id)
+ return DirectoryBuildEditor(self, old_file_id, file_id, file_parents)
+
+ def close(self):
+ pass
+
+ def _store_directory(self, file_id, parents):
+ raise NotImplementedError(self._store_directory)
+
+ def _get_file_data(self, file_id, revid):
+ raise NotImplementedError(self._get_file_data)
+
+ def _finish_commit(self):
+ raise NotImplementedError(self._finish_commit)
+
+ def abort(self):
+ pass
+
+ def _start_revision(self):
+ pass
+
+ def _store_file(self, file_id, lines, parents):
+ raise NotImplementedError(self._store_file)
def _get_existing_id(self, old_parent_id, new_parent_id, path):
assert isinstance(path, unicode)
@@ -187,82 +208,81 @@
return
self.inventory.rename(file_id, parent_id, urlutils.basename(path))
- def delete_entry(self, path, revnum, (old_parent_id, new_parent_id), pool):
- assert isinstance(path, str)
- path = path.decode("utf-8")
- if path in self._premature_deletes:
- # Delete recursively
- self._premature_deletes.remove(path)
- for p in self._premature_deletes.copy():
- if p.startswith("%s/" % path):
- self._premature_deletes.remove(p)
- else:
- self.inventory.remove_recursive_id(self._get_old_id(old_parent_id, path))
-
- def close_directory(self, (old_id, new_id)):
- self.inventory[new_id].revision = self.revid
+
+class DirectoryBuildEditor:
+ def __init__(self, editor, old_id, new_id, parent_revids=[]):
+ self.editor = editor
+ self.old_id = old_id
+ self.new_id = new_id
+ self.parent_revids = parent_revids
+
+ def close(self):
+ self.editor.inventory[self.new_id].revision = self.editor.revid
# Only record root if the target repository supports it
- self._store_directory(new_id, self.dir_baserev[new_id])
-
- def add_directory(self, path, (old_parent_id, new_parent_id), copyfrom_path, copyfrom_revnum,
- pool):
+ self.editor._store_directory(self.new_id, self.parent_revids)
+
+ if self.new_id == self.editor.inventory.root.file_id:
+ assert len(self.editor._premature_deletes) == 0
+ self.editor._finish_commit()
+
+ def add_directory(self, path, copyfrom_path=None, copyfrom_revnum=-1):
assert isinstance(path, str)
path = path.decode("utf-8")
check_filename(path)
- file_id = self._get_new_id(new_parent_id, path)
+ file_id = self.editor._get_new_id(self.new_id, path)
- self.dir_baserev[file_id] = []
- if file_id in self.inventory:
+ if file_id in self.editor.inventory:
# This directory was moved here from somewhere else, but the
# other location hasn't been removed yet.
if copyfrom_path is None:
# This should ideally never happen!
- copyfrom_path = self.old_inventory.id2path(file_id)
+ copyfrom_path = self.editor.old_inventory.id2path(file_id)
mutter('no copyfrom path set, assuming %r', copyfrom_path)
- assert copyfrom_path == self.old_inventory.id2path(file_id)
- assert copyfrom_path not in self._premature_deletes
- self._premature_deletes.add(copyfrom_path)
- self._rename(file_id, new_parent_id, path)
- ie = self.inventory[file_id]
+ assert copyfrom_path == self.editor.old_inventory.id2path(file_id)
+ assert copyfrom_path not in self.editor._premature_deletes
+ self.editor._premature_deletes.add(copyfrom_path)
+ self.editor._rename(file_id, self.new_id, path)
+ ie = self.editor.inventory[file_id]
old_file_id = file_id
else:
old_file_id = None
- ie = self.inventory.add_path(path, 'directory', file_id)
- ie.revision = self.revid
-
- return (old_file_id, file_id)
-
- def open_directory(self, path, (old_parent_id, new_parent_id), base_revnum, pool):
+ ie = self.editor.inventory.add_path(path, 'directory', file_id)
+ ie.revision = self.editor.revid
+
+ return DirectoryBuildEditor(self.editor, old_file_id, file_id)
+
+ def open_directory(self, path, base_revnum):
assert isinstance(path, str)
path = path.decode("utf-8")
assert base_revnum >= 0
- base_file_id = self._get_old_id(old_parent_id, path)
- base_revid = self.old_inventory[base_file_id].revision
- file_id = self._get_existing_id(old_parent_id, new_parent_id, path)
+ base_file_id = self.editor._get_old_id(self.old_id, path)
+ base_revid = self.editor.old_inventory[base_file_id].revision
+ file_id = self.editor._get_existing_id(self.old_id, self.new_id, path)
if file_id == base_file_id:
- self.dir_baserev[file_id] = [base_revid]
- ie = self.inventory[file_id]
+ file_parents = [base_revid]
+ ie = self.editor.inventory[file_id]
else:
# Replace if original was inside this branch
# change id of base_file_id to file_id
- ie = self.inventory[base_file_id]
+ ie = self.editor.inventory[base_file_id]
for name in ie.children:
ie.children[name].parent_id = file_id
# FIXME: Don't touch inventory internals
- del self.inventory._byid[base_file_id]
- self.inventory._byid[file_id] = ie
+ del self.editor.inventory._byid[base_file_id]
+ self.editor.inventory._byid[file_id] = ie
ie.file_id = file_id
- self.dir_baserev[file_id] = []
- ie.revision = self.revid
- return (base_file_id, file_id)
+ file_parents = []
+ ie.revision = self.editor.revid
+ return DirectoryBuildEditor(self.editor, base_file_id, file_id,
+ file_parents)
- def change_dir_prop(self, (old_id, new_id), name, value, pool):
- if new_id == self.inventory.root.file_id:
+ def change_prop(self, name, value):
+ if self.new_id == self.editor.inventory.root.file_id:
# Replay lazy_dict, since it may be more expensive
- if type(self.revmeta.fileprops) != dict:
- self.revmeta.fileprops = {}
- self.revmeta.fileprops[name] = value
+ if type(self.editor.revmeta.fileprops) != dict:
+ self.editor.revmeta.fileprops = {}
+ self.editor.revmeta.fileprops[name] = value
if name in (properties.PROP_ENTRY_COMMITTED_DATE,
properties.PROP_ENTRY_COMMITTED_REV,
@@ -276,7 +296,76 @@
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):
+ assert isinstance(path, str)
+ path = path.decode("utf-8")
+ check_filename(path)
+ file_id = self.editor._get_new_id(self.new_id, path)
+ if file_id in self.editor.inventory:
+ # This file was moved here from somewhere else, but the
+ # other location hasn't been removed yet.
+ if copyfrom_path is None:
+ # This should ideally never happen
+ copyfrom_path = self.editor.old_inventory.id2path(file_id)
+ mutter('no copyfrom path set, assuming %r', copyfrom_path)
+ assert copyfrom_path == self.editor.old_inventory.id2path(file_id)
+ assert copyfrom_path not in self.editor._premature_deletes
+ self.editor._premature_deletes.add(copyfrom_path)
+ # No need to rename if it's already in the right spot
+ self.editor._rename(file_id, self.new_id, path)
+ return FileBuildEditor(self.editor, path, file_id)
+
+ def open_file(self, path, base_revnum):
+ assert isinstance(path, str)
+ path = path.decode("utf-8")
+ base_file_id = self.editor._get_old_id(self.old_id, path)
+ base_revid = self.editor.old_inventory[base_file_id].revision
+ file_id = self.editor._get_existing_id(self.old_id, self.new_id, path)
+ is_symlink = (self.editor.inventory[base_file_id].kind == 'symlink')
+ file_data = self.editor._get_file_data(base_file_id, base_revid)
+ if file_id == base_file_id:
+ file_parents = [base_revid]
+ else:
+ # Replace
+ del self.editor.inventory[base_file_id]
+ file_parents = []
+ return FileBuildEditor(self.editor, path, file_id,
+ file_parents, file_data, is_symlink=is_symlink)
+
+ def delete_entry(self, path, revnum):
+ assert isinstance(path, str)
+ path = path.decode("utf-8")
+ if path in self.editor._premature_deletes:
+ # Delete recursively
+ self.editor._premature_deletes.remove(path)
+ for p in self.editor._premature_deletes.copy():
+ if p.startswith("%s/" % path):
+ self.editor._premature_deletes.remove(p)
+ else:
+ self.editor.inventory.remove_recursive_id(self.editor._get_old_id(self.old_id, path))
+
+
+class FileBuildEditor:
+ def __init__(self, editor, path, file_id, file_parents=[], data="",
+ is_symlink=False):
+ self.path = path
+ self.editor = editor
+ self.file_id = file_id
+ self.file_data = data
+ self.is_symlink = is_symlink
+ self.file_parents = file_parents
+ self.is_executable = None
+ self.file_stream = None
+
+ def apply_textdelta(self, base_checksum=None):
+ actual_checksum = md5.new(self.file_data).hexdigest()
+ assert (base_checksum is None or base_checksum == actual_checksum,
+ "base checksum mismatch: %r != %r" % (base_checksum,
+ actual_checksum))
+ self.file_stream = StringIO()
+ return apply_txdelta_handler(self.file_data, self.file_stream)
+
+ def change_prop(self, name, value):
if name == properties.PROP_EXECUTABLE:
# You'd expect executable to match
# properties.PROP_EXECUTABLE_VALUE, but that's not
@@ -301,50 +390,8 @@
name.startswith(SVN_PROP_BZR_PREFIX)):
mutter('unsupported file property %r', name)
- def add_file(self, path, (old_parent_id, new_parent_id), copyfrom_path, copyfrom_revnum, baton):
- assert isinstance(path, str)
- path = path.decode("utf-8")
- check_filename(path)
- self.is_symlink = False
- self.is_executable = None
- self.file_data = ""
- self.file_parents = []
- self.file_stream = None
- self.file_id = self._get_new_id(new_parent_id, path)
- if self.file_id in self.inventory:
- # This file was moved here from somewhere else, but the
- # other location hasn't been removed yet.
- if copyfrom_path is None:
- # This should ideally never happen
- copyfrom_path = self.old_inventory.id2path(self.file_id)
- mutter('no copyfrom path set, assuming %r', copyfrom_path)
- assert copyfrom_path == self.old_inventory.id2path(self.file_id)
- assert copyfrom_path not in self._premature_deletes
- self._premature_deletes.add(copyfrom_path)
- # No need to rename if it's already in the right spot
- self._rename(self.file_id, new_parent_id, path)
- return path
-
- def open_file(self, path, (old_parent_id, new_parent_id), base_revnum, pool):
- assert isinstance(path, str)
- path = path.decode("utf-8")
- base_file_id = self._get_old_id(old_parent_id, path)
- base_revid = self.old_inventory[base_file_id].revision
- self.file_id = self._get_existing_id(old_parent_id, new_parent_id, path)
- self.is_executable = None
- self.is_symlink = (self.inventory[base_file_id].kind == 'symlink')
- self.file_data = self._get_file_data(base_file_id, base_revid)
- self.file_stream = None
- if self.file_id == base_file_id:
- self.file_parents = [base_revid]
- else:
- # Replace
- del self.inventory[base_file_id]
- self.file_parents = []
- return path
-
- def close_file(self, path, checksum):
- assert isinstance(path, unicode)
+ def close(self, checksum=None):
+ assert isinstance(self.path, unicode)
if self.file_stream is not None:
self.file_stream.seek(0)
lines = osutils.split_lines(self.file_stream.read())
@@ -355,23 +402,23 @@
actual_checksum = md5_strings(lines)
assert checksum is None or checksum == actual_checksum
- self._store_file(self.file_id, lines, self.file_parents)
+ self.editor._store_file(self.file_id, lines, self.file_parents)
assert self.is_symlink in (True, False)
- if self.file_id in self.inventory:
- del self.inventory[self.file_id]
+ if self.file_id in self.editor.inventory:
+ del self.editor.inventory[self.file_id]
if self.is_symlink:
- ie = self.inventory.add_path(path, 'symlink', self.file_id)
+ ie = self.editor.inventory.add_path(self.path, 'symlink', self.file_id)
ie.symlink_target = lines[0][len("link "):]
ie.text_sha1 = None
ie.text_size = None
ie.executable = False
- ie.revision = self.revid
+ ie.revision = self.editor.revid
else:
- ie = self.inventory.add_path(path, 'file', self.file_id)
- ie.revision = self.revid
+ ie = self.editor.inventory.add_path(self.path, 'file', self.file_id)
+ ie.revision = self.editor.revid
ie.kind = 'file'
ie.symlink_target = None
ie.text_sha1 = osutils.sha_strings(lines)
@@ -380,40 +427,8 @@
if self.is_executable is not None:
ie.executable = self.is_executable
-
self.file_stream = None
- def close_edit(self):
- assert len(self._premature_deletes) == 0
- self._finish_commit()
-
- def apply_textdelta(self, file_id, base_checksum):
- actual_checksum = md5.new(self.file_data).hexdigest(),
- assert (base_checksum is None or base_checksum == actual_checksum,
- "base checksum mismatch: %r != %r" % (base_checksum,
- actual_checksum))
- self.file_stream = StringIO()
- return apply_txdelta_handler(self.file_data, self.file_stream)
-
- def _store_file(self, file_id, lines, parents):
- raise NotImplementedError(self._store_file)
-
- def _store_directory(self, file_id, parents):
- raise NotImplementedError(self._store_directory)
-
- def _get_file_data(self, file_id, revid):
- raise NotImplementedError(self._get_file_data)
-
- def _finish_commit(self):
- raise NotImplementedError(self._finish_commit)
-
- def abort_edit(self):
- pass
-
- def _start_revision(self):
- pass
-
-
class WeaveRevisionBuildEditor(RevisionBuildEditor):
"""Subversion commit editor that can write to a weave-based repository.
"""
@@ -451,7 +466,7 @@
self.target.commit_write_group()
self._write_group_active = False
- def abort_edit(self):
+ def abort(self):
if self._write_group_active:
self.target.abort_write_group()
self._write_group_active = False
@@ -489,7 +504,7 @@
:param repository: Repository to obtain the buildeditor for.
:return: Class object of class descending from RevisionBuildEditor
"""
- if hasattr(repository, '_packs'):
+ if getattr(repository, '_packs', None):
return PackRevisionBuildEditor
return WeaveRevisionBuildEditor
@@ -671,7 +686,7 @@
if not conn.is_busy():
self.source.transport.add_connection(conn)
except:
- editor.abort_edit()
+ editor.abort()
raise
prev_inv = editor.inventory
=== modified file 'logwalker.py'
--- a/logwalker.py 2008-06-17 21:03:10 +0000
+++ b/logwalker.py 2008-06-19 13:58:42 +0000
@@ -403,47 +403,42 @@
finally:
self._transport.connections.add(conn)
- class TreeLister(svn.delta.Editor):
+ class DirTreeLister:
+ def __init__(self, tree, path):
+ self.tree = tree
+ self.path = path
+
+ def change_prop(self, name, value):
+ pass
+
+ def close(self):
+ pass
+
+ def add_directory(self, path, copyfrom_path=None, copyfrom_revnum=-1):
+ """See Editor.add_directory()."""
+ self.tree.files.append(urlutils.join(self.tree.base, path))
+ return DirTreeLister(self.tree, path)
+
+ def add_file(self, path, copyfrom_path=None, copyfrom_revnum=-1):
+ self.tree.files.append(urlutils.join(self.tree.base, path))
+ return None
+
+ class TreeLister:
def __init__(self, base):
self.files = []
self.base = base
- def set_target_revision(self, revnum):
- """See Editor.set_target_revision()."""
+ def set_target_revision(self, rev):
pass
- def open_root(self, revnum, baton):
+ def open_root(self, revnum):
"""See Editor.open_root()."""
- return path
-
- def add_directory(self, path, parent_baton, copyfrom_path, copyfrom_revnum, pool):
- """See Editor.add_directory()."""
- self.files.append(urlutils.join(self.base, path))
- return path
-
- def change_dir_prop(self, id, name, value, pool):
- pass
-
- def change_file_prop(self, id, name, value, pool):
- pass
-
- def add_file(self, path, parent_id, copyfrom_path, copyfrom_revnum, baton):
- self.files.append(urlutils.join(self.base, path))
- return path
-
- def close_dir(self, id):
- pass
-
- def close_file(self, path, checksum):
- pass
-
- def close_edit(self):
- pass
-
- def abort_edit(self):
- pass
-
- def apply_textdelta(self, file_id, base_checksum):
+ return DirTreeLister(self, path)
+
+ def close(self):
+ pass
+
+ def abort(self):
pass
editor = TreeLister(path)
=== modified file 'ra.py'
--- a/ra.py 2008-06-18 11:58:24 +0000
+++ b/ra.py 2008-06-19 13:58:42 +0000
@@ -58,11 +58,11 @@
get_ssl_client_cert_file_provider = svn.client.get_ssl_client_cert_file_provider
get_ssl_client_cert_pw_file_provider = svn.client.get_ssl_client_cert_pw_file_provider
get_ssl_server_trust_file_provider = svn.client.get_ssl_server_trust_file_provider
-if hasattr(svn.client, 'get_windows_simple_provider'):
+if getattr(svn.client, 'get_windows_simple_provider', None):
get_windows_simple_provider = svn.client.get_windows_simple_provider
-if hasattr(svn.client, 'get_keychain_simple_provider'):
+if getattr(svn.client, 'get_keychain_simple_provider', None):
get_keychain_simple_provider = svn.client.get_keychain_simple_provider
-if hasattr(svn.client, 'get_windows_ssl_server_trust_provider'):
+if getattr(svn.client, 'get_windows_ssl_server_trust_provider', None):
get_windows_ssl_server_trust_provider = svn.client.get_windows_ssl_server_trust_provider
txdelta_send_stream = svn.delta.svn_txdelta_send_stream
@@ -117,8 +117,7 @@
def open_file(self, path, base_revision=-1):
assert self.base_editor.recent_baton[-1] == self.baton
- baton = svn.delta.editor_invoke_open_file(self.base_editor.editor, path, self.baton,
- base_revision)
+ baton = svn.delta.editor_invoke_open_file(self.base_editor.editor, path, self.baton, base_revision)
self.base_editor.recent_baton.append(baton)
return FileEditor(self.base_editor, baton)
@@ -204,52 +203,61 @@
self.actual = actual
def set_target_revision(self, revision):
- if getattr(self.actual, "set_target_revision", None) is not None:
- self.actual.set_target_revision(revision)
-
- def open_root(self, base_revision):
- if getattr(self.actual, "open_root", None) is not None:
- return self.actual.open_root(base_revision)
- return None
-
- def add_directory(self, path, baton, copyfrom_path, copyfrom_rev):
- if baton is not None and getattr(baton, "add_directory", None) is not None:
+ self.actual.set_target_revision(revision)
+
+ def open_root(self, base_revision, pool):
+ return self.actual.open_root(base_revision)
+
+ def add_directory(self, path, baton, copyfrom_path, copyfrom_rev, pool):
+ if baton is not None:
return baton.add_directory(path, copyfrom_path, copyfrom_rev)
return None
- def open_directory(self, path, baton, base_rev):
- if baton is not None and getattr(baton, "open_directory", None) is not None:
+ def add_file(self, path, baton, copyfrom_path, copyfrom_rev, pool):
+ if baton is not None:
+ return baton.add_file(path, copyfrom_path, copyfrom_rev)
+ return None
+
+ def delete_entry(self, path, revnum, baton, pool):
+ if baton is not None:
+ return baton.delete_entry(path, revnum)
+ return None
+
+ def open_directory(self, path, baton, base_rev, pool):
+ if baton is not None:
return baton.open_directory(path, base_rev)
return None
def close_directory(self, baton):
- if baton is not None and getattr(baton, "close", None) is not None:
+ if baton is not None:
return baton.close()
- def change_file_prop(self, baton, name, value):
- if baton is not None and getattr(baton, "change_prop", None) is not None:
+ def change_file_prop(self, baton, name, value, pool):
+ if baton is not None:
return baton.change_prop(name, value)
- def change_dir_prop(self, baton, name, value):
- if baton is not None and getattr(baton, "change_prop", None) is not None:
+ def change_dir_prop(self, baton, name, value, pool):
+ if baton is not None:
return baton.change_prop(name, value)
def apply_textdelta(self, baton, checksum):
- if baton is not None and getattr(baton, "apply_textdelta", None) is not None:
+ if baton is not None:
return baton.apply_textdelta(checksum)
def close_file(self, baton, checksum):
- if baton is not None and getattr(baton, "close", None) is not None:
+ if baton is not None:
return baton.close(checksum)
- def open_file(self, path, baton, base_rev):
- if baton is not None and getattr(self.actual, "open_file", None) is not None:
+ def open_file(self, path, baton, base_rev, pool):
+ if baton is not None:
return baton.open_file(path, base_rev)
return None
def close_edit(self):
- if getattr(self.actual, "close_edit", None) is not None:
- self.actual.close_edit()
+ self.actual.close()
+
+ def abort_edit(self):
+ self.actual.abort()
class RemoteAccess(object):
@@ -344,7 +352,9 @@
return svn.ra.get_latest_revnum(self._ra)
def _make_editor(self, editor):
- edit, edit_baton = svn.delta.make_editor(editor, None)
+ global cureditor # svn.delta.make_editor() doesn't increment the reference counter
+ cureditor = WrappedEditor(editor)
+ edit, edit_baton = svn.delta.make_editor(cureditor, None)
self._edit = edit
self._edit_baton = edit_baton
return self._edit, self._edit_baton
@@ -376,7 +386,7 @@
assert len(path) == 0 or path[0] != "/"
# ra_dav backends fail with strange errors if the path starts with a
# slash while other backends don't.
- if hasattr(svn.ra, 'get_dir2'):
+ if getattr(svn.ra, 'get_dir2', None):
fields = 0
if kind:
fields += DIRENT_KIND
@@ -427,7 +437,7 @@
def get_commit_editor(self, revprops, done_cb=None, lock_token=None, keep_locks=False):
self._mark_busy()
try:
- if hasattr(svn.ra, 'get_commit_editor3'):
+ if getattr(svn.ra, 'get_commit_editor3', None):
editor = svn.ra.get_commit_editor3(self._ra, revprops, done_cb,
lock_token, keep_locks)
elif revprops.keys() != [properties.PROP_REVISION_LOG]:
@@ -468,7 +478,7 @@
svn.core.SVN_VER_REVISION < 31470 and svn.core.SVN_VER_REVISION != 0))):
paths = ["/"]
self.mutter('svn log %r:%r %r (limit: %r)', from_revnum, to_revnum, paths, limit)
- if hasattr(svn.ra, 'get_log2'):
+ if getattr(svn.ra, 'get_log2', None):
return svn.ra.get_log2(self._ra, paths,
from_revnum, to_revnum, limit,
discover_changed_paths, strict_node_history, False,
@@ -500,7 +510,7 @@
def reparent(self, url):
if self.url == url:
return
- if hasattr(svn.ra, 'reparent'):
+ if getattr(svn.ra, 'reparent', None):
self.mutter('svn reparent %r', url)
svn.ra.reparent(self._ra, url)
self.url = url
=== modified file 'revspec.py'
--- a/revspec.py 2008-03-24 04:52:30 +0000
+++ b/revspec.py 2008-06-19 13:58:42 +0000
@@ -34,7 +34,7 @@
def _match_on(self, branch, revs):
loc = self.spec.find(':')
- if not hasattr(branch.repository, 'uuid'):
+ if not getattr(branch.repository, 'uuid', None):
raise BzrError("the svn: revisionspec can only be used with Subversion branches")
try:
return RevisionInfo.from_revision_id(branch, branch.generate_revision_id(int(self.spec[loc+1:])), branch.revision_history())
=== modified file 'tree.py'
--- a/tree.py 2008-06-18 11:58:24 +0000
+++ b/tree.py 2008-06-19 13:58:42 +0000
@@ -130,21 +130,33 @@
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
-
- def add_directory(self, path, parent_baton, copyfrom_path, copyfrom_revnum, pool):
+ return DirectoryTreeEditor(self.tree, file_id)
+
+ 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):
+ def change_prop(self, name, value):
if name in (properties.PROP_ENTRY_COMMITTED_DATE,
properties.PROP_ENTRY_LAST_AUTHOR,
properties.PROP_ENTRY_LOCK_TOKEN,
@@ -158,7 +170,25 @@
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")
+ self.is_symlink = False
+ self.is_executable = False
+ 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):
if name == properties.PROP_EXECUTABLE:
self.is_executable = (value != None)
elif name == properties.PROP_SPECIAL:
@@ -178,21 +208,12 @@
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_directory(self, id):
- pass
-
- 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:
@@ -219,13 +240,7 @@
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):
self.file_stream = StringIO()
return apply_txdelta_handler("", self.file_stream)
More information about the bazaar-commits
mailing list