annex.autocommit can be configured via git-annex config
... to control the default behavior in all clones of a repository. This includes a new Configurable data type, so the GitConfig type indicates which values can be configured this way. The implementation should be quite efficient; the config log is only read once, and only when a Configurable value has not already been set by git-config. Indeed, it would be nice in the future to extend this, so that git-config is itself only read on demand. Some commands may not need to look at the git configuration at all. This commit was sponsored by Trenton Cronholm on Patreon.
This commit is contained in:
parent
d6d23d8a15
commit
ed56dba868
14 changed files with 93 additions and 26 deletions
2
Annex.hs
2
Annex.hs
|
@ -114,7 +114,6 @@ data AnnexState = AnnexState
|
|||
, checkignorehandle :: Maybe (Maybe CheckIgnoreHandle)
|
||||
, forcebackend :: Maybe String
|
||||
, globalnumcopies :: Maybe NumCopies
|
||||
, globalconfig :: Maybe (M.Map String String)
|
||||
, forcenumcopies :: Maybe NumCopies
|
||||
, limit :: ExpandableMatcher Annex
|
||||
, uuidmap :: Maybe UUIDMap
|
||||
|
@ -166,7 +165,6 @@ newState c r = do
|
|||
, checkignorehandle = Nothing
|
||||
, forcebackend = Nothing
|
||||
, globalnumcopies = Nothing
|
||||
, globalconfig = Nothing
|
||||
, forcenumcopies = Nothing
|
||||
, limit = BuildingMatcher []
|
||||
, uuidmap = Nothing
|
||||
|
|
|
@ -42,6 +42,7 @@ import Annex.InodeSentinal
|
|||
import Git.Types
|
||||
import Git.FilePath
|
||||
import Config
|
||||
import Config.GitConfig
|
||||
import Utility.ThreadScheduler
|
||||
import Logs.Location
|
||||
import qualified Database.Keys
|
||||
|
@ -83,7 +84,7 @@ instance E.Exception WatcherControl
|
|||
|
||||
watchThread :: NamedThread
|
||||
watchThread = namedThread "Watcher" $
|
||||
ifM (liftAnnex $ annexAutoCommit <$> Annex.getGitConfig)
|
||||
ifM (liftAnnex $ getGitConfigVal annexAutoCommit)
|
||||
( runWatcher
|
||||
, waitFor ResumeWatcher runWatcher
|
||||
)
|
||||
|
|
|
@ -43,6 +43,7 @@ import Utility.Gpg
|
|||
import Annex.UUID
|
||||
import Assistant.Ssh
|
||||
import Config
|
||||
import Config.GitConfig
|
||||
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Map as M
|
||||
|
@ -76,7 +77,7 @@ getRepoConfig uuid mremote = do
|
|||
|
||||
syncable <- case mremote of
|
||||
Just r -> return $ remoteAnnexSync $ Remote.gitconfig r
|
||||
Nothing -> annexAutoCommit <$> Annex.getGitConfig
|
||||
Nothing -> getGitConfigVal annexAutoCommit
|
||||
|
||||
return $ RepoConfig
|
||||
(T.pack $ maybe "here" Remote.name mremote)
|
||||
|
|
|
@ -12,7 +12,6 @@ module Assistant.WebApp.RepoList where
|
|||
import Assistant.WebApp.Common
|
||||
import Assistant.DaemonStatus
|
||||
import Assistant.WebApp.Notifications
|
||||
import qualified Annex
|
||||
import qualified Remote
|
||||
import qualified Types.Remote as Remote
|
||||
import Remote.List (remoteListRefresh)
|
||||
|
@ -21,6 +20,7 @@ import Logs.Remote
|
|||
import Logs.Trust
|
||||
import Logs.Group
|
||||
import Config
|
||||
import Config.GitConfig
|
||||
import Git.Remote
|
||||
import Assistant.Sync
|
||||
import Config.Cost
|
||||
|
@ -152,7 +152,7 @@ repoList reposelector
|
|||
if includeHere reposelector
|
||||
then do
|
||||
r <- RepoUUID <$> getUUID
|
||||
autocommit <- annexAutoCommit <$> Annex.getGitConfig
|
||||
autocommit <- getGitConfigVal annexAutoCommit
|
||||
let hereactions = if autocommit
|
||||
then mkSyncingRepoActions r
|
||||
else mkNotSyncingRepoActions r
|
||||
|
|
|
@ -7,6 +7,8 @@ git-annex (6.20170102) UNRELEASED; urgency=medium
|
|||
taken for --json.
|
||||
* vicfg: Include the numcopies configuation.
|
||||
* config: New command for storing configuration in the git-annex branch.
|
||||
* annex.autocommit can be configured via git-annex config, to control
|
||||
the default behavior in all clones of a repository.
|
||||
* stack.yaml: Update to lts-7.18.
|
||||
* Some optimisations to string splitting code.
|
||||
* unused: When large files are checked right into git, avoid buffering
|
||||
|
|
|
@ -39,6 +39,7 @@ import qualified Git.Ref
|
|||
import qualified Git
|
||||
import qualified Remote.Git
|
||||
import Config
|
||||
import Config.GitConfig
|
||||
import Annex.Wanted
|
||||
import Annex.Content
|
||||
import Command.Get (getKey')
|
||||
|
@ -237,7 +238,7 @@ commit o = stopUnless shouldcommit $ next $ next $ do
|
|||
)
|
||||
where
|
||||
shouldcommit = pure (commitOption o)
|
||||
<&&> (annexAutoCommit <$> Annex.getGitConfig)
|
||||
<&&> getGitConfigVal annexAutoCommit
|
||||
|
||||
commitMsg :: Annex String
|
||||
commitMsg = do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{- Git configuration
|
||||
-
|
||||
- Copyright 2011-2014 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2011-2017 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
@ -24,7 +24,8 @@ data ConfigKey = ConfigKey String
|
|||
instance Show ConfigKey where
|
||||
show (ConfigKey s) = s
|
||||
|
||||
{- Looks up a setting in git config. -}
|
||||
{- Looks up a setting in git config. This is not as efficient as using the
|
||||
- GitConfig type. -}
|
||||
getConfig :: ConfigKey -> String -> Annex String
|
||||
getConfig (ConfigKey key) d = fromRepo $ Git.Config.get key d
|
||||
|
||||
|
|
36
Config/GitConfig.hs
Normal file
36
Config/GitConfig.hs
Normal file
|
@ -0,0 +1,36 @@
|
|||
{- git-annex configuration
|
||||
-
|
||||
- Copyright 2017 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
||||
module Config.GitConfig where
|
||||
|
||||
import Annex.Common
|
||||
import qualified Annex
|
||||
import Types.GitConfig
|
||||
import Git.Types
|
||||
import Logs.Config
|
||||
|
||||
{- Gets a specific setting from GitConfig. If necessary, loads the
|
||||
- repository-global defaults when the GitConfig does not yet
|
||||
- have a value. -}
|
||||
getGitConfigVal :: (GitConfig -> Configurable a) -> Annex a
|
||||
getGitConfigVal f = do
|
||||
v <- f <$> Annex.getGitConfig
|
||||
case v of
|
||||
HasConfig c -> return c
|
||||
DefaultConfig _ -> do
|
||||
r <- Annex.gitRepo
|
||||
m <- loadGlobalConfig
|
||||
let globalgc = extractGitConfig (r { config = m })
|
||||
-- This merge of the repo-global config and the git
|
||||
-- config makes all repository-global default
|
||||
-- values populate the GitConfig with HasConfig
|
||||
-- values, so it will only need to be done once.
|
||||
Annex.changeGitConfig (\gc -> mergeGitConfig gc globalgc)
|
||||
v' <- f <$> Annex.getGitConfig
|
||||
case v' of
|
||||
HasConfig c -> return c
|
||||
DefaultConfig d -> return d
|
|
@ -1,4 +1,4 @@
|
|||
{- git-annex config log
|
||||
{- git-annex repository-global config log
|
||||
-
|
||||
- Copyright 2017 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
|
@ -15,7 +15,6 @@ module Logs.Config (
|
|||
) where
|
||||
|
||||
import Annex.Common
|
||||
import qualified Annex
|
||||
import Logs
|
||||
import Logs.MapLog
|
||||
import qualified Annex.Branch
|
||||
|
@ -44,18 +43,13 @@ unsetGlobalConfig name = do
|
|||
when (curr /= Nothing) $
|
||||
setGlobalConfig' name "" -- set to empty string to unset
|
||||
|
||||
-- Reads the global config log every time.
|
||||
getGlobalConfig :: ConfigName -> Annex (Maybe ConfigValue)
|
||||
getGlobalConfig name = do
|
||||
m <- maybe loadGlobalConfig return
|
||||
=<< Annex.getState Annex.globalconfig
|
||||
return (M.lookup name m)
|
||||
getGlobalConfig name = M.lookup name <$> loadGlobalConfig
|
||||
|
||||
parseGlobalConfig :: String -> MapLog ConfigName ConfigValue
|
||||
parseGlobalConfig = parseMapLog Just Just
|
||||
|
||||
loadGlobalConfig :: Annex (M.Map ConfigName ConfigValue)
|
||||
loadGlobalConfig = do
|
||||
m <- M.filter (not . null) . simpleMap . parseGlobalConfig
|
||||
<$> Annex.Branch.get configLog
|
||||
Annex.changeState $ \s -> s { Annex.globalconfig = Just m }
|
||||
return m
|
||||
loadGlobalConfig = M.filter (not . null) . simpleMap . parseGlobalConfig
|
||||
<$> Annex.Branch.get configLog
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
-}
|
||||
|
||||
module Types.GitConfig (
|
||||
Configurable(..),
|
||||
GitConfig(..),
|
||||
extractGitConfig,
|
||||
mergeGitConfig,
|
||||
RemoteGitConfig(..),
|
||||
extractRemoteGitConfig,
|
||||
) where
|
||||
|
@ -29,6 +31,14 @@ import Utility.HumanTime
|
|||
import Utility.Gpg (GpgCmd, mkGpgCmd)
|
||||
import Utility.ThreadScheduler (Seconds(..))
|
||||
|
||||
-- | A configurable value, that may not be fully determined yet.
|
||||
data Configurable a
|
||||
= HasConfig a
|
||||
-- ^ Value is fully determined.
|
||||
| DefaultConfig a
|
||||
-- ^ A default value is known, but not all config sources
|
||||
-- have been read yet.
|
||||
|
||||
{- Main git-annex settings. Each setting corresponds to a git-config key
|
||||
- such as annex.foo -}
|
||||
data GitConfig = GitConfig
|
||||
|
@ -46,7 +56,7 @@ data GitConfig = GitConfig
|
|||
, annexDelayAdd :: Maybe Int
|
||||
, annexHttpHeaders :: [String]
|
||||
, annexHttpHeadersCommand :: Maybe String
|
||||
, annexAutoCommit :: Bool
|
||||
, annexAutoCommit :: Configurable Bool
|
||||
, annexDebug :: Bool
|
||||
, annexWebOptions :: [String]
|
||||
, annexQuviOptions :: [String]
|
||||
|
@ -93,7 +103,8 @@ extractGitConfig r = GitConfig
|
|||
, annexDelayAdd = getmayberead (annex "delayadd")
|
||||
, annexHttpHeaders = getlist (annex "http-headers")
|
||||
, annexHttpHeadersCommand = getmaybe (annex "http-headers-command")
|
||||
, annexAutoCommit = getbool (annex "autocommit") True
|
||||
, annexAutoCommit = configurable True $
|
||||
getmaybebool (annex "autocommit")
|
||||
, annexDebug = getbool (annex "debug") False
|
||||
, annexWebOptions = getwords (annex "web-options")
|
||||
, annexQuviOptions = getwords (annex "quvi-options")
|
||||
|
@ -133,10 +144,26 @@ extractGitConfig r = GitConfig
|
|||
getlist k = Git.Config.getList k r
|
||||
getwords k = fromMaybe [] $ words <$> getmaybe k
|
||||
|
||||
configurable d Nothing = DefaultConfig d
|
||||
configurable _ (Just v) = HasConfig v
|
||||
|
||||
annex k = "annex." ++ k
|
||||
|
||||
onemegabyte = 1000000
|
||||
|
||||
{- Merge a GitConfig that comes from git-config with one containing
|
||||
- repository-global defaults. -}
|
||||
mergeGitConfig :: GitConfig -> GitConfig -> GitConfig
|
||||
mergeGitConfig gitconfig repoglobals = gitconfig
|
||||
{ annexAutoCommit = merge annexAutoCommit
|
||||
}
|
||||
where
|
||||
merge f = case f gitconfig of
|
||||
HasConfig v -> HasConfig v
|
||||
DefaultConfig d -> case f repoglobals of
|
||||
HasConfig v -> HasConfig v
|
||||
DefaultConfig _ -> HasConfig d
|
||||
|
||||
{- Per-remote git-annex settings. Each setting corresponds to a git-config
|
||||
- key such as <remote>.annex-foo, or if that is not set, a default from
|
||||
- annex.foo -}
|
||||
|
|
|
@ -25,9 +25,12 @@ Only a few make sense to be able to set such that all clones of a
|
|||
repository see the setting, and so git-annex only looks for these:
|
||||
|
||||
These settings can be overridden on a per-repository basis using
|
||||
`git config`:
|
||||
`git config`.
|
||||
|
||||
None yet!
|
||||
* `annex.autocommit`
|
||||
|
||||
Set to false to prevent the git-annex assistant and git-annex sync
|
||||
from automatically committing changes to files in the repository.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
|
|
|
@ -1006,8 +1006,8 @@ Here are all the supported configuration settings.
|
|||
Set to false to prevent the git-annex assistant and git-annex sync
|
||||
from automatically committing changes to files in the repository.
|
||||
|
||||
To configure the behavior in all repositories, this can be set in
|
||||
[[git-annex-config]].
|
||||
To configure the behavior in all clones of the repository,
|
||||
this can be set in [[git-annex-config]].
|
||||
|
||||
* `annex.startupscan`
|
||||
|
||||
|
|
|
@ -3,3 +3,5 @@ when using git-annex as a minority participant in a repository (eg. because in a
|
|||
forgetting to do that explicit configuration results, in one sync command, easily results in an unwanted implicit commit that's pushed across remotes.
|
||||
|
||||
could there be a per-repository option (somewhere around .gitattributes, or maybe in the git-annex branch) that disables autocommits for the repository?
|
||||
|
||||
> [[done]] --[[Joey]]
|
||||
|
|
|
@ -793,6 +793,7 @@ Executable git-annex
|
|||
Config
|
||||
Config.Cost
|
||||
Config.Files
|
||||
Config.GitConfig
|
||||
Creds
|
||||
Crypto
|
||||
Database.Fsck
|
||||
|
|
Loading…
Reference in a new issue