git-annex 5.20150824 → 5.20150916
raw patch · 108 files changed
+1666/−504 lines, 108 files
Files
- .mailmap +1/−0
- Annex/Init.hs +12/−3
- Annex/SpecialRemote.hs +87/−0
- Assistant/Gpg.hs +3/−3
- Assistant/MakeRemote.hs +6/−6
- Assistant/Upgrade.hs +5/−4
- Assistant/WebApp/Configurators/Edit.hs +2/−1
- Assistant/WebApp/Configurators/Local.hs +3/−1
- Assistant/WebApp/Configurators/Ssh.hs +5/−2
- Assistant/WebApp/Gpg.hs +5/−3
- Build/BundledPrograms.hs +8/−6
- Build/EvilLinker.hs +1/−7
- Build/NullSoftInstaller.hs +46/−52
- Build/Version.hs +0/−1
- CHANGELOG +35/−0
- CmdLine.hs +20/−9
- CmdLine/GitAnnex/Options.hs +24/−1
- Command/Drop.hs +1/−0
- Command/EnableRemote.hs +4/−5
- Command/Fsck.hs +1/−0
- Command/Info.hs +1/−3
- Command/Init.hs +2/−0
- Command/InitRemote.hs +2/−48
- Command/Reinit.hs +2/−0
- Command/Sync.hs +55/−44
- Command/Unused.hs +1/−1
- Creds.hs +5/−2
- Crypto.hs +30/−30
- Database/Fsck.hs +5/−0
- Git/Hook.hs +1/−1
- INSTALL +1/−0
- Logs/PreferredContent.hs +3/−2
- Makefile +2/−2
- Messages.hs +7/−3
- Remote/GCrypt.hs +3/−1
- Remote/Git.hs +25/−16
- Remote/Helper/Encryptable.hs +11/−8
- Remote/Helper/Special.hs +9/−5
- Test.hs +70/−35
- Types/GitConfig.hs +8/−5
- Utility/Exception.hs +1/−4
- Utility/Gpg.hs +48/−42
- Utility/Matcher.hs +9/−0
- Utility/Misc.hs +1/−1
- Utility/OptParse.hs +1/−0
- Utility/Process.hs +5/−6
- Utility/Scheduled.hs +1/−1
- Utility/WinProcess.hs +15/−2
- Utility/winprocess.c +0/−10
- debian/changelog +35/−0
- doc/Void.mdwn +1/−0
- doc/bugs/--help_should_not_demand_being_in_the_git_repo.mdwn +25/−0
- doc/bugs/Prefered_Content_not_Taken_into_Account.mdwn +364/−0
- doc/bugs/annex.hardlink_no_longer_set_on_init_of_shared_repo.mdwn +27/−0
- doc/bugs/fsck_--incremental-schedule_does_not_work_as_documented.mdwn +73/−0
- doc/bugs/gcrypt_special_remote_fails_on_bare_remote_repos.mdwn +39/−0
- doc/bugs/git-annex_branch_not_being_pushed_after_git-annex_forget.mdwn +30/−0
- doc/bugs/git-annex_can__39__t_find_gpg_if_it__39__s_named_gpg2.mdwn +21/−0
- doc/bugs/git_annex_info_is_reporting_file_as_not_annexed_in_direct_mode.mdwn +38/−0
- doc/bugs/hPutChar_error_message_with_UTF-8_chars_above_7F_in_filenames.mdwn +2/−0
- doc/bugs/wget_invocation_should_get_timeout_options.mdwn +14/−0
- doc/bugs/windows_ssh_webapp_password_entry_broken.mdwn +4/−0
- doc/builds.mdwn +2/−0
- doc/design/external_special_remote_protocol.mdwn +1/−1
- doc/design/metadata.mdwn +1/−1
- doc/devblog/day_315__scrambling.mdwn +5/−0
- doc/devblog/day_316-318__chasing_dependencies_and_todos.mdwn +24/−0
- doc/encryption/comment_3_46e64e4856975706e06e2a012a5d8f67._comment +8/−0
- doc/forum/Add_file_to_git_index_while_in_direct_mode.mdwn +20/−0
- doc/forum/Backend_migration_and_special_remotes.mdwn +22/−0
- doc/forum/Central_server_with_automatically_merged_working_tree.mdwn +30/−0
- doc/forum/How_to_define_a_balanced_prefered_content.mdwn +5/−0
- doc/forum/Layout_mismatch_between_symlinks_and_annex_objects.mdwn +14/−0
- doc/forum/Multiple_machine_remotes_on_external_drive.mdwn +7/−0
- doc/forum/git-annex_does_not_respect_preferred_content_settings.mdwn +18/−0
- doc/forum/removing_remote.log_information_completely.mdwn +9/−0
- doc/forum/test_whether_a_file_is_already_annexed.mdwn +1/−0
- doc/git-annex-enableremote.mdwn +11/−5
- doc/git-annex-init.mdwn +8/−0
- doc/git-annex-initremote.mdwn +6/−0
- doc/git-annex-reinit.mdwn +3/−0
- doc/git-annex-sync.mdwn +17/−5
- doc/git-annex.mdwn +3/−3
- doc/install.mdwn +1/−0
- doc/install/Windows.mdwn +5/−3
- doc/install/Windows/comment_1_e5e5c7b75859493a7d94cbf7df746fb9._comment +8/−0
- doc/news/version_5.20150824.mdwn +4/−0
- doc/news/version_5.20150916.mdwn +32/−0
- doc/special_remotes.mdwn +1/−0
- doc/templates/bugtemplate.mdwn +4/−0
- doc/todo/annex.hardlink_should_also_affect_copy_to_origin.mdwn +7/−0
- doc/todo/autoenable__61__true_for_special_remotes.mdwn +20/−0
- doc/todo/enable_a_discussion_forum_or_support_system.mdwn +2/−0
- doc/todo/use_git-mktree_rather_than_index_file.mdwn +29/−0
- doc/todo/windows_support.mdwn +0/−7
- doc/trust.mdwn +6/−3
- doc/users/dave.mdwn +1/−0
- git-annex.cabal +1/−4
- man/git-annex-enableremote.1 +9/−3
- man/git-annex-init.1 +8/−0
- man/git-annex-initremote.1 +6/−0
- man/git-annex-reinit.1 +3/−0
- man/git-annex-sync.1 +15/−6
- man/git-annex.1 +3/−3
- standalone/windows/build-simple.sh +4/−10
- standalone/windows/build.sh +16/−12
- standalone/windows/ssh-keygen.cmd +0/−31
- standalone/windows/ssh.cmd +0/−31
.mailmap view
@@ -24,5 +24,6 @@ Yaroslav Halchenko <debian@onerussian.com> Yaroslav Halchenko <debian@onerussian.com> http://yarikoptic.myopenid.com/ <site-myopenid@web> Yaroslav Halchenko <debian@onerussian.com> https://www.google.com/accounts/o8/id?id=AItOawnx8kHW66N3BqmkVpgtXDlYMvr8TJ5VvfY <Yaroslav@web>+Yaroslav Halchenko <debian@onerussian.com> https://me.yahoo.com/a/EbvxpTI_xP9Aod7Mg4cwGhgjrCrdM5s-#7c0f4 <https://me.yahoo.com/a/EbvxpTI_xP9Aod7Mg4cwGhgjrCrdM5s-#7c0f4@web> Øyvind A. Holm <sunny@sunbase.org> http://sunny256.sunbase.org/ <sunny256@web> Øyvind A. Holm <sunny@sunbase.org> https://sunny256.wordpress.com/ <sunny256@web>
Annex/Init.hs view
@@ -58,12 +58,18 @@ initialize :: Maybe String -> Annex () initialize mdescription = do+ {- Has to come before any commits are made as the shared+ - clone heuristic expects no local objects. -}+ sharedclone <- checkSharedClone+ {- This will make the first commit to git, so ensure git is set up - properly to allow commits when running it. -} ensureCommit $ Annex.Branch.create prepUUID initialize'+ + initSharedClone sharedclone u <- getUUID describeUUID u =<< genDescription mdescription@@ -87,7 +93,6 @@ switchHEADBack ) createInodeSentinalFile- checkSharedClone uninitialize :: Annex () uninitialize = do@@ -198,8 +203,12 @@ maybe noop (`toDirect` f) =<< isAnnexLink f void $ liftIO clean -checkSharedClone :: Annex ()-checkSharedClone = whenM (inRepo Git.Objects.isSharedClone) $ do+checkSharedClone :: Annex Bool+checkSharedClone = inRepo Git.Objects.isSharedClone++initSharedClone :: Bool -> Annex ()+initSharedClone False = return ()+initSharedClone True = do showSideAction "Repository was cloned with --shared; setting annex.hardlink=true and making repository untrusted." u <- getUUID trustSet u UnTrusted
+ Annex/SpecialRemote.hs view
@@ -0,0 +1,87 @@+{- git-annex special remote configuration+ -+ - Copyright 2011-2015 Joey Hess <id@joeyh.name>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Annex.SpecialRemote where++import Common.Annex+import Remote (remoteTypes, remoteMap)+import Types.Remote (RemoteConfig, RemoteConfigKey, typename, setup)+import Logs.Remote+import Logs.Trust+import qualified Git.Config++import qualified Data.Map as M+import Data.Ord++type RemoteName = String++{- See if there's an existing special remote with this name.+ -+ - Prefer remotes that are not dead when a name appears multiple times. -}+findExisting :: RemoteName -> Annex (Maybe (UUID, RemoteConfig))+findExisting name = do+ t <- trustMap+ matches <- sortBy (comparing $ \(u, _c) -> M.lookup u t)+ . findByName name+ <$> Logs.Remote.readRemoteLog+ return $ headMaybe matches++newConfig :: RemoteName -> RemoteConfig+newConfig = M.singleton nameKey++findByName :: RemoteName -> M.Map UUID RemoteConfig -> [(UUID, RemoteConfig)]+findByName n = filter (matching . snd) . M.toList+ where+ matching c = case M.lookup nameKey c of+ Nothing -> False+ Just n'+ | n' == n -> True+ | otherwise -> False++remoteNames :: Annex [RemoteName]+remoteNames = do+ m <- Logs.Remote.readRemoteLog+ return $ mapMaybe (M.lookup nameKey . snd) $ M.toList m++{- find the specified remote type -}+findType :: RemoteConfig -> Either String RemoteType+findType config = maybe unspecified specified $ M.lookup typeKey config+ where+ unspecified = Left "Specify the type of remote with type="+ specified s = case filter (findtype s) remoteTypes of+ [] -> Left $ "Unknown remote type " ++ s+ (t:_) -> Right t+ findtype s i = typename i == s++{- The name of a configured remote is stored in its config using this key. -}+nameKey :: RemoteConfigKey+nameKey = "name"++{- The type of a remote is stored in its config using this key. -}+typeKey :: RemoteConfigKey+typeKey = "type"++autoEnableKey :: RemoteConfigKey+autoEnableKey = "autoenable"++autoEnable :: Annex ()+autoEnable = do+ remotemap <- M.filter configured <$> readRemoteLog+ enabled <- remoteMap id+ forM_ (M.toList remotemap) $ \(u, c) -> unless (u `M.member` enabled) $ do+ case (M.lookup nameKey c, findType c) of+ (Just name, Right t) -> whenM (canenable u) $ do+ showSideAction $ "Auto enabling special remote " ++ name+ res <- tryNonAsync $ setup t (Just u) Nothing c+ case res of+ Left e -> warning (show e)+ Right _ -> return ()+ _ -> return ()+ where+ configured rc = fromMaybe False $+ Git.Config.isTrue =<< M.lookup autoEnableKey rc+ canenable u = (/= DeadTrusted) <$> lookupTrust u
Assistant/Gpg.hs view
@@ -14,9 +14,9 @@ import qualified Data.Map as M {- Generates a gpg user id that is not used by any existing secret key -}-newUserId :: IO UserId-newUserId = do- oldkeys <- secretKeys+newUserId :: GpgCmd -> IO UserId+newUserId cmd = do+ oldkeys <- secretKeys cmd username <- myUserName let basekeyname = username ++ "'s git-annex encryption key" return $ Prelude.head $ filter (\n -> M.null $ M.filter (== n) oldkeys)
Assistant/MakeRemote.hs view
@@ -16,7 +16,7 @@ import qualified Remote.GCrypt as GCrypt import qualified Git import qualified Git.Command-import qualified Command.InitRemote+import qualified Annex.SpecialRemote import Logs.UUID import Logs.Remote import Git.Remote@@ -46,10 +46,10 @@ {- Inits a rsync special remote, and returns its name. -} makeRsyncRemote :: RemoteName -> String -> Annex String makeRsyncRemote name location = makeRemote name location $ const $ void $- go =<< Command.InitRemote.findExisting name+ go =<< Annex.SpecialRemote.findExisting name where go Nothing = setupSpecialRemote name Rsync.remote config Nothing- (Nothing, Command.InitRemote.newConfig name)+ (Nothing, Annex.SpecialRemote.newConfig name) go (Just (u, c)) = setupSpecialRemote name Rsync.remote config Nothing (Just u, c) config = M.fromList@@ -78,16 +78,16 @@ go :: Int -> Annex RemoteName go n = do let fullname = if n == 0 then name else name ++ show n- r <- Command.InitRemote.findExisting fullname+ r <- Annex.SpecialRemote.findExisting fullname case r of Nothing -> setupSpecialRemote fullname remotetype config mcreds- (Nothing, Command.InitRemote.newConfig fullname)+ (Nothing, Annex.SpecialRemote.newConfig fullname) Just _ -> go (n + 1) {- Enables an existing special remote. -} enableSpecialRemote :: SpecialRemoteMaker enableSpecialRemote name remotetype mcreds config = do- r <- Command.InitRemote.findExisting name+ r <- Annex.SpecialRemote.findExisting name case r of Nothing -> error $ "Cannot find a special remote named " ++ name Just (u, c) -> setupSpecialRemote' False name remotetype config mcreds (Just u, c)
Assistant/Upgrade.hs view
@@ -317,12 +317,13 @@ downloadDistributionInfo :: Assistant (Maybe GitAnnexDistribution) downloadDistributionInfo = do uo <- liftAnnex Url.getUrlOptions+ gpgcmd <- liftAnnex $ gpgCmd <$> Annex.getGitConfig liftIO $ withTmpDir "git-annex.tmp" $ \tmpdir -> do let infof = tmpdir </> "info" let sigf = infof ++ ".sig" ifM (Url.downloadQuiet distributionInfoUrl infof uo <&&> Url.downloadQuiet distributionInfoSigUrl sigf uo- <&&> verifyDistributionSig sigf)+ <&&> verifyDistributionSig gpgcmd sigf) ( readish <$> readFileStrict infof , return Nothing )@@ -340,13 +341,13 @@ - The gpg keyring used to verify the signature is located in - trustedkeys.gpg, next to the git-annex program. -}-verifyDistributionSig :: FilePath -> IO Bool-verifyDistributionSig sig = do+verifyDistributionSig :: GpgCmd -> FilePath -> IO Bool+verifyDistributionSig gpgcmd sig = do p <- readProgramFile if isAbsolute p then withUmask 0o0077 $ withTmpDir "git-annex-gpg.tmp" $ \gpgtmp -> do let trustedkeys = takeDirectory p </> "trustedkeys.gpg"- boolSystem gpgcmd+ boolGpgCmd gpgcmd [ Param "--no-default-keyring" , Param "--no-auto-check-trustdb" , Param "--no-options"
Assistant/WebApp/Configurators/Edit.hs view
@@ -260,7 +260,8 @@ (Just (SharedCipher _)) -> [whamlet|encrypted: encryption key stored in git repository|] (Just (EncryptedCipher _ _ (KeyIds { keyIds = ks }))) -> do- knownkeys <- liftIO secretKeys+ cmd <- liftAnnex $ gpgCmd <$> Annex.getGitConfig+ knownkeys <- liftIO (secretKeys cmd) [whamlet| encrypted using gpg key: <ul style="list-style: none">
Assistant/WebApp/Configurators/Local.hs view
@@ -16,6 +16,7 @@ import Assistant.Sync import Assistant.Restart import Annex.MakeRepo+import qualified Annex import qualified Git import qualified Git.Config import qualified Git.Command@@ -269,8 +270,9 @@ where dir = removableDriveRepository drive newrepo = do+ cmd <- liftAnnex $ gpgCmd <$> Annex.getGitConfig secretkeys <- sortBy (comparing snd) . M.toList- <$> liftIO secretKeys+ <$> liftIO (secretKeys cmd) page "Encrypt repository?" (Just Configuration) $ $(widgetFile "configurators/adddrive/encrypt") knownrepo = getFinishAddDriveR drive NoRepoKey
Assistant/WebApp/Configurators/Ssh.hs view
@@ -23,6 +23,7 @@ import Types.Remote (RemoteConfig) import Git.Types (RemoteName, fromRef) import qualified Remote.GCrypt as GCrypt+import qualified Annex import qualified Git.Construct import qualified Git.Config import qualified Git.Command@@ -422,8 +423,9 @@ | otherwise = handleexisting =<< (M.lookup u <$> liftAnnex uuidMap) where handlenew = sshConfigurator $ do+ cmd <- liftAnnex $ gpgCmd <$> Annex.getGitConfig secretkeys <- sortBy (comparing snd) . M.toList- <$> liftIO secretKeys+ <$> liftIO (secretKeys cmd) $(widgetFile "configurators/ssh/confirm") handleexisting Nothing = sshConfigurator $ -- Not a UUID we know, so prompt about combining.@@ -608,8 +610,9 @@ prepRsyncNet sshinput reponame $ \sshdata -> inpage $ checkExistingGCrypt sshdata $ do+ cmd <- liftAnnex $ gpgCmd <$> Annex.getGitConfig secretkeys <- sortBy (comparing snd) . M.toList- <$> liftIO secretKeys+ <$> liftIO (secretKeys cmd) $(widgetFile "configurators/rsync.net/encrypt") getMakeRsyncNetSharedR :: SshData -> Handler Html
Assistant/WebApp/Gpg.hs view
@@ -12,6 +12,7 @@ import Assistant.WebApp.Common import Assistant.Gpg import Utility.Gpg+import qualified Annex import qualified Git.Command import qualified Git.Remote.Remove import qualified Git.Construct@@ -50,9 +51,10 @@ withNewSecretKey :: (KeyId -> Handler Html) -> Handler Html withNewSecretKey use = do- userid <- liftIO newUserId- liftIO $ genSecretKey RSA "" userid maxRecommendedKeySize- results <- M.keys . M.filter (== userid) <$> liftIO secretKeys+ cmd <- liftAnnex $ gpgCmd <$> Annex.getGitConfig+ userid <- liftIO $ newUserId cmd+ liftIO $ genSecretKey cmd RSA "" userid maxRecommendedKeySize+ results <- M.keys . M.filter (== userid) <$> liftIO (secretKeys cmd) case results of [] -> error "Failed to generate gpg key!" (key:_) -> use key
Build/BundledPrograms.hs view
@@ -20,7 +20,7 @@ bundledPrograms = catMaybes [ Nothing #ifndef mingw32_HOST_OS- -- git is not included in the windows bundle; msysgit is used+ -- git is not included in the windows bundle; git for windows is used , Just "git" -- Not strictly needed in PATH by git-annex, but called -- by git when it sshes to a remote.@@ -28,7 +28,6 @@ , Just "git-receive-pack" , Just "git-shell" #endif- , Just "cp" #ifndef mingw32_HOST_OS -- using xargs on windows led to problems, so it's not used there , Just "xargs"@@ -38,7 +37,7 @@ #ifndef mingw32_HOST_OS -- OS X has ssh installed by default. -- Linux probably has ssh, but not guaranteed.- -- On Windows, msysgit provides ssh.+ -- On Windows, git provides ssh. , Just "ssh" , Just "ssh-keygen" #endif@@ -46,22 +45,25 @@ #ifndef mingw32_HOST_OS , Just "sh" #endif- , SysConfig.gpg- , ifset SysConfig.curl "curl" #ifndef darwin_HOST_OS -- wget on OSX has been problimatic, looking for certs in the wrong -- places. Don't ship it, use curl or the OSX's own wget if it has -- one. , ifset SysConfig.wget "wget" #endif- , ifset SysConfig.bup "bup" , SysConfig.lsof , SysConfig.gcrypt+#ifndef mingw32_HOST_OS+ -- All these utilities are included in git for Windows+ , ifset SysConfig.curl "curl"+ , SysConfig.gpg , SysConfig.sha1 , SysConfig.sha256 , SysConfig.sha512 , SysConfig.sha224 , SysConfig.sha384+ , Just "cp"+#endif #ifdef linux_HOST_OS -- used to unpack the tarball when upgrading , Just "gunzip"
Build/EvilLinker.hs view
@@ -95,18 +95,12 @@ path <- manyTill anyChar (try $ string ldcmd) void $ char ' ' params <- restOfLine- return $ CmdParams (path ++ ldcmd) (skipHack $ escapeDosPaths params) Nothing+ return $ CmdParams (path ++ ldcmd) (escapeDosPaths params) Nothing where ldcmd = "ld.exe" versionline = do void $ string "collect2 version" restOfLine--{- For unknown reasons, asking the linker to link this in fails,- - with error about multiple definitions of a symbol from the library.- - This is a horrible hack. -}-skipHack :: String -> String-skipHack = replace "dist/build/git-annex/git-annex-tmp/Utility/winprocess.o" "" {- Input contains something like - c:/program files/haskell platform/foo -LC:/Program Files/Haskell Platform/ -L...
Build/NullSoftInstaller.hs view
@@ -1,23 +1,24 @@ {- Generates a NullSoft installer program for git-annex on Windows. - - - - To build the installer, git-annex should already be built by cabal, - - and ssh and rsync etc, as well as cygwin libraries, already installed - - from cygwin. - - This uses the Haskell nsis package (cabal install nsis) - to generate a .nsi file, which is then used to produce - git-annex-installer.exe - - The installer includes git-annex, and utilities it uses, with the - - exception of git. The user needs to install git separately, - - and the installer checks for that. + - exception of git and some utilities that are bundled with git. + - The user needs to install git separately, and the installer checks + - for that. + - + - To build the installer, git-annex should already be built by cabal, + - and the necessary utility programs (rsync and wget) already installed + - in PATH from msys32. - - Copyright 2013-2015 Joey Hess <id@joeyh.name> - - Licensed under the GNU GPL version 3 or higher. -} -{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedStrings, FlexibleContexts #-} import Development.NSIS import System.Directory @@ -34,6 +35,7 @@ import Utility.CopyFile import Utility.SafeCommand import Utility.Process +import Utility.Exception import Build.BundledPrograms main = do @@ -42,19 +44,14 @@ mustSucceed "ln" [File "dist/build/git-annex/git-annex.exe", File gitannex] let license = tmpdir </> licensefile mustSucceed "sh" [Param "-c", Param $ "zcat standalone/licences.gz > '" ++ license ++ "'"] - extrabins <- forM (cygwinPrograms) $ \f -> do - p <- searchPath f - when (isNothing p) $ - print ("unable to find in PATH", f) - return p - dlls <- forM (catMaybes extrabins) findCygLibs - dllpaths <- mapM searchPath (nub (concat dlls)) - webappscript <- vbsLauncher tmpdir "git-annex-webapp" "git-annex webapp" + webappscript <- vbsLauncher tmpdir "git-annex-webapp" "git annex webapp" autostartscript <- vbsLauncher tmpdir "git-annex-autostart" "git annex assistant --autostart" let htmlhelp = tmpdir </> "git-annex.html" writeFile htmlhelp htmlHelpText - writeFile nsifile $ makeInstaller gitannex license htmlhelp - (wrappers ++ catMaybes (extrabins ++ dllpaths)) + let gitannexcmd = tmpdir </> "git-annex.cmd" + writeFile gitannexcmd "git annex %*" + writeFile nsifile $ makeInstaller + gitannex gitannexcmd license htmlhelp winPrograms [ webappscript, autostartscript ] mustSucceed "makensis" [File nsifile] removeFile nsifile -- left behind if makensis fails @@ -67,12 +64,13 @@ False -> error $ cmd ++ " failed" {- Generates a .vbs launcher which runs a command without any visible DOS - - box. -} + - box. It expects to be passed the directory where git-annex is installed. -} vbsLauncher :: FilePath -> String -> String -> IO String vbsLauncher tmpdir basename cmd = do let f = tmpdir </> basename ++ ".vbs" writeFile f $ unlines [ "Set objshell=CreateObject(\"Wscript.Shell\")" + , "objShell.CurrentDirectory = Wscript.Arguments.item(0)" , "objShell.Run(\"" ++ cmd ++ "\"), 0, False" ] return f @@ -113,8 +111,8 @@ , fromString "You can install git from http:////git-scm.com//" ] -makeInstaller :: FilePath -> FilePath -> FilePath -> [FilePath] -> [FilePath] -> String -makeInstaller gitannex license htmlhelp extrabins launchers = nsis $ do +makeInstaller :: FilePath -> FilePath -> FilePath -> FilePath -> [FilePath] -> [FilePath] -> String +makeInstaller gitannex gitannexcmd license htmlhelp extrabins launchers = nsis $ do name "git-annex" outFile $ str installer {- Installing into the same directory as git avoids needing to modify @@ -134,50 +132,61 @@ Development.NSIS.createDirectory "$SMPROGRAMS" createShortcut startMenuItem [ Target "wscript.exe" - , Parameters "\"$INSTDIR/git-annex-webapp.vbs\"" + , Parameters "\"$INSTDIR/cmd/git-annex-webapp.vbs\" \"$INSTDIR/cmd\"" , StartOptions "SW_SHOWNORMAL" - , IconFile "$INSTDIR/cmd/git-annex.exe" + , IconFile "$INSTDIR/usr/bin/git-annex.exe" , IconIndex 2 , Description "Git Annex (Webapp)" ] delete [RebootOK] $ oldStartMenuItem createShortcut autoStartItem [ Target "wscript.exe" - , Parameters "\"$INSTDIR/git-annex-autostart.vbs\"" + , Parameters "\"$INSTDIR/cmd/git-annex-autostart.vbs\" \"$INSTDIR/cmd\"" , StartOptions "SW_SHOWNORMAL" - , IconFile "$INSTDIR/cmd/git-annex.exe" + , IconFile "$INSTDIR/usr/bin/git-annex.exe" , IconIndex 2 , Description "git-annex autostart" ] section "cmd" [] $ do - setOutPath "$INSTDIR\\cmd" + -- Remove old files no longer installed in the cmd + -- directory. + removefilesFrom "$INSTDIR/cmd" (gitannex:extrabins) + -- Install everything to the same location git puts its + -- bins. This makes "git annex" work in the git bash + -- shell, since git expects to find the git-annex binary + -- there. + setOutPath "$INSTDIR\\usr\\bin" mapM_ addfile (gitannex:extrabins) + -- This little wrapper is installed in the cmd directory, + -- so that "git-annex" works (as well as "git annex"), + -- when only that directory is in PATH (ie, in a ms-dos + -- prompt window). + setOutPath "$INSTDIR\\cmd" + addfile gitannexcmd section "meta" [] $ do - setOutPath "$INSTDIR\\doc\\git\\html" + -- git opens this file when git annex --help is run. + -- (Program Files/Git/mingw32/share/doc/git-doc/git-annex.html) + setOutPath "$INSTDIR\\mingw32\\share\\doc\\git-doc" addfile htmlhelp setOutPath "$INSTDIR" addfile license + setOutPath "$INSTDIR\\cmd" mapM_ addfile launchers writeUninstaller $ str uninstaller uninstall $ do delete [RebootOK] $ startMenuItem delete [RebootOK] $ autoStartItem - removefilesFrom "$INSTDIR/cmd" (gitannex:extrabins) - removefilesFrom "$INSTDIR\\doc\\git\\html" [htmlhelp] - removefilesFrom "$INSTDIR" $ - launchers ++ - [ license - , uninstaller - ] + removefilesFrom "$INSTDIR/usr/bin" (gitannex:extrabins) + removefilesFrom "$INSTDIR/cmd" (gitannexcmd:launchers) + removefilesFrom "$INSTDIR\\mingw32\\share\\doc\\git-doc" [htmlhelp] + removefilesFrom "$INSTDIR" [license, uninstaller] where addfile f = file [] (str f) removefilesFrom d = mapM_ (\f -> delete [RebootOK] $ fromString $ d ++ "/" ++ takeFileName f) -cygwinPrograms :: [FilePath] -cygwinPrograms = map (\p -> p ++ ".exe") bundledPrograms +winPrograms :: [FilePath] +winPrograms = map (\p -> p ++ ".exe") bundledPrograms --- msysgit opens Program Files/Git/doc/git/html/git-annex.html --- when git annex --help is run. htmlHelpText :: String htmlHelpText = unlines [ "<html>" @@ -187,19 +196,4 @@ , "<a href=\"https://git-annex.branchable.com/git-annex/\">read the man page</a>." , "</body>" , "</html" - ] - --- Find cygwin libraries used by the specified executable. -findCygLibs :: FilePath -> IO [FilePath] -findCygLibs p = filter iscyg . mapMaybe parse . lines <$> readProcess "ldd" [p] - where - parse l = case words (dropWhile isSpace l) of - (dll:"=>":_dllpath:_offset:[]) -> Just dll - _ -> Nothing - iscyg f = "cyg" `isPrefixOf` f || "lib" `isPrefixOf` f - -wrappers :: [FilePath] -wrappers = - [ "standalone\\windows\\ssh.cmd" - , "standalone\\windows\\ssh-keygen.cmd" ]
Build/Version.hs view
@@ -4,7 +4,6 @@ module Build.Version where -import Data.Maybe import Control.Applicative import Data.List import System.Environment
CHANGELOG view
@@ -1,3 +1,38 @@+git-annex (5.20150916) unstable; urgency=medium++ * Fix Windows build to work with ghc 7.10.+ * init: Fix reversion in detection of repo made with git clone --shared+ * info: Support querying info of individual files in direct mode.+ * unused: Fix reversion in 5.20150727 that broke parsing of the+ --unused-refspec option. Thanks, Øyvind A. Holm.+ * Make full option parsing be done when not in a git repo, so --help+ can be displayed for commands that require a git repo, etc.+ * fsck: Work around bug in persistent that broke display of+ problematically encoded filenames on stderr when using --incremental.+ * When gpg.program is configured, it's used to get the command to run+ for gpg. Useful on systems that have only a gpg2 command or want to+ use it instead of the gpg command.+ * Windows: Switched to using git for Windows, rather than msysgit.+ Using msysgit with git-annex is no longer supported.+ * Windows: Even when the user neglects to tell the git installer to+ add git to PATH, git-annex will still work from within the git bash+ shell, and the webapp can be used too.+ * sync: Add --no-commit, --no-pull, --no-push options to turn off parts of+ the sync process, as well as supporting --commit, --pull, --push, and+ --no-content options to specify the (current) default behavior.+ * annex.hardlink extended to also try to use hard links when copying from+ the repository to a remote.+ * Improve bash completion, so it completes names of remotes and backends+ in appropriate places.+ * Special remotes configured with autoenable=true will be automatically+ enabled when git-annex init is run.+ * Fix bug in combination of preferred and required content settings.+ When one was set to the empty string and the other set to some expression,+ this bug caused all files to be wanted, instead of only files matching+ the expression.++ -- Joey Hess <id@joeyh.name> Wed, 16 Sep 2015 10:31:24 -0400+ git-annex (5.20150824) unstable; urgency=medium * Sped up downloads of files from ssh remotes, reducing the
CmdLine.hs view
@@ -36,8 +36,9 @@ Annex.eval state $ do checkEnvironment forM_ fields $ uncurry Annex.setField- (cmd, seek, globalconfig) <- parsewith cmdparser+ (cmd, seek, globalconfig) <- parsewith False cmdparser (\a -> inRepo $ a . Just)+ (liftIO . O.handleParseResult) when (cmdnomessages cmd) $ Annex.setOutput QuietOutput getParsed globalconfig@@ -47,20 +48,30 @@ performCommandAction cmd seek $ shutdown $ cmdnocommit cmd go (Left norepo) = do- (_, a, _globalconfig) <- parsewith- (fromMaybe (throw norepo) . cmdnorepo)- (\a -> a =<< Git.Config.global)- a+ let ingitrepo = \a -> a =<< Git.Config.global+ -- Parse command line with full cmdparser first,+ -- so that help can be displayed for bad parses+ -- even when not run in a repo.+ res <- parsewith False cmdparser ingitrepo return+ case res of+ Failure _ -> void (O.handleParseResult res)+ _ -> do+ -- Parse command line in norepo mode.+ (_, a, _globalconfig) <- parsewith True+ (fromMaybe (throw norepo) . cmdnorepo)+ ingitrepo+ O.handleParseResult+ a - parsewith getparser ingitrepo = + parsewith secondrun getparser ingitrepo handleresult = case parseCmd progname progdesc globaloptions allargs allcmds getparser of O.Failure _ -> do -- parse failed, so fall back to -- fuzzy matching, or to showing usage- when fuzzy $+ when (fuzzy && not secondrun) $ ingitrepo autocorrect- liftIO (O.handleParseResult (parseCmd progname progdesc globaloptions correctedargs allcmds getparser))- res -> liftIO (O.handleParseResult res)+ handleresult (parseCmd progname progdesc globaloptions correctedargs allcmds getparser)+ res -> handleresult res where autocorrect = Git.AutoCorrect.prepare (fromJust inputcmdname) cmdname cmds (fuzzy, cmds, inputcmdname, args) = findCmd fuzzyok allargs allcmds
CmdLine/GitAnnex/Options.hs view
@@ -8,9 +8,11 @@ module CmdLine.GitAnnex.Options where import Options.Applicative+import Options.Applicative.Builder.Internal import Common.Annex import qualified Git.Config+import qualified Git.Construct import Git.Types import Types.TrustLevel import Types.NumCopies@@ -26,6 +28,8 @@ import CmdLine.Option import CmdLine.Usage import CmdLine.GlobalSetter+import qualified Backend+import qualified Types.Backend as Backend -- Global options that are accepted by all git-annex sub-commands, -- although not always used.@@ -40,16 +44,19 @@ ( long "trust" <> metavar paramRemote <> help "override trust setting" <> hidden+ <> completeRemotes ) , globalSetter (Remote.forceTrust SemiTrusted) $ strOption ( long "semitrust" <> metavar paramRemote <> help "override trust setting back to default" <> hidden+ <> completeRemotes ) , globalSetter (Remote.forceTrust UnTrusted) $ strOption ( long "untrust" <> metavar paramRemote <> help "override trust setting to untrusted" <> hidden+ <> completeRemotes ) , globalSetter setgitconfig $ strOption ( long "config" <> short 'c' <> metavar "NAME=VALUE"@@ -98,7 +105,9 @@ ) parseRemoteOption :: Parser RemoteName -> Parser (DeferredParse Remote)-parseRemoteOption p = DeferredParse . (fromJust <$$> Remote.byNameWithUUID) . Just <$> p+parseRemoteOption p = DeferredParse + . (fromJust <$$> Remote.byNameWithUUID)+ . Just <$> p data FromToOptions = FromRemote (DeferredParse Remote)@@ -117,12 +126,14 @@ parseFromOption = parseRemoteOption $ strOption ( long "from" <> short 'f' <> metavar paramRemote <> help "source remote"+ <> completeRemotes ) parseToOption :: Parser (DeferredParse Remote) parseToOption = parseRemoteOption $ strOption ( long "to" <> short 't' <> metavar paramRemote <> help "destination remote"+ <> completeRemotes ) -- Options for acting on keys, rather than work tree files.@@ -179,6 +190,7 @@ ( long "in" <> short 'i' <> metavar paramRemote <> help "match files present in a remote" <> hidden+ <> completeRemotes ) , globalSetter Limit.addCopies $ strOption ( long "copies" <> short 'C' <> metavar paramRemote@@ -199,6 +211,7 @@ ( long "inbackend" <> short 'B' <> metavar paramName <> help "match files using a key-value backend" <> hidden+ <> completeBackends ) , globalSetter Limit.addInAllGroup $ strOption ( long "inallgroup" <> metavar paramGroup@@ -299,3 +312,13 @@ ( long "stop" <> help "stop daemon" )+completeRemotes :: HasCompleter f => Mod f a+completeRemotes = completer $ mkCompleter $ \input -> do+ r <- maybe (pure Nothing) (Just <$$> Git.Config.read)+ =<< Git.Construct.fromCwd+ return $ filter (input `isPrefixOf`) + (maybe [] (mapMaybe remoteName . remotes) r)+ + +completeBackends :: HasCompleter f => Mod f a+completeBackends = completeWith (map Backend.name Backend.list)
Command/Drop.hs view
@@ -46,6 +46,7 @@ parseDropFromOption = parseRemoteOption $ strOption ( long "from" <> short 'f' <> metavar paramRemote <> help "drop content from a remote"+ <> completeRemotes ) seek :: DropOptions -> CommandSeek
Command/EnableRemote.hs view
@@ -11,7 +11,7 @@ import Command import qualified Logs.Remote import qualified Types.Remote as R-import qualified Command.InitRemote as InitRemote+import qualified Annex.SpecialRemote import qualified Data.Map as M @@ -26,21 +26,20 @@ start :: [String] -> CommandStart start [] = unknownNameError "Specify the name of the special remote to enable."-start (name:ws) = go =<< InitRemote.findExisting name+start (name:ws) = go =<< Annex.SpecialRemote.findExisting name where config = Logs.Remote.keyValToConfig ws go Nothing = unknownNameError "Unknown special remote name." go (Just (u, c)) = do let fullconfig = config `M.union` c - t <- InitRemote.findType fullconfig-+ t <- either error return (Annex.SpecialRemote.findType fullconfig) showStart "enableremote" name next $ perform t u fullconfig unknownNameError :: String -> Annex a unknownNameError prefix = do- names <- InitRemote.remoteNames+ names <- Annex.SpecialRemote.remoteNames error $ prefix ++ "\n" ++ if null names then "(No special remotes are currently known; perhaps use initremote instead?)"
Command/Fsck.hs view
@@ -67,6 +67,7 @@ <*> optional (parseRemoteOption $ strOption ( long "from" <> short 'f' <> metavar paramRemote <> help "check remote"+ <> completeRemotes )) <*> optional parseincremental <*> optional (parseKeyOptions False)
Command/Info.hs view
@@ -24,7 +24,6 @@ import Utility.DataUnits import Utility.DiskFree import Annex.Content-import Annex.Link import Types.Key import Logs.UUID import Logs.Trust@@ -127,8 +126,7 @@ v' <- Remote.nameToUUID' p case v' of Right u -> uuidInfo o u- Left _ -> maybe noinfo (fileInfo o p)- =<< isAnnexLink p+ Left _ -> ifAnnexed p (fileInfo o p) noinfo ) where isdir = liftIO . catchBoolIO . (isDirectory <$$> getFileStatus)
Command/Init.hs view
@@ -10,6 +10,7 @@ import Common.Annex import Command import Annex.Init+import qualified Annex.SpecialRemote cmd :: Command cmd = dontCheck repoExists $@@ -29,4 +30,5 @@ perform :: String -> CommandPerform perform description = do initialize $ if null description then Nothing else Just description+ Annex.SpecialRemote.autoEnable next $ return True
Command/InitRemote.hs view
@@ -10,15 +10,13 @@ import qualified Data.Map as M import Common.Annex+import Annex.SpecialRemote import Command import qualified Remote import qualified Logs.Remote import qualified Types.Remote as R import Logs.UUID-import Logs.Trust -import Data.Ord- cmd :: Command cmd = command "initremote" SectionSetup "creates a special (non-git) remote"@@ -38,7 +36,7 @@ ( error $ "There is already a remote named \"" ++ name ++ "\"" , do let c = newConfig name- t <- findType config+ t <- either error return (findType config) showStart "initremote" name next $ perform t name $ M.union config c@@ -57,47 +55,3 @@ describeUUID u name Logs.Remote.configSet u c return True--{- See if there's an existing special remote with this name. -}-findExisting :: String -> Annex (Maybe (UUID, R.RemoteConfig))-findExisting name = do- t <- trustMap- matches <- sortBy (comparing $ \(u, _c) -> M.lookup u t )- . findByName name- <$> Logs.Remote.readRemoteLog- return $ headMaybe matches--newConfig :: String -> R.RemoteConfig-newConfig = M.singleton nameKey--findByName :: String -> M.Map UUID R.RemoteConfig -> [(UUID, R.RemoteConfig)]-findByName n = filter (matching . snd) . M.toList- where- matching c = case M.lookup nameKey c of- Nothing -> False- Just n'- | n' == n -> True- | otherwise -> False--remoteNames :: Annex [String]-remoteNames = do- m <- Logs.Remote.readRemoteLog- return $ mapMaybe (M.lookup nameKey . snd) $ M.toList m--{- find the specified remote type -}-findType :: R.RemoteConfig -> Annex RemoteType-findType config = maybe unspecified specified $ M.lookup typeKey config- where- unspecified = error "Specify the type of remote with type="- specified s = case filter (findtype s) Remote.remoteTypes of- [] -> error $ "Unknown remote type " ++ s- (t:_) -> return t- findtype s i = R.typename i == s--{- The name of a configured remote is stored in its config using this key. -}-nameKey :: String-nameKey = "name"--{- The type of a remote is stored in its config using this key. -}-typeKey :: String-typeKey = "type"
Command/Reinit.hs view
@@ -13,6 +13,7 @@ import Annex.UUID import Types.UUID import qualified Remote+import qualified Annex.SpecialRemote cmd :: Command cmd = dontCheck repoExists $@@ -38,4 +39,5 @@ else Remote.nameToUUID s storeUUID u initialize'+ Annex.SpecialRemote.autoEnable next $ return True
Command/Sync.hs view
@@ -60,21 +60,36 @@ data SyncOptions = SyncOptions { syncWith :: CmdParams- , contentOption :: Bool+ , commitOption :: Bool , messageOption :: Maybe String+ , pullOption :: Bool+ , pushOption :: Bool+ , contentOption :: Bool , keyOptions :: Maybe KeyOptions } optParser :: CmdParamsDesc -> Parser SyncOptions optParser desc = SyncOptions- <$> cmdParams desc- <*> invertableSwitch "content" False- ( help "also transfer file contents" + <$> (many $ argument str+ ( metavar desc+ <> completeRemotes+ ))+ <*> invertableSwitch "commit" True+ ( help "avoid git commit" ) <*> optional (strOption ( long "message" <> short 'm' <> metavar "MSG" <> help "commit message" ))+ <*> invertableSwitch "pull" True+ ( help "avoid git pulls from remotes" + )+ <*> invertableSwitch "push" True+ ( help "avoid git pushes to remotes" + )+ <*> invertableSwitch "content" False+ ( help "also transfer file contents" + ) <*> optional parseAllOption seek :: SyncOptions -> CommandSeek@@ -107,7 +122,7 @@ mapM_ includeCommandAction $ concat [ [ commit o ] , [ withbranch mergeLocal ]- , map (withbranch . pullRemote) gitremotes+ , map (withbranch . pullRemote o) gitremotes , [ mergeAnnex ] ] when (contentOption o) $@@ -118,13 +133,13 @@ -- and merge again to avoid our push overwriting -- those changes. mapM_ includeCommandAction $ concat- [ map (withbranch . pullRemote) gitremotes+ [ map (withbranch . pullRemote o) gitremotes , [ commitAnnex, mergeAnnex ] ] void $ includeCommandAction $ withbranch pushLocal -- Pushes to remotes can run concurrently.- mapM_ (commandAction . withbranch . pushRemote) gitremotes+ mapM_ (commandAction . withbranch . pushRemote o) gitremotes {- Merging may delete the current directory, so go to the top - of the repo. This also means that sync always acts on all files in the@@ -165,28 +180,26 @@ fastest = fromMaybe [] . headMaybe . Remote.byCost commit :: SyncOptions -> CommandStart-commit o = ifM (annexAutoCommit <$> Annex.getGitConfig)- ( go- , stop- )+commit o = stopUnless shouldcommit $ next $ next $ do+ commitmessage <- maybe commitMsg return (messageOption o)+ showStart "commit" ""+ Annex.Branch.commit "update"+ ifM isDirect+ ( do+ void stageDirect+ void preCommitDirect+ commitStaged Git.Branch.ManualCommit commitmessage+ , do+ inRepo $ Git.Branch.commitQuiet Git.Branch.ManualCommit+ [ Param "-a"+ , Param "-m"+ , Param commitmessage+ ]+ return True+ ) where- go = next $ next $ do- commitmessage <- maybe commitMsg return (messageOption o)- showStart "commit" ""- Annex.Branch.commit "update"- ifM isDirect- ( do- void stageDirect- void preCommitDirect- commitStaged Git.Branch.ManualCommit commitmessage- , do- inRepo $ Git.Branch.commitQuiet Git.Branch.ManualCommit- [ Param "-a"- , Param "-m"- , Param commitmessage- ]- return True- )+ shouldcommit = pure (commitOption o)+ <&&> (annexAutoCommit <$> Annex.getGitConfig) commitMsg :: Annex String commitMsg = do@@ -248,8 +261,8 @@ , Param $ Git.fromRef $ Git.Ref.base syncbranch ] g -pullRemote :: Remote -> Maybe Git.Ref -> CommandStart-pullRemote remote branch = do+pullRemote :: SyncOptions -> Remote -> Maybe Git.Ref -> CommandStart+pullRemote o remote branch = stopUnless (pure $ pullOption o) $ do showStart "pull" (Remote.name remote) next $ do showOutput@@ -282,24 +295,22 @@ branchlist Nothing = [] branchlist (Just branch) = [branch, syncBranch branch] -pushRemote :: Remote -> Maybe Git.Ref -> CommandStart-pushRemote _remote Nothing = stop-pushRemote remote (Just branch) = go =<< needpush+pushRemote :: SyncOptions -> Remote -> Maybe Git.Ref -> CommandStart+pushRemote _o _remote Nothing = stop+pushRemote o remote (Just branch) = stopUnless (pure (pushOption o) <&&> needpush) $ do+ showStart "push" (Remote.name remote)+ next $ next $ do+ showOutput+ ok <- inRepoWithSshOptionsTo (Remote.repo remote) (Remote.gitconfig remote) $+ pushBranch remote branch+ unless ok $ do+ warning $ unwords [ "Pushing to " ++ Remote.name remote ++ " failed." ]+ showLongNote "(non-fast-forward problems can be solved by setting receive.denyNonFastforwards to false in the remote's git config)"+ return ok where needpush | remoteAnnexReadOnly (Remote.gitconfig remote) = return False | otherwise = anyM (newer remote) [syncBranch branch, Annex.Branch.name]- go False = stop- go True = do- showStart "push" (Remote.name remote)- next $ next $ do- showOutput- ok <- inRepoWithSshOptionsTo (Remote.repo remote) (Remote.gitconfig remote) $- pushBranch remote branch- unless ok $ do- warning $ unwords [ "Pushing to " ++ Remote.name remote ++ " failed." ]- showLongNote "(non-fast-forward problems can be solved by setting receive.denyNonFastforwards to false in the remote's git config)"- return ok {- Pushes a regular branch like master to a remote. Also pushes the git-annex - branch.
Command/Unused.hs view
@@ -53,7 +53,7 @@ <> help "remote to check for unused content" )) <*> optional (option (eitherReader parseRefSpec)- ( long "unused-refspec" <> metavar paramRefSpec+ ( long "used-refspec" <> metavar paramRefSpec <> help "refs to consider used (default: all branches)" ))
Creds.hs view
@@ -20,6 +20,7 @@ ) where import Common.Annex+import qualified Annex import Types.Creds import Annex.Perms import Utility.FileMode@@ -65,7 +66,8 @@ return c storeconfig key (Just cipher) = do- s <- liftIO $ encrypt (getGpgEncParams c) cipher+ cmd <- gpgCmd <$> Annex.getGitConfig+ s <- liftIO $ encrypt cmd (getGpgEncParams c) cipher (feedBytes $ L.pack $ encodeCredPair creds) (readBytes $ return . L.unpack) return $ M.insert key (toB64 s) c@@ -91,7 +93,8 @@ fromcreds $ fromB64 bcreds Nothing -> return Nothing fromenccreds enccreds cipher storablecipher = do- mcreds <- liftIO $ catchMaybeIO $ decrypt cipher+ cmd <- gpgCmd <$> Annex.getGitConfig+ mcreds <- liftIO $ catchMaybeIO $ decrypt cmd cipher (feedBytes $ L.pack $ fromB64 enccreds) (readBytes $ return . L.unpack) case mcreds of
Crypto.hs view
@@ -74,27 +74,27 @@ cipherMac (MacOnlyCipher c) = c {- Creates a new Cipher, encrypted to the specified key id. -}-genEncryptedCipher :: String -> EncryptedCipherVariant -> Bool -> IO StorableCipher-genEncryptedCipher keyid variant highQuality = do- ks <- Gpg.findPubKeys keyid- random <- Gpg.genRandom highQuality size- encryptCipher (mkCipher random) variant ks+genEncryptedCipher :: Gpg.GpgCmd -> String -> EncryptedCipherVariant -> Bool -> IO StorableCipher+genEncryptedCipher cmd keyid variant highQuality = do+ ks <- Gpg.findPubKeys cmd keyid+ random <- Gpg.genRandom cmd highQuality size+ encryptCipher cmd (mkCipher random) variant ks where (mkCipher, size) = case variant of Hybrid -> (Cipher, cipherSize) -- used for MAC + symmetric PubKey -> (MacOnlyCipher, cipherBeginning) -- only used for MAC {- Creates a new, shared Cipher. -}-genSharedCipher :: Bool -> IO StorableCipher-genSharedCipher highQuality =- SharedCipher <$> Gpg.genRandom highQuality cipherSize+genSharedCipher :: Gpg.GpgCmd -> Bool -> IO StorableCipher+genSharedCipher cmd highQuality =+ SharedCipher <$> Gpg.genRandom cmd highQuality cipherSize {- Updates an existing Cipher, re-encrypting it to add or remove keyids, - depending on whether the first component is True or False. -}-updateEncryptedCipher :: [(Bool, String)] -> StorableCipher -> IO StorableCipher-updateEncryptedCipher _ SharedCipher{} = error "Cannot update shared cipher"-updateEncryptedCipher [] encipher = return encipher-updateEncryptedCipher newkeys encipher@(EncryptedCipher _ variant (KeyIds ks)) = do+updateEncryptedCipher :: Gpg.GpgCmd -> [(Bool, String)] -> StorableCipher -> IO StorableCipher+updateEncryptedCipher _ _ SharedCipher{} = error "Cannot update shared cipher"+updateEncryptedCipher _ [] encipher = return encipher+updateEncryptedCipher cmd newkeys encipher@(EncryptedCipher _ variant (KeyIds ks)) = do dropKeys <- listKeyIds [ k | (False, k) <- newkeys ] forM_ dropKeys $ \k -> unless (k `elem` ks) $ error $ "Key " ++ k ++ " was not present; cannot remove."@@ -102,10 +102,10 @@ let ks' = (addKeys ++ ks) \\ dropKeys when (null ks') $ error "Cannot remove the last key."- cipher <- decryptCipher encipher- encryptCipher cipher variant $ KeyIds ks'+ cipher <- decryptCipher cmd encipher+ encryptCipher cmd cipher variant $ KeyIds ks' where- listKeyIds = concat <$$> mapM (keyIds <$$> Gpg.findPubKeys)+ listKeyIds = concat <$$> mapM (keyIds <$$> Gpg.findPubKeys cmd) describeCipher :: StorableCipher -> String describeCipher (SharedCipher _) = "shared cipher"@@ -119,12 +119,12 @@ keys _ = "keys" {- Encrypts a Cipher to the specified KeyIds. -}-encryptCipher :: Cipher -> EncryptedCipherVariant -> KeyIds -> IO StorableCipher-encryptCipher c variant (KeyIds ks) = do+encryptCipher :: Gpg.GpgCmd -> Cipher -> EncryptedCipherVariant -> KeyIds -> IO StorableCipher+encryptCipher cmd c variant (KeyIds ks) = do -- gpg complains about duplicate recipient keyids let ks' = nub $ sort ks let params = Gpg.pkEncTo ks' ++ Gpg.stdEncryptionParams False- encipher <- Gpg.pipeStrict params cipher+ encipher <- Gpg.pipeStrict cmd params cipher return $ EncryptedCipher encipher variant (KeyIds ks') where cipher = case c of@@ -132,10 +132,10 @@ MacOnlyCipher x -> x {- Decrypting an EncryptedCipher is expensive; the Cipher should be cached. -}-decryptCipher :: StorableCipher -> IO Cipher-decryptCipher (SharedCipher t) = return $ Cipher t-decryptCipher (EncryptedCipher t variant _) =- mkCipher <$> Gpg.pipeStrict [ Param "--decrypt" ] t+decryptCipher :: Gpg.GpgCmd -> StorableCipher -> IO Cipher+decryptCipher _ (SharedCipher t) = return $ Cipher t+decryptCipher cmd (EncryptedCipher t variant _) =+ mkCipher <$> Gpg.pipeStrict cmd [ Param "--decrypt" ] t where mkCipher = case variant of Hybrid -> Cipher@@ -176,19 +176,19 @@ - read by the Reader action. Note: For public-key encryption, - recipients MUST be included in 'params' (for instance using - 'getGpgEncParams'). -}-encrypt :: (MonadIO m, MonadMask m) => [CommandParam] -> Cipher -> Feeder -> Reader m a -> m a-encrypt params cipher = case cipher of- Cipher{} -> Gpg.feedRead (params ++ Gpg.stdEncryptionParams True) $+encrypt :: (MonadIO m, MonadMask m) => Gpg.GpgCmd -> [CommandParam] -> Cipher -> Feeder -> Reader m a -> m a+encrypt cmd params cipher = case cipher of+ Cipher{} -> Gpg.feedRead cmd (params ++ Gpg.stdEncryptionParams True) $ cipherPassphrase cipher- MacOnlyCipher{} -> Gpg.pipeLazy $ params ++ Gpg.stdEncryptionParams False+ MacOnlyCipher{} -> Gpg.pipeLazy cmd $ params ++ Gpg.stdEncryptionParams False {- Runs a Feeder action, that generates content that is decrypted with the - Cipher (or using a private key if the Cipher is empty), and read by the - Reader action. -}-decrypt :: (MonadIO m, MonadMask m) => Cipher -> Feeder -> Reader m a -> m a-decrypt cipher = case cipher of- Cipher{} -> Gpg.feedRead [Param "--decrypt"] $ cipherPassphrase cipher- MacOnlyCipher{} -> Gpg.pipeLazy [Param "--decrypt"]+decrypt :: (MonadIO m, MonadMask m) => Gpg.GpgCmd -> Cipher -> Feeder -> Reader m a -> m a+decrypt cmd cipher = case cipher of+ Cipher{} -> Gpg.feedRead cmd [Param "--decrypt"] $ cipherPassphrase cipher+ MacOnlyCipher{} -> Gpg.pipeLazy cmd [Param "--decrypt"] macWithCipher :: Mac -> Cipher -> String -> String macWithCipher mac c = macWithCipher' mac (cipherMac c)
Database/Fsck.hs view
@@ -31,6 +31,7 @@ import Types.UUID import Annex.Perms import Annex.LockFile+import Messages import Database.Persist.TH import Database.Esqueleto hiding (Key)@@ -77,6 +78,10 @@ rename tmpdbdir dbdir lockFileCached =<< fromRepo (gitAnnexFsckDbLock u) h <- liftIO $ H.openDb db "fscked"++ -- work around https://github.com/yesodweb/persistent/issues/474+ liftIO setConsoleEncoding+ return $ FsckHandle h u closeDb :: FsckHandle -> Annex ()
Git/Hook.hs view
@@ -81,7 +81,7 @@ #ifndef mingw32_HOST_OS findcmd = defcmd #else- {- Like msysgit, parse the first line of the hook file,+ {- Like git for windows, parse the first line of the hook file, - look for "#!", and dispatch the interpreter on the file. -} findcmd f = do l <- headMaybe . lines <$> catchDefaultIO "" (readFile f)
INSTALL view
@@ -13,6 +13,7 @@ [[ArchLinux]] | `yaourt -Sy git-annex-bin` [[NixOS]] | `nix-env -i git-annex` [[Gentoo]] | `emerge git-annex`+ [[Void]] | `xbps-install git-annex` [[ScientificLinux5]] | [[openSUSE]] | [[Docker]] |
Logs/PreferredContent.hs view
@@ -77,8 +77,9 @@ <$> Annex.Branch.get l pc <- genmap preferredContentLog =<< groupPreferredContentMapRaw rc <- genmap requiredContentLog M.empty- -- Required content is implicitly also preferred content, so OR- let m = M.unionWith MOr pc rc+ -- Required content is implicitly also preferred content, so+ -- combine.+ let m = M.unionWith combineMatchers pc rc Annex.changeState $ \s -> s { Annex.preferredcontentmap = Just m , Annex.requiredcontentmap = Just rc
Makefile view
@@ -200,7 +200,7 @@ # Uses https://github.com/neurocyte/ghc-android android: Build/EvilSplicer echo "Running native build, to get TH splices.."- if [ ! -e dist/setup/setup ]; then $(CABAL) configure -f-Production -O0 $(ANDROID_FLAGS) -fAndroidSplice; fi+ if [ ! -e dist/setup/setup ]; then $(CABAL) configure -O0 $(ANDROID_FLAGS) -fAndroidSplice; fi mkdir -p tmp if ! $(CABAL) build --ghc-options=-ddump-splices 2> tmp/dump-splices; then tail tmp/dump-splices >&2; exit 1; fi echo "Setting up Android build tree.."@@ -240,7 +240,7 @@ # fast development built. Note: Does not rebuild C libraries, or link # executable. fast: dist/caballog- @$$(grep 'ghc --make' dist/caballog | head -n 1 | sed -e 's/-package-id [^ ]*//g' -e 's/-hide-all-packages//') -O0+ @$$(grep 'ghc --make' dist/caballog | head -n 1 | sed -e 's/-package-id [^ ]*//g' -e 's/-hide-all-packages//') -O0 -j -dynamic @ln -sf dist/build/git-annex/git-annex git-annex @$(MAKE) tags >/dev/null 2>&1 &
Messages.hs view
@@ -30,6 +30,7 @@ showHeader, showRaw, setupConsole,+ setConsoleEncoding, enableDebugOutput, disableDebugOutput, debugEnabled,@@ -176,9 +177,12 @@ <$> streamHandler stderr DEBUG <*> pure preciseLogFormatter updateGlobalLogger rootLoggerName (setLevel NOTICE . setHandlers [s])- {- This avoids ghc's output layer crashing on- - invalid encoded characters in- - filenames when printing them out. -}+ setConsoleEncoding++{- This avoids ghc's output layer crashing on invalid encoded characters in+ - filenames when printing them out. -}+setConsoleEncoding :: IO ()+setConsoleEncoding = do fileEncoding stdout fileEncoding stderr
Remote/GCrypt.hs view
@@ -20,6 +20,7 @@ import Data.Default import Common.Annex+import qualified Annex import Types.Remote import Types.GitConfig import Types.Crypto@@ -300,7 +301,8 @@ Just (EncryptedCipher _ _ (KeyIds { keyIds = ks})) -> do setConfig participants (unwords ks) let signingkey = ConfigKey $ Git.GCrypt.remoteSigningKey remotename- skeys <- M.keys <$> liftIO secretKeys+ cmd <- gpgCmd <$> Annex.getGitConfig+ skeys <- M.keys <$> liftIO (secretKeys cmd) case filter (`elem` ks) skeys of [] -> noop (k:_) -> setConfig signingkey k
Remote/Git.hs view
@@ -368,9 +368,7 @@ | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) (return False) $ do params <- Ssh.rsyncParams r Download u <- getUUID-#ifndef mingw32_HOST_OS- hardlink <- annexHardLink <$> Annex.getGitConfig-#endif+ hardlink <- wantHardLink -- run copy from perspective of remote onLocal r $ do ensureInitialized@@ -378,19 +376,9 @@ case v of Nothing -> return False Just (object, checksuccess) -> do- let copier = rsyncOrCopyFile params object dest-#ifndef mingw32_HOST_OS- let linker = createLink object dest >> return True- go <- ifM (pure hardlink <&&> not <$> isDirect)- ( return $ \m -> liftIO (catchBoolIO linker)- <||> copier m- , return copier- )-#else- let go = copier-#endif+ copier <- mkCopier hardlink params object dest runTransfer (Transfer Download u key)- file noRetry noObserver go+ file noRetry noObserver copier <&&> checksuccess | Git.repoIsSsh (repo r) = feedprogressback $ \feeder -> do direct <- isDirect@@ -506,6 +494,7 @@ checksuccessio <- Annex.withCurrentState checksuccess params <- Ssh.rsyncParams r Upload u <- getUUID+ hardlink <- wantHardLink -- run copy from perspective of remote onLocal r $ ifM (Annex.Content.inAnnex key) ( return True@@ -514,7 +503,7 @@ runTransfer (Transfer Download u key) file noRetry noObserver $ const $ Annex.Content.saveState True `after` Annex.Content.getViaTmpChecked (liftIO checksuccessio) key- (\d -> rsyncOrCopyFile params object d p)+ (\dest -> mkCopier hardlink params object dest >>= \a -> a p) ) fsckOnRemote :: Git.Repo -> [CommandParam] -> Annex (IO Bool)@@ -622,3 +611,23 @@ withQuietOutput createProcessSuccess $ proc shellcmd $ toCommand shellparams++wantHardLink :: Annex Bool+wantHardLink = (annexHardLink <$> Annex.getGitConfig) <&&> (not <$> isDirect)++-- If either the remote or local repository wants to use hard links,+-- the copier will do so, falling back to copying.+mkCopier :: Bool -> [CommandParam] -> FilePath -> FilePath -> Annex (MeterUpdate -> Annex Bool)+mkCopier remotewanthardlink rsyncparams object dest = do+ let copier = rsyncOrCopyFile rsyncparams object dest+#ifndef mingw32_HOST_OS+ localwanthardlink <- wantHardLink+ let linker = createLink object dest >> return True+ ifM (pure (remotewanthardlink || localwanthardlink) <&&> not <$> isDirect)+ ( return $ \m -> liftIO (catchBoolIO linker)+ <||> copier m+ , return copier+ )+#else+ return copier+#endif
Remote/Helper/Encryptable.hs view
@@ -50,22 +50,24 @@ - updated to be accessible to an additional encryption key. Or the user - could opt to use a shared cipher, which is stored unencrypted. -} encryptionSetup :: RemoteConfig -> Annex (RemoteConfig, EncryptionIsSetup)-encryptionSetup c = maybe genCipher updateCipher $ extractCipher c+encryptionSetup c = do+ cmd <- gpgCmd <$> Annex.getGitConfig+ maybe (genCipher cmd) (updateCipher cmd) (extractCipher c) where -- The type of encryption encryption = M.lookup "encryption" c -- Generate a new cipher, depending on the chosen encryption scheme- genCipher = case encryption of+ genCipher cmd = case encryption of _ | M.member "cipher" c || M.member "cipherkeys" c -> cannotchange Just "none" -> return (c, NoEncryption)- Just "shared" -> use "encryption setup" . genSharedCipher+ Just "shared" -> use "encryption setup" . genSharedCipher cmd =<< highRandomQuality -- hybrid encryption is the default when a keyid is -- specified but no encryption _ | maybe (M.member "keyid" c) (== "hybrid") encryption ->- use "encryption setup" . genEncryptedCipher key Hybrid+ use "encryption setup" . genEncryptedCipher cmd key Hybrid =<< highRandomQuality- Just "pubkey" -> use "encryption setup" . genEncryptedCipher key PubKey+ Just "pubkey" -> use "encryption setup" . genEncryptedCipher cmd key PubKey =<< highRandomQuality _ -> error $ "Specify " ++ intercalate " or " (map ("encryption=" ++)@@ -76,11 +78,11 @@ maybe [] (\k -> [(False,k)]) (M.lookup "keyid-" c) cannotchange = error "Cannot set encryption type of existing remotes." -- Update an existing cipher if possible.- updateCipher v = case v of+ updateCipher cmd v = case v of SharedCipher _ | maybe True (== "shared") encryption -> return (c', EncryptionIsSetup) EncryptedCipher _ variant _ | maybe True (== if variant == Hybrid then "hybrid" else "pubkey") encryption ->- use "encryption update" $ updateEncryptedCipher newkeys v+ use "encryption update" $ updateEncryptedCipher cmd newkeys v _ -> cannotchange use m a = do showNote m@@ -111,7 +113,8 @@ case M.lookup encipher cache of Just cipher -> return $ Just (cipher, encipher) Nothing -> do- cipher <- liftIO $ decryptCipher encipher+ cmd <- gpgCmd <$> Annex.getGitConfig+ cipher <- liftIO $ decryptCipher cmd encipher Annex.changeState (\s -> s { Annex.ciphers = M.insert encipher cipher cache }) return $ Just (cipher, encipher)
Remote/Helper/Special.hs view
@@ -33,6 +33,7 @@ ) where import Common.Annex+import qualified Annex import Types.StoreRetrieve import Types.Remote import Crypto@@ -195,9 +196,10 @@ rollback = void $ removeKey encr k storechunk Nothing storer k content p = storer k content p- storechunk (Just (cipher, enck)) storer k content p =+ storechunk (Just (cipher, enck)) storer k content p = do+ cmd <- gpgCmd <$> Annex.getGitConfig withBytes content $ \b ->- encrypt gpgopts cipher (feedBytes b) $+ encrypt cmd gpgopts cipher (feedBytes b) $ readBytes $ \encb -> storer (enck k) (ByteContent encb) p @@ -251,12 +253,14 @@ (Nothing, Nothing, FileContent f) | f == dest -> noop | otherwise -> liftIO $ moveFile f dest- (Just (cipher, _), _, ByteContent b) ->- decrypt cipher (feedBytes b) $+ (Just (cipher, _), _, ByteContent b) -> do+ cmd <- gpgCmd <$> Annex.getGitConfig+ decrypt cmd cipher (feedBytes b) $ readBytes write (Just (cipher, _), _, FileContent f) -> do+ cmd <- gpgCmd <$> Annex.getGitConfig withBytes content $ \b ->- decrypt cipher (feedBytes b) $+ decrypt cmd cipher (feedBytes b) $ readBytes write liftIO $ nukeFile f (Nothing, _, FileContent f) -> do
Test.hs view
@@ -181,6 +181,7 @@ unitTests note = testGroup ("Unit Tests " ++ note) [ testCase "add sha1dup" test_add_sha1dup , testCase "add extras" test_add_extras+ , testCase "shared clone" test_shared_clone , testCase "log" test_log , testCase "import" test_import , testCase "reinject" test_reinject@@ -284,6 +285,18 @@ annexed_present wormannexedfile checkbackend wormannexedfile backendWORM +test_shared_clone :: Assertion+test_shared_clone = intmpsharedclonerepo $ do+ v <- catchMaybeIO $ Utility.Process.readProcess "git" + [ "config"+ , "--bool"+ , "--get"+ , "annex.hardlink"+ ]+ print v+ v == Just "true\n"+ @? "shared clone of repo did not get annex.hardlink set"+ test_log :: Assertion test_log = intmpclonerepo $ do git_annex "log" [annexedfile] @? "log failed"@@ -848,9 +861,9 @@ test_union_merge_regression :: Assertion test_union_merge_regression = {- We need 3 repos to see this bug. -}- withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 ->- withtmpclonerepo False $ \r3 -> do+ withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 ->+ withtmpclonerepo $ \r3 -> do forM_ [r1, r2, r3] $ \r -> indir r $ do when (r /= r1) $ boolSystem "git" [Param "remote", Param "add", Param "r1", File ("../../" ++ r1)] @? "remote add"@@ -875,8 +888,8 @@ {- Regression test for the automatic conflict resolution bug fixed - in f4ba19f2b8a76a1676da7bb5850baa40d9c388e2. -} test_conflict_resolution_movein_regression :: Assertion-test_conflict_resolution_movein_regression = withtmpclonerepo False $ \r1 -> - withtmpclonerepo False $ \r2 -> do+test_conflict_resolution_movein_regression = withtmpclonerepo $ \r1 -> + withtmpclonerepo $ \r2 -> do let rname r = if r == r1 then "r1" else "r2" forM_ [r1, r2] $ \r -> indir r $ do {- Get all files, see check below. -}@@ -910,8 +923,8 @@ - file. -} test_conflict_resolution :: Assertion test_conflict_resolution = - withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 -> do+ withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 -> do indir r1 $ do disconnectOrigin writeFile conflictor "conflictor1"@@ -948,8 +961,8 @@ check True check False where- check inr1 = withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 -> do+ check inr1 = withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 -> do indir r1 $ do disconnectOrigin writeFile conflictor "conflictor"@@ -990,8 +1003,8 @@ check True check False where- check inr1 = withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 -> do+ check inr1 = withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 -> do indir r1 $ do disconnectOrigin writeFile conflictor "conflictor"@@ -1038,8 +1051,8 @@ check True True check False True where- check inr1 switchdirect = withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 ->+ check inr1 switchdirect = withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 -> whenM (isInDirect r1 <&&> isInDirect r2) $ do indir r1 $ do disconnectOrigin@@ -1088,8 +1101,8 @@ check True True check False True where- check inr1 switchdirect = withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 ->+ check inr1 switchdirect = withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 -> whenM (checkRepo (Types.coreSymlinks <$> Annex.getGitConfig) r1 <&&> isInDirect r1 <&&> isInDirect r2) $ do indir r1 $ do@@ -1139,8 +1152,8 @@ check conflictor check (conflictor </> "file") where- check remoteconflictor = withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 -> do+ check remoteconflictor = withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 -> do indir r1 $ do disconnectOrigin createDirectoryIfMissing True (parentDir remoteconflictor)@@ -1177,9 +1190,9 @@ -} test_conflict_resolution_symlink_bit :: Assertion test_conflict_resolution_symlink_bit =- withtmpclonerepo False $ \r1 ->- withtmpclonerepo False $ \r2 ->- withtmpclonerepo False $ \r3 -> do+ withtmpclonerepo $ \r1 ->+ withtmpclonerepo $ \r2 ->+ withtmpclonerepo $ \r3 -> do indir r1 $ do writeFile conflictor "conflictor" git_annex "add" [conflictor] @? "add conflicter failed"@@ -1334,9 +1347,11 @@ testscheme "hybrid" testscheme "pubkey" where- testscheme scheme = intmpclonerepo $ whenM (Utility.Path.inPath Utility.Gpg.gpgcmd) $ do- Utility.Gpg.testTestHarness @? "test harness self-test failed"- Utility.Gpg.testHarness $ do+ gpgcmd = Utility.Gpg.mkGpgCmd Nothing+ testscheme scheme = intmpclonerepo $ whenM (Utility.Path.inPath (Utility.Gpg.unGpgCmd gpgcmd)) $ do+ Utility.Gpg.testTestHarness gpgcmd + @? "test harness self-test failed"+ Utility.Gpg.testHarness gpgcmd $ do createDirectory "dir" let a cmd = git_annex cmd $ [ "foo"@@ -1384,16 +1399,16 @@ keysMatch (Utility.Gpg.KeyIds ks') = maybe False (\(Utility.Gpg.KeyIds ks2) -> sort (nub ks2) == sort (nub ks')) ks- checkCipher encipher = Utility.Gpg.checkEncryptionStream encipher . Just+ checkCipher encipher = Utility.Gpg.checkEncryptionStream gpgcmd encipher . Just checkScheme Types.Crypto.Hybrid = scheme == "hybrid" checkScheme Types.Crypto.PubKey = scheme == "pubkey" checkKeys cip mvariant = do- cipher <- Crypto.decryptCipher cip+ cipher <- Crypto.decryptCipher gpgcmd cip files <- filterM doesFileExist $ map ("dir" </>) $ concatMap (key2files cipher) keys return (not $ null files) <&&> allM (checkFile mvariant) files checkFile mvariant filename =- Utility.Gpg.checkEncryptionFile filename $+ Utility.Gpg.checkEncryptionFile gpgcmd filename $ if mvariant == Just Types.Crypto.PubKey then ks else Nothing key2files cipher = Locations.keyPaths . Crypto.encryptKey Types.Crypto.HmacSha1 cipher@@ -1472,7 +1487,7 @@ inmainrepo = indir mainrepodir intmpclonerepo :: Assertion -> Assertion-intmpclonerepo a = withtmpclonerepo False $ \r -> indir r a+intmpclonerepo a = withtmpclonerepo $ \r -> indir r a intmpclonerepoInDirect :: Assertion -> Assertion intmpclonerepoInDirect a = intmpclonerepo $@@ -1494,12 +1509,20 @@ isInDirect = checkRepo (not <$> Config.isDirect) intmpbareclonerepo :: Assertion -> Assertion-intmpbareclonerepo a = withtmpclonerepo True $ \r -> indir r a+intmpbareclonerepo a = withtmpclonerepo' (newCloneRepoConfig { bareClone = True } ) $+ \r -> indir r a -withtmpclonerepo :: Bool -> (FilePath -> Assertion) -> Assertion-withtmpclonerepo bare a = do+intmpsharedclonerepo :: Assertion -> Assertion+intmpsharedclonerepo a = withtmpclonerepo' (newCloneRepoConfig { sharedClone = True } ) $+ \r -> indir r a++withtmpclonerepo :: (FilePath -> Assertion) -> Assertion+withtmpclonerepo = withtmpclonerepo' newCloneRepoConfig++withtmpclonerepo' :: CloneRepoConfig -> (FilePath -> Assertion) -> Assertion+withtmpclonerepo' cfg a = do dir <- tmprepodir- bracket (clonerepo mainrepodir dir bare) cleanup a+ bracket (clonerepo mainrepodir dir cfg) cleanup a disconnectOrigin :: Assertion disconnectOrigin = boolSystem "git" [Param "remote", Param "rm", Param "origin"] @? "remote rm"@@ -1527,15 +1550,27 @@ configrepo dir return dir +data CloneRepoConfig = CloneRepoConfig+ { bareClone :: Bool+ , sharedClone :: Bool+ }++newCloneRepoConfig :: CloneRepoConfig+newCloneRepoConfig = CloneRepoConfig+ { bareClone = False+ , sharedClone = False+ }+ -- clones are always done as local clones; we cannot test ssh clones-clonerepo :: FilePath -> FilePath -> Bool -> IO FilePath-clonerepo old new bare = do+clonerepo :: FilePath -> FilePath -> CloneRepoConfig -> IO FilePath+clonerepo old new cfg = do cleanup new ensuretmpdir let cloneparams = catMaybes [ Just $ Param "clone" , Just $ Param "-q"- , if bare then Just (Param "--bare") else Nothing+ , if bareClone cfg then Just (Param "--bare") else Nothing+ , if sharedClone cfg then Just (Param "--shared") else Nothing , Just $ File old , Just $ File new ]@@ -1543,7 +1578,7 @@ configrepo new indir new $ git_annex "init" ["-q", new] @? "git annex init failed"- unless bare $+ unless (bareClone cfg) $ indir new $ handleforcedirect return new
Types/GitConfig.hs view
@@ -25,6 +25,7 @@ import Types.Difference import Types.RefSpec import Utility.HumanTime+import Utility.Gpg (GpgCmd, mkGpgCmd) {- Main git-annex settings. Each setting corresponds to a git-config key - such as annex.foo -}@@ -58,11 +59,12 @@ , annexListen :: Maybe String , annexStartupScan :: Bool , annexHardLink :: Bool+ , annexDifferences :: Differences+ , annexUsedRefSpec :: Maybe RefSpec , coreSymlinks :: Bool , coreSharedRepository :: SharedRepository , gcryptId :: Maybe String- , annexDifferences :: Differences- , annexUsedRefSpec :: Maybe RefSpec+ , gpgCmd :: GpgCmd } extractGitConfig :: Git.Repo -> GitConfig@@ -98,12 +100,13 @@ , annexListen = getmaybe (annex "listen") , annexStartupScan = getbool (annex "startupscan") True , annexHardLink = getbool (annex "hardlink") False- , coreSymlinks = getbool "core.symlinks" True- , coreSharedRepository = getSharedRepository r- , gcryptId = getmaybe "core.gcrypt-id" , annexDifferences = getDifferences r , annexUsedRefSpec = either (const Nothing) Just . parseRefSpec =<< getmaybe (annex "used-refspec")+ , coreSymlinks = getbool "core.symlinks" True+ , coreSharedRepository = getSharedRepository r+ , gcryptId = getmaybe "core.gcrypt-id"+ , gpgCmd = mkGpgCmd (getmaybe "gpg.program") } where getbool k d = fromMaybe d $ getmaybebool k
Utility/Exception.hs view
@@ -39,10 +39,7 @@ {- Catches IO errors and returns a Maybe -} catchMaybeIO :: MonadCatch m => m a -> m (Maybe a)-catchMaybeIO a = do- catchDefaultIO Nothing $ do- v <- a- return (Just v)+catchMaybeIO a = catchDefaultIO Nothing $ a >>= (return . Just) {- Catches IO errors and returns a default value. -} catchDefaultIO :: MonadCatch m => a -> m a -> m a
Utility/Gpg.hs view
@@ -30,11 +30,17 @@ newtype KeyIds = KeyIds { keyIds :: [KeyId] } deriving (Ord, Eq) -{- If a specific gpg command was found at configure time, use it.- - Otherwise, try to run gpg. -}-gpgcmd :: FilePath-gpgcmd = fromMaybe "gpg" SysConfig.gpg+newtype GpgCmd = GpgCmd { unGpgCmd :: String } +{- Get gpg command to use, Just what's specified or, if a specific gpg+ - command was found at configure time, use it, or otherwise, "gpg". -}+mkGpgCmd :: Maybe FilePath -> GpgCmd+mkGpgCmd (Just c) = GpgCmd c+mkGpgCmd Nothing = GpgCmd (fromMaybe "gpg" SysConfig.gpg)++boolGpgCmd :: GpgCmd -> [CommandParam] -> IO Bool+boolGpgCmd (GpgCmd cmd) = boolSystem cmd+ -- Generate an argument list to asymetrically encrypt to the given recipients. pkEncTo :: [String] -> [CommandParam] pkEncTo = concatMap (\r -> [Param "--recipient", Param r])@@ -76,19 +82,19 @@ ] {- Runs gpg with some params and returns its stdout, strictly. -}-readStrict :: [CommandParam] -> IO String-readStrict params = do+readStrict :: GpgCmd -> [CommandParam] -> IO String+readStrict (GpgCmd cmd) params = do params' <- stdParams params- withHandle StdoutHandle createProcessSuccess (proc gpgcmd params') $ \h -> do+ withHandle StdoutHandle createProcessSuccess (proc cmd params') $ \h -> do hSetBinaryMode h True hGetContentsStrict h {- Runs gpg, piping an input value to it, and returning its stdout, - strictly. -}-pipeStrict :: [CommandParam] -> String -> IO String-pipeStrict params input = do+pipeStrict :: GpgCmd -> [CommandParam] -> String -> IO String+pipeStrict (GpgCmd cmd) params input = do params' <- stdParams params- withIOHandles createProcessSuccess (proc gpgcmd params') $ \(to, from) -> do+ withIOHandles createProcessSuccess (proc cmd params') $ \(to, from) -> do hSetBinaryMode to True hSetBinaryMode from True hPutStr to input@@ -106,8 +112,8 @@ - - Note that to avoid deadlock with the cleanup stage, - the reader must fully consume gpg's input before returning. -}-feedRead :: (MonadIO m, MonadMask m) => [CommandParam] -> String -> (Handle -> IO ()) -> (Handle -> m a) -> m a-feedRead params passphrase feeder reader = do+feedRead :: (MonadIO m, MonadMask m) => GpgCmd -> [CommandParam] -> String -> (Handle -> IO ()) -> (Handle -> m a) -> m a+feedRead cmd params passphrase feeder reader = do #ifndef mingw32_HOST_OS -- pipe the passphrase into gpg on a fd (frompipe, topipe) <- liftIO System.Posix.IO.createPipe@@ -127,13 +133,13 @@ go $ passphrasefile ++ params #endif where- go params' = pipeLazy params' feeder reader+ go params' = pipeLazy cmd params' feeder reader {- Like feedRead, but without passphrase. -}-pipeLazy :: (MonadIO m, MonadMask m) => [CommandParam] -> (Handle -> IO ()) -> (Handle -> m a) -> m a-pipeLazy params feeder reader = do+pipeLazy :: (MonadIO m, MonadMask m) => GpgCmd -> [CommandParam] -> (Handle -> IO ()) -> (Handle -> m a) -> m a+pipeLazy (GpgCmd cmd) params feeder reader = do params' <- liftIO $ stdParams $ Param "--batch" : params- let p = (proc gpgcmd params')+ let p = (proc cmd params') { std_in = CreatePipe , std_out = CreatePipe , std_err = Inherit@@ -152,8 +158,8 @@ {- Finds gpg public keys matching some string. (Could be an email address, - a key id, or a name; See the section 'HOW TO SPECIFY A USER ID' of - GnuPG's manpage.) -}-findPubKeys :: String -> IO KeyIds-findPubKeys for = KeyIds . parse . lines <$> readStrict params+findPubKeys :: GpgCmd -> String -> IO KeyIds+findPubKeys cmd for = KeyIds . parse . lines <$> readStrict cmd params where params = [Param "--with-colons", Param "--list-public-keys", Param for] parse = mapMaybe (keyIdField . split ":")@@ -164,10 +170,10 @@ {- All of the user's secret keys, with their UserIds. - Note that the UserId may be empty. -}-secretKeys :: IO (M.Map KeyId UserId)-secretKeys = catchDefaultIO M.empty makemap+secretKeys :: GpgCmd -> IO (M.Map KeyId UserId)+secretKeys cmd = catchDefaultIO M.empty makemap where- makemap = M.fromList . parse . lines <$> readStrict params+ makemap = M.fromList . parse . lines <$> readStrict cmd params params = [Param "--with-colons", Param "--list-secret-keys", Param "--fixed-list-mode"] parse = extract [] Nothing . map (split ":") extract c (Just keyid) (("uid":_:_:_:_:_:_:_:_:userid:_):rest) =@@ -193,9 +199,9 @@ - The key is added to the secret key ring. - Can take a very long time, depending on system entropy levels. -}-genSecretKey :: KeyType -> Passphrase -> UserId -> Size -> IO ()-genSecretKey keytype passphrase userid keysize =- withHandle StdinHandle createProcessSuccess (proc gpgcmd params) feeder+genSecretKey :: GpgCmd -> KeyType -> Passphrase -> UserId -> Size -> IO ()+genSecretKey (GpgCmd cmd) keytype passphrase userid keysize =+ withHandle StdinHandle createProcessSuccess (proc cmd params) feeder where params = ["--batch", "--gen-key"] feeder h = do@@ -217,8 +223,8 @@ {- Creates a block of high-quality random data suitable to use as a cipher. - It is armored, to avoid newlines, since gpg only reads ciphers up to the - first newline. -}-genRandom :: Bool -> Size -> IO String-genRandom highQuality size = checksize <$> readStrict params+genRandom :: GpgCmd -> Bool -> Size -> IO String+genRandom cmd highQuality size = checksize <$> readStrict cmd params where params = [ Param "--gen-random"@@ -327,8 +333,8 @@ #ifndef mingw32_HOST_OS {- Runs an action using gpg in a test harness, in which gpg does - not use ~/.gpg/, but a directory with the test key set up to be used. -}-testHarness :: IO a -> IO a-testHarness a = do+testHarness :: GpgCmd -> IO a -> IO a+testHarness cmd a = do orig <- getEnv var bracket setup (cleanup orig) (const a) where@@ -339,8 +345,8 @@ dir <- mktmpdir $ base </> "gpgtmpXXXXXX" setEnv var dir True -- For some reason, recent gpg needs a trustdb to be set up.- _ <- pipeStrict [Param "--trust-model", Param "auto", Param "--update-trustdb"] []- _ <- pipeStrict [Param "--import", Param "-q"] $ unlines+ _ <- pipeStrict cmd [Param "--trust-model", Param "auto", Param "--update-trustdb"] []+ _ <- pipeStrict cmd [Param "--import", Param "-q"] $ unlines [testSecretKey, testKey] return dir @@ -349,22 +355,22 @@ reset _ = unsetEnv var {- Tests the test harness. -}-testTestHarness :: IO Bool-testTestHarness = do- keys <- testHarness $ findPubKeys testKeyId+testTestHarness :: GpgCmd -> IO Bool+testTestHarness cmd = do+ keys <- testHarness cmd $ findPubKeys cmd testKeyId return $ KeyIds [testKeyId] == keys #endif #ifndef mingw32_HOST_OS-checkEncryptionFile :: FilePath -> Maybe KeyIds -> IO Bool-checkEncryptionFile filename keys =- checkGpgPackets keys =<< readStrict params+checkEncryptionFile :: GpgCmd -> FilePath -> Maybe KeyIds -> IO Bool+checkEncryptionFile cmd filename keys =+ checkGpgPackets cmd keys =<< readStrict cmd params where params = [Param "--list-packets", Param "--list-only", File filename] -checkEncryptionStream :: String -> Maybe KeyIds -> IO Bool-checkEncryptionStream stream keys =- checkGpgPackets keys =<< pipeStrict params stream+checkEncryptionStream :: GpgCmd -> String -> Maybe KeyIds -> IO Bool+checkEncryptionStream cmd stream keys =+ checkGpgPackets cmd keys =<< pipeStrict cmd params stream where params = [Param "--list-packets", Param "--list-only"] @@ -372,8 +378,8 @@ - symmetrically encrypted (keys is Nothing), or encrypted to some - public key(s). - /!\ The key needs to be in the keyring! -}-checkGpgPackets :: Maybe KeyIds -> String -> IO Bool-checkGpgPackets keys str = do+checkGpgPackets :: GpgCmd -> Maybe KeyIds -> String -> IO Bool+checkGpgPackets cmd keys str = do let (asym,sym) = partition (pubkeyEncPacket `isPrefixOf`) $ filter (\l' -> pubkeyEncPacket `isPrefixOf` l' || symkeyEncPacket `isPrefixOf` l') $@@ -384,7 +390,7 @@ (Just (KeyIds ks), ls, []) -> do -- Find the master key associated with the -- encryption subkey.- ks' <- concat <$> mapM (keyIds <$$> findPubKeys)+ ks' <- concat <$> mapM (keyIds <$$> findPubKeys cmd) [ k | k:"keyid":_ <- map (reverse . words) ls ] return $ sort (nub ks) == sort (nub ks') _ -> return False
Utility/Matcher.hs view
@@ -27,6 +27,7 @@ matchM, matchMrun, isEmpty,+ combineMatchers, prop_matcher_sane ) where@@ -141,6 +142,14 @@ isEmpty :: Matcher a -> Bool isEmpty MAny = True isEmpty _ = False++{- Combines two matchers, yielding a matcher that will match anything+ - both do. But, if one matcher contains no limits, yield the other one. -}+combineMatchers :: Matcher a -> Matcher a -> Matcher a+combineMatchers a b + | isEmpty a = b+ | isEmpty b = a+ | otherwise = a `MOr` b prop_matcher_sane :: Bool prop_matcher_sane = all (\m -> match dummy m ()) $ map generate
Utility/Misc.hs view
@@ -136,7 +136,7 @@ - if this reap gets there first. -} reapZombies :: IO () #ifndef mingw32_HOST_OS-reapZombies = do+reapZombies = -- throws an exception when there are no child processes catchDefaultIO Nothing (getAnyProcessStatus False True) >>= maybe (return ()) (const reapZombies)
Utility/OptParse.hs view
@@ -9,6 +9,7 @@ import Options.Applicative import Data.Monoid+import Prelude -- | A switch that can be enabled using --foo and disabled using --no-foo. --
Utility/Process.hs view
@@ -172,7 +172,7 @@ -- returns a transcript combining its stdout and stderr, and -- whether it succeeded or failed. processTranscript :: String -> [String] -> (Maybe String) -> IO (String, Bool)-processTranscript cmd opts input = processTranscript' cmd opts Nothing input+processTranscript cmd opts = processTranscript' cmd opts Nothing processTranscript' :: String -> [String] -> Maybe [(String, String)] -> (Maybe String) -> IO (String, Bool) processTranscript' cmd opts environ input = do@@ -378,11 +378,10 @@ -- | Debugging trace for a CreateProcess. debugProcess :: CreateProcess -> IO ()-debugProcess p = do- debugM "Utility.Process" $ unwords- [ action ++ ":"- , showCmd p- ]+debugProcess p = debugM "Utility.Process" $ unwords+ [ action ++ ":"+ , showCmd p+ ] where action | piped (std_in p) && piped (std_out p) = "chat"
Utility/Scheduled.hs view
@@ -286,7 +286,7 @@ fromScheduledTime (SpecificTime h m) = show h' ++ (if m > 0 then ":" ++ pad 2 (show m) else "") ++ " " ++ ampm where- pad n s = take (n - length s) (repeat '0') ++ s+ pad n s = replicate (n - length s) '0' ++ s (h', ampm) | h == 0 = (12, "AM") | h < 12 = (h, "AM")
Utility/WinProcess.hs view
@@ -11,5 +11,18 @@ import Utility.PID -foreign import ccall unsafe "terminatepid"- terminatePID :: PID -> IO ()+import System.Win32.Process+import Control.Exception (bracket)+import Control.Monad++terminatePID :: PID -> IO ()+terminatePID p = bracket + (openProcess pROCESS_TERMINATE False p)+ (void . c_closeProcess)+ (\h -> void $ c_TerminateProcess h 1)++foreign import ccall unsafe "windows.h TerminateProcess"+ c_TerminateProcess :: ProcessHandle -> Int -> IO Int++foreign import ccall unsafe "windows.h CloseHandle"+ c_closeProcess :: ProcessHandle -> IO Bool
− Utility/winprocess.c
@@ -1,10 +0,0 @@-#include <windows.h>--void terminatepid (DWORD pid) {- HANDLE h;- h = OpenProcess(PROCESS_TERMINATE, 0, pid);- if (h != NULL) {- TerminateProcess(h, 1);- }- CloseHandle(h);-}
debian/changelog view
@@ -1,3 +1,38 @@+git-annex (5.20150916) unstable; urgency=medium++ * Fix Windows build to work with ghc 7.10.+ * init: Fix reversion in detection of repo made with git clone --shared+ * info: Support querying info of individual files in direct mode.+ * unused: Fix reversion in 5.20150727 that broke parsing of the+ --unused-refspec option. Thanks, Øyvind A. Holm.+ * Make full option parsing be done when not in a git repo, so --help+ can be displayed for commands that require a git repo, etc.+ * fsck: Work around bug in persistent that broke display of+ problematically encoded filenames on stderr when using --incremental.+ * When gpg.program is configured, it's used to get the command to run+ for gpg. Useful on systems that have only a gpg2 command or want to+ use it instead of the gpg command.+ * Windows: Switched to using git for Windows, rather than msysgit.+ Using msysgit with git-annex is no longer supported.+ * Windows: Even when the user neglects to tell the git installer to+ add git to PATH, git-annex will still work from within the git bash+ shell, and the webapp can be used too.+ * sync: Add --no-commit, --no-pull, --no-push options to turn off parts of+ the sync process, as well as supporting --commit, --pull, --push, and+ --no-content options to specify the (current) default behavior.+ * annex.hardlink extended to also try to use hard links when copying from+ the repository to a remote.+ * Improve bash completion, so it completes names of remotes and backends+ in appropriate places.+ * Special remotes configured with autoenable=true will be automatically+ enabled when git-annex init is run.+ * Fix bug in combination of preferred and required content settings.+ When one was set to the empty string and the other set to some expression,+ this bug caused all files to be wanted, instead of only files matching+ the expression.++ -- Joey Hess <id@joeyh.name> Wed, 16 Sep 2015 10:31:24 -0400+ git-annex (5.20150824) unstable; urgency=medium * Sped up downloads of files from ssh remotes, reducing the
+ doc/Void.mdwn view
@@ -0,0 +1,1 @@+git-annex can be installed in Void Linux by running: `xbps-install git-annex`.
+ doc/bugs/--help_should_not_demand_being_in_the_git_repo.mdwn view
@@ -0,0 +1,25 @@+### Please describe the problem.++subj -- happens for sync and merge commands at least+++[[!format sh """+$> git annex sync --help+git-annex: Not in a git repository.++$> git annex merge --help+git-annex: Not in a git repository.++$> git annex version +git-annex version: 5.20150819+gitgc587698-1~ndall+1+build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV Inotify DBus DesktopNotify XMPP DNS Feeds Quvi TDFA Database+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 SHA1E SHA1 MD5E MD5 WORM URL+remote types: git gcrypt S3 bup directory rsync web bittorrent webdav tahoe glacier ddar hook external++"""]]++### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)++YES -- lots of luck ;)++> [[fixed|done]] --[[Joey]]
+ doc/bugs/Prefered_Content_not_Taken_into_Account.mdwn view
@@ -0,0 +1,364 @@+### Please describe the problem.++This is a follow up to the question [1]. I've created 4 repos with the following vicfg.++[[!format sh """+# git-annex configuration+# +# Changes saved to this file will be recorded in the git-annex branch.+# +# Lines in this file have the format:+# setting field = value++# Repository trust configuration+# (Valid trust levels: trusted semitrusted untrusted dead)+# (for web)+#trust 00000000-0000-0000-0000-000000000001 = semitrusted+# (for bittorrent)+#trust 00000000-0000-0000-0000-000000000002 = semitrusted+# (for repo2)+#trust 2837f3d7-7c58-4177-8877-620213cf5146 = semitrusted+# (for repo3)+#trust b3cbb656-e797-45ba-bf43-08523d463146 = semitrusted+# (for repo1)+#trust e7673de4-d465-4557-be8f-b1400acf923e = semitrusted++# Repository groups+# (Standard groups: client transfer backup incrementalbackup smallarchive archive source manual public unwanted)+# (Separate group names with spaces)+# (for repo3)+group b3cbb656-e797-45ba-bf43-08523d463146 = PodA+# (for repo1)+group e7673de4-d465-4557-be8f-b1400acf923e = PodA+# (for repo2)+group 2837f3d7-7c58-4177-8877-620213cf5146 = PodB+# (for web)+#group 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#group 00000000-0000-0000-0000-000000000002 = ++# Repository preferred contents+# (Set to "standard" to use a repository's group's preferred contents)+# (for repo2)+wanted 2837f3d7-7c58-4177-8877-620213cf5146 = groupwanted+# (for repo1)+wanted e7673de4-d465-4557-be8f-b1400acf923e = groupwanted+# (for web)+#wanted 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#wanted 00000000-0000-0000-0000-000000000002 = +# (for repo3)+#wanted b3cbb656-e797-45ba-bf43-08523d463146 = ++# Group preferred contents+# (Used by repositories with "groupwanted" in their preferred contents)+groupwanted PodA = not copies=PodA:1+groupwanted PodB = not copies=PodB:1+#groupwanted archive = +#groupwanted backup = +#groupwanted client = +#groupwanted incrementalbackup = +#groupwanted manual = +#groupwanted public = +#groupwanted smallarchive = +#groupwanted source = +#groupwanted transfer = +#groupwanted unwanted = ++# Standard preferred contents+# (Used by wanted or groupwanted expressions containing "standard")+# (For reference only; built-in and cannot be changed!)+# standard client = (include=* and ((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1)))) or approxlackingcopies=1+# standard transfer = (not (inallgroup=client and copies=client:2) and ((include=* and ((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1)))) or approxlackingcopies=1)) or approxlackingcopies=1+# standard backup = anything+# standard incrementalbackup = ((not copies=backup:1) and (not copies=incrementalbackup:1)) or approxlackingcopies=1+# standard smallarchive = ((include=*/archive/* or include=archive/*) and ((not (copies=archive:1 or copies=smallarchive:1)) or approxlackingcopies=1)) or approxlackingcopies=1+# standard archive = (not (copies=archive:1 or copies=smallarchive:1)) or approxlackingcopies=1+# standard source = not (copies=1)+# standard manual = present and ((include=* and ((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1)))) or approxlackingcopies=1)+# standard public = inpreferreddir+# standard unwanted = not anything++# Repository required contents+# (for web)+#required 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#required 00000000-0000-0000-0000-000000000002 = +# (for repo2)+#required 2837f3d7-7c58-4177-8877-620213cf5146 = +# (for repo3)+#required b3cbb656-e797-45ba-bf43-08523d463146 = +# (for repo1)+#required e7673de4-d465-4557-be8f-b1400acf923e = ++# Scheduled activities+# (Separate multiple activities with "; ")+# (for web)+#schedule 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#schedule 00000000-0000-0000-0000-000000000002 = +# (for repo2)+#schedule 2837f3d7-7c58-4177-8877-620213cf5146 = +# (for repo3)+#schedule b3cbb656-e797-45ba-bf43-08523d463146 = +# (for repo1)+#schedule e7673de4-d465-4557-be8f-b1400acf923e = +"""]]++This works as expected each file lands in 1 on of the repos on the group, not both. My original repo one with the problem has the following vicfg.++[[!format sh """+# git-annex configuration+# +# Changes saved to this file will be recorded in the git-annex branch.+# +# Lines in this file have the format:+# setting field = value++# Repository trust configuration+# (Valid trust levels: trusted semitrusted untrusted dead)+# (for buse [origin])+trust bff7238e-bd92-4929-88a8-c59c1a1dcf03 = semitrusted+# (for web)+trust 00000000-0000-0000-0000-000000000001 = untrusted+# (for bittorrent)+trust 00000000-0000-0000-0000-000000000002 = untrusted+# (for )+trust 03b19bdc-8497-4234-9ef6-c80d78e309f8 = dead+# (for )+trust 0b1a34ce-a8e3-4002-b46a-83e96626305f = dead+# (for )+trust 1459a238-6f60-4b43-8459-f7055b49e3c5 = dead+# (for )+trust 14738d0f-2f50-4f93-a8e4-c29870d02ba1 = dead+# (for )+trust 1512a830-7789-4bc8-a4a0-4c51eedd1109 = dead+# (for )+trust 174d69cb-9b97-44df-9f15-aea00f66a61c = dead+# (for )+trust 1ade7f29-2ad0-4ab0-a816-de55ffde389e = dead+# (for )+trust 1ba9d14b-deae-46e6-b451-dbf0fa8aa934 = dead+# (for )+trust 1dda84ca-4e8c-49b4-b673-35ec2b11557b = dead+# (for )+trust 29aad234-82e6-45c9-9822-b650290c2264 = dead+# (for )+trust 2be091a2-e721-4a86-a759-c5df7a41a61d = dead+# (for )+trust 3540b01a-03f0-4a58-8ea1-7ca80002a22d = dead+# (for )+trust 39b4d431-9d55-432d-a801-eaf4cf643de1 = dead+# (for )+trust 3a443e72-e8e0-11e2-b7db-8feb865236d4 = dead+# (for )+trust 42023cde-e95f-483c-8389-54b823aed789 = dead+# (for )+trust 54a819c1-65a3-44e9-86c3-0eb602223ee8 = dead+# (for )+trust 68846c04-912d-4bfc-80f3-3b8ec1e7a3c7 = dead+# (for )+trust 69b10f7e-0214-4fd0-8138-ff4717d1f39f = dead+# (for )+trust 7b236779-a961-4e72-abfc-56b764e53a9c = dead+# (for )+trust 7cde3feb-3876-4c2a-a772-d4541eac8614 = dead+# (for )+trust 8f3e7b2b-f8de-4114-bcdd-2ef3ed932c18 = dead+# (for )+trust a3bd1546-e8df-11e2-bc54-a7edbf29f5da = dead+# (for )+trust aa830256-4c63-44e3-9a3f-33b377de79d5 = dead+# (for )+trust ad46e36b-df9c-4d45-9af1-58d17e798afa = dead+# (for )+trust b5464382-b5f8-4ec3-b36d-a378b1202497 = dead+# (for )+trust b6317827-97d3-44bd-8197-91cae0b56a19 = dead+# (for )+trust bbb5dd98-f09d-11e2-a57b-d7185df9eef1 = dead+# (for )+trust c6dfb856-a0cc-4e79-acbd-3600f4bce158 = dead+# (for )+trust ccb11b54-ecc8-11e2-ad6c-af6445c8eedc = dead+# (for )+trust cdbf33bc-17bc-49e3-b0d1-afa653a2c1f7 = dead+# (for )+trust d8cf3fb5-4e8e-4732-b566-dab6f2d9dc4c = dead+# (for )+trust e160a8ef-3b3d-4f0e-88eb-9ceba11b2f57 = dead+# (for )+trust e39439a0-1486-55a0-ada3-c9785c08d650 = dead+# (for )+trust e8bcb64b-17df-4d79-a5b6-9d444e4afa51 = dead+# (for )+trust eae76b0e-ada9-4c5e-b9e3-db5998324e70 = dead+# (for )+trust ec71b4bd-1b7b-408c-906f-91c4168fd89f = dead+# (for )+trust f936015b-d62b-4899-a3f0-8d91efb385b5 = dead+# (for damla)+#trust 132503d4-dcde-4790-aabb-ee5ba539a3a0 = semitrusted+# (for ozge)+#trust 1e1d0c4e-b1da-465f-9140-7128a7e3ee13 = semitrusted+# (for mini)+#trust 7deafa14-8add-4316-984f-9b24eb713770 = semitrusted+# (for irem)+#trust aabc3536-a423-42b6-a234-5f110607296e = semitrusted+# (for yesim)+#trust ba3593c0-ddf1-4433-9916-aa25d1a52895 = semitrusted+# (for hubic)+#trust f980f309-0ebd-41c8-9303-73aff6409365 = semitrusted++# Repository groups+# (Standard groups: client transfer backup incrementalbackup smallarchive archive source manual public unwanted)+# (Separate group names with spaces)+# (for damla)+group 132503d4-dcde-4790-aabb-ee5ba539a3a0 = PodA+# (for ozge)+group 1e1d0c4e-b1da-465f-9140-7128a7e3ee13 = PodA+# (for irem)+group aabc3536-a423-42b6-a234-5f110607296e = PodA+# (for yesim)+group ba3593c0-ddf1-4433-9916-aa25d1a52895 = PodA+# (for buse [origin])+group bff7238e-bd92-4929-88a8-c59c1a1dcf03 = PodA+# (for hubic)+group f980f309-0ebd-41c8-9303-73aff6409365 = PodB+# (for mini)+group 7deafa14-8add-4316-984f-9b24eb713770 = manual+# (for web)+#group 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#group 00000000-0000-0000-0000-000000000002 = ++# Repository preferred contents+# (Set to "standard" to use a repository's group's preferred contents)+# (for damla)+wanted 132503d4-dcde-4790-aabb-ee5ba539a3a0 = groupwanted+# (for ozge)+wanted 1e1d0c4e-b1da-465f-9140-7128a7e3ee13 = groupwanted+# (for irem)+wanted aabc3536-a423-42b6-a234-5f110607296e = groupwanted+# (for yesim)+wanted ba3593c0-ddf1-4433-9916-aa25d1a52895 = groupwanted+# (for buse [origin])+wanted bff7238e-bd92-4929-88a8-c59c1a1dcf03 = groupwanted+# (for hubic)+wanted f980f309-0ebd-41c8-9303-73aff6409365 = groupwanted+# (for mini)+wanted 7deafa14-8add-4316-984f-9b24eb713770 = standard+# (for web)+#wanted 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#wanted 00000000-0000-0000-0000-000000000002 = ++# Group preferred contents+# (Used by repositories with "groupwanted" in their preferred contents)+groupwanted storagePodA = +groupwanted storagePodB = +groupwanted PodA = not copies=PodA:1+groupwanted PodB = not copies=PodB:1+#groupwanted archive = +#groupwanted backup = +#groupwanted client = +#groupwanted incrementalbackup = +#groupwanted manual = +#groupwanted public = +#groupwanted smallarchive = +#groupwanted source = +#groupwanted transfer = +#groupwanted unwanted = ++# Standard preferred contents+# (Used by wanted or groupwanted expressions containing "standard")+# (For reference only; built-in and cannot be changed!)+# standard client = (include=* and ((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1)))) or approxlackingcopies=1+# standard transfer = (not (inallgroup=client and copies=client:2) and ((include=* and ((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1)))) or approxlackingcopies=1)) or approxlackingcopies=1+# standard backup = anything+# standard incrementalbackup = ((not copies=backup:1) and (not copies=incrementalbackup:1)) or approxlackingcopies=1+# standard smallarchive = ((include=*/archive/* or include=archive/*) and ((not (copies=archive:1 or copies=smallarchive:1)) or approxlackingcopies=1)) or approxlackingcopies=1+# standard archive = (not (copies=archive:1 or copies=smallarchive:1)) or approxlackingcopies=1+# standard source = not (copies=1)+# standard manual = present and ((include=* and ((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1)))) or approxlackingcopies=1)+# standard public = inpreferreddir+# standard unwanted = not anything++# Repository required contents+# (for damla)+required 132503d4-dcde-4790-aabb-ee5ba539a3a0 = +# (for ozge)+required 1e1d0c4e-b1da-465f-9140-7128a7e3ee13 = +# (for irem)+required aabc3536-a423-42b6-a234-5f110607296e = +# (for yesim)+required ba3593c0-ddf1-4433-9916-aa25d1a52895 = +# (for buse [origin])+required bff7238e-bd92-4929-88a8-c59c1a1dcf03 = +# (for web)+#required 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#required 00000000-0000-0000-0000-000000000002 = +# (for mini)+#required 7deafa14-8add-4316-984f-9b24eb713770 = +# (for hubic)+#required f980f309-0ebd-41c8-9303-73aff6409365 = ++# Scheduled activities+# (Separate multiple activities with "; ")+# (for web)+#schedule 00000000-0000-0000-0000-000000000001 = +# (for bittorrent)+#schedule 00000000-0000-0000-0000-000000000002 = +# (for damla)+#schedule 132503d4-dcde-4790-aabb-ee5ba539a3a0 = +# (for ozge)+#schedule 1e1d0c4e-b1da-465f-9140-7128a7e3ee13 = +# (for mini)+#schedule 7deafa14-8add-4316-984f-9b24eb713770 = +# (for irem)+#schedule aabc3536-a423-42b6-a234-5f110607296e = +# (for yesim)+#schedule ba3593c0-ddf1-4433-9916-aa25d1a52895 = +# (for buse [origin])+#schedule bff7238e-bd92-4929-88a8-c59c1a1dcf03 = +# (for hubic)+#schedule f980f309-0ebd-41c8-9303-73aff6409365 = ++"""]]++With this settings all the repos tries get all of the files files that are present in other groups. Is there a way to debug this problem and tell why git-annex is trying to get the files? According to the settings it should not. I've also tried deleting all history this is a big (around 7 TB) old repo I thought maybe something got messed up along the way but it did not fix it.++### What steps will reproduce the problem?+++### What version of git-annex are you using? On what operating system?++[[!format sh """+git-annex version: 5.20150825-g7826f84+build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV Inotify DBus DesktopNotify XMPP DNS Feeds Quvi TDFA Database +key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SKEIN256E SKEIN256 SKEIN512E SKEIN512+ SHA1E SHA1 MD5E MD5 WORM URL +remote types: git gcrypt S3 bup directory rsync web bittorrent webdav tahoe glacier ddar hook external local repository version: 5+supported repository version: 5+upgrade supported from repository versions: 0 1 2 4+"""]]++On Ubuntu 14.04. All repos are on external USB drives on the same machine except the one called "mini".++### Please provide any additional information below.++[[!format sh """+# If you can, paste a complete transcript of the problem occurring here.+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log+++# End of transcript or log.+"""]]++### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)+++[1] https://git-annex.branchable.com/forum/git-annex_does_not_respect_preferred_content_settings/++> [[fixed|done]] --[[Joey]]
@@ -0,0 +1,27 @@+### Please describe the problem.++In an earlier git-annex version (5.20141125, at least on debian), `git clone --shared` followed by `git annex init` used to set annex.hardlink to true and mark the repository as untrusted. It no longer does that.++### What steps will reproduce the problem?++(Assuming "foo" is a pre-existing repo with an annex)++ git clone --shared foo foo.shared+ cd foo.shared+ git annex init+ git config annex.hardlink++### What version of git-annex are you using? On what operating system?++5.20150824, Debian Jessie. Tried both the debian unstable package and direct cabal build.++### Please provide any additional information below.++I haven't really debugged this, but it seems that `git annex init` nowadays does some syncing (i.e. commits, i.e. objects) that it didn't used to. The hard link check tests that the current repository has alternates, but doesn't have local objects. It might be that the newly created local objects prevent the hard link check from passing. Perhaps the hard link test should only check the presence of alternates?++### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)++Sure, it's a great tool!++> Seems that bit rotted at some point. I've fixed it, and put in a test+> case. [[done]] --[[Joey]]
+ doc/bugs/fsck_--incremental-schedule_does_not_work_as_documented.mdwn view
@@ -0,0 +1,73 @@+### Please describe the problem.+git annex fsck with --incremental-schedule restarts all the time. According to the man page:++ Maybe you'd like to run a fsck for 5 hours at night, pick-+ ing up each night where it left off. You'd like this to+ continue until all files have been fscked. And once it's+ done, you'd like a new fsck pass to start, but no more+ often than once a month. Then put this in a nightly cron+ job:++ git annex fsck --incremental-schedule 30d --time-limit 5h++If I run that command (with a time limit of 10 minutes) it starts over instead of continuing where it finished off.++### What version of git-annex are you using? On what operating system?++Debian testing version on linux ++ time_machine_carl@pi:/media/backup_hdd/carl/annex$ git annex version+ git-annex version: 5.20150731-1+ build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV Inotify DBus DesktopNotify XMPP DNS Feeds Quvi TDFA Database+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E MD5E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 MD5 WORM URL+ remote types: git gcrypt S3 bup directory rsync web bittorrent webdav tahoe glacier ddar hook external+ local repository version: 5+ supported repository version: 5+ upgrade supported from repository versions: 0 1 2 4+ time_machine_carl@pi:/media/backup_hdd/carl/annex$ uname -a+ Linux pi 4.1.6+ #810 PREEMPT Tue Aug 18 15:19:58 BST 2015 armv6l GNU/Linux++and latest version built from homebrew on OS X++ Carls-MacBook-Air:CurveDe carlmod$ git annex version+ git-annex version: 5.20150824+ build flags: Assistant Webapp Webapp-secure Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi TDFA TorrentParser Database+ key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 SHA1E SHA1 MD5E MD5 WORM URL+ remote types: git gcrypt S3 bup directory rsync web bittorrent webdav tahoe glacier ddar hook external+ local repository version: unknown+ supported repository version: 5+ upgrade supported from repository versions: 0 1 2 4+ Carls-MacBook-Air:CurveDe carlmod$ uname -a+ Darwin Carls-MacBook-Air.local 14.5.0 Darwin Kernel Version 14.5.0: Wed Jul 29 02:26:53 PDT 2015; root:xnu-2782.40.9~1/RELEASE_X86_64 x86_64++++### Please provide any additional information below.++[[!format sh """+# If you can, paste a complete transcript of the problem occurring here.+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log+time_machine_carl@pi:/media/backup_hdd/carl/annex$ git annex fsck --incremental-schedule 30d --time-limit 10m+fsck 15 minutes/2014-12-15_Chorkonzert_ Gesungene Vorfreude auf das Christkind - Nachrichten Augsburg-Land, Gersthofen, Neusäß - Augsburger Allgemeine.pdf (checksum...)+ok+fsck 15 minutes/2014_midnattsloppet.pdf (checksum...)+ok+<Snip lots of files>+fsck Deklaration/archive/2014/SE/Bilagor/2013-12-31_SEB Årsbesked.pdf (checksum...)+ok++ Time limit (10m) reached!+time_machine_carl@pi:/media/backup_hdd/carl/annex$ git annex fsck --incremental-schedule 30d --time-limit 10m+fsck 15 minutes/2014-12-15_Chorkonzert_ Gesungene Vorfreude auf das Christkind - Nachrichten Augsburg-Land, Gersthofen, Neusäß - Augsburger Allgemeine.pdf (checksum...)+ok+fsck 15 minutes/2014_midnattsloppet.pdf (checksum...)+ok++# End of transcript or log.+"""]]++### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)++I manage all my important personal documents since about two or three years, spreading them out over home servers, cloud providers and off site usb-drives in foreign countries, making sure that there are always at least 4 copies available. (if my flat burns the same day that box.com goes bankrupt ...)++> [[done]] per comments --[[Joey]]
+ doc/bugs/gcrypt_special_remote_fails_on_bare_remote_repos.mdwn view
@@ -0,0 +1,39 @@+Creating a gcrypt remote on a remote bare repository fails: it tries to modify the config file in the wrong path:++(problem is in last line)++```+$ git annex initremote qech type=gcrypt encryption=hybrid gitrepo=~/astro.git keyid=0BA74AC5B9494715+initremote qech (encryption setup) (hybrid cipher with gpg key 0BA74AC5B9494715) gcrypt: Development version -- Repository format MAY CHANGE+gcrypt: Decrypting manifest+gpg: Signature made Son 13 Sep 2015 19:37:16 CEST using RSA key ID B9494715+gpg: Good signature from "Arian Sanusi <arian@sanusi.ch>"+gpg: aka "Arian Sanusi <arian@sanusi.de>"+gpg: aka "Arian Sanusi <asanusi@student.ethz.ch>"+gpg: aka "Arian Sanusi <arian@guave.org>"+gpg: aka "Arian Sanusi <asanusi@ethz.ch>"+gpg: aka "Arian Sanusi <arian@semioptimal.net>"+gcrypt: Remote ID is :id:1+DP8KgrbsvpSycQ5QKO+Von gcrypt::/home/arian-debian-ssd/astro+ * [neuer Branch] git-annex -> qech/git-annex+gcrypt: Development version -- Repository format MAY CHANGE+gcrypt: Decrypting manifest+gpg: Signature made Son 13 Sep 2015 19:37:16 CEST using RSA key ID B9494715+gpg: Good signature from "Arian Sanusi <arian@sanusi.ch>"+gpg: aka "Arian Sanusi <arian@sanusi.de>"+gpg: aka "Arian Sanusi <asanusi@student.ethz.ch>"+gpg: aka "Arian Sanusi <arian@guave.org>"+gpg: aka "Arian Sanusi <asanusi@ethz.ch>"+gpg: aka "Arian Sanusi <arian@semioptimal.net>"+Everything up-to-date+error: could not lock config file /home/arian-debian-ssd/astro.git/.git/config: Datei oder Verzeichnis nicht gefunden+git-annex: git [Param "config",Param "core.gcrypt-id",Param ":id:1+DP8KgrbsvpSycQ5QKO"] failed+```++debian stretch *pre gcc5* on amd64 here:++```+i git 1:2.5.1-1 amd64+ii git-annex 5.20150812-2 amd64+ii git-remote-gcrypt 0.20130908-7 all+```
+ doc/bugs/git-annex_branch_not_being_pushed_after_git-annex_forget.mdwn view
@@ -0,0 +1,30 @@+### Please describe the problem.+I have a repository that is being synced with a normal Bitbucket git repository (with `annex-ignore = true`). It's been created with the webapp in direct mode and I'm using the assistant.++Everything is working fine, but after running `git annex forget` the git-annex branch in Bitbucket stopped being pushed. git-annex is still working correctly, but I have a lot of useless commits in the history.++So currently I have this branches:++ # git branch -a+ * annex/direct/master+ git-annex+ master+ synced/master+ remotes/bitbucket/git-annex+ remotes/bitbucket/master+ remotes/bitbucket/synced/git-annex+ remotes/bitbucket/synced/master++And `remotes/bitbucket/git-annex` isn't being updated with the content of `git-annex`++### What version of git-annex are you using? On what operating system?++5.20150812 and 5.20150731 in Debian Sid and Testing++### Please provide any additional information below.++As I've said, git-annex is still working normally, so the solution might be to simply remove that branch.++### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)++I use `git-annex` daily with 3 repositories with a total of ~112GB, and I'm really happy with it. Thank you very much for the effort.
+ doc/bugs/git-annex_can__39__t_find_gpg_if_it__39__s_named_gpg2.mdwn view
@@ -0,0 +1,21 @@+### Please describe the problem.++git-annex requires a `gpg -> gpg2` alias, which is dangerous for other software to misuse.++### What steps will reproduce the problem?++Run any gpg-requiring operation on a machine that has only gpg2 installed and no gpg alias.++ gpg: createProcess: runInteractiveProcess: exec: does not exist (No such file or directory)++### What version of git-annex are you using? On what operating system?++git-annex version: 5.20150710++OS X, gpg2 installed with brew++### Have you had any luck using git-annex before?++git-annex took some time to get in the mentality and configure, but now it's a beautiful perfectly oiled file management system. Thanks!++> git.program support now implemented, [[done]] --[[Joey]]
+ doc/bugs/git_annex_info_is_reporting_file_as_not_annexed_in_direct_mode.mdwn view
@@ -0,0 +1,38 @@+### Please describe the problem.++I was thinking to answer Emanuele's question in forum (http://git-annex.branchable.com/forum/test_whether_a_file_is_already_annexed/) but realized that 'info' is not the way :-/ (whereis could be used I guess)++### What version of git-annex are you using? On what operating system?++5.20150826+gitg87972f5-1~ndall+1++### Please provide any additional information below.++[[!format sh """++$> git annex indirect +commit ok+indirect 1.dat ok+indirect ok+ok++$> git annex info 1.dat+file: 1.dat+size: 4 bytes+key: SHA256E-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b.dat++$> git annex direct +commit +On branch master+nothing to commit, working directory clean+ok+direct 1.dat ok+direct ok++$> git annex info 1.dat+git-annex: 1.dat is not a directory or an annexed file or a remote or a uuid+++"""]]++> [[fixed|done]] --[[Joey]]
doc/bugs/hPutChar_error_message_with_UTF-8_chars_above_7F_in_filenames.mdwn view
@@ -76,3 +76,5 @@ # End of transcript or log. """]]++> [[fixed|done]] --[[Joey]]
+ doc/bugs/wget_invocation_should_get_timeout_options.mdwn view
@@ -0,0 +1,14 @@+### Please describe the problem.++Currently if download stalls the whole 'annex get' stalls -- I have been watching the terminal with 0% for an hour now ;)++You could test that on http://github.com/datalad/mlbooks annex, just get+G.James_D.Witten_T.Hastie_R.Tibshirani-An_Introduction_to_Statistical_Learning_with_Applications_in_R.pdf++original url for the file is http://www-bcf.usc.edu/~gareth/ISL/ISLR%20Fourth%20Printing.pdf+and wgetting works for me on some boxes but not on the other, forgot why so++### What version of git-annex are you using? On what operating system?++5.20150706+gitgefc3bcd-1~ndall+1 and tried in clean debian sid docker with 5.20150812-2+
doc/bugs/windows_ssh_webapp_password_entry_broken.mdwn view
@@ -3,3 +3,7 @@ Using ssh on windows with an existing remote does work. So as a workaround, set up a passwordless ssh key that can log into the ssh server. --[[Joey]]++> I have a `winprocfix` branch that uses process-1.3 which has been+> enhanced to allow fixing this. Merging is currently blocked on+> <https://github.com/pcapriotti/optparse-applicative/issues/153> --[[Joey]]
doc/builds.mdwn view
@@ -45,3 +45,5 @@ <h2><a href="https://buildd.debian.org/status/package.php?p=git-annex&suite=sid">Debian</a></h2> <iframe width=1024 scrolling=no height=500px frameborder=0 marginheight=0 marginwidth=0 src="https://buildd.debian.org/status/package.php?p=git-annex&suite=sid"> </iframe>+<iframe width=1024 scrolling=yes height=500px frameborder=0 marginheight=0 marginwidth=0 src="http://matrix.hackage.haskell.org/package/git-annex">+</iframe>
doc/design/external_special_remote_protocol.mdwn view
@@ -134,7 +134,7 @@ (without downloading it). The remote replies with one of `CHECKURL-FAILURE`, `CHECKURL-CONTENTS`, or `CHECKURL-MULTI`. * `WHEREIS Key`- Asks the remote to provide any information it can about ways to access+ Asks the remote to provide additional information about ways to access the content of a key stored in it, such as eg, public urls. This will be displayed to the user by eg, `git annex whereis`. The remote replies with `WHEREIS-SUCCESS` or `WHEREIS-FAILURE`.
doc/design/metadata.mdwn view
@@ -177,7 +177,7 @@ * Metadata should be copied to the new key when adding a modified version of a file. **done** -* Filesystems that are not case sensative (including case preserving OSX)+* Filesystems that are not case sensitive (including case preserving OSX) will cause problems if view branches try to use different cases for 2 directories representing a metadata field.
+ doc/devblog/day_315__scrambling.mdwn view
@@ -0,0 +1,5 @@+Today was a scramble to get caught up after weeks away. Got the message+backlog down from over 160 to 123. Fixed two reversions, worked around a+[strange bug](https://github.com/yesodweb/persistent/issues/474),+and implemented support for the `gpg.program` configuration, and made+several smaller improvements.
+ doc/devblog/day_316-318__chasing_dependencies_and_todos.mdwn view
@@ -0,0 +1,24 @@+Seems that Git for Windows was released a few weeks ago, replacing msysgit.+There were a couple problems using git-annex with that package of git,+which I fixed on Thursday. The next release of git-annex won't work with+msysgit any longer though; only with Git for Windows.++On Friday, I improved the Windows package further, making it work even when+git is not added to the system PATH. In such an installation, git-annex+will now work inside the "git bash" window, and I even got the webapp+starting from the menu working without git in PATH.++----++In other dependency fun, the daily builds for Linux got broken due to a+glibc bug in Debian unstable/testing, which makes the bundled curl and ssh+segfault. With some difficulty I tracked that down, and it turns out the+bug has been [fixed upstream](https://sourceware.org/bugzilla/show_bug.cgi?id=16381)+for quite a while. The daily builds are now using the fixed glibc 2.21.++----++Today, got back to making useful improvements, rather than chasing+dependencies. Improved the bash completion for remotes and backends,+made annex.hardlink be used more, and made special remotes that are+configured with autoenable=true get automatically enabled by `git annex init`.
+ doc/encryption/comment_3_46e64e4856975706e06e2a012a5d8f67._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="whlabratz@d10941ab2681deb87122fd8f6da51f3dcdb8dbe5"+ nickname="whlabratz"+ subject="Listing GPG keys enabled for a remote with hybrid encryption"+ date="2015-09-15T22:37:35Z"+ content="""+Is there a straight-forward way to list which GPG keys are enabled for a particular remote?+"""]]
+ doc/forum/Add_file_to_git_index_while_in_direct_mode.mdwn view
@@ -0,0 +1,20 @@+Hi, ++Is there a preferred way to add files to git's index (instead of the annex) while in direct mode? ++I am trying to use git-annex for scientific data. On linux and mac in indirect mode, the git workflow is basically unchanged, and I really like the way git annex works. Unfortunately when I use git-annex on Windows, I have not found a good way to add things to git's tree. ++I've tried two things:++```+$ git annex proxy -- git add smallfile+```++This is slow because it has to copy things over to create a work tree++```+$ git config annex.largefiles="*.pdf or *.h5"+$ git annex add largefile.pdf+```++This doesn't seem to work as well as I'd like either. I'd like the equivalent of a ```git add``` command in direct mode.
+ doc/forum/Backend_migration_and_special_remotes.mdwn view
@@ -0,0 +1,22 @@+I have a large repository that is backed up to hubiC with the [special remote that I wrote](https://github.com/Schnouki/git-annex-remote-hubic). When I created this repository I used the WORM backend. But as I have some duplicated files I'd like to migrate to SHA256E to avoid storing them twice. However, when migrating a file, its location on the remote is not kept:++ % git annex whereis "2015-07-25 12.28.16.jpg"+ whereis 2015-07-25 12.28.16.jpg (2 copies) + 23fa590d-682d-43be-9851-8ba47186d763 -- [hubic]+ f6642b89-2a0f-4788-8e13-be540fdfec58 -- baldr [here]+ ok+ + % git annex migrate "2015-07-25 12.28.16.jpg" --backend SHA256E+ migrate 2015-07-25 12.28.16.jpg ok + (recording state in git...)+ + % git annex whereis "2015-07-25 12.28.16.jpg"+ whereis 2015-07-25 12.28.16.jpg (1 copy) + f6642b89-2a0f-4788-8e13-be540fdfec58 -- baldr [here]+ ok++Is there any way to store in the git-annex branch that migrated files are still available on remotes without having to re-upload all of them? hubiC is quite slow and I don't really want to re-upload 90 GB from a DSL connection…++Or would it be possible to add something in the special remote protocol to "move" a key without re-uploading it?++Thanks!
+ doc/forum/Central_server_with_automatically_merged_working_tree.mdwn view
@@ -0,0 +1,30 @@+I would appreciate some feedback on whether the following scheme is feasible or will prove unworkable. I have a few specific questions at the bottom.++# Components+* An archive of documents to be shared amongst computers+* A server that stores the archive and retains all of its contents+* A set of client machines that store only the files that they need and drop the rest++# Desired behavior+* Clients will run the assistant to handle sync'ing+* On the server, the archive should be accessible in the working tree so that other users can read the files (they do not need write access).+* It should be possible to modify the archive on the server while logged into the server+* Clients can push and pull data. The server does not push or pull data.++# Basic setup+## Set up the server and one client+* Create git annex repos on the client and server+* Add the server as a remote in the client repo++## Keep the server's working directory up to date+* Add `git merge synced/master master` to the `annex-content` hook described [here](https://git-annex.branchable.com/git-annex-shell/).+* Add `git merge synced/master master` to the `post-receive` hook.++## Keep server working tree visible to a different group+* Set `git config core.sharedrepository group` for the repository+* Add `chgrp -R shared "$(git rev-parse --show-toplevel)"` to the `annex-content`, `post-receive`, and `post-merge` hooks, where `shared` is the name of the group that you want to be able to access the server files.++# Questions+* I had to add the `post-receive` hook because updates from the assistant were not trigger the `annex-content` hook. Should they trigger it?+* Are there downsides to merging `synced/master` like this?+* If I want to edit files on the server, is it safe to edit them in the repo with this set up? Or should I create a second client repo on the server, check out the necessary files there, and then push them to the server like I would from any other client?
+ doc/forum/How_to_define_a_balanced_prefered_content.mdwn view
@@ -0,0 +1,5 @@+I have 6 drives attached to my box and I am trying to split them in to 2 groups I would like to have 2 balanced groups [1] so each file lands on two of these disks. So assuming i have disks A B C D E F, I want to create two balanced groups A B C and D E F. But I can not figure out how to defined rules using balanced_amoung(group) expression in vicfg. The only place it allows me to use the expression is the group section but how do i define a group that uses a balanced group.++++[1] https://git-annex.branchable.com/design/balanced_preferred_content/
+ doc/forum/Layout_mismatch_between_symlinks_and_annex_objects.mdwn view
@@ -0,0 +1,14 @@+I have an old repository, and I'm not sure what I have done with it, but it seems to be broken in an interesting fashion.++ $ ls -l pix/image001.jpg + lrwxrwxrwx 1 la la 187 Sep 5 11:31 pix/image001.jpg -> ../.git/annex/objects/G7/J7/SHA256-s99372--0458b0b72b394a719b72032971b880a8dfafa65e8048ec6fc6c861fc3ea5e702/SHA256-s99372--0458b0b72b394a719b72032971b880a8dfafa65e8048ec6fc6c861fc3ea5e702+ $ ls -lL pix/image001.jpg + ls: cannot access pix/image001.jpg: No such file or directory+ $ find .git/annex/objects/ -type f -name '*0458b0b72*'+ .git/annex/objects/477/75c/SHA256-s99372--0458b0b72b394a719b72032971b880a8dfafa65e8048ec6fc6c861fc3ea5e702/SHA256-s99372--0458b0b72b394a719b72032971b880a8dfafa65e8048ec6fc6c861fc3ea5e702+ $ git config annex.version+ 5++So the symlinks use a layout where index directories have two-letter names, but the actual layout in the annex uses directory names with three hexadecimal digits.++Is there some straightforward way to fix this or do I need to figure the index format and hack up a script to convert the annex repository?
+ doc/forum/Multiple_machine_remotes_on_external_drive.mdwn view
@@ -0,0 +1,7 @@+I have a question about remotes behavior on external drives.++Say I have two machines A and B each with a git annex repository at `~/repo`, and an external drive C with the same repository at `/repo`.++I can add C remotes for A and B at, for example, `/media/hdd/repo`, but I'm not certain how it works for C.++Do I stick C into A and add a remote A at path `~/repo`, then stick C into B and add a remote B with the same path `~/repo`? Does git annex handle this sanely?
+ doc/forum/git-annex_does_not_respect_preferred_content_settings.mdwn view
@@ -0,0 +1,18 @@+I have the following vicfg,++ group UUID1 = PodA+ group UUID2 = PodA+ group UUID3 = PodA+ group UUID4 = PodB++ wanted UUID1 = groupwanted+ wanted UUID2 = groupwanted+ wanted UUID3 = groupwanted+ wanted UUID4 = groupwanted++ groupwanted PodA = present and not copies=PodA:1+ groupwanted PodB = present and not copies=PodB:1++at this point repos 1 2 3 combined has 1 copy of each file and repo 4 has full copy of all files. (used to move files around manually before grouping repos). ++What I am trying to achieve is to have a copy of a file in one of the 3 repos (1 2 3) and one copy in 4. running git annex get --auto starts getting all files, files with copies on other disks. testing using git annex find --want-get --not --in . returns all remaining files not in the repo but has enough copies on other repos both PodA and PodB has copies. numofcopies is set to 2.
+ doc/forum/removing_remote.log_information_completely.mdwn view
@@ -0,0 +1,9 @@+in [[forum/remote-specific_meta-data/]], we have learned how to insert our own remote-specific metadata, in remote.log. now, we need a way to remove that data. for some reason, injecting commits in the `git-annex` branch doesn't quite work, because other assistants will overwrite that merge thanks to the [[git-union-merge]] driver.++so far, i have found that it *can* be possible to work around this problem by repeatedly doing commits on the git-annex branch and running `git-annex sync` by hand after. it stumbles and flips around for a while, but eventually does it. it does create nice sparkles in gitk: ++]++What is the proper way of removing entries from `remote.log`? How about propagating changes to the `synced/git-annex` branch? I can generate commits on `git-annex` using the git-annex index, and on the `git-annex` branch. But how should those changes be propagated to other branches?++Thanks! --[[anarcat]]
+ doc/forum/test_whether_a_file_is_already_annexed.mdwn view
@@ -0,0 +1,1 @@+I am storing the pictures I took over the years with git-annex. Frequently I come across messy old directories with lots of pictures inside and I want to know which ones were already annexed - or which ones were not. Is there a quick way to test whether the content of a given file is already annexed? I mean computing the key (hash) of the given file and testing whether it is already present among the annex objects.
doc/git-annex-enableremote.mdwn view
@@ -19,14 +19,14 @@ Some special remotes may need parameters to be specified every time they are enabled. For example, the directory special remote requires a directory=-parameter.- +parameter every time.+ This command can also be used to modify the configuration of an existing-special remote, by specifying new values for parameters that were-originally set when using initremote. (However, some settings such as+special remote, by specifying new values for parameters that are+usually set when using initremote. (However, some settings such as the as the encryption scheme cannot be changed once a special remote has been created.)- + The GPG keys that an encrypted special remote is encrypted with can be changed using the keyid+= and keyid-= parameters. These respectively add and remove keys from the list. However, note that removing a key@@ -44,6 +44,12 @@ on files that have already been copied to the remote. Hence using keyid+= and keyid-= with such remotes should be used with care, and make little sense except in cases like the revoked key example above.++If you get tired of manually enabling a special remote in each new clone,+you can pass "autoenable=true". Then when [[git-annex-init]](1) is run in+a new clone, it will will attempt to enable the special remote. Of course,+this works best when the special remote does not need anything special+to be done to get it enabled. # SEE ALSO
doc/git-annex-init.mdwn view
@@ -16,6 +16,14 @@ of a repository with its own description. If you don't provide one, one will be generated using the username, hostname and the path. +If any special remotes were configured with autoenable=true,+this will also attempt to enable them. See [[git-annex-initremote]](1).+To disable this, re-enable a remote with "autoenable=false", or+mark it as dead (see [[git-annex-dead]](1)).++This command is entirely safe, although usually pointless, to run inside an+already initialized git-annex repository.+ # SEE ALSO [[git-annex]](1)
doc/git-annex-initremote.mdwn view
@@ -36,6 +36,12 @@ to the specified GPG keys, and additional ones cannot easily be given access. +If you anticipate using the new special remote in other clones of the+repository, you can pass "autoenable=true". Then when [[git-annex-init]](1)+is run in a new clone, it will attempt to enable the special remote. Of+course, this works best when the special remote does not need anything+special to be done to get it enabled.+ # OPTIONS * `--fast`
doc/git-annex-reinit.mdwn view
@@ -17,6 +17,9 @@ repositories with the same UUID. Also, you will probably want to run a fsck. +Like `git annex init`, this attempts to enable any special remotes+that are configured with autoenable=true.+ # SEE ALSO [[git-annex]](1)
doc/git-annex-sync.mdwn view
@@ -36,21 +36,33 @@ # OPTIONS +* `--fast`++ Only sync with the remotes with the lowest annex-cost value configured.++* `--commit`, `--no-commit`++ A commit is done by default. Use --no-cmmit to avoid committing local changes.+ * `--message=msg` Use this option to specify a commit message. -* `--fast`+* `--pull`, `--no-pull` - Only sync with the remotes with the lowest annex-cost value configured.+ By default, git pulls from remotes. Use --no-pull to disable. -* `--content`+* `--push`, `--no-push` + By default, git pushes to remotes. Use --no-push to disable.++* `--content`, `--no-content`+ Normally, syncing does not transfer the contents of annexed files.- This option causes the content of files in the work tree+ The --content option causes the content of files in the work tree to also be uploaded and downloaded as necessary. - By default, this tries to get each annexed file in the work tree+ Normally this tries to get each annexed file in the work tree that the local repository does not yet have, and then copies each file in the work tree to every remote that it is syncing with. This behavior can be overridden by configuring the preferred content
doc/git-annex.mdwn view
@@ -793,7 +793,7 @@ to be large enough to need to be added to the annex. By default, all files are added to the annex. - The value is a preferred content expression. See PREFERRED CONTENT+ The value is a preferred content expression. See [[git-annex-preferred-content]](1) for details. Example:@@ -875,8 +875,8 @@ * `annex.hardlink` - Set this to `true` to make file contents be hard linked into the- repository when possible, instead of a more expensive copy.+ Set this to `true` to make file contents be hard linked between the+ repository and its remotes when possible, instead of a more expensive copy. Use with caution -- This can invalidate numcopies counting, since with hard links, fewer copies of a file can exist. So, it is a good
doc/install.mdwn view
@@ -13,6 +13,7 @@ [[ArchLinux]] | `yaourt -Sy git-annex-bin` [[NixOS]] | `nix-env -i git-annex` [[Gentoo]] | `emerge git-annex`+ [[Void]] | `xbps-install git-annex` [[ScientificLinux5]] | [[openSUSE]] | [[Docker]] |
doc/install/Windows.mdwn view
@@ -1,7 +1,7 @@ git-annex now does Windows! -* First, [install git](http://git-scm.com/downloads) (msysgit 1.9 or newer is needed) - _Be sure to tell the msysgit installer to add git to the PATH._+* First, [install msysgit](http://git-scm.com/downloads) (msysgit 1.9 is needed) + _Be sure to tell the installer to add git to the PATH._ That is, select "Use Git from the Windows Command Prompt" * Then, [install git-annex](https://downloads.kitenet.net/git-annex/windows/current/) @@ -20,6 +20,8 @@ A daily build is also available, thanks to Yury V. Zaytsev and [NEST](http://nest-initiative.org/). +This daily build now needs git for windows, not msysgit.+ * [download](https://downloads.kitenet.net/git-annex/autobuild/windows/) ([build logs](https://qa.nest-initiative.org/view/msysGit/job/msysgit-git-annex-assistant-test/)) ## building it yourself@@ -36,7 +38,7 @@ build Note that git from Cygwin is able to clone git-annex's git repository;-Msysgit cannot due to some characters in filenames.+Regular git for Windows cannot due to some characters in filenames. (To build the git-annex installer, you also need to install the NullSoft installer system.)
+ doc/install/Windows/comment_1_e5e5c7b75859493a7d94cbf7df746fb9._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="jpfeifer@4c6cf56b857caa324cbbc9f133705fb2fb3f9bef"+ nickname="jpfeifer"+ subject="Compatibility with recent version of Git for Windows"+ date="2015-09-02T17:58:41Z"+ content="""+Git for Windows now has a 64 bit version. Thus, the installation path must be adjusted accordingly. This page should note that git annex must be installed in the same folder as git itself.+"""]]
doc/news/version_5.20150824.mdwn view
@@ -24,3 +24,7 @@ * As a result of the Makefile changes, the Debian package is built with various hardening options. Although their benefit to a largely haskell program is unknown."""]]++Note: The x86-64 bit linux standalone tarball shipped with this version had+a broken version of ssh that crashed on startup. The tarball has been+updated to fix this problem.
+ doc/news/version_5.20150916.mdwn view
@@ -0,0 +1,32 @@+git-annex 5.20150916 released with [[!toggle text="these changes"]]+[[!toggleable text="""+ * Fix Windows build to work with ghc 7.10.+ * init: Fix reversion in detection of repo made with git clone --shared+ * info: Support querying info of individual files in direct mode.+ * unused: Fix reversion in 5.20150727 that broke parsing of the+ --unused-refspec option. Thanks, Øyvind A. Holm.+ * Make full option parsing be done when not in a git repo, so --help+ can be displayed for commands that require a git repo, etc.+ * fsck: Work around bug in persistent that broke display of+ problematically encoded filenames on stderr when using --incremental.+ * When gpg.program is configured, it's used to get the command to run+ for gpg. Useful on systems that have only a gpg2 command or want to+ use it instead of the gpg command.+ * Windows: Switched to using git for Windows, rather than msysgit.+ Using msysgit with git-annex is no longer supported.+ * Windows: Even when the user neglects to tell the git installer to+ add git to PATH, git-annex will still work from within the git bash+ shell, and the webapp can be used too.+ * sync: Add --no-commit, --no-pull, --no-push options to turn off parts of+ the sync process, as well as supporting --commit, --pull, --push, and+ --no-content options to specify the (current) default behavior.+ * annex.hardlink extended to also try to use hard links when copying from+ the repository to a remote.+ * Improve bash completion, so it completes names of remotes and backends+ in appropriate places.+ * Special remotes configured with autoenable=true will be automatically+ enabled when git-annex init is run.+ * Fix bug in combination of preferred and required content settings.+ When one was set to the empty string and the other set to some expression,+ this bug caused all files to be wanted, instead of only files matching+ the expression."""]]
doc/special_remotes.mdwn view
@@ -43,6 +43,7 @@ * [hubiC](https://github.com/Schnouki/git-annex-remote-hubic) * [pCloud](https://github.com/tochev/git-annex-remote-pcloud) * [[ipfs]]+* [Ceph](https://github.com/mhameed/git-annex-remote-ceph) Want to add support for something else? [[Write your own!|external]]
doc/templates/bugtemplate.mdwn view
@@ -16,3 +16,7 @@ # End of transcript or log. """]]++### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)++
+ doc/todo/annex.hardlink_should_also_affect_copy_to_origin.mdwn view
@@ -0,0 +1,7 @@+When a repo has annex.hardlink set, objects are hard-linked into the+repository when eg `git annex copy --from origin`. This should also+be done when copying files --to origin (or other remotes on the same+filesystem). This way, a quick shared clone can be used to add/modify+files, and cheaply send the changes back to the parent repo. --[[Joey]]++> [[done]] --[[Joey]]
+ doc/todo/autoenable__61__true_for_special_remotes.mdwn view
@@ -0,0 +1,20 @@+Just passing along from https://github.com/datalad/datalad/issues/77#issuecomment-134688459++joey: I do think there could be a use case for configuring a special remote with autoenable=true and have git-annex init try to enable all such remotes.++> [[done]], I made both `git init` and `git annex reinit` auto-enable+> such special remotes. For now, the assistant does not (could change).+> +> There was also the question of what to do when git-annex auto-inits+> in a clone of a repository. It wouldn't do for a command like+> `git annex find`'s output to include any messages that might be shown while+> auto-enabling special remotes as a result of an auto-init.+> Since I can't guarantee enabling special remotes will be quiet, I've not+> tried to auto-enable special remotes in this case. +> +> I think I'd have to+> exec a git-annex init process with stdout sent to stderr to implement+> this in a safe way, and due to calls to ensureInitialized in Remote.Git,+> which can auto-init a local remote, that gets particularly tricky. Best, I+> feel, to wait and see if anyone needs that.+--[[Joey]]
doc/todo/enable_a_discussion_forum_or_support_system.mdwn view
@@ -15,6 +15,8 @@ the only solution considering the first requirements, but let's give it a try. :) +[[!toc]]+ Stack exchange ==============
+ doc/todo/use_git-mktree_rather_than_index_file.mdwn view
@@ -0,0 +1,29 @@+When git-annex is updating the git-annex branch, it currently+uses a separate index file. This adds overhead and complexity to the code.+Especially when there are many files, the index file gets large and writing+it gets slow.++It might be an improvement to use `git mktree --batch` to inject a+tree object into git, without using the index file. `git hash-object`+is already used to add the files to git. All that would be needed is to+generate an updated tree containing the new file(s), and then update each+parent tree up to the root tree. This new tree can then be committed using+`git commit-tree`++The only thing I can see that might make this slow at all is reading the old+tree contents, in order to update it. This would need a `git ls-tree` for+each tree; it does not have a batch mode, so 4 processes would need to be+spawned when generating a tree that changes 1 file. For any repo that's not+very small, that's probably still faster than rewriting the index file.++Notes:++* The union merge code currently uses the index. No particular reason+ it needs to; that's just how the code is written, and it might be a large+ rewrite to change it.+* A new git-annex branch can be pushed into the repository at any time.+ The current code uses the index to detect when this happens, and+ union merges the new branch head into the index. Would need something+ like a `GIT_ANNEX_HEAD` ref to do the same if the index is removed.++Thanks to sm for indirectly suggesting this. --[[Joey]]
doc/todo/windows_support.mdwn view
@@ -69,13 +69,6 @@ has to connect twice to the remote system over ssh per file, which is much slower than on systems supporting connection caching. * glacier-cli is not easily available (probably)-* user feedback: "Git on windows installer provides openssh 4.6. git-annex installer- provides openssh 6.2 . This seems to create problems regarding how- `known_hosts` file path is setup. Setting `GIT_SSH=` to the git-annex- openssh version fixes the problem." - However, I don't know how to determine what that location is after- it's been installed. Maybe look for ssh.exe in same directory as- git-annex.exe? --[[Joey]] ## stuff needing testing
doc/trust.mdwn view
@@ -20,7 +20,7 @@ depended on to retain a copy of the file content; possibly the only [[copy|copies]]. -(Being semitrusted is the default. The `git annex semitrust` command+(Being semitrusted is the default. The [[git-annex semitrust|git-annex-semitrust]] command restores a repository to this default, when it has been overridden. The `--semitrust` option can temporarily restore a repository to this default.)@@ -34,7 +34,7 @@ if a disk is known to be dying, you can set it to untrusted and let `git annex fsck` warn about data that needs to be copied off it. -To configure a repository as untrusted, use the `git annex untrust`+To configure a repository as untrusted, use the [[git-annex untrust|git-annex-untrust]] command. ## trusted@@ -49,7 +49,7 @@ trust temporarily. To configure a repository as fully and permanently trusted,-use the `git annex trust` command.+use the [[git-annex-trust]] command. ## dead @@ -57,3 +57,6 @@ exists at all. It's appropriate to use when a drive has been lost, or a directory irretrievably deleted. It will make git-annex avoid even showing the repository as a place where data might still reside.++To configure a repository as dead and lost, use the [[git-annex-dead]]+command.
+ doc/users/dave.mdwn view
@@ -0,0 +1,1 @@+IM DAVE
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 5.20150824+Version: 5.20150916 Cabal-Version: >= 1.8 License: GPL-3 Maintainer: Joey Hess <id@joeyh.name>@@ -153,14 +153,11 @@ Build-Depends: cryptohash (>= 0.11.0) -- Fully optimize for production.- -- Parallel builds only when not building for production,- -- because ghc is known to not yield reproducible builds this way. if flag(Production) GHC-Options: -O2 if (os(windows)) Build-Depends: Win32, Win32-extras, unix-compat (>= 0.4.1.3), setenv- C-Sources: Utility/winprocess.c else Build-Depends: unix -- Need to list these because they're generated from .hsc files.
man/git-annex-enableremote.1 view
@@ -17,11 +17,11 @@ .PP Some special remotes may need parameters to be specified every time they are enabled. For example, the directory special remote requires a directory=-parameter.+parameter every time. .PP This command can also be used to modify the configuration of an existing-special remote, by specifying new values for parameters that were-originally set when using initremote. (However, some settings such as+special remote, by specifying new values for parameters that are+usually set when using initremote. (However, some settings such as the as the encryption scheme cannot be changed once a special remote has been created.) .PP@@ -42,6 +42,12 @@ on files that have already been copied to the remote. Hence using keyid+= and keyid\-= with such remotes should be used with care, and make little sense except in cases like the revoked key example above.+.PP+If you get tired of manually enabling a special remote in each new clone,+you can pass "autoenable=true". Then when git-annex\-init(1) is run in+a new clone, it will will attempt to enable the special remote. Of course,+this works best when the special remote does not need anything special+to be done to get it enabled. .PP .SH SEE ALSO git-annex(1)
man/git-annex-init.1 view
@@ -14,6 +14,14 @@ of a repository with its own description. If you don't provide one, one will be generated using the username, hostname and the path. .PP+If any special remotes were configured with autoenable=true,+this will also attempt to enable them. See git-annex\-initremote(1).+To disable this, re\-enable a remote with "autoenable=false", or+mark it as dead (see git-annex\-dead(1)).+.PP+This command is entirely safe, although usually pointless, to run inside an+already initialized git-annex repository.+.PP .SH SEE ALSO git-annex(1) .PP
man/git-annex-initremote.1 view
@@ -34,6 +34,12 @@ to the specified GPG keys, and additional ones cannot easily be given access. .PP+If you anticipate using the new special remote in other clones of the+repository, you can pass "autoenable=true". Then when git-annex\-init(1)+is run in a new clone, it will attempt to enable the special remote. Of+course, this works best when the special remote does not need anything+special to be done to get it enabled.+.PP .SH OPTIONS .IP "\fB\-\-fast\fP" .IP
man/git-annex-reinit.1 view
@@ -15,6 +15,9 @@ repositories with the same UUID. Also, you will probably want to run a fsck. .PP+Like \fBgit annex init\fP, this attempts to enable any special remotes+that are configured with autoenable=true.+.PP .SH SEE ALSO git-annex(1) .PP
man/git-annex-sync.1 view
@@ -33,19 +33,28 @@ by running "git annex sync" on the remote. .PP .SH OPTIONS-.IP "\fB\-\-message=msg\fP"+.IP "\fB\-\-fast\fP" .IP+Only sync with the remotes with the lowest annex\-cost value configured.+.IP+.IP "\fB\-\-commit\fP, \fB\-\-no\-commit\fP"+A commit is done by default. Use \-\-no\-cmmit to avoid committing local changes.+.IP+.IP "\fB\-\-message=msg\fP" Use this option to specify a commit message. .IP-.IP "\fB\-\-fast\fP"-Only sync with the remotes with the lowest annex\-cost value configured.+.IP "\fB\-\-pull\fP, \fB\-\-no\-pull\fP"+By default, git pulls from remotes. Use \-\-no\-pull to disable. .IP-.IP "\fB\-\-content\fP"+.IP "\fB\-\-push\fP, \fB\-\-no\-push\fP "+By default, git pushes to remotes. Use \-\-no\-push to disable.+.IP+.IP "\fB\-\-content\fP, \fB\-\-no\-content\fP" Normally, syncing does not transfer the contents of annexed files.-This option causes the content of files in the work tree+The \-\-content option causes the content of files in the work tree to also be uploaded and downloaded as necessary. .IP-By default, this tries to get each annexed file in the work tree+Normally this tries to get each annexed file in the work tree that the local repository does not yet have, and then copies each file in the work tree to every remote that it is syncing with. This behavior can be overridden by configuring the preferred content
man/git-annex.1 view
@@ -678,7 +678,7 @@ to be large enough to need to be added to the annex. By default, all files are added to the annex. .IP-The value is a preferred content expression. See PREFERRED CONTENT+The value is a preferred content expression. See git-annex\-preferred\-content(1) for details. .IP Example:@@ -751,8 +751,8 @@ index but not yet committed. .IP .IP "\fBannex.hardlink\fP"-Set this to \fBtrue\fP to make file contents be hard linked into the-repository when possible, instead of a more expensive copy.+Set this to \fBtrue\fP to make file contents be hard linked between the+repository and its remotes when possible, instead of a more expensive copy. .IP Use with caution \-\- This can invalidate numcopies counting, since with hard links, fewer copies of a file can exist. So, it is a good
standalone/windows/build-simple.sh view
@@ -4,10 +4,7 @@ set -e set -x -# Path to the Haskell Platform. (As mingw sh sees it)-HP="/c/Program Files/Haskell Platform/2014.2.0.0"--PATH="$HP/bin:$HP/mingw/bin:$HP/lib/extralibs/bin:/c/Program Files/Git/cmd:/c/Program Files/NSIS:$PATH"+PATH="/c/Program Files/Git/cmd:/c/Program Files/NSIS:$PATH" # Run a command with the cygwin environment available. # However, programs not from cygwin are preferred.@@ -31,14 +28,11 @@ withcyg cabal configure fi if ! withcyg cabal build; then- ghc --make Build/EvilLinker+ ghc --make Build/EvilLinker -fno-warn-tabs withcyg Build/EvilLinker fi # Build the installer cabal install nsis-ghc --make Build/NullSoftInstaller.hs-PATH="$PATH:/cygdrive/c/Program Files/NSIS"-# Want to include cygwin programs in bundle, not others, since-# it includes the cygwin libs that go with them.-withcygpreferred Build/NullSoftInstaller.exe+ghc --make Build/NullSoftInstaller.hs -fno-warn-tabs+PATH="$PATH:/cygdrive/c/Program Files/NSIS" Build/NullSoftInstaller.exe
standalone/windows/build.sh view
@@ -38,10 +38,6 @@ # for haskell libraries to link them with the cygwin library. cabal update || true -# This workaround is still needed, it seems.-#cabal install transformers-compat -fthree-#cabal install DAV-1.0- cabal install --only-dependencies || true # Detect when the last build was an incremental build and failed, @@ -58,20 +54,28 @@ withcyg cabal configure if ! withcyg cabal build; then rm -f Build/EvilLinker.exe- ghc --make Build/EvilLinker+ ghc --make Build/EvilLinker -fno-warn-tabs Build/EvilLinker fi -# Build the installer-cabal install nsis-ghc -fforce-recomp --make Build/NullSoftInstaller.hs-# Want to include cygwin programs in bundle, not others, since-# it includes the cygwin libs that go with them.-# Currently need an older version of rsync than the one from cygwin.-if [ ! -e rsync.exe ]; then+# Get extra programs to bundle with git-annex.+# These are msys2 programs, from https://msys2.github.io/.+# Since git for windows uses msys2, and includes its libraries,+# these programs will work well with it.+if [ ! -e rsync.exe ] || [ "$(sha1sum rsync.exe)" != "85cb7a4d16d274fcf8069b39042965ad26abd6aa" ]; then+ rm -f rsync.exe || true withcyg wget https://downloads.kitenet.net/git-annex/windows/assets/rsync.exe withcyg chmod +x rsync.exe fi+if [ ! -e wget.exe ] || [ "$(sha1sum wget.exe)" != "044380729200d5762965b10123a4f134806b01cf" ]; then+ rm -f wget.exe || true+ withcyg wget https://downloads.kitenet.net/git-annex/windows/assets/wget.exe+ withcyg chmod +x wget.exe+fi++# Build the installer+cabal install nsis+ghc -fforce-recomp --make Build/NullSoftInstaller.hs -fno-warn-tabs PATH=".:/c/cygwin/bin:$PATH" Build/NullSoftInstaller.exe rm -f last-incremental-failed
− standalone/windows/ssh-keygen.cmd
@@ -1,31 +0,0 @@-@rem Do not use "echo off" to not affect any child calls. - -@rem Enable extensions, the `verify other 2>nul` is a trick from the setlocal help -@verify other 2>nul -@setlocal enableDelayedExpansion -@if errorlevel 1 ( - @echo Unable to enable delayed expansion. Immediate expansion will be used. - @goto fallback -) - -@rem Get the absolute path to the parent directory, which is assumed to be the -@rem Git installation root. -@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI -@set PATH=!git_install_root!\bin;!git_install_root!\mingw\bin;!PATH! - -ssh-keygen %* -@goto end - -:fallback -@rem The above script again with immediate expansion, in case delayed expansion -@rem is unavailable. -@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI -@set PATH=%git_install_root%\bin;%git_install_root%\mingw\bin;%PATH% - -@if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH% -@if not exist "%HOME%" @set HOME=%USERPROFILE% - -ssh-keygen %* - -:end -@rem End of script
− standalone/windows/ssh.cmd
@@ -1,31 +0,0 @@-@rem Do not use "echo off" to not affect any child calls. - -@rem Enable extensions, the `verify other 2>nul` is a trick from the setlocal help -@verify other 2>nul -@setlocal enableDelayedExpansion -@if errorlevel 1 ( - @echo Unable to enable delayed expansion. Immediate expansion will be used. - @goto fallback -) - -@rem Get the absolute path to the parent directory, which is assumed to be the -@rem Git installation root. -@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI -@set PATH=!git_install_root!\bin;!git_install_root!\mingw\bin;!PATH! - -ssh %* -@goto end - -:fallback -@rem The above script again with immediate expansion, in case delayed expansion -@rem is unavailable. -@for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI -@set PATH=%git_install_root%\bin;%git_install_root%\mingw\bin;%PATH% - -@if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH% -@if not exist "%HOME%" @set HOME=%USERPROFILE% - -ssh %* - -:end -@rem End of script