summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2014-04-09 15:26:06 -0700
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2014-04-25 15:37:45 -0700
commit9c9115178efdcf0f6457cc68c6ba00de6ec2df9a (patch)
tree633869d80f6457e386926571b949bf35be18c5a0
parentf491665839e8b033d4e20cfe2ea1c66609f2adde (diff)
downloadaiaiai-9c9115178efdcf0f6457cc68c6ba00de6ec2df9a.tar.gz
aiaiai: extract patches from email prior to using git-am
Some patch authors submit patches directly attached via git-format-patch output as an attachment. Sometimes they include both the patch and the inline diff. This is problematic because it causes aiaiai to fail to apply the patch, due to git being confused about the attached patch. This patch modifies how aiaiai reads the commits, using a python script which is capable of extracting the patches from the mbox (including attachments) before calling git-am. This helps aiaiai more easily handle this weird patch case, and still works great for regular patch submissions. In addition, turn on 3-way merge of git-am, so that duplicate patches will be properly ignored (as in the case with inlined and attached patches) Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
-rwxr-xr-xhelpers/aiaiai-extract-patches76
-rw-r--r--helpers/aiaiai-sh-functions2
2 files changed, 77 insertions, 1 deletions
diff --git a/helpers/aiaiai-extract-patches b/helpers/aiaiai-extract-patches
new file mode 100755
index 0000000..fe7b7a1
--- /dev/null
+++ b/helpers/aiaiai-extract-patches
@@ -0,0 +1,76 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+
+"""
+Extract attached patches from MIME messaged passed to standard input. Will
+output an mbox where each message contains a single patch. Assumes attachments
+will begin with '>From' to indicate they are a seperate email to be extracted.
+
+Copyright 2014 Intel Corporation
+Author: Jacob Keller <jacob.e.keller@intel.com>
+License: GPLv2
+"""
+
+import argparse
+import email
+import sys
+
+def main():
+ """Extract attached patches from stdin as a MIME email."""
+ headers_to_copy = ["From", "Date", "Subject", "To"]
+
+ description = """\
+Extract git patches out of an email message, including if the patch is embedded
+in the email as an attachment from git-format-patch. %(prog)s only works on a
+single email message at a time, so another program for splitting mbox files
+such as formail is suggested."""
+
+ parser = argparse.ArgumentParser(description=description)
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument("--discard-inline",
+ dest="inline",
+ action="store_false",
+ help=("discard inlined segment, "
+ "keeping only git-format-patch attachments"))
+ group.add_argument("--discard-attachments",
+ dest="attachments",
+ action="store_false",
+ help=("discard any git-format-patch attachments, "
+ "keeping only inlined email"))
+
+ args = parser.parse_args()
+
+ # Now, grab standard input and parse it as an email message
+ msg = email.message_from_file(sys.stdin)
+ patches = []
+
+ if msg.is_multipart():
+ segments = msg.get_payload()
+ for segment in segments[:]:
+ if segment.get_payload().startswith(">From "):
+ segments.remove(segment)
+ patches.append(email.message_from_string(
+ segment.get_payload()[1:]))
+
+ inline = email.message.Message()
+ inline.set_unixfrom(msg.get_unixfrom())
+ for header in headers_to_copy:
+ inline[header] = msg[header]
+
+ if msg.is_multipart():
+ inline.set_payload("".join([x.get_payload()
+ for x in msg.get_payload()]))
+ else:
+ inline.set_payload(msg.get_payload())
+
+ if args.inline:
+ print inline.as_string(unixfrom=True)
+
+ if args.attachments:
+ for patch in patches:
+ print patch.as_string(unixfrom=True)
+
+if __name__ == "__main__":
+ sys.exit(main())
+
+# vim: ts=4 et sw=4 sts=4 ai sta:
diff --git a/helpers/aiaiai-sh-functions b/helpers/aiaiai-sh-functions
index c17255a..799672c 100644
--- a/helpers/aiaiai-sh-functions
+++ b/helpers/aiaiai-sh-functions
@@ -175,7 +175,7 @@ apply_patch()
cmt="$(git rev-parse "HEAD^{commit}")"
- am="$(git am 2>&1)" || {
+ am="$(formail -s aiaiai-extract-patches | git am --3way 2>&1)" || {
cat <<EOF
Failed to apply patch(es) with git am on top of:
$(git log -1 --oneline "$cmt")