From e955912ad0e75b4bc3f9107c4a17a11ae7d7d575 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 18 May 2023 14:37:29 -0400 Subject: [PATCH] git-annex assist assist: New command, which is the same as git-annex sync but with new files added and content transferred by default. (Also this fixes another reversion in git-annex sync, --commit --no-commit, and --message were not enabled, oops.) See added comment for why git-annex assist does commit staged changes elsewhere in the work tree, but only adds files under the cwd. Note that it does not support --no-commit, --no-push, --no-pull like sync does. My thinking is, why should it? If you want that level of control, use git commit, git annex push, git annex pull. Sync only got those options because pull and push were not split out. Sponsored-by: k0ld on Patreon --- CHANGELOG | 2 + CmdLine/GitAnnex.hs | 2 + Command/Add.hs | 5 +- Command/Assist.hs | 43 +++++++++++++ Command/Assistant.hs | 2 +- Command/Sync.hs | 34 +++++----- Command/Watch.hs | 2 +- doc/git-annex-assist.mdwn | 57 +++++++++++++++++ doc/git-annex-assistant.mdwn | 4 +- doc/git-annex-config.mdwn | 17 ++++- doc/git-annex-sync.mdwn | 2 + doc/git-annex-watch.mdwn | 2 +- doc/git-annex.mdwn | 64 +++++++++++-------- ...__git_annex_sync__39___optionally_add.mdwn | 2 + ..._6d9ef10f9534c7b95ca58913cfe3b5fd._comment | 31 +++++++++ git-annex.cabal | 2 + 16 files changed, 224 insertions(+), 47 deletions(-) create mode 100644 Command/Assist.hs create mode 100644 doc/git-annex-assist.mdwn create mode 100644 doc/todo/Having___39__git_annex_sync__39___optionally_add/comment_10_6d9ef10f9534c7b95ca58913cfe3b5fd._comment diff --git a/CHANGELOG b/CHANGELOG index e43cdbccb8..2457dc0c36 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,8 @@ git-annex (10.20230408) UNRELEASED; urgency=medium Those plus a git commit are equivilant to git-annex sync. (Note that the new commands default to syncing content, unless annex.synccontent is explicitly set to false.) + * assist: New command, which is the same as git-annex sync but with + new files added and content transferred by default. * Many commands now quote filenames that contain unusual characters the same way that git does, to avoid exposing control characters to the terminal. * Support core.quotePath, which can be set to false to display utf8 diff --git a/CmdLine/GitAnnex.hs b/CmdLine/GitAnnex.hs index 5917606d64..8fcaf956e8 100644 --- a/CmdLine/GitAnnex.hs +++ b/CmdLine/GitAnnex.hs @@ -100,6 +100,7 @@ import qualified Command.Ungroup import qualified Command.Config import qualified Command.Vicfg import qualified Command.Sync +import qualified Command.Assist import qualified Command.Pull import qualified Command.Push import qualified Command.Mirror @@ -147,6 +148,7 @@ cmds testoptparser testrunner mkbenchmarkgenerator = map addGitAnnexCommonOption , Command.Unlock.editcmd , Command.Lock.cmd , Command.Sync.cmd + , Command.Assist.cmd , Command.Pull.cmd , Command.Push.cmd , Command.Mirror.cmd diff --git a/Command/Add.hs b/Command/Add.hs index 3a00aaa637..5f0daaab08 100644 --- a/Command/Add.hs +++ b/Command/Add.hs @@ -86,7 +86,10 @@ checkGitIgnoreSwitch = CheckGitIgnore <$> (help "Do not check .gitignore when adding files") seek :: AddOptions -> CommandSeek -seek o = startConcurrency commandStages $ do +seek o = startConcurrency commandStages (seek' o) + +seek' :: AddOptions -> CommandSeek +seek' o = do largematcher <- largeFilesMatcher addunlockedmatcher <- addUnlockedMatcher annexdotfiles <- getGitConfigVal annexDotFiles diff --git a/Command/Assist.hs b/Command/Assist.hs new file mode 100644 index 0000000000..1ec83c1339 --- /dev/null +++ b/Command/Assist.hs @@ -0,0 +1,43 @@ +{- git-annex command + - + - Copyright 2023 Joey Hess + - + - Licensed under the GNU AGPL version 3 or higher. + -} + +module Command.Assist (cmd) where + +import Command +import qualified Command.Sync +import qualified Command.Add +import Annex.CheckIgnore + +cmd :: Command +cmd = withAnnexOptions [jobsOption, backendOption] $ + command "assist" SectionCommon + "add files and sync changes with remotes" + (paramRepeating paramRemote) + (myseek <--< Command.Sync.optParser Command.Sync.AssistMode) + +myseek :: Command.Sync.SyncOptions -> CommandSeek +myseek o = startConcurrency transferStages $ do + -- Run before prepMerge so it adds only files in the current + -- directory and below, not new files elsewhere in the working + -- tree. + Command.Add.seek Command.Add.AddOptions + { Command.Add.addThese = [] + , Command.Add.batchOption = NoBatch + , Command.Add.updateOnly = False + , Command.Add.largeFilesOverride = Nothing + , Command.Add.checkGitIgnoreOption = CheckGitIgnore (False) + , Command.Add.dryRunOption = DryRun False + } + + Command.Sync.prepMerge + Command.Sync.seek' o' + where + o' + | Command.Sync.contentOption o == Nothing + && Command.Sync.noContentOption o == Nothing = + o { Command.Sync.contentOption = Just True } + | otherwise = o diff --git a/Command/Assistant.hs b/Command/Assistant.hs index 66758f1941..92db99664d 100644 --- a/Command/Assistant.hs +++ b/Command/Assistant.hs @@ -24,7 +24,7 @@ cmd :: Command cmd = dontCheck repoExists $ notBareRepo $ noRepo (startNoRepo <$$> optParser) $ command "assistant" SectionCommon - "automatically sync changes" + "daemon to add files and automatically sync changes" paramNothing (seek <$$> optParser) data AssistantOptions = AssistantOptions diff --git a/Command/Sync.hs b/Command/Sync.hs index dfdc3a83b2..eaad7f0eb2 100644 --- a/Command/Sync.hs +++ b/Command/Sync.hs @@ -12,6 +12,7 @@ module Command.Sync ( cmd, seek, + seek', CurrBranch, mergeConfig, merge, @@ -94,7 +95,7 @@ cmd = withAnnexOptions [jobsOption, backendOption] $ "synchronize local repository with remotes" (paramRepeating paramRemote) (seek <--< optParser SyncMode) -data OperationMode = SyncMode | PullMode | PushMode +data OperationMode = SyncMode | PullMode | PushMode | AssistMode deriving (Eq, Show) data SyncOptions = SyncOptions @@ -151,15 +152,15 @@ optParser mode desc = SyncOptions ( long "not-only-annex" <> help "operate on git branches as well as annex" ) - <*> unlessmode SyncMode False (switch + <*> unlessmode [SyncMode] False (switch ( long "commit" <> help "commit changes to git" )) - <*> unlessmode SyncMode True (switch + <*> unlessmode [SyncMode] True (switch ( long "no-commit" <> help "avoid git commit" )) - <*> unlessmode SyncMode Nothing (optional (strOption + <*> unlessmode [SyncMode, AssistMode] Nothing (optional (strOption ( long "message" <> short 'm' <> metavar "MSG" <> help "commit message" ))) @@ -169,12 +170,14 @@ optParser mode desc = SyncOptions ) PullMode -> pure True PushMode -> pure False + AssistMode -> pure True <*> case mode of SyncMode -> invertableSwitch "push" True ( help "avoid git pushes to remotes" ) PullMode -> pure False PushMode -> pure True + AssistMode -> pure True <*> optional (flag' True ( long "content" <> help "transfer annexed file contents" @@ -190,25 +193,24 @@ optParser mode desc = SyncOptions <> help "transfer contents of annexed files in a given location" <> metavar paramPath )) - <*> whenmode PullMode False (switch + <*> whenmode [PullMode] False (switch ( long "cleanup" <> help "remove synced/ branches from previous sync" )) <*> optional parseAllOption - <*> whenmode PushMode False (invertableSwitch "resolvemerge" True + <*> whenmode [PushMode] False (invertableSwitch "resolvemerge" True ( help "do not automatically resolve merge conflicts" )) - <*> case mode of - PushMode -> pure False - _ -> parseUnrelatedHistoriesOption + <*> whenmode [PushMode] False + parseUnrelatedHistoriesOption <*> pure mode where - unlessmode m v a - | mode /= m = pure v - | otherwise = a whenmode m v a - | mode == m = pure v + | mode `elem` m = pure v | otherwise = a + unlessmode m v a + | mode `elem` m = a + | otherwise = pure v parseUnrelatedHistoriesOption :: Parser Bool parseUnrelatedHistoriesOption = @@ -240,8 +242,9 @@ instance DeferredParseClass SyncOptions where seek :: SyncOptions -> CommandSeek seek o = do warnSyncContentTransition o - + prepMerge + startConcurrency transferStages (seek' o) seek' :: SyncOptions -> CommandSeek @@ -828,6 +831,7 @@ seekSyncContent o rs currbranch = do SyncMode -> "sync" PullMode -> "pull" PushMode -> "push" + AssistMode -> "assist" gofile bloom mvar _ f k = go (Right bloom) mvar (AssociatedFile (Just f)) k @@ -1044,7 +1048,7 @@ cleanupRemote remote (Just b, _) = shouldSyncContent :: SyncOptions -> Annex Bool shouldSyncContent o | fromMaybe False (noContentOption o) = pure False - -- For git-annex pull and git-annex push, + -- For git-annex pull and git-annex push and git-annex assist, -- annex.syncontent defaults to True unless set | operationMode o /= SyncMode = annexsynccontent True | fromMaybe False (contentOption o) || not (null (contentOfOption o)) = pure True diff --git a/Command/Watch.hs b/Command/Watch.hs index 7a613ad460..340559d2b6 100644 --- a/Command/Watch.hs +++ b/Command/Watch.hs @@ -14,7 +14,7 @@ import Utility.HumanTime cmd :: Command cmd = notBareRepo $ command "watch" SectionCommon - "watch for changes and autocommit" + "daemon to watch for changes and autocommit" paramNothing (seek <$$> const (parseDaemonOptions True)) seek :: DaemonOptions -> CommandSeek diff --git a/doc/git-annex-assist.mdwn b/doc/git-annex-assist.mdwn new file mode 100644 index 0000000000..35be1d8072 --- /dev/null +++ b/doc/git-annex-assist.mdwn @@ -0,0 +1,57 @@ +# NAME + +git-annex assist - add files and sync changes with remotes + +# SYNOPSIS + +git annex assist `[remote ...]` + +# DESCRIPTION + +This command assists you in checking files into the repository +and syncing with remotes. It's the simplest possible way to use git-annex +at the command line, since only this one command needs to be run on a +regular basis. + +This command first adds any new files (in the current directory and +its children) to the repository, and commits those as well as any +modified files. Then it does the equivilant of running +[[git-annex-pull](1) followed by [[git-annex-push]](1). + +To block some files from being added to the repository, use `.gitignore` +files. + +By default, all files that are added are added to the annex, the same +as when you run `git annex add`. If you configure annex.largefiles, +files that it does not match will instead be added with `git add`. + +# OPTIONS + +* `--message=msg` + + Use this option to specify a commit message. + +* Also all options supported by [[git-annex-pull]](1) and + [[git-annex-push]](1) can be used. + +* Also the [[git-annex-common-options]](1) can be used. + +# SEE ALSO + +[[git-annex]](1) + +[[git-annex-add]](1) + +[[git-annex-pull]](1) + +[[git-annex-push]](1) + +[[git-annex-sync]](1) + +[[git-annex-assistant]](1) + +# AUTHOR + +Joey Hess + +Warning: Automatically converted into a man page by mdwn2man. Edit with care. diff --git a/doc/git-annex-assistant.mdwn b/doc/git-annex-assistant.mdwn index c0254f6156..076c26f37f 100644 --- a/doc/git-annex-assistant.mdwn +++ b/doc/git-annex-assistant.mdwn @@ -1,6 +1,6 @@ # NAME -git-annex assistant - automatically sync changes +git-annex assistant - daemon to add files and automatically sync changes # SYNOPSIS @@ -58,6 +58,8 @@ files that it does not match will instead be added with `git add`. [[git-annex-watch]](1) +[[git-annex-assist]](1) + [[git-annex-schedule]](1) For more details about the git-annex assistant, see diff --git a/doc/git-annex-config.mdwn b/doc/git-annex-config.mdwn index 6583cf0739..a0499d1c15 100644 --- a/doc/git-annex-config.mdwn +++ b/doc/git-annex-config.mdwn @@ -35,6 +35,18 @@ looks for these. It is an expression that matches the large files, eg "`include=*.mp3 or largerthan(500kb)`". See [[git-annex-matching-expression]](1) for details on the syntax. + + This configures the behavior of both git-annex and git when adding + files to the repository. By default, `git-annex add` adds all files + to the annex (except dotfiles), and `git add` adds files to git + (unless they were added to the annex previously). + When annex.largefiles is configured, both + `git annex add` and `git add` will add matching large files to the + annex, and the other files to git. + + Other git-annex commands also honor annex.largefiles, including + `git annex import`, `git annex addurl`, `git annex importfeed`, + `git-annex assist`, and the `git-annex assistant`. This sets a default, which can be overridden by annex.largefiles attributes in `.gitattributes` files, or by `git config`. @@ -64,8 +76,9 @@ looks for these. * `annex.autocommit` - Set to false to prevent the `git-annex assistant` and `git-annex sync` - from automatically committing changes to files in the repository. + Set to false to prevent the `git-annex assistant`, `git-annex assist` + and `git-annex sync` from automatically committing changes to files + in the repository. This sets a default, which can be overridden by annex.autocommit in `git config`. diff --git a/doc/git-annex-sync.mdwn b/doc/git-annex-sync.mdwn index 8e0db80410..d1c02def0a 100644 --- a/doc/git-annex-sync.mdwn +++ b/doc/git-annex-sync.mdwn @@ -74,6 +74,8 @@ content by default. That will change in a future version of git-annex, [[git-annex-push]](1) +[[git-annex-assist]](1) + # AUTHOR Joey Hess diff --git a/doc/git-annex-watch.mdwn b/doc/git-annex-watch.mdwn index b65b4dc657..7f82cbb62f 100644 --- a/doc/git-annex-watch.mdwn +++ b/doc/git-annex-watch.mdwn @@ -1,6 +1,6 @@ # NAME -git-annex watch - watch for changes +git-annex watch - daemon to watch for changes # SYNOPSIS diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index 78427a4ba5..f071e7895c 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -132,6 +132,12 @@ content from the key-value store. See [[git-annex-sync]](1) for details. +* `assist [remote ...]` + + Add files and sync changes with remotes. + + See [[git-annex-assist]](1) for details. + * `mirror [path ...] [--to=remote|--from=remote]` Mirror content of files to/from another repository. @@ -182,13 +188,13 @@ content from the key-value store. * `watch` - Watch for changes and autocommit. + Daemon to watch for changes and autocommit. See [[git-annex-watch]](1) for details. * `assistant` - Automatically sync folders between devices. + Daemon to automatically sync changes. See [[git-annex-assistant]](1) for details. @@ -904,8 +910,8 @@ repository, using [[git-annex-config]]. See its man page for a list.) annex, and the other files to git. Other git-annex commands also honor annex.largefiles, including - `git annex import`, `git annex addurl`, `git annex importfeed` - and the assistant. + `git annex import`, `git annex addurl`, `git annex importfeed`, + `git-annex assist`, and the `git-annex assistant`. * `annex.dotfiles` @@ -1177,7 +1183,7 @@ repository, using [[git-annex-config]]. See its man page for a list.) Set to false to prevent merge conflicts in the checked out branch being automatically resolved by the `git-annex assitant`, - `git-annex sync`, `git-annex pull`, `git-annex merge`, + `git-annex assist`, `git-annex sync`, `git-annex pull`, `git-annex merge`, and the git-annex post-receive hook. To configure the behavior in all clones of the repository, @@ -1188,16 +1194,17 @@ repository, using [[git-annex-config]]. See its man page for a list.) Set to true to make `git-annex sync` default to transferring annexed content. - Set to false to prevent `git-annex pull` and `git-annex push` from - transferring annexed content. + Set to false to prevent `git-annex assist`, `git-annex pull` and + `git-annex push` from transferring annexed content. To configure the behavior in all clones of the repository, this can be set in [[git-annex-config]](1). * `annex.synconlyannex` - Set to true to make git-annex sync, git-annex pull, and git-annex push - default to only operating on the git-annex branch and annexed content. + Set to true to make `git-annex assist`, `git-annex sync`, + `git-annex pull`, and `git-annex push` default to only operating + on the git-annex branch and annexed content. To configure the behavior in all clones of the repository, this can be set in [[git-annex-config]](1). @@ -1377,8 +1384,9 @@ Remotes are configured using these settings in `.git/config`. Or, it could be used if the network connection between two repositories is too slow to be used normally. - This does not prevent git-annex sync, git-annex pull, git-annex push, - or the git-annex assistant from operating on the git repository. + This does not prevent `git-annex sync`, `git-annex pull`, `git-annex push`, + `git-annex assist` or the `git-annex assistant` from operating on the + git repository. * `remote..annex-ignore-command` @@ -1388,8 +1396,9 @@ Remotes are configured using these settings in `.git/config`. * `remote..annex-sync` - If set to `false`, prevents git-annex sync (and git-annex pull, git-annex - sync, and the git-annex assistant) from operating on this remote by default. + If set to `false`, prevents `git-annex sync` (and `git-annex pull`, + `git-annex push`, `git-annex assist`, and the `git-annex assistant`) + from operating on this remote by default. * `remote..annex-sync-command` @@ -1399,20 +1408,22 @@ Remotes are configured using these settings in `.git/config`. * `remote..annex-pull` - If set to `false`, prevents git-annex sync, git-annex pull, - (and the git-annex assistant etc) from ever pulling (or fetching) - from the remote. + If set to `false`, prevents `git-annex pull`, `git-annex sync`, + `git-annex assist` and the `git-annex assistant` from ever pulling + (or fetching) from the remote. * `remote..annex-push` - If set to `false`, prevents git-annex sync, git-annex push, - (and the git-annex assistant etc) from ever pushing to the remote. + If set to `false`, prevents `git-annex push`, `git-annex sync`, + `git-annex assist` and the `git-annex assistant` from ever pushing + to the remote. * `remote..annex-readonly` If set to `true`, prevents git-annex from making changes to a remote. - This both prevents git-annex sync from pushing changes, and prevents - storing or removing files from read-only remote. + This prevents `git-annex sync` and `git-annex assist` from pushing + changes to a git repository. And it prevents storing or removing + files from read-only remote. * `remote..annex-verify`, `annex.verify` @@ -1434,9 +1445,11 @@ Remotes are configured using these settings in `.git/config`. When set to eg, "master:subdir", the special remote tracks only the subdirectory of that branch. - `git-annex sync --content` will import changes from the remote and - merge them into the annex-tracking-branch. They also export changes - made to the branch to the remote. + Setting this enables some other command to work with these special + remotes: `git-annex pull` will import changes from the remote and merge them into + the annex-tracking-branch. And `git-annex push` will export changes to + the remote. Higher-level commands `git-annex sync --content` + and `git-annex assist` both import and export. * `remote..annex-export-tracking` @@ -1928,8 +1941,9 @@ Remotes are configured using these settings in `.git/config`. * `annex.autocommit` - Set to false to prevent the git-annex assistant and git-annex sync - from automatically committing changes to files in the repository. + Set to false to prevent the `git-annex assistant`, `git-annex assist`, + and `git-annex sync` from automatically committing changes to files in + the repository. To configure the behavior in all clones of the repository, this can be set in [[git-annex-config]](1). diff --git a/doc/todo/Having___39__git_annex_sync__39___optionally_add.mdwn b/doc/todo/Having___39__git_annex_sync__39___optionally_add.mdwn index b43ad2988b..5a357bb233 100644 --- a/doc/todo/Having___39__git_annex_sync__39___optionally_add.mdwn +++ b/doc/todo/Having___39__git_annex_sync__39___optionally_add.mdwn @@ -34,3 +34,5 @@ while true;do git annex sync --content;done What do you think? Cheers, Yann + +> [[done]] as `git-annex assist` --[[Joey]] diff --git a/doc/todo/Having___39__git_annex_sync__39___optionally_add/comment_10_6d9ef10f9534c7b95ca58913cfe3b5fd._comment b/doc/todo/Having___39__git_annex_sync__39___optionally_add/comment_10_6d9ef10f9534c7b95ca58913cfe3b5fd._comment new file mode 100644 index 0000000000..be5c98392b --- /dev/null +++ b/doc/todo/Having___39__git_annex_sync__39___optionally_add/comment_10_6d9ef10f9534c7b95ca58913cfe3b5fd._comment @@ -0,0 +1,31 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 10""" + date="2023-05-18T17:45:44Z" + content=""" +Implementing `git-annex assist` now... + +A tricky point is, should it add files only in the current directory and +below, or all files in the repository? Note that the assistant can be run +in a directory and it will only add changed/new files in that directory, +although it can receive pulls that change files in other directories +(and will then download those files content). + +OTOH, `git-annex sync` commits all changes, not only those in the +current directory. (The assistant does in some circumstanges commit +changes made outside the current directory. Its behavior is a bit +inconsistent in this area.) + +So I think it makes sense for `git-annex assist` to only add files in the +current directory by default. (Of course an option like -A could be added +later.) + +And while I'm a bit ambivilant about it, I'm making it commit all staged +changes, not only those in the current directory. As well as following the +behavior of `git-annex sync` and to an extent the assistant, it seems to +me that if you run `git-annex add ../foo; git-annex assist`, you are +intentionally building up a commit that includes file "foo". The same +as if you ran `git-annex add ../foo; git-annex add .` ... If you're not, +and you care about what files get added in what commit, you can of course +commit manually. +"""]] diff --git a/git-annex.cabal b/git-annex.cabal index c4122d3de7..22342240fc 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -45,6 +45,7 @@ Extra-Source-Files: doc/git-annex-addunused.mdwn doc/git-annex-addurl.mdwn doc/git-annex-adjust.mdwn + doc/git-annex-assist.mdwn doc/git-annex-assistant.mdwn doc/git-annex-backends.mdwn doc/git-annex-calckey.mdwn @@ -709,6 +710,7 @@ Executable git-annex Command.AddUnused Command.AddUrl Command.Adjust + Command.Assist Command.Benchmark Command.CalcKey Command.CheckPresentKey