[PATCH] patch: write .rej files without rewriting EOLs

Patrick Mezard pmezard at gmail.com
Mon Dec 6 15:11:32 CST 2010


# HG changeset patch
# User Patrick Mezard <pmezard at gmail.com>
# Date 1291344030 -32400
# Branch stable
# Node ID 6956d1fec7502a91e135afbc77968734005a0ba0
# Parent  5e51254ad4d4c80669f462e310b2677f2b3c54a7
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 at gmail.com>

diff -r 5e51254ad4d4 -r 6956d1fec750 mercurial/patch.py
--- a/mercurial/patch.py	Wed Dec 01 18:46:20 2010 -0600
+++ 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():
diff -r 5e51254ad4d4 -r 6956d1fec750 tests/test-mq-eol.t
--- a/tests/test-mq-eol.t	Wed Dec 01 18:46:20 2010 -0600
+++ 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 ..


More information about the Mercurial-devel mailing list