This commit is contained in:
Joey Hess 2013-10-23 13:13:40 -04:00
parent 435ea52f3c
commit 1ab2ad86c7
3 changed files with 87 additions and 67 deletions

View file

@ -13,6 +13,7 @@ import qualified Annex
import qualified Git.Repair
import qualified Annex.Branch
import Git.Fsck (MissingObjects)
import Git.Types
def :: [Command]
def = [noCommit $ dontCheck repoExists $
@ -26,9 +27,10 @@ start = next $ next $ runRepair =<< Annex.getState Annex.force
runRepair :: Bool -> Annex Bool
runRepair forced = do
(ok, stillmissing) <- inRepo $ Git.Repair.runRepair forced
(ok, stillmissing, modifiedbranches) <- inRepo $
Git.Repair.runRepair forced
when ok $
repairAnnexBranch stillmissing
repairAnnexBranch stillmissing modifiedbranches
return ok
{- After git repository repair, the .git/annex/index file could
@ -36,23 +38,31 @@ runRepair forced = do
- its own. Since this index file is not used to stage things
- for long durations of time, it can safely be deleted if it is broken.
-
- Otherwise, commit the index file to the git-annex branch.
- Otherwise, if the git-annex branch was modified by the repair,
- commit the index file to the git-annex branch.
- This way, if the git-annex branch got rewound to an old version by
- the repository repair, or was completely deleted, this will get it back
- to a good state. Note that in the unlikely case where the git-annex
- branch is ok, and has new changes from elsewhere not yet reflected in
- the index, this does properly merge those into the index before
- committing.
- branch was rewound to a state that, had new changes from elsewhere not
- yet reflected in the index, this does properly merge those into the
- index before committing.
-}
repairAnnexBranch :: MissingObjects -> Annex ()
repairAnnexBranch missing = ifM okindex
( do
Annex.Branch.forceCommit "committing index after git repository repair"
liftIO $ putStrLn "Successfully recovered the git-annex branch using .git/annex/index"
repairAnnexBranch :: MissingObjects -> [Branch] -> Annex ()
repairAnnexBranch missing modifiedbranches
| Annex.Branch.fullname `elem` modifiedbranches = ifM okindex
( commitindex
, do
inRepo $ nukeFile . gitAnnexIndex
liftIO $ putStrLn "Had to delete the .git/annex/index file as it was corrupt. It would be a very good idea to run: git annex fsck --fast"
nukeindex
liftIO $ putStrLn "Had to delete the .git/annex/index file as it was corrupt. Since the git-annex branch is not up-to-date anymore. It would be a very good idea to run: git annex fsck --fast"
)
| otherwise = ifM okindex
( noop
, nukeindex
)
where
okindex = Annex.Branch.withIndex $
inRepo $ Git.Repair.checkIndex missing
commitindex = do
Annex.Branch.forceCommit "committing index after git repository repair"
liftIO $ putStrLn "Successfully recovered the git-annex branch using .git/annex/index"
nukeindex = inRepo $ nukeFile . gitAnnexIndex

View file

@ -421,21 +421,30 @@ displayList items header
| otherwise = items
{- Put it all together. -}
runRepair :: Bool -> Repo -> IO (Bool, MissingObjects)
runRepair :: Bool -> Repo -> IO (Bool, MissingObjects, [Branch])
runRepair forced g = do
putStrLn "Running git fsck ..."
fsckresult <- findBroken False g
if foundBroken fsckresult
then makerepairs fsckresult
else do
putStrLn "No problems found."
return (True, S.empty, [])
where
makerepairs fsckresult = do
missing <- cleanCorruptObjects fsckresult g
stillmissing <- retrieveMissingObjects missing g
if S.null stillmissing
then successfulfinish stillmissing
then successfulfinish stillmissing []
else do
putStrLn $ unwords
[ show (S.size stillmissing)
, "missing objects could not be recovered!"
]
if forced
then do
then continuerepairs stillmissing
else unsuccessfulfinish stillmissing
continuerepairs stillmissing = do
(remotebranches, goodcommits) <- removeTrackingBranches stillmissing emptyGoodCommits g
unless (null remotebranches) $
putStrLn $ unwords
@ -451,14 +460,15 @@ runRepair forced g = do
deindexedfiles <- rewriteIndex stillmissing g
displayList deindexedfiles
"Removed these missing files from the index. You should look at what files are present in your working tree and git add them back to the index when appropriate."
let modifiedbranches = resetbranches ++ deletedbranches
if null resetbranches && null deletedbranches
then successfulfinish stillmissing
then successfulfinish stillmissing modifiedbranches
else do
unless (repoIsLocalBare g) $ do
mcurr <- Branch.currentUnsafe g
case mcurr of
Nothing -> return ()
Just curr -> when (any (== curr) (resetbranches ++ deletedbranches)) $ do
Just curr -> when (any (== curr) modifiedbranches) $ do
putStrLn $ unwords
[ "You currently have"
, show curr
@ -466,19 +476,18 @@ runRepair forced g = do
]
putStrLn "Successfully recovered repository!"
putStrLn "Please carefully check that the changes mentioned above are ok.."
return (True, stillmissing)
else do
if repoIsLocalBare g
then do
putStrLn "If you have a clone of this bare repository, you should add it as a remote of this repository, and re-run git-recover-repository."
putStrLn "If there are no clones of this repository, you can instead run git-recover-repository with the --force parameter to force recovery to a possibly usable state."
else putStrLn "To force a recovery to a usable state, run this command again with the --force parameter."
return (False, stillmissing)
where
successfulfinish stillmissing = do
return (True, stillmissing, modifiedbranches)
successfulfinish stillmissing modifiedbranches = do
mapM_ putStrLn
[ "Successfully recovered repository!"
, "You should run \"git fsck\" to make sure, but it looks like"
, "everything was recovered ok."
]
return (True, stillmissing)
return (True, stillmissing, modifiedbranches)
unsuccessfulfinish stillmissing = do
if repoIsLocalBare g
then do
putStrLn "If you have a clone of this bare repository, you should add it as a remote of this repository, and re-run git-recover-repository."
putStrLn "If there are no clones of this repository, you can instead run git-recover-repository with the --force parameter to force recovery to a possibly usable state."
else putStrLn "To force a recovery to a usable state, run this command again with the --force parameter."
return (False, stillmissing, [])

View file

@ -7,6 +7,7 @@
import System.Environment
import qualified Data.Set as S
import Data.Tuple.Utils
import Common
import qualified Git
@ -35,7 +36,7 @@ main = do
forced <- parseArgs
g <- Git.Config.read =<< Git.CurrentRepo.get
ifM (fst <$> Git.Repair.runRepair forced g)
ifM (fst3 <$> Git.Repair.runRepair forced g)
( exitSuccess
, exitFailure
)