git-annex 3.20121127.1 → 3.20121211
raw patch · 177 files changed
+2647/−488 lines, 177 filesdep +yesod-formdep ~DAV
Dependencies added: yesod-form
Dependency ranges changed: DAV
Files
- Annex/Wanted.hs +10/−10
- Assistant.hs +4/−0
- Assistant/Drop.hs +20/−9
- Assistant/Install.hs +1/−1
- Assistant/Pairing/MakeRemote.hs +1/−0
- Assistant/Ssh.hs +28/−14
- Assistant/Sync.hs +1/−0
- Assistant/Threads/Committer.hs +4/−1
- Assistant/Threads/Glacier.hs +43/−0
- Assistant/Threads/TransferScanner.hs +3/−3
- Assistant/Threads/Transferrer.hs +0/−4
- Assistant/TransferQueue.hs +2/−2
- Assistant/WebApp/Common.hs +2/−1
- Assistant/WebApp/Configurators.hs +0/−1
- Assistant/WebApp/Configurators/AWS.hs +31/−13
- Assistant/WebApp/Configurators/Edit.hs +3/−2
- Assistant/WebApp/Configurators/Local.hs +0/−1
- Assistant/WebApp/Configurators/Pairing.hs +0/−1
- Assistant/WebApp/Configurators/Ssh.hs +52/−30
- Assistant/WebApp/Configurators/WebDAV.hs +30/−15
- Assistant/WebApp/Configurators/XMPP.hs +0/−1
- Assistant/WebApp/DashBoard.hs +0/−1
- Assistant/WebApp/Documentation.hs +4/−2
- Assistant/WebApp/Form.hs +77/−0
- Assistant/WebApp/Page.hs +1/−0
- Assistant/WebApp/Types.hs +18/−1
- Assistant/WebApp/routes +1/−0
- Build/OSXMkLibs.hs +77/−23
- CHANGELOG +32/−3
- Command.hs +9/−12
- Command/Copy.hs +7/−6
- Command/Drop.hs +1/−1
- Command/Get.hs +2/−2
- Creds.hs +5/−7
- Limit.hs +1/−1
- Logs/PreferredContent.hs +7/−5
- Logs/Web.hs +10/−13
- Makefile +25/−12
- Remote/Bup.hs +1/−1
- Remote/Directory.hs +2/−2
- Remote/Git.hs +2/−2
- Remote/Glacier.hs +83/−43
- Remote/Helper/AWS.hs +45/−0
- Remote/Helper/Chunked.hs +2/−3
- Remote/Helper/Encryptable.hs +3/−4
- Remote/Hook.hs +2/−2
- Remote/List.hs +1/−1
- Remote/Rsync.hs +4/−4
- Remote/S3.hs +30/−34
- Remote/Web.hs +7/−5
- Remote/WebDAV.hs +40/−51
- Types/Remote.hs +3/−3
- Types/StandardGroups.hs +1/−1
- Utility/Daemon.hs +8/−3
- Utility/Matcher.hs +5/−7
- Utility/SRV.hs +1/−0
- debian/changelog +32/−3
- debian/control +1/−1
- debian/rules +2/−2
- doc/assistant/release_notes.mdwn +35/−0
- doc/bugs/3.20121113_build_error___39__not_in_scope_getAddBoxComR__39__.mdwn +33/−0
- doc/bugs/Build-depends_needs___39__hxt__39___added_-_3.20121127.mdwn +36/−0
- doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__.mdwn +31/−0
- doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__.mdwn +19/−0
- doc/bugs/Local_pairing_fails:_PairListener_crashed.mdwn +18/−0
- doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment +10/−0
- doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment +8/−0
- doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment +8/−0
- doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX.mdwn +15/−0
- doc/bugs/Need_to_manually_install_c2hs_-_3.20121127_and_previous.mdwn +37/−0
- doc/bugs/OSX_app_issues/comment_10_bb823dc3cd6dc914ed14c176afa0b2f3._comment +8/−0
- doc/bugs/OSX_app_issues/comment_11_a30e69fed14b0809184ffe05358ab871._comment +10/−0
- doc/bugs/OSX_app_issues/comment_12_23d47b3696e537d60df1d383f33f19e4._comment +15/−0
- doc/bugs/OSX_app_issues/comment_13_be5738b42b13ec8cd828c5fa66f030e8._comment +10/−0
- doc/bugs/OSX_app_issues/comment_14_e126d87a263f3aa6261f72ee7ff086fc._comment +8/−0
- doc/bugs/OSX_app_issues/comment_15_e58bd3d66f0f43c159d2b37172f152de._comment +8/−0
- doc/bugs/OSX_app_issues/comment_16_01f2c968bad66b0ff0c09eb468325deb._comment +8/−0
- doc/bugs/OSX_app_issues/comment_17_82d9963e1fbf17644ce697e5a43943f5._comment +16/−0
- doc/bugs/OSX_app_issues/comment_18_29af9df9ea295d114574e76e15b8e737._comment +8/−0
- doc/bugs/OSX_app_issues/comment_19_6d6341b05123cd317c4eac96353c8662._comment +10/−0
- doc/bugs/OSX_app_issues/comment_2_fd560811c57df5cbc3976639642b8b19._comment +8/−0
- doc/bugs/OSX_app_issues/comment_3_08613b2e2318680508483d204a43da76._comment +76/−0
- doc/bugs/OSX_app_issues/comment_6_12bd83e7e2327c992448e87bdb85d17e._comment +15/−0
- doc/bugs/OSX_app_issues/comment_6_cea97dbbfb566a9fe463365ca4511119._comment +16/−0
- doc/bugs/OSX_app_issues/comment_7_911f187d46890093a54859032ada2442._comment +10/−0
- doc/bugs/OSX_app_issues/comment_7_93e0bb53ac2d7daef53426fbdc5f92d9._comment +15/−0
- doc/bugs/OSX_app_issues/comment_8_08b091a58106ca6050ac669579ed9ff4._comment +11/−0
- doc/bugs/OSX_app_issues/comment_8_141eac2f3fb25fe18b4268786f00ad6a._comment +8/−0
- doc/bugs/OSX_app_issues/comment_9_8464c839cb169a4c6e72bebdc2065e9a._comment +8/−0
- doc/bugs/Proxy_support.mdwn +18/−0
- doc/bugs/dropping_and_re-adding_from_web_remotes_doesn__39__t_work.mdwn +8/−0
- doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn +34/−0
- doc/bugs/git-annex_webapp_command_not_found.mdwn +25/−0
- doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn +34/−0
- doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__.mdwn +34/−0
- doc/bugs/glacier_with_assistant_bugs.mdwn +0/−2
- doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform.mdwn +20/−0
- doc/bugs/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn +39/−0
- doc/bugs/yesod-form_missing.mdwn +23/−0
- doc/design/assistant.mdwn +6/−3
- doc/design/assistant/OSX/comment_1_9290f6e6f265e906b08631224392b7bf._comment +14/−0
- doc/design/assistant/android.mdwn +2/−2
- doc/design/assistant/blog/day_142__filling_in.mdwn +9/−0
- doc/design/assistant/blog/day_143__what_next.mdwn +22/−0
- doc/design/assistant/blog/day_144__webapp_work.mdwn +8/−0
- doc/design/assistant/blog/day_145__more_webapp_work.mdwn +12/−0
- doc/design/assistant/blog/day_146__meanwhile.mdwn +22/−0
- doc/design/assistant/blog/day_147__direct_mode.mdwn +36/−0
- doc/design/assistant/blog/day_148__direct_mode.mdwn +42/−0
- doc/design/assistant/blog/day_149__rainy_day.mdwn +15/−0
- doc/design/assistant/blog/day_81__enabling_pre-existing_special_remotes.mdwn +34/−0
- doc/design/assistant/cloud.mdwn +1/−1
- doc/design/assistant/configurators.mdwn +2/−2
- doc/design/assistant/desymlink.mdwn +54/−1
- doc/design/assistant/pairing.mdwn +0/−1
- doc/design/assistant/polls/Android.mdwn +18/−0
- doc/design/assistant/polls/prioritizing_special_remotes.mdwn +1/−1
- doc/design/assistant/syncing.mdwn +1/−8
- doc/design/assistant/transfer_control.mdwn +7/−7
- doc/design/assistant/webapp.mdwn +3/−1
- doc/forum/Can__39__t_install:_Mac_OS_10.8.2.mdwn +36/−0
- doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch.mdwn +1/−0
- doc/forum/Moving_large_files_within_the_repo_without_copying___63__.mdwn +19/−0
- doc/forum/Synchronize_large_files___40__VM_images__41__.mdwn +10/−0
- doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__.mdwn +1/−0
- doc/forum/__34__du__34___equivalent_on_an_annex__63__.mdwn +5/−0
- doc/forum/benefit_of_splitting_a_repository.mdwn +10/−0
- doc/forum/dot_git_slash_annex_slash_tmp.mdwn +5/−0
- doc/forum/gadu_-_git-annex_disk_usage.mdwn +7/−0
- doc/forum/git-assistant_clarification.mdwn +11/−0
- doc/forum/git_annex_alternative.mdwn +10/−0
- doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer..mdwn +3/−0
- doc/forum/updating_the___34__number_of_copies__34__.mdwn +14/−0
- doc/forum/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn +17/−0
- doc/install/OSX.mdwn +7/−4
- doc/install/OSX/comment_4_bbe99673033e4c48c8bb3db24ee419f9._comment +8/−0
- doc/install/cabal.mdwn +4/−1
- doc/internals.mdwn +1/−1
- doc/internals/key_format.mdwn +20/−0
- doc/news/version_3.20121017.mdwn +0/−4
- doc/news/version_3.20121211.mdwn +32/−0
- doc/preferred_content.mdwn +2/−0
- doc/preferred_content/comment_1_7d45e21dfb016e9ffa4715346dd0c1a6._comment +19/−0
- doc/preferred_content/comment_2_1ccd90b009245667ad59f4d29d2a3a37._comment +8/−0
- doc/preferred_content/comment_4_384025b5fa23a3f175985a081438149f._comment +8/−0
- doc/preferred_content/comment_4_6a9bc657bc7415f0e118357d8c6664c6._comment +18/−0
- doc/preferred_content/comment_5_f0a957e67297c4bb5a8778c11b3c9fd4._comment +9/−0
- doc/scalability.mdwn +3/−3
- doc/special_remotes/bup/comment_1_96179a003da4444f6fc08867872cda0a._comment +43/−0
- doc/special_remotes/bup/comment_2_612b038c15206f9f3c2e23c7104ca627._comment +12/−0
- doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment +32/−0
- doc/tips/Decentralized_repository_behind_a_Firewall.mdwn +59/−0
- doc/tips/assume-unstaged/comment_1_44abd811ef79a85e557418e17a3927be._comment +10/−0
- doc/tips/using_Amazon_S3/comment_1_666a26f95024760c99c627eed37b1966._comment +8/−0
- doc/tips/using_Amazon_S3/comment_2_f5a0883be7dbb421b584c6dc0165f1ef._comment +8/−0
- doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment +11/−0
- doc/todo/windows_support/comment_1_3cc26ad8101a22e95a8c60cf0c4dedcc._comment +10/−0
- doc/todo/windows_support/comment_2_8acae818ce468967499050bbe3c532ea._comment +12/−0
- doc/todo/windows_support/comment_3_bd0a12f4c9b884ab8a06082842381a01._comment +8/−0
- doc/todo/windows_support/comment_4_ad06b98b2ddac866ffee334e41fee6a8._comment +8/−0
- doc/todo/windows_support/comment_5_444fc7251f57db241b6e80abae41851c._comment +10/−0
- git-annex.cabal +3/−3
- standalone/linux/git-annex +25/−0
- standalone/linux/runshell +1/−1
- standalone/osx/git-annex.app/Contents/Info.plist +0/−4
- standalone/osx/git-annex.app/Contents/MacOS/git-annex +25/−0
- standalone/osx/git-annex.app/Contents/MacOS/git-annex-webapp +1/−1
- standalone/osx/git-annex.app/Contents/MacOS/runshell +10/−24
- static/js/bootstrap-collapse.js +138/−0
- templates/configurators/addbox.com.hamlet +0/−2
- templates/configurators/addglacier.hamlet +6/−14
- templates/configurators/addrsync.net.hamlet +2/−10
- templates/configurators/adds3.hamlet +4/−14
- templates/configurators/ssh/add.hamlet +0/−3
- templates/documentation/repogroup.hamlet +38/−0
- templates/error.cassius +3/−0
- templates/error.hamlet +23/−0
Annex/Wanted.hs view
@@ -15,19 +15,19 @@ import qualified Data.Set as S {- Check if a file is preferred content for the local repository. -}-wantGet :: AssociatedFile -> Annex Bool-wantGet Nothing = return True-wantGet (Just file) = isPreferredContent Nothing S.empty file+wantGet :: Bool -> AssociatedFile -> Annex Bool+wantGet def Nothing = return def+wantGet def (Just file) = isPreferredContent Nothing S.empty file def {- Check if a file is preferred content for a remote. -}-wantSend :: AssociatedFile -> UUID -> Annex Bool-wantSend Nothing _ = return True-wantSend (Just file) to = isPreferredContent (Just to) S.empty file+wantSend :: Bool -> AssociatedFile -> UUID -> Annex Bool+wantSend def Nothing _ = return def+wantSend def (Just file) to = isPreferredContent (Just to) S.empty file def {- Check if a file can be dropped, maybe from a remote. - Don't drop files that are preferred content. -}-wantDrop :: Maybe UUID -> AssociatedFile -> Annex Bool-wantDrop _ Nothing = return True-wantDrop from (Just file) = do+wantDrop :: Bool -> Maybe UUID -> AssociatedFile -> Annex Bool+wantDrop def _ Nothing = return $ not def+wantDrop def from (Just file) = do u <- maybe getUUID (return . id) from- not <$> isPreferredContent (Just u) (S.singleton u) file+ not <$> isPreferredContent (Just u) (S.singleton u) file def
Assistant.hs view
@@ -74,6 +74,8 @@ - Thread 20: WebApp - Spawns more threads as necessary to handle clients. - Displays the DaemonStatus.+ - Thread 21: Glacier+ - Deals with retrieving files from Amazon Glacier. - - ThreadState: (MVar) - The Annex state is stored here, which allows resuscitating the@@ -136,6 +138,7 @@ import Assistant.Threads.TransferScanner import Assistant.Threads.TransferPoller import Assistant.Threads.ConfigMonitor+import Assistant.Threads.Glacier #ifdef WITH_WEBAPP import Assistant.WebApp import Assistant.Threads.WebApp@@ -208,6 +211,7 @@ , assist $ netWatcherFallbackThread , assist $ transferScannerThread , assist $ configMonitorThread+ , assist $ glacierThread , watch $ watchThread ] liftIO waitForTermination
Assistant/Drop.hs view
@@ -11,27 +11,33 @@ import Assistant.DaemonStatus import Logs.Location import Logs.Trust-import Types.Remote (AssociatedFile)+import Types.Remote (AssociatedFile, uuid) import qualified Remote import qualified Command.Drop import Command import Annex.Wanted+import Annex.Exception import Config +import qualified Data.Set as S+ {- Drop from local and/or remote when allowed by the preferred content and- - numcopies settings. If it's known to be present on a particular remote,- - -}+ - numcopies settings. -} handleDrops :: Bool -> Key -> AssociatedFile -> Maybe Remote -> Assistant () handleDrops _ _ Nothing _ = noop handleDrops fromhere key f knownpresentremote = do syncrs <- syncDataRemotes <$> getDaemonStatus liftAnnex $ do locs <- loggedLocations key- handleDrops' locs syncrs fromhere key f knownpresentremote+ handleDropsFrom locs syncrs fromhere key f knownpresentremote -handleDrops' :: [UUID] -> [Remote] -> Bool -> Key -> AssociatedFile -> Maybe Remote -> Annex ()-handleDrops' _ _ _ _ Nothing _ = noop-handleDrops' locs rs fromhere key (Just f) knownpresentremote+{- The UUIDs are ones where the content is believed to be present.+ - The Remote list can include other remotes that do not have the content;+ - only ones that match the UUIDs will be dropped from.+ - If allows to drop fromhere, that drop will be tried first. -}+handleDropsFrom :: [UUID] -> [Remote] -> Bool -> Key -> AssociatedFile -> Maybe Remote -> Annex ()+handleDropsFrom _ _ _ _ Nothing _ = noop+handleDropsFrom locs rs fromhere key (Just f) knownpresentremote | fromhere = do n <- getcopies if checkcopies n@@ -48,11 +54,12 @@ go [] _ = noop go (r:rest) n+ | uuid r `S.notMember` slocs = go rest n | checkcopies n = dropr r n >>= go rest | otherwise = noop - checkdrop n@(_, numcopies) u a = ifM (wantDrop u (Just f))- ( ifM (doCommand $ a (Just numcopies))+ checkdrop n@(_, numcopies) u a = ifM (wantDrop True u (Just f))+ ( ifM (safely $ doCommand $ a (Just numcopies)) ( return $ decrcopies n , return n )@@ -64,3 +71,7 @@ dropr r n = checkdrop n (Just $ Remote.uuid r) $ \numcopies -> Command.Drop.startRemote f numcopies key r++ safely a = either (const False) id <$> tryAnnex a++ slocs = S.fromList locs
Assistant/Install.hs view
@@ -39,7 +39,7 @@ where go Nothing = noop go (Just base) = do- let program = base ++ "runshell git-annex"+ let program = base </> "git-annex" programfile <- programFile createDirectoryIfMissing True (parentDir programfile) writeFile programfile program
Assistant/Pairing/MakeRemote.hs view
@@ -60,6 +60,7 @@ , sshUserName = Just (T.pack $ remoteUserName d) , sshDirectory = T.pack dir , sshRepoName = genSshRepoName hostname dir+ , sshPort = 22 , needsPubKey = True , rsyncOnly = False }
Assistant/Ssh.hs view
@@ -24,6 +24,7 @@ , sshUserName :: Maybe Text , sshDirectory :: Text , sshRepoName :: String+ , sshPort :: Int , needsPubKey :: Bool , rsyncOnly :: Bool }@@ -112,7 +113,7 @@ (ssh, keytype) = separate (== '-') prefix checkcomment comment- | all (\c -> isAlphaNum c || c == '@' || c == '-' || c == '_') comment = ok+ | all (\c -> isAlphaNum c || c == '@' || c == '-' || c == '_' || c == '.') comment = ok | otherwise = err "bad comment in ssh public key" addAuthorizedKeys :: Bool -> FilePath -> SshPubKey -> IO Bool@@ -188,7 +189,6 @@ setupSshKeyPair :: SshKeyPair -> SshData -> IO SshData setupSshKeyPair sshkeypair sshdata = do sshdir <- sshDir- let configfile = sshdir </> "config" createDirectoryIfMissing True sshdir unlessM (doesFileExist $ sshdir </> sshprivkeyfile) $ do@@ -200,25 +200,39 @@ unlessM (doesFileExist $ sshdir </> sshpubkeyfile) $ writeFile (sshdir </> sshpubkeyfile) (sshPubKey sshkeypair) + setSshConfig sshdata+ [ ("IdentityFile", "~/.ssh/" ++ sshprivkeyfile) ]+ where+ sshprivkeyfile = "key." ++ mangleSshHostName sshdata+ sshpubkeyfile = sshprivkeyfile ++ ".pub"++{- Setups up a ssh config with a mangled hostname.+ - Returns a modified SshData containing the mangled hostname. -}+setSshConfig :: SshData -> [(String, String)] -> IO SshData+setSshConfig sshdata config = do+ sshdir <- sshDir+ createDirectoryIfMissing True sshdir+ let configfile = sshdir </> "config" unlessM (catchBoolIO $ isInfixOf mangledhost <$> readFile configfile) $- appendFile configfile $ unlines+ appendFile configfile $ unlines $ [ "" , "# Added automatically by git-annex" , "Host " ++ mangledhost- , "\tHostname " ++ T.unpack (sshHostName sshdata)- , "\tIdentityFile ~/.ssh/" ++ sshprivkeyfile- ]-+ ] ++ map (\(k, v) -> "\t" ++ k ++ " " ++ v)+ (settings ++ config) return $ sshdata { sshHostName = T.pack mangledhost } where- sshprivkeyfile = "key." ++ mangledhost- sshpubkeyfile = sshprivkeyfile ++ ".pub"- mangledhost = mangleSshHostName- (T.unpack $ sshHostName sshdata)- (T.unpack <$> sshUserName sshdata)+ mangledhost = mangleSshHostName sshdata+ settings =+ [ ("Hostname", T.unpack $ sshHostName sshdata)+ , ("Port", show $ sshPort sshdata)+ ] -mangleSshHostName :: String -> Maybe String -> String-mangleSshHostName host user = "git-annex-" ++ host ++ (maybe "-" ('-':) user)+mangleSshHostName :: SshData -> String+mangleSshHostName sshdata = "git-annex-" ++ host ++ (maybe "-" ('-':) user)+ where+ host = T.unpack $ sshHostName sshdata+ user = T.unpack <$> sshUserName sshdata unMangleSshHostName :: String -> String unMangleSshHostName h
Assistant/Sync.hs view
@@ -174,4 +174,5 @@ updateSyncRemotes thread <- asIO $ do reconnectRemotes False [remote]+ addScanRemotes True [remote] void $ liftIO $ forkIO $ thread
Assistant/Threads/Committer.hs view
@@ -213,7 +213,10 @@ ks <- liftIO $ getSymbolicLinkStatus $ contentLocation keysource if deviceID ks == deviceID fs && fileID ks == fileID fs then a- else return Nothing+ else do+ -- remove the hard link+ void $ liftIO $ tryIO $ removeFile $ contentLocation keysource+ return Nothing {- Files can Either be Right to be added now, - or are unsafe, and must be Left for later.
+ Assistant/Threads/Glacier.hs view
@@ -0,0 +1,43 @@+{- git-annex assistant Amazon Glacier retrieval+ -+ - Copyright 2012 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}++module Assistant.Threads.Glacier where++import Assistant.Common+import Utility.ThreadScheduler+import qualified Types.Remote as Remote+import qualified Remote.Glacier as Glacier+import Logs.Transfer+import Assistant.DaemonStatus+import Assistant.TransferQueue++import qualified Data.Set as S++{- Wakes up every half hour and checks if any glacier remotes have failed+ - downloads. If so, runs glacier-cli to check if the files are now+ - available, and queues the downloads. -}+glacierThread :: NamedThread+glacierThread = NamedThread "Glacier" $ runEvery (Seconds 3600) <~> go+ where+ isglacier r = Remote.remotetype r == Glacier.remote+ go = do+ rs <- filter isglacier . syncDataRemotes <$> getDaemonStatus+ forM_ rs $ \r -> + check r =<< (liftAnnex $ getFailedTransfers $ Remote.uuid r)+ check _ [] = noop+ check r l = do+ let keys = map getkey l+ (availkeys, failedkeys) <- liftAnnex $ Glacier.jobList r keys+ let s = S.fromList (failedkeys ++ availkeys)+ let l' = filter (\p -> S.member (getkey p) s) l+ forM_ l' $ \(t, info) -> do+ liftAnnex $ removeFailedTransfer t+ queueTransferWhenSmall (associatedFile info) t r+ getkey = transferKey . fst
Assistant/Threads/TransferScanner.hs view
@@ -119,14 +119,14 @@ locs <- loggedLocations key present <- inAnnex key - handleDrops' locs syncrs present key (Just f) Nothing+ handleDropsFrom locs syncrs present key (Just f) Nothing let slocs = S.fromList locs let use a = return $ catMaybes $ map (a key slocs) syncrs if present- then filterM (wantSend (Just f) . Remote.uuid . fst)+ then filterM (wantSend True (Just f) . Remote.uuid . fst) =<< use (genTransfer Upload False)- else ifM (wantGet $ Just f)+ else ifM (wantGet True $ Just f) ( use (genTransfer Download True) , return [] ) genTransfer :: Direction -> Bool -> Key -> S.Set UUID -> Remote -> Maybe (Remote, Transfer)
Assistant/Threads/Transferrer.hs view
@@ -23,10 +23,6 @@ import System.Process (create_group) -{- For now only one transfer is run at a time. -}-maxTransfers :: Int-maxTransfers = 1- {- Dispatches transfers from the queue. -} transfererThread :: NamedThread transfererThread = NamedThread "Transferr" $ do
Assistant/TransferQueue.hs view
@@ -52,7 +52,7 @@ - condition. Honors preferred content settings. -} queueTransfersMatching :: (UUID -> Bool) -> Schedule -> Key -> AssociatedFile -> Direction -> Assistant () queueTransfersMatching matching schedule k f direction- | direction == Download = whenM (liftAnnex $ wantGet f) go+ | direction == Download = whenM (liftAnnex $ wantGet True f) go | otherwise = go where go = do@@ -72,7 +72,7 @@ uuids <- Remote.keyLocations k return $ filter (\r -> uuid r `elem` uuids) rs {- Upload to all remotes that want the content. -}- | otherwise = filterM (wantSend f . Remote.uuid) $+ | otherwise = filterM (wantSend True f . Remote.uuid) $ filter (not . Remote.readonly) rs gentransfer r = Transfer { transferDirection = direction
Assistant/WebApp/Common.hs view
@@ -10,8 +10,9 @@ import Assistant.Common as X import Assistant.WebApp as X import Assistant.WebApp.Page as X+import Assistant.WebApp.Form as X import Assistant.WebApp.Types as X import Utility.Yesod as X import Data.Text as X (Text)-+import Yesod as X hiding (textField, passwordField, insertBy, replace, joinPath, deleteBy, delete, insert, Key, Option)
Assistant/WebApp/Configurators.hs view
@@ -25,7 +25,6 @@ import Assistant.XMPP.Client #endif -import Yesod import qualified Data.Map as M {- The main configuration screen. -}
Assistant/WebApp/Configurators/AWS.hs view
@@ -5,7 +5,7 @@ - Licensed under the GNU AGPL version 3 or higher. -} -{-# LANGUAGE CPP, TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes #-}+{-# LANGUAGE CPP, FlexibleContexts, TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes #-} module Assistant.WebApp.Configurators.AWS where @@ -23,7 +23,6 @@ import Types.StandardGroups import Logs.PreferredContent -import Yesod import qualified Data.Text as T import qualified Data.Map as M @@ -49,11 +48,11 @@ data AWSInput = AWSInput { accessKeyID :: Text , secretAccessKey :: Text- -- Free form text for datacenter because Amazon adds new ones. , datacenter :: Text -- Only used for S3, not Glacier. , storageClass :: StorageClass , repoName :: Text+ , enableEncryption :: EnableEncryption } data AWSCreds = AWSCreds Text Text@@ -63,11 +62,12 @@ s3InputAForm :: AForm WebApp WebApp AWSInput s3InputAForm = AWSInput- <$> areq textField "Access Key ID" Nothing- <*> areq passwordField "Secret Access Key" Nothing- <*> areq textField "Datacenter" (Just "US")+ <$> accessKeyIDField+ <*> secretAccessKeyField+ <*> datacenterField AWS.S3 <*> areq (selectFieldList storageclasses) "Storage class" (Just StandardRedundancy) <*> areq textField "Repository name" (Just "S3")+ <*> enableEncryptionField where storageclasses :: [(Text, StorageClass)] storageclasses =@@ -77,17 +77,35 @@ glacierInputAForm :: AForm WebApp WebApp AWSInput glacierInputAForm = AWSInput- <$> areq textField "Access Key ID" Nothing- <*> areq passwordField "Secret Access Key" Nothing- <*> areq textField "Datacenter" (Just "us-east-1")+ <$> accessKeyIDField+ <*> secretAccessKeyField+ <*> datacenterField AWS.Glacier <*> pure StandardRedundancy <*> areq textField "Repository name" (Just "glacier")+ <*> enableEncryptionField awsCredsAForm :: AForm WebApp WebApp AWSCreds awsCredsAForm = AWSCreds- <$> areq textField "Access Key ID" Nothing- <*> areq passwordField "Secret Access Key" Nothing+ <$> accessKeyIDField+ <*> secretAccessKeyField +accessKeyIDField :: AForm WebApp WebApp Text+accessKeyIDField = areq (textField `withNote` help) "Access Key ID" Nothing+ where+ help = [whamlet|+<a href="https://portal.aws.amazon.com/gp/aws/securityCredentials#id_block">+ Get Amazon access keys+|]++secretAccessKeyField :: AForm WebApp WebApp Text+secretAccessKeyField = areq passwordField "Secret Access Key" Nothing++datacenterField :: AWS.Service -> AForm WebApp WebApp Text+datacenterField service = areq (selectFieldList list) "Datacenter" defregion+ where+ list = M.toList $ AWS.regionMap service+ defregion = Just $ AWS.defaultRegion service+ getAddS3R :: Handler RepHtml #ifdef WITH_S3 getAddS3R = awsConfigurator $ do@@ -97,7 +115,7 @@ FormSuccess input -> lift $ do let name = T.unpack $ repoName input makeAWSRemote S3.remote (extractCreds input) name setgroup $ M.fromList- [ ("encryption", "shared")+ [ configureEncryption $ enableEncryption input , ("type", "S3") , ("datacenter", T.unpack $ datacenter input) , ("storageclass", show $ storageClass input)@@ -118,7 +136,7 @@ FormSuccess input -> lift $ do let name = T.unpack $ repoName input makeAWSRemote Glacier.remote (extractCreds input) name setgroup $ M.fromList- [ ("encryption", "shared")+ [ configureEncryption $ enableEncryption input , ("type", "glacier") , ("datacenter", T.unpack $ datacenter input) ]
Assistant/WebApp/Configurators/Edit.hs view
@@ -25,7 +25,6 @@ import qualified Git.Command import qualified Git.Config -import Yesod import qualified Data.Text as T import qualified Data.Map as M import qualified Data.Set as S@@ -90,9 +89,10 @@ editRepositoryAForm def = RepoConfig <$> areq textField "Name" (Just $ repoName def) <*> aopt textField "Description" (Just $ repoDescription def)- <*> areq (selectFieldList $ customgroups++standardgroups) "Repository group" (Just $ repoGroup def)+ <*> areq (selectFieldList groups `withNote` help) "Repository group" (Just $ repoGroup def) <*> areq checkBoxField "Syncing enabled" (Just $ repoSyncable def) where+ groups = customgroups ++ standardgroups standardgroups :: [(Text, RepoGroup)] standardgroups = map (\g -> (T.pack $ descStandardGroup g , RepoGroupStandard g)) [minBound :: StandardGroup .. maxBound :: StandardGroup]@@ -100,6 +100,7 @@ customgroups = case repoGroup def of RepoGroupCustom s -> [(T.pack s, RepoGroupCustom s)] _ -> []+ help = [whamlet|<a href="@{RepoGroupR}">What's this?</a>|] getEditRepositoryR :: UUID -> Handler RepHtml getEditRepositoryR = editForm False
Assistant/WebApp/Configurators/Local.hs view
@@ -30,7 +30,6 @@ import Logs.PreferredContent import Utility.UserInfo -import Yesod import qualified Data.Text as T import Data.Char import System.Posix.Directory
Assistant/WebApp/Configurators/Pairing.hs view
@@ -37,7 +37,6 @@ import Utility.UserInfo import Git -import Yesod #ifdef WITH_PAIRING import qualified Data.Text as T import qualified Data.Text.Encoding as T
Assistant/WebApp/Configurators/Ssh.hs view
@@ -19,7 +19,6 @@ import Types.StandardGroups import Utility.UserInfo -import Yesod import qualified Data.Text as T import qualified Data.Map as M import Network.Socket@@ -28,9 +27,10 @@ sshConfigurator = page "Add a remote server" (Just Config) data SshInput = SshInput- { hostname :: Maybe Text- , username :: Maybe Text- , directory :: Maybe Text+ { inputHostname :: Maybe Text+ , inputUsername :: Maybe Text+ , inputDirectory :: Maybe Text+ , inputPort :: Int } deriving (Show) @@ -38,23 +38,25 @@ - the result of such a form into a SshData. -} mkSshData :: SshInput -> SshData mkSshData s = SshData - { sshHostName = fromMaybe "" $ hostname s- , sshUserName = username s- , sshDirectory = fromMaybe "" $ directory s+ { sshHostName = fromMaybe "" $ inputHostname s+ , sshUserName = inputUsername s+ , sshDirectory = fromMaybe "" $ inputDirectory s , sshRepoName = genSshRepoName- (T.unpack $ fromJust $ hostname s)- (maybe "" T.unpack $ directory s)+ (T.unpack $ fromJust $ inputHostname s)+ (maybe "" T.unpack $ inputDirectory s)+ , sshPort = inputPort s , needsPubKey = False , rsyncOnly = False } -sshInputAForm :: SshInput -> AForm WebApp WebApp SshInput-sshInputAForm def = SshInput- <$> aopt check_hostname "Host name" (Just $ hostname def)- <*> aopt check_username "User name" (Just $ username def)- <*> aopt textField "Directory" (Just $ Just $ fromMaybe (T.pack gitAnnexAssistantDefaultDir) $ directory def)+sshInputAForm :: (Field WebApp WebApp Text) -> SshInput -> AForm WebApp WebApp SshInput+sshInputAForm hostnamefield def = SshInput+ <$> aopt check_hostname "Host name" (Just $ inputHostname def)+ <*> aopt check_username "User name" (Just $ inputUsername def)+ <*> aopt textField "Directory" (Just $ Just $ fromMaybe (T.pack gitAnnexAssistantDefaultDir) $ inputDirectory def)+ <*> areq intField "Port" (Just $ inputPort def) where- check_hostname = checkM (liftIO . checkdns) textField+ check_hostname = checkM (liftIO . checkdns) hostnamefield checkdns t = do let h = T.unpack t r <- catchMaybeIO $ getAddrInfo canonname (Just h) Nothing@@ -90,8 +92,8 @@ getAddSshR = sshConfigurator $ do u <- liftIO $ T.pack <$> myUserName ((result, form), enctype) <- lift $- runFormGet $ renderBootstrap $ sshInputAForm $- SshInput Nothing (Just u) Nothing+ runFormGet $ renderBootstrap $ sshInputAForm textField $+ SshInput Nothing (Just u) Nothing 22 case result of FormSuccess sshinput -> do s <- liftIO $ testServer sshinput@@ -116,10 +118,10 @@ case (parseSshRsyncUrl =<< M.lookup "rsyncurl" m, M.lookup "name" m) of (Just sshinput, Just reponame) -> sshConfigurator $ do ((result, form), enctype) <- lift $- runFormGet $ renderBootstrap $ sshInputAForm sshinput+ runFormGet $ renderBootstrap $ sshInputAForm textField sshinput case result of FormSuccess sshinput'- | isRsyncNet (hostname sshinput') ->+ | isRsyncNet (inputHostname sshinput') -> void $ lift $ makeRsyncNet sshinput' reponame (const noop) | otherwise -> do s <- liftIO $ testServer sshinput'@@ -148,9 +150,10 @@ parseSshRsyncUrl u | not (rsyncUrlIsShell u) = Nothing | otherwise = Just $ SshInput- { hostname = val $ unMangleSshHostName host- , username = if null user then Nothing else val user- , directory = val dir+ { inputHostname = val $ unMangleSshHostName host+ , inputUsername = if null user then Nothing else val user+ , inputDirectory = val dir+ , inputPort = 22 } where val = Just . T.pack@@ -171,9 +174,9 @@ - present, while git-annex-shell is not in PATH. -} testServer :: SshInput -> IO (Either ServerStatus SshData)-testServer (SshInput { hostname = Nothing }) = return $+testServer (SshInput { inputHostname = Nothing }) = return $ Left $ UnusableServer "Please enter a host name."-testServer sshinput@(SshInput { hostname = Just hn }) = do+testServer sshinput@(SshInput { inputHostname = Just hn }) = do status <- probe [sshOpt "NumberOfPasswordPrompts" "0"] if usable status then ret status False@@ -201,7 +204,10 @@ - Otherwise, trust the host key. -} [ if knownhost then "" else sshOpt "StrictHostKeyChecking" "no" , "-n" -- don't read from stdin- , genSshHost (fromJust $ hostname sshinput) (username sshinput)+ , "-p", show (inputPort sshinput)+ , genSshHost+ (fromJust $ inputHostname sshinput)+ (inputUsername sshinput) , remotecommand ] parsetranscript . fst <$> sshTranscript sshopts ""@@ -249,6 +255,9 @@ keypair <- liftIO genSshKeyPair sshdata' <- liftIO $ setupSshKeyPair keypair sshdata makeSsh' rsync setup sshdata' (Just keypair)+ | sshPort sshdata /= 22 = do+ sshdata' <- liftIO $ setSshConfig sshdata []+ makeSsh' rsync setup sshdata' Nothing | otherwise = makeSsh' rsync setup sshdata Nothing makeSsh' :: Bool -> (Remote -> Handler ()) -> SshData -> Maybe SshKeyPair -> Handler RepHtml@@ -277,24 +286,37 @@ getAddRsyncNetR :: Handler RepHtml getAddRsyncNetR = do ((result, form), enctype) <- runFormGet $- renderBootstrap $ sshInputAForm $- SshInput Nothing Nothing Nothing+ renderBootstrap $ sshInputAForm hostnamefield $+ SshInput Nothing Nothing Nothing 22 let showform status = page "Add a Rsync.net repository" (Just Config) $ $(widgetFile "configurators/addrsync.net") case result of FormSuccess sshinput- | isRsyncNet (hostname sshinput) -> do+ | isRsyncNet (inputHostname sshinput) -> do let reponame = genSshRepoName "rsync.net" - (maybe "" T.unpack $ directory sshinput)+ (maybe "" T.unpack $ inputDirectory sshinput) makeRsyncNet sshinput reponame setupGroup | otherwise -> showform $ UnusableServer "That is not a rsync.net host name." _ -> showform UntestedServer+ where+ hostnamefield = textField `withNote` help+ help = [whamlet|+<a .btn data-toggle="collapse" data-target="#help">+ Help+<div #help .collapse>+ <div>+ When you sign up for a Rsync.net account, you should receive an #+ email from them with the host name and user name to put here.+ <div>+ The host name will be something like "usw-s001.rsync.net", and the #+ user name something like "7491"+|] makeRsyncNet :: SshInput -> String -> (Remote -> Handler ()) -> Handler RepHtml makeRsyncNet sshinput reponame setup = do- knownhost <- liftIO $ maybe (return False) knownHost (hostname sshinput)+ knownhost <- liftIO $ maybe (return False) knownHost (inputHostname sshinput) keypair <- liftIO $ genSshKeyPair sshdata <- liftIO $ setupSshKeyPair keypair $ (mkSshData sshinput)
Assistant/WebApp/Configurators/WebDAV.hs view
@@ -20,8 +20,8 @@ import Types.StandardGroups import Logs.PreferredContent import Logs.Remote+import Creds -import Yesod import qualified Data.Text as T import qualified Data.Map as M @@ -34,20 +34,29 @@ data WebDAVInput = WebDAVInput { user :: Text , password :: Text+ , embedCreds :: Bool , directory :: Text+ , enableEncryption :: EnableEncryption } +toCredPair :: WebDAVInput -> CredPair+toCredPair input = (T.unpack $ user input, T.unpack $ password input)+ boxComAForm :: AForm WebApp WebApp WebDAVInput boxComAForm = WebDAVInput <$> areq textField "Username or Email" Nothing <*> areq passwordField "Box.com Password" Nothing+ <*> areq checkBoxField "Share this account with friends?" (Just True) <*> areq textField "Directory" (Just "annex")+ <*> enableEncryptionField webDAVCredsAForm :: AForm WebApp WebApp WebDAVInput webDAVCredsAForm = WebDAVInput <$> areq textField "Username or Email" Nothing <*> areq passwordField "Password" Nothing- <*> pure (T.empty)+ <*> pure False+ <*> pure T.empty+ <*> pure NoEncryption -- not used! getAddBoxComR :: Handler RepHtml #ifdef WITH_WEBDAV@@ -56,8 +65,9 @@ runFormGet $ renderBootstrap boxComAForm case result of FormSuccess input -> lift $ - makeWebDavRemote "box.com" input setgroup $ M.fromList- [ ("encryption", "shared")+ makeWebDavRemote "box.com" (toCredPair input) setgroup $ M.fromList+ [ configureEncryption $ enableEncryption input+ , ("embedcreds", if embedCreds input then "yes" else "no") , ("type", "webdav") , ("url", "https://www.box.com/dav/" ++ T.unpack (directory input)) -- Box.com has a max file size of 100 mb, but@@ -80,18 +90,23 @@ let c = fromJust $ M.lookup uuid m let name = fromJust $ M.lookup "name" c let url = fromJust $ M.lookup "url" c- go name url+ mcreds <- runAnnex Nothing $+ getRemoteCredPairFor "webdav" c (WebDAV.davCreds uuid)+ case mcreds of+ Just creds -> webDAVConfigurator $ lift $+ makeWebDavRemote name creds (const noop) M.empty+ Nothing+ | "box.com/" `isInfixOf` url ->+ boxConfigurator $ showform name url+ | otherwise ->+ webDAVConfigurator $ showform name url where- go name url- | "box.com/" `isInfixOf` url = boxConfigurator $ enable name url- | otherwise = webDAVConfigurator $ enable name url-- enable name url = do+ showform name url = do ((result, form), enctype) <- lift $ runFormGet $ renderBootstrap webDAVCredsAForm case result of- FormSuccess creds -> lift $- makeWebDavRemote name creds (const noop) M.empty+ FormSuccess input -> lift $+ makeWebDavRemote name (toCredPair input) (const noop) M.empty _ -> do description <- lift $ runAnnex "" $ T.pack . concat <$> Remote.prettyListUUIDs [uuid]@@ -101,10 +116,10 @@ #endif #ifdef WITH_WEBDAV-makeWebDavRemote :: String -> WebDAVInput -> (Remote -> Handler ()) -> RemoteConfig -> Handler ()-makeWebDavRemote name input setup config = do+makeWebDavRemote :: String -> CredPair -> (Remote -> Handler ()) -> RemoteConfig -> Handler ()+makeWebDavRemote name creds setup config = do remotename <- runAnnex name $ fromRepo $ uniqueRemoteName name 0- liftIO $ WebDAV.setCredsEnv (T.unpack $ user input, T.unpack $ password input)+ liftIO $ WebDAV.setCredsEnv creds r <- liftAssistant $ liftAnnex $ addRemote $ do makeSpecialRemote name WebDAV.remote config return remotename
Assistant/WebApp/Configurators/XMPP.hs view
@@ -23,7 +23,6 @@ import Utility.SRV #endif -import Yesod #ifdef WITH_XMPP import Network import Network.Protocol.XMPP
Assistant/WebApp/DashBoard.hs view
@@ -22,7 +22,6 @@ import qualified Remote import qualified Git -import Yesod import Text.Hamlet import qualified Data.Map as M import Control.Concurrent
Assistant/WebApp/Documentation.hs view
@@ -13,8 +13,6 @@ import Assistant.Install (standaloneAppBase) import Build.SysConfig (packageversion) -import Yesod- {- The full license info may be included in a file on disk that can - be read in and displayed. -} licenseFile :: IO (Maybe FilePath)@@ -37,3 +35,7 @@ setTitle "License" license <- liftIO $ readFile f $(widgetFile "documentation/license")++getRepoGroupR :: Handler RepHtml+getRepoGroupR = page "About repository groups" (Just About) $ do+ $(widgetFile "documentation/repogroup")
+ Assistant/WebApp/Form.hs view
@@ -0,0 +1,77 @@+{- git-annex assistant webapp form utilities+ -+ - Copyright 2012 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU AGPL version 3 or higher.+ -}++{-# LANGUAGE FlexibleContexts, TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes #-}++module Assistant.WebApp.Form where++import Types.Remote (RemoteConfigKey)++import Yesod hiding (textField, passwordField)+import Yesod.Form.Fields as F+import Data.Text (Text)++{- Yesod's textField sets the required attribute for required fields.+ - We don't want this, because many of the forms used in this webapp + - display a modal dialog when submitted, which interacts badly with+ - required field handling by the browser.+ -+ - Required fields are still checked by Yesod.+ -}+textField :: RenderMessage master FormMessage => Field sub master Text+textField = F.textField+ { fieldView = \theId name attrs val _isReq -> [whamlet|+<input id="#{theId}" name="#{name}" *{attrs} type="text" value="#{either id id val}">+|]+ }++{- Also without required attribute. -}+passwordField :: RenderMessage master FormMessage => Field sub master Text+passwordField = F.passwordField+ { fieldView = \theId name attrs val _isReq -> toWidget [hamlet|+<input id="#{theId}" name="#{name}" *{attrs} type="password" value="#{either id id val}">+|]+ }++{- Makes a note widget be displayed after a field. -}+withNote :: Field sub master v -> GWidget sub master () -> Field sub master v+withNote field note = field { fieldView = newview }+ where+ newview theId name attrs val isReq = + let fieldwidget = (fieldView field) theId name attrs val isReq+ in [whamlet|^{fieldwidget} <span>^{note}</span>|]+++{- Makes a help button be displayed after a field, that displays a help+ - widget when clicked. Requires a unique ident for the help. -}+withHelp :: Field sub master v -> GWidget sub master () -> Text -> Field sub master v+withHelp field help ident = withNote field note+ where+ note = [whamlet|+<a .btn data-toggle="collapse" data-target="##{ident}">+ Help+<div ##{ident} .collapse>+ ^{help}+|]++data EnableEncryption = SharedEncryption | NoEncryption+ deriving (Eq)++{- Adds a check box to an AForm to control encryption. -}+enableEncryptionField :: RenderMessage master FormMessage => AForm sub master EnableEncryption+enableEncryptionField = areq (selectFieldList choices) "Encryption" (Just SharedEncryption)+ where+ choices :: [(Text, EnableEncryption)]+ choices =+ [ ("Encrypt all data", SharedEncryption)+ , ("Disable encryption", NoEncryption)+ ]++{- Generates Remote configuration for encryption. -}+configureEncryption :: EnableEncryption -> (RemoteConfigKey, String)+configureEncryption SharedEncryption = ("encryption", "shared")+configureEncryption NoEncryption = ("encryption", "none")
Assistant/WebApp/Page.hs view
@@ -60,6 +60,7 @@ addScript $ StaticR jquery_full_js addScript $ StaticR js_bootstrap_dropdown_js addScript $ StaticR js_bootstrap_modal_js+ addScript $ StaticR js_bootstrap_collapse_js $(widgetFile "page") hamletToRepHtml $(hamletFile $ hamletTemplate "bootstrap") where
Assistant/WebApp/Types.hs view
@@ -17,10 +17,13 @@ import Assistant.Types.Buddies import Utility.NotificationBroadcaster import Utility.WebApp+import Utility.Yesod import Logs.Transfer+import Build.SysConfig (packageversion) import Yesod import Yesod.Static+import Text.Hamlet import Data.Text (Text, pack, unpack) import Control.Concurrent.STM @@ -39,7 +42,7 @@ } instance Yesod WebApp where- {- Require an auth token be set when accessing any (non-static route) -}+ {- Require an auth token be set when accessing any (non-static) route -} isAuthorized _ _ = checkAuthToken secretToken {- Add the auth token to every url generated, except static subsite@@ -51,6 +54,20 @@ makeSessionBackend = webAppSessionBackend jsLoader _ = BottomOfHeadBlocking++ {- The webapp does not use defaultLayout, so this is only used+ - for error pages or any other built-in yesod page.+ - + - This can use static routes, but should use no other routes,+ - as that would expose the auth token.+ -}+ defaultLayout content = do+ webapp <- getYesod+ pageinfo <- widgetToPageContent $ do+ addStylesheet $ StaticR css_bootstrap_css+ addStylesheet $ StaticR css_bootstrap_responsive_css+ $(widgetFile "error")+ hamletToRepHtml $(hamletFile $ hamletTemplate "bootstrap") instance RenderMessage WebApp FormMessage where renderMessage _ _ = defaultFormMessage
Assistant/WebApp/routes view
@@ -3,6 +3,7 @@ /noscript/auto NoScriptAutoR GET /about AboutR GET /about/license LicenseR GET+/about/repogroups RepoGroupR GET /config ConfigR GET /config/repository RepositoriesR GET
Build/OSXMkLibs.hs view
@@ -23,35 +23,53 @@ import Utility.SafeCommand import Utility.Path +import qualified Data.Map as M+import qualified Data.Set as S++type LibMap = M.Map FilePath String+ {- Recursively find and install libs, until nothing new to install is found. -}-mklibs :: FilePath -> [FilePath] -> IO [FilePath]-mklibs appbase libdirs = do- new <- catMaybes <$> installLibs appbase- if null new- then return (libdirs++new)- else mklibs appbase (libdirs++new)+mklibs :: FilePath -> [FilePath] -> LibMap -> IO ()+mklibs appbase libdirs libmap = do+ (new, libmap') <- installLibs appbase libmap+ unless (null new) $+ mklibs appbase (libdirs++new) libmap' {- Returns directories into which new libs were installed. -}-installLibs :: FilePath -> IO [Maybe FilePath]-installLibs appbase = do- needlibs <- otool appbase- forM needlibs $ \lib -> do- let libdir = parentDir lib- let dest = appbase ++ lib+installLibs :: FilePath -> LibMap -> IO ([FilePath], LibMap)+installLibs appbase libmap = do+ (needlibs, libmap') <- otool appbase libmap+ libs <- forM needlibs $ \lib -> do+ let shortlib = fromMaybe (error "internal") (M.lookup lib libmap')+ let fulllib = dropWhile (== '/') lib+ let dest = appbase </> fulllib+ let symdest = appbase </> shortlib ifM (doesFileExist dest) ( return Nothing , do- createDirectoryIfMissing True (appbase ++ libdir)+ createDirectoryIfMissing True (parentDir dest)+ putStrLn $ "installing " ++ lib ++ " as " ++ shortlib _ <- boolSystem "cp" [File lib, File dest]- putStrLn $ "installing " ++ lib- return $ Just libdir+ _ <- boolSystem "chmod" [Param "644", File dest]+ _ <- boolSystem "ln" [Param "-s", File fulllib, File symdest]+ return $ Just appbase )+ return (catMaybes libs, libmap') -otool :: FilePath -> IO [FilePath]-otool appbase = do+{- Returns libraries to install. -}+otool :: FilePath -> LibMap -> IO ([FilePath], LibMap)+otool appbase libmap = do files <- filterM doesFileExist =<< dirContentsRecursive appbase- s <- readProcess "otool" ("-L" : files)- return $ nub $ parseOtool s+ process [] files libmap+ where+ unprocessed s = not ("@executable_path" `isInfixOf` s)+ process c [] m = return (nub $ concat c, m)+ process c (file:rest) m = do+ _ <- boolSystem "chmod" [Param "755", File file]+ libs <- filter unprocessed . parseOtool+ <$> readProcess "otool" ["-L", file]+ m' <- install_name_tool file libs m+ process (libs:c) rest m' parseOtool :: String -> [FilePath] parseOtool = catMaybes . map parse . lines@@ -60,11 +78,47 @@ | "\t" `isPrefixOf` l = headMaybe $ words l | otherwise = Nothing +{- Adjusts binaries to use libraries bundled with it, rather than the+ - system libraries. -}+install_name_tool :: FilePath -> [FilePath] -> LibMap -> IO LibMap+install_name_tool _ [] libmap = return libmap+install_name_tool binary libs libmap = do+ let (libnames, libmap') = getLibNames libs libmap+ let params = concatMap change $ zip libs libnames+ ok <- boolSystem "install_name_tool" $ params ++ [File binary]+ unless ok $+ error $ "install_name_tool failed for " ++ binary+ return libmap'+ where+ change (lib, libname) =+ [ Param "-change"+ , File lib+ , Param $ "@executable_path/" ++ libname+ ]++getLibNames :: [FilePath] -> LibMap -> ([FilePath], LibMap)+getLibNames libs libmap = go [] libs libmap+ where+ go c [] m = (reverse c, m)+ go c (l:rest) m =+ let (f, m') = getLibName l m+ in go (f:c) rest m'++{- Uses really short names for the library files it installs, because+ - binaries have arbitrarily short RPATH field limits. -}+getLibName :: FilePath -> LibMap -> (FilePath, LibMap)+getLibName lib libmap = case M.lookup lib libmap of+ Just n -> (n, libmap)+ Nothing -> (nextfreename, M.insert lib nextfreename libmap)+ where+ names = map (\c -> [c]) ['A' .. 'Z'] +++ [[n, l] | n <- ['0' .. '9'], l <- ['A' .. 'Z']]+ used = S.fromList $ M.elems libmap+ nextfreename = fromMaybe (error "ran out of short library names!") $ + headMaybe $ dropWhile (`S.member` used) names+ main :: IO () main = getArgs >>= go where go [] = error "specify OSXAPP_BASE"- go (appbase:_) = do- libdirs <- mklibs appbase []- writeFile (appbase </> "libdirs") $- unlines $ nub libdirs+ go (appbase:_) = mklibs appbase [] M.empty
CHANGELOG view
@@ -1,8 +1,37 @@-git-annex (3.20121127.1) UNRELEASED; urgency=low+git-annex (3.20121211) unstable; urgency=low - * Fix cabal build, avoiding module from hxt.+ * webapp: Defaults to sharing box.com account info with friends, allowing+ one-click enabling of the repository.+ * Fix broken .config/git-annex/program installed by standalone tarball.+ * assistant: Retrival from glacier now handled.+ * Include ssh in standalone tarball and OSX app.+ * watch: Avoid leaving hard links to files behind in .git/annex/tmp+ if a file is deleted or moved while it's being quarantined in preparation+ to being added to the annex.+ * Allow `git annex drop --from web`; of course this does not remove+ any file from the web, but it does make git-annex remove all urls+ associated with a file.+ * webapp: S3 and Glacier forms now have a select list of all+ currently-supported AWS regions.+ * webdav: Avoid trying to set props, avoiding incompatability with+ livedrive.com. Needs DAV version 0.3.+ * webapp: Prettify error display.+ * webapp: Fix bad interaction between required fields and modals.+ * webapp: Added help buttons and links next to fields that require+ explanations.+ * webapp: Encryption can be disabled when setting up remotes.+ * assistant: Avoid trying to drop content from remotes that don't have it.+ * assistant: Allow periods in ssh key comments.+ * get/copy --auto: Transfer data even if it would exceed numcopies,+ when preferred content settings want it.+ * drop --auto: Fix dropping content when there are no preferred content+ settings.+ * webapp: Allow user to specify the port when setting up a ssh or rsync+ remote.+ * assistant: Fix syncing to just created ssh remotes.+ * Enable WebDAV support in Debian package. Closes: #695532 - -- Joey Hess <joeyh@debian.org> Tue, 27 Nov 2012 22:57:39 -0400+ -- Joey Hess <joeyh@debian.org> Tue, 11 Dec 2012 11:25:03 -0400 git-annex (3.20121127) unstable; urgency=low
Command.hs view
@@ -20,7 +20,7 @@ notBareRepo, isBareRepo, numCopies,- autoCopies,+ numCopiesCheck, autoCopiesWith, checkAuto, module ReExported@@ -109,23 +109,20 @@ numCopies :: FilePath -> Annex (Maybe Int) numCopies file = readish <$> checkAttr "annex.numcopies" file +numCopiesCheck :: FilePath -> Key -> (Int -> Int -> Bool) -> Annex Bool+numCopiesCheck file key vs = do+ numcopiesattr <- numCopies file+ needed <- getNumCopies numcopiesattr+ have <- trustExclude UnTrusted =<< Remote.keyLocations key+ return $ length have `vs` needed+ {- Used for commands that have an auto mode that checks the number of known - copies of a key. - - In auto mode, first checks that the number of known - copies of the key is > or < than the numcopies setting, before running- - the action. Also checks any preferred content settings.+ - the action. -}-autoCopies :: FilePath -> Key -> (Int -> Int -> Bool) -> CommandStart -> CommandStart-autoCopies file key vs a = Annex.getState Annex.auto >>= go- where- go False = a- go True = do- numcopiesattr <- numCopies file- needed <- getNumCopies numcopiesattr- have <- trustExclude UnTrusted =<< Remote.keyLocations key- if length have `vs` needed then a else stop- autoCopiesWith :: FilePath -> Key -> (Int -> Int -> Bool) -> (Maybe Int -> CommandStart) -> CommandStart autoCopiesWith file key vs a = do numcopiesattr <- numCopies file
Command/Copy.hs view
@@ -26,10 +26,11 @@ - However, --auto mode avoids unnecessary copies, and avoids getting or - sending non-preferred content. -} start :: Maybe Remote -> Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart-start to from file (key, backend) = autoCopies file key (<) $- stopUnless shouldCopy $ - Command.Move.start to from False file (key, backend)+start to from file (key, backend) = stopUnless shouldCopy $ + Command.Move.start to from False file (key, backend) where- shouldCopy = case to of- Nothing -> checkAuto $ wantGet (Just file)- Just r -> checkAuto $ wantSend (Just file) (Remote.uuid r)+ shouldCopy = checkAuto (check <||> numCopiesCheck file key (<))+ check = case to of+ Nothing -> wantGet False (Just file)+ Just r -> wantSend False (Just file) (Remote.uuid r)+
Command/Drop.hs view
@@ -32,7 +32,7 @@ start :: Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart start from file (key, _) = autoCopiesWith file key (>) $ \numcopies ->- stopUnless (checkAuto $ wantDrop (Remote.uuid <$> from) (Just file)) $+ stopUnless (checkAuto $ wantDrop False (Remote.uuid <$> from) (Just file)) $ case from of Nothing -> startLocal file numcopies key Nothing Just remote -> do
Command/Get.hs view
@@ -24,8 +24,8 @@ withFilesInGit $ whenAnnexed $ start from] start :: Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart-start from file (key, _) = stopUnless ((not <$> inAnnex key) <&&> checkAuto (wantGet $ Just file)) $- autoCopies file key (<) $+start from file (key, _) = stopUnless (not <$> inAnnex key) $+ stopUnless (checkAuto (numCopiesCheck file key (<) <||> wantGet False (Just file))) $ do case from of Nothing -> go $ perform key file Just src ->
Creds.hs view
@@ -34,7 +34,7 @@ {- Stores creds in a remote's configuration, if the remote allows - that. Otherwise, caches them locally. -} setRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex RemoteConfig-setRemoteCredPair c storage = go =<< getRemoteCredPair' c storage+setRemoteCredPair c storage = go =<< getRemoteCredPair c storage where go (Just creds) | embedCreds c = case credPairRemoteKey storage of@@ -58,8 +58,8 @@ {- Gets a remote's credpair, from the environment if set, otherwise - from the cache in gitAnnexCredsDir, or failing that, from the - value in RemoteConfig. -}-getRemoteCredPair :: String -> RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)-getRemoteCredPair this c storage = maybe missing (return . Just) =<< getRemoteCredPair' c storage+getRemoteCredPairFor :: String -> RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)+getRemoteCredPairFor this c storage = maybe missing (return . Just) =<< getRemoteCredPair c storage where (loginvar, passwordvar) = credPairEnvironment storage missing = do@@ -70,8 +70,8 @@ ] return Nothing -getRemoteCredPair' :: RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)-getRemoteCredPair' c storage = maybe fromcache (return . Just) =<< fromenv+getRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)+getRemoteCredPair c storage = maybe fromcache (return . Just) =<< fromenv where fromenv = liftIO $ getEnvCredPair storage fromcache = maybe fromconfig (return . Just) =<< readCacheCredPair storage@@ -102,8 +102,6 @@ where (uenv, penv) = credPairEnvironment storage get = catchMaybeIO . getEnv-- {- Stores a CredPair in the environment. -} setEnvCredPair :: CredPair -> CredPairStorage -> IO ()
Limit.hs view
@@ -34,7 +34,7 @@ {- Checks if there are user-specified limits. -} limited :: Annex Bool-limited = (not . Utility.Matcher.matchesAny) <$> getMatcher'+limited = (not . Utility.Matcher.isEmpty) <$> getMatcher' {- Gets a matcher for the user-specified limits. The matcher is cached for - speed; once it's obtained the user-specified limits can't change. -}
Logs/PreferredContent.hs view
@@ -48,8 +48,8 @@ {- Checks if a file is preferred content for the specified repository - (or the current repository if none is specified). -}-isPreferredContent :: Maybe UUID -> AssumeNotPresent -> FilePath -> Annex Bool-isPreferredContent mu notpresent file = do+isPreferredContent :: Maybe UUID -> AssumeNotPresent -> FilePath -> Bool -> Annex Bool+isPreferredContent mu notpresent file def = do matchfile <- getTopFilePath <$> inRepo (toTopFilePath file) let fi = Annex.FileInfo { Annex.matchFile = matchfile@@ -58,9 +58,11 @@ u <- maybe getUUID return mu m <- preferredContentMap case M.lookup u m of- Nothing -> return True- Just matcher -> Utility.Matcher.matchMrun matcher $ \a ->- a notpresent fi+ Nothing -> return def+ Just matcher+ | Utility.Matcher.isEmpty matcher -> return def+ | otherwise -> Utility.Matcher.matchMrun matcher $ + \a -> a notpresent fi {- The map is cached for speed. -} preferredContentMap :: Annex Annex.PreferredContentMap
Logs/Web.hs view
@@ -8,9 +8,9 @@ module Logs.Web ( URLString, webUUID,- setUrl,+ getUrls, setUrlPresent,- getUrls+ setUrlMissing, ) where import Common.Annex@@ -45,16 +45,13 @@ then go ls else return us -{- Records a change in an url for a key. -}-setUrl :: Key -> URLString -> LogStatus -> Annex ()-setUrl key url status = do+setUrlPresent :: Key -> URLString -> Annex ()+setUrlPresent key url = do us <- getUrls key- unless (status == InfoPresent && url `elem` us) $ do- addLog (urlLog key) =<< logNow status url-- -- update location log to indicate that the web has the key, or not- us' <- getUrls key- logChange key webUUID (if null us' then InfoMissing else InfoPresent)+ unless (url `elem` us) $ do+ addLog (urlLog key) =<< logNow InfoPresent url+ -- update location log to indicate that the web has the key+ logChange key webUUID InfoPresent -setUrlPresent :: Key -> URLString -> Annex ()-setUrlPresent key url = setUrl key url InfoPresent+setUrlMissing :: Key -> URLString -> Annex ()+setUrlMissing key url = addLog (urlLog key) =<< logNow InfoMissing url
Makefile view
@@ -144,11 +144,11 @@ @cabal upload dist/*.tar.gz THIRDPARTY_BINS=git curl lsof xargs rsync uuid wget gpg \- sha1sum sha224sum sha256sum sha384sum sha512sum cp+ sha1sum sha224sum sha256sum sha384sum sha512sum cp ssh sh LINUXSTANDALONE_DEST=$(GIT_ANNEX_TMP_BUILD_DIR)/git-annex.linux linuxstandalone:- GIT_ANNEX_LOCAL_FEATURES="$(GIT_ANNEX_LOCAL_FEATURES) -DWITH_OLD_SSH" $(MAKE) git-annex+ $(MAKE) git-annex rm -rf "$(LINUXSTANDALONE_DEST)" @@ -160,8 +160,15 @@ ln -sf git-annex "$(LINUXSTANDALONE_DEST)/bin/git-annex-shell" zcat standalone/licences.gz > $(LINUXSTANDALONE_DEST)/LICENSE + set -e; \ for bin in $(THIRDPARTY_BINS); do \- cp "$$(which "$$bin")" "$(LINUXSTANDALONE_DEST)/bin/"; \+ p="$$(which "$$bin")"; \+ if [ -z "$$p" ]; then \+ echo "** missing $$bin" >&2; \+ exit 1; \+ else \+ cp "$$p" "$(LINUXSTANDALONE_DEST)/bin/"; \+ fi; \ done install -d "$(LINUXSTANDALONE_DEST)/git-core"@@ -186,32 +193,38 @@ OSXAPP_DEST=$(GIT_ANNEX_TMP_BUILD_DIR)/build-dmg/git-annex.app OSXAPP_BASE=$(OSXAPP_DEST)/Contents/MacOS osxapp:- GIT_ANNEX_LOCAL_FEATURES="$(GIT_ANNEX_LOCAL_FEATURES) -DWITH_OLD_SSH" $(MAKE) git-annex+ $(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)" - install -d "$(OSXAPP_BASE)/bin"- cp git-annex "$(OSXAPP_BASE)/bin/"- strip "$(OSXAPP_BASE)/bin/git-annex"- ln -sf git-annex "$(OSXAPP_BASE)/bin/git-annex-shell"+ install -d "$(OSXAPP_BASE)"+ cp git-annex "$(OSXAPP_BASE)"+ strip "$(OSXAPP_BASE)/git-annex"+ ln -sf git-annex "$(OSXAPP_BASE)/git-annex-shell" gzcat standalone/licences.gz > $(OSXAPP_BASE)/LICENSE cp $(OSXAPP_BASE)/LICENSE $(GIT_ANNEX_TMP_BUILD_DIR)/build-dmg/LICENSE.txt + set -e; \ for bin in $(THIRDPARTY_BINS); do \- cp "$$(which "$$bin")" "$(OSXAPP_BASE)/bin/"; \+ p="$$(which "$$bin")"; \+ if [ -z "$$p" ]; then \+ echo "** missing $$bin" >&2; \+ exit 1; \+ else \+ cp "$$p" "$(OSXAPP_BASE)"; \+ fi; \ done - install -d "$(OSXAPP_BASE)/git-core"- (cd "$(shell git --exec-path)" && tar c .) | (cd "$(OSXAPP_BASE)"/git-core && tar x)+ (cd "$(shell git --exec-path)" && tar c .) | (cd "$(OSXAPP_BASE)" && tar x) runghc Build/OSXMkLibs.hs $(OSXAPP_BASE) rm -f tmp/git-annex.dmg hdiutil create -size 640m -format UDRW -srcfolder $(GIT_ANNEX_TMP_BUILD_DIR)/build-dmg \ -volname git-annex -o tmp/git-annex.dmg rm -f tmp/git-annex.dmg.bz2- bzip2 tmp/git-annex.dmg+ bzip2 --fast tmp/git-annex.dmg # used by ./ghci getflags:
Remote/Bup.hs view
@@ -38,7 +38,7 @@ setup = bupSetup } -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote gen r u c = do buprepo <- getRemoteConfig r "buprepo" (error "missing buprepo") cst <- remoteCost r (if bupLocal buprepo then semiCheapRemoteCost else expensiveRemoteCost)
Remote/Directory.hs view
@@ -33,7 +33,7 @@ setup = directorySetup } -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote gen r u c = do dir <- getRemoteConfig r "directory" (error "missing directory") cst <- remoteCost r cheapRemoteCost@@ -52,7 +52,7 @@ hasKey = checkPresent dir chunksize, hasKeyCheap = True, whereisKey = Nothing,- config = Nothing,+ config = M.empty, repo = r, localpath = Just dir, readonly = False,
Remote/Git.hs view
@@ -83,7 +83,7 @@ repoCheap :: Git.Repo -> Bool repoCheap = not . Git.repoIsUrl -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote gen r u _ = new <$> remoteCost r defcst where defcst = if repoCheap r then cheapRemoteCost else expensiveRemoteCost@@ -98,7 +98,7 @@ , hasKey = inAnnex r , hasKeyCheap = repoCheap r , whereisKey = Nothing- , config = Nothing+ , config = M.empty , localpath = if Git.repoIsLocal r || Git.repoIsLocalUnknown r then Just $ Git.repoPath r else Nothing
Remote/Glacier.hs view
@@ -5,9 +5,10 @@ - Licensed under the GNU GPL version 3 or higher. -} -module Remote.Glacier (remote) where+module Remote.Glacier (remote, jobList) where import qualified Data.Map as M+import qualified Data.Text as T import System.Environment import Common.Annex@@ -36,34 +37,31 @@ setup = glacierSetup } -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote-gen r u c = do- cst <- remoteCost r veryExpensiveRemoteCost- return $ gen' r u c cst-gen' :: Git.Repo -> UUID -> Maybe RemoteConfig -> Int -> Remote-gen' r u c cst =- encryptableRemote c+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote+gen r u c = new <$> remoteCost r veryExpensiveRemoteCost+ where+ new cst = encryptableRemote c (storeEncrypted this) (retrieveEncrypted this) this- where- this = Remote {- uuid = u,- cost = cst,- name = Git.repoDescribe r,- storeKey = store this,- retrieveKeyFile = retrieve this,- retrieveKeyFileCheap = retrieveCheap this,- removeKey = remove this,- hasKey = checkPresent this,- hasKeyCheap = False,- whereisKey = Nothing,- config = c,- repo = r,- localpath = Nothing,- readonly = False,- remotetype = remote- }+ where+ this = Remote {+ uuid = u,+ cost = cst,+ name = Git.repoDescribe r,+ storeKey = store this,+ retrieveKeyFile = retrieve this,+ retrieveKeyFileCheap = retrieveCheap this,+ removeKey = remove this,+ hasKey = checkPresent this,+ hasKeyCheap = False,+ whereisKey = Nothing,+ config = c,+ repo = r,+ localpath = Nothing,+ readonly = False,+ remotetype = remote+ } glacierSetup :: UUID -> RemoteConfig -> Annex RemoteConfig glacierSetup u c = do@@ -76,7 +74,7 @@ remotename = fromJust (M.lookup "name" c) defvault = remotename ++ "-" ++ fromUUID u defaults = M.fromList- [ ("datacenter", "us-east-1")+ [ ("datacenter", T.unpack $ AWS.defaultRegion AWS.Glacier) , ("vault", defvault) ] @@ -115,13 +113,13 @@ storeHelper :: Remote -> Key -> (Handle -> IO ()) -> Annex Bool storeHelper r k feeder = go =<< glacierEnv c u where- c = fromJust $ config r+ c = config r u = uuid r params = glacierParams c [ Param "archive" , Param "upload" , Param "--name", Param $ archive r k- , Param $ remoteVault r+ , Param $ getVault $ config r , Param "-" ] go Nothing = return False@@ -135,13 +133,13 @@ retrieveHelper :: Remote -> Key -> (Handle -> IO ()) -> Annex Bool retrieveHelper r k reader = go =<< glacierEnv c u where- c = fromJust $ config r+ c = config r u = uuid r params = glacierParams c [ Param "archive" , Param "retrieve" , Param "-o-"- , Param $ remoteVault r+ , Param $ getVault $ config r , Param $ archive r k ] go Nothing = return False@@ -163,14 +161,14 @@ remove r k = glacierAction r [ Param "archive" , Param "delete"- , Param $ remoteVault r+ , Param $ getVault $ config r , Param $ archive r k ] checkPresent :: Remote -> Key -> Annex (Either String Bool) checkPresent r k = do showAction $ "checking " ++ name r- go =<< glacierEnv (fromJust $ config r) (uuid r)+ go =<< glacierEnv (config r) (uuid r) where go Nothing = return $ Left "cannot check glacier" go (Just e) = do@@ -190,7 +188,7 @@ params = [ Param "archive" , Param "checkpresent"- , Param $ remoteVault r+ , Param $ getVault $ config r , Param "--quiet" , Param $ archive r k ]@@ -205,7 +203,7 @@ return $ Right False glacierAction :: Remote -> [CommandParam] -> Annex Bool-glacierAction r params = runGlacier (fromJust $ config r) (uuid r) params+glacierAction r params = runGlacier (config r) (uuid r) params runGlacier :: RemoteConfig -> UUID -> [CommandParam] -> Annex Bool runGlacier c u params = go =<< glacierEnv c u@@ -221,7 +219,7 @@ (fromJust $ M.lookup "datacenter" c) glacierEnv :: RemoteConfig -> UUID -> Annex (Maybe [(String, String)])-glacierEnv c u = go =<< getRemoteCredPair "glacier" c creds+glacierEnv c u = go =<< getRemoteCredPairFor "glacier" c creds where go Nothing = return Nothing go (Just (user, pass)) = do@@ -231,16 +229,13 @@ creds = AWS.creds u (uk, pk) = credPairEnvironment creds -remoteVault :: Remote -> Vault-remoteVault = vault . fromJust . config--vault :: RemoteConfig -> Vault-vault = fromJust . M.lookup "vault"+getVault :: RemoteConfig -> Vault+getVault = fromJust . M.lookup "vault" archive :: Remote -> Key -> Archive archive r k = fileprefix ++ key2file k where- fileprefix = M.findWithDefault "" "fileprefix" $ fromJust $ config r+ fileprefix = M.findWithDefault "" "fileprefix" $ config r -- glacier vault create will succeed even if the vault already exists. genVault :: RemoteConfig -> UUID -> Annex ()@@ -250,5 +245,50 @@ params = [ Param "vault" , Param "create"- , Param $ vault c+ , Param $ getVault c ]++{- Partitions the input list of keys into ones which have+ - glacier retieval jobs that have succeeded, or failed.+ -+ - A complication is that `glacier job list` will display the encrypted+ - keys when the remote is encrypted.+ -}+jobList :: Remote -> [Key] -> Annex ([Key], [Key])+jobList r keys = go =<< glacierEnv (config r) (uuid r)+ where+ params = [ Param "job", Param "list" ]+ nada = ([], [])+ myvault = getVault $ config r++ go Nothing = return nada+ go (Just e) = do+ v <- liftIO $ catchMaybeIO $ + readProcessEnv "glacier" (toCommand params) (Just e)+ maybe (return nada) extract v++ extract s = do+ let result@(succeeded, failed) =+ parse nada $ (map words . lines) s+ if result == nada+ then return nada+ else do+ enckeys <- forM keys $ \k ->+ maybe k snd <$> cipherKey (config r) k+ let keymap = M.fromList $ zip enckeys keys+ let convert = catMaybes . map (`M.lookup` keymap)+ return (convert succeeded, convert failed)++ parse c [] = c+ parse c@(succeeded, failed) ((status:_date:vault:key:[]):rest)+ | vault == myvault =+ case file2key key of+ Nothing -> parse c rest+ Just k+ | "a/d" `isPrefixOf` status ->+ parse (k:succeeded, failed) rest+ | "a/e" `isPrefixOf` status ->+ parse (succeeded, k:failed) rest+ | otherwise ->+ parse c rest+ parse c (_:rest) = parse c rest
Remote/Helper/AWS.hs view
@@ -5,11 +5,16 @@ - Licensed under the GNU GPL version 3 or higher. -} +{-# LANGUAGE OverloadedStrings, TupleSections #-}+ module Remote.Helper.AWS where import Common.Annex import Creds +import qualified Data.Map as M+import Data.Text (Text)+ creds :: UUID -> CredPairStorage creds u = CredPairStorage { credPairFile = fromUUID u@@ -19,3 +24,43 @@ setCredsEnv :: CredPair -> IO () setCredsEnv p = setEnvCredPair p $ creds undefined++data Service = S3 | Glacier+ deriving (Eq)++type Region = Text++regionMap :: Service -> M.Map Text Region+regionMap = M.fromList . regionInfo++defaultRegion :: Service -> Region+defaultRegion = snd . Prelude.head . regionInfo++{- S3 and Glacier use different names for some regions. Ie, "us-east-1"+ - cannot be used with S3, while "US" cannot be used with Glacier. Dunno why.+ - Also, Glacier is not yet available in all regions. -}+regionInfo :: Service -> [(Text, Region)]+regionInfo service = map (\(t, r) -> (t, fromServiceRegion r)) $ + filter (matchingService . snd) $+ concatMap (\(t, l) -> map (t,) l) regions+ where+ regions =+ [ ("US East (N. Virginia)", [S3Region "US", GlacierRegion "us-east-1"])+ , ("US West (Oregon)", [BothRegion "us-west-2"])+ , ("US West (N. California)", [BothRegion "us-west-1"])+ , ("EU (Ireland)", [S3Region "EU", GlacierRegion "eu-west-1"])+ , ("Asia Pacific (Singapore)", [S3Region "ap-southeast-1"])+ , ("Asia Pacific (Tokyo)", [BothRegion "ap-northeast-1"])+ , ("Asia Pacific (Sydney)", [S3Region "ap-southeast-2"])+ , ("South America (São Paulo)", [S3Region "sa-east-1"])+ ]++ fromServiceRegion (BothRegion s) = s+ fromServiceRegion (S3Region s) = s+ fromServiceRegion (GlacierRegion s) = s++ matchingService (BothRegion _) = True+ matchingService (S3Region _) = service == S3+ matchingService (GlacierRegion _) = service == Glacier++data ServiceRegion = BothRegion Region | S3Region Region | GlacierRegion Region
Remote/Helper/Chunked.hs view
@@ -20,9 +20,8 @@ type ChunkSize = Maybe Int64 {- Gets a remote's configured chunk size. -}-chunkSize :: Maybe RemoteConfig -> ChunkSize-chunkSize Nothing = Nothing-chunkSize (Just m) =+chunkSize :: RemoteConfig -> ChunkSize+chunkSize m = case M.lookup "chunksize" m of Nothing -> Nothing Just v -> case readSize dataUnits v of
Remote/Helper/Encryptable.hs view
@@ -44,7 +44,7 @@ - Two additional functions must be provided by the remote, - to support storing and retrieving encrypted content. -} encryptableRemote- :: Maybe RemoteConfig+ :: RemoteConfig -> ((Cipher, Key) -> Key -> MeterUpdate -> Annex Bool) -> ((Cipher, Key) -> Key -> FilePath -> Annex Bool) -> Remote@@ -103,9 +103,8 @@ | otherwise = False {- Gets encryption Cipher, and encrypted version of Key. -}-cipherKey :: Maybe RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))-cipherKey Nothing _ = return Nothing-cipherKey (Just c) k = maybe Nothing make <$> remoteCipher c+cipherKey :: RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))+cipherKey c k = maybe Nothing make <$> remoteCipher c where make ciphertext = Just (ciphertext, encryptKey ciphertext k)
Remote/Hook.hs view
@@ -29,7 +29,7 @@ setup = hookSetup } -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote gen r u c = do hooktype <- getRemoteConfig r "hooktype" (error "missing hooktype") cst <- remoteCost r expensiveRemoteCost@@ -47,7 +47,7 @@ hasKey = checkPresent r hooktype, hasKeyCheap = False, whereisKey = Nothing,- config = Nothing,+ config = M.empty, localpath = Nothing, repo = r, readonly = False,
Remote/List.hs view
@@ -81,7 +81,7 @@ remoteGen :: (M.Map UUID RemoteConfig) -> RemoteType -> Git.Repo -> Annex Remote remoteGen m t r = do u <- getRepoUUID r- addHooks =<< generate t r u (M.lookup u m)+ addHooks =<< generate t r u (fromMaybe M.empty $ M.lookup u m) {- Updates a local git Remote, re-reading its git config. -} updateRemote :: Remote -> Annex Remote
Remote/Rsync.hs view
@@ -38,7 +38,7 @@ setup = rsyncSetup } -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote gen r u c = do o <- genRsyncOpts r c cst <- remoteCost r expensiveRemoteCost@@ -56,7 +56,7 @@ , hasKey = checkPresent r o , hasKeyCheap = False , whereisKey = Nothing- , config = Nothing+ , config = M.empty , repo = r , localpath = if rsyncUrlIsPath $ rsyncUrl o then Just $ rsyncUrl o@@ -65,12 +65,12 @@ , remotetype = remote } -genRsyncOpts :: Git.Repo -> Maybe RemoteConfig -> Annex RsyncOpts+genRsyncOpts :: Git.Repo -> RemoteConfig -> Annex RsyncOpts genRsyncOpts r c = do url <- getRemoteConfig r "rsyncurl" (error "missing rsyncurl") opts <- map Param . filter safe . words <$> getRemoteConfig r "rsync-options" ""- let escape = maybe True (\m -> M.lookup "shellescape" m /= Just "no") c+ let escape = M.lookup "shellescape" c /= Just "no" return $ RsyncOpts url opts escape where safe o
Remote/S3.hs view
@@ -11,6 +11,7 @@ import Network.AWS.S3Object import Network.AWS.S3Bucket hiding (size) import Network.AWS.AWSResult+import qualified Data.Text as T import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.Map as M import Data.Char@@ -36,34 +37,31 @@ setup = s3Setup } -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote-gen r u c = do- cst <- remoteCost r expensiveRemoteCost- return $ gen' r u c cst-gen' :: Git.Repo -> UUID -> Maybe RemoteConfig -> Int -> Remote-gen' r u c cst =- encryptableRemote c+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote+gen r u c = new <$> remoteCost r expensiveRemoteCost+ where+ new cst = encryptableRemote c (storeEncrypted this) (retrieveEncrypted this) this- where- this = Remote {- uuid = u,- cost = cst,- name = Git.repoDescribe r,- storeKey = store this,- retrieveKeyFile = retrieve this,- retrieveKeyFileCheap = retrieveCheap this,- removeKey = remove this,- hasKey = checkPresent this,- hasKeyCheap = False,- whereisKey = Nothing,- config = c,- repo = r,- localpath = Nothing,- readonly = False,- remotetype = remote- }+ where+ this = Remote {+ uuid = u,+ cost = cst,+ name = Git.repoDescribe r,+ storeKey = store this,+ retrieveKeyFile = retrieve this,+ retrieveKeyFileCheap = retrieveCheap this,+ removeKey = remove this,+ hasKey = checkPresent this,+ hasKeyCheap = False,+ whereisKey = Nothing,+ config = c,+ repo = r,+ localpath = Nothing,+ readonly = False,+ remotetype = remote+ } s3Setup :: UUID -> RemoteConfig -> Annex RemoteConfig s3Setup u c = handlehost $ M.lookup "host" c@@ -71,7 +69,7 @@ remotename = fromJust (M.lookup "name" c) defbucket = remotename ++ "-" ++ fromUUID u defaults = M.fromList- [ ("datacenter", "US")+ [ ("datacenter", T.unpack $ AWS.defaultRegion AWS.S3) , ("storageclass", "STANDARD") , ("host", defaultAmazonS3Host) , ("port", show defaultAmazonS3Port)@@ -143,13 +141,13 @@ sendObject conn object where storageclass =- case fromJust $ M.lookup "storageclass" $ fromJust $ config r of+ case fromJust $ M.lookup "storageclass" $ config r of "REDUCED_REDUNDANCY" -> REDUCED_REDUNDANCY _ -> STANDARD getsize = liftIO $ fromIntegral . fileSize <$> getFileStatus file - xheaders = filter isxheader $ M.assocs $ fromJust $ config r+ xheaders = filter isxheader $ M.assocs $ config r isxheader (h, _) = "x-amz-" `isPrefixOf` h retrieve :: Remote -> Key -> AssociatedFile -> FilePath -> Annex Bool@@ -207,10 +205,8 @@ s3Action :: Remote -> a -> ((AWSConnection, String) -> Annex a) -> Annex a s3Action r noconn action = do- when (isNothing $ config r) $- error $ "Missing configuration for special remote " ++ name r- let bucket = M.lookup "bucket" $ fromJust $ config r- conn <- s3Connection (fromJust $ config r) (uuid r)+ let bucket = M.lookup "bucket" $ config r+ conn <- s3Connection (config r) (uuid r) case (bucket, conn) of (Just b, Just c) -> action (c, b) _ -> return noconn@@ -222,7 +218,7 @@ Just "ia" -> iaMunge $ fileprefix ++ s _ -> fileprefix ++ s fileprefix = M.findWithDefault "" "fileprefix" c- c = fromJust $ config r+ c = config r bucketKey :: Remote -> String -> Key -> S3Object bucketKey r bucket k = S3Object bucket (bucketFile r k) "" [] L.empty@@ -262,7 +258,7 @@ maybe (error "Cannot connect to S3") return =<< s3Connection c u s3Connection :: RemoteConfig -> UUID -> Annex (Maybe AWSConnection)-s3Connection c u = go =<< getRemoteCredPair "S3" c (AWS.creds u)+s3Connection c u = go =<< getRemoteCredPairFor "S3" c (AWS.creds u) where go Nothing = return Nothing go (Just (ak, sk)) = return $ Just $ AWSConnection host port ak sk
Remote/Web.hs view
@@ -17,6 +17,8 @@ import qualified Utility.Url as Url import Types.Key +import qualified Data.Map as M+ remote :: RemoteType remote = RemoteType { typename = "web",@@ -33,7 +35,7 @@ r <- liftIO $ Git.Construct.remoteNamed "web" Git.Construct.fromUnknown return [r] -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote gen r _ _ = return Remote { uuid = webUUID,@@ -46,7 +48,7 @@ hasKey = checkKey, hasKeyCheap = False, whereisKey = Just getUrls,- config = Nothing,+ config = M.empty, localpath = Nothing, repo = r, readonly = True,@@ -72,9 +74,9 @@ return False dropKey :: Key -> Annex Bool-dropKey _ = do- warning "removal from web not supported"- return False+dropKey k = do+ mapM_ (setUrlMissing k) =<< getUrls k+ return True checkKey :: Key -> Annex (Either String Bool) checkKey key = do
Remote/WebDAV.hs view
@@ -7,15 +7,13 @@ {-# LANGUAGE ScopedTypeVariables #-} -module Remote.WebDAV (remote, setCredsEnv) where+module Remote.WebDAV (remote, davCreds, setCredsEnv) where import Network.Protocol.HTTP.DAV import qualified Data.Map as M import qualified Data.ByteString.UTF8 as B8 import qualified Data.ByteString.Lazy.UTF8 as L8 import qualified Data.ByteString.Lazy as L-import qualified Data.Text.Lazy as LT-import qualified Text.XML as XML import Network.URI (normalizePathSegments) import qualified Control.Exception as E import Network.HTTP.Conduit (HttpException(..))@@ -45,34 +43,31 @@ setup = webdavSetup } -gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex Remote-gen r u c = do- cst <- remoteCost r expensiveRemoteCost- return $ gen' r u c cst-gen' :: Git.Repo -> UUID -> Maybe RemoteConfig -> Int -> Remote-gen' r u c cst =- encryptableRemote c+gen :: Git.Repo -> UUID -> RemoteConfig -> Annex Remote+gen r u c = new <$> remoteCost r expensiveRemoteCost+ where+ new cst = encryptableRemote c (storeEncrypted this) (retrieveEncrypted this) this- where- this = Remote {- uuid = u,- cost = cst,- name = Git.repoDescribe r,- storeKey = store this,- retrieveKeyFile = retrieve this,- retrieveKeyFileCheap = retrieveCheap this,- removeKey = remove this,- hasKey = checkPresent this,- hasKeyCheap = False,- whereisKey = Nothing,- config = c,- repo = r,- localpath = Nothing,- readonly = False,- remotetype = remote- }+ where+ this = Remote {+ uuid = u,+ cost = cst,+ name = Git.repoDescribe r,+ storeKey = store this,+ retrieveKeyFile = retrieve this,+ retrieveKeyFileCheap = retrieveCheap this,+ removeKey = remove this,+ hasKey = checkPresent this,+ hasKeyCheap = False,+ whereisKey = Nothing,+ config = c,+ repo = r,+ localpath = Nothing,+ readonly = False,+ remotetype = remote+ } webdavSetup :: UUID -> RemoteConfig -> Annex RemoteConfig webdavSetup u c = do@@ -112,8 +107,8 @@ void $ catchMaybeHttp (deleteContent desturl user pass) davMkdir (urlParent desturl) user pass moveContent srcurl (B8.fromString desturl) user pass- storehttp url v = putContentAndProps url user pass- (noProps, (contentType, v))+ storehttp url v = putContent url user pass+ (contentType, v) retrieveCheap :: Remote -> Key -> FilePath -> Annex Bool retrieveCheap _ _ _ = return False@@ -201,14 +196,12 @@ keyurl = davLocation baseurl k ++ keyFile k davAction :: Remote -> a -> ((DavUrl, DavUser, DavPass) -> Annex a) -> Annex a-davAction r unconfigured action = case config r of- Nothing -> return unconfigured- Just c -> do- mcreds <- getCreds c (uuid r)- case (mcreds, M.lookup "url" c) of- (Just (user, pass), Just url) ->- action (url, toDavUser user, toDavPass pass)- _ -> return unconfigured+davAction r unconfigured action = do+ mcreds <- getCreds (config r) (uuid r)+ case (mcreds, M.lookup "url" $ config r) of+ (Just (user, pass), Just url) ->+ action (url, toDavUser user, toDavPass pass)+ _ -> return unconfigured toDavUser :: String -> DavUser toDavUser = B8.fromString@@ -297,14 +290,15 @@ testDav :: String -> Maybe CredPair -> Annex () testDav baseurl (Just (u, p)) = do showSideAction "testing WebDAV server"- liftIO $ either (throwIO . showEitherException) (const noop)- =<< catchHttp go+ test "make directory" $ davMkdir baseurl user pass+ test "write file" $ putContent testurl user pass+ (contentType, L.empty)+ test "delete file" $ deleteContent testurl user pass where- go = do- davMkdir baseurl user pass- putContentAndProps testurl user pass- (noProps, (contentType, L.empty))- deleteContent testurl user pass+ test desc a = liftIO $+ either (\e -> throwIO $ "WebDAV failed to " ++ desc ++ ": " ++ showEitherException e)+ (const noop)+ =<< catchHttp a user = toDavUser u pass = toDavPass p@@ -315,13 +309,8 @@ contentType :: Maybe B8.ByteString contentType = Just $ B8.fromString "application/octet-stream" -{- The DAV library requires that properties be specified when storing a file.- - This just omits any real properties. -}-noProps :: XML.Document-noProps = XML.parseText_ XML.def $ LT.pack "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<propertyupdate/>"- getCreds :: RemoteConfig -> UUID -> Annex (Maybe CredPair)-getCreds c u = getRemoteCredPair "webdav" c (davCreds u)+getCreds c u = getRemoteCredPairFor "webdav" c (davCreds u) davCreds :: UUID -> CredPairStorage davCreds u = CredPairStorage
Types/Remote.hs view
@@ -27,7 +27,7 @@ -- enumerates remotes of this type enumerate :: a [Git.Repo], -- generates a remote of this type- generate :: Git.Repo -> UUID -> Maybe RemoteConfig -> a (RemoteA a),+ generate :: Git.Repo -> UUID -> RemoteConfig -> a (RemoteA a), -- initializes or changes a remote setup :: UUID -> RemoteConfig -> a RemoteConfig }@@ -62,8 +62,8 @@ hasKeyCheap :: Bool, -- Some remotes can provide additional details for whereis. whereisKey :: Maybe (Key -> a [String]),- -- a Remote can have a persistent configuration store- config :: Maybe RemoteConfig,+ -- a Remote has a persistent configuration store+ config :: RemoteConfig, -- git configuration for the remote repo :: Git.Repo, -- a Remote can be assocated with a specific local filesystem path
Types/StandardGroups.hs view
@@ -36,6 +36,6 @@ preferredContent :: StandardGroup -> String preferredContent ClientGroup = "exclude=*/archive/* and exclude=archive/*" preferredContent TransferGroup = "not (inallgroup=client and copies=client:2) and " ++ preferredContent ClientGroup-preferredContent BackupGroup = "" -- all content is preferred+preferredContent BackupGroup = "include=*" preferredContent SmallArchiveGroup = "(include=*/archive/* or include=archive/*) and " ++ preferredContent FullArchiveGroup preferredContent FullArchiveGroup = "not (copies=archive:1 or copies=smallarchive:1)"
Utility/Daemon.hs view
@@ -19,9 +19,12 @@ - When successful, does not return. -} daemonize :: Fd -> Maybe FilePath -> Bool -> IO () -> IO () daemonize logfd pidfile changedirectory a = do+ maybe noop checkalreadyrunning pidfile _ <- forkProcess child1 out where+ checkalreadyrunning f = maybe noop (const $ alreadyRunning) + =<< checkDaemon f child1 = do _ <- createSession _ <- forkProcess child2@@ -53,15 +56,17 @@ { trunc = True } locked' <- catchMaybeIO $ setLock fd' (WriteLock, AbsoluteSeek, 0, 0) case (locked, locked') of- (Nothing, _) -> alreadyrunning- (_, Nothing) -> alreadyrunning+ (Nothing, _) -> alreadyRunning+ (_, Nothing) -> alreadyRunning _ -> do _ <- fdWrite fd' =<< show <$> getProcessID renameFile newfile file closeFd fd where newfile = file ++ ".new"- alreadyrunning = error "Daemon is already running."++alreadyRunning :: IO ()+alreadyRunning = error "Daemon is already running." {- Checks if the daemon is running, by checking that the pid file - is locked by the same process that is listed in the pid file.
Utility/Matcher.hs view
@@ -26,7 +26,7 @@ match, matchM, matchMrun,- matchesAny+ isEmpty ) where import Common@@ -105,9 +105,7 @@ go (MNot m1) = liftM not (go m1) 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- - to construct matchers that match anything but are more complicated. -}-matchesAny :: Matcher a -> Bool-matchesAny MAny = True-matchesAny _ = False+{- Checks if a matcher contains no limits. -}+isEmpty :: Matcher a -> Bool+isEmpty MAny = True+isEmpty _ = False
Utility/SRV.hs view
@@ -14,6 +14,7 @@ mkSRVTcp, mkSRV, lookupSRV,+ lookupSRVHost, ) where import Utility.Process
debian/changelog view
@@ -1,8 +1,37 @@-git-annex (3.20121127.1) UNRELEASED; urgency=low+git-annex (3.20121211) unstable; urgency=low - * Fix cabal build, avoiding module from hxt.+ * webapp: Defaults to sharing box.com account info with friends, allowing+ one-click enabling of the repository.+ * Fix broken .config/git-annex/program installed by standalone tarball.+ * assistant: Retrival from glacier now handled.+ * Include ssh in standalone tarball and OSX app.+ * watch: Avoid leaving hard links to files behind in .git/annex/tmp+ if a file is deleted or moved while it's being quarantined in preparation+ to being added to the annex.+ * Allow `git annex drop --from web`; of course this does not remove+ any file from the web, but it does make git-annex remove all urls+ associated with a file.+ * webapp: S3 and Glacier forms now have a select list of all+ currently-supported AWS regions.+ * webdav: Avoid trying to set props, avoiding incompatability with+ livedrive.com. Needs DAV version 0.3.+ * webapp: Prettify error display.+ * webapp: Fix bad interaction between required fields and modals.+ * webapp: Added help buttons and links next to fields that require+ explanations.+ * webapp: Encryption can be disabled when setting up remotes.+ * assistant: Avoid trying to drop content from remotes that don't have it.+ * assistant: Allow periods in ssh key comments.+ * get/copy --auto: Transfer data even if it would exceed numcopies,+ when preferred content settings want it.+ * drop --auto: Fix dropping content when there are no preferred content+ settings.+ * webapp: Allow user to specify the port when setting up a ssh or rsync+ remote.+ * assistant: Fix syncing to just created ssh remotes.+ * Enable WebDAV support in Debian package. Closes: #695532 - -- Joey Hess <joeyh@debian.org> Tue, 27 Nov 2012 22:57:39 -0400+ -- Joey Hess <joeyh@debian.org> Tue, 11 Dec 2012 11:25:03 -0400 git-annex (3.20121127) unstable; urgency=low
debian/control view
@@ -13,7 +13,7 @@ libghc-http-dev, libghc-utf8-string-dev, libghc-hs3-dev (>= 0.5.6),- libghc-dav-dev (>= 0.2),+ libghc-dav-dev (>= 0.3), libghc-testpack-dev, libghc-quickcheck2-dev, libghc-monad-control-dev (>= 0.3),
debian/rules view
@@ -2,9 +2,9 @@ ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH) ifeq (install ok installed,$(shell dpkg-query -W -f '$${Status}' libghc-yesod-dev 2>/dev/null))-export FEATURES=-DWITH_ASSISTANT -DWITH_S3 -DWITH_OLD_URI -DWITH_OLD_YESOD -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP+export FEATURES=-DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBDAV -DWITH_HOST -DWITH_OLD_URI -DWITH_PAIRING -DWITH_XMPP -DWITH_WEBAPP -DWITH_OLD_YESOD else-export FEATURES=-DWITH_ASSISTANT -DWITH_S3 -DWITH_OLD_URI -DWITH_PAIRING -DWITH_XMPP+export FEATURES=-DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBDAV -DWITH_HOST -DWITH_OLD_URI -DWITH_PAIRING -DWITH_XMPP endif %:
doc/assistant/release_notes.mdwn view
@@ -1,3 +1,38 @@+## version 3.20121211++This release of the git-annex assistant (which is still in beta)+consists of mostly bugfixes, user interface improvements, and improvements+to existing features.++In general, anything you can configure with the assistant's web app+will work. Some examples of use cases supported by this release include:++* Using Box.com's 5 gigabytes of free storage space as a cloud transfer+ point between between repositories that cannot directly contact+ one-another. (Many other cloud providers are also supported, from Rsync.net+ to Amazon S3, to your own ssh server.)+* Archiving or backing up files to Amazon Glacier. See [[archival_walkthrough]].+* [[Sharing repositories with friends|share_with_a_friend_walkthrough]]+ contacted through a Jabber server (such as Google Talk).+* [[Pairing|pairing_walkthrough]] two computers that are on the same local+ network (or VPN) and automatically keeping the files in the annex in+ sync as changes are made to them.+* Cloning your repository to removable drives, USB keys, etc. The assistant+ will notice when the drive is mounted and keep it in sync.+ Such a drive can be stored as an offline backup, or transported between+ computers to keep them in sync.++The following are known limitations of this release of the git-annex+assistant:++* The Max OSX standalone app may not work on all versions of Max OSX.+ Please test!+* On Mac OSX and BSD operating systems, the assistant uses kqueue to watch+ files. Kqueue has to open every directory it watches, so too many+ directories will run it out of the max number of open files (typically+ 1024), and fail. See [[bugs/Issue_on_OSX_with_some_system_limits]]+ for a workaround.+ ## version 3.20121126 This adds several features to the git-annex assistant, which is still in beta.
+ doc/bugs/3.20121113_build_error___39__not_in_scope_getAddBoxComR__39__.mdwn view
@@ -0,0 +1,33 @@+What steps will reproduce the problem?++Building from latest source, Cabal update, cabal install --only dependencies, cabal configure, Cabal build++What is the expected output? What do you see instead?++Error message from build++...++Loading package DAV-0.2 ... linking ... done.++Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libdiskfree.o ... done++Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libmounts.o ... done++final link ... done+++Assistant/Threads/WebApp.hs:47:1: Not in scope: `getAddBoxComR'++Assistant/Threads/WebApp.hs:47:1: Not in scope: `getEnableWebDAVR'+++What version of git-annex are you using? On what operating system?++Latest version via git from git-annex.branchable.com++Debian Squeeze (6.0.6)++Please provide any additional information below.++> I noticed this earlier and fixed it. [[done]] --[[Joey]]
+ doc/bugs/Build-depends_needs___39__hxt__39___added_-_3.20121127.mdwn view
@@ -0,0 +1,36 @@+What steps will reproduce the problem?++Install git-annex via cabal - either from Hackage or as a manual install. (i.e. <http://git-annex.branchable.com/install/cabal/>)++What is the expected output? What do you see instead?++Expect a clean install.++However, get the following error:++ Assistant/Install.hs:24:8:+ Could not find module `Data.AssocList'+ It is a member of the hidden package `hxt-9.3.1.1'.+ Perhaps you need to add `hxt' to the build-depends in your .cabal file.+ Use -v to see a list of the files searched for.+++What version of git-annex are you using? On what operating system?++git-annex: 3.20121127+OS: Mac OSX 10.6.8++Please provide any additional information below.++The fix seems to be as simple as adding 'htx' to the 'git-annex.cabal' file:++ Executable git-annex+ Main-Is: git-annex.hs+ Build-Depends: MissingH, hslogger, directory, filepath,+ unix, containers, utf8-string, network (>= 2.0), mtl (>= 2.1.1),+ bytestring, old-locale, time,+ -- Added htx here+ hxt,+ pcre-light, extensible-exceptions, dataenc, SHA, process, json, HTTP,++> I removed the need for hxt, which was accidental. [[done]] --[[Joey]]
+ doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__.mdwn view
@@ -0,0 +1,31 @@+Running 3.20121112 on Debian Squeeze.++Since adding a certain directory of files (just a bunch of PDFs) yesterday I am getting errors when I try to use `git annex drop .` when the files aren't present, rather doing nothing or saying 'ok', as it used to do/should do. The errors are of the form `git-annex: fd:10: hGetLine: end of file` and sometimes of the form `git-annex: fd:17: hFlush: resource vanished (Broken pipe)`. In my `daemon.log`, I have the errors++ (scanning...) Already up-to-date.+ Already up-to-date.+ TransferScanner crashed: fd:26: hGetLine: end of file+ Already up-to-date.+ (started...) git-annex: fd:25: hGetLine: end of file+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)+ [many more repetitions]++If I `git annex get` the files and then drop them again, a further attempt at a drop gives all these errors again.++> So in summary, a git-annex built against the old version of git in+> debian stable fails to work with a newer version of git, and rebuilding+> fixes it. FWIW, the git-annex backport to stable does not have this+> problem, because it checks git version at runtime. But I want to avoid+> the overhead of that check in git-annex mainline, because this old git+> version is well, very old and increasingly unlikely to be used. So,+> I don't think any changes to git-annex are warrented. [[done]] --[[Joey]]
+ doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__.mdwn view
@@ -0,0 +1,19 @@+What steps will reproduce the problem?++Adding files to a local annex set up to sync to a remote S3 one+++What is the expected output? What do you see instead?++It syncs, but maxes out the uplink+++What version of git-annex are you using? On what operating system?++3.20121112 on Debian testing+++Please provide any additional information below.++The man page lists how to configure rate limiting for rsync, not sure how to do it for this+
+ doc/bugs/Local_pairing_fails:_PairListener_crashed.mdwn view
@@ -0,0 +1,18 @@+What steps will reproduce the problem?++Attempting to pair between a local repository and a repository on a remote computer on my LAN. Pairing is initiated from my local machine and I'm interacting with the webapp on the remote machine via firefox running over an ssh -X connection. Pairing appears to work up to a point: I enter the secret at one end, the pairing request shows up at the other end. I then enter the secret at that end.++What is the expected output? What do you see instead?++Pairing should complete successfully. Instead I get the error message "PairListener crashed: bad comment in public key", followed by the public key. The pairing process then does not move beyond the 'awaiting pairing' pages.++What version of git-annex are you using? On what operating system?++Local Machine: 3.20121127, Debian Wheezy/Sid (the only package from unstable is git-annex).+Remote Machine: 3.20121113, Arch Linux (I installed the version from: https://aur.archlinux.org/packages/git-annex-bin/, which is supposedly the same as above, but reports the version specified here).++Please provide any additional information below.++None as yet. Let me know if there are any log files, etc. that I can post.++> So it was the period in the hostname! [[fixed|done]] --[[Joey]]
+ doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="http://joey.kitenet.net/"+ nickname="joey"+ subject="comment 1"+ date="2012-01-06T03:04:35Z"+ content="""+Despite `status` listing S3 support, your git-annex is actually built with S3stub, probably because it failed to find the necessary S3 module at build time. Rebuild git-annex and watch closely, you'll see \"** building without S3 support\". Look above that for the error and fix it.++It was certianly a bug that it showed S3 as supported when built without it. I've fixed that.+"""]]
+ doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://joey.kitenet.net/"+ nickname="joey"+ subject="comment 2"+ date="2012-01-06T03:08:28Z"+ content="""+BTW, you'll want to \"make clean\", since the S3stub hack symlinks a file into place and it will continue building with S3stub even if you fix the problem until you clean.+"""]]
+ doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkey8WuXUh_x5JC2c9_it1CYRnVTgdGu1M"+ nickname="Dustin"+ subject="Thank you!"+ date="2012-01-06T03:38:27Z"+ content="""+make clean and rebuild worked... Thank you+"""]]
+ doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX.mdwn view
@@ -0,0 +1,15 @@+Running the 'assistant' branch, I occassionally get++To myhost1:/Users/jtang/annex+ ! [rejected] master -> synced/master (non-fast-forward)+error: failed to push some refs to 'myhost1:/Users/jtang/annex'+hint: Updates were rejected because a pushed branch tip is behind its remote+hint: counterpart. Check out this branch and merge the remote changes+hint: (e.g. 'git pull') before pushing again.+hint: See the 'Note about fast-forwards' in 'git push --help' for details.+(Recording state in git...)++manually running a 'git annex sync' usually fixes it, I guess once the sync command runs periodically this problem will go away, is this even OSX specific? I don't quite get the behaviour that is described in [[design/assistant/blog/day_15__its_aliiive]].++> With my changes today, I've seen it successfully recover from this+> situation. [[done]] --[[Joey]]
+ doc/bugs/Need_to_manually_install_c2hs_-_3.20121127_and_previous.mdwn view
@@ -0,0 +1,37 @@+What steps will reproduce the problem?++Install git-annex via cabal - either from Hackage or as a manual install. (i.e. <http://git-annex.branchable.com/install/cabal/>)++What is the expected output? What do you see instead?++Expect a clean install.++However, get the following error:++ Configuring gnuidn-0.2...+ cabal: The program c2hs is required but it could not be found.+ Failed to install gnuidn-0.2+ cabal: Error: some packages failed to install:+ git-annex-3.20121127 depends on gnuidn-0.2 which failed to install.+ gnuidn-0.2 failed during the configure step. The exception was:+ ExitFailure 1+ network-protocol-xmpp-0.4.4 depends on gnuidn-0.2 which failed to install.++What version of git-annex are you using? On what operating system?++git-annex: 3.20121127 (and previous versions)++OS: Mac OSX 10.6.8+++Please provide any additional information below.++The fix seems as easy as++ cabal install c2hs++Should c2hs be included as a dep got git-annex or is this a bug in gnuidn?++> Apparently cabal does not support automatically installing programs+> needed for the build. I've updated the cabal installation instructions+> to document the need to install c2hs. [[done]] --[[Joey]]
+ doc/bugs/OSX_app_issues/comment_10_bb823dc3cd6dc914ed14c176afa0b2f3._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://wiggy.net/"+ nickname="Wichert"+ subject="Re: Trying to add remote server after failed attempt blocks forever"+ date="2012-11-28T21:26:36Z"+ content="""+It appears to not just wait forever: there was also a **git config --null --list** process taking all CPU. +"""]]
+ doc/bugs/OSX_app_issues/comment_11_a30e69fed14b0809184ffe05358ab871._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.154.6.49"+ subject="comment 11"+ date="2012-11-29T19:55:17Z"+ content="""+I've dealt with these ssh issues by including ssh in the app bundle.++OTOH, I don't know how `git config --null --list` could possibly take any appreciable amount of CPU to run. +"""]]
+ doc/bugs/OSX_app_issues/comment_12_23d47b3696e537d60df1d383f33f19e4._comment view
@@ -0,0 +1,15 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"+ nickname="Arve"+ subject="Make Repository hangs (git consuming 100% cpu)"+ date="2012-12-01T01:26:04Z"+ content="""+When starting git-annex from Applications first time (Finder or spotlight), pressing \"Make Repository\" hangs.++\"ps aux | grep git\" shows+arve 1723 100.0 0.0 2459668 3988 ?? R 2:00AM 0:31.30 git init --quiet /Users/arve/Desktop/annex/++Strange enough, if i start the app from terminal (/Applications/git-annex.app/Contents/MacOS/git-annex-webapp), the creation of repository works. Though, if I kill it and start git-annex from spotlight, the web frontend doesn't show, and \"git config --null --list\" is consuming 100% cpu.++My OSX version is 10.8.1+"""]]
+ doc/bugs/OSX_app_issues/comment_13_be5738b42b13ec8cd828c5fa66f030e8._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.154.6.49"+ subject="comment 13"+ date="2012-12-01T18:50:31Z"+ content="""+So it works with a controlling console, and git commands are somehow misbehaving without a controlling console. Very strange.++Any chance you can `dtrace -p` the stuck git processes to see what they're doing or what resource they're blocked on?+"""]]
+ doc/bugs/OSX_app_issues/comment_14_e126d87a263f3aa6261f72ee7ff086fc._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"+ nickname="Arve"+ subject="comment 14"+ date="2012-12-01T22:33:21Z"+ content="""+\"dtrace -p pid\" gives \"dtrace: no probes specified.\" I've tried to read man dtrace, and some online resources, dtrace is new to me. Any directions?+"""]]
+ doc/bugs/OSX_app_issues/comment_15_e58bd3d66f0f43c159d2b37172f152de._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.154.6.49"+ subject="comment 15"+ date="2012-12-01T22:49:54Z"+ content="""+Seems the command I was thinking of is really `dtruss -p`+"""]]
+ doc/bugs/OSX_app_issues/comment_16_01f2c968bad66b0ff0c09eb468325deb._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"+ nickname="Arve"+ subject="comment 16"+ date="2012-12-01T22:53:29Z"+ content="""+Returns alot of \"workq_kernreturn(0x1, 0x107D27000, 0x0) = -1 Err#22\" and occasionally \"dtrace: 36244 drops on CPU 1\"+"""]]
+ doc/bugs/OSX_app_issues/comment_17_82d9963e1fbf17644ce697e5a43943f5._comment view
@@ -0,0 +1,16 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.154.6.49"+ subject="comment 17"+ date="2012-12-01T23:08:50Z"+ content="""+Doesn't say anything to me..++Using nohup might help, or at least get us an error message to see. Edit `git-annex.app/Contents/MacOS/git-annex-webapp` and make the last line:++<pre>+nohup \"$base/runshell\" git-annex webapp \"$@\"+</pre>++It'll put a nohup.out log file in your home directory, or somewhere like that.+"""]]
+ doc/bugs/OSX_app_issues/comment_18_29af9df9ea295d114574e76e15b8e737._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"+ nickname="Arve"+ subject="comment 18"+ date="2012-12-02T00:02:51Z"+ content="""+Adding nohup doesn't produce any output (that I can find; sudo find / -name nohup.out) :/+"""]]
+ doc/bugs/OSX_app_issues/comment_19_6d6341b05123cd317c4eac96353c8662._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.154.2.244"+ subject="comment 19"+ date="2012-12-07T16:13:42Z"+ content="""+This hang seems not to occur on OSX 10.7, which is the version the autobuilder is running. So this is some sort of incompatability.++So, building git-annex from source should avoid the problem. I'd like to get a version of the app built for 10.8, have not yet been able to arrange that.+"""]]
+ doc/bugs/OSX_app_issues/comment_2_fd560811c57df5cbc3976639642b8b19._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkN91jAhoesnVI9TtWANaBPaYjd1V9Pag8"+ nickname="Benjamin"+ subject="Package for older OS X"+ date="2012-11-17T12:36:45Z"+ content="""+Is there an option to provide application bundle for older versions of OS X? The last time I tried the bundle wouldn't work under 10.5. If no specific features from newer OS X versions are required, it could be enough to add a simple switch when building.+"""]]
+ doc/bugs/OSX_app_issues/comment_3_08613b2e2318680508483d204a43da76._comment view
@@ -0,0 +1,76 @@+[[!comment format=mdwn+ username="http://edheil.wordpress.com/"+ nickname="edheil"+ subject="No luck running it on OS X Lion."+ date="2012-11-21T06:07:55Z"+ content="""+here's the crash info:++<pre>+Process: git-annex [84369]+Path: /Applications/git-annex.app/Contents/MacOS/bin/git-annex+Identifier: git-annex+Version: ??? (???)+Code Type: X86-64 (Native)+Parent Process: sh [84364]++Date/Time: 2012-11-21 00:27:03.068 -0500+OS Version: Mac OS X 10.7.5 (11G63)+Report Version: 9++Crashed Thread: 0++Exception Type: EXC_BREAKPOINT (SIGTRAP)+Exception Codes: 0x0000000000000002, 0x0000000000000000++Application Specific Information:+dyld: launch, loading dependent libraries++Dyld Error Message:+ Library not loaded: /opt/local/lib/libgss.3.dylib+ Referenced from: /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgsasl.7.dylib+ Reason: image not found++Binary Images:+ 0x105baa000 - 0x107b89fe7 +git-annex (??? - ???) <45311C82-015C-3F87-9F9B-01325EFBD0D9> /Applications/git-annex.app/Contents/MacOS/bin/git-annex+ 0x10822d000 - 0x10823eff7 +libz.1.dylib (1.2.7 - compatibility 1.0.0) <57016CC1-AD54-337E-A983-457933B24D35> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libz.1.dylib+ 0x108245000 - 0x10827dff7 +libpcre.1.dylib (2.1.0 - compatibility 2.0.0) <431BD758-FA7B-38B3-AB7E-6511EC06152E> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libpcre.1.dylib+ 0x108283000 - 0x1083b3ff7 +libxml2.2.dylib (11.0.0 - compatibility 11.0.0) <0663F820-D436-3304-B12F-9158901087EB> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libxml2.2.dylib+ 0x1083e9000 - 0x108400fef +libgsasl.7.dylib (16.6.0 - compatibility 16.0.0) <41503EE1-D58B-385C-AC2E-BEAA7D0D4E38> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgsasl.7.dylib+ 0x10840a000 - 0x1084a1fff +libgnutls.26.dylib (49.3.0 - compatibility 49.0.0) <0320352A-3336-3B6B-A7DE-F3069669AD27> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgnutls.26.dylib+ 0x1084c3000 - 0x1084f1ff7 +libidn.11.dylib (18.8.0 - compatibility 18.0.0) <97073970-9370-3F85-B943-1B989EA41148> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libidn.11.dylib+ 0x1084fc000 - 0x1085f5ff7 +libiconv.2.dylib (8.1.0 - compatibility 8.0.0) <1B8D243B-F617-301E-97B1-EE78A72617AB> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libiconv.2.dylib+ 0x108606000 - 0x108606fff +libcharset.1.dylib (2.0.0 - compatibility 2.0.0) <E3797413-2AA3-3698-B393-E1203B4799A0> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libcharset.1.dylib+ 0x10860c000 - 0x108665fef +libgmp.10.dylib (11.5.0 - compatibility 11.0.0) <EE407B22-0F44-38B6-9937-10CA6A529F37> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgmp.10.dylib+ 0x108675000 - 0x1086a2fe7 +libSystem.B.dylib (159.1.0 - compatibility 1.0.0) <7BEBB139-50BB-3112-947A-F4AA168F991C> /Applications/git-annex.app/Contents/MacOS/usr/lib/libSystem.B.dylib+ 0x1086b4000 - 0x1086c8fef +libgcc_s.1.dylib (??? - ???) <3C5BF0B8-B1E9-3B41-B52F-F7499687217C> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/gcc47/libgcc_s.1.dylib+ 0x1086d8000 - 0x1086f5ff7 +liblzma.5.dylib (6.4.0 - compatibility 6.0.0) <1D682E06-EB89-34CA-855A-AEF611C4DF86> /usr/local/lib/liblzma.5.dylib+ 0x7fff657aa000 - 0x7fff657debaf dyld (195.6 - ???) <0CD1B35B-A28F-32DA-B72E-452EAD609613> /usr/lib/dyld+ 0x7fff8b669000 - 0x7fff8b672ff7 libsystem_notify.dylib (80.1.0 - compatibility 1.0.0) <A4D651E3-D1C6-3934-AD49-7A104FD14596> /usr/lib/system/libsystem_notify.dylib+ 0x7fff8b6e4000 - 0x7fff8b6e5ff7 libsystem_sandbox.dylib (??? - ???) <2A09E4DA-F47C-35CB-B70C-E0492BA9F20E> /usr/lib/system/libsystem_sandbox.dylib+ 0x7fff8c000000 - 0x7fff8c006ff7 libunwind.dylib (30.0.0 - compatibility 1.0.0) <1E9C6C8C-CBE8-3F4B-A5B5-E03E3AB53231> /usr/lib/system/libunwind.dylib+ 0x7fff8c1c4000 - 0x7fff8c1c5ff7 libremovefile.dylib (21.1.0 - compatibility 1.0.0) <739E6C83-AA52-3C6C-A680-B37FE2888A04> /usr/lib/system/libremovefile.dylib+ 0x7fff8cf13000 - 0x7fff8cf4efff libsystem_info.dylib (??? - ???) <35F90252-2AE1-32C5-8D34-782C614D9639> /usr/lib/system/libsystem_info.dylib+ 0x7fff8dbc3000 - 0x7fff8dbc8fff libcache.dylib (47.0.0 - compatibility 1.0.0) <1571C3AB-BCB2-38CD-B3B2-C5FC3F927C6A> /usr/lib/system/libcache.dylib+ 0x7fff8dbc9000 - 0x7fff8dbd0fff libcopyfile.dylib (85.1.0 - compatibility 1.0.0) <0AB51EE2-E914-358C-AC19-47BC024BDAE7> /usr/lib/system/libcopyfile.dylib+ 0x7fff8dbdf000 - 0x7fff8dbedfff libdispatch.dylib (187.10.0 - compatibility 1.0.0) <8E03C652-922A-3399-93DE-9EA0CBFA0039> /usr/lib/system/libdispatch.dylib+ 0x7fff8dcf2000 - 0x7fff8dcf7ff7 libsystem_network.dylib (??? - ???) <5DE7024E-1D2D-34A2-80F4-08326331A75B> /usr/lib/system/libsystem_network.dylib+ 0x7fff8e1bb000 - 0x7fff8e298fef libsystem_c.dylib (763.13.0 - compatibility 1.0.0) <41B43515-2806-3FBC-ACF1-A16F35B7E290> /usr/lib/system/libsystem_c.dylib+ 0x7fff8e6e2000 - 0x7fff8e6eafff libsystem_dnssd.dylib (??? - ???) <584B321E-5159-37CD-B2E7-82E069C70AFB> /usr/lib/system/libsystem_dnssd.dylib+ 0x7fff8fab6000 - 0x7fff8fab8fff libquarantine.dylib (36.7.0 - compatibility 1.0.0) <8D9832F9-E4A9-38C3-B880-E5210B2353C7> /usr/lib/system/libquarantine.dylib+ 0x7fff8fc3e000 - 0x7fff8fc80ff7 libcommonCrypto.dylib (55010.0.0 - compatibility 1.0.0) <BB770C22-8C57-365A-8716-4A3C36AE7BFB> /usr/lib/system/libcommonCrypto.dylib+ 0x7fff90fa3000 - 0x7fff90fa9fff libmacho.dylib (800.0.0 - compatibility 1.0.0) <165514D7-1BFA-38EF-A151-676DCD21FB64> /usr/lib/system/libmacho.dylib+ 0x7fff90faa000 - 0x7fff90fabfff libunc.dylib (24.0.0 - compatibility 1.0.0) <337960EE-0A85-3DD0-A760-7134CF4C0AFF> /usr/lib/system/libunc.dylib+ 0x7fff910b4000 - 0x7fff910b8fff libmathCommon.A.dylib (2026.0.0 - compatibility 1.0.0) <FF83AFF7-42B2-306E-90AF-D539C51A4542> /usr/lib/system/libmathCommon.A.dylib+ 0x7fff916b9000 - 0x7fff916bdfff libdyld.dylib (195.6.0 - compatibility 1.0.0) <FFC59565-64BD-3B37-90A4-E2C3A422CFC1> /usr/lib/system/libdyld.dylib+ 0x7fff916be000 - 0x7fff916defff libsystem_kernel.dylib (1699.32.7 - compatibility 1.0.0) <66C9F9BD-C7B3-30D4-B1A0-03C8A6392351> /usr/lib/system/libsystem_kernel.dylib+ 0x7fff916df000 - 0x7fff916e0fff libdnsinfo.dylib (395.11.0 - compatibility 1.0.0) <853BAAA5-270F-3FDC-B025-D448DB72E1C3> /usr/lib/system/libdnsinfo.dylib+ 0x7fff929f8000 - 0x7fff929fdfff libcompiler_rt.dylib (6.0.0 - compatibility 1.0.0) <98ECD5F6-E85C-32A5-98CD-8911230CB66A> /usr/lib/system/libcompiler_rt.dylib+ 0x7fff93a3c000 - 0x7fff93a3cfff libkeymgr.dylib (23.0.0 - compatibility 1.0.0) <61EFED6A-A407-301E-B454-CD18314F0075> /usr/lib/system/libkeymgr.dylib+ 0x7fff97139000 - 0x7fff9713aff7 libsystem_blocks.dylib (53.0.0 - compatibility 1.0.0) <8BCA214A-8992-34B2-A8B9-B74DEACA1869> /usr/lib/system/libsystem_blocks.dylib+ 0x7fff9724f000 - 0x7fff9726cfff libxpc.dylib (77.19.0 - compatibility 1.0.0) <9F57891B-D7EF-3050-BEDD-21E7C6668248> /usr/lib/system/libxpc.dylib+ 0x7fff97cfe000 - 0x7fff97d08ff7 liblaunch.dylib (392.39.0 - compatibility 1.0.0) <8C235D13-2928-30E5-9E12-2CC3D6324AE2> /usr/lib/system/liblaunch.dylib+</pre>+ ++"""]]
+ doc/bugs/OSX_app_issues/comment_6_12bd83e7e2327c992448e87bdb85d17e._comment view
@@ -0,0 +1,15 @@+[[!comment format=mdwn+ username="https://me.yahoo.com/a/6xTna_B_h.ECb6_ftC2dYLytAEwrv36etg_054U-#4c1e7"+ nickname="Fake"+ subject="libncurses on 10.7"+ date="2012-10-17T21:24:24Z"+ content="""+I'm getting an error from gpg when I try to set up a repository on a remote server with encrypted rsync. Looks like libncurses in /usr/lib is 32 bit:++ Dyld Error Message:+ Library not loaded: /opt/local/lib/libncurses.5.dylib+ Referenced from: /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libreadline.6.2.dylib+ Reason: no suitable image found. Did find:+ /usr/lib/libncurses.5.dylib: mach-o, but wrong architecture+ /usr/lib/libncurses.5.dylib: mach-o, but wrong architecture+"""]]
+ doc/bugs/OSX_app_issues/comment_6_cea97dbbfb566a9fe463365ca4511119._comment view
@@ -0,0 +1,16 @@+[[!comment format=mdwn+ username="http://nico.kaiser.me/"+ nickname="Nico Kaiser"+ subject="git-annex crashing on OS X 10.8.2"+ date="2012-11-27T08:01:29Z"+ content="""+ $ /Applications/git-annex.app/Contents/MacOS/git-annex-webapp+ dyld: Symbol not found: _OBJC_CLASS_$_NSObject+ Referenced from: /usr/bin/open+ Expected in: /Applications/git-annex.app/Contents/MacOS/usr/lib/libobjc.A.dylib+ in /usr/bin/open+ WebApp crashed: failed to start web browser+ + Launching web browser on file:///var/folders/8g/_fvs7jf572l4fj03q5mhrq9r0000gn/T/webapp1196.html++"""]]
+ doc/bugs/OSX_app_issues/comment_7_911f187d46890093a54859032ada2442._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.154.6.49"+ subject="comment 7"+ date="2012-11-27T21:13:18Z"+ content="""+@Nico, that's actually kind of promising; people have been reporting much earlier crashes with OSX. This later crash is one I think I can do something about! :)++So, it looks like the standalone app build needs to run the web browser in a clean environment that doesn't use any of its bundled libraries. I've committed that change and it will be in a release later today.+"""]]
+ doc/bugs/OSX_app_issues/comment_7_93e0bb53ac2d7daef53426fbdc5f92d9._comment view
@@ -0,0 +1,15 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"+ nickname="Bret"+ subject="git-annex.app Not working on 32 bit machines"+ date="2012-11-03T19:18:47Z"+ content="""+I tried running the git-annex.app on my Core Duo Macbook pro, and it does not run at all. I get an error on my system.log++`Nov 3 12:13:26 Bret-Mac [0x0-0x15015].com.branchable.git-annex[155]: /Applications/git-annex.app/Contents/MacOS/runshell: line 52: /Applications/git-annex.app/Contents/MacOS/bin/git-annex: Bad CPU type in executable+Nov 3 12:13:26 Bret-Mac com.apple.launchd.peruser.501[92] ([0x0-0x15015].com.branchable.git-annex[155]): Exited with exit code: 1`++It works on my 64 bit machine, and this has become quite the problem for a while now, where people with newer macs dont compile back for a 32bit machine. ++Is there any hope for a pre-compiled binary that works on a 32 bit machine?+"""]]
+ doc/bugs/OSX_app_issues/comment_8_08b091a58106ca6050ac669579ed9ff4._comment view
@@ -0,0 +1,11 @@+[[!comment format=mdwn+ username="http://wiggy.net/"+ nickname="Wichert"+ subject="Adding a remote server repository fails"+ date="2012-11-28T21:17:23Z"+ content="""+The error message I get is:++> Failed to ssh to the server. Transcript: dyld: Symbol not found: ___progname Referenced from: /usr/bin/ssh Expected in: /Users/wichert/Applications/git-annex.app/Contents/MacOS/usr/lib/libSystem.B.dylib in /usr/bin/ssh++"""]]
+ doc/bugs/OSX_app_issues/comment_8_141eac2f3fb25fe18b4268786f00ad6a._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"+ nickname="Jimmy"+ subject="comment 8"+ date="2012-11-07T16:08:00Z"+ content="""+I've been updating my haskell platform install recently, i used to try and get the builder to spit out 32/64bit binaries, but recently it's just become too messy, I've just migrated to a full 64bit build system. I'm afraid I won't be able to provide 32bit builds any more.+"""]]
+ doc/bugs/OSX_app_issues/comment_9_8464c839cb169a4c6e72bebdc2065e9a._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://wiggy.net/"+ nickname="Wichert"+ subject="Trying to add remote server after failed attempt blocks forever"+ date="2012-11-28T21:23:54Z"+ content="""+Out of curiosity I checked what would happen if I tried to add a remote server repo again after it just failed with the missing library error (see previous comment). Surprisingly the webapp is now waiting forever at the *Testing server ...* message.+"""]]
+ doc/bugs/Proxy_support.mdwn view
@@ -0,0 +1,18 @@+What steps will reproduce the problem?++Adding a e.g box.com repository from behind a http proxy via webapp.++What is the expected output? What do you see instead?++Connection should be made. But there is an error message:++"Internal Server Error+connect: does not exist (Connection refused): user error"++What version of git-annex are you using? On what operating system?++3.20121127 on Archlinux++Please provide any additional information below.++I don't use networkmanager if proxy information is obtained from it. There should be a fallback to environment variables.
doc/bugs/dropping_and_re-adding_from_web_remotes_doesn__39__t_work.mdwn view
@@ -129,3 +129,11 @@ #Please provide any additional information below. This seems to be a corner case, and would probably have minimal impact on most people.++> Yeah, dropping from the web is pretty weird.+> +> I guess it makes sense to do if a website stops having a file and you don't+> want git-annex to try to download from it anymore. So, I've made dropping+> from the web remove all urls associated with the file, rather than failing.+> +> [[done]] --[[Joey]]
+ doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn view
@@ -0,0 +1,34 @@+After a series of pretty convoluted copying files around between annex'd repos and pulling changes around between repos. I noticed that occassionally when git-annex tries to stage files (the `.git-annex/*/*/*logs`) git some times gets wedged and doing a "git commit -a" doesn't seem to work or files might not get added thus leaving a bunch of untracked files or modified files that aren't staged for a commit.++I tried running a *`git rm --cached -f -r *`* then *git add -u .git-annex/* or the usual *git add* then a commit fixes things for me. If I don't do that then my subsequent merges/pulls will fail and result in *no known copies of files* I suspect git-annex might have just touched some file modes and git picked up the changes but got confused since there was no content change. It might also just be a git on OSX thing and it doesn't affect linux/bsd users.++For now it's just a bit of extra work for me when it does occur but it does not seem to occur often.++> What do you mean when you say that git "got wedged"? It hung somehow?+>+> If git-annex runs concurrently with another git command that locks+> the repository, its git add of log files can fail.+> +> Update: Also, of course, if you are running a "got annex get" or+> similar, and ctrl-c it after it has gotten some files, it can+> end up with unstaged or in some cases un-added log files that git-annex+> wrote -- since git-annex only stages log files in git on shutdown, and+> ctrl-c bypasses that.+> --[[Joey]] ++>> It "got wedged" as in git doesn't let me commit anything, even though it tells me that there is stuff to be committed in the staging area.++>>> I've never seen git refuse to commit staged files. There would have to+>>> be some error message? --[[Joey]] ++>>>> there were no error messages at all++>>>>> Can I see a transcript? I'm having difficulty getting my head around+>>>>> what git is doing. Sounds like the files could just not be `git+>>>>> added` yet, but I get the impression from other things that you say+>>>>> that it's not so simple. --[[Joey]] ++This turns out to be a bug in git, and I have posted a bug report on the mailing list.+The git-annex behavior that causes this situation is being handled as+another bug, [[git-annex directory hashing problems on osx]].+So, closing this bug report. [[done]] --[[Joey]]
+ doc/bugs/git-annex_webapp_command_not_found.mdwn view
@@ -0,0 +1,25 @@+###What steps will reproduce the problem?++ greg@x220:~/Music$ git-annex version+ git-annex version: 3.20121017++ greg@x220:~/Documents$ git-annex watch+ greg@x220:~/Documents$ git-annex: Daemon is already running.++ greg@x220:~/Documents$ git-annex assistant+ greg@x220:~/Documents$ git-annex: Daemon is already running.++ greg@x220:~/Documents$ git-annex webapp+ git-annex: unknown command webapp++This is on an Ubuntu (12.10) machine, using git-annex from ubuntu+1 (13.04), which is just an autosync from sid:++https://launchpad.net/ubuntu/+source/git-annex/3.20121017++###What is the expected output? What do you see instead?+I expect my browser to open the webapp.+++(Also, it is odd how the output of "Daemon is already running" appears after my prompt is given back to me)++> [[closing|done]]; forwarded upstream --[[Joey]]
+ doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn view
@@ -0,0 +1,34 @@+For test.com//test, I get this:++ % git annex copy . --to test.com//test+ (getting UUID for test...) git-annex: there is no git remote named "test.com//test"++And my .git/config changes from++ [remote "test.com//test"]+ url = richih@test.com:/test+ fetch = +refs/heads/*:refs/remotes/test.com//test/*++to++ [remote "test.com//test"]+ url = richih@test.com:/test+ fetch = +refs/heads/*:refs/remotes/test.com//test/*+ annex-uuid = xyz+ [remote "test"]+ annex-uuid = xyz+++Unless I am misunderstanding something, git annex gets confused about what the name of the remote it supposed to be, truncates at the dot for some operations and uses the full name for others.++> I've fixed this bug. [[done]]+> +> However, using "/" in a remote name seems likely to me to confuse +> git's own remote branch handling. Although I've never tried it.+> --[[Joey]] ++>> From what I can see, git handles / just fine, but would get upset about : which is why it's not allowed in a remote's name.+>> My naming scheme is host//path/to/annex. It sorts nicely and gives all important information left to right with the most specific parts at the beginning and end.+>> If you have any other ideas or scheme, I am all ears :)+>> Either way, thanks for fixing this so quickly.+>> -- RichiH
+ doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__.mdwn view
@@ -0,0 +1,34 @@+What steps will reproduce the problem?++run git annex assistant, add a file, which is picked up and pushed by the assistant. ++What is the expected output? What do you see instead?++a ps -ef shows a large number of defunct git processes.. for example:+<pre>+nelg 9622 1 0 02:01 ? 00:00:01 git-annex assistant+nelg 9637 9622 0 02:01 ? 00:00:00 git --git-dir=/home/nelg/Downloads/test2/.git --work-tree=/home/nelg/Downloads/test2 cat-file --batch+nelg 12080 9622 0 02:19 ? 00:00:00 [git] <defunct>+nelg 12082 9622 0 02:19 ? 00:00:00 [git] <defunct>+nelg 12083 9622 0 02:19 ? 00:00:00 [git] <defunct>+nelg 12084 9622 0 02:19 ? 00:00:00 [git] <defunct>+-----+</pre>++What version of git-annex are you using? On what operating system?++Compiled git annex from git (cbcd208d158f8e42dda03a5eeaf1bac21045a140), on Mandriva 2010.2, 32 bit, using ghc-7.4.1.+ git version 1.7.1+++Please provide any additional information below.++I also found that the version of git I have does not support the option: --allow-empty-message+So, suggest that if the version of git installed is an older version, that the params in Assistant/Threads/Committer.hs+are changed to [ Param "-m", Param "git assistant".... or something like that.++I have done this on my copy for testing it.++For testing, I am also using two repositories on the same computer. I set this up from the command line, as the web app does not seem to support syncing to two different git folders on the same computer.++> [[done]]; all zombies are squelched now in the assistant. --[[Joey]]
doc/bugs/glacier_with_assistant_bugs.mdwn view
@@ -1,5 +1,3 @@-* Need to handle retrying downloads of files from glacier after 4 hours.- * When a file is moved into archive/, the assistant that sends it to glacier is able to trust that it's in glacier and remove the local copy. But other assistants that also have a copy cannot trust that, and so
+ doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform.mdwn view
@@ -0,0 +1,20 @@+I updated haskell platform, and now++<pre>+[jtang@x00 git-annex (master)]$ make test++Assistant/Threads/NetWatcher.hs:26:2:+ warning: #warning Building without dbus support; will poll for network connection changes [-Wcpp]++Assistant/Threads/MountWatcher.hs:33:2:+ warning: #warning Building without dbus support; will use mtab polling [-Wcpp]++test.hs:11:8:+ Could not find module `Test.HUnit.Tools'+ Perhaps you meant Test.HUnit.Text (from HUnit-1.2.5.1)+ Use -v to see a list of the files searched for.+** failed to build the test suite+make: *** [test] Error 1+</pre>++Looks like a missing dep somewhere with testpack or quickcheck... I haven't had time to figure it out yet, its not git-annex specific but I thought I might log it as a reminder for myself just in case if the osxapp is more borked than usual, I probably need to flush my .cabal directory of installed userland dependancies.
+ doc/bugs/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn view
@@ -0,0 +1,39 @@+as of git-annex version 3.20110719, all git-annex commits only contain the word "update" as a commit message. given that the contents of the commit are pretty non-descriptive (SHA1 hashes for file names, uuids for repository names), i suggest to have more descriptive commit messages, as shown here:++ /mnt/usb_disk/photos/2011$ git annex get+ /mnt/usb_disk/photos/2011$ git show git-annex+ [...]+ usb-disk-photos: get 2011+ + * 10 files retrieved from 2 sources (9 from local-harddisk, 1 from my-server)+ * 120 files were already present+ * 2 files could not be retrieved+ /mnt/usb_disk/photos/2011$ cd ~/photos/2011/07+ ~/photos/2011/07$ git copy --to my-server+ ~/photos/2011/07$ git show git-annex+ [...]+ local-harddisk: copy 2011/07 to my-server+ + * 20 files pushed+ ~/photos/2011/07$++in my opinion, the messages should at least contain++* what command was used+* in which repository they were executed+* which files or directories they affected (not necessarily all files, but what was given on command line or implicitly from the working directory)++--[[chrysn]]++> The implementation of the git-annex branch precludes more descriptive+> commit messages, since a single commit can include changes that were+> previously staged to the branch's index file, or spooled to its journal+> by other git-annex commands (either concurrently running or+> interrupted commands, or even changes needed to automatically merge+> other git-annex branches).+> +> It would be possible to make it *less* verbose, with an empty commit+> message. :) --[[Joey]] ++>> Closing as this is literally impossible to do without making+>> git-annex worse. [[done]] --[[Joey]]
+ doc/bugs/yesod-form_missing.mdwn view
@@ -0,0 +1,23 @@+What steps will reproduce the problem?++build using cabal from a git checkout++What is the expected output? What do you see instead?++successful build; error message is:++Assistant/WebApp/Form.hs:15:8:+ Could not find module `Yesod.Form.Fields'+ It is a member of the hidden package `yesod-form-1.2.0'.+ Perhaps you need to add `yesod-form' to the build-depends in your .cabal file.+++What version of git-annex are you using? On what operating system?++git checkout commit 90b62db1defdd223294935ec0bbaac883cd20c04 on OS X Lion++Please provide any additional information below.++adding yesod-form to the build depends in git-annex.cabal does indeed fix the problem!++> [[done]] --[[Joey]]
doc/design/assistant.mdwn view
@@ -13,8 +13,11 @@ We are, approximately, here: -* Months 6-7 "9k bonus round": [[!traillink Android]] [[!traillink partial_content]] [[!traillink leftovers]]-* Months 8-11: more user-driven features and polishing (see remaining TODO items in all pages above)+* Month 6 "9k bonus round": [[!traillink desymlink]]+* Month 7: user-driven features and polishing; + [presentation at LCA2013](https://lca2013.linux.org.au/schedule/30059/view_talk)+* Month 8: [[!traillink Android]]+* Months 9-11: more user-driven features and polishing (see remaining TODO items in all pages above) * Month 12: "Windows purgatory" [[Windows]] ## porting@@ -23,7 +26,7 @@ ## not yet on the map: -* [[desymlink]]+* [[partial_content]] * [[deltas]] * [[leftovers]] * [[other todo items|todo]]
+ doc/design/assistant/OSX/comment_1_9290f6e6f265e906b08631224392b7bf._comment view
@@ -0,0 +1,14 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawlu-fdXIt_RF9ggvg4zP0yBbtjWQwHAMS4"+ nickname="Jörn"+ subject="Mount detection"+ date="2012-09-21T09:23:34Z"+ content="""+regarding the current mount polling on OSX: why not use the NSNotificationCenter for being notified on mount events on OSX?++Details see:++1. <http://stackoverflow.com/questions/12409458/detect-when-a-volume-is-mounted-on-os-x>+2. <http://stackoverflow.com/questions/6062299/how-to-add-an-observer-to-nsnotificationcenter-in-a-c-class-using-objective-c>+3. <https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html#//apple_ref/doc/uid/20001438>+"""]]
doc/design/assistant/android.mdwn view
@@ -40,5 +40,5 @@ ## FAT -Due to use of the fat filesystem, which doesn't do symlinks, [[nosymlink]]-is probably needed.+Due to use of the FAT filesystem, which doesn't do symlinks, [[desymlink]]+is probably needed for at least older Android devices that have SD cards.
+ doc/design/assistant/blog/day_142__filling_in.mdwn view
@@ -0,0 +1,9 @@+Just filling in a few remaining bits and pieces from this month's work.++* Made the assistant periodically check glacier-cli for archives that are+ ready, and queue downloads of them.+* The box.com configurator defaults to embedding the account info, allowing+ one-click enabling of the repository. There's a check box to control this.+* Fix some bugs with how the standalone images run git-annex.+* Included ssh in the standalone images.+* Various other bug fies.
+ doc/design/assistant/blog/day_143__what_next.mdwn view
@@ -0,0 +1,22 @@+Yesterday, I woke up and realized I didn't know what I needed to work on in+git-annex. Added a poll, [[polls/Android]] to help me decide what major+thing to work on next.++----++More flailing at the OSX monster. (A species of gelatinous cube?)+Current fun seems to involve git processes spinning if git-annex+was started without a controlling TTY. I'm befuddled by this.++----++Made the S3 and Glacier configurators have a list of regions, rather than+requiring a the region's code be entered correctly. I could not find a list of+regions, or better, an API to get a list, so I'll have to keep updating as+Amazon adds services in new regions.++----++Spent some time trying to get WebDAV to work with livedrive.com.+It doesn't like empty PROPPATCH. I've developed a change to the haskell DAV+library that will let me avoid this problem.
+ doc/design/assistant/blog/day_144__webapp_work.mdwn view
@@ -0,0 +1,8 @@+Made the webapp show runtime errors on a prettified page that includes version+info, a bug reporting link, etc.++Dealt with a bad interaction between required fields and the bootstrap modals+displayed when submitting some configuration forms. This was long, complex,+and had lots of blind alleys. In the end, I had to derive new password and+text fields in yesod that don't set the required attribute in the generated+html.
+ doc/design/assistant/blog/day_145__more_webapp_work.mdwn view
@@ -0,0 +1,12 @@+One problem with the current configurators for remotes is they have a lot+of notes and text to read at the top. I've worked on cut that down somewhat,+mostly by adding links and help buttons next to fields in the form.++I also made each form have a check box controlling whether encryption is+enabled. Mostly as a way to declutter the text at the top, which always had+to say encryption is enabled.++---++I have a fairly well worked out design for [[desymlink]]. Will wait a few+days to work on it to let it jell.
+ doc/design/assistant/blog/day_146__meanwhile.mdwn view
@@ -0,0 +1,22 @@+Biding my time while [[desymlink]] gells in my head..++Fixed a bug in the assistant's local pairing that rejected ssh keys with a+period in the comment.++Fixed a bug in the assistant that made it try to drop content from remotes+that didn't have it, and avoided a drop failure crashing a whole assistant+thread.++Made --auto behave better when preferred content is set.++Looked into making the transfer queue allow running multiple transfers at+the same time, ie, one per remote. This seems to essentially mean splitting+the queue into per remote queues. There are some complexities, and I+decided not to dive into working through it right now, since it'd be+a distraction from thinking about [[desymlink]]. Will revisit it later.++Allow specifying a port when setting up a ssh remote.++While doing that, noticed that the assistant fails to transfer files to+sync to a ssh remote that was just added. That got broken while optimising+reconnecting with a remote; fixed it.
+ doc/design/assistant/blog/day_147__direct_mode.mdwn view
@@ -0,0 +1,36 @@+Started laying the groundwork for [[desymlink]]'s direct mode.+I got rather far!++A git repo can be configured with `annex.direct` and all actions that+transfer objects to it will replace the symlinks with regular files.+Removing objects also works (and puts back a broken symlink),+as does checking if an object is present, which even detects if a file+has been modified.++So far, this works best when such a direct mode repository is used as a git+remote of another repository. It is also possible to run a few git-annex+commands, like "get" in a direct mode repository, though others, like+"drop" won't work because they rely on the symlink to map back to the key.++Direct mode relies on map files existing for each key in the repository, that tell+what file(s) use it. It also relies on cache files, that contain the last+known mtime, size, and inode of the file. So far, I've been setting these+files up by hand.++The main thing that's missing is support for transferring objects from+direct mode repositories. There's no single place I can modify to support+that (like I could for the stuff mentioned above), and also it's difficult+to do safely, since files could be modified at any time. ++So it'll need to quarantine files, to prevent a modified version from+getting sent out. I could either do this by copying the file, or by+temporarily `git annex lock`ing it. Unsure which choice would be less+annoying..++----++Also did some investigation with Jimmy of the OSX app git-config hang.+Seems to be some kind of imcompatability between the 10.7 autobuilder and+10.8. Next step is probably to try to build on 10.8. Might also+be worth trying <http://macdylibbundler.sourceforge.net/>, although my+own scripts do more or less the same thing to build the app.
+ doc/design/assistant/blog/day_148__direct_mode.mdwn view
@@ -0,0 +1,42 @@+Got object sending working in direct mode. However, I don't yet have a+reliable way to deal with files being modified while they're being+transferred. I have code that detects it on the sending side, but the+receiver is still free to move the wrong content into its annex, and record+that it has the content. So that's not acceptable, and I'll need to work+on it some more. However, at this point I can use a direct mode repository+as a remote and transfer files from and to it.++----++Automated updating of the cached mtime, etc data. Next I need to automate+generation of the key to filename mapping files. I'm thinking that I'll make+`git annex sync` do it. Then, once I get committing and +merging working in direct mode repositories (which is likely to be a+good week's worth of work), the workflow for using these repositories+will be something like this:++ git config annex.direct true+ git annex sync # pulls any changes, merges, updates maps and caches+ git annex get+ # modify files+ git annex sync # commits and pushes changes++And once I get direct mode repositories working to this degree at the+command line, I can get on with adding support to the assistant.++----++Also did some more work today on the OSX app. Am in the middle of getting+it to modify the binaries in the app to change the paths to the libraries they+depend on. This will avoid the hacky environment variable it is currently+using, and make runshell a much more usable environment. It's the right way+to do it. (I can't believe I just said RPATH was the right way to do+anything.)++In the middle of this, I discovered+<http://hackage.haskell.org/package/cabal-macosx>, which does the same+type of thing.++Anyway, I have to do some crazy hacks to work around short library name+fields in executables that I don't want to have to be specially rebuilt in+order to build the webapp. Like git.
+ doc/design/assistant/blog/day_149__rainy_day.mdwn view
@@ -0,0 +1,15 @@+Made `git annex sync` update the file mappings in direct mode.+To do this efficiently, it uses `git diff-tree` to find files that are+changed by the sync, and only updates those mappings. I'm rather happy+with this, as a first step to fully supporting sync in direct mode.++Finished the overhaul of the OSX app's library handling. It seems to work+well, and will fix a whole class of ways the OSX app could break.++Fixed a bug in the preferred content settings for backup repositories,+introduced by some changes I made to preferred content handling 4 days ago.++Fixed the Debian package to build with WebDAV support, which I forgot to+turn on before.++Planning a release tomorrow.
+ doc/design/assistant/blog/day_81__enabling_pre-existing_special_remotes.mdwn view
@@ -0,0 +1,34 @@+It's possible for one git annex repository to configure a special remote+that it makes sense for other repositories to also be able to use. Today I+added the UI to support that; in the list of repositories, such+repositories have a "enable" link.++To enable pre-existing rsync special remotes, the webapp has to do the same+probing and ssh key setup that it does when initially creating them.+Rsync.net is also handled as a special case in that code. There was one+ugly part to this.. When a rsync remote is configured in the webapp,+it uses a mangled hostname like "git-annex-example.com-user", to+make ssh use the key it sets up. That gets stored in the `remote.log`, and so+the enabling code has to unmangle it to get back to the real hostname.++---++Based on the still-running [[prioritizing_special_remotes]] poll, a lot+of people want special remote support for their phone or mp3 player.+(As opposed to running git-annex on an Android phone, which comes later..)+It'd be easy enough to make the webapp set up a directory special remote+on such a device, but that makes consuming some types of content on the+phone difficult (mp3 players seem to handle them ok based on what people tell+me). I need to think more about some of the ideas mentioned in [[android]]+for more suitable ways of storing files.++One thing's for sure: You won't want the assistant to sync all your files+to your phone! So I also need to start coming up with partial syncing+controls. One idea is for each remote to have a configurable matcher for files+it likes to receive. That could be only mp3 files, or all files inside a+given subdirectory, or all files *not* in a given subdirectory. That means+that when the assistant detects a file has been moved, it'll need to add+(or remove) a queued transfer. Lots of other things could be matched on,+like file size, number of copies, etc. Oh look, I have a+[beautiful library I wrote earlier](http://joeyh.name/blog/entry/happy_haskell_hacker)+that I can reuse!
doc/design/assistant/cloud.mdwn view
@@ -2,7 +2,7 @@ not in these pre-IPV6 days, so the cloud needs to be used to bridge between LANS. -## The cloud notification problem **done**+## The cloud notification problem (**done**) Alice and Bob have repos, and there is a cloud remote they both share. Alice adds a file; the assistant transfers it to the cloud remote.
doc/design/assistant/configurators.mdwn view
@@ -8,11 +8,11 @@ through setting up common use cases. * Create a repository (run when the web app is started without a configured- repository too).+ repository too). **done** * Clone this repo to a USB drive or other removable drive. **done** * Make a bare repo on a remote ssh server **done** * Clone this repo to another host. (Needs [[pairing]]) **done**-* Set up Amazon S3.+* Set up Amazon S3. **done** * Set up encrypted rsync remote. **done** * Rsync.net special case **done** * Set up gpg encryption key; gpg key distribution.
doc/design/assistant/desymlink.mdwn view
@@ -2,7 +2,7 @@ them upon creation, using symlinks. This is a core design simplification of git-annex.-But it is problimatic too:+But it is problematic too: * To allow directly editing files in its folder, something like [[todo/smudge]] is needed, to get rid of the symlinks that stand in for the files.@@ -40,3 +40,56 @@ Perhaps a 0 length, unreadable, unwritable file? On systems that support symlinks it could be a broken symlink like is used now, that is converted to a real file when it becomes present.++## concrete design++* Enable with annex.nosymlink or such config option.+* Use .git/ for the git repo, but `.git/annex/objects` won't be used.+* `git status` and similar will show all files as type changed, and+ `git commit` would be a very bad idea. Just don't support users running+ git commands that affect the repository in this mode.+* However, `git status` and similar also will show deleted and new files,+ which will be helpful for the assistant to use when starting up.+* Cache the mtime, size etc of files, and use this to detect when they've been+ modified when the assistant was not running. This would only need to be+ checked at startup, probably.+* Use dangling symlinks for standins for missing content, as now.+ This allows just cloning one of these repositories normally, and then+ as the files are synced in, they become real files.+* Maintain a local mapping from keys to files in the tree. This is needed+ when sending/receiving keys to know what file to access. Note that a key+ can map to multiple files. And that when a file is deleted or moved, the+ mapping needs to be updated.+* May need a reverse mapping, from files in the tree to keys? TBD+* The existing watch code detects when a file gets closed, and in this+ mode, it could be a new file, or a modified file, or an unchanged file.+ For a modified file, can compare mtime, size, etc, to see if it needs+ to be re-added.+* The inotify/kqueue interface does not tell us when a file is renamed.+ So a rename has to be treated as a delete and an add, so can have a lot+ of overhead, to re-hash the file.+* Note that this could be used without the assistant, as a git remote+ that content is transferred to and from. Without the assistant, changes+ to files in this remote would not be noticed and committed, unless+ a git-annex command were added to do so.+ Getting it basically working as a remote would be a good 1st step.++## TODO++* Deal with files changing as they're being transferred from a direct mode+ repository to another git repository. The remote repo currently will + accept the bad data and update the location log to say it has the key.+* `git annex sync` updates the key to files mappings for files changed,+ but needs much other work to handle direct mode:+ * Generate git commit, without running `git commit`, because it will+ want to stage the full files.+ * Update location logs for any files deleted by a commit.+ * Generate a git merge, without running `git merge` (or possibly running+ it in a scratch repo?), because it will stumble over the direct files.+ * Drop contents of files deleted by a merge (including updating the+ location log), or if we cannot drop,+ move their contents to `.git/annex/objects/`.+ * When a merge adds a symlink pointing at a key that is present in the+ repo, replace the symlink with the direct file (either moving out+ of `.git/annex/objects/` or hard-linking if the same key is present+ elsewhere in the tree.
doc/design/assistant/pairing.mdwn view
@@ -81,4 +81,3 @@ It should be possible for third parties to tell when pairing is done, but it's actually rather hard since they don't necessarily share the secret.-* Pairing over XMPP.
+ doc/design/assistant/polls/Android.mdwn view
@@ -0,0 +1,18 @@+Help me choose a goal for the month of December. The last poll showed +a lot of interest in using the git-annex assistant with phones, etc.++Background: git-annex uses symbolic links in its repositories. This makes it+hard to use with filesystems, such as FAT, that do not support symbolic links.+FAT filesystems are the main storage available on some Android devices that+have a micro-SD card. Other, newer Android devices don't have a SD card and so+avoid this problem.++I can either work on the idea described in+[[design/assistant/desymlink]], which could solve the symlink problem and+also could lead to a nicer workflow to editing files that are stored in+git-annex.++Or, I can work on [[Android_porting|design/assistant/android]], and try to+get the assistant working on Android's built-in storage.++[[!poll open=no 81 "solve the symlink problem first" 17 "port to Android first" 1 "other"]]
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)" 12 "Amazon Glacier (done)" 9 "Box.com (done)" 63 "My phone (or MP3 player)" 16 "Tahoe-LAFS" 6 "OpenStack SWIFT" 23 "Google Drive"]]+[[!poll open=yes 15 "Amazon S3 (done)" 12 "Amazon Glacier (done)" 9 "Box.com (done)" 66 "My phone (or MP3 player)" 17 "Tahoe-LAFS" 6 "OpenStack SWIFT" 23 "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/syncing.mdwn view
@@ -18,13 +18,9 @@ airport somewhere. * Find a way to probe available outgoing bandwidth, to throttle so we don't bufferbloat the network to death.-* Investigate the XMPP approach like dvcs-autosync does, or other ways of- signaling a change out of band. * Add a hook, so when there's a change to sync, a program can be run and do its own signaling. * --debug will show often unnecessary work being done. Optimise.-* This assumes the network is connected. It's often not, so the- [[cloud]] needs to be used to bridge between LANs. * Configurablity, including only enabling git syncing but not data transfer; only uploading new files but not downloading, and only downloading files in some directories and not others. See for use cases:@@ -41,14 +37,11 @@ working copy and checks each file. That probably needs to be done once, but further calls to the TransferScanner could eg, look at the delta between the last scan and the current one in the git-annex branch.-* Ensure that when a remote receives content, and updates its location log,- it syncs that update back out. Currently, it does not, unless the master- branch also changed. Prerequisite for: * After git sync, identify new content that we don't have that is now available on remotes, and transfer. (Needed when we have a uni-directional connection to a remote, so it won't be uploading content to us.) Note: Does not need to use the TransferScanner, if we get and check a list of the changed- files.+ files. done? * [[use multiple transfer slots|todo/Slow_transfer_for_a_lot_of_small_files.]] * The TransferQueue's list of deferred downloads could theoretically grow without bounds in memory. Limit it to a given number of entries,
doc/design/assistant/transfer_control.mdwn view
@@ -19,9 +19,6 @@ log is not updated in time, it will fail to drop unwanted content. (There's a 10 second sleep there now to avoid the race, but that's hardly a fix.)-* When a file is renamed into an archive directory, it's not immediately- transferred to archive remotes. (Next expensive scan does successfully- cause the transfer to happen). ### dropping no longer preferred content @@ -48,7 +45,7 @@ That's all! Of these, 1-4 are by far the most important. -## specifying what data a remote prefers to contain **done**+## specifying what data a remote prefers to contain (**done**) Imagine a per-remote preferred content setting, that matches things that should be stored on the remote.@@ -67,7 +64,7 @@ from the repo. So once all three laptops have the data, it is pruned from the transfer drive. -## repo groups **done**+## repo groups (**done**) Seems like git-annex needs a way to know the groups of repos. Some groups:@@ -79,7 +76,7 @@ it does not hold data for long periods of time, and tends to have a limited size. -Add a group.log that can assign repos to these or other groups. **done**+Add a group.log that can assign repos to these or other groups. (**done**) Some examples of using groups: @@ -104,7 +101,10 @@ predefined groups with pre-defined preferred content recipes. Is this good enough? -## the state change problem **done**+I think so; useful recipes can be developed on the wiki and included in+git-annex.++## the state change problem (**done**) Imagine that a trusted repo has setting like `not copies=trusted:2` This means that `git annex get --auto` should get files not in 2 trusted
doc/design/assistant/webapp.mdwn view
@@ -8,6 +8,8 @@ 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.+* Some forms display a modal message when submitted and also have required+ fields. This does not interact well. ## interface @@ -28,7 +30,7 @@ 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 removing git remotes+* allow removing git remotes **done** * allow disabling syncing to here, which should temporarily disable all local syncing.
+ doc/forum/Can__39__t_install:_Mac_OS_10.8.2.mdwn view
@@ -0,0 +1,36 @@+###Tried to install git-annex.app++- App hangs up+- Cpu "git" load is 100+- Had to force quite git-annex++###Install thru command line: using Brew++- Installed haskell+- updated cabal+- But when I do:++`+cabal install git-annex --bindir=$HOME/bin+`++**I get this**++ Resolving dependencies...+ Configuring gnuidn-0.2...+ cabal: The program c2hs is required but it could not be found.+ Configuring libxml-sax-0.7.3...+ cabal: The pkg-config package libxml-2.0 is required but it could not be found.+ cabal: Error: some packages failed to install:+ git-annex-3.20121127.1 depends on libxml-sax-0.7.3 which failed to install.+ gnuidn-0.2 failed during the configure step. The exception was:+ ExitFailure 1+ libxml-sax-0.7.3 failed during the configure step. The exception was:+ ExitFailure 1+ network-protocol-xmpp-0.4.4 depends on libxml-sax-0.7.3 which failed to install.++Any help would be greatly appreciated. ++Thanks,++Carlito
+ doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch.mdwn view
@@ -0,0 +1,1 @@+I have an external HDD which I setup as a remote manually before I started using the assistant. When I plug it in files sync fine and the git-annex branch gets synced, but the master branch doesn't; git annex sync doesn't do the job and I have to run git pull. This is annoying because it means that portable drive is useless as a backup, since it doesn't have the required metadata; I have to manually git pull to make it a useful backup. How can I make the assistant sync the metadata in--if not the master branch, at least origin/master so I could merge later without the remote available. Thanks.
+ doc/forum/Moving_large_files_within_the_repo_without_copying___63__.mdwn view
@@ -0,0 +1,19 @@+Is there a way to move a large file without "git annex unlock"ing it (Which takes very long for copying and then rehashing the file)?+Using a simple "mv" or "git mv" results in broken symlinks, if the target directory is on a different hierarchy level:++Example:++Initial State:++ $ ls -Hl Pictures:+ Pictures/showImages.jpg -> ../.git/annex/objects/90/32/SHA1-s8737--a8bfb285d0ae394cb75c86f1eb9f703fb678a51e/SHA1-s8737--a8bfb285d0ae394cb++Move: ++ $ mv Pictures/showImages.jpg .++Result: ++ $ ls -H showImages.jpg+ ls: cannot access showImages.jpg: No such file or directory+
+ doc/forum/Synchronize_large_files___40__VM_images__41__.mdwn view
@@ -0,0 +1,10 @@+Hi, ++i'm thinking to use git-annex to synchronize my virtual machine directory (Virtualbox) between 3 pc. It's quite big: more than 200GB and some of the images are 40Gb in size.++The synchronization will be over a lan (obviously). It is already in place with 2pc and unison but the configuration of the 3rd pc is cumbersome. +Does anybody have experiences with git-annex and such amount of data?++Thanks in advance++Gabriele
+ doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__.mdwn view
@@ -0,0 +1,1 @@+On BTRFS it is possible to use [reflinks / clones](https://en.wikipedia.org/wiki/Btrfs#Cloning). This is the equivalent of hardlinks except that when the file is modified, a copy is performed (copy on write). Perhaps git-annex could detect the availability of this feature and use it in case it is available (and the repository and the file are in the same filesystem).
+ doc/forum/__34__du__34___equivalent_on_an_annex__63__.mdwn view
@@ -0,0 +1,5 @@+One reason to use git-annex is to save disk space by tossing files you don't use that often.++I can find big files in the repository with git annex find --largerthan=100M, but is there a way to find large *directories*? In an ordinary filesystem I'd use "du -h" with a maxdepth to get an idea of what parts of a directory are taking up my disk space, but obviously that won't work with git annex because all the content is in .git/annex. Any ideas?++(I can get a listing of file sizes in a directory with the handy -L flag of ls -- "ls -lL" shows me the sizes of the link targets -- but that won't summarize all the sizes of subdirectories. Unless my ls-fu is just weak.)
+ doc/forum/benefit_of_splitting_a_repository.mdwn view
@@ -0,0 +1,10 @@+I am evaluating the best strategy to use git-annex to manage my media library. It consists of about 300.000 files totaling 1 TB of data.++My question is, wheither it would be of advantage to split the repo into several smaller ones (Like Photos, Videos, Musik, Books, ...)?++Would this affect performance of certain operations? I.e. Operations that have superlinear (O(n^a) with a > 1) complexity?++I am thinking about "git annex unused", which takes 22 minutes on my machine performed on the full repo. +++Do you have more interesting information on using git-annex in this scale?
+ doc/forum/dot_git_slash_annex_slash_tmp.mdwn view
@@ -0,0 +1,5 @@+When I was checking out disk usage on my home directory, I noticed a bunch of files stored in .git/annex/tmp under their own filenames, rather than in .git/annex/objects. Checking a couple, they seem to be redundant with stuff in .git/annex/objects.++Is there any way to clean that stuff up? Will the assistant eventually clean it up?++Thanks!
+ doc/forum/gadu_-_git-annex_disk_usage.mdwn view
@@ -0,0 +1,7 @@+Based on the thread over at <http://git-annex.branchable.com/forum/__34__du__34___equivalent_on_an_annex__63__/> I decided to finally write a du like utility for git-annex. A 0.01 version is up over at <http://git-annex.mysteryvortex.com/git-annex-utils.html>. It works, but I intend to make it smarter about handling git repos and annexed files, as well as adding more of the options available in the standard du utility.++Currently it will tally up the sizes of links that look like they are annexed files. I plan to make it actually interact with git and git-annex to verify the files are annexed and enable options like tallying files only from specific remotes, only missing files, not double counting files which are annexed multiple times but stored only once, etc...++I'll have time to work on this on the weekends, and plan to get my git repo up soon. After gadu is mostly complete I might work on some other tools.++Releases are signed with a PGP key with fingerprint 5E1A 65D7 D5E9 56F1 C239 43DF C6C8 9A0B 6003 8953 (available on the website)
+ doc/forum/git-assistant_clarification.mdwn view
@@ -0,0 +1,11 @@+I've noticed that if I'm using git-assistant, it wants to pull down all my files from other repos onto my laptop, even after I've dropped them. (My laptop is set up as "client," my usb drive and an ssh server as "backup".)++I want to use git annex to save space on my laptop, but of course when I'm running the assistant, it pulls everything down there, even things I've manually dropped.++Is my "I want to save space, with a partial archive on my laptop" use case simply out of scope for the assistant? So I should just be using the command line for my needs? That's fine if that's the case.++Or maybe something like this is what I should be doing? http://git-annex.branchable.com/assistant/archival_walkthrough/ ? so instead of manually "git annex drop"-ping files in place, I should set up a directory called "archive" on my machine, from which files will magically disappear and get backed up elsewhere?++If it's the case that a directory named "archive" in your checkout has the magical property of having the assistant drop and archive its contents, that's awesome, maybe just what I need, but if that behavior is spelled out in so many words anywhere I managed to miss it.++Apologies for all these questions, just enjoying the software immensely and wanting to get to know it.
+ doc/forum/git_annex_alternative.mdwn view
@@ -0,0 +1,10 @@+I really like git-annex and am thankfull to its creator!++I especially like the high level of abstraction it provides when handling backups or syncing.++But git and my ext4 filesystem and HDD just hate the amount of files/folder/symlinks it throws at them and I am asking, what the alternatives are. I am especially looking for the numcopies and "--auto" functionallity. +++Most alternatives I checked out (eps. distributed redundant filesystems) come up with other burdens or restrictions.++Do you have any experience with different systems?
+ doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer..mdwn view
@@ -0,0 +1,3 @@+A couple times working in an annex manually, I accidentally did "git add" instead of "git annex add" and ended up with files checked into my repo instead of symlinks. So now there is some file content in git, rather than in the annex. Is there any way to root that out, or is it there forever? (My limited knowledge of git says: it's there forever, unless maybe you go into the branches where it lives, do an interactive rebase to the time before it was added, remove that commit, replay history, and then garbage collect, but I have no idea if that would suddenly break git annex, and it sounds painful anyway.)++If say I were a neat freak and wanted to just start over with a clean annex, I imagine the thing to do would be to just start the hell over -- and if I wanted to do that, the way to go would be to get into a full repository, do a "git annex uninit" and then throw away the .git directory, then do "git init" and "git annex init" and then "git annex add ." ?
+ doc/forum/updating_the___34__number_of_copies__34__.mdwn view
@@ -0,0 +1,14 @@+Is it possible to let git-annex check and update the "number of copies" or "whereis" information without recalculating the checksome?++The use case is this:++I have a very large "repo1": 300.000 files 1.5 TB.++I copy it using low level tools for performance (clone the partition, netcat over network, or whatever...)++Then i do "git annex init 'repo2'". +All files exist in both repos and the simlinks are valid, but git-annex does not know about it. +The "git-annex wehereis" only shows "repo1". How can I tell him without rehashing 1.6TB?++Thx+
+ doc/forum/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn view
@@ -0,0 +1,17 @@+I am running centralized git-annex exclusively.++Similar to++ git annex get++I'd like to have a++ git annex put++which would put all files on the default remote(s).++My main reason for not wanting to use copy --to is that I need to specify the remote's name in this case which makes writing a wrapper unnecessarily hard. Also, this would allow++ mr push++to do the right thing all by itself.
doc/install/OSX.mdwn view
@@ -13,9 +13,11 @@ <pre> sudo brew update-sudo brew install haskell-platform git ossp-uuid md5sha1sum coreutils pcre libgsasl gnutls libidn libgsasl pkg-config+sudo brew install haskell-platform git ossp-uuid md5sha1sum coreutils pcre libgsasl gnutls libidn libgsasl pkg-config libxml2+sudo brew link libxml2 cabal update-cabal install git-annex --bindir=$HOME/bin+PATH=$HOME/bin:$PATH+cabal install c2hs git-annex --bindir=$HOME/bin </pre> ## using MacPorts@@ -30,14 +32,15 @@ sudo ln -s /opt/local/include/pcre.h /usr/include/pcre.h # This is hack that allows pcre-light to find pcre sudo cabal update-cabal install git-annex --bindir=$HOME/bin+PATH=$HOME/bin:$PATH+cabal install c2hs git-annex --bindir=$HOME/bin </pre> ## PATH setup Do not forget to add to your PATH variable your ~/bin folder. In your .bashrc, for example: <pre>-PATH=$HOME/bin:/usr/bin/local:$PATH+PATH=$HOME/bin:$PATH </pre> See also:
+ doc/install/OSX/comment_4_bbe99673033e4c48c8bb3db24ee419f9._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"+ nickname="Jimmy"+ subject="comment 4"+ date="2012-12-10T17:00:43Z"+ content="""+For those that care, I've updated my autobuilder to the latest version of haskell-platform 2012.4.0.0 and it appears to be building correctly.+"""]]
doc/install/cabal.mdwn view
@@ -1,7 +1,8 @@ As a haskell package, git-annex can be installed using cabal. For example: cabal update- cabal install git-annex --bindir=$HOME/bin+ PATH=$HOME/bin:$PATH+ cabal install c2hs git-annex --bindir=$HOME/bin The above downloads the latest release and installs it into a ~/bin/ directory, which you can put in your PATH.@@ -10,6 +11,8 @@ you want, and use cabal as follows inside its source tree: cabal update+ PATH=$HOME/bin:$PATH+ cabal install c2hs --bindir=$HOME/bin cabal install --only-dependencies cabal configure cabal build
doc/internals.mdwn view
@@ -11,7 +11,7 @@ First there are two levels of directories used for hashing, to prevent too many things ending up in any one directory. -Each subdirectory has the name of a key in one of the+Each subdirectory has the [[name_of_a_key|key_format]] in one of the [[key-value_backends|backends]]. The file inside also has the name of the key. This two-level structure is used because it allows the write bit to be removed from the subdirectories as well as from the files. That prevents accidentially
+ doc/internals/key_format.mdwn view
@@ -0,0 +1,20 @@+A git-annex key has this format:++ BACKEND-sNNNN-mNNNN--NAME++For example:++ SHA256E-s31390--f50d7ac4c6b9031379986bc362fcefb65f1e52621ce1708d537e740fefc59cc0.mp3++* The backend is one of the [[key-value_backends|backends]], which+ are always upper-cased.+* The name field at the end has a format dependent on the backend. It is+ always the last field, and is prefixed with "--". Unlike other fields,+ it may contain "-" in its content. It should not contain newline characters;+ otherwise nearly anything goes.+* The "-s" field is optional, and is the size of the content in bytes.+* The "-m" field is optional, and is the mtime of the file when it was+ added to git-annex, expressed as seconds from the epoch.+ This is currently only used by the WORM backend.+* Other fields could be added in the future, if needed.+* Fields may appear, in any order (though always before the name field).
− doc/news/version_3.20121017.mdwn
@@ -1,4 +0,0 @@-git-annex 3.20121017 released with [[!toggle text="these changes"]]-[[!toggleable text="""- * Fix zombie cleanup reversion introduced in 3.20121009.- * Additional fix to support git submodules."""]]
+ doc/news/version_3.20121211.mdwn view
@@ -0,0 +1,32 @@+git-annex 3.20121211 released with [[!toggle text="these changes"]]+[[!toggleable text="""+ * webapp: Defaults to sharing box.com account info with friends, allowing+ one-click enabling of the repository.+ * Fix broken .config/git-annex/program installed by standalone tarball.+ * assistant: Retrival from glacier now handled.+ * Include ssh in standalone tarball and OSX app.+ * watch: Avoid leaving hard links to files behind in .git/annex/tmp+ if a file is deleted or moved while it's being quarantined in preparation+ to being added to the annex.+ * Allow `git annex drop --from web`; of course this does not remove+ any file from the web, but it does make git-annex remove all urls+ associated with a file.+ * webapp: S3 and Glacier forms now have a select list of all+ currently-supported AWS regions.+ * webdav: Avoid trying to set props, avoiding incompatability with+ livedrive.com. Needs DAV version 0.3.+ * webapp: Prettify error display.+ * webapp: Fix bad interaction between required fields and modals.+ * webapp: Added help buttons and links next to fields that require+ explanations.+ * webapp: Encryption can be disabled when setting up remotes.+ * assistant: Avoid trying to drop content from remotes that don't have it.+ * assistant: Allow periods in ssh key comments.+ * get/copy --auto: Transfer data even if it would exceed numcopies,+ when preferred content settings want it.+ * drop --auto: Fix dropping content when there are no preferred content+ settings.+ * webapp: Allow user to specify the port when setting up a ssh or rsync+ remote.+ * assistant: Fix syncing to just created ssh remotes.+ * Enable WebDAV support in Debian package. Closes: #[695532](http://bugs.debian.org/695532)"""]]
doc/preferred_content.mdwn view
@@ -116,6 +116,8 @@ All content is preferred. +`include=*`+ ### small archive Only prefers content that's located in an "archive" directory, and
+ doc/preferred_content/comment_1_7d45e21dfb016e9ffa4715346dd0c1a6._comment view
@@ -0,0 +1,19 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"+ nickname="Sehr"+ subject="Interplay with numcopies"+ date="2012-12-05T20:41:26Z"+ content="""+How does the preferred content settings interfere with the numcopies setting?++I could not get behind it. E.g. a case I do not unterstand:++I have a preferred setting evaluating to true and still ++ git annex get --auto++does nothing, if the number of copies produced would surpass the numcopies setting.+++Thx+"""]]
+ doc/preferred_content/comment_2_1ccd90b009245667ad59f4d29d2a3a37._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.153.253.113"+ subject="comment 2"+ date="2012-12-06T17:24:29Z"+ content="""+Yeah, that didn't make sense. I've fixed it, so it gets files if needed for either numcopies or preferred content.+"""]]
+ doc/preferred_content/comment_4_384025b5fa23a3f175985a081438149f._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.153.8.117"+ subject="comment 4"+ date="2012-12-10T19:46:01Z"+ content="""+It was a bug in the backup group's preferred content pagespec, introduced by the changes I made to fix the previous problem. Now fixed.+"""]]
+ doc/preferred_content/comment_4_6a9bc657bc7415f0e118357d8c6664c6._comment view
@@ -0,0 +1,18 @@+[[!comment format=mdwn+ username="http://edheil.wordpress.com/"+ ip="173.162.44.162"+ subject="comment 4"+ date="2012-12-07T20:24:18Z"+ content="""+Built a new copy of git-annex yesterday. I have a \"client\" on my macbook, and two \"backup\"s, one on an external HD, one on an ssh git remote.++git annex get --auto works beautifully!++It doesn't seem to work for copying content *to* a place where it's needed, though.++If I drop a file from my \"backup\" USB drive, and then go back to my macbook and do a \"git annex sync\" and \"git annex copy --to=usbdrive --auto\" it does not send the file out to the USB drive, even though by preferred content settings, the USB drive should \"want\" the file because it's a backup drive and it wants all content.++Similarly, if I add a new file on my macbook and then do a \"git annex copy --to=usbdrive auto\" it does not get copied to the USB drive.++Is this missing functionality, or should the preferred content setting for remotes only affect the assistant?+"""]]
+ doc/preferred_content/comment_5_f0a957e67297c4bb5a8778c11b3c9fd4._comment view
@@ -0,0 +1,9 @@+[[!comment format=mdwn+ username="http://edheil.wordpress.com/"+ ip="173.162.44.162"+ subject="comment 5"+ date="2012-12-11T16:03:04Z"+ content="""+thanks!++"""]]
doc/scalability.mdwn view
@@ -23,9 +23,9 @@ improves this will improve. Scaling to hundreds of thousands of files is not a problem, scaling beyond that and git will start to get slow. - To some degree, git-annex works around innefficiencies in git; for- example it batches input sent to certian git commands that are slow- when run in an emormous repository.+ To some degree, git-annex works around inefficiencies in git; for+ example it batches input sent to certain git commands that are slow+ when run in an enormous repository. * It can use as much, or as little bandwidth as is available. In particular, any interrupted file transfer can be resumed by git-annex.
+ doc/special_remotes/bup/comment_1_96179a003da4444f6fc08867872cda0a._comment view
@@ -0,0 +1,43 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkgbXwQtPQSG8igdS7U8l031N8sqDmuyvk"+ nickname="Albert"+ subject="Error with bup and gnupg"+ date="2012-10-22T20:56:56Z"+ content="""+Hello,++I get this error when trying to use git-annex with bup and gnupg:++<pre>+move importable_pilot_surveys.tar (gpg) (checking localaseebup...) (to localaseebup...) +Traceback (most recent call last):+ File \"/usr/lib/bup/cmd/bup-split\", line 133, in <module>+ progress=prog)+ File \"/usr/lib/bup/bup/hashsplit.py\", line 167, in split_to_shalist+ for (sha,size,bits) in sl:+ File \"/usr/lib/bup/bup/hashsplit.py\", line 118, in _split_to_blobs+ for (blob, bits) in hashsplit_iter(files, keep_boundaries, progress):+ File \"/usr/lib/bup/bup/hashsplit.py\", line 86, in _hashsplit_iter+ bnew = next(fi)+ File \"/usr/lib/bup/bup/helpers.py\", line 86, in next+ return it.next()+ File \"/usr/lib/bup/bup/hashsplit.py\", line 49, in blobiter+ for filenum,f in enumerate(files):+ File \"/usr/lib/bup/cmd/bup-split\", line 128, in <genexpr>+ files = extra and (open(fn) for fn in extra) or [sys.stdin]+IOError: [Errno 2] No such file or directory: '-'+</pre>+++I was able to work-around this issue by altering /usr/lib/bup/cmd/bup-split (though I don't think its a bup bug) to just pull from stdin:++files = [sys.stdin]++on ~ line 128.++Any ideas? Also, do you think that bup's data-deduplication does anything when gnupg is enabled, i.e. is it just as well to use a directory remote with gnupg?++Thanks! Git annex rules!++Albert+"""]]
+ doc/special_remotes/bup/comment_2_612b038c15206f9f3c2e23c7104ca627._comment view
@@ -0,0 +1,12 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.154.0.23"+ subject="comment 2"+ date="2012-10-23T20:01:43Z"+ content="""+@Albert, thanks for reporting this bug (but put them in [[bugs]] in future please).++This is specific to using the bup special remote with encryption. Without encryption it works. And no, it won't manage to deduplicate anything that's encrypted, as far as I know. ++I think bup-split must have used - for stdin in the past, but now, it just reads from stdin when no file is specified, so I've updated git-annex.+"""]]
+ 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/tips/Decentralized_repository_behind_a_Firewall.mdwn view
@@ -0,0 +1,59 @@+If you're anything like me¹, you have a copy of your annex on a computer running at home², set up so you can access it from anywhere like this:++ ssh myhome.no-ip.org++This is totally great! Except, there is no way for your home computer to pull your changes, because there is no *on-the-go.no-ip.org*. You can get clunky and use a *bare git repository and git push*, but there is a better way.++First, install *openssh-server* on your *on-the-go* computer++ sudo apt-get install openssh-server # Adjust to your flavor of unix++Then, log into your *home* computer, with *port forwarding*:++ ssh me@myhome.no-ip.org L 2201:localhost:22++Your *home* computer can now ssh into your *on-the-go* computer, as long as you keep the above shell running.++You can now add your *on-the-go* computer as a remote on your *home* computer. Use the port forwarding shell you just connected with the command above, if you like. ++ ssh-keygen -t rsa+ ssh-copy-id me@localhost -p 2201+ cd ~/annex+ git annex remote add on-the-go ssh://me@localhost:2201/home/myuser/annex++Now you can run normal annex operations, as long as the port forwarding shell is running³.++ git annex sync+ git annex get on-the-go some/big/file+ git annex status++You can add more computers by repeating with a different port, e.g. 2202 or 2203 (or any other).++If you're security paranoid (like me), read on. If you're not, that's it! Thanks for reading!++---+Paranoid Area++Note you're granting passwordless access to your on-the-go computer to your home computer. I believe that's all right, as long as:++* Your home computer is really in your home, and not at a friend's house or some datacenter+* Your home computer can be accessed only by ssh, and not HTTP or Samba or NTP or (shoot me now!) FTP+* Only you (and perhaps trustworthy family) have access to your home computer+* You have reasonably strong passwords or key-only logins on both your home and on-the-go computers.+* You regularly install security updates on both computers (sudo apt-get update && sudo apt-get upgrade)++In any case, the setup is much, much, much more secure than Dropbox. With Dropbox, you have exactly the same setup, but:++* Your data is stored in some datacenter. It's supposed to be encrypted. It might not be.+* Lot's of people have routine access to your files, and plausible reason to. Bored employees might regularly be doing some 'maintenance work' involving your pictures.+* The dropbox software can do anything it likes on your computer, and it's closed source so you don't know if it does. A disgruntled employee could put a trojan into it.+* Dropbox might have a backdoor for employee access to any file on your computer. This might be done with the best of intentions, but a mal-intentioned or careless employee might still erase things or send sensitive files from your computer by email.+* A truly huge amount of eyes connected to incredibly smart brains have looked at openssh and found it secure. Everybody trusts openssh. With dropbox, there is, well, dropbox. Whoever that is.++-----++¹ Me=Carlo, not Joey. I'm pretty sure doing what I wrote here is a good idea, but in case it turns out to be catastrophically dumb, it's my fault, not his.++² My always-on computer at home is a raspberry pi with a 32GB USB stick. Best self-hosted dropbox you could imagine.++³ You can just forward the port, but not open a shell, by adding the -N command. This could be useful for connecting on startup, e.g. in /etc/rc.local. I prefer to open the shell to forward the ports, maybe use it, and close it to stop it.
+ doc/tips/assume-unstaged/comment_1_44abd811ef79a85e557418e17a3927be._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="https://me.yahoo.com/a/2djv2EYwk43rfJIAQXjYt_vfuOU-#a11a6"+ nickname="Olivier R"+ subject="It doesn't work 100%"+ date="2012-05-03T21:42:54Z"+ content="""+When you remove tracked files... it doesn't show the new status. it's like if the file was ignored.+++"""]]
+ doc/tips/using_Amazon_S3/comment_1_666a26f95024760c99c627eed37b1966._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY"+ nickname="Matt"+ subject="ANNEX_S3 vs AWS for keys"+ date="2012-05-29T12:24:25Z"+ content="""+The instructions state ANNEX_S3_ACCESS_KEY_ID and ANNEX_SECRET_ACCESS_KEY but git-annex cannot connect with those constants. git-annex tells me to set both \"AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY\" instead, which works. This is with Xubuntu 12.04.+"""]]
+ doc/tips/using_Amazon_S3/comment_2_f5a0883be7dbb421b584c6dc0165f1ef._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.153.81.112"+ subject="comment 2"+ date="2012-05-29T19:10:42Z"+ content="""+Thanks, I've fixed that. (You could have too.. this is a wiki ;)+"""]]
+ doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment view
@@ -0,0 +1,11 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"+ nickname="Richard"+ subject="comment 1"+ date="2011-05-17T07:27:02Z"+ content="""+Sounds like a good idea.++* git annex fsck (or similar) should check/rebuild the caches+* I would simply require a clean tree with a verbose error. 80/20 rule and defaulting to save actions.+"""]]
+ doc/todo/windows_support/comment_1_3cc26ad8101a22e95a8c60cf0c4dedcc._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkRITTYYsN0TFKN7G5sZ6BWGZOTQ88Pz4s"+ nickname="Zoltán"+ subject="cygwin"+ date="2012-05-15T00:14:08Z"+ content="""+What about [Cygwin](http://cygwin.com/)? It emulates POSIX fairly well under Windows (including signals, forking, fs (also things like /dev/null, /proc), unix file permissions), has all standard gnu utilities. It also emulates symlinks, but they are unfortunately incompatible with NTFS symlinks introduced in Vista [due to some stupid restrictions on Windows](http://cygwin.com/ml/cygwin/2009-10/msg00756.html).++If git-annex could be modified to not require symlinks to work, the it would be a pretty neat solution (and you get a real shell, not some command.com on drugs (aka cmd.exe))+"""]]
+ doc/todo/windows_support/comment_2_8acae818ce468967499050bbe3c532ea._comment view
@@ -0,0 +1,12 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawk5cj-itfFHq_yhJHdzk3QOPp-PNW_MjPU"+ nickname="Michael"+ subject="+1 Cygwin"+ date="2012-05-23T19:30:21Z"+ content="""+Windows support is a must. In my experience, binary file means proprietary editor, which means Windows.++Unfortunately, there's not much overlap between people who use graphical editors in Windows all day vs. people who are willing to tolerate Cygwin's setup.exe, compile a Haskell program, learn git and git-annex's 90-odd subcommands, and use a mintty terminal to manage their repository, especially now that there's a sexy GitHub app for Windows.++That aside, I think Windows-based content producers are still *the* audience for git-annex. First Windows support, then a GUI, then the world.+"""]]
+ doc/todo/windows_support/comment_3_bd0a12f4c9b884ab8a06082842381a01._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://xolus.net/openid/max"+ nickname="B0FH"+ subject="What about NTFS support ?"+ date="2012-08-02T17:45:10Z"+ content="""+Has git-annex been tested with an NTFS-formatted disk under Linux ? NTFS is supposed to be case-sensitive and to allow symlinks, and these are supposed to work with ntfs3g.+"""]]
+ doc/todo/windows_support/comment_4_ad06b98b2ddac866ffee334e41fee6a8._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawlc1og3PqIGudOMkFNrCCNg66vB7s-jLpc"+ nickname="Paul"+ subject="Re: What about NTFS support?"+ date="2012-08-16T19:30:38Z"+ content="""+I successfully use git-annex on an NTFS formatted external USB drive, so yes, it is possible and works well.+"""]]
+ doc/todo/windows_support/comment_5_444fc7251f57db241b6e80abae41851c._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="https://me.yahoo.com/a/dASECLNzvckz4VwqUGYsvthiplY.#d2c27"+ nickname="A. D. Sicks"+ subject="comment 5"+ date="2012-09-09T23:48:21Z"+ content="""+Haskell has C++ binding, so it should be possible to port it to .net/Mono with a VB GUI for Windows users. Windows has a primitive form of symlinks called shortcuts. Perhaps shortcut support in Windows could replace the use of symlinks. I've used shortcuts since XP to put my home Windows directory on another partition and never had a hitch...++If anyone is interested in working on this, hit me up. I would like to use this in my XP vbox to have access to files on my host OS...I have a student edition of Visual Studio 2005 to do an open source port...+"""]]
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 3.20121127.1+Version: 3.20121211 Cabal-Version: >= 1.8 License: GPL Maintainer: Joey Hess <joey@kitenet.net>@@ -73,7 +73,7 @@ CPP-Options: -DWITH_S3 if flag(WebDAV)- Build-Depends: DAV (>= 0.2), http-conduit, xml-conduit+ Build-Depends: DAV (>= 0.3), http-conduit, xml-conduit, http-types CPP-Options: -DWITH_WEBDAV if flag(Assistant) && ! os(windows) && ! os(solaris)@@ -95,7 +95,7 @@ if flag(Webapp) && flag(Assistant) Build-Depends: yesod, yesod-static, case-insensitive, http-types, transformers, wai, wai-logger, warp, blaze-builder,- crypto-api, hamlet, clientsession, aeson,+ crypto-api, hamlet, clientsession, aeson, yesod-form, template-haskell, yesod-default (>= 1.1.0), data-default CPP-Options: -DWITH_WEBAPP
+ standalone/linux/git-annex view
@@ -0,0 +1,25 @@+#!/bin/sh+base="$(dirname $0)"+if [ ! -d "$base" ]; then+ echo "** cannot find base directory (I seem to be $0)" >&2+ exit 1+fi+if [ ! -e "$base/runshell" ]; then+ echo "** cannot find $base/runshell" >&2+ exit 1+fi++# Get absolute path to base, to avoid breakage when things change directories.+orig="$(pwd)"+cd "$base"+base="$(pwd)"+cd "$orig"++# If this is a standalone app, set a variable that git-annex can use to+# install itself.+if [ -e "$base/bin/git-annex" ]; then+ GIT_ANNEX_APP_BASE="$base"+ export GIT_ANNEX_APP_BASE+fi++"$base/runshell" git-annex "$@"
standalone/linux/runshell view
@@ -67,5 +67,5 @@ shift 1 exec "$cmd" "$@" else- $SHELL+ sh fi
standalone/osx/git-annex.app/Contents/Info.plist view
@@ -26,10 +26,6 @@ <string>git-annex</string> <key>CFBundleVersion</key> <string>0.0.1</string>- <key>NSAppleScriptEnabled</key>- <true/>- <key>CGDisableCoalescedUpdates</key>- <true/> <key>LSMinimumSystemVersion</key> <string>10.5</string> <key>CFBundleDisplayName</key>
+ standalone/osx/git-annex.app/Contents/MacOS/git-annex view
@@ -0,0 +1,25 @@+#!/bin/sh+base="$(dirname $0)"+if [ ! -d "$base" ]; then+ echo "** cannot find base directory (I seem to be $0)" >&2+ exit 1+fi+if [ ! -e "$base/runshell" ]; then+ echo "** cannot find $base/runshell" >&2+ exit 1+fi++# Get absolute path to base, to avoid breakage when things change directories.+orig="$(pwd)"+cd "$base"+base="$(pwd)"+cd "$orig"++# If this is a standalone app, set a variable that git-annex can use to+# install itself.+if [ -e "$base/git-annex" ]; then+ GIT_ANNEX_APP_BASE="$base"+ export GIT_ANNEX_APP_BASE+fi++"$base/runshell" git-annex "$@"
standalone/osx/git-annex.app/Contents/MacOS/git-annex-webapp view
@@ -17,7 +17,7 @@ # If this is a standalone app, set a variable that git-annex can use to # install itself.-if [ -e "$base/bin/git-annex" ]; then+if [ -e "$base/git-annex" ]; then GIT_ANNEX_APP_BASE="$base" export GIT_ANNEX_APP_BASE fi
standalone/osx/git-annex.app/Contents/MacOS/runshell view
@@ -1,6 +1,6 @@ #!/bin/sh-# Runs a shell command (or interactive shell) using the binaries and-# libraries bundled with this app.+# Runs a shell command (or interactive shell) using the binaries +# bundled with this app. set -e @@ -11,12 +11,12 @@ exit 1 fi -if [ ! -e "$base/bin/git-annex" ]; then- echo "** base directory $base does not contain bin/git-annex" >&2+if [ ! -e "$base/git-annex" ]; then+ echo "** base directory $base does not contain git-annex" >&2 exit 1 fi-if [ ! -e "$base/bin/git" ]; then- echo "** base directory $base does not contain bin/git" >&2+if [ ! -e "$base/git" ]; then+ echo "** base directory $base does not contain git" >&2 exit 1 fi @@ -43,30 +43,16 @@ # system binaries. ORIG_PATH="$PATH" export ORIG_PATH-PATH=$base/bin:$PATH+PATH=$base:$PATH export PATH -# This makes the linker first look in the library directories bundled-# in this app. Only if it fails to find a library there will a system-# library be used.-# -# This seems to work better than DYLD_LIBRARY_PATH, which can force-# the wrong version of a library to be used, if the app bundles two-# different versions of a single library. And it seems to work better-# than DYLD_FALLBACK_LIBRARY_PATH, which fails to override old system-# versions of libraries when a program in the app needs a newer version.-ORIG_DYLD_ROOT_PATH="$DYLD_ROOT_PATH"-export ORIG_DYLD_ROOT_PATH-DYLD_ROOT_PATH=$base-export DYLD_ROOT_PATH- ORIG_GIT_EXEC_PATH="$GIT_EXEC_PATH" export ORIG_GIT_EXEC_PATH-GIT_EXEC_PATH=$base/git-core+GIT_EXEC_PATH=$base export GIT_EXEC_PATH # Indicate which variables were exported above.-GIT_ANNEX_STANDLONE_ENV="PATH DYLD_ROOT_PATH GIT_EXEC_PATH"+GIT_ANNEX_STANDLONE_ENV="PATH GIT_EXEC_PATH" export GIT_ANNEX_STANDLONE_ENV if [ "$1" ]; then@@ -74,5 +60,5 @@ shift 1 exec "$cmd" "$@" else- $SHELL+ sh fi
+ static/js/bootstrap-collapse.js view
@@ -0,0 +1,138 @@+/* =============================================================+ * bootstrap-collapse.js v2.0.2+ * http://twitter.github.com/bootstrap/javascript.html#collapse+ * =============================================================+ * Copyright 2012 Twitter, Inc.+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ * ============================================================ */++!function( $ ){++ "use strict"++ var Collapse = function ( element, options ) {+ this.$element = $(element)+ this.options = $.extend({}, $.fn.collapse.defaults, options)++ if (this.options["parent"]) {+ this.$parent = $(this.options["parent"])+ }++ this.options.toggle && this.toggle()+ }++ Collapse.prototype = {++ constructor: Collapse++ , dimension: function () {+ var hasWidth = this.$element.hasClass('width')+ return hasWidth ? 'width' : 'height'+ }++ , show: function () {+ var dimension = this.dimension()+ , scroll = $.camelCase(['scroll', dimension].join('-'))+ , actives = this.$parent && this.$parent.find('.in')+ , hasData++ if (actives && actives.length) {+ hasData = actives.data('collapse')+ actives.collapse('hide')+ hasData || actives.data('collapse', null)+ }++ this.$element[dimension](0)+ this.transition('addClass', 'show', 'shown')+ this.$element[dimension](this.$element[0][scroll])++ }++ , hide: function () {+ var dimension = this.dimension()+ this.reset(this.$element[dimension]())+ this.transition('removeClass', 'hide', 'hidden')+ this.$element[dimension](0)+ }++ , reset: function ( size ) {+ var dimension = this.dimension()++ this.$element+ .removeClass('collapse')+ [dimension](size || 'auto')+ [0].offsetWidth++ this.$element[size ? 'addClass' : 'removeClass']('collapse')++ return this+ }++ , transition: function ( method, startEvent, completeEvent ) {+ var that = this+ , complete = function () {+ if (startEvent == 'show') that.reset()+ that.$element.trigger(completeEvent)+ }++ this.$element+ .trigger(startEvent)+ [method]('in')++ $.support.transition && this.$element.hasClass('collapse') ?+ this.$element.one($.support.transition.end, complete) :+ complete()+ }++ , toggle: function () {+ this[this.$element.hasClass('in') ? 'hide' : 'show']()+ }++ }++ /* COLLAPSIBLE PLUGIN DEFINITION+ * ============================== */++ $.fn.collapse = function ( option ) {+ return this.each(function () {+ var $this = $(this)+ , data = $this.data('collapse')+ , options = typeof option == 'object' && option+ if (!data) $this.data('collapse', (data = new Collapse(this, options)))+ if (typeof option == 'string') data[option]()+ })+ }++ $.fn.collapse.defaults = {+ toggle: true+ }++ $.fn.collapse.Constructor = Collapse+++ /* COLLAPSIBLE DATA-API+ * ==================== */++ $(function () {+ $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {+ var $this = $(this), href+ , target = $this.attr('data-target')+ || e.preventDefault()+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7+ , option = $(target).data('collapse') ? 'toggle' : $this.data()+ $(target).collapse(option)+ })+ })++}( window.jQuery );
templates/configurators/addbox.com.hamlet view
@@ -8,8 +8,6 @@ Even a small amount of free storage is useful, as a transfer point # between your repositories. <p>- All data will be encrypted before being sent to Box.com.- <p> <form .form-horizontal enctype=#{enctype}> <fieldset> ^{form}
templates/configurators/addglacier.hamlet view
@@ -6,23 +6,15 @@ offline cloud storage provider. It takes several hours for requested # files to be retrieved from Glacier, making it mostly suitable for # backups and long-term data archival. #- <a href="http://aws.amazon.com/glacier/pricing/">- Pricing details <p> <i .icon-warning-sign></i> By default, only files you place in #- "archive" directories will be archived in Amazon Glacier. #- You will be charged by Amazon for data #- uploaded to Glacier, as well as data downloaded from Glacier, and a #- monthly fee for data storage.- <p>- All data will be encrypted before being sent to Amazon Glacier.+ "archive" directories will be archived in Amazon Glacier. <p>- When you sign up to Amazon Glacier, they provide you with an Access #- Key ID, and a Secret Access Key. You will need to enter both below. #- These access keys will be stored in a file that only you can #- access. #- <a href="https://portal.aws.amazon.com/gp/aws/securityCredentials#id_block">- Look up your access keys+ <i .icon-warning-sign></i> You will be charged by Amazon for data #+ uploaded to Glacier, as well as data downloaded from Glacier, and a #+ monthly fee for data storage. #+ <a href="http://aws.amazon.com/glacier/pricing/">+ Pricing details <p> <form .form-horizontal enctype=#{enctype}> <fieldset>
templates/configurators/addrsync.net.hamlet view
@@ -14,16 +14,8 @@ <div .alert .alert-error> <i .icon-warning-sign></i> #{msg} $of _- <i .icon-warning-sign></i> #- All your data will be synced to the Rsync.net repository, so make #- sure it has enough available space. Your data will be encrypted before #- it is sent to Rsync.net.- <p>- When you sign up for a Rsync.net account, you receive an #- email from them with a host name and a username. Fill that #- information in below. You also likely don't want to use your whole #- rsync.net repository for git-annex alone, so git-annex will use a #- subdirectory of it, as configured below.+ <div>+ Your data will be encrypted before it is sent to Rsync.net. <p> <form .form-horizontal enctype=#{enctype}> <fieldset>
templates/configurators/adds3.hamlet view
@@ -4,23 +4,13 @@ <p> <a href="http://aws.amazon.com/s3/">Amazon S3</a> is a cloud storage # provider. If you need a professional level of storage for your data, #- this is a good choice. #- <a href="http://aws.amazon.com/s3/pricing/">- Pricing details, including one year Free Usage Tier promotion+ this is a good choice. <p>- <i .icon-warning-sign></i> Do keep in mind that all your data #- will be synced to Amazon S3. You will be charged by Amazon for data #+ <i .icon-warning-sign></i> You will be charged by Amazon for data # uploaded to S3, as well as data downloaded from S3, and a monthly fee # for data storage. #- <p>- All data will be encrypted before being sent to Amazon S3.- <p>- When you sign up to Amazon S3, they provide you with an Access #- Key ID, and a Secret Access Key. You will need to enter both below. #- These access keys will be stored in a file that only you can #- access. #- <a href="https://portal.aws.amazon.com/gp/aws/securityCredentials#id_block">- Look up your access keys+ <a href="http://aws.amazon.com/s3/pricing/">+ Pricing details, including one year Free Usage Tier promotion <p> <form .form-horizontal enctype=#{enctype}> <fieldset>
templates/configurators/ssh/add.hamlet view
@@ -12,9 +12,6 @@ <div .alert .alert-error> <i .icon-warning-sign></i> #{msg} $of _- <i .icon-warning-sign></i> Do keep in mind that all your data #- will be synced to the server, so make sure it has enough available #- disk space and bandwidth, and that you trust it with your data. <p> <form .form-horizontal enctype=#{enctype}> <fieldset>
+ templates/documentation/repogroup.hamlet view
@@ -0,0 +1,38 @@+<div .span9 .hero-unit>+ <h2>+ Repository groups+ <p>+ Each repository you configure git-annex to use is a member of a #+ repository group. Each group of repositories has a different #+ purpose.+ <p>+ Let's start with the <b>client repositories</b>. These are the #+ repositories that contain files that you can directly use. Generally #+ you'll have one client repository per computer. The whole point of #+ the git-annex assistant is to keep these repositories in sync as you #+ change files, add files, delete files, etc.+ <p>+ The next most important repository group is the #+ <b>transfer repositories</b>. #+ These are used to transfer files between clients, when the clients #+ cannot directly talk to one-another. Transfer repositories only #+ hold the files that need to be synced to other repositories, so they #+ are relatively small.+ <p>+ You can get along without any <b>backup repositories</b>, but they're #+ a useful safeguard. These repositories accumulate every file they can #+ get ahold of. A large removable drive makes a good backup repository.+ <p>+ Next we come to the <b>archive repositories</b>.+ The archive repositories coordinate together, so that each file is #+ archived in only one place. When you move files into a folder named #+ "archive", they'll be moved to an archive repository, and removed from #+ all your client repositories. This is handy if you have old files #+ you don't need anymore, but want to keep archived for later. #+ When you copy or move a file out of an "archive" folder, it'll be #+ retrieved from the archive repository.+ <p>+ Finally, the <b>small archive repositories</b> are like other archive #+ repositories, but smaller. While archive repositories normally accumulate #+ every file they can, small archive repositories only accumulate files #+ once you put them in an "archive" directory.
+ templates/error.cassius view
@@ -0,0 +1,3 @@+body+ padding-top: 60px+ padding-bottom: 40px
+ templates/error.hamlet view
@@ -0,0 +1,23 @@+<div .navbar .navbar-fixed-top>+ <div .navbar-inner>+ <div .container>+ <a .brand>+ git-annex+ <ul .nav>+ <li .active>+ <a href="">+ Error+ <li>+ <a href="" onclick="history.back(-1);return false">+ Go Back+ <li>+ <a href="http://git-annex.branchable.com/bugs/">+ File a Bug+<div .container-fluid>+ <div .row-fluid>+ <div .span3>+ <div .span6>+ <div .alert .alert-error .alert-block>+ ^{content}+ <hr>+ git-annex version #{packageversion}