Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

idx: add findInPackIndex, ght find-idx

Find a specific full SHA in a given pack index file.
  • Loading branch information...
commit 1b9307bca0f606beaf50fec551eae1ca163c9d0b 1 parent 1d21df4
@kfish authored
Showing with 57 additions and 5 deletions.
  1. +38 −4 Git/PackIndex.hs
  2. +19 −1 tools/ght.hs
View
42 Git/PackIndex.hs
@@ -3,6 +3,7 @@
module Git.PackIndex (
dumpRawPackIndex,
+ findInPackIndex,
-- * Paths
idxPath
@@ -11,6 +12,7 @@ module Git.PackIndex (
import Control.Applicative ((<$>))
import Control.Monad (forM_)
import qualified Data.ByteString as BS
+import Data.Ord
import Data.Word (Word32)
import Foreign.Ptr
import Foreign.Storable
@@ -89,6 +91,34 @@ outOfRange :: IO a
outOfRange = error "Index out of range"
------------------------------------------------------------
+
+idxFind :: IDX -> BS.ByteString -> IO (Maybe (IDX, Int))
+idxFind idx sha = idxFind' 0 (idxSize idx)
+ where
+ idxFind' lo hi
+ | lo == hi = do
+ iSha <- idxSha1 idx lo
+ case (sha `compare` iSha) of
+ EQ -> return (Just (idx, lo))
+ _ -> return Nothing
+ | otherwise = do
+ iSha <- idxSha1 idx i
+ case (sha `compare` iSha) of
+ EQ -> return (Just (idx, i))
+ LT -> idxFind' lo i
+ GT -> idxFind' i hi
+ where
+ i = floor ((fromIntegral (lo + hi)) / 2.0)
+
+findInPackIndex :: FilePath -> BS.ByteString -> IO ()
+findInPackIndex fp sha = do
+ idx <- readIdx fp
+ m <- idxFind idx sha
+ case m of
+ Just (_, i) -> putStrLn $ "Found at index " ++ show i
+ Nothing -> putStrLn $ "Not found"
+
+------------------------------------------------------------
-- Debugging
dumpIdx :: IDX -> IO ()
@@ -120,21 +150,25 @@ idxPath idx = gitPath ("objects" </> "pack" </> ("pack-" ++ idx ++ ".idx"))
idxHeader :: Word32
idxHeader = 0xff744f63
-dumpRawPackIndex :: FilePath -> IO String
-dumpRawPackIndex fp = do
+readIdx :: FilePath -> IO IDX
+readIdx fp = do
(ptr, rawsize, offset, size) <- mmapFilePtr fp ReadOnly Nothing
let start :: Ptr (BigEndian Word32)
start = ptr `plusPtr` offset
BE hdr <- peek start
- idx <- if (hdr == idxHeader)
+ if (hdr == idxHeader)
then do
BE ver <- peekElemOff start 1
case ver of
2 -> mkIDX2 start size
_ -> error "Unknown version"
else mkIDX1 start size
+
+dumpRawPackIndex :: FilePath -> IO String
+dumpRawPackIndex fp = do
+ idx <- readIdx fp
dumpIdx idx
- return $ "Mapped region offset " ++ (show offset) ++ " size " ++ (show size)
+ return "Woot"
mkIDX1 :: Ptr (BigEndian Word32) -> Int -> IO IDX
mkIDX1 start size = do
View
20 tools/ght.hs
@@ -14,6 +14,7 @@ import Git.Commit
import Git.Pack
import Git.PackIndex
import Git.Path
+import Git.SHA
-- show-prefix, show-root use these
import System.FilePath
@@ -171,6 +172,23 @@ fIdx (idx:_) = do
else idxPath idx
------------------------------------------------------------
+-- find-idx
+--
+
+ghtFindIdx = defCmd {
+ cmdName = "find-idx",
+ cmdHandler = ghtFindIdxHandler,
+ cmdCategory = "Blob management",
+ cmdShortDesc = "Find a SHA in a pack index",
+ cmdExamples = [("Find SHA1 333fff in pack-abcd.idx", "abcd 333fff")]
+ }
+
+ghtFindIdxHandler = do
+ (fp:sha:_) <- appArgs
+ fp' <- liftIO $ fIdx [fp]
+ liftIO $ findInPackIndex fp' (readDigestBS sha)
+
+------------------------------------------------------------
-- show-raw
--
@@ -242,7 +260,7 @@ ght = def {
appCategories = ["Reporting", "Blob management"],
appSeeAlso = ["git"],
appProject = "Ght",
- appCmds = [ghtShowPrefix, ghtShowRoot, ghtShow, ghtLog, ghtShowRaw, ghtShowPack, ghtShowIdx, ghtHashObject, ghtBranch]
+ appCmds = [ghtShowPrefix, ghtShowRoot, ghtShow, ghtLog, ghtShowRaw, ghtShowPack, ghtShowIdx, ghtFindIdx, ghtHashObject, ghtBranch]
}
longDesc = "This is a bunch of trivial routines for inspecting git repositories. It is in no way useful beyond that."
Please sign in to comment.
Something went wrong with that request. Please try again.