Show More
@@ -226,7 +226,10 b' class filectx(object):' | |||
|
226 | 226 | def parents(f): |
|
227 | 227 | # we want to reuse filectx objects as much as possible |
|
228 | 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 | 234 | if follow: |
|
232 | 235 | r = f.renamed() |
@@ -234,7 +237,7 b' class filectx(object):' | |||
|
234 | 237 | pl[0] = (r[0], getlog(r[0]).rev(r[1])) |
|
235 | 238 | |
|
236 | 239 | return [ getctx(p, n) for p, n in pl if n != -1 ] |
|
237 | ||
|
240 | ||
|
238 | 241 | # find all ancestors |
|
239 | 242 | needed = {self: 1} |
|
240 | 243 | visit = [self] |
@@ -279,6 +282,13 b' class filectx(object):' | |||
|
279 | 282 | """ |
|
280 | 283 | |
|
281 | 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 | 292 | flcache = {self._path:self._filelog, fc2._path:fc2._filelog} |
|
283 | 293 | def parents(vertex): |
|
284 | 294 | if vertex in acache: |
@@ -301,3 +311,149 b' class filectx(object):' | |||
|
301 | 311 | return filectx(self._repo, f, fileid=n, filelog=flcache[f]) |
|
302 | 312 | |
|
303 | 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