changeset 3496:58905069da21 beta

Speed up of last_changeset extraction in VCS, in edge cases for git we can get 10x speed improvement by limiting the history extraction if we only need last changeset
author Marcin Kuzminski <marcin@python-works.com>
date Thu, 07 Mar 2013 13:46:24 +0100
parents 64371c42e2f1
children be41cfcf5244
files rhodecode/lib/vcs/backends/base.py rhodecode/lib/vcs/backends/git/changeset.py rhodecode/lib/vcs/backends/hg/changeset.py rhodecode/templates/files/files_browser.html
diffstat 4 files changed, 28 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/lib/vcs/backends/base.py	Thu Mar 07 12:20:03 2013 +0100
+++ b/rhodecode/lib/vcs/backends/base.py	Thu Mar 07 13:46:24 2013 +0100
@@ -20,6 +20,7 @@
     NodeAlreadyAddedError, NodeAlreadyChangedError, NodeAlreadyExistsError, \
     NodeAlreadyRemovedError, NodeDoesNotExistError, NodeNotChangedError, \
     RepositoryError
+import datetime
 
 
 class BaseRepository(object):
@@ -980,12 +981,12 @@
     """
 
     def __init__(self, cs='0' * 40, repo=None, requested_revision=None,
-                 alias=None, revision=-1, message='', author='', date=''):
+                 alias=None, revision=-1, message='', author='', date=None):
         self._empty_cs = cs
         self.revision = revision
         self.message = message
         self.author = author
-        self.date = date
+        self.date = date or datetime.datetime.fromtimestamp(0)
         self.repository = repo
         self.requested_revision = requested_revision
         self.alias = alias
--- a/rhodecode/lib/vcs/backends/git/changeset.py	Thu Mar 07 12:20:03 2013 +0100
+++ b/rhodecode/lib/vcs/backends/git/changeset.py	Thu Mar 07 13:46:24 2013 +0100
@@ -17,6 +17,7 @@
 from rhodecode.lib.vcs.utils import safe_unicode
 from rhodecode.lib.vcs.utils import date_fromtimestamp
 from rhodecode.lib.vcs.utils.lazy import LazyProperty
+from rhodecode.lib.utils2 import safe_int
 
 
 class GitChangeset(BaseChangeset):
@@ -275,10 +276,9 @@
         """
         Returns last commit of the file at the given ``path``.
         """
-        node = self.get_node(path)
-        return node.history[0]
+        return self.get_file_history(path, limit=1)[0]
 
-    def get_file_history(self, path):
+    def get_file_history(self, path, limit=None):
         """
         Returns history of file as reversed list of ``Changeset`` objects for
         which file at given ``path`` has been modified.
@@ -287,11 +287,16 @@
         which is generally not good. Should be replaced with algorithm
         iterating commits.
         """
+
         self._get_filectx(path)
-
-        cmd = 'log --pretty="format: %%H" -s -p %s -- "%s"' % (
-                  self.id, path
-               )
+        if limit:
+            cmd = 'log -n %s --pretty="format: %%H" -s -p %s -- "%s"' % (
+                      safe_int(limit, 0), self.id, path
+                   )
+        else:
+            cmd = 'log --pretty="format: %%H" -s -p %s -- "%s"' % (
+                      self.id, path
+                   )
         so, se = self.repository.run_git_command(cmd)
         ids = re.findall(r'[0-9a-fA-F]{40}', so)
         return [self.repository.get_changeset(id) for id in ids]
--- a/rhodecode/lib/vcs/backends/hg/changeset.py	Thu Mar 07 12:20:03 2013 +0100
+++ b/rhodecode/lib/vcs/backends/hg/changeset.py	Thu Mar 07 13:46:24 2013 +0100
@@ -219,19 +219,23 @@
         """
         Returns last commit of the file at the given ``path``.
         """
-        node = self.get_node(path)
-        return node.history[0]
+        return self.get_file_history(path, limit=1)[0]
 
-    def get_file_history(self, path):
+    def get_file_history(self, path, limit=None):
         """
         Returns history of file as reversed list of ``Changeset`` objects for
         which file at given ``path`` has been modified.
         """
         fctx = self._get_filectx(path)
-        nodes = [fctx.filectx(x).node() for x in fctx.filelog()]
-        changesets = [self.repository.get_changeset(hex(node))
-            for node in reversed(nodes)]
-        return changesets
+        hist = []
+        cnt = 0
+        for cs in reversed([x for x in fctx.filelog()]):
+            cnt += 1
+            hist.append(hex(fctx.filectx(cs).node()))
+            if limit and cnt == limit:
+                break
+
+        return [self.repository.get_changeset(node) for node in hist]
 
     def get_file_annotate(self, path):
         """
--- a/rhodecode/templates/files/files_browser.html	Thu Mar 07 12:20:03 2013 +0100
+++ b/rhodecode/templates/files/files_browser.html	Thu Mar 07 13:46:24 2013 +0100
@@ -89,8 +89,8 @@
                      <td>
                          %if node.is_file():
                              <div class="tooltip" title="${h.tooltip(node.last_changeset.message)}">
-                             <pre>${'r%s:%s' % (node.last_changeset.revision,node.last_changeset.short_id)}</pre>
-                            </div>
+                              <pre>${'r%s:%s' % (node.last_changeset.revision,node.last_changeset.short_id)}</pre>
+                             </div>
                          %endif
                      </td>
                      <td>