aboutsummaryrefslogtreecommitdiff
path: root/notmuch-git.py
diff options
context:
space:
mode:
authorDavid Bremner <david@tethera.net>2022-05-14 15:25:47 -0300
committerDavid Bremner <david@tethera.net>2022-06-17 08:40:19 -0300
commit7d1e5a5348eb348a4e457650ca3b929e85efde70 (patch)
treee2335d92be028b925df0adcf681a982921cc0984 /notmuch-git.py
parent99e85823c8de570c0f91bca44efa2c47cddb3cbf (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.py47
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':