Merge remote-tracking branch 'kovidgoyal/fix-482' into develop

Conflicts:
	powerline/lib/vcs/git.py
This commit is contained in:
Kim Silkebækken 2013-06-28 13:47:25 +02:00
commit afe415a398
4 changed files with 47 additions and 22 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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)