diff options
-rw-r--r-- | bitbake/lib/bb/fetch2/git.py | 133 | ||||
-rw-r--r-- | bitbake/lib/bb/tests/fetch.py | 299 |
2 files changed, 417 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: |
diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py index 510071d25d..019f22a11d 100644 --- a/bitbake/lib/bb/tests/fetch.py +++ b/bitbake/lib/bb/tests/fetch.py | |||
@@ -979,3 +979,302 @@ class GitMakeShallowTest(FetcherTest): | |||
979 | orig_revs = len(self.git('rev-list --all').splitlines()) | 979 | orig_revs = len(self.git('rev-list --all').splitlines()) |
980 | self.make_shallow(['refs/tags/1.10.0']) | 980 | self.make_shallow(['refs/tags/1.10.0']) |
981 | self.assertRevCount(orig_revs - 1746, ['--all']) | 981 | self.assertRevCount(orig_revs - 1746, ['--all']) |
982 | |||
983 | class GitShallowTest(FetcherTest): | ||
984 | def setUp(self): | ||
985 | FetcherTest.setUp(self) | ||
986 | self.gitdir = os.path.join(self.tempdir, 'git') | ||
987 | self.srcdir = os.path.join(self.tempdir, 'gitsource') | ||
988 | |||
989 | bb.utils.mkdirhier(self.srcdir) | ||
990 | self.git('init', cwd=self.srcdir) | ||
991 | self.d.setVar('WORKDIR', self.tempdir) | ||
992 | self.d.setVar('S', self.gitdir) | ||
993 | self.d.delVar('PREMIRRORS') | ||
994 | self.d.delVar('MIRRORS') | ||
995 | |||
996 | uri = 'git://%s;protocol=file;subdir=${S}' % self.srcdir | ||
997 | self.d.setVar('SRC_URI', uri) | ||
998 | self.d.setVar('SRCREV', '${AUTOREV}') | ||
999 | self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}') | ||
1000 | |||
1001 | self.d.setVar('BB_GIT_SHALLOW', '1') | ||
1002 | self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '0') | ||
1003 | self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1') | ||
1004 | |||
1005 | def assertRefs(self, expected_refs, cwd=None): | ||
1006 | if cwd is None: | ||
1007 | cwd = self.gitdir | ||
1008 | actual_refs = self.git(['for-each-ref', '--format=%(refname)'], cwd=cwd).splitlines() | ||
1009 | full_expected = self.git(['rev-parse', '--symbolic-full-name'] + expected_refs, cwd=cwd).splitlines() | ||
1010 | self.assertEqual(sorted(set(full_expected)), sorted(set(actual_refs))) | ||
1011 | |||
1012 | def assertRevCount(self, expected_count, args=None, cwd=None): | ||
1013 | if args is None: | ||
1014 | args = ['HEAD'] | ||
1015 | if cwd is None: | ||
1016 | cwd = self.gitdir | ||
1017 | revs = self.git(['rev-list'] + args, cwd=cwd) | ||
1018 | actual_count = len(revs.splitlines()) | ||
1019 | self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count)) | ||
1020 | |||
1021 | def git(self, cmd, cwd=None): | ||
1022 | if isinstance(cmd, str): | ||
1023 | cmd = 'git ' + cmd | ||
1024 | else: | ||
1025 | cmd = ['git'] + cmd | ||
1026 | if cwd is None: | ||
1027 | cwd = self.gitdir | ||
1028 | return bb.process.run(cmd, cwd=cwd)[0] | ||
1029 | |||
1030 | def add_empty_file(self, path, msg=None): | ||
1031 | if msg is None: | ||
1032 | msg = path | ||
1033 | open(os.path.join(self.srcdir, path), 'w').close() | ||
1034 | self.git(['add', path], self.srcdir) | ||
1035 | self.git(['commit', '-m', msg, path], self.srcdir) | ||
1036 | |||
1037 | def fetch(self, uri=None): | ||
1038 | if uri is None: | ||
1039 | uris = self.d.getVar('SRC_URI', True).split() | ||
1040 | uri = uris[0] | ||
1041 | d = self.d | ||
1042 | else: | ||
1043 | d = self.d.createCopy() | ||
1044 | d.setVar('SRC_URI', uri) | ||
1045 | uri = d.expand(uri) | ||
1046 | uris = [uri] | ||
1047 | |||
1048 | fetcher = bb.fetch2.Fetch(uris, d) | ||
1049 | fetcher.download() | ||
1050 | ud = fetcher.ud[uri] | ||
1051 | return fetcher, ud | ||
1052 | |||
1053 | def fetch_and_unpack(self, uri=None): | ||
1054 | fetcher, ud = self.fetch(uri) | ||
1055 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
1056 | assert os.path.exists(self.d.getVar('S')) | ||
1057 | return fetcher, ud | ||
1058 | |||
1059 | def fetch_shallow(self, uri=None, disabled=False, keepclone=False): | ||
1060 | """Fetch a uri, generating a shallow tarball, then unpack using it""" | ||
1061 | fetcher, ud = self.fetch_and_unpack(uri) | ||
1062 | assert os.path.exists(ud.clonedir), 'Git clone in DLDIR (%s) does not exist for uri %s' % (ud.clonedir, uri) | ||
1063 | |||
1064 | # Confirm that the unpacked repo is unshallow | ||
1065 | if not disabled: | ||
1066 | assert os.path.exists(os.path.join(self.dldir, ud.mirrortarballs[0])) | ||
1067 | |||
1068 | # fetch and unpack, from the shallow tarball | ||
1069 | bb.utils.remove(self.gitdir, recurse=True) | ||
1070 | bb.utils.remove(ud.clonedir, recurse=True) | ||
1071 | |||
1072 | # confirm that the unpacked repo is used when no git clone or git | ||
1073 | # mirror tarball is available | ||
1074 | fetcher, ud = self.fetch_and_unpack(uri) | ||
1075 | if not disabled: | ||
1076 | assert os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')), 'Unpacked git repository at %s is not shallow' % self.gitdir | ||
1077 | else: | ||
1078 | assert not os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')), 'Unpacked git repository at %s is shallow' % self.gitdir | ||
1079 | return fetcher, ud | ||
1080 | |||
1081 | def test_shallow_disabled(self): | ||
1082 | self.add_empty_file('a') | ||
1083 | self.add_empty_file('b') | ||
1084 | self.assertRevCount(2, cwd=self.srcdir) | ||
1085 | |||
1086 | self.d.setVar('BB_GIT_SHALLOW', '0') | ||
1087 | self.fetch_shallow(disabled=True) | ||
1088 | self.assertRevCount(2) | ||
1089 | |||
1090 | def test_shallow_nobranch(self): | ||
1091 | self.add_empty_file('a') | ||
1092 | self.add_empty_file('b') | ||
1093 | self.assertRevCount(2, cwd=self.srcdir) | ||
1094 | |||
1095 | srcrev = self.git('rev-parse HEAD', cwd=self.srcdir).strip() | ||
1096 | self.d.setVar('SRCREV', srcrev) | ||
1097 | uri = self.d.getVar('SRC_URI', True).split()[0] | ||
1098 | uri = '%s;nobranch=1;bare=1' % uri | ||
1099 | |||
1100 | self.fetch_shallow(uri) | ||
1101 | self.assertRevCount(1) | ||
1102 | |||
1103 | # shallow refs are used to ensure the srcrev sticks around when we | ||
1104 | # have no other branches referencing it | ||
1105 | self.assertRefs(['refs/shallow/default']) | ||
1106 | |||
1107 | def test_shallow_default_depth_1(self): | ||
1108 | # Create initial git repo | ||
1109 | self.add_empty_file('a') | ||
1110 | self.add_empty_file('b') | ||
1111 | self.assertRevCount(2, cwd=self.srcdir) | ||
1112 | |||
1113 | self.fetch_shallow() | ||
1114 | self.assertRevCount(1) | ||
1115 | |||
1116 | def test_shallow_depth_0_disables(self): | ||
1117 | self.add_empty_file('a') | ||
1118 | self.add_empty_file('b') | ||
1119 | self.assertRevCount(2, cwd=self.srcdir) | ||
1120 | |||
1121 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0') | ||
1122 | self.fetch_shallow(disabled=True) | ||
1123 | self.assertRevCount(2) | ||
1124 | |||
1125 | def test_current_shallow_out_of_date_clone(self): | ||
1126 | # Create initial git repo | ||
1127 | self.add_empty_file('a') | ||
1128 | self.add_empty_file('b') | ||
1129 | self.add_empty_file('c') | ||
1130 | self.assertRevCount(3, cwd=self.srcdir) | ||
1131 | |||
1132 | # Clone and generate mirror tarball | ||
1133 | fetcher, ud = self.fetch() | ||
1134 | |||
1135 | # Ensure we have a current mirror tarball, but an out of date clone | ||
1136 | self.git('update-ref refs/heads/master refs/heads/master~1', cwd=ud.clonedir) | ||
1137 | self.assertRevCount(2, cwd=ud.clonedir) | ||
1138 | |||
1139 | # Fetch and unpack, from the current tarball, not the out of date clone | ||
1140 | bb.utils.remove(self.gitdir, recurse=True) | ||
1141 | fetcher, ud = self.fetch() | ||
1142 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
1143 | self.assertRevCount(1) | ||
1144 | |||
1145 | def test_shallow_single_branch_no_merge(self): | ||
1146 | self.add_empty_file('a') | ||
1147 | self.add_empty_file('b') | ||
1148 | self.assertRevCount(2, cwd=self.srcdir) | ||
1149 | |||
1150 | self.fetch_shallow() | ||
1151 | self.assertRevCount(1) | ||
1152 | assert os.path.exists(os.path.join(self.gitdir, 'a')) | ||
1153 | assert os.path.exists(os.path.join(self.gitdir, 'b')) | ||
1154 | |||
1155 | def test_shallow_no_dangling(self): | ||
1156 | self.add_empty_file('a') | ||
1157 | self.add_empty_file('b') | ||
1158 | self.assertRevCount(2, cwd=self.srcdir) | ||
1159 | |||
1160 | self.fetch_shallow() | ||
1161 | self.assertRevCount(1) | ||
1162 | assert not self.git('fsck --dangling') | ||
1163 | |||
1164 | def test_shallow_srcrev_branch_truncation(self): | ||
1165 | self.add_empty_file('a') | ||
1166 | self.add_empty_file('b') | ||
1167 | b_commit = self.git('rev-parse HEAD', cwd=self.srcdir).rstrip() | ||
1168 | self.add_empty_file('c') | ||
1169 | self.assertRevCount(3, cwd=self.srcdir) | ||
1170 | |||
1171 | self.d.setVar('SRCREV', b_commit) | ||
1172 | self.fetch_shallow() | ||
1173 | |||
1174 | # The 'c' commit was removed entirely, and 'a' was removed from history | ||
1175 | self.assertRevCount(1, ['--all']) | ||
1176 | self.assertEqual(self.git('rev-parse HEAD').strip(), b_commit) | ||
1177 | assert os.path.exists(os.path.join(self.gitdir, 'a')) | ||
1178 | assert os.path.exists(os.path.join(self.gitdir, 'b')) | ||
1179 | assert not os.path.exists(os.path.join(self.gitdir, 'c')) | ||
1180 | |||
1181 | def test_shallow_ref_pruning(self): | ||
1182 | self.add_empty_file('a') | ||
1183 | self.add_empty_file('b') | ||
1184 | self.git('branch a_branch', cwd=self.srcdir) | ||
1185 | self.assertRefs(['master', 'a_branch'], cwd=self.srcdir) | ||
1186 | self.assertRevCount(2, cwd=self.srcdir) | ||
1187 | |||
1188 | self.fetch_shallow() | ||
1189 | |||
1190 | self.assertRefs(['master', 'origin/master']) | ||
1191 | self.assertRevCount(1) | ||
1192 | |||
1193 | def test_shallow_multi_one_uri(self): | ||
1194 | # Create initial git repo | ||
1195 | self.add_empty_file('a') | ||
1196 | self.add_empty_file('b') | ||
1197 | self.git('checkout -b a_branch', cwd=self.srcdir) | ||
1198 | self.add_empty_file('c') | ||
1199 | self.add_empty_file('d') | ||
1200 | self.git('checkout master', cwd=self.srcdir) | ||
1201 | self.add_empty_file('e') | ||
1202 | self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir) | ||
1203 | self.add_empty_file('f') | ||
1204 | self.assertRevCount(7, cwd=self.srcdir) | ||
1205 | |||
1206 | uri = self.d.getVar('SRC_URI', True).split()[0] | ||
1207 | uri = '%s;branch=master,a_branch;name=master,a_branch' % uri | ||
1208 | |||
1209 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '2') | ||
1210 | self.d.setVar('SRCREV_master', '${AUTOREV}') | ||
1211 | self.d.setVar('SRCREV_a_branch', '${AUTOREV}') | ||
1212 | |||
1213 | self.fetch_shallow(uri) | ||
1214 | |||
1215 | self.assertRevCount(3, ['--all']) | ||
1216 | self.assertRefs(['master', 'origin/master', 'origin/a_branch']) | ||
1217 | |||
1218 | def test_shallow_clone_preferred_over_shallow(self): | ||
1219 | self.add_empty_file('a') | ||
1220 | self.add_empty_file('b') | ||
1221 | |||
1222 | # Fetch once to generate the shallow tarball | ||
1223 | fetcher, ud = self.fetch() | ||
1224 | assert os.path.exists(os.path.join(self.dldir, ud.mirrortarballs[0])) | ||
1225 | |||
1226 | # Fetch and unpack with both the clonedir and shallow tarball available | ||
1227 | bb.utils.remove(self.gitdir, recurse=True) | ||
1228 | fetcher, ud = self.fetch_and_unpack() | ||
1229 | |||
1230 | # The unpacked tree should *not* be shallow | ||
1231 | self.assertRevCount(2) | ||
1232 | assert not os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')) | ||
1233 | |||
1234 | def test_shallow_mirrors(self): | ||
1235 | self.add_empty_file('a') | ||
1236 | self.add_empty_file('b') | ||
1237 | |||
1238 | # Fetch once to generate the shallow tarball | ||
1239 | fetcher, ud = self.fetch() | ||
1240 | mirrortarball = ud.mirrortarballs[0] | ||
1241 | assert os.path.exists(os.path.join(self.dldir, mirrortarball)) | ||
1242 | |||
1243 | # Set up the mirror | ||
1244 | mirrordir = os.path.join(self.tempdir, 'mirror') | ||
1245 | bb.utils.mkdirhier(mirrordir) | ||
1246 | self.d.setVar('PREMIRRORS', 'git://.*/.* file://%s/\n' % mirrordir) | ||
1247 | |||
1248 | os.rename(os.path.join(self.dldir, mirrortarball), | ||
1249 | os.path.join(mirrordir, mirrortarball)) | ||
1250 | |||
1251 | # Fetch from the mirror | ||
1252 | bb.utils.remove(self.dldir, recurse=True) | ||
1253 | bb.utils.remove(self.gitdir, recurse=True) | ||
1254 | self.fetch_and_unpack() | ||
1255 | self.assertRevCount(1) | ||
1256 | |||
1257 | def test_shallow_invalid_depth(self): | ||
1258 | self.add_empty_file('a') | ||
1259 | self.add_empty_file('b') | ||
1260 | |||
1261 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '-12') | ||
1262 | with self.assertRaises(bb.fetch2.FetchError): | ||
1263 | self.fetch() | ||
1264 | |||
1265 | if os.environ.get("BB_SKIP_NETTESTS") == "yes": | ||
1266 | print("Unset BB_SKIP_NETTESTS to run network tests") | ||
1267 | else: | ||
1268 | def test_bitbake(self): | ||
1269 | self.git('remote add --mirror=fetch origin git://github.com/openembedded/bitbake', cwd=self.srcdir) | ||
1270 | self.git('config core.bare true', cwd=self.srcdir) | ||
1271 | self.git('fetch --tags', cwd=self.srcdir) | ||
1272 | |||
1273 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '100') | ||
1274 | |||
1275 | self.fetch_shallow() | ||
1276 | |||
1277 | orig_revs = len(self.git('rev-list master', cwd=self.srcdir).splitlines()) | ||
1278 | revs = len(self.git('rev-list master').splitlines()) | ||
1279 | self.assertNotEqual(orig_revs, revs) | ||
1280 | self.assertRefs(['master', 'origin/master']) | ||