diff options
Diffstat (limited to 'bitbake/lib/bb/fetch2/git.py')
| -rw-r--r-- | bitbake/lib/bb/fetch2/git.py | 133 |
1 files changed, 118 insertions, 15 deletions
diff --git a/bitbake/lib/bb/fetch2/git.py b/bitbake/lib/bb/fetch2/git.py index 01d4bbdc2e..0412f9ff51 100644 --- a/bitbake/lib/bb/fetch2/git.py +++ b/bitbake/lib/bb/fetch2/git.py | |||
| @@ -73,8 +73,9 @@ Supported SRC_URI options are: | |||
| 73 | import errno | 73 | import errno |
| 74 | import os | 74 | import os |
| 75 | import re | 75 | import re |
| 76 | import subprocess | ||
| 77 | import tempfile | ||
| 76 | import bb | 78 | import bb |
| 77 | import errno | ||
| 78 | import bb.progress | 79 | import bb.progress |
| 79 | from bb.fetch2 import FetchMethod | 80 | from bb.fetch2 import FetchMethod |
| 80 | from bb.fetch2 import runfetchcmd | 81 | from bb.fetch2 import runfetchcmd |
| @@ -172,6 +173,11 @@ class Git(FetchMethod): | |||
| 172 | branches = ud.parm.get("branch", "master").split(',') | 173 | branches = ud.parm.get("branch", "master").split(',') |
| 173 | if len(branches) != len(ud.names): | 174 | if len(branches) != len(ud.names): |
| 174 | raise bb.fetch2.ParameterError("The number of name and branch parameters is not balanced", ud.url) | 175 | raise bb.fetch2.ParameterError("The number of name and branch parameters is not balanced", ud.url) |
| 176 | |||
| 177 | ud.cloneflags = "-s -n" | ||
| 178 | if ud.bareclone: | ||
| 179 | ud.cloneflags += " --mirror" | ||
| 180 | |||
| 175 | ud.branches = {} | 181 | ud.branches = {} |
| 176 | for pos, name in enumerate(ud.names): | 182 | for pos, name in enumerate(ud.names): |
| 177 | branch = branches[pos] | 183 | branch = branches[pos] |
| @@ -183,7 +189,9 @@ class Git(FetchMethod): | |||
| 183 | 189 | ||
| 184 | ud.basecmd = d.getVar("FETCHCMD_git") or "git -c core.fsyncobjectfiles=0" | 190 | ud.basecmd = d.getVar("FETCHCMD_git") or "git -c core.fsyncobjectfiles=0" |
| 185 | 191 | ||
| 186 | ud.write_tarballs = ((d.getVar("BB_GENERATE_MIRROR_TARBALLS") or "0") != "0") or ud.rebaseable | 192 | write_tarballs = d.getVar("BB_GENERATE_MIRROR_TARBALLS") or "0" |
| 193 | ud.write_tarballs = write_tarballs != "0" or ud.rebaseable | ||
| 194 | ud.write_shallow_tarballs = (d.getVar("BB_GENERATE_SHALLOW_TARBALLS") or write_tarballs) != "0" | ||
| 187 | 195 | ||
| 188 | ud.setup_revisions(d) | 196 | ud.setup_revisions(d) |
| 189 | 197 | ||
| @@ -205,13 +213,48 @@ class Git(FetchMethod): | |||
| 205 | if ud.rebaseable: | 213 | if ud.rebaseable: |
| 206 | for name in ud.names: | 214 | for name in ud.names: |
| 207 | gitsrcname = gitsrcname + '_' + ud.revisions[name] | 215 | gitsrcname = gitsrcname + '_' + ud.revisions[name] |
| 216 | |||
| 217 | dl_dir = d.getVar("DL_DIR") | ||
| 218 | gitdir = d.getVar("GITDIR") or (dl_dir + "/git2/") | ||
| 219 | ud.clonedir = os.path.join(gitdir, gitsrcname) | ||
| 220 | ud.localfile = ud.clonedir | ||
| 221 | |||
| 208 | mirrortarball = 'git2_%s.tar.gz' % gitsrcname | 222 | mirrortarball = 'git2_%s.tar.gz' % gitsrcname |
| 209 | ud.fullmirror = os.path.join(d.getVar("DL_DIR"), mirrortarball) | 223 | ud.fullmirror = os.path.join(dl_dir, mirrortarball) |
| 210 | ud.mirrortarballs = [mirrortarball] | 224 | ud.mirrortarballs = [mirrortarball] |
| 211 | gitdir = d.getVar("GITDIR") or (d.getVar("DL_DIR") + "/git2/") | ||
| 212 | ud.clonedir = os.path.join(gitdir, gitsrcname) | ||
| 213 | 225 | ||
| 214 | ud.localfile = ud.clonedir | 226 | ud.shallow = d.getVar("BB_GIT_SHALLOW") == "1" |
| 227 | if ud.shallow: | ||
| 228 | ud.shallow_depth = d.getVar("BB_GIT_SHALLOW_DEPTH") | ||
| 229 | if ud.shallow_depth is not None: | ||
| 230 | try: | ||
| 231 | ud.shallow_depth = int(ud.shallow_depth or 0) | ||
| 232 | except ValueError: | ||
| 233 | raise bb.fetch2.FetchError("Invalid depth for BB_GIT_SHALLOW_DEPTH: %s" % ud.shallow_depth) | ||
| 234 | else: | ||
| 235 | if not ud.shallow_depth: | ||
| 236 | ud.shallow = False | ||
| 237 | elif ud.shallow_depth < 0: | ||
| 238 | raise bb.fetch2.FetchError("Invalid depth for BB_GIT_SHALLOW_DEPTH: %s" % ud.shallow_depth) | ||
| 239 | else: | ||
| 240 | ud.shallow_depth = 1 | ||
| 241 | |||
| 242 | if ud.shallow: | ||
| 243 | tarballname = gitsrcname | ||
| 244 | if ud.bareclone: | ||
| 245 | tarballname = "%s_bare" % tarballname | ||
| 246 | |||
| 247 | for name, revision in sorted(ud.revisions.items()): | ||
| 248 | tarballname = "%s_%s" % (tarballname, ud.revisions[name][:7]) | ||
| 249 | if not ud.nobranch: | ||
| 250 | tarballname = "%s-%s" % (tarballname, ud.branches[name]) | ||
| 251 | |||
| 252 | tarballname = "%s-%s" % (tarballname, ud.shallow_depth) | ||
| 253 | |||
| 254 | fetcher = self.__class__.__name__.lower() | ||
| 255 | ud.shallowtarball = '%sshallow_%s.tar.gz' % (fetcher, tarballname) | ||
| 256 | ud.fullshallow = os.path.join(dl_dir, ud.shallowtarball) | ||
| 257 | ud.mirrortarballs.insert(0, ud.shallowtarball) | ||
| 215 | 258 | ||
| 216 | def localpath(self, ud, d): | 259 | def localpath(self, ud, d): |
| 217 | return ud.clonedir | 260 | return ud.clonedir |
| @@ -222,6 +265,8 @@ class Git(FetchMethod): | |||
| 222 | for name in ud.names: | 265 | for name in ud.names: |
| 223 | if not self._contains_ref(ud, d, name, ud.clonedir): | 266 | if not self._contains_ref(ud, d, name, ud.clonedir): |
| 224 | return True | 267 | return True |
| 268 | if ud.shallow and ud.write_shallow_tarballs and not os.path.exists(ud.fullshallow): | ||
| 269 | return True | ||
| 225 | if ud.write_tarballs and not os.path.exists(ud.fullmirror): | 270 | if ud.write_tarballs and not os.path.exists(ud.fullmirror): |
| 226 | return True | 271 | return True |
| 227 | return False | 272 | return False |
| @@ -238,8 +283,16 @@ class Git(FetchMethod): | |||
| 238 | def download(self, ud, d): | 283 | def download(self, ud, d): |
| 239 | """Fetch url""" | 284 | """Fetch url""" |
| 240 | 285 | ||
| 241 | # If the checkout doesn't exist and the mirror tarball does, extract it | 286 | no_clone = not os.path.exists(ud.clonedir) |
| 242 | if not os.path.exists(ud.clonedir) and os.path.exists(ud.fullmirror): | 287 | need_update = no_clone or self.need_update(ud, d) |
| 288 | |||
| 289 | # A current clone is preferred to either tarball, a shallow tarball is | ||
| 290 | # preferred to an out of date clone, and a missing clone will use | ||
| 291 | # either tarball. | ||
| 292 | if ud.shallow and os.path.exists(ud.fullshallow) and need_update: | ||
| 293 | ud.localpath = ud.fullshallow | ||
| 294 | return | ||
| 295 | elif os.path.exists(ud.fullmirror) and no_clone: | ||
| 243 | bb.utils.mkdirhier(ud.clonedir) | 296 | bb.utils.mkdirhier(ud.clonedir) |
| 244 | runfetchcmd("tar -xzf %s" % ud.fullmirror, d, workdir=ud.clonedir) | 297 | runfetchcmd("tar -xzf %s" % ud.fullmirror, d, workdir=ud.clonedir) |
| 245 | 298 | ||
| @@ -285,9 +338,21 @@ class Git(FetchMethod): | |||
| 285 | raise bb.fetch2.FetchError("Unable to find revision %s in branch %s even from upstream" % (ud.revisions[name], ud.branches[name])) | 338 | raise bb.fetch2.FetchError("Unable to find revision %s in branch %s even from upstream" % (ud.revisions[name], ud.branches[name])) |
| 286 | 339 | ||
| 287 | def build_mirror_data(self, ud, d): | 340 | def build_mirror_data(self, ud, d): |
| 288 | # Generate a mirror tarball if needed | 341 | if ud.shallow and ud.write_shallow_tarballs: |
| 289 | if ud.write_tarballs and not os.path.exists(ud.fullmirror): | 342 | if not os.path.exists(ud.fullshallow): |
| 290 | # it's possible that this symlink points to read-only filesystem with PREMIRROR | 343 | if os.path.islink(ud.fullshallow): |
| 344 | os.unlink(ud.fullshallow) | ||
| 345 | tempdir = tempfile.mkdtemp(dir=d.getVar('DL_DIR')) | ||
| 346 | shallowclone = os.path.join(tempdir, 'git') | ||
| 347 | try: | ||
| 348 | self.clone_shallow_local(ud, shallowclone, d) | ||
| 349 | |||
| 350 | logger.info("Creating tarball of git repository") | ||
| 351 | runfetchcmd("tar -czf %s ." % ud.fullshallow, d, workdir=shallowclone) | ||
| 352 | runfetchcmd("touch %s.done" % ud.fullshallow, d) | ||
| 353 | finally: | ||
| 354 | bb.utils.remove(tempdir, recurse=True) | ||
| 355 | elif ud.write_tarballs and not os.path.exists(ud.fullmirror): | ||
| 291 | if os.path.islink(ud.fullmirror): | 356 | if os.path.islink(ud.fullmirror): |
| 292 | os.unlink(ud.fullmirror) | 357 | os.unlink(ud.fullmirror) |
| 293 | 358 | ||
| @@ -295,6 +360,43 @@ class Git(FetchMethod): | |||
| 295 | runfetchcmd("tar -czf %s ." % ud.fullmirror, d, workdir=ud.clonedir) | 360 | runfetchcmd("tar -czf %s ." % ud.fullmirror, d, workdir=ud.clonedir) |
| 296 | runfetchcmd("touch %s.done" % ud.fullmirror, d) | 361 | runfetchcmd("touch %s.done" % ud.fullmirror, d) |
| 297 | 362 | ||
| 363 | def clone_shallow_local(self, ud, dest, d): | ||
| 364 | """Clone the repo and make it shallow. | ||
| 365 | |||
| 366 | The upstream url of the new clone isn't set at this time, as it'll be | ||
| 367 | set correctly when unpacked.""" | ||
| 368 | runfetchcmd("%s clone %s %s %s" % (ud.basecmd, ud.cloneflags, ud.clonedir, dest), d) | ||
| 369 | |||
| 370 | to_parse, shallow_branches = [], [] | ||
| 371 | for name in ud.names: | ||
| 372 | revision = ud.revisions[name] | ||
| 373 | to_parse.append('%s~%d^{}' % (revision, ud.shallow_depth - 1)) | ||
| 374 | |||
| 375 | # For nobranch, we need a ref, otherwise the commits will be | ||
| 376 | # removed, and for non-nobranch, we truncate the branch to our | ||
| 377 | # srcrev, to avoid keeping unnecessary history beyond that. | ||
| 378 | branch = ud.branches[name] | ||
| 379 | if ud.nobranch: | ||
| 380 | ref = "refs/shallow/%s" % name | ||
| 381 | elif ud.bareclone: | ||
| 382 | ref = "refs/heads/%s" % branch | ||
| 383 | else: | ||
| 384 | ref = "refs/remotes/origin/%s" % branch | ||
| 385 | |||
| 386 | shallow_branches.append(ref) | ||
| 387 | runfetchcmd("%s update-ref %s %s" % (ud.basecmd, ref, revision), d, workdir=dest) | ||
| 388 | |||
| 389 | # Map srcrev+depths to revisions | ||
| 390 | shallow_revisions = runfetchcmd("%s rev-parse %s" % (ud.basecmd, " ".join(to_parse)), d, workdir=dest).splitlines() | ||
| 391 | |||
| 392 | # Make the repository shallow | ||
| 393 | shallow_cmd = ['git', 'make-shallow', '-s'] | ||
| 394 | for b in shallow_branches: | ||
| 395 | shallow_cmd.append('-r') | ||
| 396 | shallow_cmd.append(b) | ||
| 397 | shallow_cmd.extend(shallow_revisions) | ||
| 398 | runfetchcmd(subprocess.list2cmdline(shallow_cmd), d, workdir=dest) | ||
| 399 | |||
| 298 | def unpack(self, ud, destdir, d): | 400 | def unpack(self, ud, destdir, d): |
| 299 | """ unpack the downloaded src to destdir""" | 401 | """ unpack the downloaded src to destdir""" |
| 300 | 402 | ||
| @@ -311,11 +413,12 @@ class Git(FetchMethod): | |||
| 311 | if os.path.exists(destdir): | 413 | if os.path.exists(destdir): |
| 312 | bb.utils.prunedir(destdir) | 414 | bb.utils.prunedir(destdir) |
| 313 | 415 | ||
| 314 | cloneflags = "-s -n" | 416 | if ud.shallow and (not os.path.exists(ud.clonedir) or self.need_update(ud, d)): |
| 315 | if ud.bareclone: | 417 | bb.utils.mkdirhier(destdir) |
| 316 | cloneflags += " --mirror" | 418 | runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=destdir) |
| 419 | else: | ||
| 420 | runfetchcmd("%s clone %s %s/ %s" % (ud.basecmd, ud.cloneflags, ud.clonedir, destdir), d) | ||
| 317 | 421 | ||
| 318 | runfetchcmd("%s clone %s %s/ %s" % (ud.basecmd, cloneflags, ud.clonedir, destdir), d) | ||
| 319 | repourl = self._get_repo_url(ud) | 422 | repourl = self._get_repo_url(ud) |
| 320 | runfetchcmd("%s remote set-url origin %s" % (ud.basecmd, repourl), d, workdir=destdir) | 423 | runfetchcmd("%s remote set-url origin %s" % (ud.basecmd, repourl), d, workdir=destdir) |
| 321 | if not ud.nocheckout: | 424 | if not ud.nocheckout: |
