Changeset - 2b6939a77052
[Not reviewed]
beta
0 11 0
Marcin Kuzminski - 13 years ago 2012-08-04 01:20:38
marcin@python-works.com
Bumped mercurial version to 2.3
- fixed issues with compare of two remote repos at particular revisions
- added tests for cases when mercurial update broke code and tests didn't catch this
- removed obsolete EmptyChangeset from the rhodecode code
11 files changed with 183 insertions and 75 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/changeset.py
Show inline comments
 
@@ -40,7 +40,7 @@ from rhodecode.lib.vcs.nodes import File
 
import rhodecode.lib.helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.utils import EmptyChangeset, action_logger
 
from rhodecode.lib.utils import action_logger
 
from rhodecode.lib.compat import OrderedDict
 
from rhodecode.lib import diffs
 
from rhodecode.model.db import ChangesetComment, ChangesetStatus
 
@@ -50,6 +50,7 @@ from rhodecode.model.meta import Session
 
from rhodecode.lib.diffs import wrapped_diff
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 

	
 
log = logging.getLogger(__name__)
 

	
rhodecode/controllers/compare.py
Show inline comments
 
@@ -71,6 +71,7 @@ class CompareController(BaseRepoControll
 
            redirect(url('summary_home', repo_name=repo.repo_name))
 

	
 
        except RepositoryError, e:
 
            log.error(traceback.format_exc())
 
            h.flash(str(e), category='warning')
 
            redirect(h.url('summary_home', repo_name=repo.repo_name))
 

	
rhodecode/controllers/files.py
Show inline comments
 
@@ -40,7 +40,7 @@ from rhodecode.lib.compat import Ordered
 
from rhodecode.lib.utils2 import convert_line_endings, detect_mode, safe_str
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.utils import EmptyChangeset
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 
from rhodecode.lib.vcs.conf import settings
 
from rhodecode.lib.vcs.exceptions import RepositoryError, \
 
    ChangesetDoesNotExistError, EmptyRepositoryError, \
rhodecode/controllers/summary.py
Show inline comments
 
@@ -45,7 +45,7 @@ from rhodecode.model.db import Statistic
 
from rhodecode.lib.utils2 import safe_unicode
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.utils import EmptyChangeset
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 
from rhodecode.lib.markup_renderer import MarkupRenderer
 
from rhodecode.lib.celerylib import run_task
 
from rhodecode.lib.celerylib.tasks import get_commits_stats
rhodecode/lib/diffs.py
Show inline comments
 
@@ -34,15 +34,16 @@ from itertools import tee, imap
 
from mercurial import patch
 
from mercurial.mdiff import diffopts
 
from mercurial.bundlerepo import bundlerepository
 
from mercurial import localrepo
 

	
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.lib.compat import BytesIO
 
from rhodecode.lib.vcs.utils.hgcompat import localrepo
 
from rhodecode.lib.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 
from rhodecode.lib.helpers import escape
 
from rhodecode.lib.utils import EmptyChangeset, make_ui
 
from rhodecode.lib.utils import make_ui
 

	
 

	
 
def wrap_to_table(str_):
 
@@ -599,9 +600,9 @@ def differ(org_repo, org_ref, other_repo
 
    if org_repo != other_repo:
 

	
 
        common, incoming, rheads = discovery_data
 

	
 
        other_repo_peer = localrepo.locallegacypeer(other_repo.local())
 
        # create a bundle (uncompressed if other repo is not local)
 
        if other_repo.capable('getbundle') and incoming:
 
        if other_repo_peer.capable('getbundle') and incoming:
 
            # disable repo hooks here since it's just bundle !
 
            # patch and reset hooks section of UI config to not run any
 
            # hooks on fetching archives with subrepos
rhodecode/lib/utils.py
Show inline comments
 
@@ -346,50 +346,6 @@ def invalidate_cache(cache_key, *args):
 
        ScmModel().mark_for_invalidation(name)
 

	
 

	
 
class EmptyChangeset(BaseChangeset):
 
    """
 
    An dummy empty changeset. It's possible to pass hash when creating
 
    an EmptyChangeset
 
    """
 

	
 
    def __init__(self, cs='0' * 40, repo=None, requested_revision=None,
 
                 alias=None):
 
        self._empty_cs = cs
 
        self.revision = -1
 
        self.message = ''
 
        self.author = ''
 
        self.date = ''
 
        self.repository = repo
 
        self.requested_revision = requested_revision
 
        self.alias = alias
 

	
 
    @LazyProperty
 
    def raw_id(self):
 
        """
 
        Returns raw string identifying this changeset, useful for web
 
        representation.
 
        """
 

	
 
        return self._empty_cs
 

	
 
    @LazyProperty
 
    def branch(self):
 
        return get_backend(self.alias).DEFAULT_BRANCH_NAME
 

	
 
    @LazyProperty
 
    def short_id(self):
 
        return self.raw_id[:12]
 

	
 
    def get_file_changeset(self, path):
 
        return self
 

	
 
    def get_file_content(self, path):
 
        return u''
 

	
 
    def get_file_size(self, path):
 
        return 0
 

	
 

	
 
def map_groups(path):
 
    """
 
    Given a full path to a repository, create all nested groups that this
rhodecode/lib/utils2.py
Show inline comments
 
@@ -417,6 +417,7 @@ def get_changeset_safe(repo, rev):
 
    """
 
    from rhodecode.lib.vcs.backends.base import BaseRepository
 
    from rhodecode.lib.vcs.exceptions import RepositoryError
 
    from rhodecode.lib.vcs.backends.base import EmptyChangeset
 
    if not isinstance(repo, BaseRepository):
 
        raise Exception('You must pass an Repository '
 
                        'object as first argument got %s', type(repo))
 
@@ -424,7 +425,6 @@ def get_changeset_safe(repo, rev):
 
    try:
 
        cs = repo.get_changeset(rev)
 
    except RepositoryError:
 
        from rhodecode.lib.utils import EmptyChangeset
 
        cs = EmptyChangeset(requested_revision=rev)
 
    return cs
 

	
rhodecode/lib/vcs/utils/hgcompat.py
Show inline comments
 
@@ -13,3 +13,5 @@ from mercurial.mdiff import diffopts
 
from mercurial.node import hex
 
from mercurial.encoding import tolocal
 
from mercurial import discovery
 
from mercurial import localrepo
 
from mercurial import scmutil
 
\ No newline at end of file
rhodecode/model/pull_request.py
Show inline comments
 
@@ -36,7 +36,7 @@ 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
 
from rhodecode.lib.vcs.utils.hgcompat import discovery, localrepo, scmutil
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -150,13 +150,9 @@ class PullRequestModel(BaseModel):
 
        """
 
        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)
 
        common, incoming, rheads = discovery_data
 
        if org_repo != other_repo and incoming:
 
            revs = org_repo._repo.changelog.findmissing(common, rheads)
 

	
 
            for cs in reversed(map(binascii.hexlify, revs)):
 
                changesets.append(org_repo.get_changeset(cs))
 
@@ -175,7 +171,6 @@ class PullRequestModel(BaseModel):
 
               )
 
            ]
 

	
 
            from mercurial import scmutil
 
            out = scmutil.revrange(org_repo._repo, revs)
 
            for cs in reversed(out):
 
                changesets.append(org_repo.get_changeset(cs))
 
@@ -197,17 +192,22 @@ class PullRequestModel(BaseModel):
 
        :type other_ref:
 
        """
 

	
 
        other = org_repo._repo
 
        repo = other_repo._repo
 
        tip = other[org_ref[1]]
 
        _org_repo = org_repo._repo
 
        org_rev_type, org_rev = org_ref
 

	
 
        _other_repo = other_repo._repo
 
        other_rev_type, other_rev = other_ref
 

	
 
        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]))
 
        #log.debug('Filter heads are %s[%s]' % ('', org_ref[1]))
 
        org_peer = localrepo.locallegacypeer(_org_repo.local())
 
        tmp = discovery.findcommonincoming(
 
                  repo=repo,  # other_repo we check for incoming
 
                  remote=other,  # org_repo source for incoming
 
                  heads=[tip.node()],
 
                  repo=_other_repo,  # other_repo we check for incoming
 
                  remote=org_peer,  # org_repo source for incoming
 
                  heads=[_other_repo[other_rev].node(),
 
                         _org_repo[org_rev].node()],
 
                  force=False
 
        )
 
        return tmp
 
@@ -237,8 +237,9 @@ class PullRequestModel(BaseModel):
 
                                           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)
 
                                         org_ref,
 
                                         other_repo.scm_instance,
 
                                         other_ref,
 
                                         discovery_data)
 

	
 
        return cs_ranges, discovery_data
rhodecode/model/scm.py
Show inline comments
 
@@ -40,13 +40,14 @@ from rhodecode.lib.vcs import get_backen
 
from rhodecode.lib.vcs.exceptions import RepositoryError
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 

	
 
from rhodecode import BACKENDS
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.utils2 import safe_str, safe_unicode
 
from rhodecode.lib.auth import HasRepoPermissionAny, HasReposGroupPermissionAny
 
from rhodecode.lib.utils import get_repos as get_filesystem_repos, make_ui, \
 
    action_logger, EmptyChangeset, REMOVED_REPO_PAT
 
    action_logger, REMOVED_REPO_PAT
 
from rhodecode.model import BaseModel
 
from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \
 
    UserFollowing, UserLog, User, RepoGroup, PullRequest
 
@@ -414,6 +415,12 @@ class ScmModel(BaseModel):
 

	
 
    def commit_change(self, repo, repo_name, cs, user, author, message,
 
                      content, f_path):
 
        """
 
        Commits changes
 

	
 
        :param repo: SCM instance
 

	
 
        """
 

	
 
        if repo.alias == 'hg':
 
            from rhodecode.lib.vcs.backends.hg import \
 
@@ -439,6 +446,7 @@ class ScmModel(BaseModel):
 
        action = 'push_local:%s' % tip.raw_id
 
        action_logger(user, action, repo_name)
 
        self.mark_for_invalidation(repo_name)
 
        return tip
 

	
 
    def create_node(self, repo, repo_name, cs, user, author, message, content,
 
                      f_path):
 
@@ -477,6 +485,7 @@ class ScmModel(BaseModel):
 
        action = 'push_local:%s' % tip.raw_id
 
        action_logger(user, action, repo_name)
 
        self.mark_for_invalidation(repo_name)
 
        return tip
 

	
 
    def get_nodes(self, repo_name, revision, root_path='/', flat=True):
 
        """
rhodecode/tests/functional/test_compare.py
Show inline comments
 
from rhodecode.tests import *
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.model.meta import Session
 
from rhodecode.model.db import Repository
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 

	
 

	
 
class TestCompareController(TestController):
 

	
 
    def test_index_tag(self):
 
        self.log_user()
 
        tag1='0.1.3'
 
        tag2='0.1.2'
 
        tag1 = '0.1.3'
 
        tag2 = '0.1.2'
 
        response = self.app.get(url(controller='compare', action='index',
 
                                    repo_name=HG_REPO,
 
                                    org_ref_type="tag",
 
@@ -50,3 +55,135 @@ class TestCompareController(TestControll
 
        response.mustcontain('%s@default -> %s@default' % (HG_REPO, HG_REPO))
 
        # branch are equal
 
        response.mustcontain('<tr><td>No changesets</td></tr>')
 

	
 
    def test_compare_revisions(self):
 
        self.log_user()
 
        rev1 = '3d8f361e72ab'
 
        rev2 = 'b986218ba1c9'
 
        response = self.app.get(url(controller='compare', action='index',
 
                                    repo_name=HG_REPO,
 
                                    org_ref_type="rev",
 
                                    org_ref=rev1,
 
                                    other_ref_type="rev",
 
                                    other_ref=rev2,
 
                                    ))
 
        response.mustcontain('%s@%s -> %s@%s' % (HG_REPO, rev1, HG_REPO, rev2))
 
        ## outgoing changesets between those revisions
 
        response.mustcontain("""<a href="/%s/changeset/3d8f361e72ab303da48d799ff1ac40d5ac37c67e">r1:%s</a>""" % (HG_REPO, rev1))
 

	
 
        ## files
 
        response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--c8e92ef85cd1">.hgignore</a>""" % (HG_REPO, rev1, rev2))
 

	
 
    def test_compare_remote_repos(self):
 
        self.log_user()
 

	
 
        form_data = dict(
 
            repo_name=HG_FORK,
 
            repo_name_full=HG_FORK,
 
            repo_group=None,
 
            repo_type='hg',
 
            description='',
 
            private=False,
 
            copy_permissions=False,
 
            landing_rev='tip',
 
            update_after_clone=False,
 
            fork_parent_id=Repository.get_by_repo_name(HG_REPO),
 
        )
 
        RepoModel().create_fork(form_data, cur_user=TEST_USER_ADMIN_LOGIN)
 

	
 
        Session().commit()
 

	
 
        rev1 = '7d4bc8ec6be5'
 
        rev2 = '56349e29c2af'
 

	
 
        response = self.app.get(url(controller='compare', action='index',
 
                                    repo_name=HG_REPO,
 
                                    org_ref_type="rev",
 
                                    org_ref=rev1,
 
                                    other_ref_type="rev",
 
                                    other_ref=rev2,
 
                                    repo=HG_FORK
 
                                    ))
 

	
 
        try:
 
            response.mustcontain('%s@%s -> %s@%s' % (HG_REPO, rev1, HG_FORK, rev2))
 
            ## outgoing changesets between those revisions
 

	
 
            response.mustcontain("""<a href="/%s/changeset/7d4bc8ec6be56c0f10425afb40b6fc315a4c25e7">r6:%s</a>""" % (HG_REPO, rev1))
 
            response.mustcontain("""<a href="/%s/changeset/6fff84722075f1607a30f436523403845f84cd9e">r5:6fff84722075</a>""" % (HG_REPO))
 
            response.mustcontain("""<a href="/%s/changeset/2dda4e345facb0ccff1a191052dd1606dba6781d">r4:2dda4e345fac</a>""" % (HG_REPO))
 

	
 
            ## files
 
            response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--9c390eb52cd6">vcs/backends/hg.py</a>""" % (HG_REPO, rev1, rev2))
 
            response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--41b41c1f2796">vcs/backends/__init__.py</a>""" % (HG_REPO, rev1, rev2))
 
            response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--2f574d260608">vcs/backends/base.py</a>""" % (HG_REPO, rev1, rev2))
 
        finally:
 
            RepoModel().delete(HG_FORK)
 

	
 
    def test_compare_extra_commits(self):
 
        self.log_user()
 

	
 
        repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
 
                                        description='diff-test',
 
                                        owner=TEST_USER_ADMIN_LOGIN)
 

	
 
        repo2 = RepoModel().create_repo(repo_name='one-fork', repo_type='hg',
 
                                        description='diff-test',
 
                                        owner=TEST_USER_ADMIN_LOGIN)
 

	
 
        Session().commit()
 
        r1_id = repo1.repo_id
 
        r1_name = repo1.repo_name
 
        r2_id = repo2.repo_id
 
        r2_name = repo2.repo_name
 

	
 
        #commit something !
 
        cs0 = ScmModel().create_node(
 
            repo=repo1.scm_instance, repo_name=r1_name,
 
            cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
 
            author=TEST_USER_ADMIN_LOGIN,
 
            message='commit1',
 
            content='line1',
 
            f_path='file1'
 
        )
 

	
 
        cs0_prim = ScmModel().create_node(
 
            repo=repo2.scm_instance, repo_name=r2_name,
 
            cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
 
            author=TEST_USER_ADMIN_LOGIN,
 
            message='commit1',
 
            content='line1',
 
            f_path='file1'
 
        )
 

	
 
        cs1 = ScmModel().commit_change(
 
            repo=repo2.scm_instance, repo_name=r2_name,
 
            cs=cs0_prim, user=TEST_USER_ADMIN_LOGIN, author=TEST_USER_ADMIN_LOGIN,
 
            message='commit2',
 
            content='line1\nline2',
 
            f_path='file1'
 
        )
 

	
 
        rev1 = 'default'
 
        rev2 = 'default'
 
        response = self.app.get(url(controller='compare', action='index',
 
                                    repo_name=r2_name,
 
                                    org_ref_type="branch",
 
                                    org_ref=rev1,
 
                                    other_ref_type="branch",
 
                                    other_ref=rev2,
 
                                    repo=r1_name
 
                                    ))
 

	
 
        try:
 
            response.mustcontain('%s@%s -> %s@%s' % (r2_name, rev1, r1_name, rev2))
 

	
 
            response.mustcontain("""<div class="message">commit2</div>""")
 
            response.mustcontain("""<a href="/%s/changeset/%s">r1:%s</a>""" % (r2_name, cs1.raw_id, cs1.short_id))
 
            ## files
 
            response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s#C--826e8142e6ba">file1</a>""" % (r2_name, rev1, rev2))
 

	
 

	
 
        finally:
 
            RepoModel().delete(r1_id)
 
            RepoModel().delete(r2_id)
0 comments (0 inline, 0 general)