git-annex 6.20160808 → 6.20160907
raw patch · 26 files changed
+301/−155 lines, 26 files
Files
- Annex.hs +52/−48
- Annex/Transfer.hs +59/−2
- Assistant/Pairing/Network.hs +5/−2
- Assistant/Threads/PairListener.hs +8/−5
- Build/Configure.hs +4/−5
- Build/mdwn2man +1/−1
- CHANGELOG +18/−0
- CmdLine.hs +1/−1
- Command.hs +3/−12
- Command/ExamineKey.hs +6/−5
- Command/Get.hs +10/−9
- Command/Sync.hs +1/−2
- Git/Fsck.hs +2/−0
- Git/Hook.hs +2/−19
- Logs/Transfer.hs +0/−12
- Messages/Concurrent.hs +6/−2
- Messages/Progress.hs +3/−1
- Remote/External.hs +14/−11
- Test.hs +1/−1
- Types/Command.hs +3/−1
- Types/Transfer.hs +13/−0
- Utility/Shell.hs +42/−0
- Utility/WebApp.hs +2/−2
- doc/git-annex-get.mdwn +2/−1
- doc/git-annex-smudge.mdwn +1/−1
- git-annex.cabal +42/−12
Annex.hs view
@@ -77,7 +77,7 @@ - The MVar is not exposed outside this module. - - Note that when an Annex action fails and the exception is caught,- - ny changes the action has made to the AnnexState are retained,+ - any changes the action has made to the AnnexState are retained, - due to the use of the MVar to store the state. -} newtype Annex a = Annex { runAnnex :: ReaderT (MVar AnnexState) IO a }@@ -135,56 +135,60 @@ , desktopnotify :: DesktopNotify , workers :: [Either AnnexState (Async AnnexState)] , concurrentjobs :: Maybe Int+ , activeremotes :: MVar (S.Set (Types.Remote.RemoteA Annex)) , keysdbhandle :: Maybe Keys.DbHandle , cachedcurrentbranch :: Maybe Git.Branch } -newState :: GitConfig -> Git.Repo -> AnnexState-newState c r = AnnexState- { repo = r- , repoadjustment = return- , gitconfig = c- , backends = []- , remotes = []- , remoteannexstate = M.empty- , output = def- , force = False- , fast = False- , daemon = False- , branchstate = startBranchState- , repoqueue = Nothing- , catfilehandles = M.empty- , hashobjecthandle = Nothing- , checkattrhandle = Nothing- , checkignorehandle = Nothing- , forcebackend = Nothing- , globalnumcopies = Nothing- , forcenumcopies = Nothing- , limit = BuildingMatcher []- , uuidmap = Nothing- , preferredcontentmap = Nothing- , requiredcontentmap = Nothing- , forcetrust = M.empty- , trustmap = Nothing- , groupmap = Nothing- , ciphers = M.empty- , lockcache = M.empty- , flags = M.empty- , fields = M.empty- , cleanup = M.empty- , sentinalstatus = Nothing- , useragent = Nothing- , errcounter = 0- , unusedkeys = Nothing- , tempurls = M.empty- , quviversion = Nothing- , existinghooks = M.empty- , desktopnotify = mempty- , workers = []- , concurrentjobs = Nothing- , keysdbhandle = Nothing- , cachedcurrentbranch = Nothing- }+newState :: GitConfig -> Git.Repo -> IO AnnexState+newState c r = do+ emptyactiveremotes <- newMVar S.empty+ return $ AnnexState+ { repo = r+ , repoadjustment = return+ , gitconfig = c+ , backends = []+ , remotes = []+ , remoteannexstate = M.empty+ , output = def+ , force = False+ , fast = False+ , daemon = False+ , branchstate = startBranchState+ , repoqueue = Nothing+ , catfilehandles = M.empty+ , hashobjecthandle = Nothing+ , checkattrhandle = Nothing+ , checkignorehandle = Nothing+ , forcebackend = Nothing+ , globalnumcopies = Nothing+ , forcenumcopies = Nothing+ , limit = BuildingMatcher []+ , uuidmap = Nothing+ , preferredcontentmap = Nothing+ , requiredcontentmap = Nothing+ , forcetrust = M.empty+ , trustmap = Nothing+ , groupmap = Nothing+ , ciphers = M.empty+ , lockcache = M.empty+ , flags = M.empty+ , fields = M.empty+ , cleanup = M.empty+ , sentinalstatus = Nothing+ , useragent = Nothing+ , errcounter = 0+ , unusedkeys = Nothing+ , tempurls = M.empty+ , quviversion = Nothing+ , existinghooks = M.empty+ , desktopnotify = mempty+ , workers = []+ , concurrentjobs = Nothing+ , activeremotes = emptyactiveremotes+ , keysdbhandle = Nothing+ , cachedcurrentbranch = Nothing+ } {- Makes an Annex state object for the specified git repo. - Ensures the config is read, if it was not already, and performs@@ -193,7 +197,7 @@ new r = do r' <- Git.Config.read =<< Git.relPath r let c = extractGitConfig r'- newState c <$> fixupRepo r' c+ newState c =<< fixupRepo r' c {- Performs an action in the Annex monad from a starting state, - returning a new state. -}
Annex/Transfer.hs view
@@ -1,11 +1,11 @@ {- git-annex transfers -- - Copyright 2012-2014 Joey Hess <id@joeyh.name>+ - Copyright 2012-2016 Joey Hess <id@joeyh.name> - - Licensed under the GNU GPL version 3 or higher. -} -{-# LANGUAGE CPP, FlexibleInstances #-}+{-# LANGUAGE CPP, FlexibleInstances, BangPatterns #-} module Annex.Transfer ( module X,@@ -15,9 +15,11 @@ alwaysRunTransfer, noRetry, forwardRetry,+ pickRemote, ) where import Annex.Common+import qualified Annex import Logs.Transfer as X import Types.Transfer as X import Annex.Notification as X@@ -25,8 +27,10 @@ import Utility.Metered import Annex.LockPool import Types.Remote (Verification(..))+import qualified Types.Remote as Remote import Control.Concurrent+import qualified Data.Set as S class Observable a where observeBool :: a -> Bool@@ -166,3 +170,56 @@ - to send some data. -} forwardRetry :: RetryDecider forwardRetry old new = bytesComplete old < bytesComplete new++{- Picks a remote from the list and tries a transfer to it. If the transfer+ - does not succeed, goes on to try other remotes from the list.+ -+ - The list should already be ordered by remote cost, and is normally+ - tried in order. However, when concurrent jobs are running, they will+ - be assigned different remotes of the same cost when possible. This can+ - increase total transfer speed.+ -}+pickRemote :: Observable v => [Remote] -> (Remote -> Annex v) -> Annex v+pickRemote l a = go l =<< Annex.getState Annex.concurrentjobs+ where+ go [] _ = return observeFailure+ go (r:[]) _ = a r+ go rs (Just n) | n > 1 = do+ mv <- Annex.getState Annex.activeremotes+ active <- liftIO $ takeMVar mv+ let rs' = sortBy (inactiveFirst active) rs+ goconcurrent mv active rs'+ go (r:rs) _ = do+ ok <- a r+ if observeBool ok+ then return ok+ else go rs Nothing+ goconcurrent mv active [] = do+ liftIO $ putMVar mv active+ return observeFailure+ goconcurrent mv active (r:rs) = do+ let !active' = S.insert r active+ liftIO $ putMVar mv active'+ let getnewactive = do+ active'' <- liftIO $ takeMVar mv+ let !active''' = S.delete r active''+ return active'''+ let removeactive = liftIO . putMVar mv =<< getnewactive+ ok <- a r `onException` removeactive+ if observeBool ok+ then do+ removeactive+ return ok + else do+ active'' <- getnewactive+ -- Re-sort the remaining rs + -- because other threads could have+ -- been assigned them in the meantime.+ let rs' = sortBy (inactiveFirst active'') rs+ goconcurrent mv active'' rs'++inactiveFirst :: S.Set Remote -> Remote -> Remote -> Ordering+inactiveFirst active a b+ | Remote.cost a == Remote.cost b =+ if a `S.member` active then GT else LT+ | otherwise = compare a b
Assistant/Pairing/Network.hs view
@@ -20,6 +20,8 @@ import Network.Multicast import Network.Info import Network.Socket+import qualified Network.Socket.ByteString as B+import qualified Data.ByteString.UTF8 as BU8 import qualified Data.Map as M import Control.Concurrent @@ -63,10 +65,11 @@ withSocketsDo $ bracket setup cleanup use where setup = multicastSender (multicastAddress IPv4AddrClass) pairingPort- cleanup (sock, _) = sClose sock -- FIXME does not work+ cleanup (sock, _) = close sock -- FIXME does not work use (sock, addr) = do setInterface sock (showAddr i)- maybe noop (\s -> void $ sendTo sock s addr)+ maybe noop+ (\s -> void $ B.sendTo sock (BU8.fromString s) addr) (M.lookup i cache) updatecache cache [] = cache updatecache cache (i:is)
Assistant/Threads/PairListener.hs view
@@ -20,6 +20,9 @@ import Network.Multicast import Network.Socket+import qualified Data.ByteString as B+import qualified Data.ByteString.UTF8 as BU8+import qualified Network.Socket.ByteString as B import qualified Data.Text as T pairListenerThread :: UrlRenderer -> NamedThread@@ -33,7 +36,7 @@ - or only one like lo that doesn't support multicast. -} getsock = multicastReceiver (multicastAddress IPv4AddrClass) pairingPort - go reqs cache sock = liftIO (getmsg sock []) >>= \msg -> case readish msg of+ go reqs cache sock = liftIO (getmsg sock B.empty) >>= \msg -> case readish (BU8.toString msg) of Nothing -> go reqs cache sock Just m -> do debug ["received", show msg]@@ -94,10 +97,10 @@ invalidateCache msg = filter (not . verifiedPairMsg msg) getmsg sock c = do- (msg, n, _) <- recvFrom sock chunksz- if n < chunksz- then return $ c ++ msg- else getmsg sock $ c ++ msg+ (msg, _) <- B.recvFrom sock chunksz+ if B.length msg < chunksz+ then return $ c <> msg+ else getmsg sock $ c <> msg where chunksz = 1024
Build/Configure.hs view
@@ -5,7 +5,6 @@ module Build.Configure where import Control.Applicative-import System.Environment (getArgs) import Control.Monad.IfElse import Control.Monad @@ -133,12 +132,12 @@ run :: [TestCase] -> IO () run ts = do- args <- getArgs setup config <- runTests ts- if args == ["Android"]- then writeSysConfig $ androidConfig config- else writeSysConfig config+ v <- getEnv "CROSS_COMPILE"+ case v of+ Just "Android" -> writeSysConfig $ androidConfig config+ _ -> writeSysConfig config cleanup whenM isReleaseBuild $ cabalSetup "git-annex.cabal"
Build/mdwn2man view
@@ -10,7 +10,7 @@ s{(\\?)\[\[([^\s\|\]]+)(\|[^\s\]]+)?\]\]}{$1 ? "[[$2]]" : $2}eg; s/\`([^\`]*)\`/\\fB$1\\fP/g; s/\`//g;- s/^\s*\./\\&./g;+ s/^ *\./\\&./g; if (/^#\s/) { s/^#\s/.SH /; <>; # blank;
CHANGELOG view
@@ -1,3 +1,21 @@+git-annex (6.20160907) unstable; urgency=medium++ * Windows: Handle shebang in external special remote program.+ * Fix formatting of git-annex-smudge man page, and improve mdwn2man.+ Thanks, Jim Paris.+ * examimekey: Allow being run in a git repo that is not initialized by+ git-annex yet.+ * Android: Fix disabling use of cp --reflink=auto, curl, sha224, and sha384.+ * Make --json and --quiet suppress automatic init messages, and any+ other messages that might be output before a command starts.+ Fixes a reversion introduced in version 5.20150727.+ * Assistant, repair: Filter out git fsck lines about duplicate file+ entries in tree objects.+ * get -J, sync --content -J: Download different files from different+ remotes when the remotes have the same costs.++ -- Joey Hess <id@joeyh.name> Wed, 07 Sep 2016 11:12:11 -0400+ git-annex (6.20160808) unstable; urgency=medium * metadata --json output format has changed, adding a inner json object
CmdLine.hs view
@@ -99,7 +99,7 @@ mkparser c = (,,) <$> pure c <*> getparser c- <*> combineGlobalOptions globaloptions+ <*> combineGlobalOptions (globaloptions ++ cmdglobaloptions c) synopsis n d = n ++ " - " ++ d intro = mconcat $ concatMap (\l -> [H.text l, H.line]) (synopsis progname progdesc : commandList allcmds)
Command.hs view
@@ -33,7 +33,7 @@ command :: String -> CommandSection -> String -> CmdParamsDesc -> (CmdParamsDesc -> CommandParser) -> Command command name section desc paramdesc mkparser = Command commonChecks False False name paramdesc - section desc (mkparser paramdesc) Nothing+ section desc (mkparser paramdesc) [] Nothing {- Simple option parser that takes all non-option params as-is. -} withParams :: (CmdParams -> v) -> CmdParamsDesc -> Parser v@@ -68,18 +68,9 @@ noRepo :: (String -> Parser (IO ())) -> Command -> Command noRepo a c = c { cmdnorepo = Just (a (cmdparamdesc c)) } -{- Adds global options to a command's option parser, and modifies its seek- - option to first run actions for them.- -}+{- Adds global options to a command's. -} withGlobalOptions :: [GlobalOption] -> Command -> Command-withGlobalOptions os c = c { cmdparser = apply <$> mixin (cmdparser c) }- where- mixin p = (,) - <$> p- <*> combineGlobalOptions os- apply (seek, globalsetters) = do- void $ getParsed globalsetters- seek+withGlobalOptions os c = c { cmdglobaloptions = cmdglobaloptions c ++ os } {- For start and perform stages to indicate what step to run next. -} next :: a -> Annex (Maybe a)
Command/ExamineKey.hs view
@@ -12,11 +12,12 @@ import Command.Find (parseFormatOption, showFormatted, keyVars) cmd :: Command-cmd = noCommit $ noMessages $ withGlobalOptions [jsonOption] $- command "examinekey" SectionPlumbing - "prints information from a key"- (paramRepeating paramKey)- (batchable run (optional parseFormatOption))+cmd = noCommit $ noMessages $ dontCheck repoExists $ + withGlobalOptions [jsonOption] $+ command "examinekey" SectionPlumbing + "prints information from a key"+ (paramRepeating paramKey)+ (batchable run (optional parseFormatOption)) run :: Maybe Utility.Format.Format -> String -> Annex Bool run format p = do
Command/Get.hs view
@@ -89,16 +89,17 @@ showNote "not available" showlocs return False- dispatch remotes = notifyTransfer Download afile $ trycopy remotes remotes- trycopy full [] _ = do- Remote.showTriedRemotes full- showlocs- return False- trycopy full (r:rs) witness =- ifM (probablyPresent r)- ( docopy r witness <||> trycopy full rs witness- , trycopy full rs witness+ dispatch remotes = notifyTransfer Download afile $ \witness -> do+ ok <- pickRemote remotes $ \r -> ifM (probablyPresent r)+ ( docopy r witness+ , return False )+ if ok+ then return ok+ else do+ Remote.showTriedRemotes remotes+ showlocs+ return False showlocs = Remote.showLocations False key [] "No other repository is known to contain the file." -- This check is to avoid an ugly message if a remote is a
Command/Sync.hs view
@@ -43,7 +43,6 @@ import Annex.Content import Command.Get (getKey') import qualified Command.Move-import Logs.Location import Annex.Drop import Annex.UUID import Logs.UUID@@ -470,7 +469,7 @@ -} syncFile :: Either (Maybe (Bloom Key)) (Key -> Annex ()) -> [Remote] -> AssociatedFile -> Key -> Annex Bool syncFile ebloom rs af k = do- locs <- loggedLocations k+ locs <- Remote.keyLocations k let (have, lack) = partition (\r -> Remote.uuid r `elem` locs) rs got <- anyM id =<< handleget have
Git/Fsck.hs view
@@ -104,6 +104,8 @@ findShas supportsNoDangling = catMaybes . map extractSha . concat . map words . filter wanted . lines where wanted l+ -- Skip lines like "error in tree <sha>: duplicateEntries: contains duplicate file entries"+ | "duplicateEntries" `isPrefixOf` l = False | supportsNoDangling = True | otherwise = not ("dangling " `isPrefixOf` l)
Git/Hook.hs view
@@ -12,6 +12,7 @@ import Common import Git import Utility.Tmp+import Utility.Shell #ifndef mingw32_HOST_OS import Utility.FileMode #endif@@ -75,23 +76,5 @@ runHook :: Hook -> Repo -> IO Bool runHook h r = do let f = hookFile h r- (c, ps) <- findcmd f+ (c, ps) <- findShellCommand f boolSystem c ps- where-#ifndef mingw32_HOST_OS- findcmd = defcmd-#else- {- 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)- case l of- Just ('#':'!':rest) -> case words rest of- [] -> defcmd f- (c:ps) -> do- let ps' = map Param (ps ++ [f])- ok <- inPath c- return (if ok then c else takeFileName c, ps')- _ -> defcmd f-#endif- defcmd f = return (f, [])
Logs/Transfer.hs view
@@ -15,7 +15,6 @@ import qualified Git import Utility.Metered import Utility.Percentage-import Utility.QuickCheck import Utility.PID import Annex.LockPool import Logs.TimeStamp@@ -290,17 +289,6 @@ </> "failed" </> showLcDirection direction </> filter (/= '/') (fromUUID u)--instance Arbitrary TransferInfo where- arbitrary = TransferInfo- <$> arbitrary- <*> arbitrary- <*> pure Nothing -- cannot generate a ThreadID- <*> pure Nothing -- remote not needed- <*> arbitrary- -- associated file cannot be empty (but can be Nothing)- <*> arbitrary `suchThat` (/= Just "")- <*> arbitrary prop_read_write_transferinfo :: TransferInfo -> Bool prop_read_write_transferinfo info
Messages/Concurrent.hs view
@@ -32,10 +32,12 @@ - instead. -} concurrentMessage :: OutputType -> Bool -> String -> Annex () -> Annex ()-concurrentMessage o iserror msg fallback #ifdef WITH_CONCURRENTOUTPUT+concurrentMessage o iserror msg fallback | concurrentOutputEnabled o = go =<< consoleRegion <$> Annex.getState Annex.output+#else+concurrentMessage _o _iserror _msg fallback #endif | otherwise = fallback #ifdef WITH_CONCURRENTOUTPUT@@ -67,8 +69,8 @@ - complete. -} inOwnConsoleRegion :: OutputType -> Annex a -> Annex a-inOwnConsoleRegion o a #ifdef WITH_CONCURRENTOUTPUT+inOwnConsoleRegion o a | concurrentOutputEnabled o = do r <- mkregion setregion (Just r)@@ -82,6 +84,8 @@ Right ret -> do rmregion r return ret+#else+inOwnConsoleRegion _o a #endif | otherwise = a #ifdef WITH_CONCURRENTOUTPUT
Messages/Progress.hs view
@@ -45,8 +45,8 @@ maybe noop (\m -> m n) combinemeterupdate liftIO $ clearMeter stdout meter return r- go size o@(ConcurrentOutput {}) #if WITH_CONCURRENTOUTPUT+ go size o@(ConcurrentOutput {}) | concurrentOutputEnabled o = withProgressRegion $ \r -> do (progress, meter) <- mkmeter size a $ \n -> liftIO $ do@@ -54,6 +54,8 @@ s <- renderMeter meter Regions.setConsoleRegion r ("\n" ++ s) maybe noop (\m -> m n) combinemeterupdate+#else+ go _size _o #endif | otherwise = nometer
Remote/External.hs view
@@ -21,6 +21,7 @@ import Remote.Helper.ReadOnly import Remote.Helper.Messages import Utility.Metered+import Utility.Shell import Messages.Progress import Types.Transfer import Logs.PreferredContent.Raw@@ -374,7 +375,13 @@ errrelayer <- mkStderrRelayer g <- Annex.gitRepo liftIO $ do- p <- propgit g cmdp+ (cmd, ps) <- findShellCommand basecmd+ let basep = (proc cmd (toCommand ps))+ { std_in = CreatePipe+ , std_out = CreatePipe+ , std_err = CreatePipe+ }+ p <- propgit g basep (Just hin, Just hout, Just herr, pid) <- createProcess p `catchIO` runerr fileEncoding hin@@ -391,24 +398,20 @@ , externalPrepared = Unprepared } where- cmd = externalRemoteProgram externaltype- cmdp = (proc cmd [])- { std_in = CreatePipe- , std_out = CreatePipe- , std_err = CreatePipe- }+ basecmd = externalRemoteProgram externaltype+ propgit g p = do environ <- propGitEnv g return $ p { env = Just environ } - runerr _ = error ("Cannot run " ++ cmd ++ " -- Make sure it's in your PATH and is executable.")+ runerr _ = error ("Cannot run " ++ basecmd ++ " -- Make sure it's in your PATH and is executable.") checkearlytermination Nothing = noop- checkearlytermination (Just exitcode) = ifM (inPath cmd)- ( error $ unwords [ "failed to run", cmd, "(" ++ show exitcode ++ ")" ]+ checkearlytermination (Just exitcode) = ifM (inPath basecmd)+ ( error $ unwords [ "failed to run", basecmd, "(" ++ show exitcode ++ ")" ] , do path <- intercalate ":" <$> getSearchPath- error $ cmd ++ " is not installed in PATH (" ++ path ++ ")"+ error $ basecmd ++ " is not installed in PATH (" ++ path ++ ")" ) stopExternal :: External -> Annex ()
Test.hs view
@@ -51,7 +51,6 @@ import qualified Git.FilePath import qualified Annex.Locations import qualified Types.KeySource-import qualified Types.Remote import qualified Types.Backend import qualified Types.TrustLevel import qualified Types@@ -102,6 +101,7 @@ import qualified Remote.Helper.Encryptable import qualified Types.Crypto import qualified Utility.Gpg+import qualified Types.Remote #endif optParser :: Parser TestOptions
Types/Command.hs view
@@ -1,6 +1,6 @@ {- git-annex command data types -- - Copyright 2010-2015 Joey Hess <id@joeyh.name>+ - Copyright 2010-2016 Joey Hess <id@joeyh.name> - - Licensed under the GNU GPL version 3 or higher. -}@@ -11,6 +11,7 @@ import Options.Applicative.Types (Parser) import Types+import Types.DeferredParse {- A command runs in these stages. -@@ -46,6 +47,7 @@ , cmdsection :: CommandSection , cmddesc :: String -- description of command for usage , cmdparser :: CommandParser -- command line parser+ , cmdglobaloptions :: [GlobalOption] -- additional global options , cmdnorepo :: Maybe (Parser (IO ())) -- used when not in a repo }
Types/Transfer.hs view
@@ -9,9 +9,12 @@ import Types import Utility.PID+import Utility.QuickCheck import Data.Time.Clock.POSIX import Control.Concurrent+import Control.Applicative+import Prelude {- Enough information to uniquely identify a transfer, used as the filename - of the transfer information file. -}@@ -45,3 +48,13 @@ data Direction = Upload | Download deriving (Eq, Ord, Read, Show) +instance Arbitrary TransferInfo where+ arbitrary = TransferInfo+ <$> arbitrary+ <*> arbitrary+ <*> pure Nothing -- cannot generate a ThreadID+ <*> pure Nothing -- remote not needed+ <*> arbitrary+ -- associated file cannot be empty (but can be Nothing)+ <*> arbitrary `suchThat` (/= Just "")+ <*> arbitrary
Utility/Shell.hs view
@@ -9,6 +9,19 @@ module Utility.Shell where +import Utility.SafeCommand+#ifdef mingw32_HOST_OS+import Utility.Path+import Utility.FileSystemEncoding+import Utility.Exception+import Utility.PartialPrelude+#endif++#ifdef mingw32_HOST_OS+import System.IO+import System.FilePath+#endif+ shellPath_portable :: FilePath shellPath_portable = "/bin/sh" @@ -24,3 +37,32 @@ shebang_local :: String shebang_local = "#!" ++ shellPath_local++-- | On Windows, shebang is not handled by the kernel, so to support+-- shell scripts etc, have to look at the program being run and+-- parse it for shebang.+--+-- This has no effect on Unix.+findShellCommand :: FilePath -> IO (FilePath, [CommandParam])+findShellCommand f = do+#ifndef mingw32_HOST_OS+ defcmd+#else+ l <- catchDefaultIO Nothing $ withFile f ReadMode $ \h -> do+ fileEncoding h+ headMaybe . lines <$> hGetContents h+ case l of+ Just ('#':'!':rest) -> case words rest of+ [] -> defcmd+ (c:ps) -> do+ let ps' = map Param ps ++ [File f]+ -- If the command is not inPath,+ -- take the base of it, and run eg "sh"+ -- which in some cases on windows will work+ -- despite it not being inPath.+ ok <- inPath c+ return (if ok then c else takeFileName c, ps')+ _ -> defcmd+#endif+ where+ defcmd = return (f, [])
Utility/WebApp.hs view
@@ -127,12 +127,12 @@ go' :: Int -> AddrInfo -> IO Socket go' 0 _ = error "unable to bind to local socket" go' n addr = do- r <- tryIO $ bracketOnError (open addr) sClose (useaddr addr)+ r <- tryIO $ bracketOnError (open addr) close (useaddr addr) either (const $ go' (pred n) addr) return r open addr = socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) useaddr addr sock = do preparesocket sock- bindSocket sock (addrAddress addr)+ bind sock (addrAddress addr) use sock #endif preparesocket sock = setSocketOption sock ReuseAddr 1
doc/git-annex-get.mdwn view
@@ -23,7 +23,8 @@ * `--from=remote` Normally git-annex will choose which remotes to get the content- from. Use this option to specify which remote to use. + from, preferring less expensive remotes. Use this option to specify+ which remote to use. Any files that are not available on the remote will be silently skipped.
doc/git-annex-smudge.mdwn view
@@ -25,7 +25,7 @@ clean = git-annex smudge --clean %f To make git use that filter driver, it needs to be configured in-the .gitattributes file or in `.git/config/attributes`. The latter+the `.gitattributes` file or in `.git/info/attributes`. The latter is normally configured when a repository is initialized, with the following contents:
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 6.20160808+Version: 6.20160907 Cabal-Version: >= 1.8 License: GPL-3 Maintainer: Joey Hess <id@joeyh.name>@@ -329,15 +329,42 @@ stm (>= 2.3), mtl (>= 2), uuid (>= 1.2.6),- process, data-default, case-insensitive, random, dlist,- unix-compat, SafeSemaphore, async, directory, filepath, IfElse,- MissingH, hslogger, monad-logger,- utf8-string, bytestring, text, sandi,- monad-control, transformers,- bloomfilter, edit-distance,- resourcet, http-conduit (<2.2.0), http-client, http-types,- time, old-locale,- esqueleto, persistent-sqlite, persistent (<2.5), persistent-template,+ process,+ data-default,+ case-insensitive,+ random,+ dlist,+ unix-compat,+ SafeSemaphore,+ async,+ directory,+ filepath,+ IfElse,+ MissingH,+ hslogger,+ monad-logger,+ utf8-string,+ bytestring,+ text,+ sandi,+ monad-control,+ transformers,+ bloomfilter,+ edit-distance,+ resourcet,+ http-client,+ http-types,+ -- Old version needed due to https://github.com/aristidb/aws/issues/206+ http-conduit (<2.2.0),+ time,+ old-locale,+ esqueleto,+ persistent-sqlite, + -- Old version needed due to+ -- https://github.com/prowdsponsor/esqueleto/issues/137+ -- and also temporarily to make ghc 8 builds work+ persistent (< 2.5),+ persistent-template, aeson, unordered-containers, feed,@@ -438,8 +465,11 @@ path-pieces (>= 0.1.4), warp (>= 3.0.0.5), warp-tls (>= 1.4),- wai, wai-extra,- blaze-builder, crypto-api, clientsession,+ wai,+ wai-extra,+ blaze-builder,+ crypto-api,+ clientsession, template-haskell, shakespeare (>= 2.0.0), securemem,