Mercurial > hg-git
annotate hggit/overlay.py @ 597:3964de9961ec
overlaymanifest: add iteritems(), used by recent hg versions
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Wed, 03 Apr 2013 14:37:13 -0500 |
parents | a24c2f90a3dd |
children | bf8518b09d57 |
rev | line source |
---|---|
408 | 1 # overlay classes for repositories |
2 # unifies access to unimported git objects and committed hg objects | |
3 # designed to support incoming | |
4 # | |
5 # incomplete, implemented on demand | |
6 | |
7 from mercurial import context | |
8 from mercurial.node import bin, hex, nullid | |
9 | |
10 class overlaymanifest(object): | |
11 def __init__(self, repo, sha): | |
12 self.repo = repo | |
13 self.tree = repo.handler.git.get_object(sha) | |
14 self._map = None | |
15 self._flagmap = None | |
16 | |
466
ac16efd25cc4
overlaymanifest: add the withflags method introduced in hg change a1dcd842ce17
Augie Fackler <raf@durin42.com>
parents:
423
diff
changeset
|
17 def withflags(self): |
ac16efd25cc4
overlaymanifest: add the withflags method introduced in hg change a1dcd842ce17
Augie Fackler <raf@durin42.com>
parents:
423
diff
changeset
|
18 self.load() |
ac16efd25cc4
overlaymanifest: add the withflags method introduced in hg change a1dcd842ce17
Augie Fackler <raf@durin42.com>
parents:
423
diff
changeset
|
19 return set([path for path, flag in self._flagmap.iteritems() |
ac16efd25cc4
overlaymanifest: add the withflags method introduced in hg change a1dcd842ce17
Augie Fackler <raf@durin42.com>
parents:
423
diff
changeset
|
20 if flag & 020100]) |
ac16efd25cc4
overlaymanifest: add the withflags method introduced in hg change a1dcd842ce17
Augie Fackler <raf@durin42.com>
parents:
423
diff
changeset
|
21 |
408 | 22 def copy(self): |
23 return overlaymanifest(self.repo, self.tree.id) | |
24 | |
25 def keys(self): | |
26 self.load() | |
27 return self._map.keys() | |
28 | |
29 def flags(self, path): | |
30 self.load() | |
31 | |
32 def hgflag(gitflag): | |
33 if gitflag & 0100: | |
34 return 'x' | |
35 elif gitflag & 020000: | |
36 return 'l' | |
37 else: | |
38 return '' | |
39 | |
40 return hgflag(self._flagmap[path]) | |
41 | |
42 def load(self): | |
43 if self._map is not None: | |
44 return | |
45 | |
46 self._map = {} | |
47 self._flagmap = {} | |
48 | |
49 def addtree(tree, dirname): | |
423
f29401590803
overlay: stop using deprecated tree.entries() method
Augie Fackler <durin42@gmail.com>
parents:
408
diff
changeset
|
50 for entry in tree.iteritems(): |
f29401590803
overlay: stop using deprecated tree.entries() method
Augie Fackler <durin42@gmail.com>
parents:
408
diff
changeset
|
51 if entry.mode & 040000: |
408 | 52 # expand directory |
423
f29401590803
overlay: stop using deprecated tree.entries() method
Augie Fackler <durin42@gmail.com>
parents:
408
diff
changeset
|
53 subtree = self.repo.handler.git.get_object(entry.sha) |
f29401590803
overlay: stop using deprecated tree.entries() method
Augie Fackler <durin42@gmail.com>
parents:
408
diff
changeset
|
54 addtree(subtree, dirname + entry.path + '/') |
408 | 55 else: |
423
f29401590803
overlay: stop using deprecated tree.entries() method
Augie Fackler <durin42@gmail.com>
parents:
408
diff
changeset
|
56 path = dirname + entry.path |
f29401590803
overlay: stop using deprecated tree.entries() method
Augie Fackler <durin42@gmail.com>
parents:
408
diff
changeset
|
57 self._map[path] = bin(entry.sha) |
f29401590803
overlay: stop using deprecated tree.entries() method
Augie Fackler <durin42@gmail.com>
parents:
408
diff
changeset
|
58 self._flagmap[path] = entry.mode |
408 | 59 |
60 addtree(self.tree, '') | |
61 | |
597
3964de9961ec
overlaymanifest: add iteritems(), used by recent hg versions
Augie Fackler <raf@durin42.com>
parents:
570
diff
changeset
|
62 def iteritems(self): |
3964de9961ec
overlaymanifest: add iteritems(), used by recent hg versions
Augie Fackler <raf@durin42.com>
parents:
570
diff
changeset
|
63 self.load() |
3964de9961ec
overlaymanifest: add iteritems(), used by recent hg versions
Augie Fackler <raf@durin42.com>
parents:
570
diff
changeset
|
64 return self._map.iteritems() |
3964de9961ec
overlaymanifest: add iteritems(), used by recent hg versions
Augie Fackler <raf@durin42.com>
parents:
570
diff
changeset
|
65 |
408 | 66 def __iter__(self): |
67 self.load() | |
68 return self._map.__iter__() | |
69 | |
70 def __getitem__(self, path): | |
71 self.load() | |
72 return self._map[path] | |
73 | |
74 def __delitem__(self, path): | |
75 del self._map[path] | |
76 | |
77 class overlayfilectx(object): | |
78 def __init__(self, repo, path, fileid=None): | |
79 self.repo = repo | |
80 self._path = path | |
81 self.fileid = fileid | |
82 | |
83 # this is a hack to skip copy detection | |
84 def ancestors(self): | |
85 return [self, self] | |
86 | |
87 def rev(self): | |
88 return -1 | |
89 | |
90 def path(self): | |
91 return self._path | |
92 | |
93 def filelog(self): | |
94 return self.fileid | |
95 | |
96 def data(self): | |
97 blob = self.repo.handler.git.get_object(self.fileid) | |
98 return blob.data | |
99 | |
100 class overlaychangectx(context.changectx): | |
101 def __init__(self, repo, sha): | |
102 self.repo = repo | |
103 self.commit = repo.handler.git.get_object(sha) | |
104 | |
105 def node(self): | |
106 return bin(self.commit.id) | |
107 | |
108 def rev(self): | |
109 return self.repo.rev(bin(self.commit.id)) | |
110 | |
111 def date(self): | |
112 return self.commit.author_time, self.commit.author_timezone | |
113 | |
114 def branch(self): | |
115 return 'default' | |
116 | |
117 def user(self): | |
118 return self.commit.author | |
119 | |
120 def files(self): | |
121 return [] | |
122 | |
123 def extra(self): | |
124 return {} | |
125 | |
126 def description(self): | |
127 return self.commit.message | |
128 | |
129 def parents(self): | |
130 return [overlaychangectx(self.repo, sha) for sha in self.commit.parents] | |
131 | |
132 def manifestnode(self): | |
133 return bin(self.commit.tree) | |
134 | |
135 def hex(self): | |
136 return self.commit.id | |
137 | |
138 def tags(self): | |
139 return [] | |
140 | |
141 def bookmarks(self): | |
142 return [] | |
143 | |
144 def manifest(self): | |
145 return overlaymanifest(self.repo, self.commit.tree) | |
146 | |
147 def filectx(self, path, filelog=None): | |
148 mf = self.manifest() | |
149 return overlayfilectx(self.repo, path, mf[path]) | |
150 | |
151 def flags(self, path): | |
152 mf = self.manifest() | |
153 return mf.flags(path) | |
154 | |
155 def __nonzero__(self): | |
156 return True | |
157 | |
568
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
158 def phase(self): |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
159 try: |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
160 from mercurial import phases |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
161 return phases.draft |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
162 except ImportError: |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
163 return 1 |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
164 |
408 | 165 class overlayrevlog(object): |
166 def __init__(self, repo, base): | |
167 self.repo = repo | |
168 self.base = base | |
169 | |
170 def parents(self, n): | |
171 gitrev = self.repo.revmap.get(n) | |
172 if not gitrev: | |
173 # we've reached a revision we have | |
174 return self.base.parents(n) | |
175 commit = self.repo.handler.git.get_object(n) | |
176 | |
177 def gitorhg(n): | |
178 hn = self.repo.handler.map_hg_get(hex(n)) | |
179 if hn is not None: | |
180 return bin(hn) | |
181 return n | |
182 | |
183 # currently ignores the octopus | |
184 p1 = gitorhg(bin(commit.parents[0])) | |
185 if len(commit.parents) > 1: | |
186 p2 = gitorhg(bin(commit.parents[1])) | |
187 else: | |
188 p2 = nullid | |
189 | |
190 return [p1, p2] | |
191 | |
192 def parentrevs(self, rev): | |
193 return [self.rev(p) for p in self.parents(self.node(rev))] | |
194 | |
195 def node(self, rev): | |
196 gitnode = self.repo.nodemap.get(rev) | |
197 if gitnode is None: | |
198 return self.base.node(rev) | |
199 return gitnode | |
200 | |
201 def rev(self, n): | |
202 gitrev = self.repo.revmap.get(n) | |
203 if gitrev is None: | |
204 return self.base.rev(n) | |
205 return gitrev | |
206 | |
207 def nodesbetween(self, nodelist, revs): | |
208 # this is called by pre-1.9 incoming with the nodelist we returned from | |
209 # getremotechanges. Just return it back. | |
210 return [nodelist] | |
211 | |
212 def __len__(self): | |
213 return len(self.repo.handler.repo) + len(self.repo.revmap) | |
214 | |
215 | |
216 class overlayrepo(object): | |
217 def __init__(self, handler, commits, refs): | |
218 self.handler = handler | |
219 | |
220 self.changelog = overlayrevlog(self, handler.repo.changelog) | |
221 self.manifest = overlayrevlog(self, handler.repo.manifest) | |
222 | |
223 # for incoming -p | |
224 self.root = handler.repo.root | |
225 self.getcwd = handler.repo.getcwd | |
226 self.status = handler.repo.status | |
227 self.ui = handler.repo.ui | |
228 | |
229 self.revmap = None | |
230 self.nodemap = None | |
231 self.refmap = None | |
232 self.tagmap = None | |
233 | |
234 self._makemaps(commits, refs) | |
235 | |
236 def __getitem__(self, n): | |
237 if n not in self.revmap: | |
238 return self.handler.repo[n] | |
239 return overlaychangectx(self, n) | |
240 | |
557
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
241 def node(self, n): |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
242 """Returns an Hg or Git hash for the specified Git hash""" |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
243 if bin(n) in self.revmap: |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
244 return n |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
245 return self.handler.map_hg_get(n) |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
246 |
408 | 247 def nodebookmarks(self, n): |
248 return self.refmap.get(n, []) | |
249 | |
250 def nodetags(self, n): | |
251 return self.tagmap.get(n, []) | |
252 | |
253 def rev(self, n): | |
254 return self.revmap[n] | |
255 | |
256 def filectx(self, path, fileid=None): | |
257 return overlayfilectx(self, path, fileid=fileid) | |
258 | |
259 def _makemaps(self, commits, refs): | |
260 baserev = self.handler.repo['tip'].rev() | |
261 self.revmap = {} | |
262 self.nodemap = {} | |
263 for i, n in enumerate(commits): | |
264 rev = baserev + i + 1 | |
265 self.revmap[n] = rev | |
266 self.nodemap[rev] = n | |
267 | |
268 self.refmap = {} | |
269 self.tagmap = {} | |
270 for ref in refs: | |
271 if ref.startswith('refs/heads/'): | |
272 refname = ref[11:] | |
273 self.refmap.setdefault(bin(refs[ref]), []).append(refname) | |
274 elif ref.startswith('refs/tags/'): | |
275 tagname = ref[10:] | |
276 self.tagmap.setdefault(bin(refs[ref]), []).append(tagname) |