Show More
@@ -226,7 +226,10 b' class filectx(object):' | |||||
226 | def parents(f): |
|
226 | def parents(f): | |
227 | # we want to reuse filectx objects as much as possible |
|
227 | # we want to reuse filectx objects as much as possible | |
228 | p = f._path |
|
228 | p = f._path | |
229 | pl = [ (p, f._filelog.rev(n)) for n in f._filelog.parents(f._filenode) ] |
|
229 | if f._filerev is None: # working dir | |
|
230 | pl = [ (n.path(), n.filerev()) for n in f.parents() ] | |||
|
231 | else: | |||
|
232 | pl = [ (p, n) for n in f._filelog.parentrevs(f._filerev) ] | |||
230 |
|
233 | |||
231 | if follow: |
|
234 | if follow: | |
232 | r = f.renamed() |
|
235 | r = f.renamed() | |
@@ -234,7 +237,7 b' class filectx(object):' | |||||
234 | pl[0] = (r[0], getlog(r[0]).rev(r[1])) |
|
237 | pl[0] = (r[0], getlog(r[0]).rev(r[1])) | |
235 |
|
238 | |||
236 | return [ getctx(p, n) for p, n in pl if n != -1 ] |
|
239 | return [ getctx(p, n) for p, n in pl if n != -1 ] | |
237 |
|
240 | |||
238 | # find all ancestors |
|
241 | # find all ancestors | |
239 | needed = {self: 1} |
|
242 | needed = {self: 1} | |
240 | visit = [self] |
|
243 | visit = [self] | |
@@ -279,6 +282,13 b' class filectx(object):' | |||||
279 | """ |
|
282 | """ | |
280 |
|
283 | |||
281 | acache = {} |
|
284 | acache = {} | |
|
285 | ||||
|
286 | # prime the ancestor cache for the working directory | |||
|
287 | for c in (self, fc2): | |||
|
288 | if c._filerev == None: | |||
|
289 | pl = [ (n.path(), n.filenode()) for n in c.parents() ] | |||
|
290 | acache[(c._path, None)] = pl | |||
|
291 | ||||
282 | flcache = {self._path:self._filelog, fc2._path:fc2._filelog} |
|
292 | flcache = {self._path:self._filelog, fc2._path:fc2._filelog} | |
283 | def parents(vertex): |
|
293 | def parents(vertex): | |
284 | if vertex in acache: |
|
294 | if vertex in acache: | |
@@ -301,3 +311,149 b' class filectx(object):' | |||||
301 | return filectx(self._repo, f, fileid=n, filelog=flcache[f]) |
|
311 | return filectx(self._repo, f, fileid=n, filelog=flcache[f]) | |
302 |
|
312 | |||
303 | return None |
|
313 | return None | |
|
314 | ||||
|
315 | class workingctx(changectx): | |||
|
316 | """A workingctx object makes access to data related to | |||
|
317 | the current working directory convenient.""" | |||
|
318 | def __init__(self, repo): | |||
|
319 | self._repo = repo | |||
|
320 | self._rev = None | |||
|
321 | self._node = None | |||
|
322 | ||||
|
323 | def __str__(self): | |||
|
324 | return "." | |||
|
325 | ||||
|
326 | def __nonzero__(self): | |||
|
327 | return True | |||
|
328 | ||||
|
329 | def __getattr__(self, name): | |||
|
330 | if name == '_parents': | |||
|
331 | self._parents = self._repo.parents() | |||
|
332 | return self._parents | |||
|
333 | if name == '_status': | |||
|
334 | self._status = self._repo.status() | |||
|
335 | return self._status | |||
|
336 | if name == '_manifest': | |||
|
337 | self._buildmanifest() | |||
|
338 | return self._manifest | |||
|
339 | else: | |||
|
340 | raise AttributeError, name | |||
|
341 | ||||
|
342 | def _buildmanifest(self): | |||
|
343 | """generate a manifest corresponding to the working directory""" | |||
|
344 | ||||
|
345 | man = self._parents[0].manifest().coy() | |||
|
346 | copied = self._repo.dirstate.copies() | |||
|
347 | modified, added, removed, deleted, unknown = self._status[:5] | |||
|
348 | for i,l in (("a", added), ("m", modified), ("u", unknown)): | |||
|
349 | for f in l: | |||
|
350 | man[f] = man.get(copied.get(f, f), nullid) + i | |||
|
351 | man.set(f, util.is_exec(self._repo.wjoin(f), man.execf(f))) | |||
|
352 | ||||
|
353 | for f in deleted + removed: | |||
|
354 | del man[f] | |||
|
355 | ||||
|
356 | self._manifest = man | |||
|
357 | ||||
|
358 | def manifest(self): return self._manifest | |||
|
359 | ||||
|
360 | def user(self): return self._repo.ui.username() | |||
|
361 | def date(self): return util.makedate() | |||
|
362 | def description(self): return "" | |||
|
363 | def files(self): | |||
|
364 | f = self.modified() + self.added() + self.removed() | |||
|
365 | f.sort() | |||
|
366 | return f | |||
|
367 | ||||
|
368 | def modified(self): return self._status[0] | |||
|
369 | def added(self): return self._status[1] | |||
|
370 | def removed(self): return self._status[2] | |||
|
371 | def deleted(self): return self._status[3] | |||
|
372 | def unknown(self): return self._status[4] | |||
|
373 | def clean(self): return self._status[5] | |||
|
374 | ||||
|
375 | def parents(self): | |||
|
376 | """return contexts for each parent changeset""" | |||
|
377 | return self._parents | |||
|
378 | ||||
|
379 | def children(self): | |||
|
380 | return [] | |||
|
381 | ||||
|
382 | def filectx(self, path): | |||
|
383 | """get a file context from the working directory""" | |||
|
384 | return workingfilectx(self._repo, path, workingctx=self) | |||
|
385 | ||||
|
386 | def ancestor(self, c2): | |||
|
387 | """return the ancestor context of self and c2""" | |||
|
388 | return self._parents[0].ancestor(c2) # punt on two parents for now | |||
|
389 | ||||
|
390 | class workingfilectx(filectx): | |||
|
391 | """A workingfilectx object makes access to data related to a particular | |||
|
392 | file in the working directory convenient.""" | |||
|
393 | def __init__(self, repo, path, filelog=None, workingctx=None): | |||
|
394 | """changeid can be a changeset revision, node, or tag. | |||
|
395 | fileid can be a file revision or node.""" | |||
|
396 | self._repo = repo | |||
|
397 | self._path = path | |||
|
398 | self._changeid = None | |||
|
399 | self._filerev = self._filenode = None | |||
|
400 | ||||
|
401 | if filelog: | |||
|
402 | self._filelog = filelog | |||
|
403 | if workingctx: | |||
|
404 | self._changectx = workingctx | |||
|
405 | ||||
|
406 | def __getattr__(self, name): | |||
|
407 | if name == '_changectx': | |||
|
408 | self._changectx = workingctx(repo) | |||
|
409 | return self._changectx | |||
|
410 | elif name == '_repopath': | |||
|
411 | self._repopath = self._repo.dirstate.copied(p) or self._path | |||
|
412 | elif name == '_filelog': | |||
|
413 | self._filelog = self._repo.file(self._repopath) | |||
|
414 | return self._filelog | |||
|
415 | else: | |||
|
416 | raise AttributeError, name | |||
|
417 | ||||
|
418 | def __nonzero__(self): | |||
|
419 | return True | |||
|
420 | ||||
|
421 | def __str__(self): | |||
|
422 | return "%s@." % self.path() | |||
|
423 | ||||
|
424 | def filectx(self, fileid): | |||
|
425 | '''opens an arbitrary revision of the file without | |||
|
426 | opening a new filelog''' | |||
|
427 | return filectx(self._repo, self._repopath, fileid=fileid, | |||
|
428 | filelog=self._filelog) | |||
|
429 | ||||
|
430 | def rev(self): | |||
|
431 | if hasattr(self, "_changectx"): | |||
|
432 | return self._changectx.rev() | |||
|
433 | return self._filelog.linkrev(self._filenode) | |||
|
434 | ||||
|
435 | def data(self): return self._repo.wread(self._path) | |||
|
436 | def renamed(self): | |||
|
437 | rp = self._repopath | |||
|
438 | if rp == self._path: | |||
|
439 | return None | |||
|
440 | return rp, self._workingctx._parents._manifest.get(rp, nullid) | |||
|
441 | ||||
|
442 | def parents(self): | |||
|
443 | '''return parent filectxs, following copies if necessary''' | |||
|
444 | p = self._path | |||
|
445 | rp = self._repopath | |||
|
446 | pcl = self._workingctx._parents | |||
|
447 | fl = self._filelog | |||
|
448 | pl = [ (rp, pcl[0]._manifest.get(rp, nullid), fl) ] | |||
|
449 | if len(pcl) > 1: | |||
|
450 | if rp != p: | |||
|
451 | fl = None | |||
|
452 | pl.append((p, pcl[1]._manifest.get(p, nullid), fl)) | |||
|
453 | ||||
|
454 | return [ filectx(self._repo, p, fileid=n, filelog=l) | |||
|
455 | for p,n,l in pl if n != nullid ] | |||
|
456 | ||||
|
457 | def children(self): | |||
|
458 | return [] | |||
|
459 |
General Comments 0
You need to be logged in to leave comments.
Login now