summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess <joey@kitenet.net>2013-11-20 13:01:25 -0400
committerJoey Hess <joey@kitenet.net>2013-11-20 13:13:24 -0400
commit229761fc4397ed3e8b137e65657a2583066d2764 (patch)
tree23a86559b66c670dbb7f38e4bf0eefc15458be96
parent3ed32d99829ca44abfe43c953800d8d249909997 (diff)
downloadgit-repair-229761fc4397ed3e8b137e65657a2583066d2764.tar.gz
Write a dummy .git/HEAD if the file is missing, as git otherwise will not treat the repository as a git repo.
-rw-r--r--Git/Repair.hs19
-rw-r--r--Utility/FileMode.hs4
-rw-r--r--debian/changelog2
3 files changed, 25 insertions, 0 deletions
diff --git a/Git/Repair.hs b/Git/Repair.hs
index 3e731aa..c5ec40b 100644
--- a/Git/Repair.hs
+++ b/Git/Repair.hs
@@ -36,6 +36,7 @@ import qualified Git.UpdateIndex as UpdateIndex
import qualified Git.Branch as Branch
import Utility.Tmp
import Utility.Rsync
+import Utility.FileMode
import qualified Data.Set as S
import qualified Data.ByteString.Lazy as L
@@ -444,9 +445,27 @@ displayList items header
| numitems > 10 = take 10 items ++ ["(and " ++ show (numitems - 10) ++ " more)"]
| otherwise = items
+{- Fix problems that would prevent repair from working at all
+ -
+ - A missing or corrupt .git/HEAD makes git not treat the repository as a
+ - git repo. If there is a git repo in a parent directory, it may move up
+ - the tree and use that one instead. So, cannot use `git show-ref HEAD` to
+ - test it.
+ -}
+preRepair :: Repo -> IO ()
+preRepair g = do
+ void $ tryIO $ allowRead headfile
+ unlessM (validhead <$> catchDefaultIO "" (readFile headfile)) $ do
+ nukeFile headfile
+ writeFile headfile "ref: refs/heads/master"
+ where
+ headfile = localGitDir g </> "HEAD"
+ validhead s = "ref: " `isPrefixOf` s || isJust (extractSha s)
+
{- Put it all together. -}
runRepair :: Bool -> Repo -> IO (Bool, MissingObjects, [Branch])
runRepair forced g = do
+ preRepair g
putStrLn "Running git fsck ..."
fsckresult <- findBroken False g
if foundBroken fsckresult
diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs
index 1307d38..46c6a31 100644
--- a/Utility/FileMode.hs
+++ b/Utility/FileMode.hs
@@ -64,6 +64,10 @@ preventWrite f = modifyFileMode f $ removeModes writeModes
allowWrite :: FilePath -> IO ()
allowWrite f = modifyFileMode f $ addModes [ownerWriteMode]
+{- Turns a file's owner read bit back on. -}
+allowRead :: FilePath -> IO ()
+allowRead f = modifyFileMode f $ addModes [ownerReadMode]
+
{- Allows owner and group to read and write to a file. -}
groupSharedModes :: [FileMode]
groupSharedModes =
diff --git a/debian/changelog b/debian/changelog
index 8fda54a..e34606e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@ git-repair (1.20131119) UNRELEASED; urgency=low
corruption-driven-development.
* Improve repair code in the case where the index file is corrupt,
and this hides other problems.
+ * Write a dummy .git/HEAD if the file is missing or corrupt, as
+ git otherwise will not treat the repository as a git repo.
-- Joey Hess <joeyh@debian.org> Tue, 19 Nov 2013 17:16:56 -0400