git-annex 3.20121010 → 3.20121016
raw patch · 55 files changed
+604/−207 lines, 55 filesbinary-added
Files
- Annex/Ssh.hs +6/−0
- Assistant/DaemonStatus.hs +11/−12
- Assistant/MakeRemote.hs +1/−0
- Assistant/Sync.hs +1/−1
- Assistant/Threads/MountWatcher.hs +1/−1
- Assistant/Threads/Pusher.hs +1/−1
- Assistant/Threads/TransferScanner.hs +7/−3
- Assistant/Threads/TransferWatcher.hs +2/−2
- Assistant/TransferQueue.hs +2/−2
- Assistant/WebApp.hs +1/−1
- Assistant/WebApp/Configurators.hs +1/−1
- Assistant/WebApp/Configurators/Edit.hs +35/−26
- Assistant/WebApp/Configurators/Local.hs +2/−3
- Assistant/WebApp/Configurators/Ssh.hs +1/−1
- Assistant/WebApp/Utility.hs +1/−1
- CHANGELOG +20/−0
- Command/Assistant.hs +1/−1
- Command/Help.hs +51/−0
- Command/Vicfg.hs +32/−45
- Command/WebApp.hs +1/−1
- Git/Config.hs +20/−14
- Git/Construct.hs +2/−1
- Git/CurrentRepo.hs +9/−6
- GitAnnex.hs +2/−0
- GitAnnexShell.hs +4/−5
- Logs/PreferredContent.hs +2/−2
- Makefile +10/−4
- Types/StandardGroups.hs +1/−1
- Utility/Directory.hs +1/−12
- Utility/Gpg.hs +3/−3
- Utility/Matcher.hs +10/−11
- Utility/Misc.hs +16/−2
- debian/changelog +20/−0
- doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh.mdwn +43/−0
- doc/bugs/gix-annex_help_is_homicidal.mdwn +23/−0
- doc/bugs/submodule_path_problem.mdwn +56/−0
- doc/design/assistant/blog/.day_107__memory_leak.mdwn.swp binary
- doc/design/assistant/blog/day_104__foo.mdwn +0/−15
- doc/design/assistant/blog/day_104__misc.mdwn +18/−0
- doc/design/assistant/blog/day_105__lazy_Sunday.mdwn +43/−0
- doc/design/assistant/blog/day_106__lazy_Monday.mdwn +10/−0
- doc/design/assistant/blog/day_107__memory_leak.mdwn +11/−0
- doc/design/assistant/polls/prioritizing_special_remotes.mdwn +1/−1
- doc/design/assistant/transfer_control.mdwn +40/−12
- doc/design/assistant/webapp.mdwn +2/−6
- doc/forum/Can__39__t_init_git_annex.mdwn +15/−0
- doc/news/version_3.20120825.mdwn +0/−6
- doc/news/version_3.20121016.mdwn +17/−0
- doc/preferred_content.mdwn +7/−1
- doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment +32/−0
- doc/todo/wishlist:_An_option_like_--git-dir.mdwn +3/−0
- git-annex.cabal +1/−1
- templates/configurators/adddrive.hamlet +1/−1
- templates/configurators/editrepository.hamlet +1/−1
- test.hs +2/−0
Annex/Ssh.hs view
@@ -5,6 +5,8 @@ - Licensed under the GNU GPL version 3 or higher. -} +{-# LANGUAGE CPP #-}+ module Annex.Ssh ( sshParams, sshCleanup,@@ -52,9 +54,13 @@ , return (Nothing, []) ) where+#ifdef WITH_OLD_SSH+ caching = return False+#else caching = fromMaybe SysConfig.sshconnectioncaching . Git.Config.isTrue <$> getConfig (annexConfig "sshcaching") ""+#endif cacheParams :: FilePath -> [CommandParam] cacheParams socketfile =
Assistant/DaemonStatus.hs view
@@ -41,8 +41,8 @@ -- Messages to display to the user. , alertMap :: AlertMap , lastAlertId :: AlertId- -- Ordered list of remotes to talk to.- , knownRemotes :: [Remote]+ -- Ordered list of remotes to sync with.+ , syncRemotes :: [Remote] -- Pairing request that is in progress. , pairingInProgress :: Maybe PairingInProgress -- Broadcasts notifications about all changes to the DaemonStatus@@ -89,21 +89,20 @@ return b {- Syncable remotes ordered by cost. -}-calcKnownRemotes :: Annex [Remote]-calcKnownRemotes = do+calcSyncRemotes :: Annex [Remote]+calcSyncRemotes = do rs <- filterM (repoSyncable . Remote.repo) =<< concat . Remote.byCost <$> Remote.enabledRemoteList alive <- snd <$> trustPartition DeadTrusted (map Remote.uuid rs) let good r = Remote.uuid r `elem` alive return $ filter good rs -{- Updates the cached ordered list of remotes from the list in Annex- - state. -}-updateKnownRemotes :: DaemonStatusHandle -> Annex ()-updateKnownRemotes dstatus = do- remotes <- calcKnownRemotes+{- Updates the sycRemotes list from the list of all remotes in Annex state. -}+updateSyncRemotes :: DaemonStatusHandle -> Annex ()+updateSyncRemotes dstatus = do+ remotes <- calcSyncRemotes liftIO $ modifyDaemonStatus_ dstatus $- \s -> s { knownRemotes = remotes }+ \s -> s { syncRemotes = remotes } {- Load any previous daemon status file, and store it in a MVar for this - process to use as its DaemonStatus. Also gets current transfer status. -}@@ -113,12 +112,12 @@ status <- liftIO $ flip catchDefaultIO (readDaemonStatusFile file) =<< newDaemonStatus transfers <- M.fromList <$> getTransfers- remotes <- calcKnownRemotes+ remotes <- calcSyncRemotes liftIO $ atomically $ newTMVar status { scanComplete = False , sanityCheckRunning = False , currentTransfers = transfers- , knownRemotes = remotes+ , syncRemotes = remotes } {- Don't just dump out the structure, because it will change over time,
Assistant/MakeRemote.hs view
@@ -93,6 +93,7 @@ g <- gitRepo if not (any samelocation $ Git.remotes g) then do+ let name = uniqueRemoteName basename 0 g a name return name
Assistant/Sync.hs view
@@ -156,5 +156,5 @@ {- Start syncing a newly added remote, using a background thread. -} syncNewRemote :: ThreadState -> DaemonStatusHandle -> ScanRemoteMap -> Remote -> IO () syncNewRemote st dstatus scanremotes remote = do- runThreadState st $ updateKnownRemotes dstatus+ runThreadState st $ updateSyncRemotes dstatus void $ forkIO $ reconnectRemotes "SyncRemote" st dstatus scanremotes [remote]
Assistant/Threads/MountWatcher.hs view
@@ -174,7 +174,7 @@ let (waschanged, rs') = unzip pairs when (any id waschanged) $ do Annex.changeState $ \s -> s { Annex.remotes = rs' }- updateKnownRemotes dstatus+ updateSyncRemotes dstatus return $ map snd $ filter fst pairs where checkremote repotop r = case Remote.localpath r of
Assistant/Threads/Pusher.hs view
@@ -52,7 +52,7 @@ now <- getCurrentTime if shouldPush now commits then do- remotes <- filter pushable . knownRemotes+ remotes <- filter pushable . syncRemotes <$> getDaemonStatus dstatus unless (null remotes) $ void $ alertWhile dstatus (pushAlert remotes) $
Assistant/Threads/TransferScanner.hs view
@@ -61,7 +61,7 @@ - lost. -} startupScan = addScanRemotes scanremotes True- =<< knownRemotes <$> getDaemonStatus dstatus+ =<< syncRemotes <$> getDaemonStatus dstatus {- This is a cheap scan for failed transfers involving a remote. -} failedTransferScan :: ThreadState -> DaemonStatusHandle -> TransferQueue -> Remote -> IO ()@@ -87,7 +87,7 @@ transferqueue dstatus (associatedFile info) t r {- This is a expensive scan through the full git work tree, finding- - files to download from or upload to any of the remotes.+ - files to download from or upload to any known remote. - - The scan is blocked when the transfer queue gets too large. -} expensiveScan :: ThreadState -> DaemonStatusHandle -> TransferQueue -> [Remote] -> IO ()@@ -114,7 +114,11 @@ queueTransferWhenSmall transferqueue dstatus (Just f) t r findtransfers f (key, _) = do locs <- loggedLocations key- let use a = return $ catMaybes $ map (a key locs) rs+ {- Queue transfers from any known remote. The known+ - remotes may have changed since this scan began. -}+ let use a = do+ syncrs <- liftIO $ syncRemotes <$> getDaemonStatus dstatus+ return $ catMaybes $ map (a key locs) syncrs ifM (inAnnex key) ( filterM (wantSend (Just f) . Remote.uuid . fst) =<< use (check Upload False)
Assistant/Threads/TransferWatcher.hs view
@@ -67,8 +67,8 @@ [ "transfer starting:" , show t ]- r <- headMaybe . filter (sameuuid t) . knownRemotes- <$> getDaemonStatus dstatus+ r <- headMaybe . filter (sameuuid t)+ <$> runThreadState st Remote.remoteList updateTransferInfo dstatus t info { transferRemote = r } sameuuid t r = Remote.uuid r == transferUUID t
Assistant/TransferQueue.hs view
@@ -71,7 +71,7 @@ where go = do rs <- sufficientremotes- =<< knownRemotes <$> liftIO (getDaemonStatus dstatus)+ =<< syncRemotes <$> liftIO (getDaemonStatus dstatus) let matchingrs = filter (matching . Remote.uuid) rs if null matchingrs then defer@@ -104,8 +104,8 @@ - any others in the list to try again later. -} queueDeferredDownloads :: Schedule -> TransferQueue -> DaemonStatusHandle -> Annex () queueDeferredDownloads schedule q dstatus = do- rs <- knownRemotes <$> liftIO (getDaemonStatus dstatus) l <- liftIO $ atomically $ swapTVar (deferreddownloads q) []+ rs <- syncRemotes <$> liftIO (getDaemonStatus dstatus) left <- filterM (queue rs) l unless (null left) $ liftIO $ atomically $ modifyTVar' (deferreddownloads q) $
Assistant/WebApp.hs view
@@ -153,6 +153,6 @@ listOtherRepos :: IO [(String, String)] listOtherRepos = do f <- autoStartFile- dirs <- ifM (doesFileExist f) ( lines <$> readFile f, return [])+ dirs <- nub <$> ifM (doesFileExist f) ( lines <$> readFile f, return []) names <- mapM relHome dirs return $ sort $ zip names dirs
Assistant/WebApp/Configurators.hs view
@@ -99,7 +99,7 @@ | otherwise = list =<< (++) <$> configured <*> rest where configured = do- rs <- filter (not . Remote.readonly) . knownRemotes <$>+ rs <- filter (not . Remote.readonly) . syncRemotes <$> (liftIO . getDaemonStatus =<< daemonStatus <$> getYesod) runAnnex [] $ do u <- getUUID
Assistant/WebApp/Configurators/Edit.hs view
@@ -14,15 +14,18 @@ import Assistant.WebApp.Types import Assistant.WebApp.SideBar import Assistant.WebApp.Utility+import Assistant.DaemonStatus+import Assistant.MakeRemote (uniqueRemoteName) import Utility.Yesod import qualified Remote+import qualified Remote.List as Remote import Logs.UUID import Logs.Group import Logs.PreferredContent import Types.StandardGroups import qualified Config-import Annex.UUID import qualified Git+import qualified Git.Command import Yesod import Data.Text (Text)@@ -34,15 +37,17 @@ deriving (Show, Eq) data RepoConfig = RepoConfig- { repoDescription :: Text+ { repoName :: Text+ , repoDescription :: Maybe Text , repoGroup :: RepoGroup , repoSyncable :: Bool } deriving (Show) -getRepoConfig :: UUID -> Git.Repo -> Annex RepoConfig-getRepoConfig uuid r = RepoConfig- <$> (T.pack . fromMaybe "" . M.lookup uuid <$> uuidMap)+getRepoConfig :: UUID -> Git.Repo -> Maybe Remote -> Annex RepoConfig+getRepoConfig uuid r mremote = RepoConfig+ <$> pure (T.pack $ maybe "here" Remote.name mremote)+ <*> (maybe Nothing (Just . T.pack) . M.lookup uuid <$> uuidMap) <*> getrepogroup <*> Config.repoSyncable r where@@ -52,26 +57,32 @@ maybe (RepoGroupCustom $ unwords $ S.toList groups) RepoGroupStandard (getStandardGroup groups) -{- Returns Just False if syncing should be disabled, Just True when enabled;- - Nothing when it is not changed. -}-setRepoConfig :: UUID -> Git.Repo -> RepoConfig -> Annex (Maybe Bool)-setRepoConfig uuid r c = do- describeUUID uuid $ T.unpack $ repoDescription c- case repoGroup c of- RepoGroupStandard g -> setStandardGroup uuid g- RepoGroupCustom s -> groupSet uuid $ S.fromList $ words s- ifM ((==) uuid <$> getUUID)- ( return Nothing- , do- syncable <- Config.repoSyncable r- return $ if (syncable /= repoSyncable c)- then Just $ repoSyncable c- else Nothing- )+setRepoConfig :: UUID -> Maybe Remote -> RepoConfig -> RepoConfig -> Handler ()+setRepoConfig uuid mremote oldc newc = do+ when (repoDescription oldc /= repoDescription newc) $ runAnnex undefined $+ maybe noop (describeUUID uuid . T.unpack) (repoDescription newc)+ when (repoGroup oldc /= repoGroup newc) $ runAnnex undefined $ + case repoGroup newc of+ RepoGroupStandard g -> setStandardGroup uuid g+ RepoGroupCustom s -> groupSet uuid $ S.fromList $ words s+ when (repoSyncable oldc /= repoSyncable newc) $+ changeSyncable mremote (repoSyncable newc)+ when (isJust mremote && repoName oldc /= repoName newc) $ do+ dstatus <- daemonStatus <$> getYesod+ runAnnex undefined $ do+ name <- fromRepo $ uniqueRemoteName (T.unpack $ repoName newc) 0+ inRepo $ Git.Command.run "remote"+ [ Param "rename"+ , Param $ T.unpack $ repoName oldc+ , Param name+ ]+ void $ Remote.remoteListRefresh+ updateSyncRemotes dstatus editRepositoryAForm :: RepoConfig -> AForm WebApp WebApp RepoConfig editRepositoryAForm def = RepoConfig- <$> areq textField "Description" (Just $ repoDescription def)+ <$> areq textField "Name" (Just $ repoName def)+ <*> aopt textField "Description" (Just $ repoDescription def) <*> areq (selectFieldList $ customgroups++standardgroups) "Repository group" (Just $ repoGroup def) <*> areq checkBoxField "Syncing enabled" (Just $ repoSyncable def) where@@ -95,14 +106,12 @@ setTitle "Configure repository" (repo, mremote) <- lift $ runAnnex undefined $ Remote.repoFromUUID uuid- curr <- lift $ runAnnex undefined $ getRepoConfig uuid repo+ curr <- lift $ runAnnex undefined $ getRepoConfig uuid repo mremote ((result, form), enctype) <- lift $ runFormGet $ renderBootstrap $ editRepositoryAForm curr case result of FormSuccess input -> lift $ do- syncchanged <- runAnnex undefined $- setRepoConfig uuid repo input- maybe noop (changeSyncable mremote) syncchanged+ setRepoConfig uuid mremote curr input redirect RepositoriesR _ -> showform form enctype curr where
Assistant/WebApp/Configurators/Local.hs view
@@ -209,8 +209,7 @@ Right _ -> noop Left _e -> do createDirectoryIfMissing True dir- bare <- not <$> canMakeSymlink dir- makeRepo dir bare+ makeRepo dir True {- Each repository is made a remote of the other. -} addremote dir name = runAnnex undefined $ do hostname <- maybe "host" id <$> liftIO getHostname@@ -264,7 +263,7 @@ fromJust $ postFirstRun webapp redirect $ T.pack url -{- Makes a new git-annex repository. -}+{- Makes a new git repository. -} makeRepo :: FilePath -> Bool -> IO () makeRepo path bare = do unlessM (boolSystem "git" params) $
Assistant/WebApp/Configurators/Ssh.hs view
@@ -291,7 +291,7 @@ (scanRemotes webapp) forcersync sshdata setup r- redirect $ EditRepositoryR $ Remote.uuid r+ redirect $ EditNewRepositoryR $ Remote.uuid r getAddRsyncNetR :: Handler RepHtml getAddRsyncNetR = do
Assistant/WebApp/Utility.hs view
@@ -40,7 +40,7 @@ webapp <- getYesod let dstatus = daemonStatus webapp let st = fromJust $ threadState webapp- liftIO $ runThreadState st $ updateKnownRemotes dstatus+ liftIO $ runThreadState st $ updateSyncRemotes dstatus {- Stop all transfers to or from this remote. - XXX Can't stop any ongoing scan, or git syncs. -} void $ liftIO $ dequeueTransfers (transferQueue webapp) dstatus tofrom
CHANGELOG view
@@ -1,3 +1,23 @@+git-annex (3.20121016) unstable; urgency=low++ * vicfg: New file format, avoids ambiguity with repos that have the same+ description, or no description.+ * Bug fix: A recent change caused git-annex-shell to crash.+ * Better preferred content expression for transfer repos.+ * webapp: Repository edit form can now edit the name of a repository.+ * webapp: Make bare repositories on removable drives, as there is nothing+ to ensure non-bare repos get updated when syncing.+ * webapp: Better behavior when pausing syncing to a remote when a transfer+ scan is running and queueing new transfers for that remote.+ * The standalone binaries are now built to not use ssh connection caching,+ in order to work with old versions of ssh.+ * A relative core.worktree is relative to the gitdir. Now that this is+ handled correctly, git-annex can be used in git submodules.+ * Temporarily disable use of dbus, as the haskell dbus library blows up+ when losing connection, which will need to be fixed upstream. ++ -- Joey Hess <joeyh@debian.org> Tue, 16 Oct 2012 15:25:22 -0400+ git-annex (3.20121010) unstable; urgency=low * Renamed --ingroup to --inallgroup.
Command/Assistant.hs view
@@ -54,7 +54,7 @@ let nothing = error $ "Nothing listed in " ++ autostartfile ifM (doesFileExist autostartfile) ( do- dirs <- lines <$> readFile autostartfile+ dirs <- nub . lines <$> readFile autostartfile program <- readProgramFile when (null dirs) nothing forM_ dirs $ \d -> do
+ Command/Help.hs view
@@ -0,0 +1,51 @@+{- git-annex command+ -+ - Copyright 2012 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Command.Help where++import Common.Annex+import Command+import qualified Command.Init+import qualified Command.Add+import qualified Command.Drop+import qualified Command.Get+import qualified Command.Move+import qualified Command.Copy+import qualified Command.Sync+import qualified Command.Whereis+import qualified Command.Fsck++def :: [Command]+def = [noCommit $ noRepo showHelp $ dontCheck repoExists $+ command "help" paramNothing seek "display help"]++seek :: [CommandSeek]+seek = [withWords start]++start :: [String] -> CommandStart+start _ = do+ liftIO showHelp+ stop++showHelp :: IO ()+showHelp = liftIO $ putStrLn $ unlines+ [ "The most commonly used git-annex commands are:"+ , unlines $ map cmdline $ concat+ [ Command.Init.def+ , Command.Add.def+ , Command.Drop.def+ , Command.Get.def+ , Command.Move.def+ , Command.Copy.def+ , Command.Sync.def+ , Command.Whereis.def+ , Command.Fsck.def+ ]+ , "Run git-annex without any options for a complete command and option list."+ ]+ where+ cmdline c = "\t" ++ cmdname c ++ "\t" ++ cmddesc c
Command/Vicfg.hs view
@@ -35,7 +35,8 @@ f <- fromRepo gitAnnexTmpCfgFile createAnnexDirectory $ parentDir f cfg <- getCfg- liftIO $ writeFile f $ genCfg cfg+ descs <- uuidDescriptions+ liftIO $ writeFile f $ genCfg cfg descs vicfg cfg f stop @@ -57,7 +58,6 @@ { cfgTrustMap :: TrustMap , cfgGroupMap :: M.Map UUID (S.Set Group) , cfgPreferredContentMap :: M.Map UUID String- , cfgDescriptions :: M.Map UUID String } getCfg :: Annex Cfg@@ -65,7 +65,6 @@ <$> trustMapRaw -- without local trust overrides <*> (groupsByUUID <$> groupMap) <*> preferredContentMapRaw- <*> uuidDescriptions setCfg :: Cfg -> Cfg -> Annex () setCfg curcfg newcfg = do@@ -80,13 +79,8 @@ diff f = M.differenceWith (\x y -> if x == y then Nothing else Just x) (f newcfg) (f curcfg) -genCfg :: Cfg -> String-genCfg cfg = unlines $ concat- [ intro- , trustintro, trust, defaulttrust- , groupsintro, groups, defaultgroups- , preferredcontentintro, preferredcontent, defaultpreferredcontent- ]+genCfg :: Cfg -> M.Map UUID String -> String+genCfg cfg descs = unlines $ concat [intro, trust, groups, preferredcontent] where intro = [ com "git-annex configuration"@@ -94,51 +88,49 @@ , com "Changes saved to this file will be recorded in the git-annex branch." , com "" , com "Lines in this file have the format:"- , com " setting repo = value"+ , com " setting uuid = value" ] - trustintro =+ trust = settings cfgTrustMap [ "" , com "Repository trust configuration" , com "(Valid trust levels: " ++ unwords (map showTrustLevel [Trusted .. DeadTrusted]) ++ ")" ]- trust = map (\(t, u) -> line "trust" u $ showTrustLevel t) $- sort $ map swap $ M.toList $ cfgTrustMap cfg+ (\(t, u) -> line "trust" u $ showTrustLevel t)+ (\u -> lcom $ line "trust" u $ showTrustLevel SemiTrusted) - defaulttrust = map (\u -> pcom $ line "trust" u $ showTrustLevel SemiTrusted) $- missing cfgTrustMap- groupsintro = + groups = settings cfgGroupMap [ "" , com "Repository groups" , com "(Separate group names with spaces)" ]- groups = sort $ map (\(s, u) -> line "group" u $ unwords $ S.toList s) $- map swap $ M.toList $ cfgGroupMap cfg- defaultgroups = map (\u -> pcom $ line "group" u "") $- missing cfgGroupMap+ (\(s, u) -> line "group" u $ unwords $ S.toList s)+ (\u -> lcom $ line "group" u "") - preferredcontentintro = + preferredcontent = settings cfgPreferredContentMap [ "" , com "Repository preferred contents" ]- preferredcontent = sort $ map (\(s, u) -> line "preferred-content" u s) $- map swap $ M.toList $ cfgPreferredContentMap cfg- defaultpreferredcontent = map (\u -> pcom $ line "preferred-content" u "") $- missing cfgPreferredContentMap+ (\(s, u) -> line "preferred-content" u s)+ (\u -> line "preferred-content" u "") - line setting u value = unwords- [ setting- , showu u- , "=" - , value+ settings field desc showvals showdefaults = concat+ [ desc+ , concatMap showvals $+ sort $ map swap $ M.toList $ field cfg+ , concatMap (\u -> lcom $ showdefaults u) $+ missing field ]- pcom s = "#" ++ s- showu u = fromMaybe (fromUUID u) $- M.lookup u (cfgDescriptions cfg)- missing field = S.toList $ M.keysSet (cfgDescriptions cfg) `S.difference` M.keysSet (field cfg) + line setting u value =+ [ com $ "(for " ++ (fromMaybe "" $ M.lookup u descs) ++ ")"+ , unwords [setting, fromUUID u, "=", value]+ ]+ lcom = map (\l -> if "#" `isPrefixOf` l then l else "#" ++ l)+ missing field = S.toList $ M.keysSet descs `S.difference` M.keysSet (field cfg)+ {- If there's a parse error, returns a new version of the file, - with the problem lines noted. -} parseCfg :: Cfg -> String -> Either String Cfg@@ -155,16 +147,14 @@ parse l cfg | null l = Right cfg | "#" `isPrefixOf` l = Right cfg- | null setting || null repo' = Left "missing repository name"- | otherwise = case M.lookup repo' name2uuid of- Nothing -> badval "repository" repo'- Just u -> handle cfg u setting value'+ | null setting || null u = Left "missing repository uuid"+ | otherwise = handle cfg (toUUID u) setting value' where (setting, rest) = separate isSpace l- (repo, value) = separate (== '=') rest+ (r, value) = separate (== '=') rest value' = trimspace value- repo' = reverse $ trimspace $- reverse $ trimspace repo+ u = reverse $ trimspace $+ reverse $ trimspace r trimspace = dropWhile isSpace handle cfg u setting value@@ -183,9 +173,6 @@ let m = M.insert u value (cfgPreferredContentMap cfg) in Right $ cfg { cfgPreferredContentMap = m } | otherwise = badval "setting" setting-- name2uuid = M.fromList $ map swap $- M.toList $ cfgDescriptions curcfg showerr (Just msg, l) = [parseerr ++ msg, l] showerr (Nothing, l)
Command/WebApp.hs view
@@ -75,7 +75,7 @@ autoStart :: FilePath -> IO () autoStart autostartfile = do- dirs <- lines <$> readFile autostartfile+ dirs <- nub . lines <$> readFile autostartfile edirs <- filterM doesDirectoryExist dirs case edirs of [] -> firstRun -- what else can I do? Nothing works..
Git/Config.hs view
@@ -37,7 +37,10 @@ {- Reads config even if it was read before. -} reRead :: Repo -> IO Repo-reRead = read'+reRead r = read' $ r+ { config = M.empty+ , fullconfig = M.empty+ } {- Cannot use pipeRead because it relies on the config having been already - read. Instead, chdir to the repo and run git config.@@ -90,7 +93,7 @@ store :: String -> Repo -> IO Repo store s repo = do let c = parse s- let repo' = updateLocation $ repo+ repo' <- updateLocation $ repo { config = (M.map Prelude.head c) `M.union` config repo , fullconfig = M.unionWith (++) c (fullconfig repo) }@@ -103,17 +106,23 @@ - known. Once the config is read, this can be fixed up to a Local repo, - based on the core.bare and core.worktree settings. -}-updateLocation :: Repo -> Repo+updateLocation :: Repo -> IO Repo updateLocation r@(Repo { location = LocalUnknown d })- | isBare r = newloc $ Local d Nothing- | otherwise = newloc $ Local (d </> ".git") (Just d)- where- newloc l = r { location = getworktree l }- getworktree l = case workTree r of- Nothing -> l- wt -> l { worktree = wt }-updateLocation r = r+ | isBare r = updateLocation' r $ Local d Nothing+ | otherwise = updateLocation' r $ Local (d </> ".git") (Just d)+updateLocation r@(Repo { location = l@(Local {}) }) = updateLocation' r l+updateLocation r = return r +updateLocation' :: Repo -> RepoLocation -> IO Repo+updateLocation' r l = do+ l' <- case getMaybe "core.worktree" r of+ Nothing -> return l+ Just d -> do+ {- core.worktree is relative to the gitdir -}+ top <- absPath $ gitdir l+ return $ l { worktree = Just $ absPathFrom top d }+ return $ r { location = l' }+ {- Parses git config --list or git config --null --list output into a - config map. -} parse :: String -> M.Map String [String]@@ -139,6 +148,3 @@ isBare :: Repo -> Bool isBare r = fromMaybe False $ isTrue =<< getMaybe "core.bare" r--workTree :: Repo -> Maybe FilePath-workTree = getMaybe "core.worktree"
Git/Construct.hs view
@@ -227,7 +227,8 @@ catchDefaultIO "" (readFile $ dir </> ".git") return $ if gitdirprefix `isPrefixOf` c then Just $ Local - { gitdir = drop (length gitdirprefix) c+ { gitdir = absPathFrom dir $+ drop (length gitdirprefix) c , worktree = Just dir } else Nothing
Git/CurrentRepo.hs view
@@ -31,7 +31,7 @@ get = do gd <- pathenv "GIT_DIR" r <- configure gd =<< maybe fromCwd fromPath gd- wt <- maybe (Git.Config.workTree r) Just <$> pathenv "GIT_WORK_TREE"+ wt <- maybe (worktree $ location r) Just <$> pathenv "GIT_WORK_TREE" case wt of Nothing -> return r Just d -> do@@ -42,17 +42,20 @@ where pathenv s = do v <- getEnv s- when (isJust v) $- unsetEnv s case v of+ Just d -> do+ unsetEnv s+ Just <$> absPath d Nothing -> return Nothing- Just d -> Just <$> absPath d configure Nothing r = Git.Config.read r configure (Just d) r = do r' <- Git.Config.read r -- Let GIT_DIR override the default gitdir.- return $ changelocation r' $- Local { gitdir = d, worktree = worktree (location r') }+ absd <- absPath d+ return $ changelocation r' $ Local+ { gitdir = absd+ , worktree = worktree (location r')+ } addworktree w r = changelocation r $ Local { gitdir = gitdir (location r), worktree = w } changelocation r l = r { location = l }
GitAnnex.hs view
@@ -71,6 +71,7 @@ import qualified Command.WebApp #endif #endif+import qualified Command.Help cmds :: [Command] cmds = concat@@ -123,6 +124,7 @@ , Command.WebApp.def #endif #endif+ , Command.Help.def ] options :: [Option]
GitAnnexShell.hs view
@@ -104,11 +104,10 @@ - rsync and not be useful. -} partitionParams :: [String] -> ([String], [String])-partitionParams params- | length segments < 2 = (segments !! 0, [])- | otherwise = (segments !! 0, segments !! 1)- where- segments = segment (== "--") params+partitionParams ps = case segment (== "--") ps of+ params:fieldparams:_ -> (params, fieldparams)+ [params] -> (params, [])+ _ -> ([], []) parseFields :: [String] -> [(String, String)] parseFields = map (separate (== '='))
Logs/PreferredContent.hs view
@@ -53,8 +53,8 @@ case M.lookup u m of Nothing -> return True Just matcher ->- Utility.Matcher.matchM2 matcher notpresent $- getTopFilePath file+ Utility.Matcher.matchMrun matcher $ \a ->+ a notpresent (getTopFilePath file) {- Read the preferredContentLog into a map. The map is cached for speed. -} preferredContentMap :: Annex Annex.PreferredContentMap
Makefile view
@@ -16,13 +16,13 @@ OS:=$(shell uname | sed 's/[-_].*//') ifeq ($(OS),Linux)-OPTFLAGS=-DWITH_INOTIFY -DWITH_DBUS+OPTFLAGS?=-DWITH_INOTIFY clibs=Utility/libdiskfree.o Utility/libmounts.o THREADFLAGS=$(shell if test -e `ghc --print-libdir`/libHSrts_thr.a; then printf -- -threaded; fi) else # BSD system THREADFLAGS=-threaded-OPTFLAGS=-DWITH_KQUEUE+OPTFLAGS?=-DWITH_KQUEUE clibs=Utility/libdiskfree.o Utility/libmounts.o Utility/libkqueue.o ifeq ($(OS),Darwin) # Ensure OSX compiler builds for 32 bit when using 32 bit ghc@@ -142,7 +142,10 @@ sha1sum sha224sum sha256sum sha384sum sha512sum LINUXSTANDALONE_DEST=$(GIT_ANNEX_TMP_BUILD_DIR)/git-annex.linux-linuxstandalone: $(bins)+linuxstandalone:+ $(MAKE) clean+ GIT_ANNEX_LOCAL_FEATURES="$(GIT_ANNEX_LOCAL_FEATURES) -DWITH_OLD_SSH" $(MAKE) git-annex+ rm -rf "$(LINUXSTANDALONE_DEST)" cp -R standalone/linux "$(LINUXSTANDALONE_DEST)"@@ -178,7 +181,10 @@ OSXAPP_DEST=$(GIT_ANNEX_TMP_BUILD_DIR)/build-dmg/git-annex.app OSXAPP_BASE=$(OSXAPP_DEST)/Contents/MacOS-osxapp: $(bins)+osxapp:+ $(MAKE) clean+ GIT_ANNEX_LOCAL_FEATURES="$(GIT_ANNEX_LOCAL_FEATURES) -DWITH_OLD_SSH" $(MAKE) git-annex+ rm -rf "$(OSXAPP_DEST)" install -d $(GIT_ANNEX_TMP_BUILD_DIR)/build-dmg cp -R standalone/osx/git-annex.app "$(OSXAPP_DEST)"
Types/StandardGroups.hs view
@@ -32,6 +32,6 @@ {- See doc/preferred_content.mdwn for explanations of these expressions. -} preferredContent :: StandardGroup -> String preferredContent ClientGroup = "exclude=*/archive/*"-preferredContent TransferGroup = "not inallgroup=client and " ++ preferredContent ClientGroup+preferredContent TransferGroup = "not (inallgroup=client and copies=client:2) and " ++ preferredContent ClientGroup preferredContent ArchiveGroup = "not copies=archive:1" preferredContent BackupGroup = "" -- all content is preferred
Utility/Directory.hs view
@@ -10,7 +10,7 @@ import System.IO.Error import System.Posix.Files import System.Directory-import Control.Exception (throw, bracket_)+import Control.Exception (throw) import Control.Monad import Control.Monad.IfElse import System.FilePath@@ -94,14 +94,3 @@ - cannot be removed. -} nukeFile :: FilePath -> IO () nukeFile file = whenM (doesFileExist file) $ removeFile file--{- Runs an action in another directory. -}-bracketCd :: FilePath -> IO a -> IO a-bracketCd dir a = go =<< getCurrentDirectory- where- go cwd- | dirContains dir cwd = a- | otherwise = bracket_- (changeWorkingDirectory dir)- (changeWorkingDirectory cwd)- a
Utility/Gpg.hs view
@@ -87,9 +87,9 @@ findPubKeys for = KeyIds . parse <$> readStrict params where params = [Params "--with-colons --list-public-keys", Param for]- parse = map keyIdField . filter pubKey . lines- pubKey = isPrefixOf "pub:"- keyIdField s = split ":" s !! 4+ parse = catMaybes . map (keyIdField . split ":") . lines+ keyIdField ("pub":_:_:_:f:_) = Just f+ keyIdField _ = Nothing {- Creates a block of high-quality random data suitable to use as a cipher. - It is armored, to avoid newlines, since gpg only reads ciphers up to the
Utility/Matcher.hs view
@@ -15,6 +15,8 @@ - Licensed under the GNU GPL version 3 or higher. -} +{-# LANGUAGE Rank2Types, KindSignatures #-}+ module Utility.Matcher ( Token(..), Matcher,@@ -23,7 +25,7 @@ generate, match, matchM,- matchM2,+ matchMrun, matchesAny ) where @@ -89,22 +91,19 @@ {- Runs a monadic Matcher, where Operations are actions in the monad. -} matchM :: Monad m => Matcher (v -> m Bool) -> v -> m Bool-matchM m v = go m- where- go MAny = return True- go (MAnd m1 m2) = go m1 <&&> go m2- go (MOr m1 m2) = go m1 <||> go m2- go (MNot m1) = liftM not (go m1)- go (MOp o) = o v+matchM m v = matchMrun m $ \o -> o v -matchM2 :: Monad m => Matcher (v1 -> v2 -> m Bool) -> v1 -> v2 -> m Bool-matchM2 m v1 v2 = go m+{- More generic running of a monadic Matcher, with full control over running+ - of Operations. Mostly useful in order to match on more than one+ - parameter. -}+matchMrun :: forall o (m :: * -> *). Monad m => Matcher o -> (o -> m Bool) -> m Bool+matchMrun m run = go m where go MAny = return True go (MAnd m1 m2) = go m1 <&&> go m2 go (MOr m1 m2) = go m1 <||> go m2 go (MNot m1) = liftM not (go m1)- go (MOp o) = o v1 v2+ go (MOp o) = run o {- Checks is a matcher contains no limits, and so (presumably) matches - anything. Note that this only checks the trivial case; it is possible
Utility/Misc.hs view
@@ -40,9 +40,23 @@ firstLine = takeWhile (/= '\n') {- Splits a list into segments that are delimited by items matching- - a predicate. (The delimiters are not included in the segments.) -}+ - a predicate. (The delimiters are not included in the segments.)+ - Segments may be empty. -} segment :: (a -> Bool) -> [a] -> [[a]]-segment p = filter (not . all p) . segmentDelim p+segment p l = map reverse $ go [] [] l+ where+ go c r [] = reverse $ c:r+ go c r (i:is)+ | p i = go [] (c:r) is+ | otherwise = go (i:c) r is++prop_segment_regressionTest :: Bool+prop_segment_regressionTest = all id+ -- Even an empty list is a segment.+ [ segment (== "--") [] == [[]]+ -- There are two segements in this list, even though the first is empty.+ , segment (== "--") ["--", "foo", "bar"] == [[],["foo","bar"]]+ ] {- Includes the delimiters as segments of their own. -} segmentDelim :: (a -> Bool) -> [a] -> [[a]]
debian/changelog view
@@ -1,3 +1,23 @@+git-annex (3.20121016) unstable; urgency=low++ * vicfg: New file format, avoids ambiguity with repos that have the same+ description, or no description.+ * Bug fix: A recent change caused git-annex-shell to crash.+ * Better preferred content expression for transfer repos.+ * webapp: Repository edit form can now edit the name of a repository.+ * webapp: Make bare repositories on removable drives, as there is nothing+ to ensure non-bare repos get updated when syncing.+ * webapp: Better behavior when pausing syncing to a remote when a transfer+ scan is running and queueing new transfers for that remote.+ * The standalone binaries are now built to not use ssh connection caching,+ in order to work with old versions of ssh.+ * A relative core.worktree is relative to the gitdir. Now that this is+ handled correctly, git-annex can be used in git submodules.+ * Temporarily disable use of dbus, as the haskell dbus library blows up+ when losing connection, which will need to be fixed upstream. ++ -- Joey Hess <joeyh@debian.org> Tue, 16 Oct 2012 15:25:22 -0400+ git-annex (3.20121010) unstable; urgency=low * Renamed --ingroup to --inallgroup.
+ doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh.mdwn view
@@ -0,0 +1,43 @@+What steps will reproduce the problem?++I create a new annex, added in a bunch of files.++I cloned this annex to another machine, where I already had those files, so I copied them into a directory named "foo", did "git annex add foo", and then did "git rm -r foo", and git commit'd my clone of the annex.++Then I try to "git annex sync" with the remote.++What is the expected output? What do you see instead?++I don't know, I've never used git-annex before. This is what I get each time:++ Hermes ~/Products/tmp/Movies (master) $ ga sync+ git-annex-shell: Prelude.(!!): index too large++What version of git-annex are you using? On what operating system?++It's the 'master' as of yesterday: c504f4025fec49e62601fbd4a3cd8f1270c7d221++I'm on OS X 10.8.2, using GHC 7.6.1. The annex in question has 38G in a few hundred files.++Please provide any additional information below.++I'm willing to help track this down!++> I've got it, October 9th's release +> included commit bc649a35bacbecef93e378b1497f6a05b30bf452, which included a+> change to a `segment` function. It was supposed to be a+> rewrite in terms of a more general version, but it introduced a bug+> in what it returned in an edge case and this in turn led git-annex-shell's+> parameter parser to fail in a code path that was never reachable before.+> +> It'd fail both when a new repo was running `git-annex-shell configlist`,+> and in `git-annex-shell commit`, although this latter crash was less+> noticible and I'm sure you saw the former.+> +> Fixed the reversion; fixed insufficient guards around the partial code+> (which I cannot see a way to entirely eliminate sadly; look at+> GitAnnexShell.hs's `partitionParams` and weep or let me know if you have +> any smart ideas..); added a regression test to check the non-obvious+> behavior of segment with an empty segment. I'll be releasing a new+> version with this fix as soon as I have bandwidth, ie tomorrow.+> [[done]] --[[Joey]]
+ doc/bugs/gix-annex_help_is_homicidal.mdwn view
@@ -0,0 +1,23 @@+> What steps will reproduce the problem?++Run 'git-annex help'++> What is the expected output?++Something similar to 'git-annex --help', or a pointer to --help.++> What do you see instead?++ git-annex: Unknown command 'help'+ Did you mean one of these?+ drop+ dead++> What version of git-annex are you using? On what operating system?++git-annex version 3.20120825 on Arch Linux x86_64, installed from AUR package git-annex and using the [haskell] repository for dependencies.++>> Lol, that's great! Also worth noting that with help.autocorrect=1, it'd+>> actually run drop. Only with --force can you lose data however.+>>+>> I've added a help command. [[done]] --[[Joey]]
+ doc/bugs/submodule_path_problem.mdwn view
@@ -0,0 +1,56 @@+If a submodule isn't toplevel, git-annex breaks++**What steps will reproduce the problem?**++Make two non-empty repositories:++ mkdir submod+ cd submod+ git init+ touch README && git add README+ git commit -a -m "first import of submodule"+ cd ..++ mkdir test+ cd test+ git init+ touch README && git add README+ git commit -a -m "first import of master"++Add first repository as a non-toplevel submodule:++ git submodule add ../submod lib/submod+ +Setup git-annex for the submodule inside the other repository:++ cd lib/submod+ git annex init++**What is the expected output? What do you see instead?**++Expected:++ init ok+ (Recording state in git...)++Got:++ init fatal: Could not switch to '../../../../lib': No such file or directory+ git-annex: git config [Param "annex.uuid",Param "55D974D1-73E8-489E-B454-03D164664C82"] failed+++**What version of git-annex are you using? On what operating system?**++3.20121011 compiled from git on Mac OS X 10.8+++**Please provide any additional information below.**++* git-annex read the path from the "worktree" variable in the git config.+* The git config for a submodule is storen in the main repository, e.g. "../../.git/modules/lib/submod/config"+* The path in that config is relative to the config file: "worktree = ../../../../lib/submod"+* Git-annex expect the path to be relative to the current directory, which is why it fails.++> Impressive analysis, thanks. I've fixed handling of relative+> core.worktree. [[done]] --[[Joey]]+
+ doc/design/assistant/blog/.day_107__memory_leak.mdwn.swp view
binary file changed (absent → 12288 bytes)
− doc/design/assistant/blog/day_104__foo.mdwn
@@ -1,15 +0,0 @@-Switched the OSX standalone app to use `DYLD_ROOT_PATH`.-This is the third `DYLD_*` variable I've tried; neither-of the other two worked in all situations. This one may do better.-If not, I may be stuck modifying the library names in each executable-using `install_name_tool`-([good reference for doing that](http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html)).-As far as I know, every existing dynamic library lookup system is broken-in some way other other; nothing I've seen about OSX's so far-disproves that rule.--Fixed a nasty utf-8 encoding crash that could occur when merging the-git-annex branch. I hope I'm almost done with those.--Made git-annex auto-detect when a git remote is on a sever like github-that doesn't support git-annex, and automatically set annex-ignore.
+ doc/design/assistant/blog/day_104__misc.mdwn view
@@ -0,0 +1,18 @@+Switched the OSX standalone app to use `DYLD_ROOT_PATH`.+This is the third `DYLD_*` variable I've tried; neither+of the other two worked in all situations. This one may do better.+If not, I may be stuck modifying the library names in each executable+using `install_name_tool`+([good reference for doing that](http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html)).+As far as I know, every existing dynamic library lookup system is broken+in some way other other; nothing I've seen about OSX's so far+disproves that rule.++Fixed a nasty utf-8 encoding crash that could occur when merging the+git-annex branch. I hope I'm almost done with those.++Made git-annex auto-detect when a git remote is on a sever like github+that doesn't support git-annex, and automatically set annex-ignore.++Finished the UI for pausing syncing of a remote. Making the syncing+actually stop still has some glitches to resolve.
+ doc/design/assistant/blog/day_105__lazy_Sunday.mdwn view
@@ -0,0 +1,43 @@+Did a fair amount of testing and bug fixing today. ++There is still some buggy behavior around pausing syncing to a remote,+where transfers still happen to it, but I fixed the worst bug there.++Noticed that if a non-bare repo is set up on a removable drive,+its file tree will not normally be updated as syncs come in -- because the+assistant is not running on that repo, and so incoming syncs are not+merged into the local master branch. For now I made it always use bare+repos on removable drives, but I may want to revisit this.++The repository edit form now has a field for the name of the repo,+so the ugly names that the assistant comes up with for ssh remotes+can be edited as you like. `git remote rename` is a very nice thing.++Changed the preferred content expression for transfer repos to this:+"not (inallgroup=client **and copies=client:2)**". This way, when there's+just one client, files on it will be synced to transfer repos, even+though those repos have no other clients to transfer them to. Presumably,+if a transfer repo is set up, more clients are coming soon, so this avoids+a wait. Particularly useful with removable drives, as the drive will start+being filled as soon as it's added, and can then be brought to a client+elsewhere. The "2" does mean that, once another client is found,+the data on the transfer repo will be dropped, and so if it's brought+to yet another new client, it won't have data for it right away.+I can't see way to generalize this workaround to more than 2 clients;+the transfer repo has to start dropping apparently unwanted content at+some point. Still, this will avoid a potentially very confusing behavior+when getting started.++----++I need to get that dropping of non-preferred content to happen still.+Yesterday, I did some analysis of all the events that can cause previously+preferred content to no longer be preferred, so I know all the places+I have to deal with this.++The one that's giving me some trouble is checking in the transfer scan. If it+checks for content to drop at the same time as content to transfer, it could+end up doing a lot of transfers before dropping anything. It'd be nicer to+first drop as much as it can, before getting more data, so that transfer+remotes stay as small as possible. But the scan is expensive, and it'd also+be nice not to need two passes.
+ doc/design/assistant/blog/day_106__lazy_Monday.mdwn view
@@ -0,0 +1,10 @@+I was mostly working on other things today, but I did do some bug fixing.+The worst of these is a bug introduced in 3.20121009 that breaks+`git-annex-shell configlist`. That's pretty bad for using git-annex+on servers, although you mostly won't notice unless you're just getting+started using a ssh remote, since that's when it calls configlist.+I will be releasing a new version as soon as I have bandwidth (tomorrow).++Also made the standalone Linux and OSX binaries build with ssh connection+caching disabled, since they don't bundle their own ssh and need to work+with whatever ssh is installed.
+ doc/design/assistant/blog/day_107__memory_leak.mdwn view
@@ -0,0 +1,11 @@+More bugfixes today. The assistant now seems to have enough users that+they're turning up interesting bugs, which is good. But does keep me too+busy to add many more bugs^Wcode.++The fun one today made it bloat to eat all memory when logging out of a+Linux desktop. I tracked that back to a bug in the Haskell DBUS library+when a session connection is open and the session goes away. Developed a+test case, and even profiled it, and sent it all of to the library's+author. Hopefully there will be a quick fix, in the meantime today's+release has DBUS turned off. Which is ok, it just makes it a little bit+slower to notice some events.
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 15 "Amazon S3 (done)" 9 "Amazon Glacier" 7 "Box.com" 55 "My phone (or MP3 player)" 9 "Tahoe-LAFS" 4 "OpenStack SWIFT" 16 "Google Drive"]]+[[!poll open=yes 15 "Amazon S3 (done)" 9 "Amazon Glacier" 7 "Box.com" 57 "My phone (or MP3 player)" 15 "Tahoe-LAFS" 5 "OpenStack SWIFT" 17 "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/transfer_control.mdwn view
@@ -10,16 +10,42 @@ ## TODO -* easy configuration of preferred content-* Drop no longer preferred content.- - When a file is renamed, it might stop being preferred, so- could be checked and dropped. (If there's multiple links to- the same content, this gets tricky.)- - When a file is sent or received, the sender's preferred content- settings may change, causing it to be dropped from the sender.- - May also want to check for things to drop, from both local and remotes,- when doing the expensive trasfer scan.+* preferred content settings made in the webapp (or in vicfg, or synced over) are not noticed. +### dropping no longer preferred content TODO++When a file is renamed, it might stop being preferred, so+could be checked and dropped. (If there's multiple links to+the same content, this gets tricky. Let's assume there are not.)++* When a file is sent or received, the sender's preferred content+ settings may change, causing it to be dropped from the sender.+* May also want to check for things to drop, from both local and remotes,+ when doing the expensive trasfer scan.++### analysis of changes that can result in content no longer being preferred++1. The preferred content expression can change, or a new repo is added, or+ groups change. Generally, some change to global annex state. Only way to deal+ with this is an expensive scan. (The rest of the items below come from+ analizing the terminals used in preferred content expressions.)+2. renaming of a file (ie, moved to `archive/`)+3. some other repository gets the file (`in`, `copies`)+4. some other repository drops the file (`in`, `copies` .. However, it's+ unlikely that an expression would prefer content when *more* copies+ exisited, and want to drop it when less do. That's nearly a pathological+ case.)+5. `migrate` is used to change a backend (`inbackend`; unlikely)++That's all! Of these, 2 and 3 are by far the most important.++Rename handling should certianly check 2. ++One place to check for 3 is after transferring a file; but that does not+cover all its cases, as some other repo could transfer the file. To fully+handle 3, need to either use a full scan, or examine location log history+when receiving a git-annex branch push.+ ## specifying what data a remote prefers to contain **done** Imagine a per-remote preferred content setting, that matches things that@@ -72,6 +98,10 @@ The above is all well and good for those who enjoy boolean algebra, but how to configure these sorts of expressions in the webapp? +Currently, we have a simple drop down list to select between a few+predefined groups with pre-defined preferred content recipes. Is this good+enough?+ ## the state change problem **done** Imagine that a trusted repo has setting like `not copies=trusted:2`@@ -88,6 +118,4 @@ Or, perhaps simulation could be used to detect the problem. Before dropping, check the expression. Then simulate that the drop has happened. Does the expression now make it want to add it? Then don't drop it!-How to implement this simulation?--> Solved, fwiw..+**done**.. effectively using this approach.
doc/design/assistant/webapp.mdwn view
@@ -8,11 +8,6 @@ This is quite likely because of how the div containing transfers is refereshed. If instead javascript was used to update the progress bar etc for transfers with json data, the buttons would work better.-* Disabling syncing to a remote doesn't stop any running transfer scan,- which can still queue uploads or downloads to the remote.-* Transfers from a remote with syncing disabled show as from "unknown".- (Note that it's probably not practical to prevent a remote with syncing- disabled from initiating transfers, so this can happen.) ## interface @@ -33,8 +28,9 @@ See: [[todo/wishlist:_an_"assistant"_for_web-browsing_--_tracking_the_sources_of_the_downloads]] * Display the `inotify max_user_watches` exceeded message. **done** * Display something sane when kqueue runs out of file descriptors.-* allow renaming git remotes and/or setting git-annex repo descriptions * allow removing git remotes+* allow disabling syncing to here, which should temporarily disable all+ local syncing. ## first start **done**
+ doc/forum/Can__39__t_init_git_annex.mdwn view
@@ -0,0 +1,15 @@+It seems I can't initialize git annex:++ $ git annex init "files2"+ init files2 + pre-commit hook (/Volumes/project/annex/.git/hooks/pre-commit) already exists, not configuring+ + git-annex: waitToSetLock: failed (Operation not supported)+ failed+ git-annex: init: 1 failed+ $+++ `project` is a remote file server connected via `smb://`.++ Any ideas why and how to fix?
− doc/news/version_3.20120825.mdwn
@@ -1,6 +0,0 @@-git-annex 3.20120825 released with [[!toggle text="these changes"]]-[[!toggleable text="""- * S3: Add fileprefix setting.- * Pass --use-agent to gpg when in no tty mode. Thanks, Eskild Hustvedt.- * Bugfix: Fix fsck in SHA*E backends, when the key contains composite- extensions, as added in 3.20120721."""]]
+ doc/news/version_3.20121016.mdwn view
@@ -0,0 +1,17 @@+git-annex 3.20121016 released with [[!toggle text="these changes"]]+[[!toggleable text="""+ * vicfg: New file format, avoids ambiguity with repos that have the same+ description, or no description.+ * Bug fix: A recent change caused git-annex-shell to crash.+ * Better preferred content expression for transfer repos.+ * webapp: Repository edit form can now edit the name of a repository.+ * webapp: Make bare repositories on removable drives, as there is nothing+ to ensure non-bare repos get updated when syncing.+ * webapp: Better behavior when pausing syncing to a remote when a transfer+ scan is running and queueing new transfers for that remote.+ * The standalone binaries are now built to not use ssh connection caching,+ in order to work with old versions of ssh.+ * A relative core.worktree is relative to the gitdir. Now that this is+ handled correctly, git-annex can be used in git submodules.+ * Temporarily disable use of dbus, as the haskell dbus library blows up+ when losing connection, which will need to be fixed upstream."""]]
doc/preferred_content.mdwn view
@@ -61,7 +61,13 @@ The preferred content expression for these causes them to get and retain data until all clients have a copy. -`not inallgroup=client and exclude=*/archive/*`+`not (inallgroup=client and copies=client:2) and exclude=*/archive/*`++The "copies=client:2" part of the above handles the case where+there is only one client repository. It makes a transfer repository+speculatively prefer content in this case, even though it as of yet+has nowhere to transfer it to. Presumably, another client repository+will be added later. ### archive
+ doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment view
@@ -0,0 +1,32 @@+[[!comment format=mdwn+ username="helmut"+ ip="89.0.176.236"+ subject="Asynchronous hooks?"+ date="2012-10-13T09:46:14Z"+ content="""+Is there a way to use asynchronous remotes? Interaction with git annex would have to+split the part of initiating some action from completing it.++I imagine I could `git annex copy` a file to an asynchronous remote and the command+would almost immediately complete. Later I would learn that the transfer is+completed, so the hook must be able to record that information in the `git-annex`+branch. An additional plumbing command seems required here as well as a way to+indicate that even though the store-hook completed, the file is not transferred.++Similarly `git annex get` would immediately return without actually fetching the+file. This should already be possible by returning non-zero from the retrieve-hook.+Later the hook could use plumbing level commands to actually stick the received file+into the repository.++The remove-hook should need no changes, but the checkpresent-hook would be more like+a trigger without any actual result. The extension of the plumbing required for the+extension to the receive-hook could update the location log. A downside here is that+you never know when a fsck has completed.++My proposal does not include a way to track the completion of actions, but relies on+the hook to always complete them reliably. It is not clear that this is the best road+for asynchronous hooks.++One use case for this would be a remote that is only accessible via uucp. Are there+other use cases? Is the drafted interface useful?+"""]]
+ doc/todo/wishlist:_An_option_like_--git-dir.mdwn view
@@ -0,0 +1,3 @@+I'm currently integrating git-annex support into a filesystem synchronization tool that I use, and I have a use case where I'd like to run "git annex sync' on a local directory, and then automatically ssh over to remote hosts and run "git annex sync" in the related annex on that remote host. However, while I can easily "cd" on the local, there is no really easy way to "cd" on the remote without a hack.++If I could say: git annex --annex-dir=PATH sync, where PATH is the annex directory, it would solve all my problems, and would also provide a nice correlation to the --git-dir option used by most Git commands. The basic idea is that I shouldn't have to be IN the directory to run git-annex commands, I should be able to tell git-annex which directory to apply its commands to.
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 3.20121010+Version: 3.20121016 Cabal-Version: >= 1.8 License: GPL Maintainer: Joey Hess <joey@kitenet.net>
templates/configurators/adddrive.hamlet view
@@ -3,7 +3,7 @@ Adding a removable drive <p> Clone this repository to a USB drive, memory stick, or other #- removable media. Whenever the removable drive is plugged in, its+ removable media. Whenever the removable drive is plugged in, its # content will be synced with the content of this repository. <p> $if (null writabledrives)
templates/configurators/editrepository.hamlet view
@@ -6,7 +6,7 @@ This repository is set up and ready to go! <p> Now you can do a little more configuring of it, if you like. #- Perhaps enter a better description than the automatically generated one.+ Perhaps enter a better name than the automatically generated one. $if istransfer <div .alert .alert-info> This repository is currently in the transfer group. That's the #
test.hs view
@@ -48,6 +48,7 @@ import qualified Utility.Format import qualified Utility.Verifiable import qualified Utility.Process+import qualified Utility.Misc -- for quickcheck instance Arbitrary Types.Key.Key where@@ -91,6 +92,7 @@ , qctest "prop_TimeStamp_sane" Logs.UUIDBased.prop_TimeStamp_sane , qctest "prop_addLog_sane" Logs.UUIDBased.prop_addLog_sane , qctest "prop_verifiable_sane" Utility.Verifiable.prop_verifiable_sane+ , qctest "prop_segment_regressionTest" Utility.Misc.prop_segment_regressionTest ] blackbox :: Test