mirror of
https://git.yoctoproject.org/poky
synced 2026-01-29 21:08:42 +01:00
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>
This commit is contained in:
committed by
Richard Purdie
parent
50e771d114
commit
12bb32e766
@@ -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
|
||||
patchfilevar = 'PATCHFILE="%s"' % os.path.basename(patch['file'])
|
||||
try:
|
||||
shellcmd = ["git", "--work-tree=.", "am", "--abort"]
|
||||
runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
|
||||
shellcmd = [patchfilevar, "git", "--work-tree=.", "am", "-3", "--keep-cr", "-p%s" % patch['strippath']]
|
||||
return _applypatchhelper(shellcmd, patch, force, reverse, run)
|
||||
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)
|
||||
# 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)
|
||||
finally:
|
||||
os.remove(tmpfile)
|
||||
return output
|
||||
# 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:
|
||||
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):
|
||||
|
||||
Reference in New Issue
Block a user