packages feed

git 0.2.2 → 0.3.0

raw patch · 11 files changed

+145/−34 lines, 11 filesdep −byteabledep −patiencedep ~bytestringPVP ok

version bump matches the API change (PVP)

Dependencies removed: byteable, patience

Dependency ranges changed: bytestring

API changes (from Hackage documentation)

- Data.Git.Ref: instance Data.Typeable.Internal.Typeable hash => GHC.Exception.Exception (Data.Git.Ref.RefNotFound hash)
- Data.Git.Ref: instance GHC.Exception.Exception Data.Git.Ref.RefInvalid
- Data.Git.Repository: instance Data.Typeable.Internal.Typeable hash => GHC.Exception.Exception (Data.Git.Repository.InvalidType hash)
- Data.Git.Types: instance Data.Byteable.Byteable Data.Git.Types.EntName
+ Data.Git.Diff.Patience: Both :: !t -> !t -> Item t
+ Data.Git.Diff.Patience: New :: !t -> Item t
+ Data.Git.Diff.Patience: Old :: !t -> Item t
+ Data.Git.Diff.Patience: data Item t
+ Data.Git.Diff.Patience: diff :: Ord t => [t] -> [t] -> [Item t]
+ Data.Git.Diff.Patience: instance GHC.Base.Functor Data.Git.Diff.Patience.Item
+ Data.Git.Diff.Patience: instance GHC.Classes.Eq t => GHC.Classes.Eq (Data.Git.Diff.Patience.Item t)
+ Data.Git.Diff.Patience: instance GHC.Show.Show a => GHC.Show.Show (Data.Git.Diff.Patience.Piece a)
+ Data.Git.Diff.Patience: instance GHC.Show.Show t => GHC.Show.Show (Data.Git.Diff.Patience.Item t)
+ Data.Git.Ref: instance Data.Typeable.Internal.Typeable hash => GHC.Exception.Type.Exception (Data.Git.Ref.RefNotFound hash)
+ Data.Git.Ref: instance GHC.Exception.Type.Exception Data.Git.Ref.RefInvalid
+ Data.Git.Repository: instance Data.Typeable.Internal.Typeable hash => GHC.Exception.Type.Exception (Data.Git.Repository.InvalidType hash)
+ Data.Git.Types: getEntNameBytes :: EntName -> ByteString
- Data.Git: Commit :: !(Ref hash) -> [Ref hash] -> !Person -> !Person -> Maybe ByteString -> [CommitExtra] -> !ByteString -> Commit hash
+ Data.Git: Commit :: !Ref hash -> [Ref hash] -> !Person -> !Person -> Maybe ByteString -> [CommitExtra] -> !ByteString -> Commit hash
- Data.Git: Tag :: !(Ref hash) -> !ObjectType -> !ByteString -> !Person -> !ByteString -> Tag hash
+ Data.Git: Tag :: !Ref hash -> !ObjectType -> !ByteString -> !Person -> !ByteString -> Tag hash
- Data.Git: [commitTreeish] :: Commit hash -> !(Ref hash)
+ Data.Git: [commitTreeish] :: Commit hash -> !Ref hash
- Data.Git: [tagRef] :: Tag hash -> !(Ref hash)
+ Data.Git: [tagRef] :: Tag hash -> !Ref hash
- Data.Git.Delta: Delta :: Word64 -> Word64 -> [DeltaCmd] -> Delta
+ Data.Git.Delta: Delta :: !Word64 -> !Word64 -> ![DeltaCmd] -> Delta
- Data.Git.Delta: DeltaCopy :: ByteString -> DeltaCmd
+ Data.Git.Delta: DeltaCopy :: !ByteString -> DeltaCmd
- Data.Git.Delta: DeltaSrc :: Word64 -> Word64 -> DeltaCmd
+ Data.Git.Delta: DeltaSrc :: !Word64 -> !Word64 -> DeltaCmd
- Data.Git.Diff: ModifiedRef :: (Ref hash) -> (Ref hash) -> GitFileRef hash
+ Data.Git.Diff: ModifiedRef :: Ref hash -> Ref hash -> GitFileRef hash
- Data.Git.Diff: NewRef :: (Ref hash) -> GitFileRef hash
+ Data.Git.Diff: NewRef :: Ref hash -> GitFileRef hash
- Data.Git.Diff: NormalLine :: (Item TextLine) -> FilteredDiff
+ Data.Git.Diff: NormalLine :: Item TextLine -> FilteredDiff
- Data.Git.Diff: OldAndNew :: (BlobState hash) -> (BlobState hash) -> BlobStateDiff hash
+ Data.Git.Diff: OldAndNew :: BlobState hash -> BlobState hash -> BlobStateDiff hash
- Data.Git.Diff: OldRef :: (Ref hash) -> GitFileRef hash
+ Data.Git.Diff: OldRef :: Ref hash -> GitFileRef hash
- Data.Git.Diff: OnlyNew :: (BlobState hash) -> BlobStateDiff hash
+ Data.Git.Diff: OnlyNew :: BlobState hash -> BlobStateDiff hash
- Data.Git.Diff: OnlyOld :: (BlobState hash) -> BlobStateDiff hash
+ Data.Git.Diff: OnlyOld :: BlobState hash -> BlobStateDiff hash
- Data.Git.Diff: UnModifiedRef :: (Ref hash) -> GitFileRef hash
+ Data.Git.Diff: UnModifiedRef :: Ref hash -> GitFileRef hash
- Data.Git.Monad: Commit :: !(Ref hash) -> [Ref hash] -> !Person -> !Person -> Maybe ByteString -> [CommitExtra] -> !ByteString -> Commit hash
+ Data.Git.Monad: Commit :: !Ref hash -> [Ref hash] -> !Person -> !Person -> Maybe ByteString -> [CommitExtra] -> !ByteString -> Commit hash
- Data.Git.Monad: [commitTreeish] :: Commit hash -> !(Ref hash)
+ Data.Git.Monad: [commitTreeish] :: Commit hash -> !Ref hash
- Data.Git.Monad: withBranch :: GitMonad git => Person -> RefName -> Bool -> (CommitAccessM a) -> (Maybe a -> CommitM b) -> git (Ref SHA1, b)
+ Data.Git.Monad: withBranch :: GitMonad git => Person -> RefName -> Bool -> CommitAccessM a -> (Maybe a -> CommitM b) -> git (Ref SHA1, b)
- Data.Git.Named: RefDirect :: (Ref hash) -> RefContentTy hash
+ Data.Git.Named: RefDirect :: Ref hash -> RefContentTy hash
- Data.Git.Ref: RefNotFound :: (Ref hash) -> RefNotFound hash
+ Data.Git.Ref: RefNotFound :: Ref hash -> RefNotFound hash
- Data.Git.Repository: TreeDir :: (Ref hash) -> (HTree hash) -> HTreeEnt hash
+ Data.Git.Repository: TreeDir :: Ref hash -> HTree hash -> HTreeEnt hash
- Data.Git.Repository: TreeFile :: (Ref hash) -> HTreeEnt hash
+ Data.Git.Repository: TreeFile :: Ref hash -> HTreeEnt hash
- Data.Git.Storage.Object: Loose :: (Ref hash) -> ObjectLocation hash
+ Data.Git.Storage.Object: Loose :: Ref hash -> ObjectLocation hash
- Data.Git.Storage.Object: ObjBlob :: (Blob hash) -> Object hash
+ Data.Git.Storage.Object: ObjBlob :: Blob hash -> Object hash
- Data.Git.Storage.Object: ObjCommit :: (Commit hash) -> Object hash
+ Data.Git.Storage.Object: ObjCommit :: Commit hash -> Object hash
- Data.Git.Storage.Object: ObjDeltaOfs :: (DeltaOfs hash) -> Object hash
+ Data.Git.Storage.Object: ObjDeltaOfs :: DeltaOfs hash -> Object hash
- Data.Git.Storage.Object: ObjDeltaRef :: (DeltaRef hash) -> Object hash
+ Data.Git.Storage.Object: ObjDeltaRef :: DeltaRef hash -> Object hash
- Data.Git.Storage.Object: ObjTag :: (Tag hash) -> Object hash
+ Data.Git.Storage.Object: ObjTag :: Tag hash -> Object hash
- Data.Git.Storage.Object: ObjTree :: (Tree hash) -> Object hash
+ Data.Git.Storage.Object: ObjTree :: Tree hash -> Object hash
- Data.Git.Storage.Object: Packed :: (Ref hash) -> Word64 -> ObjectLocation hash
+ Data.Git.Storage.Object: Packed :: Ref hash -> Word64 -> ObjectLocation hash
- Data.Git.Storage.Object: PtrRef :: (Ref hash) -> ObjectPtr hash
+ Data.Git.Storage.Object: PtrRef :: Ref hash -> ObjectPtr hash
- Data.Git.Storage.PackIndex: PackIndexHeader :: !Word32 -> !(Vector Word32) -> PackIndexHeader
+ Data.Git.Storage.PackIndex: PackIndexHeader :: !Word32 -> !Vector Word32 -> PackIndexHeader
- Data.Git.Types: Commit :: !(Ref hash) -> [Ref hash] -> !Person -> !Person -> Maybe ByteString -> [CommitExtra] -> !ByteString -> Commit hash
+ Data.Git.Types: Commit :: !Ref hash -> [Ref hash] -> !Person -> !Person -> Maybe ByteString -> [CommitExtra] -> !ByteString -> Commit hash
- Data.Git.Types: DeltaRef :: !(Ref hash) -> !Delta -> DeltaRef hash
+ Data.Git.Types: DeltaRef :: !Ref hash -> !Delta -> DeltaRef hash
- Data.Git.Types: Tag :: !(Ref hash) -> !ObjectType -> !ByteString -> !Person -> !ByteString -> Tag hash
+ Data.Git.Types: Tag :: !Ref hash -> !ObjectType -> !ByteString -> !Person -> !ByteString -> Tag hash
- Data.Git.Types: [commitTreeish] :: Commit hash -> !(Ref hash)
+ Data.Git.Types: [commitTreeish] :: Commit hash -> !Ref hash
- Data.Git.Types: [tagRef] :: Tag hash -> !(Ref hash)
+ Data.Git.Types: [tagRef] :: Tag hash -> !Ref hash

Files

Data/Git/Delta.hs view
@@ -5,6 +5,7 @@ -- Stability   : experimental -- Portability : unix --+{-# LANGUAGE BangPatterns #-} module Data.Git.Delta     ( Delta(..)     , DeltaCmd(..)@@ -22,13 +23,13 @@ import           Data.Git.Imports  -- | a delta is a source size, a destination size and a list of delta cmd-data Delta = Delta Word64 Word64 [DeltaCmd]+data Delta = Delta !Word64 !Word64 ![DeltaCmd]     deriving (Show,Eq)  -- | possible commands in a delta data DeltaCmd =-      DeltaCopy ByteString   -- command to insert this bytestring-    | DeltaSrc Word64 Word64 -- command to copy from source (offset, size)+      DeltaCopy !ByteString   -- command to insert this bytestring+    | DeltaSrc !Word64 !Word64 -- command to copy from source (offset, size)     deriving (Show,Eq)  -- | parse a delta.@@ -62,8 +63,9 @@                 let size   = s1 .|. s2 .|. s3                 return $ DeltaSrc offset (if size == 0 then 0x10000 else size)             | otherwise       = DeltaCopy <$> P.take (fromIntegral cmd)-        word8cond cond sh =-            if cond then (flip shiftL sh . fromIntegral) <$> P.anyByte else return 0++        word8cond False _  = return 0+        word8cond True  sh = flip shiftL sh . fromIntegral <$> P.anyByte  -- | read one delta from a lazy bytestring. deltaRead :: [ByteString] -> Maybe Delta
Data/Git/Diff.hs view
@@ -36,8 +36,9 @@ import Data.ByteString.Lazy.Char8 as L  import Data.Typeable-import Data.Algorithm.Patience as AP (Item(..), diff)+import Data.Git.Diff.Patience (Item(..), diff) + -- | represents a blob's content (i.e., the content of a file at a given -- reference). data BlobContent = FileContent [L.ByteString] -- ^ Text file's lines@@ -257,22 +258,21 @@     let (_, _, filteredDiff) = Prelude.foldr filterContext (0, AccuBottom, []) list         theList = removeTrailingBoth filteredDiff     in case Prelude.head theList of-        (NormalLine (Both l1 _)) -> if (lineNumber l1) > 1 then Separator:theList-                                                           else theList+        (NormalLine (Both l _)) -> if lineNumber l > 1 then Separator:theList else theList         _ -> theList     where -- only keep 'context'. The file is annalyzed from the bottom to the top.           -- The accumulator here is a tuple3 with (the line counter, the           -- direction and the list of elements)           filterContext :: (Item TextLine) -> (Int, GitAccu, [FilteredDiff]) -> (Int, GitAccu, [FilteredDiff])-          filterContext (Both l1 l2) (c, AccuBottom, acc) =-              if c < context then (c+1, AccuBottom, (NormalLine (Both l1 l2)):acc)-                             else (c  , AccuBottom, (NormalLine (Both l1 l2))+          filterContext b@(Both {}) (c, AccuBottom, acc) =+              if c < context then (c+1, AccuBottom, (NormalLine b):acc)+                             else (c  , AccuBottom, (NormalLine b)                                                     :((Prelude.take (context-1) acc)                                                     ++ [Separator]                                                     ++ (Prelude.drop (context+1) acc)))-          filterContext (Both l1 l2) (c, AccuTop, acc) =-              if c < context then (c+1, AccuTop   , (NormalLine (Both l1 l2)):acc)-                             else (0  , AccuBottom, (NormalLine (Both l1 l2)):acc)+          filterContext b@(Both {}) (c, AccuTop, acc) =+              if c < context then (c+1, AccuTop   , (NormalLine b):acc)+                             else (0  , AccuBottom, (NormalLine b):acc)           filterContext element (_, _, acc) =               (0, AccuTop, (NormalLine element):acc) @@ -281,8 +281,8 @@           startWithSeparator (Separator:_) = True           startWithSeparator ((NormalLine l):xs) =               case l of-                  (Both _ _) -> startWithSeparator xs-                  _          -> False+                  Both {} -> startWithSeparator xs+                  _       -> False            removeTrailingBoth :: [FilteredDiff] -> [FilteredDiff]           removeTrailingBoth diffList =
+ Data/Git/Diff/Patience.hs view
@@ -0,0 +1,108 @@+-- loosely based on the patience-0.1.1 package which is:+--+--     Copyright (c) Keegan McAllister 2011+--+module Data.Git.Diff.Patience+    ( Item(..)+    , diff+    ) where++import           Data.List+import           Data.Function (on)+import qualified Data.Map      as M+import qualified Data.IntMap   as IM++data Card a = Card !Int a !(Maybe (Card a))++-- sort using patience making stack of card with the list of elements,+-- then take the highest stack (maxView) and flatten the path back into a list+-- to get the longest increasing path+longestIncreasing :: [(Int,a)] -> [(Int,a)]+longestIncreasing =+      maybe [] (flatten . head . fst)+    . IM.maxView+    . foldl' ins IM.empty+  where+    ins :: IM.IntMap [Card a] -> (Int, a) -> IM.IntMap [Card a]+    ins m (x,a) =+        case IM.minViewWithKey gt of+            Nothing        -> IM.insert x [new] m+            Just ((k,_),_) ->+                case IM.updateLookupWithKey (\_ _ -> Nothing) k m of+                    (Just v, mm) -> IM.insert x (new : v) mm+                    (Nothing, _) -> m+      where+            (lt, gt) = IM.split x m+            prev = (head . fst) `fmap` IM.maxView lt+            new  = Card x a prev++    flatten :: Card a -> [(Int, a)]+    flatten (Card x a c) = (x,a) : maybe [] flatten c++-- Type for decomposing a diff problem.  We either have two+-- lines that match, or a recursive subproblem.+data Piece a =+      Match !a !a+    | Diff [a] [a]+    deriving (Show)++-- Get the longest common subsequence+lcs :: Ord t => [t] -> [t] -> [Piece t]+lcs ma mb =+      chop ma mb+    $ longestIncreasing+    $ sortBy (compare `on` snd)+    $ M.elems+    $ M.intersectionWith (,) (unique ma) (unique mb)+  where+    unique = M.mapMaybe id . foldr ins M.empty . zip [0..]+      where+        ins (a,x) = M.insertWith (\_ _ -> Nothing) x (Just a)++    -- Subdivides a diff problem according to the indices of matching lines.+    chop :: [t] -> [t] -> [(Int,Int)] -> [Piece t]+    chop xs ys []+        | null xs && null ys = []+        | otherwise = [Diff xs ys]+    chop xs ys ((nx,ny):ns) =+        let (xsr, (x : xse)) = splitAt nx xs+            (ysr, (y : yse)) = splitAt ny ys+         in  Diff xse yse : Match x y : chop xsr ysr ns++-- | An element of a computed difference.+data Item t =+      Old  !t+    | New  !t+    | Both !t !t+    deriving (Show,Eq)++instance Functor Item where+    fmap f (Old  x)   = Old  (f x)+    fmap f (New  x)   = New  (f x)+    fmap f (Both x y) = Both (f x) (f y)++-- | The difference between two lists using the patience algorithm+diff :: Ord t => [t] -> [t] -> [Item t]+diff = matchPrefix []+  where+    -- match the prefix between old and new document+    matchPrefix acc (x:xs) (y:ys)+        | x == y    = Both x y : matchPrefix acc xs ys+    matchPrefix acc l r = matchSuffix acc (reverse l) (reverse r)++    -- match the suffix between old and new document, accumulating the+    -- matched item in a reverse accumulator to keep TCO+    matchSuffix acc (x:xs) (y:ys)+        | x == y = matchSuffix (Both x y : acc) xs ys+    matchSuffix acc l r = diffInner (reverse acc) (reverse l) (reverse r)++    -- prefix and suffix are striped, and now do the LCS+    diffInner acc l r =+        case lcs l r of+            -- If we fail to subdivide, just record the chunk as is.+            [Diff _ _] -> fmap Old l ++ fmap New r ++ acc+            ps -> recur acc ps++    recur acc [] = acc+    recur acc (Match x y  : ps) = recur (Both x y : acc) ps+    recur acc (Diff xs ys : ps) = recur [] ps ++ matchPrefix acc xs ys
Data/Git/Monad.hs view
@@ -581,8 +581,8 @@ -- -- Example: ----- > withCurrentRepo $--- >    (r, ()) <- withNewCommit person Nothing $ do+-- > withCurrentRepo $ do+-- >    (r, ()) <- withNewCommit person (Nothing :: Maybe (Ref SHA1)) $ do -- >        setMessage "inital commit" -- >        setFile ["README.md"] "# My awesome project\n\nthis is a new project\n" -- >    branchWrite "master" r@@ -592,7 +592,7 @@ -- parent is already set to the Reference associated to the revision. -- You can, change the parents if you wish to erase, or replace, this value. ----- > withCurrentRepo $+-- > withCurrentRepo $ do -- >    readmeContent <- withCommit (Just "master") $ getFile ["README.md"] -- >    (r, ()) <- withNewCommit person (Just "master") $ do -- >        setMessage "update the README"
Data/Git/Named.hs view
@@ -142,7 +142,7 @@         getRefsRecursively dir acc (x:xs) = do             isDir <- isDirectory x             extra <- if isDir-                        then listRefsAcc [] dir+                        then listRefsAcc [] x                         else let r = UTF8.toString $ localPathEncode $ stripRoot x                               in if isValidRefName r                                     then return [fromString r]
Data/Git/Repository.hs view
@@ -42,7 +42,7 @@ import Control.Exception (Exception, throw)  import Data.Maybe (fromMaybe)-import Data.List (find)+import Data.List (find, stripPrefix) import Data.Data import Data.IORef @@ -129,7 +129,11 @@                              "HEAD"       -> [ RefHead ]                              "ORIG_HEAD"  -> [ RefOrigHead ]                              "FETCH_HEAD" -> [ RefFetchHead ]-                             _            -> map (flip ($) (RefName prefix)) [RefTag,RefBranch,RefRemote]+                             _            ->+                                maybe (map (flip ($) (RefName prefix)) [RefTag,RefBranch,RefRemote]) (:[]) $+                                        (RefBranch . RefName <$> stripPrefix "refs/heads/"   prefix)+                                    <|> (RefTag    . RefName <$> stripPrefix "refs/tags/"    prefix)+                                    <|> (RefRemote . RefName <$> stripPrefix "refs/remotes/" prefix)          tryResolvers :: HashAlgorithm hash => [IO (Maybe (Ref hash))] -> IO (Maybe (Ref hash))         tryResolvers []            = return $ if (isHexString prefix)
Data/Git/Storage/Object.hs view
@@ -45,7 +45,6 @@ import Data.Git.Imports import qualified Data.Git.Parser as P -import Data.Byteable (toBytes) import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC@@ -265,7 +264,7 @@     where writeTreeEnt (ModePerm perm,name,ref) =                 [ string7 (printf "%o" perm)                 , string7 " "-                , byteString $ toBytes name+                , byteString $ getEntNameBytes name                 , string7 "\0"                 , byteString $ toBinary ref                 ]
Data/Git/Types.hs view
@@ -19,6 +19,7 @@     , Person(..)     , EntName     , entName+    , getEntNameBytes     , EntPath     , entPathAppend     -- * modeperm type@@ -40,7 +41,6 @@  import Data.Word import Data.Bits-import Data.Byteable import Data.String import Data.ByteString (ByteString) import qualified Data.ByteString as B@@ -147,14 +147,12 @@ type Perm = Word8  -- | Entity name-newtype EntName = EntName ByteString+newtype EntName = EntName { getEntNameBytes :: ByteString }     deriving (Eq,Ord) instance Show EntName where     show (EntName e) = UTF8.toString e instance IsString EntName where     fromString s = entName $ UTF8.fromString s-instance Byteable EntName where-    toBytes (EntName n) = n  entName :: ByteString -> EntName entName bs
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2010-2016 Vincent Hanquez <vincent@snarc.org>+Copyright (c) 2010-2019 Vincent Hanquez <vincent@snarc.org>  All rights reserved. 
README.md view
@@ -7,13 +7,14 @@  git is a reimplementation of git storage and protocol in pure haskell. -what it does do:+What it does do:  * read loose objects, and packed objects. * write new loose objects * git like operations available: commit, cat-file, verify-pack, rev-list, ls-tree.+* diff between commits -what is doesn't do:+What is doesn't do:  * reimplement the whole of git. * checkout's index reading/writing, fetching, merging, diffing.
git.cabal view
@@ -1,5 +1,5 @@ Name:                git-Version:             0.2.2+Version:             0.3.0 Synopsis:            Git operations in haskell Description:     .@@ -29,7 +29,6 @@   Build-Depends:     base >= 4 && < 5                    , basement                    , bytestring >= 0.9-                   , byteable                    , containers                    , memory >= 0.13                    , cryptonite >= 0.22@@ -40,7 +39,6 @@                    , hourglass >= 0.2                    , unix-compat                    , utf8-string-                   , patience                    -- to remove                    , system-filepath                    , system-fileio@@ -58,6 +56,7 @@                      Data.Git.Revision                      Data.Git.Repository                      Data.Git.Diff+                     Data.Git.Diff.Patience   Other-modules:     Data.Git.Internal                      Data.Git.Imports                      Data.Git.OS