mercurial/patch.py
changeset 2934 2f190e998eb3
parent 2933 439fd013360d
child 2952 6ba3409f9725
equal deleted inserted replaced
2933:439fd013360d 2934:2f190e998eb3
   341     if fp is None:
   341     if fp is None:
   342         fp = repo.ui
   342         fp = repo.ui
   343 
   343 
   344     if not node1:
   344     if not node1:
   345         node1 = repo.dirstate.parents()[0]
   345         node1 = repo.dirstate.parents()[0]
       
   346 
       
   347     clcache = {}
       
   348     def getchangelog(n):
       
   349         if n not in clcache:
       
   350             clcache[n] = repo.changelog.read(n)
       
   351         return clcache[n]
       
   352     mcache = {}
       
   353     def getmanifest(n):
       
   354         if n not in mcache:
       
   355             mcache[n] = repo.manifest.read(n)
       
   356         return mcache[n]
       
   357     fcache = {}
       
   358     def getfile(f):
       
   359         if f not in fcache:
       
   360             fcache[f] = repo.file(f)
       
   361         return fcache[f]
       
   362 
   346     # reading the data for node1 early allows it to play nicely
   363     # reading the data for node1 early allows it to play nicely
   347     # with repo.status and the revlog cache.
   364     # with repo.status and the revlog cache.
   348     change = repo.changelog.read(node1)
   365     change = getchangelog(node1)
   349     mmap = repo.manifest.read(change[0])
   366     mmap = getmanifest(change[0])
   350     date1 = util.datestr(change[2])
   367     date1 = util.datestr(change[2])
   351 
   368 
   352     if not changes:
   369     if not changes:
   353         changes = repo.status(node1, node2, files, match=match)[:5]
   370         changes = repo.status(node1, node2, files, match=match)[:5]
   354     modified, added, removed, deleted, unknown = changes
   371     modified, added, removed, deleted, unknown = changes
   365         modified, added, removed = map(filterfiles, (modified, added, removed))
   382         modified, added, removed = map(filterfiles, (modified, added, removed))
   366 
   383 
   367     if not modified and not added and not removed:
   384     if not modified and not added and not removed:
   368         return
   385         return
   369 
   386 
       
   387     def renamedbetween(f, n1, n2):
       
   388         r1, r2 = map(repo.changelog.rev, (n1, n2))
       
   389         src = None
       
   390         while r2 > r1:
       
   391             cl = getchangelog(n2)[0]
       
   392             m = getmanifest(cl)
       
   393             try:
       
   394                 src = getfile(f).renamed(m[f])
       
   395             except KeyError:
       
   396                 return None
       
   397             if src:
       
   398                 f = src[0]
       
   399             n2 = repo.changelog.parents(n2)[0]
       
   400             r2 = repo.changelog.rev(n2)
       
   401         return src
       
   402 
   370     if node2:
   403     if node2:
   371         change = repo.changelog.read(node2)
   404         change = getchangelog(node2)
   372         mmap2 = repo.manifest.read(change[0])
   405         mmap2 = getmanifest(change[0])
   373         _date2 = util.datestr(change[2])
   406         _date2 = util.datestr(change[2])
   374         def date2(f):
   407         def date2(f):
   375             return _date2
   408             return _date2
   376         def read(f):
   409         def read(f):
   377             return repo.file(f).read(mmap2[f])
   410             return getfile(f).read(mmap2[f])
   378         def renamed(f):
   411         def renamed(f):
   379             src = repo.file(f).renamed(mmap2[f])
   412             return renamedbetween(f, node1, node2)
   380             return src and src[0] or None
       
   381     else:
   413     else:
   382         tz = util.makedate()[1]
   414         tz = util.makedate()[1]
   383         _date2 = util.datestr()
   415         _date2 = util.datestr()
   384         def date2(f):
   416         def date2(f):
   385             try:
   417             try:
   388                 if err.errno != errno.ENOENT: raise
   420                 if err.errno != errno.ENOENT: raise
   389                 return _date2
   421                 return _date2
   390         def read(f):
   422         def read(f):
   391             return repo.wread(f)
   423             return repo.wread(f)
   392         def renamed(f):
   424         def renamed(f):
   393             return repo.dirstate.copies.get(f)
   425             src = repo.dirstate.copies.get(f)
       
   426             parent = repo.dirstate.parents()[0]
       
   427             if src:
       
   428                 f = src[0]
       
   429             of = renamedbetween(f, node1, parent)
       
   430             if of:
       
   431                 return of
       
   432             elif src:
       
   433                 cl = getchangelog(parent)[0]
       
   434                 return (src, getmanifest(cl)[src])
       
   435             else:
       
   436                 return None
   394 
   437 
   395     if repo.ui.quiet:
   438     if repo.ui.quiet:
   396         r = None
   439         r = None
   397     else:
   440     else:
   398         hexfunc = repo.ui.verbose and hex or short
   441         hexfunc = repo.ui.verbose and hex or short
   402         copied = {}
   445         copied = {}
   403         for f in added:
   446         for f in added:
   404             src = renamed(f)
   447             src = renamed(f)
   405             if src:
   448             if src:
   406                 copied[f] = src
   449                 copied[f] = src
   407         srcs = [x[1] for x in copied.items()]
   450         srcs = [x[1][0] for x in copied.items()]
   408 
   451 
   409     all = modified + added + removed
   452     all = modified + added + removed
   410     all.sort()
   453     all.sort()
   411     for f in all:
   454     for f in all:
   412         to = None
   455         to = None
   413         tn = None
   456         tn = None
   414         dodiff = True
   457         dodiff = True
   415         if f in mmap:
   458         if f in mmap:
   416             to = repo.file(f).read(mmap[f])
   459             to = getfile(f).read(mmap[f])
   417         if f not in removed:
   460         if f not in removed:
   418             tn = read(f)
   461             tn = read(f)
   419         if opts.git:
   462         if opts.git:
   420             def gitmode(x):
   463             def gitmode(x):
   421                 return x and '100755' or '100644'
   464                 return x and '100755' or '100644'
   430                 if node2:
   473                 if node2:
   431                     mode = gitmode(mmap2.execf(f))
   474                     mode = gitmode(mmap2.execf(f))
   432                 else:
   475                 else:
   433                     mode = gitmode(util.is_exec(repo.wjoin(f), None))
   476                     mode = gitmode(util.is_exec(repo.wjoin(f), None))
   434                 if f in copied:
   477                 if f in copied:
   435                     a = copied[f]
   478                     a, arev = copied[f]
   436                     omode = gitmode(mmap.execf(a))
   479                     omode = gitmode(mmap.execf(a))
   437                     addmodehdr(header, omode, mode)
   480                     addmodehdr(header, omode, mode)
   438                     op = a in removed and 'rename' or 'copy'
   481                     op = a in removed and 'rename' or 'copy'
   439                     header.append('%s from %s\n' % (op, a))
   482                     header.append('%s from %s\n' % (op, a))
   440                     header.append('%s to %s\n' % (op, f))
   483                     header.append('%s to %s\n' % (op, f))
   441                     to = repo.file(a).read(mmap[a])
   484                     to = getfile(a).read(arev)
   442                 else:
   485                 else:
   443                     header.append('new file mode %s\n' % mode)
   486                     header.append('new file mode %s\n' % mode)
   444             elif f in removed:
   487             elif f in removed:
   445                 if f in srcs:
   488                 if f in srcs:
   446                     dodiff = False
   489                     dodiff = False