Patchwork [2,of,2,stable] mq: create non-lossy patches, also with custom global diff configuration

login
register
mail settings
Submitter Mads Kiilerich
Date Sept. 10, 2017, 10:43 p.m.
Message ID <987a85c42b08ab2a82cc.1505083408@xps>
Download mbox | patch
Permalink /patch/23749/
State Accepted
Headers show

Comments

Mads Kiilerich - Sept. 10, 2017, 10:43 p.m.
# HG changeset patch
# User Mads Kiilerich <mads@kiilerich.com>
# Date 1505083344 -7200
#      Mon Sep 11 00:42:24 2017 +0200
# Branch stable
# Node ID 987a85c42b08ab2a82cce39b004e00b708320d0e
# Parent  e05e50fbdeaf7eb52a2936e1dfe98643d68c334e
mq: create non-lossy patches, also with custom global diff configuration

Users with custom [diff] configuration most certainly didn't intend it to make
mq lose changes. It could:

 * git is handled perfectly fine.

 * nobinary could make mq leave some files out from the patches.

 * noprefix could make mq itself (and probably also other tools) fail to apply
   patches without the usual a/b prefix.

 * ignorews, ignorewsamount, or ignoreblanklines could create patches with
   missing whitespace that could fail to apply correctly.

Thus, when refreshing patches, use patch.difffeatureopts, optionally with git
as before, but without the config options for whitespace and format changing
that most likely will cause loss or problems.

(patch.diffopts is just patch.difffeatureopts with all options enabled and can
be replaced with that.)

Patch

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -503,8 +503,11 @@  class queue(object):
         self.guardsdirty = False
         self.activeguards = None
 
-    def diffopts(self, opts=None, patchfn=None):
-        diffopts = patchmod.diffopts(self.ui, opts)
+    def diffopts(self, opts=None, patchfn=None, plain=False):
+        """Return diff options tweaked for this mq use, possibly upgrading to
+        git format, and possibly plain and without lossy options."""
+        diffopts = patchmod.difffeatureopts(self.ui, opts,
+            git=True, whitespace=not plain, formatchanging=not plain)
         if self.gitmode == 'auto':
             diffopts.upgrade = True
         elif self.gitmode == 'keep':
@@ -1177,7 +1180,7 @@  class queue(object):
         date = opts.get('date')
         if date:
             date = util.parsedate(date)
-        diffopts = self.diffopts({'git': opts.get('git')})
+        diffopts = self.diffopts({'git': opts.get('git')}, plain=True)
         if opts.get('checkname', True):
             self.checkpatchname(patchfn)
         inclsubs = checksubstate(repo)
@@ -1642,7 +1645,8 @@  class queue(object):
                 substatestate = repo.dirstate['.hgsubstate']
 
             ph = patchheader(self.join(patchfn), self.plainmode)
-            diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
+            diffopts = self.diffopts({'git': opts.get('git')}, patchfn,
+                                     plain=True)
             if newuser:
                 ph.setuser(newuser)
             if newdate:
diff --git a/tests/test-mq-git.t b/tests/test-mq-git.t
--- a/tests/test-mq-git.t
+++ b/tests/test-mq-git.t
@@ -235,13 +235,35 @@  Test how [diff] configuration influence 
   # Date 0 0
   # Parent  cf0bfe72686a47d8d7d7b4529a3adb8b0b449a9f
   
+  diff -r cf0bfe72686a -r fb9c4422b0f3 a
+  --- a/a
+  +++ b/a
+  @@ -1,1 +1,1 @@
+  -a
+  + a
   $ cat .hg/patches/diff
   # HG changeset patch
   # Date 0 0
   # Parent  fb9c4422b0f37dd576522dd9a3f99b825c177efe
   
-  diff --git b b
-  Binary file b has changed
+  diff --git a/a b/a
+  --- a/a
+  +++ b/a
+  @@ -1,1 +1,1 @@
+  - a
+  +  a
+  diff --git a/b b/b
+  index 78981922613b2afb6025042ff6bd878ac1994e85..f76dd238ade08917e6712764a16a22005a50573d
+  GIT binary patch
+  literal 1
+  Ic${MZ000310RR91
+  
+  diff --git a/c b/c
+  --- a/c
+  +++ b/c
+  @@ -1,1 +1,2 @@
+   a
+  +
 
   $ cd ..