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