Commits

Stefan Saasen committed d54af8d

Move the modules related to remote operations into the Git.Remote namespace

  • Participants
  • Parent commits 09b7402

Comments (0)

Files changed (10)

File src/Git/Common.hs

   , isMsbSet
   , eitherToMaybe
   , GitRepository(..)
+  , Ref(..)
   , ObjectId
   , WithRepository
   , fromOctets
 ) where
 
+import qualified Data.ByteString.Char8 as C
 import Control.Monad.Reader
 import Text.Printf      (printf)
 import Numeric          (showHex)
 
 type WithRepository = ReaderT GitRepository IO
 
+data Ref = Ref {
+    getObjId        :: C.ByteString
+  , getRefName      :: C.ByteString
+} deriving (Show, Eq)
+
 data GitRepository = GitRepository {
     getName         :: String
 } deriving (Show, Eq)

File src/Git/PackProtocol.hs

-{-# LANGUAGE OverloadedStrings #-}
-
-module Git.PackProtocol(
-    parsePacket
-  , toRef
-  , PacketLine(..)
-  , Ref(..)
-) where
-
-
-import qualified Data.Attoparsec.Lazy as AL
-import qualified Data.Attoparsec.Char8 as AC
-import qualified Data.ByteString.Char8 as C
-import qualified Data.ByteString.Lazy.Char8 as L
-import Data.Attoparsec.Combinator
-import Data.Attoparsec.Char8 hiding (char, space, take)
-import Data.Maybe
-
-data Ref = Ref {
-    getObjId        :: C.ByteString
-  , getRefName      :: C.ByteString
-} deriving (Show, Eq)
-
-data PacketLine = FirstLine {
-    objId           :: C.ByteString
-   ,ref             :: C.ByteString
-   ,capabilities    :: [C.ByteString]
-} | RefLine {
-    objId           :: C.ByteString
-   ,ref             :: C.ByteString
-} | NullLine {
-    zeroId          :: C.ByteString
-} deriving (Show, Eq)
-
-toRef :: PacketLine -> Maybe Ref
-toRef (FirstLine oId r _)   = Just (Ref oId r)
-toRef (RefLine oId r)       = Just (Ref oId r)
-toRef _                     = Nothing
-
-
-parsePacket :: L.ByteString -> [PacketLine]
-parsePacket line = fromMaybe [] $ AL.maybeResult $ AL.parse parseLines line
-
-parseLines :: Parser [PacketLine]
-parseLines = parseLine `sepBy` AC.char '\n'
-
-parseLine :: Parser PacketLine
-parseLine = choice [parseFirstLine, parseRef]
-
-
-parseFirstLine :: Parser PacketLine
-parseFirstLine = do
-    objId' <- AC.take 40
-    space
-    ref' <- takeTill (== '\0')
-    nul
-    capabilities' <- takeTill (== '\n')
-    return $ FirstLine objId' ref' (C.split ' ' capabilities')
-
-parseRef :: Parser PacketLine
-parseRef = do
-    objId' <- AC.take 40
-    space
-    ref' <- takeTill (== '\n')
-    return $ RefLine objId' ref'
-
-space, nul :: Parser Char
-space       = satisfy (== ' ')
-nul         = satisfy (== '\0')
-

File src/Git/Remote.hs

-{-# LANGUAGE OverloadedStrings, BangPatterns, RecordWildCards #-}
-
-module Git.Remote(
-    clone
-  , lsRemote
-  , parseRemote
-  , Remote(..)
-) where
-
-import qualified Data.Attoparsec.Char8 as AC
-import Data.Attoparsec.Combinator
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Char8 as C
-import qualified Data.ByteString.Lazy as L
-import Control.Applicative                      ((<$>))
-import Control.Monad.Reader                     (runReaderT)
-import System.Directory                         (removeFile, createDirectoryIfMissing)
-import System.FilePath                          ((</>), takeFileName, dropExtension)
-import Network.Socket                           (withSocketsDo)
-import System.IO                                (hPutStr, stderr, hFlush)
-import Text.Printf
-import Data.Maybe
-import Data.List
-import Git.Common
-import Git.TcpClient
-import Git.PackProtocol
-import Git.Store.ObjectStore
-import Git.Repository
-
-data Remote = Remote {
-    getHost         :: String
-  , getPort         :: Maybe Int
-  , getRepository   :: String
-} deriving (Eq, Show)
-
--- | Parse a URL that is using the git protocol format.
--- E.g. git://git.apache.org:9418/foo.git
---
--- Schema:
---   * git://host.xz[:port]/path/to/repo.git/
---   * git://host.xz[:port]/~[user]/path/to/repo.git/
---
--- See the "GIT URLS" section on
--- http://www.kernel.org/pub/software/scm/git/docs/git-clone.html
-parseRemote :: B.ByteString -> Maybe Remote
-parseRemote = eitherToMaybe . AC.parseOnly parser
-    where parser = do
-            host <- "git://" AC..*> domain
-            port <- option Nothing (Just <$> (":" AC..*> AC.decimal))
-            slash
-            repo <- AC.takeByteString
-            return $ Remote (C.unpack host) port (C.unpack repo)
-          domain = AC.takeTill (\x -> x == '/' || x == ':')
-          slash  = AC.satisfy (== '/')
-
--- | Clone the given git repository (only the git protocol is currently
--- supported) into a new directory.
---
--- <url> The git URL to clone from
--- [<directory>] The name of the directory to clone into (optional)
-clone :: String -> Maybe String -> IO ()
-clone url maybeDirectory =
-    case parseRemote $ C.pack url of
-        Just remote -> let gitRepoName = fromMaybe (repositoryName remote) maybeDirectory
-                       in clone' (GitRepository gitRepoName) remote
-        _           -> putStrLn $ "Invalid URL" ++ url
-
-clone' :: GitRepository -> Remote -> IO ()
-clone' repo remote@Remote{..} = do
-        (refs,packFile) <- receivePack remote
-        let dir = pathForPack repo
-            -- E.g. in native git this is something like .git/objects/pack/tmp_pack_6bo2La
-            tmpPack = dir </> "tmp_pack_incoming"
-        _ <- createDirectoryIfMissing True dir
-        B.writeFile tmpPack packFile
-        _ <- runReaderT (createGitRepositoryFromPackfile tmpPack refs) repo
-        removeFile tmpPack
-        runReaderT checkoutHead repo
-
--- | List references in a remote repository
-lsRemote :: String -> IO ()
-lsRemote url =
-    case parseRemote $ C.pack url of
-        Just remote -> do
-            packetLines <- lsRemote' remote
-            mapM_ (\line -> printf "%s\t%s\n" (C.unpack $ objId line) (C.unpack $ ref line)) packetLines
-        _           -> putStrLn $ "Invalid URL" ++ url
-
-lsRemote' :: Remote -> IO [PacketLine]
-lsRemote' Remote{..} = withSocketsDo $
-    withConnection getHost (show $ fromMaybe 9418 getPort) $ \sock -> do
-        let payload = refDiscovery getHost getRepository
-        send sock payload
-        response <- receive sock
-        send sock flushPkt -- Tell the server to disconnect
-        return $ parsePacket $ L.fromChunks [response]
-
-refDiscovery :: String -> String -> String
-refDiscovery host repo = pktLine $ "git-upload-pack /" ++ repo ++ "\0host="++host++"\0"
-
-repositoryName :: Remote -> String
-repositoryName = takeFileName . dropExtension . getRepository
-
-toObjId :: PacketLine -> Maybe String
-toObjId (FirstLine obj _ _) = Just $ C.unpack obj
-toObjId (RefLine obj _)     = Just $ C.unpack obj
-toObjId _                   = Nothing
-
-
--- PKT-LINE("want" SP obj-id SP capability-list LF)
--- PKT-LINE("want" SP obj-id LF)
-createNegotiationRequest :: [String] -> [PacketLine] -> String
-createNegotiationRequest capabilities = concatMap (++ "") . nub . map (pktLine . (++ "\n")) . foldl' (\acc e -> if null acc then first acc e else additional acc e) [] . wants . filter filterPeeledTags . filter filterRefs
-                    where wants              = mapMaybe toObjId
-                          first acc obj      = acc ++ ["want " ++ obj ++ " " ++ unwords capabilities]
-                          additional acc obj = acc ++ ["want " ++ obj]
-                          filterPeeledTags   = not . isSuffixOf "^{}" . C.unpack . ref
-                          filterRefs line    = let r = C.unpack $ ref line
-                                                   predicates = map ($ r) [isPrefixOf "refs/tags/", isPrefixOf "refs/heads/"]
-                                               in or predicates
-
-
-
-receivePack :: Remote -> IO ([Ref], B.ByteString)
-receivePack Remote{..} = withSocketsDo $
-    withConnection getHost (show $ fromMaybe 9418 getPort) $ \sock -> do
-        let payload = refDiscovery getHost getRepository
-        send sock payload
-        response <- receive sock
-        let pack    = parsePacket $ L.fromChunks [response]
-            request = createNegotiationRequest ["multi_ack_detailed",
-                        "side-band-64k",
-                        "agent=git/1.8.1"] pack ++ flushPkt ++ pktLine "done\n"
-        send sock request
-        !rawPack <- receiveWithSideband sock (printSideband . C.unpack)
-        return (mapMaybe toRef pack, rawPack)
-    where printSideband str = do
-                        hPutStr stderr str
-                        hFlush stderr

File src/Git/Remote/Operations.hs

+{-# LANGUAGE OverloadedStrings, BangPatterns, RecordWildCards #-}
+
+module Git.Remote.Operations (
+    clone
+  , lsRemote
+  , parseRemote
+  , Remote(..)
+) where
+
+import qualified Data.Attoparsec.Char8 as AC
+import Data.Attoparsec.Combinator
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Char8 as C
+import qualified Data.ByteString.Lazy as L
+import Control.Applicative                      ((<$>))
+import Control.Monad.Reader                     (runReaderT)
+import System.Directory                         (removeFile, createDirectoryIfMissing)
+import System.FilePath                          ((</>), takeFileName, dropExtension)
+import Network.Socket                           (withSocketsDo)
+import System.IO                                (hPutStr, stderr, hFlush)
+import Text.Printf
+import Data.Maybe
+import Data.List
+import Git.Common
+import Git.Remote.TcpClient
+import Git.Remote.PackProtocol
+import Git.Store.ObjectStore
+import Git.Repository
+
+data Remote = Remote {
+    getHost         :: String
+  , getPort         :: Maybe Int
+  , getRepository   :: String
+} deriving (Eq, Show)
+
+-- | Parse a URL that is using the git protocol format.
+-- E.g. git://git.apache.org:9418/foo.git
+--
+-- Schema:
+--   * git://host.xz[:port]/path/to/repo.git/
+--   * git://host.xz[:port]/~[user]/path/to/repo.git/
+--
+-- See the "GIT URLS" section on
+-- http://www.kernel.org/pub/software/scm/git/docs/git-clone.html
+parseRemote :: B.ByteString -> Maybe Remote
+parseRemote = eitherToMaybe . AC.parseOnly parser
+    where parser = do
+            host <- "git://" AC..*> domain
+            port <- option Nothing (Just <$> (":" AC..*> AC.decimal))
+            slash
+            repo <- AC.takeByteString
+            return $ Remote (C.unpack host) port (C.unpack repo)
+          domain = AC.takeTill (\x -> x == '/' || x == ':')
+          slash  = AC.satisfy (== '/')
+
+-- | Clone the given git repository (only the git protocol is currently
+-- supported) into a new directory.
+--
+-- <url> The git URL to clone from
+-- [<directory>] The name of the directory to clone into (optional)
+clone :: String -> Maybe String -> IO ()
+clone url maybeDirectory =
+    case parseRemote $ C.pack url of
+        Just remote -> let gitRepoName = fromMaybe (repositoryName remote) maybeDirectory
+                       in clone' (GitRepository gitRepoName) remote
+        _           -> putStrLn $ "Invalid URL" ++ url
+
+clone' :: GitRepository -> Remote -> IO ()
+clone' repo remote@Remote{..} = do
+        (refs,packFile) <- receivePack remote
+        let dir = pathForPack repo
+            -- E.g. in native git this is something like .git/objects/pack/tmp_pack_6bo2La
+            tmpPack = dir </> "tmp_pack_incoming"
+        _ <- createDirectoryIfMissing True dir
+        B.writeFile tmpPack packFile
+        _ <- runReaderT (createGitRepositoryFromPackfile tmpPack refs) repo
+        removeFile tmpPack
+        runReaderT checkoutHead repo
+
+-- | List references in a remote repository
+lsRemote :: String -> IO ()
+lsRemote url =
+    case parseRemote $ C.pack url of
+        Just remote -> do
+            packetLines <- lsRemote' remote
+            mapM_ (\line -> printf "%s\t%s\n" (C.unpack $ objId line) (C.unpack $ ref line)) packetLines
+        _           -> putStrLn $ "Invalid URL" ++ url
+
+lsRemote' :: Remote -> IO [PacketLine]
+lsRemote' Remote{..} = withSocketsDo $
+    withConnection getHost (show $ fromMaybe 9418 getPort) $ \sock -> do
+        let payload = refDiscovery getHost getRepository
+        send sock payload
+        response <- receive sock
+        send sock flushPkt -- Tell the server to disconnect
+        return $ parsePacket $ L.fromChunks [response]
+
+refDiscovery :: String -> String -> String
+refDiscovery host repo = pktLine $ "git-upload-pack /" ++ repo ++ "\0host="++host++"\0"
+
+repositoryName :: Remote -> String
+repositoryName = takeFileName . dropExtension . getRepository
+
+toObjId :: PacketLine -> Maybe String
+toObjId (FirstLine obj _ _) = Just $ C.unpack obj
+toObjId (RefLine obj _)     = Just $ C.unpack obj
+toObjId _                   = Nothing
+
+
+-- PKT-LINE("want" SP obj-id SP capability-list LF)
+-- PKT-LINE("want" SP obj-id LF)
+createNegotiationRequest :: [String] -> [PacketLine] -> String
+createNegotiationRequest capabilities = concatMap (++ "") . nub . map (pktLine . (++ "\n")) . foldl' (\acc e -> if null acc then first acc e else additional acc e) [] . wants . filter filterPeeledTags . filter filterRefs
+                    where wants              = mapMaybe toObjId
+                          first acc obj      = acc ++ ["want " ++ obj ++ " " ++ unwords capabilities]
+                          additional acc obj = acc ++ ["want " ++ obj]
+                          filterPeeledTags   = not . isSuffixOf "^{}" . C.unpack . ref
+                          filterRefs line    = let r = C.unpack $ ref line
+                                                   predicates = map ($ r) [isPrefixOf "refs/tags/", isPrefixOf "refs/heads/"]
+                                               in or predicates
+
+
+
+receivePack :: Remote -> IO ([Ref], B.ByteString)
+receivePack Remote{..} = withSocketsDo $
+    withConnection getHost (show $ fromMaybe 9418 getPort) $ \sock -> do
+        let payload = refDiscovery getHost getRepository
+        send sock payload
+        response <- receive sock
+        let pack    = parsePacket $ L.fromChunks [response]
+            request = createNegotiationRequest ["multi_ack_detailed",
+                        "side-band-64k",
+                        "agent=git/1.8.1"] pack ++ flushPkt ++ pktLine "done\n"
+        send sock request
+        !rawPack <- receiveWithSideband sock (printSideband . C.unpack)
+        return (mapMaybe toRef pack, rawPack)
+    where printSideband str = do
+                        hPutStr stderr str
+                        hFlush stderr

File src/Git/Remote/PackProtocol.hs

+{-# LANGUAGE OverloadedStrings #-}
+
+module Git.Remote.PackProtocol (
+    parsePacket
+  , toRef
+  , PacketLine(..)
+) where
+
+
+import qualified Data.Attoparsec.Lazy as AL
+import qualified Data.Attoparsec.Char8 as AC
+import qualified Data.ByteString.Char8 as C
+import qualified Data.ByteString.Lazy.Char8 as L
+import Data.Attoparsec.Combinator
+import Data.Attoparsec.Char8 hiding (char, space, take)
+import Data.Maybe
+import Git.Common                   (Ref(..))
+
+data PacketLine = FirstLine {
+    objId           :: C.ByteString
+   ,ref             :: C.ByteString
+   ,capabilities    :: [C.ByteString]
+} | RefLine {
+    objId           :: C.ByteString
+   ,ref             :: C.ByteString
+} | NullLine {
+    zeroId          :: C.ByteString
+} deriving (Show, Eq)
+
+toRef :: PacketLine -> Maybe Ref
+toRef (FirstLine oId r _)   = Just (Ref oId r)
+toRef (RefLine oId r)       = Just (Ref oId r)
+toRef _                     = Nothing
+
+
+parsePacket :: L.ByteString -> [PacketLine]
+parsePacket line = fromMaybe [] $ AL.maybeResult $ AL.parse parseLines line
+
+parseLines :: Parser [PacketLine]
+parseLines = parseLine `sepBy` AC.char '\n'
+
+parseLine :: Parser PacketLine
+parseLine = choice [parseFirstLine, parseRef]
+
+
+parseFirstLine :: Parser PacketLine
+parseFirstLine = do
+    objId' <- AC.take 40
+    space
+    ref' <- takeTill (== '\0')
+    nul
+    capabilities' <- takeTill (== '\n')
+    return $ FirstLine objId' ref' (C.split ' ' capabilities')
+
+parseRef :: Parser PacketLine
+parseRef = do
+    objId' <- AC.take 40
+    space
+    ref' <- takeTill (== '\n')
+    return $ RefLine objId' ref'
+
+space, nul :: Parser Char
+space       = satisfy (== ' ')
+nul         = satisfy (== '\0')
+

File src/Git/Remote/TcpClient.hs

+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, BangPatterns #-}
+
+-- | A git compatible TcpClient that understands the git packet line format.
+module Git.Remote.TcpClient (
+   withConnection
+ , send
+ , receiveWithSideband
+ , receiveFully
+ , receive
+) where
+
+import qualified Data.ByteString.Char8 as C
+import qualified Data.ByteString as B
+import Network.Socket hiding                    (recv, send)
+import Network.Socket.ByteString                (recv, sendAll)
+import Data.Monoid                              (mempty, mappend)
+import Numeric                                  (readHex)
+
+withConnection :: HostName -> ServiceName -> (Socket -> IO b) -> IO b
+withConnection host port consumer = do
+    sock <- openConnection host port
+    r <- consumer sock
+    sClose sock
+    return r
+
+
+send :: Socket -> String -> IO ()
+send sock msg = sendAll sock $ C.pack msg
+
+
+-- | Read from the socket until the peer closes its half side of the
+-- connection.
+receiveFully :: Socket -> IO C.ByteString
+receiveFully sock = receive' sock mempty
+   where receive' s acc = do
+            msg <- recv s 4096
+            if C.null msg then return acc else receive' s $ mappend acc msg
+
+
+-- see sideband.c
+-- FIXME: the git client prepends "remote: " to the output coming from the
+-- remote
+receiveWithSideband :: Socket -> (B.ByteString -> IO a) -> IO B.ByteString
+receiveWithSideband sock f = recrec mempty
+    where recrec acc = do
+            !maybeLine <- readPacketLine sock
+            let skip = recrec acc
+            case maybeLine of
+                Just "NAK\n" -> skip -- ignore here...
+                Just line -> case B.uncons line of
+                                Just (1, rest)  -> recrec (acc `mappend` rest)
+                                Just (2, rest)  -> f ("remote: " `C.append` rest) >> skip -- FIXME - scan for linebreaks and prepend "remote: " accordingly (see sideband.c)
+                                Just (_, rest)  -> fail $ C.unpack rest
+                                Nothing         -> skip
+                Nothing   -> return acc
+
+-- | Read packet lines.
+receive :: Socket -> IO C.ByteString
+receive sock = receive' sock mempty
+    where receive' s acc = do
+            maybeLine <- readPacketLine s
+            maybe (return acc) (receive' s . mappend acc) maybeLine
+
+-- =================================================================================
+
+openConnection :: HostName -> ServiceName -> IO Socket
+openConnection host port = do
+        addrinfos <- getAddrInfo Nothing (Just host) (Just port)
+        let serveraddr = head addrinfos
+        sock <- socket (addrFamily serveraddr) Stream defaultProtocol
+        connect sock (addrAddress serveraddr)
+        return sock
+
+-- | Read a packet line
+readPacketLine :: Socket -> IO (Maybe C.ByteString)
+readPacketLine sock = do
+        msg <- loop C.empty 4 -- check for a zero length return -> disconnected
+        if C.null msg then return Nothing else
+            case readHex $ C.unpack msg of
+                ((l,_):_) | l > 4 -> do
+                     line <- loop C.empty (l-4)
+                     return $ Just line
+                _ -> return Nothing
+    where loop acc expected = do
+            line <- recv sock expected
+            let len  = C.length line
+                acc' = acc `C.append` line
+                cont = len /= expected && not (C.null line)
+            if cont then loop acc' (expected - len) else return acc'
+
+{-
+If 'side-band' or 'side-band-64k' capabilities have been specified by
+the client, the server will send the packfile data multiplexed.
+
+Each packet starting with the packet-line length of the amount of data
+that follows, followed by a single byte specifying the sideband the
+following data is coming in on.
+
+In 'side-band' mode, it will send up to 999 data bytes plus 1 control
+code, for a total of up to 1000 bytes in a pkt-line.  In 'side-band-64k'
+mode it will send up to 65519 data bytes plus 1 control code, for a
+total of up to 65520 bytes in a pkt-line.
+
+The sideband byte will be a '1', '2' or a '3'. Sideband '1' will contain
+packfile data, sideband '2' will be used for progress information that the
+client will generally print to stderr and sideband '3' is used for error
+information.
+
+If no 'side-band' capability was specified, the server will stream the
+entire packfile without multiplexing.
+-}

File src/Git/Store/ObjectStore.hs

 import Text.Printf                                          (printf)
 import Git.Pack.Packfile
 import Git.Pack.Delta                                       (patch)
-import Git.Common                                           (GitRepository(..), ObjectId, WithRepository)
-import Git.PackProtocol                                     (Ref(..))
+import Git.Common                                           (GitRepository(..), ObjectId, WithRepository, Ref(..))
 -- Tree
 import Git.Store.Blob
 import System.FilePath

File src/Git/TcpClient.hs

-{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, BangPatterns #-}
-
--- | A git compatible TcpClient that understands the git packet line format.
-module Git.TcpClient (
-   withConnection
- , send
- , receiveWithSideband
- , receiveFully
- , receive
-) where
-
-import qualified Data.ByteString.Char8 as C
-import qualified Data.ByteString as B
-import Network.Socket hiding                    (recv, send)
-import Network.Socket.ByteString                (recv, sendAll)
-import Data.Monoid                              (mempty, mappend)
-import Numeric                                  (readHex)
-
-withConnection :: HostName -> ServiceName -> (Socket -> IO b) -> IO b
-withConnection host port consumer = do
-    sock <- openConnection host port
-    r <- consumer sock
-    sClose sock
-    return r
-
-
-send :: Socket -> String -> IO ()
-send sock msg = sendAll sock $ C.pack msg
-
-
--- | Read from the socket until the peer closes its half side of the
--- connection.
-receiveFully :: Socket -> IO C.ByteString
-receiveFully sock = receive' sock mempty
-   where receive' s acc = do
-            msg <- recv s 4096
-            if C.null msg then return acc else receive' s $ mappend acc msg
-
-
--- see sideband.c
--- FIXME: the git client prepends "remote: " to the output coming from the
--- remote
-receiveWithSideband :: Socket -> (B.ByteString -> IO a) -> IO B.ByteString
-receiveWithSideband sock f = recrec mempty
-    where recrec acc = do
-            !maybeLine <- readPacketLine sock
-            let skip = recrec acc
-            case maybeLine of
-                Just "NAK\n" -> skip -- ignore here...
-                Just line -> case B.uncons line of
-                                Just (1, rest)  -> recrec (acc `mappend` rest)
-                                Just (2, rest)  -> f ("remote: " `C.append` rest) >> skip -- FIXME - scan for linebreaks and prepend "remote: " accordingly (see sideband.c)
-                                Just (_, rest)  -> fail $ C.unpack rest
-                                Nothing         -> skip
-                Nothing   -> return acc
-
--- | Read packet lines.
-receive :: Socket -> IO C.ByteString
-receive sock = receive' sock mempty
-    where receive' s acc = do
-            maybeLine <- readPacketLine s
-            maybe (return acc) (receive' s . mappend acc) maybeLine
-
--- =================================================================================
-
-openConnection :: HostName -> ServiceName -> IO Socket
-openConnection host port = do
-        addrinfos <- getAddrInfo Nothing (Just host) (Just port)
-        let serveraddr = head addrinfos
-        sock <- socket (addrFamily serveraddr) Stream defaultProtocol
-        connect sock (addrAddress serveraddr)
-        return sock
-
--- | Read a packet line
-readPacketLine :: Socket -> IO (Maybe C.ByteString)
-readPacketLine sock = do
-        msg <- loop C.empty 4 -- check for a zero length return -> disconnected
-        if C.null msg then return Nothing else
-            case readHex $ C.unpack msg of
-                ((l,_):_) | l > 4 -> do
-                     line <- loop C.empty (l-4)
-                     return $ Just line
-                _ -> return Nothing
-    where loop acc expected = do
-            line <- recv sock expected
-            let len  = C.length line
-                acc' = acc `C.append` line
-                cont = len /= expected && not (C.null line)
-            if cont then loop acc' (expected - len) else return acc'
-
-{-
-If 'side-band' or 'side-band-64k' capabilities have been specified by
-the client, the server will send the packfile data multiplexed.
-
-Each packet starting with the packet-line length of the amount of data
-that follows, followed by a single byte specifying the sideband the
-following data is coming in on.
-
-In 'side-band' mode, it will send up to 999 data bytes plus 1 control
-code, for a total of up to 1000 bytes in a pkt-line.  In 'side-band-64k'
-mode it will send up to 65519 data bytes plus 1 control code, for a
-total of up to 65520 bytes in a pkt-line.
-
-The sideband byte will be a '1', '2' or a '3'. Sideband '1' will contain
-packfile data, sideband '2' will be used for progress information that the
-client will generally print to stderr and sideband '3' is used for error
-information.
-
-If no 'side-band' capability was specified, the server will stream the
-entire packfile without multiplexing.
--}
 module Main where
 
-import System.Environment   (getArgs)
-import Data.Maybe           (listToMaybe)
-import Git.Remote
+import System.Environment       (getArgs)
+import Data.Maybe               (listToMaybe)
+import Git.Remote.Operations
 import Git.Unpack
 
 main :: IO ()

File tests/src/Git/RemoteTests.hs

   ) where
 
 import qualified Test.HUnit as H
-import Git.Remote
+import Git.Remote.Operations
 import Test.QuickCheck hiding ((.&.))
 import Test.Framework (Test, defaultMain, testGroup)
 import Test.Framework.Providers.QuickCheck2 (testProperty)