@@ -13,6 +13,45 @@ using Printf
1313use_cli_git () = Base. get_bool_env (" JULIA_PKG_USE_CLI_GIT" , false )
1414const RESOLVING_DELTAS_HEADER = " Resolving Deltas:"
1515
16+ # Check if LibGit2 supports shallow clones (requires LibGit2 >= 1.7.0)
17+ # We check both the LibGit2 version and the existence of `isshallow` to ensure
18+ # the shallow clone functionality is available
19+ function supports_shallow_clone ()
20+ # This seems buggy on Windows? Get some weird CI errors with it.
21+ if Sys. iswindows ()
22+ return false
23+ end
24+ has_version = @static if isdefined (LibGit2, :VERSION )
25+ LibGit2. VERSION >= v " 1.7.0"
26+ else
27+ false
28+ end
29+ has_isshallow = isdefined (LibGit2, :isshallow )
30+ return has_version && has_isshallow
31+ end
32+
33+ # Check if a URL is a local path or file:// URL
34+ # Shallow clones are only supported for network protocols (HTTP, HTTPS, Git, SSH)
35+ function is_local_repo (url:: AbstractString )
36+ # Check if it's a local filesystem path
37+ ispath (url) && return true
38+ # Check if it uses file:// protocol
39+ startswith (url, " file://" ) && return true
40+ return false
41+ end
42+
43+ # Check if a repository is a shallow clone
44+ function isshallow (repo:: LibGit2.GitRepo )
45+ if supports_shallow_clone () && isdefined (LibGit2, :isshallow )
46+ return LibGit2. isshallow (repo)
47+ else
48+ # Fallback: check for .git/shallow file
49+ repo_path = LibGit2. path (repo)
50+ shallow_file = joinpath (repo_path, " shallow" )
51+ return isfile (shallow_file)
52+ end
53+ end
54+
1655function transfer_progress (progress:: Ptr{LibGit2.TransferProgress} , p:: Any )
1756 progress = unsafe_load (progress)
1857 @assert haskey (p, :transfer_progress )
@@ -89,11 +128,17 @@ function checkout_tree_to_path(repo::LibGit2.GitRepo, tree::LibGit2.GitObject, p
89128 end
90129end
91130
92- function clone (io:: IO , url, source_path; header = nothing , credentials = nothing , isbare = false , kwargs... )
131+ function clone (io:: IO , url, source_path; header = nothing , credentials = nothing , isbare = false , depth :: Integer = 0 , kwargs... )
93132 url = String (url):: String
94133 source_path = String (source_path):: String
95134 @assert ! isdir (source_path) || isempty (readdir (source_path))
96135 url = normalize_url (url)
136+
137+ # Disable shallow clones for local repos (not supported) or if LibGit2 doesn't support it
138+ if depth > 0 && (is_local_repo (url) || ! supports_shallow_clone ())
139+ depth = 0
140+ end
141+
97142 printpkgstyle (io, :Cloning , header === nothing ? " git-repo `$url `" : header)
98143 bar = MiniProgressBar (header = " Cloning:" , color = Base. info_color ())
99144 fancyprint = can_fancyprint (io)
@@ -103,8 +148,10 @@ function clone(io::IO, url, source_path; header = nothing, credentials = nothing
103148 end
104149 return try
105150 if use_cli_git ()
106- args = [" --quiet" , url, source_path]
107- isbare && pushfirst! (args, " --bare" )
151+ args = [" --quiet" ]
152+ depth > 0 && push! (args, " --depth=$depth " )
153+ isbare && push! (args, " --bare" )
154+ push! (args, url, source_path)
108155 cmd = ` git clone $args `
109156 try
110157 run (pipeline (cmd; stdout = devnull ))
@@ -124,7 +171,12 @@ function clone(io::IO, url, source_path; header = nothing, credentials = nothing
124171 LibGit2. Callbacks ()
125172 end
126173 mkpath (source_path)
127- return LibGit2. clone (url, source_path; callbacks, credentials, isbare, kwargs... )
174+ # Only pass depth if shallow clones are supported and depth > 0
175+ if depth > 0
176+ return LibGit2. clone (url, source_path; callbacks, credentials, isbare, depth, kwargs... )
177+ else
178+ return LibGit2. clone (url, source_path; callbacks, credentials, isbare, kwargs... )
179+ end
128180 end
129181 catch err
130182 rm (source_path; force = true , recursive = true )
@@ -149,10 +201,16 @@ function geturl(repo)
149201 end
150202end
151203
152- function fetch (io:: IO , repo:: LibGit2.GitRepo , remoteurl = nothing ; header = nothing , credentials = nothing , refspecs = [" " ], kwargs... )
204+ function fetch (io:: IO , repo:: LibGit2.GitRepo , remoteurl = nothing ; header = nothing , credentials = nothing , refspecs = [" " ], depth :: Integer = 0 , kwargs... )
153205 if remoteurl === nothing
154206 remoteurl = geturl (repo)
155207 end
208+
209+ # Disable shallow fetches for local repos (not supported) or if LibGit2 doesn't support it
210+ if depth > 0 && (is_local_repo (remoteurl) || ! supports_shallow_clone ())
211+ depth = 0
212+ end
213+
156214 fancyprint = can_fancyprint (io)
157215 remoteurl = normalize_url (remoteurl)
158216 printpkgstyle (io, :Updating , header === nothing ? " git-repo `$remoteurl `" : header)
@@ -174,15 +232,23 @@ function fetch(io::IO, repo::LibGit2.GitRepo, remoteurl = nothing; header = noth
174232 return try
175233 if use_cli_git ()
176234 let remoteurl = remoteurl
177- cmd = ` git -C $(LibGit2. path (repo)) fetch -q $remoteurl $(only (refspecs)) `
235+ args = [" -C" , LibGit2. path (repo), " fetch" , " -q" ]
236+ depth > 0 && push! (args, " --depth=$depth " )
237+ push! (args, remoteurl, only (refspecs))
238+ cmd = ` git $args `
178239 try
179240 run (pipeline (cmd; stdout = devnull ))
180241 catch err
181242 Pkg. Types. pkgerror (" The command $(cmd) failed, error: $err " )
182243 end
183244 end
184245 else
185- return LibGit2. fetch (repo; remoteurl, callbacks, credentials, refspecs, kwargs... )
246+ # Only pass depth if shallow clones are supported and depth > 0
247+ if depth > 0
248+ return LibGit2. fetch (repo; remoteurl, callbacks, credentials, refspecs, depth, kwargs... )
249+ else
250+ return LibGit2. fetch (repo; remoteurl, callbacks, credentials, refspecs, kwargs... )
251+ end
186252 end
187253 catch err
188254 err isa LibGit2. GitError || rethrow ()
0 commit comments