packages feed

git-annex 6.20170321 → 6.20170510

raw patch · 37 files changed

+821/−200 lines, 37 filesdep ~process

Dependency ranges changed: process

Files

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}