summaryrefslogtreecommitdiff
path: root/Git
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-10-21 16:19:00 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-10-21 16:20:54 -0400
commitafe0cc0bb4fbe3876c35462dece4670617263877 (patch)
treef23797ee89c453d7c82f35e47bb5fc197662a5f4 /Git
parent727566ad23efc6c36a4a4473b3299af913f6ce03 (diff)
corrupt branch resetting (but not yet reflog walking)
Diffstat (limited to 'Git')
-rw-r--r--Git/RecoverRepository.hs43
1 files changed, 37 insertions, 6 deletions
diff --git a/Git/RecoverRepository.hs b/Git/RecoverRepository.hs
index f40450f46..330063abe 100644
--- a/Git/RecoverRepository.hs
+++ b/Git/RecoverRepository.hs
@@ -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