Skip to content

Commit

Permalink
source-repository: Use git shallow clones
Browse files Browse the repository at this point in the history
Cloning the entire repository for the purpose of compiling packages
specified in source-repository-packages is wasted effort. To read and
compile the package, we need only the HEAD of the repository, thus a
shallow clone is sufficient.

Fixes #7264
  • Loading branch information
alt-romes authored and mpickering committed Aug 14, 2024
1 parent a9f9d11 commit 70c4f21
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions cabal-install/src/Distribution/Client/VCS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -460,19 +460,21 @@ vcsGit =
vcsCloneRepo verbosity prog repo srcuri destdir =
[programInvocation prog cloneArgs]
-- And if there's a tag, we have to do that in a second step:
++ [git (resetArgs tag) | tag <- maybeToList (srpTag repo)]
++ [git (step tag) | tag <- maybeToList (srpTag repo), step <- [fetchArgs, resetArgs]]
++ [ git (["submodule", "sync", "--recursive"] ++ verboseArg)
, git (["submodule", "update", "--init", "--force", "--recursive"] ++ verboseArg)
]
where
git args = (programInvocation prog args){progInvokeCwd = Just destdir}
cloneArgs =
["clone", srcuri, destdir]
["clone", "--depth=1", srcuri, destdir]
++ branchArgs
++ verboseArg
branchArgs = case srpBranch repo of
Just b -> ["--branch", b]
Nothing -> []
-- To checkout/reset to a particular commit, we must first fetch it (since the base clone is shallow).
fetchArgs tag = "fetch" : verboseArg ++ ["origin", tag]
resetArgs tag = "reset" : verboseArg ++ ["--hard", tag, "--"]
verboseArg = ["--quiet" | verbosity < Verbosity.normal]

Expand Down Expand Up @@ -510,7 +512,9 @@ vcsGit =
let gitModulesDir = localDir </> ".git" </> "modules"
gitModulesExists <- doesDirectoryExist gitModulesDir
when gitModulesExists $ removeDirectoryRecursive gitModulesDir
git localDir resetArgs
when (resetTarget /= "HEAD") $ do
git localDir fetchArgs -- first fetch the tag if needed
git localDir resetArgs -- only then reset to the commit
git localDir $ ["submodule", "sync", "--recursive"] ++ verboseArg
git localDir $ ["submodule", "update", "--force", "--init", "--recursive"] ++ verboseArg
git localDir $ ["submodule", "foreach", "--recursive"] ++ verboseArg ++ ["git clean -ffxdq"]
Expand All @@ -524,13 +528,15 @@ vcsGit =
}

cloneArgs =
["clone", "--no-checkout", loc, localDir]
["clone", "--depth=1", "--no-checkout", loc, localDir]
++ case peer of
Nothing -> []
Just peerLocalDir -> ["--reference", peerLocalDir]
++ verboseArg
where
loc = srpLocation
-- To checkout/reset to a particular commit, we must first fetch it (since the base clone is shallow).
fetchArgs = "fetch" : verboseArg ++ ["origin", resetTarget]
resetArgs = "reset" : verboseArg ++ ["--hard", resetTarget, "--"]
resetTarget = fromMaybe "HEAD" (srpBranch `mplus` srpTag)
verboseArg = ["--quiet" | verbosity < Verbosity.normal]
Expand Down

0 comments on commit 70c4f21

Please sign in to comment.