--- a/mercurial/patch.py Wed Aug 16 19:46:18 2006 -0700
+++ b/mercurial/patch.py Wed Aug 16 19:49:45 2006 -0700
@@ -343,10 +343,27 @@
if not node1:
node1 = repo.dirstate.parents()[0]
+
+ clcache = {}
+ def getchangelog(n):
+ if n not in clcache:
+ clcache[n] = repo.changelog.read(n)
+ return clcache[n]
+ mcache = {}
+ def getmanifest(n):
+ if n not in mcache:
+ mcache[n] = repo.manifest.read(n)
+ return mcache[n]
+ fcache = {}
+ def getfile(f):
+ if f not in fcache:
+ fcache[f] = repo.file(f)
+ return fcache[f]
+
# reading the data for node1 early allows it to play nicely
# with repo.status and the revlog cache.
- change = repo.changelog.read(node1)
- mmap = repo.manifest.read(change[0])
+ change = getchangelog(node1)
+ mmap = getmanifest(change[0])
date1 = util.datestr(change[2])
if not changes:
@@ -367,17 +384,32 @@
if not modified and not added and not removed:
return
+ def renamedbetween(f, n1, n2):
+ r1, r2 = map(repo.changelog.rev, (n1, n2))
+ src = None
+ while r2 > r1:
+ cl = getchangelog(n2)[0]
+ m = getmanifest(cl)
+ try:
+ src = getfile(f).renamed(m[f])
+ except KeyError:
+ return None
+ if src:
+ f = src[0]
+ n2 = repo.changelog.parents(n2)[0]
+ r2 = repo.changelog.rev(n2)
+ return src
+
if node2:
- change = repo.changelog.read(node2)
- mmap2 = repo.manifest.read(change[0])
+ change = getchangelog(node2)
+ mmap2 = getmanifest(change[0])
_date2 = util.datestr(change[2])
def date2(f):
return _date2
def read(f):
- return repo.file(f).read(mmap2[f])
+ return getfile(f).read(mmap2[f])
def renamed(f):
- src = repo.file(f).renamed(mmap2[f])
- return src and src[0] or None
+ return renamedbetween(f, node1, node2)
else:
tz = util.makedate()[1]
_date2 = util.datestr()
@@ -390,7 +422,18 @@
def read(f):
return repo.wread(f)
def renamed(f):
- return repo.dirstate.copies.get(f)
+ src = repo.dirstate.copies.get(f)
+ parent = repo.dirstate.parents()[0]
+ if src:
+ f = src[0]
+ of = renamedbetween(f, node1, parent)
+ if of:
+ return of
+ elif src:
+ cl = getchangelog(parent)[0]
+ return (src, getmanifest(cl)[src])
+ else:
+ return None
if repo.ui.quiet:
r = None
@@ -404,7 +447,7 @@
src = renamed(f)
if src:
copied[f] = src
- srcs = [x[1] for x in copied.items()]
+ srcs = [x[1][0] for x in copied.items()]
all = modified + added + removed
all.sort()
@@ -413,7 +456,7 @@
tn = None
dodiff = True
if f in mmap:
- to = repo.file(f).read(mmap[f])
+ to = getfile(f).read(mmap[f])
if f not in removed:
tn = read(f)
if opts.git:
@@ -432,13 +475,13 @@
else:
mode = gitmode(util.is_exec(repo.wjoin(f), None))
if f in copied:
- a = copied[f]
+ a, arev = copied[f]
omode = gitmode(mmap.execf(a))
addmodehdr(header, omode, mode)
op = a in removed and 'rename' or 'copy'
header.append('%s from %s\n' % (op, a))
header.append('%s to %s\n' % (op, f))
- to = repo.file(a).read(mmap[a])
+ to = getfile(a).read(arev)
else:
header.append('new file mode %s\n' % mode)
elif f in removed: