diff options
author | Philip Lorenz <philip.lorenz@bmw.de> | 2024-02-22 14:14:47 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-02-23 14:34:05 +0000 |
commit | 0e3bcc51037aa8e1f7992756f7476a879625b114 (patch) | |
tree | 348709c9d92fb8972ebf7383054c522e59511864 /bitbake/lib/bb/tests/fetch.py | |
parent | fff242b5d21f9d856557ed9367fa43fa8b435be5 (diff) | |
download | poky-0e3bcc51037aa8e1f7992756f7476a879625b114.tar.gz |
bitbake: fetch2: Ensure that git LFS objects are available
The current implementation only performs a git lfs fetch alongside of a
regular git fetch. This causes issues when the downloaded revision is
already part of the fetched repository (e.g. because of moving back in
history or the updated revision already being part of the repository at
the time of the initial clone).
Fix this by explicitly checking whether the required LFS objects are
available in the downloade directory before confirming that a downloaded
repository is up-to-date.
This issue previously went unnoticed as git lfs would silently fetch the
missing objects during the `unpack` task. With network isolation turned
on, this no longer works, and unpacking fails.
(Bitbake rev: cfae1556bf671acec119a6c8bbc4b667a856b9ae)
Signed-off-by: Philip Lorenz <philip.lorenz@bmw.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/tests/fetch.py')
-rw-r--r-- | bitbake/lib/bb/tests/fetch.py | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py index 5ed5b5607f..e988e26c0a 100644 --- a/bitbake/lib/bb/tests/fetch.py +++ b/bitbake/lib/bb/tests/fetch.py | |||
@@ -6,6 +6,7 @@ | |||
6 | # SPDX-License-Identifier: GPL-2.0-only | 6 | # SPDX-License-Identifier: GPL-2.0-only |
7 | # | 7 | # |
8 | 8 | ||
9 | import contextlib | ||
9 | import unittest | 10 | import unittest |
10 | import hashlib | 11 | import hashlib |
11 | import tempfile | 12 | import tempfile |
@@ -2261,10 +2262,14 @@ class GitLfsTest(FetcherTest): | |||
2261 | 2262 | ||
2262 | bb.utils.mkdirhier(self.srcdir) | 2263 | bb.utils.mkdirhier(self.srcdir) |
2263 | self.git_init(cwd=self.srcdir) | 2264 | self.git_init(cwd=self.srcdir) |
2264 | with open(os.path.join(self.srcdir, '.gitattributes'), 'wt') as attrs: | 2265 | self.commit_file('.gitattributes', '*.mp3 filter=lfs -text') |
2265 | attrs.write('*.mp3 filter=lfs -text') | 2266 | |
2266 | self.git(['add', '.gitattributes'], cwd=self.srcdir) | 2267 | def commit_file(self, filename, content): |
2267 | self.git(['commit', '-m', "attributes", '.gitattributes'], cwd=self.srcdir) | 2268 | with open(os.path.join(self.srcdir, filename), "w") as f: |
2269 | f.write(content) | ||
2270 | self.git(["add", filename], cwd=self.srcdir) | ||
2271 | self.git(["commit", "-m", "Change"], cwd=self.srcdir) | ||
2272 | return self.git(["rev-parse", "HEAD"], cwd=self.srcdir).strip() | ||
2268 | 2273 | ||
2269 | def fetch(self, uri=None, download=True): | 2274 | def fetch(self, uri=None, download=True): |
2270 | uris = self.d.getVar('SRC_URI').split() | 2275 | uris = self.d.getVar('SRC_URI').split() |
@@ -2285,6 +2290,44 @@ class GitLfsTest(FetcherTest): | |||
2285 | return unpacked_lfs_file | 2290 | return unpacked_lfs_file |
2286 | 2291 | ||
2287 | @skipIfNoGitLFS() | 2292 | @skipIfNoGitLFS() |
2293 | def test_fetch_lfs_on_srcrev_change(self): | ||
2294 | """Test if fetch downloads missing LFS objects when a different revision within an existing repository is requested""" | ||
2295 | self.git(["lfs", "install", "--local"], cwd=self.srcdir) | ||
2296 | |||
2297 | @contextlib.contextmanager | ||
2298 | def hide_upstream_repository(): | ||
2299 | """Hide the upstream repository to make sure that git lfs cannot pull from it""" | ||
2300 | temp_name = self.srcdir + ".bak" | ||
2301 | os.rename(self.srcdir, temp_name) | ||
2302 | try: | ||
2303 | yield | ||
2304 | finally: | ||
2305 | os.rename(temp_name, self.srcdir) | ||
2306 | |||
2307 | def fetch_and_verify(revision, filename, content): | ||
2308 | self.d.setVar('SRCREV', revision) | ||
2309 | fetcher, ud = self.fetch() | ||
2310 | |||
2311 | with hide_upstream_repository(): | ||
2312 | workdir = self.d.getVar('WORKDIR') | ||
2313 | fetcher.unpack(workdir) | ||
2314 | |||
2315 | with open(os.path.join(workdir, "git", filename)) as f: | ||
2316 | self.assertEqual(f.read(), content) | ||
2317 | |||
2318 | commit_1 = self.commit_file("a.mp3", "version 1") | ||
2319 | commit_2 = self.commit_file("a.mp3", "version 2") | ||
2320 | |||
2321 | self.d.setVar('SRC_URI', "git://%s;protocol=file;lfs=1;branch=master" % self.srcdir) | ||
2322 | |||
2323 | # Seed the local download folder by fetching the latest commit and verifying that the LFS contents are | ||
2324 | # available even when the upstream repository disappears. | ||
2325 | fetch_and_verify(commit_2, "a.mp3", "version 2") | ||
2326 | # Verify that even when an older revision is fetched, the needed LFS objects are fetched into the download | ||
2327 | # folder. | ||
2328 | fetch_and_verify(commit_1, "a.mp3", "version 1") | ||
2329 | |||
2330 | @skipIfNoGitLFS() | ||
2288 | @skipIfNoNetwork() | 2331 | @skipIfNoNetwork() |
2289 | def test_real_git_lfs_repo_succeeds_without_lfs_param(self): | 2332 | def test_real_git_lfs_repo_succeeds_without_lfs_param(self): |
2290 | self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master") | 2333 | self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master") |