aboutsummaryrefslogtreecommitdiffstats
path: root/libbe/storage
diff options
context:
space:
mode:
Diffstat (limited to 'libbe/storage')
-rw-r--r--libbe/storage/base.py10
-rw-r--r--libbe/storage/vcs/base.py29
-rw-r--r--libbe/storage/vcs/bzr.py11
-rw-r--r--libbe/storage/vcs/hg.py20
4 files changed, 44 insertions, 26 deletions
diff --git a/libbe/storage/base.py b/libbe/storage/base.py
index 84ec1d4..10649a8 100644
--- a/libbe/storage/base.py
+++ b/libbe/storage/base.py
@@ -53,11 +53,15 @@ class InvalidStorageVersion(ConnectionError):
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
diff --git a/libbe/storage/vcs/base.py b/libbe/storage/vcs/base.py
index 716283a..fa64b4e 100644
--- a/libbe/storage/vcs/base.py
+++ b/libbe/storage/vcs/base.py
@@ -756,7 +756,7 @@ os.listdir(self.get_path("bugs")):
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:
@@ -926,6 +926,33 @@ os.listdir(self.get_path("bugs")):
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.
diff --git a/libbe/storage/vcs/bzr.py b/libbe/storage/vcs/bzr.py
index 285ecf1..e1cd2e5 100644
--- a/libbe/storage/vcs/bzr.py
+++ b/libbe/storage/vcs/bzr.py
@@ -134,7 +134,9 @@ class Bzr(base.VCS):
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:
@@ -145,13 +147,13 @@ class Bzr(base.VCS):
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)
@@ -252,8 +254,7 @@ class Bzr(base.VCS):
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()
diff --git a/libbe/storage/vcs/hg.py b/libbe/storage/vcs/hg.py
index 824f687..5295a57 100644
--- a/libbe/storage/vcs/hg.py
+++ b/libbe/storage/vcs/hg.py
@@ -112,23 +112,9 @@ class Hg(base.VCS):
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)