changeset 2337:f8c953c6b040 codereview

Created base for diffing two repositories inside rhodecode
author Marcin Kuzminski <marcin@python-works.com>
date Fri, 25 May 2012 18:29:31 +0200
parents aa2f0e4382e9
children 8fe7c1024719
files rhodecode/controllers/compare.py rhodecode/lib/diffs.py rhodecode/templates/compare/compare_diff.html
diffstat 3 files changed, 160 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/compare.py	Thu May 24 23:19:17 2012 +0200
+++ b/rhodecode/controllers/compare.py	Fri May 25 18:29:31 2012 +0200
@@ -26,12 +26,15 @@
 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__)
 
@@ -47,7 +50,8 @@
     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
@@ -64,7 +68,8 @@
             _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)
 
@@ -79,17 +84,47 @@
 
         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])
+
+        _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()
+
+        c.changes = [('change?', None, diff, cs1, cs2, stats,)]
+
+        return render('compare/compare_diff.html')
+
+
+
         
-        vs 
-        
-        REPO: %s 
-        REF: %s        
-        </pre>
-        ''' % (org_repo, org_ref, other_repo, other_ref)
--- a/rhodecode/lib/diffs.py	Thu May 24 23:19:17 2012 +0200
+++ b/rhodecode/lib/diffs.py	Fri May 25 18:29:31 2012 +0200
@@ -522,3 +522,32 @@
         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))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/templates/compare/compare_diff.html	Fri May 25 18:29:31 2012 +0200
@@ -0,0 +1,82 @@
+## -*- 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>