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 Config
import Git.Types import Git.Types
import Git.Sha import Git.Sha
import Git.FilePath
import qualified Git.Ref import qualified Git.Ref
import Command.Export (filterExport, getExportCommit, seekExport) import Command.Export (filterExport, getExportCommit, seekExport)
import Command.Sync (syncBranch) import Command.Sync (syncBranch)
@ -60,17 +61,23 @@ proxyExportTree = do
pushedbranches <- liftIO $ pushedbranches <- liftIO $
S.fromList . map snd . parseHookInput S.fromList . map snd . parseHookInput
<$> B.hGetContents stdin <$> B.hGetContents stdin
let waspushed b = S.member b pushedbranches let waspushed (r, (b, d))
|| S.member (syncBranch b) pushedbranches | S.member (Git.Ref.branchRef b) pushedbranches =
case filter (waspushed . Git.Ref.branchRef . fst . snd) rbs of Just (r, b, d)
[] -> return () | S.member (Git.Ref.branchRef (syncBranch b)) pushedbranches =
rbs' -> forM_ rbs' $ \((r, b), _) -> go r b 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 where
canexport r = case remoteAnnexTrackingBranch (Remote.gitconfig r) of canexport r = case remoteAnnexTrackingBranch (Remote.gitconfig r) of
Nothing -> return Nothing Nothing -> return Nothing
Just branch -> Just branch ->
ifM (isExportSupported r) ifM (isExportSupported r)
( return (Just ((r, branch), splitRemoteAnnexTrackingBranchSubdir branch)) ( return (Just (r, splitRemoteAnnexTrackingBranchSubdir branch))
, return Nothing , return Nothing
) )
@ -79,7 +86,7 @@ proxyExportTree = do
Just t -> do Just t -> do
tree <- filterExport r t tree <- filterExport r t
mtbcommitsha <- getExportCommit r b mtbcommitsha <- getExportCommit r b
seekExport r tree mtbcommitsha [] seekExport r tree mtbcommitsha [r]
parseHookInput :: B.ByteString -> [((Sha, Sha), Ref)] parseHookInput :: B.ByteString -> [((Sha, Sha), Ref)]
parseHookInput = mapMaybe parse . B8.lines 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. * 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 * Implement `git-annex export treeish --to=foo --from=bar`, which
gets from bar as needed to send to foo. Make post-retrieve use gets from bar as needed to send to foo. Make post-retrieve use
`--to=r --from=r` to handle the multiple files case. `--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 an exporttree=yes special remote that does not have
annexobjects=yes, to avoid foot shooting. annexobjects=yes, to avoid foot shooting.
* Added --from option to `git-annex export`.
## items deferred until later for p2p protocol over http ## items deferred until later for p2p protocol over http
* `git-annex p2phttp` should support serving several repositories at the same * `git-annex p2phttp` should support serving several repositories at the same