Commit 5bcb896f authored by Arkadiusz Hiler's avatar Arkadiusz Hiler

parsemail: Catch errors caused by duplicate patches in revision

Let's assume mail structure with replies like this:

[1/2] Patch 1
  |- [2/2] Patch 2
  |- [2/2] Another Patch 2

When the "Another Patch 2" comes in, it's going to get inserted in the
same revision at the same place as the original "Patch 2", which results
in integrity error.

This is the single most common reason for administration notifications.

There is not really much we can do, as the reasons for such emails are
so ambiguous that the best we can do is to discard them, just like we
are doing now. So let's make it silent.
Signed-off-by: Arkadiusz Hiler's avatarArkadiusz Hiler <>
parent 790a99bd
Pipeline #18902 passed with stages
in 7 minutes and 11 seconds
......@@ -45,6 +45,7 @@ from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import MultipleObjectsReturned
from django.db.models import Q
from django.db import IntegrityError
from django.utils.log import AdminEmailHandler
from django.utils import six
from django.utils.six.moves import map
......@@ -815,7 +816,10 @@ def parse_mail(mail):
patch.delegate = delegate
if revision:
revision.add_patch(patch, content.patch_order)
revision.add_patch(patch, content.patch_order)
except IntegrityError:
LOGGER.debug('Duplicate patch in revision, ignoring')
LOGGER.debug('Patch saved')
if comment:
......@@ -21,7 +21,7 @@ from email import message_from_string
from email.mime.text import MIMEText
from email.utils import make_msgid
from django.test import TestCase
from django.test import TestCase, TransactionTestCase
from patchwork.bin.parsemail import (find_content, find_author, find_project,
parse_mail, split_prefixes, clean_subject,
......@@ -337,6 +337,28 @@ class MultipleProjectPatchTest(TestCase):
class DuplicatePatchInRevision(TransactionTestCase):
fixtures = ['default_states', 'default_events']
test_comment = 'Test Comment'
patch_filename = '0001-add-line.patch'
def testParsedProjects(self):
patch = read_patch(self.patch_filename)
patch1 = create_email(self.test_comment + '\n' + patch,
subject="[PATCH 1/2] Meep Meep]")
patch2 = create_email(self.test_comment + '\n' + patch,
subject="[PATCH 2/2] Meep Meep2]",
del patch2['Message-Id']
patch2['Message-Id'] = '<>'
class MultipleProjectPatchCommentTest(MultipleProjectPatchTest):
"""Test that followups to multiple-project patches end up on the
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment