summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-10-23 13:13:40 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-10-23 13:19:37 -0400
commit9ed8dd6be036e79e3ec7f5781b9f7b8864e1bc0e (patch)
treeba2d9f0ea9fe3eed88ac9ab0aa5e2133e14d13fa
parentb77b0848ee28093b63e3ab0d1ea494e430ffe58b (diff)
minor
-rw-r--r--Command/Repair.hs40
-rw-r--r--Git/Repair.hs109
-rw-r--r--git-recover-repository.hs3
3 files changed, 86 insertions, 66 deletions
diff --git a/Command/Repair.hs b/Command/Repair.hs
index b95934268..8808ef9de 100644
--- a/Command/Repair.hs
+++ b/Command/Repair.hs
@@ -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"
- , 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"
- )
+repairAnnexBranch :: MissingObjects -> [Branch] -> Annex ()
+repairAnnexBranch missing modifiedbranches
+ | Annex.Branch.fullname `elem` modifiedbranches = ifM okindex
+ ( commitindex
+ , do
+ 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
diff --git a/Git/Repair.hs b/Git/Repair.hs
index bb540fbd7..cc54e49dc 100644
--- a/Git/Repair.hs
+++ b/Git/Repair.hs
@@ -421,64 +421,73 @@ 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
- missing <- cleanCorruptObjects fsckresult g
- stillmissing <- retrieveMissingObjects missing g
- if S.null stillmissing
- then successfulfinish stillmissing
+ 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 []
+ else do
+ putStrLn $ unwords
+ [ show (S.size stillmissing)
+ , "missing objects could not be recovered!"
+ ]
+ if forced
+ then continuerepairs stillmissing
+ else unsuccessfulfinish stillmissing
+ continuerepairs stillmissing = do
+ (remotebranches, goodcommits) <- removeTrackingBranches stillmissing emptyGoodCommits g
+ unless (null remotebranches) $
putStrLn $ unwords
- [ show (S.size stillmissing)
- , "missing objects could not be recovered!"
+ [ "removed"
+ , show (length remotebranches)
+ , "remote tracking branches that referred to missing objects"
]
- if forced
- then do
- (remotebranches, goodcommits) <- removeTrackingBranches stillmissing emptyGoodCommits g
- unless (null remotebranches) $
- putStrLn $ unwords
- [ "removed"
- , show (length remotebranches)
- , "remote tracking branches that referred to missing objects"
- ]
- (resetbranches, deletedbranches, _) <- resetLocalBranches stillmissing goodcommits g
- displayList (map show resetbranches)
- "Reset these local branches to old versions before the missing objects were committed:"
- displayList (map show deletedbranches)
- "Deleted these local branches, which could not be recovered due to missing objects:"
- 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."
- if null resetbranches && null deletedbranches
- then successfulfinish stillmissing
- else do
- unless (repoIsLocalBare g) $ do
- mcurr <- Branch.currentUnsafe g
- case mcurr of
- Nothing -> return ()
- Just curr -> when (any (== curr) (resetbranches ++ deletedbranches)) $ do
- putStrLn $ unwords
- [ "You currently have"
- , show curr
- , "checked out. You may have staged changes in the index that can be committed to recover the lost state of this branch!"
- ]
- 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
+ (resetbranches, deletedbranches, _) <- resetLocalBranches stillmissing goodcommits g
+ displayList (map show resetbranches)
+ "Reset these local branches to old versions before the missing objects were committed:"
+ displayList (map show deletedbranches)
+ "Deleted these local branches, which could not be recovered due to missing objects:"
+ 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 modifiedbranches
+ else do
+ unless (repoIsLocalBare g) $ do
+ mcurr <- Branch.currentUnsafe g
+ case mcurr of
+ Nothing -> return ()
+ Just curr -> when (any (== curr) modifiedbranches) $ do
+ putStrLn $ unwords
+ [ "You currently have"
+ , show curr
+ , "checked out. You may have staged changes in the index that can be committed to recover the lost state of this branch!"
+ ]
+ putStrLn "Successfully recovered repository!"
+ putStrLn "Please carefully check that the changes mentioned above are ok.."
+ 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, [])
diff --git a/git-recover-repository.hs b/git-recover-repository.hs
index 556e2a39b..3e348f5bb 100644
--- a/git-recover-repository.hs
+++ b/git-recover-repository.hs
@@ -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
)