##// END OF EJS Templates
Switch cat command to use walk code....
Switch cat command to use walk code. The old syntax of "hg cat FILE REV" is now obsolete. Use "hg cat -r REV FILE" instead, as for all other commands.

File last commit:

r1015:22571b8d default
r1254:e6560042 default
Show More
mdiff.py
123 lines | 3.0 KiB | text/x-python | PythonLexer
mpm@selenic.com
mdiff.py: kill #! line, add copyright notice...
r239 # mdiff.py - diff and patch routines for mercurial
#
# Copyright 2005 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
mpm@selenic.com
Start using bdiff for generating deltas...
r432 import difflib, struct, bdiff
from mpatch import *
mpm@selenic.com
Add automatic binary file detection to diff and export...
r1015 from util import *
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0
mpm@selenic.com
Add automatic binary file detection to diff and export...
r1015 def unidiff(a, ad, b, bd, fn, r=None, text=False):
Thomas Arendsen Hein
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli....
r396
mpm@selenic.com
unidiff: punt on comparing empty files
r35 if not a and not b: return ""
mpm@selenic.com
Attempt to make diff deal with null sources properly...
r264
mpm@selenic.com
Add automatic binary file detection to diff and export...
r1015 if not text and (binary(a) or binary(b)):
l = ['Binary file %s has changed\n' % fn]
elif a == None:
mpm@selenic.com
Attempt to make diff deal with null sources properly...
r264 b = b.splitlines(1)
l1 = "--- %s\t%s\n" % ("/dev/null", ad)
l2 = "+++ %s\t%s\n" % ("b/" + fn, bd)
l3 = "@@ -0,0 +1,%d @@\n" % len(b)
l = [l1, l2, l3] + ["+" + e for e in b]
elif b == None:
a = a.splitlines(1)
l1 = "--- %s\t%s\n" % ("a/" + fn, ad)
l2 = "+++ %s\t%s\n" % ("/dev/null", bd)
l3 = "@@ -1,%d +0,0 @@\n" % len(a)
l = [l1, l2, l3] + ["-" + e for e in a]
else:
a = a.splitlines(1)
b = b.splitlines(1)
mpm@selenic.com
diff: use tab to separate date from filename...
r272 l = list(difflib.unified_diff(a, b, "a/" + fn, "b/" + fn))
mpm@selenic.com
unidiff: handle empty diffs more gracefully...
r278 if not l: return ""
mpm@selenic.com
diff: use tab to separate date from filename...
r272 # difflib uses a space, rather than a tab
l[0] = l[0][:-2] + "\t" + ad + "\n"
l[1] = l[1][:-2] + "\t" + bd + "\n"
mpm@selenic.com
hg diff: fix missing final newline bug
r170
for ln in xrange(len(l)):
if l[ln][-1] != '\n':
l[ln] += "\n\ No newline at end of file\n"
Thomas Arendsen Hein
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli....
r396 if r:
l.insert(0, "diff %s %s\n" %
(' '.join(["-r %s" % rev for rev in r]), fn))
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 return "".join(l)
def sortdiff(a, b):
la = lb = 0
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 lena = len(a)
lenb = len(b)
mpm@selenic.com
Whitespace cleanups...
r515
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 while 1:
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 am, bm, = la, lb
# walk over matching lines
mpm@selenic.com
mdiff: fix the fix...
r326 while lb < lenb and la < lena and a[la] == b[lb] :
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 la += 1
lb += 1
mpm@selenic.com
mdiff: revert grouping optimization for the time being...
r318
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 if la > am:
yield (am, bm, la - am) # return a match
# skip mismatched lines from b
mpm@selenic.com
Fix another sortdiff cornercase...
r361 while la < lena and lb < lenb and b[lb] < a[la]:
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 lb += 1
mpm@selenic.com
mdiff: revert grouping optimization for the time being...
r318
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 if lb >= lenb:
break
mpm@selenic.com
Whitespace cleanups...
r515
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 # skip mismatched lines from a
mpm@selenic.com
Fix another sortdiff cornercase...
r361 while la < lena and lb < lenb and b[lb] > a[la]:
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 la += 1
if la >= lena:
break
mpm@selenic.com
Whitespace cleanups...
r515
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 yield (lena, lenb, 0)
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0
def diff(a, b, sorted=0):
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 if not a:
s = "".join(b)
return s and (struct.pack(">lll", 0, 0, len(s)) + s)
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 bin = []
p = [0]
for i in a: p.append(p[-1] + len(i))
if sorted:
mpm@selenic.com
hg commit: user and date options...
r317 try:
d = sortdiff(a, b)
except:
raise
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 else:
mpm@selenic.com
mdiff: reinstate new algorithm...
r325 d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
la = 0
lb = 0
for am, bm, size in d:
s = "".join(b[lb:bm])
if am > la or s:
bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
la = am + size
lb = bm + size
mpm@selenic.com
Whitespace cleanups...
r515
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 return "".join(bin)
mpm@selenic.com
Add a function to return the new text from a binary diff
r120 def patchtext(bin):
pos = 0
t = []
while pos < len(bin):
p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
pos += 12
t.append(bin[pos:pos + l])
pos += l
return "".join(t)
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 def patch(a, bin):
mpm@selenic.com
Add an O(m + nlog n) patching extension
r72 return patches(a, [bin])
mpm@selenic.com
Start using bdiff for generating deltas...
r432
textdiff = bdiff.bdiff