mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-21 10:28:09 +01:00
CLI/git: add reset command
Sometimes merging is not what we want with tags; in particular it tends to keep tags in the local repo that have been removed elsewhere. This commit provides a new reset command; the reset itself is trivial, but the work is to provide a safety check that uses the existing --force and git.safe_fraction machinery.
This commit is contained in:
parent
6b9fccb2e2
commit
30740296e7
2 changed files with 80 additions and 3 deletions
|
@ -368,7 +368,7 @@ class CachedIndex:
|
||||||
_git(args=['read-tree', self.current_treeish], wait=True)
|
_git(args=['read-tree', self.current_treeish], wait=True)
|
||||||
|
|
||||||
|
|
||||||
def check_safe_fraction(status):
|
def _check_fraction(change):
|
||||||
safe = 0.1
|
safe = 0.1
|
||||||
conf = _notmuch_config_get ('git.safe_fraction')
|
conf = _notmuch_config_get ('git.safe_fraction')
|
||||||
if conf and conf != '':
|
if conf and conf != '':
|
||||||
|
@ -379,7 +379,7 @@ def check_safe_fraction(status):
|
||||||
_LOG.error('No existing tags with given prefix, stopping.')
|
_LOG.error('No existing tags with given prefix, stopping.')
|
||||||
_LOG.error('Use --force to override.')
|
_LOG.error('Use --force to override.')
|
||||||
exit(1)
|
exit(1)
|
||||||
change = len(status['added'])+len(status['deleted'])
|
|
||||||
fraction = change/total
|
fraction = change/total
|
||||||
_LOG.debug('total messages {:d}, change: {:d}, fraction: {:f}'.format(total,change,fraction))
|
_LOG.debug('total messages {:d}, change: {:d}, fraction: {:f}'.format(total,change,fraction))
|
||||||
if fraction > safe:
|
if fraction > safe:
|
||||||
|
@ -387,6 +387,25 @@ def check_safe_fraction(status):
|
||||||
_LOG.error('Use --force to override or reconfigure git.safe_fraction.')
|
_LOG.error('Use --force to override or reconfigure git.safe_fraction.')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
def check_safe_fraction(status):
|
||||||
|
|
||||||
|
change = len(status['added'])+len(status['deleted'])
|
||||||
|
_check_fraction(change)
|
||||||
|
|
||||||
|
def check_diff_fraction():
|
||||||
|
|
||||||
|
# check number of directories (i.e. messages) changed.
|
||||||
|
change_set = set()
|
||||||
|
|
||||||
|
with _git(args=['diff', '--name-only', 'HEAD', '@{upstream}'],
|
||||||
|
stdout=_subprocess.PIPE) as git:
|
||||||
|
for path in git.stdout:
|
||||||
|
change_set.add(_os.path.dirname(path))
|
||||||
|
|
||||||
|
change=len(change_set)
|
||||||
|
_check_fraction(change)
|
||||||
|
|
||||||
|
|
||||||
def commit(treeish='HEAD', message=None, force=False):
|
def commit(treeish='HEAD', message=None, force=False):
|
||||||
"""
|
"""
|
||||||
Commit prefix-matching tags from the notmuch database to Git.
|
Commit prefix-matching tags from the notmuch database to Git.
|
||||||
|
@ -619,6 +638,15 @@ def push(repository=None, refspecs=None):
|
||||||
_git(args=args, wait=True)
|
_git(args=args, wait=True)
|
||||||
|
|
||||||
|
|
||||||
|
def reset(force=False):
|
||||||
|
"""
|
||||||
|
reset the local git branch to match the remote one
|
||||||
|
"""
|
||||||
|
if not force:
|
||||||
|
check_diff_fraction()
|
||||||
|
|
||||||
|
_git(args=["reset","--soft","origin/master"],wait=True)
|
||||||
|
|
||||||
def status():
|
def status():
|
||||||
"""
|
"""
|
||||||
Show pending updates in notmuch or git repo.
|
Show pending updates in notmuch or git repo.
|
||||||
|
@ -1047,6 +1075,7 @@ if __name__ == '__main__':
|
||||||
'merge',
|
'merge',
|
||||||
'pull',
|
'pull',
|
||||||
'push',
|
'push',
|
||||||
|
'reset',
|
||||||
'status',
|
'status',
|
||||||
]:
|
]:
|
||||||
func = locals()[command]
|
func = locals()[command]
|
||||||
|
@ -1141,6 +1170,10 @@ if __name__ == '__main__':
|
||||||
'Refspec (usually a branch name) to push. See '
|
'Refspec (usually a branch name) to push. See '
|
||||||
'the <refspec> entry in the OPTIONS section of '
|
'the <refspec> entry in the OPTIONS section of '
|
||||||
'git-push(1) for other possibilities.'))
|
'git-push(1) for other possibilities.'))
|
||||||
|
elif command == 'reset':
|
||||||
|
subparser.add_argument(
|
||||||
|
'-f', '--force', action='store_true',
|
||||||
|
help='reset a large fraction of tags.')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,51 @@ cat <<EOF > EXPECTED
|
||||||
EOF
|
EOF
|
||||||
test_expect_equal_file EXPECTED OUTPUT
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
test_begin_subtest "reset"
|
||||||
|
notmuch git -C reset.git -p '' clone remote.git
|
||||||
|
notmuch git -C reset.git checkout --force
|
||||||
|
notmuch tag +test4 id:20091117190054.GU3165@dottiness.seas.harvard.edu
|
||||||
|
notmuch git -C remote.git commit --force
|
||||||
|
notmuch tag -test4 id:20091117190054.GU3165@dottiness.seas.harvard.edu
|
||||||
|
notmuch git -C reset.git fetch
|
||||||
|
notmuch git -C reset.git reset
|
||||||
|
notmuch git -C reset.git checkout --force
|
||||||
|
notmuch dump id:20091117190054.GU3165@dottiness.seas.harvard.edu | grep -v '^#' > OUTPUT
|
||||||
|
cat <<EOF > EXPECTED
|
||||||
|
+inbox +signed +test2 +test3 +test4 +unread -- id:20091117190054.GU3165@dottiness.seas.harvard.edu
|
||||||
|
EOF
|
||||||
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
test_begin_subtest "reset (require force for large change)"
|
||||||
|
notmuch git -C reset2.git -p '' clone remote.git
|
||||||
|
notmuch git -C reset2.git checkout --force
|
||||||
|
notmuch tag +test5 '*'
|
||||||
|
notmuch git -C remote.git commit --force
|
||||||
|
notmuch tag -test5 '*'
|
||||||
|
notmuch git -C reset2.git fetch
|
||||||
|
test_expect_code 1 "notmuch git -C reset2.git -l debug reset"
|
||||||
|
|
||||||
|
test_begin_subtest "reset (don't require force for large change to one message)"
|
||||||
|
notmuch git -C reset3.git -p '' clone remote.git
|
||||||
|
notmuch git -C reset3.git checkout --force
|
||||||
|
notmuch dump id:20091117190054.GU3165@dottiness.seas.harvard.edu > BEFORE
|
||||||
|
for tag in $(seq 1 100); do
|
||||||
|
notmuch tag +$tag id:20091117190054.GU3165@dottiness.seas.harvard.edu
|
||||||
|
done
|
||||||
|
notmuch git -C remote.git commit --force
|
||||||
|
notmuch restore < BEFORE
|
||||||
|
notmuch git -C reset3.git fetch
|
||||||
|
test_expect_code 0 "notmuch git -C reset3.git -l debug reset"
|
||||||
|
|
||||||
|
test_begin_subtest "reset --force"
|
||||||
|
notmuch git -C reset4.git -p '' clone remote.git
|
||||||
|
notmuch git -C reset4.git checkout --force
|
||||||
|
notmuch tag +test6 '*'
|
||||||
|
notmuch git -C remote.git commit --force
|
||||||
|
notmuch tag -test6 '*'
|
||||||
|
notmuch git -C reset4.git fetch
|
||||||
|
test_expect_code 0 "notmuch git -C reset4.git -l debug reset --force"
|
||||||
|
|
||||||
test_begin_subtest "environment passed through when run as 'notmuch git'"
|
test_begin_subtest "environment passed through when run as 'notmuch git'"
|
||||||
env NOTMUCH_GIT_DIR=foo NOTMUCH_GIT_PREFIX=bar NOTMUCH_PROFILE=default notmuch git -C tags.git -p '' -ldebug status |& \
|
env NOTMUCH_GIT_DIR=foo NOTMUCH_GIT_PREFIX=bar NOTMUCH_PROFILE=default notmuch git -C tags.git -p '' -ldebug status |& \
|
||||||
grep '^env ' | notmuch_dir_sanitize > OUTPUT
|
grep '^env ' | notmuch_dir_sanitize > OUTPUT
|
||||||
|
@ -311,7 +356,6 @@ prefix = env::
|
||||||
EOF
|
EOF
|
||||||
test_expect_equal_file EXPECTED OUTPUT
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
|
||||||
test_begin_subtest "init, xdg default location"
|
test_begin_subtest "init, xdg default location"
|
||||||
repo=home/.local/share/notmuch/default/git
|
repo=home/.local/share/notmuch/default/git
|
||||||
notmuch git -ldebug init |& grep '^repository' | notmuch_dir_sanitize > OUTPUT
|
notmuch git -ldebug init |& grep '^repository' | notmuch_dir_sanitize > OUTPUT
|
||||||
|
|
Loading…
Reference in a new issue