@@ -28,15 +28,14 @@ import os
2828import platform
2929import re
3030import shutil
31- import signal
3231import socket
3332import stat
3433import subprocess
3534import time
3635import urllib .error
3736import urllib .request
37+ from itertools import count
3838from pathlib import Path
39- from threading import Thread
4039from typing import Dict , Optional
4140
4241SECRET_BASEURL_TPL = "{}/secrets/v1/secret/{{}}" .format (os .environ .get ("TASKCLUSTER_PROXY_URL" , "http://taskcluster" ).rstrip ('/' ))
@@ -556,6 +555,7 @@ def git_fetch(
556555 ref : str ,
557556 remote : str = "origin" ,
558557 tags : bool = False ,
558+ shallow : bool = False ,
559559 env : Optional [Dict [str , str ]] = None ,
560560):
561561 args = ["git" , "fetch" ]
@@ -564,7 +564,20 @@ def git_fetch(
564564 args .extend (["--tags" , "--force" ])
565565
566566 args .extend ([remote , ref ])
567- retry_required_command (b"vcs" , args , cwd = destination_path , extra_env = env )
567+
568+ if shallow :
569+ for deepen in range (10 , 100 , 10 ):
570+ args [2 :2 ] = [f"--deepen={ deepen } " ]
571+ run_command (b"vcs" , args , cwd = destination_path , extra_env = env )
572+
573+ ret = run_command (b"vcs" , ["git" , "cat-file" , "-e" , ref ])
574+ if ret == 0 :
575+ return
576+
577+ print (f"unable to fetch { ref } from { remote } in shallow clone" )
578+ sys .exit (1 )
579+ else :
580+ retry_required_command (b"vcs" , args , cwd = destination_path , extra_env = env )
568581
569582
570583def _clean_git_checkout (destination_path ):
@@ -615,6 +628,7 @@ def git_checkout(
615628 commit : Optional [str ],
616629 ssh_key_file : Optional [Path ],
617630 ssh_known_hosts_file : Optional [Path ],
631+ shallow_clone : bool = False ,
618632):
619633 env = {
620634 # abort if transfer speed is lower than 1kB/s for 1 minute
@@ -651,9 +665,18 @@ def git_checkout(
651665 args = [
652666 "git" ,
653667 "clone" ,
668+ ]
669+
670+ if shallow_clone :
671+ # Use shallow clone with depth 1 for minimal history
672+ args .extend (["--depth=1" ])
673+ # Skip checkout initially
674+ args .extend (["--no-checkout" ])
675+
676+ args .extend ([
654677 base_repo if base_repo else head_repo ,
655678 destination_path ,
656- ]
679+ ])
657680
658681 retry_required_command (b"vcs" , args , extra_env = env )
659682
@@ -673,7 +696,7 @@ def git_checkout(
673696
674697 # If a ref isn't provided, we fetch all refs from head_repo, which may be slow.
675698 target = ref if ref else "+refs/heads/*:refs/remotes/work/*"
676- git_fetch (destination_path , target , remote = head_repo , tags = tags , env = env )
699+ git_fetch (destination_path , target , remote = head_repo , tags = tags , shallow = shallow_clone , env = env )
677700
678701 args = [
679702 "git" ,
@@ -861,11 +884,17 @@ def add_vcs_arguments(parser, project, name):
861884 "--%s-sparse-profile" % project ,
862885 help = "Path to sparse profile for %s checkout" % name ,
863886 )
887+ parser .add_argument (
888+ "--%s-shallow-clone" % project ,
889+ action = "store_true" ,
890+ help = "Use shallow clone for %s" % name ,
891+ )
864892
865893
866894def collect_vcs_options (args , project , name ):
867895 checkout = getattr (args , "%s_checkout" % project )
868896 sparse_profile = getattr (args , "%s_sparse_profile" % project )
897+ shallow_clone = getattr (args , "%s_shallow_clone" % project )
869898
870899 env_prefix = project .upper ()
871900
@@ -910,6 +939,7 @@ def collect_vcs_options(args, project, name):
910939 "repo-type" : repo_type ,
911940 "ssh-secret-name" : private_key_secret ,
912941 "pip-requirements" : pip_requirements ,
942+ "shallow-clone" : shallow_clone ,
913943 }
914944
915945
@@ -958,6 +988,7 @@ def vcs_checkout_from_args(options):
958988 revision ,
959989 ssh_key_file ,
960990 ssh_known_hosts_file ,
991+ options .get ("shallow-clone" , False ),
961992 )
962993 elif options ["repo-type" ] == "hg" :
963994 if not revision and not ref :
0 commit comments