{-# LANGUAGE UndecidableInstances #-} module Darcs.Patch.Rebase.Legacy.Item ( RebaseItem(..) , toRebaseChanges ) where import Darcs.Prelude import Darcs.Patch.Format ( PatchListFormat(..) ) import Darcs.Patch.Named ( Named(..) ) import Darcs.Patch.Read ( ReadPatch(..) ) import Darcs.Patch.FromPrim ( PrimPatchBase, PrimOf ) import Darcs.Patch.Rebase.Change ( RebaseChange(..), addNamedToRebase ) import Darcs.Patch.Rebase.Fixup ( RebaseFixup(..) ) import Darcs.Patch.RepoPatch ( RepoPatch ) import Darcs.Util.Parser ( Parser, lexString ) import Darcs.Patch.Witnesses.Ordered import Darcs.Patch.Witnesses.Sealed import Darcs.Patch.Witnesses.Show ( Show1, Show2 ) import qualified Darcs.Util.Diff as D import Control.Applicative ( (<|>) ) import qualified Data.ByteString as B ( ByteString ) import qualified Data.ByteString.Char8 as BC ( pack ) -- |A single item in the rebase state consists of either -- a patch that is being edited, or a fixup that adjusts -- the context so that a subsequent patch that is being edited -- \"makes sense\". -- -- @ToEdit@ holds a patch that is being edited. The name ('PatchInfo') of -- the patch will typically be the name the patch had before -- it was added to the rebase state; if it is moved back -- into the repository it must be given a fresh name to account -- for the fact that it will not necessarily have the same -- dependencies or content as the original patch. This is typically -- done by changing the @Ignore-This@ junk. -- -- @Fixup@ adjusts the context so that a subsequent @ToEdit@ patch -- is correct. Where possible, @Fixup@ changes are commuted -- as far as possible into the rebase state, so any remaining -- ones will typically cause a conflict when the @ToEdit@ patch -- is moved back into the repository. data RebaseItem p wX wY where ToEdit :: Named p wX wY -> RebaseItem p wX wY Fixup :: RebaseFixup (PrimOf p) wX wY -> RebaseItem p wX wY deriving instance (Show2 p, Show2 (PrimOf p)) => Show (RebaseItem p wX wY) instance (Show2 p, Show2 (PrimOf p)) => Show1 (RebaseItem p wX) instance (Show2 p, Show2 (PrimOf p)) => Show2 (RebaseItem p) toRebaseChanges :: forall p wX wY . RepoPatch p => FL (RebaseItem p) wX wY -> Sealed (FL (RebaseChange (PrimOf p)) wX) toRebaseChanges NilFL = Sealed NilFL toRebaseChanges (Fixup f :>: ps) = case toRebaseChanges ps of Sealed (RC fixups toedit :>: rest) -> Sealed (RC (f :>: fixups) toedit :>: rest) Sealed NilFL -> error "rebase chain with Fixup at end" toRebaseChanges (ToEdit te :>: ps) = unseal (addNamedToRebase @p D.MyersDiff te) (toRebaseChanges ps) -- This Read instance partly duplicates the instances for RebaseFixup, -- but are left this way given this code is now here only for backwards compatibility of the on-disk -- format and we might want to make future changes to RebaseFixup. instance (PrimPatchBase p, PatchListFormat p, ReadPatch p) => ReadPatch (RebaseItem p) where readPatch' = mapSeal ToEdit <$> readWith (BC.pack "rebase-toedit") <|> mapSeal (Fixup . PrimFixup) <$> readWith (BC.pack "rebase-fixup" ) <|> mapSeal (Fixup . NameFixup) <$> readWith (BC.pack "rebase-name" ) where readWith :: forall q wX . ReadPatch q => B.ByteString -> Parser (Sealed (q wX)) readWith str = do lexString str lexString (BC.pack "(") res <- readPatch' lexString (BC.pack ")") return res