packages feed

git-annex 5.20150420 → 5.20150508

raw patch · 144 files changed

+1809/−893 lines, 144 filesdep +sandidep −dataencdep ~dbusdep ~path-piecesdep ~warpbinary-added

Dependencies added: sandi

Dependencies removed: dataenc

Dependency ranges changed: dbus, path-pieces, warp, yesod, yesod-core, yesod-default, yesod-form, yesod-static

Files

.mailmap view
@@ -1,7 +1,28 @@+Antoine Beaupré <anarcat@koumbit.org> anarcat <anarcat@web>+Antoine Beaupré <anarcat@koumbit.org> https://id.koumbit.net/anarcat <https://id.koumbit.net/anarcat@web>+Greg Grossmeier <greg@grossmeier.net> http://grossmeier.net/ <greg@web>+Jimmy Tang <jtang@tchpc.tcd.ie> jtang <jtang@web>+Joachim Breitner <mail@joachim-breitner.de> http://www.joachim-breitner.de/ <nomeata@web>+Joey Hess <id@joeyh.name> Joey Hess <joey@gnu.kitenet.net>+Joey Hess <id@joeyh.name> Joey Hess <joey@kitenet.net>+Joey Hess <id@joeyh.name> Joey Hess <joeyh@debian.org>+Joey Hess <id@joeyh.name> Joey Hess <joeyh@fischer.debian.org>+Joey Hess <id@joeyh.name> Joey Hess <joeyh@joeyh.name>+Joey Hess <id@joeyh.name> Joey Hess <joeyh@oberon.tam-lin.net>+Joey Hess <id@joeyh.name> Joey Hess <joeyh@oberon.underhill.private> Joey Hess <id@joeyh.name> http://joey.kitenet.net/ <joey@web>-Joey Hess <id@joeyh.name> http://joeyh.name/ <joey@web> Joey Hess <id@joeyh.name> http://joeyh.name/ <http://joeyh.name/@web>+Joey Hess <id@joeyh.name> http://joeyh.name/ <joey@web>+Joey Hess <id@joeyh.name> https://www.google.com/accounts/o8/id?id=AItOawmJfIszzreLNvCqzqzvTayA9_9L6gb9RtY <Joey@web>+Johan Kiviniemi <devel@johan.kiviniemi.name> http://johan.kiviniemi.name/ <Johan@web>+Johan Kiviniemi <devel@johan.kiviniemi.name> http://johan.kiviniemi.name/ <http://johan.kiviniemi.name/@web>+Nicolas Pouillard <nicolas.pouillard@gmail.com> http://ertai.myopenid.com/ <npouillard@web>+Peter Simons <simons@cryp.to> Peter Simons <simons@ubuntu-12.04>+Peter Simons <simons@cryp.to> http://peter-simons.myopenid.com/ <http://peter-simons.myopenid.com/@web>+Philipp Kern <pkern@debian.org> http://phil.0x539.de/ <Philipp_Kern@web>+Richard Hartmann <richih@debian.org> https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U <Richard@web> Yaroslav Halchenko <debian@onerussian.com> Yaroslav Halchenko <debian@onerussian.com> http://yarikoptic.myopenid.com/ <site-myopenid@web> Yaroslav Halchenko <debian@onerussian.com> https://www.google.com/accounts/o8/id?id=AItOawnx8kHW66N3BqmkVpgtXDlYMvr8TJ5VvfY <Yaroslav@web>-Richard Hartmann <richih@debian.org> https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U <Richard@web>+Øyvind A. Holm <sunny@sunbase.org> http://sunny256.sunbase.org/ <sunny256@web>+Øyvind A. Holm <sunny@sunbase.org> https://sunny256.wordpress.com/ <sunny256@web>
Annex.hs view
@@ -5,7 +5,7 @@  - Licensed under the GNU GPL version 3 or higher.  -} -{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, PackageImports #-}+{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, PackageImports, BangPatterns #-}  module Annex ( 	Annex,@@ -32,6 +32,7 @@ 	getRemoteGitConfig, 	withCurrentState, 	changeDirectory,+	incError, ) where  import Common@@ -309,3 +310,9 @@ 	liftIO $ setCurrentDirectory d 	r' <- liftIO $ Git.relPath r 	changeState $ \s -> s { repo = r' }++incError :: Annex ()+incError = changeState $ \s -> +	let ! c = errcounter s + 1 +	    ! s' = s { errcounter = c }+	in s'
Annex/Drop.hs view
@@ -9,7 +9,7 @@  import Common.Annex import Logs.Trust-import Config.NumCopies+import Annex.NumCopies import Types.Remote (uuid) import Types.Key (key2file) import qualified Remote
+ Annex/NumCopies.hs view
@@ -0,0 +1,147 @@+{- git-annex numcopies configuration and checking+ -+ - Copyright 2014-2015 Joey Hess <id@joeyh.name>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Annex.NumCopies (+	module Types.NumCopies,+	module Logs.NumCopies,+	getFileNumCopies,+	getGlobalFileNumCopies,+	getNumCopies,+	deprecatedNumCopies,+	defaultNumCopies,+	numCopiesCheck,+	numCopiesCheck',+	verifyEnoughCopies,+	knownCopies,+) where++import Common.Annex+import qualified Annex+import Types.NumCopies+import Logs.NumCopies+import Logs.Trust+import Annex.CheckAttr+import qualified Remote+import Annex.UUID+import Annex.Content++defaultNumCopies :: NumCopies+defaultNumCopies = NumCopies 1++fromSources :: [Annex (Maybe NumCopies)] -> Annex NumCopies+fromSources = fromMaybe defaultNumCopies <$$> getM id++{- The git config annex.numcopies is deprecated. -}+deprecatedNumCopies :: Annex (Maybe NumCopies)+deprecatedNumCopies = annexNumCopies <$> Annex.getGitConfig++{- Value forced on the command line by --numcopies. -}+getForcedNumCopies :: Annex (Maybe NumCopies)+getForcedNumCopies = Annex.getState Annex.forcenumcopies++{- Numcopies value from any of the non-.gitattributes configuration+ - sources. -}+getNumCopies :: Annex NumCopies+getNumCopies = fromSources+	[ getForcedNumCopies+	, getGlobalNumCopies+	, deprecatedNumCopies+	]++{- Numcopies value for a file, from any configuration source, including the+ - deprecated git config. -}+getFileNumCopies :: FilePath -> Annex NumCopies+getFileNumCopies f = fromSources+	[ getForcedNumCopies+	, getFileNumCopies' f+	, deprecatedNumCopies+	]++{- This is the globally visible numcopies value for a file. So it does+ - not include local configuration in the git config or command line+ - options. -}+getGlobalFileNumCopies :: FilePath  -> Annex NumCopies+getGlobalFileNumCopies f = fromSources+	[ getFileNumCopies' f+	]++getFileNumCopies' :: FilePath  -> Annex (Maybe NumCopies)+getFileNumCopies' file = maybe getGlobalNumCopies (return . Just) =<< getattr+  where+	getattr = (NumCopies <$$> readish)+		<$> checkAttr "annex.numcopies" file++{- Checks if numcopies are satisfied for a file by running a comparison+ - between the number of (not untrusted) copies that are+ - belived to exist, and the configured value. -}+numCopiesCheck :: FilePath -> Key -> (Int -> Int -> v) -> Annex v+numCopiesCheck file key vs = do+	have <- trustExclude UnTrusted =<< Remote.keyLocations key+	numCopiesCheck' file vs have++numCopiesCheck' :: FilePath -> (Int -> Int -> v) -> [UUID] -> Annex v+numCopiesCheck' file vs have = do+	NumCopies needed <- getFileNumCopies file+	return $ length have `vs` needed++{- Verifies that enough copies of a key exist amoung the listed remotes,+ - priting an informative message if not.+ -}+verifyEnoughCopies +	:: String -- message to print when there are no known locations+	-> Key+	-> NumCopies+	-> [UUID] -- repos to skip (generally untrusted remotes)+	-> [UUID] -- repos that are trusted or already verified to have it+	-> [Remote] -- remotes to check to see if they have it+	-> Annex Bool+verifyEnoughCopies nolocmsg key need skip trusted tocheck = +	helper [] [] (nub trusted) (nub tocheck)+  where+	helper bad missing have []+		| NumCopies (length have) >= need = return True+		| otherwise = do+			notEnoughCopies key need have (skip++missing) bad nolocmsg+			return False+	helper bad missing have (r:rs)+		| NumCopies (length have) >= need = return True+		| otherwise = do+			let u = Remote.uuid r+			let duplicate = u `elem` have+			haskey <- Remote.hasKey r key+			case (duplicate, haskey) of+				(False, Right True)  -> helper bad missing (u:have) rs+				(False, Left _)      -> helper (r:bad) missing have rs+				(False, Right False) -> helper bad (u:missing) have rs+				_                    -> helper bad missing have rs++notEnoughCopies :: Key -> NumCopies -> [UUID] -> [UUID] -> [Remote] -> String -> Annex ()+notEnoughCopies key need have skip bad nolocmsg = do+	showNote "unsafe"+	showLongNote $+		"Could only verify the existence of " +++		show (length have) ++ " out of " ++ show (fromNumCopies need) ++ +		" necessary copies"+	Remote.showTriedRemotes bad+	Remote.showLocations True key (have++skip) nolocmsg++{- Cost ordered lists of remotes that the location log indicates+ - may have a key.+ -+ - Also returns a list of UUIDs that are trusted to have the key+ - (some may not have configured remotes). If the current repository+ - currently has the key, and is not untrusted, it is included in this list.+ -}+knownCopies :: Key -> Annex ([Remote], [UUID])+knownCopies key = do+	(remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key+	u <- getUUID+	trusteduuids' <- ifM (inAnnex key <&&> (<= SemiTrusted) <$> lookupTrust u)+		( pure (u:trusteduuids)+		, pure trusteduuids+		)+	return (remotes, trusteduuids')
Assistant/Install.hs view
@@ -145,10 +145,12 @@ 		, "Name=" ++ command 		, "Icon=git-annex" 		, unwords-			[ "Exec=sh -c 'cd \"$(dirname '%U')\" &&"+			[ "Exec=sh -c 'cd \"$(dirname \"$1\")\" &&" 			, program 			, command-			, "--notify-start --notify-finish -- %U'"+			, "--notify-start --notify-finish -- \"$1\"'"+			, "false" -- this becomes $0 in sh, so unused+			, "%f" 			] 		] #else
Assistant/Threads/MountWatcher.hs view
@@ -63,11 +63,7 @@ 				wasmounted <- liftIO $ swapMVar mvar nowmounted 				handleMounts urlrenderer wasmounted nowmounted 			liftIO $ forM_ mountChanged $ \matcher ->-#if MIN_VERSION_dbus(0,10,7) 				void $ addMatch client matcher handleevent-#else-				listen client matcher handleevent-#endif 		, do 			liftAnnex $ 				warning "No known volume monitor available through dbus; falling back to mtab polling"
Assistant/Threads/NetWatcher.hs view
@@ -112,11 +112,7 @@  -} listenNMConnections :: Client -> (Bool -> IO ()) -> IO () listenNMConnections client setconnected =-#if MIN_VERSION_dbus(0,10,7) 	void $ addMatch client matcher-#else-	listen client matcher-#endif 		$ \event -> mapM_ handleevent 			(map dictionaryItems $ mapMaybe fromVariant $ signalBody event)   where@@ -166,11 +162,7 @@ 		| any (== wicd_disconnected) status = setconnected False 		| otherwise = noop 	match matcher a = -#if MIN_VERSION_dbus(0,10,7) 		void $ addMatch client matcher a-#else-		listen client matcher a-#endif #endif  handleConnection :: Assistant ()
− Assistant/WebApp/Bootstrap3.hs
@@ -1,260 +0,0 @@-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE OverloadedStrings #-}--- | Helper functions for creating forms when using Bootstrap v3.--- This is a copy of the Yesod.Form.Bootstrap3 module that has been slightly--- modified to be compatible with Yesod 1.0.1-module Assistant.WebApp.Bootstrap3-  ( -- * Rendering forms-    renderBootstrap3-  , BootstrapFormLayout(..)-  , BootstrapGridOptions(..)-    -- * Field settings-  , bfs-  , withPlaceholder-  , withAutofocus-  , withLargeInput-  , withSmallInput-    -- * Submit button-  , bootstrapSubmit-  , mbootstrapSubmit-  , BootstrapSubmit(..)-  ) where--import Control.Arrow (second)-import Control.Monad (liftM)-import Data.Text (Text)-import Data.String (IsString(..))-import Yesod.Core--import qualified Data.Text as T--import Yesod.Form.Types-import Yesod.Form.Functions---- | Create a new 'FieldSettings' with the classes that are--- required by Bootstrap v3.------ Since: yesod-form 1.3.8-bfs :: RenderMessage site msg => msg -> FieldSettings site-bfs msg =-    FieldSettings (SomeMessage msg) Nothing Nothing Nothing [("class", "form-control")]----- | Add a placeholder attribute to a field.  If you need i18n--- for the placeholder, currently you\'ll need to do a hack and--- use 'getMessageRender' manually.------ Since: yesod-form 1.3.8-withPlaceholder :: Text -> FieldSettings site -> FieldSettings site-withPlaceholder placeholder fs = fs { fsAttrs = newAttrs }-    where newAttrs = ("placeholder", placeholder) : fsAttrs fs----- | Add an autofocus attribute to a field.------ Since: yesod-form 1.3.8-withAutofocus :: FieldSettings site -> FieldSettings site-withAutofocus fs = fs { fsAttrs = newAttrs }-    where newAttrs = ("autofocus", "autofocus") : fsAttrs fs----- | Add the @input-lg@ CSS class to a field.------ Since: yesod-form 1.3.8-withLargeInput :: FieldSettings site -> FieldSettings site-withLargeInput fs = fs { fsAttrs = newAttrs }-    where newAttrs = addClass "input-lg" (fsAttrs fs)----- | Add the @input-sm@ CSS class to a field.------ Since: yesod-form 1.3.8-withSmallInput :: FieldSettings site -> FieldSettings site-withSmallInput fs = fs { fsAttrs = newAttrs }-    where newAttrs = addClass "input-sm" (fsAttrs fs)---addClass :: Text -> [(Text, Text)] -> [(Text, Text)]-addClass klass []                    = [("class", klass)]-addClass klass (("class", old):rest) = ("class", T.concat [old, " ", klass]) : rest-addClass klass (other         :rest) = other : addClass klass rest----- | How many bootstrap grid columns should be taken (see--- 'BootstrapFormLayout').------ Since: yesod-form 1.3.8-data BootstrapGridOptions =-    ColXs !Int-  | ColSm !Int-  | ColMd !Int-  | ColLg !Int-    deriving (Eq, Ord, Show)--toColumn :: BootstrapGridOptions -> String-toColumn (ColXs 0) = ""-toColumn (ColSm 0) = ""-toColumn (ColMd 0) = ""-toColumn (ColLg 0) = ""-toColumn (ColXs columns) = "col-xs-" ++ show columns-toColumn (ColSm columns) = "col-sm-" ++ show columns-toColumn (ColMd columns) = "col-md-" ++ show columns-toColumn (ColLg columns) = "col-lg-" ++ show columns--toOffset :: BootstrapGridOptions -> String-toOffset (ColXs 0) = ""-toOffset (ColSm 0) = ""-toOffset (ColMd 0) = ""-toOffset (ColLg 0) = ""-toOffset (ColXs columns) = "col-xs-offset-" ++ show columns-toOffset (ColSm columns) = "col-sm-offset-" ++ show columns-toOffset (ColMd columns) = "col-md-offset-" ++ show columns-toOffset (ColLg columns) = "col-lg-offset-" ++ show columns--addGO :: BootstrapGridOptions -> BootstrapGridOptions -> BootstrapGridOptions-addGO (ColXs a) (ColXs b) = ColXs (a+b)-addGO (ColSm a) (ColSm b) = ColSm (a+b)-addGO (ColMd a) (ColMd b) = ColMd (a+b)-addGO (ColLg a) (ColLg b) = ColLg (a+b)-addGO a b     | a > b = addGO b a-addGO (ColXs a) other = addGO (ColSm a) other-addGO (ColSm a) other = addGO (ColMd a) other-addGO (ColMd a) other = addGO (ColLg a) other-addGO (ColLg _) _     = error "Yesod.Form.Bootstrap.addGO: never here"----- | The layout used for the bootstrap form.------ Since: yesod-form 1.3.8-data BootstrapFormLayout =-    BootstrapBasicForm-  | BootstrapInlineForm-  | BootstrapHorizontalForm-      { bflLabelOffset :: !BootstrapGridOptions-      , bflLabelSize   :: !BootstrapGridOptions-      , bflInputOffset :: !BootstrapGridOptions-      , bflInputSize   :: !BootstrapGridOptions-      }-    deriving (Show)----- | Render the given form using Bootstrap v3 conventions.------ Sample Hamlet for 'BootstrapHorizontalForm':------ >  <form .form-horizontal role=form method=post action=@{ActionR} enctype=#{formEnctype}>--- >    ^{formWidget}--- >    ^{bootstrapSubmit MsgSubmit}------ Since: yesod-form 1.3.8-renderBootstrap3 :: BootstrapFormLayout -> FormRender sub master a-renderBootstrap3 formLayout aform fragment = do-    (res, views') <- aFormToForm aform-    let views = views' []-        has (Just _) = True-        has Nothing  = False-        widget = [whamlet|-            #{fragment}-            $forall view <- views-              <div .form-group :fvRequired view:.required :not $ fvRequired view:.optional :has $ fvErrors view:.has-error>-                $case formLayout-                  $of BootstrapBasicForm-                    $if nequals (fvId view) bootstrapSubmitId-                      <label for=#{fvId view}>#{fvLabel view}-                    ^{fvInput view}-                    ^{helpWidget view}-                  $of BootstrapInlineForm-                    $if nequals (fvId view) bootstrapSubmitId-                      <label .sr-only for=#{fvId view}>#{fvLabel view}-                    ^{fvInput view}-                    ^{helpWidget view}-                  $of BootstrapHorizontalForm _a _b _c _d-                    $if nequals (fvId view) bootstrapSubmitId-                      <label .control-label .#{toOffset (bflLabelOffset formLayout)} .#{toColumn (bflLabelSize formLayout)} for=#{fvId view}>#{fvLabel view}-                      <div .#{toOffset (bflInputOffset formLayout)} .#{toColumn (bflInputSize formLayout)}>-                        ^{fvInput view}-                        ^{helpWidget view}-                    $else-                      <div .#{toOffset (addGO (bflInputOffset formLayout) (addGO (bflLabelOffset formLayout) (bflLabelSize formLayout)))} .#{toColumn (bflInputSize formLayout)}>-                        ^{fvInput view}-                        ^{helpWidget view}-                |]-    return (res, widget)-  where-    nequals a b = a /= b -- work around older hamlet versions not liking /=---- | (Internal) Render a help widget for tooltips and errors.-helpWidget :: FieldView sub master -> GWidget sub master ()-helpWidget view = [whamlet|-    $maybe tt <- fvTooltip view-      <span .help-block>#{tt}-    $maybe err <- fvErrors view-      <span .help-block>#{err}-|]----- | How the 'bootstrapSubmit' button should be rendered.------ Since: yesod-form 1.3.8-data BootstrapSubmit msg =-    BootstrapSubmit-        { bsValue   :: msg-          -- ^ The text of the submit button.-        , bsClasses :: Text-          -- ^ Classes added to the @<button>@.-        , bsAttrs   :: [(Text, Text)]-          -- ^ Attributes added to the @<button>@.-        } deriving (Show)--instance IsString msg => IsString (BootstrapSubmit msg) where-    fromString msg = BootstrapSubmit (fromString msg) " btn-default " []----- | A Bootstrap v3 submit button disguised as a field for--- convenience.  For example, if your form currently is:------ > Person <$> areq textField "Name"    Nothing--- >        <*> areq textField "Surname" Nothing------ Then just change it to:------ > Person <$> areq textField "Name"    Nothing--- >        <*> areq textField "Surname" Nothing--- >        <*  bootstrapSubmit "Register"------ (Note that @<*@ is not a typo.)------ Alternatively, you may also just create the submit button--- manually as well in order to have more control over its--- layout.------ Since: yesod-form 1.3.8-bootstrapSubmit :: (RenderMessage master msg) => BootstrapSubmit msg -> AForm sub master ()-bootstrapSubmit = formToAForm . liftM (second return) . mbootstrapSubmit----- | Same as 'bootstrapSubmit' but for monadic forms.  This isn't--- as useful since you're not going to use 'renderBootstrap3'--- anyway.------ Since: yesod-form 1.3.8-mbootstrapSubmit :: (RenderMessage master msg) => BootstrapSubmit msg -> MForm sub master (FormResult (), FieldView sub master)-mbootstrapSubmit (BootstrapSubmit msg classes attrs) =-    let res = FormSuccess ()-        widget = [whamlet|<button class="btn #{classes}" type=submit *{attrs}>_{msg}|]-        fv  = FieldView { fvLabel    = ""-                        , fvTooltip  = Nothing-                        , fvId       = bootstrapSubmitId-                        , fvInput    = widget-                        , fvErrors   = Nothing-                        , fvRequired = False }-    in return (res, fv)----- | A royal hack.  Magic id used to identify whether a field--- should have no label.  A valid HTML4 id which is probably not--- going to clash with any other id should someone use--- 'bootstrapSubmit' outside 'renderBootstrap3'.-bootstrapSubmitId :: Text-bootstrapSubmitId = "b:ootstrap___unique__:::::::::::::::::submit-id"
Assistant/WebApp/Common.hs view
@@ -5,8 +5,6 @@  - Licensed under the GNU AGPL version 3 or higher.  -} -{-# LANGUAGE CPP #-}- module Assistant.WebApp.Common (module X) where  import Assistant.Common as X@@ -15,9 +13,5 @@ import Assistant.WebApp.Form as X import Assistant.WebApp.Types as X import Assistant.WebApp.RepoId as X-#if MIN_VERSION_yesod(1,2,0) import Utility.Yesod as X hiding (textField, passwordField, insertBy, replace, joinPath, deleteBy, delete, insert, Key, Option)-#else-import Utility.Yesod as X hiding (textField, passwordField, selectField, selectFieldList, insertBy, replace, joinPath, deleteBy, delete, insert, Key, Option)-#endif import Data.Text as X (Text)
+ Assistant/WebApp/Configurators/.Ssh.hs.swp view

binary file changed (absent → 16384 bytes)

Assistant/WebApp/Configurators/Local.hs view
@@ -50,18 +50,10 @@  -  - Validates that the path entered is not empty, and is a safe value  - to use as a repository. -}-#if MIN_VERSION_yesod(1,2,0) repositoryPathField :: forall (m :: * -> *). (MonadIO m, HandlerSite m ~ WebApp) => Bool -> Field m Text-#else-repositoryPathField :: forall sub. Bool -> Field sub WebApp Text-#endif repositoryPathField autofocus = Field-#if ! MIN_VERSION_yesod_form(1,2,0)-	{ fieldParse = parse-#else 	{ fieldParse = \l _ -> parse l 	, fieldEnctype = UrlEncoded-#endif 	, fieldView = view 	}   where
Assistant/WebApp/Configurators/Preferences.hs view
@@ -17,7 +17,7 @@ import qualified Git import Config import Config.Files-import Config.NumCopies+import Annex.NumCopies import Utility.DataUnits import Git.Config import Types.Distribution
Assistant/WebApp/Configurators/Ssh.hs view
@@ -86,11 +86,7 @@ 	, inputPort = sshPort s 	} -#if MIN_VERSION_yesod(1,2,0) sshInputAForm :: Field Handler Text -> SshInput -> AForm Handler SshInput-#else-sshInputAForm :: Field WebApp WebApp Text -> SshInput -> AForm WebApp WebApp SshInput-#endif sshInputAForm hostnamefield d = normalize <$> gen   where 	gen = SshInput
Assistant/WebApp/Form.hs view
@@ -8,28 +8,15 @@ {-# LANGUAGE FlexibleContexts, TypeFamilies, QuasiQuotes #-} {-# LANGUAGE MultiParamTypeClasses, TemplateHaskell #-} {-# LANGUAGE OverloadedStrings, RankNTypes #-}-{-# LANGUAGE CPP #-}  module Assistant.WebApp.Form where  import Assistant.WebApp.Types import Assistant.Gpg -#if MIN_VERSION_yesod(1,2,0) import Yesod hiding (textField, passwordField) import Yesod.Form.Fields as F-#else-import Yesod hiding (textField, passwordField, selectField, selectFieldList)-import Yesod.Form.Fields as F hiding (selectField, selectFieldList)-import Data.String (IsString (..))-import Control.Monad (unless)-import Data.Maybe (listToMaybe)-#endif-#if MIN_VERSION_yesod_form(1,3,8) import Yesod.Form.Bootstrap3 as Y hiding (bfs)-#else-import Assistant.WebApp.Bootstrap3 as Y hiding (bfs)-#endif import Data.Text (Text)  {- Yesod's textField sets the required attribute for required fields.@@ -61,60 +48,8 @@ |] 	} -{- In older Yesod versions attrs is written into the <option> tag instead of the- - surrounding <select>. This breaks the Bootstrap 3 layout of select fields as- - it requires the "form-control" class on the <select> tag.- - We need to change that to behave the same way as in newer versions.- -}-#if ! MIN_VERSION_yesod(1,2,0)-selectFieldList :: (Eq a, RenderMessage master FormMessage, RenderMessage master msg) => [(msg, a)] -> Field sub master a-selectFieldList = selectField . optionsPairs--selectField :: (Eq a, RenderMessage master FormMessage) => GHandler sub master (OptionList a) -> Field sub master a-selectField = selectFieldHelper-	(\theId name attrs inside -> [whamlet|<select ##{theId} name=#{name} *{attrs}>^{inside}|]) -- outside-	(\_theId _name isSel -> [whamlet|<option value=none :isSel:selected>_{MsgSelectNone}|]) -- onOpt-	(\_theId _name _attrs value isSel text -> [whamlet|<option value=#{value} :isSel:selected>#{text}|]) -- inside--selectFieldHelper :: (Eq a, RenderMessage master FormMessage)-	=> (Text -> Text -> [(Text, Text)] -> GWidget sub master () -> GWidget sub master ())-	-> (Text -> Text -> Bool -> GWidget sub master ())-	-> (Text -> Text -> [(Text, Text)] -> Text -> Bool -> Text -> GWidget sub master ())-	-> GHandler sub master (OptionList a) -> Field sub master a-selectFieldHelper outside onOpt inside opts' = Field-	{ fieldParse = \x -> do-		opts <- opts'-		return $ selectParser opts x-	, fieldView = \theId name attrs val isReq -> do-		opts <- fmap olOptions $ lift opts'-		outside theId name attrs $ do-			unless isReq $ onOpt theId name $ not $ render opts val `elem` map optionExternalValue opts-			flip mapM_ opts $ \opt -> inside-				theId-				name-				((if isReq then (("required", "required"):) else id) attrs)-				(optionExternalValue opt)-				((render opts val) == optionExternalValue opt)-				(optionDisplay opt)-	}-  where-	render _ (Left _) = ""-	render opts (Right a) = maybe "" optionExternalValue $ listToMaybe $ filter ((== a) . optionInternalValue) opts-	selectParser _ [] = Right Nothing-	selectParser opts (s:_) = case s of-		"" -> Right Nothing-		"none" -> Right Nothing-		x -> case olReadExternal opts x of-			Nothing -> Left $ SomeMessage $ MsgInvalidEntry x-			Just y -> Right $ Just y-#endif- {- Makes a note widget be displayed after a field. -}-#if MIN_VERSION_yesod(1,2,0) withNote :: (Monad m, ToWidget (HandlerSite m) a) => Field m v -> a -> Field m v-#else-withNote :: Field sub master v -> GWidget sub master () -> Field sub master v-#endif withNote field note = field { fieldView = newview }   where 	newview theId name attrs val isReq = @@ -122,11 +57,7 @@ 		in [whamlet|^{fieldwidget}&nbsp;&nbsp;<span>^{note}</span>|]  {- Note that the toggle string must be unique on the form. -}-#if MIN_VERSION_yesod(1,2,0) withExpandableNote :: (Monad m, ToWidget (HandlerSite m) w) => Field m v -> (String, w) -> Field m v-#else-withExpandableNote :: Field sub master v -> (String, GWidget sub master ()) -> Field sub master v-#endif withExpandableNote field (toggle, note) = withNote field $ [whamlet| <a .btn .btn-default data-toggle="collapse" data-target="##{ident}">#{toggle}</a> <div ##{ident} .collapse>@@ -136,11 +67,7 @@ 	ident = "toggle_" ++ toggle  {- Adds a check box to an AForm to control encryption. -}-#if MIN_VERSION_yesod(1,2,0) enableEncryptionField :: (RenderMessage site FormMessage) => AForm (HandlerT site IO) EnableEncryption-#else-enableEncryptionField :: RenderMessage master FormMessage => AForm sub master EnableEncryption-#endif enableEncryptionField = areq (selectFieldList choices) (bfs "Encryption") (Just SharedEncryption)   where 	choices :: [(Text, EnableEncryption)]
Assistant/WebApp/Notifications.hs view
@@ -5,13 +5,7 @@  - Licensed under the GNU AGPL version 3 or higher.  -} -{-# LANGUAGE CPP, QuasiQuotes, TemplateHaskell, OverloadedStrings #-}--#if defined VERSION_yesod_default-#if ! MIN_VERSION_yesod_default(1,1,0)-#define WITH_OLD_YESOD-#endif-#endif+{-# LANGUAGE QuasiQuotes, TemplateHaskell, OverloadedStrings #-}  module Assistant.WebApp.Notifications where @@ -26,9 +20,7 @@  import Data.Text (Text) import qualified Data.Text as T-#ifndef WITH_OLD_YESOD import qualified Data.Aeson.Types as Aeson-#endif  {- Add to any widget to make it auto-update using long polling.  -@@ -42,15 +34,9 @@  -} autoUpdate :: Text -> Route WebApp -> Int -> Int -> Widget autoUpdate tident geturl ms_delay ms_startdelay = do-#ifdef WITH_OLD_YESOD-	let delay = show ms_delay-	let startdelay = show ms_startdelay-	let ident = "'" ++ T.unpack tident ++ "'"-#else 	let delay = Aeson.String (T.pack (show ms_delay)) 	let startdelay = Aeson.String (T.pack (show ms_startdelay)) 	let ident = Aeson.String tident-#endif 	$(widgetFile "notifications/longpolling")  {- Notifier urls are requested by the javascript, to avoid allocation
Assistant/WebApp/Types.hs view
@@ -8,7 +8,6 @@ {-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell, OverloadedStrings, RankNTypes #-} {-# LANGUAGE FlexibleInstances, FlexibleContexts, ViewPatterns #-}-{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-orphans #-}  module Assistant.WebApp.Types where@@ -83,58 +82,30 @@ instance RenderMessage WebApp FormMessage where 	renderMessage _ _ = defaultFormMessage -#if MIN_VERSION_yesod(1,2,0) instance LiftAnnex Handler where-#else-instance LiftAnnex (GHandler sub WebApp) where-#endif 	liftAnnex a = ifM (noAnnex <$> getYesod) 		( error "internal liftAnnex" 		, liftAssistant $ liftAnnex a 		) -#if MIN_VERSION_yesod(1,2,0) instance LiftAnnex (WidgetT WebApp IO) where-#else-instance LiftAnnex (GWidget WebApp WebApp) where-#endif 	liftAnnex = liftH . liftAnnex  class LiftAssistant m where 	liftAssistant :: Assistant a -> m a -#if MIN_VERSION_yesod(1,2,0) instance LiftAssistant Handler where-#else-instance LiftAssistant (GHandler sub WebApp) where-#endif 	liftAssistant a = liftIO . flip runAssistant a 		=<< assistantData <$> getYesod -#if MIN_VERSION_yesod(1,2,0) instance LiftAssistant (WidgetT WebApp IO) where-#else-instance LiftAssistant (GWidget WebApp WebApp) where-#endif 	liftAssistant = liftH . liftAssistant -#if MIN_VERSION_yesod(1,2,0) type MkMForm x = MForm Handler (FormResult x, Widget)-#else-type MkMForm x = MForm WebApp WebApp (FormResult x, Widget)-#endif -#if MIN_VERSION_yesod(1,2,0) type MkAForm x = AForm Handler x-#else-type MkAForm x = AForm WebApp WebApp x-#endif -#if MIN_VERSION_yesod(1,2,0) type MkField x = Monad m => RenderMessage (HandlerSite m) FormMessage => Field m x-#else-type MkField x = RenderMessage master FormMessage => Field sub master x-#endif  data RepoSelector = RepoSelector 	{ onlyCloud :: Bool@@ -153,12 +124,6 @@  data RepoKey = RepoKey KeyId | NoRepoKey 	deriving (Read, Show, Eq, Ord)--#if ! MIN_VERSION_path_pieces(0,1,4)-instance PathPiece Bool where-	toPathPiece = pack . show-	fromPathPiece = readish . unpack-#endif  instance PathPiece RemovableDrive where 	toPathPiece = pack . show
Assistant/XMPP.hs view
@@ -22,7 +22,8 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.XML.Types-import qualified "dataenc" Codec.Binary.Base64 as B64+import qualified "sandi" Codec.Binary.Base64 as B64+import Data.Bits.Utils  {- Name of the git-annex tag, in our own XML namespace.  - (Not using a namespace URL to avoid unnecessary bloat.) -}@@ -212,10 +213,10 @@  {- Base 64 encoding a ByteString to use as the content of a tag. -} encodeTagContent :: ByteString -> [Node]-encodeTagContent b = [NodeContent $ ContentText $ T.pack $ B64.encode $ B.unpack b]+encodeTagContent b = [NodeContent $ ContentText $ T.pack $ w82s $ B.unpack $ B64.encode b]  decodeTagContent :: Element -> Maybe ByteString-decodeTagContent elt = B.pack <$> B64.decode s+decodeTagContent elt = either (const Nothing) Just (B64.decode $ B.pack $ s2w8 s)   where 	s = T.unpack $ T.concat $ elementText elt 
Build/BundledPrograms.hs view
@@ -35,12 +35,13 @@ #endif 	, Just "rsync" #ifndef darwin_HOST_OS+#ifndef mingw32_HOST_OS 	-- OS X has ssh installed by default. 	-- Linux probably has ssh, but not guaranteed.-	-- On Windows, msysgit provides ssh, but not in PATH, -	-- so we ship our own.+	-- On Windows, msysgit provides ssh. 	, Just "ssh" 	, Just "ssh-keygen"+#endif #endif #ifndef mingw32_HOST_OS 	, Just "sh"
Build/DistributionUpdate.hs view
@@ -10,7 +10,7 @@  import Common.Annex import Types.Distribution-import Build.Version+import Build.Version (getChangelogVersion, Version) import Utility.UserInfo import Utility.Url import qualified Git.Construct
Build/NullSoftInstaller.hs view
@@ -1,7 +1,8 @@ {- Generates a NullSoft installer program for git-annex on Windows.
  - 
  - To build the installer, git-annex should already be built by cabal,
- - and ssh and rsync, as well as cygwin libraries, already installed.
+ - and ssh and rsync etc, as well as cygwin libraries, already installed
+ - from cygwin.
  -
  - This uses the Haskell nsis package (cabal install nsis)
  - to generate a .nsi file, which is then used to produce
@@ -11,7 +12,7 @@  - exception of git. The user needs to install git separately,
  - and the installer checks for that.
  -
- - Copyright 2013 Joey Hess <id@joeyh.name>
+ - Copyright 2013-2015 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU GPL version 3 or higher.
  -}
@@ -22,13 +23,17 @@ import System.Directory
 import System.FilePath
 import Control.Monad
+import Control.Applicative
 import Data.String
 import Data.Maybe
+import Data.Char
+import Data.List (nub, isPrefixOf)
 
 import Utility.Tmp
 import Utility.Path
 import Utility.CopyFile
 import Utility.SafeCommand
+import Utility.Process
 import Build.BundledPrograms
 
 main = do
@@ -37,17 +42,19 @@ 		mustSucceed "ln" [File "dist/build/git-annex/git-annex.exe", File gitannex]
 		let license = tmpdir </> licensefile
 		mustSucceed "sh" [Param "-c", Param $ "zcat standalone/licences.gz > '" ++ license ++ "'"]
-		extrabins <- forM (cygwinPrograms ++ cygwinDlls) $ \f -> do
+		extrabins <- forM (cygwinPrograms) $ \f -> do
 			p <- searchPath f
 			when (isNothing p) $
 				print ("unable to find in PATH", f)
 			return p
+		dlls <- forM (catMaybes extrabins) findCygLibs
+		dllpaths <- mapM searchPath (nub (concat dlls))
 		webappscript <- vbsLauncher tmpdir "git-annex-webapp" "git-annex webapp"
 		autostartscript <- vbsLauncher tmpdir "git-annex-autostart" "git annex assistant --autostart"
 		let htmlhelp = tmpdir </> "git-annex.html"
 		writeFile htmlhelp htmlHelpText
 		writeFile nsifile $ makeInstaller gitannex license htmlhelp
-			(catMaybes extrabins)
+			(wrappers ++ catMaybes (extrabins ++ dllpaths))
 			[ webappscript, autostartscript ]
 		mustSucceed "makensis" [File nsifile]
 	removeFile nsifile -- left behind if makensis fails
@@ -85,7 +92,7 @@ gitInstallDir :: Exp FilePath
 gitInstallDir = fromString "$PROGRAMFILES\\Git"
 
--- This intentionall has a different name than git-annex or
+-- This intentionally has a different name than git-annex or
 -- git-annex-webapp, since it is itself treated as an executable file.
 -- Also, on XP, the filename is displayed, not the description.
 startMenuItem :: Exp FilePath
@@ -169,54 +176,6 @@ cygwinPrograms :: [FilePath]
 cygwinPrograms = map (\p -> p ++ ".exe") bundledPrograms
 
--- These are the dlls needed by Cygwin's rsync, ssh, etc.
--- TODO: Use ldd (available in cygwin) to automatically find all
--- needed libs.
-cygwinDlls :: [FilePath]
-cygwinDlls =
-	[ "cygwin1.dll"
-	, "cygasn1-8.dll"
-	, "cygattr-1.dll"
-	, "cygheimbase-1.dll"
-	, "cygroken-18.dll"
-	, "cygcom_err-2.dll"
-	, "cygheimntlm-0.dll"
-	, "cygsqlite3-0.dll"
-	, "cygcrypt-0.dll"
-	, "cyghx509-5.dll"
-	, "cygssp-0.dll"
-	, "cygcrypto-1.0.0.dll"
-	, "cygiconv-2.dll"
-	, "cyggcc_s-1.dll"
-	, "cygintl-8.dll"
-	, "cygwind-0.dll"
-	, "cyggssapi-3.dll"
-	, "cyggssapi_krb5-2.dll"
-	, "cygkrb5-26.dll"
-	, "cygz.dll"
-	, "cygidn-11.dll"
-	, "cyggnutls-28.dll"
-	, "libcrypto.dll"
-	, "libssl.dll"
-	, "cyggcrypt-11.dll"
-	, "cyggpg-error-0.dll"
-	, "cygp11-kit-0.dll"
-	, "cygffi-6.dll"
-	, "cygbz2-1.dll"
-	, "cygreadline7.dll"
-	, "cygncursesw-10.dll"
-	, "cygusb0.dll"
-	, "cyghogweed-2.dll"
-	, "cygk5crypto-3.dll"
-	, "cygkrb5support-0.dll"
-	, "cyggmp-10.dll"
-	, "cygkrb5-3.dll"
-	, "cygnettle-4.dll"
-	, "cygtasn1-6.dll"
-	, "cygpcre-1.dll"
-	, "cyguuid-1.dll"
-	]
-
 -- msysgit opens Program Files/Git/doc/git/html/git-annex.html
 -- when git annex --help is run.
 htmlHelpText :: String
@@ -228,4 +187,19 @@ 	, "<a href=\"https://git-annex.branchable.com/git-annex/\">read the man page</a>."
 	, "</body>"
 	, "</html"
+	]
+
+-- Find cygwin libraries used by the specified executable.
+findCygLibs :: FilePath -> IO [FilePath]
+findCygLibs p = filter iscyg . mapMaybe parse . lines <$> readProcess "ldd" [p]
+  where
+	parse l = case words (dropWhile isSpace l) of
+		(dll:"=>":_dllpath:_offset:[]) -> Just dll
+		_ -> Nothing
+	iscyg f = "cyg" `isPrefixOf` f || "lib" `isPrefixOf` f
+
+wrappers :: [FilePath]
+wrappers = 
+	[ "standalone\\windows\\ssh.cmd"
+	, "standalone\\windows\\ssh-keygen.cmd"
 	]
Build/Version.hs view
@@ -67,6 +67,3 @@ 		| otherwise = s 	  where 		fullfield = field ++ ": "--main :: IO ()-main = putStr =<< getVersion
CHANGELOG view
@@ -1,3 +1,57 @@+git-annex (5.20150508) unstable; urgency=medium++  * Improve behavior when a git-annex command is told to operate+    on a file that doesn't exist. It will now continue to other+    files specified after that on the command line, and only error out at+    the end.+  * S3: Enable debug logging when annex.debug or --debug is set.+  * S3: git annex info will show additional information about a S3 remote+    (endpoint, port, storage class)+  * S3: Let git annex enableremote be used, without trying to recreate+    a bucket that should already exist.+  * S3: Fix incompatability with bucket names used by hS3; the aws library+    cannot handle upper-case bucket names. git-annex now converts them to+    lower case automatically.+  * import: Check for gitignored files before moving them into the tree.+    (Needs git 1.8.4 or newer.)+  * import: Don't stop entire import when one file fails due to being+    gitignored or conflicting with something in the work tree.+  * import: Before removing a duplicate file in --deduplicate or+    --clean-duplicates mode, verify that enough copies of its content still+    exist.+  * Improve integration with KDE's file manager to work with dolphin+    version 14.12.3 while still being compatable with 4.14.2.+    Thanks, silvio.+  * assistant: Added --autostop to complement --autostart.+  * Work around wget bug #784348 which could cause it to clobber git-annex+    symlinks when downloading from ftp.+  * Support checking ftp urls for file presence.+  * Fix bogus failure of fsck --fast.+  * fsck: Ignore error recording the fsck in the activity log,+    which can happen when running fsck in a read-only repository.+    Closes: #698559+    (fsck can still need to write to the repository if it find problems,+    but a successful fsck can be done read-only)+  * Improve quvi 0.4 output parsing to handle cases wher there is no known+    filename extension. This is currently the case when using quvi with+    youtube. In this case, the extension ".m" will be used.+  * Dropped support for older versions of yesod, warp, and dbus than the ones+    in Debian Jessie.+  * Switch from the obsolete dataenc library for base64 encoding to sandi.+    (Thanks, Magnus Therning)+  * Debian's ghc now supports TH on arm! Adjust build dependencies+    to build the webapp on arm, and enable DAV support on arm. \o/+  * Adjust some other arch specific build dependencies that are now+    available on more architectures in Devian unstable.+  * Windows: Remove cygwin ssh, the newer version of which has stopped+    honoring the setting of HOME. Instead, copy msysgit's ssh into PATH.+    Note that setting up a remote ssh server using password authentication+    is known to be broken in this release on Windows.+  * Windows: Roll back to an older version of rsync from cygwin.+    The newer version has some dependency on a newer ssh from cygwin.++ -- Joey Hess <id@joeyh.name>  Fri, 08 May 2015 13:42:30 -0400+ git-annex (5.20150420) unstable; urgency=medium    * Fix activity log parsing, which caused the log to not retain
@@ -28,10 +28,6 @@ Copyright: © 2010-2014 Joey Hess <id@joeyh.name> License: GPL-3+ -Files: Assistant/WebApp/Bootstrap3.hs-Copyright: 2010 Michael Snoyman-License: BSD-2-clause- Files: doc/logo* */favicon.ico standalone/osx/git-annex.app/Contents/Resources/git-annex.icns standalone/android/icons/* Copyright: 2007 Henrik Nyh <http://henrik.nyh.se/>            2010 Joey Hess <id@joeyh.name>
CmdLine/Action.hs view
@@ -5,8 +5,6 @@  - Licensed under the GNU GPL version 3 or higher.  -} -{-# LANGUAGE BangPatterns #-}- module CmdLine.Action where  import Common.Annex@@ -45,14 +43,11 @@ 	account (Right True) = return True 	account (Right False) = incerr 	account (Left err) = do-		showErr err+		toplevelWarning True (show err) 		showEndFail 		incerr 	incerr = do-		Annex.changeState $ \s -> -			let ! c = Annex.errcounter s + 1 -			    ! s' = s { Annex.errcounter = c }-			in s'+		Annex.incError 		return False  {- Runs a single command action through the start, perform and cleanup
+ CmdLine/Batch.hs view
@@ -0,0 +1,41 @@+{- git-annex batch commands+ -+ - Copyright 2015 Joey Hess <id@joeyh.name>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module CmdLine.Batch where++import Common.Annex+import Command++batchOption :: Option+batchOption = flagOption [] "batch" "enable batch mode"++data BatchMode = Batch | NoBatch+type Batchable t = BatchMode -> t -> CommandStart++-- A Batchable command can run in batch mode, or not.+-- In batch mode, one line at a time is read, parsed, and a reply output to+-- stdout. In non batch mode, the command's parameters are parsed and+-- a reply output for each.+batchable :: ((t -> CommandStart) -> CommandSeek) -> Batchable t -> CommandSeek+batchable seeker starter params = ifM (getOptionFlag batchOption)+	( batchloop+	, seeker (starter NoBatch) params+	)+  where+	batchloop = do+		mp <- liftIO $ catchMaybeIO getLine+		case mp of+			Nothing -> return ()+			Just p -> do+				seeker (starter Batch) [p]+				batchloop++-- bad input is indicated by an empty line in batch mode. In non batch+-- mode, exit on bad input.+batchBadInput :: BatchMode -> Annex ()+batchBadInput NoBatch = liftIO exitFailure+batchBadInput Batch = liftIO $ putStrLn ""
CmdLine/Seek.hs view
@@ -218,8 +218,9 @@ 	ll <- inRepo $ \g -> concat <$> forM (segmentXargsOrdered params) 		(runSegmentPaths (\fs -> Git.Command.leaveZombie <$> a fs g)) 	forM_ (map fst $ filter (null . snd) $ zip params ll) $ \p ->-		unlessM (isJust <$> liftIO (catchMaybeIO $ getSymbolicLinkStatus p)) $-			error $ p ++ " not found"+		unlessM (isJust <$> liftIO (catchMaybeIO $ getSymbolicLinkStatus p)) $ do+			toplevelWarning False (p ++ " not found")+			Annex.incError 	return $ concat ll  notSymlink :: FilePath -> IO Bool
Command/Add.hs view
@@ -116,7 +116,10 @@  - Lockdown can fail if a file gets deleted, and Nothing will be returned.  -} lockDown :: FilePath -> Annex (Maybe KeySource)-lockDown = either (\e -> showErr e >> return Nothing) (return . Just) <=< lockDown'+lockDown = either +		(\e -> warning (show e) >> return Nothing)+		(return . Just)+	<=< lockDown'  lockDown' :: FilePath -> Annex (Either IOException KeySource) lockDown' file = ifM crippledFileSystem
Command/AddUrl.hs view
@@ -178,7 +178,7 @@ 		pathmax <- liftIO $ fileNameLengthLimit "." 		let file = flip fromMaybe optfile $ 			truncateFilePath pathmax $ sanitizeFilePath $-				Quvi.pageTitle page ++ "." ++ Quvi.linkSuffix link+				Quvi.pageTitle page ++ "." ++ fromMaybe "m" (Quvi.linkSuffix link) 		showStart "addurl" file 		next $ performQuvi relaxed urlstring (Quvi.linkUrl link) file #else
Command/Assistant.hs view
@@ -20,7 +20,7 @@ import System.Environment  cmd :: [Command]-cmd = [noRepo checkAutoStart $ dontCheck repoExists $ withOptions options $+cmd = [noRepo checkNoRepoOpts $ dontCheck repoExists $ withOptions options $ 	notBareRepo $ command "assistant" paramNothing seek SectionCommon 		"automatically sync changes"] @@ -30,11 +30,15 @@ 	, Command.Watch.stopOption 	, autoStartOption 	, startDelayOption+	, autoStopOption 	]  autoStartOption :: Option autoStartOption = flagOption [] "autostart" "start in known repositories" +autoStopOption :: Option+autoStopOption = flagOption [] "autostop" "stop in known repositories"+ startDelayOption :: Option startDelayOption = fieldOption [] "startdelay" paramNumber "delay before running startup scan" @@ -43,25 +47,31 @@ 	stopdaemon <- getOptionFlag Command.Watch.stopOption 	foreground <- getOptionFlag Command.Watch.foregroundOption 	autostart <- getOptionFlag autoStartOption+	autostop <- getOptionFlag autoStopOption 	startdelay <- getOptionField startDelayOption (pure . maybe Nothing parseDuration)-	withNothing (start foreground stopdaemon autostart startdelay) ps+	withNothing (start foreground stopdaemon autostart autostop startdelay) ps -start :: Bool -> Bool -> Bool -> Maybe Duration -> CommandStart-start foreground stopdaemon autostart startdelay+start :: Bool -> Bool -> Bool -> Bool -> Maybe Duration -> CommandStart+start foreground stopdaemon autostart autostop startdelay 	| autostart = do 		liftIO $ autoStart startdelay 		stop+	| autostop = do+		liftIO autoStop+		stop 	| otherwise = do 		liftIO ensureInstalled 		ensureInitialized 		Command.Watch.start True foreground stopdaemon startdelay -{- Run outside a git repository. Check to see if any parameter is- - --autostart and enter autostart mode. -}-checkAutoStart :: CmdParams -> IO ()-checkAutoStart _ = ifM (elem "--autostart" <$> getArgs)+{- Run outside a git repository; support autostart and autostop mode. -}+checkNoRepoOpts :: CmdParams -> IO ()+checkNoRepoOpts _ = ifM (elem "--autostart" <$> getArgs) 	( autoStart Nothing-	, error "Not in a git repository."+	, ifM (elem "--autostop" <$> getArgs)+		( autoStop+		, error "Not in a git repository."+		) 	)   autoStart :: Maybe Duration -> IO ()@@ -89,3 +99,15 @@ 			[ Param "assistant" 			, Param $ "--startdelay=" ++ fromDuration (fromMaybe (Duration 5) startdelay) 			]++autoStop :: IO ()+autoStop = do+	dirs <- liftIO readAutoStartFile+	program <- programPath+	forM_ dirs $ \d -> do+		putStrLn $ "git-annex autostop in " ++ d+		setCurrentDirectory d+		ifM (boolSystem program [Param "assistant", Param "--stop"])+			( putStrLn "ok"+			, putStrLn "failed"+			)
Command/ContentLocation.hs view
@@ -9,19 +9,20 @@  import Common.Annex import Command+import CmdLine.Batch import Annex.Content  cmd :: [Command]-cmd = [noCommit $ noMessages $+cmd = [withOptions [batchOption] $ noCommit $ noMessages $ 	command "contentlocation" (paramRepeating paramKey) seek 		SectionPlumbing "looks up content for a key"]  seek :: CommandSeek-seek = withKeys start+seek = batchable withKeys start -start :: Key -> CommandStart-start k = do-	liftIO . maybe exitFailure putStrLn+start :: Batchable Key+start batchmode k = do+	maybe (batchBadInput batchmode) (liftIO . putStrLn) 		=<< inAnnex' (pure True) Nothing check k 	stop   where
Command/Copy.hs view
@@ -12,7 +12,7 @@ import qualified Command.Move import qualified Remote import Annex.Wanted-import Config.NumCopies+import Annex.NumCopies  cmd :: [Command] cmd = [withOptions copyOptions $ command "copy" paramPaths seek
Command/Drop.hs view
@@ -15,7 +15,7 @@ import Logs.Location import Logs.Trust import Logs.PreferredContent-import Config.NumCopies+import Annex.NumCopies import Annex.Content import Annex.Wanted import Annex.Notification@@ -72,7 +72,7 @@ 	(remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key 	let trusteduuids' = case knownpresentremote of 		Nothing -> trusteduuids-		Just r -> nub (Remote.uuid r:trusteduuids)+		Just r -> Remote.uuid r:trusteduuids 	untrusteduuids <- trustGet UnTrusted 	let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids'++untrusteduuids) 	u <- getUUID@@ -91,17 +91,9 @@ 	-- Filter the remote it's being dropped from out of the lists of 	-- places assumed to have the key, and places to check. 	-- When the local repo has the key, that's one additional copy,-	-- as long asthe local repo is not untrusted.-	(remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key-	present <- inAnnex key-	u <- getUUID-	trusteduuids' <- if present-		then ifM ((<= SemiTrusted) <$> lookupTrust u)-			( pure (u:trusteduuids)-			, pure trusteduuids-			)-		else pure trusteduuids-	let have = filter (/= uuid) trusteduuids'+	-- as long as the local repo is not untrusted.+	(remotes, trusteduuids) <- knownCopies key+	let have = filter (/= uuid) trusteduuids 	untrusteduuids <- trustGet UnTrusted 	let tocheck = filter (/= remote) $ 		Remote.remotesWithoutUUID remotes (have++untrusteduuids)@@ -131,45 +123,20 @@  - --force overrides and always allows dropping.  -} canDrop :: UUID -> Key -> AssociatedFile -> NumCopies -> [UUID] -> [Remote] -> [UUID] -> Annex Bool-canDrop dropfrom key afile numcopies have check skip = ifM (Annex.getState Annex.force)-	( return True-	, checkRequiredContent dropfrom key afile-		<&&>-	  findCopies key numcopies skip have check-	)--findCopies :: Key -> NumCopies -> [UUID] -> [UUID] -> [Remote] -> Annex Bool-findCopies key need skip = helper [] []-  where-	helper bad missing have []-		| NumCopies (length have) >= need = return True-		| otherwise = notEnoughCopies key need have (skip++missing) bad-	helper bad missing have (r:rs)-		| NumCopies (length have) >= need = return True-		| otherwise = do-			let u = Remote.uuid r-			let duplicate = u `elem` have-			haskey <- Remote.hasKey r key-			case (duplicate, haskey) of-				(False, Right True)  -> helper bad missing (u:have) rs-				(False, Left _)      -> helper (r:bad) missing have rs-				(False, Right False) -> helper bad (u:missing) have rs-				_                    -> helper bad missing have rs--notEnoughCopies :: Key -> NumCopies -> [UUID] -> [UUID] -> [Remote] -> Annex Bool-notEnoughCopies key need have skip bad = do-	unsafe-	showLongNote $-		"Could only verify the existence of " ++-		show (length have) ++ " out of " ++ show (fromNumCopies need) ++ -		" necessary copies"-	Remote.showTriedRemotes bad-	Remote.showLocations True key (have++skip)-		"Rather than dropping this file, try using: git annex move"-	hint-	return False+canDrop dropfrom key afile numcopies have check skip = +	ifM (Annex.getState Annex.force)+		( return True+			, ifM (checkRequiredContent dropfrom key afile+				<&&> verifyEnoughCopies nolocmsg key numcopies skip have check+				)+				( return True+				, do+					hint+					return False+				)+		)   where-	unsafe = showNote "unsafe"+	nolocmsg = "Rather than dropping this file, try using: git annex move" 	hint = showLongNote "(Use --force to override this check, or adjust numcopies.)"  checkRequiredContent :: UUID -> Key -> AssociatedFile -> Annex Bool
Command/DropUnused.hs view
@@ -14,7 +14,7 @@ import qualified Remote import qualified Git import Command.Unused (withUnusedMaps, UnusedMaps(..), startUnused)-import Config.NumCopies+import Annex.NumCopies  cmd :: [Command] cmd = [withOptions [Command.Drop.dropFromOption] $
Command/ExamineKey.hs view
@@ -9,21 +9,22 @@  import Common.Annex import Command+import CmdLine.Batch import qualified Utility.Format import Command.Find (formatOption, getFormat, showFormatted, keyVars) import Types.Key  cmd :: [Command]-cmd = [noCommit $ noMessages $ withOptions [formatOption, jsonOption] $+cmd = [noCommit $ noMessages $ withOptions [formatOption, jsonOption, batchOption] $ 	command "examinekey" (paramRepeating paramKey) seek 	SectionPlumbing "prints information from a key"]  seek :: CommandSeek seek ps = do 	format <- getFormat-	withKeys (start format) ps+	batchable withKeys (start format) ps -start :: Maybe Utility.Format.Format -> Key -> CommandStart-start format key = do+start :: Maybe Utility.Format.Format -> Batchable Key+start format _ key = do 	showFormatted format (key2file key) (keyVars key) 	stop
Command/Fsck.hs view
@@ -24,7 +24,7 @@ import Logs.Location import Logs.Trust import Logs.Activity-import Config.NumCopies+import Annex.NumCopies import Annex.UUID import Utility.DataUnits import Config@@ -76,7 +76,7 @@ 		(withFilesInGit $ whenAnnexed $ start from i) 		ps 	withFsckDb i FsckDb.closeDb-	recordActivity Fsck u+	void $ tryIO $ recordActivity Fsck u  start :: Maybe Remote -> Incremental -> FilePath -> Key -> CommandStart start from inc file key = do@@ -112,14 +112,15 @@ 	dispatch (Left err) = do 		showNote err 		return False-	dispatch (Right True) = withtmp $ \tmpfile ->-		ifM (getfile tmpfile)-			( go True (Just tmpfile)-			, do+	dispatch (Right True) = withtmp $ \tmpfile -> do+		r <- getfile tmpfile+		case r of+			Nothing -> go True Nothing+			Just True -> go True (Just tmpfile)+			Just False -> do 				warning "failed to download file from remote" 				void $ go True Nothing 				return False-			) 	dispatch (Right False) = go False Nothing 	go present localcopy = check 		[ verifyLocationLogRemote key file remote present@@ -137,13 +138,14 @@ 		cleanup `after` a tmp 	getfile tmp = ifM (checkDiskSpace (Just tmp) key 0) 		( ifM (Remote.retrieveKeyFileCheap remote key tmp)-			( return True+			( return (Just True) 			, ifM (Annex.getState Annex.fast)-				( return False-				, Remote.retrieveKeyFile remote key Nothing tmp dummymeter+				( return Nothing+				, Just <$>+					Remote.retrieveKeyFile remote key Nothing tmp dummymeter 				) 			)-		, return False+		, return (Just False) 		) 	dummymeter _ = noop 
Command/Get.hs view
@@ -12,7 +12,7 @@ import qualified Remote import Annex.Content import Annex.Transfer-import Config.NumCopies+import Annex.NumCopies import Annex.Wanted import qualified Command.Move 
Command/Import.hs view
@@ -16,6 +16,10 @@ import Remote import Types.KeySource import Types.Key+import Annex.CheckIgnore+import Annex.NumCopies+import Types.TrustLevel+import Logs.Trust  cmd :: [Command] cmd = [withOptions opts $ notBareRepo $ command "import" paramPaths seek@@ -75,23 +79,41 @@   where 	deletedup k = do 		showNote $ "duplicate of " ++ key2file k-		liftIO $ removeFile srcfile-		next $ return True+		ifM (verifiedExisting k destfile)+			( do+				liftIO $ removeFile srcfile+				next $ return True+			, do+				warning "Could not verify that the content is still present in the annex; not removing from the import location."+				stop+			) 	importfile = do-		handleexisting =<< liftIO (catchMaybeIO $ getSymbolicLinkStatus destfile)+		ignored <- not <$> Annex.getState Annex.force <&&> checkIgnored destfile+		if ignored+			then do+				warning $ "not importing " ++ destfile ++ " which is .gitignored (use --force to override)"+				stop+			else do+				existing <- liftIO (catchMaybeIO $ getSymbolicLinkStatus destfile)+				case existing of+					Nothing -> importfilechecked+					(Just s)+						| isDirectory s -> notoverwriting "(is a directory)"+						| otherwise -> ifM (Annex.getState Annex.force)+							( do+								liftIO $ nukeFile destfile+								importfilechecked+							, notoverwriting "(use --force to override, or a duplication option such as --deduplicate to clean up)"+							)+	importfilechecked = do 		liftIO $ createDirectoryIfMissing True (parentDir destfile) 		liftIO $ if mode == Duplicate || mode == SkipDuplicates 			then void $ copyFileExternal CopyAllMetaData srcfile destfile 			else moveFile srcfile destfile 		Command.Add.perform destfile-	handleexisting Nothing = noop-	handleexisting (Just s)-		| isDirectory s = notoverwriting "(is a directory)"-		| otherwise = ifM (Annex.getState Annex.force)-			( liftIO $ nukeFile destfile-			, notoverwriting "(use --force to override, or a duplication option such as --deduplicate to clean up)"-			)-	notoverwriting why = error $ "not overwriting existing " ++ destfile ++ " " ++ why+	notoverwriting why = do+		warning $ "not overwriting existing " ++ destfile ++ " " ++ why+		stop 	checkdup dupa notdupa = do 		backend <- chooseBackend destfile 		let ks = KeySource srcfile srcfile Nothing@@ -107,3 +129,14 @@ 		CleanDuplicates -> checkdup (Just deletedup) Nothing 		SkipDuplicates -> checkdup Nothing (Just importfile) 		_ -> return (Just importfile)++verifiedExisting :: Key -> FilePath -> Annex Bool+verifiedExisting key destfile = do+	-- Look up the numcopies setting for the file that it would be+	-- imported to, if it were imported.+	need <- getFileNumCopies destfile++	(remotes, trusteduuids) <- knownCopies key+	untrusteduuids <- trustGet UnTrusted+	let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids++untrusteduuids)+	verifyEnoughCopies [] key need trusteduuids [] tocheck
Command/ImportFeed.hs view
@@ -196,7 +196,7 @@ 					Just link -> do 						let videourl = Quvi.linkUrl link 						checkknown videourl $-							rundownload videourl ("." ++ Quvi.linkSuffix link) $ \f ->+							rundownload videourl ("." ++ fromMaybe "m" (Quvi.linkSuffix link)) $ \f -> 								maybeToList <$> addUrlFileQuvi (relaxedOpt opts) quviurl videourl f #else 		return False
Command/Info.hs view
@@ -30,7 +30,7 @@ import Logs.UUID import Logs.Trust import Logs.Location-import Config.NumCopies+import Annex.NumCopies import Remote import Config import Utility.Percentage
Command/LookupKey.hs view
@@ -9,18 +9,20 @@  import Common.Annex import Command+import CmdLine.Batch import Annex.CatFile import Types.Key  cmd :: [Command]-cmd = [notBareRepo $ noCommit $ noMessages $+cmd = [withOptions [batchOption] $ notBareRepo $ noCommit $ noMessages $ 	command "lookupkey" (paramRepeating paramFile) seek 		SectionPlumbing "looks up key used for file"]  seek :: CommandSeek-seek = withStrings start+seek = batchable withStrings start -start :: String -> CommandStart-start file = do-	liftIO . maybe exitFailure (putStrLn . key2file) =<< catKeyFile file+start :: Batchable String+start batchmode file = do+	maybe (batchBadInput batchmode) (liftIO . putStrLn . key2file)+		=<< catKeyFile file 	stop
Command/Mirror.hs view
@@ -14,7 +14,7 @@ import qualified Command.Get import qualified Remote import Annex.Content-import Config.NumCopies+import Annex.NumCopies  cmd :: [Command] cmd = [withOptions mirrorOptions $ command "mirror" paramPaths seek
Command/NumCopies.hs view
@@ -10,7 +10,7 @@ import Common.Annex import qualified Annex import Command-import Config.NumCopies+import Annex.NumCopies import Types.Messages  cmd :: [Command]
− Config/NumCopies.hs
@@ -1,85 +0,0 @@-{- git-annex numcopies configuration- -- - Copyright 2014 Joey Hess <id@joeyh.name>- -- - Licensed under the GNU GPL version 3 or higher.- -}--module Config.NumCopies (-	module Types.NumCopies,-	module Logs.NumCopies,-	getFileNumCopies,-	getGlobalFileNumCopies,-	getNumCopies,-	deprecatedNumCopies,-	defaultNumCopies,-	numCopiesCheck,-	numCopiesCheck',-) where--import Common.Annex-import qualified Annex-import Types.NumCopies-import Logs.NumCopies-import Logs.Trust-import Annex.CheckAttr-import qualified Remote--defaultNumCopies :: NumCopies-defaultNumCopies = NumCopies 1--fromSources :: [Annex (Maybe NumCopies)] -> Annex NumCopies-fromSources = fromMaybe defaultNumCopies <$$> getM id--{- The git config annex.numcopies is deprecated. -}-deprecatedNumCopies :: Annex (Maybe NumCopies)-deprecatedNumCopies = annexNumCopies <$> Annex.getGitConfig--{- Value forced on the command line by --numcopies. -}-getForcedNumCopies :: Annex (Maybe NumCopies)-getForcedNumCopies = Annex.getState Annex.forcenumcopies--{- Numcopies value from any of the non-.gitattributes configuration- - sources. -}-getNumCopies :: Annex NumCopies-getNumCopies = fromSources-	[ getForcedNumCopies-	, getGlobalNumCopies-	, deprecatedNumCopies-	]--{- Numcopies value for a file, from any configuration source, including the- - deprecated git config. -}-getFileNumCopies :: FilePath -> Annex NumCopies-getFileNumCopies f = fromSources-	[ getForcedNumCopies-	, getFileNumCopies' f-	, deprecatedNumCopies-	]--{- This is the globally visible numcopies value for a file. So it does- - not include local configuration in the git config or command line- - options. -}-getGlobalFileNumCopies :: FilePath  -> Annex NumCopies-getGlobalFileNumCopies f = fromSources-	[ getFileNumCopies' f-	]--getFileNumCopies' :: FilePath  -> Annex (Maybe NumCopies)-getFileNumCopies' file = maybe getGlobalNumCopies (return . Just) =<< getattr-  where-	getattr = (NumCopies <$$> readish)-		<$> checkAttr "annex.numcopies" file--{- Checks if numcopies are satisfied for a file by running a comparison- - between the number of (not untrusted) copies that are- - belived to exist, and the configured value. -}-numCopiesCheck :: FilePath -> Key -> (Int -> Int -> v) -> Annex v-numCopiesCheck file key vs = do-	have <- trustExclude UnTrusted =<< Remote.keyLocations key-	numCopiesCheck' file vs have--numCopiesCheck' :: FilePath -> (Int -> Int -> v) -> [UUID] -> Annex v-numCopiesCheck' file vs have = do-	NumCopies needed <- getFileNumCopies file-	return $ length have `vs` needed
Limit.hs view
@@ -15,7 +15,7 @@ import Annex.Content import Annex.UUID import Logs.Trust-import Config.NumCopies+import Annex.NumCopies import Types.TrustLevel import Types.Key import Types.Group
Messages.hs view
@@ -19,7 +19,7 @@ 	showEndOk, 	showEndFail, 	showEndResult,-	showErr,+	toplevelWarning, 	warning, 	warningIO, 	indent,@@ -117,15 +117,16 @@ 		| ok = "ok" 		| otherwise = "failed" -showErr :: (Show a) => a -> Annex ()-showErr e = warning' $ "git-annex: " ++ show e+toplevelWarning :: Bool -> String -> Annex ()+toplevelWarning makeway s = warning' makeway ("git-annex: " ++ s)  warning :: String -> Annex ()-warning = warning' . indent+warning = warning' True . indent -warning' :: String -> Annex ()-warning' w = do-	handleMessage q $ putStr "\n"+warning' :: Bool -> String -> Annex ()+warning' makeway w = do+	when makeway $+		handleMessage q $ putStr "\n" 	liftIO $ do 		hFlush stdout 		hPutStrLn stderr w
Remote.hs view
@@ -282,7 +282,9 @@ 	let uuidsskipped = filteruuids uuids (u:exclude++uuidswanted) 	ppuuidswanted <- prettyPrintUUIDs "wanted" uuidswanted 	ppuuidsskipped <- prettyPrintUUIDs "skipped" uuidsskipped-	showLongNote $ message ppuuidswanted ppuuidsskipped+	let msg = message ppuuidswanted ppuuidsskipped+	unless (null msg) $+		showLongNote msg 	ignored <- filter (remoteAnnexIgnore . gitconfig) <$> remoteList 	unless (null ignored) $ 		showLongNote $ "(Note that these git remotes have annex-ignore set: " ++ unwords (map name ignored) ++ ")"
Remote/Helper/Encryptable.hs view
@@ -20,7 +20,8 @@ ) where  import qualified Data.Map as M-import qualified "dataenc" Codec.Binary.Base64 as B64+import qualified "sandi" Codec.Binary.Base64 as B64+import qualified Data.ByteString as B import Data.Bits.Utils  import Common.Annex@@ -172,12 +173,12 @@ 		]  {- Not using Utility.Base64 because these "Strings" are really- - bags of bytes and that would convert to unicode and not roung-trip+ - bags of bytes and that would convert to unicode and not round-trip  - cleanly. -} toB64bs :: String -> String-toB64bs = B64.encode . s2w8+toB64bs = w82s . B.unpack . B64.encode . B.pack . s2w8  fromB64bs :: String -> String-fromB64bs s = fromMaybe bad $ w82s <$> B64.decode s+fromB64bs s = either (const bad) (w82s . B.unpack) (B64.decode $ B.pack $ s2w8 s)   where 	bad = error "bad base64 encoded data"
Remote/Helper/Special.hs view
@@ -199,7 +199,7 @@ 				readBytes $ \encb -> 					storer (enck k) (ByteContent encb) p -	-- call retrieve-r to get chunks; decrypt them; stream to dest file+	-- call retriever to get chunks; decrypt them; stream to dest file 	retrieveKeyFileGen k dest p enc = 		safely $ prepareretriever k $ safely . go 	  where
Remote/S3.hs view
@@ -28,6 +28,8 @@ import Control.Monad.Catch import Data.Conduit import Data.IORef+import Data.Bits.Utils+import System.Log.Logger  import Common.Annex import Types.Remote@@ -88,13 +90,7 @@ 			, availability = GloballyAvailable 			, remotetype = remote 			, mkUnavailable = gen r u (M.insert "host" "!dne!" c) gc-			, getInfo = includeCredsInfo c (AWS.creds u) $ catMaybes-				[ Just ("bucket", fromMaybe "unknown" (getBucketName c))-				, if configIA c-					then Just ("internet archive item", iaItemUrl $ fromMaybe "unknown" $ getBucketName c)-					else Nothing-				, Just ("partsize", maybe "unlimited" (roughSize storageUnits False) (getPartSize c))-				]+			, getInfo = includeCredsInfo c (AWS.creds u) (s3Info c) 			, claimUrl = Nothing 			, checkUrl = Nothing 			}@@ -102,9 +98,9 @@ s3Setup :: Maybe UUID -> Maybe CredPair -> RemoteConfig -> Annex (RemoteConfig, UUID) s3Setup mu mcreds c = do 	u <- maybe (liftIO genUUID) return mu-	s3Setup' u mcreds c-s3Setup' :: UUID -> Maybe CredPair -> RemoteConfig -> Annex (RemoteConfig, UUID)-s3Setup' u mcreds c = if configIA c then archiveorg else defaulthost+	s3Setup' (isNothing mu) u mcreds c+s3Setup' :: Bool -> UUID -> Maybe CredPair -> RemoteConfig -> Annex (RemoteConfig, UUID)+s3Setup' new u mcreds c = if configIA c then archiveorg else defaulthost   where 	remotename = fromJust (M.lookup "name" c) 	defbucket = remotename ++ "-" ++ fromUUID u@@ -124,7 +120,8 @@ 		(c', encsetup) <- encryptionSetup c 		c'' <- setRemoteCredPair encsetup c' (AWS.creds u) mcreds 		let fullconfig = c'' `M.union` defaults-		genBucket fullconfig u+		when new $+			genBucket fullconfig u 		use fullconfig  	archiveorg = do@@ -132,7 +129,7 @@ 		c' <- setRemoteCredPair noEncryptionUsed c (AWS.creds u) mcreds 		-- Ensure user enters a valid bucket name, since 		-- this determines the name of the archive.org item.-		let validbucket = replace " " "-" $ map toLower $+		let validbucket = replace " " "-" $ 			fromMaybe (error "specify bucket=") $ 				getBucketName c' 		let archiveconfig = @@ -149,7 +146,7 @@ 			writeUUIDFile archiveconfig u 		use archiveconfig --- Sets up a http connection manager for S3 encdpoint, which allows+-- Sets up a http connection manager for S3 endpoint, which allows -- http connections to be reused across calls to the helper. prepareS3 :: Remote -> S3Info -> (S3Handle -> helper) -> Preparer helper prepareS3 r info = resourcePrepare $ const $@@ -388,13 +385,13 @@ 	=> S3Handle 	-> r 	-> ResourceT IO a-sendS3Handle' h = AWS.pureAws (hawscfg h) (hs3cfg h) (hmanager h)+sendS3Handle' h r = AWS.pureAws (hawscfg h) (hs3cfg h) (hmanager h) r  withS3Handle :: RemoteConfig -> UUID -> S3Info -> (S3Handle -> Annex a) -> Annex a withS3Handle c u info a = do 	creds <- getRemoteCredPairFor "S3" c (AWS.creds u) 	awscreds <- liftIO $ genCredentials $ fromMaybe nocreds creds-	let awscfg = AWS.Configuration AWS.Timestamp awscreds (AWS.defaultLog AWS.Error)+	let awscfg = AWS.Configuration AWS.Timestamp awscreds debugMapper 	bracketIO (newManager httpcfg) closeManager $ \mgr ->  		a $ S3Handle mgr awscfg s3cfg info   where@@ -450,7 +447,7 @@ 		}  getBucketName :: RemoteConfig -> Maybe BucketName-getBucketName = M.lookup "bucket"+getBucketName = map toLower <$$> M.lookup "bucket"  getStorageClass :: RemoteConfig -> S3.StorageClass getStorageClass c = case M.lookup "storageclass" c of@@ -518,3 +515,26 @@ mkLocationConstraint :: AWS.Region -> S3.LocationConstraint mkLocationConstraint "US" = S3.locationUsClassic mkLocationConstraint r = r++debugMapper :: AWS.Logger+debugMapper level t = forward "S3" (T.unpack t)+  where+	forward = case level of+		AWS.Debug -> debugM+		AWS.Info -> infoM+		AWS.Warning -> warningM+		AWS.Error -> errorM++s3Info :: RemoteConfig -> [(String, String)]+s3Info c = catMaybes+	[ Just ("bucket", fromMaybe "unknown" (getBucketName c))+	, Just ("endpoint", w82s (S.unpack (S3.s3Endpoint s3c)))+	, Just ("port", show (S3.s3Port s3c))+	, Just ("storage class", show (getStorageClass c))+	, if configIA c+		then Just ("internet archive item", iaItemUrl $ fromMaybe "unknown" $ getBucketName c)+		else Nothing+	, Just ("partsize", maybe "unlimited" (roughSize storageUnits False) (getPartSize c))+	]+  where+	s3c = s3Configuration c
Utility/Base64.hs view
@@ -1,23 +1,22 @@ {- Simple Base64 encoding of Strings  -- - Copyright 2011 Joey Hess <id@joeyh.name>+ - Copyright 2011, 2015 Joey Hess <id@joeyh.name>  -  - License: BSD-2-clause  -}  module Utility.Base64 (toB64, fromB64Maybe, fromB64, prop_b64_roundtrips) where -import qualified "dataenc" Codec.Binary.Base64 as B64-import Control.Applicative+import qualified "sandi" Codec.Binary.Base64 as B64 import Data.Maybe-import qualified Data.ByteString.Lazy as L-import Data.ByteString.Lazy.UTF8 (fromString, toString)+import Data.ByteString.UTF8 (fromString, toString)  toB64 :: String -> String	-toB64 = B64.encode . L.unpack . fromString+toB64 = toString . B64.encode . fromString  fromB64Maybe :: String -> Maybe String-fromB64Maybe s = toString . L.pack <$> B64.decode s+fromB64Maybe s = either (const Nothing) (Just . toString)+	(B64.decode $ fromString s)  fromB64 :: String -> String fromB64 = fromMaybe bad . fromB64Maybe
Utility/FileMode.hs view
@@ -151,7 +151,11 @@  - as writeFile.  -} writeFileProtected :: FilePath -> String -> IO ()-writeFileProtected file content = withUmask 0o0077 $+writeFileProtected file content = writeFileProtected' file +	(\h -> hPutStr h content)++writeFileProtected' :: FilePath -> (Handle -> IO ()) -> IO ()+writeFileProtected' file writer = withUmask 0o0077 $ 	withFile file WriteMode $ \h -> do 		void $ tryIO $ modifyFileMode file $ removeModes otherGroupModes-		hPutStr h content+		writer h
Utility/Quvi.hs view
@@ -30,7 +30,7 @@ 	} deriving (Show)  data Link = Link-	{ linkSuffix :: String+	{ linkSuffix :: Maybe String 	, linkUrl :: URLString 	} deriving (Show) @@ -43,7 +43,7 @@  instance FromJSON Link where 	parseJSON (Object v) = Link-		<$> v .: "file_suffix"+		<$> v .:? "file_suffix" 		<*> v .: "url" 	parseJSON _ = mzero @@ -53,7 +53,7 @@ 	<$> get "QUVI_MEDIA_PROPERTY_TITLE" 	<*> ((:[]) <$> 		( Link-			<$> get "QUVI_MEDIA_STREAM_PROPERTY_CONTAINER"+			<$> Just <$> (get "QUVI_MEDIA_STREAM_PROPERTY_CONTAINER") 			<*> get "QUVI_MEDIA_STREAM_PROPERTY_URL" 		) 	    )
Utility/SafeCommand.hs view
@@ -1,6 +1,6 @@ {- safely running shell commands  -- - Copyright 2010-2013 Joey Hess <id@joeyh.name>+ - Copyright 2010-2015 Joey Hess <id@joeyh.name>  -  - License: BSD-2-clause  -}@@ -44,23 +44,32 @@  - if it succeeded or failed.  -} boolSystem :: FilePath -> [CommandParam] -> IO Bool-boolSystem command params = boolSystemEnv command params Nothing+boolSystem command params = boolSystem' command params id -boolSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool-boolSystemEnv command params environ = dispatch <$> safeSystemEnv command params environ+boolSystem' :: FilePath -> [CommandParam] -> (CreateProcess -> CreateProcess) -> IO Bool+boolSystem' command params mkprocess = dispatch <$> safeSystem' command params mkprocess   where 	dispatch ExitSuccess = True 	dispatch _ = False +boolSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool+boolSystemEnv command params environ = boolSystem' command params $+	\p -> p { env = environ }+ {- Runs a system command, returning the exit status. -} safeSystem :: FilePath -> [CommandParam] -> IO ExitCode-safeSystem command params = safeSystemEnv command params Nothing+safeSystem command params = safeSystem' command params id -safeSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO ExitCode-safeSystemEnv command params environ = do-	(_, _, _, pid) <- createProcess (proc command $ toCommand params)-		{ env = environ }+safeSystem' :: FilePath -> [CommandParam] -> (CreateProcess -> CreateProcess) -> IO ExitCode+safeSystem' command params mkprocess = do+	(_, _, _, pid) <- createProcess p 	waitForProcess pid+  where+	p = mkprocess $ proc command (toCommand params)++safeSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO ExitCode+safeSystemEnv command params environ = safeSystem' command params $ +	\p -> p { env = environ }  {- Wraps a shell command line inside sh -c, allowing it to be run in a  - login shell that may not support POSIX shell, eg csh. -}
Utility/Url.hs view
@@ -25,6 +25,9 @@ ) where  import Common+import Utility.Tmp+import qualified Build.SysConfig+ import Network.URI import Network.HTTP.Conduit import Network.HTTP.Types@@ -32,8 +35,6 @@ import qualified Data.ByteString as B import qualified Data.ByteString.UTF8 as B8 -import qualified Build.SysConfig- type URLString = String  type Headers = [String]@@ -122,10 +123,14 @@ 			| Build.SysConfig.curl -> do 				output <- catchDefaultIO "" $ 					readProcess "curl" $ toCommand curlparams+				let len = extractlencurl output+				let good = found len Nothing 				case lastMaybe (lines output) of-					Just ('2':_:_) -> found-						(extractlencurl output)-						Nothing+					Just ('2':_:_) -> good+					-- don't try to parse ftp status+					-- codes; if curl got a length,+					-- it's good+					_ | "ftp" `isInfixOf` uriScheme u && isJust len -> good 					_ -> dne 			| otherwise -> dne 	Nothing -> dne@@ -242,8 +247,15 @@ 		writeFile file "" 		go "curl" $ headerparams ++ quietopt "-s" ++ 			[Params "-f -L -C - -# -o"]-	go cmd opts = boolSystem cmd $-		addUserAgent uo $ reqParams uo++opts++[File file, File url]+	+	{- Run wget in a temp directory because it has been buggy+	 - and overwritten files in the current directory, even though+	 - it was asked to write to a file elsewhere. -}+	go cmd opts = withTmpDir "downloadurl" $ \tmp -> do+		absfile <- absPath file+		let ps = addUserAgent uo $ reqParams uo++opts++[File absfile, File url]+		boolSystem' cmd ps $ \p -> p { cwd = Just tmp }+	 	quietopt s 		| quiet = [Param s] 		| otherwise = []
Utility/WebApp.hs view
@@ -94,11 +94,7 @@ -- disable buggy sloworis attack prevention code webAppSettings :: Settings -#if MIN_VERSION_warp(2,1,0) webAppSettings = setTimeout halfhour defaultSettings-#else-webAppSettings = defaultSettings { settingsTimeout = halfhour }-#endif   where 	halfhour = 30 * 60 @@ -155,11 +151,7 @@  {- Rather than storing a session key on disk, use a random key  - that will only be valid for this run of the webapp. -}-#if MIN_VERSION_yesod(1,2,0) webAppSessionBackend :: Yesod.Yesod y => y -> IO (Maybe Yesod.SessionBackend)-#else-webAppSessionBackend :: Yesod.Yesod y => y -> IO (Maybe (Yesod.SessionBackend y))-#endif webAppSessionBackend _ = do 	g <- newGenIO :: IO SystemRandom 	case genBytes 96 g of@@ -170,18 +162,8 @@   where 	timeout = 120 * 60 -- 120 minutes 	use key =-#if MIN_VERSION_yesod(1,2,0) 		Just . Yesod.clientSessionBackend key . fst 			<$> Yesod.clientSessionDateCacher timeout-#else-#if MIN_VERSION_yesod(1,1,7)-		Just . Yesod.clientSessionBackend2 key . fst-			<$> Yesod.clientSessionDateCacher timeout-#else-		return $ Just $-			Yesod.clientSessionBackend key timeout-#endif-#endif  #ifdef WITH_WEBAPP_SECURE type AuthToken = SecureMem@@ -219,11 +201,7 @@  - Note that the usual Yesod error page is bypassed on error, to avoid  - possibly leaking the auth token in urls on that page!  -}-#if MIN_VERSION_yesod(1,2,0) checkAuthToken :: (Monad m, Yesod.MonadHandler m) => (Yesod.HandlerSite m -> AuthToken) -> m Yesod.AuthResult-#else-checkAuthToken :: forall t sub. (t -> AuthToken) -> Yesod.GHandler sub t Yesod.AuthResult-#endif checkAuthToken extractAuthToken = do 	webapp <- Yesod.getYesod 	req <- Yesod.getRequest
Utility/Yesod.hs view
@@ -20,69 +20,37 @@ #if ! MIN_VERSION_yesod(1,4,0) 	, withUrlRenderer #endif-#if ! MIN_VERSION_yesod(1,2,0)-	, Html-#endif 	) where -#if MIN_VERSION_yesod(1,2,0) import Yesod as Y-#else-import Yesod as Y hiding (Html)-#endif-#if MIN_VERSION_yesod_form(1,3,8) import Yesod.Form.Bootstrap3 as Y hiding (bfs)-#else-import Assistant.WebApp.Bootstrap3 as Y hiding (bfs)-#endif #ifndef __NO_TH__ import Yesod.Default.Util import Language.Haskell.TH.Syntax (Q, Exp)-#if MIN_VERSION_yesod_default(1,1,0) import Data.Default (def) import Text.Hamlet hiding (Html) #endif-#endif #if ! MIN_VERSION_yesod(1,4,0)-#if MIN_VERSION_yesod(1,2,0) import Data.Text (Text) #endif-#endif  #ifndef __NO_TH__ widgetFile :: String -> Q Exp-#if ! MIN_VERSION_yesod_default(1,1,0)-widgetFile = widgetFileNoReload-#else widgetFile = widgetFileNoReload $ def 	{ wfsHamletSettings = defaultHamletSettings 		{ hamletNewlines = AlwaysNewlines 		} 	}-#endif  hamletTemplate :: FilePath -> FilePath hamletTemplate f = globFile "hamlet" f #endif  {- Lift Handler to Widget -}-#if MIN_VERSION_yesod(1,2,0) liftH :: Monad m => HandlerT site m a -> WidgetT site m a liftH = handlerToWidget-#else-liftH :: MonadLift base m => base a -> m a-liftH = lift-#endif -{- Misc new names for stuff. -}-#if ! MIN_VERSION_yesod(1,2,0)-withUrlRenderer :: forall master sub. HtmlUrl (Route master) -> GHandler sub master RepHtml-withUrlRenderer = hamletToRepHtml--type Html = RepHtml-#else #if ! MIN_VERSION_yesod_core(1,2,20) withUrlRenderer :: MonadHandler m => ((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output) -> m output withUrlRenderer = giveUrlRenderer-#endif #endif
build.bat view
@@ -1,1 +1,1 @@-C:\CYGWIN\BIN\SH.EXE standalone/windows/build-simple.sh+sh standalone/windows/build-simple.sh
debian/changelog view
@@ -1,3 +1,57 @@+git-annex (5.20150508) unstable; urgency=medium++  * Improve behavior when a git-annex command is told to operate+    on a file that doesn't exist. It will now continue to other+    files specified after that on the command line, and only error out at+    the end.+  * S3: Enable debug logging when annex.debug or --debug is set.+  * S3: git annex info will show additional information about a S3 remote+    (endpoint, port, storage class)+  * S3: Let git annex enableremote be used, without trying to recreate+    a bucket that should already exist.+  * S3: Fix incompatability with bucket names used by hS3; the aws library+    cannot handle upper-case bucket names. git-annex now converts them to+    lower case automatically.+  * import: Check for gitignored files before moving them into the tree.+    (Needs git 1.8.4 or newer.)+  * import: Don't stop entire import when one file fails due to being+    gitignored or conflicting with something in the work tree.+  * import: Before removing a duplicate file in --deduplicate or+    --clean-duplicates mode, verify that enough copies of its content still+    exist.+  * Improve integration with KDE's file manager to work with dolphin+    version 14.12.3 while still being compatable with 4.14.2.+    Thanks, silvio.+  * assistant: Added --autostop to complement --autostart.+  * Work around wget bug #784348 which could cause it to clobber git-annex+    symlinks when downloading from ftp.+  * Support checking ftp urls for file presence.+  * Fix bogus failure of fsck --fast.+  * fsck: Ignore error recording the fsck in the activity log,+    which can happen when running fsck in a read-only repository.+    Closes: #698559+    (fsck can still need to write to the repository if it find problems,+    but a successful fsck can be done read-only)+  * Improve quvi 0.4 output parsing to handle cases wher there is no known+    filename extension. This is currently the case when using quvi with+    youtube. In this case, the extension ".m" will be used.+  * Dropped support for older versions of yesod, warp, and dbus than the ones+    in Debian Jessie.+  * Switch from the obsolete dataenc library for base64 encoding to sandi.+    (Thanks, Magnus Therning)+  * Debian's ghc now supports TH on arm! Adjust build dependencies+    to build the webapp on arm, and enable DAV support on arm. \o/+  * Adjust some other arch specific build dependencies that are now+    available on more architectures in Devian unstable.+  * Windows: Remove cygwin ssh, the newer version of which has stopped+    honoring the setting of HOME. Instead, copy msysgit's ssh into PATH.+    Note that setting up a remote ssh server using password authentication+    is known to be broken in this release on Windows.+  * Windows: Roll back to an older version of rsync from cygwin.+    The newer version has some dependency on a newer ssh from cygwin.++ -- Joey Hess <id@joeyh.name>  Fri, 08 May 2015 13:42:30 -0400+ git-annex (5.20150420) unstable; urgency=medium    * Fix activity log parsing, which caused the log to not retain
debian/control view
@@ -11,12 +11,12 @@ 	libghc-hslogger-dev, 	libghc-pcre-light-dev, 	libghc-cryptohash-dev (>= 0.11.0),-	libghc-dataenc-dev,+	libghc-sandi-dev, 	libghc-utf8-string-dev, 	libghc-aws-dev (>= 0.9.2-2~), 	libghc-conduit-dev, 	libghc-resourcet-dev,-	libghc-dav-dev (>= 1.0) [amd64 i386 kfreebsd-amd64 kfreebsd-i386 powerpc],+	libghc-dav-dev (>= 1.0) [amd64 armel armhf i386 kfreebsd-amd64 kfreebsd-i386 powerpc ppc64el hurd-i386], 	libghc-quickcheck2-dev, 	libghc-monad-control-dev (>= 0.3), 	libghc-exceptions-dev (>= 0.6),@@ -31,18 +31,20 @@ 	libghc-edit-distance-dev, 	libghc-hinotify-dev [linux-any], 	libghc-stm-dev (>= 2.3),-	libghc-dbus-dev (>= 0.10.3) [linux-any],+	libghc-dbus-dev (>= 0.10.7) [linux-any], 	libghc-fdo-notify-dev (>= 0.3) [linux-any],-	libghc-yesod-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-yesod-static-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-yesod-default-dev [i386 amd64 kfreebsd-amd64 powerpc],-	libghc-hamlet-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-shakespeare-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-clientsession-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-warp-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-warp-tls-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-wai-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],-	libghc-wai-extra-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc],+	libghc-yesod-dev (>= 1.2.6.1) [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-yesod-core-dev (>= 1.2.19) [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-yesod-form-dev (>= 1.3.15) [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-yesod-static-dev (>= 1.2.4) [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-yesod-default-dev (>= 1.2.0) [i386 amd64 armel armhf kfreebsd-amd64 powerpc ppc64el],+	libghc-hamlet-dev [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-shakespeare-dev [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-clientsession-dev [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-warp-dev (>= 3.0.0.5) [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-warp-tls-dev [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el],+	libghc-wai-dev [i386 amd64 kfreebsd-i386 armel armhf kfreebsd-amd64 powerpc ppc64el],+	libghc-wai-extra-dev [i386 amd64 armel armhf kfreebsd-i386 kfreebsd-amd64 powerpc ppc64el], 	libghc-securemem-dev, 	libghc-byteable-dev, 	libghc-dns-dev,@@ -64,13 +66,12 @@ 	libghc-esqueleto-dev, 	libghc-monad-logger-dev, 	libghc-feed-dev (>= 0.3.9.2),-	libghc-regex-tdfa-dev [!mipsel !s390],-	libghc-regex-compat-dev [mipsel s390],-	libghc-tasty-dev (>= 0.7) [!sparc],-	libghc-tasty-hunit-dev [!sparc],-	libghc-tasty-quickcheck-dev [!sparc],-	libghc-tasty-rerun-dev [!sparc],-	libghc-optparse-applicative-dev [!sparc],+	libghc-regex-tdfa-dev,+	libghc-tasty-dev (>= 0.7),+	libghc-tasty-hunit-dev,+	libghc-tasty-quickcheck-dev,+	libghc-tasty-rerun-dev,+	libghc-optparse-applicative-dev, 	lsof [!kfreebsd-i386 !kfreebsd-amd64 !hurd-any], 	ikiwiki, 	perlmagick,@@ -80,7 +81,6 @@ 	curl, 	openssh-client, 	git-remote-gcrypt (>= 0.20130908-6),-	llvm-3.4 [armel armhf], Maintainer: Gergely Nagy <algernon@madhouse-project.org> Standards-Version: 3.9.6 Vcs-Git: git://git.kitenet.net/git-annex
debian/copyright view
@@ -28,10 +28,6 @@ Copyright: © 2010-2014 Joey Hess <id@joeyh.name> License: GPL-3+ -Files: Assistant/WebApp/Bootstrap3.hs-Copyright: 2010 Michael Snoyman-License: BSD-2-clause- Files: doc/logo* */favicon.ico standalone/osx/git-annex.app/Contents/Resources/git-annex.icns standalone/android/icons/* Copyright: 2007 Henrik Nyh <http://henrik.nyh.se/>            2010 Joey Hess <id@joeyh.name>
debian/create-standalone-changelog view
@@ -9,7 +9,7 @@  # This is the same method that the configure script uses when git-annex is # built from git master.-ANNEX_VERSION=$(runghc Build/Version.hs)+ANNEX_VERSION=$(runghc Build/BuildVersion.hs)  ANNEX_NDVERSION=$( echo ${ANNEX_VERSION} | sed -e 's,-,+git,' -e 's,$,-1~ndall+1,') 
debian/patches/standalone-build view
@@ -6,7 +6,7 @@  --- a/debian/control +++ b/debian/control-@@ -87,11 +87,13 @@ Vcs-Git: git://git.kitenet.net/git-annex+@@ -89,11 +89,13 @@ Vcs-Git: git://git.kitenet.net/git-annex  Homepage: http://git-annex.branchable.com/  XS-Testsuite: autopkgtest  @@ -23,7 +23,7 @@  	rsync,  	wget,  	curl,-@@ -110,7 +112,7 @@ Suggests:+@@ -112,7 +114,7 @@ Suggests:  	bup,  	tahoe-lafs,  	libnss-mdns,@@ -32,7 +32,7 @@   git-annex allows managing files with git, without checking the file   contents into git. While that may seem paradoxical, it is useful when   dealing with files larger than git can currently easily handle, whether due-@@ -128,3 +130,7 @@ Description: manage files with git, with+@@ -130,3 +132,7 @@ Description: manage files with git, with   noticing when files are changed, and automatically committing them   to git and transferring them to other computers. The git-annex webapp   makes it easy to set up and use git-annex this way.@@ -54,9 +54,9 @@ +debian/git-annex-standalone/usr/lib/git-annex.linux/usr/share/man/man1/git-annex* --- a/debian/rules +++ b/debian/rules-@@ -12,6 +12,15 @@ export RELEASE_BUILD=1- # Rules for providing a standalone build of annex.- #+@@ -8,6 +8,15 @@ export RELEASE_BUILD=1+ %:+ 	dh $@   +override_dh_auto_build: +	make linuxstandalone@@ -67,6 +67,6 @@ +override_dh_fixperms: +	dh_fixperms -Xld-linux ++ # Run this target to build git-annex-standalone.deb  build-standalone:- 	[ -e .git ]- 	git checkout debian/changelog+ 	test -e .git
debian/rules view
@@ -13,7 +13,7 @@ 	test -e .git 	git checkout debian/changelog 	quilt pop -a || true-	QUILT_SERIES=series.standalone-build quilt push -a+	QUILT_PATCHES=debian/patches QUILT_SERIES=series.standalone-build quilt push -a 	debian/create-standalone-changelog 	dpkg-buildpackage -rfakeroot 	quilt pop -a
+ doc/Android/comment_6_455bcbd36c7b5eeb905cc56da4666b07._comment view
@@ -0,0 +1,30 @@+[[!comment format=mdwn+ username="madduck"+ subject="Weirdness when run from adb shell"+ date="2015-05-06T14:28:43Z"+ content="""+How is this designed to work in the contact of Androids crap permissions?++    shell@kminilte:/ $ /data/data/ga.androidterm/runshell+    /system/bin/sh: /data/data/ga.androidterm/runshell: can't execute: Permission denied++    126|shell@kminilte:/ $ /system/bin/sh /data/data/ga.androidterm/runshell+    Falling back to hardcoded app location; cannot find expected files in /data/app-lib++    shell@kminilte:/sdcard/git-annex.home $ git+    /system/bin/sh: git: not found++    127|shell@kminilte:/sdcard/git-annex.home $ echo $PATH+    /data/data/ga.androidterm/bin:/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin++    shell@kminilte:/sdcard/git-annex.home $ /data/data/ga.androidterm/bin/git                                                          <+    /data/data/ga.androidterm/bin/git: Permission denied++    shell@kminilte:/sdcard/git-annex.home $ ls -l /data/data/ga.androidterm/bin -d+    drwx------ u0_a255  u0_a255           2015-05-05 07:58 bin++    shell@kminilte:/sdcard/git-annex.home $ id+    uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0+++"""]]
doc/bugs/Can__39__t_get_content_from_S3_with_s3-aws_library.mdwn view
@@ -55,3 +55,8 @@  # End of transcript or log. """]]++> I think I've made all the git-annex improvements that are going to come+> from this bug report. There's still the open bug on the aws library to better+> follow these redirects. Anyway, I think it makes sense to call this+> bug [[done]]. --[[Joey]]
+ doc/bugs/Data_loss_when_doing___96__git_annex_import_--force__96__.mdwn view
@@ -0,0 +1,59 @@+### Please describe the problem.++Calling `git annex import --force file-in-working-copy` removes `file-in-working-copy` from disk.++My workflow is:++1) copy the CR2 files from a card to the desired directory structure using a tool of my choice,+2) import the created directory layout to git-annex++### What version of git-annex are you using? On what operating system?++[[!format sh """+$ git-annex version+git-annex version: 5.20150327+build flags: Pairing Testsuite S3 DBus DNS Feeds Quvi TDFA+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E MD5E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 MD5 WORM URL+remote types: git gcrypt S3 bup directory rsync web bittorrent tahoe glacier ddar hook external+local repository version: 5+supported repository version: 5+upgrade supported from repository versions: 0 1 2 4+"""]]++### How to reproduce:++[[!format sh """+jkt@svist ~/temp $ mkdir annex-add-force-data-loss+jkt@svist ~/temp $ cd annex-add-force-data-loss/+jkt@svist ~/temp/annex-add-force-data-loss $ git init+Initialized empty Git repository in /home/jkt/temp/annex-add-force-data-loss/.git/+jkt@svist ~/temp/annex-add-force-data-loss $ echo 1234 > foo+jkt@svist ~/temp/annex-add-force-data-loss $ ls -al+total 16K+drwxr-xr-x  3 jkt jkt   27 May  8 13:54 .+drwx------ 55 jkt jkt 8.0K May  8 13:54 ..+drwxr-xr-x  6 jkt jkt   96 May  8 13:54 .git+-rw-r--r--  1 jkt jkt    5 May  8 13:54 foo+jkt@svist ~/temp/annex-add-force-data-loss $ git annex import --force foo+git-annex: First run: git-annex init+jkt@svist ~/temp/annex-add-force-data-loss $ git annex init+init  ok+(recording state in git...)+jkt@svist ~/temp/annex-add-force-data-loss $ ls -al+total 16K+drwxr-xr-x  3 jkt jkt   27 May  8 13:54 .+drwx------ 55 jkt jkt 8.0K May  8 13:54 ..+drwxr-xr-x  8 jkt jkt  119 May  8 13:54 .git+-rw-r--r--  1 jkt jkt    5 May  8 13:54 foo+jkt@svist ~/temp/annex-add-force-data-loss $ git annex import --force foo+import foo +git-annex: foo: rename: does not exist (No such file or directory)+failed+git-annex: import: 1 failed+jkt@svist ~/temp/annex-add-force-data-loss $ ls -al+total 12K+drwxr-xr-x  3 jkt jkt   17 May  8 13:55 .+drwx------ 55 jkt jkt 8.0K May  8 13:54 ..+drwxr-xr-x  8 jkt jkt  119 May  8 13:55 .git+"""]]+...and the file is gone :(.
doc/bugs/Git-Annex_requires_all_repositories_to_repair.mdwn view
@@ -1,3 +1,6 @@ I recently had my git-annex repository die and it needed to be repaired. Two of my repositories are external hard drives. When I tried to use git-annex repair, it would churn for some hours, then error because the external hard drives were not plugged in. When I brought the two hard drives home from the various places that they are (safely) stored, it all worked fine, but it would have been great if git-annex repair could somehow do what it could with what was connected and do the rest as and when the other drives are plugged in. This must only become more of a problem as git-annex is used for longer, as one may have a handful of USB keys storing a little on each.  [[!taglink moreinfo]]++> With the lack of an error message or any followup, it's hard to take+> this bug seriously, so [[done]] --[[Joey]]
doc/bugs/Repository_Information_Is_Lost.mdwn view
@@ -31,3 +31,9 @@ """]]  [[!tag moreinfo]]++> No followup for over a year, and not enough information in the intial+> report to know if there's a bug at all. It occurs to me that the user+> might have just forgotten to push the git-annex branch to wherever they+> later cloned the repo from. `git annex sync` would fix that mistake up.+> Anyway, [[done]]. --[[Joey]]
doc/bugs/Small_archive_behaving_like_archive.mdwn view
@@ -31,3 +31,6 @@ """]]  [[!tag moreinfo]]++> Since there's a plausible explanation in my comment and no followup,+> [[done]] --[[Joey]]
doc/bugs/addurl_+_sync_vs_addurl_+_commit.mdwn view
@@ -22,3 +22,6 @@     supported repository version: 5     upgrade supported from repository versions: 0 1 2 4 This is on Linux.++> In the lack of any followups, I'm confident this was a case of user+> error, so closing. [[done]] --[[Joey]]
+ doc/bugs/clean-duplicates_causes_data_loss.mdwn view
@@ -0,0 +1,30 @@+### Please describe the problem.++Use of git-annex import --clean-duplicates can cause data loss, where git-annex deletes content that it doesn't actually have a copy of (i.e. there is no duplicate).++### What steps will reproduce the problem?++I've written a quick'n'dirty test script which goes through a bunch of combinations and tests --clean-duplicates. Given an 'origin' repo containing 'a' and 'b' content and a clone of it ('import') which doesn't contain 'a' and 'b' content.++g-a import --clean-duplicates ~/tmp/importme (containing a, b and c) into 'import' after:++    Origin is set to trusted in import, b is dropped from within origin:+  b is deleted from importme even though no annexes have copies (reasonable, as origin is set to trusted and import thinks it has the content).++    Origin is set to semitrusted in import, b is dropped within origin:+  b is deleted from importme even though no annexes have copies (this is most likely one to bite people).++    Origin is set to untrusted in import, b is dropped within origin:+  b is deleted from importme even though no annexes have copies and git-annex has been explicitly told to not trust information about origin :( This is really surprising behaviour!++### What version of git-annex are you using? On what operating system?++* 5.20150409+* Arch Linux (git-annex-bin)++### Please provide any additional information below.++I can provide the script if it is wanted (coded in Perl, couple of non-core dependencies).++> Decided to go ahead and make it check remotes like drop does, so [[done]]+> --[[Joey]]
doc/bugs/corrupt_backend_upon_sync__63__.mdwn view
@@ -74,3 +74,5 @@  # End of transcript or log. """]]++[[!tag moreinfo]]
+ doc/bugs/dolphin_integration_file_is_broken.mdwn view
@@ -0,0 +1,37 @@+### Please describe the problem.++git annex will automatically create the file++.kde/share/kde4/services/ServiceMenus/git-annex.desktop++However the actions created do not work because the variable used is %U (file:/// style URL) which git annex does not understand.++According to http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html++Also the escaping seems broken. The following line is one that works for me.++    Exec=sh -c 'cd "$(dirname -- "$1")" && git-annex get --notify-start --notify-finish -- "$1"' command_string_is_ignored %f++or simply++    Exec=git-annex get --notify-start --notify-finish -- %F++### What steps will reproduce the problem?+++### What version of git-annex are you using? On what operating system?++5.20141125++### Please provide any additional information below.++[[!format sh """+# If you can, paste a complete transcript of the problem occurring here.+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log+++# End of transcript or log.+"""]]++> [[fixed|done]]; confirmed the new version still works on filenames with+> spaces in them. --[[Joey]]
doc/bugs/failure_to_return_to_indirect_mode_on_usb.mdwn view
@@ -17,3 +17,7 @@ """]]  [[!tag moreinfo]]++> I don't like closing bug reports, but after over a year with no followup,+> and with the original bug report lacking even an error message, closing+> it seems like the best course of action. [[done]] --[[Joey]]
+ doc/bugs/git_annex_importfeed_not_working_on_youtube_playlists.mdwn view
@@ -0,0 +1,39 @@+### Please describe the problem.+The [podcasts page](https://git-annex.branchable.com/tips/downloading_podcasts/) mentions that you should be able to use `git annex importfeed` on youtube playlists, however, that doesn't seem to work (or I am using it incorrectly).++For example:++    » git annex importfeed --fast "https://www.youtube.com/playlist?list=PLz8YL4HVC87X3tYVYOjOLzSasPwgUsMPT"+    (checking known urls...)+    importfeed https://www.youtube.com/playlist?list=PLz8YL4HVC87X3tYVYOjOLzSasPwgUsMPT+    /var/folders/kb/fplmcbhs4z52p4x59cqgm4kw0000gn/T/f     [  <=>                                                                                                              ] 460.08K  1.87MB/s   in 0.2s++      warning: bad feed content+    ok++### What steps will reproduce the problem?++1. Enter a git annex repository+2. Attempt to import a youtube playlist feed (see command above) with `--fast`++### What version of git-annex are you using? On what operating system?++    » git annex version+    git-annex version: 5.20150205+    build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi TDFA TorrentParser+    key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E MD5E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 MD5 WORM URL+    remote types: git gcrypt S3 bup directory rsync web bittorrent webdav tahoe glacier ddar hook external+    local repository version: 5+    supported repository version: 5+    upgrade supported from repository versions: 0 1 2 4++This is on Mac OSX 10.10.3, with git-annex installed via homebrew++> You have to give it an url to a RSS feed containing the playlist.+> +> For example, `git annex importfeed+> 'http://gdata.youtube.com/feeds/api/playlists/PLz8ZG1e9MPlzefklz1Gv79icjywTXycR-'`+> still works despite there having been various news stories about youtube+> removing RSS functionality.+> +> I've added this example to the documentation. [[done]] --[[Joey]]
doc/bugs/git_annex_list__47__whereis_and_uncommited_local_changes.mdwn view
@@ -28,3 +28,6 @@ Linux 3.14.3  [[!tag confirmed]]++> I think it's reasonable for whereis to show location tracking information+> which may be out of date for many reasons, and so, [[done]] --[[Joey]]
+ doc/bugs/rsync_on_windows_broken_by_upgrade.mdwn view
@@ -0,0 +1,69 @@+rsync on windows has been broken by the upgrade to a newer version of+cygwin. `rsync user@host:file file` opens the ssh connection, but hangs+up with a protocol error. Apparently it doesn't get even the protocol+version message from the server.++Problem doesn't seem to affect the bundled ssh, just rsync. --[[Joey]]++> Update: Apparently there are two ssh's! msysgit bundles one (did it used+> to in PATH?) and git-annex bundles one from cygwin. msysgit's ends up+> in Git/bin and git-annex's in Git/cmd.+> +> Seems that cygwin's rsync cannot use git's ssh for whatever reason.+> +> So the workaround is to+> delete Git/bin/ssh.exe and leave Git/cmd/ssh.exe. Then rsync works.+> However, this may screw up git's use of ssh or other stuff.+>+> Particularly, cygwin's ssh doesn't honor HOME anymore, instead using+> the getpwent home, which doesn't exist. +> +> Also, see+> [[webapp_fails_to_connect_to_ssh_repository___40__windows__41__]]+> which is the inverse of this bug perhaps, or at least seems related.+> +> Using 2 ssh's that try to use config from different places seems like+> a losing propisition. Need to find an rsync that works with git's ssh.+> --[[Joey]]+> +> > Update: The git bin/ directory is only in PATH when inside "git bash".+> > This bug only seems to affect using git-annex that way. The git bash+> > PATH has `bin` before `cmd`.+> > +> > Also, git seems to work ok using the newer ssh from cygwin.+> > However, that ssh tries to write to a .ssh/known_hosts+> > in a cygwin location and so doesn't remember hosts.+> >+> > What a mess. You can install any version of Linux and get rsync, ssh,+> > git that all integrate and work together. Or you can use Windows and+> > enjoy the pain(TM) --[[Joey]] ++>>> Possible fixes:+>>> +>>> * Roll the bundled ssh and rsync back to the older versions.+>>> +>>>   **This works**. And, seems that the older version of ssh from cygwin+>>>   looks at HOME, rather than getpwent home which the newer+>>>   cygwin ssh does.+>>>  +>>> * Roll the bundled rsync back, drop ssh. Rely on msysgit's bundled ssh,+>>>   copying it into cmd so it's in PATH. Check: Does this combo work?+>>>+>>>   **This works**! rsync 3.0.9 works ok with msysgit's bundled ssh.+>>>   rsync 3.1.1 is the one that needs a newer ssh. **[[done]]**+>>>+>>>   Note that this means we're using an old version of rsync+>>>   from cygwin with libraries from a newer cygwin. That might prove+>>>   fragile as cygwin is upgraded.+>>>+>>> * Hope that msysgit gets updated to include a newer version of ssh+>>>   which works with the new rsync.+>>>+>>>   (Seems reasonable as a long-term plan, assuming that the +>>>   new rsync's problem with ssh is that it needs a new one, and not some+>>>   special cygwin thing.)+>>>+>>> * Get rsync from somewhere else, perhaps msysgit. (Maybe also get ssh+>>>   from msysgit?)+>>> * Keep the new rsync from cygwin, and build ssh from source,+>>>   patching it to use HOME in preference to getpwent home.
+ doc/bugs/ssh_fails_in_windows_nightly_build.mdwn view
@@ -0,0 +1,10 @@+### Please describe the problem.++After installing a nightly build from https://qa.nest-initiative.org/view/msysGit/job/msysgit-git-annex-assistant-test/, ssh fails to run when launched by the webapp. It shows a system error dialog with the message "The program can't start because msys-crypto-1.0.0.dll is missing...". The dll is present in $PROGRAMFILES/Git/bin, and ssh works when run from the command line.++[[!format sh """+Version: 5.20150508-g8e96a31+Build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV DNS Feeds Quvi TDFA TorrentParser+"""]]++> sigh.. [[fixed|done]] now.. --[[Joey]]
doc/bugs/ssh_portnum_bugs.mdwn view
@@ -13,3 +13,6 @@ When I was experiencing this issue, I was running the default on Jessie/Wheezy. Now I'm running the latest (via auto-update and distributed binary) but don't know if this is still an issue with latest versions (I switched to 22 as a workaround).  [[!tag moreinfo]]++> Closing as it seems likely this is an old bug fixed after wheezy.+> [[done]] --[[Joey]]
+ doc/bugs/webapp_fails_to_connect_to_ssh_repository___40__windows__41__.mdwn view
@@ -0,0 +1,40 @@+### Please describe the problem.++I added a remote repository, and it successfully tested the ssh connection to the server. Nothing happens, however, once it comes to actually creating the remote repository (or merging with an existing one). It'll just sit there forever, never actually connecting to the server.++A quick look in process explorer shows something of what's going on: git-annex has launched ssh, and ssh is spamming subprocesses. It's launching ssh.exe which is launching git-annex.exe (yes, on the local machine.) It exits right away, but the command line is "C:\Program Files (x86)\Git\cmd\git-annex.exe" "Please type 'yes' or 'no': ". I've no idea why it's doing that though.++If I kill that parent ssh process, I get this error message in the transcript:++    Could not create directory '/home/db48x/.ssh'.++This seems a bit dubious; both my local computer and the remote computer have a ~/.ssh directory.++In order to rule out a problem with my local computer (an ancient install of Git or cygwin/msys or something, we've tried this on fresh computers which have never had git installed; we get exactly the same problem there.++### What steps will reproduce the problem?++Create or connect to a repository via SSH.++### What version of git-annex are you using? On what operating system?++Windows 7++    Version: 5.20150420-gb0ebb23+    Build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV DNS Feeds Quvi TDFA TorrentParser++### Please provide any additional information below.++While this is going on, the log has is showing that it's executing the following command:++[[!format sh """+[2015-04-28 22:34:16 Pacific Daylight Time] chat: ssh ["-oNumberOfPasswordPrompts=1","-p","22","db48x@eambar.db48x.net","sh -c 'mkdir -p '\"'\"'annex'\"'\"'&&cd '\"'\"'annex'\"'\"'&&if [ ! -d .git ]; then if [ -x ~/.ssh/git-annex-wrapper ]; then ~/.ssh/git-annex-wrapper git init --bare --shared; else git init --bare --shared; fi && if [ -x ~/.ssh/git-annex-wrapper ]; then ~/.ssh/git-annex-wrapper git config receive.denyNonFastforwards; else git config receive.denyNonFastforwards; fi ;fi&&mkdir -p ~/.ssh&&if [ ! -e ~/.ssh/git-annex-shell ]; then (echo '\"'\"'#!/bin/sh'\"'\"';echo '\"'\"'set -e'\"'\"';echo '\"'\"'if [ \"x$SSH_ORIGINAL_COMMAND\" != \"x\" ]; then'\"'\"';echo '\"'\"'exec git-annex-shell -c \"$SSH_ORIGINAL_COMMAND\"'\"'\"';echo '\"'\"'else'\"'\"';echo '\"'\"'exec git-annex-shell -c \"$@\"'\"'\"';echo '\"'\"'fi'\"'\"') > ~/.ssh/git-annex-shell; fi&&chmod 700 ~/.ssh/git-annex-shell&&touch ~/.ssh/authorized_keys&&chmod 600 ~/.ssh/authorized_keys&&echo '\"'\"'command=\"env GIT_ANNEX_SHELL_DIRECTORY='\"'\"'\"'\"'\"'\"'\"'\"'annex'\"'\"'\"'\"'\"'\"'\"'\"' ~/.ssh/git-annex-shell\",no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDiPFdIMyYCBmc14f9cUZaG36Zw+NziqX9Z+xGl5GAYq16nORxVc+70Bj+A9cHoHLzTMBJnw7G/f7xJNGbKNgKUPKZohT8AQfg8lnyK8qpyzI2dJB3R0vPBMPxZCBm4IOpdB6ad3B6dUiyNtyMn1hza7GVhIFOsHfGG+K3PGtFgwOz/Zj+2zmcZIL/BHObFsba/yhQxbsjLYPI7mmNV9CLb1+XcR0z2okWvxu28lOrcIXDAdEhp1cjjjpBhwTH1F8/gJcJ6ENBa4JiGt/oEKb1b/pXLaMX6dRjc/gYoy7z0Hw7RD73hH+UtPj5TAeKwoNdaVXdqSsVI+3ql+O5PFTxt db48x@caradhras\n'\"'\"' >>~/.ssh/authorized_keys'"]+"""]]++> This sounds like it's all down to the newer ssh from cygwin ignoring HOME+> and trying to use /home/user which doesn't work very well outside cygwin.+>+> Since git-annex has switched to not include that ssh any longer, and+> instead use the ssh that's bundled with msysgit, I think this bug is+> closed. [[done]] Upgrading to the latest daily build should fix your+> system's ssh. Please followup if I'm wrong. --[[Joey]]
+ doc/bugs/windows_ssh_webapp_password_entry_broken.mdwn view
@@ -0,0 +1,5 @@+Recent changes to ssh on Windows have broken the webapps's support for+entering a password when adding a ssh remote.++Using ssh on windows with an existing remote does work. So as a workaround,+set up a passwordless ssh key that can log into the ssh server. --[[Joey]]
+ doc/bugs/wrong_synopsis_in_manpage_of_git_annex_pre-commit.mdwn view
@@ -0,0 +1,36 @@+### Please describe the problem.++The synopsis in the manpage of git annex pre-commit mentions+git annex instead of git annex pre-commit.++I'll attach a patch to fix the manpage, below:++[[!format diff """+From f5fed6ccdcef3bcb8be07691265842d437037dec Mon Sep 17 00:00:00 2001+From: Felix Gruber <felgru@gmx.de>+Date: Fri, 1 May 2015 02:05:32 +0200+Subject: [PATCH] fix synopsis in manpage of git annex pre-commit++---+ doc/git-annex-pre-commit.mdwn | 2 +-+ 1 file changed, 1 insertion(+), 1 deletion(-)++diff --git a/doc/git-annex-pre-commit.mdwn b/doc/git-annex-pre-commit.mdwn+index e0f6fdb..bc1e86e 100644+--- a/doc/git-annex-pre-commit.mdwn++++ b/doc/git-annex-pre-commit.mdwn+@@ -4,7 +4,7 @@ git-annex pre-commit - run by git pre-commit hook+ + # SYNOPSIS+ +-git annex  `[path ...]`++git annex pre-commit `[path ...]`+ + # DESCRIPTION+ +-- +2.1.4+"""]]++> You know, this is a wiki, you could fix it yourself. With git push even.+> In any case [[done]] now. --[[Joey]]
+ doc/design/balanced_preferred_content.mdwn view
@@ -0,0 +1,66 @@+Say we have 2 backup drives and want to fill them both evenly with files,+different files in each drive. Currently, preferred content cannot express+that entirely:++* One way is to use a-m* and n-z*, but that's unlikely to split filenames evenly. +* Or, can let both repos take whatever files, perhaps at random, that the+  other repo is not know to contain, but then repos will race and both get+  the same file, or similarly if they are not communicating frequently.++So, let's add a new expression: `balanced_amoung(group)`++This would work by taking the list of uuids of all repositories in the+group, and sorting them, which yields a list from 0..M-1 repositories.++To decide which repository wants key K, convert K to a number N in some+stable way and then `N mod M` yields the number of the repository that+wants it, while all the rest don't.++(Since git-annex keys can be pretty long and not all of them are random+hashes, let's md5sum the key and then use the md5 as a number.)++This expression is stable as long as the members of the group don't change.+I think that's stable enough to work as a preferred content expression.++Now, you may want to be able to add a third repo and have the data be+rebalanced, with some moving to it. And that would happen. However, as this+scheme stands, it's equally likely that adding repo3 will make repo1 and+repo2 want to swap files between them. So, we'll want to add some+precautions to avoid a lof of data moving around in this case:++	((balanced_amoung(backup) and not (copies=backup:1)) or present++So once file lands on a backup drive, it stays there, even if more backup+drives change the balancing.++-----++Some limitations:++* The item size is not taken into account. One repo could end up with a+  much larger item or items and so fill up faster. And the other repo+  wouldn't then notice it was full and take up some slack.+* With the complicated expression above, adding a new repo when one +  is full would not necessarily result in new files going to one of the 2+  repos that still have space. Some items would end up going to the full+  repo.++These can be dealt with by noticing when a repo is full and moving some+of it's files (any will do) to other repos in its group. I don't see a way+to make preferred content express that movement though; it would need to be+a manual/scripted process.++-----++What if we have 5 backup repos and want each file to land in 3 of them?+There's a simple change that can support that:+`balanced_amoung(group:3)`++This works the same as before, but rather than just `N mod M`, take+`N+I mod M` where I is [0..2] to get the list of 3 repositories that want a+key.++This does not really avoid the limitations above, but having more repos+that want each file will reduce the chances that no repo will be able to+take a given file. In the [[iabackup]] scenario, new clients will just be+assigned until all the files reach the desired level or replication.
+ doc/design/iabackup/comment_4_465c0966c96a57d189f678d4fa724aa0._comment view
@@ -0,0 +1,13 @@+[[!comment format=mdwn+ username="https://me.yahoo.com/a/idrn495us85k6mwfdMUolYIsyp4-#cf755"+ subject="It's not so bad .. only about 10PB"+ date="2015-04-30T01:19:38Z"+ content="""+The good news is that web-archive (.ARC) items are not publicly browsable, and that's about half of the archive's content, so you're only looking at about 10PB to backup.++The bad news is that unless you can work something out with archive.org (which seems unlikely; web-archive items are restricted to protect them legally), or use the old waybackup interface (which I don't think works anymore), or use the wayback machine (which last I heard only supported a few hundred connections per second) you'll only be able to back up half their data.++Still, non-web items seem like a nice place to start.+++"""]]
+ doc/design/iabackup/comment_5_7e4d1db9c69c63e79ca13db2ad87c384._comment view
@@ -0,0 +1,7 @@+[[!comment format=mdwn+ username="db48x"+ subject="14 of 21PB, actually"+ date="2015-04-30T02:58:05Z"+ content="""+IA helpfully did a quick count for us: https://archive.org/details/ia-bak-census_20150304+"""]]
+ doc/devblog/day_278__release_day.mdwn view
@@ -0,0 +1,25 @@+I hope that today's git-annex release will be landing in Debian unstable+toward the end of the month. And I'm looking forward to some changes that+have been blocked by wanting to keep git-annex buildable on Debian 7.++Yesterday I got rid of the [SHA](http://hackage.haskell.org/package/SHA/)+dependency, switching git-annex to use a newer version of cryptohash for+HMAC generation (which its author Vincent Hanquez kindly added to it when I+requested it, waay back in 2013). I'm considering using the LambdaCase+extension to clean up a lot of the code next, and there are 500+ lines of+old yesod compatability code I can eventually remove.++These changes and others will prevent backporting to the soon to be Debian+oldstable, but the standalone tarball will still work there. And, the+git-annex-standalone.deb that can be installed on any version of Debian is+[now available from the NeuroDebian repository](http://neuro.debian.net/install_pkg.html?p=git-annex-standalone),+and its build support has been merged into the source tree.++In the run up to the release today, I also dealt with getting the+Windows build tested and working, now that it's been updated to newer+versions of rsync, ssh, etc from Cygwin. Had to add several more dlls to+the installer. That testing also turned up a case where `git-annex init`+could fail, which got a last-minute fix.++PS, scroll down [this 10 year of git timeline](https://www.atlassian.com/git/articles/10-years-of-git/)+and see what you find!
+ doc/devblog/day_279__.mdwn view
@@ -0,0 +1,10 @@+Posted a design for [[design/balanced_preferred_content]]. This would let+preferred content expressions assign each file to N repositories out of a+group, selected using Math. Adding a repository could optionally be+configured to automatically rebalance the files (not very bandwidth+efficiently though). I think some have asked for a feature like this+before, so read the design and see if it would be useful for you.++Spent a while debugging a problem with a S3 remote, which seems to have+been a misconfiguration in the end. But several improvements came out of+it to make it easier to debug S3 in the future etc.
+ doc/devblog/day_280__slow_week.mdwn view
@@ -0,0 +1,16 @@+Reduced activity this week (didn't work on the assistant after all),+but several things got done:++Monday: Fixed `fsck --fast --from remote` to not fail when the remote+didn't support fast copy mode. And dealt with an incompatability in S3 bucket+names; the old hS3 library supported upper-case bucket names but the new+one needs them all in lower case.++Wednesday: Caught up on most recent backlog, made some improvements+to error handling in `import`, and improved integration with KDE's file+manager to work with newer versions.++Today: Made `import --deduplicate/--clean-duplicates` actively +verify that enough copies of a file exist before deleting it. And,+thinking about some options for batch mode access to git-annex plumbing,+to speed up things that use it a lot.
+ doc/devblog/day_281__catching_up__and_arm_autobuilder_needed.mdwn view
@@ -0,0 +1,43 @@+I've not been blogging, but have been busy this week. Backlog is down to+113 messages.++Tuesday: I got a weird bug report where `git annex get` was deleting+a file. This turned out to be a bug in `wget ftp://...` where it would+delete a symlink that was not where it had been told to download the fie+to. I put a workaround in git-annex; wget is now run in a temp+directory. But this was a legitimate wget bug, and it's now been reported+to the wget developers and will hopefully get fixed there.++Wednesday: Added a --batch mode for several plumbing commands+(contentlocation, examinekey, and lookupkey). This avoids startup overhead,+and so lets a lot of queries be done much faster. The implementation+should make it easy to add --batch to more plumbing commands as needed,+and could probably extend to non-plumbing commands too.++Today: The first 5 hours involved an incompatable mess of ssh and rsync+versions on Windows. A gordian knot of brokenness and depedency hell.+I finally found a solution which involves downgrading the cygwin rsync+to an older version, and using msysgit's ssh rather than cygwin's.++Finished up today with more post-Debian-release changes. Landed a patch to+switch from dataenc to sandi that had been waiting since 2013, and got+sandi installed on all the git-annex autobuilders. Finished up with some+prep for a release tomorrow.++----++Finally, Debian has a new enough ghc that it can build template haskell+on arm! So, whenever a new version of git-annex finally gets into Debian+(I hope soon), the webapp will be available on arm for those arm laptops.+Yay!++This also means I have the opportunity to make the standalone arm build+be done much more simply. Currently it involves qemu and a separate+companion native mode container that it has to ssh to and build stuff,+that has to have the same versions of all libraries. It's just enormously+complicated and touchy. With template haskell building support, all that+complexity can fall away. ++What I'd really like to do is get a fast-ish arm box with 2gb of ram+hosted somewhere, and use that to do the builds, in native mode.+Anyone want to help provide such a box for git-annex arm autobuilds?
+ doc/forum/How_do_I_backup_my_data_to_blue_ray_disks__63__.mdwn view
@@ -0,0 +1,1 @@+I have several TB of media on a Debian ZFS server. If I created a git-annex repo for the data, how hard would it be get git-annex (using bup I assume) to back up the files onto a set of Blu Ray disks? I realize that 8TB of data would take about 320 BR 25GB disks, but it seems like git annex would be great for identifying what disk(s) I needed to recover a file. I'm good at bash scripting, and use git daily. I have no experience with git-annex or bup however. Any links to information or suggestions is very appreciated. Thanks!
+ doc/forum/Multiple_repos_on_same_path.mdwn view
@@ -0,0 +1,12 @@+I want to use git-annex to manage some data which I keep at, say, /home/my_user/data .+I have multiple external storage devices for this repo, such as /run/media/my_user/data1 e++BUT, I also have multiple machines, e.g. my desktop and my laptop. +These all have the data under /home/my_user/data, as I like to keep my paths consistent. +So, when I connect my external media to these machines, practically they see the same repo path, though these are different repos.++1. Should I try to create multiple repos with the same path, or should I just add one++2. Can I expect any major issues from this set-up?++  
+ doc/forum/Using_a_glacier_remote_as_a_backup.mdwn view
@@ -0,0 +1,28 @@+Hallo everybody,++I have an ARM based Synology NAS and I would like to use git annex to replace the "backup" solution provided by Synology. The basic idea is that I want files in a safe place when the house burns down or they get removed by accident.++Since I only care about the latest version and want to make really sure local programs (cifs service, photostation and so on) do not run into trouble caused by symlinks, I guess direct mode is what I want. I have been tinkering around and things seem to be working for the most part. A few questions remain:++Assuming I have all files synced to glacier and then accidentally remove all content and try to recover with the bare repo - with metadata but without content. the situation looks like this. ++    ➜  syno-archive git:(annex/direct/master) git annex status test.txt+    D test.txt+    ➜  syno-archive git:(annex/direct/master)+    +I try to get my files back out of glacier:++    ➜  syno-archive git:(annex/direct/master) git annex get test.txt   +    get test.txt (from glacier...) +    ok                      +    (Recording state in git...)+    ➜  syno-archive git:(annex/direct/master)++Contrary to my expectation, text.txt did not appear on disk.++Given the bare repo, you would one recover all content (thousands of files)? I expected "git annex get --all" to do the trick. ++PS: This is from git-annex version 5.20141125++regards+Andreas
+ doc/forum/Where_did_my_files_go__63__.mdwn view
@@ -0,0 +1,20 @@+I import some files that I've seen before somewhere:++    $ git annex import --deduplicate .../download+    ...+    import download/What_is_The_Digital_Fiction_Factory-Conker_Media.pdf (duplicate) ok+    ...++But the resulting download directory is empty, and `list` doesn't show any of the files:++    $ git annex list --allrepos What_is_The_Digital_Fiction_Factory-Conker_Media.pdf+    here+    |...+    |...+    |...+    |...+    |...+    |...+    git-annex: What_is_The_Digital_Fiction_Factory-Conker_Media.pdf not found++How do I find out where this file can be found?
+ doc/forum/git_annex_windows_and_rsync.mdwn view
@@ -0,0 +1,26 @@+Issue with getting files from a Linux ssh/rsync repo.++I have a centralized repo on a small linux VM that I synchronize my workstations with, most are linux machines but one is a windows one.  I installed msysgit and git-annex for windows, and then run the following:+++    git clone ssh://user@IP.ADDRESS/home/user/annex annex  +    cd annex  +    git annex init 'windows'  +    git annex copy --from origin  +++So basically I am just trying to get a copy of the central repo onto this windows machine for starters and get:+++    rsync: connection unexpectedly closed (0 bytes received so far) [sender]+    rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.1] +    rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]  +    rsync error: error in rsync protoco  rsync failed -- run git annex again to resume file transfer  +    l dafailed+    ta stream (code 12) atcopy  +++And I get this message for every file.+++I do have cygwin with rsync and ssh installed on this machine previously so I tried on a separate machine thinking there may be compatibility issues with no avail either.  I am not sure if this is an existing issue/work in progress with Windows/git-annex or if it is something I am just experiencing.  
+ doc/forum/pre-commit_hook_to_use_git_annex_for_only_large_files.mdwn view
@@ -0,0 +1,55 @@+I've wanted to use git-annex for the longest time, but I really only wanted to use it if the files were over a certain size, otherwise, I just want to use regular git.++After writing this pre-commit hook, I wanted to share and get some feedback.++This would be saved as `.git/hooks/pre-commit`++    #!/bin/sh+    let MAX=1*1024*1024  # 1048576 == 1 MB+    if [ ! -d '.git/annex/' ]; then+      /usr/local/bin/git annex init >/dev/null 2>&1+    fi+    if git rev-parse --verify HEAD >/dev/null 2>&1; then+      against=HEAD+    else+      # Initial commit: diff against an empty tree object+      against=$(/usr/local/bin/git hash-object -t tree /dev/null)+    fi+    /usr/local/bin/git diff-index --cached $against | \+      /usr/bin/tr '\t' ' ' | \+      /usr/bin/cut -d ' ' -f4,6- | \+      while read line; do+        sha1=$(/usr/bin/cut -d ' ' -f1 <<< "$line")+        if [ "$sha1" == "0000000000000000000000000000000000000000" ]; then+          continue+        fi+        size=$(/usr/local/bin/git cat-file -s "$sha1")+        if [ $size -ge $MAX ]; then+          file=$(/usr/bin/cut -d ' ' -f2- <<< "$line")+          /usr/local/bin/git update-index --force-remove "$file"+          /usr/local/bin/git annex add "$file"+          /usr/bin/killall -TERM Finder+        fi+    done+    /usr/local/bin/git annex pre-commit .++I also wrote an `Unlock Git Annex File.workflow` service for OS X:++    set gitAnnex to "/Applications/git-annex.app/Contents/MacOS/git-annex"++    tell application "Finder"+            repeat with theItem in (get selection)+                    if file type of theItem is "slnk" then+                            set theFolder to quoted form of POSIX path of (container of theItem as alias)+                            set filePath to do shell script "/usr/bin/basename " & quoted form of POSIX path of (theItem as text)+                            set theCommand to "cd " & theFolder & "; " & gitAnnex & " unlock '" & filePath & "'"+                            do shell script theCommand+                    end if+            end repeat+    end tell++Use Automator to create a new service that receives selected "files or folders" in "Finder.app". Then drag the "Run AppleScript" action to the workflow panel. The script above should be copied into the code area replacing all the default content.++Am I all alone in wanting these types of scripts?++- Peter
+ doc/forum/rsync_regression_on_Windows.mdwn view
@@ -0,0 +1,16 @@+I'm on Windows 7 and msysgit. The rsync that comes with the git-annex installer downloaded on January 19 2015 works fine (rsync version 3.0.9, protocol version 30; git annex version 5.20150113-gcf247cf). The rsync that comes with the current git-annex installer errors out (rsync version 3.1.1  protocol version 31; git annex v ersion 5.20150420-gb0ebb23). I don't think it's a version/protocol mismatch, as I get the error against a server with the same version and protocol.++[[!format sh """+$ rsync -rvvp anton@myhost:wtmp/ wtmp+opening connection using: ssh -l anton myhost rsync --server --sender -vv+pre.iLsfx . wtmp/  (10 args)+rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]+rsync error: error in rsync protocol data stream (code 12) at io.c(226) [Receiver=3.1.1]++$ ssh -l anton myhost rsync --version+rsync  version 3.1.1  protocol version 31+...++"""]]++Bug or user error?
doc/git-annex-assistant.mdwn view
@@ -34,7 +34,12 @@  * `--stop` -  Stop a running daemon.+  Stop a running daemon in the current repository.++* `--autostop`++  The complement to --autostart; stops all running daemons in the+  repositories listed in the autostart file.  # SEE ALSO 
doc/git-annex-contentlocation.mdwn view
@@ -16,6 +16,17 @@ tree, and while its content should correspond to the key, the file could become modified at any time after git-annex checks it. +# OPTIONS++* `--batch`++  Enable batch mode, in which a line containing the key is read from+  stdin, the filename to its content is output to stdout (with a trailing+  newline), and repeat.++  Note that if a key's content is not present, an empty line is output to+  stdout instead.+ # SEE ALSO  [[git-annex]](1)
doc/git-annex-copy.mdwn view
@@ -16,6 +16,8 @@    Use this option to copy the content of files from the specified   remote to the local repository.+  +  Any files that are not available on the remote will be silently skipped.  * `--to=remote` 
doc/git-annex-examinekey.mdwn view
@@ -33,6 +33,11 @@   Enable JSON output. This is intended to be parsed by programs that use   git-annex. Each line of output is a JSON object. +* `--batch`++  Enable batch mode, in which a line containing a key is read from stdin,+  the information about it is output to stdout, and repeat.+ # EXAMPLES  The location a key's value is stored (in indirect mode)
doc/git-annex-get.mdwn view
@@ -23,7 +23,9 @@ * `--from=remote`    Normally git-annex will choose which remotes to get the content-  from. Use this option to specify which remote to use.+  from. Use this option to specify which remote to use. +  +  Any files that are not available on the remote will be silently skipped.  * `--all` 
doc/git-annex-import.mdwn view
@@ -16,8 +16,9 @@  When importing files, there's a possibility of importing a duplicate of a file that is already known to git-annex -- its content is either-present in the local repository already, or git-annex knows of anther-repository that contains it.+present in the local repository already, or git-annex knows of another+repository that contains it, or it was present in the annex before but has+been removed now.  By default, importing a duplicate of a known file will result in a new filename being added to the repository, so the duplicate file@@ -51,6 +52,12 @@    Does not import any files, but any files found in the import location   that are duplicates are deleted.++* `--force`++  Allow existing files to be overwritten by newly imported files.++  Also, causes .gitignore to not take effect when adding files.  * file matching options 
doc/git-annex-lookupkey.mdwn view
@@ -13,6 +13,16 @@ the file is not present in the index, or is not a git-annex managed file), nothing is output, and it exits nonzero. +# OPTIONS++* `--batch`++  Enable batch mode, in which a line containing the filename is read from+  stdin, the key is output to stdout (with a trailing newline), and repeat.++  Note that is there is no key corresponding to the file, an empty line is+  output to stdout instead.+ # SEE ALSO  [[git-annex]](1)
doc/git-annex-metadata.mdwn view
@@ -66,6 +66,19 @@   Enable JSON output. This is intended to be parsed by programs that use   git-annex. Each line of output is a JSON object. +* `--all`++  Specify instead of a file to get/set metadata on all known keys.++* `--unused`++  Specify instead of a file to get/set metadata on+  files found by last run of git-annex unused.++* `--key=keyname`++  Specify instead of a file to get/set metadata of the specified key.+ # EXAMPLES  To set some tags on a file and also its author:
doc/git-annex-pre-commit.mdwn view
@@ -4,7 +4,7 @@  # SYNOPSIS -git annex  `[path ...]`+git annex pre-commit `[path ...]`  # DESCRIPTION 
doc/git-annex-watch.mdwn view
@@ -30,7 +30,7 @@  * `--stop` -  Stop a running daemon.+  Stop a running daemon in the current repository.  # SEE ALSO 
doc/git-annex-whereis.mdwn view
@@ -32,6 +32,19 @@   The [[git-annex-matching-options]](1)   can be used to specify files to act on. +* `--key=keyname`++  Show where a particular git-annex key is located.++* `--all`++  Show whereis information for all known keys.++* `--unused`++  Show whereis information for files found by last run of git-annex unused.++ # SEE ALSO  [[git-annex]](1)
doc/install/Debian.mdwn view
@@ -2,6 +2,10 @@  	sudo apt-get install git-annex +## Debian 8.0 "jessie"++	sudo apt-get install git-annex+ ## Debian 7.0 "wheezy":  	sudo apt-get install git-annex
doc/install/OSX/MacPorts.mdwn view
@@ -8,7 +8,7 @@ Then execute  <pre>-sudo port install git-core ossp-uuid md5sha1sum coreutils gnutls libxml2 libgsasl pkgconfig+sudo port install git ossp-uuid md5sha1sum coreutils gnutls libxml2 libgsasl pkgconfig sudo cabal update PATH=$HOME/bin:$PATH cabal install c2hs git-annex --bindir=$HOME/bin
+ doc/metadata/comment_3_50b17af1cf75ce88c4aef59dcd971b82._comment view
@@ -0,0 +1,7 @@+[[!comment format=mdwn+ username="madduck"+ subject="Overwriting metadata from json"+ date="2015-04-30T18:42:45Z"+ content="""+I see that --json allows me to export metadata in a well-parseable format. I'd really like to be able to pipe this into a file, edit the file and then pipe it back to git-annex, causing the metadata for each file to be rewritten from the JSON input. This would make it trivial to write an external metadata editor (like vidir, vorbistagedit, git annex vicfg even… etc.)+"""]]
+ doc/metadata/comment_4_237721c5e8f66f303a1828810573a23d._comment view
@@ -0,0 +1,15 @@+[[!comment format=mdwn+ username="joey"+ subject="""comment 4"""+ date="2015-05-01T19:38:36Z"+ content="""+@madduck, you could file a todo if you want about that.++However, I have my doubts; if the json supposed to include the full set of+metadata for the file? If so, that seems a potentially expensive interface.+If not, it would be hard to tell when metadata should be deleted, or when+multiple values are being set, vs a value being changed. ++The current interface to set metadata deals with these possibilities in a+compact and sensible way.+"""]]
+ doc/metadata/comment_5_fd30444aecfc4792eb4dbfdebc230786._comment view
@@ -0,0 +1,9 @@+[[!comment format=mdwn+ username="madduck"+ subject="TODO written"+ date="2015-05-06T14:24:56Z"+ content="""+@joeyh, yes, it would overwrite all metadata. The idea would be to export with --json, manipulate, import…++http://git-annex.branchable.com/todo/ability_to_set_metadata_from_json/?updated+"""]]
− doc/news/version_5.20150327.mdwn
@@ -1,22 +0,0 @@-git-annex 5.20150327 released with [[!toggle text="these changes"]]-[[!toggleable text="""-   * readpresentkey: New plumbing command for checking location log.-   * checkpresentkey: New plumbing command to check if a key can be verified-     to be present on a remote.-   * Added a post-update-annex hook, which is run after the git-annex branch-     is updated. Needed for git update-server-info.-   * migrate: --force will force migration of keys already using the-     destination backend. Useful in rare cases.-   * Man pages for individual commands now available, and can be-     opened using "git annex help &lt;command&gt;"-   * --auto is no longer a global option; only get, drop, and copy-     accept it. (Not a behavior change unless you were passing it to a-     command that ignored it.)-   * Improve error message when --in @date is used and there is no-     reflog for the git-annex branch.-   * assistant: Committing a whole lot of files at once could overflow-     command-line length limits and cause the commit to fail. This-     only happened when using the assistant in an indirect mode repository.-   * Work around curl bug when asked to download an empty url to a file.-   * Fix bug introduced in the last release that broke git-annex sync-     when git-annex was installed from the standalone tarball."""]]
+ doc/news/version_5.20150508.mdwn view
@@ -0,0 +1,51 @@+git-annex 5.20150508 released with [[!toggle text="these changes"]]+[[!toggleable text="""+   * Improve behavior when a git-annex command is told to operate+     on a file that doesn't exist. It will now continue to other+     files specified after that on the command line, and only error out at+     the end.+   * S3: Enable debug logging when annex.debug or --debug is set.+   * S3: git annex info will show additional information about a S3 remote+     (endpoint, port, storage class)+   * S3: Let git annex enableremote be used, without trying to recreate+     a bucket that should already exist.+   * S3: Fix incompatability with bucket names used by hS3; the aws library+     cannot handle upper-case bucket names. git-annex now converts them to+     lower case automatically.+   * import: Check for gitignored files before moving them into the tree.+     (Needs git 1.8.4 or newer.)+   * import: Don't stop entire import when one file fails due to being+     gitignored or conflicting with something in the work tree.+   * import: Before removing a duplicate file in --deduplicate or+     --clean-duplicates mode, verify that enough copies of its content still+     exist.+   * Improve integration with KDE's file manager to work with dolphin+     version 14.12.3 while still being compatable with 4.14.2.+     Thanks, silvio.+   * assistant: Added --autostop to complement --autostart.+   * Work around wget bug #784348 which could cause it to clobber git-annex+     symlinks when downloading from ftp.+   * Support checking ftp urls for file presence.+   * Fix bogus failure of fsck --fast.+   * fsck: Ignore error recording the fsck in the activity log,+     which can happen when running fsck in a read-only repository.+     Closes: #[698559](http://bugs.debian.org/698559)+     (fsck can still need to write to the repository if it find problems,+     but a successful fsck can be done read-only)+   * Improve quvi 0.4 output parsing to handle cases wher there is no known+     filename extension. This is currently the case when using quvi with+     youtube. In this case, the extension ".m" will be used.+   * Dropped support for older versions of yesod, warp, and dbus than the ones+     in Debian Jessie.+   * Switch from the obsolete dataenc library for base64 encoding to sandi.+     (Thanks, Magnus Therning)+   * Debian's ghc now supports TH on arm! Adjust build dependencies+     to build the webapp on arm, and enable DAV support on arm. \o/+   * Adjust some other arch specific build dependencies that are now+     available on more architectures in Devian unstable.+   * Windows: Remove cygwin ssh, the newer version of which has stopped+     honoring the setting of HOME. Instead, copy msysgit's ssh into PATH.+     Note that setting up a remote ssh server using password authentication+     is known to be broken in this release on Windows.+   * Windows: Roll back to an older version of rsync from cygwin.+     The newer version has some dependency on a newer ssh from cygwin."""]]
+ doc/required_content/comment_2_d475f4afc84a58afe7af6d492de3ebe5._comment view
@@ -0,0 +1,7 @@+[[!comment format=mdwn+ username="joey"+ subject="""comment 2"""+ date="2015-04-29T18:04:52Z"+ content="""+`git annex required` was recently added to the CLI.+"""]]
doc/tips/centralized_git_repository_tutorial.mdwn view
@@ -1,13 +1,13 @@ The [[walkthrough]] builds up a decentralized git repository setup, but git-annex can also be used with a centralized bare repository, just like git can. This tutorial shows how to set up a centralized repository hosted on-GitHub.+GitHub on GitLab or your own git server.  ## set up the repository, and make a checkout  I've created a repository for technical talk videos, which you can [fork on Github](https://github.com/joeyh/techtalks).-Or make your own repository on GitHub (or elsewhere) now.+Or make your own repository on GitHub (or GitLab elsewhere) now.  On your laptop, [[install]] git-annex, and clone the repository: @@ -21,12 +21,14 @@ 	init my laptop ok  Let's tell git-annex that GitHub doesn't support running git-annex-shell there.++	# git config remote.origin.annex-ignore true+ This means you can't store annexed file *contents* on GitHub; it would really be better to host the bare repository on your own server, which would not have this limitation. (If you want to do that, check out-[[using_gitolite_with_git-annex]].)--	# git config remote.origin.annex-ignore true+[[using_gitolite_with_git-annex]].) Or, you could use GitLab, which+*does* [support git-annex on their servers](https://about.gitlab.com/2015/02/17/gitlab-annex-solves-the-problem-of-versioning-large-binaries-with-git/).  ## add files to the repository @@ -53,9 +55,9 @@ 	# git mv kitenet.net_~joey_screencasts_git-annex_coding_in_haskell.ogg git-annex_coding_in_haskell.ogg 	# git commit -m 'better filenames' -Now push your changes back to the central repository. This first time,-remember to push the git-annex branch, which is used to track the file-contents.+Now push your changes back to the central repository. As well as pushing+the master branch, remember to push the git-annex branch, which is used to+track the file contents.  	# git push origin master git-annex 	To git@github.com:joeyh/techtalks.git@@ -126,7 +128,7 @@ After you use git-annex to move files around, remember to push,  which will broadcast its updated location information. -	# git push+	# git push origin master git-annex  ## take it farther 
doc/tips/downloading_podcasts.mdwn view
@@ -75,6 +75,10 @@ `git annex importfeed` on youtube playlists. It will automatically download the videos linked to by the playlist. +For this you need an rss file containing links to the videos.+For example, this url currently works:+<http://gdata.youtube.com/feeds/api/playlists/PLz8ZG1e9MPlzefklz1Gv79icjywTXycR->+ ## metadata  As well as storing the urls for items imported from a feed, git-annex can
+ doc/todo/ability_to_set_metadata_from_json.mdwn view
@@ -0,0 +1,6 @@+I can export metadata to JSON format, which is nice as this can now be read into any other tool and manipulated. But I cannot find a way to set the metadata from JSON and so I am left to figure out what changes need to be made via the g-a interface to get to the desired state, and that is hard to get right.++Maybe g-a metadata could grow an import-json function which would set (overwrite) the metadata for the given file(s) from JSON input.++Thanks,+-m
+ doc/todo/enable_fsck_--fast_for_S3_remotes.mdwn view
@@ -0,0 +1,30 @@+At the moment, ``git annex fsck --fast -f S3remote`` fails as++[[!format sh """+> git annex fsck --fast -f S3remote+(checking cloud...) [2015-04-24 21:39:35 BST] String to sign: "HEAD\n\n\nFri, 24 Apr 2015 20:39:35 GMT\n/BUCKET/GPGHMACSHA1--6e7e880f80de44ddd845c6241198622b9102eaa1"+[2015-04-24 21:39:35 BST] Host: "BUCKET.s3-ap-southeast-2.amazonaws.com"+[2015-04-24 21:39:35 BST] Path: "/GPGHMACSHA1--6e7e880f80de44ddd845c6241198622b9102eaa1"+[2015-04-24 21:39:35 BST] Query string: ""+[2015-04-24 21:39:36 BST] Response status: Status {statusCode = 200, statusMessage = "OK"}+[2015-04-24 21:39:36 BST] Response header 'x-amz-id-2': 'D9wtD8voZZgijJRc6i8i0QasAo85REdMMf4GpRaER5+g6sDaUYtCKi42RCdYU0kBxrx4d4dM4xM='+[2015-04-24 21:39:36 BST] Response header 'x-amz-request-id': 'DDF95C327078E584'+[2015-04-24 21:39:36 BST] Response header 'Date': 'Fri, 24 Apr 2015 20:39:37 GMT'+[2015-04-24 21:39:36 BST] Response header 'Last-Modified': 'Sun, 02 Nov 2014 05:42:48 GMT'+[2015-04-24 21:39:36 BST] Response header 'ETag': '"3bd1b766a68a305ba0495af36b353a07"'+[2015-04-24 21:39:36 BST] Response header 'Accept-Ranges': 'bytes'+[2015-04-24 21:39:36 BST] Response header 'Content-Type': ''+[2015-04-24 21:39:36 BST] Response header 'Content-Length': '775647'+[2015-04-24 21:39:36 BST] Response header 'Server': 'AmazonS3'+[2015-04-24 21:39:36 BST] Response metadata: S3: request ID=<none>, x-amz-id-2=<none>++  failed to download file from remote++failed+"""]]+++while ``git annex fsck -f S3remote`` works fine. But, to check for the presence of a file (which is my understanding of what ``--fast`` is for here), it shouldn't be necessary to download the file.++> [[fixed|done]]; it was not supposed to fail at all in this case, and +> won't anymore. --[[Joey]]
+ doc/todo/make_glacier-cli_executable_path_configurable.mdwn view
@@ -0,0 +1,8 @@+[glacier-cli](https://github.com/basak/glacier-cli) calls its own command `glacier` rather than `glacier-cli` or something else.  This conflicts with [boto](https://github.com/boto/boto/)'s own `glacier` executable, as noted here:++* <https://github.com/basak/glacier-cli/issues/30>+* <https://github.com/basak/glacier-cli/issues/47>++Whilst the `glacier-cli` project should resolve this conflict, it would be good if git-annex could be made to use a configurable path for this executable, rather than just assuming that it has been installed as `glacier`.  After all, its installation procedure is simply telling the user to run `ln -s`, so there's no reason why the user couldn't make the target of this command `~/bin/glacier-cli` rather than `~/bin/glacier` - it's really irrelevant what the source file inside the git repo is called.++Of course, [`checkSaneGlacierCommand`](https://github.com/joeyh/git-annex/blob/master/Remote/Glacier.hs#L307) is still very much worth having, for safety.
doc/todo/replace_dataenc_with_sandi.mdwn view
@@ -2,3 +2,5 @@  sandi is available in jessie, but not wheezy, so this is pending EOL of wheezy support. --[[Joey]]++> [[fixed|done]] --[[Joey]]
doc/todo/server-level_daemon__63__.mdwn view
@@ -186,3 +186,18 @@  3. it is Debian-specific (a proper init script would be POSIX only and/or a `.service` file)  Maybe using [metainit](https://wiki.debian.org/MetaInit) would be a good idea here? --[[anarcat]]++> This strikes me as a bad idea if the system has regular desktop etc+> users; the assistant can already start itself when they login and +> a separate user has the same problems the separate mpd user seems to;+> of separating the user from the files that effcetively belong to them.+> +> It's fine if you're doing something more specialized, but that seems+> like an unusual case and not one that git-annex should cater to.+> +> Anyway, it's about 5 lines to write a systemd service file. I've added+> `git annex assistant --autostop` that such a service can use if desired.+> +> Since I don't want to include that in git-annex and be stuck supporting+> it, and it should be easy for users to add if they need it, I think I'm+> going to call this [[done]]. --[[Joey]] 
+ doc/todo/smudge/comment_4_5ff4ad15865a93dc8c066220561936b2._comment view
@@ -0,0 +1,9 @@+[[!comment format=mdwn+ username="tomekwi"+ subject="How about the other way round?"+ date="2015-04-25T09:13:31Z"+ content="""+If I understand this right, this feature should allow us to say to *git*: “Hey, from now on whenever I `git add` a `*.png` file, add it to *git-annex* instead!”++How about saying to *git-annex*: “Hey, whenever I `git-annex add` a file which is *not* `*.png`, add it to *git* instead! Or at least leave it unadded so that I can decide later.” Is it possible now? If not, would it be reasonable to add such a feature?+"""]]
+ doc/todo/smudge/comment_5_80bbc3710f9a18644571c6dd60baf4e5._comment view
@@ -0,0 +1,7 @@+[[!comment format=mdwn+ username="joey"+ subject="""comment 5"""+ date="2015-04-29T15:30:50Z"+ content="""+That feature already exists (annex.largefiles).+"""]]
+ doc/todo/smudge/comment_6_86f536515575a6c2ed3a89c80b2c232f._comment view
@@ -0,0 +1,7 @@+[[!comment format=mdwn+ username="tomekwi"+ subject="comment 6"+ date="2015-04-29T20:38:51Z"+ content="""+Thanks! Looks great :)+"""]]
+ doc/trust/comment_1_305e4e7c6b75db29212b758e8504d8c9._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawlJl0OCe6AJEnIFIcg-t5Rhk-lI_Y-tWUs"+ nickname="Michael"+ subject="default trust for hosts"+ date="2015-05-01T21:41:05Z"+ content="""+Is it possible to set a default trust per host (e.g. in `~/.gitconfig`)?++I have one server that does its own backups, and a client that I'd like to keep thin across multiple repositories.+"""]]
+ doc/trust/comment_2_2262eaa830306d3dc75999bc0433b6a8._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="joey"+ subject="""comment 2"""+ date="2015-05-05T18:07:02Z"+ content="""+You can use `remote.<name>.annex-trustlevel` as documented in the git-annex+man page.+"""]]
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 5.20150420+Version: 5.20150508 Cabal-Version: >= 1.8 License: GPL-3 Maintainer: Joey Hess <id@joeyh.name>@@ -105,7 +105,7 @@   Main-Is: git-annex.hs   Build-Depends: MissingH, hslogger, directory, filepath,    containers (>= 0.5.0.0), utf8-string, mtl (>= 2),-   bytestring, old-locale, time, dataenc, process, json,+   bytestring, old-locale, time, sandi, process, json,    base (>= 4.5 && < 4.9), monad-control, exceptions (>= 0.6), transformers,    IfElse, text, QuickCheck >= 2.1, bloomfilter, edit-distance,    SafeSemaphore, uuid, random, dlist, unix-compat, async, stm (>= 2.3),@@ -183,7 +183,7 @@    if (os(linux))     if flag(Dbus)-      Build-Depends: dbus (>= 0.10.3)+      Build-Depends: dbus (>= 0.10.7)       CPP-Options: -DWITH_DBUS        if flag(DesktopNotify)@@ -199,10 +199,17 @@    if flag(Webapp)     Build-Depends:-     yesod, yesod-default, yesod-static, yesod-form, yesod-core,-     wai, wai-extra, warp, warp-tls,+     yesod (>= 1.2.6), +     yesod-default (>= 1.2.0),+     yesod-static (>= 1.2.4),+     yesod-form (>= 1.3.15),+     yesod-core (>= 1.2.19),+     path-pieces (>= 0.1.4),+     warp (>= 3.0.0.5),+     warp-tls,+     wai, wai-extra,      blaze-builder, crypto-api, hamlet, clientsession,-     template-haskell, aeson, path-pieces,+     template-haskell, aeson,      shakespeare     CPP-Options: -DWITH_WEBAPP   if flag(Webapp) && flag (Webapp-secure)
man/git-annex-assistant.1 view
@@ -28,7 +28,11 @@ Avoid forking to the background. .IP .IP "\fB\-\-stop\fP"-Stop a running daemon.+Stop a running daemon in the current repository.+.IP+.IP "\fB\-\-autostop\fP"+The complement to \-\-autostart; stops all running daemons in the+repositories listed in the autostart file. .IP .SH SEE ALSO git-annex(1)
man/git-annex-contentlocation.1 view
@@ -14,6 +14,16 @@ tree, and while its content should correspond to the key, the file could become modified at any time after git-annex checks it. .PP+.SH OPTIONS+.IP "\fB\-\-batch\fP"+.IP+Enable batch mode, in which a line containing the key is read from+stdin, the filename to its content is output to stdout (with a trailing+newline), and repeat.+.IP+Note that if a key's content is not present, an empty line is output to+stdout instead.+.IP .SH SEE ALSO git-annex(1) .PP
man/git-annex-copy.1 view
@@ -14,6 +14,8 @@ Use this option to copy the content of files from the specified remote to the local repository. .IP+Any files that are not available on the remote will be silently skipped.+.IP .IP "\fB\-\-to=remote\fP" Use this option to copy the content of files from the local repository to the specified remote.
man/git-annex-examinekey.1 view
@@ -29,6 +29,10 @@ Enable JSON output. This is intended to be parsed by programs that use git-annex. Each line of output is a JSON object. .IP+.IP "\fB\-\-batch\fP"+Enable batch mode, in which a line containing a key is read from stdin,+the information about it is output to stdout, and repeat.+.IP .SH EXAMPLES The location a key's value is stored (in indirect mode) can be looked up by running:
man/git-annex-get.1 view
@@ -19,7 +19,9 @@ .IP .IP "\fB\-\-from=remote\fP" Normally git-annex will choose which remotes to get the content-from. Use this option to specify which remote to use.+from. Use this option to specify which remote to use. +.IP+Any files that are not available on the remote will be silently skipped. .IP .IP "\fB\-\-all\fP" Rather than specifying a filename or path to get, this option can be
man/git-annex-import.1 view
@@ -14,8 +14,9 @@ .PP When importing files, there's a possibility of importing a duplicate of a file that is already known to git-annex \-\- its content is either-present in the local repository already, or git-annex knows of anther-repository that contains it.+present in the local repository already, or git-annex knows of another+repository that contains it, or it was present in the annex before but has+been removed now. .PP By default, importing a duplicate of a known file will result in a new filename being added to the repository, so the duplicate file@@ -45,6 +46,11 @@ .IP "\fB\-\-clean\-duplicates\fP" Does not import any files, but any files found in the import location that are duplicates are deleted.+.IP+.IP "\fB\-\-force\fP"+Allow existing files to be overwritten by newly imported files.+.IP+Also, causes .gitignore to not take effect when adding files. .IP .IP "file matching options" Many of the git-annex\-matching\-options(1)
man/git-annex-lookupkey.1 view
@@ -11,6 +11,15 @@ the file is not present in the index, or is not a git-annex managed file), nothing is output, and it exits nonzero. .PP+.SH OPTIONS+.IP "\fB\-\-batch\fP"+.IP+Enable batch mode, in which a line containing the filename is read from+stdin, the key is output to stdout (with a trailing newline), and repeat.+.IP+Note that is there is no key corresponding to the file, an empty line is+output to stdout instead.+.IP .SH SEE ALSO git-annex(1) .PP
man/git-annex-metadata.1 view
@@ -54,6 +54,16 @@ Enable JSON output. This is intended to be parsed by programs that use git-annex. Each line of output is a JSON object. .IP+.IP "\fB\-\-all\fP"+Specify instead of a file to get/set metadata on all known keys.+.IP+.IP "\fB\-\-unused\fP"+Specify instead of a file to get/set metadata on+files found by last run of git-annex unused.+.IP+.IP "\fB\-\-key=keyname\fP"+Specify instead of a file to get/set metadata of the specified key.+.IP .SH EXAMPLES To set some tags on a file and also its author: .PP
man/git-annex-pre-commit.1 view
@@ -3,7 +3,7 @@ git-annex pre\-commit \- run by git pre\-commit hook .PP .SH SYNOPSIS-git annex  \fB[path ...]\fP+git annex pre\-commit \fB[path ...]\fP .PP .SH DESCRIPTION This is meant to be called from git's pre\-commit hook. \fBgit annex init\fP
man/git-annex-watch.1 view
@@ -26,7 +26,7 @@ Avoid forking to the background. .IP .IP "\fB\-\-stop\fP"-Stop a running daemon.+Stop a running daemon in the current repository. .IP .SH SEE ALSO git-annex(1)
man/git-annex-whereis.1 view
@@ -28,6 +28,15 @@ The git-annex\-matching\-options(1) can be used to specify files to act on. .IP+.IP "\fB\-\-key=keyname\fP"+Show where a particular git-annex key is located.+.IP+.IP "\fB\-\-all\fP"+Show whereis information for all known keys.+.IP+.IP "\fB\-\-unused\fP"+Show whereis information for files found by last run of git-annex unused.+.IP .SH SEE ALSO git-annex(1) .PP
standalone/android/cabal.config view
@@ -54,7 +54,7 @@              data-default-instances-containers ==0.0.1,              data-default-instances-dlist ==0.0.1,              data-default-instances-old-locale ==0.0.1,-             dataenc ==0.14.0.7,+             sandi ==0.3.0.1,              dbus ==0.10.8,              distributive ==0.4.4,              dlist ==0.7.0.1,
standalone/windows/build-simple.sh view
@@ -4,10 +4,10 @@ set -e set -x -# Path to the Haskell Platform.-HP="/c/Program Files/Haskell Platform/2013.2.0.0"+# Path to the Haskell Platform. (As mingw sh sees it)+HP="/c/Program Files/Haskell Platform/2014.2.0.0" -PATH="$HP/bin:$HP/lib/extralibs/bin:$PATH"+PATH="$HP/bin:$HP/mingw/bin:$HP/lib/extralibs/bin:/c/Program Files/Git/cmd:/c/Program Files/NSIS:$PATH"  # Run a command with the cygwin environment available. # However, programs not from cygwin are preferred.@@ -21,8 +21,10 @@ # Install haskell dependencies. # cabal install is not run in cygwin, because we don't want configure scripts # for haskell libraries to link them with the cygwin library.-cabal update || true-cabal install --only-dependencies || true+if ! cabal install --only-dependencies; then+	cabal update || true+	cabal install --only-dependencies+fi  # Build git-annex if [ ! -e "dist/setup-config" ]; then
standalone/windows/build.sh view
@@ -16,9 +16,6 @@ withcyg () { 	PATH="$PATH:/c/cygwin/bin" "$@" }-withcygpreferred () {-	PATH="/c/cygwin/bin:$PATH" "$@"-}  # This tells git-annex where to upgrade itself from. UPGRADE_LOCATION=http://downloads.kitenet.net/git-annex/windows/current/git-annex-installer.exe@@ -70,7 +67,12 @@ ghc -fforce-recomp --make Build/NullSoftInstaller.hs # Want to include cygwin programs in bundle, not others, since # it includes the cygwin libs that go with them.-withcygpreferred Build/NullSoftInstaller.exe+# Currently need an older version of rsync than the one from cygwin.+if [ ! -e rsync.exe ]; then+	withcyg wget https://downloads.kitenet.net/git-annex/windows/assets/rsync.exe+	withcyg chmod +x rsync.exe+fi+PATH=".:/c/cygwin/bin:$PATH" Build/NullSoftInstaller.exe  rm -f last-incremental-failed 
+ standalone/windows/ssh-keygen.cmd view
@@ -0,0 +1,31 @@+@rem Do not use "echo off" to not affect any child calls.
+
+@rem Enable extensions, the `verify other 2>nul` is a trick from the setlocal help
+@verify other 2>nul
+@setlocal enableDelayedExpansion
+@if errorlevel 1 (
+    @echo Unable to enable delayed expansion. Immediate expansion will be used.
+    @goto fallback
+)
+
+@rem Get the absolute path to the parent directory, which is assumed to be the
+@rem Git installation root.
+@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI
+@set PATH=!git_install_root!\bin;!git_install_root!\mingw\bin;!PATH!
+
+ssh-keygen %*
+@goto end
+
+:fallback
+@rem The above script again with immediate expansion, in case delayed expansion
+@rem is unavailable.
+@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI
+@set PATH=%git_install_root%\bin;%git_install_root%\mingw\bin;%PATH%
+
+@if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH%
+@if not exist "%HOME%" @set HOME=%USERPROFILE%
+
+ssh-keygen %*
+
+:end
+@rem End of script
+ standalone/windows/ssh.cmd view
@@ -0,0 +1,31 @@+@rem Do not use "echo off" to not affect any child calls.
+
+@rem Enable extensions, the `verify other 2>nul` is a trick from the setlocal help
+@verify other 2>nul
+@setlocal enableDelayedExpansion
+@if errorlevel 1 (
+    @echo Unable to enable delayed expansion. Immediate expansion will be used.
+    @goto fallback
+)
+
+@rem Get the absolute path to the parent directory, which is assumed to be the
+@rem Git installation root.
+@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI
+@set PATH=!git_install_root!\bin;!git_install_root!\mingw\bin;!PATH!
+
+ssh %*
+@goto end
+
+:fallback
+@rem The above script again with immediate expansion, in case delayed expansion
+@rem is unavailable.
+@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI
+@set PATH=%git_install_root%\bin;%git_install_root%\mingw\bin;%PATH%
+
+@if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH%
+@if not exist "%HOME%" @set HOME=%USERPROFILE%
+
+ssh %*
+
+:end
+@rem End of script