diff options
| author | David Bremner <david@tethera.net> | 2022-05-14 15:25:47 -0300 |
|---|---|---|
| committer | David Bremner <david@tethera.net> | 2022-06-17 08:40:19 -0300 |
| commit | 7d1e5a5348eb348a4e457650ca3b929e85efde70 (patch) | |
| tree | e2335d92be028b925df0adcf681a982921cc0984 /notmuch-git.py | |
| parent | 99e85823c8de570c0f91bca44efa2c47cddb3cbf (diff) | |
CLI/git: add safety checks for checkout and commit
Commits or checkouts that modify a large fraction of the messages in
the database should be relatively rare (and in some automated process,
probably non-existent). For initial setup, where such operations are
expected, the user can pass --force.
Diffstat (limited to 'notmuch-git.py')
| -rw-r--r-- | notmuch-git.py | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/notmuch-git.py b/notmuch-git.py index 35785336..f188660c 100644 --- a/notmuch-git.py +++ b/notmuch-git.py @@ -239,6 +239,16 @@ def _tag_query(prefix=None): prefix = TAG_PREFIX return '(tag (starts-with "{:s}"))'.format(prefix.replace('"','\\\"')) +def count_messages(prefix=None): + "count messages with a given prefix." + (status, stdout, stderr) = _spawn( + args=['notmuch', 'count', '--query=sexp', _tag_query(prefix)], + stdout=_subprocess.PIPE, wait=True) + if status != 0: + _LOG.error("failed to run notmuch config") + sys.exit(1) + return int(stdout.rstrip()) + def get_tags(prefix=None): "Get a list of tags with a given prefix." (status, stdout, stderr) = _spawn( @@ -357,7 +367,26 @@ class CachedIndex: _git(args=['read-tree', self.current_treeish], wait=True) -def commit(treeish='HEAD', message=None): +def check_safe_fraction(status): + safe = 0.1 + conf = _notmuch_config_get ('git.safe_fraction') + if conf and conf != '': + safe=float(conf) + + total = count_messages (TAG_PREFIX) + if total == 0: + _LOG.error('No existing tags with given prefix, stopping.'.format(safe)) + _LOG.error('Use --force to override.') + exit(1) + change = len(status['added'])+len(status['deleted']) + fraction = change/total + _LOG.debug('total messages {:d}, change: {:d}, fraction: {:f}'.format(total,change,fraction)) + if fraction > safe: + _LOG.error('safe fraction {:f} exceeded, stopping.'.format(safe)) + _LOG.error('Use --force to override or reconfigure git.safe_fraction.') + exit(1) + +def commit(treeish='HEAD', message=None, force=False): """ Commit prefix-matching tags from the notmuch database to Git. """ @@ -368,6 +397,9 @@ def commit(treeish='HEAD', message=None): _LOG.warning('Nothing to commit') return + if not force: + check_safe_fraction (status) + with CachedIndex(NOTMUCH_GIT_DIR, treeish) as index: try: _update_index(status=status) @@ -445,7 +477,7 @@ def init(remote=None): wait=True) -def checkout(): +def checkout(force=None): """ Update the notmuch database from Git. @@ -453,6 +485,10 @@ def checkout(): to Git. """ status = get_status() + + if not force: + check_safe_fraction(status) + with _spawn( args=['notmuch', 'tag', '--batch'], stdin=_subprocess.PIPE) as p: for id, tags in status['added'].items(): @@ -943,6 +979,10 @@ if __name__ == '__main__': help=( "Argument passed through to 'git archive'. Set anything " 'before <tree-ish>, see git-archive(1) for details.')) + elif command == 'checkout': + subparser.add_argument( + '-f', '--force', action='store_true', + help='checkout a large fraction of tags.') elif command == 'clone': subparser.add_argument( 'repository', @@ -952,6 +992,9 @@ if __name__ == '__main__': 'specifying repositories.')) elif command == 'commit': subparser.add_argument( + '-f', '--force', action='store_true', + help='commit a large fraction of tags.') + subparser.add_argument( 'message', metavar='MESSAGE', default='', nargs='?', help='Text for the commit message.') elif command == 'fetch': |
