summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/fetch2/gitsm.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/fetch2/gitsm.py')
-rw-r--r--bitbake/lib/bb/fetch2/gitsm.py107
1 files changed, 84 insertions, 23 deletions
diff --git a/bitbake/lib/bb/fetch2/gitsm.py b/bitbake/lib/bb/fetch2/gitsm.py
index c622771d21..f7f3af7212 100644
--- a/bitbake/lib/bb/fetch2/gitsm.py
+++ b/bitbake/lib/bb/fetch2/gitsm.py
@@ -20,11 +20,12 @@ NOTE: Switching a SRC_URI from "git://" to "gitsm://" requires a clean of your r
import os
import bb
import copy
+import shutil
+import tempfile
from bb.fetch2.git import Git
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
from bb.fetch2 import Fetch
-from bb.fetch2 import BBFetchException
class GitSM(Git):
def supports(self, ud, d):
@@ -77,7 +78,7 @@ class GitSM(Git):
module_hash = ""
if not module_hash:
- logger.debug(1, "submodule %s is defined, but is not initialized in the repository. Skipping", m)
+ logger.debug("submodule %s is defined, but is not initialized in the repository. Skipping", m)
continue
submodules.append(m)
@@ -87,9 +88,9 @@ class GitSM(Git):
subrevision[m] = module_hash.split()[2]
# Convert relative to absolute uri based on parent uri
- if uris[m].startswith('..'):
+ if uris[m].startswith('..') or uris[m].startswith('./'):
newud = copy.copy(ud)
- newud.path = os.path.realpath(os.path.join(newud.path, uris[m]))
+ newud.path = os.path.normpath(os.path.join(newud.path, uris[m]))
uris[m] = Git._get_repo_url(self, newud)
for module in submodules:
@@ -114,10 +115,21 @@ class GitSM(Git):
# This has to be a file reference
proto = "file"
url = "gitsm://" + uris[module]
+ if url.endswith("{}{}".format(ud.host, ud.path)):
+ raise bb.fetch2.FetchError("Submodule refers to the parent repository. This will cause deadlock situation in current version of Bitbake." \
+ "Consider using git fetcher instead.")
url += ';protocol=%s' % proto
url += ";name=%s" % module
url += ";subpath=%s" % module
+ url += ";nobranch=1"
+ url += ";lfs=%s" % self._need_lfs(ud)
+ # Note that adding "user=" here to give credentials to the
+ # submodule is not supported. Since using SRC_URI to give git://
+ # URL a password is not supported, one have to use one of the
+ # recommended way (eg. ~/.netrc or SSH config) which does specify
+ # the user (See comment in git.py).
+ # So, we will not take patches adding "user=" support here.
ld = d.createCopy()
# Not necessary to set SRC_URI, since we're passing the URI to
@@ -131,7 +143,7 @@ class GitSM(Git):
ld.setVar('SRCPV', d.getVar('SRCPV'))
ld.setVar('SRCREV_FORMAT', module)
- function(ud, url, module, paths[module], ld)
+ function(ud, url, module, paths[module], workdir, ld)
return submodules != []
@@ -139,21 +151,37 @@ class GitSM(Git):
if Git.need_update(self, ud, d):
return True
- try:
- # Check for the nugget dropped by the download operation
- known_srcrevs = runfetchcmd("%s config --get-all bitbake.srcrev" % \
- (ud.basecmd), d, workdir=ud.clonedir)
+ need_update_list = []
+ def need_update_submodule(ud, url, module, modpath, workdir, d):
+ url += ";bareclone=1;nobranch=1"
- if ud.revisions[ud.names[0]] not in known_srcrevs.split():
- return True
- except bb.fetch2.FetchError:
- # No srcrev nuggets, so this is new and needs to be updated
+ try:
+ newfetch = Fetch([url], d, cache=False)
+ new_ud = newfetch.ud[url]
+ if new_ud.method.need_update(new_ud, d):
+ need_update_list.append(modpath)
+ except Exception as e:
+ logger.error('gitsm: submodule update check failed: %s %s' % (type(e).__name__, str(e)))
+ need_update_result = True
+
+ # If we're using a shallow mirror tarball it needs to be unpacked
+ # temporarily so that we can examine the .gitmodules file
+ if ud.shallow and os.path.exists(ud.fullshallow) and not os.path.exists(ud.clonedir):
+ tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR"))
+ runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=tmpdir)
+ self.process_submodules(ud, tmpdir, need_update_submodule, d)
+ shutil.rmtree(tmpdir)
+ else:
+ self.process_submodules(ud, ud.clonedir, need_update_submodule, d)
+
+ if need_update_list:
+ logger.debug('gitsm: Submodules requiring update: %s' % (' '.join(need_update_list)))
return True
return False
def download(self, ud, d):
- def download_submodule(ud, url, module, modpath, d):
+ def download_submodule(ud, url, module, modpath, workdir, d):
url += ";bareclone=1;nobranch=1"
# Is the following still needed?
@@ -162,18 +190,24 @@ class GitSM(Git):
try:
newfetch = Fetch([url], d, cache=False)
newfetch.download()
- # Drop a nugget to add each of the srcrevs we've fetched (used by need_update)
- runfetchcmd("%s config --add bitbake.srcrev %s" % \
- (ud.basecmd, ud.revisions[ud.names[0]]), d, workdir=ud.clonedir)
except Exception as e:
logger.error('gitsm: submodule download failed: %s %s' % (type(e).__name__, str(e)))
raise
Git.download(self, ud, d)
- self.process_submodules(ud, ud.clonedir, download_submodule, d)
+
+ # If we're using a shallow mirror tarball it needs to be unpacked
+ # temporarily so that we can examine the .gitmodules file
+ if ud.shallow and os.path.exists(ud.fullshallow) and self.need_update(ud, d):
+ tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR"))
+ runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=tmpdir)
+ self.process_submodules(ud, tmpdir, download_submodule, d)
+ shutil.rmtree(tmpdir)
+ else:
+ self.process_submodules(ud, ud.clonedir, download_submodule, d)
def unpack(self, ud, destdir, d):
- def unpack_submodules(ud, url, module, modpath, d):
+ def unpack_submodules(ud, url, module, modpath, workdir, d):
url += ";bareclone=1;nobranch=1"
# Figure out where we clone over the bare submodules...
@@ -184,6 +218,10 @@ class GitSM(Git):
try:
newfetch = Fetch([url], d, cache=False)
+ # modpath is needed by unpack tracer to calculate submodule
+ # checkout dir
+ new_ud = newfetch.ud[url]
+ new_ud.modpath = modpath
newfetch.unpack(root=os.path.dirname(os.path.join(repo_conf, 'modules', module)))
except Exception as e:
logger.error('gitsm: submodule unpack failed: %s %s' % (type(e).__name__, str(e)))
@@ -209,7 +247,30 @@ class GitSM(Git):
ret = self.process_submodules(ud, ud.destdir, unpack_submodules, d)
if not ud.bareclone and ret:
- # All submodules should already be downloaded and configured in the tree. This simply sets
- # up the configuration and checks out the files. The main project config should remain
- # unmodified, and no download from the internet should occur.
- runfetchcmd("%s submodule update --recursive --no-fetch" % (ud.basecmd), d, quiet=True, workdir=ud.destdir)
+ # All submodules should already be downloaded and configured in the tree. This simply
+ # sets up the configuration and checks out the files. The main project config should
+ # remain unmodified, and no download from the internet should occur. As such, lfs smudge
+ # should also be skipped as these files were already smudged in the fetch stage if lfs
+ # was enabled.
+ runfetchcmd("GIT_LFS_SKIP_SMUDGE=1 %s submodule update --recursive --no-fetch" % (ud.basecmd), d, quiet=True, workdir=ud.destdir)
+
+ def implicit_urldata(self, ud, d):
+ import shutil, subprocess, tempfile
+
+ urldata = []
+ def add_submodule(ud, url, module, modpath, workdir, d):
+ url += ";bareclone=1;nobranch=1"
+ newfetch = Fetch([url], d, cache=False)
+ urldata.extend(newfetch.expanded_urldata())
+
+ # If we're using a shallow mirror tarball it needs to be unpacked
+ # temporarily so that we can examine the .gitmodules file
+ if ud.shallow and os.path.exists(ud.fullshallow) and ud.method.need_update(ud, d):
+ tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR"))
+ subprocess.check_call("tar -xzf %s" % ud.fullshallow, cwd=tmpdir, shell=True)
+ self.process_submodules(ud, tmpdir, add_submodule, d)
+ shutil.rmtree(tmpdir)
+ else:
+ self.process_submodules(ud, ud.clonedir, add_submodule, d)
+
+ return urldata