diff options
Diffstat (limited to 'bitbake/lib/bb/fetch2/git.py')
-rw-r--r-- | bitbake/lib/bb/fetch2/git.py | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/bitbake/lib/bb/fetch2/git.py b/bitbake/lib/bb/fetch2/git.py index df33fb6aeb..b43ee0da39 100644 --- a/bitbake/lib/bb/fetch2/git.py +++ b/bitbake/lib/bb/fetch2/git.py | |||
@@ -325,7 +325,10 @@ class Git(FetchMethod): | |||
325 | return ud.clonedir | 325 | return ud.clonedir |
326 | 326 | ||
327 | def need_update(self, ud, d): | 327 | def need_update(self, ud, d): |
328 | return self.clonedir_need_update(ud, d) or self.shallow_tarball_need_update(ud) or self.tarball_need_update(ud) | 328 | return self.clonedir_need_update(ud, d) \ |
329 | or self.shallow_tarball_need_update(ud) \ | ||
330 | or self.tarball_need_update(ud) \ | ||
331 | or self.lfs_need_update(ud, d) | ||
329 | 332 | ||
330 | def clonedir_need_update(self, ud, d): | 333 | def clonedir_need_update(self, ud, d): |
331 | if not os.path.exists(ud.clonedir): | 334 | if not os.path.exists(ud.clonedir): |
@@ -337,6 +340,15 @@ class Git(FetchMethod): | |||
337 | return True | 340 | return True |
338 | return False | 341 | return False |
339 | 342 | ||
343 | def lfs_need_update(self, ud, d): | ||
344 | if self.clonedir_need_update(ud, d): | ||
345 | return True | ||
346 | |||
347 | for name in ud.names: | ||
348 | if not self._lfs_objects_downloaded(ud, d, name, ud.clonedir): | ||
349 | return True | ||
350 | return False | ||
351 | |||
340 | def clonedir_need_shallow_revs(self, ud, d): | 352 | def clonedir_need_shallow_revs(self, ud, d): |
341 | for rev in ud.shallow_revs: | 353 | for rev in ud.shallow_revs: |
342 | try: | 354 | try: |
@@ -467,7 +479,7 @@ class Git(FetchMethod): | |||
467 | if missing_rev: | 479 | if missing_rev: |
468 | raise bb.fetch2.FetchError("Unable to find revision %s even from upstream" % missing_rev) | 480 | raise bb.fetch2.FetchError("Unable to find revision %s even from upstream" % missing_rev) |
469 | 481 | ||
470 | if self._contains_lfs(ud, d, ud.clonedir) and self._need_lfs(ud): | 482 | if self.lfs_need_update(ud, d): |
471 | # Unpack temporary working copy, use it to run 'git checkout' to force pre-fetching | 483 | # Unpack temporary working copy, use it to run 'git checkout' to force pre-fetching |
472 | # of all LFS blobs needed at the srcrev. | 484 | # of all LFS blobs needed at the srcrev. |
473 | # | 485 | # |
@@ -710,6 +722,35 @@ class Git(FetchMethod): | |||
710 | raise bb.fetch2.FetchError("The command '%s' gave output with more then 1 line unexpectedly, output: '%s'" % (cmd, output)) | 722 | raise bb.fetch2.FetchError("The command '%s' gave output with more then 1 line unexpectedly, output: '%s'" % (cmd, output)) |
711 | return output.split()[0] != "0" | 723 | return output.split()[0] != "0" |
712 | 724 | ||
725 | def _lfs_objects_downloaded(self, ud, d, name, wd): | ||
726 | """ | ||
727 | Verifies whether the LFS objects for requested revisions have already been downloaded | ||
728 | """ | ||
729 | # Bail out early if this repository doesn't use LFS | ||
730 | if not self._need_lfs(ud) or not self._contains_lfs(ud, d, wd): | ||
731 | return True | ||
732 | |||
733 | # The Git LFS specification specifies ([1]) the LFS folder layout so it should be safe to check for file | ||
734 | # existence. | ||
735 | # [1] https://github.com/git-lfs/git-lfs/blob/main/docs/spec.md#intercepting-git | ||
736 | cmd = "%s lfs ls-files -l %s" \ | ||
737 | % (ud.basecmd, ud.revisions[name]) | ||
738 | output = runfetchcmd(cmd, d, quiet=True, workdir=wd).rstrip() | ||
739 | # Do not do any further matching if no objects are managed by LFS | ||
740 | if not output: | ||
741 | return True | ||
742 | |||
743 | # Match all lines beginning with the hexadecimal OID | ||
744 | oid_regex = re.compile("^(([a-fA-F0-9]{2})([a-fA-F0-9]{2})[A-Fa-f0-9]+)") | ||
745 | for line in output.split("\n"): | ||
746 | oid = re.search(oid_regex, line) | ||
747 | if not oid: | ||
748 | bb.warn("git lfs ls-files output '%s' did not match expected format." % line) | ||
749 | if not os.path.exists(os.path.join(wd, "lfs", "objects", oid.group(2), oid.group(3), oid.group(1))): | ||
750 | return False | ||
751 | |||
752 | return True | ||
753 | |||
713 | def _need_lfs(self, ud): | 754 | def _need_lfs(self, ud): |
714 | return ud.parm.get("lfs", "1") == "1" | 755 | return ud.parm.get("lfs", "1") == "1" |
715 | 756 | ||