initRepo' desc mgroup
{- Initialize the master branch, so things that expect
- to have it will work, before any files are added. -}
- unlessM (Git.Config.isBare <$> gitRepo) $ do
+ unlessM (fromMaybe False . Git.Config.isBare <$> gitRepo) $ do
cmode <- annexCommitMode <$> Annex.getGitConfig
void $ inRepo $ Git.Branch.commitCommand cmode
(Git.Branch.CommitQuiet True)
* info, enableremotemote, renameremote: Avoid a confusing message when more
than one repository matches the user provided name.
* info: Exit nonzero when the input is not supported.
+ * Fix more breakage caused by git's fix for CVE-2022-24765, this time
+ involving a remote that is a local bare repository not owned by the
+ current user.
-- Joey Hess <id@joeyh.name> Mon, 06 Feb 2023 13:39:18 -0400
- based on the core.bare and core.worktree settings.
-}
updateLocation :: Repo -> IO Repo
-updateLocation r@(Repo { location = LocalUnknown d })
- | isBare r = ifM (doesDirectoryExist (fromRawFilePath dotgit))
- ( updateLocation' r $ Local dotgit Nothing
- , updateLocation' r $ Local d Nothing
- )
- | otherwise = updateLocation' r $ Local dotgit (Just d)
+updateLocation r@(Repo { location = LocalUnknown d }) = case isBare r of
+ Just True -> ifM (doesDirectoryExist (fromRawFilePath dotgit))
+ ( updateLocation' r $ Local dotgit Nothing
+ , updateLocation' r $ Local d Nothing
+ )
+ Just False -> mknonbare
+ {- core.bare not in config, probably because safe.directory
+ - did not allow reading the config -}
+ Nothing -> ifM (Git.Construct.isBareRepo (fromRawFilePath d))
+ ( mkbare
+ , mknonbare
+ )
where
dotgit = d P.</> ".git"
+ -- git treats eg ~/foo as a bare git repository located in
+ -- ~/foo/.git if ~/foo/.git/config has core.bare=true
+ mkbare = ifM (doesDirectoryExist (fromRawFilePath dotgit))
+ ( updateLocation' r $ Local dotgit Nothing
+ , updateLocation' r $ Local d Nothing
+ )
+ mknonbare = updateLocation' r $ Local dotgit (Just d)
+
updateLocation r@(Repo { location = l@(Local {}) }) = updateLocation' r l
updateLocation r = return r
boolConfig' True = "true"
boolConfig' False = "false"
-isBare :: Repo -> Bool
-isBare r = fromMaybe False $ isTrueFalse' =<< getMaybe coreBare r
+{- Note that repoIsLocalBare is often better to use than this. -}
+isBare :: Repo -> Maybe Bool
+isBare r = isTrueFalse' =<< getMaybe coreBare r
coreBare :: ConfigKey
coreBare = "core.bare"
{- Construction of Git Repo objects
-
- - Copyright 2010-2021 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2023 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
checkForRepo,
newFrom,
adjustGitDirFile,
+ isBareRepo,
) where
#ifndef mingw32_HOST_OS
checkForRepo dir =
check isRepo $
check (checkGitDirFile (toRawFilePath dir)) $
- check isBareRepo $
+ check (checkdir (isBareRepo dir)) $
return Nothing
where
check test cont = maybe cont (return . Just) =<< test
, return Nothing
)
isRepo = checkdir $
- gitSignature (".git" </> "config")
+ doesFileExist (dir </> ".git" </> "config")
<||>
-- A git-worktree lacks .git/config, but has .git/gitdir.
-- (Normally the .git is a file, not a symlink, but it can
-- be converted to a symlink and git will still work;
-- this handles that case.)
- gitSignature (".git" </> "gitdir")
- isBareRepo = checkdir $ gitSignature "config"
- <&&> doesDirectoryExist (dir </> "objects")
- gitSignature file = doesFileExist $ dir </> file
+ doesFileExist (dir </> ".git" </> "gitdir")
+
+isBareRepo :: FilePath -> IO Bool
+isBareRepo dir = doesFileExist (dir </> "config")
+ <&&> doesDirectoryExist (dir </> "objects")
-- Check for a .git file.
checkGitDirFile :: RawFilePath -> IO (Maybe RepoLocation)
}
r <- Git.Config.read $ (newFrom loc)
{ gitDirSpecifiedExplicitly = True }
- return $ if Git.Config.isBare r
+ return $ if fromMaybe False (Git.Config.isBare r)
then r { location = (location r) { worktree = Nothing } }
else r
configure Nothing Nothing = giveup "Not in a git repository."
Right r' -> do
-- Cache when http remote is not bare for
-- optimisation.
- unless (Git.Config.isBare r') $
+ unless (fromMaybe False $ Git.Config.isBare r') $
setremote setRemoteBare False
return r'
Left err -> do
detects and warns that safe.directory is needed to use the
remote. --[[Joey]]
-> What's causing this is that Git.Config.read is called
-> on the repo, but git refuses to list the repo's config,
-> so updateLocation does not see that the repo is bare
-> when it checks isBare. And so it proceeds to set gitdir
-> to the default non-bare "dir/.git" value.
->
-> One way to deal with this would be to make isBare a tristate,
-> since core.bare is not in the listed config at all.
->
-> Or, make Git.Construct.fromPath detect when a repo is bare
-> w/o parsing config, and indicate that in the Repo it
-> generates.
+> [[fixed|done]] --[[Joey]]