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