Mercurial > hg-git
annotate hggit/overlay.py @ 570:a24c2f90a3dd
Merge obsolete marker fix.
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Mon, 29 Oct 2012 21:34:37 -0500 |
parents | 4f4ab2d89375 41f6e3df67b1 |
children | 3964de9961ec |
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 | |
62 def __iter__(self): | |
63 self.load() | |
64 return self._map.__iter__() | |
65 | |
66 def __getitem__(self, path): | |
67 self.load() | |
68 return self._map[path] | |
69 | |
70 def __delitem__(self, path): | |
71 del self._map[path] | |
72 | |
73 class overlayfilectx(object): | |
74 def __init__(self, repo, path, fileid=None): | |
75 self.repo = repo | |
76 self._path = path | |
77 self.fileid = fileid | |
78 | |
79 # this is a hack to skip copy detection | |
80 def ancestors(self): | |
81 return [self, self] | |
82 | |
83 def rev(self): | |
84 return -1 | |
85 | |
86 def path(self): | |
87 return self._path | |
88 | |
89 def filelog(self): | |
90 return self.fileid | |
91 | |
92 def data(self): | |
93 blob = self.repo.handler.git.get_object(self.fileid) | |
94 return blob.data | |
95 | |
96 class overlaychangectx(context.changectx): | |
97 def __init__(self, repo, sha): | |
98 self.repo = repo | |
99 self.commit = repo.handler.git.get_object(sha) | |
100 | |
101 def node(self): | |
102 return bin(self.commit.id) | |
103 | |
104 def rev(self): | |
105 return self.repo.rev(bin(self.commit.id)) | |
106 | |
107 def date(self): | |
108 return self.commit.author_time, self.commit.author_timezone | |
109 | |
110 def branch(self): | |
111 return 'default' | |
112 | |
113 def user(self): | |
114 return self.commit.author | |
115 | |
116 def files(self): | |
117 return [] | |
118 | |
119 def extra(self): | |
120 return {} | |
121 | |
122 def description(self): | |
123 return self.commit.message | |
124 | |
125 def parents(self): | |
126 return [overlaychangectx(self.repo, sha) for sha in self.commit.parents] | |
127 | |
128 def manifestnode(self): | |
129 return bin(self.commit.tree) | |
130 | |
131 def hex(self): | |
132 return self.commit.id | |
133 | |
134 def tags(self): | |
135 return [] | |
136 | |
137 def bookmarks(self): | |
138 return [] | |
139 | |
140 def manifest(self): | |
141 return overlaymanifest(self.repo, self.commit.tree) | |
142 | |
143 def filectx(self, path, filelog=None): | |
144 mf = self.manifest() | |
145 return overlayfilectx(self.repo, path, mf[path]) | |
146 | |
147 def flags(self, path): | |
148 mf = self.manifest() | |
149 return mf.flags(path) | |
150 | |
151 def __nonzero__(self): | |
152 return True | |
153 | |
568
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
154 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
|
155 try: |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
156 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
|
157 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
|
158 except ImportError: |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
159 return 1 |
41f6e3df67b1
overlaychangectx: fix compatibility with mercurial 2.4-rc (no attribute _repo)
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
160 |
408 | 161 class overlayrevlog(object): |
162 def __init__(self, repo, base): | |
163 self.repo = repo | |
164 self.base = base | |
165 | |
166 def parents(self, n): | |
167 gitrev = self.repo.revmap.get(n) | |
168 if not gitrev: | |
169 # we've reached a revision we have | |
170 return self.base.parents(n) | |
171 commit = self.repo.handler.git.get_object(n) | |
172 | |
173 def gitorhg(n): | |
174 hn = self.repo.handler.map_hg_get(hex(n)) | |
175 if hn is not None: | |
176 return bin(hn) | |
177 return n | |
178 | |
179 # currently ignores the octopus | |
180 p1 = gitorhg(bin(commit.parents[0])) | |
181 if len(commit.parents) > 1: | |
182 p2 = gitorhg(bin(commit.parents[1])) | |
183 else: | |
184 p2 = nullid | |
185 | |
186 return [p1, p2] | |
187 | |
188 def parentrevs(self, rev): | |
189 return [self.rev(p) for p in self.parents(self.node(rev))] | |
190 | |
191 def node(self, rev): | |
192 gitnode = self.repo.nodemap.get(rev) | |
193 if gitnode is None: | |
194 return self.base.node(rev) | |
195 return gitnode | |
196 | |
197 def rev(self, n): | |
198 gitrev = self.repo.revmap.get(n) | |
199 if gitrev is None: | |
200 return self.base.rev(n) | |
201 return gitrev | |
202 | |
203 def nodesbetween(self, nodelist, revs): | |
204 # this is called by pre-1.9 incoming with the nodelist we returned from | |
205 # getremotechanges. Just return it back. | |
206 return [nodelist] | |
207 | |
208 def __len__(self): | |
209 return len(self.repo.handler.repo) + len(self.repo.revmap) | |
210 | |
211 | |
212 class overlayrepo(object): | |
213 def __init__(self, handler, commits, refs): | |
214 self.handler = handler | |
215 | |
216 self.changelog = overlayrevlog(self, handler.repo.changelog) | |
217 self.manifest = overlayrevlog(self, handler.repo.manifest) | |
218 | |
219 # for incoming -p | |
220 self.root = handler.repo.root | |
221 self.getcwd = handler.repo.getcwd | |
222 self.status = handler.repo.status | |
223 self.ui = handler.repo.ui | |
224 | |
225 self.revmap = None | |
226 self.nodemap = None | |
227 self.refmap = None | |
228 self.tagmap = None | |
229 | |
230 self._makemaps(commits, refs) | |
231 | |
232 def __getitem__(self, n): | |
233 if n not in self.revmap: | |
234 return self.handler.repo[n] | |
235 return overlaychangectx(self, n) | |
236 | |
557
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
237 def node(self, n): |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
238 """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
|
239 if bin(n) in self.revmap: |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
240 return n |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
241 return self.handler.map_hg_get(n) |
4f4ab2d89375
gitrepo: initial support for listkeys
David M. Carr <david@carrclan.us>
parents:
466
diff
changeset
|
242 |
408 | 243 def nodebookmarks(self, n): |
244 return self.refmap.get(n, []) | |
245 | |
246 def nodetags(self, n): | |
247 return self.tagmap.get(n, []) | |
248 | |
249 def rev(self, n): | |
250 return self.revmap[n] | |
251 | |
252 def filectx(self, path, fileid=None): | |
253 return overlayfilectx(self, path, fileid=fileid) | |
254 | |
255 def _makemaps(self, commits, refs): | |
256 baserev = self.handler.repo['tip'].rev() | |
257 self.revmap = {} | |
258 self.nodemap = {} | |
259 for i, n in enumerate(commits): | |
260 rev = baserev + i + 1 | |
261 self.revmap[n] = rev | |
262 self.nodemap[rev] = n | |
263 | |
264 self.refmap = {} | |
265 self.tagmap = {} | |
266 for ref in refs: | |
267 if ref.startswith('refs/heads/'): | |
268 refname = ref[11:] | |
269 self.refmap.setdefault(bin(refs[ref]), []).append(refname) | |
270 elif ref.startswith('refs/tags/'): | |
271 tagname = ref[10:] | |
272 self.tagmap.setdefault(bin(refs[ref]), []).append(tagname) |