[PATCH] Added option to normalize line endings when patching (issue1019)

Colin Caughie c.caughie at indigovision.com
Thu Jun 4 16:49:52 CDT 2009


# HG changeset patch
# User Colin Caughie <c.caughie at indigovision.com>
# Date 1244151854 -3600
# Node ID b0e557ccca4ba3b2ca31c5496346ef2d14d90eee
# Parent  dd3ebf81af433e37d301b3093f7e151bb52e01f8
Added option to normalize line endings when patching (issue1019)

This adds an option patch.eol that can be used to a) normalize the line endings
of the input file when applying a patch, and b) replace all line endings with
a fixed value when writing the output file.
This fixes the import command for win32text users, as well as mq, transplant
et al. It does not attempt to fix all possible line ending issues.

diff -r dd3ebf81af43 -r b0e557ccca4b mercurial/patch.py
--- a/mercurial/patch.py        Wed Jun 03 17:12:48 2009 -0500
+++ b/mercurial/patch.py        Thu Jun 04 22:44:14 2009 +0100
@@ -13,6 +13,7 @@
 import sys, tempfile, zlib

 gitre = re.compile('diff --git a/(.*) b/(.*)')
+eolre = re.compile('[\r\n]+')

 class PatchError(Exception):
     pass
@@ -239,6 +240,17 @@
         self.ui = ui
         self.lines = []
         self.exists = False
+        eolopt = self.ui.config('patch', 'eol')
+        if eolopt:
+            if eolopt == 'crlf':
+                self.eol = '\r\n'
+            elif eolopt == 'lf':
+                self.eol = '\n'
+            else:
+                raise util.Abort(_('invalid eol option: %s') % eolopt)
+        else:
+            self.eol = None
+
         self.missing = missing
         if not missing:
             try:
@@ -260,14 +272,20 @@
     def readlines(self, fname):
         fp = self.opener(fname, 'r')
         try:
-            return fp.readlines()
+            if not self.eol:
+                return fp.readlines()
+            else:
+                return [eolre.sub('\n', l) for l in fp.readlines()]
         finally:
             fp.close()

     def writelines(self, fname, lines):
         fp = self.opener(fname, 'w')
         try:
-            fp.writelines(lines)
+            if not self.eol:
+                fp.writelines(lines)
+            else:
+                fp.writelines([eolre.sub(self.eol, l) for l in lines])
         finally:
             fp.close()

diff -r dd3ebf81af43 -r b0e557ccca4b tests/test-patch-eol
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-patch-eol      Thu Jun 04 22:44:14 2009 +0100
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+cat > print.py <<EOF
+import sys
+print(sys.stdin.read().replace('\n', '<LF>').replace('\r', '<CR>').replace('\0', '<NUL>'))
+EOF
+
+hg init a
+mkdir a/d1
+mkdir a/d1/d2
+cat > a/a <<EOF
+Line1
+Line2
+Line3
+Line4
+EOF
+cat > a/d1/d2/a <<EOF
+LineA
+LineB
+LineC
+LineD
+EOF
+hg --cwd a ci -Ama
+
+cat > a/a <<EOF
+Inserted line
+Line1
+Line3
+Line4 changed
+EOF
+cat > a/d1/d2/a <<EOF
+LineA
+Inserted line
+LineB
+LineD changed
+EOF
+
+hg --cwd a ci -u someone -d '1 0' -m'second change'
+
+echo % import exported patch with eol=crlf
+hg clone -r0 -U a b
+
+echo '[extensions]' >> b/.hg/hgrc
+echo 'win32text = ' >> b/.hg/hgrc
+echo '[decode]' >> b/.hg/hgrc
+echo '** = cleverdecode:' >> b/.hg/hgrc
+echo '[encode]' >> b/.hg/hgrc
+echo '** = cleverencode:' >> b/.hg/hgrc
+echo '[patch]' >> b/.hg/hgrc
+echo 'eol=crlf' >> b/.hg/hgrc
+
+hg --cwd b update
+hg --cwd a export tip > tip.patch
+hg --cwd b import ../tip.patch
+
+echo % check diff is correct
+hg --cwd b tip -p
+
+echo % check output eols are correct
+python print.py < b/a
+python print.py < b/d1/d2/a
+
+echo % import exported patch with eol=lf
+hg clone -r0 -U a c
+
+echo '[extensions]' >> c/.hg/hgrc
+echo 'win32text = ' >> c/.hg/hgrc
+echo '[decode]' >> c/.hg/hgrc
+echo '** = cleverdecode:' >> c/.hg/hgrc
+echo '[encode]' >> c/.hg/hgrc
+echo '** = cleverencode:' >> c/.hg/hgrc
+echo '[patch]' >> c/.hg/hgrc
+echo 'eol=lf' >> c/.hg/hgrc
+
+hg --cwd c update
+hg --cwd a export tip > tip.patch
+hg --cwd c import ../tip.patch
+
+echo % check diff is correct
+hg --cwd c tip -p
+
+echo % check output eols are correct
+python print.py < c/a
+python print.py < c/d1/d2/a
+
+rm -r a
+rm -r b
+rm -r c
diff -r dd3ebf81af43 -r b0e557ccca4b tests/test-patch-eol.out
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-patch-eol.out  Thu Jun 04 22:44:14 2009 +0100
@@ -0,0 +1,80 @@
+adding a
+adding d1/d2/a
+% import exported patch with eol=crlf
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 2 changes to 2 files
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+applying ../tip.patch
+% check diff is correct
+changeset:   1:b9f56dcdd816
+tag:         tip
+user:        someone
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     second change
+
+diff -r 373c0b1d4bc3 -r b9f56dcdd816 a
+--- a/a        Thu Jan 01 00:00:00 1970 +0000
++++ b/a        Thu Jan 01 00:00:01 1970 +0000
+@@ -1,4 +1,4 @@
++Inserted line
+ Line1
+-Line2
+ Line3
+-Line4
++Line4 changed
+diff -r 373c0b1d4bc3 -r b9f56dcdd816 d1/d2/a
+--- a/d1/d2/a  Thu Jan 01 00:00:00 1970 +0000
++++ b/d1/d2/a  Thu Jan 01 00:00:01 1970 +0000
+@@ -1,4 +1,4 @@
+ LineA
++Inserted line
+ LineB
+-LineC
+-LineD
++LineD changed
+
+% check output eols are correct
+Inserted line<CR><LF>Line1<CR><LF>Line3<CR><LF>Line4 changed<CR><LF>
+LineA<CR><LF>Inserted line<CR><LF>LineB<CR><LF>LineD changed<CR><LF>
+% import exported patch with eol=lf
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 2 changes to 2 files
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+applying ../tip.patch
+% check diff is correct
+changeset:   1:b9f56dcdd816
+tag:         tip
+user:        someone
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     second change
+
+diff -r 373c0b1d4bc3 -r b9f56dcdd816 a
+--- a/a        Thu Jan 01 00:00:00 1970 +0000
++++ b/a        Thu Jan 01 00:00:01 1970 +0000
+@@ -1,4 +1,4 @@
++Inserted line
+ Line1
+-Line2
+ Line3
+-Line4
++Line4 changed
+diff -r 373c0b1d4bc3 -r b9f56dcdd816 d1/d2/a
+--- a/d1/d2/a  Thu Jan 01 00:00:00 1970 +0000
++++ b/d1/d2/a  Thu Jan 01 00:00:01 1970 +0000
+@@ -1,4 +1,4 @@
+ LineA
++Inserted line
+ LineB
+-LineC
+-LineD
++LineD changed
+
+% check output eols are correct
+Inserted line<LF>Line1<LF>Line3<LF>Line4 changed<LF>
+LineA<LF>Inserted line<LF>LineB<LF>LineD changed<LF>


Latest News at: http://www.indigovision.com/news2009.php



More information about the Mercurial-devel mailing list