diff --git a/Remote/Rsync.hs b/Remote/Rsync.hs index 571cd8f5ee..60cbf4595f 100644 --- a/Remote/Rsync.hs +++ b/Remote/Rsync.hs @@ -22,9 +22,10 @@ import Utility.RsyncFile type RsyncUrl = String -data RsyncOpts = RsyncOpts { - rsyncUrl :: RsyncUrl, - rsyncOptions :: [CommandParam] +data RsyncOpts = RsyncOpts + { rsyncUrl :: RsyncUrl + , rsyncOptions :: [CommandParam] + , rsyncShellEscape :: Bool } remote :: RemoteType @@ -37,7 +38,7 @@ remote = RemoteType { gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote gen r u c = do - o <- genRsyncOpts r + o <- genRsyncOpts r c cst <- remoteCost r expensiveRemoteCost return $ encryptableRemote c (storeEncrypted o) @@ -58,11 +59,13 @@ gen r u c = do remotetype = remote } -genRsyncOpts :: Git.Repo -> Annex RsyncOpts -genRsyncOpts r = do +genRsyncOpts :: Git.Repo -> Maybe RemoteConfig -> Annex RsyncOpts +genRsyncOpts r c = do url <- getRemoteConfig r "rsyncurl" (error "missing rsyncurl") - opts <- getRemoteConfig r "rsync-options" "" - return $ RsyncOpts url $ map Param $ filter safe $ words opts + opts <- map Param . filter safe . words + <$> getRemoteConfig r "rsync-options" "" + let escape = maybe True (\m -> M.lookup "shellescape" m /= Just "no") c + return $ RsyncOpts url opts escape where safe o -- Don't allow user to pass --delete to rsync; @@ -86,7 +89,7 @@ rsyncSetup u c = do rsyncEscape :: RsyncOpts -> String -> String rsyncEscape o s - | rsyncUrlIsShell (rsyncUrl o) = shellEscape s + | rsyncShellEscape o && rsyncUrlIsShell (rsyncUrl o) = shellEscape s | otherwise = s rsyncUrls :: RsyncOpts -> Key -> [String] diff --git a/debian/changelog b/debian/changelog index 27a6bab2b8..033b739de5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +git-annex (3.20120431) UNRELEASED; urgency=low + + * Rsync special remotes can be configured with shellescape=no + to avoid shell quoting that is normally done when using rsync over ssh. + This is known to be needed for certian rsync hosting providers + (specificially hidrive.strato.com) that use rsync over ssh but do not + pass it through the shell. + + -- Joey Hess Wed, 02 May 2012 13:06:18 -0400 + git-annex (3.20120430) unstable; urgency=low * Fix use of annex.diskreserve config setting. diff --git a/doc/special_remotes/rsync.mdwn b/doc/special_remotes/rsync.mdwn index 90d544a1e1..286615460c 100644 --- a/doc/special_remotes/rsync.mdwn +++ b/doc/special_remotes/rsync.mdwn @@ -24,5 +24,13 @@ These parameters can be passed to `git annex initremote` to configure rsync: * `rsyncurl` - Required. This is the url or `hostname:/directory` to pass to rsync to tell it where to store content. +* `shellescape` - Optional. Set to "no" to avoid shell escaping normally + done when using rsync over ssh. That escaping is needed with typical + setups, but not with some hosting providers that do not expose rsynced + filenames to the shell. You'll know you need this option if `git annex get` + from the special remote fails with an error message containing a single + quote (`'`) character. If that happens, you can re-run initremote + setting shellescape=no. + The `annex-rsync-options` git configuration setting can be used to pass parameters to rsync.