incubator-allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From john...@apache.org
Subject [45/50] git commit: [#6686] Implement an indexless last_commit_ids for Git
Date Tue, 22 Oct 2013 21:50:55 GMT
[#6686] Implement an indexless last_commit_ids for Git

NB: This is not fully indexless, since it still needs the model data for
controller dispatch and pulling the commit summary info (though the
later could easily be gotten from git while getting the last_commit_ids
just by changing the pretty=format param, it would just require more
refactoring to surface / cache it).

Signed-off-by: Cory Johns <cjohns@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a482b458
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a482b458
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a482b458

Branch: refs/heads/cj/6422
Commit: a482b45810c1698c9cccd64ff55e4e8e2609a580
Parents: 5ee1e72
Author: Cory Johns <cjohns@slashdotmedia.com>
Authored: Tue Oct 1 14:52:00 2013 +0000
Committer: Cory Johns <cjohns@slashdotmedia.com>
Committed: Mon Oct 21 20:31:08 2013 +0000

----------------------------------------------------------------------
 ForgeGit/forgegit/model/git_repo.py             | 42 ++++++++++++++++++++
 .../forgegit/tests/model/test_repository.py     | 14 +++++++
 2 files changed, 56 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a482b458/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 3efc519..1f2ae37 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -26,6 +26,7 @@ from collections import namedtuple
 from datetime import datetime
 from glob import glob
 import gzip
+from time import time
 
 import tg
 import git
@@ -497,6 +498,47 @@ class GitImplementation(M.RepositoryImplementation):
         self._repo.default_branch_name = name
         session(self._repo).flush(self._repo)
 
+    def last_commit_ids(self, commit, paths):
+        """
+        Find the ID of the last commit to touch each path.
+        """
+        def prefix_paths_union(a, b):
+            """
+            Given two sets of paths, a and b, find the items from a that
+            are either in b or are parent directories of items in b.
+            """
+            union = a & b
+            prefixes = a - b
+            candidates = b - a
+            for prefix in prefixes:
+                for candidate in candidates:
+                    if candidate.startswith(prefix + '/'):
+                        union.add(prefix)
+                        break
+            return union
+        result = {}
+        paths = set(paths)
+        orig_commit_id = commit_id = commit._id
+        timeout = float(tg.config.get('lcd_timeout', 60))
+        start_time = time()
+        while paths and commit_id:
+            if time() - start_time > timeout:
+                log.error('last_commit_ids timeout for %s on %s', orig_commit_id, ', '.join(paths))
+                return result
+            lines = self._git.git.log(
+                    orig_commit_id, '--', *paths,
+                    pretty='format:%H',
+                    name_only=True,
+                    max_count=1,
+                    no_merges=True).split('\n')
+            commit_id = lines[0]
+            changes = set(lines[1:])
+            changed = prefix_paths_union(paths, changes)
+            for path in changed:
+                result[path] = commit_id
+            paths -= changed
+        return result
+
 class _OpenedGitBlob(object):
     CHUNK_SIZE=4096
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a482b458/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index a494886..ea615b6 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -432,6 +432,20 @@ class TestGitImplementation(unittest.TestCase):
                 Object(name='foo', object_id='1e146e67985dcd71c74de79613719bef7bddca4a'),
             ])
 
+    def test_last_commit_ids(self):
+        repo_dir = pkg_resources.resource_filename(
+            'forgegit', 'tests/data/testrename.git')
+        repo = mock.Mock(full_fs_path=repo_dir)
+        impl = GM.git_repo.GitImplementation(repo)
+        lcd = lambda c, p: impl.last_commit_ids(mock.Mock(_id=c), p)
+        self.assertEqual(lcd('13951944969cf45a701bf90f83647b309815e6d5', ['f2.txt', 'f3.txt']),
{
+                'f2.txt': '259c77dd6ee0e6091d11e429b56c44ccbf1e64a3',
+                'f3.txt': '653667b582ef2950c1954a0c7e1e8797b19d778a',
+            })
+        self.assertEqual(lcd('259c77dd6ee0e6091d11e429b56c44ccbf1e64a3', ['f2.txt', 'f3.txt']),
{
+                'f2.txt': '259c77dd6ee0e6091d11e429b56c44ccbf1e64a3',
+            })
+
 
 class TestGitCommit(unittest.TestCase):
 


Mime
View raw message