bitbake: bitbake: fetch2: git: Update Git-LFS download and tests

When downloading a Git repository containing an LFS, the Git hooks
are not always initialized correctly to perform the download. This
change updates the Git downloader to run the "git lfs install" command
in order to "smudge" the LFS files. The tests have also been updated
to do checks for situations in which git lfs is not installed, as
the application was required to be installed for any of the tests
to run previously.

The Git LFS functionality was working to some degree previously,
but this change also updates the fetcher to allow LFS downloads for
nobranch SRC_URIs.

(Bitbake rev: 05f8529fb439db93d85a892704b6f2f0ac0c9217)

Signed-off-by: Desone Burns II <dburns@seegrid.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Desone Burns
2023-11-03 11:45:49 -04:00
committed by Richard Purdie
parent 6a87f5d53b
commit 7aab731f1e
2 changed files with 47 additions and 28 deletions

View File

@@ -52,6 +52,11 @@ Supported SRC_URI options are:
For local git:// urls to use the current branch HEAD as the revision for use with
AUTOREV. Implies nobranch.
- lfs
Enable the checkout to use LFS for large files. This will download all LFS files
in the download step, as the unpack step does not have network access.
The default is "1", set lfs=0 to skip.
"""
# Copyright (C) 2005 Richard Purdie
@@ -629,6 +634,8 @@ class Git(FetchMethod):
raise bb.fetch2.FetchError("Repository %s has LFS content, install git-lfs on host to download (or set lfs=0 to ignore it)" % (repourl))
elif not need_lfs:
bb.note("Repository %s has LFS content but it is not being fetched" % (repourl))
else:
runfetchcmd("%s lfs install" % ud.basecmd, d, workdir=destdir)
if not ud.nocheckout:
if subpath:
@@ -688,8 +695,11 @@ class Git(FetchMethod):
Check if the repository has 'lfs' (large file) content
"""
# The bare clonedir doesn't use the remote names; it has the branch immediately.
if wd == ud.clonedir:
if ud.nobranch:
# If no branch is specified, use the current git commit
refname = self._build_revision(ud, d, ud.names[0])
elif wd == ud.clonedir:
# The bare clonedir doesn't use the remote names; it has the branch immediately.
refname = ud.branches[ud.names[0]]
else:
refname = "origin/%s" % ud.branches[ud.names[0]]

View File

@@ -2277,7 +2277,7 @@ class GitLfsTest(FetcherTest):
@skipIfNoGitLFS()
@skipIfNoNetwork()
def test_real_git_lfs_repo_succeeds(self):
def test_real_git_lfs_repo_skips(self):
self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master;lfs=0")
f = self.get_real_git_lfs_file()
# This is the actual non-smudged placeholder file on the repo if git-lfs does not run
@@ -2290,24 +2290,41 @@ class GitLfsTest(FetcherTest):
with open(f) as fh:
self.assertEqual(lfs_file, fh.read())
@skipIfNoGitLFS()
def test_lfs_enabled(self):
import shutil
uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir
self.d.setVar('SRC_URI', uri)
# Careful: suppress initial attempt at downloading until
# we know whether git-lfs is installed.
# With git-lfs installed, test that we can fetch and unpack
fetcher, ud = self.fetch()
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))
@skipIfNoGitLFS()
def test_lfs_disabled(self):
import shutil
uri = 'git://%s;protocol=file;lfs=0;branch=master' % self.srcdir
self.d.setVar('SRC_URI', uri)
# Verify that the fetcher can survive even if the source
# repository has Git LFS usage configured.
fetcher, ud = self.fetch()
fetcher.unpack(self.d.getVar('WORKDIR'))
def test_lfs_enabled_not_installed(self):
import shutil
uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir
self.d.setVar('SRC_URI', uri)
# Careful: suppress initial attempt at downloading
fetcher, ud = self.fetch(uri=None, download=False)
self.assertIsNotNone(ud.method._find_git_lfs)
# If git-lfs can be found, the unpack should be successful. Only
# attempt this with the real live copy of git-lfs installed.
if ud.method._find_git_lfs(self.d):
fetcher.download()
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))
# Artificially assert that git-lfs is not installed, so
# we can verify a failure to unpack in it's absence.
old_find_git_lfs = ud.method._find_git_lfs
try:
# If git-lfs cannot be found, the unpack should throw an error
@@ -2319,29 +2336,21 @@ class GitLfsTest(FetcherTest):
finally:
ud.method._find_git_lfs = old_find_git_lfs
def test_lfs_disabled(self):
def test_lfs_disabled_not_installed(self):
import shutil
uri = 'git://%s;protocol=file;lfs=0;branch=master' % self.srcdir
self.d.setVar('SRC_URI', uri)
# In contrast to test_lfs_enabled(), allow the implicit download
# done by self.fetch() to occur here. The point of this test case
# is to verify that the fetcher can survive even if the source
# repository has Git LFS usage configured.
fetcher, ud = self.fetch()
self.assertIsNotNone(ud.method._find_git_lfs)
# Careful: suppress initial attempt at downloading
fetcher, ud = self.fetch(uri=None, download=False)
# Artificially assert that git-lfs is not installed, so
# we can verify a failure to unpack in it's absence.
old_find_git_lfs = ud.method._find_git_lfs
try:
# If git-lfs can be found, the unpack should be successful. A
# live copy of git-lfs is not required for this case, so
# unconditionally forge its presence.
ud.method._find_git_lfs = lambda d: True
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))
# If git-lfs cannot be found, the unpack should be successful
# Even if git-lfs cannot be found, the unpack should be successful
fetcher.download()
ud.method._find_git_lfs = lambda d: False
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))