patch: write .rej files without rewriting EOLs stable
authorPatrick Mezard <pmezard@gmail.com>
Fri, 03 Dec 2010 11:40:30 +0900
branchstable
changeset 13100 66d7a1250c9b
parent 13073 acebcefa86d4
child 13102 2956945c3bee
patch: write .rej files without rewriting EOLs Do not pass reject file content to patchfile.writelines() to: - Avoid line endings transformations - Avoid polluting overriding implementations with unrelated data. They should override write_rej() to deal or ignore reject files properly. Bug report, analysis and original patch and test by Shun-ichi GOTO <shunichi.goto@gmail.com>
mercurial/patch.py
tests/test-mq-eol.t
--- a/mercurial/patch.py	Thu Dec 02 01:28:38 2010 -0200
+++ b/mercurial/patch.py	Fri Dec 03 11:40:30 2010 +0900
@@ -485,6 +485,15 @@
         for x, s in enumerate(self.lines):
             self.hash.setdefault(s, []).append(x)
 
+    def makerejlines(self, fname):
+        base = os.path.basename(fname)
+        yield "--- %s\n+++ %s\n" % (base, base)
+        for x in self.rej:
+            for l in x.hunk:
+                yield l
+                if l[-1] != '\n':
+                    yield "\n\ No newline at end of file\n"
+
     def write_rej(self):
         # our rejects are a little different from patch(1).  This always
         # creates rejects in the same form as the original patch.  A file
@@ -499,16 +508,9 @@
             _("%d out of %d hunks FAILED -- saving rejects to file %s\n") %
             (len(self.rej), self.hunks, fname))
 
-        def rejlines():
-            base = os.path.basename(self.fname)
-            yield "--- %s\n+++ %s\n" % (base, base)
-            for x in self.rej:
-                for l in x.hunk:
-                    yield l
-                    if l[-1] != '\n':
-                        yield "\n\ No newline at end of file\n"
-
-        self.writelines(fname, rejlines())
+        fp = self.opener(fname, 'w')
+        fp.writelines(self.makerejlines(self.fname))
+        fp.close()
 
     def apply(self, h):
         if not h.complete():
--- a/tests/test-mq-eol.t	Thu Dec 02 01:28:38 2010 -0200
+++ b/tests/test-mq-eol.t	Fri Dec 03 11:40:30 2010 +0900
@@ -141,3 +141,67 @@
   $ hg qpop
   popping eol.diff
   patch queue now empty
+  $ cd ..
+
+
+Test .rej file EOL are left unchanged
+
+  $ hg init testeol
+  $ cd testeol
+  $ python -c "file('a', 'wb').write('1\r\n2\r\n3\r\n4')"
+  $ hg ci -Am adda
+  adding a
+  $ python -c "file('a', 'wb').write('1\r\n2\r\n33\r\n4')"
+  $ hg qnew patch1
+  $ hg qpop
+  popping patch1
+  patch queue now empty
+  $ python -c "file('a', 'wb').write('1\r\n22\r\n33\r\n4')"
+  $ hg ci -m changea
+
+  $ hg --config 'patch.eol=LF' qpush
+  applying patch1
+  patching file a
+  Hunk #1 FAILED at 0
+  1 out of 1 hunks FAILED -- saving rejects to file a.rej
+  patch failed, unable to continue (try -v)
+  patch failed, rejects left in working dir
+  errors during apply, please fix and refresh patch1
+  [2]
+  $ hg qpop
+  popping patch1
+  patch queue now empty
+  $ cat a.rej
+  --- a
+  +++ a
+  @@ -1,4 +1,4 @@
+   1\r (esc)
+   2\r (esc)
+  -3\r (esc)
+  +33\r (esc)
+   4
+  \ No newline at end of file
+
+  $ hg --config 'patch.eol=auto' qpush
+  applying patch1
+  patching file a
+  Hunk #1 FAILED at 0
+  1 out of 1 hunks FAILED -- saving rejects to file a.rej
+  patch failed, unable to continue (try -v)
+  patch failed, rejects left in working dir
+  errors during apply, please fix and refresh patch1
+  [2]
+  $ hg qpop
+  popping patch1
+  patch queue now empty
+  $ cat a.rej
+  --- a
+  +++ a
+  @@ -1,4 +1,4 @@
+   1\r (esc)
+   2\r (esc)
+  -3\r (esc)
+  +33\r (esc)
+   4
+  \ No newline at end of file
+  $ cd ..