diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2014-12-19 11:41:49 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-12-21 12:37:56 +0000 |
commit | 12bb32e766d79ed9c6e5ac511f45a5fa40712781 (patch) | |
tree | d12687f7e0b1677cb261473fea487df29f569874 | |
parent | 50e771d1140276b8f5d472237e4cb41cf512e5df (diff) | |
download | poky-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.py | 112 |
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 | ||
201 | class GitApplyTree(PatchTree): | 201 | class 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 | ||
321 | class QuiltTree(PatchSet): | 373 | class QuiltTree(PatchSet): |