summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2014-12-19 11:41:49 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-12-21 12:37:56 +0000
commit12bb32e766d79ed9c6e5ac511f45a5fa40712781 (patch)
treed12687f7e0b1677cb261473fea487df29f569874
parent50e771d1140276b8f5d472237e4cb41cf512e5df (diff)
downloadpoky-12bb32e766d79ed9c6e5ac511f45a5fa40712781.tar.gz
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. (From OE-Core rev: 765b7bad50eae5b79d13a3f4988dc440c3d9787f) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oe/patch.py112
1 files changed, 82 insertions, 30 deletions
diff --git a/meta/lib/oe/patch.py b/meta/lib/oe/patch.py
index 522778140c..b838be80be 100644
--- a/meta/lib/oe/patch.py
+++ b/meta/lib/oe/patch.py
@@ -199,6 +199,8 @@ class PatchTree(PatchSet):
199 self.Pop(all=True) 199 self.Pop(all=True)
200 200
201class GitApplyTree(PatchTree): 201class GitApplyTree(PatchTree):
202 patch_line_prefix = '%% original patch'
203
202 def __init__(self, dir, d): 204 def __init__(self, dir, d):
203 PatchTree.__init__(self, dir, d) 205 PatchTree.__init__(self, dir, d)
204 206
@@ -256,10 +258,6 @@ class GitApplyTree(PatchTree):
256 if author_re.match(authorval): 258 if author_re.match(authorval):
257 author = authorval 259 author = authorval
258 outlines.append(line) 260 outlines.append(line)
259 # Add a pointer to the original patch file name
260 if outlines and outlines[-1].strip():
261 outlines.append('\n')
262 outlines.append('(from original patch: %s)\n' % os.path.basename(patchfile))
263 # Write out commit message to a file 261 # Write out commit message to a file
264 with tempfile.NamedTemporaryFile('w', delete=False) as tf: 262 with tempfile.NamedTemporaryFile('w', delete=False) as tf:
265 tmpfile = tf.name 263 tmpfile = tf.name
@@ -274,7 +272,35 @@ class GitApplyTree(PatchTree):
274 cmd.append('--date="%s"' % date) 272 cmd.append('--date="%s"' % date)
275 return (tmpfile, cmd) 273 return (tmpfile, cmd)
276 274
275 @staticmethod
276 def extractPatches(tree, startcommit, outdir):
277 import tempfile
278 import shutil
279 tempdir = tempfile.mkdtemp(prefix='oepatch')
280 try:
281 shellcmd = ["git", "format-patch", startcommit, "-o", tempdir]
282 out = runcmd(["sh", "-c", " ".join(shellcmd)], tree)
283 if out:
284 for srcfile in out.split():
285 patchlines = []
286 outfile = None
287 with open(srcfile, 'r') as f:
288 for line in f:
289 if line.startswith(GitApplyTree.patch_line_prefix):
290 outfile = line.split()[-1].strip()
291 continue
292 patchlines.append(line)
293 if not outfile:
294 outfile = os.path.basename(srcfile)
295 with open(os.path.join(outdir, outfile), 'w') as of:
296 for line in patchlines:
297 of.write(line)
298 finally:
299 shutil.rmtree(tempdir)
300
277 def _applypatch(self, patch, force = False, reverse = False, run = True): 301 def _applypatch(self, patch, force = False, reverse = False, run = True):
302 import shutil
303
278 def _applypatchhelper(shellcmd, patch, force = False, reverse = False, run = True): 304 def _applypatchhelper(shellcmd, patch, force = False, reverse = False, run = True):
279 if reverse: 305 if reverse:
280 shellcmd.append('-R') 306 shellcmd.append('-R')
@@ -286,36 +312,62 @@ class GitApplyTree(PatchTree):
286 312
287 return runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) 313 return runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
288 314
315 # Add hooks which add a pointer to the original patch file name in the commit message
316 commithook = os.path.join(self.dir, '.git', 'hooks', 'commit-msg')
317 commithook_backup = commithook + '.devtool-orig'
318 applyhook = os.path.join(self.dir, '.git', 'hooks', 'applypatch-msg')
319 applyhook_backup = applyhook + '.devtool-orig'
320 if os.path.exists(commithook):
321 shutil.move(commithook, commithook_backup)
322 if os.path.exists(applyhook):
323 shutil.move(applyhook, applyhook_backup)
324 with open(commithook, 'w') as f:
325 # NOTE: the formatting here is significant; if you change it you'll also need to
326 # change other places which read it back
327 f.write('echo >> $1\n')
328 f.write('echo "%s: $PATCHFILE" >> $1\n' % GitApplyTree.patch_line_prefix)
329 os.chmod(commithook, 0755)
330 shutil.copy2(commithook, applyhook)
289 try: 331 try:
290 shellcmd = ["git", "--work-tree=.", "am", "-3", "--keep-cr", "-p%s" % patch['strippath']] 332 patchfilevar = 'PATCHFILE="%s"' % os.path.basename(patch['file'])
291 return _applypatchhelper(shellcmd, patch, force, reverse, run)
292 except CmdError:
293 # Need to abort the git am, or we'll still be within it at the end
294 try:
295 shellcmd = ["git", "--work-tree=.", "am", "--abort"]
296 runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
297 except CmdError:
298 pass
299 # Fall back to git apply
300 shellcmd = ["git", "--git-dir=.", "apply", "-p%s" % patch['strippath']]
301 try: 333 try:
302 output = _applypatchhelper(shellcmd, patch, force, reverse, run) 334 shellcmd = [patchfilevar, "git", "--work-tree=.", "am", "-3", "--keep-cr", "-p%s" % patch['strippath']]
335 return _applypatchhelper(shellcmd, patch, force, reverse, run)
303 except CmdError: 336 except CmdError:
304 # Fall back to patch 337 # Need to abort the git am, or we'll still be within it at the end
305 output = PatchTree._applypatch(self, patch, force, reverse, run) 338 try:
306 # Add all files 339 shellcmd = ["git", "--work-tree=.", "am", "--abort"]
307 shellcmd = ["git", "add", "-f", "."] 340 runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
308 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) 341 except CmdError:
309 # Exclude the patches directory 342 pass
310 shellcmd = ["git", "reset", "HEAD", self.patchdir] 343 # Fall back to git apply
311 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) 344 shellcmd = ["git", "--git-dir=.", "apply", "-p%s" % patch['strippath']]
312 # Commit the result 345 try:
313 (tmpfile, shellcmd) = self.prepareCommit(patch['file']) 346 output = _applypatchhelper(shellcmd, patch, force, reverse, run)
314 try: 347 except CmdError:
348 # Fall back to patch
349 output = PatchTree._applypatch(self, patch, force, reverse, run)
350 # Add all files
351 shellcmd = ["git", "add", "-f", "."]
352 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
353 # Exclude the patches directory
354 shellcmd = ["git", "reset", "HEAD", self.patchdir]
315 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) 355 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
316 finally: 356 # Commit the result
317 os.remove(tmpfile) 357 (tmpfile, shellcmd) = self.prepareCommit(patch['file'])
318 return output 358 try:
359 shellcmd.insert(0, patchfilevar)
360 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
361 finally:
362 os.remove(tmpfile)
363 return output
364 finally:
365 os.remove(commithook)
366 os.remove(applyhook)
367 if os.path.exists(commithook_backup):
368 shutil.move(commithook_backup, commithook)
369 if os.path.exists(applyhook_backup):
370 shutil.move(applyhook_backup, applyhook)
319 371
320 372
321class QuiltTree(PatchSet): 373class QuiltTree(PatchSet):