summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/fetch2/git.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/fetch2/git.py')
-rw-r--r--bitbake/lib/bb/fetch2/git.py45
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