##// END OF EJS Templates
patch: use contexts for diff
Benoit Boissinot -
r3967:dccb8324 default
parent child Browse files
Show More
@@ -7,7 +7,7 b''
7 7
8 8 from i18n import _
9 9 from node import *
10 import base85, cmdutil, mdiff, util
10 import base85, cmdutil, mdiff, util, context, revlog
11 11 import cStringIO, email.Parser, os, popen2, re, sha
12 12 import sys, tempfile, zlib
13 13
@@ -436,27 +436,25 b' def diff(repo, node1=None, node2=None, f'
436 436 if not node1:
437 437 node1 = repo.dirstate.parents()[0]
438 438
439 clcache = {}
440 def getchangelog(n):
441 if n not in clcache:
442 clcache[n] = repo.changelog.read(n)
443 return clcache[n]
444 mcache = {}
445 def getmanifest(n):
446 if n not in mcache:
447 mcache[n] = repo.manifest.read(n)
448 return mcache[n]
449 fcache = {}
450 def getfile(f):
451 if f not in fcache:
452 fcache[f] = repo.file(f)
453 return fcache[f]
439 ccache = {}
440 def getctx(r):
441 if r not in ccache:
442 ccache[r] = context.changectx(repo, r)
443 return ccache[r]
444
445 flcache = {}
446 def getfilectx(f, ctx):
447 flctx = ctx.filectx(f, filelog=flcache.get(f))
448 if f not in flcache:
449 flcache[f] = flctx._filelog
450 return flctx
454 451
455 452 # reading the data for node1 early allows it to play nicely
456 453 # with repo.status and the revlog cache.
457 change = getchangelog(node1)
458 mmap = getmanifest(change[0])
459 date1 = util.datestr(change[2])
454 ctx1 = context.changectx(repo, node1)
455 # force manifest reading
456 man1 = ctx1.manifest()
457 date1 = util.datestr(ctx1.date())
460 458
461 459 if not changes:
462 460 changes = repo.status(node1, node2, files, match=match)[:5]
@@ -476,67 +474,38 b' def diff(repo, node1=None, node2=None, f'
476 474 if not modified and not added and not removed:
477 475 return
478 476
479 # returns False if there was no rename between n1 and n2
480 # returns None if the file was created between n1 and n2
481 # returns the (file, node) present in n1 that was renamed to f in n2
482 def renamedbetween(f, n1, n2):
483 r1, r2 = map(repo.changelog.rev, (n1, n2))
477 if node2:
478 ctx2 = context.changectx(repo, node2)
479 else:
480 ctx2 = context.workingctx(repo)
481 man2 = ctx2.manifest()
482
483 # returns False if there was no rename between ctx1 and ctx2
484 # returns None if the file was created between ctx1 and ctx2
485 # returns the (file, node) present in ctx1 that was renamed to f in ctx2
486 def renamed(f):
487 startrev = ctx1.rev()
488 c = ctx2
489 crev = c.rev()
490 if crev is None:
491 crev = repo.changelog.count()
484 492 orig = f
485 src = None
486 while r2 > r1:
487 cl = getchangelog(n2)
488 if f in cl[3]:
489 m = getmanifest(cl[0])
493 while crev > startrev:
494 if f in c.files():
490 495 try:
491 src = getfile(f).renamed(m[f])
492 except KeyError:
496 src = getfilectx(f, c).renamed()
497 except revlog.LookupError:
493 498 return None
494 499 if src:
495 500 f = src[0]
496 n2 = repo.changelog.parents(n2)[0]
497 r2 = repo.changelog.rev(n2)
498 cl = getchangelog(n1)
499 m = getmanifest(cl[0])
500 if f not in m:
501 crev = c.parents()[0].rev()
502 # try to reuse
503 c = getctx(crev)
504 if f not in man1:
501 505 return None
502 506 if f == orig:
503 507 return False
504 return f, m[f]
505
506 if node2:
507 change = getchangelog(node2)
508 mmap2 = getmanifest(change[0])
509 _date2 = util.datestr(change[2])
510 def date2(f):
511 return _date2
512 def read(f):
513 return getfile(f).read(mmap2[f])
514 def renamed(f):
515 return renamedbetween(f, node1, node2)
516 else:
517 tz = util.makedate()[1]
518 _date2 = util.datestr()
519 def date2(f):
520 try:
521 return util.datestr((os.lstat(repo.wjoin(f)).st_mtime, tz))
522 except OSError, err:
523 if err.errno != errno.ENOENT: raise
524 return _date2
525 def read(f):
526 return repo.wread(f)
527 def renamed(f):
528 src = repo.dirstate.copied(f)
529 parent = repo.dirstate.parents()[0]
530 if src:
531 f = src
532 of = renamedbetween(f, node1, parent)
533 if of or of is None:
534 return of
535 elif src:
536 cl = getchangelog(parent)[0]
537 return (src, getmanifest(cl)[src])
538 else:
539 return None
508 return f
540 509
541 510 if repo.ui.quiet:
542 511 r = None
@@ -550,7 +519,7 b' def diff(repo, node1=None, node2=None, f'
550 519 src = renamed(f)
551 520 if src:
552 521 copied[f] = src
553 srcs = [x[1][0] for x in copied.items()]
522 srcs = [x[1] for x in copied.items()]
554 523
555 524 all = modified + added + removed
556 525 all.sort()
@@ -560,10 +529,10 b' def diff(repo, node1=None, node2=None, f'
560 529 tn = None
561 530 dodiff = True
562 531 header = []
563 if f in mmap:
564 to = getfile(f).read(mmap[f])
532 if f in man1:
533 to = getfilectx(f, ctx1).data()
565 534 if f not in removed:
566 tn = read(f)
535 tn = getfilectx(f, ctx2).data()
567 536 if opts.git:
568 537 def gitmode(x):
569 538 return x and '100755' or '100644'
@@ -574,13 +543,10 b' def diff(repo, node1=None, node2=None, f'
574 543
575 544 a, b = f, f
576 545 if f in added:
577 if node2:
578 mode = gitmode(mmap2.execf(f))
579 else:
580 mode = gitmode(util.is_exec(repo.wjoin(f), None))
546 mode = gitmode(man2.execf(f))
581 547 if f in copied:
582 a, arev = copied[f]
583 omode = gitmode(mmap.execf(a))
548 a = copied[f]
549 omode = gitmode(man1.execf(a))
584 550 addmodehdr(header, omode, mode)
585 551 if a in removed and a not in gone:
586 552 op = 'rename'
@@ -589,7 +555,7 b' def diff(repo, node1=None, node2=None, f'
589 555 op = 'copy'
590 556 header.append('%s from %s\n' % (op, a))
591 557 header.append('%s to %s\n' % (op, f))
592 to = getfile(a).read(arev)
558 to = getfilectx(a, ctx1).data()
593 559 else:
594 560 header.append('new file mode %s\n' % mode)
595 561 if util.binary(tn):
@@ -598,14 +564,11 b' def diff(repo, node1=None, node2=None, f'
598 564 if f in srcs:
599 565 dodiff = False
600 566 else:
601 mode = gitmode(mmap.execf(f))
567 mode = gitmode(man1.execf(f))
602 568 header.append('deleted file mode %s\n' % mode)
603 569 else:
604 omode = gitmode(mmap.execf(f))
605 if node2:
606 nmode = gitmode(mmap2.execf(f))
607 else:
608 nmode = gitmode(util.is_exec(repo.wjoin(f), mmap.execf(f)))
570 omode = gitmode(man1.execf(f))
571 nmode = gitmode(man2.execf(f))
609 572 addmodehdr(header, omode, nmode)
610 573 if util.binary(to) or util.binary(tn):
611 574 dodiff = 'binary'
@@ -615,7 +578,10 b' def diff(repo, node1=None, node2=None, f'
615 578 fp.write(''.join(header))
616 579 b85diff(fp, to, tn)
617 580 elif dodiff:
618 text = mdiff.unidiff(to, date1, tn, date2(f), f, r, opts=opts)
581 text = mdiff.unidiff(to, date1,
582 # ctx2 date may be dynamic
583 tn, util.datestr(ctx2.date()),
584 f, r, opts=opts)
619 585 if text or len(header) > 1:
620 586 fp.write(''.join(header))
621 587 fp.write(text)
General Comments 0
You need to be logged in to leave comments. Login now