add support for staging other types of blobs, like symlinks, into the index
Also added a utility TopFilePath type, which could stand to be used more widely.
This commit is contained in:
parent
993e6459a3
commit
91db540769
4 changed files with 53 additions and 7 deletions
34
Git/FilePath.hs
Normal file
34
Git/FilePath.hs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{- git FilePath library
|
||||||
|
-
|
||||||
|
- Different git commands use different types of FilePaths to refer to
|
||||||
|
- files in the repository. Some commands use paths relative to the
|
||||||
|
- top of the repository even when run in a subdirectory. Adding some
|
||||||
|
- types helps keep that straight.
|
||||||
|
-
|
||||||
|
- Copyright 2012 Joey Hess <joey@kitenet.net>
|
||||||
|
-
|
||||||
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Git.FilePath (
|
||||||
|
TopFilePath,
|
||||||
|
getTopFilePath,
|
||||||
|
toTopFilePath,
|
||||||
|
asTopFilePath,
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Common
|
||||||
|
import Git
|
||||||
|
|
||||||
|
{- A FilePath, relative to the top of the git repository. -}
|
||||||
|
newtype TopFilePath = TopFilePath { getTopFilePath :: FilePath }
|
||||||
|
|
||||||
|
{- The input FilePath can be absolute, or relative to the CWD. -}
|
||||||
|
toTopFilePath :: FilePath -> Git.Repo -> IO TopFilePath
|
||||||
|
toTopFilePath file repo = TopFilePath <$>
|
||||||
|
relPathDirToFile (repoPath repo) <$> absPath file
|
||||||
|
|
||||||
|
{- The input FilePath must already be relative to the top of the git
|
||||||
|
- repository -}
|
||||||
|
asTopFilePath :: FilePath -> TopFilePath
|
||||||
|
asTopFilePath file = TopFilePath file
|
|
@ -63,3 +63,11 @@ readObjectType "commit" = Just CommitObject
|
||||||
readObjectType "tree" = Just TreeObject
|
readObjectType "tree" = Just TreeObject
|
||||||
readObjectType _ = Nothing
|
readObjectType _ = Nothing
|
||||||
|
|
||||||
|
{- Types of blobs. -}
|
||||||
|
data BlobType = FileBlob | ExecutableBlob | SymlinkBlob
|
||||||
|
|
||||||
|
{- Git uses magic numbers to denote the type of a blob. -}
|
||||||
|
instance Show BlobType where
|
||||||
|
show FileBlob = "100644"
|
||||||
|
show ExecutableBlob = "100755"
|
||||||
|
show SymlinkBlob = "120000"
|
||||||
|
|
|
@ -22,6 +22,7 @@ import Git.Command
|
||||||
import Git.UpdateIndex
|
import Git.UpdateIndex
|
||||||
import Git.HashObject
|
import Git.HashObject
|
||||||
import Git.Types
|
import Git.Types
|
||||||
|
import Git.FilePath
|
||||||
|
|
||||||
{- Performs a union merge between two branches, staging it in the index.
|
{- Performs a union merge between two branches, staging it in the index.
|
||||||
- Any previously staged changes in the index will be lost.
|
- Any previously staged changes in the index will be lost.
|
||||||
|
@ -79,7 +80,7 @@ mergeFile info file h repo = case filter (/= nullSha) [Ref asha, Ref bsha] of
|
||||||
[_colonmode, _bmode, asha, bsha, _status] = words info
|
[_colonmode, _bmode, asha, bsha, _status] = words info
|
||||||
getcontents s = map L.unpack . L.lines .
|
getcontents s = map L.unpack . L.lines .
|
||||||
L.decodeUtf8 <$> catObject h s
|
L.decodeUtf8 <$> catObject h s
|
||||||
use sha = return $ Just $ update_index_line sha file
|
use sha = return $ Just $ update_index_line sha FileBlob $ asTopFilePath file
|
||||||
|
|
||||||
{- Calculates a union merge between a list of refs, with contents.
|
{- Calculates a union merge between a list of refs, with contents.
|
||||||
-
|
-
|
||||||
|
|
|
@ -8,15 +8,17 @@
|
||||||
module Git.UpdateIndex (
|
module Git.UpdateIndex (
|
||||||
Streamer,
|
Streamer,
|
||||||
stream_update_index,
|
stream_update_index,
|
||||||
|
ls_tree,
|
||||||
update_index_line,
|
update_index_line,
|
||||||
ls_tree
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import System.Cmd.Utils
|
import System.Cmd.Utils
|
||||||
|
|
||||||
import Common
|
import Common
|
||||||
import Git
|
import Git
|
||||||
|
import Git.Types
|
||||||
import Git.Command
|
import Git.Command
|
||||||
|
import Git.FilePath
|
||||||
|
|
||||||
{- Streamers are passed a callback and should feed it lines in the form
|
{- Streamers are passed a callback and should feed it lines in the form
|
||||||
- read by update-index, and generated by ls-tree. -}
|
- read by update-index, and generated by ls-tree. -}
|
||||||
|
@ -37,13 +39,14 @@ stream_update_index repo as = do
|
||||||
hPutStr h s
|
hPutStr h s
|
||||||
hPutStr h "\0"
|
hPutStr h "\0"
|
||||||
|
|
||||||
{- Generates a line suitable to be fed into update-index, to add
|
|
||||||
- a given file with a given sha. -}
|
|
||||||
update_index_line :: Sha -> FilePath -> String
|
|
||||||
update_index_line sha file = "100644 blob " ++ show sha ++ "\t" ++ file
|
|
||||||
|
|
||||||
{- Gets the current tree for a ref. -}
|
{- Gets the current tree for a ref. -}
|
||||||
ls_tree :: Ref -> Repo -> Streamer
|
ls_tree :: Ref -> Repo -> Streamer
|
||||||
ls_tree (Ref x) repo streamer = mapM_ streamer =<< pipeNullSplit params repo
|
ls_tree (Ref x) repo streamer = mapM_ streamer =<< pipeNullSplit params repo
|
||||||
where
|
where
|
||||||
params = map Param ["ls-tree", "-z", "-r", "--full-tree", x]
|
params = map Param ["ls-tree", "-z", "-r", "--full-tree", x]
|
||||||
|
|
||||||
|
{- Generates a line suitable to be fed into update-index, to add
|
||||||
|
- a given file with a given sha. -}
|
||||||
|
update_index_line :: Sha -> BlobType -> TopFilePath -> String
|
||||||
|
update_index_line sha filetype file =
|
||||||
|
show filetype ++ " blob " ++ show sha ++ "\t" ++ getTopFilePath file
|
||||||
|
|
Loading…
Add table
Reference in a new issue