git-annex 5.20140320 → 5.20140402
raw patch · 108 files changed
+2086/−363 lines, 108 filesdep +fdo-notifybinary-added
Dependencies added: fdo-notify
Files
- Annex.hs +8/−8
- Annex/Branch/Transitions.hs +6/−2
- Annex/FileMatcher.hs +7/−10
- Annex/Notification.hs +81/−0
- Annex/Transfer.hs +131/−0
- Assistant/Alert/Utility.hs +0/−1
- Assistant/Install.hs +30/−1
- Assistant/Ssh.hs +1/−1
- Assistant/Threads/ConfigMonitor.hs +5/−3
- Assistant/Threads/Watcher.hs +4/−3
- BuildFlags.hs +3/−0
- CHANGELOG +37/−0
- CmdLine/Option.hs +6/−0
- CmdLine/Seek.hs +11/−8
- Command/Add.hs +8/−3
- Command/AddUrl.hs +20/−16
- Command/ConfigList.hs +18/−2
- Command/Drop.hs +47/−17
- Command/DropUnused.hs +2/−2
- Command/Get.hs +9/−11
- Command/List.hs +2/−2
- Command/Move.hs +8/−6
- Command/PreCommit.hs +28/−1
- Command/SendKey.hs +1/−1
- Command/TransferKey.hs +5/−5
- Command/TransferKeys.hs +5/−4
- Command/Unannex.hs +34/−21
- Command/Uninit.hs +1/−1
- Command/Vicfg.hs +16/−1
- Common.hs +1/−0
- INSTALL +1/−0
- Limit.hs +22/−24
- Locations.hs +5/−0
- Logs.hs +4/−0
- Logs/PreferredContent.hs +40/−23
- Logs/PreferredContent/Raw.hs +17/−4
- Logs/Transfer.hs +0/−102
- Remote/Git.hs +3/−3
- Remote/Glacier.hs +5/−3
- Remote/Tahoe.hs +1/−1
- Types/DesktopNotify.hs +27/−0
- Types/FileMatcher.hs +21/−0
- Types/Limit.hs +0/−20
- Types/MetaData.hs +3/−1
- Utility/FileMode.hs +12/−7
- Utility/Matcher.hs +1/−1
- Utility/ThreadScheduler.hs +5/−2
- Utility/Url.hs +2/−1
- Utility/WebApp.hs +0/−1
- debian/changelog +37/−0
- debian/control +1/−0
- doc/assistant/downloadnotification.png binary
- doc/assistant/nautilusmenu.png binary
- doc/bugs/Assistant_lost_dbus_connection_spamming_log.mdwn +10/−0
- doc/bugs/Crash_when_disabling_syncing_in_the_webapp.mdwn +23/−0
- doc/bugs/Race_condition_between_watch__47__assistant_and_addurl.mdwn +195/−0
- doc/bugs/git-annex_fails_to_initialize_under_Windows.mdwn +212/−0
- doc/bugs/git_annex_test_under_windows_8.1.mdwn +67/−0
- doc/bugs/issues_with_non-posix_compatible_shells.mdwn +41/−0
- doc/bugs/problem_to_addurl_--file_with_ftp.mdwn +67/−0
- doc/bugs/problems_with_glacier.mdwn +65/−0
- doc/bugs/set_metadata_on_wrong_files.mdwn +90/−0
- doc/copies.mdwn +3/−0
- doc/design/assistant/polls/prioritizing_special_remotes.mdwn +1/−1
- doc/design/assistant/telehash.mdwn +3/−0
- doc/design/roadmap.mdwn +2/−2
- doc/devblog/day_139-140__traveling.mdwn +17/−0
- doc/devblog/day_141__f-droid_sprint.mdwn +3/−0
- doc/devblog/day_142__digging_out.mdwn +13/−0
- doc/devblog/day_143__foolish_hiatus.mdwn +20/−0
- doc/devblog/day_144__catching_up.mdwn +12/−0
- doc/forum/Generating_a_Temp_View_of_Available_Files.mdwn +1/−0
- doc/forum/faking_location_information.mdwn +19/−0
- doc/forum/ignore_changes_made_by_a_remote.mdwn +8/−0
- doc/forum/telehash_syncing.mdwn +10/−0
- doc/forum/unrelated_repositories_sync.mdwn +15/−0
- doc/forum/view_from_numeric_values.mdwn +9/−0
- doc/forum/view_including_files_with_no_tags.mdwn +5/−0
- doc/git-annex-shell.mdwn +6/−1
- doc/git-annex.mdwn +25/−7
- doc/install.mdwn +1/−0
- doc/install/ArchLinux/comment_6_1d597d6a95f9c2df7dae6e98813e4865._comment +36/−0
- doc/install/ArchLinux/comment_7_2d708977e2fad6b68803494576382df5._comment +10/−0
- doc/install/ArchLinux/comment_8_5b5f5e0b64e5bfb1ea12e8b251c6fb5f._comment +15/−0
- doc/install/Docker.mdwn +27/−0
- doc/internals.mdwn +7/−0
- doc/metadata.mdwn +4/−4
- doc/news/version_5.20140402.mdwn +34/−0
- doc/preferred_content.mdwn +4/−4
- doc/related_software.mdwn +2/−1
- doc/required_content.mdwn +17/−0
- doc/special_remotes/tahoe.mdwn +5/−1
- doc/tips/automatically_adding_metadata.mdwn +1/−1
- doc/tips/file_manager_integration.mdwn +100/−0
- doc/todo.mdwn +1/−1
- doc/todo/Bittorrent-like_features.mdwn +2/−0
- doc/todo/New_special_remote_suggeston_-_clean_directory.mdwn +8/−0
- doc/todo/Pause_all_transfers_in_all_annexes_watched_by_the_assistant.mdwn +11/−0
- doc/todo/Views_Demo.mdwn +2/−0
- doc/todo/clear_file_names_in_special_remotes.mdwn +13/−0
- doc/todo/required_content.mdwn +16/−0
- doc/todo/tahoe_lfs_for_reals.mdwn +4/−2
- doc/todo/using_file_metadata_for_preferred___40__wanted__41___content.mdwn +12/−0
- git-annex-shell.1 +6/−1
- git-annex.1 +23/−7
- git-annex.cabal +15/−7
- standalone/android/haskell-patches/unbounded-delays_crossbuild.patch +25/−0
- standalone/android/install-haskell-packages +1/−0
Annex.hs view
@@ -10,7 +10,6 @@ module Annex ( Annex, AnnexState(..),- PreferredContentMap, new, run, eval,@@ -60,8 +59,8 @@ import Types.NumCopies import Types.LockPool import Types.MetaData+import Types.DesktopNotify import Types.CleanupActions-import qualified Utility.Matcher import qualified Data.Map as M import qualified Data.Set as S import Utility.Quvi (QuviVersion)@@ -80,9 +79,6 @@ Applicative ) -type Matcher a = Either [Utility.Matcher.Token a] (Utility.Matcher.Matcher a)-type PreferredContentMap = M.Map UUID (Utility.Matcher.Matcher (S.Set UUID -> MatchInfo -> Annex Bool))- -- internal state storage data AnnexState = AnnexState { repo :: Git.Repo@@ -103,9 +99,10 @@ , forcebackend :: Maybe String , globalnumcopies :: Maybe NumCopies , forcenumcopies :: Maybe NumCopies- , limit :: Matcher (MatchInfo -> Annex Bool)+ , limit :: ExpandableMatcher Annex , uuidmap :: Maybe UUIDMap- , preferredcontentmap :: Maybe PreferredContentMap+ , preferredcontentmap :: Maybe (FileMatcherMap Annex)+ , requiredcontentmap :: Maybe (FileMatcherMap Annex) , shared :: Maybe SharedRepository , forcetrust :: TrustMap , trustmap :: Maybe TrustMap@@ -122,6 +119,7 @@ , unusedkeys :: Maybe (S.Set Key) , quviversion :: Maybe QuviVersion , existinghooks :: M.Map Git.Hook.Hook Bool+ , desktopnotify :: DesktopNotify } newState :: GitConfig -> Git.Repo -> AnnexState@@ -144,9 +142,10 @@ , forcebackend = Nothing , globalnumcopies = Nothing , forcenumcopies = Nothing- , limit = Left []+ , limit = BuildingMatcher [] , uuidmap = Nothing , preferredcontentmap = Nothing+ , requiredcontentmap = Nothing , shared = Nothing , forcetrust = M.empty , trustmap = Nothing@@ -163,6 +162,7 @@ , unusedkeys = Nothing , quviversion = Nothing , existinghooks = M.empty+ , desktopnotify = mempty } {- Makes an Annex state object for the specified git repo.
Annex/Branch/Transitions.hs view
@@ -32,8 +32,12 @@ dropDead :: FilePath -> String -> TrustMap -> FileTransition dropDead f content trustmap = case getLogVariety f of- Just UUIDBasedLog -> ChangeFile $- UUIDBased.showLog id $ dropDeadFromUUIDBasedLog trustmap $ UUIDBased.parseLog Just content+ Just UUIDBasedLog+ -- Don't remove the dead repo from the trust log,+ -- because git remotes may still exist, and they need+ -- to still know it's dead.+ | f == trustLog -> PreserveFile+ | otherwise -> ChangeFile $ UUIDBased.showLog id $ dropDeadFromUUIDBasedLog trustmap $ UUIDBased.parseLog Just content Just NewUUIDBasedLog -> ChangeFile $ UUIDBased.showLogNew id $ dropDeadFromUUIDBasedLog trustmap $ UUIDBased.parseLogNew Just content Just (PresenceLog _) ->
Annex/FileMatcher.hs view
@@ -13,7 +13,6 @@ import Limit import Utility.Matcher import Types.Group-import Types.Limit import Logs.Group import Logs.Remote import Annex.UUID@@ -25,12 +24,10 @@ import Data.Either import qualified Data.Set as S -type FileMatcher = Matcher MatchFiles--checkFileMatcher :: FileMatcher -> FilePath -> Annex Bool+checkFileMatcher :: (FileMatcher Annex) -> FilePath -> Annex Bool checkFileMatcher matcher file = checkMatcher matcher Nothing (Just file) S.empty True -checkMatcher :: FileMatcher -> Maybe Key -> AssociatedFile -> AssumeNotPresent -> Bool -> Annex Bool+checkMatcher :: (FileMatcher Annex) -> Maybe Key -> AssociatedFile -> AssumeNotPresent -> Bool -> Annex Bool checkMatcher matcher mkey afile notpresent def | isEmpty matcher = return def | otherwise = case (mkey, afile) of@@ -48,15 +45,15 @@ , relFile = file } -matchAll :: FileMatcher+matchAll :: FileMatcher Annex matchAll = generate [] -parsedToMatcher :: [Either String (Token MatchFiles)] -> Either String FileMatcher+parsedToMatcher :: [Either String (Token (MatchFiles Annex))] -> Either String (FileMatcher Annex) parsedToMatcher parsed = case partitionEithers parsed of ([], vs) -> Right $ generate vs (es, _) -> Left $ unwords $ map ("Parse failure: " ++) es -exprParser :: FileMatcher -> FileMatcher -> GroupMap -> M.Map UUID RemoteConfig -> Maybe UUID -> String -> [Either String (Token MatchFiles)]+exprParser :: FileMatcher Annex -> FileMatcher Annex -> GroupMap -> M.Map UUID RemoteConfig -> Maybe UUID -> String -> [Either String (Token (MatchFiles Annex))] exprParser matchstandard matchgroupwanted groupmap configmap mu expr = map parse $ tokenizeMatcher expr where@@ -69,7 +66,7 @@ preferreddir = fromMaybe "public" $ M.lookup "preferreddir" =<< (`M.lookup` configmap) =<< mu -parseToken :: FileMatcher -> FileMatcher -> MkLimit -> MkLimit -> GroupMap -> String -> Either String (Token MatchFiles)+parseToken :: FileMatcher Annex -> FileMatcher Annex -> MkLimit Annex -> MkLimit Annex -> GroupMap -> String -> Either String (Token (MatchFiles Annex)) parseToken matchstandard matchgroupwanted checkpresent checkpreferreddir groupmap t | t `elem` tokens = Right $ token t | t == "standard" = call matchstandard@@ -106,7 +103,7 @@ {- Generates a matcher for files large enough (or meeting other criteria) - to be added to the annex, rather than directly to git. -}-largeFilesMatcher :: Annex FileMatcher+largeFilesMatcher :: Annex (FileMatcher Annex) largeFilesMatcher = go =<< annexLargeFiles <$> Annex.getGitConfig where go Nothing = return matchAll
+ Annex/Notification.hs view
@@ -0,0 +1,81 @@+{- git-annex desktop notifications+ -+ - Copyright 2014 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE CPP #-}++module Annex.Notification where++import Common.Annex+import Logs.Transfer+#ifdef WITH_DBUS_NOTIFICATIONS+import qualified Annex+import Types.DesktopNotify+import qualified DBus.Notify as Notify+import qualified DBus.Client+#endif++-- Witness that notification has happened.+data NotifyWitness = NotifyWitness++{- Wrap around an action that performs a transfer, which may run multiple+ - attempts. Displays notification when supported and when the user asked+ - for it. -}+notifyTransfer :: Direction -> Maybe FilePath -> (NotifyWitness -> Annex Bool) -> Annex Bool+notifyTransfer _ Nothing a = a NotifyWitness+#ifdef WITH_DBUS_NOTIFICATIONS+notifyTransfer direction (Just f) a = do+ wanted <- Annex.getState Annex.desktopnotify+ let action = if direction == Upload then "uploading" else "downloading"+ let basedesc = action ++ " " ++ f+ let startdesc = "started " ++ basedesc+ let enddesc ok = if ok+ then "finished " ++ basedesc+ else basedesc ++ " failed"+ if (notifyStart wanted || notifyFinish wanted)+ then do+ client <- liftIO DBus.Client.connectSession+ startnotification <- liftIO $ if notifyStart wanted+ then Just <$> Notify.notify client (mkNote startdesc)+ else pure Nothing+ ok <- a NotifyWitness+ when (notifyFinish wanted) $ liftIO $ void $ maybe + (Notify.notify client $ mkNote $ enddesc ok)+ (\n -> Notify.replace client n $ mkNote $ enddesc ok)+ startnotification+ return ok+ else a NotifyWitness+#else+notifyTransfer _ (Just _) a = do a NotifyWitness+#endif++notifyDrop :: Maybe FilePath -> Bool -> Annex ()+notifyDrop Nothing _ = noop+#ifdef WITH_DBUS_NOTIFICATIONS+notifyDrop (Just f) ok = do+ wanted <- Annex.getState Annex.desktopnotify+ when (notifyFinish wanted) $ liftIO $ do+ client <- DBus.Client.connectSession+ let msg = if ok+ then "dropped " ++ f+ else "failed to drop" ++ f+ void $ Notify.notify client (mkNote msg)+#else+notifyDrop (Just _) _ = noop+#endif++#ifdef WITH_DBUS_NOTIFICATIONS+mkNote :: String -> Notify.Note+mkNote desc = Notify.blankNote+ { Notify.appName = "git-annex"+ , Notify.body = Just $ Notify.Text desc+ , Notify.hints =+ [ Notify.Category Notify.Transfer+ , Notify.Urgency Notify.Low+ , Notify.SuppressSound True+ ]+ }+#endif
+ Annex/Transfer.hs view
@@ -0,0 +1,131 @@+{- git-annex transfers+ -+ - Copyright 2012-2014 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE CPP #-}++module Annex.Transfer (+ module X,+ upload,+ download,+ runTransfer,+ noRetry,+ forwardRetry,+) where++import Common.Annex+import Logs.Transfer as X+import Annex.Notification as X+import Annex.Perms+import Annex.Exception+import Utility.Metered+#ifdef mingw32_HOST_OS+import Utility.WinLock+#endif++import Control.Concurrent++upload :: UUID -> Key -> AssociatedFile -> RetryDecider -> (MeterUpdate -> Annex Bool) -> NotifyWitness -> Annex Bool+upload u key f d a _witness = runTransfer (Transfer Upload u key) f d a++download :: UUID -> Key -> AssociatedFile -> RetryDecider -> (MeterUpdate -> Annex Bool) -> NotifyWitness -> Annex Bool+download u key f d a _witness = runTransfer (Transfer Download u key) f d a++{- Runs a transfer action. Creates and locks the lock file while the+ - action is running, and stores info in the transfer information+ - file.+ -+ - If the transfer action returns False, the transfer info is + - left in the failedTransferDir.+ -+ - If the transfer is already in progress, returns False.+ -+ - An upload can be run from a read-only filesystem, and in this case+ - no transfer information or lock file is used.+ -}+runTransfer :: Transfer -> Maybe FilePath -> RetryDecider -> (MeterUpdate -> Annex Bool) -> Annex Bool+runTransfer t file shouldretry a = do+ info <- liftIO $ startTransferInfo file+ (meter, tfile, metervar) <- mkProgressUpdater t info+ mode <- annexFileMode+ (fd, inprogress) <- liftIO $ prep tfile mode info+ if inprogress+ then do+ showNote "transfer already in progress"+ return False+ else do+ ok <- retry info metervar $+ bracketIO (return fd) (cleanup tfile) (const $ a meter)+ unless ok $ recordFailedTransfer t info+ return ok+ where+#ifndef mingw32_HOST_OS+ prep tfile mode info = do+ mfd <- catchMaybeIO $+ openFd (transferLockFile tfile) ReadWrite (Just mode)+ defaultFileFlags { trunc = True }+ case mfd of+ Nothing -> return (Nothing, False)+ Just fd -> do+ locked <- catchMaybeIO $+ setLock fd (WriteLock, AbsoluteSeek, 0, 0)+ if isNothing locked+ then return (Nothing, True)+ else do+ void $ tryIO $ writeTransferInfoFile info tfile+ return (mfd, False)+#else+ prep tfile _mode info = do+ v <- catchMaybeIO $ lockExclusive (transferLockFile tfile)+ case v of+ Nothing -> return (Nothing, False)+ Just Nothing -> return (Nothing, True)+ Just (Just lockhandle) -> do+ void $ tryIO $ writeTransferInfoFile info tfile+ return (Just lockhandle, False)+#endif+ cleanup _ Nothing = noop+ cleanup tfile (Just lockhandle) = do+ void $ tryIO $ removeFile tfile+#ifndef mingw32_HOST_OS+ void $ tryIO $ removeFile $ transferLockFile tfile+ closeFd lockhandle+#else+ {- Windows cannot delete the lockfile until the lock+ - is closed. So it's possible to race with another+ - process that takes the lock before it's removed,+ - so ignore failure to remove.+ -}+ dropLock lockhandle+ void $ tryIO $ removeFile $ transferLockFile tfile+#endif+ retry oldinfo metervar run = do+ v <- tryAnnex run+ case v of+ Right b -> return b+ Left _ -> do+ b <- getbytescomplete metervar+ let newinfo = oldinfo { bytesComplete = Just b }+ if shouldretry oldinfo newinfo+ then retry newinfo metervar run+ else return False+ getbytescomplete metervar+ | transferDirection t == Upload =+ liftIO $ readMVar metervar+ | otherwise = do+ f <- fromRepo $ gitAnnexTmpObjectLocation (transferKey t)+ liftIO $ catchDefaultIO 0 $+ fromIntegral . fileSize <$> getFileStatus f++type RetryDecider = TransferInfo -> TransferInfo -> Bool++noRetry :: RetryDecider+noRetry _ _ = False++{- Retries a transfer when it fails, as long as the failed transfer managed+ - to send some data. -}+forwardRetry :: RetryDecider+forwardRetry old new = bytesComplete old < bytesComplete new
Assistant/Alert/Utility.hs view
@@ -14,7 +14,6 @@ import qualified Data.Text as T import Data.Text (Text) import qualified Data.Map as M-import Data.Monoid {- This is as many alerts as it makes sense to display at a time. - A display might be smaller, or larger, the point is to not overwhelm the
Assistant/Install.hs view
@@ -35,11 +35,14 @@ - - Note that this is done every time it's started, so if the user moves - it around, the paths this sets up won't break.+ -+ - Nautilus hook script installation is done even for packaged apps,+ - since it has to go into the user's home directory. -} ensureInstalled :: IO () ensureInstalled = go =<< standaloneAppBase where- go Nothing = noop+ go Nothing = installNautilus "git-annex" go (Just base) = do let program = base </> "git-annex" programfile <- programFile@@ -77,6 +80,32 @@ createDirectoryIfMissing True (parentDir shim) viaTmp writeFile shim content modifyFileMode shim $ addModes [ownerExecuteMode]++ installNautilus program++installNautilus :: FilePath -> IO ()+#ifdef linux_HOST_OS+installNautilus program = do+ scriptdir <- (\d -> d </> "nautilus" </> "scripts") <$> userDataDir+ genscript scriptdir "get"+ genscript scriptdir "drop"+ where+ genscript scriptdir action =+ installscript (scriptdir </> scriptname action) $ unlines+ [ shebang_local+ , autoaddedcomment+ , "exec " ++ program ++ " " ++ action ++ " --notify-start --notify-finish -- \"$@\""+ ]+ scriptname action = "git-annex " ++ action+ installscript f c = whenM (safetoinstallscript f) $ do+ writeFile f c+ modifyFileMode f $ addModes [ownerExecuteMode]+ safetoinstallscript f = catchDefaultIO True $+ elem autoaddedcomment . lines <$> readFileStrict f+ autoaddedcomment = "# Automatically added by git-annex, do not edit. (To disable, chmod 600 this file.)"+#else+installNautilus _ = noop+#endif {- Returns a cleaned up environment that lacks settings used to make the - standalone builds use their bundled libraries and programs.
Assistant/Ssh.hs view
@@ -197,7 +197,7 @@ - long perl script. -} | otherwise = pubkey where- limitcommand = "command=\"GIT_ANNEX_SHELL_DIRECTORY="++shellEscape dir++" ~/.ssh/git-annex-shell\",no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty "+ limitcommand = "command=\"env GIT_ANNEX_SHELL_DIRECTORY="++shellEscape dir++" ~/.ssh/git-annex-shell\",no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty " {- Generates a ssh key pair. -} genSshKeyPair :: IO SshKeyPair
Assistant/Threads/ConfigMonitor.hs view
@@ -62,15 +62,17 @@ , (groupLog, void $ liftAnnex groupMapLoad) , (numcopiesLog, void $ liftAnnex globalNumCopiesLoad) , (scheduleLog, void updateScheduleLog)- -- Preferred content settings depend on most of the other configs,- -- so will be reloaded whenever any configs change.+ -- Preferred and required content settings depend on most of the+ -- other configs, so will be reloaded whenever any configs change. , (preferredContentLog, noop)+ , (requiredContentLog, noop)+ , (groupPreferredContentLog, noop) ] reloadConfigs :: Configs -> Assistant () reloadConfigs changedconfigs = do sequence_ as- void $ liftAnnex preferredContentMapLoad+ void $ liftAnnex preferredRequiredMapsLoad {- Changes to the remote log, or the trust log, can affect the - syncRemotes list. Changes to the uuid log may affect its - display so are also included. -}
Assistant/Threads/Watcher.hs view
@@ -35,6 +35,7 @@ import Annex.CheckIgnore import Annex.Link import Annex.FileMatcher+import Types.FileMatcher import Annex.ReplaceFile import Git.Types import Config@@ -196,7 +197,7 @@ | otherwise = f {- Small files are added to git as-is, while large ones go into the annex. -}-add :: FileMatcher -> FilePath -> Assistant (Maybe Change)+add :: FileMatcher Annex -> FilePath -> Assistant (Maybe Change) add bigfilematcher file = ifM (liftAnnex $ checkFileMatcher bigfilematcher file) ( pendingAddChange file , do@@ -205,7 +206,7 @@ madeChange file AddFileChange ) -onAdd :: FileMatcher -> Handler+onAdd :: FileMatcher Annex -> Handler onAdd matcher file filestatus | maybe False isRegularFile filestatus = unlessIgnored file $@@ -218,7 +219,7 @@ {- In direct mode, add events are received for both new files, and - modified existing files. -}-onAddDirect :: Bool -> FileMatcher -> Handler+onAddDirect :: Bool -> FileMatcher Annex -> Handler onAddDirect symlinkssupported matcher file fs = do v <- liftAnnex $ catKeyFile file case (v, fs) of
BuildFlags.hs view
@@ -57,6 +57,9 @@ #ifdef WITH_DBUS , "DBus" #endif+#ifdef WITH_DESKTOP_NOTIFY+ , "DesktopNotify"+#endif #ifdef WITH_XMPP , "XMPP" #else
CHANGELOG view
@@ -1,3 +1,40 @@+git-annex (5.20140402) unstable; urgency=medium++ * unannex, uninit: Avoid committing after every file is unannexed,+ for massive speedup.+ * --notify-finish switch will cause desktop notifications after each + file upload/download/drop completes+ (using the dbus Desktop Notifications Specification)+ * --notify-start switch will show desktop notifications when each+ file upload/download starts.+ * webapp: Automatically install Nautilus integration scripts+ to get and drop files.+ * tahoe: Pass -d parameter before subcommand; putting it after+ the subcommand no longer works with tahoe-lafs version 1.10.+ (Thanks, Alberto Berti)+ * forget --drop-dead: Avoid removing the dead remote from the trust.log,+ so that if git remotes for it still exist anywhere, git annex info+ will still know it's dead and not show it.+ * git-annex-shell: Make configlist automatically initialize+ a remote git repository, as long as a git-annex branch has+ been pushed to it, to simplify setup of remote git repositories,+ including via gitolite.+ * add --include-dotfiles: New option, perhaps useful for backups.+ * Version 5.20140227 broke creation of glacier repositories,+ not including the datacenter and vault in their configuration.+ This bug is fixed, but glacier repositories set up with the broken+ version of git-annex need to have the datacenter and vault set+ in order to be usable. This can be done using git annex enableremote+ to add the missing settings. For details, see+ http://git-annex.branchable.com/bugs/problems_with_glacier/+ * Added required content configuration.+ * assistant: Improve ssh authorized keys line generated in local pairing+ or for a remote ssh server to set environment variables in an + alternative way that works with the non-POSIX fish shell, as well+ as POSIX shells.++ -- Joey Hess <joeyh@debian.org> Wed, 02 Apr 2014 16:42:53 -0400+ git-annex (5.20140320) unstable; urgency=medium * Fix zombie leak and general inneficiency when copying files to a
CmdLine/Option.hs view
@@ -20,6 +20,7 @@ import Common.Annex import qualified Annex import Types.Messages+import Types.DesktopNotify import Limit import CmdLine.Usage @@ -41,6 +42,10 @@ "don't show debug messages" , Option ['b'] ["backend"] (ReqArg setforcebackend paramName) "specify key-value backend to use"+ , Option [] ["notify-finish"] (NoArg (setdesktopnotify mkNotifyFinish))+ "show desktop notification after transfer finishes"+ , Option [] ["notify-start"] (NoArg (setdesktopnotify mkNotifyStart))+ "show desktop notification after transfer completes" ] where setforce v = Annex.changeState $ \s -> s { Annex.force = v }@@ -49,6 +54,7 @@ setforcebackend v = Annex.changeState $ \s -> s { Annex.forcebackend = Just v } setdebug = Annex.changeGitConfig $ \c -> c { annexDebug = True } unsetdebug = Annex.changeGitConfig $ \c -> c { annexDebug = False }+ setdesktopnotify v = Annex.changeState $ \s -> s { Annex.desktopnotify = Annex.desktopnotify s <> v } matcherOptions :: [Option] matcherOptions =
CmdLine/Seek.hs view
@@ -30,14 +30,15 @@ withFilesInGit a params = seekActions $ prepFiltered a $ seekHelper LsFiles.inRepo params -withFilesNotInGit :: (FilePath -> CommandStart) -> CommandSeek-withFilesNotInGit a params = do- {- dotfiles are not acted on unless explicitly listed -}- files <- filter (not . dotfile) <$>- seekunless (null ps && not (null params)) ps- dotfiles <- seekunless (null dotps) dotps- seekActions $ prepFiltered a $- return $ concat $ segmentPaths params (files++dotfiles)+withFilesNotInGit :: Bool -> (FilePath -> CommandStart) -> CommandSeek+withFilesNotInGit skipdotfiles a params+ | skipdotfiles = do+ {- dotfiles are not acted on unless explicitly listed -}+ files <- filter (not . dotfile) <$>+ seekunless (null ps && not (null params)) ps+ dotfiles <- seekunless (null dotps) dotps+ go (files++dotfiles)+ | otherwise = go =<< seekunless False params where (dotps, ps) = partition dotfile params seekunless True _ = return []@@ -45,6 +46,8 @@ force <- Annex.getState Annex.force g <- gitRepo liftIO $ Git.Command.leaveZombie <$> LsFiles.notInRepo force l g+ go l = seekActions $ prepFiltered a $+ return $ concat $ segmentPaths params l withPathContents :: ((FilePath, FilePath) -> CommandStart) -> CommandSeek withPathContents a params = seekActions $
Command/Add.hs view
@@ -34,9 +34,13 @@ import Utility.Tmp def :: [Command]-def = [notBareRepo $ command "add" paramPaths seek SectionCommon- "add files to annex"]+def = [notBareRepo $ withOptions [includeDotFilesOption] $+ command "add" paramPaths seek SectionCommon+ "add files to annex"] +includeDotFilesOption :: Option+includeDotFilesOption = flagOption [] "include-dotfiles" "don't skip dotfiles"+ {- Add acts on both files not checked into git yet, and unlocked files. - - In direct mode, it acts on any files that have changed. -}@@ -47,7 +51,8 @@ ( start file , stop )- go withFilesNotInGit+ skipdotfiles <- not <$> Annex.getFlag (optionName includeDotFilesOption)+ go $ withFilesNotInGit skipdotfiles ifM isDirect ( go withFilesMaybeModified , go withFilesUnlocked
Command/AddUrl.hs view
@@ -26,7 +26,7 @@ import Config import Annex.Content.Direct import Logs.Location-import qualified Logs.Transfer as Transfer+import qualified Annex.Transfer as Transfer #ifdef WITH_QUVI import Annex.Quvi import qualified Utility.Quvi as Quvi@@ -116,9 +116,10 @@ prepGetViaTmpChecked sizedkey $ do tmp <- fromRepo $ gitAnnexTmpObjectLocation key showOutput- ok <- Transfer.download webUUID key (Just file) Transfer.forwardRetry $ const $ do- liftIO $ createDirectoryIfMissing True (parentDir tmp)- downloadUrl [videourl] tmp+ ok <- Transfer.notifyTransfer Transfer.Download (Just file) $+ Transfer.download webUUID key (Just file) Transfer.forwardRetry $ const $ do+ liftIO $ createDirectoryIfMissing True (parentDir tmp)+ downloadUrl [videourl] tmp if ok then cleanup quviurl file key (Just tmp) else return False@@ -133,17 +134,20 @@ | relaxed = do setUrlPresent key url next $ return True- | otherwise = do- (exists, samesize) <- Url.withUrlOptions $ Url.check url (keySize key)- if exists && samesize- then do- setUrlPresent key url- next $ return True- else do- warning $ if exists- then "url does not have expected file size (use --relaxed to bypass this check) " ++ url- else "failed to verify url exists: " ++ url- stop+ | otherwise = ifM (elem url <$> getUrls key)+ ( stop+ , do+ (exists, samesize) <- Url.withUrlOptions $ Url.check url (keySize key)+ if exists && samesize+ then do+ setUrlPresent key url+ next $ return True+ else do+ warning $ "while adding a new url to an already annexed file, " ++ if exists+ then "url does not have expected file size (use --relaxed to bypass this check) " ++ url+ else "failed to verify url exists: " ++ url+ stop+ ) addUrlFile :: Bool -> URLString -> FilePath -> Annex Bool addUrlFile relaxed url file = do@@ -179,7 +183,7 @@ , return False ) where- runtransfer dummykey tmp = + runtransfer dummykey tmp = Transfer.notifyTransfer Transfer.Download (Just file) $ Transfer.download webUUID dummykey (Just file) Transfer.forwardRetry $ const $ do liftIO $ createDirectoryIfMissing True (parentDir tmp) downloadUrl [url] tmp
Command/ConfigList.hs view
@@ -1,6 +1,6 @@ {- git-annex command -- - Copyright 2010 Joey Hess <joey@kitenet.net>+ - Copyright 2010-2014 Joey Hess <joey@kitenet.net> - - Licensed under the GNU GPL version 3 or higher. -}@@ -10,6 +10,8 @@ import Common.Annex import Command import Annex.UUID+import Annex.Init+import qualified Annex.Branch import qualified Git.Config import Remote.GCrypt (coreGCryptId) @@ -22,9 +24,23 @@ start :: CommandStart start = do- u <- getUUID+ u <- findOrGenUUID showConfig "annex.uuid" $ fromUUID u showConfig coreGCryptId =<< fromRepo (Git.Config.get coreGCryptId "") stop where showConfig k v = liftIO $ putStrLn $ k ++ "=" ++ v++{- The repository may not yet have a UUID; automatically initialize it+ - when there's a git-annex branch available. -}+findOrGenUUID :: Annex UUID+findOrGenUUID = do+ u <- getUUID+ if u /= NoUUID+ then return u+ else ifM Annex.Branch.hasSibling+ ( do+ initialize Nothing+ getUUID+ , return NoUUID+ )
Command/Drop.hs view
@@ -14,10 +14,14 @@ import Annex.UUID import Logs.Location import Logs.Trust+import Logs.PreferredContent import Config.NumCopies import Annex.Content import Annex.Wanted+import Annex.Notification +import qualified Data.Set as S+ def :: [Command] def = [withOptions [dropFromOption] $ command "drop" paramPaths seek SectionCommon "indicate content of files not currently wanted"]@@ -44,27 +48,34 @@ startLocal :: AssociatedFile -> NumCopies -> Key -> Maybe Remote -> CommandStart startLocal afile numcopies key knownpresentremote = stopUnless (inAnnex key) $ do showStart' "drop" key afile- next $ performLocal key numcopies knownpresentremote+ next $ performLocal key afile numcopies knownpresentremote startRemote :: AssociatedFile -> NumCopies -> Key -> Remote -> CommandStart startRemote afile numcopies key remote = do showStart' ("drop " ++ Remote.name remote) key afile- next $ performRemote key numcopies remote+ next $ performRemote key afile numcopies remote -performLocal :: Key -> NumCopies -> Maybe Remote -> CommandPerform-performLocal key numcopies knownpresentremote = lockContent key $ do+performLocal :: Key -> AssociatedFile -> NumCopies -> Maybe Remote -> CommandPerform+performLocal key afile numcopies knownpresentremote = lockContent key $ do (remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key let trusteduuids' = case knownpresentremote of Nothing -> trusteduuids Just r -> nub (Remote.uuid r:trusteduuids) untrusteduuids <- trustGet UnTrusted let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids'++untrusteduuids)- stopUnless (canDropKey key numcopies trusteduuids' tocheck []) $ do- removeAnnex key- next $ cleanupLocal key+ u <- getUUID+ ifM (canDrop u key afile numcopies trusteduuids' tocheck [])+ ( do+ removeAnnex key+ notifyDrop afile True+ next $ cleanupLocal key+ , do+ notifyDrop afile False+ stop+ ) -performRemote :: Key -> NumCopies -> Remote -> CommandPerform-performRemote key numcopies remote = lockContent key $ do+performRemote :: Key -> AssociatedFile -> NumCopies -> Remote -> CommandPerform+performRemote key afile numcopies remote = lockContent key $ do -- 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.@@ -76,7 +87,7 @@ untrusteduuids <- trustGet UnTrusted let tocheck = filter (/= remote) $ Remote.remotesWithoutUUID remotes (have++untrusteduuids)- stopUnless (canDropKey key numcopies have tocheck [uuid]) $ do+ stopUnless (canDrop uuid key afile numcopies have tocheck [uuid]) $ do ok <- Remote.removeKey remote key next $ cleanupRemote key remote ok where@@ -95,13 +106,19 @@ {- Checks specified remotes to verify that enough copies of a key exist to - allow it to be safely removed (with no data loss). Can be provided with- - some locations where the key is known/assumed to be present. -}-canDropKey :: Key -> NumCopies -> [UUID] -> [Remote] -> [UUID] -> Annex Bool-canDropKey key numcopies have check skip = do- force <- Annex.getState Annex.force- if force || numcopies == NumCopies 0- then return True- else findCopies key numcopies skip have check+ - some locations where the key is known/assumed to be present.+ -+ - Also checks if it's required content, and refuses to drop if so.+ -+ - --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 [] []@@ -136,6 +153,19 @@ where unsafe = showNote "unsafe" hint = showLongNote "(Use --force to override this check, or adjust numcopies.)"++checkRequiredContent :: UUID -> Key -> AssociatedFile -> Annex Bool+checkRequiredContent u k afile =+ ifM (isRequiredContent (Just u) S.empty (Just k) afile False)+ ( requiredContent+ , return True+ )++requiredContent :: Annex Bool+requiredContent = do+ showLongNote "That file is required content, it cannot be dropped!"+ showLongNote "(Use --force to override this check, or adjust required content configuration.)"+ return False {- In auto mode, only runs the action if there are enough - copies on other semitrusted repositories. -}
Command/DropUnused.hs view
@@ -34,8 +34,8 @@ where dropremote r = do showAction $ "from " ++ Remote.name r- Command.Drop.performRemote key numcopies r- droplocal = Command.Drop.performLocal key numcopies Nothing+ Command.Drop.performRemote key Nothing numcopies r+ droplocal = Command.Drop.performLocal key Nothing numcopies Nothing from = Annex.getField $ optionName Command.Drop.dropFromOption performOther :: (Key -> Git.Repo -> FilePath) -> Key -> CommandPerform
Command/Get.hs view
@@ -11,7 +11,7 @@ import Command import qualified Remote import Annex.Content-import Logs.Transfer+import Annex.Transfer import Config.NumCopies import Annex.Wanted import qualified Command.Move@@ -69,15 +69,15 @@ showNote "not available" showlocs return False- dispatch remotes = trycopy remotes remotes- trycopy full [] = do+ dispatch remotes = notifyTransfer Download afile $ trycopy remotes remotes+ trycopy full [] _ = do Remote.showTriedRemotes full showlocs return False- trycopy full (r:rs) =+ trycopy full (r:rs) witness = ifM (probablyPresent r)- ( docopy r (trycopy full rs)- , trycopy full rs+ ( docopy r witness <||> trycopy full rs witness+ , trycopy full rs witness ) showlocs = Remote.showLocations key [] "No other repository is known to contain the file."@@ -87,8 +87,6 @@ | Remote.hasKeyCheap r = either (const False) id <$> Remote.hasKey r key | otherwise = return True- docopy r continue = do- ok <- download (Remote.uuid r) key afile noRetry $ \p -> do- showAction $ "from " ++ Remote.name r- Remote.retrieveKeyFile r key afile dest p- if ok then return ok else continue+ docopy r = download (Remote.uuid r) key afile noRetry $ \p -> do+ showAction $ "from " ++ Remote.name r+ Remote.retrieveKeyFile r key afile dest p
Command/List.hs view
@@ -38,7 +38,7 @@ getList :: Annex [(UUID, RemoteName, TrustLevel)] getList = ifM (Annex.getFlag $ optionName allrepos)- ( nubBy ((==) `on` fst3) <$> ((++) <$> getRemotes <*> getAll)+ ( nubBy ((==) `on` fst3) <$> ((++) <$> getRemotes <*> getAllUUIDs) , getRemotes ) where@@ -48,7 +48,7 @@ hereu <- getUUID heretrust <- lookupTrust hereu return $ (hereu, "here", heretrust) : zip3 (map uuid rs) (map name rs) ts- getAll = do+ getAllUUIDs = do rs <- M.toList <$> uuidMap rs3 <- forM rs $ \(u, n) -> (,,) <$> pure u
Command/Move.hs view
@@ -14,8 +14,8 @@ import Annex.Content import qualified Remote import Annex.UUID+import Annex.Transfer import Logs.Presence-import Logs.Transfer def :: [Command] def = [withOptions moveOptions $ command "move" paramPaths seek@@ -98,8 +98,9 @@ stop Right False -> do showAction $ "to " ++ Remote.name dest- ok <- upload (Remote.uuid dest) key afile noRetry $- Remote.storeKey dest key afile+ ok <- notifyTransfer Upload afile $+ upload (Remote.uuid dest) key afile noRetry $+ Remote.storeKey dest key afile if ok then do Remote.logStatus dest key InfoPresent@@ -155,9 +156,10 @@ , handle move =<< go ) where- go = download (Remote.uuid src) key afile noRetry $ \p -> do- showAction $ "from " ++ Remote.name src- getViaTmp key $ \t -> Remote.retrieveKeyFile src key afile t p+ go = notifyTransfer Download afile $ + download (Remote.uuid src) key afile noRetry $ \p -> do+ showAction $ "from " ++ Remote.name src+ getViaTmp key $ \t -> Remote.retrieveKeyFile src key afile t p handle _ False = stop -- failed handle False True = next $ return True -- copy complete handle True True = do -- finish moving
Command/PreCommit.hs view
@@ -5,6 +5,8 @@ - Licensed under the GNU GPL version 3 or higher. -} +{-# LANGUAGE CPP #-}+ module Command.PreCommit where import Common.Annex@@ -16,11 +18,17 @@ import Annex.Hook import Annex.View import Annex.View.ViewedFile+import Annex.Perms+import Annex.Exception import Logs.View import Logs.MetaData import Types.View import Types.MetaData +#ifdef mingw32_HOST_OS+import Utility.WinLock+#endif+ import qualified Data.Set as S def :: [Command]@@ -28,7 +36,7 @@ "run by git pre-commit hook"] seek :: CommandSeek-seek ps = ifM isDirect+seek ps = lockPreCommitHook $ ifM isDirect ( do -- update direct mode mappings for committed files withWords startDirect ps@@ -82,3 +90,22 @@ showset v | isSet v = "+" | otherwise = "-"++{- Takes exclusive lock; blocks until available. -}+lockPreCommitHook :: Annex a -> Annex a+lockPreCommitHook a = do+ lockfile <- fromRepo gitAnnexPreCommitLock+ createAnnexDirectory $ takeDirectory lockfile+ mode <- annexFileMode+ bracketIO (lock lockfile mode) unlock (const a)+ where+#ifndef mingw32_HOST_OS+ lock lockfile mode = do+ l <- liftIO $ noUmask mode $ createFile lockfile mode+ liftIO $ waitToSetLock l (WriteLock, AbsoluteSeek, 0, 0)+ return l+ unlock = closeFd+#else+ lock lockfile _mode = liftIO $ waitToLock $ lockExclusive lockfile+ unlock = dropLock+#endif
Command/SendKey.hs view
@@ -12,7 +12,7 @@ import Annex.Content import Annex import Utility.Rsync-import Logs.Transfer+import Annex.Transfer import qualified CmdLine.GitAnnexShell.Fields as Fields import Utility.Metered
Command/TransferKey.hs view
@@ -11,7 +11,7 @@ import Command import Annex.Content import Logs.Location-import Logs.Transfer+import Annex.Transfer import qualified Remote import Types.Remote @@ -41,7 +41,7 @@ _ -> error "specify either --from or --to" toPerform :: Remote -> Key -> AssociatedFile -> CommandPerform-toPerform remote key file = go $+toPerform remote key file = go Upload file $ upload (uuid remote) key file forwardRetry $ \p -> do ok <- Remote.storeKey remote key file p when ok $@@ -49,9 +49,9 @@ return ok fromPerform :: Remote -> Key -> AssociatedFile -> CommandPerform-fromPerform remote key file = go $+fromPerform remote key file = go Upload file $ download (uuid remote) key file forwardRetry $ \p -> getViaTmp key $ \t -> Remote.retrieveKeyFile remote key file t p -go :: Annex Bool -> CommandPerform-go a = a >>= liftIO . exitBool+go :: Direction -> AssociatedFile -> (NotifyWitness -> Annex Bool) -> CommandPerform+go direction file a = notifyTransfer direction file a >>= liftIO . exitBool
Command/TransferKeys.hs view
@@ -13,7 +13,7 @@ import Command import Annex.Content import Logs.Location-import Logs.Transfer+import Annex.Transfer import qualified Remote import Types.Key @@ -34,14 +34,15 @@ stop where runner (TransferRequest direction remote key file)- | direction == Upload = + | direction == Upload = notifyTransfer direction file $ upload (Remote.uuid remote) key file forwardRetry $ \p -> do ok <- Remote.storeKey remote key file p when ok $ Remote.logStatus remote key InfoPresent return ok- | otherwise = download (Remote.uuid remote) key file forwardRetry $ \p ->- getViaTmp key $ \t -> Remote.retrieveKeyFile remote key file t p+ | otherwise = notifyTransfer direction file $+ download (Remote.uuid remote) key file forwardRetry $ \p ->+ getViaTmp key $ \t -> Remote.retrieveKeyFile remote key file t p {- stdin and stdout are connected with the caller, to be used for - communication with it. But doing a transfer might involve something
Command/Unannex.hs view
@@ -16,16 +16,48 @@ import Annex.Content import Annex.Content.Direct import qualified Git.Command-import qualified Git.LsFiles as LsFiles+import qualified Git.Ref+import qualified Git.DiffTree as DiffTree import Utility.CopyFile+import Command.PreCommit (lockPreCommitHook) def :: [Command] def = [command "unannex" paramPaths seek SectionUtility "undo accidential add command"] seek :: CommandSeek-seek = withFilesInGit $ whenAnnexed start+seek = wrapUnannex . (withFilesInGit $ whenAnnexed start) +wrapUnannex :: Annex a -> Annex a+wrapUnannex a = ifM isDirect+ ( a+ {- Run with the pre-commit hook disabled, to avoid confusing+ - behavior if an unannexed file is added back to git as+ - a normal, non-annexed file and then committed.+ - Otherwise, the pre-commit hook would think that the file+ - has been unlocked and needs to be re-annexed.+ -+ - At the end, make a commit removing the unannexed files.+ -}+ , ifM cleanindex+ ( lockPreCommitHook $ commit `after` a+ , error "Cannot proceed with uncommitted changes staged in the index. Recommend you: git commit"+ )+ )+ where+ commit = inRepo $ Git.Command.run+ [ Param "commit"+ , Param "-q"+ , Param "--allow-empty"+ , Param "--no-verify"+ , Param "-m", Param "content removed from git annex"+ ]+ cleanindex = do+ (diff, cleanup) <- inRepo $ DiffTree.diffIndex Git.Ref.headRef+ if null diff+ then void (liftIO cleanup) >> return True+ else void (liftIO cleanup) >> return False+ start :: FilePath -> (Key, Backend) -> CommandStart start file (key, _) = stopUnless (inAnnex key) $ do showStart "unannex" file@@ -36,26 +68,7 @@ performIndirect :: FilePath -> Key -> CommandPerform performIndirect file key = do liftIO $ removeFile file- - -- git rm deletes empty directory without --cached inRepo $ Git.Command.run [Params "rm --cached --force --quiet --", File file]- - -- If the file was already committed, it is now staged for removal.- -- Commit that removal now, to avoid later confusing the- -- pre-commit hook, if this file is later added back to- -- git as a normal non-annexed file, to thinking that the- -- file has been unlocked and needs to be re-annexed.- (s, reap) <- inRepo $ LsFiles.staged [file]- unless (null s) $- inRepo $ Git.Command.run- [ Param "commit"- , Param "-q"- , Param "--no-verify"- , Param "-m", Param "content removed from git annex"- , Param "--", File file- ]- void $ liftIO reap- next $ cleanupIndirect file key cleanupIndirect :: FilePath -> Key -> CommandCleanup
Command/Uninit.hs view
@@ -36,7 +36,7 @@ seek :: CommandSeek seek ps = do- withFilesNotInGit (whenAnnexed startCheckIncomplete) ps+ withFilesNotInGit False (whenAnnexed startCheckIncomplete) ps withFilesInGit (whenAnnexed Command.Unannex.start) ps finish
Command/Vicfg.hs view
@@ -61,6 +61,7 @@ { cfgTrustMap :: TrustMap , cfgGroupMap :: M.Map UUID (S.Set Group) , cfgPreferredContentMap :: M.Map UUID PreferredContentExpression+ , cfgRequiredContentMap :: M.Map UUID PreferredContentExpression , cfgGroupPreferredContentMap :: M.Map Group PreferredContentExpression , cfgScheduleMap :: M.Map UUID [ScheduledActivity] }@@ -70,6 +71,7 @@ <$> trustMapRaw -- without local trust overrides <*> (groupsByUUID <$> groupMap) <*> preferredContentMapRaw+ <*> requiredContentMapRaw <*> groupPreferredContentMapRaw <*> scheduleMap @@ -79,6 +81,7 @@ mapM_ (uncurry trustSet) $ M.toList $ cfgTrustMap diff mapM_ (uncurry groupSet) $ M.toList $ cfgGroupMap diff mapM_ (uncurry preferredContentSet) $ M.toList $ cfgPreferredContentMap diff+ mapM_ (uncurry requiredContentSet) $ M.toList $ cfgRequiredContentMap diff mapM_ (uncurry groupPreferredContentSet) $ M.toList $ cfgGroupPreferredContentMap diff mapM_ (uncurry scheduleSet) $ M.toList $ cfgScheduleMap diff @@ -87,6 +90,7 @@ { cfgTrustMap = diff cfgTrustMap , cfgGroupMap = diff cfgGroupMap , cfgPreferredContentMap = diff cfgPreferredContentMap+ , cfgRequiredContentMap = diff cfgRequiredContentMap , cfgGroupPreferredContentMap = diff cfgGroupPreferredContentMap , cfgScheduleMap = diff cfgScheduleMap }@@ -102,6 +106,7 @@ , preferredcontent , grouppreferredcontent , standardgroups+ , requiredcontent , schedule ] where@@ -137,6 +142,11 @@ [ com "Repository preferred contents" ] (\(s, u) -> line "wanted" u s) (\u -> line "wanted" u "standard")+ + requiredcontent = settings cfg descs cfgRequiredContentMap+ [ com "Repository required contents" ]+ (\(s, u) -> line "required" u s)+ (\u -> line "required" u "") grouppreferredcontent = settings' cfg allgroups cfgGroupPreferredContentMap [ com "Group preferred contents"@@ -228,6 +238,12 @@ Nothing -> let m = M.insert u value (cfgPreferredContentMap cfg) in Right $ cfg { cfgPreferredContentMap = m }+ | setting == "required" = + case checkPreferredContentExpression value of+ Just e -> Left e+ Nothing ->+ let m = M.insert u value (cfgRequiredContentMap cfg)+ in Right $ cfg { cfgRequiredContentMap = m } | setting == "groupwanted" = case checkPreferredContentExpression value of Just e -> Left e@@ -255,7 +271,6 @@ [ com "** There was a problem parsing your input!" , com "** Search for \"Parse error\" to find the bad lines." , com "** Either fix the bad lines, or delete them (to discard your changes)."- , "" ] parseerr = com "** Parse error in next line: "
Common.hs view
@@ -11,6 +11,7 @@ import Data.Maybe as X import Data.List as X hiding (head, tail, init, last) import Data.String.Utils as X hiding (join)+import Data.Monoid as X import System.FilePath as X import System.Directory as X
INSTALL view
@@ -14,6 +14,7 @@ [[Gentoo]] | `emerge git-annex` [[ScientificLinux5]] | [[openSUSE]] | + [[Docker]] | [[Windows]] | [download installer](http://downloads.kitenet.net/git-annex/windows/current/) **alpha** """]]
Limit.hs view
@@ -20,7 +20,6 @@ import Types.Key import Types.Group import Types.FileMatcher-import Types.Limit import Types.MetaData import Logs.MetaData import Logs.Group@@ -45,21 +44,20 @@ getMatcher = Utility.Matcher.matchM <$> getMatcher' getMatcher' :: Annex (Utility.Matcher.Matcher (MatchInfo -> Annex Bool))-getMatcher' = do- m <- Annex.getState Annex.limit- case m of- Right r -> return r- Left l -> do- let matcher = Utility.Matcher.generate (reverse l)- Annex.changeState $ \s ->- s { Annex.limit = Right matcher }- return matcher+getMatcher' = go =<< Annex.getState Annex.limit+ where+ go (CompleteMatcher matcher) = return matcher+ go (BuildingMatcher l) = do+ let matcher = Utility.Matcher.generate (reverse l)+ Annex.changeState $ \s ->+ s { Annex.limit = CompleteMatcher matcher }+ return matcher {- Adds something to the limit list, which is built up reversed. -} add :: Utility.Matcher.Token (MatchInfo -> Annex Bool) -> Annex () add l = Annex.changeState $ \s -> s { Annex.limit = prepend $ Annex.limit s } where- prepend (Left ls) = Left $ l:ls+ prepend (BuildingMatcher ls) = BuildingMatcher $ l:ls prepend _ = error "internal" {- Adds a new token. -}@@ -67,21 +65,21 @@ addToken = add . Utility.Matcher.token {- Adds a new limit. -}-addLimit :: Either String MatchFiles -> Annex ()+addLimit :: Either String (MatchFiles Annex) -> Annex () addLimit = either error (\l -> add $ Utility.Matcher.Operation $ l S.empty) {- Add a limit to skip files that do not match the glob. -} addInclude :: String -> Annex () addInclude = addLimit . limitInclude -limitInclude :: MkLimit+limitInclude :: MkLimit Annex limitInclude glob = Right $ const $ return . matchGlobFile glob {- Add a limit to skip files that match the glob. -} addExclude :: String -> Annex () addExclude = addLimit . limitExclude -limitExclude :: MkLimit+limitExclude :: MkLimit Annex limitExclude glob = Right $ const $ return . not . matchGlobFile glob matchGlobFile :: String -> (MatchInfo -> Bool)@@ -119,10 +117,10 @@ else inAnnex key {- Limit to content that is currently present on a uuid. -}-limitPresent :: Maybe UUID -> MkLimit+limitPresent :: Maybe UUID -> MkLimit Annex limitPresent u _ = Right $ matchPresent u -matchPresent :: Maybe UUID -> MatchFiles+matchPresent :: Maybe UUID -> MatchFiles Annex matchPresent u _ = checkKey $ \key -> do hereu <- getUUID if u == Just hereu || isNothing u@@ -132,7 +130,7 @@ return $ maybe False (`elem` us) u {- Limit to content that is in a directory, anywhere in the repository tree -}-limitInDir :: FilePath -> MkLimit+limitInDir :: FilePath -> MkLimit Annex limitInDir dir = const $ Right $ const go where go (MatchingFile fi) = return $ elem dir $ splitPath $ takeDirectory $ matchFile fi@@ -143,7 +141,7 @@ addCopies :: String -> Annex () addCopies = addLimit . limitCopies -limitCopies :: MkLimit+limitCopies :: MkLimit Annex limitCopies want = case split ":" want of [v, n] -> case parsetrustspec v of Just checker -> go n $ checktrust checker@@ -169,7 +167,7 @@ addLackingCopies :: Bool -> String -> Annex () addLackingCopies approx = addLimit . limitLackingCopies approx -limitLackingCopies :: Bool -> MkLimit+limitLackingCopies :: Bool -> MkLimit Annex limitLackingCopies approx want = case readish want of Just needed -> Right $ \notpresent mi -> flip checkKey mi $ handle mi needed notpresent@@ -191,7 +189,7 @@ - This has a nice optimisation: When a file exists, - its key is obviously not unused. -}-limitUnused :: MatchFiles+limitUnused :: MatchFiles Annex limitUnused _ (MatchingFile _) = return False limitUnused _ (MatchingKey k) = S.member k <$> unusedKeys @@ -202,7 +200,7 @@ m <- groupMap addLimit $ limitInAllGroup m groupname -limitInAllGroup :: GroupMap -> MkLimit+limitInAllGroup :: GroupMap -> MkLimit Annex limitInAllGroup m groupname | S.null want = Right $ const $ const $ return True | otherwise = Right $ \notpresent -> checkKey $ check notpresent@@ -219,7 +217,7 @@ addInBackend :: String -> Annex () addInBackend = addLimit . limitInBackend -limitInBackend :: MkLimit+limitInBackend :: MkLimit Annex limitInBackend name = Right $ const $ checkKey check where check key = pure $ keyBackendName key == name@@ -231,7 +229,7 @@ addSmallerThan :: String -> Annex () addSmallerThan = addLimit . limitSize (<) -limitSize :: (Maybe Integer -> Maybe Integer -> Bool) -> MkLimit+limitSize :: (Maybe Integer -> Maybe Integer -> Bool) -> MkLimit Annex limitSize vs s = case readSize dataUnits s of Nothing -> Left "bad size" Just sz -> Right $ go sz@@ -249,7 +247,7 @@ addMetaData :: String -> Annex () addMetaData = addLimit . limitMetaData -limitMetaData :: MkLimit+limitMetaData :: MkLimit Annex limitMetaData s = case parseMetaData s of Left e -> Left e Right (f, v) ->
Locations.hs view
@@ -41,6 +41,7 @@ gitAnnexMergeDir, gitAnnexJournalDir, gitAnnexJournalLock,+ gitAnnexPreCommitLock, gitAnnexIndex, gitAnnexIndexStatus, gitAnnexViewIndex,@@ -256,6 +257,10 @@ {- Lock file for the journal. -} gitAnnexJournalLock :: Git.Repo -> FilePath gitAnnexJournalLock r = gitAnnexDir r </> "journal.lck"++{- Lock file for the pre-commit hook. -}+gitAnnexPreCommitLock :: Git.Repo -> FilePath+gitAnnexPreCommitLock r = gitAnnexDir r </> "precommit.lck" {- .git/annex/index is used to stage changes to the git-annex branch -} gitAnnexIndex :: Git.Repo -> FilePath
Logs.hs view
@@ -35,6 +35,7 @@ , trustLog , groupLog , preferredContentLog+ , requiredContentLog , scheduleLog ] @@ -69,6 +70,9 @@ preferredContentLog :: FilePath preferredContentLog = "preferred-content.log"++requiredContentLog :: FilePath+requiredContentLog = "required-content.log" groupPreferredContentLog :: FilePath groupPreferredContentLog = "group-preferred-content.log"
Logs/PreferredContent.hs view
@@ -6,16 +6,19 @@ -} module Logs.PreferredContent (- preferredContentLog, preferredContentSet,+ requiredContentSet, groupPreferredContentSet, isPreferredContent,+ isRequiredContent, preferredContentMap,- preferredContentMapLoad, preferredContentMapRaw,+ requiredContentMap,+ requiredContentMapRaw, groupPreferredContentMapRaw, checkPreferredContentExpression, setStandardGroup,+ preferredRequiredMapsLoad, ) where import qualified Data.Map as M@@ -28,43 +31,57 @@ import qualified Annex import Logs import Logs.UUIDBased-import qualified Utility.Matcher+import Utility.Matcher hiding (tokens) import Annex.FileMatcher import Annex.UUID-import Types.Limit import Types.Group import Types.Remote (RemoteConfig) import Logs.Group import Logs.Remote+import Types.FileMatcher import Types.StandardGroups import Limit {- Checks if a file is preferred content for the specified repository - (or the current repository if none is specified). -} isPreferredContent :: Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool-isPreferredContent mu notpresent mkey afile def = do+isPreferredContent = checkMap preferredContentMap++isRequiredContent :: Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool+isRequiredContent = checkMap requiredContentMap++checkMap :: Annex (FileMatcherMap Annex) -> Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool+checkMap getmap mu notpresent mkey afile def = do u <- maybe getUUID return mu- m <- preferredContentMap+ m <- getmap case M.lookup u m of Nothing -> return def Just matcher -> checkMatcher matcher mkey afile notpresent def -{- The map is cached for speed. -}-preferredContentMap :: Annex Annex.PreferredContentMap-preferredContentMap = maybe preferredContentMapLoad return+preferredContentMap :: Annex (FileMatcherMap Annex)+preferredContentMap = maybe (fst <$> preferredRequiredMapsLoad) return =<< Annex.getState Annex.preferredcontentmap -{- Loads the map, updating the cache. -}-preferredContentMapLoad :: Annex Annex.PreferredContentMap-preferredContentMapLoad = do+requiredContentMap :: Annex (FileMatcherMap Annex)+requiredContentMap = maybe (snd <$> preferredRequiredMapsLoad) return+ =<< Annex.getState Annex.requiredcontentmap++preferredRequiredMapsLoad :: Annex (FileMatcherMap Annex, FileMatcherMap Annex)+preferredRequiredMapsLoad = do groupmap <- groupMap configmap <- readRemoteLog- groupwantedmap <- groupPreferredContentMapRaw- m <- simpleMap- . parseLogWithUUID ((Just .) . makeMatcher groupmap configmap groupwantedmap)- <$> Annex.Branch.get preferredContentLog- Annex.changeState $ \s -> s { Annex.preferredcontentmap = Just m }- return m+ let genmap l gm = simpleMap+ . parseLogWithUUID ((Just .) . makeMatcher groupmap configmap gm)+ <$> Annex.Branch.get l+ pc <- genmap preferredContentLog =<< groupPreferredContentMapRaw+ rc <- genmap requiredContentLog M.empty+ -- Required content is implicitly also preferred content, so OR+ let m = M.unionWith MOr pc rc+ Annex.changeState $ \s -> s+ { Annex.preferredcontentmap = Just m+ , Annex.requiredcontentmap = Just rc+ }+ return (m, rc) {- This intentionally never fails, even on unparsable expressions, - because the configuration is shared among repositories and newer@@ -75,11 +92,11 @@ -> M.Map Group PreferredContentExpression -> UUID -> PreferredContentExpression- -> FileMatcher+ -> FileMatcher Annex makeMatcher groupmap configmap groupwantedmap u = go True True where go expandstandard expandgroupwanted expr- | null (lefts tokens) = Utility.Matcher.generate $ rights tokens+ | null (lefts tokens) = generate $ rights tokens | otherwise = unknownMatcher u where tokens = exprParser matchstandard matchgroupwanted groupmap configmap (Just u) expr@@ -102,10 +119,10 @@ - - This avoid unwanted/expensive changes to the content, until the problem - is resolved. -}-unknownMatcher :: UUID -> FileMatcher-unknownMatcher u = Utility.Matcher.generate [present]+unknownMatcher :: UUID -> FileMatcher Annex+unknownMatcher u = generate [present] where- present = Utility.Matcher.Operation $ matchPresent (Just u)+ present = Operation $ matchPresent (Just u) {- Checks if an expression can be parsed, if not returns Just error -} checkPreferredContentExpression :: PreferredContentExpression -> Maybe String
Logs/PreferredContent/Raw.hs view
@@ -21,14 +21,23 @@ {- Changes the preferred content configuration of a remote. -} preferredContentSet :: UUID -> PreferredContentExpression -> Annex ()-preferredContentSet uuid@(UUID _) val = do+preferredContentSet = setLog preferredContentLog++requiredContentSet :: UUID -> PreferredContentExpression -> Annex ()+requiredContentSet = setLog requiredContentLog++setLog :: FilePath -> UUID -> PreferredContentExpression -> Annex ()+setLog logfile uuid@(UUID _) val = do ts <- liftIO getPOSIXTime- Annex.Branch.change preferredContentLog $+ Annex.Branch.change logfile $ showLog id . changeLog ts uuid val . parseLog Just- Annex.changeState $ \s -> s { Annex.preferredcontentmap = Nothing }-preferredContentSet NoUUID _ = error "unknown UUID; cannot modify"+ Annex.changeState $ \s -> s + { Annex.preferredcontentmap = Nothing+ , Annex.requiredcontentmap = Nothing+ }+setLog _ NoUUID _ = error "unknown UUID; cannot modify" {- Changes the preferred content configuration of a group. -} groupPreferredContentSet :: Group -> PreferredContentExpression -> Annex ()@@ -43,6 +52,10 @@ preferredContentMapRaw :: Annex (M.Map UUID PreferredContentExpression) preferredContentMapRaw = simpleMap . parseLog Just <$> Annex.Branch.get preferredContentLog++requiredContentMapRaw :: Annex (M.Map UUID PreferredContentExpression)+requiredContentMapRaw = simpleMap . parseLog Just+ <$> Annex.Branch.get requiredContentLog groupPreferredContentMapRaw :: Annex (M.Map Group PreferredContentExpression) groupPreferredContentMapRaw = simpleMap . parseMapLog Just Just
Logs/Transfer.hs view
@@ -88,108 +88,6 @@ percentComplete (Transfer { transferKey = key }) info = percentage <$> keySize key <*> Just (fromMaybe 0 $ bytesComplete info) -type RetryDecider = TransferInfo -> TransferInfo -> Bool--noRetry :: RetryDecider-noRetry _ _ = False--{- Retries a transfer when it fails, as long as the failed transfer managed- - to send some data. -}-forwardRetry :: RetryDecider-forwardRetry old new = bytesComplete old < bytesComplete new--upload :: UUID -> Key -> AssociatedFile -> RetryDecider -> (MeterUpdate -> Annex Bool) -> Annex Bool-upload u key = runTransfer (Transfer Upload u key)--download :: UUID -> Key -> AssociatedFile -> RetryDecider -> (MeterUpdate -> Annex Bool) -> Annex Bool-download u key = runTransfer (Transfer Download u key)--{- Runs a transfer action. Creates and locks the lock file while the- - action is running, and stores info in the transfer information- - file.- -- - If the transfer action returns False, the transfer info is - - left in the failedTransferDir.- -- - If the transfer is already in progress, returns False.- -- - An upload can be run from a read-only filesystem, and in this case- - no transfer information or lock file is used.- -}-runTransfer :: Transfer -> Maybe FilePath -> RetryDecider -> (MeterUpdate -> Annex Bool) -> Annex Bool-runTransfer t file shouldretry a = do- info <- liftIO $ startTransferInfo file- (meter, tfile, metervar) <- mkProgressUpdater t info- mode <- annexFileMode- (fd, inprogress) <- liftIO $ prep tfile mode info- if inprogress- then do- showNote "transfer already in progress"- return False- else do- ok <- retry info metervar $- bracketIO (return fd) (cleanup tfile) (const $ a meter)- unless ok $ recordFailedTransfer t info- return ok- where-#ifndef mingw32_HOST_OS- prep tfile mode info = do- mfd <- catchMaybeIO $- openFd (transferLockFile tfile) ReadWrite (Just mode)- defaultFileFlags { trunc = True }- case mfd of- Nothing -> return (Nothing, False)- Just fd -> do- locked <- catchMaybeIO $- setLock fd (WriteLock, AbsoluteSeek, 0, 0)- if isNothing locked- then return (Nothing, True)- else do- void $ tryIO $ writeTransferInfoFile info tfile- return (mfd, False)-#else- prep tfile _mode info = do- v <- catchMaybeIO $ lockExclusive (transferLockFile tfile)- case v of- Nothing -> return (Nothing, False)- Just Nothing -> return (Nothing, True)- Just (Just lockhandle) -> do- void $ tryIO $ writeTransferInfoFile info tfile- return (Just lockhandle, False)-#endif- cleanup _ Nothing = noop- cleanup tfile (Just lockhandle) = do- void $ tryIO $ removeFile tfile-#ifndef mingw32_HOST_OS- void $ tryIO $ removeFile $ transferLockFile tfile- closeFd lockhandle-#else- {- Windows cannot delete the lockfile until the lock- - is closed. So it's possible to race with another- - process that takes the lock before it's removed,- - so ignore failure to remove.- -}- dropLock lockhandle- void $ tryIO $ removeFile $ transferLockFile tfile-#endif- retry oldinfo metervar run = do- v <- tryAnnex run- case v of- Right b -> return b- Left _ -> do- b <- getbytescomplete metervar- let newinfo = oldinfo { bytesComplete = Just b }- if shouldretry oldinfo newinfo- then retry newinfo metervar run- else return False- getbytescomplete metervar- | transferDirection t == Upload =- liftIO $ readMVar metervar- | otherwise = do- f <- fromRepo $ gitAnnexTmpObjectLocation (transferKey t)- liftIO $ catchDefaultIO 0 $- fromIntegral . fileSize <$> getFileStatus f- {- Generates a callback that can be called as transfer progresses to update - the transfer info file. Also returns the file it'll be updating, and a - MVar that can be used to read the number of bytesComplete. -}
Remote/Git.hs view
@@ -24,7 +24,7 @@ import qualified Git.GCrypt import qualified Annex import Logs.Presence-import Logs.Transfer+import Annex.Transfer import Annex.UUID import Annex.Exception import qualified Annex.Content@@ -321,7 +321,7 @@ case v of Nothing -> return False Just (object, checksuccess) ->- upload u key file noRetry+ runTransfer (Transfer Download u key) file noRetry (rsyncOrCopyFile params object dest) <&&> checksuccess | Git.repoIsSsh (repo r) = feedprogressback $ \feeder -> do@@ -418,7 +418,7 @@ ( return True , do ensureInitialized- download u key file noRetry $ const $+ runTransfer (Transfer Download u key) file noRetry $ const $ Annex.Content.saveState True `after` Annex.Content.getViaTmpChecked (liftIO checksuccessio) key (\d -> rsyncOrCopyFile params object d p)
Remote/Glacier.hs view
@@ -82,7 +82,7 @@ unless enabling $ genVault fullconfig u gitConfigSpecialRemote u fullconfig "glacier" "true"- return (c', u)+ return (fullconfig, u) where remotename = fromJust (M.lookup "name" c) defvault = remotename ++ "-" ++ fromUUID u@@ -225,7 +225,8 @@ glacierParams c params = datacenter:params where datacenter = Param $ "--region=" ++- fromJust (M.lookup "datacenter" c)+ fromMaybe (error "Missing datacenter configuration")+ (M.lookup "datacenter" c) glacierEnv :: RemoteConfig -> UUID -> Annex (Maybe [(String, String)]) glacierEnv c u = go =<< getRemoteCredPairFor "glacier" c creds@@ -239,7 +240,8 @@ (uk, pk) = credPairEnvironment creds getVault :: RemoteConfig -> Vault-getVault = fromJust . M.lookup "vault"+getVault = fromMaybe (error "Missing vault configuration") + . M.lookup "vault" archive :: Remote -> Key -> Archive archive r k = fileprefix ++ key2file k
Remote/Tahoe.hs view
@@ -216,7 +216,7 @@ tahoeParams :: TahoeConfigDir -> String -> [CommandParam] -> [CommandParam] tahoeParams configdir command params = - Param command : Param "-d" : File configdir : params+ Param "-d" : File configdir : Param command : params storeCapability :: UUID -> Key -> Capability -> Annex () storeCapability u k cap = setRemoteState u k cap
+ Types/DesktopNotify.hs view
@@ -0,0 +1,27 @@+{- git-annex DesktopNotify type+ -+ - Copyright 2014 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Types.DesktopNotify where++import Data.Monoid++data DesktopNotify = DesktopNotify+ { notifyStart :: Bool+ , notifyFinish :: Bool+ }+ deriving (Show)++instance Monoid DesktopNotify where+ mempty = DesktopNotify False False+ mappend (DesktopNotify s1 f1) (DesktopNotify s2 f2) =+ DesktopNotify (s1 || s2) (f1 || f2)++mkNotifyStart :: DesktopNotify+mkNotifyStart = DesktopNotify True False++mkNotifyFinish :: DesktopNotify+mkNotifyFinish = DesktopNotify False True
Types/FileMatcher.hs view
@@ -7,8 +7,13 @@ module Types.FileMatcher where +import Types.UUID (UUID) import Types.Key (Key)+import Utility.Matcher (Matcher, Token) +import qualified Data.Map as M+import qualified Data.Set as S+ data MatchInfo = MatchingFile FileInfo | MatchingKey Key@@ -17,3 +22,19 @@ { relFile :: FilePath -- may be relative to cwd , matchFile :: FilePath -- filepath to match on; may be relative to top }++type FileMatcherMap a = M.Map UUID (Utility.Matcher.Matcher (S.Set UUID -> MatchInfo -> a Bool))++type MkLimit a = String -> Either String (MatchFiles a)++type AssumeNotPresent = S.Set UUID++type MatchFiles a = AssumeNotPresent -> MatchInfo -> a Bool++type FileMatcher a = Matcher (MatchFiles a)++-- This is a matcher that can have tokens added to it while it's being+-- built, and once complete is compiled to an unchangable matcher.+data ExpandableMatcher a+ = BuildingMatcher [Token (MatchInfo -> a Bool)]+ | CompleteMatcher (Matcher (MatchInfo -> a Bool))
− Types/Limit.hs
@@ -1,20 +0,0 @@-{- types for limits- -- - Copyright 2013 Joey Hess <joey@kitenet.net>- -- - Licensed under the GNU GPL version 3 or higher.- -}--{-# LANGUAGE CPP #-}--module Types.Limit where--import Common.Annex-import Types.FileMatcher--import qualified Data.Set as S--type MkLimit = String -> Either String MatchFiles--type AssumeNotPresent = S.Set UUID-type MatchFiles = AssumeNotPresent -> MatchInfo -> Annex Bool
Types/MetaData.hs view
@@ -264,7 +264,9 @@ instance Arbitrary MetaData where arbitrary = do size <- arbitrarySizedBoundedIntegral `suchThat` (< 500)- MetaData . M.fromList <$> vector size+ MetaData . M.filterWithKey legal . M.fromList <$> vector size+ where+ legal k _v = legalField $ fromMetaField k instance Arbitrary MetaValue where arbitrary = MetaValue <$> arbitrary <*> arbitrary
Utility/FileMode.hs view
@@ -9,15 +9,18 @@ module Utility.FileMode where -import Common-+import System.IO+import Control.Monad import Control.Exception (bracket) import System.PosixCompat.Types+import Utility.PosixFiles #ifndef mingw32_HOST_OS import System.Posix.Files #endif import Foreign (complement) +import Utility.Exception+ {- Applies a conversion function to a file's mode. -} modifyFileMode :: FilePath -> (FileMode -> FileMode) -> IO () modifyFileMode f convert = void $ modifyFileMode' f convert@@ -56,6 +59,12 @@ executeModes :: [FileMode] executeModes = [ownerExecuteMode, groupExecuteMode, otherExecuteMode] +otherGroupModes :: [FileMode]+otherGroupModes = + [ groupReadMode, otherReadMode+ , groupWriteMode, otherWriteMode+ ]+ {- Removes the write bits from a file. -} preventWrite :: FilePath -> IO () preventWrite f = modifyFileMode f $ removeModes writeModes@@ -145,9 +154,5 @@ writeFileProtected :: FilePath -> String -> IO () writeFileProtected file content = withUmask 0o0077 $ withFile file WriteMode $ \h -> do- void $ tryIO $ modifyFileMode file $- removeModes- [ groupReadMode, otherReadMode- , groupWriteMode, otherWriteMode- ]+ void $ tryIO $ modifyFileMode file $ removeModes otherGroupModes hPutStr h content
Utility/Matcher.hs view
@@ -19,7 +19,7 @@ module Utility.Matcher ( Token(..),- Matcher,+ Matcher(..), token, tokens, generate,
Utility/ThreadScheduler.hs view
@@ -10,9 +10,12 @@ module Utility.ThreadScheduler where -import Common-+import Control.Monad import Control.Concurrent+#ifndef mingw32_HOST_OS+import Control.Monad.IfElse+import System.Posix.IO+#endif #ifndef mingw32_HOST_OS import System.Posix.Signals #ifndef __ANDROID__
Utility/Url.hs view
@@ -77,7 +77,8 @@ Nothing -> dne | otherwise -> if Build.SysConfig.curl then do- output <- readProcess "curl" $ toCommand curlparams+ output <- catchDefaultIO "" $+ readProcess "curl" $ toCommand curlparams case lastMaybe (lines output) of Just ('2':_:_) -> return (True, extractsize output) _ -> dne
Utility/WebApp.hs view
@@ -33,7 +33,6 @@ import qualified Data.Text.Encoding as TE import Blaze.ByteString.Builder.Char.Utf8 (fromText) import Blaze.ByteString.Builder (Builder)-import Data.Monoid import Control.Arrow ((***)) import Control.Concurrent #ifdef WITH_WEBAPP_SECURE
debian/changelog view
@@ -1,3 +1,40 @@+git-annex (5.20140402) unstable; urgency=medium++ * unannex, uninit: Avoid committing after every file is unannexed,+ for massive speedup.+ * --notify-finish switch will cause desktop notifications after each + file upload/download/drop completes+ (using the dbus Desktop Notifications Specification)+ * --notify-start switch will show desktop notifications when each+ file upload/download starts.+ * webapp: Automatically install Nautilus integration scripts+ to get and drop files.+ * tahoe: Pass -d parameter before subcommand; putting it after+ the subcommand no longer works with tahoe-lafs version 1.10.+ (Thanks, Alberto Berti)+ * forget --drop-dead: Avoid removing the dead remote from the trust.log,+ so that if git remotes for it still exist anywhere, git annex info+ will still know it's dead and not show it.+ * git-annex-shell: Make configlist automatically initialize+ a remote git repository, as long as a git-annex branch has+ been pushed to it, to simplify setup of remote git repositories,+ including via gitolite.+ * add --include-dotfiles: New option, perhaps useful for backups.+ * Version 5.20140227 broke creation of glacier repositories,+ not including the datacenter and vault in their configuration.+ This bug is fixed, but glacier repositories set up with the broken+ version of git-annex need to have the datacenter and vault set+ in order to be usable. This can be done using git annex enableremote+ to add the missing settings. For details, see+ http://git-annex.branchable.com/bugs/problems_with_glacier/+ * Added required content configuration.+ * assistant: Improve ssh authorized keys line generated in local pairing+ or for a remote ssh server to set environment variables in an + alternative way that works with the non-POSIX fish shell, as well+ as POSIX shells.++ -- Joey Hess <joeyh@debian.org> Wed, 02 Apr 2014 16:42:53 -0400+ git-annex (5.20140320) unstable; urgency=medium * Fix zombie leak and general inneficiency when copying files to a
debian/control view
@@ -30,6 +30,7 @@ libghc-hinotify-dev [linux-any], libghc-stm-dev (>= 2.3), libghc-dbus-dev (>= 0.10.3) [linux-any],+ libghc-fdo-notify-dev (>= 0.3) [linux-any], libghc-yesod-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc], libghc-yesod-static-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc], libghc-yesod-default-dev [i386 amd64 kfreebsd-amd64 powerpc sparc],
+ doc/assistant/downloadnotification.png view
binary file changed (absent → 4513 bytes)
binary file changed (absent → 59867 bytes)
doc/bugs/Assistant_lost_dbus_connection_spamming_log.mdwn view
@@ -76,3 +76,13 @@ lost dbus connection; falling back to polling (SocketError {socketErrorMessage = "connect: does not exist (No such file or directory)", socketErrorFatal = True, socketErrorAddress = Just (Address "unix:path=/var/run/dbus/system_bus_socket")}) """]]++> [[done]]; This turned out to not be dbus related, but the http server failing,+> and I fixed that bug.+> +> AFAICS the user running git-annex did not have their own dbus daemon+> running, and that's why the low-volume dbus messages come up. +> Probably because this is an embedded device, and so no desktop+> environment. git-annex only uses dbus for detecting network connection+> changes and removable media mounts. None of which probably matter in an+> embedded environment. --[[Joey]]
+ doc/bugs/Crash_when_disabling_syncing_in_the_webapp.mdwn view
@@ -0,0 +1,23 @@+### Please describe the problem.+The watcher crashes.++I only need to restart the thread in the pop-up to get everything to work again, but I'm reporting just in case that this issue has any other implications.+++### What steps will reproduce the problem?+I open the webapp and in the minutes before it starts syncing (syncing is enabled) I disable it (clicking in the 'syncing enabled' text).++This produces a crash every time.+++### What version of git-annex are you using? On what operating system?+5.20140320 in Debian sid and testing+++### Please provide any additional information below.+This is all I can see in the logs++[[!format sh """+Watcher crashed: PauseWatcher+[2014-03-26 08:54:57 CET] Watcher: warning Watcher crashed: PauseWatcher+"""]]
+ doc/bugs/Race_condition_between_watch__47__assistant_and_addurl.mdwn view
@@ -0,0 +1,195 @@+Addurl can fail due to an apparent race condition when watch or assistant is running and the repository is in direct mode. The following stress test script encounters the bug consistently on my system. I am running git-annex 5.20140320 on on Ubuntu 13.10.++[[!format sh """+#!/bin/sh+set -eu++cleanup() {+ local dir+ dir="$1"; shift+ if [ -d "$dir" ]; then+ (+ set -x+ fuser -k -w "$dir/annex/.git/annex/daemon.log" || :+ find "$dir" -type d -exec chmod 700 '{}' '+'+ find "$dir" -type f -exec chmod 600 '{}' '+'+ rm -fr "$dir"+ )+ fi+}++go() {+ local dir+ dir="$(mktemp -d "${TMP:-/tmp}/stress-annex.XXXXXXXXXX")"+ trap "cleanup '$dir'" 0 1 2 13 15++ (+ cd "$dir"+ mkdir annex+ cd annex+ set -x++ git init+ git annex init+ git annex direct+ git annex watch++ for n in $(seq 100); do+ git annex addurl --file=foo http://heh.fi/robots.txt+ git annex sync+ rm -f foo+ git annex sync+ done++ git annex watch --stop+ git annex uninit+ )++ cleanup "$dir"+ trap - 0 1 2 13 14+}++go+"""]]++Script output:++[[!format sh """+% ./stress-annex++ git init+Initialized empty Git repository in /tmp/stress-annex.OKj6D8kVmV/annex/.git/++ git annex init+init ok+(Recording state in git...)++ git annex direct+commit +On branch master++Initial commit++nothing to commit+ok+direct ok++ git annex watch++ seq 100++ git annex addurl --file=foo http://heh.fi/robots.txt+addurl foo (downloading http://heh.fi/robots.txt ...) +--2014-03-27 03:14:29-- http://heh.fi/robots.txt+Resolving heh.fi (heh.fi)... 83.145.237.222+Connecting to heh.fi (heh.fi)|83.145.237.222|:80... connected.+HTTP request sent, awaiting response... 200 OK+Length: 0 [text/plain]+Saving to: ‘/tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’++ [ <=> ] 0 --.-K/s in 0s ++2014-03-27 03:14:29 (0.00 B/s) - ‘/tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’ saved [0/0]++(Recording state in git...)+ok+(Recording state in git...)++ git annex sync+commit ok++ rm -f foo++ git annex sync+commit (Recording state in git...)+ok+(Recording state in git...)++ git annex addurl --file=foo http://heh.fi/robots.txt+addurl foo (downloading http://heh.fi/robots.txt ...) +--2014-03-27 03:14:29-- http://heh.fi/robots.txt+Resolving heh.fi (heh.fi)... 83.145.237.222+Connecting to heh.fi (heh.fi)|83.145.237.222|:80... connected.+HTTP request sent, awaiting response... 200 OK+Length: 0 [text/plain]+Saving to: ‘/tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’++ [ <=> ] 0 --.-K/s in 0s ++2014-03-27 03:14:29 (0.00 B/s) - ‘/tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’ saved [0/0]++(Recording state in git...)+ok+(Recording state in git...)++ git annex sync+commit ok++ rm -f foo++ git annex sync+commit (Recording state in git...)+ok+(Recording state in git...)++ git annex addurl --file=foo http://heh.fi/robots.txt+addurl foo (downloading http://heh.fi/robots.txt ...) +--2014-03-27 03:14:29-- http://heh.fi/robots.txt+Resolving heh.fi (heh.fi)... 83.145.237.222+Connecting to heh.fi (heh.fi)|83.145.237.222|:80... connected.+HTTP request sent, awaiting response... 200 OK+Length: 0 [text/plain]+Saving to: ‘/tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’++ [ <=> ] 0 --.-K/s in 0s ++2014-03-27 03:14:29 (0.00 B/s) - ‘/tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’ saved [0/0]+++git-annex: /tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/: openTempFile: permission denied (Permission denied)+failed+git-annex: addurl: 1 failed++ fuser -k -w /tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/daemon.log+/tmp/stress-annex.OKj6D8kVmV/annex/.git/annex/daemon.log: 30704 30709 30735 30738 30778++ find /tmp/stress-annex.OKj6D8kVmV -type d -exec chmod 700 {} +++ find /tmp/stress-annex.OKj6D8kVmV -type f -exec chmod 600 {} +++ rm -fr /tmp/stress-annex.OKj6D8kVmV+"""]]++The script also seems to encounter another issue. The output when seq 100 is changed to seq 1 and addurl happens to succeed:++[[!format sh """++ git init+Initialized empty Git repository in /tmp/stress-annex.QEs0pNyS9z/annex/.git/++ git annex init+init ok+(Recording state in git...)++ git annex direct+commit +On branch master++Initial commit++nothing to commit+ok+direct ok++ git annex watch++ seq 1++ git annex addurl --file=foo http://heh.fi/robots.txt+addurl foo (downloading http://heh.fi/robots.txt ...) +--2014-03-27 03:17:20-- http://heh.fi/robots.txt+Resolving heh.fi (heh.fi)... 83.145.237.222+Connecting to heh.fi (heh.fi)|83.145.237.222|:80... connected.+HTTP request sent, awaiting response... 200 OK+Length: 0 [text/plain]+Saving to: ‘/tmp/stress-annex.QEs0pNyS9z/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’++ [ <=> ] 0 --.-K/s in 0s ++2014-03-27 03:17:20 (0.00 B/s) - ‘/tmp/stress-annex.QEs0pNyS9z/annex/.git/annex/tmp/URL--http&c%%heh.fi%robots.txt’ saved [0/0]++(Recording state in git...)+ok+(Recording state in git...)++ git annex sync+commit ok++ rm -f foo++ git annex sync+commit (Recording state in git...)+ok+(Recording state in git...)++ git annex watch --stop++ git annex uninit+git-annex: /tmp/stress-annex.QEs0pNyS9z/annex/.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.map: removeLink: permission denied (Permission denied)++ fuser -k -w /tmp/stress-annex.QEs0pNyS9z/annex/.git/annex/daemon.log++ :++ find /tmp/stress-annex.QEs0pNyS9z -type d -exec chmod 700 {} +++ find /tmp/stress-annex.QEs0pNyS9z -type f -exec chmod 600 {} +++ rm -fr /tmp/stress-annex.QEs0pNyS9z+"""]]
+ doc/bugs/git-annex_fails_to_initialize_under_Windows.mdwn view
@@ -0,0 +1,212 @@+### Please describe the problem.+Git-annex fails to initialize and fails tests.++### What steps will reproduce the problem?+Attempted initialization:++ C:\Users\Andrew\Documents\GitHub\git-annex-test [master]> git annex init+ init+ Detected a filesystem without fifo support.++ Disabling ssh connection caching.++ Detected a crippled filesystem.++ Enabling direct mode.+ fatal: index file open failed: Invalid argument+ git-annex: git [Param "checkout",Param "-q",Param "-B",Param "annex/direct/master"] failed++Tests:++ C:\Users\Andrew\Documents\GitHub\git-annex-test [master]> git annex test+ Tests+ QuickCheck+ prop_idempotent_deencode_git: OK+ +++ OK, passed 1000 tests.+ prop_idempotent_deencode: OK+ +++ OK, passed 1000 tests.+ prop_idempotent_fileKey: OK+ +++ OK, passed 1000 tests.+ prop_idempotent_key_encode: OK+ +++ OK, passed 1000 tests.+ prop_idempotent_key_decode: OK+ +++ OK, passed 1000 tests.+ prop_idempotent_shellEscape: OK+ +++ OK, passed 1000 tests.+ prop_idempotent_shellEscape_multiword: OK+ +++ OK, passed 1000 tests.+ prop_logs_sane: OK+ +++ OK, passed 1000 tests.+ prop_idempotent_configEscape: OK+ +++ OK, passed 1000 tests.+ prop_parse_show_Config: OK+ +++ OK, passed 1000 tests.+ prop_parentDir_basics: OK+ +++ OK, passed 1000 tests.+ prop_relPathDirToFile_basics: OK+ +++ OK, passed 1000 tests.+ prop_relPathDirToFile_regressionTest: OK+ +++ OK, passed 1000 tests.+ prop_cost_sane: OK+ +++ OK, passed 1000 tests.+ prop_matcher_sane: OK+ +++ OK, passed 1000 tests.+ prop_HmacSha1WithCipher_sane: OK+ +++ OK, passed 1000 tests.+ prop_TimeStamp_sane: OK+ +++ OK, passed 1000 tests.+ prop_addLog_sane: OK+ +++ OK, passed 1000 tests.+ prop_verifiable_sane: OK+ +++ OK, passed 1000 tests.+ prop_segment_regressionTest: OK+ +++ OK, passed 1000 tests.+ prop_read_write_transferinfo: OK+ +++ OK, passed 1000 tests.+ prop_read_show_inodecache: OK+ +++ OK, passed 1000 tests.+ prop_parse_show_log: OK+ +++ OK, passed 1000 tests.+ prop_read_show_TrustLevel: OK+ +++ OK, passed 1000 tests.+ prop_parse_show_TrustLog: OK+ +++ OK, passed 1000 tests.+ prop_hashes_stable: OK+ +++ OK, passed 1000 tests.+ prop_schedule_roundtrips: OK+ +++ OK, passed 1000 tests.+ prop_duration_roundtrips: OK+ +++ OK, passed 1000 tests.+ prop_metadata_sane: OK+ +++ OK, passed 1000 tests.+ prop_metadata_serialize: OK+ +++ OK, passed 1000 tests.+ prop_branchView_legal: OK+ +++ OK, passed 1000 tests.+ prop_view_roundtrips: OK+ +++ OK, passed 1000 tests.+ prop_viewedFile_rountrips: I n i t TOeKs+ ts+ i n+i+t+: OK, passed 1000 tests.+ Unit Tests+ add sha1dup: git-annex: System.PosixCompat.User.getEffectiveUserID: not support+ ed: illegal operation+ FAIL+ init failed+ add: git-annex: System.PosixCompat.User.getEffectiveUserID: not supported: illegal operation+ FAIL+ add failed++ 2 out of 2 tests failed+ FAIL+ Exception: init tests failed! cannot continue+ add extras: FAIL+ Exception: init tests failed! cannot continue+ reinject: FAIL+ Exception: init tests failed! cannot continue+ unannex (no copy): FAIL+ Exception: init tests failed! cannot continue+ unannex (with copy): FAIL+ Exception: init tests failed! cannot continue+ drop (no remote): FAIL+ Exception: init tests failed! cannot continue+ drop (with remote): FAIL+ Exception: init tests failed! cannot continue+ drop (untrusted remote): FAIL+ Exception: init tests failed! cannot continue+ get: FAIL+ Exception: init tests failed! cannot continue+ move: FAIL+ Exception: init tests failed! cannot continue+ copy: FAIL+ Exception: init tests failed! cannot continue+ lock: FAIL+ Exception: init tests failed! cannot continue+ edit (no pre-commit): FAIL+ Exception: init tests failed! cannot continue+ edit (pre-commit): FAIL+ Exception: init tests failed! cannot continue+ fix: FAIL+ Exception: init tests failed! cannot continue+ trust: FAIL+ Exception: init tests failed! cannot continue+ fsck (basics): FAIL+ Exception: init tests failed! cannot continue+ fsck (bare): FAIL+ Exception: init tests failed! cannot continue+ fsck (local untrusted): FAIL+ Exception: init tests failed! cannot continue+ fsck (remote untrusted): FAIL+ Exception: init tests failed! cannot continue+ migrate: FAIL+ Exception: init tests failed! cannot continue+ migrate (via gitattributes): FAIL+ Exception: init tests failed! cannot continue+ unused: FAIL+ Exception: init tests failed! cannot continue+ describe: FAIL+ Exception: init tests failed! cannot continue+ find: FAIL+ Exception: init tests failed! cannot continue+ merge: FAIL+ Exception: init tests failed! cannot continue+ info: FAIL+ Exception: init tests failed! cannot continue+ version: FAIL+ Exception: init tests failed! cannot continue+ sync: FAIL+ Exception: init tests failed! cannot continue+ union merge regression: FAIL+ Exception: init tests failed! cannot continue+ conflict resolution: FAIL+ Exception: init tests failed! cannot continue+ conflict_resolution (mixed directory and file): FAIL+ Exception: init tests failed! cannot continue+ conflict_resolution (mixed directory and file) 2: FAIL+ Exception: init tests failed! cannot continue+ map: FAIL+ Exception: init tests failed! cannot continue+ uninit: FAIL+ Exception: init tests failed! cannot continue+ uninit (in git-annex branch): FAIL+ Exception: init tests failed! cannot continue+ upgrade: FAIL+ Exception: init tests failed! cannot continue+ whereis: FAIL+ Exception: init tests failed! cannot continue+ hook remote: FAIL+ Exception: init tests failed! cannot continue+ directory remote: FAIL+ Exception: init tests failed! cannot continue+ rsync remote: FAIL+ Exception: init tests failed! cannot continue+ bup remote: FAIL+ Exception: init tests failed! cannot continue+ crypto: FAIL+ Exception: init tests failed! cannot continue+ preferred content: FAIL+ Exception: init tests failed! cannot continue+ add subdirs: FAIL+ Exception: init tests failed! cannot continue+ + 45 out of 78 tests failed+ (This could be due to a bug in git-annex, or an incompatability+ with utilities, such as git, installed on this system.)++### What version of git-annex are you using? On what operating system?+ C:\Users\Andrew\Documents\GitHub\git-annex-test [master]> git --version+ git version 1.8.4.msysgit.0+ C:\Users\Andrew\Documents\GitHub\git-annex-test [master]> git annex version+ git-annex version: 5.20140227-gd872677+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV DNS Feeds Quvi TDFA CryptoHash+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256+ SKEIN512 WORM URL+ remote types: git gcrypt S3 bup directory rsync web webdav tahoe glacier hook external+ local repository version: 5+ supported repository version: 5+ upgrade supported from repository versions: 2 3 4+ C:\Users\Andrew\Documents\GitHub\git-annex-test [master]> (Get-WmiObject -class Win32_OperatingSystem).Caption+ Microsoft Windows 8.1++### Please provide any additional information below.+^^^ See above
+ doc/bugs/git_annex_test_under_windows_8.1.mdwn view
@@ -0,0 +1,67 @@+### Please describe the problem.+I installed git and git annex under Windows (8.1) and ran git annex test. All except one tests passed with "ok"++### What steps will reproduce the problem?+git annex test +under Windows 8.1++### What version of git-annex are you using? On what operating system?+$ git --version+git version 1.9.0.msysgit.0++$ git annex version+git-annex version: 5.20140320-g63535e3+build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV DNS Feeds Quvi TDFA CryptoHash key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL +remote types: git gcrypt S3 bup directory rsync web webdav tahoe glacier hook external local repository version: 5 supported repository version: 5 upgrade supported from repository versions: 2 3 4++Windows 8.1++### 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++ prop_view_roundtrips: FAIL+ *** Failed! Falsifiable (after 814 tests and 5 shrinks):+ "a"+ IMneitta DTaetsat s(+fr o miLniistt: [(MetaField "1\194",fromList [MetaValue (CurrentlySet True) "\r++\231Gb\157\227\ETB\bG",MetaValue (CurrentlySet True) "\DEL\239~\243_p\DC2."]),(+MetaField "EG",fromList [MetaValue (CurrentlySet True) "",MetaValue (CurrentlySe+t True) "\v\205] .T(",MetaValue (CurrentlySet False) "\NAK\128lo\169w",MetaValue+ (CurrentlySet True) "\SYN\STX\ENQ\n#u\ETXv\CANP<F)",MetaValue (CurrentlySet Fal+se) "\US\213~",MetaValue (CurrentlySet False) "K\r3\v\165\&0\RSqk#\141",MetaValu+e (CurrentlySet False) "Kx\b\231\156\220?+\216\v\146",MetaValue (CurrentlySet Tr+ue) "j.\189\150\FS3{\233S\STX\SItg",MetaValue (CurrentlySet True) "\242\248\134\+206\bal\174\135A\SI"]),(MetaField "k",fromList [MetaValue (CurrentlySet True) "\+FS\150\129\b\fhjV\DC3\203",MetaValue (CurrentlySet False) "V.&sZ\245\f\a_\227\14+0",MetaValue (CurrentlySet True) "\136r\ENQK{/\SI'\SYNN\235Q?",MetaValue (Curren+tlySet True) "\179\255\233\227v\SUB]\n8",MetaValue (CurrentlySet True) "\238S\DC+1"]),(MetaField "\179",fromList [MetaValue (CurrentlySet True) "\SOH+\ENQ",MetaV+alue (CurrentlySet True) "\ACK{\140\248I\DLEw^\\\ENQF4",MetaValue (CurrentlySet+False) "\FSc\239\r)HL\STX#V\DC1",MetaValue (CurrentlySet True) "Hc\219\146\230\1+79\207",MetaValue (CurrentlySet False) "I]",MetaValue (CurrentlySet False) "P\19+6\&0o\214\&8iH\251",MetaValue (CurrentlySet True) "`X",MetaValue (CurrentlySet F+alse) "u\DEL\DC3Q\200",MetaValue (CurrentlySet True) "\128?",MetaValue (Currentl+ySet True) "\225\135\f>\128\US~p",MetaValue (CurrentlySet False) "\250C\b\DC1\17+6\154KT\191\SOf?\SI"]),(MetaField "\225a",fromList [MetaValue (CurrentlySet True+) "",MetaValue (CurrentlySet True) "\b\ETB\b",MetaValue (CurrentlySet True) "\f\+161\FS\176h-\ta\169\t",MetaValue (CurrentlySet False) "4",MetaValue (CurrentlySe+t True) "A\FS\244V:\249kl5\ETX\SOH\SI)",MetaValue (CurrentlySet False) "Z",MetaV+alue (CurrentlySet True) "\\Lt~\235v\"\211\DLE\NAK\210",MetaValue (CurrentlySet+False) "a\SYNN",MetaValue (CurrentlySet True) "g:init test repo U5j\167G\ap-\ETX+",MetaValue (CurrentlySet False) "l\NULoW\238rD",MetaValue (CurrentlySet True) "+}\202\141\183Nxr",MetaValue (CurrentlySet False) "\170=\216S\ETB\187\SUB+!\DC3",+MetaValue (CurrentlySet True) "\240H\GS\NAK\ETB\SYNRq\153\&4\204\EOT"])])+ True+ Use --quickcheck-replay '13 347062936 40785707' to reproduce.+ prop_viewedFile_rountrips: OK+ +++ OK, passed 1000 t+e s tDse.t++# End of transcript or log.+"""]]++> A sort of windows-specific bug in the test suite. I've fixed it. [[done]]+> --[[Joey]]
+ doc/bugs/issues_with_non-posix_compatible_shells.mdwn view
@@ -0,0 +1,41 @@+### Please describe the problem.+Some internals of git annex does not check if the shell it is running is Posix-compatible, ie. bash.++I am using fish, and after setting up local pairing, and working, I switched back the login-shell to fish, and when syncing a file, I got this error, read from daemon.log:++fish: Unknown command 'GIT_ANNEX_SHELL_DIRECTORY=/home/s/annex'. Did you mean to run ~/.ssh/git-annex-shell with a modified environment? Try 'env GIT_ANNEX_SHELL_DIRECTORY=/home/s/annex ~/.ssh/git-annex-shell...'. See the help section on the set command by typing 'help set'.+Standard input: GIT_ANNEX_SHELL_DIRECTORY='/home/s/annex' ~/.ssh/git-annex-shell+ ^+fatal: Could not read from remote repository.++Please make sure you have the correct access rights+and the repository exists.++### What steps will reproduce the problem?+Set up local pairing ( I believe having sh/bash as login terminal is necessary for this).+Switch back to fish as login-shell with chsh -s /usr/bin/fish+Add a file to either repository.++### What version of git-annex are you using? On what operating system?+[s@b ~]$ git annex version+git-annex version: 5.20140320-g63535e3+build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi TDFA CryptoHash+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL+remote types: git gcrypt S3 bup directory rsync web webdav tahoe glacier hook external++### 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]] so+> +> I have not tried to make the assistant go back and fix up existing+> `authorized_keys` lines. So if someone had been using a posix shell and+> switched to fish, they'll hit this and need to fix it themselves. I judge+> this is pretty small number of users. --[[Joey]]
+ doc/bugs/problem_to_addurl_--file_with_ftp.mdwn view
@@ -0,0 +1,67 @@+### Please describe the problem.+I want to addurl using ftp protocol.+`git annex addurl ftp://...` works fine, but `git annex addurl --file` fails with an error "failed to verify url exists".++### What steps will reproduce the problem?++setting up a new repo++ % alias ga + ga=/home/applis/git-annex.linux/git-annex + % ga init + init ok + (Recording state in git...) ++addurl --file works with http++ % wget http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz + [...] + 2014-03-27 15:25:06 (10,1 MB/s) - ‘git-annex-standalone-amd64.tar.gz’ saved [30689438/30689438] + % ga add git-annex-standalone-amd64.tar.gz + add git-annex-standalone-amd64.tar.gz ok + (Recording state in git...) + % ga addurl http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz --file git-annex-standalone-amd64.tar.gz + addurl git-annex-standalone-amd64.tar.gz ok + (Recording state in git...) ++addurl works with ftp:++ % ga addurl ftp://ftp.belnet.be/debian-cd/7.4.0-live/i386/iso-hybrid/debian-live-7.4-i386-lxde-desktop.iso.log + addurl ftp.belnet.be_debian_cd_7.4.0_live_i386_iso_hybrid_debian_live_7.4_i386_lxde_desktop.iso.log (downloading ftp://ftp.belnet.be/debian-cd/7.4.0-live/i386/iso-hybrid/debian-live-7.4-i386-lxde-desktop.iso.log ...) + [...] + 2014-03-27 15:27:47 (11,1 MB/s) - ‘/data/annex/.git/annex/tmp/URL--ftp&c%%ftp.belnet.be%debian-cd%7.4.0-live%i386%iso-hybrid%debian-live-7.4-i386-lxde-desktop.iso.log’ saved [1235181] + ok + (Recording state in git...) ++addurl --file doesn't work with ftp++ % wget ftp://ftp.belnet.be/debian-cd/7.4.0-live/i386/iso-hybrid/debian-live-7.4-i386-standard.iso.zsync + [...] + 2014-03-27 15:29:32 (19,4 MB/s) - ‘debian-live-7.4-i386-standard.iso.zsync’ saved [1932014] + % ga add debian-live-7.4-i386-standard.iso.zsync + add debian-live-7.4-i386-standard.iso.zsync ok + (Recording state in git...) + % ga addurl ftp://ftp.belnet.be/debian-cd/7.4.0-live/i386/iso-hybrid/debian-live-7.4-i386-standard.iso.zsync --file debian-live-7.4-i386-standard.iso.zsync + addurl debian-live-7.4-i386-standard.iso.zsync + failed to verify url exists: ftp://ftp.belnet.be/debian-cd/7.4.0-live/i386/iso-hybrid/debian-live-7.4-i386-standard.iso.zsync + failed + git-annex: addurl: 1 failed ++### What version of git-annex are you using? On what operating system?++I am using current git-annex binary linux version on Fedora 19.++ % which git ; git --version + /usr/bin/git + git version 1.8.3.1 + % which ga ; ga version + ga=/home/applis/git-annex.linux/git-annex + git-annex version: 5.20140320-g63535e3 + build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi TDFA CryptoHash + key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL + remote types: git gcrypt S3 bup directory rsync web webdav tahoe glacier hook external + local repository version: 5 + supported repository version: 5 + upgrade supported from repository versions: 0 1 2 4 ++> [[done]] --[[Joey]]
+ doc/bugs/problems_with_glacier.mdwn view
@@ -0,0 +1,65 @@+### Please describe the problem.+Annex errors when copying to glacier.++### What version of git-annex are you using? On what operating system?++OS X 10.9.2 Build 13C64++ git-annex version: 5.20140318-gdcf93d0+ build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi TDFA CryptoHash+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL+ remote types: git gcrypt S3 bup directory rsync web webdav tahoe glacier hook external+ local repository version: 5+ supported repository version: 5+ upgrade supported from repository versions: 0 1 2 4++### 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++> git annex initremote glacier type=glacier encryption=hybrid keyid=E9053BDA datacenter=us-west-1 ║██████████╠ ∞ ∞+initremote glacier (encryption setup) (hybrid cipher with gpg key B608B8F6E9053BDA) ok+(Recording state in git...)+> git annex copy Cobalt\ Strike\ Tradecraft --to=glacier --debug+[2014-03-27 07:27:39 PDT] read: git ["--git-dir=/Users/akraut/Desktop/annexes/media/.git","--work-tree=/Users/akraut/Desktop/annexes/media","show-ref","git-annex"]+[2014-03-27 07:27:39 PDT] read: git ["--git-dir=/Users/akraut/Desktop/annexes/media/.git","--work-tree=/Users/akraut/Desktop/annexes/media","show-ref","--hash","refs/heads/git-annex"]+[2014-03-27 07:27:39 PDT] read: git ["--git-dir=/Users/akraut/Desktop/annexes/media/.git","--work-tree=/Users/akraut/Desktop/annexes/media","log","refs/heads/git-annex..9f59057d857784e6ae6b3dcd6793092264375913","--oneline","-n1"]+[2014-03-27 07:27:39 PDT] chat: git ["--git-dir=/Users/akraut/Desktop/annexes/media/.git","--work-tree=/Users/akraut/Desktop/annexes/media","cat-file","--batch"]+[2014-03-27 07:27:39 PDT] read: git ["config","--null","--list"]+[2014-03-27 07:27:39 PDT] read: git ["--git-dir=/Users/akraut/Desktop/annexes/media/.git","--work-tree=/Users/akraut/Desktop/annexes/media","ls-files","--cached","-z","--","Cobalt Strike Tradecraft"]+copy Cobalt Strike Tradecraft/Tradecraft__1_of_9____Introduction.mp4 (gpg) [2014-03-27 07:27:39 PDT] chat: gpg ["--quiet","--trust-model","always","--decrypt"]++You need a passphrase to unlock the secret key for+user: "Andrew Mark Kraut <akraut@gmail.com>"+4096-bit ELG-E key, ID 353E49B9, created 2008-11-11 (main key ID E9053BDA)++(checking glacier...) [2014-03-27 07:27:46 PDT] read: glacier ["--region=us-west-1","archive","checkpresent","git-annex: Maybe.fromJust: Nothing++# End of transcript or log.+"""]]++> This was a bug introduced last month, it forgot to receord the+> datacenter and vault used when initializing the glacier repository.+> +> I've fixed the bug, but this does not fix repositories created with+> the broken version. I considered just making it use the default+> datacenter and vault for such a repository, but +> a) those may change in the future+> and I don't want to have to worry about breaking such a repository+> going forward and b) someone may have overridden it to use another+> datacenter or vault name and so it shouldn't blindly assume the defaults.+> +> Instead, there's a manual fix up step you need to do. Luckily quite easy.+> For example: +> +> git annex enableremote myglacier datacenter=us-east-1 vault=myglacier-fae9be57-8eb4-47af-932f-136b9b40e669+> +> The default datacenter is us-east-1, and the default vault name is+> "$remotename-$uuid". So you just have to tell it these values+> once with an enableremote command, and it will then work. ++> You don't even need to get the fixed version of git-annex to work+> around the bug this way.. Although it does have better error messages+> too. [[fixed|done]] --[[Joey]]
+ doc/bugs/set_metadata_on_wrong_files.mdwn view
@@ -0,0 +1,90 @@+### Please describe the problem.++For an example I wanted to add different metadata to some test files,+but the outcome is that the last metadata gets applied to all three files. see transcript below.++++### What steps will reproduce the problem?++1. Create a git annex repository+2. add a few files+3. add some metadata to the files, same keys, differnt values+4. watch the metadata, only the last added one is shown for all files+++### What version of git-annex are you using? On what operating system?+ $cat /etc/debian_version; uname -a; git annex version+ 7.4+ Linux jupiter 3.13.0ct #33 SMP PREEMPT Tue Jan 21 05:04:01 CET 2014 x86_64 GNU/Linux+ git-annex version: 5.20140306~bpo70+1+ build flags: Assistant Webapp Pairing S3 Inotify DBus XMPP Feeds Quvi TDFA+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL+ remote types: git gcrypt S3 bup directory rsync web tahoe glacier hook external+ local repository version: 5+ supported repository version: 5+ upgrade supported from repository versions: 0 1 2 4+++### Please provide any additional information below.++Debian/Wheezy with git annex from backports. The test was done in /tmp which is a tmpfs.+++[[!format sh """+$export LC_ALL=C+$mkdir /tmp/annextest+$cd /tmp/annextest+$git init+Initialized empty Git repository in /tmp/annextest/.git/+$git annex init+init ok+(Recording state in git...)++$touch a.txt b.txt c.txt+$git annex add a.txt b.txt c.txt+add a.txt ok+add b.txt ok+add c.txt ok+(Recording state in git...)+$git commit -m init+[master (root-commit) 5470bdb] init+ 3 files changed, 3 insertions(+)+ create mode 120000 a.txt+ create mode 120000 b.txt+ create mode 120000 c.txt++$git annex metadata a.txt -s foo=bar -s num=1+metadata a.txt + foo=bar+ num=1+ok+(Recording state in git...)+$git annex metadata b.txt -s foo=baz -s num=2+metadata b.txt + foo=baz+ num=2+ok+(Recording state in git...)+$git annex metadata c.txt -s foo=barf -s num=3+metadata c.txt + foo=barf+ num=3+ok+(Recording state in git...)+$git annex metadata+metadata a.txt + foo=barf+ num=3+ok+metadata b.txt + foo=barf+ num=3+ok+metadata c.txt + foo=barf+ num=3+ok+"""]]++> [[fixed|done]]; documentation improved --[[Joey]]
doc/copies.mdwn view
@@ -30,3 +30,6 @@ With N=2, in order to drop the file content from Laptop, it would need access to both USB and Server.++For more complicated requirements about which repositories contain which+content, see [[required_content]].
doc/design/assistant/polls/prioritizing_special_remotes.mdwn view
@@ -6,7 +6,7 @@ Help me prioritize my work: What special remote would you most like to use with the git-annex assistant? -[[!poll open=yes 16 "Amazon S3 (done)" 12 "Amazon Glacier (done)" 9 "Box.com (done)" 71 "My phone (or MP3 player)" 25 "Tahoe-LAFS" 10 "OpenStack SWIFT" 31 "Google Drive"]]+[[!poll open=yes 16 "Amazon S3 (done)" 12 "Amazon Glacier (done)" 9 "Box.com (done)" 71 "My phone (or MP3 player)" 25 "Tahoe-LAFS" 10 "OpenStack SWIFT" 33 "Google Drive"]] This poll is ordered with the options I consider easiest to build listed first. Mostly because git-annex already supports them and they
doc/design/assistant/telehash.mdwn view
@@ -11,6 +11,9 @@ * Rapid development, situation may change in a month or 2. * Is it secure? A security review should be done by competant people (not Joey). See <https://github.com/telehash/telehash.org/issues/23>+* **Haskell version** + <https://github.com/alanz/htelehash/tree/v2/src/TeleHash>+ Development on v2 in haskell is just starting up! ## implementation basics
doc/design/roadmap.mdwn view
@@ -10,8 +10,8 @@ * Month 4 [[!traillink assistant/windows text="Windows webapp"]], Linux arm, [[!traillink todo/support_for_writing_external_special_remotes]] * Month 5 user-driven features and polishing * Month 6 get Windows out of beta, [[!traillink design/metadata text="metadata and views"]]-* **Month 7 user-driven features and polishing**-* Month 8 [[!traillink assistant/telehash]]+* Month 7 user-driven features and polishing+* **Month 8 [[!traillink assistant/telehash]]** * Month 9 [[!traillink assistant/gpgkeys]] [[!traillink assistant/sshpassword]] * Month 10 get [[assistant/Android]] out of beta * Month 11 [[!traillink assistant/chunks]] [[!traillink assistant/deltas]]
+ doc/devblog/day_139-140__traveling.mdwn view
@@ -0,0 +1,17 @@+Yesterday coded up one nice improvement on the plane -- `git annex unannex`+(and `uninit`) is now tons faster. Before it did a git commit after every+file processed, now there's just 1 commit at the end. This required using+some locking to prevent the `pre-commit` hook from running in a confusing+state.++Today. LibrePlanet and a surprising amount of development. I've+added [[tips/file_manager_integration]], only for Nautilus so far.+The main part of this was adding --notify-start and --notify-finish, which+use dbus desktop notifications to provide feedback. ++(Made possible thanks to Max Rabkin for updating+[fdo-notify](http://hackage.haskell.org/package/fdo-notify) to use the+new dbus library, and ion for developing the initial Nautilus integration+scripts.)++Today's work and LibrePlanet visit was sponsored by Jürgen Lüters.
+ doc/devblog/day_141__f-droid_sprint.mdwn view
@@ -0,0 +1,3 @@+Attended at the f-droid sprint at LibrePlanet, and have been getting a+handle on how their build server works with an eye toward adding git-annex+to it. Not entirely successful getting vagrant to build an image yet.
+ doc/devblog/day_142__digging_out.mdwn view
@@ -0,0 +1,13 @@+Catching up on conference backlog. 36 messages backlog remains.++Fixed `git-annex-shell configlist` to automatically initialize a+git remote when a git-annex branch had been pushed to it. This is necessary+for gitolite to be easy to use, and I'm sure it used to work.++Updated the Debian backport and made a Debian package of the+fdo-notify haskell library used for notifications.++Applied a patch from Alberto Berti to fix support for tahoe-lafs+1.10.++And various other bug fixes and small improvements.
+ doc/devblog/day_143__foolish_hiatus.mdwn view
@@ -0,0 +1,20 @@+Last week's trip was productive, but I came home more tired than I+realized. Found myself being snappy & stressed, so I have been on break.++I did do a little git-annex dev in the past 5 days. On Saturday I+implemented [[todo/preferred_content]] (although without the active checks+I think it probably ought to have.) Yesterday I had a long conversation+with the Tahoe developers about improving git-annex's tahoe integration.++Today, I have been wrapping up [building propellor](http://joeyh.name/code/propellor/).+To test its docker support, I used propellor to build and deploy a+container that is a git-annex autobuilder. I'll be replacing the old+autobuilder setup with this shortly, and expect to also publish docker+images for git-annex autobuilders, so anyone who wants to can run their+own autobuilder really easily.++---++I have April penciled in on the roadmap as the month to do telehash.+I don't know if telehash-c is ready for me yet, but it has had a lot of+activity lately, so this schedule may still work out!
+ doc/devblog/day_144__catching_up.mdwn view
@@ -0,0 +1,12 @@+Got caught up on all recent bugs and questions, although I still have a+backlog of 27 older things that I really should find time for.++Fixed a couple of bugs. One was that the assistant set up ssh+`authorized_keys` that didn't work with the fish shell.++Also got caught up on the current state of telehash-c. Have not quite+gotten it to work, but it seems pretty close to being able to see it do+something useful for the first time.++Pushing out a release this evening with a good number of changes left over+from March.
+ doc/forum/Generating_a_Temp_View_of_Available_Files.mdwn view
@@ -0,0 +1,1 @@+Is it possible to generate a view of files currently available on the annex? My use case is that I have pretty large repo (couple of TBs) and I have partial checkouts on multiple machines instead of seeing 100s of broken symlinks I would like to just filter filter files that are present on the machine?
+ doc/forum/faking_location_information.mdwn view
@@ -0,0 +1,19 @@+Hi++I am using git-annex even if people I exchange data with (currently) don‘t use it for there data. My idea behind this is that I would like to know from where I got a file, whom I gave a file and who does (probably) still have a copy of the file. To do this you need to trick git-annex location tracking feature a bit. I successfully managed to achieve this in a simple data exchange which only consisted of me coping over files to one of my git-annex repos. I did the following to make git-annex believe that the files are in two repos without the need to *copy* them around the repos.++This is what I did in this simple case:++1. mounted the drive from someone+2. made a clone of my git-annex repo on the filesystem which should hold the copy of the data+3. initialized the cloned repo with `git annex init "Drive from person X"`+4. imported the files to the cloned repo with `git annex import --duplicate $path_to_files_from_person_x`+5. `git annex sync` in the cloned repo+6. `git annex sync` in main repo+7. `git annex move . --to origin` in the cloned repo++The impotent part (and the limit) here was that you can not sync these two repos after you moved files to the main repo. The problem is that there will be situations where I will have to sync them also after moving files around (for example if I want to store new files in multiple repos (and not just one main repo), or if I also want to copy files over to drives from someone).++Note: I have also worked out a solution to allow someone to choose which files he/she would like to get as described [on superuser.com](http://superuser.com/a/717689).++Are there better ways to fake location information then the thing I came up with (except making multiple repos for one person/drive)? Can multiple remotes be merged to one remote?
+ doc/forum/ignore_changes_made_by_a_remote.mdwn view
@@ -0,0 +1,8 @@+Hi,++I have two repo one in direct (on windows) and one in indirect mode. From time to time the files in the direct repo are replaced by empty files however running git annex fsck always solves it.+The problem is that today I did run git annex sync before running git annex fsck and git annex has then created two -variants for each of my files one empty and one with the content.+I guess the easier for me is to just scrap that repo and make a new one however how do I prevent the changes to propagate now? I guess that if I now run git annex sync on my other repo all those small files are going to have linked created for them there as well.++I hope this is clear,+Thanks in advance.
+ doc/forum/telehash_syncing.mdwn view
@@ -0,0 +1,10 @@+Hi++I have read some info about telehash. It looks verry promising. I was wondering though how syncing will work. For example. I have 2 computers. Normal PC and a laptop. Mostly only one is on at a time. ++* Sync messages will be sent over telehash protocoll ?+* What if I push some changes (they will be synced to a shared repository) and laptop is not online. How will git-annex know what to sync from a shared repository ?+* Do you plan to send files/commits directly to online clients ? If 2 friends are online at the same time.+* What will happen with data on a shared repository if all clients have synced content ? Will it be deleted since it is not longer needed ?++I was thinking of a model where you sync directly (if possible), and just drop shared content to repo for offline users. Whan everyone have pulled content it may be removed from shared repo.
@@ -0,0 +1,15 @@+I have no idea how to search for this here, so I'll just go the "lazy web" approach and just ask.++Say I have two "conference" repos. One is the famous [conference procedings](https://github.com/RichiH/conference_proceedings) repo, and another one is a totally unrelated repo of local conferences that are not of world-wide significance. Let's call this second repo `presentations`.++I would like to have my videos of both repos in a single repo.++Can I add the `conference procedings` repo as a git remote to the `presentations` repo and have it do the right thing?++In fact, I'm not even sure what the right thing would be here, I guess that's the first thing I would like to clear up. But I would like to do things like what the new [[metadata]] system does. For example, I would have only the "Debian" directory from `conference procedings` in my `presentations` repo.++How would that work? Would I need to do some [subtree merging](http://git-scm.com/book/ch6-7.html) magic? or `git subtree`? or submodules? or should i just use myrepos and pretend I never brought up this idea?++thanks! -- [[anarcat]]++related: [[tips/migrating_two_seperate_disconnected_directories_to_git_annex/]] - but that creates a merged repo...
+ doc/forum/view_from_numeric_values.mdwn view
@@ -0,0 +1,9 @@+Hi Joey,++it would be nice when views could take numeric comparisons as filters.++ git annex metadata -s length=273.0 john_cage_4_33.mp3++ git annex view length<=300++... here is the catch, < and > don't work well in shell, this needs some other Syntax. I think the underlying machinery (using numeric comparisons instead globs) should be quite trivial. Any Ideas about a Syntax?
+ doc/forum/view_including_files_with_no_tags.mdwn view
@@ -0,0 +1,5 @@+Hi++Is it possible to create a view which also includes files with no tag?++I use something like `git annex view 'rating=*'` to view files sorted by rating but this view does not include files which don‘t have a rating yet. What I was looking for is a way to show tagged files and untagged files in one view.
doc/git-annex-shell.mdwn view
@@ -26,7 +26,12 @@ * configlist directory This outputs a subset of the git configuration, in the same form as- `git config --list`+ `git config --list`. This is used to get the annex.uuid of the remote+ repository.++ When run in a repository that does not yet have an annex.uuid, one+ will be created, as long as a git-annex branch has already been pushed to+ the repository. * inannex directory [key ...]
doc/git-annex.mdwn view
@@ -62,11 +62,15 @@ * `add [path ...]` - Adds files in the path to the annex. Files that are already checked into- git, or that git has been configured to ignore will be silently skipped.- (Use `--force` to add ignored files.) Dotfiles are skipped unless explicitly- listed.+ Adds files in the path to the annex. If no path is specified, adds+ files from the current directory and below.+ + Files that are already checked into git, or that git has been configured+ to ignore will be silently skipped. (Use `--force` to add ignored files.) + Dotfiles are skipped unless explicitly listed, or the --include-dotfiles+ option is used.+ * `get [path ...]` Makes the content of annexed files available in this repository. This@@ -707,8 +711,9 @@ * `metadata [path ...] [-s field=value -s field+=value -s field-=value ...] [-g field]` - Each file can have any number of metadata fields attached to it,- which each in turn have any number of values. + The content of a file can have any number of metadata fields + attached to it to describe it. Each metadata field can in turn+ have any number of values. This command can be used to set metadata, or show the currently set metadata.@@ -1053,6 +1058,19 @@ Overrides the User-Agent to use when downloading files from the web. +* `--notify-finish`++ Caused a desktop notification to be displayed after each successful+ file download and upload.++ (Only supported on some platforms, eg Linux with dbus. A no-op when+ not supported.)++* `--notify-start`++ Caused a desktop notification to be displayed when a file upload+ or download has started, or when a file is dropped.+ * `-c name=value` Overrides git configuration settings. May be specified multiple times.@@ -1697,7 +1715,7 @@ `~/.config/git-annex/autostart` is a list of git repositories to start the git-annex assistant in. -`.git/hooks/pre-commit-annex` in your git repsitory will be run whenever+`.git/hooks/pre-commit-annex` in your git repository will be run whenever a commit is made, either by git commit, git-annex sync, or the git-annex assistant.
doc/install.mdwn view
@@ -14,6 +14,7 @@ [[Gentoo]] | `emerge git-annex` [[ScientificLinux5]] | [[openSUSE]] | + [[Docker]] | [[Windows]] | [download installer](http://downloads.kitenet.net/git-annex/windows/current/) **alpha** """]]
+ doc/install/ArchLinux/comment_6_1d597d6a95f9c2df7dae6e98813e4865._comment view
@@ -0,0 +1,36 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawmqWbWVRH2k9spSMqKfIXBP1G3ekkj9Igg"+ nickname="Rado"+ subject="problem installing using cabal: language-javascript missing"+ date="2014-03-28T22:38:04Z"+ content="""+Configuring gnuidn-0.2.1...+cabal: The program c2hs is required but it could not be found.+Failed to install gnuidn-0.2.1+Configuring language-javascript-0.5.9...+cabal: The program happy version >=1.18.5 is required but it could not be+found.+Failed to install language-javascript-0.5.9+cabal: Error: some packages failed to install:+git-annex-5.20140320 depends on language-javascript-0.5.9 which failed to+install.+gnuidn-0.2.1 failed during the configure step. The exception was:+ExitFailure 1+hjsmin-0.1.4.6 depends on language-javascript-0.5.9 which failed to install.+language-javascript-0.5.9 failed during the configure step. The exception was:+ExitFailure 1+network-protocol-xmpp-0.4.6 depends on gnuidn-0.2.1 which failed to install.+yesod-static-1.2.2.4 depends on language-javascript-0.5.9 which failed to+install.+[r-c@rc-laptop ~]$ cabal install language-javascript+Resolving dependencies...+Configuring language-javascript-0.5.9...+cabal: The program happy version >=1.18.5 is required but it could not be+found.+Failed to install language-javascript-0.5.9+cabal: Error: some packages failed to install:+language-javascript-0.5.9 failed during the configure step. The exception was:+ExitFailure 1++Can you help how to solve?+"""]]
+ doc/install/ArchLinux/comment_7_2d708977e2fad6b68803494576382df5._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="http://alerque.com/"+ nickname="Caleb"+ subject="dep problems"+ date="2014-03-28T22:50:37Z"+ content="""+@rado The Haskel dependencies can be a nightmare to sort out for the un-initiated. You can side-step the whole issue by uninstalling the pre-built version that that has all the dependencies built in out of the box.++Just grab the git-annex-bin package from the AUR and be done with it. (The -bin and -standalone packages recently merged so there is just -bin now).+"""]]
+ doc/install/ArchLinux/comment_8_5b5f5e0b64e5bfb1ea12e8b251c6fb5f._comment view
@@ -0,0 +1,15 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawmqWbWVRH2k9spSMqKfIXBP1G3ekkj9Igg"+ nickname="Rado"+ subject="I solved it installing dependencies....but dont know hot to start it..."+ date="2014-03-29T07:45:19Z"+ content="""+cabal install gsasl+cabal install happy+cabal install language-javascript+cabal install alex+cabal install c2hs++after installing writing in terminal: git-annex, git-annex webapp does nothing...+can you help how to start git-annex?+"""]]
+ doc/install/Docker.mdwn view
@@ -0,0 +1,27 @@+There is not yet a pre-built Docker image for git-annex. However, it's+easy to add it to an image.++For example:++ docker run -i -t joeyh/debian-unstable apt-get install git-annex++# autobuilders++The git-annex Linux autobuilds are built using a Docker container.+If you'd like to set up your own autobuilder in a Docker container,+the image that is used is not currently published, but you can build+a new image using [Propellor](http://joeyh.name/code/propellor). Just+install Propellor and add this to its `config.hs`:++[[!format haskell """+host hostname@"your.machine.net" = Just $ props+ & Docker.configured+ & Docker.docked container hostname "amd64-git-annex-builder"++container _ "amd64-git-annex-builder" = in Just $ Docker.containerFrom+ (image $ System (Debian Unstable) "amd64")+ [ Docker.inside $ props & GitAnnexBuilder.builder "amd64" "15 * * * *" False ]+"""]]++This will autobuild every hour at :15, and the autobuilt image will be+left inside the container in /home/builder/gitbuilder/out/
doc/internals.mdwn view
@@ -150,6 +150,13 @@ repository, while files not matching it are preferred to be stored somewhere else. +## `required-content.log`++Used to indicate which repositories are required to contain which file+contents.++File format is identical to preferred-content.log.+ ## `group-preferred-content.log` Contains standard preferred content settings for groups. (Overriding or
doc/metadata.mdwn view
@@ -1,7 +1,7 @@-git-annex allows you to store arbitrary metadata about files stored in the-git-annex repository. The metadata is stored in the `git-annex` branch, and-so is automatically kept in sync with the rest of git-annex's state, such-as [[location_tracking]] information.+git-annex allows you to store arbitrary metadata about the content of files+stored in the git-annex repository. The metadata is stored in the+`git-annex` branch, and so is automatically kept in sync with the rest of+git-annex's state, such as [[location_tracking]] information. Some of the things you can do with metadata include:
+ doc/news/version_5.20140402.mdwn view
@@ -0,0 +1,34 @@+git-annex 5.20140402 released with [[!toggle text="these changes"]]+[[!toggleable text="""+ * unannex, uninit: Avoid committing after every file is unannexed,+ for massive speedup.+ * --notify-finish switch will cause desktop notifications after each+ file upload/download/drop completes+ (using the dbus Desktop Notifications Specification)+ * --notify-start switch will show desktop notifications when each+ file upload/download starts.+ * webapp: Automatically install Nautilus integration scripts+ to get and drop files.+ * tahoe: Pass -d parameter before subcommand; putting it after+ the subcommand no longer works with tahoe-lafs version 1.10.+ (Thanks, Alberto Berti)+ * forget --drop-dead: Avoid removing the dead remote from the trust.log,+ so that if git remotes for it still exist anywhere, git annex info+ will still know it's dead and not show it.+ * git-annex-shell: Make configlist automatically initialize+ a remote git repository, as long as a git-annex branch has+ been pushed to it, to simplify setup of remote git repositories,+ including via gitolite.+ * add --include-dotfiles: New option, perhaps useful for backups.+ * Version 5.20140227 broke creation of glacier repositories,+ not including the datacenter and vault in their configuration.+ This bug is fixed, but glacier repositories set up with the broken+ version of git-annex need to have the datacenter and vault set+ in order to be usable. This can be done using git annex enableremote+ to add the missing settings. For details, see+ http://git-annex.branchable.com/bugs/problems\_with\_glacier/+ * Added required content configuration.+ * assistant: Improve ssh authorized keys line generated in local pairing+ or for a remote ssh server to set environment variables in an+ alternative way that works with the non-POSIX fish shell, as well+ as POSIX shells."""]]
doc/preferred_content.mdwn view
@@ -1,7 +1,7 @@ git-annex tries to ensure that the configured number of [[copies]] of your data always exist, and leaves it up to you to use commands like `git annex get` and `git annex drop` to move the content to the repositories you want-to contain it. But sometimes, it can be good to have more fine-grained+to contain it. But often, it can be good to have more fine-grained control over which content is wanted by which repositories. Configuring this allows the git-annex assistant as well as `git annex get --auto`, `git annex drop --auto`, `git annex sync --content`,@@ -33,9 +33,9 @@ To check at the command line which files are matched by preferred content settings, you can use the --want-get and --want-drop options. -For example, "git annex find --want-get --not --in ." will find all the-files that "git annex get --auto" will want to get, and "git annex find---want-drop --in ." will find all the files that "git annex drop --auto"+For example, `git annex find --want-get --not --in .` will find all the+files that `git annex get --auto` will want to get, and `git annex find+--want-drop --in .` will find all the files that `git annex drop --auto` will want to drop. The expressions are very similar to the matching options documented
@@ -11,4 +11,5 @@ utility, with a `-A` switch that enables git-annex support. * Emacs Org mode can auto-commit attached files to git-annex. * [git annex darktable integration](https://github.com/xxv/darktable-git-annex)-* [Nautilus file manager ingegration](https://gist.github.com/ion1/9660286)+* Emacs's [Magit mode](http://www.emacswiki.org/emacs/Magit) has+ [magit integration](http://melpa.milkbox.net/?utm_source=dlvr.it&utm_medium=twitter#/magit-annex)
+ doc/required_content.mdwn view
@@ -0,0 +1,17 @@+Required content settings can be configured to do more complicated+things than just setting the required number of [[copies]] of your data.+For example, you could require that data be archived in at least two+archival repositories, and also require that one copy be stored offsite.++The format of required content expressions is the same as+[[preferred_content]] expressions.++Required content settings can be edited using `git annex vicfg`.+Each repository can have its own settings, and other repositories will+try to honor those settings when interacting with it.++While [[preferred_content]] expresses a preference, it can be overridden+by simply using `git annex drop`. On the other hand, required content+settings are enforced; `git annex drop` will refuse to drop a file if+doing so would violate its required content settings.+(Although even this can be overridden using `--force`).
doc/special_remotes/tahoe.mdwn view
@@ -22,8 +22,12 @@ These parameters can be passed to `git annex initremote` to configure the tahoe remote. +* `shared-convergence-secret` - Optional. Can be useful to set to+ allow tahoe to deduplicate information. By default, a new+ shared-convergence-secret is created for each tahoe remote.+ * `embedcreds` - Optional. Set to "yes" embed the tahoe credentials - (specifically the introducer furl and shared-convergence-secret)+ (specifically the introducer-furl and shared-convergence-secret) inside the git repository, which allows other clones to also use them in order to access the tahoe grid.
doc/tips/automatically_adding_metadata.mdwn view
@@ -17,7 +17,7 @@ Now any fields you list in metadata.extract to will be extracted and stored when files are committed. -To get a list of all possible fields, run: `extract -L | sed ' ' _`+To get a list of all possible fields, run: `extract -L | sed 's/ /_/g'` By default, if a git-annex already has a metadata field for a file, its value will not be overwritten with metadata taken from files.
+ doc/tips/file_manager_integration.mdwn view
@@ -0,0 +1,100 @@+Integrating git-annex and your file manager provides an easy way to select+annexed files to get or drop.++[[!toc]]++## GNOME (nautilus)++Recent git-annex comes with built-in nautilus integration. Just pick the+action from the menu.++[[!img assistant/nautilusmenu.png]]++[[!img assistant/downloadnotification.png]]++This is set up by making simple scripts in+`~/.local/share/nautilus/scripts`, with names like "git-annex get"++## KDE (Dolphin/Konqueror)++Create a file `~/.kde4/share/kde4/services/ServiceMenus/git-annex.desktop` with the following contents:++ [Desktop Entry]+ Type=Service+ ServiceTypes=all/allfiles+ MimeType=all/all;+ Actions=GitAnnexGet;GitAnnexDrop;+ X-KDE-Priority=TopLevel+ X-KDE-Submenu=Git-Annex+ X-KDE-Icon=git-annex+ X-KDE-ServiceTypes=KonqPopupMenu/Plugin++ [Desktop Action GitAnnexGet]+ Name=Get+ Icon=git-annex+ Exec=git-annex get --notify-start --notify-finish -- %U++ [Desktop Action GitAnnexDrop]+ Name=Drop+ Icon=git-annex+ Exec=git-annex drop --notify-start --notify-finish -- %U++## XFCE (Thunar)++XFCE uses the Thunar file manager, which can also be easily configured to allow for custom actions. Just go to the "Configure custom actions..." item in the "Edit" menu, and create a custom action for get and drop with the following commands:++ git-annex drop --notify-start --notify-finish -- %F++for drop, and for get:++ git-annex drop --notify-start --notify-finish -- %F++This gives me the resulting config on disk, in `.config/Thunar/uca.xml`:++ <action>+ <icon>git-annex</icon>+ <name>git-annex get</name>+ <unique-id>1396278104182858-3</unique-id>+ <command>git-annex get --notify-start --notify-finish -- %F</command>+ <description>get the files from a remote git annex repository</description>+ <patterns>*</patterns>+ <directories/>+ <audio-files/>+ <image-files/>+ <other-files/>+ <text-files/>+ <video-files/>+ </action>+ <action>+ <icon>git-annex</icon>+ <name>git-annex drop</name>+ <unique-id>1396278093174843-2</unique-id>+ <command>git-annex drop --notify-start --notify-finish -- %F</command>+ <description>drop the files from the local repository</description>+ <patterns>*</patterns>+ <directories/>+ <audio-files/>+ <image-files/>+ <other-files/>+ <text-files/>+ <video-files/>+ </action>++The complete instructions on how to setup actions is [in the XFCE documentation](http://docs.xfce.org/xfce/thunar/custom-actions).++## your file manager here++Edit this page and add instructions!++## general++If your file manager can run a command on a file, it should be easy to+integrate git-annex with it. A simple script will suffice:++ #!/bun/sh+ git-annex get --notify-start --notify-finish -- "$@"++The --notify-start and --notify-stop options make git-annex display a+desktop notification. This is useful to give the user an indication that+their action took effect. Desktop notifications are currently only+implenented for Linux.
doc/todo.mdwn view
@@ -1,4 +1,4 @@-This is git-annex's todo list. Link items to [[todo/done]] when done.+This is git-annex's todo list. Link items to [[todo/done]] when done. A more complete [[design/roadmap/]] is also available. [[!inline pages="./todo/* and !./todo/done and !link(done) and !*/Discussion" actions=yes postform=yes show=0 archive=yes]]
doc/todo/Bittorrent-like_features.mdwn view
@@ -29,6 +29,8 @@ This was originally posted [[as a forum post|forum/Wishlist:_Bittorrent-like_transfers]] by [[users/GLITTAH]]. +Update: note how [[design/assistant/telehash/]] may be able to answer this specific use case.+ Using an external client (addurl torrent support) =================================================
doc/todo/New_special_remote_suggeston_-_clean_directory.mdwn view
@@ -13,3 +13,11 @@ First and foremost, this can't be (really really shouldn't be) a trusted remote; my wife could accidentally delete all files on the NAS while I am away. So my local git-annex shouldn't assume the NAS counts towards numcopies (unless I'm a real masochist). Secondly, what to do when files change/are added/removed on the special remote? Probably the same thing that the assistant does with everything. The only thing special is that new/modified files will need to be copied locally from this special remote before being added to the annex (to get hash and such).++> This is not feaisble given git-annex's design. If I wanted to+> make something completely unlike git-annex, I suppose it could be done,+> but it's off topic here. [[wontfix|done]]. +>+> If you want to use git-annex on a Synology NAS, the arm standalone build+> will work, and then you can use the command-line, or the assistant+> to maintain a git repository that contains your files as desired. --[[Joey]]
+ doc/todo/Pause_all_transfers_in_all_annexes_watched_by_the_assistant.mdwn view
@@ -0,0 +1,11 @@+## Use case:++You have a few annexes that the assistant is watching for you. You're somewhere with poor wifi speed. You also just added a bunch of big files to a few annexes. Now all of a sudden your connection suffers and you want an easy way to pause all transfers until you're on a faster connection without losing the automatic 'add' and such of the assistant (iow: without having to shutdown the daemon).++## Proposal:++A "Pause all transfers" button in the webapp that pauses all transfers from all annexes the assistant is watching.++It should toggle to "Resume all transfers" when pushed so you can also easily start the transfers again when you get somewhere else.++This may or may not make more sense if the webapp showed all watched repos in a single view (instead of the separate pages/views as it is now).
doc/todo/Views_Demo.mdwn view
@@ -11,3 +11,5 @@ FWIW, Bob++> [[closing|done]]; requested feature was already present --[[Joey]]
+ doc/todo/clear_file_names_in_special_remotes.mdwn view
@@ -0,0 +1,13 @@+To properly use amazon AWS S3 for CDN, we need to publish videos to S3. Ideally, we would like to do this via git-annex as the back-end of video.debian.net is being migrated to git-annex by me, atm.++Obviously, we will need clear text names and proper directory structure, not SHA512E file names. This would need to be supported by the S3 special remote.++I talked to TobiasTheViking in the past and he hinted at a reasonably clean way to do this, but that a clean solution would need support from git-annex. I will link him to this page and ask him to supply whatever info is needed.+++Thanks,+Richard++> This is not feaisble given git-annex's design. If I wanted to+> make something completely unlike git-annex, I suppose it could be done,+> but it's off topic here. [[wontfix|done]] --[[Joey]]
doc/todo/required_content.mdwn view
@@ -5,3 +5,19 @@ For example, I might want a repository that is required to contain `*.jpeg`. This would make get --auto get it (it's implicitly part of the preferred content), and would make drop refuse to drop it.++> I've implemented the basic required content. Currently only configurable+> via `vicfg`, because I don't think a lot of people are going to want to+> use it.+> +> Note that I did not yet add the active verification discussed below.+> So if required content is set to `not inallgroup=backup`, or+> `not copies=10`, trying to drop a file will not go off and prove+> that there are 10 copies or that the file is in every repository in +> the backup group. It will assume that the location log is accurate+> and go by that.+> +> I think this is enough to cover Richard's case, at least.+> In his example, A B and C are in group anchor and have required+> content set to `include=*`, and D E F have it set to+> `not inallgroup=anchor`. --[[Joey]]
doc/todo/tahoe_lfs_for_reals.mdwn view
@@ -12,10 +12,12 @@ To support a special remote, a mapping is needed from git-annex keys to Tahoe keys, stored in the git-annex branch. -> This is now done, however, there are 2 known+> This is now done, however, there are 3 known > problems: > > * tahoe start run unncessarily <https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2149> > * web.port can conflict <https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2147>-> +> * Nothing renews leases, which is a problem on grids that expire.+> <https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2212>+ > --[[Joey]]
+ doc/todo/using_file_metadata_for_preferred___40__wanted__41___content.mdwn view
@@ -0,0 +1,12 @@+Having the option of choosing for every file if we want it in our repository or not would be a great feature. It is currently possible using the wanted expression, but it is not very flexible, or it becomes unmaintainable.++I tried with two repositories a and b, with the following wanted expressions :++* for a: `not metadata=unwanted=<uuid-of-a>`+* for b: `not metadata=unwanted=<uuid-of-b>`++I think those expressions should be included in standard wanted expressions.++Also, to improbe the feature, it should be possible to set (or remove) metadata in directories, and those should automatically affect their content.++And we could imagine a `git annex unwant` command that would add the unwanted metadata to a file, copy it to other repositories, and attempt to drop it.
git-annex-shell.1 view
@@ -22,7 +22,12 @@ .PP .IP "configlist directory" This outputs a subset of the git configuration, in the same form as-\fBgit config \-\-list\fP+\fBgit config \-\-list\fP. This is used to get the annex.uuid of the remote+repository.+.IP+When run in a repository that does not yet have an annex.uuid, one+will be created, as long as a git\-annex branch has already been pushed to+the repository. .IP .IP "inannex directory [key ...]" This checks if all specified keys are present in the annex,
git-annex.1 view
@@ -57,11 +57,15 @@ subdirectories). .PP .IP "\fBadd [path ...]\fP"-Adds files in the path to the annex. Files that are already checked into-git, or that git has been configured to ignore will be silently skipped.-(Use \fB\-\-force\fP to add ignored files.) Dotfiles are skipped unless explicitly-listed.+Adds files in the path to the annex. If no path is specified, adds+files from the current directory and below. .IP+Files that are already checked into git, or that git has been configured+to ignore will be silently skipped. (Use \fB\-\-force\fP to add ignored files.)+.IP+Dotfiles are skipped unless explicitly listed, or the \-\-include\-dotfiles+option is used.+.IP .IP "\fBget [path ...]\fP" Makes the content of annexed files available in this repository. This will involve copying them from another repository, or downloading them,@@ -652,8 +656,9 @@ .SH METADATA COMMANDS .IP "\fBmetadata [path ...] [\-s field=value \-s field+=value \-s field\-=value ...] [\-g field]\fP" .IP-Each file can have any number of metadata fields attached to it,-which each in turn have any number of values. +The content of a file can have any number of metadata fields +attached to it to describe it. Each metadata field can in turn+have any number of values. .IP This command can be used to set metadata, or show the currently set metadata.@@ -959,6 +964,17 @@ .IP "\fB\-\-user\-agent=value\fP" Overrides the User\-Agent to use when downloading files from the web. .IP+.IP "\fB\-\-notify\-finish\fP"+Caused a desktop notification to be displayed after each successful+file download and upload.+.IP+(Only supported on some platforms, eg Linux with dbus. A no\-op when+not supported.)+.IP+.IP "\fB\-\-notify\-start\fP"+Caused a desktop notification to be displayed when a file upload+or download has started, or when a file is dropped.+.IP .IP "\fB\-c name=value\fP" Overrides git configuration settings. May be specified multiple times. .IP@@ -1519,7 +1535,7 @@ \fB~/.config/git\-annex/autostart\fP is a list of git repositories to start the git\-annex assistant in. .PP-\fB.git/hooks/pre\-commit\-annex\fP in your git repsitory will be run whenever+\fB.git/hooks/pre\-commit\-annex\fP in your git repository will be run whenever a commit is made, either by git commit, git\-annex sync, or the git\-annex assistant. .PP
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 5.20140320+Version: 5.20140402 Cabal-Version: >= 1.8 License: GPL-3 Maintainer: Joey Hess <joey@kitenet.net>@@ -85,6 +85,9 @@ Flag CryptoHash Description: Enable use of cryptohash for checksumming +Flag DesktopNotify+ Description: Enable desktop environment notifications+ Flag EKG Description: Enable use of EKG to monitor git-annex as it runs (at http://localhost:4242/) Default: False@@ -167,10 +170,16 @@ CPP-Options: -DWITH_KQUEUE C-Sources: Utility/libkqueue.c - if os(linux) && flag(Dbus)- Build-Depends: dbus (>= 0.10.3)- CPP-Options: -DWITH_DBUS+ if (os(linux))+ if flag(Dbus)+ Build-Depends: dbus (>= 0.10.3)+ CPP-Options: -DWITH_DBUS + if flag(DesktopNotify)+ if flag(Dbus)+ Build-Depends: dbus (>= 0.10.3), fdo-notify (>= 0.3)+ CPP-Options: -DWITH_DESKTOP_NOTIFY -DWITH_DBUS_NOTIFICATIONS+ if flag(Android) Build-Depends: data-endian CPP-Options: -D__ANDROID__ -DANDROID_SPLICES -D__NO_TH__@@ -182,11 +191,10 @@ yesod, yesod-default, yesod-static, yesod-form, yesod-core, http-types, transformers, wai, wai-logger, warp, warp-tls, blaze-builder, crypto-api, hamlet, clientsession,- template-haskell, data-default, aeson, network-conduit,- byteable+ template-haskell, data-default, aeson, network-conduit CPP-Options: -DWITH_WEBAPP if flag(Webapp) && flag (Webapp-secure)- Build-Depends: warp-tls (>= 1.4), securemem+ Build-Depends: warp-tls (>= 1.4), securemem, byteable CPP-Options: -DWITH_WEBAPP_SECURE if flag(Pairing)
+ standalone/android/haskell-patches/unbounded-delays_crossbuild.patch view
@@ -0,0 +1,25 @@+From 0ad071f80ee72e7b8ca5b0b70dfae5bbf8677969 Mon Sep 17 00:00:00 2001+From: Joey Hess <joey@kitenet.net>+Date: Wed, 12 Mar 2014 12:18:17 -0400+Subject: [PATCH] cross build++---+ unbounded-delays.cabal | 2 +-+ 1 file changed, 1 insertion(+), 1 deletion(-)++diff --git a/unbounded-delays.cabal b/unbounded-delays.cabal+index 76d0a50..0f27569 100644+--- a/unbounded-delays.cabal++++ b/unbounded-delays.cabal+@@ -1,7 +1,7 @@+ name: unbounded-delays+ version: 0.1.0.6+ cabal-version: >= 1.6+-build-type: Custom++build-type: Simple+ author: Bas van Dijk <v.dijk.bas@gmail.com>+ Roel van Dijk <vandijk.roel@gmail.com>+ maintainer: Bas van Dijk <v.dijk.bas@gmail.com>+-- +1.7.10.4+
standalone/android/install-haskell-packages view
@@ -108,6 +108,7 @@ patched gnutls patched libxml-sax patched network-protocol-xmpp+ patched unbounded-delays cd ..