Changeset - ae5ac36cdf83
[Not reviewed]
beta
0 1 0
Mads Kiilerich - 13 years ago 2013-01-03 18:05:18
madski@unity3d.com
pull request: use unionrepo instead of outgoing

This makes it possible to look the 'moving target' symbols up in the right repo.

Using a revset with the right revisions also removes the need for pruning
changesets that are outside the requested range.

It will also not be confused by changesets that for some reason has been pulled
to the repo but haven't been merged yet. They are going to be 'merged' by the
'pull' request and should thus be a part of what is reviewed.
1 file changed with 11 insertions and 27 deletions:
0 comments (0 inline, 0 general)
rhodecode/model/pull_request.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.model.pull_request
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    pull request model for RhodeCode
 

	
 
    :created_on: Jun 6, 2012
 
    :author: marcink
 
    :copyright: (C) 2012-2012 Marcin Kuzminski <marcin@python-works.com>
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import logging
 
import binascii
 
import datetime
 
import re
 

	
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.model.meta import Session
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib import helpers as h, unionrepo
 
from rhodecode.model import BaseModel
 
from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification,\
 
    ChangesetStatus
 
from rhodecode.model.notification import NotificationModel
 
from rhodecode.lib.utils2 import safe_unicode
 

	
 
from rhodecode.lib.vcs.utils.hgcompat import discovery, localrepo, scmutil, \
 
    findcommonoutgoing
 
from rhodecode.lib.vcs.utils.hgcompat import scmutil
 
from rhodecode.lib.vcs.utils import safe_str
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class PullRequestModel(BaseModel):
 

	
 
    cls = PullRequest
 

	
 
    def __get_pull_request(self, pull_request):
 
        return self._get_instance(PullRequest, pull_request)
 

	
 
    def get_all(self, repo):
 
        repo = self._get_repo(repo)
 
        return PullRequest.query()\
 
                .filter(PullRequest.other_repo == repo)\
 
                .order_by(PullRequest.created_on)\
 
                .all()
 

	
 
    def create(self, created_by, org_repo, org_ref, other_repo, other_ref,
 
               revisions, reviewers, title, description=None):
 
        from rhodecode.model.changeset_status import ChangesetStatusModel
 

	
 
        created_by_user = self._get_user(created_by)
 
        org_repo = self._get_repo(org_repo)
 
        other_repo = self._get_repo(other_repo)
 

	
 
        new = PullRequest()
 
        new.org_repo = org_repo
 
        new.org_ref = org_ref
 
        new.other_repo = other_repo
 
        new.other_ref = other_ref
 
        new.revisions = revisions
 
        new.title = title
 
        new.description = description
 
        new.author = created_by_user
 
        self.sa.add(new)
 
        Session().flush()
 
        #members
 
        for member in reviewers:
 
            _usr = self._get_user(member)
 
            reviewer = PullRequestReviewers(_usr, new)
 
            self.sa.add(reviewer)
 

	
 
        #reset state to under-review
 
        ChangesetStatusModel().set_status(
 
            repo=org_repo,
 
            status=ChangesetStatus.STATUS_UNDER_REVIEW,
 
@@ -147,118 +145,104 @@ class PullRequestModel(BaseModel):
 
                    .filter(PullRequestReviewers.user_id==uid,
 
                            PullRequestReviewers.pull_request==pull_request)\
 
                    .scalar()
 
            if reviewer:
 
                self.sa.delete(reviewer)
 

	
 
    def delete(self, pull_request):
 
        pull_request = self.__get_pull_request(pull_request)
 
        Session().delete(pull_request)
 

	
 
    def close_pull_request(self, pull_request):
 
        pull_request = self.__get_pull_request(pull_request)
 
        pull_request.status = PullRequest.STATUS_CLOSED
 
        pull_request.updated_on = datetime.datetime.now()
 
        self.sa.add(pull_request)
 

	
 
    def _get_changesets(self, alias, org_repo, org_ref, other_repo, other_ref):
 
        """
 
        Returns a list of changesets that are incoming from org_repo@org_ref
 
        to other_repo@other_ref
 

	
 
        :param org_repo:
 
        :param org_ref:
 
        :param other_repo:
 
        :param other_ref:
 
        :param tmp:
 
        """
 

	
 
        changesets = []
 

	
 
        if alias == 'hg':
 
            # lookup up the exact node id
 
            _revset_predicates = {
 
                    'branch': 'branch',
 
                    'book': 'bookmark',
 
                    'tag': 'tag',
 
                    'rev': 'id',
 
                }
 
            org_rev_spec = "%s('%s')" % (_revset_predicates[org_ref[0]],
 
                                         safe_str(org_ref[1]))
 
            org_rev = scmutil.revsingle(org_repo._repo,
 
                                         org_rev_spec)
 
            other_rev_spec = "%s('%s')" % (_revset_predicates[other_ref[0]],
 
                                           safe_str(other_ref[1]))
 
            other_rev = scmutil.revsingle(other_repo._repo, other_rev_spec)
 

	
 
            #case two independent repos
 
            if org_repo != other_repo:
 
                revs = [
 
                    org_repo._repo.lookup(org_ref[1]),
 
                    org_repo._repo.lookup(other_ref[1]), # lookup up in the wrong repo!
 
                ]
 
    
 
                obj = findcommonoutgoing(org_repo._repo,
 
                            localrepo.locallegacypeer(other_repo._repo.local()),
 
                            revs,
 
                            force=True)
 
                revs = obj.missing
 
    
 
                for cs in map(binascii.hexlify, revs):
 
                    _cs = org_repo.get_changeset(cs)
 
                    changesets.append(_cs)
 
                # in case we have revisions filter out the ones not in given range
 
                if org_ref[0] == 'rev' and other_ref[0] == 'rev':
 
                    revs = [x.raw_id for x in changesets]
 
                    start = org_ref[1]
 
                    stop = other_ref[1]
 
                    changesets = changesets[revs.index(start):revs.index(stop) + 1]
 
                hgrepo = unionrepo.unionrepository(org_repo.baseui,
 
                                                   org_repo.path,
 
                                                   other_repo.path)
 
                revs = ["ancestors(id('%s')) and not ancestors(id('%s'))" %
 
                        (org_rev, other_rev)]
 

	
 
            #no remote compare do it on the same repository
 
            else:
 
                hgrepo = org_repo._repo
 
                revs = ["ancestors(id('%s')) and not ancestors(id('%s'))" %
 
                        (other_rev, org_rev)]
 
    
 
                out = scmutil.revrange(org_repo._repo, revs)
 
                for cs in (out):
 
                    changesets.append(org_repo.get_changeset(cs))
 
            out = scmutil.revrange(hgrepo, revs)
 
            for cs in (out):
 
                changesets.append(org_repo.get_changeset(cs))
 

	
 
        elif alias == 'git':
 
            assert org_repo == other_repo, (org_repo, other_repo) # no git support for different repos
 
            so, se = org_repo.run_git_command(
 
                'log --reverse --pretty="format: %%H" -s -p %s..%s' % (org_ref[1],
 
                                                                       other_ref[1])
 
            )
 
            ids = re.findall(r'[0-9a-fA-F]{40}', so)
 
            for cs in (ids):
 
                changesets.append(org_repo.get_changeset(cs))
 

	
 
        return changesets
 

	
 
    def get_compare_data(self, org_repo, org_ref, other_repo, other_ref):
 
        """
 
        Returns incoming changesets for mercurial repositories
 

	
 
        :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')
 

	
 
        org_repo_scm = org_repo.scm_instance
 
        other_repo_scm = other_repo.scm_instance
 

	
 
        alias = org_repo.scm_instance.alias
 
        cs_ranges = self._get_changesets(alias,
 
                                         org_repo_scm, org_ref,
 
                                         other_repo_scm, other_ref)
 
        return cs_ranges
0 comments (0 inline, 0 general)