public inbox for openembedded-core@lists.openembedded.org
 help / color / mirror / Atom feed
From: Paul Eggleton <paul.eggleton@linux.intel.com>
To: openembedded-core@lists.openembedded.org
Subject: [PATCH 07/15] lib/oe/patch: add support for extracting patches from git tree
Date: Fri, 19 Dec 2014 11:41:49 +0000	[thread overview]
Message-ID: <e4dd3e1b3225109ff4cde54a5261f315ef2c191a.1418984743.git.paul.eggleton@linux.intel.com> (raw)
In-Reply-To: <cover.1418984743.git.paul.eggleton@linux.intel.com>
In-Reply-To: <cover.1418984743.git.paul.eggleton@linux.intel.com>

When patches from a recipe have been written out to a git tree, we also
want to be able to do the reverse so we can update the patches next to
the recipe. This is implemented by adding a comment to each commit
message (using git hooks) which we can extract later on.

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
---
 meta/lib/oe/patch.py | 112 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 82 insertions(+), 30 deletions(-)

diff --git a/meta/lib/oe/patch.py b/meta/lib/oe/patch.py
index 5227781..b838be8 100644
--- a/meta/lib/oe/patch.py
+++ b/meta/lib/oe/patch.py
@@ -199,6 +199,8 @@ class PatchTree(PatchSet):
         self.Pop(all=True)
 
 class GitApplyTree(PatchTree):
+    patch_line_prefix = '%% original patch'
+
     def __init__(self, dir, d):
         PatchTree.__init__(self, dir, d)
 
@@ -256,10 +258,6 @@ class GitApplyTree(PatchTree):
                 if author_re.match(authorval):
                     author = authorval
             outlines.append(line)
-        # Add a pointer to the original patch file name
-        if outlines and outlines[-1].strip():
-            outlines.append('\n')
-        outlines.append('(from original patch: %s)\n' % os.path.basename(patchfile))
         # Write out commit message to a file
         with tempfile.NamedTemporaryFile('w', delete=False) as tf:
             tmpfile = tf.name
@@ -274,7 +272,35 @@ class GitApplyTree(PatchTree):
             cmd.append('--date="%s"' % date)
         return (tmpfile, cmd)
 
+    @staticmethod
+    def extractPatches(tree, startcommit, outdir):
+        import tempfile
+        import shutil
+        tempdir = tempfile.mkdtemp(prefix='oepatch')
+        try:
+            shellcmd = ["git", "format-patch", startcommit, "-o", tempdir]
+            out = runcmd(["sh", "-c", " ".join(shellcmd)], tree)
+            if out:
+                for srcfile in out.split():
+                    patchlines = []
+                    outfile = None
+                    with open(srcfile, 'r') as f:
+                        for line in f:
+                            if line.startswith(GitApplyTree.patch_line_prefix):
+                                outfile = line.split()[-1].strip()
+                                continue
+                            patchlines.append(line)
+                    if not outfile:
+                        outfile = os.path.basename(srcfile)
+                    with open(os.path.join(outdir, outfile), 'w') as of:
+                        for line in patchlines:
+                            of.write(line)
+        finally:
+            shutil.rmtree(tempdir)
+
     def _applypatch(self, patch, force = False, reverse = False, run = True):
+        import shutil
+
         def _applypatchhelper(shellcmd, patch, force = False, reverse = False, run = True):
             if reverse:
                 shellcmd.append('-R')
@@ -286,36 +312,62 @@ class GitApplyTree(PatchTree):
 
             return runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
 
+        # Add hooks which add a pointer to the original patch file name in the commit message
+        commithook = os.path.join(self.dir, '.git', 'hooks', 'commit-msg')
+        commithook_backup = commithook + '.devtool-orig'
+        applyhook = os.path.join(self.dir, '.git', 'hooks', 'applypatch-msg')
+        applyhook_backup = applyhook + '.devtool-orig'
+        if os.path.exists(commithook):
+            shutil.move(commithook, commithook_backup)
+        if os.path.exists(applyhook):
+            shutil.move(applyhook, applyhook_backup)
+        with open(commithook, 'w') as f:
+            # NOTE: the formatting here is significant; if you change it you'll also need to
+            # change other places which read it back
+            f.write('echo >> $1\n')
+            f.write('echo "%s: $PATCHFILE" >> $1\n' % GitApplyTree.patch_line_prefix)
+        os.chmod(commithook, 0755)
+        shutil.copy2(commithook, applyhook)
         try:
-            shellcmd = ["git", "--work-tree=.", "am", "-3", "--keep-cr", "-p%s" % patch['strippath']]
-            return _applypatchhelper(shellcmd, patch, force, reverse, run)
-        except CmdError:
-            # Need to abort the git am, or we'll still be within it at the end
-            try:
-                shellcmd = ["git", "--work-tree=.", "am", "--abort"]
-                runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
-            except CmdError:
-                pass
-            # Fall back to git apply
-            shellcmd = ["git", "--git-dir=.", "apply", "-p%s" % patch['strippath']]
+            patchfilevar = 'PATCHFILE="%s"' % os.path.basename(patch['file'])
             try:
-                output = _applypatchhelper(shellcmd, patch, force, reverse, run)
+                shellcmd = [patchfilevar, "git", "--work-tree=.", "am", "-3", "--keep-cr", "-p%s" % patch['strippath']]
+                return _applypatchhelper(shellcmd, patch, force, reverse, run)
             except CmdError:
-                # Fall back to patch
-                output = PatchTree._applypatch(self, patch, force, reverse, run)
-            # Add all files
-            shellcmd = ["git", "add", "-f", "."]
-            output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
-            # Exclude the patches directory
-            shellcmd = ["git", "reset", "HEAD", self.patchdir]
-            output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
-            # Commit the result
-            (tmpfile, shellcmd) = self.prepareCommit(patch['file'])
-            try:
+                # Need to abort the git am, or we'll still be within it at the end
+                try:
+                    shellcmd = ["git", "--work-tree=.", "am", "--abort"]
+                    runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
+                except CmdError:
+                    pass
+                # Fall back to git apply
+                shellcmd = ["git", "--git-dir=.", "apply", "-p%s" % patch['strippath']]
+                try:
+                    output = _applypatchhelper(shellcmd, patch, force, reverse, run)
+                except CmdError:
+                    # Fall back to patch
+                    output = PatchTree._applypatch(self, patch, force, reverse, run)
+                # Add all files
+                shellcmd = ["git", "add", "-f", "."]
+                output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
+                # Exclude the patches directory
+                shellcmd = ["git", "reset", "HEAD", self.patchdir]
                 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
-            finally:
-                os.remove(tmpfile)
-            return output
+                # Commit the result
+                (tmpfile, shellcmd) = self.prepareCommit(patch['file'])
+                try:
+                    shellcmd.insert(0, patchfilevar)
+                    output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
+                finally:
+                    os.remove(tmpfile)
+                return output
+        finally:
+            os.remove(commithook)
+            os.remove(applyhook)
+            if os.path.exists(commithook_backup):
+                shutil.move(commithook_backup, commithook)
+            if os.path.exists(applyhook_backup):
+                shutil.move(applyhook_backup, applyhook)
 
 
 class QuiltTree(PatchSet):
-- 
1.9.3



  parent reply	other threads:[~2014-12-19 11:42 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-19 11:41 [PATCH 00/15] Developer workflow tools Paul Eggleton
2014-12-19 11:41 ` [PATCH 01/15] meta-environment: don't mark tasks as nostamp Paul Eggleton
2014-12-19 11:41 ` [PATCH 02/15] classes/package: move read_shlib_providers() to a common unit Paul Eggleton
2014-12-19 11:41 ` [PATCH 03/15] lib/oe/patch: fall back to patch if git apply fails Paul Eggleton
2014-12-19 11:41 ` [PATCH 04/15] lib/oe/patch: auto-commit when falling back from git am Paul Eggleton
2014-12-19 11:41 ` [PATCH 05/15] lib/oe/patch: use --keep-cr with " Paul Eggleton
2014-12-19 11:41 ` [PATCH 06/15] lib/oe/patch.py: abort "git am" if it fails Paul Eggleton
2014-12-19 11:41 ` Paul Eggleton [this message]
2014-12-19 11:41 ` [PATCH 08/15] lib/oe: add recipeutils module Paul Eggleton
2014-12-19 11:41 ` [PATCH 09/15] oeqa/utils: make get_bb_var() more reliable Paul Eggleton
2014-12-19 11:41 ` [PATCH 10/15] classes/externalsrc: set do_compile as nostamp Paul Eggleton
2014-12-19 11:41 ` [PATCH 11/15] scripts/recipetool: Add a recipe auto-creation script Paul Eggleton
2014-12-19 11:41 ` [PATCH 12/15] scripts: add scriptutils module Paul Eggleton
2014-12-19 11:41 ` [PATCH 13/15] scripts/devtool: add development helper tool Paul Eggleton
2014-12-19 11:41 ` [PATCH 14/15] scripts/devtool: Support deploy/undeploy function Paul Eggleton
2014-12-19 11:41 ` [PATCH 15/15] devtool: add QA tests Paul Eggleton
2014-12-23 12:30 ` [PATCH 00/15] Developer workflow tools Trevor Woerner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e4dd3e1b3225109ff4cde54a5261f315ef2c191a.1418984743.git.paul.eggleton@linux.intel.com \
    --to=paul.eggleton@linux.intel.com \
    --cc=openembedded-core@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox