Merge remote-tracking branch 'kovidgoyal/fix-482' into develop
Conflicts: powerline/lib/vcs/git.py
This commit is contained in:
commit
afe415a398
|
@ -84,14 +84,18 @@ class INotifyWatch(INotify):
|
|||
eno = ctypes.get_errno()
|
||||
if eno != errno.ENOTDIR:
|
||||
self.handle_error()
|
||||
# Try watching path as a file
|
||||
flags |= (self.MODIFY | self.ATTRIB)
|
||||
wd = self._add_watch(self._inotify_fd, buf, flags)
|
||||
if wd == -1:
|
||||
self.handle_error()
|
||||
# Try watching path as a file
|
||||
flags |= (self.MODIFY | self.ATTRIB)
|
||||
wd = self._add_watch(self._inotify_fd, buf, flags)
|
||||
if wd == -1:
|
||||
self.handle_error()
|
||||
self.watches[path] = wd
|
||||
self.modified[path] = False
|
||||
|
||||
def is_watched(self, path):
|
||||
with self.lock:
|
||||
return realpath(path) in self.watches
|
||||
|
||||
def __call__(self, path):
|
||||
''' Return True if path has been modified since the last call. Can
|
||||
raise OSError if the path does not exist. '''
|
||||
|
@ -141,6 +145,10 @@ class StatWatch(object):
|
|||
with self.lock:
|
||||
self.watches.pop(path, None)
|
||||
|
||||
def is_watched(self, path):
|
||||
with self.lock:
|
||||
return realpath(path) in self.watches
|
||||
|
||||
def __call__(self, path):
|
||||
path = realpath(path)
|
||||
with self.lock:
|
||||
|
|
|
@ -31,11 +31,12 @@ class INotifyTreeWatcher(INotify):
|
|||
|
||||
is_dummy = False
|
||||
|
||||
def __init__(self, basedir):
|
||||
def __init__(self, basedir, ignore_event=None):
|
||||
super(INotifyTreeWatcher, self).__init__()
|
||||
self.basedir = realpath(basedir)
|
||||
self.watch_tree()
|
||||
self.modified = True
|
||||
self.ignore_event = (lambda path, name: False) if ignore_event is None else ignore_event
|
||||
|
||||
def watch_tree(self):
|
||||
self.watched_dirs = {}
|
||||
|
@ -93,7 +94,7 @@ class INotifyTreeWatcher(INotify):
|
|||
|
||||
self.MODIFY | self.CREATE | self.DELETE |
|
||||
self.MOVE_SELF | self.MOVED_FROM | self.MOVED_TO |
|
||||
self.ATTRIB | self.MOVE_SELF | self.DELETE_SELF)
|
||||
self.ATTRIB | self.DELETE_SELF)
|
||||
if wd == -1:
|
||||
eno = ctypes.get_errno()
|
||||
if eno == errno.ENOTDIR:
|
||||
|
@ -112,7 +113,7 @@ class INotifyTreeWatcher(INotify):
|
|||
return
|
||||
path = self.watched_rmap.get(wd, None)
|
||||
if path is not None:
|
||||
self.modified = True
|
||||
self.modified = not self.ignore_event(path, name)
|
||||
if mask & self.CREATE:
|
||||
# A new sub-directory might have been created, monitor it.
|
||||
try:
|
||||
|
@ -152,10 +153,10 @@ class TreeWatcher(object):
|
|||
self.last_query_times = {}
|
||||
self.expire_time = expire_time * 60
|
||||
|
||||
def watch(self, path, logger=None):
|
||||
def watch(self, path, logger=None, ignore_event=None):
|
||||
path = realpath(path)
|
||||
try:
|
||||
w = INotifyTreeWatcher(path)
|
||||
w = INotifyTreeWatcher(path, ignore_event=ignore_event)
|
||||
except (INotifyError, DirTooLarge) as e:
|
||||
if logger is not None:
|
||||
logger.warn('Failed to watch path: {0} with error: {1}'.format(path, e))
|
||||
|
@ -176,14 +177,14 @@ class TreeWatcher(object):
|
|||
for path in pop:
|
||||
del self.last_query_times[path]
|
||||
|
||||
def __call__(self, path, logger=None):
|
||||
def __call__(self, path, logger=None, ignore_event=None):
|
||||
path = realpath(path)
|
||||
self.expire_old_queries()
|
||||
self.last_query_times[path] = monotonic()
|
||||
w = self.watches.get(path, None)
|
||||
if w is None:
|
||||
try:
|
||||
self.watch(path)
|
||||
self.watch(path, logger=logger, ignore_event=ignore_event)
|
||||
except NoSuchDir:
|
||||
pass
|
||||
return True
|
||||
|
|
|
@ -39,8 +39,10 @@ def get_branch_name(directory, config_file, get_func):
|
|||
global branch_name_cache
|
||||
with branch_lock:
|
||||
# Check if the repo directory was moved/deleted
|
||||
fw = file_watcher()
|
||||
is_watched = fw.is_watched(directory)
|
||||
try:
|
||||
changed = file_watcher()(directory)
|
||||
changed = fw(directory)
|
||||
except OSError as e:
|
||||
if getattr(e, 'errno', None) != errno.ENOENT:
|
||||
raise
|
||||
|
@ -48,12 +50,13 @@ def get_branch_name(directory, config_file, get_func):
|
|||
if changed:
|
||||
branch_name_cache.pop(config_file, None)
|
||||
# Remove the watches for this repo
|
||||
file_watcher().unwatch(directory)
|
||||
file_watcher().unwatch(config_file)
|
||||
if is_watched:
|
||||
fw.unwatch(directory)
|
||||
fw.unwatch(config_file)
|
||||
else:
|
||||
# Check if the config file has changed
|
||||
try:
|
||||
changed = file_watcher()(config_file)
|
||||
changed = fw(config_file)
|
||||
except OSError as e:
|
||||
if getattr(e, 'errno', None) != errno.ENOENT:
|
||||
raise
|
||||
|
@ -176,7 +179,7 @@ class TreeStatusCache(dict):
|
|||
def __call__(self, repo, logger):
|
||||
key = repo.directory
|
||||
try:
|
||||
if self.tw(key):
|
||||
if self.tw(key, logger=logger, ignore_event=getattr(repo, 'ignore_event', None)):
|
||||
self.pop(key, None)
|
||||
except OSError as e:
|
||||
logger.warn('Failed to check %s for changes, with error: %s'% key, e)
|
||||
|
@ -209,7 +212,7 @@ def debug():
|
|||
''' To use run python -c "from powerline.lib.vcs import debug; debug()" some_file_to_watch '''
|
||||
import sys
|
||||
dest = sys.argv[-1]
|
||||
repo = guess(dest)
|
||||
repo = guess(os.path.abspath(dest))
|
||||
if repo is None:
|
||||
print ('%s is not a recognized vcs repo' % dest)
|
||||
raise SystemExit(1)
|
||||
|
@ -224,3 +227,5 @@ def debug():
|
|||
raw_input('Press Enter to check again: ')
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
except EOFError:
|
||||
pass
|
||||
|
|
|
@ -36,19 +36,29 @@ def do_status(directory, path, func):
|
|||
with open(gitd, 'rb') as f:
|
||||
raw = f.read().partition(b':')[2].strip()
|
||||
gitd = os.path.abspath(os.path.join(directory, raw))
|
||||
return get_file_status(directory, os.path.join(gitd, 'index'),
|
||||
path, '.gitignore', func, extra_ignore_files=(os.path.join(gitd, 'info/exclude'),))
|
||||
# We need HEAD as without it using fugitive to commit causes the
|
||||
# current file's status (and only the current file) to not be updated
|
||||
# for some reason I cannot be bothered to figure out.
|
||||
return get_file_status(
|
||||
directory, os.path.join(gitd, 'index'),
|
||||
path, '.gitignore', func, extra_ignore_files=tuple(os.path.join(gitd, x) for x in ('logs/HEAD', 'info/exclude')))
|
||||
return func(directory, path)
|
||||
|
||||
def ignore_event(path, name):
|
||||
# Ignore changes to the index.lock file, since they happen frequently and
|
||||
# dont indicate an actual change in the working tree status
|
||||
return False
|
||||
return path.endswith('.git') and name == 'index.lock'
|
||||
|
||||
try:
|
||||
import pygit2 as git
|
||||
|
||||
class Repository(object):
|
||||
__slots__ = ('directory')
|
||||
__slots__ = ('directory', 'ignore_event')
|
||||
|
||||
def __init__(self, directory):
|
||||
self.directory = os.path.abspath(directory)
|
||||
self.ignore_event = ignore_event
|
||||
|
||||
def do_status(self, directory, path):
|
||||
if path:
|
||||
|
@ -131,10 +141,11 @@ except ImportError:
|
|||
yield line[:-1].decode('utf-8')
|
||||
|
||||
class Repository(object):
|
||||
__slots__ = ('directory',)
|
||||
__slots__ = ('directory', 'ignore_event')
|
||||
|
||||
def __init__(self, directory):
|
||||
self.directory = os.path.abspath(directory)
|
||||
self.ignore_event = ignore_event
|
||||
|
||||
def _gitcmd(self, directory, *args):
|
||||
return readlines(('git',) + args, directory)
|
||||
|
|
Loading…
Reference in New Issue