--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -9,6 +9,7 @@
import tg
import pysvn
+from pymongo.errors import DuplicateKeyError
from ming.base import Object
from ming.orm import Mapper, FieldProperty, session
@@ -94,12 +95,16 @@
def _url(self):
return 'file://%s%s' % (self._repo.fs_path, self._repo.name)
- def shorthand_for_commit(self, commit):
- return '[r%d]' % self._revno(commit.object_id)
+ def shorthand_for_commit(self, oid):
+ return '[r%d]' % self._revno(oid)
def url_for_commit(self, commit):
+ if isinstance(commit, basestring):
+ object_id = commit
+ else:
+ object_id = commit.object_id
return '%s%d/' % (
- self._repo.url(), self._revno(commit.object_id))
+ self._repo.url(), self._revno(object_id))
def init(self):
fullname = self._setup_paths()
@@ -161,6 +166,10 @@
if result is None: return None
result.set_context(self._repo)
return result
+
+ def all_commit_ids(self):
+ head_revno = self._revno(self._repo.heads[0].object_id)
+ return map(self._oid, range(1, head_revno+1))
def new_commits(self, all_commits=False):
head_revno = self._revno(self._repo.heads[0].object_id)
@@ -234,6 +243,41 @@
continue
lst[path.action].append(h.really_unicode(path.path))
+ def refresh_commit_info(self, oid, seen_object_ids):
+ from allura.model.repo import CommitDoc
+ if CommitDoc.m.find(dict(_id=oid)).count():
+ return False
+ try:
+ log.info('Refresh %r %r', oid, self._repo)
+ revno = self._revno(oid)
+ rev = self._revision(oid)
+ try:
+ log_entry = self._svn.log(
+ self._url,
+ revision_start=rev,
+ limit=1,
+ discover_changed_paths=True)[0]
+ except pysvn.ClientError:
+ log.info('ClientError processing %r %r, treating as empty', oid, self._repo, exc_info=True)
+ log_entry = Object(date='', message='', changed_paths=[])
+ user = Object(
+ name=log_entry.get('author', '--none--'),
+ email='',
+ date=datetime.utcfromtimestamp(log_entry.date))
+ ci_doc = CommitDoc(dict(
+ _id=oid,
+ tree_id=None,
+ committed=user,
+ authored=user,
+ message=log_entry.message,
+ parent_ids=[],
+ child_ids=[]))
+ if revno > 1:
+ ci_doc.parent_ids = [ self._oid(revno-1) ]
+ ci_doc.m.insert(safe=True)
+ except DuplicateKeyError:
+ return False
+
def compute_tree(self, commit, tree_path='/'):
tree_path = tree_path[:-1]
tree_id = self._tree_oid(commit.object_id, tree_path)
@@ -270,6 +314,40 @@
session(tree).flush(tree)
return tree_id
+ def compute_tree_new(self, commit, tree_path='/'):
+ from allura.model import repo as RM
+ tree_path = tree_path[:-1]
+ tree_id = self._tree_oid(commit.object_id, tree_path)
+ tree, isnew = RM.Tree.upsert(tree_id)
+ if not isnew: return tree_id
+ log.debug('Computing tree for %s: %s',
+ self._revno(commit.object_id), tree_path)
+ rev = self._revision(commit.object_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)
+ tree.delete()
+ return None
+ log.debug('Compute tree for %d paths', len(infos))
+ for path, info in infos[1:]:
+ if info.kind == pysvn.node_kind.dir:
+ tree.tree_ids.append(Object(
+ id=self._tree_oid(commit.object_id, path),
+ name=path))
+ elif info.kind == pysvn.node_kind.file:
+ tree.blob_ids.append(Object(
+ id=self._tree_oid(commit.object_id, path),
+ name=path))
+ else:
+ assert False
+ session(tree).flush(tree)
+ return tree_id
+
def _tree_oid(self, commit_id, path):
data = 'tree\n%s\n%s' % (commit_id, h.really_unicode(path))
return sha1(data.encode('utf-8')).hexdigest()