diff options
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://"): |
