--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -76,7 +76,7 @@
while ci is not None and limit > 0:
yield ci._id
limit -= 1
- ci = ci.parent()
+ ci = ci.get_parent()
def latest(self, branch=None):
if self._impl is None: return None
@@ -416,15 +416,8 @@
log.debug('Compute tree for %d paths', len(infos))
tree_ids = []
blob_ids = []
+ lcd_entries = []
for path, info in infos[1:]:
- last_commit_id = self._oid(info['last_changed_rev'].number)
- last_commit = M.repo.Commit.query.get(_id=last_commit_id)
- M.repo_refresh.set_last_commit(
- self._repo._id,
- re.sub(r'/?$', '/', tree_path), # force it to end with /
- path,
- self._tree_oid(commit._id, path),
- M.repo_refresh.get_commit_info(last_commit))
if info.kind == pysvn.node_kind.dir:
tree_ids.append(Object(
id=self._tree_oid(commit._id, path),
@@ -435,19 +428,26 @@
name=path))
else:
assert False
+ lcd_entries.append(dict(
+ name=path,
+ commit_id=self._oid(info.last_changed_rev.number),
+ ))
tree, is_new = RM.Tree.upsert(tree_id,
tree_ids=tree_ids,
blob_ids=blob_ids,
other_ids=[],
)
if is_new:
- trees_doc = RM.TreesDoc.m.get(_id=commit._id)
- if not trees_doc:
- trees_doc = RM.TreesDoc(dict(
- _id=commit._id,
- tree_ids=[]))
- trees_doc.tree_ids.append(tree_id)
- trees_doc.m.save(safe=False)
+ commit_id = self._oid(infos[0][1].last_changed_rev.number)
+ path = tree_path.strip('/')
+ RM.TreesDoc.m.update_partial(
+ {'_id': commit._id},
+ {'$addToSet': {'tree_ids': tree_id}},
+ upsert=True)
+ RM.LastCommitDoc.m.update_partial(
+ {'commit_id': commit_id, 'path': path},
+ {'commit_id': commit_id, 'path': path, 'entries': lcd_entries},
+ upsert=True)
return tree_id
def _tree_oid(self, commit_id, path):
@@ -574,5 +574,34 @@
log.info('ClientError processing commits for path %s, rev %s, treating as empty', path, rev, exc_info=True)
return 0
+ def last_commit_ids(self, commit, paths):
+ '''
+ Return a mapping {path: commit_id} of the _id of the last
+ commit to touch each path, starting from the given commit.
+
+ Since SVN Diffs are computed on-demand, we can't walk the
+ commit tree to find these. However, we can ask SVN for it
+ with a single call, so it shouldn't be too expensive.
+
+ NB: This assumes that all paths are direct children of a
+ single common parent path (i.e., you are only asking for
+ a subset of the nodes of a single tree, one level deep).
+ '''
+ tree_path = os.path.commonprefix(paths).strip('/')
+ rev = self._revision(commit._id)
+ try:
+ infos = self._svn.info2(
+ self._url + tree_path,
+ revision=rev,
+ depth=pysvn.depth.immediates)
+ except pysvn.ClientError:
+ log.exception('Error computing tree for %s: %s(%s)',
+ self._repo, commit, tree_path)
+ return None
+ entries = {}
+ for path, info in infos[1:]:
+ if path in paths:
+ entries[path] = self._oid(info.last_changed_rev.number)
+ return entries
Mapper.compile_all()