Changeset - f8c953c6b040
[Not reviewed]
codereview
0 2 1
Marcin Kuzminski - 13 years ago 2012-05-25 18:29:31
marcin@python-works.com
Created base for diffing two repositories inside rhodecode
3 files changed with 159 insertions and 13 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/compare.py
Show inline comments
 
@@ -23,18 +23,21 @@
 
#
 
# 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 traceback
 

	
 
from webob.exc import HTTPNotFound
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 

	
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from webob.exc import HTTPNotFound
 
from rhodecode.lib import diffs
 

	
 
from rhodecode.model.db import Repository
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class CompareController(BaseRepoController):
 

	
 
@@ -44,13 +47,14 @@ class CompareController(BaseRepoControll
 
    def __before__(self):
 
        super(CompareController, self).__before__()
 

	
 
    def _handle_ref(self, ref):
 
        """
 
        Parse the org...other string
 
        Possible formats are `(branch|book|tag):<name>...(branch|book|tag):<othername>`
 
        Possible formats are 
 
            `(branch|book|tag):<name>...(branch|book|tag):<othername>`
 

	
 
        :param ref: <orginal_reference>...<other_reference>
 
        :type ref: str
 
        """
 
        org_repo = c.rhodecode_repo.name
 

	
 
@@ -61,13 +65,14 @@ class CompareController(BaseRepoControll
 

	
 
        def other_parser(other):
 
            _other_repo = request.GET.get('repo')
 
            _repo = org_repo
 
            name, val = other.split(':')
 
            if _other_repo:
 
                _repo = _other_repo #TODO: do an actual repo loookup within rhodecode
 
                #TODO: do an actual repo loookup within rhodecode
 
                _repo = _other_repo
 

	
 
            return _repo, (name, val)
 

	
 
        if '...' in ref:
 
            try:
 
                org, other = ref.split('...')
 
@@ -76,20 +81,50 @@ class CompareController(BaseRepoControll
 
                return org_repo, org_ref, other_repo, other_ref
 
            except:
 
                log.error(traceback.format_exc())
 

	
 
        raise HTTPNotFound
 

	
 
    def _get_changesets(self, org_repo, org_ref, other_repo, other_ref):
 
        changesets = []
 
        #case two independent repos
 
        if org_repo != other_repo:
 
            from mercurial import discovery
 
            import binascii
 
            out = discovery.findcommonoutgoing(org_repo._repo, other_repo._repo)
 
            for cs in map(binascii.hexlify, out.missing):
 
                changesets.append(org_repo.get_changeset(cs))
 
        else:
 
            for cs in map(binascii.hexlify, out):
 
                changesets.append(org_repo.get_changeset(cs))
 

	
 
        return changesets
 

	
 
    def index(self, ref):
 

	
 
        org_repo, org_ref, other_repo, other_ref = self._handle_ref(ref)
 
        return '''
 
        <pre>
 
        REPO: %s 
 
        REF: %s 
 

	
 
        c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
 
        c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
 

	
 
        c.cs_ranges = self._get_changesets(org_repo.scm_instance,
 
                                           org_ref,
 
                                           other_repo.scm_instance,
 
                                           other_ref)
 

	
 
        c.org_ref = org_ref[1]
 
        c.other_ref = other_ref[1]
 
        cs1 = org_repo.scm_instance.get_changeset(org_ref[1])
 
        cs2 = other_repo.scm_instance.get_changeset(other_ref[1])
 
        
 
        vs 
 
        _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref)
 
        diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
 

	
 
        diff = diff_processor.as_html(enable_comments=False)
 
        stats = diff_processor.stat()
 
        
 
        REPO: %s 
 
        REF: %s        
 
        </pre>
 
        ''' % (org_repo, org_ref, other_repo, other_ref)
 
        c.changes = [('change?', None, diff, cs1, cs2, stats,)]
 

	
 
        return render('compare/compare_diff.html')
 

	
 

	
 

	
 
        
rhodecode/lib/diffs.py
Show inline comments
 
@@ -519,6 +519,35 @@ class DiffProcessor(object):
 

	
 
    def stat(self):
 
        """
 
        Returns tuple of added, and removed lines for this instance
 
        """
 
        return self.adds, self.removes
 

	
 

	
 
def differ(org_repo, org_ref, 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:
 
    """
 
    ignore_whitespace = False
 
    context = 3
 
    from mercurial import patch
 
    from mercurial.mdiff import diffopts
 

	
 
    org_repo = org_repo.scm_instance._repo
 
    other_repo = other_repo.scm_instance._repo
 

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

	
 
    opts = diffopts(git=True, ignorews=ignore_whitespace, context=context)
 

	
 
    return ''.join(patch.diff(org_repo, node1=org_ref, node2=other_ref,
 
                              opts=opts))
rhodecode/templates/compare/compare_diff.html
Show inline comments
 
new file 100644
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    TODO FIll this in
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(u'Home',h.url('/'))}
 
    &raquo;
 
    ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
 
    &raquo;
 
    TODO! 
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('changelog')}
 
</%def>
 

	
 
<%def name="main()">
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <div class="table">
 
        <div id="body" class="diffblock">
 
            <div class="code-header cv">
 
                <h3 class="code-header-title">${_('Compare View')}</h3>
 
                <div>
 
                ${'%s@%s' % (c.org_repo.repo_name, c.org_ref)} -> ${'%s@%s' % (c.other_repo.repo_name, c.other_ref)}
 
                </div>
 
            </div>
 
        </div>
 
        <div id="changeset_compare_view_content">
 
            <div class="container">
 
            <table class="compare_view_commits noborder">
 
            %for cnt,cs in enumerate(c.cs_ranges):
 
                <tr>
 
                <td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(h.email(cs.author),14)}"/></div></td>
 
                <td>${h.link_to('r%s:%s' % (cs.revision,h.short_id(cs.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</td>
 
                <td><div class="author">${h.person(cs.author)}</div></td>
 
                <td><span class="tooltip" title="${h.age(cs.date)}">${cs.date}</span></td>
 
                <td>
 
                  %if hasattr(c,'statuses') and c.statuses:
 
                    <div title="${_('Changeset status')}" class="changeset-status-ico"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses[cnt])}" /></div>
 
                  %endif
 
                </td>
 
                <td><div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message),c.repo_name)}</div></td>
 
                </tr>
 
            %endfor
 
            </table>
 
            </div>
 
            <div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Files affected')}</div>
 
            <div class="cs_files">
 
              %for change,filenode,diff,cs1,cs2,st in c.changes[cs.raw_id]:
 
                  <div class="cs_${change}">${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=h.FID(cs.raw_id,filenode.path)))}</div>
 
              %endfor
 
            </div>
 
        </div>
 

	
 
    </div>
 

	
 
     <script type="text/javascript">
 

	
 
      YUE.onDOMReady(function(){
 

	
 
          YUE.on(YUQ('.diff-menu-activate'),'click',function(e){
 
              var act = e.currentTarget.nextElementSibling;
 

	
 
              if(YUD.hasClass(act,'active')){
 
                  YUD.removeClass(act,'active');
 
                  YUD.setStyle(act,'display','none');
 
              }else{
 
                  YUD.addClass(act,'active');
 
                  YUD.setStyle(act,'display','');
 
              }
 
          });
 
      })
 
    </script>
 
    </div>
 
</%def>
0 comments (0 inline, 0 general)