##// END OF EJS Templates
added basic comparision of two repositories using bundles...
marcink -
r2355:29a80968 codereview
parent child Browse files
Show More
@@ -86,24 +86,30 b' class CompareController(BaseRepoControll'
86 86
87 87 raise HTTPNotFound
88 88
89 def _get_changesets(self, org_repo, org_ref, other_repo, other_ref):
90 changesets = []
91 #case two independent repos
92 if org_repo != other_repo:
89 def _get_discovery(self,org_repo, org_ref, other_repo, other_ref):
93 90 from mercurial import discovery
94 91 other = org_repo._repo
95 92 repo = other_repo._repo
96 onlyheads = None
97 tmp = discovery.findcommonincoming(repo=repo,
98 remote=other,
99 heads=onlyheads, force=False)
93 tmp = discovery.findcommonincoming(
94 repo=repo, # other_repo we check for incoming
95 remote=other, # org_repo source for incoming
96 heads=[other[org_ref[1]].node()],
97 force=False
98 )
99 return tmp
100
101 def _get_changesets(self, org_repo, org_ref, other_repo, other_ref, tmp):
102 changesets = []
103 #case two independent repos
104 if org_repo != other_repo:
100 105 common, incoming, rheads = tmp
106
101 107 if not incoming:
102 108 revs = []
103 109 else:
104 revs = other.changelog.findmissing(common, rheads)
110 revs = org_repo._repo.changelog.findmissing(common, rheads)
105 111
106 for cs in map(binascii.hexlify, revs):
112 for cs in reversed(map(binascii.hexlify, revs)):
107 113 changesets.append(org_repo.get_changeset(cs))
108 114 else:
109 115 revs = ['ancestors(%s) and not ancestors(%s)' % (org_ref[1],
@@ -117,21 +123,26 b' class CompareController(BaseRepoControll'
117 123
118 124 def index(self, ref):
119 125 org_repo, org_ref, other_repo, other_ref = self._handle_ref(ref)
120 c.swap_url = h.url('compare_home', repo_name=c.repo_name,
126 c.swap_url = h.url('compare_home', repo_name=other_repo,
121 127 ref='%s...%s' % (':'.join(other_ref),
122 ':'.join(org_ref)))
128 ':'.join(org_ref)),
129 repo=org_repo)
123 130 c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
124 131 c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
125
132 tmp = self._get_discovery(org_repo.scm_instance,
133 org_ref,
134 other_repo.scm_instance,
135 other_ref)
126 136 c.cs_ranges = self._get_changesets(org_repo.scm_instance,
127 137 org_ref,
128 138 other_repo.scm_instance,
129 other_ref)
139 other_ref,
140 tmp)
130 141
131 142 c.org_ref = org_ref[1]
132 143 c.other_ref = other_ref[1]
133 144 # diff needs to have swapped org with other to generate proper diff
134 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref)
145 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref, tmp)
135 146 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
136 147 _parsed = diff_processor.prepare()
137 148
@@ -26,16 +26,23 b''
26 26 # along with this program. If not, see <http://www.gnu.org/licenses/>.
27 27
28 28 import re
29 import io
29 30 import difflib
30 31 import markupsafe
32
31 33 from itertools import tee, imap
32 34
35 from mercurial import patch
36 from mercurial.mdiff import diffopts
37 from mercurial.bundlerepo import bundlerepository
38 from mercurial import localrepo
39
33 40 from pylons.i18n.translation import _
34 41
35 42 from rhodecode.lib.vcs.exceptions import VCSError
36 43 from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode
37 44 from rhodecode.lib.helpers import escape
38 from rhodecode.lib.utils import EmptyChangeset
45 from rhodecode.lib.utils import EmptyChangeset, make_ui
39 46
40 47
41 48 def wrap_to_table(str_):
@@ -534,7 +541,7 b' class DiffProcessor(object):'
534 541 return self.adds, self.removes
535 542
536 543
537 def differ(org_repo, org_ref, other_repo, other_ref):
544 def differ(org_repo, org_ref, other_repo, other_ref, discovery_data=None):
538 545 """
539 546 General differ between branches, bookmarks or separate but releated
540 547 repositories
@@ -548,18 +555,55 b' def differ(org_repo, org_ref, other_repo'
548 555 :param other_ref:
549 556 :type other_ref:
550 557 """
558
551 559 ignore_whitespace = False
552 560 context = 3
553 from mercurial import patch
554 from mercurial.mdiff import diffopts
555
556 561 org_repo = org_repo.scm_instance._repo
557 562 other_repo = other_repo.scm_instance._repo
558
563 opts = diffopts(git=True, ignorews=ignore_whitespace, context=context)
559 564 org_ref = org_ref[1]
560 565 other_ref = other_ref[1]
561 566
562 opts = diffopts(git=True, ignorews=ignore_whitespace, context=context)
567 if org_repo != other_repo:
568
569 common, incoming, rheads = discovery_data
570 # create a bundle (uncompressed if other repo is not local)
571 if other_repo.capable('getbundle'):
572 # disable repo hooks here since it's just bundle !
573 # patch and reset hooks section of UI config to not run any
574 # hooks on fetching archives with subrepos
575 for k, _ in other_repo.ui.configitems('hooks'):
576 other_repo.ui.setconfig('hooks', k, None)
577
578 unbundle = other_repo.getbundle('incoming', common=common,
579 heads=rheads)
580
581 buf = io.BytesIO()
582 while True:
583 chunk = unbundle._stream.read(1024*4)
584 if not chunk:
585 break
586 buf.write(chunk)
563 587
588 buf.seek(0)
589 unbundle._stream = buf
590
591 class InMemoryBundleRepo(bundlerepository):
592 def __init__(self, ui, path, bundlestream):
593 self._tempparent = None
594 localrepo.localrepository.__init__(self, ui, path)
595 self.ui.setconfig('phases', 'publish', False)
596
597 self.bundle = bundlestream
598
599 # dict with the mapping 'filename' -> position in the bundle
600 self.bundlefilespos = {}
601
602 ui = make_ui('db')
603 bundlerepo = InMemoryBundleRepo(ui, path=other_repo.root,
604 bundlestream=unbundle)
605 return ''.join(patch.diff(bundlerepo, node1=org_ref, node2=other_ref,
606 opts=opts))
607 else:
564 608 return ''.join(patch.diff(org_repo, node1=org_ref, node2=other_ref,
565 609 opts=opts))
General Comments 0
You need to be logged in to leave comments. Login now