You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2013/10/01 17:06:40 UTC
git commit: [#6686] Implement an indexless last_commit_ids for Git
Updated Branches:
refs/heads/cj/6686 [created] 363e3a2f8
[#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 <cj...@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/363e3a2f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/363e3a2f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/363e3a2f
Branch: refs/heads/cj/6686
Commit: 363e3a2f887ede99d22fa6928cb95e11044c9843
Parents: 182a724
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Oct 1 14:52:00 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Oct 1 15:06:19 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/363e3a2f/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 29af6c7..938dc8a 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
@@ -495,6 +496,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/363e3a2f/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 575ccba..ab2ef8f 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):