support sha256 git repos

Git will eventually switch to sha2 and there will not be one single
shaSize anymore, but two (40 and 64).

Changed all parsers for git plumbing output to support both sizes of
shas.

One potential problem this does not deal with is, if somewhere in
git-annex it reads two shas from different sources, and compares them
to see if they're the same sha, it would fail if they're sha1 and sha256
of the same value. I don't know if that will really be a concern.
This commit is contained in:
Joey Hess 2020-01-07 11:35:17 -04:00
parent b5fc1b97f7
commit 5e4deb3620
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
15 changed files with 62 additions and 45 deletions

View file

@ -1,6 +1,6 @@
{- git SHA stuff
-
- Copyright 2011 Joey Hess <id@joeyh.name>
- Copyright 2011,2020 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
@ -21,8 +21,8 @@ getSha subcommand a = maybe bad return =<< extractSha <$> a
- it, but nothing else. -}
extractSha :: String -> Maybe Sha
extractSha s
| len == shaSize = val s
| len == shaSize + 1 && length s' == shaSize = val s'
| len `elem` shaSizes = val s
| len - 1 `elem` shaSizes && length s' == len - 1 = val s'
| otherwise = Nothing
where
len = length s
@ -31,13 +31,30 @@ extractSha s
| all (`elem` "1234567890ABCDEFabcdef") v = Just $ Ref v
| otherwise = Nothing
{- Size of a git sha. -}
shaSize :: Int
shaSize = 40
{- Sizes of git shas. -}
shaSizes :: [Int]
shaSizes =
[ 40 -- sha1 (must come first)
, 64 -- sha256
]
nullSha :: Ref
nullSha = Ref $ replicate shaSize '0'
{- Git plumbing often uses a all 0 sha to represent things like a
- deleted file. -}
nullShas :: [Sha]
nullShas = map (\n -> Ref (replicate n '0')) shaSizes
{- Git's magic empty tree. -}
{- Sha to provide to git plumbing when deleting a file.
-
- It's ok to provide a sha1; git versions that use sha256 will map the
- sha1 to the sha256, or probably just treat all null sha1 specially
- the same as all null sha256. -}
deleteSha :: Sha
deleteSha = Prelude.head nullShas
{- Git's magic empty tree.
-
- It's ok to provide the sha1 of this to git to refer to an empty tree;
- git versions that use sha256 will map the sha1 to the sha256.
-}
emptyTree :: Ref
emptyTree = Ref "4b825dc642cb6eb9a060e54bf8d69288fbee4904"