# HG changeset patch # User Marcin Kuzminski # Date 2017-09-27 11:21:57 # Node ID 69819530b6e1b94ea6b1e0615ebc4936bb2e3454 # Parent 2dddc5079510daa8450d8c85d75ccd8058cd65c5 changelog: fix and optimize loading of chunks for file history. - load-next/prev wasn't working - make sure pagination works as expected - speed up certain actions by pre-loading more attributes diff --git a/rhodecode/apps/repository/__init__.py b/rhodecode/apps/repository/__init__.py --- a/rhodecode/apps/repository/__init__.py +++ b/rhodecode/apps/repository/__init__.py @@ -199,6 +199,9 @@ def includeme(config): config.add_route( name='repo_changelog_elements', pattern='/{repo_name:.*?[^/]}/changelog_elements', repo_route=True) + config.add_route( + name='repo_changelog_elements_file', + pattern='/{repo_name:.*?[^/]}/changelog_elements/{commit_id}/{f_path:.*}', repo_route=True) # Compare config.add_route( diff --git a/rhodecode/apps/repository/views/repo_changelog.py b/rhodecode/apps/repository/views/repo_changelog.py --- a/rhodecode/apps/repository/views/repo_changelog.py +++ b/rhodecode/apps/repository/views/repo_changelog.py @@ -162,6 +162,11 @@ class RepoChangelogView(RepoAppView): self._register_global_c(c) return c + def _get_preload_attrs(self): + pre_load = ['author', 'branch', 'date', 'message', 'parents', + 'obsolete', 'phase', 'hidden'] + return pre_load + @LoginRequired() @HasRepoPermissionAnyDecorator( 'repository.read', 'repository.write', 'repository.admin') @@ -181,6 +186,8 @@ class RepoChangelogView(RepoAppView): c.branch_name = branch_name = self.request.GET.get('branch') or '' c.book_name = book_name = self.request.GET.get('bookmark') or '' + c.f_path = f_path + c.commit_id = commit_id hist_limit = safe_int(self.request.GET.get('limit')) or None p = safe_int(self.request.GET.get('page', 1), 1) @@ -190,7 +197,7 @@ class RepoChangelogView(RepoAppView): self._check_if_valid_branch(branch_name, self.db_repo_name, f_path) c.changelog_for_path = f_path - pre_load = ['author', 'branch', 'date', 'message', 'parents'] + pre_load = self._get_preload_attrs() commit_ids = [] partial_xhr = self.request.environ.get('HTTP_X_PARTIAL_XHR') @@ -200,6 +207,7 @@ class RepoChangelogView(RepoAppView): log.debug('generating changelog for path %s', f_path) # get the history for the file ! base_commit = self.rhodecode_vcs_repo.get_commit(commit_id) + try: collection = base_commit.get_file_history( f_path, limit=hist_limit, pre_load=pre_load) @@ -239,6 +247,7 @@ class RepoChangelogView(RepoAppView): h.route_path('repo_changelog', repo_name=self.db_repo_name)) if partial_xhr or self.request.environ.get('HTTP_X_PJAX'): + # case when loading dynamic file history in file view # loading from ajax, we don't want the first result, it's popped # in the code above html = render( @@ -261,9 +270,16 @@ class RepoChangelogView(RepoAppView): route_name='repo_changelog_elements', request_method=('GET', 'POST'), renderer='rhodecode:templates/changelog/changelog_elements.mako', xhr=True) + @view_config( + route_name='repo_changelog_elements_file', request_method=('GET', 'POST'), + renderer='rhodecode:templates/changelog/changelog_elements.mako', + xhr=True) def repo_changelog_elements(self): c = self.load_default_context() + commit_id = self.request.matchdict.get('commit_id') + f_path = self._get_f_path(self.request.matchdict) chunk_size = 20 + hist_limit = safe_int(self.request.GET.get('limit')) or None def wrap_for_error(err): html = '' \ @@ -273,20 +289,30 @@ class RepoChangelogView(RepoAppView): c.branch_name = branch_name = self.request.GET.get('branch') or '' c.book_name = book_name = self.request.GET.get('bookmark') or '' + c.f_path = f_path + c.commit_id = commit_id c.selected_name = branch_name or book_name if branch_name and branch_name not in self.rhodecode_vcs_repo.branches_all: return wrap_for_error( safe_str('Branch: {} is not valid'.format(branch_name))) - pre_load = ['author', 'branch', 'date', 'message', 'parents'] - collection = self.rhodecode_vcs_repo.get_commits( - branch_name=branch_name, pre_load=pre_load) + pre_load = self._get_preload_attrs() + + if f_path: + base_commit = self.rhodecode_vcs_repo.get_commit(commit_id) + collection = base_commit.get_file_history( + f_path, limit=hist_limit, pre_load=pre_load) + collection = list(reversed(collection)) + else: + collection = self.rhodecode_vcs_repo.get_commits( + branch_name=branch_name, pre_load=pre_load) p = safe_int(self.request.GET.get('page', 1), 1) try: self._load_changelog_data( - c, collection, p, chunk_size, dynamic=True) + c, collection, p, chunk_size, dynamic=True, + f_path=f_path, commit_id=commit_id) except EmptyRepositoryError as e: return wrap_for_error(safe_str(e)) except (RepositoryError, CommitDoesNotExistError, Exception) as e: @@ -296,7 +322,7 @@ class RepoChangelogView(RepoAppView): prev_data = None next_data = None - prev_graph = json.loads(self.request.POST.get('graph', '')) + prev_graph = json.loads(self.request.POST.get('graph') or '{}') if self.request.GET.get('chunk') == 'prev': next_data = prev_graph diff --git a/rhodecode/lib/vcs/backends/git/commit.py b/rhodecode/lib/vcs/backends/git/commit.py --- a/rhodecode/lib/vcs/backends/git/commit.py +++ b/rhodecode/lib/vcs/backends/git/commit.py @@ -64,6 +64,12 @@ class GitCommit(base.BaseCommit): "status", # mercurial specific property not supported here "_file_paths", + # mercurial specific property not supported here + 'obsolete', + # mercurial specific property not supported here + 'phase', + # mercurial specific property not supported here + 'hidden' ] def __init__(self, repository, raw_id, idx, pre_load=None): @@ -261,9 +267,10 @@ class GitCommit(base.BaseCommit): child_ids.extend(found_ids) return self._make_commits(child_ids) - def _make_commits(self, commit_ids): - return [self.repository.get_commit(commit_id=commit_id) - for commit_id in commit_ids] + def _make_commits(self, commit_ids, pre_load=None): + return [ + self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) + for commit_id in commit_ids] def get_file_mode(self, path): """ diff --git a/rhodecode/lib/vcs/backends/hg/commit.py b/rhodecode/lib/vcs/backends/hg/commit.py --- a/rhodecode/lib/vcs/backends/hg/commit.py +++ b/rhodecode/lib/vcs/backends/hg/commit.py @@ -81,6 +81,8 @@ class MercurialCommit(base.BaseCommit): value = utcdate_fromtimestamp(*value) elif attr in ["children", "parents"]: value = self._make_commits(value) + elif attr in ["phase"]: + value = self._get_phase_text(value) self.__dict__[attr] = value @LazyProperty @@ -147,8 +149,8 @@ class MercurialCommit(base.BaseCommit): def short_id(self): return self.raw_id[:12] - def _make_commits(self, indexes): - return [self.repository.get_commit(commit_idx=idx) + def _make_commits(self, indexes, pre_load=None): + return [self.repository.get_commit(commit_idx=idx, pre_load=pre_load) for idx in indexes if idx >= 0] @LazyProperty @@ -159,14 +161,17 @@ class MercurialCommit(base.BaseCommit): parents = self._remote.ctx_parents(self.idx) return self._make_commits(parents) + def _get_phase_text(self, phase_id): + return { + 0: 'public', + 1: 'draft', + 2: 'secret', + }.get(phase_id) or '' + @LazyProperty def phase(self): phase_id = self._remote.ctx_phase(self.idx) - phase_text = { - 0: 'public', - 1: 'draft', - 2: 'secret', - }.get(phase_id) or '' + phase_text = self._get_phase_text(phase_id) return safe_unicode(phase_text) diff --git a/rhodecode/public/js/rhodecode/routes.js b/rhodecode/public/js/rhodecode/routes.js --- a/rhodecode/public/js/rhodecode/routes.js +++ b/rhodecode/public/js/rhodecode/routes.js @@ -166,6 +166,7 @@ function registerRCRoutes() { pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']); pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); pyroutes.register('repo_changelog_elements', '/%(repo_name)s/changelog_elements', ['repo_name']); + pyroutes.register('repo_changelog_elements_file', '/%(repo_name)s/changelog_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']); pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']); pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']); diff --git a/rhodecode/public/js/src/rhodecode/changelog.js b/rhodecode/public/js/src/rhodecode/changelog.js --- a/rhodecode/public/js/src/rhodecode/changelog.js +++ b/rhodecode/public/js/src/rhodecode/changelog.js @@ -94,7 +94,7 @@ var CommitsController = function () { $('#graph_nodes').css({'padding-top': padding}); }; - this.getChunkUrl = function (page, chunk, branch) { + this.getChunkUrl = function (page, chunk, branch, commit_id, f_path) { var urlData = { 'repo_name': templateContext.repo_name, 'page': page, @@ -104,12 +104,24 @@ var CommitsController = function () { if (branch !== undefined && branch !== '') { urlData['branch'] = branch; } + if (commit_id !== undefined && commit_id !== '') { + urlData['commit_id'] = commit_id; + } + if (f_path !== undefined && f_path !== '') { + urlData['f_path'] = f_path; + } - return pyroutes.url('repo_changelog_elements', urlData); + if (urlData['commit_id'] && urlData['f_path']) { + return pyroutes.url('repo_changelog_elements_file', urlData); + } + else { + return pyroutes.url('repo_changelog_elements', urlData); + } + }; - this.loadNext = function (node, page, branch) { - var loadUrl = this.getChunkUrl(page, 'next', branch); + this.loadNext = function (node, page, branch, commit_id, f_path) { + var loadUrl = this.getChunkUrl(page, 'next', branch, commit_id, f_path); var postData = {'graph': JSON.stringify(this.getCurrentGraphData())}; $.post(loadUrl, postData, function (data) { @@ -119,8 +131,8 @@ var CommitsController = function () { }) }; - this.loadPrev = function (node, page, branch) { - var loadUrl = this.getChunkUrl(page, 'prev', branch); + this.loadPrev = function (node, page, branch, commit_id, f_path) { + var loadUrl = this.getChunkUrl(page, 'prev', branch, commit_id, f_path); var postData = {'graph': JSON.stringify(this.getCurrentGraphData())}; $.post(loadUrl, postData, function (data) { diff --git a/rhodecode/templates/changelog/changelog_elements.mako b/rhodecode/templates/changelog/changelog_elements.mako --- a/rhodecode/templates/changelog/changelog_elements.mako +++ b/rhodecode/templates/changelog/changelog_elements.mako @@ -5,7 +5,7 @@ % if c.prev_page: - + ${_('load previous')} @@ -131,7 +131,7 @@ % if c.next_page: - + ${_('load next')}