Mercurial > kallithea
comparison rhodecode/lib/unionrepo.py @ 3407:6354556781ef beta
update unionrepo for Mercurial 2.5.1
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Wed, 27 Feb 2013 01:26:38 +0100 |
parents | ead7a902998c |
children | f3283898d431 |
comparison
equal
deleted
inserted
replaced
3406:4e9f00ddde4a | 3407:6354556781ef |
---|---|
1 # unionrepo.py - repository class for viewing union of repositories | 1 # unionrepo.py - repository class for viewing union of repository changesets |
2 # | 2 # |
3 # Derived from Mercurial 2.5 bundlerepo.py | 3 # Derived from bundlerepo.py |
4 # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com> | 4 # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com> |
5 # Copyright 2013 Unity Technologies, Mads Kiilerich <madski@unity3d.com> | 5 # Copyright 2013 Unity Technologies, Mads Kiilerich <madski@unity3d.com> |
6 # | 6 # |
7 # This software may be used and distributed according to the terms of the | 7 # This software may be used and distributed according to the terms of the |
8 # GNU General Public License version 2 or any later version. | 8 # GNU General Public License version 2 or any later version. |
9 | 9 |
10 """Repository class for in-memory pull of one local repository to another. | 10 """Repository class for "in-memory pull" of one local repository to another, |
11 allowing operations like diff and log with revsets. | |
11 """ | 12 """ |
12 | 13 |
14 import os | |
13 from mercurial.node import nullid | 15 from mercurial.node import nullid |
14 from mercurial import util, mdiff | 16 from mercurial.i18n import _ |
17 from mercurial import util, mdiff, cmdutil, scmutil | |
15 from mercurial import localrepo, changelog, manifest, filelog, revlog | 18 from mercurial import localrepo, changelog, manifest, filelog, revlog |
16 | 19 |
17 class unionrevlog(revlog.revlog): | 20 class unionrevlog(revlog.revlog): |
18 def __init__(self, opener, indexfile, revlog2, linkmapper): | 21 def __init__(self, opener, indexfile, revlog2, linkmapper): |
19 # How it works: | 22 # How it works: |
20 # To retrieve a revision, we just need to know the node id so we can | 23 # To retrieve a revision, we just need to know the node id so we can |
21 # look it up in revlog2. | 24 # look it up in revlog2. |
22 # | 25 # |
23 # basemap is indexed with revisions coming from the second revlog. | |
24 # | |
25 # To differentiate a rev in the second revlog from a rev in the revlog, | 26 # To differentiate a rev in the second revlog from a rev in the revlog, |
26 # we check revision against basemap. | 27 # we check revision against repotiprev. |
28 opener = scmutil.readonlyvfs(opener) | |
27 revlog.revlog.__init__(self, opener, indexfile) | 29 revlog.revlog.__init__(self, opener, indexfile) |
28 self.revlog2 = revlog2 | 30 self.revlog2 = revlog2 |
29 | 31 |
30 self.basemap = {} # mapping rev that is in revlog2 to ... nothing | |
31 n = len(self) | 32 n = len(self) |
33 self.repotiprev = n - 1 | |
32 self.bundlerevs = set() # used by 'bundle()' revset expression | 34 self.bundlerevs = set() # used by 'bundle()' revset expression |
33 for rev2 in self.revlog2: | 35 for rev2 in self.revlog2: |
34 rev = self.revlog2.index[rev2] | 36 rev = self.revlog2.index[rev2] |
35 # rev numbers - in revlog2, very different from self.rev | 37 # rev numbers - in revlog2, very different from self.rev |
36 _start, _csize, _rsize, _base, linkrev, p1rev, p2rev, node = rev | 38 _start, _csize, _rsize, _base, linkrev, p1rev, p2rev, node = rev |
40 link = n | 42 link = n |
41 else: # rev must be mapped from repo2 cl to unified cl by linkmapper | 43 else: # rev must be mapped from repo2 cl to unified cl by linkmapper |
42 link = linkmapper(linkrev) | 44 link = linkmapper(linkrev) |
43 | 45 |
44 if node in self.nodemap: | 46 if node in self.nodemap: |
45 # this happens for for the common revlog revisions | 47 # this happens for the common revlog revisions |
46 self.bundlerevs.add(self.nodemap[node]) | 48 self.bundlerevs.add(self.nodemap[node]) |
47 continue | 49 continue |
48 | 50 |
49 p1node = self.revlog2.node(p1rev) | 51 p1node = self.revlog2.node(p1rev) |
50 p2node = self.revlog2.node(p2rev) | 52 p2node = self.revlog2.node(p2rev) |
51 | 53 |
52 e = (None, None, None, None, | 54 e = (None, None, None, None, |
53 link, self.rev(p1node), self.rev(p2node), node) | 55 link, self.rev(p1node), self.rev(p2node), node) |
54 self.basemap[n] = None | |
55 self.index.insert(-1, e) | 56 self.index.insert(-1, e) |
56 self.nodemap[node] = n | 57 self.nodemap[node] = n |
57 self.bundlerevs.add(n) | 58 self.bundlerevs.add(n) |
58 n += 1 | 59 n += 1 |
59 | 60 |
60 def _chunk(self, rev): | 61 def _chunk(self, rev): |
61 if rev not in self.basemap: | 62 if rev <= self.repotiprev: |
62 return revlog.revlog._chunk(self, rev) | 63 return revlog.revlog._chunk(self, rev) |
63 return self.revlog2._chunk(self.node(rev)) | 64 return self.revlog2._chunk(self.node(rev)) |
64 | 65 |
65 def revdiff(self, rev1, rev2): | 66 def revdiff(self, rev1, rev2): |
66 """return or calculate a delta between two revisions""" | 67 """return or calculate a delta between two revisions""" |
67 if rev1 in self.basemap and rev2 in self.basemap: | 68 if rev1 > self.repotiprev and rev2 > self.repotiprev: |
68 return self.revlog2.revdiff( | 69 return self.revlog2.revdiff( |
69 self.revlog2.rev(self.node(rev1)), | 70 self.revlog2.rev(self.node(rev1)), |
70 self.revlog2.rev(self.node(rev2))) | 71 self.revlog2.rev(self.node(rev2))) |
71 elif rev1 not in self.basemap and rev2 not in self.basemap: | 72 elif rev1 <= self.repotiprev and rev2 <= self.repotiprev: |
72 return revlog.revlog.revdiff(self, rev1, rev2) | 73 return revlog.revlog.revdiff(self, rev1, rev2) |
73 | 74 |
74 return mdiff.textdiff(self.revision(self.node(rev1)), | 75 return mdiff.textdiff(self.revision(self.node(rev1)), |
75 self.revision(self.node(rev2))) | 76 self.revision(self.node(rev2))) |
76 | 77 |
86 rev = self.rev(node) | 87 rev = self.rev(node) |
87 | 88 |
88 if node == nullid: | 89 if node == nullid: |
89 return "" | 90 return "" |
90 | 91 |
91 if rev in self.basemap: | 92 if rev > self.repotiprev: |
92 text = self.revlog2.revision(node) | 93 text = self.revlog2.revision(node) |
93 self._cache = (node, rev, text) | 94 self._cache = (node, rev, text) |
94 else: | 95 else: |
95 text = revlog.revlog.revision(self, rev) | 96 text = revlog.revlog.revision(self, rev) |
96 # already cached | 97 # already cached |
142 | 143 |
143 self._url = 'union:%s+%s' % (util.expandpath(path), | 144 self._url = 'union:%s+%s' % (util.expandpath(path), |
144 util.expandpath(path2)) | 145 util.expandpath(path2)) |
145 self.repo2 = localrepo.localrepository(ui, path2) | 146 self.repo2 = localrepo.localrepository(ui, path2) |
146 | 147 |
147 @util.propertycache | 148 @localrepo.unfilteredpropertycache |
148 def changelog(self): | 149 def changelog(self): |
149 return unionchangelog(self.sopener, self.repo2.sopener) | 150 return unionchangelog(self.sopener, self.repo2.sopener) |
150 | 151 |
151 def _clrev(self, rev2): | 152 def _clrev(self, rev2): |
152 """map from repo2 changelog rev to temporary rev in self.changelog""" | 153 """map from repo2 changelog rev to temporary rev in self.changelog""" |
153 node = self.repo2.changelog.node(rev2) | 154 node = self.repo2.changelog.node(rev2) |
154 return self.changelog.rev(node) | 155 return self.changelog.rev(node) |
155 | 156 |
156 @util.propertycache | 157 @localrepo.unfilteredpropertycache |
157 def manifest(self): | 158 def manifest(self): |
158 return unionmanifest(self.sopener, self.repo2.sopener, | 159 return unionmanifest(self.sopener, self.repo2.sopener, |
159 self._clrev) | 160 self._clrev) |
160 | 161 |
161 def url(self): | 162 def url(self): |
172 return False | 173 return False |
173 | 174 |
174 def peer(self): | 175 def peer(self): |
175 return unionpeer(self) | 176 return unionpeer(self) |
176 | 177 |
178 def getcwd(self): | |
179 return os.getcwd() # always outside the repo | |
180 | |
177 def instance(ui, path, create): | 181 def instance(ui, path, create): |
178 u = util.url(path) | 182 if create: |
179 assert u.scheme == 'union' | 183 raise util.Abort(_('cannot create new union repository')) |
180 repopath, repopath2 = u.path.split("+", 1) | 184 parentpath = ui.config("bundle", "mainreporoot", "") |
185 if not parentpath: | |
186 # try to find the correct path to the working directory repo | |
187 parentpath = cmdutil.findrepo(os.getcwd()) | |
188 if parentpath is None: | |
189 parentpath = '' | |
190 if parentpath: | |
191 # Try to make the full path relative so we get a nice, short URL. | |
192 # In particular, we don't want temp dir names in test outputs. | |
193 cwd = os.getcwd() | |
194 if parentpath == cwd: | |
195 parentpath = '' | |
196 else: | |
197 cwd = os.path.join(cwd,'') | |
198 if parentpath.startswith(cwd): | |
199 parentpath = parentpath[len(cwd):] | |
200 if path.startswith('union:'): | |
201 s = path.split(":", 1)[1].split("+", 1) | |
202 if len(s) == 1: | |
203 repopath, repopath2 = parentpath, s[0] | |
204 else: | |
205 repopath, repopath2 = s | |
206 else: | |
207 repopath, repopath2 = parentpath, path | |
181 return unionrepository(ui, repopath, repopath2) | 208 return unionrepository(ui, repopath, repopath2) |