You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by tv...@apache.org on 2012/12/04 15:26:14 UTC

[11/29] git commit: [#5037] ticket:184 added log for file and dir

[#5037] ticket:184 added log for file and dir


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

Branch: refs/heads/tv/5382
Commit: 24f5081f826150d25af4d81df9458200215070b8
Parents: 212e90e
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Wed Oct 10 18:19:25 2012 +0400
Committer: Cory Johns <jo...@geek.net>
Committed: Mon Dec 3 23:56:20 2012 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py            |   17 ++-
 Allura/allura/model/repository.py                  |    7 ++
 Allura/allura/templates/repo/file.html             |    2 +-
 Allura/allura/templates/repo/tree.html             |    2 +-
 ForgeGit/forgegit/model/git_repo.py                |    6 +
 .../forgegit/tests/functional/test_controllers.py  |    9 ++
 ForgeGit/forgegit/tests/model/test_repository.py   |    9 ++
 ForgeHg/forgehg/model/hg.py                        |   82 ++++++++++++++-
 .../forgehg/tests/functional/test_controllers.py   |    9 ++
 ForgeHg/forgehg/tests/model/test_repository.py     |    5 +
 ForgeSVN/forgesvn/model/svn.py                     |   10 ++
 .../forgesvn/tests/functional/test_controllers.py  |   11 ++
 ForgeSVN/forgesvn/tests/model/test_repository.py   |    6 +
 13 files changed, 166 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index e2caa82..0dc101d 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -426,13 +426,17 @@ class CommitBrowser(BaseController):
     @with_trailing_slash
     @validate(dict(page=validators.Int(if_empty=0),
                    limit=validators.Int(if_empty=25)))
-    def log(self, limit=25, page=0, **kw):
+    def log(self, limit=25, page=0, path="", **kw):
         limit, page, start = g.handle_paging(limit, page, default=25)
-        revisions = c.app.repo.log(
-                branch=self._commit._id,
-                offset=start,
-                limit=limit)
-        count = c.app.repo.count(branch=self._commit._id)
+        if path[0:1] == "/":
+            path = path[1:]
+        commits = c.app.repo.get_commits_by_path(path=path)
+        index = 0
+        if self._commit._id in commits:
+            index = commits.index(self._commit._id)
+        commits = commits[index:]
+        count = len(commits)
+        revisions = M.repo.Commit.query.find({'_id': {'$in': commits[start:start + limit]}}).sort('committed.date', -1)
         c.log_widget = self.log_widget
         return dict(
             username=c.user._id and c.user.username,
@@ -443,6 +447,7 @@ class CommitBrowser(BaseController):
             count=count,
             **kw)
 
+
 class TreeBrowser(BaseController, DispatchIndex):
     tree_widget = SCMTreeWidget()
     FileBrowserClass=None

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 9867cf0..6246393 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -104,6 +104,10 @@ class RepositoryImplementation(object):
         '''Return a blob size in bytes'''
         raise NotImplementedError, 'blob_size'
 
+    def get_commits_by_path(self, path):
+        '''Return a list of commits'''
+        raise NotImplementedError, 'get_commits_by_path'
+
     @classmethod
     def shorthand_for_commit(cls, oid):
         return '[%s]' % oid[:6]
@@ -224,6 +228,9 @@ class Repository(Artifact, ActivityObject):
             ci.set_context(self)
             yield ci
 
+    def get_commits_by_path(self, path):
+        return self._impl.get_commits_by_path(path)
+
     def init_as_clone(self, source_path, source_name, source_url):
         self.upstream_repo.name = source_name
         self.upstream_repo.url = source_url

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/Allura/allura/templates/repo/file.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/file.html b/Allura/allura/templates/repo/file.html
index 83afe6c..4f43dfe 100644
--- a/Allura/allura/templates/repo/file.html
+++ b/Allura/allura/templates/repo/file.html
@@ -13,7 +13,7 @@
 {% endblock %}
 
 {% block actions %}
-<a href="{{blob.commit.url()}}log/">
+<a href="{{blob.commit.url()}}log/?path={{ blob.path() }}">
   <b data-icon="{{g.icons.history.char}}" class="ico {{g.icons.history.css}}" title="History"> </b> History
 </a>
 {% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/Allura/allura/templates/repo/tree.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/tree.html b/Allura/allura/templates/repo/tree.html
index b496c73..31d7b2b 100644
--- a/Allura/allura/templates/repo/tree.html
+++ b/Allura/allura/templates/repo/tree.html
@@ -12,7 +12,7 @@ Tree <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a> {{commit_labels(co
 {% endblock %}
 
 {% block actions %}
-<a href="{{commit.url()}}log/">
+<a href="{{commit.url()}}log/?path={{ path }}">
   <b data-icon="{{g.icons.history.char}}" class="ico {{g.icons.history.css}}" title="History"> </b> History
 </a>
 {% if c.user and c.user != c.user.anonymous() %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 3501e38..08fe91d 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -234,6 +234,12 @@ class GitImplementation(M.RepositoryImplementation):
         doc.m.save(safe=False)
         return doc
 
+    def get_commits_by_path(self, path):
+        result = []
+        for c in self._git.iter_commits(paths=path):
+            result.append(c.hexsha)
+        return result
+
     def log(self, object_id, skip, count):
         obj = self._git.commit(object_id)
         candidates = [ obj ]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index f3d34e0..8d3330c 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -95,6 +95,15 @@ class TestRootController(_TestCase):
 
     def test_log(self):
         resp = self.app.get('/src-git/ref/master~/log/')
+        resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/')
+        assert 'Initial commit' in resp
+        assert 'Change README' in resp
+        resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/README')
+        assert 'Change README ' in resp
+        assert 'Add README ' in resp
+        assert "Initial commit " not in resp
+        resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/test')
+        assert 'No (more) commits' in resp
 
     def test_tags(self):
         resp = self.app.get('/src-git/ref/master~/tags/')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/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 a73f07d..8b930a7 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -254,6 +254,15 @@ class TestGitCommit(unittest.TestCase):
         for d in diffs:
             print d
 
+    def test_get_commits_by_path(self):
+        assert ("9a7df788cf800241e3bb5a849c8870f2f8259d98"
+                in self.repo.get_commits_by_path(''))
+        assert ("1e146e67985dcd71c74de79613719bef7bddca4a"
+                in self.repo.get_commits_by_path('README'))
+        assert ("df30427c488aeab84b2352bdf88a3b19223f9d7a"
+                in self.repo.get_commits_by_path('README'))
+        assert [] == self.repo.get_commits_by_path('test')
+
 
 class TestGitHtmlView(unittest.TestCase):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeHg/forgehg/model/hg.py
----------------------------------------------------------------------
diff --git a/ForgeHg/forgehg/model/hg.py b/ForgeHg/forgehg/model/hg.py
index 22d9227..2a32206 100644
--- a/ForgeHg/forgehg/model/hg.py
+++ b/ForgeHg/forgehg/model/hg.py
@@ -10,7 +10,9 @@ from ConfigParser import ConfigParser
 import tg
 from pylons import app_globals as g
 os.environ['HGRCPATH'] = '' # disable loading .hgrc
-from mercurial import ui, hg
+from mercurial import ui, hg, cmdutil, error
+from mercurial.node import nullrev
+
 from pymongo.errors import DuplicateKeyError
 
 from ming.base import Object
@@ -229,6 +231,76 @@ class HgImplementation(M.RepositoryImplementation):
         doc.m.save(safe=False)
         return doc
 
+    def get_commits(self, ui, repo, *pats, **opts):
+        matchfn = cmdutil.match(repo, pats, opts, default='relpath')
+        if opts.get('copies') and opts.get('rev'):
+            endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
+        else:
+            endrev = len(repo)
+        rcache = {}
+        ncache = {}
+
+        def getrenamed(fn, rev):
+            if fn not in rcache:
+                rcache[fn] = {}
+                ncache[fn] = {}
+                fl = repo.file(fn)
+                for i in fl:
+                    node = fl.node(i)
+                    lr = fl.linkrev(i)
+                    renamed = fl.renamed(node)
+                    rcache[fn][lr] = renamed
+                    if renamed:
+                        ncache[fn][node] = renamed
+                    if lr >= endrev:
+                        break
+            if rev in rcache[fn]:
+                return rcache[fn][rev]
+
+            try:
+                return repo[rev][fn].renamed()
+            except error.LookupError:
+                pass
+            return None
+
+        df = False
+
+        def prep(ctx, fns):
+            rev = ctx.rev()
+            parents = [
+                p for p in repo.changelog.parentrevs(rev) if p != nullrev
+            ]
+            if opts.get('no_merges') and len(parents) == 2:
+                return
+            if opts.get('only_merges') and len(parents) != 2:
+                return
+            if opts.get('only_branch') and ctx.branch() not in opts['only_branch']:
+                return
+            if df and not df(ctx.date()[0]):
+                return
+            if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
+                return
+            if opts.get('keyword'):
+                for k in [kw.lower() for kw in opts['keyword']]:
+                    if (k in ctx.user().lower() or
+                        k in ctx.description().lower() or
+                        k in " ".join(ctx.files()).lower()):
+                        break
+                else:
+                    return
+
+            copies = []
+            if opts.get('copies') and rev:
+                for fn in ctx.files():
+                    rename = getrenamed(fn, rev)
+                    if rename:
+                        copies.append((fn, rename[0]))
+
+        revs = []
+        for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
+            revs.append(ctx.hex())
+        return revs
+
     def log(self, object_id, skip, count):
         obj = self._hg[object_id]
         candidates = [ obj ]
@@ -291,4 +363,12 @@ class HgImplementation(M.RepositoryImplementation):
         tree = self.refresh_tree_info(fake_tree, set())
         return tree._id
 
+    def get_commits_by_path(self, path):
+        return self.get_commits(
+            ui.ui(),
+            self._hg,
+            self._repo.fs_path + '/' + self._repo.name + '/'+path,
+            rev=None,
+            user=None)
+
 Mapper.compile_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeHg/forgehg/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeHg/forgehg/tests/functional/test_controllers.py b/ForgeHg/forgehg/tests/functional/test_controllers.py
index 2d823b5..c66e116 100644
--- a/ForgeHg/forgehg/tests/functional/test_controllers.py
+++ b/ForgeHg/forgehg/tests/functional/test_controllers.py
@@ -173,6 +173,15 @@ class TestRootController(TestController):
         validate_chunk=True)
         assert 'Cannot display: file marked as a binary type.' in resp
 
+    def test_log(self):
+        r = self.app.get('/p/test/src-hg/ci/4a7f7ec0dcf5f005eb5d177b3d8c00bfc8159843/log/?path=')
+        assert "add test.jpg " in r
+        assert "Add README" in r
+        r = self.app.get('/p/test/src-hg/ci/4a7f7ec0dcf5f005eb5d177b3d8c00bfc8159843/log/?path=/README')
+        assert "add test.jpg " not in r
+        assert "Add README" in r
+        assert "Modify README" in r
+
 
 class TestLogPagination(TestController):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeHg/forgehg/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeHg/forgehg/tests/model/test_repository.py b/ForgeHg/forgehg/tests/model/test_repository.py
index bfb05ca..26f7ac7 100644
--- a/ForgeHg/forgehg/tests/model/test_repository.py
+++ b/ForgeHg/forgehg/tests/model/test_repository.py
@@ -247,3 +247,8 @@ class TestHgCommit(unittest.TestCase):
                  +self.rev.diffs.copied)
         for d in diffs:
             print d
+
+    def test_get_commits_by_path(self):
+        assert len(self.repo.get_commits_by_path('')) == 5
+        assert len(self.repo.get_commits_by_path('README')) == 2
+        assert len(self.repo.get_commits_by_path('test')) == 0

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index 48d2c9c..b8550d5 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -468,4 +468,14 @@ class SVNImplementation(M.RepositoryImplementation):
     def _oid(self, revno):
         return '%s:%s' % (self._repo._id, revno)
 
+    def  get_commits_by_path(self, path):
+        result = []
+        try:
+            for l in self._svn.log(url_or_path=self._url + "/" + path):
+                result.append(self._oid('') + str(l.revision.number))
+            return result
+        except:
+            return result
+
+
 Mapper.compile_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeSVN/forgesvn/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/functional/test_controllers.py b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
index 9c09769..a093242 100644
--- a/ForgeSVN/forgesvn/tests/functional/test_controllers.py
+++ b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
@@ -118,6 +118,17 @@ class TestRootController(SVNTestController):
         r = self.app.get('/p/test/admin/src/checkout_url')
         assert 'value="a"' in r
 
+    def test_log(self):
+        r = self.app.get('/src/2/log/?path=')
+        assert "Create readme" in r
+        assert "Add path " in r
+        r = self.app.get('/src/2/log/?path=README')
+        assert "Modify readme" in r
+        assert "Remove hello.txt" not in r
+        assert "Create readme " in r
+        r = self.app.get('/src/2/log/?path=test')
+        assert 'No (more) commits' in r
+
 
 class TestImportController(SVNTestController):
     def test_index(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/24f5081f/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 7d8b826..fb65a70 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -287,6 +287,12 @@ class TestSVNRev(unittest.TestCase):
         for d in diffs:
             print d
 
+    def test_get_commits_by_path(self):
+        assert  len(self.repo.get_commits_by_path('')) == 5
+        assert  len(self.repo.get_commits_by_path('README')) == 2
+        assert  len(self.repo.get_commits_by_path('test')) == 0
+
+
 class _Test(unittest.TestCase):
     idgen = ( 'obj_%d' % i for i in count())