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