diff --git a/rhodecode/controllers/pullrequests.py b/rhodecode/controllers/pullrequests.py --- a/rhodecode/controllers/pullrequests.py +++ b/rhodecode/controllers/pullrequests.py @@ -24,6 +24,9 @@ # along with this program. If not, see . import logging import traceback +import binascii + +from webob.exc import HTTPNotFound from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect @@ -32,9 +35,13 @@ from pylons.i18n.translation import _ from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib import helpers as h -from rhodecode.model.db import User, PullRequest +from rhodecode.lib import diffs +from rhodecode.model.db import User, PullRequest, Repository, ChangesetStatus from rhodecode.model.pull_request import PullRequestModel from rhodecode.model.meta import Session +from rhodecode.model.repo import RepoModel +from rhodecode.model.comment import ChangesetCommentsModel +from rhodecode.model.changeset_status import ChangesetStatusModel log = logging.getLogger(__name__) @@ -50,12 +57,12 @@ class PullrequestsController(BaseRepoCon def _get_repo_refs(self, repo): hist_l = [] - branches_group = ([('branch:' + k, k) for k in repo.branches.keys()], - _("Branches")) - bookmarks_group = ([('book:' + k, k) for k in repo.bookmarks.keys()], - _("Bookmarks")) - tags_group = ([('tag:' + k, k) for k in repo.tags.keys()], - _("Tags")) + branches_group = ([('branch:%s:%s' % (k, v), k) for + k, v in repo.branches.iteritems()], _("Branches")) + bookmarks_group = ([('book:%s:%s' % (k, v), k) for + k, v in repo.bookmarks.iteritems()], _("Bookmarks")) + tags_group = ([('tag:%s:%s' % (k, v), k) for + k, v in repo.tags.iteritems()], _("Tags")) hist_l.append(bookmarks_group) hist_l.append(branches_group) @@ -63,6 +70,11 @@ class PullrequestsController(BaseRepoCon return hist_l + def show_all(self, repo_name): + c.pull_requests = PullRequestModel().get_all(repo_name) + c.repo_name = repo_name + return render('/pullrequests/pullrequest_show_all.html') + def index(self): org_repo = c.rhodecode_db_repo c.org_refs = self._get_repo_refs(c.rhodecode_repo) @@ -128,6 +140,118 @@ class PullrequestsController(BaseRepoCon return redirect(url('changelog_home', repo_name=repo_name)) + def _get_changesets(self, org_repo, org_ref, other_repo, other_ref, tmp): + changesets = [] + #case two independent repos + if org_repo != other_repo: + common, incoming, rheads = tmp + + if not incoming: + revs = [] + else: + revs = org_repo._repo.changelog.findmissing(common, rheads) + + for cs in reversed(map(binascii.hexlify, revs)): + changesets.append(org_repo.get_changeset(cs)) + else: + revs = ['ancestors(%s) and not ancestors(%s)' % (org_ref[1], + other_ref[1])] + from mercurial import scmutil + out = scmutil.revrange(org_repo._repo, revs) + for cs in reversed(out): + changesets.append(org_repo.get_changeset(cs)) + + return changesets + + def _get_discovery(self, org_repo, org_ref, other_repo, other_ref): + from mercurial import discovery + other = org_repo._repo + repo = other_repo._repo + tip = other[org_ref[1]] + log.debug('Doing discovery for %s@%s vs %s@%s' % ( + org_repo, org_ref, other_repo, other_ref) + ) + log.debug('Filter heads are %s[%s]' % (tip, org_ref[1])) + tmp = discovery.findcommonincoming( + repo=repo, # other_repo we check for incoming + remote=other, # org_repo source for incoming + heads=[tip.node()], + force=False + ) + return tmp + + def _compare(self, pull_request): + + org_repo = pull_request.org_repo + org_ref_type, org_ref_, org_ref = pull_request.org_ref.split(':') + other_repo = pull_request.other_repo + other_ref_type, other_ref, other_ref_ = pull_request.other_ref.split(':') + + org_ref = (org_ref_type, org_ref) + other_ref = (other_ref_type, other_ref) + + c.org_repo = org_repo + c.other_repo = other_repo + + discovery_data = self._get_discovery(org_repo.scm_instance, + org_ref, + other_repo.scm_instance, + other_ref) + c.cs_ranges = self._get_changesets(org_repo.scm_instance, + org_ref, + other_repo.scm_instance, + other_ref, + discovery_data) + + c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in + c.cs_ranges]) + # defines that we need hidden inputs with changesets + c.as_form = request.GET.get('as_form', False) + if request.environ.get('HTTP_X_PARTIAL_XHR'): + return render('compare/compare_cs.html') + + c.org_ref = org_ref[1] + c.other_ref = other_ref[1] + # diff needs to have swapped org with other to generate proper diff + _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref, + discovery_data) + diff_processor = diffs.DiffProcessor(_diff, format='gitdiff') + _parsed = diff_processor.prepare() + + c.files = [] + c.changes = {} + + for f in _parsed: + fid = h.FID('', f['filename']) + c.files.append([fid, f['operation'], f['filename'], f['stats']]) + diff = diff_processor.as_html(enable_comments=False, diff_lines=[f]) + c.changes[fid] = [f['operation'], f['filename'], diff] + def show(self, repo_name, pull_request_id): + repo_model = RepoModel() + c.users_array = repo_model.get_users_js() + c.users_groups_array = repo_model.get_users_groups_js() c.pull_request = PullRequest.get(pull_request_id) + ##TODO: need more generic solution + self._compare(c.pull_request) + + # inline comments + c.inline_cnt = 0 + c.inline_comments = ChangesetCommentsModel()\ + .get_inline_comments(c.rhodecode_db_repo.repo_id, + pull_request=pull_request_id) + # count inline comments + for __, lines in c.inline_comments: + for comments in lines.values(): + c.inline_cnt += len(comments) + # comments + c.comments = ChangesetCommentsModel()\ + .get_comments(c.rhodecode_db_repo.repo_id, + pull_request=pull_request_id) + + # changeset(pull-request) statuse + c.current_changeset_status = ChangesetStatusModel()\ + .get_status(c.rhodecode_db_repo.repo_id, + pull_request=pull_request_id) + c.changeset_statuses = ChangesetStatus.STATUSES return render('/pullrequests/pullrequest_show.html')