corrupt branch resetting (but not yet reflog walking)
This commit is contained in:
parent
fcd91be6f0
commit
18487c779f
3 changed files with 58 additions and 15 deletions
|
@ -169,11 +169,40 @@ copyObjects srcr destr = rsync
|
|||
|
||||
{- To deal with missing objects that cannot be recovered, resets any
|
||||
- local branches to point to an old commit before the missing
|
||||
- objects.
|
||||
- objects. Returns all branches that were changed, and deleted.
|
||||
-}
|
||||
resetLocalBranches :: MissingObjects -> GoodCommits -> Repo -> IO [Branch]
|
||||
resetLocalBranches missing goodcommits r = do
|
||||
error "TODO"
|
||||
resetLocalBranches :: MissingObjects -> GoodCommits -> Repo -> IO ([Branch], [Branch], GoodCommits)
|
||||
resetLocalBranches missing goodcommits r =
|
||||
go [] [] goodcommits =<< filter islocalbranch <$> getAllRefs r
|
||||
where
|
||||
islocalbranch b = "refs/heads/" `isPrefixOf` show b
|
||||
go changed deleted gcs [] = return (changed, deleted, gcs)
|
||||
go changed deleted gcs (b:bs) = do
|
||||
(mc, gcs') <- findUncorruptedCommit missing gcs b r
|
||||
case mc of
|
||||
Just c
|
||||
| c == b -> go changed deleted gcs' bs
|
||||
| otherwise -> do
|
||||
reset b c
|
||||
go (b:changed) deleted gcs' bs
|
||||
Nothing -> do
|
||||
(mc', gcs'') <- findOldBranch missing gcs' b r
|
||||
case mc' of
|
||||
Just c
|
||||
| c == b -> go changed deleted gcs' bs
|
||||
| otherwise -> do
|
||||
reset b c
|
||||
go (b:changed) deleted gcs'' bs
|
||||
Nothing -> do
|
||||
nukeBranchRef b r
|
||||
go changed (b:deleted) gcs'' bs
|
||||
reset b c = do
|
||||
nukeBranchRef b r
|
||||
void $ runBool
|
||||
[ Param "branch"
|
||||
, Param (show $ Ref.base b)
|
||||
, Param (show c)
|
||||
] r
|
||||
|
||||
{- To deal with missing objects that cannot be recovered, removes
|
||||
- any remote tracking branches that reference them. Returns a list of
|
||||
|
@ -255,6 +284,7 @@ findUncorruptedCommit missing goodcommits branch r = do
|
|||
else do
|
||||
(ls, cleanup) <- pipeNullSplit
|
||||
[ Param "log"
|
||||
, Param "-z"
|
||||
, Param "--format=%H"
|
||||
, Param (show branch)
|
||||
] r
|
||||
|
@ -284,11 +314,12 @@ verifyCommit missing goodcommits commit r
|
|||
| otherwise = do
|
||||
(ls, cleanup) <- pipeNullSplit
|
||||
[ Param "log"
|
||||
, Param "-z"
|
||||
, Param "--format=%H %T"
|
||||
, Param (show commit)
|
||||
] r
|
||||
let committrees = map parse ls
|
||||
if any isNothing committrees
|
||||
if any isNothing committrees || null committrees
|
||||
then do
|
||||
void cleanup
|
||||
return (False, goodcommits)
|
||||
|
@ -304,7 +335,7 @@ verifyCommit missing goodcommits commit r
|
|||
<$> extractSha commitsha
|
||||
<*> extractSha treesha
|
||||
_ -> Nothing
|
||||
check [] = return False
|
||||
check [] = return True
|
||||
check ((commit, tree):rest)
|
||||
| checkGoodCommit commit goodcommits = return True
|
||||
| otherwise = verifyTree missing tree r <&&> check rest
|
||||
|
|
|
@ -143,8 +143,7 @@ that was found for it.
|
|||
`git annex fsck --fast` to fix up any object location info.
|
||||
* Remote tracking branches can just be removed, and then `git fetch`
|
||||
from the remote, which will re-download missing objects from it and
|
||||
reinstate the tracking branch.
|
||||
* For other branches (or tags), it's best to not rewrite them, because
|
||||
that could get really confusing. Instead, delete the old broken branch,
|
||||
and make a "recovered/$branch" that holds the last good commit (if one
|
||||
was found).
|
||||
reinstate the tracking branch. **done**
|
||||
* For other branches, reset them to last good commit, or delete
|
||||
if none was found.
|
||||
* (Decided not to touch tags.)
|
||||
|
|
|
@ -16,6 +16,7 @@ import Common
|
|||
import qualified Git.CurrentRepo
|
||||
import qualified Git.RecoverRepository
|
||||
import qualified Git.Config
|
||||
import qualified Git.Branch
|
||||
|
||||
header :: String
|
||||
header = "Usage: git-recover-repository"
|
||||
|
@ -34,7 +35,7 @@ parseArgs = do
|
|||
enableDebugOutput :: IO ()
|
||||
enableDebugOutput = do
|
||||
s <- setFormatter
|
||||
<$> streamHandler stderr NOTICE
|
||||
<$> streamHandler stderr DEBUG -- NOTICE
|
||||
<*> pure (simpleLogFormatter "$msg")
|
||||
updateGlobalLogger rootLoggerName (setLevel DEBUG . setHandlers [s])
|
||||
|
||||
|
@ -66,8 +67,20 @@ main = do
|
|||
, show (length remotebranches)
|
||||
, "remote tracking branches that referred to missing objects"
|
||||
]
|
||||
localbranches <- Git.RecoverRepository.resetLocalBranches stillmissing goodcommits g
|
||||
unless (null localbranches) $ do
|
||||
(resetbranches, deletedbranches, _) <- Git.RecoverRepository.resetLocalBranches stillmissing goodcommits g
|
||||
unless (null resetbranches) $ do
|
||||
putStrLn "Reset these local branches to old versions before the missing objects were committed:"
|
||||
putStr $ unlines $ map show localbranches
|
||||
putStr $ unlines $ map show resetbranches
|
||||
unless (null deletedbranches) $ do
|
||||
putStrLn "Deleted these local branches, which could not be recovered due to missing objects:"
|
||||
putStr $ unlines $ map show deletedbranches
|
||||
mcurr <- Git.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!"
|
||||
]
|
||||
else putStrLn "To force a recovery to a usable state, run this command again with the --force parameter."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue