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())