git-phoenix 0.0.1 → 0.0.2
raw patch · 13 files changed
+227/−193 lines, 13 filesdep +lazy-scopePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: lazy-scope
API changes (from Hackage documentation)
- Data.Git.Phoenix.Commit: type LbsPair = (LByteString, LByteString)
- Data.Git.Phoenix.Io: hGet :: MonadIO m => Handle -> Int -> m ByteString
- Data.Git.Phoenix.Io: hGetContents :: MonadIO m => Handle -> m LByteString
- Data.Git.Phoenix.Io: hPut :: MonadIO m => Handle -> LByteString -> m ()
- Data.Git.Phoenix.Prelude: hClose :: MonadIO m => Handle -> m ()
- Data.Git.Phoenix.Prelude: hIsOpen :: MonadIO m => Handle -> m Bool
- Data.Git.Phoenix.Prelude: withBinaryFile :: MonadUnliftIO m => FilePath -> IOMode -> (Handle -> m a) -> m a
+ Data.Git.Phoenix.Io: hPutLbs :: MonadIO m => Handle -> LByteString -> m ()
+ Data.Git.Phoenix.Io: writeBinaryFile :: MonadUnliftIO m => FilePath -> IOMode -> (Handle -> m ()) -> m ()
+ Data.Git.Phoenix.Object: compressedDisambiguateBs :: forall {k} (s :: k). Bs s
+ Data.Git.Phoenix.Object: compressedDisambiguateLen :: Int64
+ Data.Git.Phoenix.Prelude: (!!?) :: [a] -> Int -> Maybe a
+ Data.Git.Phoenix.Prelude: ($!) :: (a -> b) -> a -> b
+ Data.Git.Phoenix.Prelude: ($) :: (a -> b) -> a -> b
+ Data.Git.Phoenix.Prelude: ($<) :: Contravariant f => f b -> b -> f a
+ Data.Git.Phoenix.Prelude: ($>) :: Functor f => f a -> b -> f b
+ Data.Git.Phoenix.Prelude: ($dmhashWithSalt) :: (Hashable a, Generic a, GHashable Zero (Rep a)) => Int -> a -> Int
+ Data.Git.Phoenix.Prelude: (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
+ Data.Git.Phoenix.Prelude: (&&) :: Bool -> Bool -> Bool
+ Data.Git.Phoenix.Prelude: (&&^) :: Monad m => m Bool -> m Bool -> m Bool
+ Data.Git.Phoenix.Prelude: (&) :: a -> (a -> b) -> b
+ Data.Git.Phoenix.Prelude: (*) :: Num a => a -> a -> a
+ Data.Git.Phoenix.Prelude: (**) :: Floating a => a -> a -> a
+ Data.Git.Phoenix.Prelude: (*>) :: Applicative f => f a -> f b -> f b
+ Data.Git.Phoenix.Prelude: (+) :: Num a => a -> a -> a
+ Data.Git.Phoenix.Prelude: (++) :: [a] -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: (-) :: Num a => a -> a -> a
+ Data.Git.Phoenix.Prelude: (.) :: (b -> c) -> (a -> b) -> a -> c
+ Data.Git.Phoenix.Prelude: (/) :: Fractional a => a -> a -> a
+ Data.Git.Phoenix.Prelude: (/=) :: Eq a => a -> a -> Bool
+ Data.Git.Phoenix.Prelude: (:|) :: a -> [a] -> NonEmpty a
+ Data.Git.Phoenix.Prelude: (<$!>) :: Monad m => (a -> b) -> m a -> m b
+ Data.Git.Phoenix.Prelude: (<$) :: Functor f => a -> f b -> f a
+ Data.Git.Phoenix.Prelude: (<$>) :: Functor f => (a -> b) -> f a -> f b
+ Data.Git.Phoenix.Prelude: (<&>) :: Functor f => f a -> (a -> b) -> f b
+ Data.Git.Phoenix.Prelude: (<) :: Ord a => a -> a -> Bool
+ Data.Git.Phoenix.Prelude: (<*) :: Applicative f => f a -> f b -> f a
+ Data.Git.Phoenix.Prelude: (<**>) :: Applicative f => f a -> f (a -> b) -> f b
+ Data.Git.Phoenix.Prelude: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
+ Data.Git.Phoenix.Prelude: (<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
+ Data.Git.Phoenix.Prelude: (<<<) :: forall {k} cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ Data.Git.Phoenix.Prelude: (<=) :: Ord a => a -> a -> Bool
+ Data.Git.Phoenix.Prelude: (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
+ Data.Git.Phoenix.Prelude: (<>) :: Semigroup a => a -> a -> a
+ Data.Git.Phoenix.Prelude: (<|>) :: Alternative f => f a -> f a -> f a
+ Data.Git.Phoenix.Prelude: (=<<) :: Monad m => (a -> m b) -> m a -> m b
+ Data.Git.Phoenix.Prelude: (==) :: Eq a => a -> a -> Bool
+ Data.Git.Phoenix.Prelude: (>$$<) :: Contravariant f => f b -> (a -> b) -> f a
+ Data.Git.Phoenix.Prelude: (>$) :: Contravariant f => b -> f b -> f a
+ Data.Git.Phoenix.Prelude: (>$<) :: Contravariant f => (a -> b) -> f b -> f a
+ Data.Git.Phoenix.Prelude: (>) :: Ord a => a -> a -> Bool
+ Data.Git.Phoenix.Prelude: (>=) :: Ord a => a -> a -> Bool
+ Data.Git.Phoenix.Prelude: (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
+ Data.Git.Phoenix.Prelude: (>>) :: Monad m => m a -> m b -> m b
+ Data.Git.Phoenix.Prelude: (>>=) :: Monad m => m a -> (a -> m b) -> m b
+ Data.Git.Phoenix.Prelude: (>>>) :: forall {k} cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ Data.Git.Phoenix.Prelude: (?:) :: Maybe a -> a -> a
+ Data.Git.Phoenix.Prelude: (??) :: Functor f => f (a -> b) -> a -> f b
+ Data.Git.Phoenix.Prelude: (^) :: (Num a, Integral b) => a -> b -> a
+ Data.Git.Phoenix.Prelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
+ Data.Git.Phoenix.Prelude: (||) :: Bool -> Bool -> Bool
+ Data.Git.Phoenix.Prelude: (||^) :: Monad m => m Bool -> m Bool -> m Bool
+ Data.Git.Phoenix.Prelude: -- | Type of a single element of the structure.
+ Data.Git.Phoenix.Prelude: All :: Bool -> All
+ Data.Git.Phoenix.Prelude: Alt :: f a -> Alt (f :: k -> Type) (a :: k)
+ Data.Git.Phoenix.Prelude: Any :: Bool -> Any
+ Data.Git.Phoenix.Prelude: Ap :: f a -> Ap (f :: k -> Type) (a :: k)
+ Data.Git.Phoenix.Prelude: AppendMode :: IOMode
+ Data.Git.Phoenix.Prelude: BlockBuffering :: Maybe Int -> BufferMode
+ Data.Git.Phoenix.Prelude: Bug :: SomeException -> CallStack -> Bug
+ Data.Git.Phoenix.Prelude: Comparison :: (a -> a -> Ordering) -> Comparison a
+ Data.Git.Phoenix.Prelude: Compose :: f (g a) -> Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1)
+ Data.Git.Phoenix.Prelude: Const :: a -> Const a (b :: k)
+ Data.Git.Phoenix.Prelude: D# :: Double# -> Double
+ Data.Git.Phoenix.Prelude: Down :: a -> Down a
+ Data.Git.Phoenix.Prelude: Dual :: a -> Dual a
+ Data.Git.Phoenix.Prelude: EQ :: Ordering
+ Data.Git.Phoenix.Prelude: Endo :: (a -> a) -> Endo a
+ Data.Git.Phoenix.Prelude: Equivalence :: (a -> a -> Bool) -> Equivalence a
+ Data.Git.Phoenix.Prelude: ExceptT :: m (Either e a) -> ExceptT e (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: F# :: Float# -> Float
+ Data.Git.Phoenix.Prelude: False :: Bool
+ Data.Git.Phoenix.Prelude: First :: Maybe a -> First a
+ Data.Git.Phoenix.Prelude: GT :: Ordering
+ Data.Git.Phoenix.Prelude: Identity :: a -> Identity a
+ Data.Git.Phoenix.Prelude: Just :: a -> Maybe a
+ Data.Git.Phoenix.Prelude: LT :: Ordering
+ Data.Git.Phoenix.Prelude: Last :: Maybe a -> Last a
+ Data.Git.Phoenix.Prelude: Left :: a -> Either a b
+ Data.Git.Phoenix.Prelude: LineBuffering :: BufferMode
+ Data.Git.Phoenix.Prelude: MaybeT :: m (Maybe a) -> MaybeT (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: NoBuffering :: BufferMode
+ Data.Git.Phoenix.Prelude: Nothing :: Maybe a
+ Data.Git.Phoenix.Prelude: Op :: (b -> a) -> Op a b
+ Data.Git.Phoenix.Prelude: Predicate :: (a -> Bool) -> Predicate a
+ Data.Git.Phoenix.Prelude: Product :: a -> Product a
+ Data.Git.Phoenix.Prelude: Proxy :: Proxy (t :: k)
+ Data.Git.Phoenix.Prelude: ReadMode :: IOMode
+ Data.Git.Phoenix.Prelude: ReadWriteMode :: IOMode
+ Data.Git.Phoenix.Prelude: ReaderT :: (r -> m a) -> ReaderT r (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: Right :: b -> Either a b
+ Data.Git.Phoenix.Prelude: SomeException :: e -> SomeException
+ Data.Git.Phoenix.Prelude: SomeNat :: Proxy n -> SomeNat
+ Data.Git.Phoenix.Prelude: StateT :: (s -> m (a, s)) -> StateT s (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: Sum :: a -> Sum a
+ Data.Git.Phoenix.Prelude: True :: Bool
+ Data.Git.Phoenix.Prelude: Undefined :: Undefined
+ Data.Git.Phoenix.Prelude: WriteMode :: IOMode
+ Data.Git.Phoenix.Prelude: ZipList :: [a] -> ZipList a
+ Data.Git.Phoenix.Prelude: [appEndo] :: Endo a -> a -> a
+ Data.Git.Phoenix.Prelude: [getAll] :: All -> Bool
+ Data.Git.Phoenix.Prelude: [getAlt] :: Alt (f :: k -> Type) (a :: k) -> f a
+ Data.Git.Phoenix.Prelude: [getAny] :: Any -> Bool
+ Data.Git.Phoenix.Prelude: [getAp] :: Ap (f :: k -> Type) (a :: k) -> f a
+ Data.Git.Phoenix.Prelude: [getComparison] :: Comparison a -> a -> a -> Ordering
+ Data.Git.Phoenix.Prelude: [getCompose] :: Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) -> f (g a)
+ Data.Git.Phoenix.Prelude: [getConst] :: Const a (b :: k) -> a
+ Data.Git.Phoenix.Prelude: [getDown] :: Down a -> a
+ Data.Git.Phoenix.Prelude: [getDual] :: Dual a -> a
+ Data.Git.Phoenix.Prelude: [getEquivalence] :: Equivalence a -> a -> a -> Bool
+ Data.Git.Phoenix.Prelude: [getFirst] :: First a -> Maybe a
+ Data.Git.Phoenix.Prelude: [getLast] :: Last a -> Maybe a
+ Data.Git.Phoenix.Prelude: [getOp] :: Op a b -> b -> a
+ Data.Git.Phoenix.Prelude: [getPredicate] :: Predicate a -> a -> Bool
+ Data.Git.Phoenix.Prelude: [getProduct] :: Product a -> a
+ Data.Git.Phoenix.Prelude: [getSum] :: Sum a -> a
+ Data.Git.Phoenix.Prelude: [getZipList] :: ZipList a -> [a]
+ Data.Git.Phoenix.Prelude: [runIdentity] :: Identity a -> a
+ Data.Git.Phoenix.Prelude: [runMaybeT] :: MaybeT (m :: Type -> Type) a -> m (Maybe a)
+ Data.Git.Phoenix.Prelude: [runReaderT] :: ReaderT r (m :: Type -> Type) a -> r -> m a
+ Data.Git.Phoenix.Prelude: [runStateT] :: StateT s (m :: Type -> Type) a -> s -> m (a, s)
+ Data.Git.Phoenix.Prelude: abs :: Num a => a -> a
+ Data.Git.Phoenix.Prelude: absurd :: Void -> a
+ Data.Git.Phoenix.Prelude: acos :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: acosh :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: all :: Foldable t => (a -> Bool) -> t a -> Bool
+ Data.Git.Phoenix.Prelude: allM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
+ Data.Git.Phoenix.Prelude: and :: Foldable t => t Bool -> Bool
+ Data.Git.Phoenix.Prelude: andM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
+ Data.Git.Phoenix.Prelude: any :: Foldable t => (a -> Bool) -> t a -> Bool
+ Data.Git.Phoenix.Prelude: anyM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
+ Data.Git.Phoenix.Prelude: appendFile :: MonadIO m => FilePath -> String -> m ()
+ Data.Git.Phoenix.Prelude: appendFileBS :: MonadIO m => FilePath -> ByteString -> m ()
+ Data.Git.Phoenix.Prelude: appendFileLBS :: MonadIO m => FilePath -> LByteString -> m ()
+ Data.Git.Phoenix.Prelude: appendFileLText :: MonadIO m => FilePath -> LText -> m ()
+ Data.Git.Phoenix.Prelude: appendFileText :: MonadIO m => FilePath -> Text -> m ()
+ Data.Git.Phoenix.Prelude: appliedTo :: Applicative f => f a -> f (a -> b) -> f b
+ Data.Git.Phoenix.Prelude: asTypeOf :: a -> a -> a
+ Data.Git.Phoenix.Prelude: asin :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: asinh :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: ask :: MonadReader r m => m r
+ Data.Git.Phoenix.Prelude: asks :: MonadReader r m => (r -> a) -> m a
+ Data.Git.Phoenix.Prelude: asum :: (Foldable t, Alternative f) => t (f a) -> f a
+ Data.Git.Phoenix.Prelude: asumMap :: forall b m f a. (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
+ Data.Git.Phoenix.Prelude: atan :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: atan2 :: RealFloat a => a -> a -> a
+ Data.Git.Phoenix.Prelude: atanh :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Data.Git.Phoenix.Prelude: atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Data.Git.Phoenix.Prelude: atomicModifyIORef'_ :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Data.Git.Phoenix.Prelude: atomicModifyIORef_ :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Data.Git.Phoenix.Prelude: atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()
+ Data.Git.Phoenix.Prelude: atomically :: MonadIO m => STM a -> m a
+ Data.Git.Phoenix.Prelude: backtraceDesired :: Exception e => e -> Bool
+ Data.Git.Phoenix.Prelude: biList :: Bifoldable t => t a a -> [a]
+ Data.Git.Phoenix.Prelude: biall :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
+ Data.Git.Phoenix.Prelude: biand :: Bifoldable t => t Bool Bool -> Bool
+ Data.Git.Phoenix.Prelude: biany :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
+ Data.Git.Phoenix.Prelude: biasum :: (Bifoldable t, Alternative f) => t (f a) (f a) -> f a
+ Data.Git.Phoenix.Prelude: bielem :: (Bifoldable t, Eq a) => a -> t a a -> Bool
+ Data.Git.Phoenix.Prelude: bifind :: Bifoldable t => (a -> Bool) -> t a a -> Maybe a
+ Data.Git.Phoenix.Prelude: bifold :: (Bifoldable p, Monoid m) => p m m -> m
+ Data.Git.Phoenix.Prelude: bifoldMap :: (Bifoldable p, Monoid m) => (a -> m) -> (b -> m) -> p a b -> m
+ Data.Git.Phoenix.Prelude: bifoldMapDefault :: (Bitraversable t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m
+ Data.Git.Phoenix.Prelude: bifoldl :: Bifoldable p => (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c
+ Data.Git.Phoenix.Prelude: bifoldl' :: Bifoldable t => (a -> b -> a) -> (a -> c -> a) -> a -> t b c -> a
+ Data.Git.Phoenix.Prelude: bifoldlM :: (Bifoldable t, Monad m) => (a -> b -> m a) -> (a -> c -> m a) -> a -> t b c -> m a
+ Data.Git.Phoenix.Prelude: bifoldr :: Bifoldable p => (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c
+ Data.Git.Phoenix.Prelude: bifoldr' :: Bifoldable t => (a -> c -> c) -> (b -> c -> c) -> c -> t a b -> c
+ Data.Git.Phoenix.Prelude: bifoldrM :: (Bifoldable t, Monad m) => (a -> c -> m c) -> (b -> c -> m c) -> c -> t a b -> m c
+ Data.Git.Phoenix.Prelude: bifor :: (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d)
+ Data.Git.Phoenix.Prelude: bifor_ :: (Bifoldable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f ()
+ Data.Git.Phoenix.Prelude: bilength :: Bifoldable t => t a b -> Int
+ Data.Git.Phoenix.Prelude: bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
+ Data.Git.Phoenix.Prelude: bimapDefault :: Bitraversable t => (a -> b) -> (c -> d) -> t a c -> t b d
+ Data.Git.Phoenix.Prelude: binull :: Bifoldable t => t a b -> Bool
+ Data.Git.Phoenix.Prelude: bior :: Bifoldable t => t Bool Bool -> Bool
+ Data.Git.Phoenix.Prelude: bisequence :: (Bitraversable t, Applicative f) => t (f a) (f b) -> f (t a b)
+ Data.Git.Phoenix.Prelude: bisequence_ :: (Bifoldable t, Applicative f) => t (f a) (f b) -> f ()
+ Data.Git.Phoenix.Prelude: bitraverse :: (Bitraversable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
+ Data.Git.Phoenix.Prelude: bitraverse_ :: (Bifoldable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f ()
+ Data.Git.Phoenix.Prelude: bool :: a -> a -> Bool -> a
+ Data.Git.Phoenix.Prelude: boundedEnumFrom :: (Enum a, Bounded a) => a -> [a]
+ Data.Git.Phoenix.Prelude: boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a]
+ Data.Git.Phoenix.Prelude: break :: (a -> Bool) -> [a] -> ([a], [a])
+ Data.Git.Phoenix.Prelude: bs2Scoped :: forall {k} a (s :: k). (LByteString -> a) -> Bs s -> Scoped s a
+ Data.Git.Phoenix.Prelude: bug :: (HasCallStack, Exception e) => e -> a
+ Data.Git.Phoenix.Prelude: byteSwap16 :: Word16 -> Word16
+ Data.Git.Phoenix.Prelude: byteSwap32 :: Word32 -> Word32
+ Data.Git.Phoenix.Prelude: byteSwap64 :: Word64 -> Word64
+ Data.Git.Phoenix.Prelude: callStack :: HasCallStack => CallStack
+ Data.Git.Phoenix.Prelude: catMaybes :: [Maybe a] -> [a]
+ Data.Git.Phoenix.Prelude: catchSTM :: Exception e => STM a -> (e -> STM a) -> STM a
+ Data.Git.Phoenix.Prelude: ceiling :: (RealFrac a, Integral b) => a -> b
+ Data.Git.Phoenix.Prelude: chainedTo :: Monad m => (a -> m b) -> m a -> m b
+ Data.Git.Phoenix.Prelude: chr :: Int -> Char
+ Data.Git.Phoenix.Prelude: class a ~# b => (a :: k) ~ (b :: k)
+ Data.Git.Phoenix.Prelude: class Applicative f => Alternative (f :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Functor f => Applicative (f :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Bifoldable (p :: Type -> Type -> Type)
+ Data.Git.Phoenix.Prelude: class forall a. () => Functor p a => Bifunctor (p :: Type -> Type -> Type)
+ Data.Git.Phoenix.Prelude: class (Bifunctor t, Bifoldable t) => Bitraversable (t :: Type -> Type -> Type)
+ Data.Git.Phoenix.Prelude: class Bounded a
+ Data.Git.Phoenix.Prelude: class a ~R# b => Coercible (a :: k) (b :: k)
+ Data.Git.Phoenix.Prelude: class Contravariant (f :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class ConvertUtf8 a b
+ Data.Git.Phoenix.Prelude: class Enum a
+ Data.Git.Phoenix.Prelude: class Eq a
+ Data.Git.Phoenix.Prelude: class (Typeable e, Show e) => Exception e
+ Data.Git.Phoenix.Prelude: class Fractional a => Floating a
+ Data.Git.Phoenix.Prelude: class Foldable (t :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Num a => Fractional a
+ Data.Git.Phoenix.Prelude: class Functor (f :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Generic a
+ Data.Git.Phoenix.Prelude: class Eq a => Hashable a
+ Data.Git.Phoenix.Prelude: class (Real a, Enum a) => Integral a
+ Data.Git.Phoenix.Prelude: class IsLabel (x :: Symbol) a
+ Data.Git.Phoenix.Prelude: class IsList l
+ Data.Git.Phoenix.Prelude: class IsString a
+ Data.Git.Phoenix.Prelude: class KnownNat (n :: Nat)
+ Data.Git.Phoenix.Prelude: class LazyStrict l s | l -> s, s -> l
+ Data.Git.Phoenix.Prelude: class Applicative m => Monad (m :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Monad m => MonadFail (m :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Monad m => MonadIO (m :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Monad m => MonadReader r (m :: Type -> Type) | m -> r
+ Data.Git.Phoenix.Prelude: class Monad m => MonadState s (m :: Type -> Type) | m -> s
+ Data.Git.Phoenix.Prelude: class forall (m :: Type -> Type). Monad m => Monad t m => MonadTrans (t :: Type -> Type -> Type -> Type)
+ Data.Git.Phoenix.Prelude: class Semigroup a => Monoid a
+ Data.Git.Phoenix.Prelude: class Num a
+ Data.Git.Phoenix.Prelude: class One x where {
+ Data.Git.Phoenix.Prelude: class Eq a => Ord a
+ Data.Git.Phoenix.Prelude: class Read a
+ Data.Git.Phoenix.Prelude: class (Num a, Ord a) => Real a
+ Data.Git.Phoenix.Prelude: class (RealFrac a, Floating a) => RealFloat a
+ Data.Git.Phoenix.Prelude: class (Real a, Fractional a) => RealFrac a
+ Data.Git.Phoenix.Prelude: class Semigroup a
+ Data.Git.Phoenix.Prelude: class Show a
+ Data.Git.Phoenix.Prelude: class ToLText a
+ Data.Git.Phoenix.Prelude: class ToString a
+ Data.Git.Phoenix.Prelude: class ToText a
+ Data.Git.Phoenix.Prelude: class (Functor t, Foldable t) => Traversable (t :: Type -> Type)
+ Data.Git.Phoenix.Prelude: class Typeable (a :: k)
+ Data.Git.Phoenix.Prelude: coerce :: Coercible a b => a -> b
+ Data.Git.Phoenix.Prelude: compare :: Ord a => a -> a -> Ordering
+ Data.Git.Phoenix.Prelude: comparing :: Ord a => (b -> a) -> b -> b -> Ordering
+ Data.Git.Phoenix.Prelude: comparisonEquivalence :: Comparison a -> Equivalence a
+ Data.Git.Phoenix.Prelude: concat :: Foldable t => t [a] -> [a]
+ Data.Git.Phoenix.Prelude: concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
+ Data.Git.Phoenix.Prelude: condM :: forall {k1} {k2} (s :: k1) m (a :: k2). [(Scoped s Bool, m a)] -> m a -> m a
+ Data.Git.Phoenix.Prelude: const :: a -> b -> a
+ Data.Git.Phoenix.Prelude: contramap :: Contravariant f => (a' -> a) -> f a -> f a'
+ Data.Git.Phoenix.Prelude: cos :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: cosh :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: currentCallStack :: IO [String]
+ Data.Git.Phoenix.Prelude: curry :: ((a, b) -> c) -> a -> b -> c
+ Data.Git.Phoenix.Prelude: cycle :: [a] -> [a]
+ Data.Git.Phoenix.Prelude: cycle1 :: Semigroup m => m -> m
+ Data.Git.Phoenix.Prelude: data Bool
+ Data.Git.Phoenix.Prelude: data BufferMode
+ Data.Git.Phoenix.Prelude: data Bug
+ Data.Git.Phoenix.Prelude: data ByteString
+ Data.Git.Phoenix.Prelude: data CallStack
+ Data.Git.Phoenix.Prelude: data Char
+ Data.Git.Phoenix.Prelude: data Double
+ Data.Git.Phoenix.Prelude: data Either a b
+ Data.Git.Phoenix.Prelude: data Float
+ Data.Git.Phoenix.Prelude: data HashMap k v
+ Data.Git.Phoenix.Prelude: data HashSet a
+ Data.Git.Phoenix.Prelude: data IO a
+ Data.Git.Phoenix.Prelude: data IOMode
+ Data.Git.Phoenix.Prelude: data IORef a
+ Data.Git.Phoenix.Prelude: data IdentityT (f :: k -> Type) (a :: k)
+ Data.Git.Phoenix.Prelude: data Int
+ Data.Git.Phoenix.Prelude: data Int16
+ Data.Git.Phoenix.Prelude: data Int32
+ Data.Git.Phoenix.Prelude: data Int64
+ Data.Git.Phoenix.Prelude: data Int8
+ Data.Git.Phoenix.Prelude: data IntMap a
+ Data.Git.Phoenix.Prelude: data IntSet
+ Data.Git.Phoenix.Prelude: data Integer
+ Data.Git.Phoenix.Prelude: data LazyT (s :: k) (m :: k1 -> Type) (a :: k1)
+ Data.Git.Phoenix.Prelude: data MVar a
+ Data.Git.Phoenix.Prelude: data Map k a
+ Data.Git.Phoenix.Prelude: data Maybe a
+ Data.Git.Phoenix.Prelude: data Natural
+ Data.Git.Phoenix.Prelude: data NonEmpty a
+ Data.Git.Phoenix.Prelude: data Ordering
+ Data.Git.Phoenix.Prelude: data Proxy (t :: k)
+ Data.Git.Phoenix.Prelude: data Ratio a
+ Data.Git.Phoenix.Prelude: data STM a
+ Data.Git.Phoenix.Prelude: data Scoped (s :: k) a
+ Data.Git.Phoenix.Prelude: data Seq a
+ Data.Git.Phoenix.Prelude: data Set a
+ Data.Git.Phoenix.Prelude: data ShortByteString
+ Data.Git.Phoenix.Prelude: data SomeException
+ Data.Git.Phoenix.Prelude: data SomeNat
+ Data.Git.Phoenix.Prelude: data TMVar a
+ Data.Git.Phoenix.Prelude: data TVar a
+ Data.Git.Phoenix.Prelude: data Text
+ Data.Git.Phoenix.Prelude: data Undefined
+ Data.Git.Phoenix.Prelude: data UnicodeException
+ Data.Git.Phoenix.Prelude: data Void
+ Data.Git.Phoenix.Prelude: data Word
+ Data.Git.Phoenix.Prelude: data Word16
+ Data.Git.Phoenix.Prelude: data Word32
+ Data.Git.Phoenix.Prelude: data Word64
+ Data.Git.Phoenix.Prelude: data Word8
+ Data.Git.Phoenix.Prelude: data WrappedMonoid m
+ Data.Git.Phoenix.Prelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
+ Data.Git.Phoenix.Prelude: decodeUtf8 :: ConvertUtf8 a b => b -> a
+ Data.Git.Phoenix.Prelude: decodeUtf8' :: ByteString -> Either UnicodeException Text
+ Data.Git.Phoenix.Prelude: decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a
+ Data.Git.Phoenix.Prelude: decodeUtf8With :: OnDecodeError -> ByteString -> Text
+ Data.Git.Phoenix.Prelude: defaultComparison :: Ord a => Comparison a
+ Data.Git.Phoenix.Prelude: defaultEquivalence :: Eq a => Equivalence a
+ Data.Git.Phoenix.Prelude: denominator :: Ratio a -> a
+ Data.Git.Phoenix.Prelude: die :: MonadIO m => String -> m a
+ Data.Git.Phoenix.Prelude: displayException :: Exception e => e -> String
+ Data.Git.Phoenix.Prelude: div :: Integral a => a -> a -> a
+ Data.Git.Phoenix.Prelude: divMod :: Integral a => a -> a -> (a, a)
+ Data.Git.Phoenix.Prelude: drop :: Int -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: dropWhile :: (a -> Bool) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: either :: (a -> c) -> (b -> c) -> Either a b -> c
+ Data.Git.Phoenix.Prelude: elem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool
+ Data.Git.Phoenix.Prelude: empty :: Alternative f => f a
+ Data.Git.Phoenix.Prelude: encodeFloat :: RealFloat a => Integer -> Int -> a
+ Data.Git.Phoenix.Prelude: encodeUtf8 :: ConvertUtf8 a b => a -> b
+ Data.Git.Phoenix.Prelude: enumFrom :: Enum a => a -> [a]
+ Data.Git.Phoenix.Prelude: enumFromThen :: Enum a => a -> a -> [a]
+ Data.Git.Phoenix.Prelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
+ Data.Git.Phoenix.Prelude: enumFromTo :: Enum a => a -> a -> [a]
+ Data.Git.Phoenix.Prelude: error :: forall a t. (HasCallStack, IsText t) => t -> a
+ Data.Git.Phoenix.Prelude: etaReaderT :: forall r (m :: Type -> Type) a. ReaderT r m a -> ReaderT r m a
+ Data.Git.Phoenix.Prelude: evalState :: State s a -> s -> a
+ Data.Git.Phoenix.Prelude: evalStateT :: Monad m => StateT s m a -> s -> m a
+ Data.Git.Phoenix.Prelude: evaluateNF :: (NFData a, MonadIO m) => a -> m a
+ Data.Git.Phoenix.Prelude: evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
+ Data.Git.Phoenix.Prelude: evaluateWHNF :: MonadIO m => a -> m a
+ Data.Git.Phoenix.Prelude: evaluateWHNF_ :: MonadIO m => a -> m ()
+ Data.Git.Phoenix.Prelude: evaluatingState :: s -> State s a -> a
+ Data.Git.Phoenix.Prelude: evaluatingStateT :: Functor f => s -> StateT s f a -> f a
+ Data.Git.Phoenix.Prelude: even :: Integral a => a -> Bool
+ Data.Git.Phoenix.Prelude: exceptToMaybeT :: forall (m :: Type -> Type) e a. Functor m => ExceptT e m a -> MaybeT m a
+ Data.Git.Phoenix.Prelude: execState :: State s a -> s -> s
+ Data.Git.Phoenix.Prelude: execStateT :: Monad m => StateT s m a -> s -> m s
+ Data.Git.Phoenix.Prelude: executingState :: s -> State s a -> s
+ Data.Git.Phoenix.Prelude: executingStateT :: Functor f => s -> StateT s f a -> f s
+ Data.Git.Phoenix.Prelude: exitFailure :: MonadIO m => m a
+ Data.Git.Phoenix.Prelude: exitSuccess :: MonadIO m => m a
+ Data.Git.Phoenix.Prelude: exitWith :: MonadIO m => ExitCode -> m a
+ Data.Git.Phoenix.Prelude: exp :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: fail :: MonadFail m => String -> m a
+ Data.Git.Phoenix.Prelude: filter :: (a -> Bool) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
+ Data.Git.Phoenix.Prelude: find :: Foldable t => (a -> Bool) -> t a -> Maybe a
+ Data.Git.Phoenix.Prelude: first :: Bifunctor p => (a -> b) -> p a c -> p b c
+ Data.Git.Phoenix.Prelude: fix :: (a -> a) -> a
+ Data.Git.Phoenix.Prelude: flap :: Functor f => f (a -> b) -> a -> f b
+ Data.Git.Phoenix.Prelude: flip :: (a -> b -> c) -> b -> a -> c
+ Data.Git.Phoenix.Prelude: flipfoldl' :: Foldable f => (a -> b -> b) -> b -> f a -> b
+ Data.Git.Phoenix.Prelude: floatDigits :: RealFloat a => a -> Int
+ Data.Git.Phoenix.Prelude: floatRadix :: RealFloat a => a -> Integer
+ Data.Git.Phoenix.Prelude: floatRange :: RealFloat a => a -> (Int, Int)
+ Data.Git.Phoenix.Prelude: floor :: (RealFrac a, Integral b) => a -> b
+ Data.Git.Phoenix.Prelude: fmap :: Functor f => (a -> b) -> f a -> f b
+ Data.Git.Phoenix.Prelude: fold :: (Foldable t, Monoid m) => t m -> m
+ Data.Git.Phoenix.Prelude: foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Data.Git.Phoenix.Prelude: foldMap' :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Data.Git.Phoenix.Prelude: foldMapA :: (Semigroup b, Monoid b, Applicative m, Foldable f) => (a -> m b) -> f a -> m b
+ Data.Git.Phoenix.Prelude: foldMapM :: (Monoid b, Monad m, Foldable f) => (a -> m b) -> f a -> m b
+ Data.Git.Phoenix.Prelude: foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b
+ Data.Git.Phoenix.Prelude: foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
+ Data.Git.Phoenix.Prelude: foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
+ Data.Git.Phoenix.Prelude: forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
+ Data.Git.Phoenix.Prelude: forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
+ Data.Git.Phoenix.Prelude: for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()
+ Data.Git.Phoenix.Prelude: forever :: Applicative f => f a -> f b
+ Data.Git.Phoenix.Prelude: fromEnum :: Enum a => a -> Int
+ Data.Git.Phoenix.Prelude: fromException :: Exception e => SomeException -> Maybe e
+ Data.Git.Phoenix.Prelude: fromInteger :: Num a => Integer -> a
+ Data.Git.Phoenix.Prelude: fromIntegral :: (Integral a, Num b) => a -> b
+ Data.Git.Phoenix.Prelude: fromLabel :: IsLabel x a => a
+ Data.Git.Phoenix.Prelude: fromLazy :: LazyStrict l s => l -> s
+ Data.Git.Phoenix.Prelude: fromLeft :: a -> Either a b -> a
+ Data.Git.Phoenix.Prelude: fromList :: IsList l => [Item l] -> l
+ Data.Git.Phoenix.Prelude: fromListN :: IsList l => Int -> [Item l] -> l
+ Data.Git.Phoenix.Prelude: fromMaybe :: a -> Maybe a -> a
+ Data.Git.Phoenix.Prelude: fromRational :: Fractional a => Rational -> a
+ Data.Git.Phoenix.Prelude: fromRight :: b -> Either a b -> b
+ Data.Git.Phoenix.Prelude: fromShort :: ShortByteString -> ByteString
+ Data.Git.Phoenix.Prelude: fromStrict :: LazyStrict l s => s -> l
+ Data.Git.Phoenix.Prelude: fromString :: IsString a => String -> a
+ Data.Git.Phoenix.Prelude: fst :: (a, b) -> a
+ Data.Git.Phoenix.Prelude: gcd :: Integral a => a -> a -> a
+ Data.Git.Phoenix.Prelude: genericDrop :: Integral i => i -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: genericLength :: Num i => [a] -> i
+ Data.Git.Phoenix.Prelude: genericReplicate :: Integral i => i -> a -> [a]
+ Data.Git.Phoenix.Prelude: genericSplitAt :: Integral i => i -> [a] -> ([a], [a])
+ Data.Git.Phoenix.Prelude: genericTake :: Integral i => i -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: get :: MonadState s m => m s
+ Data.Git.Phoenix.Prelude: getArgs :: MonadIO m => m [String]
+ Data.Git.Phoenix.Prelude: getCallStack :: CallStack -> [([Char], SrcLoc)]
+ Data.Git.Phoenix.Prelude: getLine :: MonadIO m => m Text
+ Data.Git.Phoenix.Prelude: getStackTrace :: IO (Maybe [Location])
+ Data.Git.Phoenix.Prelude: gets :: MonadState s m => (s -> a) -> m a
+ Data.Git.Phoenix.Prelude: group :: Eq a => [a] -> [[a]]
+ Data.Git.Phoenix.Prelude: guard :: Alternative f => Bool -> f ()
+ Data.Git.Phoenix.Prelude: guardM :: MonadPlus m => m Bool -> m ()
+ Data.Git.Phoenix.Prelude: guarded :: Alternative f => (a -> Bool) -> a -> f a
+ Data.Git.Phoenix.Prelude: hFlush :: MonadIO m => Handle -> m ()
+ Data.Git.Phoenix.Prelude: hGetBuffering :: MonadIO m => Handle -> m BufferMode
+ Data.Git.Phoenix.Prelude: hIsEOF :: MonadIO m => Handle -> m Bool
+ Data.Git.Phoenix.Prelude: hSetBuffering :: MonadIO m => Handle -> BufferMode -> m ()
+ Data.Git.Phoenix.Prelude: hashNub :: Hashable a => [a] -> [a]
+ Data.Git.Phoenix.Prelude: hashWithSalt :: Hashable a => Int -> a -> Int
+ Data.Git.Phoenix.Prelude: head :: IsNonEmpty f a a "head" => f a -> a
+ Data.Git.Phoenix.Prelude: hoistEither :: forall (m :: Type -> Type) e a. Applicative m => Either e a -> ExceptT e m a
+ Data.Git.Phoenix.Prelude: hoistMaybe :: forall (m :: Type -> Type) a. Applicative m => Maybe a -> MaybeT m a
+ Data.Git.Phoenix.Prelude: id :: a -> a
+ Data.Git.Phoenix.Prelude: identity :: a -> a
+ Data.Git.Phoenix.Prelude: ifM :: Monad m => m Bool -> m a -> m a -> m a
+ Data.Git.Phoenix.Prelude: infinitely :: Applicative f => f a -> f Void
+ Data.Git.Phoenix.Prelude: infix 4 ~
+ Data.Git.Phoenix.Prelude: infix 9 !!?
+ Data.Git.Phoenix.Prelude: infixl 0 `hashWithSalt`
+ Data.Git.Phoenix.Prelude: infixl 1 >>
+ Data.Git.Phoenix.Prelude: infixl 3 <|>
+ Data.Git.Phoenix.Prelude: infixl 4 <$
+ Data.Git.Phoenix.Prelude: infixl 6 +
+ Data.Git.Phoenix.Prelude: infixl 7 `mod`
+ Data.Git.Phoenix.Prelude: infixr 0 `seq`
+ Data.Git.Phoenix.Prelude: infixr 1 >=>
+ Data.Git.Phoenix.Prelude: infixr 3 &&&
+ Data.Git.Phoenix.Prelude: infixr 6 <>
+ Data.Git.Phoenix.Prelude: infixr 8 **
+ Data.Git.Phoenix.Prelude: infixr 9 `Compose`
+ Data.Git.Phoenix.Prelude: init :: IsNonEmpty f a [a] "init" => f a -> [a]
+ Data.Git.Phoenix.Prelude: inits :: [a] -> [[a]]
+ Data.Git.Phoenix.Prelude: intNub :: [Int] -> [Int]
+ Data.Git.Phoenix.Prelude: intNubOn :: (a -> Int) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: integerToBounded :: (Integral a, Bounded a) => Integer -> Maybe a
+ Data.Git.Phoenix.Prelude: integerToNatural :: Integer -> Maybe Natural
+ Data.Git.Phoenix.Prelude: intercalate :: [a] -> [[a]] -> [a]
+ Data.Git.Phoenix.Prelude: intersperse :: a -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: inverseMap :: (Bounded a, Enum a, Ord k) => (a -> k) -> k -> Maybe a
+ Data.Git.Phoenix.Prelude: isDenormalized :: RealFloat a => a -> Bool
+ Data.Git.Phoenix.Prelude: isEmptyTMVar :: TMVar a -> STM Bool
+ Data.Git.Phoenix.Prelude: isIEEE :: RealFloat a => a -> Bool
+ Data.Git.Phoenix.Prelude: isInfinite :: RealFloat a => a -> Bool
+ Data.Git.Phoenix.Prelude: isJust :: Maybe a -> Bool
+ Data.Git.Phoenix.Prelude: isLeft :: Either a b -> Bool
+ Data.Git.Phoenix.Prelude: isNaN :: RealFloat a => a -> Bool
+ Data.Git.Phoenix.Prelude: isNegativeZero :: RealFloat a => a -> Bool
+ Data.Git.Phoenix.Prelude: isNothing :: Maybe a -> Bool
+ Data.Git.Phoenix.Prelude: isPrefixOf :: Eq a => [a] -> [a] -> Bool
+ Data.Git.Phoenix.Prelude: isRight :: Either a b -> Bool
+ Data.Git.Phoenix.Prelude: iterate :: (a -> a) -> a -> [a]
+ Data.Git.Phoenix.Prelude: join :: Monad m => m (m a) -> m a
+ Data.Git.Phoenix.Prelude: last :: IsNonEmpty f a a "last" => f a -> a
+ Data.Git.Phoenix.Prelude: lcm :: Integral a => a -> a -> a
+ Data.Git.Phoenix.Prelude: leftToMaybe :: Either l r -> Maybe l
+ Data.Git.Phoenix.Prelude: lefts :: [Either a b] -> [a]
+ Data.Git.Phoenix.Prelude: length :: Foldable t => t a -> Int
+ Data.Git.Phoenix.Prelude: lenientDecode :: OnDecodeError
+ Data.Git.Phoenix.Prelude: lift :: (MonadTrans t, Monad m) => m a -> t m a
+ Data.Git.Phoenix.Prelude: liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
+ Data.Git.Phoenix.Prelude: liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
+ Data.Git.Phoenix.Prelude: liftIO :: MonadIO m => IO a -> m a
+ Data.Git.Phoenix.Prelude: lines :: IsText t "lines" => t -> [t]
+ Data.Git.Phoenix.Prelude: listToMaybe :: [a] -> Maybe a
+ Data.Git.Phoenix.Prelude: local :: MonadReader r m => (r -> r) -> m a -> m a
+ Data.Git.Phoenix.Prelude: logBase :: Floating a => a -> a -> a
+ Data.Git.Phoenix.Prelude: lookupEnv :: MonadIO m => String -> m (Maybe String)
+ Data.Git.Phoenix.Prelude: many :: Alternative f => f a -> f [a]
+ Data.Git.Phoenix.Prelude: map :: (a -> b) -> [a] -> [b]
+ Data.Git.Phoenix.Prelude: mapAccumL :: Traversable t => (s -> a -> (s, b)) -> s -> t a -> (s, t b)
+ Data.Git.Phoenix.Prelude: mapAccumR :: Traversable t => (s -> a -> (s, b)) -> s -> t a -> (s, t b)
+ Data.Git.Phoenix.Prelude: mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c])
+ Data.Git.Phoenix.Prelude: mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
+ Data.Git.Phoenix.Prelude: mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
+ Data.Git.Phoenix.Prelude: mapMaybe :: (a -> Maybe b) -> [a] -> [b]
+ Data.Git.Phoenix.Prelude: mapMaybeM :: Monad m => (a -> m (Maybe b)) -> [a] -> m [b]
+ Data.Git.Phoenix.Prelude: mappend :: Monoid a => a -> a -> a
+ Data.Git.Phoenix.Prelude: max :: Ord a => a -> a -> a
+ Data.Git.Phoenix.Prelude: maxBound :: Bounded a => a
+ Data.Git.Phoenix.Prelude: maxInt :: Int
+ Data.Git.Phoenix.Prelude: maybe :: b -> (a -> b) -> Maybe a -> b
+ Data.Git.Phoenix.Prelude: maybeAt :: Int -> [a] -> Maybe a
+ Data.Git.Phoenix.Prelude: maybeToExceptT :: forall (m :: Type -> Type) e a. Functor m => e -> MaybeT m a -> ExceptT e m a
+ Data.Git.Phoenix.Prelude: maybeToLeft :: r -> Maybe l -> Either l r
+ Data.Git.Phoenix.Prelude: maybeToList :: Maybe a -> [a]
+ Data.Git.Phoenix.Prelude: maybeToMonoid :: Monoid m => Maybe m -> m
+ Data.Git.Phoenix.Prelude: maybeToRight :: l -> Maybe r -> Either l r
+ Data.Git.Phoenix.Prelude: mconcat :: Monoid a => [a] -> a
+ Data.Git.Phoenix.Prelude: mempty :: Monoid a => a
+ Data.Git.Phoenix.Prelude: memptyIfFalse :: Monoid m => Bool -> m -> m
+ Data.Git.Phoenix.Prelude: memptyIfTrue :: Monoid m => Bool -> m -> m
+ Data.Git.Phoenix.Prelude: mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
+ Data.Git.Phoenix.Prelude: min :: Ord a => a -> a -> a
+ Data.Git.Phoenix.Prelude: minBound :: Bounded a => a
+ Data.Git.Phoenix.Prelude: minInt :: Int
+ Data.Git.Phoenix.Prelude: mkWeakTMVar :: TMVar a -> IO () -> IO (Weak (TMVar a))
+ Data.Git.Phoenix.Prelude: mod :: Integral a => a -> a -> a
+ Data.Git.Phoenix.Prelude: modify :: MonadState s m => (s -> s) -> m ()
+ Data.Git.Phoenix.Prelude: modify' :: MonadState s m => (s -> s) -> m ()
+ Data.Git.Phoenix.Prelude: modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Data.Git.Phoenix.Prelude: modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Data.Git.Phoenix.Prelude: modifyTVar' :: TVar a -> (a -> a) -> STM ()
+ Data.Git.Phoenix.Prelude: mplus :: MonadPlus m => m a -> m a -> m a
+ Data.Git.Phoenix.Prelude: mtimesDefault :: (Integral b, Monoid a) => b -> a -> a
+ Data.Git.Phoenix.Prelude: mzero :: MonadPlus m => m a
+ Data.Git.Phoenix.Prelude: natVal :: forall (n :: Nat) proxy. KnownNat n => proxy n -> Natural
+ Data.Git.Phoenix.Prelude: negate :: Num a => a -> a
+ Data.Git.Phoenix.Prelude: newEmptyMVar :: MonadIO m => m (MVar a)
+ Data.Git.Phoenix.Prelude: newEmptyTMVar :: STM (TMVar a)
+ Data.Git.Phoenix.Prelude: newEmptyTMVarIO :: MonadIO m => m (TMVar a)
+ Data.Git.Phoenix.Prelude: newIORef :: MonadIO m => a -> m (IORef a)
+ Data.Git.Phoenix.Prelude: newMVar :: MonadIO m => a -> m (MVar a)
+ Data.Git.Phoenix.Prelude: newTMVar :: a -> STM (TMVar a)
+ Data.Git.Phoenix.Prelude: newTMVarIO :: MonadIO m => a -> m (TMVar a)
+ Data.Git.Phoenix.Prelude: newTVar :: a -> STM (TVar a)
+ Data.Git.Phoenix.Prelude: newTVarIO :: MonadIO m => a -> m (TVar a)
+ Data.Git.Phoenix.Prelude: newtype All
+ Data.Git.Phoenix.Prelude: newtype Alt (f :: k -> Type) (a :: k)
+ Data.Git.Phoenix.Prelude: newtype Any
+ Data.Git.Phoenix.Prelude: newtype Ap (f :: k -> Type) (a :: k)
+ Data.Git.Phoenix.Prelude: newtype Comparison a
+ Data.Git.Phoenix.Prelude: newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1)
+ Data.Git.Phoenix.Prelude: newtype Const a (b :: k)
+ Data.Git.Phoenix.Prelude: newtype Down a
+ Data.Git.Phoenix.Prelude: newtype Dual a
+ Data.Git.Phoenix.Prelude: newtype Endo a
+ Data.Git.Phoenix.Prelude: newtype Equivalence a
+ Data.Git.Phoenix.Prelude: newtype ExceptT e (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: newtype First a
+ Data.Git.Phoenix.Prelude: newtype Identity a
+ Data.Git.Phoenix.Prelude: newtype Last a
+ Data.Git.Phoenix.Prelude: newtype MaybeT (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: newtype Op a b
+ Data.Git.Phoenix.Prelude: newtype Predicate a
+ Data.Git.Phoenix.Prelude: newtype Product a
+ Data.Git.Phoenix.Prelude: newtype ReaderT r (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: newtype StateT s (m :: Type -> Type) a
+ Data.Git.Phoenix.Prelude: newtype Sum a
+ Data.Git.Phoenix.Prelude: newtype ZipList a
+ Data.Git.Phoenix.Prelude: nonEmpty :: [a] -> Maybe (NonEmpty a)
+ Data.Git.Phoenix.Prelude: not :: Bool -> Bool
+ Data.Git.Phoenix.Prelude: notElem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool
+ Data.Git.Phoenix.Prelude: null :: Foldable t => t a -> Bool
+ Data.Git.Phoenix.Prelude: numerator :: Ratio a -> a
+ Data.Git.Phoenix.Prelude: odd :: Integral a => a -> Bool
+ Data.Git.Phoenix.Prelude: on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
+ Data.Git.Phoenix.Prelude: one :: One x => OneItem x -> x
+ Data.Git.Phoenix.Prelude: optional :: Alternative f => f a -> f (Maybe a)
+ Data.Git.Phoenix.Prelude: or :: Foldable t => t Bool -> Bool
+ Data.Git.Phoenix.Prelude: orM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
+ Data.Git.Phoenix.Prelude: ord :: Char -> Int
+ Data.Git.Phoenix.Prelude: ordNub :: Ord a => [a] -> [a]
+ Data.Git.Phoenix.Prelude: ordNubOn :: Ord b => (a -> b) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: otherwise :: Bool
+ Data.Git.Phoenix.Prelude: partitionEithers :: [Either a b] -> ([a], [b])
+ Data.Git.Phoenix.Prelude: partitionWith :: (a -> Either b c) -> [a] -> ([b], [c])
+ Data.Git.Phoenix.Prelude: pass :: Applicative f => f ()
+ Data.Git.Phoenix.Prelude: pattern Exc :: Exception e => e -> SomeException
+ Data.Git.Phoenix.Prelude: permutations :: [a] -> [[a]]
+ Data.Git.Phoenix.Prelude: phantom :: (Functor f, Contravariant f) => f a -> f b
+ Data.Git.Phoenix.Prelude: pi :: Floating a => a
+ Data.Git.Phoenix.Prelude: pred :: Enum a => a -> a
+ Data.Git.Phoenix.Prelude: prettyCallStack :: CallStack -> String
+ Data.Git.Phoenix.Prelude: prettySrcLoc :: SrcLoc -> String
+ Data.Git.Phoenix.Prelude: print :: forall a m. (MonadIO m, Show a) => a -> m ()
+ Data.Git.Phoenix.Prelude: product :: forall a f. (Foldable f, Num a) => f a -> a
+ Data.Git.Phoenix.Prelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
+ Data.Git.Phoenix.Prelude: pure :: Applicative f => a -> f a
+ Data.Git.Phoenix.Prelude: put :: MonadState s m => s -> m ()
+ Data.Git.Phoenix.Prelude: putBS :: MonadIO m => ByteString -> m ()
+ Data.Git.Phoenix.Prelude: putBSLn :: MonadIO m => ByteString -> m ()
+ Data.Git.Phoenix.Prelude: putLBS :: MonadIO m => LByteString -> m ()
+ Data.Git.Phoenix.Prelude: putLBSLn :: MonadIO m => LByteString -> m ()
+ Data.Git.Phoenix.Prelude: putLText :: MonadIO m => LText -> m ()
+ Data.Git.Phoenix.Prelude: putLTextLn :: MonadIO m => LText -> m ()
+ Data.Git.Phoenix.Prelude: putMVar :: MonadIO m => MVar a -> a -> m ()
+ Data.Git.Phoenix.Prelude: putStr :: MonadIO m => String -> m ()
+ Data.Git.Phoenix.Prelude: putStrLn :: MonadIO m => String -> m ()
+ Data.Git.Phoenix.Prelude: putTMVar :: TMVar a -> a -> STM ()
+ Data.Git.Phoenix.Prelude: putText :: MonadIO m => Text -> m ()
+ Data.Git.Phoenix.Prelude: putTextLn :: MonadIO m => Text -> m ()
+ Data.Git.Phoenix.Prelude: quot :: Integral a => a -> a -> a
+ Data.Git.Phoenix.Prelude: quotRem :: Integral a => a -> a -> (a, a)
+ Data.Git.Phoenix.Prelude: readEither :: Read a => String -> Either Text a
+ Data.Git.Phoenix.Prelude: readFile :: MonadIO m => FilePath -> m String
+ Data.Git.Phoenix.Prelude: readFile' :: MonadIO m => FilePath -> m String
+ Data.Git.Phoenix.Prelude: readFileBS :: MonadIO m => FilePath -> m ByteString
+ Data.Git.Phoenix.Prelude: readFileLBS :: MonadIO m => FilePath -> m LByteString
+ Data.Git.Phoenix.Prelude: readFileLText :: MonadIO m => FilePath -> m LText
+ Data.Git.Phoenix.Prelude: readFileText :: MonadIO m => FilePath -> m Text
+ Data.Git.Phoenix.Prelude: readIORef :: MonadIO m => IORef a -> m a
+ Data.Git.Phoenix.Prelude: readMVar :: MonadIO m => MVar a -> m a
+ Data.Git.Phoenix.Prelude: readMaybe :: Read a => String -> Maybe a
+ Data.Git.Phoenix.Prelude: readTMVar :: TMVar a -> STM a
+ Data.Git.Phoenix.Prelude: readTVar :: TVar a -> STM a
+ Data.Git.Phoenix.Prelude: readTVarIO :: MonadIO m => TVar a -> m a
+ Data.Git.Phoenix.Prelude: reader :: MonadReader r m => (r -> a) -> m a
+ Data.Git.Phoenix.Prelude: reads :: Read a => ReadS a
+ Data.Git.Phoenix.Prelude: realToFrac :: (Real a, Fractional b) => a -> b
+ Data.Git.Phoenix.Prelude: recip :: Fractional a => a -> a
+ Data.Git.Phoenix.Prelude: rem :: Integral a => a -> a -> a
+ Data.Git.Phoenix.Prelude: repeat :: a -> [a]
+ Data.Git.Phoenix.Prelude: replicate :: Int -> a -> [a]
+ Data.Git.Phoenix.Prelude: replicateM :: Applicative m => Int -> m a -> m [a]
+ Data.Git.Phoenix.Prelude: replicateM_ :: Applicative m => Int -> m a -> m ()
+ Data.Git.Phoenix.Prelude: return :: Monad m => a -> m a
+ Data.Git.Phoenix.Prelude: reverse :: [a] -> [a]
+ Data.Git.Phoenix.Prelude: rightToMaybe :: Either l r -> Maybe r
+ Data.Git.Phoenix.Prelude: rights :: [Either a b] -> [b]
+ Data.Git.Phoenix.Prelude: round :: (RealFrac a, Integral b) => a -> b
+ Data.Git.Phoenix.Prelude: runExceptT :: ExceptT e m a -> m (Either e a)
+ Data.Git.Phoenix.Prelude: runReader :: Reader r a -> r -> a
+ Data.Git.Phoenix.Prelude: runState :: State s a -> s -> (a, s)
+ Data.Git.Phoenix.Prelude: scanl :: (b -> a -> b) -> b -> [a] -> [b]
+ Data.Git.Phoenix.Prelude: scanl' :: (b -> a -> b) -> b -> [a] -> [b]
+ Data.Git.Phoenix.Prelude: scanl1 :: (a -> a -> a) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: scanr :: (a -> b -> b) -> b -> [a] -> [b]
+ Data.Git.Phoenix.Prelude: scanr1 :: (a -> a -> a) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: sconcat :: Semigroup a => NonEmpty a -> a
+ Data.Git.Phoenix.Prelude: second :: Bifunctor p => (b -> c) -> p a b -> p a c
+ Data.Git.Phoenix.Prelude: seq :: a -> b -> b
+ Data.Git.Phoenix.Prelude: sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
+ Data.Git.Phoenix.Prelude: sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
+ Data.Git.Phoenix.Prelude: sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
+ Data.Git.Phoenix.Prelude: sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
+ Data.Git.Phoenix.Prelude: show :: forall b a. (Show a, IsString b) => a -> b
+ Data.Git.Phoenix.Prelude: showStackTrace :: IO (Maybe String)
+ Data.Git.Phoenix.Prelude: signum :: Num a => a -> a
+ Data.Git.Phoenix.Prelude: sin :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: sinh :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: snd :: (a, b) -> b
+ Data.Git.Phoenix.Prelude: some :: Alternative f => f a -> f [a]
+ Data.Git.Phoenix.Prelude: someNatVal :: Natural -> SomeNat
+ Data.Git.Phoenix.Prelude: sort :: Ord a => [a] -> [a]
+ Data.Git.Phoenix.Prelude: sortBy :: (a -> a -> Ordering) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: sortNub :: Ord a => [a] -> [a]
+ Data.Git.Phoenix.Prelude: sortOn :: Ord b => (a -> b) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: sortWith :: Ord b => (a -> b) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: span :: (a -> Bool) -> [a] -> ([a], [a])
+ Data.Git.Phoenix.Prelude: splitAt :: Int -> [a] -> ([a], [a])
+ Data.Git.Phoenix.Prelude: sqrt :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: state :: MonadState s m => (s -> (a, s)) -> m a
+ Data.Git.Phoenix.Prelude: stderr :: Handle
+ Data.Git.Phoenix.Prelude: stdin :: Handle
+ Data.Git.Phoenix.Prelude: stdout :: Handle
+ Data.Git.Phoenix.Prelude: stimes :: (Semigroup a, Integral b) => b -> a -> a
+ Data.Git.Phoenix.Prelude: stimesIdempotent :: Integral b => b -> a -> a
+ Data.Git.Phoenix.Prelude: stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a
+ Data.Git.Phoenix.Prelude: stimesMonoid :: (Integral b, Monoid a) => b -> a -> a
+ Data.Git.Phoenix.Prelude: strictDecode :: OnDecodeError
+ Data.Git.Phoenix.Prelude: subsequences :: [a] -> [[a]]
+ Data.Git.Phoenix.Prelude: subtract :: Num a => a -> a -> a
+ Data.Git.Phoenix.Prelude: succ :: Enum a => a -> a
+ Data.Git.Phoenix.Prelude: sum :: forall a f. (Foldable f, Num a) => f a -> a
+ Data.Git.Phoenix.Prelude: swap :: (a, b) -> (b, a)
+ Data.Git.Phoenix.Prelude: swapMVar :: MonadIO m => MVar a -> a -> m a
+ Data.Git.Phoenix.Prelude: swapTMVar :: TMVar a -> a -> STM a
+ Data.Git.Phoenix.Prelude: tail :: IsNonEmpty f a [a] "tail" => f a -> [a]
+ Data.Git.Phoenix.Prelude: tails :: [a] -> [[a]]
+ Data.Git.Phoenix.Prelude: take :: Int -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: takeMVar :: MonadIO m => MVar a -> m a
+ Data.Git.Phoenix.Prelude: takeTMVar :: TMVar a -> STM a
+ Data.Git.Phoenix.Prelude: takeWhile :: (a -> Bool) -> [a] -> [a]
+ Data.Git.Phoenix.Prelude: tan :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: tanh :: Floating a => a -> a
+ Data.Git.Phoenix.Prelude: throwSTM :: Exception e => e -> STM a
+ Data.Git.Phoenix.Prelude: toBs :: forall {k} (s :: k). LByteString -> Bs s
+ Data.Git.Phoenix.Prelude: toEnum :: Enum a => Int -> a
+ Data.Git.Phoenix.Prelude: toException :: Exception e => e -> SomeException
+ Data.Git.Phoenix.Prelude: toInteger :: Integral a => a -> Integer
+ Data.Git.Phoenix.Prelude: toIntegralSized :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b
+ Data.Git.Phoenix.Prelude: toLText :: ToLText a => a -> LText
+ Data.Git.Phoenix.Prelude: toLazy :: LazyStrict l s => s -> l
+ Data.Git.Phoenix.Prelude: toLbs :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m LByteString
+ Data.Git.Phoenix.Prelude: toList :: Foldable t => t a -> [a]
+ Data.Git.Phoenix.Prelude: toRational :: Real a => a -> Rational
+ Data.Git.Phoenix.Prelude: toShort :: ByteString -> ShortByteString
+ Data.Git.Phoenix.Prelude: toStrict :: LazyStrict l s => l -> s
+ Data.Git.Phoenix.Prelude: toString :: ToString a => a -> String
+ Data.Git.Phoenix.Prelude: toText :: ToText a => a -> Text
+ Data.Git.Phoenix.Prelude: trace :: String -> a -> a
+ Data.Git.Phoenix.Prelude: traceId :: String -> String
+ Data.Git.Phoenix.Prelude: traceM :: Applicative f => String -> f ()
+ Data.Git.Phoenix.Prelude: traceShow :: Show a => a -> b -> b
+ Data.Git.Phoenix.Prelude: traceShowId :: Show a => a -> a
+ Data.Git.Phoenix.Prelude: traceShowM :: (Show a, Applicative f) => a -> f ()
+ Data.Git.Phoenix.Prelude: traceShowWith :: Show b => (a -> b) -> a -> a
+ Data.Git.Phoenix.Prelude: transpose :: [[a]] -> [[a]]
+ Data.Git.Phoenix.Prelude: traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ Data.Git.Phoenix.Prelude: traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
+ Data.Git.Phoenix.Prelude: truncate :: (RealFrac a, Integral b) => a -> b
+ Data.Git.Phoenix.Prelude: tryPutMVar :: MonadIO m => MVar a -> a -> m Bool
+ Data.Git.Phoenix.Prelude: tryPutTMVar :: TMVar a -> a -> STM Bool
+ Data.Git.Phoenix.Prelude: tryReadMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Data.Git.Phoenix.Prelude: tryReadTMVar :: TMVar a -> STM (Maybe a)
+ Data.Git.Phoenix.Prelude: tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Data.Git.Phoenix.Prelude: tryTakeTMVar :: TMVar a -> STM (Maybe a)
+ Data.Git.Phoenix.Prelude: type Bs (s :: k) = Scoped s LByteString
+ Data.Git.Phoenix.Prelude: type Constraint = CONSTRAINT LiftedRep
+ Data.Git.Phoenix.Prelude: type FilePath = String
+ Data.Git.Phoenix.Prelude: type HasCallStack = ?callStack :: CallStack
+ Data.Git.Phoenix.Prelude: type LByteString = ByteString
+ Data.Git.Phoenix.Prelude: type LText = Text
+ Data.Git.Phoenix.Prelude: type Nat = Natural
+ Data.Git.Phoenix.Prelude: type OnDecodeError = OnError Word8 Char
+ Data.Git.Phoenix.Prelude: type OnError a b = String -> Maybe a -> Maybe b
+ Data.Git.Phoenix.Prelude: type OneItem x;
+ Data.Git.Phoenix.Prelude: type Rational = Ratio Integer
+ Data.Git.Phoenix.Prelude: type Reader r = ReaderT r Identity
+ Data.Git.Phoenix.Prelude: type State s = StateT s Identity
+ Data.Git.Phoenix.Prelude: type String = [Char]
+ Data.Git.Phoenix.Prelude: type Type = TYPE LiftedRep
+ Data.Git.Phoenix.Prelude: type family CmpNat (a :: Natural) (b :: Natural) :: Ordering
+ Data.Git.Phoenix.Prelude: unScope :: forall {k} a (m :: Type -> Type) (s :: k). (NFData a, Monad m) => Scoped s a -> LazyT s m a
+ Data.Git.Phoenix.Prelude: uncons :: [a] -> Maybe (a, [a])
+ Data.Git.Phoenix.Prelude: uncurry :: (a -> b -> c) -> (a, b) -> c
+ Data.Git.Phoenix.Prelude: undefined :: HasCallStack => a
+ Data.Git.Phoenix.Prelude: unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
+ Data.Git.Phoenix.Prelude: universe :: (Bounded a, Enum a) => [a]
+ Data.Git.Phoenix.Prelude: universeNonEmpty :: (Bounded a, Enum a) => NonEmpty a
+ Data.Git.Phoenix.Prelude: unless :: Applicative f => Bool -> f () -> f ()
+ Data.Git.Phoenix.Prelude: unlessM :: Monad m => m Bool -> m () -> m ()
+ Data.Git.Phoenix.Prelude: unlines :: IsText t "unlines" => [t] -> t
+ Data.Git.Phoenix.Prelude: unstableNub :: Hashable a => [a] -> [a]
+ Data.Git.Phoenix.Prelude: unwords :: IsText t "unwords" => [t] -> t
+ Data.Git.Phoenix.Prelude: unzip :: [(a, b)] -> ([a], [b])
+ Data.Git.Phoenix.Prelude: unzip3 :: [(a, b, c)] -> ([a], [b], [c])
+ Data.Git.Phoenix.Prelude: usingReader :: r -> Reader r a -> a
+ Data.Git.Phoenix.Prelude: usingReaderT :: r -> ReaderT r m a -> m a
+ Data.Git.Phoenix.Prelude: usingState :: s -> State s a -> (a, s)
+ Data.Git.Phoenix.Prelude: usingStateT :: s -> StateT s m a -> m (a, s)
+ Data.Git.Phoenix.Prelude: vacuous :: Functor f => f Void -> f a
+ Data.Git.Phoenix.Prelude: viaNonEmpty :: (NonEmpty a -> b) -> [a] -> Maybe b
+ Data.Git.Phoenix.Prelude: void :: Functor f => f a -> f ()
+ Data.Git.Phoenix.Prelude: when :: Applicative f => Bool -> f () -> f ()
+ Data.Git.Phoenix.Prelude: whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()
+ Data.Git.Phoenix.Prelude: whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
+ Data.Git.Phoenix.Prelude: whenLeft :: Applicative f => a -> Either l r -> (l -> f a) -> f a
+ Data.Git.Phoenix.Prelude: whenLeftM :: Monad m => a -> m (Either l r) -> (l -> m a) -> m a
+ Data.Git.Phoenix.Prelude: whenLeftM_ :: Monad m => m (Either l r) -> (l -> m ()) -> m ()
+ Data.Git.Phoenix.Prelude: whenLeft_ :: Applicative f => Either l r -> (l -> f ()) -> f ()
+ Data.Git.Phoenix.Prelude: whenM :: Monad m => m Bool -> m () -> m ()
+ Data.Git.Phoenix.Prelude: whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()
+ Data.Git.Phoenix.Prelude: whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()
+ Data.Git.Phoenix.Prelude: whenNothing :: Applicative f => Maybe a -> f a -> f a
+ Data.Git.Phoenix.Prelude: whenNothingM :: Monad m => m (Maybe a) -> m a -> m a
+ Data.Git.Phoenix.Prelude: whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m ()
+ Data.Git.Phoenix.Prelude: whenNothing_ :: Applicative f => Maybe a -> f () -> f ()
+ Data.Git.Phoenix.Prelude: whenRight :: Applicative f => a -> Either l r -> (r -> f a) -> f a
+ Data.Git.Phoenix.Prelude: whenRightM :: Monad m => a -> m (Either l r) -> (r -> m a) -> m a
+ Data.Git.Phoenix.Prelude: whenRightM_ :: Monad m => m (Either l r) -> (r -> m ()) -> m ()
+ Data.Git.Phoenix.Prelude: whenRight_ :: Applicative f => Either l r -> (r -> f ()) -> f ()
+ Data.Git.Phoenix.Prelude: withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
+ Data.Git.Phoenix.Prelude: withFrozenCallStack :: HasCallStack => (HasCallStack => a) -> a
+ Data.Git.Phoenix.Prelude: withReader :: (r' -> r) -> Reader r a -> Reader r' a
+ Data.Git.Phoenix.Prelude: withReaderT :: forall r' r (m :: Type -> Type) a. (r' -> r) -> ReaderT r m a -> ReaderT r' m a
+ Data.Git.Phoenix.Prelude: withState :: (s -> s) -> State s a -> State s a
+ Data.Git.Phoenix.Prelude: words :: IsText t "words" => t -> [t]
+ Data.Git.Phoenix.Prelude: writeFile :: MonadIO m => FilePath -> String -> m ()
+ Data.Git.Phoenix.Prelude: writeFileBS :: MonadIO m => FilePath -> ByteString -> m ()
+ Data.Git.Phoenix.Prelude: writeFileLBS :: MonadIO m => FilePath -> LByteString -> m ()
+ Data.Git.Phoenix.Prelude: writeFileLText :: MonadIO m => FilePath -> LText -> m ()
+ Data.Git.Phoenix.Prelude: writeFileText :: MonadIO m => FilePath -> Text -> m ()
+ Data.Git.Phoenix.Prelude: writeIORef :: MonadIO m => IORef a -> a -> m ()
+ Data.Git.Phoenix.Prelude: writeTVar :: TVar a -> a -> STM ()
+ Data.Git.Phoenix.Prelude: xor :: Bits a => a -> a -> a
+ Data.Git.Phoenix.Prelude: zip :: [a] -> [b] -> [(a, b)]
+ Data.Git.Phoenix.Prelude: zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
+ Data.Git.Phoenix.Prelude: zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
+ Data.Git.Phoenix.Prelude: zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c]
+ Data.Git.Phoenix.Prelude: zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m ()
+ Data.Git.Phoenix.Prelude: }
+ Data.Git.Phoenix.Tree: getDestDir :: MonadReader PhoenixExtractConf m => m FilePath
- Data.Git.Phoenix.Commit: extractAuthor :: LByteString -> LbsPair
+ Data.Git.Phoenix.Commit: extractAuthor :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m (Bs s, Bs s)
- Data.Git.Phoenix.Commit: extractCommitTs :: LByteString -> Maybe (Int64, LByteString)
+ Data.Git.Phoenix.Commit: extractCommitTs :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m (Maybe (Int64, Bs s))
- Data.Git.Phoenix.Commit: extractField :: Word8 -> LByteString -> (LByteString -> LbsPair) -> LByteString -> LbsPair
+ Data.Git.Phoenix.Commit: extractField :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Word8 -> Bs s -> (Bs s -> LazyT s m (Bs s, Bs s)) -> Bs s -> LazyT s m (Bs s, Bs s)
- Data.Git.Phoenix.Commit: extractMessage :: LByteString -> LByteString
+ Data.Git.Phoenix.Commit: extractMessage :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m (Bs s)
- Data.Git.Phoenix.Commit: extractParent :: ByteString -> LbsPair
+ Data.Git.Phoenix.Commit: extractParent :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m (Bs s, Bs s)
- Data.Git.Phoenix.Commit: extractTreeHash :: LByteString -> LbsPair
+ Data.Git.Phoenix.Commit: extractTreeHash :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m (Bs s, Bs s)
- Data.Git.Phoenix.Io: withCompressed :: (HasCallStack, NFData a, MonadUnliftIO m, HasInHandlesSem m) => FilePath -> (HasCallStack => ByteString -> m a) -> m a
+ Data.Git.Phoenix.Io: withCompressed :: forall {k} a m. (NFData a, MonadUnliftIO m, HasInHandlesSem m) => FilePath -> (forall (s :: k). () => Bs s -> LazyT s m a) -> m a
- Data.Git.Phoenix.Io: withCompressedH :: (NFData a, MonadUnliftIO m, HasInHandlesSem m) => FilePath -> (Tagged Compressed LByteString -> LByteString -> m a) -> m a
+ Data.Git.Phoenix.Io: withCompressedH :: forall {k} a m. (NFData a, MonadUnliftIO m, HasInHandlesSem m) => FilePath -> (forall (s :: k). () => Tagged Compressed (Bs s) -> Bs s -> LazyT s m a) -> m a
- Data.Git.Phoenix.Io: withHandle :: (NFData a, MonadUnliftIO m, HasInHandlesSem m) => FilePath -> (Handle -> m a) -> m a
+ Data.Git.Phoenix.Io: withHandle :: forall {k} a m. (NFData a, MonadUnliftIO m, HasInHandlesSem m) => FilePath -> (forall (s :: k). () => Handle s -> LazyT s m a) -> m a
- Data.Git.Phoenix.Io: withHandleX :: (NFData a, MonadUnliftIO m, HasInHandlesSem m) => IOMode -> FilePath -> (Handle -> m a) -> m a
+ Data.Git.Phoenix.Io: withHandleX :: forall {k} a m. (NFData a, MonadUnliftIO m, HasInHandlesSem m) => IOMode -> FilePath -> (forall (s :: k). () => Handle s -> LazyT s m a) -> m a
- Data.Git.Phoenix.Object: blob :: ByteString
+ Data.Git.Phoenix.Object: blob :: forall {k} (s :: k). Bs s
- Data.Git.Phoenix.Object: classifyGitObject :: LByteString -> Maybe GitObjType
+ Data.Git.Phoenix.Object: classifyGitObject :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m (Maybe GitObjType)
- Data.Git.Phoenix.Object: commit :: ByteString
+ Data.Git.Phoenix.Object: commit :: forall {k} (s :: k). Bs s
- Data.Git.Phoenix.Object: compressedDisambiguate :: ByteString
+ Data.Git.Phoenix.Object: compressedDisambiguate :: LByteString
- Data.Git.Phoenix.Object: disambiguate :: ByteString
+ Data.Git.Phoenix.Object: disambiguate :: LByteString
- Data.Git.Phoenix.Object: gitObjectP :: LByteString -> Bool
+ Data.Git.Phoenix.Object: gitObjectP :: forall {k} (m :: Type -> Type) (s :: k). Monad m => Bs s -> LazyT s m Bool
- Data.Git.Phoenix.Object: tree :: ByteString
+ Data.Git.Phoenix.Object: tree :: forall {k} (s :: k). Bs s
- Data.Git.Phoenix.Prelude: infixr 2 .|
+ Data.Git.Phoenix.Prelude: infixr 2 ||
- Data.Git.Phoenix.Prelude: infixr 5 </>
+ Data.Git.Phoenix.Prelude: infixr 5 :|
- Data.Git.Phoenix.Tree: dropTreeHeader :: LByteString -> LByteString
+ Data.Git.Phoenix.Tree: dropTreeHeader :: forall {k} (s :: k). Bs s -> Bs s
- Data.Git.Phoenix.Tree: parseTreeObject :: PhoenixExtractM m => FilePath -> Tagged Compressed LByteString -> LByteString -> m (Either (Tagged Compressed LByteString) [(DOF, LByteString)])
+ Data.Git.Phoenix.Tree: parseTreeObject :: forall {k} (m :: Type -> Type) (s :: k). PhoenixExtractM m => FilePath -> Tagged Compressed (Bs s) -> Bs s -> LazyT s m (Either (Tagged Compressed LByteString) [(DOF, LByteString)])
Files
- changelog.md +3/−0
- git-phoenix.cabal +2/−1
- src/Data/Git/Phoenix/Commit.hs +26/−27
- src/Data/Git/Phoenix/CommitSearch.hs +18/−14
- src/Data/Git/Phoenix/Extraction.hs +37/−27
- src/Data/Git/Phoenix/HeadsDiscovery.hs +18/−15
- src/Data/Git/Phoenix/Io.hs +16/−25
- src/Data/Git/Phoenix/Object.hs +28/−16
- src/Data/Git/Phoenix/Prelude.hs +2/−2
- src/Data/Git/Phoenix/ShaCollision.hs +6/−6
- src/Data/Git/Phoenix/Tree.hs +44/−34
- src/Data/Git/Phoenix/Uber.hs +26/−25
- test/Data/Git/Phoenix/Test.hs +1/−1
changelog.md view
@@ -1,4 +1,7 @@ # git-phoenix changelog +## Version 0.0.2 2025-07-14+ * use lazy-scope+ ## Version 0.0.1 2025-06-28 * init
git-phoenix.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: git-phoenix-version: 0.0.1+version: 0.0.2 synopsis: Recover Git repositories from disk recovery tool output (photorec) description:@@ -201,6 +201,7 @@ , deepseq < 2 , extra < 2 , filepath < 2+ , lazy-scope < 1 , lens < 6 , memory < 1 , pretty-hex < 2
src/Data/Git/Phoenix/Commit.hs view
@@ -1,57 +1,56 @@ module Data.Git.Phoenix.Commit where -import Data.ByteString.Lazy qualified as L import Data.ByteString.Lazy.Char8 qualified as L8 import Data.Time import Data.Time.Clock.POSIX (posixSecondsToUTCTime)--- import Data.Time.Format.Internal import Data.Word8 qualified as W+import Lazy.Scope as S import Relude -type LbsPair = (LByteString, LByteString)- extractField ::- Word8 -> LByteString -> (LByteString -> LbsPair) -> LByteString -> LbsPair+ Monad m =>+ Word8 -> Bs s -> (Bs s -> LazyT s m (Bs s, Bs s)) -> Bs s -> LazyT s m (Bs s, Bs s) extractField b field parseValue bs =- case L.dropWhile (/= b) bs of- "" -> ("", "")- bs' ->- if field `L.isPrefixOf` bs'- then parseValue $ L.drop (L.length field) bs'- else extractField b field parseValue $ L.drop 1 bs'+ case S.dropWhile (/= b) bs of+ "" -> pure ("", "")+ bs' -> condM+ [ ( field `S.isPrefixOf` bs'+ , parseValue (S.length field `S.drop` bs') )+ ]+ (extractField b field parseValue $ S.drop 1 bs') -extractParent :: L.ByteString -> LbsPair+extractParent :: Monad m => Bs s -> LazyT s m (Bs s, Bs s) extractParent =- extractField W._lf "\nparent " (L.span W.isHexDigit)+ extractField W._lf "\nparent " (pure . S.span W.isHexDigit) -extractAuthor :: LByteString -> LbsPair+extractAuthor :: Monad m => Bs s -> LazyT s m (Bs s, Bs s) extractAuthor =- extractField W._lf "\nauthor " (L.span (/= W._less))+ extractField W._lf "\nauthor " (pure . S.span (/= W._less)) -extractCommitTs :: LByteString -> Maybe (Int64, LByteString)+extractCommitTs :: Monad m => Bs s -> LazyT s m (Maybe (Int64, Bs s)) extractCommitTs bs =- case extractField W._greater "> " (L.span (/= W._lf)) bs of+ extractField W._greater "> " (pure . S.span (/= W._lf)) bs >>= \case (tsBs, bs') ->- case L8.readInt64 tsBs of- Nothing -> Nothing+ unScope (bs2Scoped L8.readInt64 tsBs) >>= \case+ Nothing -> pure $ Nothing Just (epoch', spcTzBs) ->- case L8.readInt64 $ L.dropWhile W.isSpace spcTzBs of- Nothing -> Nothing+ unScope (bs2Scoped L8.readInt64 $ S.dropWhile W.isSpace $ toBs spcTzBs) >>= \case+ Nothing -> pure $ Nothing Just (tz, _) -> let tzAbs = abs tz (tzH, tzM) = tzAbs `divMod` 100 in- Just (epoch' + (tzH * 3600 + tzM * 60) * signum tz, bs')+ pure $ Just (epoch' + (tzH * 3600 + tzM * 60) * signum tz, bs') -extractMessage :: LByteString -> LByteString+extractMessage :: Monad m => Bs s -> LazyT s m (Bs s) extractMessage bs =- case extractField W._lf "\n\n" (L.span (/= W._lf)) bs of- (msgFirstLine, _) -> msgFirstLine+ extractField W._lf "\n\n" (pure . S.span (/= W._lf)) bs >>= \case+ (msgFirstLine, _) -> pure msgFirstLine -extractTreeHash :: LByteString -> LbsPair+extractTreeHash :: Monad m => Bs s -> LazyT s m (Bs s, Bs s) extractTreeHash =- extractField 0 "\0tree " (L.span W.isHexDigit)+ extractField 0 "\0tree " (pure . S.span W.isHexDigit) epoch :: UTCTime epoch = posixSecondsToUTCTime 0
src/Data/Git/Phoenix/CommitSearch.hs view
@@ -16,6 +16,8 @@ import Text.Regex.TDFA.ByteString.Lazy import Text.Regex.TDFA ++ data CommitObject = CommitObject { message :: LByteString@@ -31,27 +33,29 @@ where -- "commit 192\NULtree 844eaa6a04859d069e9ae10f2c6c293d23efc459\nauthor Daniil Iaitskov <dyaitskov@gmail.com> 1750985584 -0800\ncommitter Daniil Iaitskov <dyaitskov@gmail.com> 1 750 985 584 -0800\n\n init git-phoenix\n" goCommit bs =- case extractAuthor bs of+ extractAuthor bs >>= \case ("", _) -> pure []- (author, bs') ->- case extractCommitTs bs' of+ (authorBs, bs') ->+ extractCommitTs bs' >>= \case Nothing -> pure [] Just (commitTs, bs'') ->- case extractMessage bs'' of- message ->- let sha = gitPath2Bs . shaToPath . showDigest $ sha1 bs in- pure [CommitObject {message, sha, commitTs, author}]+ extractMessage bs'' >>= toLbs >>=+ \message -> do+ author <- toLbs authorBs+ sha <- unScope $ bs2Scoped (gitPath2Bs . shaToPath . showDigest . sha1) bs+ pure [CommitObject {message, sha, commitTs, author}] go :: FilePath -> m [CommitObject] go absGop = do- lr <- withCompressedH absGop $ \cbs bs ->- case classifyGitObject bs of- Just BlobType -> pure $ Right []- Just TreeType -> pure $ Right []- Just CommitType -> Right <$> goCommit bs- Just CollidedHash -> pure $ Left cbs- Nothing -> pure $ Right []+ lr <-+ withCompressedH absGop $ \cbs bs ->+ classifyGitObject bs >>= \case+ Just BlobType -> pure $ Right []+ Just TreeType -> pure $ Right []+ Just CommitType -> Right <$> goCommit bs+ Just CollidedHash -> Left <$> sequenceA (fmap toLbs cbs)+ Nothing -> pure $ Right [] case lr of Right cmt -> pure cmt Left cbs -> do
src/Data/Git/Phoenix/Extraction.hs view
@@ -2,51 +2,61 @@ import Data.ByteString.Lazy.Char8 qualified as L8 import Data.Git.Phoenix.App-import Data.Git.Phoenix.CmdArgs-import Data.Git.Phoenix.Commit+ ( PhoenixExtractConf(destGitDir, uberDir), PhoenixExtractM )+import Data.Git.Phoenix.CmdArgs ( ShaPrefix )+import Data.Git.Phoenix.Commit ( extractParent, extractTreeHash ) import Data.Git.Phoenix.Io+ ( writeBinaryFile,+ hPutLbs,+ saveCompressedBs,+ withCompressed,+ withCompressedH ) import Data.Git.Phoenix.Object+ ( classifyGitObject,+ toCommitSha,+ GitObjType(CommitType, BlobType, TreeType, CollidedHash),+ GitObjTypeG(Tree, Commit),+ GitPath(..) ) import Data.Git.Phoenix.Prelude-import Data.Git.Phoenix.Repo-import Data.Git.Phoenix.Sha-import Data.Git.Phoenix.ShaCollision-import Data.Git.Phoenix.Tree+import Data.Git.Phoenix.Repo ( initGitRepo )+import Data.Git.Phoenix.Sha ( shaToPath )+import Data.Git.Phoenix.ShaCollision ( uniqBs )+import Data.Git.Phoenix.Tree ( extractTree ) -readCommitObject :: PhoenixExtractM m => GitPath Commit -> m (Maybe (GitPath Commit), GitPath Tree)+readCommitObject :: forall m. PhoenixExtractM m => GitPath Commit -> m (Maybe (GitPath Commit), GitPath Tree) readCommitObject gop = go . (</> toFp gop) . untag =<< asks uberDir where+ goCommit :: forall s. Bs s -> LazyT s m (Maybe (GitPath Commit), GitPath Tree) goCommit bs =- case extractTreeHash $ $(tr "eee/bs") bs of+ extractTreeHash {- fix traceEmbrace to uncomment this snippet: $ $(tr "eee/bs") -} bs >>= \case ("", _) -> fail $ show gop <> " does not have tree field" (treeComit, bs') -> do gitDir <- untag <$> asks destGitDir- saveCompressedBs- (gitDir </> ".git" </> "objects" </> toFp gop)- bs- case extractParent bs' of- ("", _) -> pure (Nothing, shaToPath $ L8.unpack treeComit)- (!ph, _) -> pure ( Just . shaToPath $ L8.unpack ph- , $(tr "/treeComit") . shaToPath $ L8.unpack treeComit- )+ saveCompressedBs (gitDir </> ".git" </> "objects" </> toFp gop) =<< toLbs bs+ extractParent bs' >>= \case+ ("", _) -> (Nothing, ) . shaToPath . L8.unpack <$> toLbs treeComit+ (!ph, _) -> (,)+ <$> (Just . shaToPath . L8.unpack <$> toLbs ph)+ <*> ( $(tr "/treeComit") . shaToPath . L8.unpack <$> toLbs treeComit) go absGop = do- lr <- withCompressedH absGop $ \cbs bs ->- case classifyGitObject bs of- Just BlobType -> fail $ show gop <> " is Git blob but expected Git commit"- Just TreeType -> fail $ show gop <> " is Git tree but expected Git commit"- Just CommitType -> Right <$> goCommit bs- Just CollidedHash -> pure $ Left cbs- Nothing -> fail $ show gop <> " is not a Git commit object"+ lr <-+ withCompressedH absGop $ \cbs bs ->+ classifyGitObject bs >>= \case+ Just BlobType -> fail $ show gop <> " is Git blob but expected Git commit"+ Just TreeType -> fail $ show gop <> " is Git tree but expected Git commit"+ Just CommitType -> Right <$> goCommit bs+ Just CollidedHash -> Left <$> sequenceA (fmap toLbs cbs)+ Nothing -> fail $ show gop <> " is not a Git commit object" case lr of Right cmt -> pure cmt Left cbs -> do uniPath <- uniqBs gop cbs CommitType withCompressed uniPath $ \ubs ->- case classifyGitObject ubs of+ classifyGitObject ubs >>= \case Just CommitType -> goCommit ubs ops -> fail $ "Uniq BS of " <> show gop <> " is not commit but " <> show ops - extractCommit :: PhoenixExtractM m => GitPath Commit -> m () extractCommit ohp = do liftIO $(trIo "/ohp")@@ -63,10 +73,10 @@ initGitRepo gitDir let uc = GitPath . $(tw "/udr up") $ makeRelative udr up extractCommit uc- withBinaryFile+ writeBinaryFile (gitDir </> ".git" </> "refs" </> "heads" </> "master") WriteMode- (`hPut` toCommitSha uc)+ (`hPutLbs` toCommitSha uc) [] -> fail $ "No commit matching prefix: " <> show rootCommit ambiP -> fail $ "Commit prefix is ambioguous:\n " <> intercalate "\n" ambiP
src/Data/Git/Phoenix/HeadsDiscovery.hs view
@@ -16,6 +16,7 @@ import Data.Time.Format import Text.Regex.TDFA.ByteString.Lazy import Text.Regex.TDFA+import Lazy.Scope qualified as S data CommitObject = CommitObject@@ -36,30 +37,32 @@ Just gp -> fmap (gp,) <$> go gop where orphanCommit parent bs =- case extractAuthor bs of+ extractAuthor bs >>= \case ("", _) -> pure []- (comAuthor, bs') ->- case extractCommitTs bs' of+ (comAuthorBs, bs') ->+ extractCommitTs bs' >>= \case Nothing -> pure [] Just (commitTs, bs'') ->- case extractMessage bs'' of- message ->- pure [CommitObject {message, commitTs, comAuthor, parent}]+ extractMessage bs'' >>= S.toLbs >>=+ \message -> do+ comAuthor <- S.toLbs comAuthorBs+ pure [CommitObject {message, commitTs, comAuthor, parent}] goCommit bs =- case extractParent bs of+ extractParent bs >>= \case ("", bs') -> orphanCommit Nothing bs'- (parent, bs') -> orphanCommit (Just $ hexToBin parent) bs'+ (parent, bs') -> (`orphanCommit` bs') =<< (Just . hexToBin <$> S.toLbs parent) go :: FilePath -> m [CommitObject] go absGop = do- lr <- withCompressedH absGop $ \cbs bs ->- case classifyGitObject bs of- Just BlobType -> pure $ Right []- Just TreeType -> pure $ Right []- Just CommitType -> Right <$> goCommit bs- Just CollidedHash -> pure $ Left cbs- Nothing -> pure $ Right []+ lr <-+ withCompressedH absGop $ \cbs bs ->+ classifyGitObject bs >>= \case+ Just BlobType -> pure $ Right []+ Just TreeType -> pure $ Right []+ Just CommitType -> Right <$> goCommit bs+ Just CollidedHash -> Left <$> sequenceA (fmap S.toLbs cbs)+ Nothing -> pure $ Right [] case lr of Right cmt -> pure cmt Left cbs -> do
src/Data/Git/Phoenix/Io.hs view
@@ -1,9 +1,10 @@ module Data.Git.Phoenix.Io where import Data.ByteString.Lazy qualified as L-import Data.ByteString qualified as BS import Data.Git.Phoenix.Prelude-import System.IO (openBinaryFile)+import System.IO qualified as IO+import Lazy.Scope as S+import UnliftIO.IO qualified as U class HasInHandlesSem m where getInHandlesSem :: m QSem@@ -14,49 +15,39 @@ data Compressed withHandleX :: (NFData a, MonadUnliftIO m, HasInHandlesSem m) =>- IOMode -> FilePath -> (Handle -> m a) -> m a+ IOMode -> FilePath -> (forall s. Handle s -> LazyT s m a) -> m a withHandleX mode fp a = do s <- getInHandlesSem bracket_ (waitQSem s) (signalQSem s) $- -- withFile is not applicable because Handle might be closed twice- -- https://github.com/haskell/bytestring/issues/707- bracket (liftIO $ openBinaryFile fp mode)- (\h -> whenM (hIsOpen h) $ hClose h) go- where- go h = do- !r <- a h- case rnf r of- () -> pure r+ withBinaryFile fp mode a + withHandle :: (NFData a, MonadUnliftIO m, HasInHandlesSem m) =>- FilePath -> (Handle -> m a) -> m a+ FilePath -> (forall s. Handle s -> LazyT s m a) -> m a withHandle = withHandleX ReadMode withCompressedH :: (NFData a, MonadUnliftIO m, HasInHandlesSem m) => FilePath ->- (Tagged Compressed LByteString -> LByteString -> m a) ->+ (forall s. Tagged Compressed (Bs s) -> Bs s -> LazyT s m a) -> m a withCompressedH fp a =- withHandle ($(tr "/fp") fp) $ \inH -> hGetContents inH >>= (\cbs -> a (Tagged cbs) $ decompress cbs)+ withHandle ($(tr "/fp") fp) $ \inH -> hGetContents inH >>= (\cbs -> a (Tagged cbs) $ mapLbs decompress cbs) -withCompressed :: (HasCallStack, NFData a, MonadUnliftIO m, HasInHandlesSem m) =>- FilePath -> (HasCallStack => L.ByteString -> m a) -> m a+withCompressed :: (NFData a, MonadUnliftIO m, HasInHandlesSem m) =>+ FilePath -> (forall s. Bs s -> LazyT s m a) -> m a withCompressed fp a = withCompressedH fp (\_cbs bs -> a bs) -hGet :: MonadIO m => Handle -> Int -> m ByteString-hGet h n = liftIO $ BS.hGet h n--hGetContents :: MonadIO m => Handle -> m LByteString-hGetContents h = liftIO $ L.hGetContents h+writeBinaryFile :: MonadUnliftIO m => FilePath -> IOMode -> (IO.Handle -> m ()) -> m ()+writeBinaryFile fp mode cb = U.withBinaryFile fp mode cb -hPut :: MonadIO m => Handle -> LByteString -> m ()-hPut h bs = liftIO $ L.hPut h bs+hPutLbs :: MonadIO m => IO.Handle -> LByteString -> m ()+hPutLbs h bs = liftIO $ L.hPut h bs -- | just 'copyFile' is not possible due to trash after archive saveCompressedBs :: MonadUnliftIO m => FilePath -> LByteString -> m () saveCompressedBs fp bs = do createDirectoryIfMissing False $ dropFileName fp- withBinaryFile ($(tr "/fp") fp) WriteMode $ \h -> hPut h $ compress bs+ withBinaryFile ($(tr "/fp") fp) WriteMode $ \h -> S.hPut h $ compress bs readNumber :: MonadIO m => Int -> Int -> m Int readNumber minVal maxVal = go
src/Data/Git/Phoenix/Object.hs view
@@ -1,10 +1,13 @@+{-# OPTIONS_GHC -Wno-orphans #-} module Data.Git.Phoenix.Object where import Data.Binary qualified as B import Data.ByteString.Lazy qualified as L import Data.ByteString.Lazy.Char8 qualified as L8 import Data.Git.Phoenix.Prelude+import Lazy.Scope qualified as S + data GitObjType = CommitType | TreeType | BlobType | CollidedHash deriving (Show, Eq) data GitObjTypeG = Commit | Tree deriving (Show, Eq)@@ -15,32 +18,41 @@ toCommitSha :: GitPath t -> LByteString toCommitSha (GitPath p) = L8.pack $ filter (/= '/') p -classifyGitObject :: LByteString -> Maybe GitObjType-classifyGitObject bs- | blob `L.isPrefixOf` bs = pure BlobType- | tree `L.isPrefixOf` bs = pure TreeType- | commit `L.isPrefixOf` bs = pure CommitType- | disambiguate `L.isPrefixOf` bs = pure CollidedHash- | otherwise = Nothing+classifyGitObject :: Monad m => Bs s -> LazyT s m (Maybe GitObjType)+classifyGitObject bs =+ condM+ [ (blob `S.isPrefixOf` bs, pure $ pure BlobType)+ , (tree `S.isPrefixOf` bs, pure $ pure TreeType)+ , (commit `S.isPrefixOf` bs, pure $ pure CommitType)+ , (toBs disambiguate `S.isPrefixOf` bs, pure $ pure CollidedHash)+ ]+ (pure Nothing) -commit, tree, blob, disambiguate :: L.ByteString-disambiguate = "disambigate "+commit, tree, blob :: Bs s commit = "commit " blob = "blob " tree = "tree " -gitObjectP :: LByteString -> Bool+disambiguate :: LByteString+disambiguate = "disambigate "++gitObjectP :: Monad m => Bs s -> LazyT s m Bool gitObjectP bs =- case classifyGitObject bs of+ classifyGitObject bs >>= pure . \case Nothing -> False Just CollidedHash -> False Just _ -> True -compressedDisambiguate :: L.ByteString-compressedDisambiguate =- compressWith- (defaultCompressParams { compressLevel = CompressionLevel 0 })- disambiguate+compressedDisambiguate :: LByteString+compressedDisambiguate = compressWith params disambiguate+ where+ params = defaultCompressParams { compressLevel = CompressionLevel 0 }++compressedDisambiguateBs :: Bs s+compressedDisambiguateBs = toBs compressedDisambiguate++compressedDisambiguateLen :: Int64+compressedDisambiguateLen = L.length compressedDisambiguate encodedIntLen :: Int64 encodedIntLen = L.length . B.encode $ L.length ""
src/Data/Git/Phoenix/Prelude.hs view
@@ -18,11 +18,11 @@ import Data.List as X ((!?)) import Data.Tagged as X (Tagged (..), untag) import Data.Word8 as X (isHexDigit)-import Relude as X+import Lazy.Scope as X (LazyT, Scoped, Bs, unScope, toLbs, condM, toBs, bs2Scoped)+import Relude as X hiding (Handle) import System.FilePath as X ((</>), dropFileName, splitFileName, makeRelative) import System.Time.Extra as X import Text.Printf as X-import UnliftIO.IO as X (withBinaryFile, hIsOpen, hClose) import UnliftIO.QSem as X (QSem, newQSem, signalQSem, waitQSem) import UnliftIO.Exception as X (bracket, bracket_, catch) import UnliftIO.Directory as X
src/Data/Git/Phoenix/ShaCollision.hs view
@@ -8,16 +8,16 @@ import Data.Git.Phoenix.Io import Data.Git.Phoenix.Object import Data.Git.Phoenix.Prelude-+import Lazy.Scope qualified as S disambiguateByPair :: PhoenixM m => GitObjType -> [FilePath] -> m [FilePath] disambiguateByPair tt links = fmap (snd . head) . groupWith fst . sort . catMaybes <$> mapM go links where- go l = do- withCompressed l $ \bs -> do- case classifyGitObject bs of- Just x | x == tt -> pure $ Just (bs, l)+ go l =+ withCompressed l $ \bs ->+ classifyGitObject bs >>= \case+ Just x | x == tt -> Just . (, l) <$> S.toLbs bs | otherwise -> pure Nothing Nothing -> pure Nothing @@ -66,4 +66,4 @@ error $ "List of files with collided SHA is corrupted (error: " <> show e <> ") near: " <> show bs - cbs = L.drop (L.length compressedDisambiguate) preCbs+ cbs = L.drop compressedDisambiguateLen preCbs
src/Data/Git/Phoenix/Tree.hs view
@@ -7,9 +7,10 @@ import Data.Git.Phoenix.Sha import Data.Git.Phoenix.ShaCollision import Data.Git.Phoenix.Io+import Lazy.Scope as S -dropTreeHeader :: LByteString -> LByteString-dropTreeHeader = L.drop 1 . L.dropWhile (/= 0)+dropTreeHeader :: Bs s -> Bs s+dropTreeHeader = S.drop 1 . S.dropWhile (/= 0) data DOF = Dir | File deriving (Eq, Show, Generic) @@ -57,16 +58,16 @@ parseTreeObject :: PhoenixExtractM m => FilePath ->- Tagged Compressed LByteString ->- LByteString ->- m (Either (Tagged Compressed LByteString) [(DOF, LByteString)])+ Tagged Compressed (Bs s) ->+ Bs s ->+ LazyT s m (Either (Tagged Compressed LByteString) [(DOF, LByteString)]) parseTreeObject gop cbs bs =- case classifyGitObject bs of+ classifyGitObject bs >>= \case Just BlobType -> fail $ gop <> " is Git blob but expected Git tree" Just CommitType -> fail $ gop <> " is Git commit but expected Git tree"- Just TreeType -> do- pure . Right . readTreeShas $ dropTreeHeader bs- Just CollidedHash -> pure $ Left cbs+ Just TreeType ->+ Right <$> unScope (bs2Scoped readTreeShas (dropTreeHeader bs))+ Just CollidedHash -> Left <$> sequenceA (fmap toLbs cbs) Nothing -> fail $ gop <> " is not a Git tree object" onRight_ :: Monad m => (b -> m ()) -> Either a b -> m (Either a b)@@ -74,7 +75,9 @@ v@(Left _) -> pure v r@(Right v) -> f v >> pure r -extractTree :: PhoenixExtractM m => GitPath Tree -> m ()+getDestDir :: MonadReader PhoenixExtractConf m => m FilePath+getDestDir = (\(Tagged r) -> r </> ".git" </> "objects") <$> asks destGitDir+extractTree :: forall m. PhoenixExtractM m => GitPath Tree -> m () extractTree treeHash = do Tagged udr <- asks uberDir dd <- getDestDir@@ -82,11 +85,14 @@ mapM_ (copyTreeLinks dd) . $(tw "len/") where copyTree treePath trH = do- let save bs = do+ let+ save :: forall s. Bs s -> LazyT s m ()+ save bs = do destDir <- getDestDir- saveCompressedBs (destDir </> toFp trH) bs- rl <- withCompressedH treePath $ \cTreeBs treeBs ->- parseTreeObject treePath cTreeBs treeBs >>= onRight_ (\_ -> save treeBs)+ saveCompressedBs (destDir </> toFp trH) =<< toLbs bs+ rl <- withCompressedH treePath $+ \cTreeBs treeBs ->+ parseTreeObject treePath cTreeBs treeBs >>= onRight_ (\_ -> save treeBs) shas <- case rl of Right shas' -> pure shas' Left cbs -> do@@ -94,41 +100,45 @@ withCompressed uniPath (\ubs -> do save ubs- pure . readTreeShas $ dropTreeHeader ubs+ unScope (bs2Scoped readTreeShas $ dropTreeHeader ubs) ) pure shas- getDestDir = (\(Tagged r) -> r </> ".git" </> "objects") <$> asks destGitDir+ copyTreeLinks destDir (dof, binSha) = do (Tagged udr) <- asks uberDir liftIO $(trIo "/destDir binSha") let shaP = binSha2Path binSha absSha = udr </> toFp shaP- saveBlob = saveCompressedBs (destDir </> toFp shaP)+ saveBlob :: forall s. Bs s -> LazyT s m ()+ saveBlob = toLbs >=> saveCompressedBs (destDir </> toFp shaP)+ saveTree :: forall s. Bs s -> LazyT s m [(DOF, LByteString)] saveTree bs = do saveBlob bs- pure . readTreeShas $ dropTreeHeader bs- nonRec <- withCompressedH absSha $ \cbs bs ->- case classifyGitObject bs of- Just BlobType- | dof == File -> JustBlob <$> saveBlob bs- | otherwise -> fail $ absSha <> " is not a GIT blob"- Just TreeType- | dof == Dir -> TreeShas <$> saveTree bs- | otherwise -> fail $ absSha <> " is not a GIT tree"- Just CollidedHash ->- pure $ Collision cbs- _ -> fail $ absSha <> " is not a GIT tree nor GIT blob nor disambiguate file"+ unScope (bs2Scoped readTreeShas $ dropTreeHeader bs)+ nonRec <-+ withCompressedH absSha $ \cbs bs ->+ classifyGitObject bs >>= \case+ Just BlobType+ | dof == File -> JustBlob <$> saveBlob bs+ | otherwise -> fail $ absSha <> " is not a GIT blob"+ Just TreeType+ | dof == Dir -> TreeShas <$> saveTree bs+ | otherwise -> fail $ absSha <> " is not a GIT tree"+ Just CollidedHash ->+ Collision <$> sequenceA (fmap toLbs cbs)+ _ -> fail $ absSha <> " is not a GIT tree nor GIT blob nor disambiguate file" case nonRec of JustBlob () -> pure () TreeShas rows -> mapM_ (copyTreeLinks destDir) rows Collision cbs' -> do uniPath <- uniqBs shaP cbs' (dofToGitObjType dof)- !lr <- withCompressed uniPath $ \ubs ->- case classifyGitObject ubs of- Just BlobType -> Left <$> saveBlob ubs- Just TreeType -> Right <$> saveTree ubs- _ -> fail $ absSha <> " is not GIT tree nor GIT blob"+ !lr <-+ withCompressed uniPath $ \ubs ->+ classifyGitObject ubs >>= \case+ Just BlobType -> Left <$> saveBlob ubs+ Just TreeType -> Right <$> saveTree ubs+ _ -> fail $ absSha <> " is not GIT tree nor GIT blob" case lr of Left () -> pure () Right rows -> mapM_ (copyTreeLinks destDir) rows
src/Data/Git/Phoenix/Uber.hs view
@@ -13,6 +13,7 @@ import Data.Git.Phoenix.Sha import Data.List qualified as I import Data.Map.Strict qualified as M+import Lazy.Scope as S type ShaDedupMap = M.Map ComHash Int @@ -28,25 +29,25 @@ gitObjectFilePath :: GitObject -> FilePath gitObjectFilePath = uncurry (</>) . I.splitAt 2 . showDigest . gobHash -mkGitObject :: PhoenixM m => FilePath -> m (Maybe GitObject)-mkGitObject fp =- withHandle fp $ \inH -> do- magicBs <- hGet inH 2- if zlibP magicBs- then do- (`catch` skipCorruptedFile) $ do- headerBs <- (toLazy magicBs <>) . toLazy <$> hGet inH 510- if gitObjectP $ decompress headerBs- then do- !goh <- sha1 . decompress . (headerBs <>) <$> hGetContents inH- pure . Just $! GitObject goh fp- else- pure Nothing- else pure Nothing+mkGitObject :: forall m. PhoenixM m => FilePath -> m (Maybe GitObject)+mkGitObject fp = go where+ go :: m (Maybe GitObject)+ go =+ withHandle fp $ \inH -> unScope =<< do+ magicBs <- S.hGet inH 2+ if zlibP magicBs+ then do+ (`catch` skipCorruptedFile) $ do+ headerBs <- (toLazy magicBs <>) . toLazy <$> S.hGet inH 510+ ifM (gitObjectP . toBs $ decompress headerBs)+ (S.bs2Scoped (Just . (`GitObject` fp) . sha1 . decompress) . (toBs headerBs <>) <$> S.hGetContents inH)+ (pure (pure Nothing))+ else pure (pure Nothing)+ skipCorruptedFile (_ :: DecompressError) = do liftIO $ $(trIo "Skip corrupted file/fp")- pure Nothing+ pure (pure Nothing) zlibNoCompression = "\x0078\x0001" zlibDefaultCompression = "\x0078\x009C"@@ -70,20 +71,20 @@ replaceSymLinkWithDisambiguate uberGob gob = do firstGobOrigin <- L8.pack <$> getSymbolicLinkTarget uberGob removeFile uberGob- withBinaryFile uberGob WriteMode $ \oh ->- hPut oh . mconcat $ [ compressedDisambiguate- , B.encode $ L.length firstGobOrigin- , firstGobOrigin- , B.encode $ L.length gobPacked- , gobPacked- ]+ S.withBinaryFile uberGob WriteMode $ \oh ->+ hPutBs oh . mconcat $ (compressedDisambiguateBs : fmap toBs [+ B.encode $ L.length firstGobOrigin+ , firstGobOrigin+ , B.encode $ L.length gobPacked+ , gobPacked+ ]) where gobPacked = L8.pack $ gobOrigin gob appendPathToUberGob :: MonadUnliftIO m => FilePath -> GitObject -> m () appendPathToUberGob uberGob gob =- withBinaryFile uberGob AppendMode $ \oh ->- hPut oh $ gobLen <> gobPacked+ writeBinaryFile uberGob AppendMode $ \oh ->+ hPutLbs oh $ gobLen <> gobPacked where gobPacked = L8.pack $ gobOrigin gob gobLen = B.encode $ L.length gobPacked
test/Data/Git/Phoenix/Test.hs view
@@ -7,7 +7,7 @@ import Data.Git.Phoenix.Prelude import Test.QuickCheck as QC import UnliftIO.Directory-import UnliftIO.IO (hSeek, SeekMode (..))+import UnliftIO.IO ( SeekMode(AbsoluteSeek), hSeek, withBinaryFile ) import UnliftIO.Temporary currentHead :: String