git-annex 6.20170321 → 6.20170510
raw patch · 37 files changed
+821/−200 lines, 37 filesdep ~process
Dependency ranges changed: process
Files
- Annex.hs +2/−2
- Annex/Multicast.hs +54/−0
- Annex/Ssh.hs +14/−5
- Assistant/Sync.hs +17/−7
- Assistant/WebApp/Documentation.hs +1/−1
- Backend.hs +23/−33
- BuildFlags.hs +0/−81
- BuildInfo.hs +114/−0
- CHANGELOG +30/−0
- CmdLine/GitAnnex.hs +4/−0
- Command/Add.hs +13/−3
- Command/EnableRemote.hs +21/−9
- Command/Migrate.hs +2/−4
- Command/Multicast.hs +253/−0
- Command/Sync.hs +6/−3
- Command/Version.hs +2/−1
- Logs.hs +3/−0
- Logs/Location.hs +13/−6
- Logs/Multicast.hs +33/−0
- Remote/GCrypt.hs +12/−6
- Remote/Git.hs +3/−6
- RemoteDaemon/Common.hs +8/−1
- RemoteDaemon/Transport/Ssh.hs +2/−2
- RemoteDaemon/Transport/Tor.hs +2/−2
- Test.hs +1/−0
- Types/GitConfig.hs +11/−2
- Utility/FileMode.hs +4/−1
- doc/git-annex-add.mdwn +5/−0
- doc/git-annex-calckey.mdwn +1/−1
- doc/git-annex-dead.mdwn +3/−2
- doc/git-annex-multicast.mdwn +95/−0
- doc/git-annex-remotedaemon.mdwn +3/−0
- doc/git-annex-sync.mdwn +20/−7
- doc/git-annex.mdwn +33/−6
- git-annex.cabal +8/−4
- stack.yaml +4/−5
- templates/documentation/about.hamlet +1/−0
Annex.hs view
@@ -98,7 +98,7 @@ { repo :: Git.Repo , repoadjustment :: (Git.Repo -> IO Git.Repo) , gitconfig :: GitConfig- , backends :: [BackendA Annex]+ , backend :: Maybe (BackendA Annex) , remotes :: [Types.Remote.RemoteA Annex] , remoteannexstate :: M.Map UUID AnnexState , output :: MessageState@@ -149,7 +149,7 @@ { repo = r , repoadjustment = return , gitconfig = c- , backends = []+ , backend = Nothing , remotes = [] , remoteannexstate = M.empty , output = def
+ Annex/Multicast.hs view
@@ -0,0 +1,54 @@+{- git-annex multicast receive callback+ -+ - Copyright 2017 Joey Hess <id@joeyh.name>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE CPP #-}++module Annex.Multicast where++import Config.Files+import Utility.Env+import Utility.PartialPrelude++import System.Process+import System.IO+import GHC.IO.Handle.FD+#if ! MIN_VERSION_process(1,4,2)+import System.Posix.IO (handleToFd)+#endif+import Control.Applicative+import Prelude++multicastReceiveEnv :: String+multicastReceiveEnv = "GIT_ANNEX_MULTICAST_RECEIVE"++multicastCallbackEnv :: IO (FilePath, [(String, String)], Handle)+multicastCallbackEnv = do+ gitannex <- readProgramFile+#if MIN_VERSION_process(1,4,2)+ -- This will even work on Windows+ (rfd, wfd) <- createPipeFd+ rh <- fdToHandle rfd+#else+ (rh, wh) <- createPipe+ wfd <- handleToFd wh+#endif+ environ <- addEntry multicastReceiveEnv (show wfd) <$> getEnvironment+ return (gitannex, environ, rh)++-- This is run when uftpd has received a file. Rather than move+-- the file into the annex here, which would require starting up the+-- Annex monad, parsing git config, and verifying the content, simply+-- output to the specified FD the filename. This keeps the time+-- that uftpd is not receiving the next file as short as possible.+runMulticastReceive :: [String] -> String -> IO ()+runMulticastReceive ("-I":_sessionid:fs) hs = case readish hs of+ Just fd -> do+ h <- fdToHandle fd+ mapM_ (hPutStrLn h) fs+ hClose h+ Nothing -> return ()+runMulticastReceive _ _ = return ()
Annex/Ssh.hs view
@@ -52,10 +52,13 @@ {- Generates a command to ssh to a given host (or user@host) on a given - port. This includes connection caching parameters, and any ssh-options.- - If GIT_SSH or GIT_SSH_COMMAND is set, they are used instead. -}+ - If GIT_SSH or GIT_SSH_COMMAND is enabled, they are used instead. -} sshCommand :: ConsumeStdin -> (SshHost, Maybe SshPort) -> RemoteGitConfig -> SshCommand -> Annex (FilePath, [CommandParam])-sshCommand cs (host, port) gc remotecmd = maybe go return- =<< liftIO (gitSsh' host port remotecmd (consumeStdinParams cs))+sshCommand cs (host, port) gc remotecmd = ifM (liftIO safe_GIT_SSH)+ ( maybe go return+ =<< liftIO (gitSsh' host port remotecmd (consumeStdinParams cs))+ , go+ ) where go = do ps <- sshOptions cs (host, port) gc []@@ -81,6 +84,12 @@ , [Param "-T"] ] +{- Due to passing -n to GIT_SSH and GIT_SSH_COMMAND, some settings+ - of those that expect exactly git's parameters will break. So only+ - use those if the user set GIT_ANNEX_USE_GIT_SSH to say it's ok. -}+safe_GIT_SSH :: IO Bool+safe_GIT_SSH = (== Just "1") <$> getEnv "GIT_ANNEX_USE_GIT_SSH"+ consumeStdinParams :: ConsumeStdin -> [CommandParam] consumeStdinParams ConsumeStdin = [] consumeStdinParams NoConsumeStdin = [Param "-n"]@@ -305,13 +314,13 @@ - to set GIT_SSH=git-annex, and set sshOptionsEnv when running git - commands. -- - If GIT_SSH or GIT_SSH_COMMAND are set, this has no effect. -}+ - If GIT_SSH or GIT_SSH_COMMAND are enabled, this has no effect. -} sshOptionsTo :: Git.Repo -> RemoteGitConfig -> Git.Repo -> Annex Git.Repo sshOptionsTo remote gc localr | not (Git.repoIsUrl remote) || Git.repoIsHttp remote = unchanged | otherwise = case Git.Url.hostuser remote of Nothing -> unchanged- Just host -> ifM (liftIO gitSshEnvSet)+ Just host -> ifM (liftIO $ safe_GIT_SSH <&&> gitSshEnvSet) ( unchanged , do (msockfile, _) <- sshCachingInfo (host, Git.Url.port remote)
Assistant/Sync.hs view
@@ -110,8 +110,14 @@ pushToRemotes :: [Remote] -> Assistant [Remote] pushToRemotes remotes = do now <- liftIO getCurrentTime- let remotes' = filter (not . remoteAnnexReadOnly . Remote.gitconfig) remotes+ let remotes' = filter (wantpush . Remote.gitconfig) remotes syncAction remotes' (pushToRemotes' now)+ where+ wantpush gc+ | remoteAnnexReadOnly gc = False+ | not (remoteAnnexPush gc) = False+ | otherwise = True+ pushToRemotes' :: UTCTime -> [Remote] -> Assistant [Remote] pushToRemotes' now remotes = do (g, branch, u) <- liftAnnex $ do@@ -195,16 +201,20 @@ manualPull currentbranch remotes = do g <- liftAnnex gitRepo let (_xmppremotes, normalremotes) = partition Remote.isXMPPRemote remotes- failed <- forM normalremotes $ \r -> do- g' <- liftAnnex $ sshOptionsTo (Remote.repo r) (Remote.gitconfig r) g- ifM (liftIO $ Git.Command.runBool [Param "fetch", Param $ Remote.name r] g')- ( return Nothing- , return $ Just r- )+ failed <- forM normalremotes $ \r -> if wantpull $ Remote.gitconfig r+ then do+ g' <- liftAnnex $ sshOptionsTo (Remote.repo r) (Remote.gitconfig r) g+ ifM (liftIO $ Git.Command.runBool [Param "fetch", Param $ Remote.name r] g')+ ( return Nothing+ , return $ Just r+ )+ else return Nothing haddiverged <- liftAnnex Annex.Branch.forceUpdate forM_ normalremotes $ \r -> liftAnnex $ Command.Sync.mergeRemote r currentbranch Command.Sync.mergeConfig return (catMaybes failed, haddiverged)+ where+ wantpull gc = remoteAnnexPull gc {- Start syncing a remote, using a background thread. -} syncRemote :: Remote -> Assistant ()
Assistant/WebApp/Documentation.hs view
@@ -12,7 +12,7 @@ import Assistant.WebApp.Common import Assistant.Install (standaloneAppBase) import Build.SysConfig (packageversion)-import BuildFlags+import BuildInfo {- The full license info may be included in a file on disk that can - be read in and displayed. -}
Backend.hs view
@@ -7,7 +7,7 @@ module Backend ( list,- orderedList,+ defaultBackend, genKey, getBackend, chooseBackend,@@ -33,40 +33,29 @@ list :: [Backend] list = Backend.Hash.backends ++ Backend.WORM.backends ++ Backend.URL.backends -{- List of backends in the order to try them when storing a new key. -}-orderedList :: Annex [Backend]-orderedList = do- l <- Annex.getState Annex.backends -- list is cached here- if not $ null l- then return l- else do- f <- Annex.getState Annex.forcebackend- case f of- Just name | not (null name) ->- return [lookupname name]- _ -> do- l' <- gen . annexBackends <$> Annex.getGitConfig- Annex.changeState $ \s -> s { Annex.backends = l' }- return l'+{- Backend to use by default when generating a new key. -}+defaultBackend :: Annex Backend+defaultBackend = maybe cache return =<< Annex.getState Annex.backend where- gen [] = list- gen ns = map lookupname ns+ cache = do+ n <- maybe (annexBackend <$> Annex.getGitConfig) (return . Just)+ =<< Annex.getState Annex.forcebackend+ let b = case n of+ Just name | valid name -> lookupname name+ _ -> Prelude.head list+ Annex.changeState $ \s -> s { Annex.backend = Just b }+ return b+ valid name = not (null name) lookupname = lookupBackendVariety . parseKeyVariety -{- Generates a key for a file, trying each backend in turn until one- - accepts it. -}+{- Generates a key for a file. -} genKey :: KeySource -> Maybe Backend -> Annex (Maybe (Key, Backend))-genKey source trybackend = do- bs <- orderedList- let bs' = maybe bs (: bs) trybackend- genKey' bs' source-genKey' :: [Backend] -> KeySource -> Annex (Maybe (Key, Backend))-genKey' [] _ = return Nothing-genKey' (b:bs) source = do+genKey source preferredbackend = do+ b <- maybe defaultBackend return preferredbackend r <- B.getKey b source- case r of- Nothing -> genKey' bs source- Just k -> return $ Just (makesane k, b)+ return $ case r of+ Nothing -> Nothing+ Just k -> Just (makesane k, b) where -- keyNames should not contain newline characters. makesane k = k { keyName = map fixbadchar (keyName k) }@@ -82,13 +71,14 @@ return Nothing {- Looks up the backend that should be used for a file.- - That can be configured on a per-file basis in the gitattributes file. -}+ - That can be configured on a per-file basis in the gitattributes file,+ - or forced with --backend. -} chooseBackend :: FilePath -> Annex (Maybe Backend) chooseBackend f = Annex.getState Annex.forcebackend >>= go where- go Nothing = maybeLookupBackendVariety . parseKeyVariety+ go Nothing = maybeLookupBackendVariety . parseKeyVariety <$> checkAttr "annex.backend" f- go (Just _) = Just . Prelude.head <$> orderedList+ go (Just _) = Just <$> defaultBackend {- Looks up a backend by variety. May fail if unsupported or disabled. -} lookupBackendVariety :: KeyVariety -> Backend
− BuildFlags.hs
@@ -1,81 +0,0 @@-{- git-annex build flags reporting- -- - Copyright 2013 Joey Hess <id@joeyh.name>- -- - Licensed under the GNU GPL version 3 or higher.- -}--{-# LANGUAGE CPP #-}--module BuildFlags where--buildFlags :: [String]-buildFlags = filter (not . null)- [ ""-#ifdef WITH_ASSISTANT- , "Assistant"-#else-#warning Building without the assistant.-#endif-#ifdef WITH_WEBAPP- , "Webapp"-#else-#warning Building without the webapp. You probably need to install Yesod..-#endif-#ifdef WITH_PAIRING- , "Pairing"-#else-#warning Building without local pairing.-#endif-#ifdef WITH_TESTSUITE- , "Testsuite"-#else-#warning Building without the testsuite.-#endif-#ifdef WITH_S3- , "S3"-#if MIN_VERSION_aws(0,10,6)- ++ "(multipartupload)"-#endif-#if MIN_VERSION_aws(0,13,0)- ++ "(storageclasses)"-#endif-#else-#warning Building without S3.-#endif-#ifdef WITH_WEBDAV- , "WebDAV"-#else-#warning Building without WebDAV.-#endif-#ifdef WITH_INOTIFY- , "Inotify"-#endif-#ifdef WITH_FSEVENTS- , "FsEvents"-#endif-#ifdef WITH_KQUEUE- , "Kqueue"-#endif-#ifdef WITH_DBUS- , "DBus"-#endif-#ifdef WITH_DESKTOP_NOTIFY- , "DesktopNotify"-#endif-#ifdef WITH_CONCURRENTOUTPUT- , "ConcurrentOutput"-#else-#warning Building without ConcurrentOutput-#endif-#ifdef WITH_TORRENTPARSER- , "TorrentParser"-#endif-#ifdef WITH_MAGICMIME- , "MagicMime"-#endif- -- Always enabled now, but users may be used to seeing these flags- -- listed.- , "Feeds"- , "Quvi"- ]
+ BuildInfo.hs view
@@ -0,0 +1,114 @@+{- git-annex build info reporting+ -+ - Copyright 2013-2017 Joey Hess <id@joeyh.name>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE CPP #-}++module BuildInfo where++import Data.List+import Data.Ord+import qualified Data.CaseInsensitive as CI++buildFlags :: [String]+buildFlags = filter (not . null)+ [ ""+#ifdef WITH_ASSISTANT+ , "Assistant"+#else+#warning Building without the assistant.+#endif+#ifdef WITH_WEBAPP+ , "Webapp"+#else+#warning Building without the webapp. You probably need to install Yesod..+#endif+#ifdef WITH_PAIRING+ , "Pairing"+#else+#warning Building without local pairing.+#endif+#ifdef WITH_TESTSUITE+ , "Testsuite"+#else+#warning Building without the testsuite.+#endif+#ifdef WITH_S3+ , "S3"+#if MIN_VERSION_aws(0,10,6)+ ++ "(multipartupload)"+#endif+#if MIN_VERSION_aws(0,13,0)+ ++ "(storageclasses)"+#endif+#else+#warning Building without S3.+#endif+#ifdef WITH_WEBDAV+ , "WebDAV"+#else+#warning Building without WebDAV.+#endif+#ifdef WITH_INOTIFY+ , "Inotify"+#endif+#ifdef WITH_FSEVENTS+ , "FsEvents"+#endif+#ifdef WITH_KQUEUE+ , "Kqueue"+#endif+#ifdef WITH_DBUS+ , "DBus"+#endif+#ifdef WITH_DESKTOP_NOTIFY+ , "DesktopNotify"+#endif+#ifdef WITH_CONCURRENTOUTPUT+ , "ConcurrentOutput"+#else+#warning Building without ConcurrentOutput+#endif+#ifdef WITH_TORRENTPARSER+ , "TorrentParser"+#endif+#ifdef WITH_MAGICMIME+ , "MagicMime"+#endif+ -- Always enabled now, but users may be used to seeing these flags+ -- listed.+ , "Feeds"+ , "Quvi"+ ]++-- Not a complete list, let alone a listing transitive deps, but only+-- the ones that are often interesting to know.+dependencyVersions :: [String]+dependencyVersions = map fmt $ sortBy (comparing (CI.mk . fst))+ [ ("feed", VERSION_feed)+ , ("uuid", VERSION_uuid)+ , ("bloomfilter", VERSION_bloomfilter)+ , ("http-client", VERSION_http_client)+ , ("persistent-sqlite", VERSION_persistent_sqlite)+ , ("cryptonite", VERSION_cryptonite)+#ifdef WITH_S3+ , ("aws", VERSION_aws)+#endif+#ifdef WITH_WEBDAV+ , ("DAV", VERSION_DAV)+#endif+#ifdef WITH_TORRENTPARSER+ , ("torrent", VERSION_torrent)+#endif+#ifdef WITH_WEBAPP+ , ("yesod", VERSION_yesod)+#endif +#ifdef TOOL_VERSION_ghc+ , ("ghc", TOOL_VERSION_ghc)+#endif+ ]+ where+ fmt (p, v) = p ++ "-" ++ v
CHANGELOG view
@@ -1,3 +1,33 @@+git-annex (6.20170510) unstable; urgency=medium++ * When a http remote does not expose an annex.uuid config, only warn+ about it once, not every time git-annex is run.+ * multicast: New command, uses uftp to multicast annexed files, for eg+ a classroom setting.+ * Added remote.<name>.annex-push and remote.<name>.annex-pull+ which can be useful to make remotes that don't get fully synced with+ local changes.+ * Disable git-annex's support for GIT_SSH and GIT_SSH_COMMAND, unless+ GIT_ANNEX_USE_GIT_SSH=1 is also set in the environment. This is+ necessary because as feared, the extra -n parameter that git-annex+ passes breaks uses of these environment variables that expect exactly+ the parameters that git passes.+ * enableremote: When enabling a non-special remote, param=value+ parameters can't be used, so error out if any are provided.+ * enableremote: Fix re-enabling of special remotes that have a git+ url, so that eg, encryption key changes take effect. They were silently+ ignored, a reversion introduced in 6.20160527.+ * gcrypt: Support re-enabling to change eg, encryption parameters.+ This was never supported before.+ * git annex add -u now supported, analagous to git add -u+ * version: Added "dependency versions" line.+ * Keys marked as dead are now skipped by --all.+ * annex.backend is the new name for what was annex.backends, and takes+ a single key-value backend, rather than the unncessary and confusing+ list. The old option still works if set.++ -- Joey Hess <id@joeyh.name> Wed, 10 May 2017 15:05:22 -0400+ git-annex (6.20170321) unstable; urgency=medium * Bugfix: Passing a command a filename that does not exist sometimes
CmdLine/GitAnnex.hs view
@@ -14,6 +14,7 @@ import Command import Utility.Env import Annex.Ssh+import Annex.Multicast import Types.Test import qualified Command.Help@@ -53,6 +54,7 @@ import qualified Command.InitRemote import qualified Command.EnableRemote import qualified Command.EnableTor+import qualified Command.Multicast import qualified Command.Expire import qualified Command.Repair import qualified Command.Unused@@ -144,6 +146,7 @@ , Command.InitRemote.cmd , Command.EnableRemote.cmd , Command.EnableTor.cmd+ , Command.Multicast.cmd , Command.Reinject.cmd , Command.Unannex.cmd , Command.Uninit.cmd@@ -242,4 +245,5 @@ envmodes = [ (sshOptionsEnv, runSshOptions args) , (sshAskPassEnv, runSshAskPass)+ , (multicastReceiveEnv, runMulticastReceive args) ]
Command/Add.hs view
@@ -1,6 +1,6 @@ {- git-annex command -- - Copyright 2010, 2013 Joey Hess <id@joeyh.name>+ - Copyright 2010-2017 Joey Hess <id@joeyh.name> - - Licensed under the GNU GPL version 3 or higher. -}@@ -30,6 +30,7 @@ { addThese :: CmdParams , includeDotFiles :: Bool , batchOption :: BatchMode+ , updateOnly :: Bool } optParser :: CmdParamsDesc -> Parser AddOptions@@ -40,6 +41,11 @@ <> help "don't skip dotfiles" ) <*> parseBatchOption+ <*> switch+ ( long "update"+ <> short 'u'+ <> help "only update tracked files"+ ) seek :: AddOptions -> CommandSeek seek o = allowConcurrentOutput $ do@@ -52,10 +58,14 @@ ) ) case batchOption o of- Batch -> batchFiles gofile+ Batch+ | updateOnly o ->+ giveup "--update --batch is not supported"+ | otherwise -> batchFiles gofile NoBatch -> do let go a = a gofile (addThese o)- go (withFilesNotInGit (not $ includeDotFiles o))+ unless (updateOnly o) $+ go (withFilesNotInGit (not $ includeDotFiles o)) go withFilesMaybeModified unlessM (versionSupportsUnlockedPointers <||> isDirect) $ go withFilesOldUnlocked
Command/EnableRemote.hs view
@@ -39,16 +39,28 @@ matchingname r = Git.remoteName r == Just name go [] = startSpecialRemote name (Logs.Remote.keyValToConfig rest) =<< Annex.SpecialRemote.findExisting name- go (r:_) = startNormalRemote name r+ go (r:_) = do+ -- This could be either a normal git remote or a special+ -- remote that has an url (eg gcrypt).+ rs <- Remote.remoteList+ case filter (\rmt -> Remote.name rmt == name) rs of+ (rmt:_) | Remote.remotetype rmt == Remote.Git.remote ->+ startNormalRemote name rest r+ _ -> go [] -startNormalRemote :: Git.RemoteName -> Git.Repo -> CommandStart-startNormalRemote name r = do- showStart "enableremote" name- next $ next $ do- setRemoteIgnore r False- r' <- Remote.Git.configRead False r- u <- getRepoUUID r'- return $ u /= NoUUID+-- Normal git remotes are special-cased; enableremote retries probing+-- the remote uuid.+startNormalRemote :: Git.RemoteName -> [String] -> Git.Repo -> CommandStart+startNormalRemote name restparams r+ | null restparams = do+ showStart "enableremote" name+ next $ next $ do+ setRemoteIgnore r False+ r' <- Remote.Git.configRead False r+ u <- getRepoUUID r'+ return $ u /= NoUUID+ | otherwise = giveup $+ "That is a normal git remote; passing these parameters does not make sense: " ++ unwords restparams startSpecialRemote :: Git.RemoteName -> Remote.RemoteConfig -> Maybe (UUID, Remote.RemoteConfig) -> CommandStart startSpecialRemote name config Nothing = do
Command/Migrate.hs view
@@ -36,15 +36,13 @@ Nothing -> stop Just oldbackend -> do exists <- inAnnex key- newbackend <- choosebackend =<< chooseBackend file+ newbackend <- maybe defaultBackend return + =<< chooseBackend file if (newbackend /= oldbackend || upgradableKey oldbackend key || forced) && exists then do showStart "migrate" file next $ perform file key oldbackend newbackend else stop- where- choosebackend Nothing = Prelude.head <$> orderedList- choosebackend (Just backend) = return backend {- Checks if a key is upgradable to a newer representation. -
+ Command/Multicast.hs view
@@ -0,0 +1,253 @@+{- git-annex command+ -+ - Copyright 2017 Joey Hess <id@joeyh.name>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE CPP #-}++module Command.Multicast where++import Command+import Logs.Multicast+import Annex.Multicast+import Annex.WorkTree+import Annex.Content+import Annex.UUID+import Annex.Perms+import Utility.FileMode+#ifndef mingw32_HOST_OS+import Creds+#endif+import qualified Limit+import Types.FileMatcher+import qualified Git.LsFiles as LsFiles+import Utility.Hash+import Utility.Tmp+import Config++import Data.Char+import qualified Data.ByteString.Lazy.UTF8 as B8+import qualified Data.Map as M+import Control.Concurrent.Async++cmd :: Command+cmd = command "multicast" SectionCommon "multicast file distribution"+ paramNothing (seek <$$> optParser)++data MultiCastAction+ = GenAddress+ | Send+ | Receive+ deriving (Show)++data MultiCastOptions = MultiCastOptions MultiCastAction [CommandParam] [FilePath]+ deriving (Show)++optParser :: CmdParamsDesc -> Parser MultiCastOptions+optParser _ = MultiCastOptions + <$> (genaddressp <|> sendp <|> receivep)+ <*> many uftpopt+ <*> cmdParams paramPaths+ where+ genaddressp = flag' GenAddress+ ( long "gen-address"+ <> help "generate multicast encryption key and store address in git-annex branch"+ )+ sendp = flag' Send+ ( long "send"+ <> help "multicast files"+ )+ receivep = flag' Receive+ ( long "receive"+ <> help "listen for multicast files and store in repository"+ )+ uftpopt = Param <$> strOption+ ( long "uftp-opt"+ <> short 'U'+ <> help "passed on to uftp/uftpd"+ <> metavar "OPTION"+ )++seek :: MultiCastOptions -> CommandSeek+seek (MultiCastOptions GenAddress _ _) = commandAction genAddress +seek (MultiCastOptions Send ups fs) = commandAction $ send ups fs+seek (MultiCastOptions Receive ups []) = commandAction $ receive ups+seek (MultiCastOptions Receive _ _) = giveup "Cannot specify list of files with --receive; this receives whatever files the sender chooses to send."++genAddress :: CommandStart+genAddress = do+ showStart "gen-address" ""+ k <- uftpKey+ (s, ok) <- case k of+ KeyContainer s -> liftIO $ genkey (Param s)+ KeyFile f -> do+ createAnnexDirectory (takeDirectory f)+ liftIO $ nukeFile f+ liftIO $ protectedOutput $ genkey (File f)+ case (ok, parseFingerprint s) of+ (False, _) -> giveup $ "uftp_keymgt failed: " ++ s+ (_, Nothing) -> giveup $ "Failed to find fingerprint in uftp_keymgt output: " ++ s+ (True, Just fp) -> next $ next $ do+ recordFingerprint fp =<< getUUID+ return True+ where+ -- Annoyingly, the fingerprint is output to stderr.+ genkey p = processTranscript "uftp_keymgt" ps Nothing+ where+ ps = toCommand $+ [ Param "-g"+ , keyparam+ , p+ ]+ -- uftp only supports rsa up to 2048 which is on the lower+ -- limit of secure RSA key sizes. Instead, use an EC curve.+ -- Except for on Windows XP, secp521r1 is supported on all+ -- platforms by uftp. DJB thinks it's pretty good compared+ -- with other NIST curves: "there's one standard NIST curve+ -- using a nice prime, namely 2521−1 but the sheer size of this+ -- prime makes it much slower than NIST P-256"+ -- (http://blog.cr.yp.to/20140323-ecdsa.html)+ -- Since this key is only used to set up the block encryption,+ -- its slow speed is ok.+ keyparam = Param "ec:secp521r1"++parseFingerprint :: String -> Maybe Fingerprint+parseFingerprint = Fingerprint <$$> lastMaybe . filter isfingerprint . words + where+ isfingerprint s = + let os = filter (all isHexDigit) (splitc ':' s)+ in length os == 20+ +send :: [CommandParam] -> [FilePath] -> CommandStart+send ups fs = withTmpFile "send" $ \t h -> do+ -- Need to be able to send files with the names of git-annex+ -- keys, and uftp does not allow renaming the files that are sent.+ -- In a direct mode repository, the annex objects do not have+ -- the names of keys, and would have to be copied, which is too+ -- expensive.+ whenM isDirect $+ giveup "Sorry, multicast send cannot be done from a direct mode repository."+ + showStart "generating file list" ""+ fs' <- seekHelper LsFiles.inRepo fs+ matcher <- Limit.getMatcher+ let addlist f o = whenM (matcher $ MatchingFile $ FileInfo f f) $+ liftIO $ hPutStrLn h o+ forM_ fs' $ \f -> do+ mk <- lookupFile f+ case mk of+ Nothing -> noop+ Just k -> withObjectLoc k (addlist f) (const noop)+ liftIO $ hClose h+ showEndOk++ showStart "sending files" ""+ showOutput+ serverkey <- uftpKey+ u <- getUUID+ withAuthList $ \authlist -> do+ let ps =+ -- Force client authentication.+ [ Param "-c"+ , Param "-Y", Param "aes256-cbc"+ , Param "-h", Param "sha512"+ -- Picked ecdh_ecdsa for perfect forward secrecy,+ -- and because a EC key exchange algorithm is+ -- needed since all keys are EC.+ , Param "-e", Param "ecdh_ecdsa"+ , Param "-k", uftpKeyParam serverkey+ , Param "-U", Param (uftpUID u)+ -- only allow clients on the authlist+ , Param "-H", Param ("@"++authlist)+ -- pass in list of files to send+ , Param "-i", File t+ ] ++ ups+ liftIO (boolSystem "uftp" ps) >>= showEndResult+ stop++receive :: [CommandParam] -> CommandStart+receive ups = do+ showStart "receiving multicast files" ""+ showNote "Will continue to run until stopped by ctrl-c"+ + showOutput+ clientkey <- uftpKey+ u <- getUUID+ (callback, environ, statush) <- liftIO multicastCallbackEnv+ tmpobjdir <- fromRepo gitAnnexTmpObjectDir+ createAnnexDirectory tmpobjdir+ withTmpDirIn tmpobjdir "multicast" $ \tmpdir -> withAuthList $ \authlist -> do+ abstmpdir <- liftIO $ absPath tmpdir+ abscallback <- liftIO $ searchPath callback+ let ps =+ -- Avoid it running as a daemon.+ [ Param "-d"+ -- Require encryption.+ , Param "-E"+ , Param "-k", uftpKeyParam clientkey+ , Param "-U", Param (uftpUID u)+ -- Only allow servers on the authlist+ , Param "-S", Param authlist+ -- Receive files into tmpdir+ -- (it needs an absolute path)+ , Param "-D", File abstmpdir+ -- Run callback after each file received+ -- (it needs an absolute path)+ , Param "-s", Param (fromMaybe callback abscallback)+ ] ++ ups+ runner <- liftIO $ async $+ hClose statush+ `after` boolSystemEnv "uftpd" ps (Just environ)+ mapM_ storeReceived . lines =<< liftIO (hGetContents statush)+ showEndResult =<< liftIO (wait runner)+ stop++storeReceived :: FilePath -> Annex ()+storeReceived f = do+ case file2key (takeFileName f) of+ Nothing -> do+ warning $ "Received a file " ++ f ++ " that is not a git-annex key. Deleting this file."+ liftIO $ nukeFile f+ Just k -> void $+ getViaTmp' AlwaysVerify k $ \dest -> unVerified $+ liftIO $ catchBoolIO $ do+ rename f dest+ return True++-- Under Windows, uftp uses key containers, which are not files on the+-- filesystem.+data UftpKey = KeyFile FilePath | KeyContainer String++uftpKeyParam :: UftpKey -> CommandParam+uftpKeyParam (KeyFile f) = File f+uftpKeyParam (KeyContainer s) = Param s++uftpKey :: Annex UftpKey+#ifdef mingw32_HOST_OS+uftpKey = do+ u <- getUUID+ return $ KeyContainer $ "annex-" ++ fromUUID u+#else+uftpKey = KeyFile <$> cacheCredsFile "multicast"+#endif++-- uftp needs a unique UID for each client and server, which +-- is a 8 digit hex number in the form "0xnnnnnnnn"+-- Derive it from the UUID.+uftpUID :: UUID -> String+uftpUID u = "0x" ++ (take 8 $ show $ sha2_256 $ B8.fromString (fromUUID u))++withAuthList :: (FilePath -> Annex a) -> Annex a+withAuthList a = do+ m <- knownFingerPrints+ withTmpFile "authlist" $ \t h -> do+ liftIO $ hPutStr h (genAuthList m)+ liftIO $ hClose h+ a t++genAuthList :: M.Map UUID Fingerprint -> String+genAuthList = unlines . map fmt . M.toList+ where+ fmt (u, Fingerprint f) = uftpUID u ++ "|" ++ f
Command/Sync.hs view
@@ -360,7 +360,7 @@ ] g pullRemote :: SyncOptions -> [Git.Merge.MergeConfig] -> Remote -> CurrBranch -> CommandStart-pullRemote o mergeconfig remote branch = stopUnless (pure $ pullOption o) $ do+pullRemote o mergeconfig remote branch = stopUnless (pure $ pullOption o && wantpull) $ do showStart "pull" (Remote.name remote) next $ do showOutput@@ -370,6 +370,7 @@ fetch = inRepoWithSshOptionsTo (Remote.repo remote) (Remote.gitconfig remote) $ Git.Command.runBool [Param "fetch", Param $ Remote.name remote]+ wantpull = remoteAnnexPull (Remote.gitconfig remote) {- The remote probably has both a master and a synced/master branch. - Which to merge from? Well, the master has whatever latest changes@@ -400,7 +401,7 @@ showStart "push" (Remote.name remote) next $ next $ do showOutput- ok <- inRepoWithSshOptionsTo (Remote.repo remote) (Remote.gitconfig remote) $+ ok <- inRepoWithSshOptionsTo (Remote.repo remote) gc $ pushBranch remote branch if ok then postpushupdate@@ -410,7 +411,8 @@ return ok where needpush- | remoteAnnexReadOnly (Remote.gitconfig remote) = return False+ | remoteAnnexReadOnly gc = return False+ | not (remoteAnnexPush gc) = return False | otherwise = anyM (newer remote) [syncBranch branch, Annex.Branch.name] -- Do updateInstead emulation for remotes on eg removable drives -- formatted FAT, where the post-update hook won't run.@@ -426,6 +428,7 @@ , return True ) | otherwise = return True+ gc = Remote.gitconfig remote {- Pushes a regular branch like master to a remote. Also pushes the git-annex - branch.
Command/Version.hs view
@@ -10,7 +10,7 @@ import Command import qualified Build.SysConfig as SysConfig import Annex.Version-import BuildFlags+import BuildInfo import Types.Key import qualified Types.Backend as B import qualified Types.Remote as R@@ -63,6 +63,7 @@ showPackageVersion = do vinfo "git-annex version" SysConfig.packageversion vinfo "build flags" $ unwords buildFlags+ vinfo "dependency versions" $ unwords dependencyVersions vinfo "key/value backends" $ unwords $ map (formatKeyVariety . B.backendVariety) Backend.list vinfo "remote types" $ unwords $ map R.typename Remote.remoteTypes
Logs.hs view
@@ -41,6 +41,7 @@ , scheduleLog , activityLog , differenceLog+ , multicastLog ] {- All the ways to get a key from a presence log file -}@@ -93,6 +94,8 @@ differenceLog :: FilePath differenceLog = "difference.log" +multicastLog :: FilePath+multicastLog = "multicast.log" {- The pathname of the location log file for a given key. -} locationLogFile :: GitConfig -> Key -> String
Logs/Location.hs view
@@ -86,7 +86,7 @@ checkDead key = do config <- Annex.getGitConfig ls <- compactLog <$> readLog (locationLogFile config key)- return $ all (\l -> status l == InfoDead) ls+ return $! all (\l -> status l == InfoDead) ls {- Updates the log to say that a key is dead. - @@ -111,17 +111,24 @@ } {- Finds all keys that have location log information.- - (There may be duplicate keys in the list.) -}+ - (There may be duplicate keys in the list.)+ -+ - Keys that have been marked as dead are not included.+ -} loggedKeys :: Annex [Key]-loggedKeys = mapMaybe locationLogFileKey <$> Annex.Branch.files+loggedKeys = loggedKeys' (not <$$> checkDead) +{- Note that sel should be strict, to avoid the filterM building many+ - thunks. -} +loggedKeys' :: (Key -> Annex Bool) -> Annex [Key]+loggedKeys' sel = filterM sel =<<+ (mapMaybe locationLogFileKey <$> Annex.Branch.files)+ {- Finds all keys that have location log information indicating - they are present for the specified repository. -} loggedKeysFor :: UUID -> Annex [Key]-loggedKeysFor u = filterM isthere =<< loggedKeys+loggedKeysFor u = loggedKeys' isthere where- {- This should run strictly to avoid the filterM- - building many thunks containing keyLocations data. -} isthere k = do us <- loggedLocations k let !there = u `elem` us
+ Logs/Multicast.hs view
@@ -0,0 +1,33 @@+{- git-annex multicast fingerprint log+ -+ - Copyright 2017 Joey Hess <id@joeyh.name>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Logs.Multicast (+ Fingerprint(..),+ recordFingerprint,+ knownFingerPrints,+) where++import Data.Time.Clock.POSIX++import Annex.Common+import qualified Annex.Branch+import Logs+import Logs.UUIDBased++import qualified Data.Map as M++newtype Fingerprint = Fingerprint String+ deriving (Eq, Read, Show)++recordFingerprint :: Fingerprint -> UUID -> Annex ()+recordFingerprint fp uuid = do+ ts <- liftIO getPOSIXTime+ Annex.Branch.change multicastLog $+ showLog show . changeLog ts uuid fp . parseLog readish++knownFingerPrints :: Annex (M.Map UUID Fingerprint)+knownFingerPrints = simpleMap . parseLog readish <$> Annex.Branch.get activityLog
Remote/GCrypt.hs view
@@ -31,7 +31,6 @@ import qualified Git.Config import qualified Git.GCrypt import qualified Git.Construct-import qualified Git.Types as Git () import qualified Annex.Branch import Config import Config.Cost@@ -176,11 +175,18 @@ go Nothing = giveup "Specify gitrepo=" go (Just gitrepo) = do (c', _encsetup) <- encryptionSetup c gc- inRepo $ Git.Command.run - [ Param "remote", Param "add"- , Param remotename- , Param $ Git.GCrypt.urlPrefix ++ gitrepo- ]++ let url = Git.GCrypt.urlPrefix ++ gitrepo+ rs <- fromRepo Git.remotes+ case filter (\r -> Git.remoteName r == Just remotename) rs of+ [] -> inRepo $ Git.Command.run + [ Param "remote", Param "add"+ , Param remotename+ , Param url+ ]+ (r:_)+ | Git.repoLocation r == url -> noop+ | otherwise -> error "Another remote with the same name already exists." setGcryptEncryption c' remotename
Remote/Git.hs view
@@ -248,18 +248,15 @@ , return Nothing ) case v of- Nothing -> do- warning $ "Failed to get annex.uuid configuration of repository " ++ Git.repoDescribe r- return r- Just (Left _) -> do- set_ignore "not usable by git-annex" False- return r Just (Right r') -> do -- Cache when http remote is not bare for -- optimisation. unless (Git.Config.isBare r') $ setremote setRemoteBare False return r'+ _ -> do+ set_ignore "not usable by git-annex" False+ return r store = observe $ \r' -> do g <- gitRepo
RemoteDaemon/Common.hs view
@@ -8,7 +8,7 @@ module RemoteDaemon.Common ( liftAnnex , inLocalRepo- , checkNewShas+ , checkShouldFetch , ConnectionStatus(..) , robustConnection ) where@@ -34,6 +34,13 @@ inLocalRepo :: TransportHandle -> (Git.Repo -> IO a) -> IO a inLocalRepo (TransportHandle (LocalRepo g) _) a = a g++-- Check if some shas should be fetched from the remote,+-- and presumably later merged.+checkShouldFetch :: RemoteGitConfig -> TransportHandle -> [Git.Sha] -> IO Bool+checkShouldFetch gc transporthandle shas+ | remoteAnnexPull gc = checkNewShas transporthandle shas+ | otherwise = return False -- Check if any of the shas are actally new in the local git repo, -- to avoid unnecessary fetching.
RemoteDaemon/Transport/Ssh.hs view
@@ -36,7 +36,7 @@ transportUsingCmd' cmd params rr url transporthandle ichan ochan transportUsingCmd' :: FilePath -> [CommandParam] -> Transport-transportUsingCmd' cmd params (RemoteRepo r _) url transporthandle ichan ochan =+transportUsingCmd' cmd params (RemoteRepo r gc) url transporthandle ichan ochan = robustConnection 1 $ do (Just toh, Just fromh, Just errh, pid) <- createProcess (proc cmd (toCommand params))@@ -74,7 +74,7 @@ send (CONNECTED url) handlestdout fromh Just (SshRemote.CHANGED (ChangedRefs shas)) -> do- whenM (checkNewShas transporthandle shas) $+ whenM (checkShouldFetch gc transporthandle shas) $ fetch handlestdout fromh -- avoid reconnect on protocol error
RemoteDaemon/Transport/Tor.hs view
@@ -129,7 +129,7 @@ -- Connect to peer's tor hidden service. transport :: Transport-transport (RemoteRepo r _) url@(RemoteURI uri) th ichan ochan =+transport (RemoteRepo r gc) url@(RemoteURI uri) th ichan ochan = case unformatP2PAddress (show uri) of Nothing -> return () Just addr -> robustConnection 1 $ do@@ -168,7 +168,7 @@ v <- runNetProto conn P2P.notifyChange case v of Right (Just (ChangedRefs shas)) -> do- whenM (checkNewShas th shas) $+ whenM (checkShouldFetch gc th shas) $ fetch handlepeer conn _ -> return ConnectionClosed
Test.hs view
@@ -2110,6 +2110,7 @@ -- Make git and git-annex access ssh remotes on the local -- filesystem, without using ssh at all. , ("GIT_SSH_COMMAND", "git-annex test --fakessh --")+ , ("GIT_ANNEX_USE_GIT_SSH", "1") , ("TESTMODE", show testmode) ]
Types/GitConfig.hs view
@@ -48,7 +48,7 @@ , annexNumCopies :: Maybe NumCopies , annexDiskReserve :: Integer , annexDirect :: Bool- , annexBackends :: [String]+ , annexBackend :: Maybe String , annexQueueSize :: Maybe Int , annexBloomCapacity :: Maybe Int , annexBloomAccuracy :: Maybe Int@@ -98,7 +98,12 @@ , annexDiskReserve = fromMaybe onemegabyte $ readSize dataUnits =<< getmaybe (annex "diskreserve") , annexDirect = getbool (annex "direct") False- , annexBackends = getwords (annex "backends")+ , annexBackend = maybe+ -- annex.backends is the old name of the option, still used+ -- when annex.backend is not set.+ (headMaybe $ getwords (annex "backends"))+ Just+ (getmaybe (annex "backend")) , annexQueueSize = getmayberead (annex "queuesize") , annexBloomCapacity = getmayberead (annex "bloomcapacity") , annexBloomAccuracy = getmayberead (annex "bloomaccuracy")@@ -181,6 +186,8 @@ , remoteAnnexCostCommand :: Maybe String , remoteAnnexIgnore :: Bool , remoteAnnexSync :: Bool+ , remoteAnnexPull :: Bool+ , remoteAnnexPush :: Bool , remoteAnnexReadOnly :: Bool , remoteAnnexVerify :: Bool , remoteAnnexTrustLevel :: Maybe String@@ -218,6 +225,8 @@ , remoteAnnexCostCommand = notempty $ getmaybe "cost-command" , remoteAnnexIgnore = getbool "ignore" False , remoteAnnexSync = getbool "sync" True+ , remoteAnnexPull = getbool "pull" True+ , remoteAnnexPush = getbool "push" True , remoteAnnexReadOnly = getbool "readonly" False , remoteAnnexVerify = getbool "verify" True , remoteAnnexTrustLevel = notempty $ getmaybe "trustlevel"
Utility/FileMode.hs view
@@ -177,7 +177,10 @@ (\h -> hPutStr h content) writeFileProtected' :: FilePath -> (Handle -> IO ()) -> IO ()-writeFileProtected' file writer = withUmask 0o0077 $+writeFileProtected' file writer = protectedOutput $ withFile file WriteMode $ \h -> do void $ tryIO $ modifyFileMode file $ removeModes otherGroupModes writer h++protectedOutput :: IO a -> IO a+protectedOutput = withUmask 0o0077
doc/git-annex-add.mdwn view
@@ -56,6 +56,11 @@ Adds multiple files in parallel. This may be faster. For example: `-J4` +* `--update` `-u`++ Like `git add --update`, this does not add new files, but any updates+ to tracked files will be added to the index.+ * `--json` Enable JSON output. This is intended to be parsed by programs that use
doc/git-annex-calckey.mdwn view
@@ -12,7 +12,7 @@ to refer to a file. The file is not added to the annex by this command. The key is output to stdout. -The backend used is the first listed in the annex.backends configuration+The backend used is the one from the annex.backend configuration setting, which can be overridden by the --backend option. For example, to force use of the SHA1 backend:
doc/git-annex-dead.mdwn view
@@ -17,8 +17,9 @@ description, or their UUID. (To undo, use `git-annex semitrust`.) When a key is specified, indicates that the content of that key has been-irretrievably lost. This prevents `git annex fsck --all` from complaining-about it. (To undo, add the key's content back to the repository,+irretrievably lost. This prevents commands like `git annex fsck --all`+from complaining about it; `--all` will not operate on the key anymore.+(To undo, add the key's content back to the repository, by using eg, `git-annex reinject`.) # SEE ALSO
+ doc/git-annex-multicast.mdwn view
@@ -0,0 +1,95 @@+# NAME++git-annex multicast - multicast file distribution++# SYNOPSIS++git annex multicast [options]++# DESCRIPTION++Multicast allows files to be broadcast to multiple receivers,+typically on a single local network.++The uftp program is used for multicast.+<http://uftp-multicast.sourceforge.net/>++# OPTIONS++* `--gen-address`++ Generates a multicast encryption key and stores a corresponding multicast+ address to the git-annex branch.++* `--send [file]`++ Sends the specified files to any receivers whose multicast addresses+ are stored in the git-annex branch.++ When no files are specified, all annexed files in the current directory+ and subdirectories are sent.++ The [[git-annex-matching-options]] can be used to control which files to+ send. For example:++ git annex multicast send . --not --copies 2++* `--receive`++ Receives files from senders whose multicast addresses+ are stored in the git-annex brach.++ As each file is received, its filename is displayed. This is the filename+ that the sender used; the local working tree may use a different name+ for the file, or not contain a link to the file.++ This command continues running, until it is interrupted by you pressing+ ctrl-c.++ Note that the configured annex.diskreserve is not honored by this+ command, because `uftpd` receives the actual files, and can receive+ any size file.++* `--uftp-opt=option` `-Uoption`++ Pass an option on to the uftp/uftpd command. May be specified multiple+ times.++ For example, to broadcast at 50 Mbps:++ git annex multicast send -U-R -U50000++# EXAMPLE++Suppose a teacher wants to multicast files to students in a classroom.++This assumes that the teacher and students have cloned a git-annex+repository, and both can push changes to its git-annex branch,+or otherwise push changes to each-other.++First, the teacher runs `git annex multicast --gen-address; git annex sync`++Next, students each run `git annex multicast --gen-address; git annex sync`++Once all the students have generated addresses, the teacher runs+`git annex sync` once more. (Now the students all have received the+teacher's address, and the teacher has received all the student's addresses.)++Next students each run `git annex multicast --receive`++Finally, once the students are all listening (ahem), teacher runs+`git annex multicast --send`++# SEE ALSO++[[git-annex]](1)++uftp(1)++uftpd(1)++# AUTHOR++Joey Hess <id@joeyh.name>++Warning: Automatically converted into a man page by mdwn2man. Edit with care.
doc/git-annex-remotedaemon.mdwn view
@@ -29,6 +29,9 @@ repository. This is only done if you first run `git annex enable-tor`. Use `git annex p2p` to configure access to tor-annex remotes. +Note that when `remote.<name>.annex-pull` is set to false, the remotedaemon+will avoid fetching changes from that remote.+ # OPTIONS * `--foreground`
doc/git-annex-sync.mdwn view
@@ -8,10 +8,7 @@ # DESCRIPTION -Use this command when you want to synchronize the local repository with-one or more of its remotes. You can specify the remotes (or remote-groups) to sync with by name; the default if none are specified is to-sync with all remotes.+This command synchronizes the local repository with its remotes. The sync process involves first committing any local changes to files that have previously been added to the repository,@@ -36,6 +33,12 @@ # OPTIONS +* `[remote]`++ By default, all remotes are synced, except for remotes that have+ `remote.<name>.annex-sync` set to false. By specifying the names+ of remotes (or remote groups), you can control which ones to sync with.+ * `--fast` Only sync with the remotes with the lowest annex-cost value configured.@@ -52,11 +55,21 @@ * `--pull`, `--no-pull` - By default, git pulls from remotes. Use --no-pull to disable.+ By default, git pulls from remotes. Use --no-pull to disable all pulling. + When `remote.<name>.annex-pull` or `remote.<name>.annex-sync`+ are set to false, pulling is disabled for those remotes, and using+ `--pull` will not enable it.+ * `--push`, `--no-push` - By default, git pushes to remotes. Use --no-push to disable.+ By default, git pushes changes to remotes.+ Use --no-push to disable all pushing.+ + When `remote.<name>.annex-push` or `remote.<name>.annex-sync` are+ set to false, or `remote.<name>.annex-readonly` is set to true,+ pushing is disabled for those remotes, and using `--push` will not enable+ it. * `--content`, `--no-content` @@ -64,7 +77,7 @@ The --content option causes the content of files in the work tree to also be uploaded and downloaded as necessary. - The annex.synccontent configuration can be set to true to make content+ The `annex.synccontent` configuration can be set to true to make content be synced by default. Normally this tries to get each annexed file in the work tree
doc/git-annex.mdwn view
@@ -164,6 +164,12 @@ See [[git-annex-undo]](1) for details. +* `multicast`++ Multicast file distribution.++ See [[git-annex-multicast]](1) for details.+ * `watch` Watch for changes and autocommit.@@ -821,14 +827,17 @@ A unique UUID for this repository (automatically set). -* `annex.backends`+* `annex.backend` - Space-separated list of names of the key-value backends to use- when adding new files to the repository.+ Name of the default key-value backend to use when adding new files+ to the repository. This is overridden by annex annex.backend configuration in the- .gitattributes files.+ .gitattributes files, and by the --backend option. + (This used to be named `annex.backends`, and that will still be used+ if set.)+ * `annex.securehashesonly` Set to true to indicate that the repository should only use@@ -1150,8 +1159,19 @@ * `remote.<name>.annex-sync` If set to `false`, prevents git-annex sync (and the git-annex assistant)- from syncing with this remote.+ from syncing with this remote by default. However, `git annex sync <name>`+ can still be used to sync with the remote. +* `remote.<name>.annex-pull`++ If set to `false`, prevents git-annex sync (and the git-annex assistant+ etc) from ever pulling (or fetching) from the remote.++* `remote.<name>.annex-push`++ If set to `false`, prevents git-annex sync (and the git-annex assistant+ etc) from ever pushing to the remote.+ * `remote.<name>.annex-readonly` If set to `true`, prevents git-annex from making changes to a remote.@@ -1200,6 +1220,10 @@ to or from this remote. For example, to force IPv6, and limit the bandwidth to 100Kbyte/s, set it to `-6 --bwlimit 100` + Note that git-annex-shell has a whitelist of allowed rsync options,+ and others will not be be passed to the remote rsync. So using some+ options may break the communication between the local and remote rsyncs.+ * `remote.<name>.annex-rsync-upload-options` Options to use when using rsync to upload a file to a remote.@@ -1417,7 +1441,10 @@ Handled similarly to the same as described in git(1). The one difference is that git-annex will sometimes pass an additional "-n" parameter to these, as the first parameter, to prevent ssh from- reading from stdin.+ reading from stdin. Since that can break existing uses of these+ environment variables that don't expect the extra parameter, you will+ need to set `GIT_ANNEX_USE_GIT_SSH=1` to make git-annex support+ these. Note that setting either of these environment variables prevents git-annex from automatically enabling ssh connection caching
git-annex.cabal view
@@ -1,11 +1,11 @@ Name: git-annex-Version: 6.20170321+Version: 6.20170510 Cabal-Version: >= 1.8 License: GPL-3 Maintainer: Joey Hess <id@joeyh.name> Author: Joey Hess Stability: Stable-Copyright: 2010-2016 Joey Hess+Copyright: 2010-2017 Joey Hess License-File: COPYRIGHT Homepage: http://git-annex.branchable.com/ Build-type: Custom@@ -90,6 +90,7 @@ doc/git-annex-migrate.mdwn doc/git-annex-mirror.mdwn doc/git-annex-move.mdwn+ doc/git-annex-multicast.mdwn doc/git-annex-numcopies.mdwn doc/git-annex-p2p.mdwn doc/git-annex-pre-commit.mdwn@@ -383,7 +384,7 @@ if (os(windows)) Build-Depends: Win32, Win32-extras, unix-compat (>= 0.4.1.3), setenv,- process (>= 1.3.0.0)+ process (>= 1.4.2.0) else Build-Depends: unix if impl(ghc <= 7.6.3)@@ -518,6 +519,7 @@ Annex.MakeRepo Annex.MetaData Annex.MetaData.StandardFields+ Annex.Multicast Annex.Notification Annex.NumCopies Annex.Path@@ -662,7 +664,7 @@ Build.Standalone Build.TestConfig Build.Version- BuildFlags+ BuildInfo CmdLine CmdLine.Action CmdLine.Batch@@ -732,6 +734,7 @@ Command.Migrate Command.Mirror Command.Move+ Command.Multicast Command.NotifyChanges Command.NumCopies Command.P2P@@ -857,6 +860,7 @@ Logs.Location Logs.MapLog Logs.MetaData+ Logs.Multicast Logs.NumCopies Logs.PreferredContent Logs.PreferredContent.Raw
stack.yaml view
@@ -17,11 +17,10 @@ packages: - '.' extra-deps:-- esqueleto-2.5.1-- yesod-default-1.2.0+- aws-0.16 - bloomfilter-2.0.1.0-- network-multicast-0.2.0-- torrent-10000.0.1+- torrent-10000.1.1+- yesod-default-1.2.0 explicit-setup-deps: git-annex: true-resolver: lts-7.18+resolver: lts-8.6
templates/documentation/about.hamlet view
@@ -32,3 +32,4 @@ Version: #{packageversion} <br> Build flags: #{unwords buildFlags}+ Dependency versions: #{unwords dependencyVersions}