diff --git a/Annex.hs b/Annex.hs index c9feb7540e..f659a4f886 100644 --- a/Annex.hs +++ b/Annex.hs @@ -189,6 +189,7 @@ data AnnexState = AnnexState , sentinalstatus :: Maybe SentinalStatus , useragent :: Maybe String , errcounter :: Integer + , skippedfiles :: Bool , adjustedbranchrefreshcounter :: Integer , unusedkeys :: Maybe (S.Set Key) , tempurls :: M.Map Key URLString @@ -248,6 +249,7 @@ newAnnexState c r = do , sentinalstatus = Nothing , useragent = Nothing , errcounter = 0 + , skippedfiles = False , adjustedbranchrefreshcounter = 0 , unusedkeys = Nothing , tempurls = M.empty diff --git a/Benchmark.hs b/Benchmark.hs index c48cbbd091..434d9764d8 100644 --- a/Benchmark.hs +++ b/Benchmark.hs @@ -32,9 +32,9 @@ mkGenerator cmds userinput = do forM_ l $ \(cmd, seek, st) -> -- The cmd is run for benchmarking without startup or -- shutdown actions. - Annex.eval st $ performCommandAction cmd seek noop + Annex.eval st $ performCommandAction False cmd seek noop where - -- Simplified versio of CmdLine.dispatch, without support for fuzzy + -- Simplified version of CmdLine.dispatch, without support for fuzzy -- matching or out-of-repo commands. parsesubcommand ps = do (cmd, seek, globalconfig) <- liftIO $ O.handleParseResult $ diff --git a/CmdLine.hs b/CmdLine.hs index eb75e66e11..1cb7953660 100644 --- a/CmdLine.hs +++ b/CmdLine.hs @@ -62,7 +62,7 @@ dispatch' subcommandname args fuzzy cmds allargs allcmds fields getgitrepo progn forM_ fields $ uncurry Annex.setField prepRunCommand cmd globalsetter startup - performCommandAction cmd seek $ + performCommandAction True cmd seek $ shutdown $ cmdnocommit cmd go (Left norepo) = do let ingitrepo = \a -> a =<< Git.Config.global diff --git a/CmdLine/Action.hs b/CmdLine/Action.hs index 29baea29ec..6d7932bb0b 100644 --- a/CmdLine/Action.hs +++ b/CmdLine/Action.hs @@ -30,19 +30,32 @@ import qualified Data.Map.Strict as M import qualified System.Console.Regions as Regions {- Runs a command, starting with the check stage, and then - - the seek stage. Finishes by running the continutation, and - - then showing a count of any failures. -} -performCommandAction :: Command -> CommandSeek -> Annex () -> Annex () -performCommandAction Command { cmdcheck = c, cmdname = name } seek cont = do + - the seek stage. Finishes by running the continuation. + - + - Can exit when there was a problem or when files were skipped. + - Also shows a count of any failures when that is enabled. + -} +performCommandAction :: Bool -> Command -> CommandSeek -> Annex () -> Annex () +performCommandAction canexit (Command { cmdcheck = c, cmdname = name }) seek cont = do mapM_ runCheck c Annex.changeState $ \s -> s { Annex.errcounter = 0 } seek finishCommandActions cont - showerrcount =<< Annex.getState Annex.errcounter + st <- Annex.getState id + when canexit $ liftIO $ case (Annex.errcounter st, Annex.skippedfiles st) of + (0, False) -> noop + (errcnt, False) -> do + showerrcount errcnt + exitWith $ ExitFailure 1 + (0, True) -> exitskipped + (errcnt, True) -> do + showerrcount errcnt + exitskipped where - showerrcount 0 = noop - showerrcount cnt = giveup $ name ++ ": " ++ show cnt ++ " failed" + showerrcount cnt = hPutStrLn stderr $ + name ++ ": " ++ show cnt ++ " failed" + exitskipped = exitWith $ ExitFailure 101 commandActions :: [CommandStart] -> Annex () commandActions = mapM_ commandAction @@ -315,7 +328,7 @@ checkSizeLimit (Just sizelimitvar) startmsg a = Nothing -> do fsz <- catchMaybeIO $ withObjectLoc k $ liftIO . getFileSize - maybe noop go fsz + maybe skipped go fsz Nothing -> a where go sz = do @@ -327,4 +340,8 @@ checkSizeLimit (Just sizelimitvar) startmsg a = writeTVar sizelimitvar n' return True else return False - when fits a + if fits + then a + else skipped + + skipped = Annex.changeState $ \s -> s { Annex.skippedfiles = True } diff --git a/doc/git-annex-common-options.mdwn b/doc/git-annex-common-options.mdwn index cf44cf40e5..7b8efed2bd 100644 --- a/doc/git-annex-common-options.mdwn +++ b/doc/git-annex-common-options.mdwn @@ -89,6 +89,9 @@ Most of these options are accepted by all git-annex commands. In some cases, an annexed file's size is not known. This option will prevent git-annex from processing such files. + When the size limit prevents git-annex from acting on any files, + it will exit with a special code, 101. + * `--semitrust=repository` * `--untrust=repository` diff --git a/doc/todo/size_limits_for_drop__47__move__47__copy__47__get.mdwn b/doc/todo/size_limits_for_drop__47__move__47__copy__47__get.mdwn index a93f700df5..9742d3c021 100644 --- a/doc/todo/size_limits_for_drop__47__move__47__copy__47__get.mdwn +++ b/doc/todo/size_limits_for_drop__47__move__47__copy__47__get.mdwn @@ -5,3 +5,5 @@ This way you could quickly "garbage collect" a few dozen GiB from your annex rep Another issue this could be used to mitigates is that, for some reason, git-annex doesn't auto-stop the transfer when the repos on my external drives are full properly. I imagine there are many more use-cases where quickly being able to set a limit for the amount of data a command should act on could come in handy. + +> [[done]] --[[Joey]] diff --git a/doc/todo/size_limits_for_drop__47__move__47__copy__47__get/comment_2_8687c2bb69c83d3d8ebfa877a0d7b32f._comment b/doc/todo/size_limits_for_drop__47__move__47__copy__47__get/comment_2_8687c2bb69c83d3d8ebfa877a0d7b32f._comment new file mode 100644 index 0000000000..341f1f3847 --- /dev/null +++ b/doc/todo/size_limits_for_drop__47__move__47__copy__47__get/comment_2_8687c2bb69c83d3d8ebfa877a0d7b32f._comment @@ -0,0 +1,14 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 2""" + date="2021-06-04T20:35:26Z" + content=""" +--size-limit is implemented, for most git-annex commands. + +Ones like `git-annex add` that don't operate on annexed files don't support +it, at least yet. + +Ones like git-annex export/import/sync I'm not sure it makes sense to +support it, since they kind of operate at a higher level than individual +files. +"""]]