[oe-commits] Paul Eggleton : lib/oe/patch: add support for extracting patches from git tree

git at git.openembedded.org git at git.openembedded.org
Sat Dec 20 11:24:52 UTC 2014


Module: openembedded-core.git
Branch: master-next
Commit: 403cb4bc81daeaa5aa327b14e442f6307b36a7a8
URL:    http://git.openembedded.org/?p=openembedded-core.git&a=commit;h=403cb4bc81daeaa5aa327b14e442f6307b36a7a8

Author: Paul Eggleton <paul.eggleton at linux.intel.com>
Date:   Fri Dec 19 11:41:49 2014 +0000

lib/oe/patch: add support for extracting patches from git tree

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 at linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie at linuxfoundation.org>

---

 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):



More information about the Openembedded-commits mailing list