% Copyright (C) 2003,2005 David Roundy % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2, or (at your option) % any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; see the file COPYING. If not, write to % the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, % Boston, MA 02110-1301, USA. \subsection{darcs repair} \begin{code} module Repair ( repair ) where import Workaround ( getCurrentDirectory ) import Directory (setCurrentDirectory ) import IO import System ( exitWith, ExitCode(..) ) import Monad ( when, ) import DarcsCommands import DarcsArguments ( DarcsFlag( Verbose, Quiet ), any_verbosity, working_repo_dir, umask_option, ) import Patch ( patch2patchinfo ) import Repository ( withRepoLock ) import DarcsRepo ( lazily_read_repo, am_in_repo, get_checkpoint_by_default, apply_patches_with_feedback, simple_feedback ) import Pristine ( identifyPristine, checkPristine, replacePristine ) import Depends ( get_patches_beyond_tag ) import Lock( withTempDir ) import Check ( check_uniqueness ) import Printer ( putDocLn, text ) #include "impossible.h" \end{code} \options{repair} \begin{code} repair_description :: String repair_description = "Repair the corrupted repository." \end{code} \haskell{repair_help} \begin{code} repair_help :: String repair_help = "Repair attempts to fix corruption that may have entered your\n"++ "repository.\n" \end{code} \begin{code} repair :: DarcsCommand repair = DarcsCommand {command_name = "repair", command_help = repair_help, command_description = repair_description, command_extra_args = 0, command_extra_arg_help = [], command_command = repair_cmd, command_prereq = am_in_repo, command_get_arg_possibilities = return [], command_argdefaults = nodefaults, command_darcsoptions = [any_verbosity, working_repo_dir, umask_option]} \end{code} Repair currently will only repair damage to the pristine tree. Fortunately this is just the sort of corruption that is most likely to happen. \begin{code} repair_cmd :: [DarcsFlag] -> [String] -> IO () repair_cmd opts _ = let putVerbose s = when (Verbose `elem` opts) $ putDocLn s putInfo s = when (not $ Quiet `elem` opts) $ putDocLn s feedback = simple_feedback opts in withRepoLock opts $ \_ -> do check_uniqueness putVerbose putInfo patches <- lazily_read_repo "." maybe_chk <- get_checkpoint_by_default opts "." formerdir <- getCurrentDirectory withTempDir (formerdir++"/_darcs/newpristine") $ \newcur -> do putVerbose $ text "Applying patches..." case maybe_chk of Just chk -> case patch2patchinfo chk of Just chtg -> do putVerbose $ text "I am repairing from a checkpoint." apply_patches_with_feedback [] feedback putInfo $ (chtg, Just chk) : reverse (concat $ get_patches_beyond_tag chtg patches) Nothing -> impossible -- checkpoint is always a tag Nothing -> apply_patches_with_feedback [] feedback putInfo $ reverse $ concat patches -- withTempDir ignores error on delete -- hence the hack below. setCurrentDirectory formerdir cur <- identifyPristine is_same <- checkPristine newcur cur if is_same then do putStrLn "The repository is already consistent, no changes made." exitWith ExitSuccess else do putStrLn "Fixing pristine tree..." replacePristine newcur cur exitWith ExitSuccess \end{code}