6 # of the GNU General Public License, incorporated herein by reference. |
6 # of the GNU General Public License, incorporated herein by reference. |
7 |
7 |
8 from node import nullid, nullrev, short, hex |
8 from node import nullid, nullrev, short, hex |
9 from i18n import _ |
9 from i18n import _ |
10 import ancestor, bdiff, revlog, util, os, errno |
10 import ancestor, bdiff, revlog, util, os, errno |
|
11 |
|
12 class propertycache(object): |
|
13 def __init__(self, func): |
|
14 self.func = func |
|
15 self.name = func.__name__ |
|
16 def __get__(self, obj, type=None): |
|
17 result = self.func(obj) |
|
18 setattr(obj, self.name, result) |
|
19 return result |
11 |
20 |
12 class changectx(object): |
21 class changectx(object): |
13 """A changecontext object makes access to data related to a particular |
22 """A changecontext object makes access to data related to a particular |
14 changeset convenient.""" |
23 changeset convenient.""" |
15 def __init__(self, repo, changeid=''): |
24 def __init__(self, repo, changeid=''): |
49 return not (self == other) |
58 return not (self == other) |
50 |
59 |
51 def __nonzero__(self): |
60 def __nonzero__(self): |
52 return self._rev != nullrev |
61 return self._rev != nullrev |
53 |
62 |
54 def __getattr__(self, name): |
63 def _changeset(self): |
55 if name == '_changeset': |
64 return self._repo.changelog.read(self.node()) |
56 self._changeset = self._repo.changelog.read(self.node()) |
65 _changeset = propertycache(_changeset) |
57 return self._changeset |
66 |
58 elif name == '_manifest': |
67 def _manifest(self): |
59 self._manifest = self._repo.manifest.read(self._changeset[0]) |
68 return self._repo.manifest.read(self._changeset[0]) |
60 return self._manifest |
69 _manifest = propertycache(_manifest) |
61 elif name == '_manifestdelta': |
70 |
62 md = self._repo.manifest.readdelta(self._changeset[0]) |
71 def _manifestdelta(self): |
63 self._manifestdelta = md |
72 return self._repo.manifest.readdelta(self._changeset[0]) |
64 return self._manifestdelta |
73 _manifestdelta = propertycache(_manifestdelta) |
65 elif name == '_parents': |
74 |
66 p = self._repo.changelog.parentrevs(self._rev) |
75 def _parents(self): |
67 if p[1] == nullrev: |
76 p = self._repo.changelog.parentrevs(self._rev) |
68 p = p[:-1] |
77 if p[1] == nullrev: |
69 self._parents = [changectx(self._repo, x) for x in p] |
78 p = p[:-1] |
70 return self._parents |
79 return [changectx(self._repo, x) for x in p] |
71 else: |
80 _parents = propertycache(_parents) |
72 raise AttributeError(name) |
|
73 |
81 |
74 def __contains__(self, key): |
82 def __contains__(self, key): |
75 return key in self._manifest |
83 return key in self._manifest |
76 |
84 |
77 def __getitem__(self, key): |
85 def __getitem__(self, key): |
191 if changectx is not None: |
199 if changectx is not None: |
192 self._changectx = changectx |
200 self._changectx = changectx |
193 if fileid is not None: |
201 if fileid is not None: |
194 self._fileid = fileid |
202 self._fileid = fileid |
195 |
203 |
196 def __getattr__(self, name): |
204 def _changectx(self): |
197 if name == '_changectx': |
205 return changectx(self._repo, self._changeid) |
198 self._changectx = changectx(self._repo, self._changeid) |
206 _changectx = propertycache(_changectx) |
199 return self._changectx |
207 |
200 elif name == '_filelog': |
208 def _filelog(self): |
201 self._filelog = self._repo.file(self._path) |
209 return self._repo.file(self._path) |
202 return self._filelog |
210 _filelog = propertycache(_filelog) |
203 elif name == '_changeid': |
211 |
204 if '_changectx' in self.__dict__: |
212 def _changeid(self): |
205 self._changeid = self._changectx.rev() |
213 if '_changectx' in self.__dict__: |
206 else: |
214 return self._changectx.rev() |
207 self._changeid = self._filelog.linkrev(self._filerev) |
|
208 return self._changeid |
|
209 elif name == '_filenode': |
|
210 if '_fileid' in self.__dict__: |
|
211 self._filenode = self._filelog.lookup(self._fileid) |
|
212 else: |
|
213 self._filenode = self._changectx.filenode(self._path) |
|
214 return self._filenode |
|
215 elif name == '_filerev': |
|
216 self._filerev = self._filelog.rev(self._filenode) |
|
217 return self._filerev |
|
218 elif name == '_repopath': |
|
219 self._repopath = self._path |
|
220 return self._repopath |
|
221 else: |
215 else: |
222 raise AttributeError(name) |
216 return self._filelog.linkrev(self._filerev) |
|
217 _changeid = propertycache(_changeid) |
|
218 |
|
219 def _filenode(self): |
|
220 if '_fileid' in self.__dict__: |
|
221 return self._filelog.lookup(self._fileid) |
|
222 else: |
|
223 return self._changectx.filenode(self._path) |
|
224 _filenode = propertycache(_filenode) |
|
225 |
|
226 def _filerev(self): |
|
227 return self._filelog.rev(self._filenode) |
|
228 _filerev = propertycache(_filerev) |
|
229 |
|
230 def _repopath(self): |
|
231 return self._path |
|
232 _repopath = propertycache(_repopath) |
223 |
233 |
224 def __nonzero__(self): |
234 def __nonzero__(self): |
225 try: |
235 try: |
226 n = self._filenode |
236 n = self._filenode |
227 return True |
237 return True |
503 return True |
513 return True |
504 |
514 |
505 def __contains__(self, key): |
515 def __contains__(self, key): |
506 return self._dirstate[key] not in "?r" |
516 return self._dirstate[key] not in "?r" |
507 |
517 |
508 def __getattr__(self, name): |
518 def _manifest(self): |
509 if name == '_status': |
|
510 self._status = self._repo.status(unknown=True) |
|
511 return self._status |
|
512 elif name == '_user': |
|
513 self._user = self._repo.ui.username() |
|
514 return self._user |
|
515 elif name == '_date': |
|
516 self._date = util.makedate() |
|
517 return self._date |
|
518 if name == '_manifest': |
|
519 self._buildmanifest() |
|
520 return self._manifest |
|
521 elif name == '_parents': |
|
522 p = self._repo.dirstate.parents() |
|
523 if p[1] == nullid: |
|
524 p = p[:-1] |
|
525 self._parents = [changectx(self._repo, x) for x in p] |
|
526 return self._parents |
|
527 else: |
|
528 raise AttributeError(name) |
|
529 |
|
530 def _buildmanifest(self): |
|
531 """generate a manifest corresponding to the working directory""" |
519 """generate a manifest corresponding to the working directory""" |
532 |
520 |
533 man = self._parents[0].manifest().copy() |
521 man = self._parents[0].manifest().copy() |
534 copied = self._repo.dirstate.copies() |
522 copied = self._repo.dirstate.copies() |
535 cf = lambda x: man.flags(copied.get(x, x)) |
523 cf = lambda x: man.flags(copied.get(x, x)) |
545 |
533 |
546 for f in deleted + removed: |
534 for f in deleted + removed: |
547 if f in man: |
535 if f in man: |
548 del man[f] |
536 del man[f] |
549 |
537 |
550 self._manifest = man |
538 return man |
|
539 _manifest = propertycache(_manifest) |
|
540 |
|
541 def _status(self): |
|
542 return self._repo.status(unknown=True) |
|
543 _status = propertycache(_status) |
|
544 |
|
545 def _user(self): |
|
546 return self._repo.ui.username() |
|
547 _user = propertycache(_user) |
|
548 |
|
549 def _date(self): |
|
550 return util.makedate() |
|
551 _date = propertycache(_date) |
|
552 |
|
553 def _parents(self): |
|
554 p = self._repo.dirstate.parents() |
|
555 if p[1] == nullid: |
|
556 p = p[:-1] |
|
557 self._parents = [changectx(self._repo, x) for x in p] |
|
558 return self._parents |
|
559 _parents = propertycache(_parents) |
551 |
560 |
552 def manifest(self): return self._manifest |
561 def manifest(self): return self._manifest |
553 |
562 |
554 def user(self): return self._user or self._repo.ui.username() |
563 def user(self): return self._user or self._repo.ui.username() |
555 def date(self): return self._date |
564 def date(self): return self._date |
620 if filelog: |
629 if filelog: |
621 self._filelog = filelog |
630 self._filelog = filelog |
622 if workingctx: |
631 if workingctx: |
623 self._changectx = workingctx |
632 self._changectx = workingctx |
624 |
633 |
625 def __getattr__(self, name): |
634 def _changectx(self): |
626 if name == '_changectx': |
635 return workingctx(self._repo) |
627 self._changectx = workingctx(self._repo) |
636 _changectx = propertycache(_changectx) |
628 return self._changectx |
637 |
629 elif name == '_repopath': |
638 def _repopath(self): |
630 self._repopath = (self._repo.dirstate.copied(self._path) |
639 return self._repo.dirstate.copied(self._path) or self._path |
631 or self._path) |
640 _repopath = propertycache(_repopath) |
632 return self._repopath |
641 |
633 elif name == '_filelog': |
642 def _filelog(self): |
634 self._filelog = self._repo.file(self._repopath) |
643 return self._repo.file(self._repopath) |
635 return self._filelog |
644 _filelog = propertycache(_filelog) |
636 else: |
|
637 raise AttributeError(name) |
|
638 |
645 |
639 def __nonzero__(self): |
646 def __nonzero__(self): |
640 return True |
647 return True |
641 |
648 |
642 def __str__(self): |
649 def __str__(self): |