diff options
author | Frederic Martinsons <frederic.martinsons@gmail.com> | 2023-03-31 07:45:25 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-04-01 11:36:26 +0100 |
commit | 11180fd52801680ab4ea85865368f3d9e837f2e0 (patch) | |
tree | 3581b822d7487ea8a04df8de5f2d34121cd1c685 /meta/lib | |
parent | da1bcf08089d8276a156a221af405863b6746b7b (diff) | |
download | poky-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')
-rw-r--r-- | meta/lib/oe/patch.py | 57 |
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) |