merge with crew.
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -10,6 +10,20 @@ import struct, bdiff, util, mpatch
demandload(globals(), "re")
+def splitnewlines(text, keepends=False):
+ '''like str.splitlines, but only split on newlines.'''
+ i = 0
+ lines = []
+ while True:
+ n = text.find('\n', i)
+ if n == -1:
+ last = text[i:]
+ if last:
+ lines.append(last)
+ return lines
+ lines.append(text[i:keepends and n+1 or n])
+ i = n + 1
+
def unidiff(a, ad, b, bd, fn, r=None, text=False,
showfunc=False, ignorews=False):
@@ -19,7 +33,7 @@ def unidiff(a, ad, b, bd, fn, r=None, te
if not text and (util.binary(a) or util.binary(b)):
l = ['Binary file %s has changed\n' % fn]
elif not a:
- b = b.splitlines(1)
+ b = splitnewlines(b, keepends=True)
if a is None:
l1 = "--- %s\t%s\n" % ("/dev/null", epoch)
else:
@@ -28,7 +42,7 @@ def unidiff(a, ad, b, bd, fn, r=None, te
l3 = "@@ -0,0 +1,%d @@\n" % len(b)
l = [l1, l2, l3] + ["+" + e for e in b]
elif not b:
- a = a.splitlines(1)
+ a = splitnewlines(a, keepends=True)
l1 = "--- %s\t%s\n" % ("a/" + fn, ad)
if b is None:
l2 = "+++ %s\t%s\n" % ("/dev/null", epoch)
@@ -37,8 +51,8 @@ def unidiff(a, ad, b, bd, fn, r=None, te
l3 = "@@ -1,%d +0,0 @@\n" % len(a)
l = [l1, l2, l3] + ["-" + e for e in a]
else:
- al = a.splitlines(1)
- bl = b.splitlines(1)
+ al = splitnewlines(a, keepends=True)
+ bl = splitnewlines(b, keepends=True)
l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
showfunc=showfunc, ignorews=ignorews))
if not l: return ""
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -34,10 +34,25 @@ def vlog(*msg):
print m,
print
+def splitnewlines(text):
+ '''like str.splitlines, but only split on newlines.
+ keep line endings.'''
+ i = 0
+ lines = []
+ while True:
+ n = text.find('\n', i)
+ if n == -1:
+ last = text[i:]
+ if last:
+ lines.append(last)
+ return lines
+ lines.append(text[i:n+1])
+ i = n + 1
+
def show_diff(expected, output):
for line in difflib.unified_diff(expected, output,
"Expected output", "Test output", lineterm=''):
- print line
+ sys.stdout.write(line)
def find_program(program):
"""Search PATH for a executable program"""
@@ -125,7 +140,7 @@ def output_coverage():
vlog("# Running: "+cmd)
os.system(cmd)
-def run(cmd, split_lines=True):
+def run(cmd):
"""Run command in a sub-process, capturing the output (stdout and stderr).
Return the exist code, and output."""
# TODO: Use subprocess.Popen if we're running on Python 2.4
@@ -141,9 +156,7 @@ def run(cmd, split_lines=True):
proc.tochild.close()
output = proc.fromchild.read()
ret = proc.wait()
- if split_lines:
- output = output.splitlines()
- return ret, output
+ return ret, splitnewlines(output)
def run_one(test):
vlog("# Test", test)
@@ -180,22 +193,23 @@ def run_one(test):
# If reference output file exists, check test output against it
if os.path.exists(ref):
f = open(ref, "r")
- ref_out = f.read().splitlines()
+ ref_out = splitnewlines(f.read())
f.close()
- if out != ref_out:
- diffret = 1
- print "\nERROR: %s output changed" % (test)
- show_diff(ref_out, out)
+ else:
+ ref_out = ['']
+ if out != ref_out:
+ diffret = 1
+ print "\nERROR: %s output changed" % (test)
+ show_diff(ref_out, out)
if ret:
print "\nERROR: %s failed with error code %d" % (test, ret)
elif diffret:
ret = diffret
if ret != 0: # Save errors to a file for diagnosis
- f = open(err, "w")
+ f = open(err, "wb")
for line in out:
f.write(line)
- f.write("\n")
f.close()
os.chdir(TESTDIR)
new file mode 100755
--- /dev/null
+++ b/tests/test-diff-newlines
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+hg init
+python -c 'print "confuse str.splitlines\nembedded\rnewline"' > a
+hg ci -Ama -d '1 0'
+echo clean diff >> a
+hg ci -mb -d '2 0'
+hg diff -r0 -r1
new file mode 100644
--- /dev/null
+++ b/tests/test-diff-newlines.out
@@ -0,0 +1,8 @@
+adding a
+diff -r 107ba6f817b5 -r 310ce7989cdc a
+--- a/a Thu Jan 01 00:00:01 1970 +0000
++++ b/a Thu Jan 01 00:00:02 1970 +0000
+@@ -1,2 +1,3 @@ confuse str.splitlines
+ confuse str.splitlines
+ embedded
newline
++clean diff