aboutsummaryrefslogtreecommitdiffstats
path: root/libbe/storage/vcs/hg.py
diff options
context:
space:
mode:
Diffstat (limited to 'libbe/storage/vcs/hg.py')
-rw-r--r--libbe/storage/vcs/hg.py91
1 files changed, 74 insertions, 17 deletions
diff --git a/libbe/storage/vcs/hg.py b/libbe/storage/vcs/hg.py
index 824f687..076943a 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)
@@ -172,6 +158,77 @@ class Hg(base.VCS):
return None # before initial commit.
return id
+ def _diff(self, revision):
+ return self._u_invoke_client(
+ 'diff', '-r', revision, '--git')
+
+ def _parse_diff(self, diff_text):
+ """
+ Example diff text:
+
+ diff --git a/.be/dir/bugs/modified b/.be/dir/bugs/modified
+ --- a/.be/dir/bugs/modified
+ +++ b/.be/dir/bugs/modified
+ @@ -1,1 +1,1 @@ some value to be modified
+ -some value to be modified
+ \ No newline at end of file
+ +a new value
+ \ No newline at end of file
+ diff --git a/.be/dir/bugs/moved b/.be/dir/bugs/moved
+ deleted file mode 100644
+ --- a/.be/dir/bugs/moved
+ +++ /dev/null
+ @@ -1,1 +0,0 @@
+ -this entry will be moved
+ \ No newline at end of file
+ diff --git a/.be/dir/bugs/moved2 b/.be/dir/bugs/moved2
+ new file mode 100644
+ --- /dev/null
+ +++ b/.be/dir/bugs/moved2
+ @@ -0,0 +1,1 @@
+ +this entry will be moved
+ \ No newline at end of file
+ diff --git a/.be/dir/bugs/new b/.be/dir/bugs/new
+ new file mode 100644
+ --- /dev/null
+ +++ b/.be/dir/bugs/new
+ @@ -0,0 +1,1 @@
+ +this entry is new
+ \ No newline at end of file
+ diff --git a/.be/dir/bugs/removed b/.be/dir/bugs/removed
+ deleted file mode 100644
+ --- a/.be/dir/bugs/removed
+ +++ /dev/null
+ @@ -1,1 +0,0 @@
+ -this entry will be deleted
+ \ No newline at end of file
+ """
+ new = []
+ modified = []
+ removed = []
+ lines = diff_text.splitlines()
+ for i,line in enumerate(lines):
+ if not line.startswith('diff '):
+ continue
+ file_a,file_b = line.split()[-2:]
+ assert file_a.startswith('a/'), \
+ 'missformed file_a %s' % file_a
+ assert file_b.startswith('b/'), \
+ 'missformed file_a %s' % file_b
+ file = file_a[2:]
+ assert file_b[2:] == file, \
+ 'diff file missmatch %s != %s' % (file_a, file_b)
+ if lines[i+1].startswith('new '):
+ new.append(file)
+ elif lines[i+1].startswith('deleted '):
+ removed.append(file)
+ else:
+ modified.append(file)
+ return (new,modified,removed)
+
+ def _vcs_changed(self, revision):
+ return self._parse_diff(self._diff(revision))
+
if libbe.TESTING == True:
base.make_vcs_testcase_subclasses(Hg, sys.modules[__name__])