Changeset - a07296564f6b
[Not reviewed]
beta
0 3 0
Mads Kiilerich - 13 years ago 2013-02-01 23:13:10
madski@unity3d.com
compare: show aggregated diff of what will be merged to other repo, using merge ancestor

pull_request.get_compare_data will also now return the ancestor that would be
used for actual merging. Showing a diff from that ancestor instead of the first
'new' changeset will give a more realistic diff that doesn't include merges.
3 files changed with 27 insertions and 25 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/compare.py
Show inline comments
 
@@ -117,48 +117,46 @@ class CompareController(BaseRepoControll
 
            log.error('compare of two different kind of remote repos not available')
 
            raise HTTPNotFound
 

	
 
        partial = request.environ.get('HTTP_X_PARTIAL_XHR')
 
        self.__get_cs_or_redirect(rev=org_ref, repo=org_repo, partial=partial)
 
        self.__get_cs_or_redirect(rev=other_ref, repo=other_repo, partial=partial)
 

	
 
        if rev_start and rev_end:
 
            #replace our org_ref with given CS
 
            org_ref = ('rev', rev_start)
 
            other_ref = ('rev', rev_end)
 

	
 
        c.cs_ranges = PullRequestModel().get_compare_data(
 
                                    org_repo, org_ref, other_repo, other_ref,
 
                                    )
 
        c.cs_ranges, ancestor = 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])
 
        c.target_repo = c.other_repo.repo_name
 
        # defines that we need hidden inputs with changesets
 
        c.as_form = request.GET.get('as_form', False)
 
        if partial:
 
            return render('compare/compare_cs.html')
 

	
 
        c.org_ref = org_ref[1]
 
        c.other_ref = other_ref[1]
 

	
 
        if c.cs_ranges and c.org_repo != c.other_repo:
 
            # case we want a simple diff without incoming changesets, just
 
            # for review purposes. Make the diff on the forked repo, with
 
        if ancestor  and c.org_repo != c.other_repo:
 
            # case we want a simple diff without incoming changesets,
 
            # previewing what will be merged.
 
            # Make the diff on the forked repo, with
 
            # revision that is common ancestor
 
            _org_ref = org_ref
 
            org_ref = ('rev', getattr(c.cs_ranges[0].parents[0]
 
                                      if c.cs_ranges[0].parents
 
                                      else EmptyChangeset(), 'raw_id'))
 
            log.debug('Changed org_ref from %s to %s' % (_org_ref, org_ref))
 
            log.debug('Using ancestor %s as org_ref instead of %s', ancestor, _org_ref)
 
            org_ref = ('rev', ancestor)
 
            org_repo = other_repo
 

	
 
        diff_limit = self.cut_off_limit if not fulldiff else None
 

	
 
        _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref)
 

	
 
        diff_processor = diffs.DiffProcessor(_diff or '', format='gitdiff',
 
                                             diff_limit=diff_limit)
 
        _parsed = diff_processor.prepare()
 

	
 
        c.limited_diff = False
 
        if isinstance(_parsed, LimitedDiffContainer):
rhodecode/lib/diffs.py
Show inline comments
 
@@ -704,13 +704,13 @@ def differ(org_repo, org_ref, other_repo
 
    other_repo = other_repo_scm._repo
 

	
 
    org_ref = org_ref[1]
 
    other_ref = other_ref[1]
 

	
 
    if org_repo_scm == other_repo_scm:
 
        log.debug('running diff between %s@%s and %s@%s'
 
                  % (org_repo.path, org_ref, other_repo.path, other_ref))
 
        _diff = org_repo_scm.get_diff(rev1=org_ref, rev2=other_ref,
 
            ignore_whitespace=ignore_whitespace, context=context)
 
        return _diff
 

	
 
    return ''
 
    return '' # FIXME: when is it ever relevant to return nothing?
rhodecode/model/pull_request.py
Show inline comments
 
@@ -151,35 +151,35 @@ class PullRequestModel(BaseModel):
 
    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
 
        Returns a list of changesets that can be merged from org_repo@org_ref
 
        to other_repo@other_ref ... and the ancestor that would be used for merge
 

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

	
 
        changesets = []
 
        ancestor = None
 

	
 
        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,
 
@@ -193,39 +193,43 @@ class PullRequestModel(BaseModel):
 
                hgrepo = unionrepo.unionrepository(other_repo.baseui,
 
                                                   other_repo.path,
 
                                                   org_repo.path)
 
                # all the changesets we are looking for will be in other_repo,
 
                # so rev numbers from hgrepo can be used in other_repo
 

	
 
            #no remote compare do it on the same repository
 
            else:
 
                hgrepo = other_repo._repo
 

	
 
            revs = ["ancestors(id('%s')) and not ancestors(id('%s'))" %
 
                    (other_rev, org_rev)]
 
            out = scmutil.revrange(hgrepo, revs)
 
            for cs in (out):
 
                changesets.append(other_repo.get_changeset(cs))
 
            changesets = [other_repo.get_changeset(cs)
 
                          for cs in scmutil.revrange(hgrepo, revs)]
 

	
 
            if org_repo != other_repo:
 
                ancestors = scmutil.revrange(hgrepo,
 
                     ["ancestor(id('%s'), id('%s'))" % (org_rev, other_rev)])
 
                if len(ancestors) == 1:
 
                    ancestor = hgrepo[ancestors[0]].hex()
 

	
 
        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))
 
            changesets = [org_repo.get_changeset(cs)
 
                          for cs in re.findall(r'[0-9a-fA-F]{40}', so)]
 

	
 
        return changesets
 
        return changesets, ancestor
 

	
 
    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:
 
@@ -233,16 +237,16 @@ class PullRequestModel(BaseModel):
 
        """
 

	
 
        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
 
        cs_ranges, ancestor = self._get_changesets(alias,
 
                                                   org_repo_scm, org_ref,
 
                                                   other_repo_scm, other_ref)
 
        return cs_ranges, ancestor
0 comments (0 inline, 0 general)