class InvalidID (KeyError):
def __init__(self, id=None, revision=None, msg=None):
- if msg == None and id != None:
- msg = id
- KeyError.__init__(self, msg)
+ KeyError.__init__(self, id)
+ self.msg = msg
self.id = id
self.revision = revision
+ def __str__(self):
+ if self.msg == None:
+ return '%s in revision %s' % (self.id, self.revision)
+ return self.msg
+
class InvalidRevision (KeyError):
pass
path = id_to_path(id)
ancestors = []
while True:
- if path == self.repo:
+ if not path.startswith(self.repo + os.path.sep):
break
path = os.path.dirname(path)
try:
return None
return ret
+ def _u_find_id_from_manifest(self, id, manifest, revision=None):
+ """
+ Search for the relative path to id using manifest, a list of all files.
+
+ Returns None if the id is not found.
+ """
+ be_dir = self._cached_path_id._spacer_dirs[0]
+ be_dir_sep = self._cached_path_id._spacer_dirs[0] + os.path.sep
+ files = [f for f in manifest if f.startswith(be_dir_sep)]
+ for file in files:
+ if not file.startswith(be_dir+os.path.sep):
+ continue
+ parts = file.split(os.path.sep)
+ dir = parts.pop(0) # don't add the first spacer dir
+ for part in parts[:-1]:
+ dir = os.path.join(dir, part)
+ if not dir in files:
+ files.append(dir)
+ for file in files:
+ try:
+ p_id = self._u_path_to_id(file)
+ if p_id == id:
+ return file
+ except (SpacerCollision, InvalidPath):
+ pass
+ raise InvalidID(id, revision=revision)
+
def _u_find_id(self, id, revision):
"""
Search for the relative path to id as of revision.
return cmd.outf.getvalue()
def _vcs_path(self, id, revision):
- return self._u_find_id(id, revision)
+ manifest = self._vcs_listdir(
+ self.repo, revision=revision, recursive=True)
+ return self._u_find_id_from_manifest(id, manifest, revision=revision)
def _vcs_isdir(self, path, revision):
try:
raise
return True
- def _vcs_listdir(self, path, revision):
+ def _vcs_listdir(self, path, revision, recursive=False):
path = os.path.join(self.repo, path)
revision = self._parse_revision_string(revision)
cmd = bzrlib.builtins.cmd_ls()
cmd.outf = StringIO.StringIO()
try:
- cmd.run(revision=revision, path=path)
+ cmd.run(revision=revision, path=path, recursive=recursive)
except bzrlib.errors.BzrCommandError, e:
if 'not present in revision' in str(e):
raise base.InvalidPath(path, root=self.repo, revision=revision)
new = []
modified = []
removed = []
- lines = diff_text.splitlines()
- for i,line in enumerate(lines):
+ for line in diff_text.splitlines():
if not line.startswith('=== '):
continue
fields = line.split()
return self._u_invoke_client('cat', '-r', revision, path)
def _vcs_path(self, id, revision):
- output = self._u_invoke_client('manifest', '--rev', revision)
- be_dir = self._cached_path_id._spacer_dirs[0]
- be_dir_sep = self._cached_path_id._spacer_dirs[0] + os.path.sep
- files = [f for f in output.splitlines() if f.startswith(be_dir_sep)]
- for file in files:
- if not file.startswith(be_dir+os.path.sep):
- continue
- parts = file.split(os.path.sep)
- dir = parts.pop(0) # don't add the first spacer dir
- for part in parts[:-1]:
- dir = os.path.join(dir, part)
- if not dir in files:
- files.append(dir)
- for file in files:
- if self._u_path_to_id(file) == id:
- return file
- raise base.InvalidId(id, revision=revision)
+ manifest = self._u_invoke_client(
+ 'manifest', '--rev', revision).splitlines()
+ return self._u_find_id_from_manifest(id, manifest, revision=revision)
def _vcs_isdir(self, path, revision):
output = self._u_invoke_client('manifest', '--rev', revision)