hgext/inotify/__init__.py
changeset 20622 352abbb0be88
parent 20621 5beb49fd5958
child 20623 84f6bc03b4e5
equal deleted inserted replaced
20621:5beb49fd5958 20622:352abbb0be88
     1 # __init__.py - inotify-based status acceleration for Linux
       
     2 #
       
     3 # Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
       
     4 # Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
       
     5 #
       
     6 # This software may be used and distributed according to the terms of the
       
     7 # GNU General Public License version 2 or any later version.
       
     8 
       
     9 '''accelerate status report using Linux's inotify service'''
       
    10 
       
    11 # todo: socket permissions
       
    12 
       
    13 from mercurial.i18n import _
       
    14 from mercurial import util
       
    15 import server
       
    16 from client import client, QueryFailed
       
    17 
       
    18 testedwith = 'internal'
       
    19 
       
    20 def serve(ui, repo, **opts):
       
    21     '''start an inotify server for this repository'''
       
    22     server.start(ui, repo.dirstate, repo.root, opts)
       
    23 
       
    24 def debuginotify(ui, repo, **opts):
       
    25     '''debugging information for inotify extension
       
    26 
       
    27     Prints the list of directories being watched by the inotify server.
       
    28     '''
       
    29     cli = client(ui, repo)
       
    30     response = cli.debugquery()
       
    31 
       
    32     ui.write(_('directories being watched:\n'))
       
    33     for path in response:
       
    34         ui.write(('  %s/\n') % path)
       
    35 
       
    36 def reposetup(ui, repo):
       
    37     if not util.safehasattr(repo, 'dirstate'):
       
    38         return
       
    39 
       
    40     class inotifydirstate(repo.dirstate.__class__):
       
    41 
       
    42         # We'll set this to false after an unsuccessful attempt so that
       
    43         # next calls of status() within the same instance don't try again
       
    44         # to start an inotify server if it won't start.
       
    45         _inotifyon = True
       
    46 
       
    47         def status(self, match, subrepos, ignored, clean, unknown):
       
    48             files = match.files()
       
    49             if '.' in files:
       
    50                 files = []
       
    51             if (self._inotifyon and not ignored and not subrepos and
       
    52                 not self._dirty):
       
    53                 cli = client(ui, repo)
       
    54                 try:
       
    55                     result = cli.statusquery(files, match, False,
       
    56                                             clean, unknown)
       
    57                 except QueryFailed, instr:
       
    58                     ui.debug(str(instr))
       
    59                     # don't retry within the same hg instance
       
    60                     inotifydirstate._inotifyon = False
       
    61                     pass
       
    62                 else:
       
    63                     if ui.config('inotify', 'debug'):
       
    64                         r2 = super(inotifydirstate, self).status(
       
    65                             match, [], False, clean, unknown)
       
    66                         for c, a, b in zip('LMARDUIC', result, r2):
       
    67                             for f in a:
       
    68                                 if f not in b:
       
    69                                     ui.warn('*** inotify: %s +%s\n' % (c, f))
       
    70                             for f in b:
       
    71                                 if f not in a:
       
    72                                     ui.warn('*** inotify: %s -%s\n' % (c, f))
       
    73                         result = r2
       
    74                     return result
       
    75             return super(inotifydirstate, self).status(
       
    76                 match, subrepos, ignored, clean, unknown)
       
    77 
       
    78     repo.dirstate.__class__ = inotifydirstate
       
    79 
       
    80 cmdtable = {
       
    81     'debuginotify':
       
    82         (debuginotify, [], ('hg debuginotify')),
       
    83     '^inserve':
       
    84         (serve,
       
    85          [('d', 'daemon', None, _('run server in background')),
       
    86           ('', 'daemon-pipefds', '',
       
    87            _('used internally by daemon mode'), _('NUM')),
       
    88           ('t', 'idle-timeout', '',
       
    89            _('minutes to sit idle before exiting'), _('NUM')),
       
    90           ('', 'pid-file', '',
       
    91            _('name of file to write process ID to'), _('FILE'))],
       
    92          _('hg inserve [OPTION]...')),
       
    93     }