Fix bug that made bare repos be treated as non-bare when --git-dir was used.
authorJoey Hess <joeyh@joeyh.name>
Thu, 21 Nov 2019 17:16:42 +0000 (13:16 -0400)
committerJoey Hess <joeyh@joeyh.name>
Thu, 21 Nov 2019 17:26:02 +0000 (13:26 -0400)
Eg:

git clone url --bare r
git --git-dir r annex init

This resulted in worktree = Just "." and so several things that check
worktree to determine when the repo is bare ran code paths intended for
non-bare. One such code path[1] ran git checkout with --worktree=. which
actually makes it ignore core.bare config, and so the current directory
got populated with a checkout of the master branch in this example. There
was probably also other breakage.

The fix is a bit complicated because whether the repo is bare is not
known until after Git.Config reads the config, but Git.Config handles
setting the RepoLocations's worktree when core.worktree is set. So have
to assume the worktree is the cwd, let core.worktree override that,
and then if the repo turns out to be bare, it's set back to Nothing.
(And then GIT_WORK_TREE can still override all of that.)

[1] switchHEADBack, which runs even when the clone is not from a bare repo.

CHANGELOG
Git/CurrentRepo.hs

index ab28d365ae24c4fe5f8036ac75121adf732fa053..4cb6c989ab9098133e50f353861baff9b244607a 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,8 @@ git-annex (7.20191115) UNRELEASED; urgency=medium
   * git-lfs: When there's a git remote with an url that's known to be
     used for git-lfs, automatically enable the special remote.
   * sync, assistant: Pull and push from git-lfs remotes.
+  * Fix bug that made bare repos be treated as non-bare when --git-dir
+    was used.
 
  -- Joey Hess <id@joeyh.name>  Fri, 15 Nov 2019 11:57:19 -0400
 
index f4cdf286348efb108cbddfe04a1e1777ac48ef36..f8383326a531b57c9ded54a3ebf3c535406da092 100644 (file)
@@ -67,8 +67,12 @@ get = do
        configure (Just d) _ = do
                absd <- absPath d
                curr <- getCurrentDirectory
-               Git.Config.read $ newFrom $
+               r <- Git.Config.read $ newFrom $
                        Local { gitdir = absd, worktree = Just curr }
+               return $ if Git.Config.isBare r
+                       then r { location = (location r) { worktree = Nothing } }
+                       else r
+
        configure Nothing Nothing = giveup "Not in a git repository."
 
        addworktree w r = changelocation r $