git-remote-annex: mostly implemented pushing

Full pushing will probably work, but is untested.
Incremental pushing is not implemented yet.

While a fairly straightforward port of the shell prototype, the details
of exactly how to get the objects to the remote were tricky. And the
prototype did not consider how to deal with partial failures and
interruptions.

I've taken considerable care to make sure it always leaves things in a
consistent state when interrupted or when it loses access to a remote in
the middle of a push.

Sponsored-by: Leon Schuermann on Patreon
This commit is contained in:
Joey Hess 2024-05-09 16:11:16 -04:00
parent 797f27ab05
commit f2d17cf154
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
3 changed files with 254 additions and 14 deletions

View file

@ -174,8 +174,9 @@ forEachRef ps repo = map gen . S8.lines <$>
gen l = let (r, b) = separate' (== fromIntegral (ord ' ')) l
in (Ref r, Ref b)
{- Deletes a ref. This can delete refs that are not branches,
- which git branch --delete refuses to delete. -}
{- Deletes a ref when it contains the specified sha.
- This can delete refs that are not branches, which
- git branch --delete refuses to delete. -}
delete :: Sha -> Ref -> Repo -> IO ()
delete oldvalue ref = run
[ Param "update-ref"
@ -184,6 +185,14 @@ delete oldvalue ref = run
, Param $ fromRef oldvalue
]
{- Deletes a ref no matter what it contains. -}
delete' :: Ref -> Repo -> IO ()
delete' ref = run
[ Param "update-ref"
, Param "-d"
, Param $ fromRef ref
]
{- Gets the sha of the tree a ref uses.
-
- The ref may be something like a branch name, and it could contain
@ -201,6 +210,19 @@ tree (Ref ref) = extractSha <$$> pipeReadStrict
-- de-reference commit objects to the tree
else ref <> ":"
{- Check if the first ref is an ancestor of the second ref.
-
- Note that if the two refs point to the same commit, it is considered
- to be an ancestor of itself.
-}
isAncestor :: Ref -> Ref -> Repo -> IO Bool
isAncestor r1 r2 = runBool
[ Param "merge-base"
, Param "--ancestor"
, Param (fromRef r1)
, Param (fromRef r2)
]
{- Checks if a String is a legal git ref name.
-
- The rules for this are complex; see git-check-ref-format(1) -}