post-receive: use the exporttree=yes remote as a source

This handles cases where a single key is used by multiple files in the
exported tree. When using `git-annex push`, the key's content gets
stored in the annexobjects location, and then when the branch is pushed,
it gets renamed from the annexobjects location to the first exported
file. For subsequent exported files, a copy of the content needs to be
made. This causes it to download the key from the remote in order to
upload another copy to it.

This is not needed when using `git push` followed by `git-annex copy --to`
the proxied remote, because the received key is stored at all export
locations then.

Also, fixed handling of the synced branch push, it was exporting master
when synced/master was pushed.

Note that currently, the first push to the remote does not see that it
is able to get a key from it in order to upload it back. It displays
"(not available)". The second push is able to. Since git-annex push
pushes first the synced branch and then the branch, this does end up
with a full export being made, but it is not quite right.
This commit is contained in:
Joey Hess 2024-08-08 12:28:12 -04:00
parent 7294d23d78
commit a2eb3b450a
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 16 additions and 14 deletions

View file

@ -20,6 +20,7 @@ import qualified Types.Remote as Remote
import Config
import Git.Types
import Git.Sha
import Git.FilePath
import qualified Git.Ref
import Command.Export (filterExport, getExportCommit, seekExport)
import Command.Sync (syncBranch)
@ -60,17 +61,23 @@ proxyExportTree = do
pushedbranches <- liftIO $
S.fromList . map snd . parseHookInput
<$> B.hGetContents stdin
let waspushed b = S.member b pushedbranches
|| S.member (syncBranch b) pushedbranches
case filter (waspushed . Git.Ref.branchRef . fst . snd) rbs of
[] -> return ()
rbs' -> forM_ rbs' $ \((r, b), _) -> go r b
let waspushed (r, (b, d))
| S.member (Git.Ref.branchRef b) pushedbranches =
Just (r, b, d)
| S.member (Git.Ref.branchRef (syncBranch b)) pushedbranches =
Just (r, syncBranch b, d)
| otherwise = Nothing
case headMaybe (mapMaybe waspushed rbs) of
Just (r, b, Nothing) -> go r b
Just (r, b, Just d) -> go r $
Git.Ref.branchFileRef b (getTopFilePath d)
Nothing -> noop
where
canexport r = case remoteAnnexTrackingBranch (Remote.gitconfig r) of
Nothing -> return Nothing
Just branch ->
ifM (isExportSupported r)
( return (Just ((r, branch), splitRemoteAnnexTrackingBranchSubdir branch))
( return (Just (r, splitRemoteAnnexTrackingBranchSubdir branch))
, return Nothing
)
@ -79,7 +86,7 @@ proxyExportTree = do
Just t -> do
tree <- filterExport r t
mtbcommitsha <- getExportCommit r b
seekExport r tree mtbcommitsha []
seekExport r tree mtbcommitsha [r]
parseHookInput :: B.ByteString -> [((Sha, Sha), Ref)]
parseHookInput = mapMaybe parse . B8.lines

View file

@ -35,13 +35,6 @@ Planned schedule of work:
* A proxied exporttree=yes special remote is not untrusted, and should be.
* Handle cases where a single key is used by multiple files in the exported
tree. Need to download from the special remote in order to export
multiple copies to it. (In particular, this is needed when using
`git-annex push`. When using first `git push` followed by
`git-annex copy --to` the proxied remote, the received key is stored
to all export locations.)
* Implement `git-annex export treeish --to=foo --from=bar`, which
gets from bar as needed to send to foo. Make post-retrieve use
`--to=r --from=r` to handle the multiple files case.
@ -69,6 +62,8 @@ Planned schedule of work:
an exporttree=yes special remote that does not have
annexobjects=yes, to avoid foot shooting.
* Added --from option to `git-annex export`.
## items deferred until later for p2p protocol over http
* `git-annex p2phttp` should support serving several repositories at the same