summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/fetch2/git.py
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2023-08-24 13:53:32 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-08-30 10:41:54 +0100
commit10f38157a069cb6938323cadd5e523037a29ace9 (patch)
treed73d3a051c062adad9ba4a51327853ee7a03a6fd /bitbake/lib/bb/fetch2/git.py
parent264e5fef9e8e15d2fca02b392ea1331c55ceea7c (diff)
downloadpoky-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.py30
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
65import os 65import os
66import re 66import re
67import shlex 67import shlex
68import shutil
68import subprocess 69import subprocess
69import tempfile 70import tempfile
70import bb 71import 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://"):