##// END OF EJS Templates
context: add __int__ and hex methods
Matt Mackall -
r6763:403682f1 default
parent child Browse files
Show More
@@ -1,742 +1,749
1 1 # context.py - changeset and file context objects for mercurial
2 2 #
3 3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 from node import nullid, nullrev, short
8 from node import nullid, nullrev, short, hex
9 9 from i18n import _
10 10 import ancestor, bdiff, revlog, util, os, errno
11 11
12 12 class changectx(object):
13 13 """A changecontext object makes access to data related to a particular
14 14 changeset convenient."""
15 15 def __init__(self, repo, changeid=''):
16 16 """changeid is a revision number, node, or tag"""
17 17 if changeid == '':
18 18 changeid = '.'
19 19 self._repo = repo
20 20 self._node = self._repo.lookup(changeid)
21 21 self._rev = self._repo.changelog.rev(self._node)
22 22
23 23 def __str__(self):
24 24 return short(self.node())
25 25
26 def __int__(self):
27 return self.rev()
28
26 29 def __repr__(self):
27 30 return "<changectx %s>" % str(self)
28 31
29 32 def __hash__(self):
30 33 try:
31 34 return hash(self._rev)
32 35 except AttributeError:
33 36 return id(self)
34 37
35 38 def __eq__(self, other):
36 39 try:
37 40 return self._rev == other._rev
38 41 except AttributeError:
39 42 return False
40 43
41 44 def __ne__(self, other):
42 45 return not (self == other)
43 46
44 47 def __nonzero__(self):
45 48 return self._rev != nullrev
46 49
47 50 def __getattr__(self, name):
48 51 if name == '_changeset':
49 52 self._changeset = self._repo.changelog.read(self.node())
50 53 return self._changeset
51 54 elif name == '_manifest':
52 55 self._manifest = self._repo.manifest.read(self._changeset[0])
53 56 return self._manifest
54 57 elif name == '_manifestdelta':
55 58 md = self._repo.manifest.readdelta(self._changeset[0])
56 59 self._manifestdelta = md
57 60 return self._manifestdelta
58 61 elif name == '_parents':
59 62 p = self._repo.changelog.parents(self._node)
60 63 if p[1] == nullid:
61 64 p = p[:-1]
62 65 self._parents = [changectx(self._repo, x) for x in p]
63 66 return self._parents
64 67 else:
65 68 raise AttributeError, name
66 69
67 70 def __contains__(self, key):
68 71 return key in self._manifest
69 72
70 73 def __getitem__(self, key):
71 74 return self.filectx(key)
72 75
73 76 def __iter__(self):
74 77 for f in util.sort(self._manifest):
75 78 yield f
76 79
77 80 def changeset(self): return self._changeset
78 81 def manifest(self): return self._manifest
79 82
80 83 def rev(self): return self._rev
81 84 def node(self): return self._node
85 def hex(self): return hex(self._node)
82 86 def user(self): return self._changeset[1]
83 87 def date(self): return self._changeset[2]
84 88 def files(self): return self._changeset[3]
85 89 def description(self): return self._changeset[4]
86 90 def branch(self): return self._changeset[5].get("branch")
87 91 def extra(self): return self._changeset[5]
88 92 def tags(self): return self._repo.nodetags(self._node)
89 93
90 94 def parents(self):
91 95 """return contexts for each parent changeset"""
92 96 return self._parents
93 97
94 98 def children(self):
95 99 """return contexts for each child changeset"""
96 100 c = self._repo.changelog.children(self._node)
97 101 return [changectx(self._repo, x) for x in c]
98 102
99 103 def _fileinfo(self, path):
100 104 if '_manifest' in self.__dict__:
101 105 try:
102 106 return self._manifest[path], self._manifest.flags(path)
103 107 except KeyError:
104 108 raise revlog.LookupError(self._node, path,
105 109 _('not found in manifest'))
106 110 if '_manifestdelta' in self.__dict__ or path in self.files():
107 111 if path in self._manifestdelta:
108 112 return self._manifestdelta[path], self._manifestdelta.flags(path)
109 113 node, flag = self._repo.manifest.find(self._changeset[0], path)
110 114 if not node:
111 115 raise revlog.LookupError(self._node, path,
112 116 _('not found in manifest'))
113 117
114 118 return node, flag
115 119
116 120 def filenode(self, path):
117 121 return self._fileinfo(path)[0]
118 122
119 123 def flags(self, path):
120 124 try:
121 125 return self._fileinfo(path)[1]
122 126 except revlog.LookupError:
123 127 return ''
124 128
125 129 def filectx(self, path, fileid=None, filelog=None):
126 130 """get a file context from this changeset"""
127 131 if fileid is None:
128 132 fileid = self.filenode(path)
129 133 return filectx(self._repo, path, fileid=fileid,
130 134 changectx=self, filelog=filelog)
131 135
132 136 def filectxs(self):
133 137 """generate a file context for each file in this changeset's
134 138 manifest"""
135 139 for f in util.sort(mf):
136 140 yield self.filectx(f, fileid=mf[f])
137 141
138 142 def ancestor(self, c2):
139 143 """
140 144 return the ancestor context of self and c2
141 145 """
142 146 n = self._repo.changelog.ancestor(self._node, c2._node)
143 147 return changectx(self._repo, n)
144 148
145 149 class filectx(object):
146 150 """A filecontext object makes access to data related to a particular
147 151 filerevision convenient."""
148 152 def __init__(self, repo, path, changeid=None, fileid=None,
149 153 filelog=None, changectx=None):
150 154 """changeid can be a changeset revision, node, or tag.
151 155 fileid can be a file revision or node."""
152 156 self._repo = repo
153 157 self._path = path
154 158
155 159 assert (changeid is not None
156 160 or fileid is not None
157 161 or changectx is not None)
158 162
159 163 if filelog:
160 164 self._filelog = filelog
161 165
162 166 if changeid is not None:
163 167 self._changeid = changeid
164 168 if changectx is not None:
165 169 self._changectx = changectx
166 170 if fileid is not None:
167 171 self._fileid = fileid
168 172
169 173 def __getattr__(self, name):
170 174 if name == '_changectx':
171 175 self._changectx = changectx(self._repo, self._changeid)
172 176 return self._changectx
173 177 elif name == '_filelog':
174 178 self._filelog = self._repo.file(self._path)
175 179 return self._filelog
176 180 elif name == '_changeid':
177 181 if '_changectx' in self.__dict__:
178 182 self._changeid = self._changectx.rev()
179 183 else:
180 184 self._changeid = self._filelog.linkrev(self._filenode)
181 185 return self._changeid
182 186 elif name == '_filenode':
183 187 if '_fileid' in self.__dict__:
184 188 self._filenode = self._filelog.lookup(self._fileid)
185 189 else:
186 190 self._filenode = self._changectx.filenode(self._path)
187 191 return self._filenode
188 192 elif name == '_filerev':
189 193 self._filerev = self._filelog.rev(self._filenode)
190 194 return self._filerev
191 195 elif name == '_repopath':
192 196 self._repopath = self._path
193 197 return self._repopath
194 198 else:
195 199 raise AttributeError, name
196 200
197 201 def __nonzero__(self):
198 202 try:
199 203 n = self._filenode
200 204 return True
201 205 except revlog.LookupError:
202 206 # file is missing
203 207 return False
204 208
205 209 def __str__(self):
206 210 return "%s@%s" % (self.path(), short(self.node()))
207 211
208 212 def __repr__(self):
209 213 return "<filectx %s>" % str(self)
210 214
211 215 def __hash__(self):
212 216 try:
213 217 return hash((self._path, self._fileid))
214 218 except AttributeError:
215 219 return id(self)
216 220
217 221 def __eq__(self, other):
218 222 try:
219 223 return (self._path == other._path
220 224 and self._fileid == other._fileid)
221 225 except AttributeError:
222 226 return False
223 227
224 228 def __ne__(self, other):
225 229 return not (self == other)
226 230
227 231 def filectx(self, fileid):
228 232 '''opens an arbitrary revision of the file without
229 233 opening a new filelog'''
230 234 return filectx(self._repo, self._path, fileid=fileid,
231 235 filelog=self._filelog)
232 236
233 237 def filerev(self): return self._filerev
234 238 def filenode(self): return self._filenode
235 239 def flags(self): return self._changectx.flags(self._path)
236 240 def filelog(self): return self._filelog
237 241
238 242 def rev(self):
239 243 if '_changectx' in self.__dict__:
240 244 return self._changectx.rev()
241 245 if '_changeid' in self.__dict__:
242 246 return self._changectx.rev()
243 247 return self._filelog.linkrev(self._filenode)
244 248
245 249 def linkrev(self): return self._filelog.linkrev(self._filenode)
246 250 def node(self): return self._changectx.node()
247 251 def user(self): return self._changectx.user()
248 252 def date(self): return self._changectx.date()
249 253 def files(self): return self._changectx.files()
250 254 def description(self): return self._changectx.description()
251 255 def branch(self): return self._changectx.branch()
252 256 def manifest(self): return self._changectx.manifest()
253 257 def changectx(self): return self._changectx
254 258
255 259 def data(self): return self._filelog.read(self._filenode)
256 260 def path(self): return self._path
257 261 def size(self): return self._filelog.size(self._filerev)
258 262
259 263 def cmp(self, text): return self._filelog.cmp(self._filenode, text)
260 264
261 265 def renamed(self):
262 266 """check if file was actually renamed in this changeset revision
263 267
264 268 If rename logged in file revision, we report copy for changeset only
265 269 if file revisions linkrev points back to the changeset in question
266 270 or both changeset parents contain different file revisions.
267 271 """
268 272
269 273 renamed = self._filelog.renamed(self._filenode)
270 274 if not renamed:
271 275 return renamed
272 276
273 277 if self.rev() == self.linkrev():
274 278 return renamed
275 279
276 280 name = self.path()
277 281 fnode = self._filenode
278 282 for p in self._changectx.parents():
279 283 try:
280 284 if fnode == p.filenode(name):
281 285 return None
282 286 except revlog.LookupError:
283 287 pass
284 288 return renamed
285 289
286 290 def parents(self):
287 291 p = self._path
288 292 fl = self._filelog
289 293 pl = [(p, n, fl) for n in self._filelog.parents(self._filenode)]
290 294
291 295 r = self._filelog.renamed(self._filenode)
292 296 if r:
293 297 pl[0] = (r[0], r[1], None)
294 298
295 299 return [filectx(self._repo, p, fileid=n, filelog=l)
296 300 for p,n,l in pl if n != nullid]
297 301
298 302 def children(self):
299 303 # hard for renames
300 304 c = self._filelog.children(self._filenode)
301 305 return [filectx(self._repo, self._path, fileid=x,
302 306 filelog=self._filelog) for x in c]
303 307
304 308 def annotate(self, follow=False, linenumber=None):
305 309 '''returns a list of tuples of (ctx, line) for each line
306 310 in the file, where ctx is the filectx of the node where
307 311 that line was last changed.
308 312 This returns tuples of ((ctx, linenumber), line) for each line,
309 313 if "linenumber" parameter is NOT "None".
310 314 In such tuples, linenumber means one at the first appearance
311 315 in the managed file.
312 316 To reduce annotation cost,
313 317 this returns fixed value(False is used) as linenumber,
314 318 if "linenumber" parameter is "False".'''
315 319
316 320 def decorate_compat(text, rev):
317 321 return ([rev] * len(text.splitlines()), text)
318 322
319 323 def without_linenumber(text, rev):
320 324 return ([(rev, False)] * len(text.splitlines()), text)
321 325
322 326 def with_linenumber(text, rev):
323 327 size = len(text.splitlines())
324 328 return ([(rev, i) for i in xrange(1, size + 1)], text)
325 329
326 330 decorate = (((linenumber is None) and decorate_compat) or
327 331 (linenumber and with_linenumber) or
328 332 without_linenumber)
329 333
330 334 def pair(parent, child):
331 335 for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
332 336 child[0][b1:b2] = parent[0][a1:a2]
333 337 return child
334 338
335 339 getlog = util.cachefunc(lambda x: self._repo.file(x))
336 340 def getctx(path, fileid):
337 341 log = path == self._path and self._filelog or getlog(path)
338 342 return filectx(self._repo, path, fileid=fileid, filelog=log)
339 343 getctx = util.cachefunc(getctx)
340 344
341 345 def parents(f):
342 346 # we want to reuse filectx objects as much as possible
343 347 p = f._path
344 348 if f._filerev is None: # working dir
345 349 pl = [(n.path(), n.filerev()) for n in f.parents()]
346 350 else:
347 351 pl = [(p, n) for n in f._filelog.parentrevs(f._filerev)]
348 352
349 353 if follow:
350 354 r = f.renamed()
351 355 if r:
352 356 pl[0] = (r[0], getlog(r[0]).rev(r[1]))
353 357
354 358 return [getctx(p, n) for p, n in pl if n != nullrev]
355 359
356 360 # use linkrev to find the first changeset where self appeared
357 361 if self.rev() != self.linkrev():
358 362 base = self.filectx(self.filerev())
359 363 else:
360 364 base = self
361 365
362 366 # find all ancestors
363 367 needed = {base: 1}
364 368 visit = [base]
365 369 files = [base._path]
366 370 while visit:
367 371 f = visit.pop(0)
368 372 for p in parents(f):
369 373 if p not in needed:
370 374 needed[p] = 1
371 375 visit.append(p)
372 376 if p._path not in files:
373 377 files.append(p._path)
374 378 else:
375 379 # count how many times we'll use this
376 380 needed[p] += 1
377 381
378 382 # sort by revision (per file) which is a topological order
379 383 visit = []
380 384 for f in files:
381 385 fn = [(n.rev(), n) for n in needed if n._path == f]
382 386 visit.extend(fn)
383 387
384 388 hist = {}
385 389 for r, f in util.sort(visit):
386 390 curr = decorate(f.data(), f)
387 391 for p in parents(f):
388 392 if p != nullid:
389 393 curr = pair(hist[p], curr)
390 394 # trim the history of unneeded revs
391 395 needed[p] -= 1
392 396 if not needed[p]:
393 397 del hist[p]
394 398 hist[f] = curr
395 399
396 400 return zip(hist[f][0], hist[f][1].splitlines(1))
397 401
398 402 def ancestor(self, fc2):
399 403 """
400 404 find the common ancestor file context, if any, of self, and fc2
401 405 """
402 406
403 407 acache = {}
404 408
405 409 # prime the ancestor cache for the working directory
406 410 for c in (self, fc2):
407 411 if c._filerev == None:
408 412 pl = [(n.path(), n.filenode()) for n in c.parents()]
409 413 acache[(c._path, None)] = pl
410 414
411 415 flcache = {self._repopath:self._filelog, fc2._repopath:fc2._filelog}
412 416 def parents(vertex):
413 417 if vertex in acache:
414 418 return acache[vertex]
415 419 f, n = vertex
416 420 if f not in flcache:
417 421 flcache[f] = self._repo.file(f)
418 422 fl = flcache[f]
419 423 pl = [(f, p) for p in fl.parents(n) if p != nullid]
420 424 re = fl.renamed(n)
421 425 if re:
422 426 pl.append(re)
423 427 acache[vertex] = pl
424 428 return pl
425 429
426 430 a, b = (self._path, self._filenode), (fc2._path, fc2._filenode)
427 431 v = ancestor.ancestor(a, b, parents)
428 432 if v:
429 433 f, n = v
430 434 return filectx(self._repo, f, fileid=n, filelog=flcache[f])
431 435
432 436 return None
433 437
434 438 class workingctx(changectx):
435 439 """A workingctx object makes access to data related to
436 440 the current working directory convenient.
437 441 parents - a pair of parent nodeids, or None to use the dirstate.
438 442 date - any valid date string or (unixtime, offset), or None.
439 443 user - username string, or None.
440 444 extra - a dictionary of extra values, or None.
441 445 changes - a list of file lists as returned by localrepo.status()
442 446 or None to use the repository status.
443 447 """
444 448 def __init__(self, repo, parents=None, text="", user=None, date=None,
445 449 extra=None, changes=None):
446 450 self._repo = repo
447 451 self._rev = None
448 452 self._node = None
449 453 self._text = text
450 454 if date:
451 455 self._date = util.parsedate(date)
452 456 else:
453 457 self._date = util.makedate()
454 458 if user:
455 459 self._user = user
456 460 else:
457 461 self._user = self._repo.ui.username()
458 462 if parents:
459 463 p1, p2 = parents
460 464 self._parents = [changectx(self._repo, p) for p in (p1, p2)]
461 465 if changes:
462 466 self._status = list(changes)
463 467
464 468 self._extra = {}
465 469 if extra:
466 470 self._extra = extra.copy()
467 471 if 'branch' not in self._extra:
468 472 branch = self._repo.dirstate.branch()
469 473 try:
470 474 branch = branch.decode('UTF-8').encode('UTF-8')
471 475 except UnicodeDecodeError:
472 476 raise util.Abort(_('branch name not in UTF-8!'))
473 477 self._extra['branch'] = branch
474 478 if self._extra['branch'] == '':
475 479 self._extra['branch'] = 'default'
476 480
477 481 def __str__(self):
478 482 return str(self._parents[0]) + "+"
479 483
480 484 def __nonzero__(self):
481 485 return True
482 486
483 487 def __getattr__(self, name):
484 488 if name == '_status':
485 489 self._status = self._repo.status(unknown=True)
486 490 return self._status
487 491 if name == '_manifest':
488 492 self._buildmanifest()
489 493 return self._manifest
490 494 elif name == '_parents':
491 495 p = self._repo.dirstate.parents()
492 496 if p[1] == nullid:
493 497 p = p[:-1]
494 498 self._parents = [changectx(self._repo, x) for x in p]
495 499 return self._parents
496 500 else:
497 501 raise AttributeError, name
498 502
499 503 def _buildmanifest(self):
500 504 """generate a manifest corresponding to the working directory"""
501 505
502 506 man = self._parents[0].manifest().copy()
503 507 copied = self._repo.dirstate.copies()
504 508 cf = lambda x: man.flags(copied.get(x, x))
505 509 ff = self._repo.dirstate.flagfunc(cf)
506 510 modified, added, removed, deleted, unknown = self._status[:5]
507 511 for i, l in (("a", added), ("m", modified), ("u", unknown)):
508 512 for f in l:
509 513 man[f] = man.get(copied.get(f, f), nullid) + i
510 514 try:
511 515 man.set(f, ff(f))
512 516 except OSError:
513 517 pass
514 518
515 519 for f in deleted + removed:
516 520 if f in man:
517 521 del man[f]
518 522
519 523 self._manifest = man
520 524
521 525 def manifest(self): return self._manifest
522 526
523 527 def user(self): return self._user
524 528 def date(self): return self._date
525 529 def description(self): return self._text
526 530 def files(self):
527 531 return util.sort(self._status[0] + self._status[1] + self._status[2])
528 532
529 533 def modified(self): return self._status[0]
530 534 def added(self): return self._status[1]
531 535 def removed(self): return self._status[2]
532 536 def deleted(self): return self._status[3]
533 537 def unknown(self): return self._status[4]
534 538 def clean(self): return self._status[5]
535 539 def branch(self): return self._extra['branch']
536 540 def extra(self): return self._extra
537 541
538 542 def tags(self):
539 543 t = []
540 544 [t.extend(p.tags()) for p in self.parents()]
541 545 return t
542 546
543 547 def children(self):
544 548 return []
545 549
546 550 def flags(self, path):
547 551 if '_manifest' in self.__dict__:
548 552 try:
549 553 return self._manifest.flags(path)
550 554 except KeyError:
551 555 return ''
552 556
553 557 pnode = self._parents[0].changeset()[0]
554 558 orig = self._repo.dirstate.copies().get(path, path)
555 559 node, flag = self._repo.manifest.find(pnode, orig)
556 560 try:
557 561 ff = self._repo.dirstate.flagfunc(lambda x: flag or '')
558 562 return ff(path)
559 563 except OSError:
560 564 pass
561 565
562 566 if not node or path in self.deleted() or path in self.removed():
563 567 return ''
564 568 return flag
565 569
566 570 def filectx(self, path, filelog=None):
567 571 """get a file context from the working directory"""
568 572 return workingfilectx(self._repo, path, workingctx=self,
569 573 filelog=filelog)
570 574
571 575 def ancestor(self, c2):
572 576 """return the ancestor context of self and c2"""
573 577 return self._parents[0].ancestor(c2) # punt on two parents for now
574 578
575 579 class workingfilectx(filectx):
576 580 """A workingfilectx object makes access to data related to a particular
577 581 file in the working directory convenient."""
578 582 def __init__(self, repo, path, filelog=None, workingctx=None):
579 583 """changeid can be a changeset revision, node, or tag.
580 584 fileid can be a file revision or node."""
581 585 self._repo = repo
582 586 self._path = path
583 587 self._changeid = None
584 588 self._filerev = self._filenode = None
585 589
586 590 if filelog:
587 591 self._filelog = filelog
588 592 if workingctx:
589 593 self._changectx = workingctx
590 594
591 595 def __getattr__(self, name):
592 596 if name == '_changectx':
593 597 self._changectx = workingctx(self._repo)
594 598 return self._changectx
595 599 elif name == '_repopath':
596 600 self._repopath = (self._repo.dirstate.copied(self._path)
597 601 or self._path)
598 602 return self._repopath
599 603 elif name == '_filelog':
600 604 self._filelog = self._repo.file(self._repopath)
601 605 return self._filelog
602 606 else:
603 607 raise AttributeError, name
604 608
605 609 def __nonzero__(self):
606 610 return True
607 611
608 612 def __str__(self):
609 613 return "%s@%s" % (self.path(), self._changectx)
610 614
611 615 def filectx(self, fileid):
612 616 '''opens an arbitrary revision of the file without
613 617 opening a new filelog'''
614 618 return filectx(self._repo, self._repopath, fileid=fileid,
615 619 filelog=self._filelog)
616 620
617 621 def rev(self):
618 622 if '_changectx' in self.__dict__:
619 623 return self._changectx.rev()
620 624 return self._filelog.linkrev(self._filenode)
621 625
622 626 def data(self): return self._repo.wread(self._path)
623 627 def renamed(self):
624 628 rp = self._repopath
625 629 if rp == self._path:
626 630 return None
627 631 return rp, self._changectx._parents[0]._manifest.get(rp, nullid)
628 632
629 633 def parents(self):
630 634 '''return parent filectxs, following copies if necessary'''
631 635 p = self._path
632 636 rp = self._repopath
633 637 pcl = self._changectx._parents
634 638 fl = self._filelog
635 639 pl = [(rp, pcl[0]._manifest.get(rp, nullid), fl)]
636 640 if len(pcl) > 1:
637 641 if rp != p:
638 642 fl = None
639 643 pl.append((p, pcl[1]._manifest.get(p, nullid), fl))
640 644
641 645 return [filectx(self._repo, p, fileid=n, filelog=l)
642 646 for p,n,l in pl if n != nullid]
643 647
644 648 def children(self):
645 649 return []
646 650
647 651 def size(self): return os.stat(self._repo.wjoin(self._path)).st_size
648 652 def date(self):
649 653 t, tz = self._changectx.date()
650 654 try:
651 655 return (int(os.lstat(self._repo.wjoin(self._path)).st_mtime), tz)
652 656 except OSError, err:
653 657 if err.errno != errno.ENOENT: raise
654 658 return (t, tz)
655 659
656 660 def cmp(self, text): return self._repo.wread(self._path) == text
657 661
658 662 class memctx(object):
659 663 """A memctx is a subset of changectx supposed to be built on memory
660 664 and passed to commit functions.
661 665
662 666 NOTE: this interface and the related memfilectx are experimental and
663 667 may change without notice.
664 668
665 669 parents - a pair of parent nodeids.
666 670 filectxfn - a callable taking (repo, memctx, path) arguments and
667 671 returning a memctx object.
668 672 date - any valid date string or (unixtime, offset), or None.
669 673 user - username string, or None.
670 674 extra - a dictionary of extra values, or None.
671 675 """
672 676 def __init__(self, repo, parents, text, files, filectxfn, user=None,
673 677 date=None, extra=None):
674 678 self._repo = repo
675 679 self._rev = None
676 680 self._node = None
677 681 self._text = text
678 682 self._date = date and util.parsedate(date) or util.makedate()
679 683 self._user = user or self._repo.ui.username()
680 684 parents = [(p or nullid) for p in parents]
681 685 p1, p2 = parents
682 686 self._parents = [changectx(self._repo, p) for p in (p1, p2)]
683 687 files = util.sort(list(files))
684 688 self._status = [files, [], [], [], []]
685 689 self._filectxfn = filectxfn
686 690
687 691 self._extra = extra and extra.copy() or {}
688 692 if 'branch' not in self._extra:
689 693 self._extra['branch'] = 'default'
690 694 elif self._extra.get('branch') == '':
691 695 self._extra['branch'] = 'default'
692 696
693 697 def __str__(self):
694 698 return str(self._parents[0]) + "+"
695 699
700 def __int__(self):
701 return self._rev
702
696 703 def __nonzero__(self):
697 704 return True
698 705
699 706 def user(self): return self._user
700 707 def date(self): return self._date
701 708 def description(self): return self._text
702 709 def files(self): return self.modified()
703 710 def modified(self): return self._status[0]
704 711 def added(self): return self._status[1]
705 712 def removed(self): return self._status[2]
706 713 def deleted(self): return self._status[3]
707 714 def unknown(self): return self._status[4]
708 715 def clean(self): return self._status[5]
709 716 def branch(self): return self._extra['branch']
710 717 def extra(self): return self._extra
711 718 def flags(self, f): return self[f].flags()
712 719
713 720 def parents(self):
714 721 """return contexts for each parent changeset"""
715 722 return self._parents
716 723
717 724 def filectx(self, path, filelog=None):
718 725 """get a file context from the working directory"""
719 726 return self._filectxfn(self._repo, self, path)
720 727
721 728 class memfilectx(object):
722 729 """A memfilectx is a subset of filectx supposed to be built by client
723 730 code and passed to commit functions.
724 731 """
725 732 def __init__(self, path, data, islink, isexec, copied):
726 733 """copied is the source file path, or None."""
727 734 self._path = path
728 735 self._data = data
729 736 self._flags = (islink and 'l' or '') + (isexec and 'x' or '')
730 737 self._copied = None
731 738 if copied:
732 739 self._copied = (copied, nullid)
733 740
734 741 def __nonzero__(self): return True
735 742 def __str__(self): return "%s@%s" % (self.path(), self._changectx)
736 743 def path(self): return self._path
737 744 def data(self): return self._data
738 745 def flags(self): return self._flags
739 746 def isexec(self): return 'x' in self._flags
740 747 def islink(self): return 'l' in self._flags
741 748 def renamed(self): return self._copied
742 749
General Comments 0
You need to be logged in to leave comments. Login now