Changeset - 29a8096820dc
[Not reviewed]
codereview
0 2 0
Marcin Kuzminski - 13 years ago 2012-05-28 23:21:43
marcin@python-works.com
added basic comparision of two repositories using bundles
and hg incomming
2 files changed with 79 insertions and 24 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/compare.py
Show inline comments
 
@@ -86,24 +86,30 @@ class CompareController(BaseRepoControll
 

	
 
        raise HTTPNotFound
 

	
 
    def _get_changesets(self, org_repo, org_ref, other_repo, other_ref):
 
    def _get_discovery(self,org_repo, org_ref, other_repo, other_ref):
 
        from mercurial import discovery
 
        other = org_repo._repo
 
        repo = other_repo._repo
 
        tmp = discovery.findcommonincoming(
 
                  repo=repo,  # other_repo we check for incoming
 
                  remote=other,  # org_repo source for incoming
 
                  heads=[other[org_ref[1]].node()],
 
                  force=False
 
        )
 
        return tmp
 

	
 
    def _get_changesets(self, org_repo, org_ref, other_repo, other_ref, tmp):
 
        changesets = []
 
        #case two independent repos
 
        if org_repo != other_repo:
 
            from mercurial import discovery
 
            other = org_repo._repo
 
            repo = other_repo._repo
 
            onlyheads = None
 
            tmp = discovery.findcommonincoming(repo=repo,
 
                                               remote=other,
 
                                               heads=onlyheads, force=False)
 
            common, incoming, rheads = tmp
 

	
 
            if not incoming:
 
                revs = []
 
            else:
 
                revs = other.changelog.findmissing(common, rheads)
 
                revs = org_repo._repo.changelog.findmissing(common, rheads)
 

	
 
            for cs in map(binascii.hexlify, revs):
 
            for cs in reversed(map(binascii.hexlify, revs)):
 
                changesets.append(org_repo.get_changeset(cs))
 
        else:
 
            revs = ['ancestors(%s) and not ancestors(%s)' % (org_ref[1],
 
@@ -117,21 +123,26 @@ class CompareController(BaseRepoControll
 

	
 
    def index(self, ref):
 
        org_repo, org_ref, other_repo, other_ref = self._handle_ref(ref)
 
        c.swap_url = h.url('compare_home', repo_name=c.repo_name,
 
        c.swap_url = h.url('compare_home', repo_name=other_repo,
 
                           ref='%s...%s' % (':'.join(other_ref),
 
                                            ':'.join(org_ref)))
 
                                            ':'.join(org_ref)),
 
                           repo=org_repo)
 
        c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
 
        c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
 

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

	
 
        c.org_ref = org_ref[1]
 
        c.other_ref = other_ref[1]
 
        # diff needs to have swapped org with other to generate proper diff
 
        _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref)
 
        _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref, tmp)
 
        diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
 
        _parsed = diff_processor.prepare()
 

	
rhodecode/lib/diffs.py
Show inline comments
 
@@ -26,16 +26,23 @@
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import re
 
import io
 
import difflib
 
import markupsafe
 

	
 
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.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode
 
from rhodecode.lib.helpers import escape
 
from rhodecode.lib.utils import EmptyChangeset
 
from rhodecode.lib.utils import EmptyChangeset, make_ui
 

	
 

	
 
def wrap_to_table(str_):
 
@@ -534,7 +541,7 @@ class DiffProcessor(object):
 
        return self.adds, self.removes
 

	
 

	
 
def differ(org_repo, org_ref, other_repo, other_ref):
 
def differ(org_repo, org_ref, other_repo, other_ref, discovery_data=None):
 
    """
 
    General differ between branches, bookmarks or separate but releated 
 
    repositories
 
@@ -548,18 +555,55 @@ def differ(org_repo, org_ref, 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
 

	
 
    opts = diffopts(git=True, ignorews=ignore_whitespace, context=context)
 
    org_ref = org_ref[1]
 
    other_ref = other_ref[1]
 

	
 
    opts = diffopts(git=True, ignorews=ignore_whitespace, context=context)
 
    if org_repo != other_repo:
 

	
 
        common, incoming, rheads = discovery_data
 
        # create a bundle (uncompressed if other repo is not local)
 
        if other_repo.capable('getbundle'):
 
            # 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
 
            for k, _ in other_repo.ui.configitems('hooks'):
 
                other_repo.ui.setconfig('hooks', k, None)
 

	
 
            unbundle = other_repo.getbundle('incoming', common=common,
 
                                            heads=rheads)
 

	
 
            buf = io.BytesIO()
 
            while True:
 
                chunk = unbundle._stream.read(1024*4)
 
                if not chunk:
 
                    break
 
                buf.write(chunk)
 

	
 
    return ''.join(patch.diff(org_repo, node1=org_ref, node2=other_ref,
 
                              opts=opts))
 
            buf.seek(0)
 
            unbundle._stream = buf
 

	
 
        class InMemoryBundleRepo(bundlerepository):
 
            def __init__(self, ui, path, bundlestream):
 
                self._tempparent = None
 
                localrepo.localrepository.__init__(self, ui, path)
 
                self.ui.setconfig('phases', 'publish', False)
 

	
 
                self.bundle = bundlestream
 

	
 
                # dict with the mapping 'filename' -> position in the bundle
 
                self.bundlefilespos = {}
 

	
 
        ui = make_ui('db')
 
        bundlerepo = InMemoryBundleRepo(ui, path=other_repo.root,
 
                                        bundlestream=unbundle)
 
        return ''.join(patch.diff(bundlerepo, node1=org_ref, node2=other_ref,
 
                                  opts=opts))
 
    else:
 
        return ''.join(patch.diff(org_repo, node1=org_ref, node2=other_ref,
 
                                  opts=opts))
0 comments (0 inline, 0 general)