% Copyright (C) 2002-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.
\darcsCommand{revert}
\begin{code}

moduleDarcs.Commands.Revert(revert)whereimportSystem.Exit(ExitCode(..),exitWith)importControl.Monad(when)importData.List(sort)importEnglish(englishNum,This(..),Noun(..))importDarcs.Commands(DarcsCommand(..),nodefaults)importDarcs.Arguments(DarcsFlag(All,Debug),ignoretimes,workingRepoDir,allInteractive,fixSubPaths,areFileArgs,listRegisteredFiles,umaskOption,)importDarcs.Utils(askUser)importDarcs.RepoPath(toFilePath)importDarcs.Repository(withRepoLock,($-),withGutsOf,add_to_pending,applyToWorking,amInRepository,readRecorded,unrecordedChanges)importDarcs.Patch(invert,applyToFilepaths,commute)importDarcs.Witnesses.Ordered(FL(..),(:>)(..),lengthFL,nullFL,(+>+))importDarcs.SelectChanges(with_selected_last_changes_to_files')importDarcs.Patch.TouchesFiles(choose_touching)importDarcs.Commands.Unrevert(writeUnrevert)importDarcs.Witnesses.Sealed(unsafeUnseal)revertDescription::StringrevertDescription="Discard unrecorded changes."revertHelp::StringrevertHelp="The `darcs revert' command discards unrecorded changes the working\n"++"tree. As with `darcs record', you will be asked which hunks (changes)\n"++"to revert. The --all switch can be used to avoid such prompting. If\n"++"files or directories are specified, other parts of the working tree\n"++"are not reverted.\n"++"\n"++"In you accidentally reverted something you wanted to keep (for\n"++"example, typing `darcs rev -a' instead of `darcs rec -a'), you can\n"++"immediately run `darcs unrevert' to restore it. This is only\n"++"guaranteed to work if the repository has not changed since `darcs\n"++"revert' ran.\n"revert::DarcsCommandrevert=DarcsCommand{commandName="revert",commandHelp=revertHelp,commandDescription=revertDescription,commandExtraArgs=-1,commandExtraArgHelp=["[FILE or DIRECTORY]..."],commandCommand=revertCmd,commandPrereq=amInRepository,commandGetArgPossibilities=listRegisteredFiles,commandArgdefaults=nodefaults,commandAdvancedOptions=[ignoretimes,umaskOption],commandBasicOptions=[allInteractive,workingRepoDir]}revertCmd::[DarcsFlag]->[String]->IO()revertCmdoptsargs=withRepoLockopts$-\repository->dofiles<-sort`fmap`fixSubPathsoptsargswhen(areFileArgsfiles)$putStrLn$"Reverting changes in "++unwords(mapshowfiles)++"..\n"changes<-unrecordedChangesoptsrepositoryfilesletpre_changed_files=applyToFilepaths(invertchanges)(maptoFilePathfiles)rec<-readRecordedrepositorycaseunsafeUnseal$choose_touchingpre_changed_fileschangesofNilFL->putStrLn"There are no changes to revert!"_->with_selected_last_changes_to_files'"revert"optsNothingpre_changed_fileschanges$\(norevert:>p)->ifnullFLpthenputStrLn$"If you don't want to revert after all,"++" that's fine with me!"elsedolettheseChanges=englishNum(lengthFLp).This.Noun$"change"yorn<-ifAll`elem`optsthenreturn"y"elseaskUser$"Do you really want to revert "++theseChanges"? "caseyornof('y':_)->return()_->exitWith$ExitSuccesswithGutsOfrepository$doadd_to_pendingrepository$invertpwhen(Debug`elem`opts)$putStrLn"About to write the unrevert file."casecommute(norevert:>p)ofJust(p':>_)->writeUnrevertrepositoryp'recNilFLNothing->writeUnrevertrepository(norevert+>+p)recNilFLwhen(Debug`elem`opts)$putStrLn"About to apply to the working directory."applyToWorkingrepositoryopts(invertp)`catch`\e->fail("Unable to apply inverse patch!"++showe)putStrLn"Finished reverting."