diff --git a/rhodecode/controllers/compare.py b/rhodecode/controllers/compare.py --- a/rhodecode/controllers/compare.py +++ b/rhodecode/controllers/compare.py @@ -25,7 +25,6 @@ # 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 @@ -37,6 +36,7 @@ from rhodecode.lib.auth import LoginRequ from rhodecode.lib import diffs from rhodecode.model.db import Repository +from rhodecode.model.pull_request import PullRequestModel log = logging.getLogger(__name__) @@ -49,46 +49,6 @@ class CompareController(BaseRepoControll def __before__(self): super(CompareController, self).__before__() - 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 _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 index(self, org_ref_type, org_ref, other_ref_type, other_ref): org_repo = c.rhodecode_db_repo.repo_name @@ -108,15 +68,9 @@ class CompareController(BaseRepoControll log.error('Could not found repo %s or %s' % (org_repo, other_repo)) raise HTTPNotFound - 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.cs_ranges, discovery_data = PullRequestModel().get_compare_data( + org_repo, org_ref, other_repo, other_ref + ) c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in c.cs_ranges]) diff --git a/rhodecode/controllers/pullrequests.py b/rhodecode/controllers/pullrequests.py --- a/rhodecode/controllers/pullrequests.py +++ b/rhodecode/controllers/pullrequests.py @@ -140,47 +140,13 @@ 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)) + def _load_compare_data(self, pull_request): + """ + Load context data needed for generating compare diff - 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): + :param pull_request: + :type pull_request: + """ org_repo = pull_request.org_repo org_ref_type, org_ref_, org_ref = pull_request.org_ref.split(':') @@ -193,22 +159,14 @@ class PullrequestsController(BaseRepoCon 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.cs_ranges, discovery_data = PullRequestModel().get_compare_data( + org_repo, org_ref, other_repo, other_ref + ) 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] @@ -232,8 +190,9 @@ class PullrequestsController(BaseRepoCon 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) + + # load compare data into template context + self._load_compare_data(c.pull_request) # inline comments c.inline_cnt = 0 diff --git a/rhodecode/lib/vcs/utils/hgcompat.py b/rhodecode/lib/vcs/utils/hgcompat.py --- a/rhodecode/lib/vcs/utils/hgcompat.py +++ b/rhodecode/lib/vcs/utils/hgcompat.py @@ -12,3 +12,4 @@ from mercurial.match import match from mercurial.mdiff import diffopts from mercurial.node import hex from mercurial.encoding import tolocal +from mercurial import discovery \ No newline at end of file diff --git a/rhodecode/model/pull_request.py b/rhodecode/model/pull_request.py --- a/rhodecode/model/pull_request.py +++ b/rhodecode/model/pull_request.py @@ -24,6 +24,7 @@ # along with this program. If not, see . import logging +import binascii from pylons.i18n.translation import _ from rhodecode.lib import helpers as h @@ -32,6 +33,8 @@ from rhodecode.model.db import PullReque from rhodecode.model.notification import NotificationModel from rhodecode.lib.utils2 import safe_unicode +from rhodecode.lib.vcs.utils.hgcompat import discovery + log = logging.getLogger(__name__) @@ -82,3 +85,103 @@ class PullRequestModel(BaseModel): type_=Notification.TYPE_PULL_REQUEST,) return new + + def _get_changesets(self, org_repo, org_ref, other_repo, other_ref, + discovery_data): + """ + Returns a list of changesets that are incoming from org_repo@org_ref + to other_repo@other_ref + + :param org_repo: + :type org_repo: + :param org_ref: + :type org_ref: + :param other_repo: + :type other_repo: + :param other_ref: + :type other_ref: + :param tmp: + :type tmp: + """ + changesets = [] + #case two independent repos + if org_repo != other_repo: + common, incoming, rheads = discovery_data + + 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): + """ + Get's mercurial discovery data used to calculate difference between + repos and refs + + :param org_repo: + :type org_repo: + :param org_ref: + :type org_ref: + :param other_repo: + :type other_repo: + :param other_ref: + :type other_ref: + """ + + 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 get_compare_data(self, org_repo, org_ref, other_repo, other_ref): + """ + Returns a tuple of incomming changesets, and discoverydata cache + + :param org_repo: + :type org_repo: + :param org_ref: + :type org_ref: + :param other_repo: + :type other_repo: + :param other_ref: + :type other_ref: + """ + + if len(org_ref) != 2 or not isinstance(org_ref, (list, tuple)): + raise Exception('org_ref must be a two element list/tuple') + + if len(other_ref) != 2 or not isinstance(org_ref, (list, tuple)): + raise Exception('other_ref must be a two element list/tuple') + + discovery_data = self._get_discovery(org_repo.scm_instance, + org_ref, + other_repo.scm_instance, + other_ref) + cs_ranges = self._get_changesets(org_repo.scm_instance, + org_ref, + other_repo.scm_instance, + other_ref, + discovery_data) + return cs_ranges, discovery_data