summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe/patch.py
diff options
context:
space:
mode:
authorFrederic Martinsons <frederic.martinsons@gmail.com>2023-03-31 07:45:25 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-04-01 11:36:26 +0100
commit11180fd52801680ab4ea85865368f3d9e837f2e0 (patch)
tree3581b822d7487ea8a04df8de5f2d34121cd1c685 /meta/lib/oe/patch.py
parentda1bcf08089d8276a156a221af405863b6746b7b (diff)
downloadpoky-11180fd52801680ab4ea85865368f3d9e837f2e0.tar.gz
patch: support of git patches when the source uri contained subpath parameter
This is for a specific case where: - A recipe use a subpath on a git repo (e.g. git://repo.git/projects;subpath=subproject) - The recipe contains a patch to apply - a devtool modify is used on this recipe With these conditions, the patch cannot be applied at all. GitApplyTree class is used for handling patch under devtool, but when subpath is present in SRC_URI, the resulting git tree is dirty (every files and directories which was not in subpath are suppressed) and so "git am" refuse to apply patches. That would not be an issue since the GitApplyTree have a fallback to PatchTree in case of error, but during this error management, there is a "git reset --hard HEAD" call which suppress the subpath operation and finally prevents the patch to be applied even with PatchTree. When devtool is not involved, only PatchTree class is used and the above problem is irrelevant. To support git patching during devtool, the presence of subpath and the dirtyness of the repo are checked. If both conditions are met, we directly call PatchTree like it was already done in case of error during git apply. (From OE-Core rev: d86cac2759cf7e91f4ff240833385e28e729ab79) Signed-off-by: Frederic Martinsons <frederic.martinsons@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oe/patch.py')
-rw-r--r--meta/lib/oe/patch.py57
1 files changed, 44 insertions, 13 deletions
diff --git a/meta/lib/oe/patch.py b/meta/lib/oe/patch.py
index b2dc8d0a90..d047b3b947 100644
--- a/meta/lib/oe/patch.py
+++ b/meta/lib/oe/patch.py
@@ -499,6 +499,36 @@ class GitApplyTree(PatchTree):
499 finally: 499 finally:
500 shutil.rmtree(tempdir) 500 shutil.rmtree(tempdir)
501 501
502 def _need_dirty_check(self):
503 fetch = bb.fetch2.Fetch([], self.d)
504 check_dirtyness = False
505 for url in fetch.urls:
506 url_data = fetch.ud[url]
507 parm = url_data.parm
508 # a git url with subpath param will surely be dirty
509 # since the git tree from which we clone will be emptied
510 # from all files that are not in the subpath
511 if url_data.type == 'git' and parm.get('subpath'):
512 check_dirtyness = True
513 return check_dirtyness
514
515 def _commitpatch(self, patch, patchfilevar):
516 output = ""
517 # Add all files
518 shellcmd = ["git", "add", "-f", "-A", "."]
519 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
520 # Exclude the patches directory
521 shellcmd = ["git", "reset", "HEAD", self.patchdir]
522 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
523 # Commit the result
524 (tmpfile, shellcmd) = self.prepareCommit(patch['file'], self.commituser, self.commitemail)
525 try:
526 shellcmd.insert(0, patchfilevar)
527 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
528 finally:
529 os.remove(tmpfile)
530 return output
531
502 def _applypatch(self, patch, force = False, reverse = False, run = True): 532 def _applypatch(self, patch, force = False, reverse = False, run = True):
503 import shutil 533 import shutil
504 534
@@ -534,6 +564,19 @@ class GitApplyTree(PatchTree):
534 shutil.copy2(commithook, applyhook) 564 shutil.copy2(commithook, applyhook)
535 try: 565 try:
536 patchfilevar = 'PATCHFILE="%s"' % os.path.basename(patch['file']) 566 patchfilevar = 'PATCHFILE="%s"' % os.path.basename(patch['file'])
567 if self._need_dirty_check():
568 # Check dirtyness of the tree
569 try:
570 output = runcmd(["git", "--work-tree=%s" % reporoot, "status", "--short"])
571 except CmdError:
572 pass
573 else:
574 if output:
575 # The tree is dirty, not need to try to apply patches with git anymore
576 # since they fail, fallback directly to patch
577 output = PatchTree._applypatch(self, patch, force, reverse, run)
578 output += self._commitpatch(patch, patchfilevar)
579 return output
537 try: 580 try:
538 shellcmd = [patchfilevar, "git", "--work-tree=%s" % reporoot] 581 shellcmd = [patchfilevar, "git", "--work-tree=%s" % reporoot]
539 self.gitCommandUserOptions(shellcmd, self.commituser, self.commitemail) 582 self.gitCommandUserOptions(shellcmd, self.commituser, self.commitemail)
@@ -560,19 +603,7 @@ class GitApplyTree(PatchTree):
560 except CmdError: 603 except CmdError:
561 # Fall back to patch 604 # Fall back to patch
562 output = PatchTree._applypatch(self, patch, force, reverse, run) 605 output = PatchTree._applypatch(self, patch, force, reverse, run)
563 # Add all files 606 output += self._commitpatch(patch, patchfilevar)
564 shellcmd = ["git", "add", "-f", "-A", "."]
565 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
566 # Exclude the patches directory
567 shellcmd = ["git", "reset", "HEAD", self.patchdir]
568 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
569 # Commit the result
570 (tmpfile, shellcmd) = self.prepareCommit(patch['file'], self.commituser, self.commitemail)
571 try:
572 shellcmd.insert(0, patchfilevar)
573 output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
574 finally:
575 os.remove(tmpfile)
576 return output 607 return output
577 finally: 608 finally:
578 shutil.rmtree(hooks_dir) 609 shutil.rmtree(hooks_dir)