diff mbox series

parser: recognise git commit consisting only of empty new file

Message ID 20190228042953.29432-1-dja@axtens.net
State Accepted
Headers show
Series parser: recognise git commit consisting only of empty new file | expand

Commit Message

Daniel Axtens Feb. 28, 2019, 4:29 a.m. UTC
Commits with only an empty new file are liable to be missed.
The parser state machine doesn't recognise the headers "new
file mode" and "index": teach it about them.

Add a test to demonstrate.

It's a little bit academic as you don't usually send patches like
that but sometimes you do, especially if you're a snowpatch dev :)

Closes: #256
Reported-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---

Apologies for the long radio silence. I'm now in a job where Patchwork
is slightly adjacent to my role, so I have a bit more flexibility to work
on it. The usual lack of promises apply.
---
 patchwork/parser.py                           | 10 +++---
 .../tests/mail/0021-git-empty-new-file.mbox   | 32 +++++++++++++++++++
 patchwork/tests/test_parser.py                |  5 +++
 3 files changed, 43 insertions(+), 4 deletions(-)
 create mode 100644 patchwork/tests/mail/0021-git-empty-new-file.mbox

Comments

Andrew Donnellan Feb. 28, 2019, 4:38 a.m. UTC | #1
On 28/2/19 3:29 pm, Daniel Axtens wrote:
> Commits with only an empty new file are liable to be missed.
> The parser state machine doesn't recognise the headers "new
> file mode" and "index": teach it about them.
> 
> Add a test to demonstrate.
> 
> It's a little bit academic as you don't usually send patches like
> that but sometimes you do, especially if you're a snowpatch dev :)
> 
> Closes: #256
> Reported-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> Signed-off-by: Daniel Axtens <dja@axtens.net>

LGTM, thanks for fixing this

Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>

> ---
> 
> Apologies for the long radio silence. I'm now in a job where Patchwork
> is slightly adjacent to my role, so I have a bit more flexibility to work
> on it. The usual lack of promises apply.
> ---
>   patchwork/parser.py                           | 10 +++---
>   .../tests/mail/0021-git-empty-new-file.mbox   | 32 +++++++++++++++++++
>   patchwork/tests/test_parser.py                |  5 +++
>   3 files changed, 43 insertions(+), 4 deletions(-)
>   create mode 100644 patchwork/tests/mail/0021-git-empty-new-file.mbox
> 
> diff --git a/patchwork/parser.py b/patchwork/parser.py
> index 946b66851d7c..712780a498c4 100644
> --- a/patchwork/parser.py
> +++ b/patchwork/parser.py
> @@ -742,7 +742,7 @@ def parse_patch(content):
>       # 3: patch header line 2 (+++)
>       # 4: patch hunk header line (@@ line)
>       # 5: patch hunk content
> -    # 6: patch meta header (rename from/rename to)
> +    # 6: patch meta header (rename from/rename to/new file/index)
>       #
>       # valid transitions:
>       #  0 -> 1 (diff, Index:)
> @@ -752,7 +752,7 @@ def parse_patch(content):
>       #  3 -> 4 (@@ line)
>       #  4 -> 5 (patch content)
>       #  5 -> 1 (run out of lines from @@-specifed count)
> -    #  1 -> 6 (rename from / rename to)
> +    #  1 -> 6 (rename from / rename to / new file / index)
>       #  6 -> 2 (---)
>       #  6 -> 1 (other text)
>       #
> @@ -782,7 +782,8 @@ def parse_patch(content):
>               if line.startswith('--- '):
>                   state = 2
>   
> -            if line.startswith(('rename from ', 'rename to ')):
> +            if line.startswith(('rename from ', 'rename to ',
> +                                'new file mode ', 'index ')):
>                   state = 6
>           elif state == 2:
>               if line.startswith('+++ '):
> @@ -843,7 +844,8 @@ def parse_patch(content):
>               else:
>                   state = 5
>           elif state == 6:
> -            if line.startswith(('rename to ', 'rename from ')):
> +            if line.startswith(('rename to ', 'rename from ',
> +                                'new file mode ', 'index ')):
>                   patchbuf += buf + line
>                   buf = ''
>               elif line.startswith('--- '):
> diff --git a/patchwork/tests/mail/0021-git-empty-new-file.mbox b/patchwork/tests/mail/0021-git-empty-new-file.mbox
> new file mode 100644
> index 000000000000..c3be48e6eb39
> --- /dev/null
> +++ b/patchwork/tests/mail/0021-git-empty-new-file.mbox
> @@ -0,0 +1,32 @@
> +From andrew.donnellan@au1.ibm.com Thu Feb 28 00:37:42 2019
> +Delivered-To: dja@axtens.net
> +Received: by 2002:a4a:2812:0:0:0:0:0 with SMTP id h18csp2242ooa;
> +        Wed, 27 Feb 2019 16:37:59 -0800 (PST)
> +From: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> +Subject: [snowpatch] [PATCH 1/3] Test commit; please ignore
> +To: Daniel Axtens <dja@axtens.net>
> +Date: Thu, 28 Feb 2019 11:37:42 +1100
> +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
> + Thunderbird/60.5.1
> +MIME-Version: 1.0
> +Content-Language: en-AU
> +
> +
> +Doing some snowpatching.
> +---
> +  banana | 0
> +  1 file changed, 0 insertions(+), 0 deletions(-)
> +  create mode 100644 banana
> +
> +diff --git a/banana b/banana
> +new file mode 100644
> +index 000000000000..e69de29bb2d1
> +--
> +2.11.0
> +
> +_______________________________________________
> +snowpatch mailing list
> +snowpatch@lists.ozlabs.org
> +https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.ozlabs.org_listinfo_snowpatch&d=DwIDAg&c=jf_iaSHvJObTbx-siA1ZOg&r=-pHOU8dm1U-U1crivyxKr_-xvZrIBB8YUqvA3el0Ee0&m=VWJFv-r8DBhr5gE3qkDHngtXenfi5deVGQpQcAyKocY&s=pn_W97wan_5Uwi-2wli6N87gaeoNFy7pchZS_cPHtOY&e=
> +
> +
> diff --git a/patchwork/tests/test_parser.py b/patchwork/tests/test_parser.py
> index 664edd5bab44..ddbcf5b15a19 100644
> --- a/patchwork/tests/test_parser.py
> +++ b/patchwork/tests/test_parser.py
> @@ -583,6 +583,11 @@ class PatchParseTest(PatchTest):
>           self.assertEqual(diff.count("\nrename to "), 2)
>           self.assertEqual(diff.count('\n-a\n+b'), 1)
>   
> +    def test_git_new_empty_file(self):
> +        diff, message = self._find_content('0021-git-empty-new-file.mbox')
> +        self.assertTrue(diff is not None)
> +        self.assertTrue(message is not None)
> +
>       def test_cvs_format(self):
>           diff, message = self._find_content('0007-cvs-format-diff.mbox')
>           self.assertTrue(diff.startswith('Index'))
>
Stephen Finucane March 2, 2019, 1:07 p.m. UTC | #2
On Thu, 2019-02-28 at 15:29 +1100, Daniel Axtens wrote:
> Commits with only an empty new file are liable to be missed.
> The parser state machine doesn't recognise the headers "new
> file mode" and "index": teach it about them.
> 
> Add a test to demonstrate.
> 
> It's a little bit academic as you don't usually send patches like
> that but sometimes you do, especially if you're a snowpatch dev :)
> 
> Closes: #256
> Reported-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> Signed-off-by: Daniel Axtens <dja@axtens.net>

Reviewed-by: Stephen Finucane <stephen@that.guru>

...and applied. Thanks!
Daniel Axtens March 7, 2019, 3:01 a.m. UTC | #3
Stephen Finucane <stephen@that.guru> writes:

> On Thu, 2019-02-28 at 15:29 +1100, Daniel Axtens wrote:
>> Commits with only an empty new file are liable to be missed.
>> The parser state machine doesn't recognise the headers "new
>> file mode" and "index": teach it about them.
>> 
>> Add a test to demonstrate.
>> 
>> It's a little bit academic as you don't usually send patches like
>> that but sometimes you do, especially if you're a snowpatch dev :)
>> 
>> Closes: #256
>> Reported-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
>> Signed-off-by: Daniel Axtens <dja@axtens.net>
>
> Reviewed-by: Stephen Finucane <stephen@that.guru>
>
> ...and applied. Thanks!

Thanks! Should we apply this to stable as well? (I'm happy to do the
legwork and apply it if you're OK with it.)

Regards,
Daniel
Stephen Finucane March 7, 2019, 11:53 a.m. UTC | #4
On Thu, 2019-03-07 at 14:01 +1100, Daniel Axtens wrote:
> Stephen Finucane <stephen@that.guru> writes:
> 
> > On Thu, 2019-02-28 at 15:29 +1100, Daniel Axtens wrote:
> > > Commits with only an empty new file are liable to be missed.
> > > The parser state machine doesn't recognise the headers "new
> > > file mode" and "index": teach it about them.
> > > 
> > > Add a test to demonstrate.
> > > 
> > > It's a little bit academic as you don't usually send patches like
> > > that but sometimes you do, especially if you're a snowpatch dev :)
> > > 
> > > Closes: #256
> > > Reported-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> > > Signed-off-by: Daniel Axtens <dja@axtens.net>
> > 
> > Reviewed-by: Stephen Finucane <stephen@that.guru>
> > 
> > ...and applied. Thanks!
> 
> Thanks! Should we apply this to stable as well? (I'm happy to do the
> legwork and apply it if you're OK with it.)
> 
> Regards,
> Daniel

Already done [1] :) I guess we should cut another release there
shortly. Might be almost time for a v2.2.0 too?

Stephen

[1] https://github.com/getpatchwork/patchwork/commit/0c60d688d0ac3cf41477970b9c8d299ef1d4227b
diff mbox series

Patch

diff --git a/patchwork/parser.py b/patchwork/parser.py
index 946b66851d7c..712780a498c4 100644
--- a/patchwork/parser.py
+++ b/patchwork/parser.py
@@ -742,7 +742,7 @@  def parse_patch(content):
     # 3: patch header line 2 (+++)
     # 4: patch hunk header line (@@ line)
     # 5: patch hunk content
-    # 6: patch meta header (rename from/rename to)
+    # 6: patch meta header (rename from/rename to/new file/index)
     #
     # valid transitions:
     #  0 -> 1 (diff, Index:)
@@ -752,7 +752,7 @@  def parse_patch(content):
     #  3 -> 4 (@@ line)
     #  4 -> 5 (patch content)
     #  5 -> 1 (run out of lines from @@-specifed count)
-    #  1 -> 6 (rename from / rename to)
+    #  1 -> 6 (rename from / rename to / new file / index)
     #  6 -> 2 (---)
     #  6 -> 1 (other text)
     #
@@ -782,7 +782,8 @@  def parse_patch(content):
             if line.startswith('--- '):
                 state = 2
 
-            if line.startswith(('rename from ', 'rename to ')):
+            if line.startswith(('rename from ', 'rename to ',
+                                'new file mode ', 'index ')):
                 state = 6
         elif state == 2:
             if line.startswith('+++ '):
@@ -843,7 +844,8 @@  def parse_patch(content):
             else:
                 state = 5
         elif state == 6:
-            if line.startswith(('rename to ', 'rename from ')):
+            if line.startswith(('rename to ', 'rename from ',
+                                'new file mode ', 'index ')):
                 patchbuf += buf + line
                 buf = ''
             elif line.startswith('--- '):
diff --git a/patchwork/tests/mail/0021-git-empty-new-file.mbox b/patchwork/tests/mail/0021-git-empty-new-file.mbox
new file mode 100644
index 000000000000..c3be48e6eb39
--- /dev/null
+++ b/patchwork/tests/mail/0021-git-empty-new-file.mbox
@@ -0,0 +1,32 @@ 
+From andrew.donnellan@au1.ibm.com Thu Feb 28 00:37:42 2019
+Delivered-To: dja@axtens.net
+Received: by 2002:a4a:2812:0:0:0:0:0 with SMTP id h18csp2242ooa;
+        Wed, 27 Feb 2019 16:37:59 -0800 (PST)
+From: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Subject: [snowpatch] [PATCH 1/3] Test commit; please ignore
+To: Daniel Axtens <dja@axtens.net>
+Date: Thu, 28 Feb 2019 11:37:42 +1100
+User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
+ Thunderbird/60.5.1
+MIME-Version: 1.0
+Content-Language: en-AU
+
+
+Doing some snowpatching.
+---
+  banana | 0
+  1 file changed, 0 insertions(+), 0 deletions(-)
+  create mode 100644 banana
+
+diff --git a/banana b/banana
+new file mode 100644
+index 000000000000..e69de29bb2d1
+-- 
+2.11.0
+
+_______________________________________________
+snowpatch mailing list
+snowpatch@lists.ozlabs.org
+https://lists.ozlabs.org/listinfo/snowpatch
+
+
diff --git a/patchwork/tests/test_parser.py b/patchwork/tests/test_parser.py
index 664edd5bab44..ddbcf5b15a19 100644
--- a/patchwork/tests/test_parser.py
+++ b/patchwork/tests/test_parser.py
@@ -583,6 +583,11 @@  class PatchParseTest(PatchTest):
         self.assertEqual(diff.count("\nrename to "), 2)
         self.assertEqual(diff.count('\n-a\n+b'), 1)
 
+    def test_git_new_empty_file(self):
+        diff, message = self._find_content('0021-git-empty-new-file.mbox')
+        self.assertTrue(diff is not None)
+        self.assertTrue(message is not None)
+
     def test_cvs_format(self):
         diff, message = self._find_content('0007-cvs-format-diff.mbox')
         self.assertTrue(diff.startswith('Index'))