diff --git a/CHANGELOG b/CHANGELOG index 1df80e22d5..165873f769 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,7 @@ git-annex (8.20210311) UNRELEASED; urgency=medium special remote, fix a bug that caused the url to to not be removed. * unregisterurl: Fix a bug that caused an url to not be unregistered when it is claimed by a special remote other than the web. + * Work around some buggy webdav server behavior involving renaming files. -- Joey Hess Fri, 12 Mar 2021 12:06:37 -0400 diff --git a/Remote/WebDAV.hs b/Remote/WebDAV.hs index 3ffa2dc049..a816df4338 100644 --- a/Remote/WebDAV.hs +++ b/Remote/WebDAV.hs @@ -247,15 +247,24 @@ removeExportDirectoryDav hdl dir = withDavHandle hdl $ \h -> runExport h $ \_dav renameExportDav :: DavHandleVar -> Key -> ExportLocation -> ExportLocation -> Annex (Maybe ()) renameExportDav hdl _k src dest = case (exportLocation src, exportLocation dest) of - (Right srcl, Right destl) -> withDavHandle hdl $ \h -> - -- box.com's DAV endpoint has buggy handling of renames, - -- so avoid renaming when using it. - if boxComUrl `isPrefixOf` baseURL h - then return Nothing - else runExport h $ \dav -> do - maybe noop (void . mkColRecursive) (locationParent destl) - moveDAV (baseURL dav) srcl destl - return (Just ()) + (Right srcl, Right destl) -> withDavHandle hdl $ \h -> do + -- Several webdav servers have buggy handing of renames, + -- and fail to rename in some circumstances. + -- Since after a failure it's not clear where the file ended + -- up, recover by deleting both the source and destination. + -- The file will later be re-uploaded to the destination, + -- so this deletion is ok. + let go = runExport h $ \dav -> do + maybe noop (void . mkColRecursive) (locationParent destl) + moveDAV (baseURL dav) srcl destl + return (Just ()) + let recover = do + void $ runExport h $ \_dav -> safely $ + inLocation srcl delContentM + void $ runExport h $ \_dav -> safely $ + inLocation destl delContentM + return Nothing + catchNonAsync go (const recover) (Left err, _) -> giveup err (_, Left err) -> giveup err diff --git a/Types/Remote.hs b/Types/Remote.hs index ff632fad83..3a8f01761e 100644 --- a/Types/Remote.hs +++ b/Types/Remote.hs @@ -280,7 +280,10 @@ data ExportActions a = ExportActions , checkPresentExport :: Key -> ExportLocation -> a Bool -- Renames an already exported file. -- - -- If the remote does not support renames, it can return Nothing. + -- If the remote does not support the requested rename, + -- it can return Nothing. It's ok if the remove deletes + -- the file in such a situation too; it will be re-exported to + -- recover. -- -- Throws an exception if the remote cannot be accessed, or -- the file doesn't exist or cannot be renamed. @@ -393,3 +396,4 @@ data ImportActions a = ImportActions -> [ContentIdentifier] -> a Bool } + diff --git a/doc/bugs/WEBDAV_export_has_wrong_subdirectory_content.mdwn b/doc/bugs/WEBDAV_export_has_wrong_subdirectory_content.mdwn index b539f78e24..766107e940 100644 --- a/doc/bugs/WEBDAV_export_has_wrong_subdirectory_content.mdwn +++ b/doc/bugs/WEBDAV_export_has_wrong_subdirectory_content.mdwn @@ -55,3 +55,4 @@ Thx! [[!tag projects/datalad]] +> [[fixed|done]] --[[Joey]] diff --git a/doc/bugs/WEBDAV_export_has_wrong_subdirectory_content/comment_11_03ea7014854be4fa9f40a8815616b81d._comment b/doc/bugs/WEBDAV_export_has_wrong_subdirectory_content/comment_11_03ea7014854be4fa9f40a8815616b81d._comment new file mode 100644 index 0000000000..e758873603 --- /dev/null +++ b/doc/bugs/WEBDAV_export_has_wrong_subdirectory_content/comment_11_03ea7014854be4fa9f40a8815616b81d._comment @@ -0,0 +1,16 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 11""" + date="2021-03-22T16:27:10Z" + content=""" +Ok, failed kind of like I expected, although I have to say the filenames +don't entirely make sense to me. +("git-annex-webdav-tmp" is not used in filenames when renaming an exported +file, only when storing it in the first place) + +So what seems to make sense for git-annex to do when renaming an exported +file is: Try to rename, and if it fails, delete the source and the +destination -- since it has no idea what may have been left in either place +-- and then fall back to uploading the file again instead. I have +implemented that. +"""]]