diff options
author | Joshua Watt <JPEWhacker@gmail.com> | 2023-08-24 13:53:32 -0600 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-08-30 10:41:54 +0100 |
commit | 10f38157a069cb6938323cadd5e523037a29ace9 (patch) | |
tree | d73d3a051c062adad9ba4a51327853ee7a03a6fd /bitbake/lib/bb/fetch2/git.py | |
parent | 264e5fef9e8e15d2fca02b392ea1331c55ceea7c (diff) | |
download | poky-10f38157a069cb6938323cadd5e523037a29ace9.tar.gz |
bitbake: fetch2: git: Check if clone directory is a git repo
If the clone target directory exists and is a valid git repo, but the
git directory is not a child, it needs to be erased and re-cloned. One
example of how this can happen is if a clone creates the directory, but
then fails to actual clone and make it a git repository. This left-over
directory can be particularly problematic if the download directory is a
descent of some top layer git repo (e.g. the default with poky), as the
commands that operate on the remote later will then mangle the layers
git repository instead of the download git repo.
(Bitbake rev: 2117db3146ce38bb4a6e2df40b6cd2ab11b514d5)
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.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.py | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/bitbake/lib/bb/fetch2/git.py b/bitbake/lib/bb/fetch2/git.py index 2a3c06fe4e..33895e09b2 100644 --- a/bitbake/lib/bb/fetch2/git.py +++ b/bitbake/lib/bb/fetch2/git.py | |||
@@ -65,6 +65,7 @@ import fnmatch | |||
65 | import os | 65 | import os |
66 | import re | 66 | import re |
67 | import shlex | 67 | import shlex |
68 | import shutil | ||
68 | import subprocess | 69 | import subprocess |
69 | import tempfile | 70 | import tempfile |
70 | import bb | 71 | import bb |
@@ -365,8 +366,35 @@ class Git(FetchMethod): | |||
365 | runfetchcmd(fetch_cmd, d, workdir=ud.clonedir) | 366 | runfetchcmd(fetch_cmd, d, workdir=ud.clonedir) |
366 | repourl = self._get_repo_url(ud) | 367 | repourl = self._get_repo_url(ud) |
367 | 368 | ||
369 | needs_clone = False | ||
370 | if os.path.exists(ud.clonedir): | ||
371 | # The directory may exist, but not be the top level of a bare git | ||
372 | # repository in which case it needs to be deleted and re-cloned. | ||
373 | try: | ||
374 | # Since clones can be bare, use --absolute-git-dir instead of --show-toplevel | ||
375 | output = runfetchcmd("LANG=C %s rev-parse --absolute-git-dir" % ud.basecmd, d, workdir=ud.clonedir) | ||
376 | except bb.fetch2.FetchError as e: | ||
377 | logger.warning("Unable to get top level for %s (not a git directory?): %s", ud.clonedir, e) | ||
378 | needs_clone = True | ||
379 | else: | ||
380 | toplevel = os.path.abspath(output.rstrip()) | ||
381 | abs_clonedir = os.path.abspath(ud.clonedir).rstrip('/') | ||
382 | # The top level Git directory must either be the clone directory | ||
383 | # or a child of the clone directory. Any ancestor directory of | ||
384 | # the clone directory is not valid as the Git directory (and | ||
385 | # probably belongs to some other unrelated repository), so a | ||
386 | # clone is required | ||
387 | if os.path.commonprefix([abs_clonedir, toplevel]) != abs_clonedir: | ||
388 | logger.warning("Top level directory '%s' doesn't match expected '%s'. Re-cloning", toplevel, ud.clonedir) | ||
389 | needs_clone = True | ||
390 | |||
391 | if needs_clone: | ||
392 | shutil.rmtree(ud.clonedir) | ||
393 | else: | ||
394 | needs_clone = True | ||
395 | |||
368 | # If the repo still doesn't exist, fallback to cloning it | 396 | # If the repo still doesn't exist, fallback to cloning it |
369 | if not os.path.exists(ud.clonedir): | 397 | if needs_clone: |
370 | # We do this since git will use a "-l" option automatically for local urls where possible, | 398 | # We do this since git will use a "-l" option automatically for local urls where possible, |
371 | # but it doesn't work when git/objects is a symlink, only works when it is a directory. | 399 | # but it doesn't work when git/objects is a symlink, only works when it is a directory. |
372 | if repourl.startswith("file://"): | 400 | if repourl.startswith("file://"): |