summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/fetch2/git.py
diff options
context:
space:
mode:
authorMatt Hoosier <matt.hoosier@garmin.com>2021-01-22 10:55:13 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-01-23 17:10:46 +0000
commit45c02843d181b5f1872ad30f4d847c395233a676 (patch)
tree1b61559ebf14f9b5a97b283b6860dd795024b674 /bitbake/lib/bb/fetch2/git.py
parent8e92ec78322909ca5ad6ceda582b611fa77a9964 (diff)
downloadpoky-45c02843d181b5f1872ad30f4d847c395233a676.tar.gz
bitbake: fetch/git: download LFS content too during do_fetch
Insert an explicit pass to fetch all blobs needed by Git LFS, during the fetch() function. This avoids the default behavior of Git LFS to wait until 'git checkout' to begin downloading the blobs pointed to by LFS records. Network access is not allowed at that point in the recipe's lifecycle. [YOCTO #14191] (Bitbake rev: 0efac66043662e7a2027192f50e92e982db2ba1c) Signed-off-by: Matt Hoosier <matt.hoosier@garmin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/fetch2/git.py')
-rw-r--r--bitbake/lib/bb/fetch2/git.py44
1 files changed, 41 insertions, 3 deletions
diff --git a/bitbake/lib/bb/fetch2/git.py b/bitbake/lib/bb/fetch2/git.py
index df9538a60d..e3ba80a3f5 100644
--- a/bitbake/lib/bb/fetch2/git.py
+++ b/bitbake/lib/bb/fetch2/git.py
@@ -384,6 +384,35 @@ class Git(FetchMethod):
384 if missing_rev: 384 if missing_rev:
385 raise bb.fetch2.FetchError("Unable to find revision %s even from upstream" % missing_rev) 385 raise bb.fetch2.FetchError("Unable to find revision %s even from upstream" % missing_rev)
386 386
387 if self._contains_lfs(ud, d, ud.clonedir) and self._need_lfs(ud):
388 # Unpack temporary working copy, use it to run 'git checkout' to force pre-fetching
389 # of all LFS blobs needed at the the srcrev.
390 #
391 # It would be nice to just do this inline here by running 'git-lfs fetch'
392 # on the bare clonedir, but that operation requires a working copy on some
393 # releases of Git LFS.
394 tmpdir = tempfile.mkdtemp(dir=d.getVar('DL_DIR'))
395 try:
396 # Do the checkout. This implicitly involves a Git LFS fetch.
397 self.unpack(ud, tmpdir, d)
398
399 # Scoop up a copy of any stuff that Git LFS downloaded. Merge them into
400 # the bare clonedir.
401 #
402 # As this procedure is invoked repeatedly on incremental fetches as
403 # a recipe's SRCREV is bumped throughout its lifetime, this will
404 # result in a gradual accumulation of LFS blobs in <ud.clonedir>/lfs
405 # corresponding to all the blobs reachable from the different revs
406 # fetched across time.
407 #
408 # Only do this if the unpack resulted in a .git/lfs directory being
409 # created; this only happens if at least one blob needed to be
410 # downloaded.
411 if os.path.exists(os.path.join(tmpdir, "git", ".git", "lfs")):
412 runfetchcmd("tar -cf - lfs | tar -xf - -C %s" % ud.clonedir, d, workdir="%s/git/.git" % tmpdir)
413 finally:
414 bb.utils.remove(tmpdir, recurse=True)
415
387 def build_mirror_data(self, ud, d): 416 def build_mirror_data(self, ud, d):
388 if ud.shallow and ud.write_shallow_tarballs: 417 if ud.shallow and ud.write_shallow_tarballs:
389 if not os.path.exists(ud.fullshallow): 418 if not os.path.exists(ud.fullshallow):
@@ -479,7 +508,7 @@ class Git(FetchMethod):
479 if os.path.exists(destdir): 508 if os.path.exists(destdir):
480 bb.utils.prunedir(destdir) 509 bb.utils.prunedir(destdir)
481 510
482 need_lfs = ud.parm.get("lfs", "1") == "1" 511 need_lfs = self._need_lfs(ud)
483 512
484 if not need_lfs: 513 if not need_lfs:
485 ud.basecmd = "GIT_LFS_SKIP_SMUDGE=1 " + ud.basecmd 514 ud.basecmd = "GIT_LFS_SKIP_SMUDGE=1 " + ud.basecmd
@@ -568,6 +597,9 @@ class Git(FetchMethod):
568 raise bb.fetch2.FetchError("The command '%s' gave output with more then 1 line unexpectedly, output: '%s'" % (cmd, output)) 597 raise bb.fetch2.FetchError("The command '%s' gave output with more then 1 line unexpectedly, output: '%s'" % (cmd, output))
569 return output.split()[0] != "0" 598 return output.split()[0] != "0"
570 599
600 def _need_lfs(self, ud):
601 return ud.parm.get("lfs", "1") == "1"
602
571 def _contains_lfs(self, ud, d, wd): 603 def _contains_lfs(self, ud, d, wd):
572 """ 604 """
573 Check if the repository has 'lfs' (large file) content 605 Check if the repository has 'lfs' (large file) content
@@ -578,8 +610,14 @@ class Git(FetchMethod):
578 else: 610 else:
579 branchname = "master" 611 branchname = "master"
580 612
581 cmd = "%s grep lfs origin/%s:.gitattributes | wc -l" % ( 613 # The bare clonedir doesn't use the remote names; it has the branch immediately.
582 ud.basecmd, ud.branches[ud.names[0]]) 614 if wd == ud.clonedir:
615 refname = ud.branches[ud.names[0]]
616 else:
617 refname = "origin/%s" % ud.branches[ud.names[0]]
618
619 cmd = "%s grep lfs %s:.gitattributes | wc -l" % (
620 ud.basecmd, refname)
583 621
584 try: 622 try:
585 output = runfetchcmd(cmd, d, quiet=True, workdir=wd) 623 output = runfetchcmd(cmd, d, quiet=True, workdir=wd)