Search code examples
githaskellbytestring

Get magic number from git packfile index in Haskell


I'm wanting to get the magic number from a git packfile index to ensure that it is indeed a packfile. The pack format documentation states that the magic number is "/377tOc". When I open the packfile with Ruby for example, I get this back when reading the file:

> File.open("pack-4412d2306cfe9a0b6d1b9b4430abc767022e8a3c.idx").read(4)
=> "\377tOc"

But in Haskell I get this:

> h <- openFile "pack-4412d2306cfe9a0b6d1b9b4430abc767022e8a3c.idx" ReadMode
> Data.ByteString.hGet h 4
=> "\255tOc"

I take it I'm missing something obvious, but it's not clear to me what that is. What am I doing wrong here?


Solution

  • The non-ascii character ('\255') is just being shown in decimal, not octal.

    Confirming, according to od the first 4 bytes are indeed, in octal/ascii or 1 byte decimal:

    > $ od -c foo.idx  | head -1
    0000000 377   t   O   c  \0  \0  \0 002  \0  \0 002 250  \0  \0 005   B
    
    > $ od -t u1 /tmp/x | head -1
    0000000 255 116  79  99   0   0   0   2   0   0   2 168   0   0   5  66
    

    And in Haskell:

    > s <- Data.ByteString.readFile "foo.idx"
    > Data.ByteString.take 4 s
    "\255tOc"
    

    So, just remember that 255 in decimal is 377 in octal.