From 1de31211124b162014c2a37e34d06567b3c1d90c Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 21 Nov 2024 16:13:09 -0800 Subject: [PATCH 1/3] VCS: Fix weird tag creation Creating a tag with an arbitrary user-supplied name can cause problems. If we fetch, we can just use `FETCH_HEAD` as the ref name directly! ``` Running: git fetch origin d1dc91fd977bb4b28f0e01966fa08640a1283318 From /private/var/folders/z5/fclwwdms3r1gq4k4p3pkvvc00000gn/T/vcstest-90401/src * branch d1dc91fd977bb4b28f0e01966fa08640a1283318 -> FETCH_HEAD Running: git tag -f d1dc91fd977bb4b28f0e01966fa08640a1283318 FETCH_HEAD Running: git reset --hard d1dc91fd977bb4b28f0e01966fa08640a1283318 -- warning: refname 'd1dc91fd977bb4b28f0e01966fa08640a1283318' is ambiguous. Git normally never creates a ref that ends with 40 hex characters because it will be ignored when you just specify 40-hex. These refs may be created by mistake. For example, git switch -c $br $(git rev-parse ...) where "$br" is somehow empty and a 40-hex ref is created. Please examine these refs and maybe delete them. Turn this message off by running "git config advice.objectNameWarning false" ``` --- cabal-install/src/Distribution/Client/VCS.hs | 33 ++++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/cabal-install/src/Distribution/Client/VCS.hs b/cabal-install/src/Distribution/Client/VCS.hs index 33b7078bd79..b0c5b140bc3 100644 --- a/cabal-install/src/Distribution/Client/VCS.hs +++ b/cabal-install/src/Distribution/Client/VCS.hs @@ -506,6 +506,8 @@ vcsGit = | dir <- (primaryLocalDir : map snd secondaryRepos) ] + -- NOTE: Repositories are cloned once, but can be synchronized multiple times. + -- Therefore, this code has to work with both `git clone` and `git fetch`. vcsSyncRepo verbosity gitProg SourceRepositoryPackage{..} localDir peer = do exists <- doesDirectoryExist localDir if exists @@ -532,10 +534,23 @@ vcsGit = (removePathForcibly gitModulesDir) (\e -> if isPermissionError e then removePathForcibly gitModulesDir else throw e) else removeDirectoryRecursive gitModulesDir - 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 + + -- If we want a particular branch or tag, fetch it. + ref <- case srpBranch `mplus` srpTag of + Nothing -> pure "HEAD" + Just ref -> do + git localDir ("fetch" : verboseArg ++ ["origin", ref]) + pure ref + + -- Then, reset to the appropriate ref. + git localDir $ + "reset" + : verboseArg + ++ [ "--hard" + , ref + , "--" + ] + git localDir $ ["submodule", "sync", "--recursive"] ++ verboseArg git localDir $ ["submodule", "update", "--force", "--init", "--recursive"] ++ verboseArg git localDir $ ["submodule", "foreach", "--recursive"] ++ verboseArg ++ ["git clean -ffxdq"] @@ -556,15 +571,7 @@ vcsGit = ++ 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] gitProgram :: Program From 51855989ff75b3098a809f0016f0b3dc4eacb288 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 25 Nov 2024 16:17:46 -0800 Subject: [PATCH 2/3] tests: postCheckoutCommand: Don't hide verbose output!! --- .../PackageTests/postCheckoutCommand/cabal.out | 9 +++++++++ .../PackageTests/postCheckoutCommand/cabal.test.hs | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.out b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.out index 8165f4408ff..a304511e1ef 100644 --- a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.out +++ b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.out @@ -1,2 +1,11 @@ # cabal v2-build +Configuration is affected by the following files: +- cabal.positive.project +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - example-1.0 (lib) (first run) +Configuring library for example-1.0... +Preprocessing library for example-1.0... +Building library for example-1.0... # cabal v2-build diff --git a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs index 50e45454ff3..d96d7676501 100644 --- a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs +++ b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs @@ -2,6 +2,6 @@ import Test.Cabal.Prelude main = cabalTest $ do withProjectFile "cabal.positive.project" $ do - cabal "v2-build" ["-v0"] + cabal "v2-build" [] withProjectFile "cabal.negative.project" $ do - fails $ cabal "v2-build" ["-v0"] + fails $ cabal "v2-build" [] From 18a040a6f0977f76a91fa681b955536fc3fcde2d Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 25 Nov 2024 16:18:48 -0800 Subject: [PATCH 3/3] VCS: Use `FETCH_HEAD` actually --- cabal-install/src/Distribution/Client/VCS.hs | 32 +++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/VCS.hs b/cabal-install/src/Distribution/Client/VCS.hs index b0c5b140bc3..f19ca5ff566 100644 --- a/cabal-install/src/Distribution/Client/VCS.hs +++ b/cabal-install/src/Distribution/Client/VCS.hs @@ -539,8 +539,38 @@ vcsGit = ref <- case srpBranch `mplus` srpTag of Nothing -> pure "HEAD" Just ref -> do + -- /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ + -- /!\ MULTIPLE HOURS HAVE BEEN LOST HERE!! /!\ + -- /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ + -- + -- If you run `git fetch origin MY_TAG`, then the tag _will_ be + -- fetched, but no local ref (e.g. `refs/tags/MY_TAG`) will be + -- created. + -- + -- This means that doing `git fetch origin MY_TAG && git reset --hard + -- MY_TAG` will fail with a message like `unknown revision MY_TAG`. + -- + -- There are two ways around this: + -- + -- 1. Provide a refmap explicitly: + -- + -- git fetch --refmap="+refs/tags/*:refs/tags/*" origin MYTAG + -- + -- This tells Git to create local tags matching remote tags. It's + -- not in the default refmap so you need to set it explicitly. + -- (You can also set it with `git config set --local + -- remote.origin.fetch ...`.) + -- + -- 2. Use `FETCH_HEAD` directly: Git writes a `FETCH_HEAD` ref + -- containing the commit that was just fetched. This feels a bit + -- nasty but seems to work reliably, even if nothing was fetched. + -- (That is, deleting `FETCH_HEAD` and re-running a `git fetch` + -- command will succesfully recreate the `FETCH_HEAD` ref.) + -- + -- Option 2 is what Cabal has done historically, and we're keeping it + -- for now. Option 1 is possible but seems to have little benefit. git localDir ("fetch" : verboseArg ++ ["origin", ref]) - pure ref + pure "FETCH_HEAD" -- Then, reset to the appropriate ref. git localDir $