1
0
mirror of https://git.yoctoproject.org/poky synced 2026-05-30 00:20:08 +00:00

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>
This commit is contained in:
Joshua Watt
2023-08-24 13:53:32 -06:00
committed by Richard Purdie
parent 264e5fef9e
commit 10f38157a0
+29 -1
View File
@@ -65,6 +65,7 @@ import fnmatch
import os
import re
import shlex
import shutil
import subprocess
import tempfile
import bb
@@ -365,8 +366,35 @@ class Git(FetchMethod):
runfetchcmd(fetch_cmd, d, workdir=ud.clonedir)
repourl = self._get_repo_url(ud)
needs_clone = False
if os.path.exists(ud.clonedir):
# The directory may exist, but not be the top level of a bare git
# repository in which case it needs to be deleted and re-cloned.
try:
# Since clones can be bare, use --absolute-git-dir instead of --show-toplevel
output = runfetchcmd("LANG=C %s rev-parse --absolute-git-dir" % ud.basecmd, d, workdir=ud.clonedir)
except bb.fetch2.FetchError as e:
logger.warning("Unable to get top level for %s (not a git directory?): %s", ud.clonedir, e)
needs_clone = True
else:
toplevel = os.path.abspath(output.rstrip())
abs_clonedir = os.path.abspath(ud.clonedir).rstrip('/')
# The top level Git directory must either be the clone directory
# or a child of the clone directory. Any ancestor directory of
# the clone directory is not valid as the Git directory (and
# probably belongs to some other unrelated repository), so a
# clone is required
if os.path.commonprefix([abs_clonedir, toplevel]) != abs_clonedir:
logger.warning("Top level directory '%s' doesn't match expected '%s'. Re-cloning", toplevel, ud.clonedir)
needs_clone = True
if needs_clone:
shutil.rmtree(ud.clonedir)
else:
needs_clone = True
# If the repo still doesn't exist, fallback to cloning it
if not os.path.exists(ud.clonedir):
if needs_clone:
# We do this since git will use a "-l" option automatically for local urls where possible,
# but it doesn't work when git/objects is a symlink, only works when it is a directory.
if repourl.startswith("file://"):