diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py --- a/rhodecode/config/routing.py +++ b/rhodecode/config/routing.py @@ -514,6 +514,10 @@ def make_map(config): rmap.connect('shortlog_home', '/{repo_name:.*?}/shortlog', controller='shortlog', conditions=dict(function=check_repo)) + rmap.connect('shortlog_file_home', '/{repo_name:.*?}/shortlog/{revision}/{f_path:.*}', + controller='shortlog', f_path=None, + conditions=dict(function=check_repo)) + rmap.connect('branches_home', '/{repo_name:.*?}/branches', controller='branches', conditions=dict(function=check_repo)) diff --git a/rhodecode/controllers/shortlog.py b/rhodecode/controllers/shortlog.py --- a/rhodecode/controllers/shortlog.py +++ b/rhodecode/controllers/shortlog.py @@ -26,12 +26,16 @@ import logging from pylons import tmpl_context as c, request, url +from pylons.i18n.translation import _ +from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.helpers import RepoPage from pylons.controllers.util import redirect from rhodecode.lib.utils2 import safe_int +from rhodecode.lib.vcs.exceptions import NodeDoesNotExistError, ChangesetError,\ + RepositoryError log = logging.getLogger(__name__) @@ -44,19 +48,53 @@ class ShortlogController(BaseRepoControl def __before__(self): super(ShortlogController, self).__before__() - def index(self, repo_name): + def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True): + """ + Safe way to get changeset if error occur it redirects to tip with + proper message + + :param rev: revision to fetch + :param repo_name: repo name to redirect after + """ + + try: + return c.rhodecode_repo.get_changeset(rev) + except RepositoryError, e: + h.flash(str(e), category='warning') + redirect(h.url('shortlog_home', repo_name=repo_name)) + + def index(self, repo_name, revision=None, f_path=None): p = safe_int(request.params.get('page', 1), 1) size = safe_int(request.params.get('size', 20), 20) def url_generator(**kw): return url('shortlog_home', repo_name=repo_name, size=size, **kw) - c.repo_changesets = RepoPage(c.rhodecode_repo, page=p, + collection = c.rhodecode_repo + c.file_history = f_path + if f_path: + f_path = f_path.lstrip('/') + # get the history for the file ! + tip_cs = c.rhodecode_repo.get_changeset() + try: + collection = tip_cs.get_file_history(f_path) + except (NodeDoesNotExistError, ChangesetError): + #this node is not present at tip ! + try: + cs = self.__get_cs_or_redirect(revision, repo_name) + collection = cs.get_file_history(f_path) + except RepositoryError, e: + h.flash(str(e), category='warning') + redirect(h.url('shortlog_home', repo_name=repo_name)) + collection = list(reversed(collection)) + + c.repo_changesets = RepoPage(collection, page=p, items_per_page=size, url=url_generator) - page_revisions = [x.raw_id for x in list(c.repo_changesets)] + page_revisions = [x.raw_id for x in list(collection)] c.statuses = c.rhodecode_db_repo.statuses(page_revisions) if not c.repo_changesets: + h.flash(_('There are no changesets yet'), category='warning') return redirect(url('summary_home', repo_name=repo_name)) c.shortlog_data = render('shortlog/shortlog_data.html') diff --git a/rhodecode/lib/vcs/backends/git/changeset.py b/rhodecode/lib/vcs/backends/git/changeset.py --- a/rhodecode/lib/vcs/backends/git/changeset.py +++ b/rhodecode/lib/vcs/backends/git/changeset.py @@ -162,6 +162,13 @@ class GitChangeset(BaseChangeset): elif isinstance(obj, objects.Tree): return NodeKind.DIR + def _get_filectx(self, path): + path = self._fix_path(path) + if self._get_kind(path) != NodeKind.FILE: + raise ChangesetError("File does not exist for revision %r at " + " %r" % (self.raw_id, path)) + return path + def _get_file_nodes(self): return chain(*(t[2] for t in self.walk())) @@ -264,6 +271,7 @@ class GitChangeset(BaseChangeset): 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 ) diff --git a/rhodecode/lib/vcs/backends/hg/changeset.py b/rhodecode/lib/vcs/backends/hg/changeset.py --- a/rhodecode/lib/vcs/backends/hg/changeset.py +++ b/rhodecode/lib/vcs/backends/hg/changeset.py @@ -181,7 +181,7 @@ class MercurialChangeset(BaseChangeset): path = self._fix_path(path) if self._get_kind(path) != NodeKind.FILE: raise ChangesetError("File does not exist for revision %r at " - " %r" % (self.revision, path)) + " %r" % (self.raw_id, path)) return self._ctx.filectx(path) def _extract_submodules(self): diff --git a/rhodecode/public/css/style.css b/rhodecode/public/css/style.css --- a/rhodecode/public/css/style.css +++ b/rhodecode/public/css/style.css @@ -2650,15 +2650,14 @@ h3.files_location { #graph_content .container .mid .message a:hover{ text-decoration: none; } -#content #graph_content .message .revision-link, -#changeset_content .container .message .revision-link + +.revision-link { color:#3F6F9F; font-weight: bold !important; } -#content #graph_content .message .issue-tracker-link, -#changeset_content .container .message .issue-tracker-link{ +.issue-tracker-link{ color:#3F6F9F; font-weight: bold !important; } diff --git a/rhodecode/templates/files/files_history_box.html b/rhodecode/templates/files/files_history_box.html --- a/rhodecode/templates/files/files_history_box.html +++ b/rhodecode/templates/files/files_history_box.html @@ -8,6 +8,7 @@ ${h.select('diff1',c.file_changeset.raw_id,c.file_history)} ${h.submit('diff',_('diff to revision'),class_="ui-btn")} ${h.submit('show_rev',_('show at revision'),class_="ui-btn")} + ${h.link_to(_('show full history'),h.url('shortlog_file_home',repo_name=c.repo_name, revision=c.file_changeset.raw_id, f_path=c.f_path),class_="ui-btn")} ${h.hidden('annotate', c.annotate)} ${h.end_form()} diff --git a/rhodecode/templates/shortlog/shortlog.html b/rhodecode/templates/shortlog/shortlog.html --- a/rhodecode/templates/shortlog/shortlog.html +++ b/rhodecode/templates/shortlog/shortlog.html @@ -11,7 +11,13 @@ » ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} » - ${_('shortlog')} + %if c.file_history: + ${h.link_to(_('shortlog'),h.url('shortlog_home',repo_name=c.repo_name))} + » + ${c.file_history} + %else: + ${_('shortlog')} + %endif %def> <%def name="page_nav()"> diff --git a/rhodecode/templates/shortlog/shortlog_data.html b/rhodecode/templates/shortlog/shortlog_data.html --- a/rhodecode/templates/shortlog/shortlog_data.html +++ b/rhodecode/templates/shortlog/shortlog_data.html @@ -30,9 +30,7 @@