From b6c28eef30b12eb5bc9a3fb49fe7b06fc0b1774b Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Tue, 6 Aug 2024 14:39:38 +0100 Subject: [PATCH] source-repository: Use git shallow clones 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. Note that this doesn't change the behaviour of `cabal get -s` which still does a full clone (--depth=1 is only used in vcsSyncRepo, not in vcsCloneRepo) Fixes #7264 --- cabal-install/src/Distribution/Client/VCS.hs | 17 +++++++++++++++-- .../PackageTests/ExtraProgPath/setup.out | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/cabal-install/src/Distribution/Client/VCS.hs b/cabal-install/src/Distribution/Client/VCS.hs index 57c0a82376e..029e190a790 100644 --- a/cabal-install/src/Distribution/Client/VCS.hs +++ b/cabal-install/src/Distribution/Client/VCS.hs @@ -483,6 +483,9 @@ vcsGit = resetArgs tag = "reset" : verboseArg ++ ["--hard", tag, "--"] verboseArg = ["--quiet" | verbosity < Verbosity.normal] + -- Note: No --depth=1 for vcsCloneRepo since that is used for `cabal get -s`, + -- whereas `vcsSyncRepo` is used for source-repository-package where we do want shallow clones. + vcsSyncRepos :: Verbosity -> ConfiguredProgram @@ -529,7 +532,10 @@ vcsGit = (removePathForcibly gitModulesDir) (\e -> if isPermissionError e then removePathForcibly gitModulesDir else throw e) else removeDirectoryRecursive gitModulesDir - git localDir resetArgs + when (resetTarget /= "HEAD") $ do + git localDir fetchArgs -- first fetch the tag if needed + git localDir setTagArgs + 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"] @@ -543,13 +549,20 @@ 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] + -- And then create the Tag from the FETCH_HEAD (which we should have just fetched) + setTagArgs = ["tag", "-f", resetTarget, "FETCH_HEAD"] + -- Then resetting to that tag will work (if we don't create the tag + -- locally from FETCH_HEAD, it won't exist). resetArgs = "reset" : verboseArg ++ ["--hard", resetTarget, "--"] resetTarget = fromMaybe "HEAD" (srpBranch `mplus` srpTag) verboseArg = ["--quiet" | verbosity < Verbosity.normal] diff --git a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out index a64476a2939..ed22f251035 100644 --- a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out +++ b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out @@ -1,8 +1,8 @@ # cabal v2-build -Configuration is affected by the following files: -- cabal.project Warning: cannot determine version of /pkg-config : "" +Configuration is affected by the following files: +- cabal.project Resolving dependencies... Error: [Cabal-7107] Could not resolve dependencies: