%Copyright(C)2002-2005DavidRoundy%%Thisprogramisfreesoftware;youcanredistributeitand/ormodify%itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby%theFreeSoftwareFoundation;eitherversion2,or(atyouroption)%anylaterversion.%%Thisprogramisdistributedinthehopethatitwillbeuseful,%butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof%MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe%GNUGeneralPublicLicenseformoredetails.%%YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense%alongwiththisprogram;seethefileCOPYING.Ifnot,writeto%theFreeSoftwareFoundation,Inc.,51FranklinStreet,FifthFloor,%Boston,MA02110-1301,USA.\subsection{darcsunrecord}\label{unrecord}\begin{code}{-# OPTIONS_GHC -cpp #-}{-# LANGUAGE CPP #-}moduleDarcs.Commands.Unrecord(unrecord,unpull,obliterate,get_last_patches)whereimportControl.Monad(when)importSystem.Exit(exitWith,ExitCode(ExitSuccess))importDarcs.SlurpDirectory(wait_a_moment)importDarcs.Hopefully(hopefully)importDarcs.Commands(DarcsCommand(..),nodefaults,loggers,command_alias)importDarcs.Arguments(DarcsFlag(Verbose),working_repo_dir,nocompress,definePatches,match_several_or_last,deps_sel,ignoretimes,all_interactive,umask_option,)importDarcs.Match(first_match,match_first_patchset,match_a_patchread)importDarcs.Repository(PatchSet,PatchInfoAnd,withGutsOf,withRepoLock,($-),slurp_recorded,tentativelyRemovePatches,finalizeRepositoryChanges,tentativelyAddToPending,applyToWorking,get_unrecorded,read_repo,amInRepository,sync_repo,)importDarcs.Patch(Patchy,RepoPatch,invert,commutex,effect)importDarcs.Ordered(RL(..),(:<)(..),(:>)(..),(:\/:)(..),(+<+),mapFL_FL,nullFL,concatRL,reverseRL,mapRL)importDarcs.Patch.Depends(get_common_and_uncommon)importDarcs.SelectChanges(with_selected_last_changes_reversed)importProgress(debugMessage)importDarcs.Sealed(Sealed(..),FlippedSeal(..),mapFlipped)#include "gadts.h"unrecord_description::Stringunrecord_description="Remove recorded patches without changing the working copy."\end{code}\options{unrecord}\haskell{unrecord_help}Unrecordcanbethoughtofasundo-record.Ifarecordisfollowedbyanunrecord,everythinglookslikebeforetherecord;allthepreviouslyunrecordedchangesareback,andcanberecordedagaininanewpatch.Theunrecordedpatchhoweverisactuallyremovedfromyourrepository,sothereisnowaytorecorditagaintogetitback.\footnote{Thepatchfileitselfisnotactuallydeleted,butitscontextislost,soitcannotbereliablyread---your only choice would betogoinbyhandandreaditscontents.}.Ifyouwanttoremovethechangesfromtheworkingcopytoo(wheretheyotherwisewillshowupasunrecordedchangesagain),you'llalsoneedto\verb!darcsrevert!.Todounrecordandrevertinonego,youcanuse\verb!darcsobliterate!.Ifyoudon'trevertafterunrecording,thenthechangesmadebytheunrecordedpatchesareleftinyourworkingtree.Ifthesepatchesareactuallyfromanotherrepository,interaction(eitherpushesorpulls)withthatrepositorymaybemassivelysloweddown,asdarcstriestocopewiththefactthatyouappeartohavemadealargenumberofchangesthatconflictwiththosepresentintheotherrepository.Soifyoureallywanttoundotheresultofa\emph{pull}operation,useobliterate!Unrecordisprimarilyintendedforwhenyourecordapatch,realizeitneedsjustonemorechange,butwouldrathernothaveaseparatepatchforjustthatonechange.\newcommand{\pullwarning}[1]{\textbf{WARNING:}#1shouldnotberunwhenthereisapossibilitythatanotherusermaybepullingfromthesamerepository.Attemptingtodosomaycauserepositorycorruption.}\pullwarning{Unrecord}\begin{options}--from-match, --from-patch, --from-tag, --last\end{options}Usuallyyouonlywanttounrecordthelatestchanges,andalmostneverwouldyouwanttounrecordchangesbeforeatag---youwouldhavetohaveunrecordedthetagaswelltodothat.Therefore,andforefficiency,darcsonlypromptsyouforthelatestpatches,aftersomeoptimaltag.Ifyoudowanttounrecordmorepatchesinonego,therearethe\verb!--from!and\verb!--last!optionstosettheearliestpatchselectabletounrecord.\begin{options}--matches, --patches, --tags, --no-deps\end{options}The\verb!--patches!,\verb!--matches!,\verb!--tags!,and\verb!--no-deps!optionscanbeusedtoselectwhichpatchestounrecord,asdescribedinsubsection~\ref{selecting}.Withtheseoptionsyoucanspecifywhatpatchorpatchestobepromptedforbyunrecord.Thisisespeciallyusefulwhenyouwanttounrecordpatcheswithdependencies,sinceallthedependentpatches(butnoothers)willbeincludedinthechoices.Orifyouuse\verb!--no-deps!youwon'tbeaskedaboutpatchesthatcan'tbeunrecordedduetodependingpatches.Selectingpatchescanbeslow,sodarcscutsthesearchatthelastoptimizedtag.Usethe\verb!--from!or\verb!--last!optionstosearchmoreorfewerpatches.\begin{code}unrecord_help::Stringunrecord_help="Unrecord does the opposite of record in that it makes the changes from\n"++"patches active changes again which you may record or revert later. The\n"++"working copy itself will not change.\n"++"Beware that you should not use this command if you are going to\n"++"re-record the changes in any way and there is a possibility that\n"++"another user may have already pulled the patch.\n"unrecord::DarcsCommandunrecord=DarcsCommand{command_name="unrecord",command_help=unrecord_help,command_description=unrecord_description,command_extra_args=0,command_extra_arg_help=[],command_command=unrecord_cmd,command_prereq=amInRepository,command_get_arg_possibilities=return[],command_argdefaults=nodefaults,command_advanced_options=[nocompress,umask_option],command_basic_options=[match_several_or_last,deps_sel,all_interactive,working_repo_dir]}unrecord_cmd::[DarcsFlag]->[String]->IO()unrecord_cmdopts_=withRepoLockopts$-\repository->dolet(logMessage,_,_)=loggersoptsrecorded<-slurp_recordedrepositoryallpatches<-read_reporepositoryFlippedSealpatches<-return$iffirst_matchoptsthenget_last_patchesoptsallpatcheselsematchingHeadoptsallpatcheswith_selected_last_changes_reversed"unrecord"optsrecorded(reverseRLpatches)$\(_:>to_unrecord)->dowhen(nullFLto_unrecord)$dologMessage"No patches selected!"exitWithExitSuccesswhen(Verbose`elem`opts)$logMessage"About to write out (potentially) modified patches..."definePatchesto_unrecordwithGutsOfrepository$dotentativelyRemovePatchesrepositoryopts$mapFL_FLhopefullyto_unrecordfinalizeRepositoryChangesrepositorysync_reporepositorylogMessage"Finished unrecording."get_last_patches::RepoPatchp=>[DarcsFlag]->PatchSetpC(r)->FlippedSeal(RL(PatchInfoAndp))C(r)get_last_patchesoptsps=casematch_first_patchsetoptspsofSealedp1s->caseget_common_and_uncommon(ps,p1s)of(_,us:\/:_)->FlippedSeal$concatRLusunpull_description::Stringunpull_description="Opposite of pull; unsafe if patch is not in remote repository."unpull_help::Stringunpull_help="Unpull completely removes recorded patches from your local repository.\n"++"The changes will be undone in your working copy and the patches will not be\n"++"shown in your changes list anymore.\n"++"Beware that if the patches are not still present in another repository you\n"++"will lose precious code by unpulling!\n"unpull::DarcsCommandunpull=(command_alias"unpull"obliterate){command_help=unpull_help,command_description=unpull_description,command_command=unpull_cmd}unpull_cmd::[DarcsFlag]->[String]->IO()unpull_cmd=generic_obliterate_cmd"unpull"\end{code}\subsection{darcsobliterate}\begin{code}obliterate_description::Stringobliterate_description="Delete selected patches from the repository. (UNSAFE!)"obliterate_help::Stringobliterate_help="Obliterate completely removes recorded patches from your local repository.\n"++"The changes will be undone in your working copy and the patches will not be\n"++"shown in your changes list anymore.\n"++"Beware that you can lose precious code by obliterating!\n"\end{code}\options{obliterate}\haskell{obliterate_help}Obliteratedeletesapatchfromtherepository\emph{and}removesthosechangesfromtheworkingdirectory.Itisthereforea\emph{verydangerous}command.Whentherearenolocalchanges,obliterateisequivalenttoanunrecordfollowedbyarevert,exceptthatrevertcanbeunreverted.Inthecaseoftags,obliterateremovesthetagitself,notanyotherpatches.Notethatunpullwastheoldnameforobliterate.Unpullisstillanhiddenaliasforobliterate.\pullwarning{Obliterate}\begin{options}--from-match, --from-patch, --from-tag, --last\end{options}Usuallyyouonlywanttoobliteratethelatestchanges,andalmostneverwouldyouwanttoobliteratechangesbeforeatag---you would have to have obliteratedthetagaswelltodothat.Therefore,andforefficiency,darcsonlypromptsyouforthelatestpatches,aftersomeoptimaltag.Ifyoudowanttoobliteratemorepatchesinonego,therearethe\verb!--from!and\verb!--last!optionstosettheearliestpatchselectabletoobliterate.\begin{options}--matches, --patches, --tags, --no-deps\end{options}The\verb!--patches!,\verb!--matches!,\verb!--tags!,and\verb!--no-deps!optionscanbeusedtoselectwhichpatchestoobliterate,asdescribedinsubsection~\ref{selecting}.Withtheseoptionsyoucanspecifywhatpatchorpatchestobepromptedforbyobliterate.Thisisespeciallyusefulwhenyouwanttoobliteratepatcheswithdependencies,sinceallthedependentpatches(butnoothers)willbeincludedinthechoices.Orifyouuse\verb!--no-deps!youwon'tbeaskedaboutpatchesthatcan'tbeobliteratedduetodependingpatches.Selectingpatchescanbeslow,sodarcscutsthesearchatthelastoptimizedtag.Usethe\verb!--from!or\verb!--last!optionstosearchmoreorfewerpatches.\begin{code}obliterate::DarcsCommandobliterate=DarcsCommand{command_name="obliterate",command_help=obliterate_help,command_description=obliterate_description,command_extra_args=0,command_extra_arg_help=[],command_command=obliterate_cmd,command_prereq=amInRepository,command_get_arg_possibilities=return[],command_argdefaults=nodefaults,command_advanced_options=[nocompress,ignoretimes,umask_option],command_basic_options=[match_several_or_last,deps_sel,all_interactive,working_repo_dir]}obliterate_cmd::[DarcsFlag]->[String]->IO()obliterate_cmd=generic_obliterate_cmd"obliterate"generic_obliterate_cmd::String->[DarcsFlag]->[String]->IO()generic_obliterate_cmdcmdnameopts_=withRepoLockopts$-\repository->dolet(logMessage,_,_)=loggersoptsrecorded<-slurp_recordedrepositorypend<-get_unrecordedrepositoryallpatches<-read_reporepositoryFlippedSealpatches<-return$iffirst_matchoptsthenget_last_patchesoptsallpatcheselsematchingHeadoptsallpatcheswith_selected_last_changes_reversedcmdnameoptsrecorded(reverseRLpatches)$\(_:>ps)->casecommutex(pend:<effectps)ofNothing->fail$"Can't "++cmdname++" patch without reverting some unrecorded change."Just(p_after_pending:<_)->dowhen(nullFLps)$dologMessage"No patches selected!"exitWithExitSuccessdefinePatchespswithGutsOfrepository$dotentativelyRemovePatchesrepositoryopts(mapFL_FLhopefullyps)tentativelyAddToPendingrepositoryopts$invert$effectpsfinalizeRepositoryChangesrepositorydebugMessage"Waiting a bit for timestamps to differ..."wait_a_momentdebugMessage"Applying patches to working directory..."applyToWorkingrepositoryopts(invertp_after_pending)`catch`\e->fail("Couldn't undo patch in working dir.\n"++showe)sync_reporepositorylogMessage$"Finished "++present_participlecmdname++"."matchingHead::Patchyp=>[DarcsFlag]->PatchSetpC(r)->FlippedSeal(RL(PatchInfoAndp))C(r)matchingHeadopts(x:<:_)|or(mapRL(match_a_patchreadopts)x)=FlippedSealxmatchingHeadopts(x:<:xs)=(x+<+)`mapFlipped`matchingHeadoptsxsmatchingHead_NilRL=FlippedSealNilRLpresent_participle::String->Stringpresent_participlev|lastv=='e'=initv++"ing"|otherwise=v++"ing"\end{code}